2023-02-21 11:36 AM
I'm trying to configure and collect data from a BNO055 IMU over UART/RS232, using an STM32L552ZET6Q. The BNO055 is on a remote board, connected via cable to the STM32L5 microcontroller. Additionally, I am using a MAX3232CUE+T on either side of the cable to convert the signal from UART to RS232 and back again.
Unfortunately, I am running into a problem, where when I try to read data from the BNO055, the UART doesn't seem to pick it up. I checked with a logic analyzer and I can confirm that the BNO055 is responding as expected, but the STM32 doesn't seem to realize that anything has arrived. I set the wait time for HAL_UART_RECEIVE to HAL_MAX_DELAY, and it just waits forever.
In the below picture, a request is sent for the BNO055's id (0xA0). This command is composed of a start byte (0xAA), Read or Write (0x01 for read), What is being read (0x00) and how many bytes of data the BNO055 should send back (1, 0x01).
The response back from the BNO055 is success (0xBB), length of the data (0x01) and the data (0xA0).
I took this capture very close to the STM32 UART GPIO, so I can be reasonably confident that the transmission reached the other side successfully, and the BNO055 successfully interpreted the command and responded appropriately. However, the STM32 doesn't seem to have realized that anything has arrived.
Here's the function that corresponds to the above image, specifically the uartRead line:
void BNO055_beginUART(bno055_uart *chip)
{
uint8_t val = 0x00;
bno055_resetUART(chip);
uint8_t id[3];
uartRead(chip, BNO055_CHIP_ID, 1, id);
if (id[2] != BNO055_ID) {
printf("Can't find BNO055, id: 0x%02x. Please check your wiring.\r\n", id[2]);
}
bno055_setPageUart(chip, 0);
// Select BNO055 config mode
bno055_setOperationModeConfigUART(chip);
uartWrite(chip, BNO055_SYS_TRIGGER, 1, &val);
bno055_delay(10);
}
And here's uartRead:
void uartRead(bno055_uart *chip, uint8_t reg, uint8_t len, uint8_t *data)
{
uint8_t status;
uint8_t transmit_buf[128] = {0xAA, 0x01, reg, len};
uint8_t receive_buf[128];
status = HAL_UART_Transmit(&chip->uart_bus, transmit_buf, 4, 50);
if(status != HAL_OK)
{
printf("ERROR: %d", status);
return;
}
//bno055_delay(10);
status = HAL_UART_Receive(&chip->uart_bus, receive_buf, (len+2), 5000);
if(status != HAL_OK)
{
printf("ERROR: %d", status);
return;
}
if(receive_buf[0] != 0xBB)
{
switch(data[1])
{
case 0x02:
printf("Read Failure");
break;
case 0x04:
printf("Register Map Invalid Address");
break;
case 0x05:
printf("Register Map Write Disabled");
break;
case 0x06:
printf("Wrong Start Byte");
break;
case 0x07:
printf("Bus over run error");
break;
case 0x08:
printf("Max length error");
break;
case 0x09:
printf("Min length error");
break;
case 0x0A:
printf("receive character timeout");
}
}
}
This is the current configuration I have for UART4, which I am using to try to communicate with the BNO055.
edit: Include datasheet and UART application notes for BN055
https://cdn-shop.adafruit.com/datasheets/BST_BNO055_DS000_12.pdf
2023-02-21 02:07 PM
Show your code when transmitting and waiting for a response from the device.
2023-02-21 05:22 PM
Check the pin configurations, at the GPIO
Make sure the UART isn't blocking reception due to a sticky error like noise, parity, etc.
2023-02-22 06:52 AM
I got the code you asked for in the main question now. Sorry I forgot to include it before.
I'm using polling right now, but I'm wondering if I should switch to interrupt or DMA instead. I thought I'd stick with polling for now to get to grips with the setup, then switch to IT or DMA after I had polling working.
2023-02-22 06:53 AM
How would I confirm that?
2023-02-22 07:01 AM
I'd use the debugger and inspect the RCC, GPIO and UART registers directly
Errors presumably flagging in UART->SR or iSR
2023-02-22 07:12 AM
Thanks for the pointers. Wait, I just remembered something. I can't remember where, but I think I saw something regarding UART RX errors throwing an interrupt. Does that sound familiar?
edit: Wow, I'm out of it. I just saw the isr stuff in your comment...
2023-02-22 07:47 AM
Is this the area you were talking about? I was also poking around in the Register and SFR sections, but I'm not well-versed enough to notice when something is amiss. It didn't look like any errors were getting thrown. By all accounts, it's just using HAL_MAX_DELAY and running forever, looping inside the UART_WaitOnFlagUntilTimeout() function.
2023-02-22 08:05 AM
Hi @ESpra.1
You could check in your huart->Instance->ISR if ORE bit is set or not. If set, this indicates Overrun error has been detected.
ORE bit set is preventing further reception. In order to have Reception active again,you should clear this flag, by writing corresponding bit in ICR.
Just in case ...
2023-02-22 08:16 AM
I'll look into that. For now though, this is what I'm seeing