source: rtems/bsps/powerpc/mvme5500/GT64260/GT64260TWSI.c @ 8f12ee32

Last change on this file since 8f12ee32 was 8f12ee32, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 25, 2018 at 8:22:37 AM

bsp/mvme5500: Move source files to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Two-Wire Serial Interface (TWSI) support for the GT64260
3 */
4
5/*
6 * Copyright (c) 2004, Brookhaven National Laboratory and
7 *                 Shuchen Kate Feng <feng1@bnl.gov>
8 * All rights reserved.
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution.
12 *
13 * See section 24:TWSI interface of "the GT-64260B System Controller
14 * for powerPc Processors Data Sheet".
15 *
16 * For full TWSI protocol description look in Philips Semiconductor
17 * TWSI spec.
18 *
19 * We need it to read out I2C devices used for the MVME5500
20 * (eg. the memory SPD and VPD).
21 */
22
23#include <libcpu/spr.h>  /*registers.h included here for rtems_bsp_delay()*/
24#include <libcpu/io.h>
25#include <rtems/bspIo.h>
26
27#include "bsp/gtreg.h"
28#include "bsp/GT64260TWSI.h"
29
30#define MAX_LOOP 100
31
32#define TWSI_DEBUG 0
33
34static int TWSI_initFlg = 0;  /* TWSI Initialization Flag */
35
36void GT64260TWSIinit(void)
37{
38  if ( !TWSI_initFlg ) {
39#if TWSI_DEBUG
40   printk("GT64260TWSIinit(");
41#endif
42   outl( 0, TWSI_SFT_RST); /* soft reset */
43   rtems_bsp_delay(1000);
44
45   /* See 24.2.5 : Assume bus speed is 133MHZ
46    * Try to be close to the default frequency : 62.5KHZ
47    * value 0x2c: 69.27 KHz TWSI bus clock
48    */
49   outl(0x2c, TWSI_BAUDE_RATE);
50   rtems_bsp_delay(1000);
51
52   /* Set Acknowledge and enable TWSI in the Control register */
53   outl(0x44, TWSI_CTRL);
54   rtems_bsp_delay(4000);
55   TWSI_initFlg = 1;
56#if TWSI_DEBUG
57   printk(")\n");
58#endif
59  }
60}
61
62/* return the interrupt flag */
63static int GT64260TWSIintFlag(void)
64{
65  unsigned int loop;
66
67  for (loop = 0; loop < MAX_LOOP; loop++ ) {
68    /* Return 1 if the interrupt flag is set */
69    if (inl(TWSI_CTRL) & TWSI_INTFLG)
70      return(1);
71    rtems_bsp_delay(1000);
72  }
73  return(0);
74}
75
76int GT64260TWSIstop(void)
77{
78
79#if TWSI_DEBUG
80  printk("GT64260TWSIstop(");
81#endif
82
83  outl((inl(TWSI_CTRL) | TWSI_STOP), TWSI_CTRL);
84  rtems_bsp_delay(1000);
85
86  /* Check if interrupt flag bit is set*/
87  if (GT64260TWSIintFlag()) {
88     outl((inl( TWSI_CTRL) & ~TWSI_INTFLG), TWSI_CTRL);
89     rtems_bsp_delay(1000);
90#if TWSI_DEBUG
91     printk(")\n");
92#endif
93     return(0);
94  }
95#if TWSI_DEBUG
96     printk("NoIntFlag\n");
97#endif
98  return(-1);
99}
100
101int GT64260TWSIstart(void)
102{
103  unsigned int loop;
104  unsigned int status;
105
106#if TWSI_DEBUG
107  printk("GT64260TWSIstart(");
108#endif
109  /* Initialize the TWSI interface */
110  GT64260TWSIinit();
111
112  /* set the start bit */
113  outl((TWSI_START | TWSI_TWSIEN), TWSI_CTRL);
114  rtems_bsp_delay(1000);
115
116  if (GT64260TWSIintFlag()) {
117    /* Check for completion of START sequence */
118    for (loop = 0; loop<MAX_LOOP; loop++ ) {
119      /* if (start condition transmitted) ||
120       *    (repeated start condition transmitted )
121       */
122      if (((status= inl( TWSI_STATUS)) == 8) || (status == 0x10)) {
123#if TWSI_DEBUG
124        printk(")");
125#endif
126        return(0);
127      }
128      rtems_bsp_delay(1000);
129    }
130  }
131  /* if loop ends or intFlag ==0 */
132  GT64260TWSIstop();
133  return(-1);
134}
135
136int GT64260TWSIread(unsigned char * pData, int lastByte)
137{
138  unsigned int loop;
139
140#if TWSI_DEBUG
141  printk("GT64260TWSIread(");
142#endif
143  /* Clear INTFLG and set ACK and ENABLE bits */
144  outl((TWSI_ACK | TWSI_TWSIEN), TWSI_CTRL);
145  rtems_bsp_delay(1000);
146
147  if (GT64260TWSIintFlag()) {
148    for (loop = 0; loop< MAX_LOOP; loop++) {
149      /* if Master received read data, acknowledge transmitted */
150      if ( (inl( TWSI_STATUS) == 0x50)) {
151        *pData = (unsigned char) inl( TWSI_DATA);
152        rtems_bsp_delay(1500);
153
154        /* Clear INTFLAG and set Enable bit only */
155        if (lastByte)
156         outl(TWSI_TWSIEN, TWSI_CTRL);
157        rtems_bsp_delay(1500);
158#if TWSI_DEBUG
159        printk(")\n");
160#endif
161        return(0);
162      }
163      rtems_bsp_delay(1000);
164    } /* end for */
165  }
166  /* if loop ends or intFlag ==0 */
167  GT64260TWSIstop();
168  return(-1);
169}
170
171/* do a TWSI write cycle on the TWSI bus*/
172int GT64260TWSIwrite(unsigned char Data)
173{
174  unsigned int loop;
175  unsigned int status;
176
177#if TWSI_DEBUG
178  printk("GT64260TWSIwrite(");
179#endif
180  /* Write data into the TWSI data register */
181  outl(((unsigned int) Data), TWSI_DATA);
182  rtems_bsp_delay(1000);
183
184  /* Clear INTFLG in the control register to drive data onto TWSI bus */
185  outl(0, TWSI_CTRL);
186  rtems_bsp_delay(1000);
187
188  if (GT64260TWSIintFlag() ) {
189    for (loop = 0; loop< MAX_LOOP; loop++) {
190      rtems_bsp_delay(1000);
191      /* if address + write bit transmitted, acknowledge not received */
192      if ( (status = inl( TWSI_STATUS)) == 0x20) {
193        /* No device responding, generate STOP and return -1 */
194        printk("no device responding\n");
195        GT64260TWSIstop();
196        return(-1);
197      }
198      /* if (address + write bit transmitted, acknowledge received)
199       * (Master transmmitted data byte, acknowledge received)
200       *    (address + read bit transmitted, acknowledge received)
201       */
202      if ((status == 0x18)||(status == 0x28)||(status == 0x40)) {
203#if TWSI_DEBUG
204        printk(")\n");
205#endif
206        return(0);
207      }
208      rtems_bsp_delay(1000);
209    } /* end for */
210  }
211  printk("No correct status, timeout\n");
212  GT64260TWSIstop();
213  return(-1);
214}
Note: See TracBrowser for help on using the repository browser.