why SPI USART_RX blocks transfering signal on EFR32FG14

Thread Starter

yef smith

Joined Aug 2, 2020
756
Hello,I am trying to communicate with SPI device as you can see bellow.
I put in endless loop the process of sending commands and getting response.
At first i send commands and then i expect to get 8 bit response.
but when i put the following line RxBuffer=USART_Rx(USART1); after the TX command.
I get zero data sent from my device .
Why my RxBuffer=USART_Rx(USART1); blocking the TX commands?
Thanks.

Code:
/**************************************************************************//**
 * @main_series1_PG1_EFR.c
 * @brief Demonstrates USART1 as SPI master.
 * @version 0.0.2
 ******************************************************************************
 * @section License
 * <b>Copyright 2018 Silicon Labs, Inc. http://www.silabs.com</b>
 *******************************************************************************
 *
 * This file is licensed under the Silabs License Agreement. See the file
 * "Silabs_License_Agreement.txt" for details. Before using this software for
 * any purpose, you must agree to the terms of that agreement.
 *
 ******************************************************************************/

#include <stdint.h>
#include <stdbool.h>
#include "bsp.h"
#include "bsp_trace.h"


#include "em_emu.h"


#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"
#include "em_ldma.h"

#define TX_WREN_BUFFER_SIZE   1
#define TX_WRITE_BUFFER_SIZE   5
#define TX_READ_BUFFER_SIZE   4

#define RX_BUFFER_SIZE   1


uint8_t Tx_WREN[TX_WREN_BUFFER_SIZE] = {0x06};//write enable command
uint8_t Tx_CHIP_ERASE[TX_WREN_BUFFER_SIZE] = {0xC7};//Chip Erase
uint8_t Tx_READ_STATUS[TX_WREN_BUFFER_SIZE] = {0x05};//read status
uint8_t Tx_PP[TX_WRITE_BUFFER_SIZE] = {0x02,0x00,0x00,0x00,0xE6}; //write to all zero register the value EF
uint8_t Tx_READ[TX_READ_BUFFER_SIZE] = {0x03,0x00,0x00,0x00}; //read register 00,00,00,00

uint32_t TxBufferIndex = 0;

uint8_t RxBuffer;
//uint32_t RxBufferIndex = 0;

volatile uint32_t msTicks; /* counts 1ms timeTicks */

void Delay(uint32_t dlyTicks);

void SysTick_Handler(void)
{
  msTicks++;       /* increment counter necessary in Delay()*/
}
void Delay(uint32_t dlyTicks)
{
  uint32_t curTicks;

  curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks) ;
}
int main(void)
{
    int i;
     CHIP_Init();
    CMU_ClockEnable(cmuClock_GPIO, true);
        CMU_ClockEnable(cmuClock_USART1, true);
        CMU_ClockEnable(cmuClock_USART0, true);

        // Configure GPIO mode
        GPIO_PinModeSet(gpioPortC, 8, gpioModePushPull, 0); // US1_CLK is push pull
        GPIO_PinModeSet(gpioPortA, 4, gpioModePushPull, 1); // US1_CS is push pull
        GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1); // delay gpi
        GPIO_PinModeSet(gpioPortC, 6, gpioModePushPull, 1); // US1_TX (MOSI) is push pull
        GPIO_PinModeSet(gpioPortC, 7, gpioModeInput, 1);    // US1_RX (MISO) is input

        // Start with default config, then modify as necessary
        USART_InitSync_TypeDef config = USART_INITSYNC_DEFAULT;
        config.master       = true;            // master mode
        config.baudrate     = 1000000;         // CLK freq is 1 MHz
        config.autoCsEnable = false;            // CS pin controlled by firmware, not hardware
        config.clockMode    = usartClockMode0; // clock idle low, sample on rising/first edge
        config.msbf         = true;            // send MSB first
        config.enable       = usartDisable;    // Make sure to keep USART disabled until it's all set up
        USART_InitSync(USART1, &config);

        USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;

        // set pin modes for UART TX and RX pins
          GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 1);
          GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1);
          ///////////////////////////////////

            USART_InitAsync(USART0, &init);

            USART0->ROUTELOC0 =(USART_ROUTELOC0_TXLOC_LOC0)  | // US1_TX (MOSI) on location 11 = PC6 per datasheet section 6.4 = EXP Header pin 4
           (USART_ROUTELOC0_RXLOC_LOC0);   // US1_RX (MISO) on location 11 = PC7 per datasheet section 6.4 = EXP Header pin 6

        // Set USART pin locations
        USART1->ROUTELOC0 = (USART_ROUTELOC0_CLKLOC_LOC11) | // US1_CLK       on location 11 = PC8
                            (USART_ROUTELOC0_CSLOC_LOC11)  | // US1_CS        Manual
                            (USART_ROUTELOC0_TXLOC_LOC11)  | // US1_TX (MOSI) on location 11 = PC6
                            (USART_ROUTELOC0_RXLOC_LOC11);   // US1_RX (MISO) on location 11 = PC7

        // Enable USART pins
        USART1->ROUTEPEN = USART_ROUTEPEN_CLKPEN  | USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN;
        // Enable USART1
           USART_Enable(USART1, usartEnable);
           TxBufferIndex = 0;

           if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) {
                 while (1) ;
               }

           while(1)
     {

                                      for(i=0;i<200;i++)
                                      {
                                      GPIO_PinOutSet(gpioPortA,5);
                                          GPIO_PinOutClear(gpioPortA,5);
                                            }

              GPIO_PinOutClear(gpioPortA,4);
               USART_SpiTransfer(USART1,Tx_WREN[0]);
            GPIO_PinOutSet(gpioPortA,4);

                                                 for(i=0;i<10;i++)
                                                  {
                                                  GPIO_PinOutSet(gpioPortA,5);
                                                      GPIO_PinOutClear(gpioPortA,5);
                                                        }
         GPIO_PinOutClear(gpioPortA,4);
         USART_SpiTransfer(USART1,Tx_READ_STATUS[0]);
         GPIO_PinOutSet(gpioPortA,4);

         RxBuffer=USART_Rx(USART1);




             }//end while(1)

}
 

mckenney

Joined Nov 10, 2018
125
The SPI doesn't separate Tx from Rx. Every byte you Tx automatically gets an Rx byte back. Often you are not interested in this Rx byte, but there it is.

A typical transaction might look like: (a) send request byte, throw away result (b) send another (so-called "dummy") byte and capture the resulting Rx byte as your answer. Look through your (slave) device data sheet, and I expect you'll find a waveform diagram that illustrates this.

You could fix this by adding a USART_Tx(0xFF) call preceding your USART_Rx, but I recommend rather that you stick with USART_SpiTransfer() for every byte. spiTransfer does both the Tx and Rx; if you try to separate them you'll quickly end up mired in stale status if you're not very careful.

https://siliconlabs.github.io/Gecko...USART.html#ga85160dfc5405a7fd0f35948fc45450df
 
Top