Question
Problems porting mbed project to SPL
Posted on October 27, 2016 at 09:10
Hello,
I ported the microchip MiWi stack to STM32(NucleoL152RE) initaly using the mbed hardware librarys. I do not use the mbed compiler, but rather imported it into EmBitz and use the arm-none-eabi-gcc/g++ compilers. The MRF24J40 RF-module is connected to the SPI connections on the Nucleo board. This worked. But as the mbed-os is too locked down and the underlying HAL has virtually no documentation I switched to the SPL, therefore created a new project in EmBitz. The MiWi stack only has very little interface to the hardware, I just adapted the SPI communication, pin interrupt and a symbol timer. But the implementation with the SPL does not work, as in there is no communication to other Nodes of the network. So far I checked various thing, compiler and linker settings, linker scripts, #defines, diffed some files, but the problem persists. So, where is my problem? This is the code to initalise the hardware, SPI on GPIOA 5-7, interrupt on GPIOC 7, CS at GPIOB6 and Reset at GPIO9
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_5;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOA, &GPIO_InitStructure);
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_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_ResetBits(GPIOA, GPIO_Pin_9);
//Set Wake high
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ToggleBits(GPIOB, GPIO_Pin_5);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource7);
EXTI_InitStructure.EXTI_Line = EXTI_Line7;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x10;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//EXTI_GenerateSWInterrupt(EXTI_Line7);
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI1, &SPI_InitStructure);
SPI_CalculateCRC(SPI1, DISABLE);
SPI_Cmd(SPI1, ENABLE);
The code to read and write SPI data:
1.
uint8_t SendSPIData(uint8_t data)
2.
{
3.
//Wait for the data register to be empty
4.
while
(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
5.
SPI_I2S_SendData(SPI1,data);
6.
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
7.
return
SPI_I2S_ReceiveData(SPI1);
8.
}
Init Symbol Timer, 16µs per Tick
MIWI_TICK ticks;
void
InitSymbolTimer(
void
)
{
ticks.Val = 0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
TIM_TimeBaseInitTypeDef TIM_InitStructure;
TIM_TimeBaseStructInit(&TIM_InitStructure);
TIM_DeInit(TIM5);
TIM_InitStructure.TIM_Prescaler = 512;
//16 * (SystemCoreClock / 1000000);
TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_InitStructure.TIM_Period = 0xffffffff;
TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM5, &TIM_InitStructure);
TIM_Cmd(TIM5, ENABLE);
} Within the code I execute the EXTI interrupt
1.
EXTI_GenerateSWInterrupt(EXTI_Line7);
To communicate with the module:
uint8_t MRF24J40_Handler::PHYGetLongRAMAddr(INPUT uint16_t address)
{
uint8_t toReturn;
EXTI->IMR &= ~EXTI_Line7;
GPIO_ResetBits(GPIOB, GPIO_Pin_6);
wait_us(1);
SendSPIData(((address >> 3)&0x7F) | 0x80);
// MCC_SPI
SendSPIData(((address << 5)&0xE0));
// MCC_SPI
toReturn = ReadSPIData(0x00);
// MCC_SPI
while
(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == 1);
wait_us(1);
GPIO_SetBits(GPIOB, GPIO_Pin_6);
EXTI->IMR |= EXTI_Line7;
return
toReturn;
}