00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 #include <stdlib.h>
00030 #include <string.h>
00031 #include <util/twi.h>
00032 
00033 #include <autoconf.h>
00034 #include <aversive/errno.h>
00035 #include <i2c.h>
00036 
00037 #if I2C_SEND_BUFFER_SIZE < 1
00038 #error "I2C_SEND_BUFFER_SIZE must be at least 1"
00039 #endif
00040 
00041 #if I2C_RECV_BUFFER_SIZE < 1
00042 #error "I2C_RECV_BUFFER_SIZE must be at least 1"
00043 #endif
00044 
00047 static void (*g_recv_event)(uint8_t *, int8_t) = NULL;
00048 
00051 static void (*g_recv_byte_event)(uint8_t, uint8_t, uint8_t) = NULL;
00052 
00055 static void (*g_send_event)(int8_t) = NULL;
00056 
00057 static volatile i2c_mode_t g_mode = I2C_MODE_UNINIT;
00058 static volatile uint8_t g_status = I2C_STATUS_READY;
00059 
00060 static volatile uint8_t g_ctrl = 0; 
00061 static volatile uint8_t g_sync_res = 0; 
00062 static uint8_t g_send_buf[I2C_SEND_BUFFER_SIZE];
00063 static uint8_t g_recv_buf[I2C_RECV_BUFFER_SIZE];
00064 static volatile uint8_t g_dest = 0; 
00065 
00066 
00067 static volatile uint8_t g_send_nbytes = 0; 
00068 static volatile uint8_t g_send_size = 0; 
00069 static volatile uint8_t g_recv_nbytes = 0; 
00070 static volatile uint8_t g_recv_size = 0; 
00071 
00072 #if I2C_DEBUG == 1
00073 #include <stdio.h>
00074 #include <aversive/pgmspace.h>
00075 static volatile uint8_t g_prev_twstatus = 0;
00076 static volatile uint8_t g_intr_cpt = 0;
00077 static volatile uint8_t g_prev_status = 0;
00078 static volatile uint8_t g_command = 0;
00079 #endif
00080 
00088 void 
00089 i2c_init(i2c_mode_t mode, uint8_t add)
00090 {
00091         uint8_t flags;
00092 
00093         IRQ_LOCK(flags);
00094   
00095         if (mode == I2C_MODE_UNINIT) {
00096                 
00097                 TWCR = 0;
00098                 IRQ_UNLOCK(flags);
00099                 return;
00100         }
00101 #ifdef CONFIG_MODULE_I2C_MASTER
00102         else if (mode == I2C_MODE_MASTER) {
00103                 
00104                 TWCR = (1<<TWEN) | (1<<TWIE) ;
00105         }
00106 #endif
00107         else {
00108                 
00109                 TWCR = (1<<TWEN) | (1<<TWIE) | (1<<TWEA) ;
00110         }
00111 
00112         TWBR = I2C_BITRATE;
00113   
00114         
00115         if(I2C_PRESCALER & 1)
00116                 sbi(TWSR, TWPS0);
00117         if(I2C_PRESCALER & 2)
00118                 sbi(TWSR, TWPS1);
00119         
00120         
00121         TWAR = add << 1 ;
00122         
00123         
00124         if (add & 0x80)
00125                 sbi(TWAR, TWGCE);
00126         
00127         
00128         g_mode = mode;
00129         g_status = I2C_STATUS_READY;
00130         g_dest = 0;
00131         g_ctrl = 0;
00132         g_recv_nbytes = 0;
00133         g_recv_size = 0;
00134         g_send_nbytes = 0;
00135         g_send_size = 0;
00136 
00137         IRQ_UNLOCK(flags);
00138 }
00139 
00140 
00152 void 
00153 i2c_register_recv_event(void (*event)(uint8_t *, int8_t))
00154 {
00155         uint8_t flags;
00156         IRQ_LOCK(flags);
00157         g_recv_event = event ;
00158         IRQ_UNLOCK(flags);
00159 }
00160 
00168 void 
00169 i2c_register_recv_byte_event(void (*event)(uint8_t, uint8_t, uint8_t))
00170 {
00171         uint8_t flags;
00172         IRQ_LOCK(flags);
00173         g_recv_byte_event = event ;
00174         IRQ_UNLOCK(flags);
00175 }
00176 
00186 void 
00187 i2c_register_send_event(void (*event)(int8_t))
00188 {
00189         uint8_t flags;
00190         IRQ_LOCK(flags);
00191         g_send_event = event ;
00192         IRQ_UNLOCK(flags);
00193 }
00194 
00211 int8_t 
00212 i2c_send(uint8_t dest_add, uint8_t *buf, uint8_t size, uint8_t ctrl) 
00213 {
00214         uint8_t flags;
00215 
00216         IRQ_LOCK(flags);
00217         if (g_mode == I2C_MODE_UNINIT) {
00218                 IRQ_UNLOCK(flags);
00219                 return -ENXIO;
00220         }
00221         
00222         if (g_status & (I2C_STATUS_MASTER_XMIT |
00223                         I2C_STATUS_MASTER_RECV |
00224                         I2C_STATUS_SLAVE_XMIT_WAIT |
00225                         I2C_STATUS_SLAVE_XMIT)) {
00226                 IRQ_UNLOCK(flags);
00227                 return -EBUSY;
00228         }
00229 
00230         if (size > I2C_SEND_BUFFER_SIZE) { 
00231                 IRQ_UNLOCK(flags);
00232                 return -EINVAL;
00233         }
00234 
00235         
00236         if (g_mode == I2C_MODE_SLAVE) {
00237                 if (dest_add != I2C_ADD_MASTER) {
00238                         IRQ_UNLOCK(flags);
00239                         return -EINVAL;
00240                 }
00241         }
00242         else {
00243                 if (dest_add >= I2C_ADD_MASTER) {
00244                         IRQ_UNLOCK(flags);
00245                         return -EINVAL;
00246                 }
00247         }
00248 
00249         
00250 
00251         if ( g_send_buf != buf ) {
00252                 g_dest = dest_add;
00253                 g_send_size = size;
00254                 g_ctrl = ctrl;
00255                 memcpy(g_send_buf, buf, size);
00256         }
00257 
00258         
00259 
00260         if (dest_add != I2C_ADD_MASTER) {
00261                 g_status |= I2C_STATUS_MASTER_XMIT;
00262                 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTA);
00263         }
00264         else {
00265                 
00266                 g_status |= I2C_STATUS_SLAVE_XMIT_WAIT;
00267         }
00268 
00269         IRQ_UNLOCK(flags);
00270 
00271         
00272 
00273         if (ctrl & I2C_CTRL_SYNC) {
00274                 while ( 1 ) {
00275                         IRQ_LOCK(flags);
00276                         if (g_status & I2C_STATUS_OP_FINISHED) {
00277                                 g_status &= ~(I2C_STATUS_MASTER_XMIT |
00278                                               I2C_STATUS_MASTER_RECV |
00279                                               I2C_STATUS_SLAVE_XMIT |
00280                                               I2C_STATUS_SLAVE_RECV |
00281                                               I2C_STATUS_OP_FINISHED);
00282                                 break;
00283                         }
00284                         IRQ_UNLOCK(flags);
00285                 }
00286                 IRQ_UNLOCK(flags);
00287                 if (g_sync_res == size)
00288                         return 0;
00289                 return g_sync_res;
00290         }
00291         
00292         return -ESUCCESS;
00293 }
00294 
00295 
00301 int8_t 
00302 i2c_resend(void) 
00303 {
00304         return i2c_send(g_dest, g_send_buf, g_send_size, g_ctrl);
00305 }
00306 
00310 int8_t 
00311 i2c_rerecv(void) 
00312 {
00313         return i2c_recv(g_dest, g_recv_size, g_ctrl);
00314 }
00315 
00319 void
00320 i2c_release_bus(void)
00321 {
00322         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTO);
00323 }
00324 
00328 void
00329 i2c_reset(void)
00330 {
00331         uint8_t flags;
00332 
00333         IRQ_LOCK(flags);
00334         TWCR = 0;
00335         g_status = I2C_STATUS_READY;
00336 #ifdef CONFIG_MODULE_I2C_MASTER
00337         if (g_mode == I2C_MODE_MASTER) 
00338                 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
00339         else
00340 #endif
00341                 TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | 
00342                         (1<<TWSTO) | (1<<TWEA);
00343         IRQ_UNLOCK(flags);
00344 }
00345 
00352 int8_t i2c_recv(uint8_t dest_add, uint8_t size, uint8_t ctrl)
00353 {
00354 #ifndef CONFIG_MODULE_I2C_MASTER
00355         return -EINVAL;
00356 #else
00357         uint8_t flags;
00358 
00359         IRQ_LOCK(flags);
00360         if (g_mode == I2C_MODE_UNINIT) {
00361                 IRQ_UNLOCK(flags);
00362                 return -ENXIO;
00363         }
00364         
00365         if (g_status != I2C_STATUS_READY) {
00366                 IRQ_UNLOCK(flags);
00367                 return -EBUSY;
00368         }
00369 
00370         if (size > I2C_SEND_BUFFER_SIZE) { 
00371                 IRQ_UNLOCK(flags);
00372                 return -EINVAL;
00373         }
00374 
00375         if (g_mode == I2C_MODE_SLAVE || dest_add >= I2C_ADD_MASTER) {
00376                 IRQ_UNLOCK(flags);
00377                 return -EINVAL;
00378         }
00379 
00380         g_ctrl = ctrl;
00381         g_recv_size = size;
00382         g_status |= I2C_STATUS_MASTER_RECV;
00383         g_dest = dest_add ; 
00384         TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWSTA);
00385 
00386         IRQ_UNLOCK(flags);
00387 
00388         
00389 
00390         if (ctrl & I2C_CTRL_SYNC) {
00391                 while ( 1 ) {
00392                         IRQ_LOCK(flags);
00393                         if (g_status & I2C_STATUS_OP_FINISHED) {
00394                                 g_status &= ~(I2C_STATUS_MASTER_XMIT |
00395                                               I2C_STATUS_MASTER_RECV |
00396                                               I2C_STATUS_SLAVE_XMIT |
00397                                               I2C_STATUS_SLAVE_RECV |
00398                                               I2C_STATUS_OP_FINISHED);
00399                                 break;
00400                         }
00401                         IRQ_UNLOCK(flags);
00402                 }
00403                 IRQ_UNLOCK(flags);
00404                 if (g_sync_res == size)
00405                         return 0;
00406                 return g_sync_res;
00407         }
00408         
00409         return -ESUCCESS;
00410 #endif
00411 }
00412 
00413 
00420 int8_t i2c_flush(void)
00421 {
00422         uint8_t flags;
00423         IRQ_LOCK(flags);
00424         if ( ! (g_status & I2C_STATUS_SLAVE_XMIT_WAIT) ) {
00425                 IRQ_UNLOCK(flags);
00426                 return -EBUSY;
00427         }
00428 
00429         g_status &= ~(I2C_STATUS_SLAVE_XMIT_WAIT);
00430         IRQ_UNLOCK(flags);
00431         
00432         return -ESUCCESS;
00433 }
00434 
00435 
00447 uint8_t i2c_set_recv_size(uint8_t size)
00448 {
00449         uint8_t flags;
00450 
00451         IRQ_LOCK(flags);
00452 
00453         
00454         if (! (g_status & I2C_STATUS_MASTER_RECV)) {
00455                 IRQ_UNLOCK(flags);
00456                 return -EBUSY;
00457         }
00458 
00459         
00460 
00461 
00462         
00463         if (size > I2C_SEND_BUFFER_SIZE || size <= g_recv_nbytes) {
00464                 IRQ_UNLOCK(flags);
00465                 return -EINVAL;
00466         }
00467         
00468         g_recv_size = size;
00469 
00470         IRQ_UNLOCK(flags);
00471         return -ESUCCESS;
00472 }
00473 
00474 
00478 i2c_mode_t i2c_mode(void)
00479 {
00480         return g_mode;
00481 }
00482 
00486 uint8_t i2c_status(void)
00487 {
00488         return g_status;
00489 }
00490 
00495 uint8_t i2c_get_recv_buffer(uint8_t *buf, uint8_t size)
00496 {
00497         uint8_t flags;
00498 
00499         IRQ_LOCK(flags);
00500         
00501         if ( g_status & (I2C_STATUS_MASTER_RECV |
00502                           I2C_STATUS_SLAVE_RECV) ) {
00503                 IRQ_UNLOCK(flags);
00504                 return -EBUSY;
00505         }
00506 
00507         if (size > g_recv_nbytes) 
00508                 size = g_recv_nbytes;
00509         memcpy(buf, g_recv_buf, size);
00510 
00511         IRQ_UNLOCK(flags);
00512 
00513         return size;
00514 }
00515 
00516 #if I2C_DEBUG == 1
00517 void i2c_debug(void)
00518 {
00519         printf_P(PSTR("mode=0x%x\r\n"), g_mode);
00520         printf_P(PSTR("status=0x%x\r\n"), g_status);
00521         printf_P(PSTR("ctrl=0x%x\r\n"), g_ctrl);
00522         printf_P(PSTR("dst=%d\r\n"), g_dest);
00523         printf_P(PSTR("send_nbytes=%d, send_size=%d\r\n"), g_send_nbytes, g_send_size);
00524         printf_P(PSTR("recv_nbytes=%d, recv_size=%d\r\n"), g_recv_nbytes, g_recv_size);
00525         printf_P(PSTR("prev_twstatus=0x%x\r\n"), g_prev_twstatus);
00526         printf_P(PSTR("intr_cpt=%d\r\n"), g_intr_cpt);
00527         printf_P(PSTR("prev_status=0x%x\r\n"), g_prev_status);
00528         printf_P(PSTR("prev_command=0x%x\r\n"), g_command);
00529 }
00530 #endif
00531 
00538 SIGNAL(SIG_2WIRE_SERIAL)
00539 {
00540         uint8_t hard_status;
00541         uint8_t command = (1<<TWINT) | (1<<TWEN) | (1<<TWIE);
00542 
00543         hard_status = TW_STATUS;
00544 
00545 #if I2C_DEBUG == 1
00546         g_prev_twstatus = hard_status;
00547         g_intr_cpt++;
00548 #endif
00549         switch(hard_status) {
00550 
00551 #ifdef CONFIG_MODULE_I2C_MASTER
00552         case TW_START:      
00553         case TW_REP_START:
00554                 
00555 
00556 
00557                 if (g_status & I2C_STATUS_MASTER_RECV) {
00558                         TWDR = (g_dest << 1) | (0x01);
00559                         g_recv_nbytes = 0;
00560                 }
00561                 else {
00562                         TWDR = (g_dest << 1);
00563                         g_send_nbytes = 0;
00564                 }
00565                 break;
00566 
00567 
00568                 
00569 
00570         case TW_MT_SLA_ACK:
00571                 
00572                 TWDR = g_send_buf[g_send_nbytes++];
00573                 break;
00574 
00575         case TW_MT_SLA_NACK:
00576                 
00577                 g_send_nbytes = -ENOENT;
00578                 g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_XMIT_EVT);
00579                 break;
00580 
00581         case TW_MT_DATA_ACK: 
00582                 
00583 
00584                 if (g_send_nbytes >= g_send_size) {
00585                         g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_XMIT_EVT);
00586                 }
00587                 else {
00588                         TWDR = g_send_buf[g_send_nbytes++];
00589                 }
00590                 break;
00591 
00592         case TW_MT_DATA_NACK:
00593                 
00594 
00595 
00596                 g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_XMIT_EVT);
00597                 break;
00598       
00599 
00600                 
00601 
00602         case TW_MR_SLA_ACK:
00603                 
00604 
00605 
00606                 if (g_recv_size > 1)
00607                         command |= (1<<TWEA);
00608                 break;
00609                 
00610         case TW_MR_SLA_NACK:
00611                 
00612                 g_recv_nbytes = -ENOENT;
00613                 g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_RECV_EVT);
00614                 break;
00615 
00616         case TW_MR_DATA_ACK:
00617                 
00618                 if (g_recv_nbytes < g_recv_size) {
00619                         g_recv_buf[g_recv_nbytes] = TWDR;
00620 
00621                         if(g_recv_byte_event)
00622                                 g_recv_byte_event(hard_status, g_recv_nbytes, g_recv_buf[g_recv_nbytes]);
00623 
00624                         g_recv_nbytes++;
00625                 }
00626                 
00627                 if (g_recv_nbytes < g_recv_size) {
00628                         command |= (1<<TWEA);
00629                 }
00630                 break;
00631 
00632         case TW_MR_DATA_NACK:
00633                 
00634                 if (g_recv_nbytes < g_recv_size) {
00635                         g_recv_buf[g_recv_nbytes] = TWDR;
00636 
00637                         if(g_recv_byte_event)
00638                                 g_recv_byte_event(hard_status, g_recv_nbytes, g_recv_buf[g_recv_nbytes]);
00639                         g_recv_nbytes ++;
00640                 }
00641                 g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_RECV_EVT);
00642                 break;
00643 
00644 
00645                 
00646 
00647         case TW_MT_ARB_LOST:
00648                 
00649                 
00650                 if (g_status & I2C_STATUS_MASTER_XMIT) {
00651                         g_recv_nbytes = -EAGAIN;
00652                         g_status |= I2C_STATUS_NEED_RECV_EVT;
00653                 }
00654                 else if (g_status & I2C_STATUS_MASTER_RECV) {
00655                         g_send_nbytes = -EAGAIN;
00656                         g_status |= I2C_STATUS_NEED_XMIT_EVT;           
00657                 }
00658                  
00659                 break;
00660 
00661 #endif      
00662 
00663         
00664                 
00665 
00666         case TW_SR_ARB_LOST_SLA_ACK:
00667         case TW_SR_ARB_LOST_GCALL_ACK:
00668         case TW_SR_GCALL_ACK:
00669         case TW_SR_SLA_ACK:
00670                 
00671 
00672                 g_recv_nbytes = 0;
00673                 g_recv_size = I2C_RECV_BUFFER_SIZE;
00674                 g_status |= I2C_STATUS_SLAVE_RECV;
00675                 command |= (1<<TWEA);
00676                 break;
00677 
00678         case TW_SR_DATA_ACK:
00679         case TW_SR_GCALL_DATA_ACK:
00680                 
00681 
00682                 if (g_recv_nbytes < g_recv_size) {
00683                         g_recv_buf[g_recv_nbytes] = TWDR;
00684                         if(g_recv_byte_event)
00685                                 g_recv_byte_event(hard_status, g_recv_nbytes, g_recv_buf[g_recv_nbytes]);
00686                         g_recv_nbytes++;
00687                 }
00688                 
00689 
00690                 if (g_recv_nbytes < g_recv_size) {
00691                         command |= (1<<TWEA);
00692                 }
00693                 break;
00694 
00695         case TW_SR_GCALL_DATA_NACK:
00696         case TW_SR_DATA_NACK:    
00697                 
00698                 if (g_recv_nbytes < g_recv_size) {
00699                         g_recv_buf[g_recv_nbytes] = TWDR;
00700 
00701                         if(g_recv_byte_event)
00702                                 g_recv_byte_event(hard_status, g_recv_nbytes, g_recv_buf[g_recv_nbytes]);
00703                         g_recv_nbytes++;
00704                 }
00705                 break;
00706     
00707         case TW_SR_STOP:
00708                 
00709                 g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_RECV_EVT);
00710                 break;
00711 
00712       
00713                 
00714 
00715         case TW_ST_ARB_LOST_SLA_ACK:
00716         case TW_ST_SLA_ACK: 
00717                 
00718 
00719                 g_send_nbytes = 0;
00720                 if (! (g_status & I2C_STATUS_SLAVE_XMIT_WAIT)) {
00721                         TWDR = 0;
00722                         g_send_size=0;
00723                 }
00724                 
00725 
00726   
00727                 else {
00728                         if (g_send_size > 1) {
00729                                 command |= (1<<TWEA);
00730                         }
00731                         TWDR = g_send_buf[g_send_nbytes++];
00732                 }
00733                 g_status &= ~(I2C_STATUS_SLAVE_XMIT_WAIT);
00734                 g_status |= I2C_STATUS_SLAVE_XMIT;
00735                 break;
00736       
00737         case TW_ST_DATA_ACK:
00738                 
00739 
00740                 if (g_send_size > g_send_nbytes + 1)
00741                         command |= (1<<TWEA);
00742                 TWDR = g_send_buf[g_send_nbytes++];
00743                 break;
00744 
00745         case TW_ST_DATA_NACK:
00746                 
00747                 g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_XMIT_EVT);
00748                 break;
00749 
00750 
00751         case TW_ST_LAST_DATA:
00752                 
00753                 g_status |= (I2C_STATUS_OP_FINISHED | I2C_STATUS_NEED_XMIT_EVT);
00754                 break;
00755 
00756             
00757                 
00758 
00759         case TW_BUS_ERROR:
00760                 command |= (1<<TWSTO);
00761                 g_status |= I2C_STATUS_OP_FINISHED;
00762                 break;
00763     
00764         default :
00765                 
00766                 g_status |= I2C_STATUS_OP_FINISHED;
00767                 break;
00768 
00769         }
00770         
00771 #if I2C_DEBUG == 1
00772         g_prev_status = g_status;
00773 #endif
00774 
00775         
00776         if (g_status & I2C_STATUS_OP_FINISHED) {
00777                 
00778 
00779 #ifdef CONFIG_MODULE_I2C_MASTER
00780                 if (g_mode != I2C_MODE_MASTER) {
00781                         command |= (1<<TWEA);
00782                 }
00783                 else if ( ! (g_ctrl & I2C_CTRL_DONT_RELEASE_BUS) ) {
00784                         
00785                         command |= (1<<TWSTO);
00786                 }
00787 #else 
00788                 command |= (1<<TWEA);
00789 #endif
00790                 
00791 
00792                 if ( ! (g_ctrl & I2C_CTRL_SYNC) ) {
00793                         g_status &= ~(I2C_STATUS_MASTER_XMIT |
00794                                       I2C_STATUS_MASTER_RECV |
00795                                       I2C_STATUS_SLAVE_XMIT |
00796                                       I2C_STATUS_SLAVE_RECV |
00797                                       I2C_STATUS_OP_FINISHED);
00798                 }
00799         }
00800                 
00801         
00802         if ( ! (g_ctrl & I2C_CTRL_SYNC) ) {
00803                 if ( (g_status & I2C_STATUS_NEED_XMIT_EVT) && g_send_event) {
00804                         g_send_event(g_send_nbytes);
00805                 }
00806                 if ( (g_status & I2C_STATUS_NEED_RECV_EVT) && g_recv_event) {
00807                         g_recv_event(g_recv_buf, g_recv_nbytes);
00808                 }
00809         }
00810         else {
00811                 if ( g_status & (I2C_STATUS_MASTER_XMIT | I2C_STATUS_SLAVE_XMIT) )
00812                         g_sync_res = g_send_nbytes;
00813                 else 
00814                         g_sync_res = g_recv_nbytes;
00815         }
00816         g_status &= ~(I2C_STATUS_NEED_XMIT_EVT | I2C_STATUS_NEED_RECV_EVT);
00817         
00818 #if I2C_DEBUG == 1
00819         g_command = command;
00820 #endif
00821 
00822         
00823 
00824 
00825         if (TWCR & (1<<TWINT))
00826                 TWCR = command; 
00827 }