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

Getting started with SPI

Hello. I have a nRF52832 DK and I'm trying to modify the SPI example code found here: 

/nRF5_SDK_15.0.0/nRF5_SDK_15.0.0_a53641a/examples/peripheral/spi

I'm using the nRF52832 DK as the master and a digital potentiometer (MCP4131) as the slave, and Netbeans 8.2 as my IDE. 

I want to be able to read and write to registers as well as perform commands as described in section 7 of the MCP4131 datasheet

I've been able to send the "Nordic" string on the MOSI bus that I read on an oscilloscope. However, I'm struggling to write hexadecimal values to the following function:

<APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));>

I've tried modifying the value of TEST_STRING from "Nordic" to various hexadecimal formats such as 0x80, %80x, 0X80, "0x80", etc. but I get various errors when I try to do this.

Shouldn't I be able to store a hex value in a static uint8_t value? I feel like I'm missing something obvious here.

Any help would be greatly appreciated! Here is the complete example code for reference:

<

/**
* Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form, except as embedded into a Nordic
* Semiconductor ASA integrated circuit in a product or a software update for
* such product, must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 4. This software, with or without modification, must only be used with a
* Nordic Semiconductor ASA integrated circuit.
*
* 5. Any software provided in binary form under this license must not be reverse
* engineered, decompiled, modified and/or disassembled.
*
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */

#define TEST_STRING "Nordic"
static uint8_t m_tx_buf[] = TEST_STRING; /**< TX buffer. */
static uint8_t m_rx_buf[sizeof(TEST_STRING) + 1]; /**< RX buffer. */
static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */

/**
* @brief SPI user event handler.
* @param event
*/

void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
void * p_context)
{
spi_xfer_done = true;
NRF_LOG_INFO("Transfer completed.");
if (m_rx_buf[0] != 0)
{
NRF_LOG_INFO(" Received:");
NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
}
}

int main(void)
{
bsp_board_init(BSP_INIT_LEDS);

APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();

nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = SPI_SS_PIN;
spi_config.miso_pin = SPI_MISO_PIN;
spi_config.mosi_pin = SPI_MOSI_PIN;
spi_config.sck_pin = SPI_SCK_PIN;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));

NRF_LOG_INFO("SPI example started.");

while (1)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf, 0, m_length);
spi_xfer_done = false;

APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf,m_length, m_rx_buf, m_length));

//NRF_DRV_SPI_XFER_TX(m_tx_buf, m_length);

while (!spi_xfer_done)
{
__WFE();
}

NRF_LOG_FLUSH();

bsp_board_led_invert(BSP_BOARD_LED_0);
nrf_delay_us(1000000);
}
}.

  • Hey Payton,

    I've tried modifying the value of TEST_STRING from "Nordic" to various hexadecimal formats such as 0x80, %80x, 0X80, "0x80", etc. but I get various errors when I try to do this.

    What error do you get when you replace "Nordic" with "0x80" ?

    Also I suggest you try Segger Embedded Studio for any embedded development with our devices as we do not support Netbeans in our SDK.  

    Cheers,

    Håkon.

  • Thanks for the response! No error is given because a variable in quotes is seen as a string and saved as ASCII in the register, similar to how "Nordic" is saved (apologies, I should have said "various issues" not "various errors"). Replacing "Nordic" with "0x80" in the code sends the ASCII 'version' of 0x80 on MOSI. ie, using a conversion tool, one can see that 0x80 is saved as 00110000 01111000 00111000 00110000 0001010. This binary value is exactly what is transmitted on MOSI, as I can see from using an oscilloscope. My issue is that some 8-bit binary values cannot be accessed by ASCII characters (eg, see binary values 10000000-10011111 on an extended ASCII table). So basically I need a way to save these and other values to static uint8_t m_tx_buf[] without using quotes and strings.

  • Hey Payton,

    I was convinced that we were talking about UART for some reason, but now I realize it's SPI. 

    We're gonna start by reading the status register: 

    uint16_t MOSI; //TX buffer
    uint16_t MISO; //RX buffer
    
    MOSI = 0b0101111111111111; //4 bits address (0x5) + 2 control bits (0x3=read) +    \
    //10 bits data. 
    //The data bits on MOSI are called the Over Read Character and is used to let the  \
    //slave continue to send even though the master has sent want it needs for the     \
    //current transfer. Most SPI slaves needs an ORC of 0xFF/0b11111111 to function    \
    //properly.
    
    //After the transfer is complete you need to extract the data bits out of MISO:
    uint16_t DATA = MISO & 0b0000001111111111; // The mask of actual data bits. 
    
    ------------------------------------------------------------------------------------
    To make things more readable you can do the following:
    # define DATA_MSK 0b0000001111111111 
    // Now you can extract the bits in a more human-readable form
    uint16_t DATA = MISO & DATA_MSK;
    
    More advanced:
    #define WIPER0_ADDR 0x00 
    #define TCON_ADDR   0x04
    #define STATUS_ADDR 0x05
    
    #define WRITE_CMD   0x00
    #define INCR_CMD    0x01
    #define DECR_CMD    0x02
    #define READ_CMD    0x03
    
    #define ADDR_POS    12
    #define CMD_POS     10
    
    uint16_t encode_tx_buffer(uint8_t addr, uint8_t cmd)
    {
        return ((addr << ADDR_POS)|(cmd << CMD_POS) | DATA_MSK);
    }
    // To read the status register now:
    uint16_t MOSI = encode_tx_buffer(STATUS_ADDR, READ_CMD); 
    // Should be equal to 0b0101111111111111. 

    I wrote the code in this text editor so there might be some unwanted "features" present, just a heads-up.

    Cheers,

    Håkon.

Related