00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <cubeos.h>
00017 #include <mc68332.h>
00018 #include <ivtab.h>
00019 #include <i2cd.h>
00020 #include <pcf8584.h>
00021 #include <stdio.h>
00022
00030 struct i2c i2c[2];
00031
00038 static void GenerateStop (struct i2c *p, unsigned char mess)
00039 {
00040 p->m_state = MASTER_IDLE;
00041 p->m_buff[p->m_tail]->status = mess;
00042 p->m_buff[p->m_tail]->procBytes = p->m_dcnt;
00043 if (++p->m_tail >= MBUFLEN)
00044 p->m_tail = 0;
00045 p->m_cnt--;
00046 ssem_signal (p->m_sem);
00047
00048
00049
00050 if (p->m_cnt == 0) {
00051 p->mode = I2C_SLAVE_MODE;
00052 } else {
00053 (p->m_state_handler) (p);
00054 }
00055 }
00056
00062 void _I2C_master_handler (struct i2c *p)
00063 {
00064 struct i2c_device *dev;
00065 struct i2cmess *msg;
00066 unsigned long timeoutcnt;
00067 unsigned char dummy;
00068
00069 dev = p->ioaddr;
00070 msg = p->m_buff[p->m_tail];
00071
00072 switch (p->m_state) {
00073 case MASTER_IDLE:
00074 timeoutcnt = I2C_TIMEOUT_VAL;
00075 while (!(dev->control & BB) && timeoutcnt--);
00076
00077 if (timeoutcnt) {
00078 p->m_dcnt = 0;
00079 p->m_state = (msg->address & 1) ? MASTER_WAIT_ACK : MASTER_SEND;
00080 dev->data = msg->address;
00081 dev->control = PIN | ESO | ENI | STA | ACK;
00082
00083 } else {
00084 GenerateStop (p, I2C_TIME_OUT);
00085 }
00086 return;
00087 case MASTER_SEND:
00088 if (dev->control & LAB) {
00089 p->mode = I2C_SLAVE_MODE;
00090 (p->s_state_handler) (p);
00091 p->mode = I2C_MASTER_MODE;
00092 GenerateStop (p, I2C_ARBITRATION_LOST);
00093 return;
00094 }
00095 if (dev->control & LRB) {
00096 dev->control = PIN | ESO | ENI | STO | ACK;
00097 GenerateStop (p, I2C_NACK_ON_DATA);
00098
00099 } else if (p->m_dcnt < msg->nrBytes)
00100 dev->data = msg->buf[p->m_dcnt++];
00101 else {
00102 dev->control = PIN | ESO | ENI | STO | ACK;
00103 GenerateStop (p, I2C_OK);
00104 }
00105 break;
00106 case MASTER_WAIT_ACK:
00107 if (dev->control & LAB) {
00108 p->mode = I2C_SLAVE_MODE;
00109 (p->s_state_handler) (p);
00110 p->mode = I2C_MASTER_MODE;
00111 GenerateStop (p, I2C_ARBITRATION_LOST);
00112 return;
00113 }
00114 if (dev->control & LRB) {
00115 dev->control = PIN | ESO | ENI | STO | ACK;
00116 GenerateStop (p, I2C_NACK_ON_ADDRESS);
00117 } else {
00118 if (msg->nrBytes == 1) {
00119 p->m_state = MASTER_RECV_LAST;
00120 dev->control = ESO | ENI;
00121 } else {
00122 p->m_state = MASTER_RECV;
00123 }
00124 dummy = dev->data;
00125
00126 }
00127 break;
00128 case MASTER_RECV:
00129 if (p->m_dcnt + 2 == msg->nrBytes) {
00130 dev->control = ESO | ENI;
00131 p->m_state = MASTER_RECV_LAST;
00132 }
00133 msg->buf[p->m_dcnt++] = dev->data;
00134 break;
00135 case MASTER_RECV_LAST:
00136 dev->control = PIN | ESO | ENI | STO | ACK;
00137 msg->buf[p->m_dcnt++] = dev->data;
00138 GenerateStop (p, I2C_OK);
00139 break;
00140 default:
00141 GenerateStop (p, I2C_ERR);
00142 break;
00143 }
00144 }
00145
00146
00152 void _I2C_slave_handler (struct i2c *p)
00153 {
00154 register struct i2c_device *dev;
00155
00156 dev = p->ioaddr;
00157
00158 switch (p->s_state) {
00159 case SLAVE_IDLE:
00160 if (dev->control & AAS) {
00161 if (dev->data & 1) {
00162 p->s_state = SLAVE_SEND;
00163 } else {
00164 if (p->s_icnt >= SBUFLEN) {
00165 p->s_status |= I2C_SLAVE_IBUF_OVERFLOW;
00166 dev->control = PIN | ESO | ENI;
00167 ssem_signal (p->s_isem);
00168 } else {
00169 p->s_state = SLAVE_RECV;
00170 }
00171 }
00172 } else {
00173 dev->control = PIN | ESO | ENI;
00174 }
00175 return;
00176 case SLAVE_SEND:
00177 if (dev->control & LRB) {
00178 p->s_state = SLAVE_IDLE;
00179 ssem_signal (p->s_osem);
00180 }
00181 if (p->s_ocnt == 0) {
00182 dev->data = 0xff;
00183 p->s_status |= I2C_SLAVE_OBUF_EMPTY;
00184 } else {
00185 dev->data = p->s_obuff[p->s_optr++];
00186 p->s_ocnt--;
00187 }
00188 return;
00189 case SLAVE_RECV:
00190 if (dev->control & STS) {
00191 p->s_state = SLAVE_IDLE;
00192 dev->control = PIN | ESO | ENI | ACK;
00193 ssem_signal (p->s_isem);
00194 } else if (p->s_icnt == SBUFLEN) {
00195 dev->control = PIN | ESO | ENI;
00196 p->s_state = SLAVE_IDLE;
00197 ssem_signal (p->s_isem);
00198 } else {
00199 p->s_ibuff[p->s_iptr++] = dev->data;
00200 p->s_icnt++;
00201 }
00202 return;
00203 default:
00204 dev->control = PIN | ESO | ENI | ACK;
00205 p->s_status |= I2C_SLAVE_ERR;
00206 return;
00207 }
00208 }
00209
00220 void I2C_inthandler (unsigned long minor)
00221 {
00222 struct i2c *p;
00223
00224 p = &i2c[minor];
00225 if (p->mode == I2C_MASTER_MODE)
00226 (p->m_state_handler) (p);
00227 else
00228 (p->s_state_handler) (p);
00229 }
00230
00237 int I2C_init (int which, unsigned long ioaddr)
00238 {
00239 register struct i2c *iptr;
00240 register struct i2c_device *chip;
00241 unsigned short v;
00242
00243 printf("I2C init called\n");
00244
00245 if (which == I2CA) {
00246 if (I2CA_BASE == 0)
00247 return (-1);
00248
00249
00250 _KERN_IVTab_setvector (I2CA_VECTORNUM, I2C_int_a);
00251
00252 #ifdef I2C_INITCSA
00253 if (I2C_INITCSA) {
00254 writeshort (SIM_CSBAR4, ioaddr >> 8);
00255 writeshort (SIM_CSOR4, 0x7ffa);
00256
00257 v = readshort (SIM_CSPAR0);
00258 v |= 0xc00;
00259 v &= 0xfbff;
00260 writeshort (SIM_CSPAR0, v);
00261 }
00262 #endif
00263 iptr = &(i2c[0]);
00264 } else if (which == I2CB) {
00265 if (I2CB_BASE == 0)
00266 return (-1);
00267 _KERN_IVTab_setvector (I2CB_VECTORNUM, I2C_int_b);
00268
00269 #ifdef I2C_INITCSB
00270 if (I2C_INITCSB) {
00271 writeshort (SIM_CSBAR3, ioaddr >> 8);
00272 writeshort (SIM_CSOR3, 0x7ffa);
00273
00274 v = readshort (SIM_CSPAR0);
00275 v |= 0x300;
00276 v &= 0xfeff;
00277 writeshort (SIM_CSPAR0, v);
00278 }
00279 #endif
00280 iptr = &(i2c[1]);
00281 } else
00282 return (-1);
00283
00284
00285 iptr->ioaddr = (struct i2c_device *) ioaddr;
00286 iptr->mode = I2C_SLAVE_MODE;
00287 iptr->m_head = iptr->m_tail = 0;
00288
00289 iptr->m_sem = MBUFLEN;
00290 iptr->m_cnt = 0;
00291 iptr->m_dcnt = 0;
00292 iptr->m_state_handler = &_I2C_master_handler;
00293 iptr->m_state = MASTER_IDLE;
00294
00295 iptr->s_iptr = 0;
00296 iptr->s_isem = 0;
00297 iptr->s_icnt = 0;
00298 iptr->s_optr = 0;
00299 iptr->s_osem = 0;
00300 iptr->s_ocnt = 0;
00301 iptr->s_state_handler = &_I2C_slave_handler;
00302 iptr->s_state = SLAVE_IDLE;
00303 iptr->s_status = 0;
00304
00305
00306 chip = iptr->ioaddr;
00307 chip->control = 0x80;
00308 if (which == I2CA)
00309 chip->data = I2CA_SLAVE_ADDR;
00310 else
00311 chip->data = I2CB_SLAVE_ADDR;
00312 chip->control = 0xa0;
00313 chip->data = I2C_SPEED;
00314 chip->control = PIN | ESO | ENI | ACK;
00315 return (0);
00316 }
00317
00318
00319
00326 int I2C_Start_I2C_Transfer (unsigned char which, struct i2cmess *msg)
00327 {
00328 struct i2c *hdl;
00329 int timeout;
00330
00331 if (which == I2CA)
00332 hdl = &i2c[0];
00333 else
00334 hdl = &i2c[1];
00335
00336 if (!(hdl->ioaddr)) {
00337 msg->status = I2C_NO_BUS;
00338 return (-1);
00339 }
00340
00341 msg->status = I2C_NOT_PROCESSED;
00342 ssem_wait (hdl->m_sem);
00343 hdl->m_buff[hdl->m_head++] = msg;
00344 ++hdl->m_cnt;
00345 if (hdl->m_head >= MBUFLEN)
00346 hdl->m_head = 0;
00347
00348
00349 if ((hdl->mode == I2C_SLAVE_MODE) && (hdl->s_state == SLAVE_IDLE)) {
00350 hdl->mode = I2C_MASTER_MODE;
00351 disable ();
00352 (hdl->m_state_handler) (hdl);
00353 enable ();
00354 }
00355 timeout = 0;
00356 while ((msg->status == I2C_NOT_PROCESSED) && (++timeout < 1000000));
00357 if (timeout > 0)
00358 return (-1);
00359
00360 switch (msg->status) {
00361 case I2C_OK:
00362 return (0);
00363 break;
00364 case I2C_NACK_ON_DATA:
00365 return (-1);
00366 break;
00367 case I2C_NACK_ON_ADDRESS:
00368 return (-1);
00369 break;
00370 case I2C_ARBITRATION_LOST:
00371 return (-1);
00372 break;
00373 case I2C_TIME_OUT:
00374 return (-1);
00375 break;
00376 case I2C_ERR:
00377 return (-1);
00378 break;
00379 default:
00380 return (-1);
00381 break;
00382 }
00383
00384 }
00385
00392 int I2C_slprocess (unsigned char which, struct i2cmess *msg)
00393 {
00394 struct i2c *hdl;
00395 int i;
00396
00397 if (which == I2CA)
00398 hdl = &i2c[0];
00399 else
00400 hdl = &i2c[1];
00401
00402 if (!(hdl->ioaddr)) {
00403 msg->status = I2C_NO_BUS;
00404 return (-1);
00405 }
00406
00407 msg->status = I2C_NOT_PROCESSED;
00408
00409 if (msg->nrBytes != SBUFLEN)
00410 return (-1);
00411
00412 if (msg->address & 1) {
00413 ssem_wait (hdl->s_isem);
00414 disable ();
00415 for (i = 0; i < hdl->s_icnt; i++)
00416 msg->buf[i] = hdl->s_ibuff[i];
00417 msg->procBytes = hdl->s_icnt;
00418 hdl->s_icnt = 0;
00419 hdl->s_iptr = 0;
00420 if (hdl->s_status == 0)
00421 msg->status = I2C_OK;
00422 if (hdl->s_status & I2C_SLAVE_IBUF_OVERFLOW) {
00423 msg->status = I2C_ERR;
00424 hdl->s_status &= ~I2C_SLAVE_IBUF_OVERFLOW;
00425 }
00426 enable ();
00427 } else {
00428 disable ();
00429 for (i = 0; i < SBUFLEN; i++)
00430 hdl->s_obuff[i] = msg->buf[i];
00431 hdl->s_ocnt = SBUFLEN;
00432 hdl->s_optr = 0;
00433 enable ();
00434 ssem_wait (hdl->s_osem);
00435 disable ();
00436 msg->procBytes = hdl->s_ocnt;
00437 hdl->s_ocnt = 0;
00438 hdl->s_optr = 0;
00439 if (hdl->s_status == 0)
00440 msg->status = I2C_OK;
00441 if (hdl->s_status & I2C_SLAVE_OBUF_EMPTY) {
00442 msg->status = I2C_ERR;
00443 hdl->s_status &= ~I2C_SLAVE_OBUF_EMPTY;
00444 }
00445 enable ();
00446 }
00447 return (0);
00448 }
00449
00457 int I2C_process (unsigned char whichBus, unsigned char whichQueue, struct i2cmess *msg)
00458 {
00459 if (whichQueue == I2C_MASTER)
00460 return I2C_Start_I2C_Transfer (whichBus, msg);
00461 else
00462 return I2C_slprocess (whichBus, msg);
00463 }
00464
00465
00474 int I2C_messagestatus (struct i2cmess *msg)
00475 {
00476 switch (msg->status) {
00477 case I2C_OK:
00478 return (0);
00479 break;
00480 case I2C_NACK_ON_DATA:
00481 printf ("I2C: transfer interupted\n");
00482 return (-1);
00483 break;
00484 case I2C_NACK_ON_ADDRESS:
00485 printf ("I2C: device not present\n");
00486 return (-1);
00487 break;
00488 case I2C_ARBITRATION_LOST:
00489 printf ("I2C: arbitration lost\n");
00490 return (-1);
00491 break;
00492 case I2C_TIME_OUT:
00493 printf ("I2C: time-out\n\r");
00494 return (-1);
00495 break;
00496 case I2C_ERR:
00497 printf ("I2C: master handler in strange state\n");
00498 return (-1);
00499 break;
00500 case I2C_NO_BUS:
00501 printf ("I2C: there is no such bus\n");
00502 return (-1);
00503 break;
00504 default:
00505 printf ("I2C: unknown status (%d)\n\r", msg->status);
00506 return (-1);
00507 break;
00508 }
00509
00510 }
00511
00517 int I2C_scanbus (unsigned char bus)
00518 {
00519
00520 struct i2cmess msg;
00521 unsigned char buf[10];
00522 int i, j;
00523 int count = 0;
00524 int ret;
00525
00526 for (i = 0; i < 127; i++) {
00527
00528 msg.address = i << 1;
00529 msg.nrBytes = 1;
00530 msg.buf = buf;
00531 for (j = 0; j < 10; j++)
00532 buf[j] = 0;
00533
00534 ret = I2C_process (bus, I2C_MASTER, &msg);
00535
00536 switch (msg.status) {
00537 case I2C_OK:
00538 printf ("found device at adress 0x%x \n", msg.address);
00539 count++;
00540 break;
00541 case I2C_TIME_OUT:
00542 case I2C_NACK_ON_ADDRESS:
00543 case I2C_NACK_ON_DATA:
00544 printf (".");
00545 fflush (stdout);
00546 break;
00547 case I2C_NO_BUS:
00548 I2C_messagestatus (&msg);
00549 return (-1);
00550 break;
00551 default:
00552 I2C_messagestatus (&msg);
00553 }
00554
00555 }
00556 return (count);
00557 }