Why SPI sequence doesnt match MSB order

Status
Not open for further replies.

yefj

Advanced Member level 5
Joined
Sep 12, 2019
Messages
1,505
Helped
1
Reputation
2
Reaction score
5
Trophy points
38
Activity points
9,114
Hello,I am sending a sequence as shown bellow MSB first order(EFR32)
but when i look at the sequence displayed on osciloscope shown bellow, i see 111 from the left end and 11 from the right end it doesnt match the sequence i am sending .
the attached code shown bellow.
Where did i go wrong?
Thanks.




Code:
#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_WRSR_BUFFER_SIZE   4
#define TX_RDSR_BUFFER_SIZE   1

#define RX_BUFFER_SIZE   1


uint8_t Tx_WREN[TX_WREN_BUFFER_SIZE] = {0x06};//write enable command
uint8_t Tx_WRSR[TX_WRSR_BUFFER_SIZE] = {0x01,0x2F,0xEF,0xD8}; //write status register
uint8_t Tx_RDSR[TX_RDSR_BUFFER_SIZE] = {0x05}; //read status register

uint32_t TxBufferIndex = 0;

uint32_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)
{
     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(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) ;
               }
           USART1->IEN = USART_IEN_TXC; //enable TXC interrupt flag

           while(1)
     {
              Delay(1);
                GPIO_PinOutClear(gpioPortA,4);
               USART_Tx(USART1, Tx_WRSR[0]);
                while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
               USART_Tx(USART1, Tx_WRSR[1]);
                 while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
                  USART_Tx(USART1, Tx_WRSR[2]);
                while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
                 USART_Tx(USART1, Tx_WRSR[3]);
                while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
               GPIO_PinOutSet(gpioPortA,4);
              Delay(1);

             }

}
 
Last edited:

Without clock trace, it's impossible to decode the oscilloscope data. You are misinterpreting the gap between first and second byte as multiple one bits.
 

Hi,

I agree with FvM, show the clock combined with the data.
I assume the bit order as well as the byte order is correct. MSB first.

Klaus
 


I don't see a post with waveforms fitting the said data sequence. If I overlooked something, please tell the post #. Bad enough that you are starting multiple threads about the same problem. Please observe forum rules in this regard.
 

Hello FVM, yes sorry it wont happen again i tried to delete the reply in the other thread to avoid double reply,but i cant anymore.
. regarding the SCOPE photos,i will make it orders here too as well:
I am using MX25R8035F flash wich is in EFR32FG14 starter kit:
**broken link removed**
to communicate with it i am using those three commands one after the other:
1. Write enable 0x06
2.Write to address of all zeros the value of FF ,so in hex its : 02,00,00,00,00,FF
3. reading from adress all zeros the command is 03,00,00,00,00.

there is a printscreen bellow for 0x06 ,using the cursors i saw the data flow from right to left (one cursor time bigger then the other)and i see that if we send 0000,0110 we get the photo bellow.
I am showing printscreen of other commands too,and what i see as shown in the last photo that as i send those 3 commnd threw MOSI i get all one data from MISO although even when i put E6 as data which is 11100110.
I dont have this data i get all 1 data.
The full code is attached bellow.
Where did i go wrong in reading my data from that device?
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   6
#define TX_READ_BUFFER_SIZE   5

#define RX_BUFFER_SIZE   1


uint8_t Tx_WREN[TX_WREN_BUFFER_SIZE] = {0x06};//write enable command
uint8_t Tx_PP[TX_WRITE_BUFFER_SIZE] = {0x02,0x00,0x00,0x00,0x00,0xFF}; //write to all zero register the value FF
uint8_t Tx_READ[TX_READ_BUFFER_SIZE] = {0x03,0x00,0x00,0x00,0x00}; //read register

uint32_t TxBufferIndex = 0;

uint32_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)
{
     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(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) ;
               }
           USART1->IEN = USART_IEN_TXC; //enable TXC interrupt flag

           while(1)
     {

              Delay(1);
              GPIO_PinOutClear(gpioPortA,4);
            USART_Tx(USART1, Tx_WREN[0]);
            while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
            GPIO_PinOutSet(gpioPortA,4);

              Delay(1);
                GPIO_PinOutClear(gpioPortA,4);
               USART_Tx(USART1, Tx_PP[0]);
                while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
               USART_Tx(USART1, Tx_PP[1]);
                 while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
                  USART_Tx(USART1, Tx_PP[2]);
                while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
                 USART_Tx(USART1, Tx_PP[3]);
                 while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
                USART_Tx(USART1, Tx_PP[4]);
                while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
                USART_Tx(USART1, Tx_PP[5]);
                while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
                 GPIO_PinOutSet(gpioPortA,4);
                Delay(1);
                //Tx_READ
               GPIO_PinOutClear(gpioPortA,4);
               USART_Tx(USART1, Tx_READ[0]);
              while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
               USART_Tx(USART1, Tx_READ[1]);
               while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
               USART_Tx(USART1, Tx_READ[2]);
               while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
               USART_Tx(USART1, Tx_READ[3]);
               while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high
               USART_Tx(USART1, Tx_READ[4]);
               while( !(USART1->STATUS & USART_STATUS_TXC) );  //wait TILL TXC goes high

               GPIO_PinOutSet(gpioPortA,4);




             }

}
 

Other than claimed in post #1, MISO is showing correct data for the first sequences. I don't see where the code fails to write 0xE6, the value doesn't seem to occur in the code.
 

Hello FVM, E6 is 11100110 my MISO is all 111111111 its not showing E6.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…