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

nRF52832 SPI Slave clock frequency.

Hi 

We are developing by connecting nRF52832 to SMT32f303cb's SPI interface.

SMT32f303cb operates as an SPI Master.

If the clock frequency of SPI Master is changed to 8Mhz, 4Mhz or 2Mhz, normal communication with nRF52832 operates only at 2Mhz.

We want to use the 8Mhz.

I attached the source code related to SPI communication.

How can I fix it?

***** ST (stm32f303cb)*****  

static void MX_SPI1_Init(void)

  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;  

  //hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;   // 8MHz

  //hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;   // 4MHz
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;   // 2MHz
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 7;
  hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
  hspi1.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}  

 

 
int testSendCnt = 0;

void cis_test_send(void)
{
    uint32_t len;
    char      dbgBuf[16];
    char      sendBuf[36];
 
    for (len = 1; len < 25; len++) {
        sendBuf[len+4] = len;
    }
 
    sendBuf[0] = 0xA5;
    sendBuf[1] = 0xDE;
    sendBuf[2] = 0xAD;
    sendBuf[3] = 0xBE;
    sendBuf[4] = 0xEF;
 
    *(uint32_t *)&sendBuf[26] = testSendCnt;
 
    sendBuf[30] = 0x0d;
    sendBuf[31] = 0x0a;
 
    //for (len = 0; len < BT_SEND_MAX; len++) 
    {
 
        while(HAL_SPI_GetState(&hspi1)==HAL_SPI_STATE_BUSY_TX){ }
 
        //if (HAL_OK == HAL_SPI_Transmit(&hspi1, &sendBuf[len], 1, 1000)) {
        if (HAL_OK == HAL_SPI_Transmit(&hspi1, &sendBuf[len], 36, 1000)) {
            while(HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY) { }
            sprintf(dbgBuf, "%02x ", sendBuf[len]);
            HAL_UART_Transmit(&huart3, dbgBuf, 3, 0xFFFF);
        } else {
            Error_Handler();
            HAL_UART_Transmit(&huart3, "err: spi\r\n", 10, 0xFFFF);
            return;
        }  
    } 
    testSendCnt++;
    sprintf(dbgBuf, "test %05d\r\n", testSendCnt);
    HAL_UART_Transmit(&huart3, dbgBuf, 12, 0xFFFF);
}  

 

***** BT : nRF52832*****

 

void spi_init(void) // +-kebi
{
    nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;
 
    spis_config.sck_pin      = 3; //APP_SPIS_SCK_PIN; ;          
    spis_config.csn_pin      = 29; //APP_SPIS_CS_PIN;                 
    spis_config.mosi_pin     = 28; // APP_SPIS_MOSI_PIN;                
    spis_config.miso_pin     = 4; //APP_SPIS_MISO_PIN;              
    
    spis_config.mode         = NRF_SPIS_MODE_0; ///< SCK active high, sample on leading edge of clock.                       
    spis_config.bit_order    = NRF_SPIS_BIT_ORDER_MSB_FIRST;          
    spis_config.csn_pullup   = NRFX_SPIS_DEFAULT_CSN_PULLUP;          
    spis_config.miso_drive   = NRFX_SPIS_DEFAULT_MISO_DRIVE; 
#if 1         
    spis_config.def          = NRFX_SPIS_DEFAULT_DEF;                 
    spis_config.orc          = NRFX_SPIS_DEFAULT_ORC;         
#else
    spis_config.def          = 36;                 
    spis_config.orc          = 36;     
#endif    
    spis_config.irq_priority = NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY;
    //spis_config.irq_priority = 2; //NRFX_SPIS_DEFAULT_CONFIG_IRQ_PRIORITY; // 6
 
    APP_ERROR_CHECK(nrf_drv_spis_init(&spis, &spis_config, spis_event_handler));
}

 

 

uint8_t     gSpiRecvCnt = 0;
 
void spis_event_handler(nrf_drv_spis_event_t event)
{
    BT_Status_type *StsBt= &AppStsBt;
    timer_conter_Typedef* tc= ScanStat.ptc;
    uint8_t ii, jj;
    char uBuf[120];
     
    switch (event.evt_type){
    case NRF_DRV_SPIS_XFER_DONE:
        //ScanStat.spi_rp= false;    ///< spi packet
수신 완료
 
        if (event.rx_amount == 0)  return;
#if 0
        sprintf(uBuf, "%02d\r\n", event.rx_amount);
        app_uart_send(4, uBuf);
         
        for (ii = gSpiRecvCnt; ii < (event.rx_amount + gSpiRecvCnt); ii++) {
            sprintf(uBuf, "%02d-%02x\r\n", ii, m_rx_buf[gSpiCur][ii]);
            app_uart_send(7, uBuf);
        }
 
#endif
 
        gSpiRecvCnt += event.rx_amount;
        //APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, 0, 0, &m_rx_buf[gSpiCur][gSpiRecvCnt], 1));  

        APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, 0, 0, &m_rx_buf[gSpiCur][gSpiRecvCnt], 32));
 
        if (gSpiRecvCnt > 32) {
#if 0
            for (ii = 0, jj = 0; ii < 32; ii++, jj+=3) {
                sprintf(uBuf+jj, "%02x ", m_rx_buf[gSpiCur][ii]);
            }
            sprintf(uBuf+jj, "\r\n");   
            app_uart_send(jj+2, uBuf);
 
            sprintf(uBuf, "%02d-5A-End\r\n", gSpiCur);
            app_uart_send(11, uBuf);
#endif
            gSpiRecvCnt = 0;
 
            if (m_rx_buf[gSpiCur][0] == 0x5A) {
                gSpiCur++;
                if (gSpiCur >= SPI_MAX_QUEUE) gSpiCur = 0;
 
                //AppFlg.flag = 1;
 
                //AppFlg.msg = SPI_RCV_DONE;
                //AppFlg.msg = COMPLETED_SCAN_ROW;
                //spis_xfer_done++;
            } else {
                gSpiCur++;
                if (gSpiCur >= SPI_MAX_QUEUE) gSpiCur = 0;
            }

            //ScanStat.spi_rp= false;    ///< spi packet 수신 완료
        }
       
        break;
 
    case NRFX_SPIS_BUFFERS_SET_DONE:
        break;
    default:
        NRF_LOG_INFO("event acquired\n");
        break;
    }

 

 

int main(void)
{
    bool erase_bonds;
    NRF_POWER->TASKS_CONSTLAT = 1;
    uint8_t     ttt = 0;
    // Initialize.
    //    uint32_t err_code = app_timer_init();
    //    APP_ERROR_CHECK(err_code);
 
    log_init();
    init_gpio();
#ifdef BT_DBG
    uart_init(); // ++kebi
#endif
    timers_init();
    drv_timer_init();
    spi_init();      // -- kebi
    ble_stack_init();
 
    flash_store_init();
    mem_config_init();
    cust_init();
 
    power_management_init();
 
    gap_params_init();
    gatt_init();
    services_init();
 
    advertising_init();
    conn_params_init();
 
    gatt_mtu_set(m_test_params.att_mtu);
 
    conn_evt_len_ext_set(m_test_params.conn_evt_len_ext_enabled);
 
    usr_advertising_start();
 
    // Enter main loop.
    InitQueue();
    spis_xfer_done = 0;
 
    gSpiCur = 0;
    gSendCur = 0;
 
    //APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, m_tx_buf, 0, &m_rx_buf[0][0], 1));
    APP_ERROR_CHECK(nrf_drv_spis_buffers_set(&spis, 0, 0, &m_rx_buf[0][0], 32));
 
    app_uart_send(12, "BT Start!!\r\n");
     
    while(1) {
        CheckFlag();
        //while (!spis_xfer_done && !AppFlg.flag && !AppBtFlg.flag) 
        while (!spis_xfer_done) 
        {
            __WFE();
        }
        //idle_state_handle();
        if (ttt) {
            ttt = 0;
            app_uart_send(3, "+\r\n");
        } else {
            ttt = 1;
            app_uart_send(3, "-\r\n");
        }
    }
}

Parents Reply Children
  • There is no frequency config on the nRF side for the SPIS peripheral, it will run at whatever frequency the SPI master uses

    Indeed.

    That's the whole point of a synchronous link like SPI: the same would apply to any slave - not specific to nRF.

    (other that the physical limit on the maximum frequency of the slave's hardware).

    Of course, the faster the data is going, the more careful you have to be with your slave  code to ensure that it has the capacity to handle the data ...

  • Thank you for your reply.

    Do you know the nRF52832's maximum frequency?

  • Thank you for your reply.

    I mean there are issues with communications when the frequency is set higher.

    SPI Master has confirmed normal operation at 4Mhz and 8Mhz.

    However, It does not work when connected with nRF52832 in 4Mhz and 8Mhz.

    It worked fine at 2Mhz.

    Do you know the nRF52832's maximum frequency?

  • The problem is the drive strength of the output pins, methinks. Try this:

    //Edit: I misread the original post aw awneil points out; these are inputs
    //      but need to be set to high-Drive on the ST
     nrf_gpio_cfg(APP_SPI0_CS_PIN,  NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
     nrf_gpio_cfg(APP_SPI_MOSI_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
     nrf_gpio_cfg(APP_SPI_SCK_PIN,  NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
    
    So just this on the nRF52: 
     nrf_gpio_cfg(APP_SPI_MISO_PIN,  NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_H0H1, NRF_GPIO_PIN_NOSENSE);
    

    or the equivalent in whatever IDE you are using; the idea is High Drive '1' and '0' for CS, SCK and MOSI pins which are output from the ST and MISO which is output from the nRF52 in order to get 4MHz, 8MHz or even 16MHz operation. This must be done after the SPI initialisation, not before.

  • SPI Master has confirmed normal operation at 4Mhz and 8Mhz

    How, exactly, has that been confirmed?

    The problem is the drive strength of the output pins, methinks

    Note that the STM32 also has settings for this - so check there also.

    CS, SCK and MOSI pins which are output from the nRF52

    No: the nRF is Slave here - so those are all inputs.

    MISO is an output on the Slave.

    - have you looked at the wires with an oscilloscope - that should show you if you have drive strength problems ...

Related