Reputation: 97
I have little bit problem when reading Rx Buffer in STM32 SPI. I can watch my signal when transmit or receive in my scope. But I never can get any data in my Rx Buffer. I just use coocox software for this project.
For this project, I use STM32F103 and LoRa module (SX1278). I use Full duplex communication for my SPI Configuration. There is 2 cycle to read register status in my LoRa module. First cycle is to write address and second cycle is for read/write register. My problem is reading register in my LoRa module.
This is my simple code to read register.
void SPI2_IRQHandler(void)
{
RxSPIBuff = &Buffer_Rx[0];
if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET)
{
/* Store the I2S2 received data in the relative data table */
//Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI2);
//if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_FLAG_RXNE)==SET)
USART_SendData(USART1, SPI_I2S_ReceiveData(SPI2));
}
}
void InitSPI_Lora(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// RCC Peripheral Configuration
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// GPIO Configuration
GPIO_InitStructure.GPIO_Pin = MOSI_LoRa | SCLK_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_LoRa, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = NSS_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PeriphNSS_LoRa, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = MISO_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_LoRa, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Reset_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PeriphRst_LoRa, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = DIO0_LoRa;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PeriphDI0_LoRa, &GPIO_InitStructure);
// SPI Configuration
SPI_InitStruct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_32; // 7us every 8 bit data
SPI_InitStruct.SPI_CPHA=SPI_CPHA_1Edge;
SPI_InitStruct.SPI_CPOL=SPI_CPOL_Low;
SPI_InitStruct.SPI_DataSize=SPI_DataSize_8b;
SPI_InitStruct.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_FirstBit=SPI_FirstBit_MSB;
SPI_InitStruct.SPI_Mode=SPI_Mode_Master;
SPI_InitStruct.SPI_NSS=SPI_NSS_Soft;
// NVIC Configuration
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* SPI1 IRQ Channel configuration */
NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
SPI_I2S_DeInit(SPI2);
/* Enable the I2S1 RxNE interrupt */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
SPI_Init(SPI2, &SPI_InitStruct);
SPI_Cmd(SPI2, ENABLE);
}
void SendSPI_Lora(unsigned short val, unsigned char status)
{
SPI_I2S_SendData(SPI2, val);
while(SPI_I2S_GetITStatus(SPI2, SPI_I2S_FLAG_TXE)==SET);
SPI_I2S_ClearFlag(SPI2, SPI_I2S_FLAG_TXE);
}
void AccessSPI(unsigned char Cmd, unsigned short *ptrBuff, unsigned char Operation)
{
unsigned short m, temp;
NSS_LO_LoRa;
SendSPI_Lora(Cmd, kWriteSPI); // Send Command
if (Operation==kWriteSPI)
{
temp=*ptrBuff;
SendSPI_Lora(temp, Operation);
}
else
{
RxIdx=0;
SendSPI_Lora(0, Operation);
ptrBuff = RxSPIBuff;
}
Delay(2);
NSS_HI_LoRa;
}
// Main Sequence
void test(void)
{
unsigned char statusLoRa,buff,irqFlags,newData,newOpMode;
unsigned char size = 0;
AccessSPI(R_REGISTER|RegVersion, &newOpMode, kReadSPI);
}
Pict 1. Write signal in MOSI pin
Pict 2. Read Signal in MISO pin
I think my problem is about delay to receive data after transmit data with SPI. But i cannot solve this problem because i should transmit data to receive. Is there any solution for this?
Upvotes: 2
Views: 2041
Reputation: 891
SPI_I2S_GetFlagStatus
instead of SPI_I2S_GetITStatus
while(SPI_I2S_GetITStatus(SPI2, SPI_I2S_FLAG_TXE)==SET);
is an error. Reference manual for STM32F103, page 710:
The TXE flag (Tx buffer empty) is set when the data are transferred from the Tx buffer to the shift register. It indicates that the internal Tx buffer is ready to be loaded with the next data.
So it should be while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE)==RESET);
With RXNE interrupt you will be sending to USART also after sending the first byte (the register addess)
Here is a CMSIS code for similar transmission ("First cycle is to write address and second cycle is for read/write register.", but without using interrupts, and using STM32F4 with SPI configured as follows:
//af5, afrl
GPIOB->AFR[0] |= ( GPIO_AFRL_AFSEL3_2 | GPIO_AFRL_AFSEL3_0 |
GPIO_AFRL_AFSEL5_2 | GPIO_AFRL_AFSEL5_0 );
GPIOA->AFR[0] |= ( GPIO_AFRL_AFSEL6_2 | GPIO_AFRL_AFSEL6_0 );
//B3 SCK
//A6 MISO
//B5 MOSI
//B6 SS
GPIOA->MODER |= ( GPIO_MODER_MODE6_1 );
GPIOB->MODER |= ( GPIO_MODER_MODE3_1 |
GPIO_MODER_MODE5_1 |
GPIO_MODER_MODE6_0 ); //alternate, 6 output
GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPD6_Msk ); // no pull
GPIOB->PUPDR |= GPIO_PUPDR_PUPD3_1;
Are you using a Nano board? If so into which connector did you plug your MISO? I've spent a week once because I have plugged it into Arduino connector that was connected to some other peripheral instead of Morpho connector.
Upvotes: 1