This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to get command/data on I2C Slave, which has been send from I2C master.

Hi All,

I am trying to implement I2C Slave functionality on NRF52832, So NRF52832 will act as a I2C slave. 

So i found there is an example TWIS Slave and TWI Master Mode Drivers Example (https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v12.2.0%2Ftwi_master_with_twis_slave_example.html). 

This is geed example to start. 

But i have a doubt, i am not sure how to receive data/command from I2C master and I2C slave device should respond against that data.  

in the example there is twis_event_handler() callback function which handles read/write operation on I2C slave device, So whenever master has to read data it just send a request to the i2c slave and twis_event_handler() callback function will get triggered, we get p_event->type and p_event->data.buf_req. So in response to this I2C slave send the data to the master. 

But suppose i have to send following command/data  from master to request some data from i2c slave

1).  0xA1 0xA2  0x1 0x2

2)   0xA4 0xA5  

So, how and where i2c slave will receive this command, so that according to received data/command, i2c slave can respond to the master. It would be great help if i can get some example.

Thanks & Regards

Pradeep

Parents
  • Hi Jorgen,

    May you please confirm, is the following implementation correct


    uint8_t buffer[20] = {0};
    int i = 0;
    int j = 0;
    static void twis_event_handler(nrf_drv_twis_evt_t const * const p_event)
    {
    debug_printf(" \nevent handler");
    switch (p_event->type)
    {
    case TWIS_EVT_READ_REQ:
    if (p_event->data.buf_req)
    {
    buffer[i] = p_event->data.rx_amount;
    i++;
    }
    break;
    case TWIS_EVT_READ_DONE:
    i = 0;
    break;
    case TWIS_EVT_WRITE_REQ:
    if (p_event->data.buf_req)
    {

    buffer[j] = p_event->data.tx_amount;
    j++;
    break;
    }
    break;
    case TWIS_EVT_WRITE_DONE:
    j = 0;
    break;

    case TWIS_EVT_READ_ERROR:
    case TWIS_EVT_WRITE_ERROR:
    case TWIS_EVT_GENERAL_ERROR:
    m_error_flag = true;
    break;
    default:
    break;
    }
    }

  • That code seems to do nothing TWIS-related. I was thinking something in the line of this (not compiled/tested):

    #define TWIS_MAX_LENGHT 20
    uint8_t tx_buffer[TWIS_MAX_LENGHT] = {0};
    uint8_t rx_buffer[TWIS_MAX_LENGHT] = {0};
    
    uint8_t rx_length = 0;
    
    uint8_t command1[4] = {0xA1, 0xA2, 0x01, 0x02};
    uint8_t command2[2] = {0xA4, 0xA5};
    
    uint8_t command1_response[16] = {0x00};
    uint8_t command2_response[8] = {0x55};
      
    static void twis_event_handler(nrf_drv_twis_evt_t const * const p_event)
    {
    	debug_printf(" \nevent handler");
    	switch (p_event->type)
    	{
    	case TWIS_EVT_READ_REQ:
    		if (p_event->data.buf_req)
    		{
    		nrf_drv_twis_tx_prepare(&m_twis, tx_buffer, TWIS_MAX_LENGHT);
    		}
    		break;
    	case TWIS_EVT_READ_DONE:
    		if(p_event->data.tx_amount == 4 && memcmp(tx_buffer, command1, 4) == 0)
    		{
    			// Fill rx_buffer with correct response for command1
    			memcpy(rx_buffer, command1_response, sizeof(command1_response));
    			rx_length = sizeof(command1_response);
    		}
    		else if(p_event->data.tx_amount == 2 && memcmp(tx_buffer, command2, 2) == 0)
    		{
    			// Fill rx_buffer with correct response for command2
    			memcpy(rx_buffer, command2_response, sizeof(command2_response));
    			rx_length = sizeof(command2_response);
    		}
    		else
    		{
    			// Fill buffer with default char to tell master command is not supported/recognized
    			memset(rx_buffer, 0xFF, TWIS_MAX_LENGHT);
    			rx_length = TWIS_MAX_LENGHT
    		}
    		break;
    	case TWIS_EVT_WRITE_REQ:
    		if (p_event->data.buf_req)
    		{
    			nrf_drv_twis_rx_prepare(&m_twis, rx_buffer, rx_length);
    		}
    		break;
    	case TWIS_EVT_WRITE_DONE:
    		// Clear buffer
    		memset(rx_buffer, 0x00, TWIS_MAX_LENGHT);
    		break;
    
    	case TWIS_EVT_READ_ERROR:
    	case TWIS_EVT_WRITE_ERROR:
    	case TWIS_EVT_GENERAL_ERROR:
    		m_error_flag = true;
    		break;
    		default:
    		break;
    	}
    }

Reply
  • That code seems to do nothing TWIS-related. I was thinking something in the line of this (not compiled/tested):

    #define TWIS_MAX_LENGHT 20
    uint8_t tx_buffer[TWIS_MAX_LENGHT] = {0};
    uint8_t rx_buffer[TWIS_MAX_LENGHT] = {0};
    
    uint8_t rx_length = 0;
    
    uint8_t command1[4] = {0xA1, 0xA2, 0x01, 0x02};
    uint8_t command2[2] = {0xA4, 0xA5};
    
    uint8_t command1_response[16] = {0x00};
    uint8_t command2_response[8] = {0x55};
      
    static void twis_event_handler(nrf_drv_twis_evt_t const * const p_event)
    {
    	debug_printf(" \nevent handler");
    	switch (p_event->type)
    	{
    	case TWIS_EVT_READ_REQ:
    		if (p_event->data.buf_req)
    		{
    		nrf_drv_twis_tx_prepare(&m_twis, tx_buffer, TWIS_MAX_LENGHT);
    		}
    		break;
    	case TWIS_EVT_READ_DONE:
    		if(p_event->data.tx_amount == 4 && memcmp(tx_buffer, command1, 4) == 0)
    		{
    			// Fill rx_buffer with correct response for command1
    			memcpy(rx_buffer, command1_response, sizeof(command1_response));
    			rx_length = sizeof(command1_response);
    		}
    		else if(p_event->data.tx_amount == 2 && memcmp(tx_buffer, command2, 2) == 0)
    		{
    			// Fill rx_buffer with correct response for command2
    			memcpy(rx_buffer, command2_response, sizeof(command2_response));
    			rx_length = sizeof(command2_response);
    		}
    		else
    		{
    			// Fill buffer with default char to tell master command is not supported/recognized
    			memset(rx_buffer, 0xFF, TWIS_MAX_LENGHT);
    			rx_length = TWIS_MAX_LENGHT
    		}
    		break;
    	case TWIS_EVT_WRITE_REQ:
    		if (p_event->data.buf_req)
    		{
    			nrf_drv_twis_rx_prepare(&m_twis, rx_buffer, rx_length);
    		}
    		break;
    	case TWIS_EVT_WRITE_DONE:
    		// Clear buffer
    		memset(rx_buffer, 0x00, TWIS_MAX_LENGHT);
    		break;
    
    	case TWIS_EVT_READ_ERROR:
    	case TWIS_EVT_WRITE_ERROR:
    	case TWIS_EVT_GENERAL_ERROR:
    		m_error_flag = true;
    		break;
    		default:
    		break;
    	}
    }

Children
No Data
Related