cancel
Showing results for 
Search instead for 
Did you mean: 

How to check for Rx/TX Errors using DS3231?

DGood.2
Associate II

This is my first STM32 project, I have little experience with the CubeIDE or STM32. I am trying to move over from doing all of my previous projects on Arduino.

I have got the DS3231 working using the STM32CubeIDE. Board = Nucleo 144 - F413ZH.

I am reading the time, that I set, and I am printing it to the serial monitor using UART.

I am using the following to read and when required, write to the DS3231:

#define DS3231_ADDRESS 0xD0

HAL_I2C_Mem_Write(&hi2c1, DS3231_ADDRESS, 0x00, 1, setArray, 7, 1000);

HAL_I2C_Mem_Read(&hi2c1, DS3231_ADDRESS, 0x00, 1, getArray, 7, 1000);

As you might see, I have just got two functions called set and get time that include these lines.

However, I would like to understand how to use the HAL_StatusTypeDef to check if there are any errors on the I2C lines. Similar to what is implemented in DigiKeys video on youtube titled "Getting Started With STM32 and Nucleo Part 2". But I cannot understand how to implement it with the DS3231.

I have tried similar implementations of the following but cannot get it working:

ret = HAL_I2C_Master_Transmit(hi2c, DevAddress, pData, Size, Timeout)

ret = HAL_I2C_Master_Receive(hi2c, DevAddress, pData, Size, Timeout)

The goal is to print out "Rx Error" or "Tx Error" if the corresponding SDA or SDL line is disconnected.

1 ACCEPTED SOLUTION

Accepted Solutions

>  how do you know it is only success/error/timeout

Because enum HAL_StatusTypeDef only has the following values: HAL_OK, HAL_ERROR, HAL_BUSY, HAL_TIMEOUT

https://github.com/STMicroelectronics/stm32f4xx_hal_driver/blob/c91c4a744c5bcf881c5172a4f064bbc5eb7a5e39/Inc/stm32f4xx_hal_def.h#L39

>if (return != success) {

​>Print Tx/Rx Error on UART;

>​}​

if (return != HAL_OK) {
  printf("i2c error = %#X\n", hi2c1.ErrorCode);
}

View solution in original post

4 REPLIES 4
Pavel A.
Evangelist III

The return value of HAL_I2C_Mem_Write/Read is only success/error/timeout.

Details are returned in hi2c1.ErrorCode. It is a bit mask.

https://github.com/STMicroelectronics/stm32f4xx_hal_driver/blob/c91c4a744c5bcf881c5172a4f064bbc5eb7a5e39/Inc/stm32f4xx_hal_i2c.h#L165

Thank you for the post.

Correct me if I am wrong please, but with this info, could I do something similar to the following:

return = HAL_I2C_Mem_Write/Read;

if (return != success) {

Print Tx/Rx Error on UART;

}​

​On an educational point, how do you know it is only success/error/timeout please? I can see the HAL_I2C_ERROR bitmask; from no error through to DMA parameter. But I cant see why this isnt HAL_OK?

>  how do you know it is only success/error/timeout

Because enum HAL_StatusTypeDef only has the following values: HAL_OK, HAL_ERROR, HAL_BUSY, HAL_TIMEOUT

https://github.com/STMicroelectronics/stm32f4xx_hal_driver/blob/c91c4a744c5bcf881c5172a4f064bbc5eb7a5e39/Inc/stm32f4xx_hal_def.h#L39

>if (return != success) {

​>Print Tx/Rx Error on UART;

>​}​

if (return != HAL_OK) {
  printf("i2c error = %#X\n", hi2c1.ErrorCode);
}

Thank you for the help Pavel. I understand now.

I implemented the following and it works:

ret = HAL_I2C_Mem_Read(&hi2c1, DS3231_ADDRESS, 0x00, 1, getArray, 7, 1000);

if (ret != HAL_OK) {

sprintf((char*)testBuf, "I2C Rx Error = %lu\r\n", hi2c1.ErrorCode);

HAL_UART_Transmit(&huart3, testBuf, strlen((char*)testBuf), HAL_MAX_DELAY);

}

Removing the SDL and SDA lines both produces a Rx error, as I am not 100% how the DS3231 is being read I guess.

In Digikey's video the temp sensor requires a transmit before each read, but the DS3231 doesn't.

My transmit code produces the Tx error when I do the write so I can see any Tx errors when I go to write, so I think its okay:

ret = HAL_I2C_Mem_Write(&hi2c1, DS3231_ADDRESS, 0x00, 1, setArray, 7, 1000);

if (ret != HAL_OK) {

sprintf((char*)testBuf, "I2C Tx Error = %lu\r\n", hi2c1.ErrorCode);

HAL_UART_Transmit(&huart3, testBuf, strlen((char*)testBuf), HAL_MAX_DELAY);

}

Thanks again!