cancel
Showing results for 
Search instead for 
Did you mean: 

Problems porting mbed project to SPL

cloidnerux
Associate
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;

}

2 REPLIES 2
Amel NASRI
ST Employee
Posted on October 27, 2016 at 09:50

Hi hebeler.jochen,

Please note that HAL drivers are used in mbed, so there is no way to port mbed project to SPL. In this case, you need to create your own project based on SPL.

As it seems this what you did, I recommend you to debug your project and try to identify where is it sticking.

Then I would like to know what do you mean by ''HAL has virtually no documentation''. From my side I don't agree that there is no HAL documentation. Besides to what you have as documentation in the Cube package, you find user manuals in

http://www.st.com/content/st_com/en/products/embedded-software/mcus-embedded-software/stm32-embedded-software/stm32cube-embedded-software/stm32cubel1.html

.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

cloidnerux
Associate
Posted on October 27, 2016 at 13:06

Hello,

yes, as I mentioned already, I ported all the function from the mbed and HAL drivers to the SPL. 

I find it hard to debug at the moment, as there is no clear fault, besides the fact that only the hardware access changed, while the complete stack remains the same, yet it somehow is different. Also debugging in system is not that easy, as the debugging slows the execution down to a point where timing errors with the MRF24J40 occure.

To the documentation of HAL/mbed: Yes, there are examples and documentation, but they are mostly limited to the most basic stuff. Doing something with multiple peripherals and DMA, changing configuration in an interrupt or using the full potential of a hardware module are rarely documented.