2013-10-07 12:54 PM
Hi,
I am using the Discovery F3, I am trying to interface with an SPI port device which requires a 32 bit transfer and 8 bits for address, in the data sheet, the data size is between 4 and 16 bits.
I would know if there is a way to do this stuff. Any help would be appreciated. Thanks #stm32f3-spi2013-10-07 07:01 PM
You should be able to use 8-bit mode, and simply decompose the 32-bit address into four consecutive transfers. You control the CS pin, the transfers will occur back-to-back, and the data is synchronous.
2013-10-08 09:21 AM
Ok, thanks for your replay. This is the code :
#include ''stm32f30x.h'' /** * @brief Configures the different GPIO ports. * @param None * @retval None */ /* variables ---------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; /* Set up GPIO for SPI */ void SPI_GPIO_init(){ //Disable SPI SPI_I2S_DeInit(SPI1); // Enable clock for SPI 1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); // Enable Clock for SPI GPIOA RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); // Set up SCLK, MISO and MOSI pins GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; // Select pins ( SCLK | MISO | MOSI) GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // Set as AF mode GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); // Configure GPIO Alternate function as SPI1 GPIO_PinAFConfig(GPIOA, GPIO_Pin_5, GPIO_AF_5); // SPI1 SCLK GPIO_PinAFConfig(GPIOA, GPIO_Pin_6, GPIO_AF_5); // SPI1 MISO GPIO_PinAFConfig(GPIOA, GPIO_Pin_7, GPIO_AF_5); // SPI1 MOSI // Set up CS pin GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15; // PA15 taken as SPI1_NSS GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // OType, Speed and PuPd are the same GPIO_Init(GPIOA, &GPIO_InitStructure); } /* Set up SPI and related parameters */ void SPI_init(){ // Configure SPI 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_Low; SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure); // Enable SPI1 SPI_Cmd(SPI1, ENABLE); // ensure RXNE is initially clear SPI_ReceiveData8(SPI1); } /** * @brief write data width bytes from SPI interface. * @param passed address & data * @retval None */ void write(uint8_t address, uint32_t data ) { int x=0; uint8_t * txBuffer = (uint8_t*)&data; // gpio init SPI_GPIO_init(); // Init SPI1 SPI_init(); /* Transfer procedure */ /* Wait for SPI1 Tx buffer empty */ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); GPIO_WriteBit( GPIOA,GPIO_Pin_15,Bit_RESET ); // drive the CS line low /* Send SPI address */ SPI_SendData8(SPI1, address); for (x=3; x >= 0 ; x-- ) { while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); /* Send SPI data high */ SPI_SendData8(SPI1, txBuffer[x]); } //wait for last bit to be sent while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); GPIO_WriteBit(GPIOA, GPIO_Pin_15,Bit_SET ); // drive the CS line high } But SPI_SendData8() doesn't write data to DR register, because it has : void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data) { uint32_t spixbase = 0x00; /* Check the parameters */ assert_param(IS_SPI_ALL_PERIPH(SPIx)); spixbase = (uint32_t)SPIx; spixbase += 0x0C; *(__IO uint8_t *) spixbase = Data; }2013-10-09 01:13 PM
Hi,
In the User Manual of the STM32F3, in the pin description PA6: SPI1_MISO, PA7:SPI1_MOSI. In the same time PB4: SPI1_MISO, PB5: SPI1_MOSI. How can we choose between the two configuration ? Thanks in advance for your help2013-10-09 07:51 PM
GPIO_PinAFConfig() controls the pin routing, the options are finite, ie not a cross-bar switch, but rather a mux
The SPIx->DR register is at offset 12 (0x0C) from the base of the peripheral.2013-10-10 07:27 AM
2013-10-11 06:10 AM
Any help please, i have tried many programs to get work the SPI but i always have 0x0 in the DR register.
2013-10-11 10:36 AM
I'm not actively using the F3, so best I can offer is a quick static analysis.
GPIO_PinAFConfig(GPIOA, GPIO_Pin_5, GPIO_AF_5); The second parameter here is wrong (mask), should be using GPIO_PinSource5 (index), see also all other instances. The AF seems valid for the pins being used. There are some mixed comments about SPI2/SPI3, pins/settings valid for SPI3 Also don't look at peripheral registers in the debugger, it will break them, DR is handled differently between a read/write (two unique registers), ie you can't see what you wrote, and reading it clears internal state flags.2013-10-12 11:54 AM
Ok clive1, thanks for you answer.
There are some mixed comments about SPI2/SPI3, pins/settings valid for SPI3: yes because i tried with SPI2, when it doesn't work i change it to SPI3 but not comments:)Also don't look at peripheral registers in the debugger, it will break them, DR is handled differently between a read/write (two unique registers), ie you can't see what you wrote, and reading it clears internal state flags : so how can i visualize data in this case ?2013-10-12 01:53 PM
The debugger can be invasive, you want to look at the peripherals indirectly, ie instrument your output when you already read SR and DR as part of the code flow, or store them in variables you can inspect directly.
Peripherals, and their registers, generally do not behave like memory devices. You can use the ''Peripheral View/Watch'' to get a general sense of how things are set (baud rate, bit settings, etc), but be cautious that they may set or clear bits you might be interested in, or break downstream code expectations.