AnsweredAssumed Answered

i2c_cpal_driver V2 scl hold low by slave

Question asked by hohenberg.jost on Dec 16, 2015
Hi,
e have an application that uses the i2c cpal driver V2
as included in STM32F30x_DSP_StdPeriph_Lib_V1.2.3 (UM1566)
i took the code from the example I2C_TwoBoards
and configured one board as master, a second as slave.
Both boards use an stm32f334c8T6.
I use CPAL_I2C_IT_PROGMODEL and USE_I2C1.

On the Logic Analyzer one can see that the master sends the address, the slaves hardware acknowledges it
and then holding down the scl line permanently.
It seems it never gets to an interrupt.
Any idea whatcould be  wrong?

Here are the i2c  functions:

void cpal_i2c_master_init(void)
{     
            // Deinitialize I2Cx Device

                I2C1_SMBAGPIOInit();
                CPAL_I2C_DeInit(&MASTERSTRUCTURE);
         
                 /* Set HSI as I2C clock source */
                RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
 
            /* Configure the device structure */
                CPAL_I2C_StructInit(&MASTERSTRUCTURE);      // Set all fields to default
                //Initialize CPAL I2C structure parameters values
                CPAL_I2C_StructInit(&MASTERSTRUCTURE);
                MASTERSTRUCTURE.wCPAL_Options =  CPAL_OPT_NO_MEM_ADDR | CPAL_OPT_I2C_AUTOMATIC_END; //CPAL_OPT_I2C_NACK_ADD ; //CPAL_OPT_NO_MEM_ADDR|

                #ifdef CPAL_I2C_DMA_PROGMODEL
                    MASTERSTRUCTURE.CPAL_ProgModel = CPAL_PROGMODEL_DMA;
                #elif defined (CPAL_I2C_IT_PROGMODEL)  // defined in stm32f30x_i2c_cpal.conf.h
                    MASTERSTRUCTURE.CPAL_ProgModel = CPAL_PROGMODEL_INTERRUPT;
                #else
                 #error "Please select one of the programming model (in main.h)"
                #endif

                // Set I2C Speed
                MASTERSTRUCTURE.pCPAL_I2C_Struct->I2C_Timing = MASTER_I2C_TIMING;

                // Select Master Mode
                MASTERSTRUCTURE.CPAL_Mode = CPAL_MODE_MASTER;

                //Initialize I2Cx Device
            //    CPAL_I2C_Init(&MASTERSTRUCTURE);
        /* Initialize Transfer parameters */
                MASTERSTRUCTURE.pCPAL_TransferTx = &sTxStructure;
                MASTERSTRUCTURE.pCPAL_TransferRx = &sRxStructure;


                sTxStructure.wNumData = BufferSize;
                sTxStructure.pbBuffer = (uint8_t*)BufferTX;
                sTxStructure.wAddr1 = STM32_DISPLAY_SLAVE_READ_ADDR;
                
                sRxStructure.pbBuffer = (uint8_t*)BufferRX;
                sRxStructure.wNumData = BufferSize;
                sRxStructure.wAddr1 = OWNADDRESS;
                MASTERSTRUCTURE.CPAL_State = CPAL_STATE_READY;
                CPAL_I2C_Init(&MASTERSTRUCTURE);  
    
}

////////////////////////i2c slave init////////////////////////////////////
void I2C_SlaveReset(void)
{
        SLAVESTRUCTURE.CPAL_State = CPAL_STATE_READY;
        SLAVESTRUCTURE.wCPAL_DevError = CPAL_I2C_ERR_NONE ;
        SLAVESTRUCTURE.wCPAL_Timeout  = CPAL_I2C_TIMEOUT_DEFAULT;
 
        /* DeInitialize CPAL device */
        CPAL_I2C_DeInit(&SLAVESTRUCTURE);  
 
        /* Initialize CPAL device with the selected parameters */
        CPAL_I2C_Init(&SLAVESTRUCTURE);
}
void cpal_i2c_slave_init(void)
{

 
 
  // CPAL_InitTypeDef (I2C1_DevStructure);
  /* Deinitialize I2Cx Device */
  CPAL_I2C_DeInit(&SLAVESTRUCTURE);
   /* Set HSI as I2C clock source */
                RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
 
  /* Initialize CPAL I2C structure parameters values */
  CPAL_I2C_StructInit(&SLAVESTRUCTURE);
  SLAVESTRUCTURE.wCPAL_Options = CPAL_OPT_NO_MEM_ADDR | CPAL_OPT_I2C_WAKEUP_STOP;
#ifdef CPAL_I2C_DMA_PROGMODEL
  SLAVESTRUCTURE.CPAL_ProgModel = CPAL_PROGMODEL_DMA;
#elif defined (CPAL_I2C_IT_PROGMODEL)
  SLAVESTRUCTURE.CPAL_ProgModel = CPAL_PROGMODEL_INTERRUPT;
#else
 #error "Please select one of the programming model (in main.h)"
#endif

  /* Configure Own address 1 */
  SLAVESTRUCTURE.pCPAL_I2C_Struct->I2C_OwnAddress1 = OWNADDRESS;

  /* Set I2C Speed */
  SLAVESTRUCTURE.pCPAL_I2C_Struct->I2C_Timing = SLAVE_I2C_TIMING;

  /* Select Slave Mode */
  SLAVESTRUCTURE.CPAL_Mode = CPAL_MODE_SLAVE;

  /* Initialize I2Cx Device*/
  CPAL_I2C_Init(&SLAVESTRUCTURE);

 
    /* Reset BufferRX value */
    Reset_bBuffer(BufferRX, BufferSize);

    /* Initialize Transfer parameters */
    SLAVESTRUCTURE.pCPAL_TransferRx = &sRxStructure;
        SLAVESTRUCTURE.pCPAL_TransferTx = &sTxStructure;
    sRxStructure.wNumData = BufferSize;
    sRxStructure.pbBuffer = (uint8_t*)BufferRX;
        sTxStructure.wNumData = BufferSize;
    sTxStructure.pbBuffer = (uint8_t*)BufferTX;
    
}


//////////////////the master transmit//////////////////
int I2C_MASTER_write(uint8_t addr,uint8_t sense_cmd , uint8_t *data, uint8_t data_len)
{
        
      if((MASTERSTRUCTURE.CPAL_State != CPAL_STATE_READY)&& \
        (MASTERSTRUCTURE.CPAL_State != CPAL_STATE_BUSY_RX) &&\
          (MASTERSTRUCTURE.CPAL_State != CPAL_STATE_DISABLED))return ERR_TYPE_BUSY;
        
        
        sTxStructure.wAddr1 = addr;
        BufferTX[0] = SET_COMMAND;
        BufferTX[1] = sense_cmd;
        BufferTX[2]=3+data_Len; // num of bytes to send
        for( i=0 ; i < data_len; i++)
        {
                BufferTX[i + 3]= *data;
        }
        
        sTxStructure.wNumData = data_len + 3;
        
        MASTERSTRUCTURE.CPAL_Mode = CPAL_MODE_MASTER;
        /* Force the CPAL state to ready (in case a read operation has been initiated) */
        MASTERSTRUCTURE.CPAL_State = CPAL_STATE_READY;
        /* Write operation */

        if(CPAL_I2C_Write(&MASTERSTRUCTURE)==CPAL_PASS)
        {
                return ERR_TYPE_TX_DATA_SUCCESS;
        }
        else return ERR_TYPE_TX;
            
}

Outcomes