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

SPI master on nRF5122

I'm using nRF51822 SoC and I have a LIS3DSH accelerometer connected to the ship via SPI bus . I used the SPI master example . So i used the switch_state() function then took the rx_data and tx_data . But when debugging the Keil logic analyzer don't show me any modifacation . Does that mean that i didn't configure the spi right ? IN addiction to that , I have in the data sheet of the LIS3DSH the addressees of the registers containing the X ,Y and Z values , what shall i do to extract them ?

  • (Since you didn't mention, I assume you are using SDK 8 and the nRF51 DK)

    Did you have a look at the documentation for that example? developer.nordicsemi.com/.../a00046.html.

    It says you need to connect the MOSI and MISO pins of both SPI 0 and SPI 1. That is:

    pin 1 -> pin 3

    pin 12 -> pin 14

    Now LED 2 should blink. And you should see activity on one of the two SPI interfaces every second.

    The read sequence of the LIS3DSH is described in the datasheet in section 6.2.1. First you need to set the RW-bit high, then write out the address of the X, Y or Z register you want to read. Then read the SDO line.

    The code would look something like this:

    int main(void)
    {
        bsp_configuration();
    	
    	uint8_t OUT_X_L_addr = 0x28;       // The address of the register you want to write
    	uint8_t tx_data[2] = {0x00, 0x00}; // Transmit register
    	uint8_t rx_data[2] = {0x00, 0x00}; // Receive register
    
        for (;; ){
    		spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
    		tx_data[0] = (0x80 | OUT_X_L_addr); //Add the RW bit to the address.
    		spi_master_send_recv(SPI_MASTER_0, tx_data, 2, rx_data, 2);
    
            // Now rx_data[1] should contain the OUT_X_L value;
        }
    }
    

    EDIT:

    Here is a step by step guide to include spi_master to a BLE project (SDK 7.2):

    1. Add spi_master.c to your project

    2. #include "spi_master.h" in main.c

    3. #include "app_util_platform.h" in main.c

    4. add ..\..\..\..\..\..\components\drivers_nrf\spi_master to your include path in the C/C++ fan in options

    5. Add the init function to main.c:

       static void spi_master_init(spi_master_hw_instance_t   spi_master_instance,
                               spi_master_event_handler_t spi_master_event_handler,
                               const bool                 lsb)
       {
           uint32_t err_code = NRF_SUCCESS;
           spi_master_config_t spi_config = SPI_MASTER_INIT_DEFAULT;
       	spi_config.SPI_Pin_SCK  = SPIM0_SCK_PIN;
       	spi_config.SPI_Pin_MISO = SPIM0_MISO_PIN;
       	spi_config.SPI_Pin_MOSI = SPIM0_MOSI_PIN;
       	spi_config.SPI_Pin_SS   = SPIM0_SS_PIN;
           spi_config.SPI_CONFIG_ORDER = (lsb ? SPI_CONFIG_ORDER_LsbFirst : SPI_CONFIG_ORDER_MsbFirst);
      
           err_code = spi_master_open(spi_master_instance, &spi_config);
           APP_ERROR_CHECK(err_code);
      
           // Register event handler for SPI master.
           spi_master_evt_handler_reg(spi_master_instance, spi_master_event_handler);
       }
      
    6. Add the event handler to main.c:

       void spi_master_0_event_handler(spi_master_evt_t spi_master_evt){}
      
    7. Add SPI_MASTER_0_ENABLE to the 'Define' field in the C/C++ fan under options.

    8. To test, add this to your main(void) function after ble_stack_init():

         uint8_t OUT_X_L_addr = 0x28;       // The address of the register you want to write
         uint8_t tx_data[2] = {0x00, 0x00}; // Transmit register
         uint8_t rx_data[2] = {0x00, 0x00}; // Receive register
         spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
         for (;; )
         {
           tx_data[0] = (0x80 | OUT_X_L_addr); //Add the RW bit to the address.
           spi_master_send_recv(SPI_MASTER_0, tx_data, 2, rx_data, 2);
           power_manage();
         }
      

    Here is my main.c file. It is based on the ble_app_beacon example. It is important that you initialize the spi after the softdevice (ble_stack_init()). Have a look at the file and see if you have done things any differently.

  • i'm using 7.2.0 sdk , and the nRF51 Dk but without a motherboard .

  • If you may plz take a look at what i did ( i can't use the loop back example since i have no mother board) : in the spi-master_init() i configure the pins

    <code>
    spi_config.SPI_Freq= SPI_FREQUENCY_FREQUENCY_M1;
    					  spi_config.SPI_CONFIG_CPHA=SPI_CONFIG_CPHA_Leading ;
    					  spi_config.SPI_CONFIG_CPOL=SPI_CONFIG_CPOL_ActiveHigh;
                spi_config.SPI_Pin_SCK  = 8;
                spi_config.SPI_Pin_MISO = 5;
                spi_config.SPI_Pin_MOSI = 4;
                spi_config.SPI_Pin_SS   = 3;
    					spi_config.SPI_DisableAllIRQ= 0;
    					spi_config.SPI_PriorityIRQ=APP_IRQ_PRIORITY_LOW ;
    					spi_config.SPI_CONFIG_ORDER= SPI_CONFIG_ORDER_LsbFirst;
    </code>
    

    then in main code , i did as you said :

    <code>
    spi_master_init(SPI_MASTER_0, spi_master_0_event_handler, false);
          tx_data[0] = (0x80 | OUT_X_L_addr); //Add the RW bit to the address.  
    			spi_master_send_recv(SPI_MASTER_0, tx_data, 2, rx_data, 2);
    			  if (rx_data[1] != 0 )
    				{	
    				  LedBlink();
    				}
    </code>
    

    but while debugging it never reaches the if (..) , it stops in : spi_master_send_recv(..) .. //Disable interrupt SPI. APP_ERROR_CHECK(sd_nvic_DisableIRQ(p_spi_instance->irq_type)); ..} . What did i do wrong ? Or is there some thing missing ?

  • any idea plz why it stops in APP_ERROR_CHECK(sd_nvic_DisableIRQ(p_spi_instance->irq_type)); ?

  • I don't know what that could be. You can post your code as an attachment in your question. Then I can test it here and see if it works.

Related