2017-08-30 11:32 AM
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 #stm32f72017-08-30 11:58 AM
>>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?
2017-08-30 02:41 PM
,
,
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?
2017-08-30 03:40 PM
>>
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.
2017-08-31 12:00 PM
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,
2017-11-08 05:45 AM
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() andXbee_hasData. How can they be called?
Look farward to hearing from you and see more of your code if possible.
Best regards,
Hailing
2017-11-09 05:56 AM
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=false2017-11-09 01:21 PM
Here is an interesting link
, i will give it a try2018-02-05 09:39 AM
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
2018-02-06 08:57 AM
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.