2021-09-24 04:04 AM
I am trying USART communication with using DMA. Code written with HAL library is working on STM32F0 but it doesn't work on L0. I am getting irrelevant data at terminal.
Also HAL_UARTEx_RxEventCallback function can called on F0 but not on L0.
Here is the some of my code.
Where I am wrong ?
/* USER CODE BEGIN PV */
#define RxBuf_SIZE 10
#define MainBuf_SIZE 10
char TxBuffer[4]={0x12,0x34,0x56,0x78};
uint8_t RxBuffer[RxBuf_SIZE],MainBuf[MainBuf_SIZE];
char str[24];
int sayi=0;
uint16_t oldPos = 0;
uint16_t newPos = 0;
int isOK = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
{
__NOP();
}
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
oldPos = newPos; // Update the last position before copying new data
/* If the data in large and it is about to exceed the buffer size, we have to route it to the start of the buffer
* This is to maintain the circular buffer
* The old data in the main buffer will be overlapped
*/
if (oldPos+Size > MainBuf_SIZE) // If the current position + new data size is greater than the main buffer
{
uint16_t datatocopy = MainBuf_SIZE-oldPos; // find out how much space is left in the main buffer
memcpy ((uint8_t *)MainBuf+oldPos, RxBuffer, datatocopy); // copy data in that remaining space
oldPos = 0; // point to the start of the buffer
memcpy ((uint8_t *)MainBuf, (uint8_t *)RxBuffer+datatocopy, (Size-datatocopy)); // copy the remaining data
newPos = (Size-datatocopy); // update the position
}
/* if the current position + new data size is less than the main buffer
* we will simply copy the data into the buffer and update the position
*/
else
{
memcpy ((uint8_t *)MainBuf+oldPos, RxBuffer, Size);
newPos = Size+oldPos;
}
for(int i=Size;i<RxBuf_SIZE;i++)
RxBuffer[i]=0;
/* start the DMA again */
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, (uint8_t *) RxBuffer, RxBuf_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
}
/* USER CODE BEGIN 2 */
HAL_UART_Transmit_DMA(&huart1,(uint8_t*)TxBuffer,sizeof(TxBuffer));
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuffer, RxBuf_SIZE);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_UART_Transmit_DMA(&huart1,(uint8_t*)TxBuffer,sizeof(TxBuffer));
HAL_Delay(20);
}
/* USER CODE END 3 */
Solved! Go to Solution.
2021-09-24 07:01 AM
> i send 0x77 from terminal, STM take 0x44. Terminal send 0x7F, STM take 0x40
This sounds like inverted signal.
Do you use any level converters, different between the 'F0 and 'L0 cases?
If not, read out and compare USART_CR2.RXINV bit.
JW
2021-09-24 05:40 AM
> I am getting irrelevant data at terminal.
Incorrectly set baudrate, maybe consequence of incorrectly set system clock (or incorrectly set constant which in Cube determines crystal frequency, I don't use Cube don't know how it's called/set).
Observe Tx pin using oscilloscope/logic analyzer. Try to switch baudrate on receiver.
Problem with Rx is probably of the same nature, incorrect baudrate resulting in framing etc. errors.
JW
2021-09-24 06:04 AM
Baudrate is same. Actually everything is same. Code works on STM32F051K6T6, STM32F091RCT, STM32F072RB but it doesn't work on STM32L072RB.
Actually data that got, it's not irrelevant. For example i send 0x77 from terminal, STM take 0x44. Terminal send 0x7F, STM take 0x40.
I must change MCU F to L series (Because Standart Peripheral Library is not working on L0 series) . If i can't , project will cancelled.
2021-09-24 07:01 AM
> i send 0x77 from terminal, STM take 0x44. Terminal send 0x7F, STM take 0x40
This sounds like inverted signal.
Do you use any level converters, different between the 'F0 and 'L0 cases?
If not, read out and compare USART_CR2.RXINV bit.
JW
2021-09-24 11:19 AM
Call HAL_UARTEx_ReceiveToIdle_DMA prior to HAL_UART_Transmit_DMA. Wait long enough between transmissions for the stream to go idle. 20ms may not be enough for your unspecified data rate.
2021-09-25 05:30 AM
Thank you JW. I fixed it. All thins about TX&RX Active Level inversion settings. Thank you so much.