SPI-Brigde (capseld), for polling interrupt, it is neccessary to adapt the constructor and the function getInt()
SC18IS602.cpp
- Committer:
- x1dmoesc
- Date:
- 2020-04-23
- Revision:
- 3:9cf83f16c17d
- Parent:
- 2:cb90c271c412
File content as of revision 3:9cf83f16c17d:
#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(); //
wait(0.01);
//getInt_ptr = NULL;
}
//******************************************************************************//
// 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(); //
wait(0.01);
}
//******************************************************************************//
// 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(); //
wait(0.01);
}
//******************************************************************************//
//
//******************************************************************************//
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 = not i2c->write(SC18IS602_W, cData, iLength);
//printf("%d\n", bAck);
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 = not 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){
//printf("GPIO\n");
return pca->getGPIO1_B7(true);
}
if(iINT == 2){
//printf("PIN\n");
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(uint8_t uiCS, 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)
if( uiCS != CMD_RW.CS0 and uiCS != CMD_RW.CS1
and uiCS != CMD_RW.CS2 and uiCS != CMD_RW.CS3){ // If uiCS not element of CMD_RW, than return NACK (faiure)
return NACK;
}
uiNumByte = 0;
cCmd[uiNumByte] = uiCS; // 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
waitFor(INTERRUPT); // If there was an interrupt, wait until it is cleared
clearInt();
waitFor(not 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(uint8_t uiCS, 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)
if( uiCS != CMD_RW.CS0 and uiCS != CMD_RW.CS1
and uiCS != CMD_RW.CS2 and uiCS != CMD_RW.CS3){ // If uiCS not element of CMD_RW, than return NACK (faiure)
return NACK;
}
// send first time Read comand
uiNumByte = 0;
cCmd[uiNumByte++] = uiCS; // send via SPI and CS0 (SS0)
cCmd[uiNumByte++] = cAdrByte;
for(int n = uiNum - 1 ; n >= 0; n--) {
cCmd[uiNumByte++] = 0x00;
}
if(getInt() == INTERRUPT){ // If interrupt isn't cleard, then
//printf("Interrupt...");
clearInt(); // clear interrupt
waitFor(not INTERRUPT); // wait until interrupt is cleard
}
bAck = sendViaI2C(cCmd, uiNumByte, "Send Rx Cmd via SPI");
waitFor(INTERRUPT);
clearInt();
// send secound time read comand (dummy) to receive data from first read command
cCmd[0] = CMD_RW.CS0; // send via SPI and CS0 (SS0)
//cCmd[++uiNumByte] = cAdrByte;
//for(int n = uiNum - 1 ; n >= 0; n--) {
// cCmd[++uiNumByte] = 0x00;
//}
//uiNumByte++;
waitFor(not INTERRUPT); // If there was an interrupt, wait until it is cleared
bAck = sendViaI2C(cCmd, uiNumByte, "Send dummy data via SPI");
waitFor(INTERRUPT); // wait until sending is finished and an interrupt occurs
clearInt();
uiNumByte--;
bAck = (bool) readViaI2C(cDataBytes, uiNumByte, "RX via SPI");
/*printf("Rx: ");
for(int i = 0; i < uiNumByte; i++){
printf("0x%02x ", cDataBytes[i]);
}
printf("\n");*/
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;
}
//******************************************************************************//
//
//******************************************************************************//
void SC18IS602::waitFor(bool bInt){
iTimeOut = 1000;
while((getInt() != bInt) and iTimeOut > 0) {
iTimeOut--;
wait(1e-3);
}
if(iTimeOut == 0) printf("TimeOut: Interrupt\n");
}
//******************************************************************************//
// musst modified
//******************************************************************************//
/*void SC18IS602::setIntFuncPtr( bool (*Int_ptr)(void)){
getInt_ptr = Int_ptr;
}*/