cancel
Showing results for 
Search instead for 
Did you mean: 

Xbee STM32F4/7 USRT DMA

Grozea.Ion
Associate II
Posted on August 30, 2017 at 20:32

Hi,

When using normal transmit on UART i can send a message from a router to a coordinator without no issue

HAL_UART_Transmit(&huart2, (uint8_t*)xFrame, sLen,100);

, but when i try to send it using 

HAL_UART_Transmit_DMA(&huart2, (uint8_t*)xFrame, sLen);

{

_Error_Handler(__FILE__, __LINE__);

}

while (xUartReady != SET)

{

}

xUartReady = RESET;

The 

xUartReady is handled in the callback function.

Did any of you had this issue? How it was solved?

#stm32f4 #uart-dma #xbee #stm32f7
11 REPLIES 11
Posted on August 30, 2017 at 20:58

>>The 

xUartReady is handled in the callback function.

Ok, but you don't show that code or the definition of xUartReady. Is it volatile? Do you do anything in the callback?

>>Did any of you had this issue? How it was solved?

What issue specifically, bit light on detail and context here? Why bother to use DMA if you're just going to block?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on August 30, 2017 at 21:41

 ,

 ,

Hello Clive,

below is the code

The UART DMA code

♯ include 'usart.h'

UART_HandleTypeDef huart2,

 ,

DMA_HandleTypeDef hdma_usart2_rx,

 ,

DMA_HandleTypeDef hdma_usart2_tx,

__IO ITStatus xUartReady,

volatile uint8_t xRxBuff[x_Buff_Size],

 ,

volatile uint8_t xTxBuff[x_Buff_Size],

♯ define x_headPtr ((x_Buff_Size - huart2.hdmarx->,Instance->,NDTR) &, x_Buff_Size1)

 ,

static uint32_t x_tailPtr,

void myUART_Init(void)

 ,

{

 ,

huart2.Instance = USART2,

 ,

huart2.Init.BaudRate = 115200,

 ,

huart2.Init.WordLength = UART_WORDLENGTH_8B,

 ,

huart2.Init.StopBits = UART_STOPBITS_1,

 ,

huart2.Init.Parity = UART_PARITY_NONE,

 ,

huart2.Init.Mode = UART_MODE_TX_RX,

 ,

huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE,

 ,

huart2.Init.OverSampling = UART_OVERSAMPLING_16,

 ,

HAL_UART_DeInit(&,huart2),

 ,

HAL_UART_Init(&,huart2),

 ,

 ,

}

void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)

 ,

{

 ,

GPIO_InitTypeDef GPIO_InitStruct,

 ,

__HAL_RCC_USART2_CLK_ENABLE(),

 ,

GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3,

 ,

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP,

 ,

GPIO_InitStruct.Pull = GPIO_PULLUP,

 ,

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH,

 ,

GPIO_InitStruct.Alternate = GPIO_AF7_USART2,

 ,

HAL_GPIO_Init(GPIOA, &,GPIO_InitStruct),

 ,

/* USART2 DMA Init */

 ,

/* USART2_RX Init */

 ,

hdma_usart2_rx.Instance = DMA1_Stream5,

 ,

hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4,

 ,

hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY,

 ,

hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE,

 ,

hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE,

 ,

hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE,

 ,

hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE,

 ,

hdma_usart2_rx.Init.Mode = DMA_CIRCULAR,

 ,

hdma_usart2_rx.Init.Priority = DMA_PRIORITY_LOW,

 ,

hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE,

 ,

HAL_DMA_Init(&,hdma_usart2_rx),

 ,

__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart2_rx),

 ,

/* USART2_TX Init */

 ,

hdma_usart2_tx.Instance = DMA1_Stream6,

 ,

hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4,

 ,

hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH,

 ,

hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE,

 ,

hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE,

 ,

hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE,

 ,

hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE,

 ,

hdma_usart2_tx.Init.Mode = DMA_NORMAL,

 ,

hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW,

 ,

hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE,

 ,

HAL_DMA_Init(&,hdma_usart2_tx),

 ,

__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart2_tx),

 ,

/* USART2 interrupt Init */

 ,

HAL_NVIC_SetPriority(USART2_IRQn, 0, 0),

 ,

HAL_NVIC_EnableIRQ(USART2_IRQn),

 ,

}

void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)

 ,

{

 ,

__HAL_RCC_USART2_CLK_DISABLE(),

 ,

HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3),

 ,

HAL_DMA_DeInit(uartHandle->,hdmarx),

 ,

HAL_DMA_DeInit(uartHandle->,hdmatx),

 ,

HAL_NVIC_DisableIRQ(USART2_IRQn),

 ,

}

/* Set transmission flag: trasfer complete*/

 ,

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

 ,

{

 ,

xUartReady = SET,

 ,

}

/* Set transmission flag: trasfer complete*/

 ,

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)

 ,

{

 ,

xUartReady = SET,

 ,

}

void Xbee_Init(void){

 ,

__HAL_UART_FLUSH_DRREGISTER(&,huart2),

 ,

if(HAL_UART_Receive_DMA(&,huart2, (uint8_t *)xRxBuff, x_Buff_Size) != HAL_OK)

 ,

{

 ,

_Error_Handler(__FILE__, __LINE__),

 ,

}

 ,

xUartReady = SET,

 ,

}

uint8_t Xbee_hasData(void) {

 ,

if(x_tailPtr == x_headPtr) {

 ,

return 0,

 ,

}

 ,

return 1,

 ,

}

uint8_t Xbee_Read(void) {

 ,

// if is not needed because we must use Xbee_hasData first

 ,

// uint8_t x = 0,

 ,

// if(x_tailPtr != x_headPtr) {

 ,

uint8_t x = xRxBuff[x_tailPtr++],

 ,

x_tailPtr &,= x_Buff_Size1,

 ,

// }

 ,

return x,

 ,

}

The send function

void xBee_sendData(uint8_t mLen)

 ,

{

 ,

uint8_t c = 0,// counter

 ,

uint8_t cSum = 0,//check sum for messege

 ,

uint8_t sLen = 18 + mLen,// length of the message to send

 ,

uint8_t xFrame[sLen],//the message to send to coordinator

 ,

//0x7E, 0x00, 0x00, 0x10, 0x01, 0x00, 0x13, 0xA2, 0x00, 0x40, 0xBD, 0xEC, 0x72, 0xFF, 0xFE, 0x00, 0x00

 ,

//7E 00 12 10 01 00 13 A2 00 40 BD EC 72 FF FE 00 00 74 65 73 74 21

 ,

xFrame[0] = START_BYTE,

 ,

xFrame[1] = 0x00,//first byte of msg length

 ,

xFrame[2] = sLen - 4,//second byte of msg length

 ,

xFrame[3] = 0x10,//Frame type

 ,

xFrame[4] = 0x01,//Frame ID

 ,

for(c = 0, c <, 8, c++)

 ,

xFrame[5+c] = addrCoord[c],//

 ,

xFrame[13] = 0xFF,//Send to all

 ,

xFrame[14] = 0xFE,//Send to all

 ,

xFrame[15] = 0x00,//Broadcast radius

 ,

xFrame[16] = 0x00,//Option byte

 ,

for(c = 0, c <, (mLen), c++)

 ,

xFrame[17 + c] = xOutMsg[c],

 ,

 ,

for(c = 3, c <, (xFrame[2] + 3), c++)

 ,

{

 ,

cSum += xFrame[c],

 ,

printf('%d->,%02x \n', c,xFrame[c]),

 ,

}

 ,

xFrame[sLen-1] = 255-cSum,

 ,

for(c = 0, c <, sLen, c++)

 ,

printf('%d->,%02x ', c,xFrame[c]),

 ,

printf('\n'),

 ,

//the actual transmission

 ,

// HAL_UART_Transmit(&,huart2, (uint8_t*)xFrame, sLen,100), //<,-using this way it works

//using the one below doesnt work

 ,

HAL_UART_Transmit_DMA(&,huart2, (uint8_t*)xFrame, sLen),

 ,

{

 ,

_Error_Handler(__FILE__, __LINE__),

 ,

}

 ,

while (xUartReady != SET)

 ,

{

 ,

}

 ,

xUartReady = RESET,

 ,

}

and in main i have

xOutMsg[0] = 't',

 ,

xOutMsg[1] = 'e',

 ,

xOutMsg[2] = 's',

 ,

xOutMsg[3] = 't',

 ,

while (1)

 ,

{

HAL_Delay(30),

 ,

xBee_sendData(4),

}

PS: is it just my browser or the format code on the forum is not working?

Posted on August 30, 2017 at 22:40

>>

PS: is it just my browser or the format code on the forum is not working?

You have to click on the thread title to get the option, the 'In Box view' doesn't provide it. Using the tool also automatically places the post into moderation so someone at ST has to check it.

 

Does the DMA flag an error? Does it hit the call back? Do you enable the NVIC and interrupts for the DMA controller?

I would generally refrain from using the same flag in two interrupts. And would make sure it was clear prior to sending the command that would set it.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on August 31, 2017 at 19:00

Hello Clive,

I have changed __IO ITStatus to volatile uint8_t xRxReady, xTxReady;

The NVIC/Interrupts are OK, no error on DMA, the callback is called every time.

I have noticed while debugging that the messages are sent, so i added a small delay after transmission and is working.

while (xTxReady != SET)

{

printf('*\n');

}

//HAL_UART_Transmit(&huart2, (uint8_t*)xFrame, sLen,100);

xTxReady = RESET;

if(HAL_UART_Transmit_DMA(&huart2, (uint8_t*)xFrame, sLen) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

//HAL_Delay(1);

I have connected a serial-usb directly to Xbee pins and i am seeing the message getting to Xbee with or without delay (also by using the code without your suggestions implemented).

My best guess is that it has something to do with the Xbee MCU, however it doesn't make sense to me the added delay after transmission command, the 1ms should be compensated by changing the delay in the main loop...

Any idea what else can be wrong?

BR,

Hailing SKY
Associate II
Posted on November 08, 2017 at 14:45

Dear Grozea,

Have you addressed those issues? I am new to STM32F4 and XBee, but I have a project going on with these unites. I would like to know if you can share more of your code if possbile. I saw your code above. There are something I am still confusing. For example, you have functions for receiving data, namely 

Xbee_Read() and 

Xbee_hasData. How can they be called?

Look farward to hearing from you and see more of your code if possible.

Best regards,

Hailing 

Posted on November 09, 2017 at 13:56

have a look at the attached files, this project is still work in progress because i have issues with a 746 Disco and UART

________________

Attachments :

RemoteSensorF4.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyJS&d=%2Fa%2F0X0000000b5u%2FecqYwIK_ZVDtR8znMDcxQVV.qMQW9frOi9Ktu0uPIXQ&asPdf=false
Posted on November 09, 2017 at 21:21

Here is an interesting link

https://community.st.com/0D50X00009XkW2nSAF

, i will give it a try

Posted on February 05, 2018 at 17:39

Dear Grozea,

I am currently working on STM32L4+Xbee Module. I would like to know if I can use a coordinator to wake up an end device and the MCU connected to the end device. Basically, the coordinator will send a request to the end device; after the end device receive the message, the end device will generate an interrupt to wake the MCU up. This is the idea. Do you think if I can do this? If so which mode or pins, do I need to use? Please let me know if you have any idea.

Thank,

Hai

Posted on February 06, 2018 at 16:57

Hi,

I have looked into DM00148033.pdf page 12, here they state that from Sleep mode you can use 'Any interrupt or event'.

Using STM32CubeMx you can see the pins that are supporting external interrupts as GPIO_EXTIxx,where xx is the interrupt.

You can also use the UART as a wakeup, look in the pdf.