Higher Speed SPI Configurations

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
inca
Posts: 37
Joined: Mon Apr 22, 2013 12:08 am

Higher Speed SPI Configurations

Post by inca »

I had an SPI1 driver that seemed to only want to work under lower speeds. It works for my EEPROM and ADC at low speeds, but FLASH does not work at all.

SPIConfig for FLASH looks like so, as copied from various available references, most notably testhal/STM32F1xx/SPI:

Code: Select all

/*
 * SPI configuration (maybe 18MHz for flash, CPHA=0, CPOL=0, MSb first).
 */
static const SPIConfig spicfg = {
  NULL,
  GPIOC,
  GPIOC_SPI1_FLASH_CSn,
  SPI_CR1_BR_2 | SPI_CR1_BR_1 | SPI_CR1_BR_0 // SPI_CR1_DFF // 8 bit data frame
};


BR means BaudRate. Setting more BR bits slows the SPI clock down, as per the testhal multithreaded example.
It appears that SPIConfig can configure the CR1 register of the SPI (see stm32f10x.h or similar platform header file for your device).

So if I had an SPI_InitStructure like so:

Code: Select all

 /* SPI1 configuration */
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);
 
  /* Enable SPI1  */
  SPI_Cmd(SPI1, ENABLE);


That would indicate the need to set more CR1 registers, such as CPOL and CPHA, which is not obvious due to STM's naming convention. See the Wikipedia page on CPOL and such to help keep things straight.

From the stm32f1xx.h header file, I grabbed the CPOL and CPHA defines for CR1 and added it to my SPIConfig, which has resolved high speed issues with the EEPROM, as the ADC just doesn't run that fast:

Code: Select all

/*
 * SPI configuration (maybe 18MHz for flash, CPHA=0, CPOL=0, MSb first).
 */
static const SPIConfig spicfg = {
  NULL,
  GPIOC,
  GPIOC_SPI1_FLASH_CSn,
  SPI_CR1_CPHA | SPI_CR1_CPOL
};


FLASH is still not yet up, but I am sure it is a silly mistake that I will find after some proper rest. I hope this can help other users of ChibiOS.

Cheers!
inca
Posts: 37
Joined: Mon Apr 22, 2013 12:08 am

Re: Higher Speed SPI Configurations

Post by inca »

Code documentation for the CR1 register configurations which may be OR'd together in the last element of a SPIConfig struct (Note that some bits may automatically be handled by ChibiOS, but not all, especially CPHA and CPOL):

Code: Select all

/*
 * SPI_CR1 Register Bit Definition for STM32F107
 *
 * Bit 0 SPI_CR1_CPHA: Clock phase
 *  0: The first clock transition is the first data capture edge
 *  1: The second clock transition is the first data capture edge
 * Bit 1 SPI_CR1_CPOL: Clock polarity
 *  0: CK to 0 when idle
 *  1: CK to 1 when idle
 * Bits 5:3 SPI_CR1_BR[2:0]: Baud rate control
 *  000: f_PCLK/2100: f_PCLK/32
 *  001: f_PCLK/4101: f_PCLK/64
 *  010: f_PCLK/8110: f_PCLK/128
 *  011: f_PCLK/16111: f_PCLK/256
 * Bit 7 SPI_CR1_LSBFIRST: Frame format
 *  0: MSB transmitted first
 *  1: LSB transmitted first
 * Bit 8 SPI_CR1_SSI: Internal slave select
 *  This bit has an effect only when the SSM bit is set. The value of this bit
 *      is forced onto the NSS pin and the IO value of the NSS pin is ignored.
 * Bit 9 SPI_CR1_SSM: Software slave management
 *  When SSM is set, the NSS pin input is replaced with the SSI bit value.
 *  0: Software slave management disabled
 *  1: Software slave management enabled
 * Bit 10 SPI_CR1_RXONLY: Receive only
 * Bit 11 SPI_CR1_DFF: Data frame format
 *  0: 8-bit data frame format is selected for transmission/reception
 *  1: 16-bit data frame format is selected for transmission/reception
 * Bit 12 SPI_CR1_CRCNEXT: CRC transfer next
 * Bit 13 SPI_CR1_CRCEN: Hardware CRC calculation enable
 * Bit 14 SPI_CR1_BIDIOE: Output enable in bidirectional mode
 *  Combined with the BIDImode, this bit selects the direction of transfer
 *  0: Output disabled (receive-only mode)
 *  1: Output enabled (transmit-only mode)
 * Bit 15 SPI_CR1_BIDIMODE: Bidirectional data mode enable
 *  0: 2-line unidirectional data mode selected
 *  1: 1-line bidirectional data mode selected
 */


PS: I have no idea how the SPI_CR1_BR2 bit actually affects anything. The reference manual does not add any clarity to those seemingly random possible baud rates on the left hand column above.
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: Higher Speed SPI Configurations

Post by Giovanni »

Hi,

In general most drivers have registers to be configured in their XXXConfig structures. The registers are not described because users are meant to use the Reference Manual in doing this.
Usually the only bits that should be documented (and some older drivers are not compliant with this) are those that:
1) You can't use, for example the CRC in the STM32 SPI driver.
2) Are enforced internally by the driver and should not be specified.

The rationale for this is that setting bits in the registers ofter requires an explanation that goes beyond the simple bits description, the ChibiOS configuration structures are pretty low level in the non-portable part and require understanding of the HW in order to setup features.

Giovanni
etmatrix
Posts: 46
Joined: Sun Oct 21, 2012 10:05 pm

Re: Higher Speed SPI Configurations

Post by etmatrix »

inca wrote:PS: I have no idea how the SPI_CR1_BR2 bit actually affects anything. The reference manual does not add any clarity to those seemingly random possible baud rates on the left hand column above.
I had a similar problem and I wrote this post
inca
Posts: 37
Joined: Mon Apr 22, 2013 12:08 am

Re: Higher Speed SPI Configurations

Post by inca »

The comments got clobbered for the BR register documentation, hence my confusion. It reads like so:

Code: Select all

* Bits 5:3 SPI_CR1_BR[2:0]: Baud rate control
*  000: f_PCLK/2   100: f_PCLK/32
*  001: f_PCLK/4   101: f_PCLK/64
*  010: f_PCLK/8   110: f_PCLK/128
*  011: f_PCLK/16  111: f_PCLK/256
Post Reply