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

TWI AND SPI in a single code

Hi ,

Need a bit of help here.

I am trying to use TWI and SPI in a single code for communicating with two different slave devices, the LTC2941 coulomb counter and the EM4325 RFID tag. I have written a switch case program similar to the one given in SDK 12.3.0 , and added an SPI case for the same. Here is a snippet of my main function (it is similar to the twis_master_with_twis_slave code provided in the SDK) :

int main(void)
{
    ret_code_t err_code;
    /* Initialization of UART */
    bsp_board_leds_init();

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    /* Initializing simulated EEPROM */
    err_code = eeprom_simulator_init();
    APP_ERROR_CHECK(err_code);

    /* Initializing TWI master interface for EEPROM */
    err_code = twi_master_init();
    APP_ERROR_CHECK(err_code);
  
 
  
    while (1)
   
    {  

    nrf_delay_us(9000) ; 
   
   // Welcome message 
    NRF_LOG_RAW_INFO(
            "\n \n This battery state of charge example \r\n"
            "You can access coulumb counter and rfid using following commands:\r\n"
    );
    help_print();

    NRF_LOG_FLUSH();
        uint8_t c = NRF_LOG_GETCHAR();

        switch ((char)c)
        {
        case '\n':
        case '\r':
            break;
        case 'p': // print eeprom data 
            do_print_data();
            break;
    
        case 'w': // configure or write into ltc2941 
            //do_string_write();
    write_into_kunal_ltc2941(); 
            break;
        
    case 'c': // clear the eeprom data 
            do_clear_eeprom();
            break;
    
    case 'q': // get the state of charge 
     SOC(); 
      break ; 
    
    
   case 's': // swap the battery and store data in the rfid tag 
     rfid_spi() ;
     break ; 
    
        case 'x':
            {
                uint32_t error = eeprom_simulator_error_get_and_clear();
                NRF_LOG_WARNING("Error word: %x\r\n", (unsigned int)error);
            } 
            break;

   
     
        default:
            NRF_LOG_RAW_INFO("You selected %c\r\n", (char)c);
            NRF_LOG_RAW_INFO("Unknown command, try one of the following:\r\n");
            help_print();
            break;
        }
        if (eeprom_simulator_error_check())
        {
            NRF_LOG_RAW_INFO(
                    "WARNING: EEPROM transmission error detected.\r\n"
                    "Use 'x' command to read error word.\r\n"
            );
        }
        NRF_LOG_FLUSH();
    }
  
} 

EM4325 datasheet : http://www.emmicroelectronic.com/products/rf-identification-security/epc-and-uhf-ics/em4325

LTC 2941 datasheet : http://cds.linear.com/docs/en/datasheet/2941fb.pdf

Here is the rfid_spi() function which is being called inside the switch case statement for communicating with EM4325 :

static void rfid_spi(void)
{
	uint32_t spike_clk = 24 ;
	uint32_t spike_miso = 23;
	uint32_t spike_mosi = 22 ;
	

	nrf_spim_enable( (NRF_SPIM_Type *)SPI_INSTANCE); 
	
	//nrf_spim_event_clear((NRF_SPIM_Type *)SPI_INSTANCE , NRF_SPI_EVENT_READY ) ;
	
	nrf_spim_configure((NRF_SPIM_Type *) SPI_INSTANCE , NRF_SPIM_MODE_0 , NRF_SPIM_BIT_ORDER_MSB_FIRST) ; 
	
	nrf_spim_pins_set( (NRF_SPIM_Type *)SPI_INSTANCE , spike_clk  ,spike_mosi, spike_miso   ) ;
	
	nrf_spim_frequency_set((NRF_SPIM_Type *)SPI_INSTANCE, NRF_SPIM_FREQ_250K);
	
//	nrf_spim_int_enable ((NRF_SPIM_Type *)SPI_INSTANCE,SPI_INTENSET_READY_Set) ;

				//memset(m_rx_buf, 0, 20); //m_length
        spi_xfer_done = false;
					const uint8_t p1 = 0xff; 
					const uint8_t p2 = 0x65;
				  m_tx_buf[0] = 0xE8;    /**< TX buffer. */
					m_tx_buf[1] = 0x2c;
					m_tx_buf[2] = 0xee ;
					m_tx_buf[3] = 0xab;
	
	nrf_gpio_cfg_output(25) ; // slave select pin 
	nrf_gpio_pin_clear(25) ;  // set ss pin to low to activate SPI 
	
	nrf_spim_task_trigger((NRF_SPIM_Type *)SPI_INSTANCE, NRF_SPIM_TASK_START ) ;	// start spi
	
	bool gg =	nrf_spim_event_check  ( (NRF_SPIM_Type *) SPI_INSTANCE,  NRF_SPIM_EVENT_STARTED ) ;
	NRF_LOG_RAW_INFO("\n has spi started?  %x \n",gg) ;
	
	for (int i=0 ; i<sizeof(m_tx_buf) ; i++){
	
	nrf_spim_tx_buffer_set((NRF_SPIM_Type *)SPI_INSTANCE , &(m_tx_buf[i]), 5 ) ;
	bool gg = nrf_spim_event_check((NRF_SPIM_Type *) SPI_INSTANCE, NRF_SPIM_EVENT_STARTED ) ;
	NRF_LOG_RAW_INFO("event is   %x % \r\n", gg);
	}

	nrf_delay_us(8000) ; //delay required for EM4325 write operation.
	
	for (int i=0 ; i<sizeof(m_rx_buf) ; i++){
	nrf_spim_rx_buffer_set((NRF_SPIM_Type *)SPI_INSTANCE,&m_rx_buf[i],20) ;
	NRF_LOG_RAW_INFO("\n receive buffer byte %d =  %x % \r\n", i, m_rx_buf[i]);

	}
	nrf_gpio_pin_set(25) ;
	nrf_spim_disable( (NRF_SPIM_Type *) SPI_INSTANCE);
 }

I am using the SPIM HAL to communicate with EM4325, this is because when I tried to integrate the spi and twi master codes (of SDK 12.3) , it was giving me garbage values in the receive buffer of the SPI, hence I tried to use the HAL. When I used the SPIM HAL, .( I have referred to the following webpage for using the HAL, my SPI Instance is 2 and TWI instance is 0 ----- https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk52.v0.9.2%2Fgroup__nrf__spim__hal.html ) 

I tried to use the event check function but it was returning me zero values , which indicated that the SPI was not being initiated by the HAL functions

What is the reason for this?? I have attached the serial window output below:

Can someone please help me with a switch case code in which I can use SPI for one switch case and I2C for another ? Is it possible to do this using HAL or with the API which have been provided in SDK 12.3 itself?

Also, when do I know if I should use EASY DMA or not?

Thanking you in advance,

Kunal.

Parents
  • Hi, I think you will  have to first combine the spi and twi examples, for instance (I believe the same examples are available in SDKv12.3):
    \nRF5_SDK_14.2.0_17b948a\nRF5_SDK_14.2.0_17b948a\examples\peripheral\spi\
    \nRF5_SDK_14.2.0_17b948a\nRF5_SDK_14.2.0_17b948a\examples\peripheral\twi_sensor\

    You can use EasyDMA if you are using the nRF52-series, this is configured in sdk_config.h, it is typically preferred since there is less CPU work.

     

Reply
  • Hi, I think you will  have to first combine the spi and twi examples, for instance (I believe the same examples are available in SDKv12.3):
    \nRF5_SDK_14.2.0_17b948a\nRF5_SDK_14.2.0_17b948a\examples\peripheral\spi\
    \nRF5_SDK_14.2.0_17b948a\nRF5_SDK_14.2.0_17b948a\examples\peripheral\twi_sensor\

    You can use EasyDMA if you are using the nRF52-series, this is configured in sdk_config.h, it is typically preferred since there is less CPU work.

     

Children
No Data
Related