SPI-Brigde (capseld), for polling interrupt, it is neccessary to adapt the constructor and the function getInt()

SC18IS602.cpp

Committer:
x1dmoesc
Date:
2019-02-01
Revision:
0:833cb2c6da5d
Child:
1:2a7edc2be6df

File content as of revision 0:833cb2c6da5d:

#include "SC18IS602.h"
#include "mbed.h"

//******************************************************************************//
// constructor
//******************************************************************************//
SC18IS602::SC18IS602(I2C *_i2c, uint8_t uiAdr)                  //
    :   SC18IS602_W(HARD_ADR | (uiAdr & USER_ADR_MASK) << 1),                   // Initialisation list:     const WRITE
        SC18IS602_R( SC18IS602_W | 0x01),                                       //                          const READ
        iINT(0){
                                                                                //
    i2c = _i2c;                                                                 //
    bAck = NACK;                                                                //
    for(int i = 0; i < BUFFER_SIZE; i++)                                        // clear buffer
        cCmd[i] = 0;   
        
    if(getInt())  clearInt();                                                   //

}



//******************************************************************************//
// constructor
//******************************************************************************//
SC18IS602::SC18IS602(I2C *_i2c, PCA9555 *_pca , uint8_t uiAdr)                  //
    :   SC18IS602_W(HARD_ADR | (uiAdr & USER_ADR_MASK) << 1),                   // Initialisation list:     const WRITE
        SC18IS602_R( SC18IS602_W | 0x01),                                       //                          const READ
        iINT(1){
                                                                                //
    i2c = _i2c;                                                                 //
    pca = _pca;                                                                 //
    bAck = NACK;                                                                //
    for(int i = 0; i < BUFFER_SIZE; i++)                                        // clear buffer
        cCmd[i] = 0;   
        
    if(getInt())  clearInt();                                                   //

}



//******************************************************************************//
// constructor
//******************************************************************************//
SC18IS602::SC18IS602(I2C *_i2c, DigitalIn *_IntPin, uint8_t uiAdr)//
    :   SC18IS602_W(HARD_ADR | (uiAdr & USER_ADR_MASK) << 1),                   // Initialisation list:     const WRITE
        SC18IS602_R( SC18IS602_W | 0x01),                                       //                          const READ
        iINT(2){
                                                                                //
    i2c = _i2c;                                                                 //
    IntPin = _IntPin;                                                                 //
    bAck = NACK;                                                                //
    for(int i = 0; i < BUFFER_SIZE; i++)                                        // clear buffer
        cCmd[i] = 0;   
        
    if(getInt())  clearInt();                                                   //

}


//******************************************************************************//
// 
//******************************************************************************//
bool SC18IS602::configSPI(uint8_t uiConf){                                      //
                                                                                //
    cCmd[0] = ADR_SPI_CONF;                                                     //
    cCmd[1] = uiConf & 0x2F;                                                    // clear reserved bits 0b0010'1111
    sprintf(cDebug, "Config SPI:%*s0x%02x", 5, " ", uiConf);
    return sendViaI2C(cCmd, 2, cDebug);                                        //
}



//******************************************************************************//
// 
//******************************************************************************//
bool SC18IS602::enableGPIO(uint8_t uiConf){                                     //
                                                                                //
    cCmd[0] = ADR_GPIO_EN;                                                      //
    cCmd[1] = uiConf & 0x0F;                                                    // clear reserved bits 0b0000'1111
    return sendViaI2C(cCmd, 2, "Enable GPIO");                                                //
}




//******************************************************************************//
// 
//******************************************************************************//
bool SC18IS602::configGPIO(uint8_t uiConf){                                     //
                                                                                //
    cCmd[0] = ADR_GPIO_CONF;                                                    //
    cCmd[1] = uiConf;                                                           // clear reserved bits 0b0000'1111
    return sendViaI2C(cCmd, 2);                                                //
}



/******************************************************************************/
// sends via I2C and returns ACK or NACK
/******************************************************************************/
bool SC18IS602::sendViaI2C(const char *cData, int iLength, string sDebug)
{  
    bAck = (bool) i2c->write(SC18IS602_W, cData, iLength);       
    
    if (bAck == ACK) {
        return ACK;
        
    } else {
        if(sizeof(sDebug) != NULL)  printf("%s:%*s", sDebug.c_str(), 10, " ");
        printf("NACK\n");    
        return NACK;
    }
}



/******************************************************************************/
// sends via I2C and returns ACK or NACK
/******************************************************************************/
bool SC18IS602::readViaI2C(char *cData, int iLength, string sDebug){  

    bAck = (bool) i2c->read(SC18IS602_R, cData, iLength);       
    
    if (bAck == ACK) {
        return ACK;
        
    } else {
        if(sizeof(sDebug) != NULL)  printf("%s:%*s", sDebug.c_str(), 10, " ");
        printf("NACK\n"); 
        return NACK;
    }
}


//******************************************************************************//
//  get interrupt status
//******************************************************************************//
bool SC18IS602::getInt(){
    //printf("Wait for Int...\n");  
    //wait(0.1);
    if(iINT == 0) return INTERRUPT;
    if(iINT == 1) return pca->getGPIO1_B7(true);
    if(iINT == 2) return IntPin->read();
    
    return not INTERRUPT;
}



/******************************************************************************/
// clears the interrupt pin
// returns 0(ACK) on success otherwise 1 (NACK)
/******************************************************************************/
bool SC18IS602::clearInt(){
    cCmd[0] = 0xF1;
    return sendViaI2C(cCmd, 1, "clear interrupt");
}


//******************************************************************************//
// toggle GPIO Pins                                                             //
//******************************************************************************//
bool SC18IS602::gpio_toggle(uint8_t uiPort){                                    //
    
    uiPort &= 0x0F;                                                             // clear reserved bits
    
    cCmd[0] = ADR_GPIO_READ;                                                    // Read from GPIO port
    sendViaI2C(cCmd, 1, "Read GPIO");
    bAck = (bool) readViaI2C(&cCmd[1], 1);
        
    if(bAck == NACK) return bAck;                                               // if NACK, return
    
    cCmd[0] = ADR_GPIO_WRITE;
    cCmd[1] ^= uiPort;                                                          // toogle given pins (uiTogllePin)
    return sendViaI2C(cCmd, 2, "GPIO tog");

}


/******************************************************************************/
// swith the GPIO Pin for debugging on
/******************************************************************************/
bool SC18IS602::GPIO_pin3_off()
{
    cCmd[0] = ADR_GPIO_WRITE;
    cCmd[1] = (1 << GPIO_CS3);
    return sendViaI2C(cCmd, 2, "GPIO off");
}


/******************************************************************************/
// swith the GPIO Pin for debugging off
/******************************************************************************/
bool SC18IS602::GPIO_pin3_on()
{
    cCmd[0] = ADR_GPIO_WRITE;
    cCmd[1] = (0 << GPIO_CS3);
    return sendViaI2C(cCmd, 2, "GPIO on");
}



//******************************************************************************//
//
//******************************************************************************//
bool SC18IS602::sendViaSPI(char cAdrByte, char *cDataBytes, uint8_t uiNum)
{
    if((int)uiNum >= BUFFER_SIZE - 1)                                           // If number of sending Bytes greather than BUFFER_SIZE - 1 (Register-Adress-Byte)
        return NACK;                                                            // returns NACK (failure)
    
    
    uiNumByte = 0;
    cCmd[uiNumByte] = CMD_RW_CS0;                                               // send via SPI and CS0 (SS0)
    cCmd[++uiNumByte] = cAdrByte;
    for(int n = uiNum - 1 ; n >= 0; n--) {
        cCmd[++uiNumByte] = cDataBytes[n];
    }
    
    
    uiNumByte++;                                                                // char cCmd counts from 0, so the number is +1    
    bAck = sendViaI2C(cCmd, uiNumByte, "TX via SPI");                          // send via SPI  

    
    while(getInt() == not INTERRUPT);                                           // wait until sending is finished and an interrupt occurs
    clearInt();  
    while(getInt() == INTERRUPT);                                               // If there was an interrupt, wait until it is cleared
    
    return bAck;
}



//******************************************************************************//
//  returns reading data. The first byte is the status byte
//******************************************************************************//
bool SC18IS602::readViaSPI(char cAdrByte, char *cDataBytes, uint8_t uiNum)
{
    if((int)uiNum >= BUFFER_SIZE - 1)                                           // If number of sending Bytes greather than BUFFER_SIZE - 1 (Register-Adress-Byte)
        return NACK;                                                            // returns NACK (failure)    
    
    
    // send first time Read comand
    uiNumByte = 0;
    cCmd[uiNumByte] = CMD_RW_CS0;                                               // send via SPI and CS0 (SS0)
    cCmd[++uiNumByte] = cAdrByte;

     for(int n = uiNum - 1 ; n >= 0; n--) {
        cCmd[++uiNumByte] = 0x00;
    }
    uiNumByte++;                                                                // char cCmd counts from 0, so the number is +1
                                                                      
    while(getInt() == INTERRUPT);                                               // If there was an interrupt, wait until it is cleared
    bAck = sendViaI2C(cCmd, uiNumByte, "RX via SPI");
    while(getInt() == not INTERRUPT);
    clearInt();


    // send secound time read comand (dummy) to receive data from first read command
    uiNumByte = 0;
    cCmd[uiNumByte++] = CMD_RW_CS0;
     for(int n = uiNum - 1 ; n >= 0; n--) {
        cCmd[uiNumByte++] = 0x00;
    }
    
    while(getInt() == INTERRUPT);                                               // If there was an interrupt, wait until it is cleared
    bAck =  sendViaI2C(cCmd, uiNumByte, "RX via SPI");
    while(getInt() == not INTERRUPT);                                           // wait until sending is finished and an interrupt occurs
    clearInt();
       
    
    bAck = (bool) readViaI2C(cDataBytes, uiNumByte);
    
    int n = 0;
    for(int i = 0;  i < int(uiNumByte/2); i++){
        n = uiNumByte - 1 - i;
        //printf("%d <-> %d\n", i, n);
        cDataBytes[i] = cDataBytes[i] ^ cDataBytes[n];
        cDataBytes[n] = cDataBytes[i] ^ cDataBytes[n];
        cDataBytes[i] = cDataBytes[i] ^ cDataBytes[n];
    }
    
    return bAck;
}