stm32 SPI + DMA - c

I try to send data with SPI using DMA channel. When I send without DMA everything is OK, but with DMA sth is wrong. When I debug my program SPI DR register is always 0. I would like to use dma circular mode to send my array all the time. There is my code
GPIO INIT:
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPI_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(GPIO_PERIPH_CLOCK, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
GPIO_PinAFConfig(GPIOB, AF_PIN_SOURCE, GPIO_AF);
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
SPI INIT
SPI_I2S_DeInit(SPI1);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
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);
SPI_Cmd(SPI1, ENABLE);
DMA INIT:
DMA_InitTypeDef dma;
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&dma);
dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
dma.DMA_MemoryBaseAddr = (uint32_t)spi_tx_buffer;
dma.DMA_MemoryInc = DMA_MemoryInc_Enable;
dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
dma.DMA_DIR = DMA_DIR_PeripheralDST;
dma.DMA_BufferSize = BUFFERSIZE;
dma.DMA_Mode = DMA_Mode_Circular;
dma.DMA_M2M = DMA_M2M_Disable;
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
DMA_Init(DMA1_Channel1, &dma);
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);
simple main
int main(void) {
periph_init();
while (1) {
for(int j=0; j<10000000; j++){
j++;
j--;
}
}
return 0;
}
What I'm doing wrong?

As I mentioned in comments, your SPI has no connection with DMA1_Channel1. According to this data sheet, you should use DMA1_Channel3.

Related

I can't see any signal on the CAN_TX line

I try to use the CAN bus on an STM32F303 discovery board, and I am using the PD0→RX and PD1→TX pins.
I want to try to send a message and analyse on the oscilloscope. So my configuration is seen below in the code blocks.
When I analyse with the oscilloscope which pins are PD0 and PD1, I can't see anything on the oscilloscope.
Where is my fault?
This is my code:
#include <stm32f30x.h>
#include <stm32f30x_i2c.h>
#include <stm32f30x_rcc.h>
#include <stm32f30x_syscfg.h>
#include <stm32f30x_exti.h>
// #include <stm32f30x_misc.h>
#include "main.h"
#include <stdio.h>
#include "common.h"
#include "io_periph_defs.h"
#include "stm32f30x.h"
#include <stdio.h>
#include "conf.h"
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
CanRxMsg RxMessage;
void Init_TxMes(CanTxMsg *TxMessage)
{
/* Transmit INITIALIZATION*/
TxMessage->IDE = CAN_ID_STD;
TxMessage->DLC = 2;
TxMessage->StdId = 0x321;
TxMessage->RTR = CAN_RTR_DATA;
}
void Init_RxMes(CanRxMsg *RxMessage)
{
uint8_t i = 0;
RxMessage->StdId = 0;
RxMessage->IDE = CAN_ID_STD;
RxMessage->DLC = 0;
RxMessage->FMI = 0;
for (i = 0; i < 8; i++)
{
RxMessage->Data[i] = 0;
}
}
void CAN_setup(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable the clock for CAN
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
/* Configure CAN1 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure CAN1 TX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_9);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_9);
/* Enable the CAN global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = CAN1_SCE_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
NVIC_Init(&NVIC_InitStructure);
CAN_DeInit(CAN1);
/* Configure CAN1 **************************************************/
/* Struct init*/
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
/* CAN Baudrate = 125kbps (CAN clocked at 36 MHz) */
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 16;
CAN_Init(CAN1, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
}
int main(void)
{
int i;
uint8_t TransmitMailbox = 0;
CAN_setup(); // Set up CAN interface
Init_TxMes(&TxMessage);
init_pin(GPIOA, GPIO_Pin_8, GPIO_Mode_OUT, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP);
while (1)
{
TxMessage.Data[0] = 0xAA;
GPIO_SetBits(GPIOA, GPIO_Pin_8); // Transmit data
TransmitMailbox = CAN_Transmit(CAN1, &TxMessage);
i = 0;
while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK))
; // I put a breakpoint here to check
// and found the message is pending.
GPIO_ResetBits(GPIOA, GPIO_Pin_8); // Transmit data
//i++;
}
}
I think there is the problem, but how can I solve it?
Stacking in loop.
while ((CAN_TransmitStatus(CAN1, TransmitMailbox) != CANTXOK)

stm32f4 discovery CAN transmit

This is my program for CAN transmit. I just want to see through the
oscilloscope wether something is being sent or not. I am using stm32f407
and attolic true studio for it, but i am unable to see any signal on my
tx pin. Kindly tell me where is my mistake. Do i need to connect the transciever externally and also how can i access CAN_H and CAN_L pins.
#include "stm32f4xx.h"
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_ClocksTypeDef RCC_Clocks;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
RCC_GetClocksFreq(&RCC_Clocks);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);`
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq;
CAN_InitStructure.CAN_Prescaler = 4;
CAN_Init(CAN1, &CAN_InitStructure);
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
// transmit */
TxMessage.StdId= 0x123;
TxMessage.ExtId= 0x00;
TxMessage.RTR= CAN_RTR_DATA;
TxMessage.IDE= CAN_ID_STD;
TxMessage.DLC= 4;
TxMessage.Data[0]= 0x02;
TxMessage.Data[1]= 0x11;
TxMessage.Data[2]=0x11;
TxMessage.Data[3]=0x11;
while(1)
{
volatile uint_t i;
unit8_t TransmitMailbox= 0;
//sprintf(TxMessage.Data, "Imran\n");
TransmitMailbox= CAN_Transmit(CAN1,&TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1,TransmitMailbox) !=CANTXOK)&& (i !=0xFFFFFF))
{
i++;
}
}
}
Try to turn on the Automatic Wake Up by changing to the following line:
CAN_InitStructure.CAN_AWUM = ENABLE;
The stm32f407 has only the CAN Controller without the internal transciever, so you need to connect it externaly. Also you have to connect another device into your CAN Bus to see something (remember about the terminators).
Please explain what do you mean by saying that:
how can i access CAN_H and CAN_L pins
PS. You should not put each functionality into one routine because it is unreadable.

STM32F4 multiple SPI_I2S_GetFlagStatus crashes the program

I'm trying to implement a simple http server on my stm32F411RE nucleo board from here, but of course I've run into some problems - so far, I managed to narrow the current one to the fact, that after about 20 calls to
SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE); My program crashes. By crash, I mean goes to the Infinite Loop defined in the startup file, reason being "Program received signal SIGINT, Interrupt."
My spi is initialised like that:
void SPI1_Init(void){
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable SPI1 and GPIOA clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
//SCK, MISO, MOSI
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//CS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//CS down
GPIO_SetBits(GPIOA, GPIO_Pin_2);
SPI_InitTypeDef SPI_InitStructure;
/* 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_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
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);
}
after the initialization, I do this:
for(tmpCnt = 0; tmpCnt < 100; tmpCnt++){
SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE);
}
and it crashes after about 20 iterations. I am using the standard peripheral library, and System Workbench with all stock settings of compiler and everything else. At the moment nothing is connected to the SPI pins, could that be the problem?
calling
(SPI1->SR) instead of SPI_I2S_GetFlagStatus
has the same effect so I guess that the problem lies withing reading the register. Why could that be? I'm really stuck at the moment, so any help would be appreciated.
EDIT:
Ok, it turns out that I missed a bit of code that seems to cause this behaviour - before the SPi1->SR calls, I also had this function called:
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
SysTick->LOAD = ticks - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
SysTick->VAL = 0; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
why does it break the SPI1->SR access? could there be anything else wrong? My main function:
int main(void)
{
int tmpCnt = 0;
int rev = 0;
//uint16_t writedat = 22;
RCC_Init();
SPI1_Init();
//SysTick_Config(1000);
for(tmpCnt = 0; tmpCnt < 50; tmpCnt++){
SPI1->SR ;
}
enc28j60Init((unsigned char *)enc28j60_MAC);
//simple_server();
rev = enc28j60getrev();
return rev;
}
RCC_Init does not seem to change anything in the behaviour of the SPI1->SR.
As before, any advice would be welcome.

STM32F407 SPI reciveing only 0xFF (255) or 0

Recently I have been trying to receive a data from my STM32F407 motion sensor. I have the following code:
uint8_t SPI1_Read(){
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // CS low
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET){}
SPI_I2S_SendData(SPI1, 0x00);
while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)==RESET){}
return SPI_I2S_ReceiveData(SPI1);
}
void SPI1_Write(uint8_t data){
while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET){}
SPI_I2S_SendData(SPI1, data);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET){}
SPI_I2S_ReceiveData(SPI1);
}
volatile static int vrednost, vrednost1, vrednost2;
int main(void)
{
// Vkljuci driver za GPIOD
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
// Nastavi registre za LED diode
GPIO_InitTypeDef inicializacijskaStruktura;
inicializacijskaStruktura.GPIO_Mode = GPIO_Mode_OUT;
inicializacijskaStruktura.GPIO_OType = GPIO_OType_PP;
inicializacijskaStruktura.GPIO_PuPd = GPIO_PuPd_NOPULL;
inicializacijskaStruktura.GPIO_Speed = GPIO_Speed_100MHz;
inicializacijskaStruktura.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOD, &inicializacijskaStruktura);
SPI_and_GPIO_Init();
// init
SPI1_Write(0x20);
SPI1_Write(0x47);
SPI1_Write(0x0F);
SPI1_Write(0xBC);
while(1)
{
SPI1_Write(0x20);
vrednost=SPI1_Read();
SPI1_Write(0x24);
vrednost1=SPI1_Read();
SPI1_Write(0x28);
vrednost2=SPI1_Read();
if(vrednost<122){
GPIO_SetBits(GPIOD, GPIO_Pin_12);
}
else{
GPIO_ResetBits(GPIOD, GPIO_Pin_12);
}
if(vrednost1<122)
GPIO_SetBits(GPIOD, GPIO_Pin_13);
else
GPIO_ResetBits(GPIOD, GPIO_Pin_13);
if(vrednost2<122)
GPIO_SetBits(GPIOD, GPIO_Pin_14);
else
GPIO_ResetBits(GPIOD, GPIO_Pin_14);
}
}
void SPI_and_GPIO_Init(){
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable the SPI periph */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* Enable SCK, MOSI and MISO GPIO clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA , ENABLE);
/* Enable CS GPIO clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* SPI pins configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* SPI configuration -------------------------------------------------------*/
SPI_I2S_DeInit(SPI1);
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
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_4;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
/* Enable SPI1 */
SPI_SSOutputCmd(SPI1, ENABLE);
SPI_Cmd(SPI1, ENABLE);
/* Configure GPIO PIN for Lis Chip select */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* Deselect : Chip Select high */
GPIO_SetBits(GPIOE, GPIO_Pin_3);
}
Upper code works fine, but the problem is that always when I try to read motion sensor, i get 0xFF or in another words 255. I read data by sending dummy text and then read data.
I have been also given an advice to set Slave Select pin (SS) to zero, but I don't know how to do that.
Does anybody know?
To hazard a guess - typically with SPI, SS is driven low (enable) at the start of each write/read then driven high (disable) at the end of each write/read to indicate end of transmission. Without pulling out the board, that's what I'd bet on.
If that's not it - ST is pretty good at providing examples. The source code on their product page includes an example using their MEMs accelerometer (Utilities/STM32F4-Discovery/stm32f4_discovery_lis302dl.c/.h).

Using STM32 Timer

I am working on the timer of STM32. I need two pulses like in the picture.
Frequency of CLK is 50 kHz and frequency of SI is 381.67 Hz. I need the SI to go low before the rising edge of next clock pulse but in the logic analyzer of Keil I saw the SI was in a different position relatively to CLK for each pulse, like shown on below picture. How can I fix it?
void Init_TIMER(void)
{
TIM_TimeBaseInitTypeDef TIM_BaseInitStructure2, TIM_BaseInitStructure3, TIM_BaseInitStructure4;
TIM_OCInitTypeDef TIM_OCInitStructure2, TIM_OCInitStructure3;
TIM_DeInit(TIM2);
TIM_DeInit(TIM3);
TIM_DeInit(TIM4);
TIM_InternalClockConfig(TIM2);
TIM_InternalClockConfig(TIM3);
TIM_InternalClockConfig(TIM4);
/************************************************/
/********TIMER2**********************************/
/************************************************/
TIM_BaseInitStructure2.TIM_Period = 180; //180/9000000=..ms 50KHZ
TIM_BaseInitStructure2.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure2.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure2.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, & TIM_BaseInitStructure2);
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
TIM_OCInitStructure2.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure2.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure2.TIM_Pulse = 90;
TIM_OCInitStructure2.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC2Init(TIM2, & TIM_OCInitStructure2);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
/*****************************************************/
/********TIMER3***************************************/
/*****************************************************/
TIM_BaseInitStructure3.TIM_Period = 23580; //23580/9000000=... ms 381.67HZ 50KHZ/131=381.67HZ
TIM_BaseInitStructure3.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure3.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure3.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, & TIM_BaseInitStructure3);
TIM_ClearFlag(TIM3, TIM_FLAG_Update);
TIM_OCInitStructure3.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure3.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure3.TIM_Pulse = 50;
TIM_OCInitStructure3.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM3, & TIM_OCInitStructure3);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
/********************************************************/
/********TIMER4 to make sampling frequency **************/
/*******************************************************/
TIM_BaseInitStructure4.TIM_Period = 90; //90/9000000=0.01ms 100KHZ
TIM_BaseInitStructure4.TIM_Prescaler = 7; //SYSCLK=72M, TIM1_CLK=72/8=9MHz
TIM_BaseInitStructure4.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseInitStructure4.TIM_CounterMode = TIM_CounterMode_Up;
//TIM_BaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, & TIM_BaseInitStructure4);
TIM_ARRPreloadConfig(TIM4, DISABLE);
TIM_ClearFlag(TIM4, TIM_FLAG_Update);
/**********************************************/
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_Cmd(TIM2, ENABLE);
TIM_ARRPreloadConfig(TIM3, ENABLE);
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM4, ENABLE);
}
void GPIO_Configuration()
{
GPIO_InitTypeDef GPIO_InitStructure;
/*PA1 TIM2_CH2*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, & GPIO_InitStructure);
/*PA7 TIM3_CH2*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, & GPIO_InitStructure);
}
I had similar project where I had used taos TSL1402R matrix.
Instead of timer I used an SPI with circular DMA.
DMA buffer was 0x0, 0x0.....0x0, 0x1.
SI was connected to SPI MISO,
And CLK was connected to SPI_CLK.
Hope this will help.

Resources