Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronic Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Register Log in

Why disabled autoCsEnable in SPI doesn't allow CS gpio control in EFR32FG14

yefj

Full Member level 6
Joined
Sep 12, 2019
Messages
366
Helped
0
Reputation
0
Reaction score
2
Trophy points
18
Activity points
1,907
Hello, I want to create a 4 byte SPI transmition,so i need my Chip select to be manual.
My Chip Select is PC9 as shown in the photo bellow from the starter kit manual.
I have connected my scope to Chip select and CLK.
At first as you can see bellow that When i have AUTO CS the SPI picture is fine.
But when i made autoCsEnable false, And i tried to do manual GPIO controlling of PC9 ,it didnt allow me that.
I even could not make PC9 to be VDD,and the most amazing thing is that i have built before almost identical code for EFM32 and it worked fine.
Where did i go wrong?
Thanks.

1610628778310.png

1610629176351.png
1610629700656.png


Code:
#include "em_device.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_usart.h"

#define TX_BUFFER_SIZE   4
#define RX_BUFFER_SIZE   TX_BUFFER_SIZE

uint8_t com1[TX_BUFFER_SIZE] = {0x03,0x0F,0xFF,0xF0};


uint8_t RxBuffer[RX_BUFFER_SIZE];

/**************************************************************************//**
* @brief Initialize USART1
*****************************************************************************/
void initUSART1 (void)
{
  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_USART1, true);

  // Configure GPIO mode
  GPIO_PinModeSet(gpioPortC, 8, gpioModePushPull, 0); // US1_CLK is push pull
  GPIO_PinModeSet(gpioPortC, 9, 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
// GPIO_PinModeSet(gpioPortA, 0, gpioModePushPull, 1); //delay


  // 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 hardware, not firmware
  config.clockMode    = usartClockMode1; // 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);

  // Set USART pin locations
  USART1->ROUTELOC0 = (USART_ROUTELOC0_CLKLOC_LOC11) | // US1_CLK       on location 11 = PC8 per datasheet section 6.4 = EXP Header pin 8
                      (USART_ROUTELOC0_CSLOC_LOC11)  | // US1_CS        on location 11 = PC9 per datasheet section 6.4 = EXP Header pin 10
                      (USART_ROUTELOC0_TXLOC_LOC11)  | // US1_TX (MOSI) on location 11 = PC6 per datasheet section 6.4 = EXP Header pin 4
                      (USART_ROUTELOC0_RXLOC_LOC11);   // US1_RX (MISO) on location 11 = PC7 per datasheet section 6.4 = EXP Header pin 6

  // Enable USART pins
  USART1->ROUTEPEN = USART_ROUTEPEN_CLKPEN | USART_ROUTEPEN_CSPEN | USART_ROUTEPEN_TXPEN | USART_ROUTEPEN_RXPEN;

  // Enable USART1
  USART_Enable(USART1, usartEnable);
}

/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void)
{
  uint32_t i;

  // Initialize chip
  CHIP_Init();

  // Initialize USART1 as SPI slave
  initUSART1();
  GPIO_PinOutSet(gpioPortC,9);
  for(i=0;i<115;i++)//delay loop for making stable PC9
              {
               GPIO_PinOutSet(gpioPortA,5);
               GPIO_PinOutClear(gpioPortA,5);
               }
  while(1)
  {
     GPIO_PinOutClear(gpioPortC,9);
              USART_SpiTransfer(USART1,com1[0]);
              USART_SpiTransfer(USART1,com1[1]);
              USART_SpiTransfer(USART1,com1[2]);
              USART_SpiTransfer(USART1,com1[3]);
           GPIO_PinOutSet(gpioPortC,9);
            for(i=0;i<115;i++)//delay loop for making stable PC9
            {
              GPIO_PinOutSet(gpioPortA,5);
              GPIO_PinOutClear(gpioPortA,5);
             }
  }
}
 
Last edited:

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,591
Helped
4,782
Reputation
9,581
Reaction score
4,562
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
124,351
I've never used that device but I would guess the 'USART_SpiTransfer' function is reclaiming the pin for its own use. Maybe the USART1->ROUTELOC0 is responsible as it seems to grab PC9 again. Experimentally, try moving the CS signal to a different pin and see it that works.

Your comment "// Initialize USART1 as SPI slave" doesn't make sense as only the master device should be driving chip select outputs.

Incidentally, your code would be easier to read if you associated the pin name with its number, for example:

#define US1_CS gpioPortC,9 // at the top of your code in an a header file
then instead of
GPIO_PinOutSet(gpioPortC,9);
you could use
GPIO_PinOutSet(US1_CS);

The resulting code would be the same but the source would be easier to read. It also means you only have to change the definition once to change the pin throughout the whole source code.

Brian.
 

yefj

Full Member level 6
Joined
Sep 12, 2019
Messages
366
Helped
0
Reputation
0
Reaction score
2
Trophy points
18
Activity points
1,907
Hello Brian,I have emplemented the same principle before for EFM32LG in the code shown bellow.
Also I made a working SPI for efr32fg14 ,I dont know why it decided to disable all GPIO commnds for CS gpio PC9 pin for manual Chip select in efr32fg14.
Code:
//EFM32LG working manual Chip select SPI
#include <stdint.h>
#include <stdbool.h>



#include "em_emu.h"
#include "bsp.h"
#include "bsp_trace.h"


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

#define TX_BUFFER_SIZE   4
#define RX_BUFFER_SIZE   TX_BUFFER_SIZE



uint8_t com1[TX_BUFFER_SIZE] = {0x03,0x0F,0xFF,0xF0};
uint8_t com0[TX_BUFFER_SIZE] = {0x03,0x00,0x00,0x00};

uint8_t com2[TX_BUFFER_SIZE] = {0x08,0x00,0xFF,0x02};

uint8_t com3[TX_BUFFER_SIZE] = {0x0E,0x00,0x00,0x00};
uint8_t com4[TX_BUFFER_SIZE] = {0x00,0x00,0x00,0x00};
uint32_t TxBufferIndex = 0;

uint8_t RxBuffer[RX_BUFFER_SIZE] = {0};
uint32_t RxBufferIndex = 0;

volatile uint32_t msTicks;

void Delay(uint32_t dlyTicks);

void SysTick_Handler(void)
{
  msTicks++; 
}

void Delay(uint32_t dlyTicks)
{
  uint32_t curTicks;

  curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks) ;
}

int main(void)
{
    int i;
  // Initialize chip
  CHIP_Init();
  if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) {
        while (1) ;
  }

  CMU_ClockEnable(cmuClock_GPIO, true);
  CMU_ClockEnable(cmuClock_USART0, true);
  GPIO_PinModeSet(gpioPortE, 12, gpioModePushPull, 0);
    GPIO_PinModeSet(gpioPortA, 2, gpioModePushPull, 1);
    GPIO_PinModeSet(gpioPortE, 10, gpioModePushPull, 0);
    GPIO_PinModeSet(gpioPortE, 11, gpioModeInput, 1); 
    GPIO_PinModeSet(gpioPortA, 3, gpioModePushPull, 0);
    GPIO_PinModeSet(gpioPortA, 1, gpioModePushPull, 1);
    GPIO_PinModeSet(gpioPortA, 5, gpioModePushPull, 1);

   USART_InitSync_TypeDef config = USART_INITSYNC_DEFAULT;
   config.master       = true;       
   config.baudrate     = 1000000;   
   config.autoCsEnable = false;       

   config.clockMode    = usartClockMode1;
   config.msbf         = true;       

   USART_InitSync(USART0, &config);
   USART0->ROUTE = USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
//USART2->FRAME=USART_FRAME_DATABITS_EIGHT;

   ///////////////////////////////////////////
   USART_Enable(USART0, usartEnable);
    TxBufferIndex = 0;


  while(1)
  {
    //  Delay(1);

        GPIO_PinOutClear(gpioPortA,2);
        USART_SpiTransfer(USART0,com1[0]);
        USART_SpiTransfer(USART0,com1[1]);
        USART_SpiTransfer(USART0,com1[2]);
        USART_SpiTransfer(USART0,com1[3]);
      GPIO_PinOutSet(gpioPortA,2);
      for(i=0;i<115;i++)
      {
       GPIO_PinOutSet(gpioPortA,5);
       GPIO_PinOutClear(gpioPortA,5);
       }
              GPIO_PinOutClear(gpioPortA,2);
              USART_SpiTransfer(USART0,com0[0]);
              USART_SpiTransfer(USART0,com0[1]);
              USART_SpiTransfer(USART0,com0[2]);
              USART_SpiTransfer(USART0,com0[3]);
            GPIO_PinOutSet(gpioPortA,2);
            for(i=0;i<100;i++)
            {
             GPIO_PinOutSet(gpioPortA,5);
             GPIO_PinOutClear(gpioPortA,5);
             }

  

  }
  }
 

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
18,761
Helped
4,184
Reputation
8,370
Reaction score
4,120
Trophy points
113
Activity points
123,389
Hi,

Don't know abut EFR32 ... but STM32xx needs a pullup - if I remember right in "hardware mode".
In software mode it needs to be enabled/disabled...

I use 74HC138 to generate multiple CS from the global CS and port pins.
3 pins for up to 8 devices.

Klaus
 

yefj

Full Member level 6
Joined
Sep 12, 2019
Messages
366
Helped
0
Reputation
0
Reaction score
2
Trophy points
18
Activity points
1,907
Hello Klauss,Yes you are Absolutely right.the EFM32 board i programmed had DAC8004 connected to it and there were pullup resistors in the diagram.
I want to connect my efr32fg14 SPI pins ,SDA,SCL,Chip Select to my bread board and connect pullup resistors between them and 3.3v ,then connect them to the DAC80004EVB i bought.
What values do you recommend to use? 5.1Kohms as in I2C?
Thanks.
 
Last edited:

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,591
Helped
4,782
Reputation
9,581
Reaction score
4,562
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
124,351
Maybe the wording is ambiguous but I assumed 'gpioModePushPull' meant the pin would source or sink current but as I said, I have never used that particular processor.

Brian.
 

    yefj

    points: 2
    Helpful Answer Positive Rating

KlausST

Super Moderator
Staff member
Joined
Apr 17, 2014
Messages
18,761
Helped
4,184
Reputation
8,370
Reaction score
4,120
Trophy points
113
Activity points
123,389
Hi,

If I remember right we configured the CS as push pull, but it acted as open drain.
We did a lot of search through documents until we find where they mentioned "open rain only".

Klaus

You talk about SCL, SDA and CS.
* SDA and SCL usually are I2C signals
* and CS usually is an SPI signal
 

yefj

Full Member level 6
Joined
Sep 12, 2019
Messages
366
Helped
0
Reputation
0
Reaction score
2
Trophy points
18
Activity points
1,907
Hello Brian,Klauss i found the source of the problem.
For some reason in EFR32FG when we define manual CS SPI we need to remove the enabling of the CS PIN in the USART definition.SO i get now SPI just as i wanted and i will try and connect it to the DAC80004EVB.
Thanks.
Code:
USART1->ROUTEPEN = USART_ROUTEPEN_CLKPEN|USART_ROUTEPEN_TXPEN|USART_ROUTEPEN_RXPEN;
 

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top