embedded/projects/osp-steval-mki109v2/sources/app/i2c_slavecomm_t.c
void I2C_Slave_Handler(I2C_TypeDef *pI2C, uint8_t irqCh)
{
    uint32_t i2cslvstate = I2C_GetLastEvent(pI2C);
    uint8_t slvRxData;

    /* If error event - clear it */
    if ((irqCh == I2C_SLAVE_BUS_ERROR_IRQ_CH) && ((i2cslvstate & 0xFF00) != 0))
    {
        pI2C->SR1 &= 0x00FF;

        if ((i2cslvstate & 0xFF00) == I2C_EVENT_SLAVE_ACK_FAILURE)
        {
            /* Master NAKed - this was end of transaction when slave is transmitting */
            isr_evt_set(I2C_SLAVE_XFER_DONE, asfTaskHandleTable[I2CSLAVE_COMM_TASK_ID].handle );
            slave_xfer.rxCnt = 0;
            return;
        }
    }

    /* Below three states are for Slave mode: Address Received, TX, and RX. */
    switch ( i2cslvstate )
    {
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:  /* 00020040 */
    case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF):
        SensorHubIntLow(); //Deassert Interrupt
        slvRxData = (uint8_t)I2C_ReceiveData(pI2C);
        slave_xfer.rxCnt++;
        if (slave_xfer.rxCnt == 1) //First byte received must be the register address
        {
            switch (slvRxData)
            {
            case SH_REG_IRQ_CAUSE:
                slave_xfer.txBuff = &SlaveRegMap.irq_cause;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_RD_LEN:
                slave_xfer.txBuff = &SlaveRegMap.read_len;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_ACK:
                //TODO -- Need to define state machine logic that would handle ACK
                break;

            case SH_REG_REQUEST:
                //TODO
                break;

            case SH_REG_WHO_AM_I:
                slave_xfer.txBuff = &SlaveRegMap.whoami;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_VERSION0:
                slave_xfer.txBuff = &SlaveRegMap.version0;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_VERSION1:
                slave_xfer.txBuff = &SlaveRegMap.version1;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_RD_MEM:
                slave_xfer.txBuff = &SlaveRegMap.rd_mem[0];
                slave_xfer.txSz = SlaveRegMap.read_len;
                slave_xfer.txCnt = 0;
                break;

            case SH_REG_WR_MEM:
            default:
                //Not supported at this time so just NACK it for now
                I2C_AcknowledgeConfig(pI2C, DISABLE);
                break;

            case 0xEE: //Ack write
                //Ack is ignored for now
                break;
            }
        }
        else
        {
            //TODO Implement host command functions
        }
        break;

    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:  /* 00060082 */
        slave_xfer.rxCnt = 0; /* I2C Read Mode - no more receive */
        /* Fall thru */
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: /* 00060080 */
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
    case 0x00060004: //Sometimes we get this event and the driver is stuck in ISR!
        /* In transmit we will do not want to send data beyond the register set */
        if (&slave_xfer.txBuff[slave_xfer.txCnt] < &SlaveRegMap.endMarker)
        {
            I2C_SendData(pI2C, slave_xfer.txBuff[slave_xfer.txCnt++]);
        }
        else
        {
            I2C_SendData(pI2C, I2C_OVERREACH_VAL); //This value signifies read beyond allowed range
        }
        break;

    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: /* 00020002 */
        /* Nothing to do except continue */
        break;

    case I2C_EVENT_SLAVE_STOP_DETECTED: /* This is end of transaction when slave is receiving */
        /* if (STOPF==1) Read SR1;Write CR1 */
        I2C_GetFlagStatus(pI2C, I2C_FLAG_STOPF);
        I2C_Cmd(pI2C, ENABLE);
        isr_evt_set(I2C_SLAVE_XFER_DONE, asfTaskHandleTable[I2CSLAVE_COMM_TASK_ID].handle );
        slave_xfer.rxCnt = 0;
        /* Re-enable ACK (in case it was disabled) */
        I2C_AcknowledgeConfig(pI2C, ENABLE);
        break;

    default:
        break;
    }
}
/****************************************************************************************************
 * @fn      I2C_Slave_Handler
 *          Handles the I2C Slave communication events
 *
 ***************************************************************************************************/
@fn      I2C_Slave_Handler
Handles the I2C Slave communication events
@fn I2C_Slave_Handler Handles the I2C Slave communication events
void I2C_Slave_Handler(I2C_TypeDef *pI2C, uint8_t irqCh)
{
    uint32_t i2cslvstate = I2C_GetLastEvent(pI2C);
    uint8_t slvRxData;
    if ((irqCh == I2C_SLAVE_BUS_ERROR_IRQ_CH) && ((i2cslvstate & 0xFF00) != 0))
    {
        pI2C->SR1 &= 0x00FF;
        if ((i2cslvstate & 0xFF00) == I2C_EVENT_SLAVE_ACK_FAILURE)
        {
            isr_evt_set(I2C_SLAVE_XFER_DONE, asfTaskHandleTable[I2CSLAVE_COMM_TASK_ID].handle );
            slave_xfer.rxCnt = 0;
            return;
        }
    }
    switch ( i2cslvstate )
    {
    case I2C_EVENT_SLAVE_BYTE_RECEIVED:  
    case (I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF):
        SensorHubIntLow(); 
        slvRxData = (uint8_t)I2C_ReceiveData(pI2C);
        slave_xfer.rxCnt++;
        if (slave_xfer.rxCnt == 1) 
        {
            switch (slvRxData)
            {
            case SH_REG_IRQ_CAUSE:
                slave_xfer.txBuff = &SlaveRegMap.irq_cause;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;
            case SH_REG_RD_LEN:
                slave_xfer.txBuff = &SlaveRegMap.read_len;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;
            case SH_REG_ACK:
                break;
            case SH_REG_REQUEST:
                break;
            case SH_REG_WHO_AM_I:
                slave_xfer.txBuff = &SlaveRegMap.whoami;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;
            case SH_REG_VERSION0:
                slave_xfer.txBuff = &SlaveRegMap.version0;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;
            case SH_REG_VERSION1:
                slave_xfer.txBuff = &SlaveRegMap.version1;
                slave_xfer.txSz = TX_LENGTH;
                slave_xfer.txCnt = 0;
                break;
            case SH_REG_RD_MEM:
                slave_xfer.txBuff = &SlaveRegMap.rd_mem[0];
                slave_xfer.txSz = SlaveRegMap.read_len;
                slave_xfer.txCnt = 0;
                break;
            case SH_REG_WR_MEM:
            default:
                I2C_AcknowledgeConfig(pI2C, DISABLE);
                break;
            case 0xEE: 
                break;
            }
        }
        else
        {
             Implement host command functions
        }
        break;
    case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:  
        slave_xfer.rxCnt = 0; 
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTING: 
    case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
    case 0x00060004: 
        if (&slave_xfer.txBuff[slave_xfer.txCnt] < &SlaveRegMap.endMarker)
        {
            I2C_SendData(pI2C, slave_xfer.txBuff[slave_xfer.txCnt++]);
        }
        else
        {
            I2C_SendData(pI2C, I2C_OVERREACH_VAL); 
        }
        break;
    case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED: 
        break;
    case I2C_EVENT_SLAVE_STOP_DETECTED: 
        I2C_GetFlagStatus(pI2C, I2C_FLAG_STOPF);
        I2C_Cmd(pI2C, ENABLE);
        isr_evt_set(I2C_SLAVE_XFER_DONE, asfTaskHandleTable[I2CSLAVE_COMM_TASK_ID].handle );
        slave_xfer.rxCnt = 0;
        I2C_AcknowledgeConfig(pI2C, ENABLE);
        break;
    default:
        break;
    }
}
void I2C_Slave_Handler ( I2C_TypeDef * pI2C , uint8_t irqCh ) { uint32_t i2cslvstate = I2C_GetLastEvent ( pI2C ) ; uint8_t slvRxData ; if ( ( irqCh == I2C_SLAVE_BUS_ERROR_IRQ_CH ) && ( ( i2cslvstate & 0xFF00 ) != 0 ) ) { pI2C -> SR1 &= 0x00FF ; if ( ( i2cslvstate & 0xFF00 ) == I2C_EVENT_SLAVE_ACK_FAILURE ) { isr_evt_set ( I2C_SLAVE_XFER_DONE , asfTaskHandleTable [ I2CSLAVE_COMM_TASK_ID ] . handle ) ; slave_xfer . rxCnt = 0 ; return ; } } switch ( i2cslvstate ) { case I2C_EVENT_SLAVE_BYTE_RECEIVED : case ( I2C_EVENT_SLAVE_BYTE_RECEIVED | I2C_SR1_BTF ) : SensorHubIntLow ( ) ; slvRxData = ( uint8_t ) I2C_ReceiveData ( pI2C ) ; slave_xfer . rxCnt ++ ; if ( slave_xfer . rxCnt == 1 ) { switch ( slvRxData ) { case SH_REG_IRQ_CAUSE : slave_xfer . txBuff = & SlaveRegMap . irq_cause ; slave_xfer . txSz = TX_LENGTH ; slave_xfer . txCnt = 0 ; break ; case SH_REG_RD_LEN : slave_xfer . txBuff = & SlaveRegMap . read_len ; slave_xfer . txSz = TX_LENGTH ; slave_xfer . txCnt = 0 ; break ; case SH_REG_ACK : break ; case SH_REG_REQUEST : break ; case SH_REG_WHO_AM_I : slave_xfer . txBuff = & SlaveRegMap . whoami ; slave_xfer . txSz = TX_LENGTH ; slave_xfer . txCnt = 0 ; break ; case SH_REG_VERSION0 : slave_xfer . txBuff = & SlaveRegMap . version0 ; slave_xfer . txSz = TX_LENGTH ; slave_xfer . txCnt = 0 ; break ; case SH_REG_VERSION1 : slave_xfer . txBuff = & SlaveRegMap . version1 ; slave_xfer . txSz = TX_LENGTH ; slave_xfer . txCnt = 0 ; break ; case SH_REG_RD_MEM : slave_xfer . txBuff = & SlaveRegMap . rd_mem [ 0 ] ; slave_xfer . txSz = SlaveRegMap . read_len ; slave_xfer . txCnt = 0 ; break ; case SH_REG_WR_MEM : default : I2C_AcknowledgeConfig ( pI2C , DISABLE ) ; break ; case 0xEE : break ; } } else { } break ; case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED : slave_xfer . rxCnt = 0 ; case I2C_EVENT_SLAVE_BYTE_TRANSMITTING : case I2C_EVENT_SLAVE_BYTE_TRANSMITTED : case 0x00060004 : if ( & slave_xfer . txBuff [ slave_xfer . txCnt ] < & SlaveRegMap . endMarker ) { I2C_SendData ( pI2C , slave_xfer . txBuff [ slave_xfer . txCnt ++ ] ) ; } else { I2C_SendData ( pI2C , I2C_OVERREACH_VAL ) ; } break ; case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED : break ; case I2C_EVENT_SLAVE_STOP_DETECTED : I2C_GetFlagStatus ( pI2C , I2C_FLAG_STOPF ) ; I2C_Cmd ( pI2C , ENABLE ) ; isr_evt_set ( I2C_SLAVE_XFER_DONE , asfTaskHandleTable [ I2CSLAVE_COMM_TASK_ID ] . handle ) ; slave_xfer . rxCnt = 0 ; I2C_AcknowledgeConfig ( pI2C , ENABLE ) ; break ; default : break ; } }
@fn      I2C_Slave_Handler
          Handles the I2C Slave communication events
@fn I2C_Slave_Handler Handles the I2C Slave communication events
/* If error event - clear it */ /* Master NAKed - this was end of transaction when slave is transmitting */ /* Below three states are for Slave mode: Address Received, TX, and RX. */ /* 00020040 */ //Deassert Interrupt //First byte received must be the register address //TODO -- Need to define state machine logic that would handle ACK //TODO //Not supported at this time so just NACK it for now //Ack write //Ack is ignored for now //TODO Implement host command functions /* 00060082 */ /* I2C Read Mode - no more receive */ /* Fall thru */ /* 00060080 */ //Sometimes we get this event and the driver is stuck in ISR! /* In transmit we will do not want to send data beyond the register set */ //This value signifies read beyond allowed range /* 00020002 */ /* Nothing to do except continue */ /* This is end of transaction when slave is receiving */ /* if (STOPF==1) Read SR1;Write CR1 */ /* Re-enable ACK (in case it was disabled) */