David Möschwitzer / SC18IS602
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SC18IS602.cpp Source File

SC18IS602.cpp

00001 #include "SC18IS602.h"
00002 #include "mbed.h"
00003 
00004 //******************************************************************************//
00005 // constructor
00006 //******************************************************************************//
00007 SC18IS602::SC18IS602(I2C *_i2c, uint8_t uiAdr)                  //
00008     :   SC18IS602_W(HARD_ADR | (uiAdr & USER_ADR_MASK) << 1),                   // Initialisation list:     const WRITE
00009         SC18IS602_R( SC18IS602_W | 0x01),                                       //                          const READ
00010         iINT(0){
00011                                                                                 //
00012     i2c = _i2c;                                                                 //
00013     bAck = NACK;                                                                //
00014     for(int i = 0; i < BUFFER_SIZE; i++)                                        // clear buffer
00015         cCmd[i] = 0;   
00016         
00017     if(getInt())  clearInt();                                                   //
00018     wait(0.01);
00019     
00020     //getInt_ptr = NULL;
00021 
00022 }
00023 
00024 
00025 
00026 //******************************************************************************//
00027 // constructor
00028 //******************************************************************************//
00029 SC18IS602::SC18IS602(I2C *_i2c, PCA9555 *_pca , uint8_t uiAdr)                  //
00030     :   SC18IS602_W(HARD_ADR | (uiAdr & USER_ADR_MASK) << 1),                   // Initialisation list:     const WRITE
00031         SC18IS602_R( SC18IS602_W | 0x01),                                       //                          const READ
00032         iINT(1){
00033                                                                                 //
00034     i2c = _i2c;                                                                 //
00035     pca = _pca;                                                                 //
00036     bAck = NACK;                                                                //
00037     for(int i = 0; i < BUFFER_SIZE; i++)                                        // clear buffer
00038         cCmd[i] = 0;   
00039     
00040     if(getInt())  clearInt();                                                   //
00041     wait(0.01);
00042 }
00043 
00044 
00045 
00046 //******************************************************************************//
00047 // constructor
00048 //******************************************************************************//
00049 SC18IS602::SC18IS602(I2C *_i2c, DigitalIn *_IntPin, uint8_t uiAdr)//
00050     :   SC18IS602_W(HARD_ADR | (uiAdr & USER_ADR_MASK) << 1),                   // Initialisation list:     const WRITE
00051         SC18IS602_R( SC18IS602_W | 0x01),                                       //                          const READ
00052         iINT(2){
00053                                                                                 //
00054     i2c = _i2c;                                                                 //
00055     IntPin = _IntPin;                                                                 //
00056     bAck = NACK;                                                                //
00057     for(int i = 0; i < BUFFER_SIZE; i++)                                        // clear buffer
00058         cCmd[i] = 0;   
00059         
00060     if(getInt())  clearInt();                                                   //
00061     wait(0.01);
00062 
00063 }
00064 
00065 
00066 //******************************************************************************//
00067 // 
00068 //******************************************************************************//
00069 bool SC18IS602::configSPI(uint8_t uiConf){                                      //
00070                                                                                 //
00071     cCmd[0] = ADR_SPI_CONF;                                                     //
00072     cCmd[1] = uiConf & 0x2F;                                                    // clear reserved bits 0b0010'1111
00073     sprintf(cDebug, "Config SPI:%*s0x%02x", 5, " ", uiConf);
00074     return sendViaI2C(cCmd, 2, cDebug);                                        //
00075 }
00076 
00077 
00078 
00079 //******************************************************************************//
00080 // 
00081 //******************************************************************************//
00082 bool SC18IS602::enableGPIO(uint8_t uiConf){                                     //
00083                                                                                 //
00084     cCmd[0] = ADR_GPIO.EN;                                                      //
00085     cCmd[1] = uiConf & 0x0F;                                                    // clear reserved bits 0b0000'1111
00086     return sendViaI2C(cCmd, 2, "Enable GPIO");                                                //
00087 }
00088 
00089 
00090 
00091 
00092 //******************************************************************************//
00093 // 
00094 //******************************************************************************//
00095 bool SC18IS602::configGPIO(uint8_t uiConf){                                     //
00096                                                                                 //
00097     cCmd[0] = ADR_GPIO.CONF;                                                    //
00098     cCmd[1] = uiConf;                                                           // clear reserved bits 0b0000'1111
00099     return sendViaI2C(cCmd, 2);                                                //
00100 }
00101 
00102 
00103 
00104 /******************************************************************************/
00105 // sends via I2C and returns ACK or NACK
00106 /******************************************************************************/
00107 bool SC18IS602::sendViaI2C(const char *cData, int iLength, string sDebug)
00108 {  
00109     bAck = not i2c->write(SC18IS602_W, cData, iLength);       
00110     //printf("%d\n", bAck);
00111     if (bAck == ACK) {
00112         return ACK;
00113         
00114     } else {
00115         if(sizeof(sDebug) != NULL)  printf("%s:%*s", sDebug.c_str(), 10, " ");
00116         printf("NACK\n");    
00117         return NACK;
00118     }
00119 }
00120 
00121 
00122 
00123 /******************************************************************************/
00124 // sends via I2C and returns ACK or NACK
00125 /******************************************************************************/
00126 bool SC18IS602::readViaI2C(char *cData, int iLength, string sDebug){  
00127 
00128     bAck = not i2c->read(SC18IS602_R, cData, iLength);       
00129     
00130     if (bAck == ACK) {
00131         return ACK;
00132         
00133     } else {
00134         if(sizeof(sDebug) != NULL)  printf("%s:%*s", sDebug.c_str(), 10, " ");
00135         printf("NACK\n"); 
00136         return NACK;
00137     }
00138 }
00139 
00140 
00141 //******************************************************************************//
00142 //  get interrupt status
00143 //******************************************************************************//
00144 bool SC18IS602::getInt(){
00145     //printf("Wait for Int...\n");  
00146     //wait(0.1);
00147     if(iINT == 0){ 
00148         return INTERRUPT;
00149     }
00150     
00151     if(iINT == 1){
00152         //printf("GPIO\n");
00153         return pca->getGPIO1_B7(true);
00154     }
00155     
00156     if(iINT == 2){
00157         //printf("PIN\n");
00158         return IntPin->read();
00159     }
00160     
00161     return not INTERRUPT;
00162 }
00163 
00164 
00165 
00166 /******************************************************************************/
00167 // clears the interrupt pin
00168 // returns 0(ACK) on success otherwise 1 (NACK)
00169 /******************************************************************************/
00170 bool SC18IS602::clearInt(){
00171     cCmd[0] = 0xF1;
00172     return sendViaI2C(cCmd, 1, "clear interrupt");
00173 }
00174 
00175 
00176 //******************************************************************************//
00177 // toggle GPIO Pins                                                             //
00178 //******************************************************************************//
00179 bool SC18IS602::gpio_toggle(uint8_t uiPort){                                    //
00180     
00181     uiPort &= 0x0F;                                                             // clear reserved bits
00182     
00183     cCmd[0] = ADR_GPIO.READ;                                                    // Read from GPIO port
00184     sendViaI2C(cCmd, 1, "Read GPIO");
00185     bAck = (bool) readViaI2C(&cCmd[1], 1);
00186         
00187     if(bAck == NACK) return bAck;                                               // if NACK, return
00188     
00189     cCmd[0] = ADR_GPIO.WRITE;
00190     cCmd[1] ^= uiPort;                                                          // toogle given pins (uiTogllePin)
00191     return sendViaI2C(cCmd, 2, "GPIO tog");
00192 
00193 }
00194 
00195 
00196 /******************************************************************************/
00197 // swith the GPIO Pin for debugging on
00198 /******************************************************************************/
00199 bool SC18IS602::gpio_pin3_off()
00200 {
00201     cCmd[0] = ADR_GPIO.WRITE;
00202     cCmd[1] = (1 << GPIO.CS3);
00203     return sendViaI2C(cCmd, 2, "GPIO off");
00204 }
00205 
00206 
00207 /******************************************************************************/
00208 // swith the GPIO Pin for debugging off
00209 /******************************************************************************/
00210 bool SC18IS602::gpio_pin3_on()
00211 {
00212     cCmd[0] = ADR_GPIO.WRITE;
00213     cCmd[1] = (0 << GPIO.CS3);
00214     return sendViaI2C(cCmd, 2, "GPIO on");
00215 }
00216 
00217 
00218 
00219 //******************************************************************************//
00220 //
00221 //******************************************************************************//
00222 bool SC18IS602::sendViaSPI(uint8_t uiCS, char cAdrByte, char *cDataBytes, uint8_t uiNum)
00223 {
00224     if((int)uiNum >= BUFFER_SIZE - 1)                                           // If number of sending Bytes greather than BUFFER_SIZE - 1 (Register-Adress-Byte)
00225         return NACK;                                                            // returns NACK (failure)
00226         
00227         
00228     if( uiCS != CMD_RW.CS0 and uiCS != CMD_RW.CS1 
00229         and uiCS != CMD_RW.CS2 and uiCS != CMD_RW.CS3){                         // If uiCS not element of CMD_RW, than return NACK (faiure)
00230             return NACK;
00231     }
00232     
00233     
00234     uiNumByte = 0;
00235     cCmd[uiNumByte] = uiCS;                                                     // send via SPI and CS0 (SS0)
00236     cCmd[++uiNumByte] = cAdrByte;
00237     for(int n = uiNum - 1 ; n >= 0; n--) {
00238         cCmd[++uiNumByte] = cDataBytes[n];
00239     }
00240     
00241     
00242     uiNumByte++;                                                                // char cCmd counts from 0, so the number is +1    
00243     bAck = sendViaI2C(cCmd, uiNumByte, "TX via SPI");                           // send via SPI      
00244     waitFor(INTERRUPT);                                                         // If there was an interrupt, wait until it is cleared   
00245     clearInt();  
00246     waitFor(not INTERRUPT);                                                      // If there was an interrupt, wait until it is cleared
00247     
00248     return bAck;
00249 }
00250 
00251 
00252 
00253 //******************************************************************************//
00254 //  returns reading data. The first byte is the status byte
00255 //******************************************************************************//
00256 bool SC18IS602::readViaSPI(uint8_t uiCS, char cAdrByte, char *cDataBytes, uint8_t uiNum)
00257 {   
00258     if((int)uiNum >= BUFFER_SIZE - 1)                                           // If number of sending Bytes greather than BUFFER_SIZE - 1 (Register-Adress-Byte)
00259         return NACK;                                                            // returns NACK (failure)    
00260     
00261     
00262     if( uiCS != CMD_RW.CS0 and uiCS != CMD_RW.CS1 
00263         and uiCS != CMD_RW.CS2 and uiCS != CMD_RW.CS3){                         // If uiCS not element of CMD_RW, than return NACK (faiure)
00264             return NACK;
00265     }
00266 
00267     
00268     // send first time Read comand
00269     uiNumByte = 0;
00270     cCmd[uiNumByte++] = uiCS;                                                   // send via SPI and CS0 (SS0)
00271     cCmd[uiNumByte++] = cAdrByte;
00272     
00273     for(int n = uiNum - 1 ; n >= 0; n--) {
00274         cCmd[uiNumByte++] = 0x00;
00275     }
00276 
00277     
00278     if(getInt() == INTERRUPT){                                                  // If interrupt isn't cleard, then 
00279         //printf("Interrupt...");
00280         clearInt();                                                             // clear interrupt
00281         waitFor(not INTERRUPT);                                                 // wait until interrupt is cleard
00282     }
00283     
00284     
00285 
00286     bAck = sendViaI2C(cCmd, uiNumByte, "Send Rx Cmd via SPI");
00287     waitFor(INTERRUPT);
00288     clearInt();
00289     
00290  
00291     // send secound time read comand (dummy) to receive data from first read command   
00292     cCmd[0] = CMD_RW.CS0;                                               // send via SPI and CS0 (SS0)
00293     //cCmd[++uiNumByte] = cAdrByte;
00294     
00295     //for(int n = uiNum - 1 ; n >= 0; n--) {
00296     //    cCmd[++uiNumByte] = 0x00;
00297     //}
00298     //uiNumByte++; 
00299         
00300     
00301     waitFor(not INTERRUPT);                                                      // If there was an interrupt, wait until it is cleared                
00302     bAck =  sendViaI2C(cCmd, uiNumByte, "Send dummy data via SPI");
00303     waitFor(INTERRUPT);                                                      // wait until sending is finished and an interrupt occurs
00304     clearInt();
00305     uiNumByte--; 
00306     
00307     bAck = (bool) readViaI2C(cDataBytes, uiNumByte, "RX via SPI");
00308     
00309     /*printf("Rx: ");
00310     for(int i = 0; i < uiNumByte; i++){
00311         printf("0x%02x  ", cDataBytes[i]);
00312     }
00313     printf("\n");*/
00314    
00315     
00316     int n = 0;
00317     for(int i = 0;  i < int(uiNumByte/2); i++){
00318         n = uiNumByte - 1 - i;
00319         //printf("%d <-> %d\n", i, n);
00320         cDataBytes[i] = cDataBytes[i] ^ cDataBytes[n];
00321         cDataBytes[n] = cDataBytes[i] ^ cDataBytes[n];
00322         cDataBytes[i] = cDataBytes[i] ^ cDataBytes[n];
00323     }
00324     
00325     return bAck;
00326 }
00327 
00328 
00329 
00330 //******************************************************************************//
00331 //
00332 //******************************************************************************//
00333 void SC18IS602::waitFor(bool bInt){
00334     iTimeOut = 1000;
00335     
00336     while((getInt() !=  bInt) and iTimeOut > 0) {
00337         iTimeOut--;
00338         wait(1e-3);
00339     }
00340     
00341     if(iTimeOut == 0) printf("TimeOut: Interrupt\n");        
00342 }
00343 
00344 
00345 //******************************************************************************//
00346 // musst modified
00347 //******************************************************************************//
00348 /*void SC18IS602::setIntFuncPtr( bool (*Int_ptr)(void)){
00349     getInt_ptr = Int_ptr;
00350     
00351 }*/