H753_CPP_I2C_DS3231_RTC_01 1.0
STM32H753 DS3231 real-time clock over I2C, with an AT24C32 EEPROM marker that stops the clock being set twice, built on the STM32_DS3231 and STM32_AT24C32 libraries
Loading...
Searching...
No Matches
AT24C32.h File Reference

Types, constants and function prototypes of the STM32_AT24C32 driver. More...

#include "main.h"
#include <stdint.h>

Go to the source code of this file.

Data Structures

struct  AT24C32_t
 

Macros

#define AT24C32_SIZE_BYTES   4096U
 
#define AT24C32_PAGE_SIZE   32U
 
#define AT24C32_MAX_ADDRESS_PINS   7U
 
#define AT24C32_DEFAULT_MAX_ATTEMPTS   3U
 
#define AT24C32_I2C_TIMEOUT_MS   100U
 
#define AT24C32_WRITE_TIMEOUT_MS   20U
 

Enumerations

enum  AT24C32_Status_t { AT24C32_OK = 0 , AT24C32_ERR_PARAM , AT24C32_ERR_NOT_FOUND , AT24C32_ERR_BUS }
 

Functions

AT24C32_Status_t at24c32Init (AT24C32_t *dev, I2C_HandleTypeDef *hi2c, uint8_t addressPins, uint8_t maxAttempts)
 Set up a driver handle and check that an AT24C32 answers on the bus.
 
AT24C32_Status_t at24c32Read (AT24C32_t *dev, uint16_t memAddress, uint8_t *data, uint16_t length)
 Read bytes from the memory.
 
AT24C32_Status_t at24c32Write (AT24C32_t *dev, uint16_t memAddress, const uint8_t *data, uint16_t length)
 Write bytes to the memory.
 

Detailed Description

Types, constants and function prototypes of the STM32_AT24C32 driver.

Every function is documented where it is defined, in AT24C32.c.

Error handling
A failed HAL I2C read or write is something the program cannot continue from, but only some failures are worth retrying. A transient communication failure (HAL_BUSY, HAL_TIMEOUT, or HAL_ERROR with an I2C error code for a bus problem: bus error, arbitration lost, acknowledge failure, overrun or timeout) is retried: the complete transaction is sent again, up to AT24C32_t::maxAttempts times in all. Retrying is safe here because writing the same bytes to the same address twice gives the same result. Any other failure, such as HAL_ERROR from a bad parameter or a peripheral in the wrong state, cannot be fixed by trying again and is not retried. A write cycle that does not finish within AT24C32_WRITE_TIMEOUT_MS is also a failure. Once the attempts are used up, or at once for a failure that is not retried, the driver calls Error_Handler() from main.h, which does not return. AT24C32_t::lastStatus holds the HAL status of the most recent failed attempt.

Problems that are the caller's to handle are returned as an AT24C32_Status_t instead: a bad argument, an address range that runs past the end of the memory, and a chip that does not answer in at24c32Init().

Wiring
On the ZS-042 module the EEPROM shares SCL and SDA with the DS3231, and its address pins A0 to A2 are pulled up to VCC, so the chip answers at 0x57 (pass addressPins = 7 to at24c32Init()). Bridging the module's A0, A1 and A2 solder pads ties the corresponding pin to ground and changes the address. The write-protect pin is tied to ground on the module, so writes are always enabled.
Warning
Power the ZS-042 from 3.3 V, not 5 V: at 5 V the module's battery charging circuit pushes current into a non-rechargeable CR2032, and its pull-ups put 5 V on SCL and SDA. See the STM32_DS3231 documentation for the details. The AT24C32 works from 3.3 V.
Thread safety and ISR safety
Not thread-safe and not ISR-safe. A write is several blocking HAL I2C transactions in a row (one per page, each followed by acknowledge polling) on a peripheral handle that other code may share, with no lock. A second caller (another RTOS task, or an interrupt handler) that uses the same I2C peripheral between those steps would interleave with this driver and corrupt both transfers. Call the driver from one context, or put a mutex around every use of the shared I2C handle. Do not call it from an interrupt handler: the HAL calls block and the write wait polls HAL_GetTick().
Endurance
The datasheet guarantees about one million write cycles per byte at 25 degrees Celsius. Do not rewrite the same location in a fast loop.

Definition in file AT24C32.h.

Macro Definition Documentation

◆ AT24C32_DEFAULT_MAX_ATTEMPTS

#define AT24C32_DEFAULT_MAX_ATTEMPTS   3U

Number of attempts used when at24c32Init() is given 0 for maxAttempts.

Definition at line 88 of file AT24C32.h.

Referenced by at24c32Init().

◆ AT24C32_I2C_TIMEOUT_MS

#define AT24C32_I2C_TIMEOUT_MS   100U

Timeout, in milliseconds, of one HAL I2C transfer.

Definition at line 91 of file AT24C32.h.

Referenced by at24c32Init().

◆ AT24C32_MAX_ADDRESS_PINS

#define AT24C32_MAX_ADDRESS_PINS   7U

Highest value of the A2 A1 A0 address pins (they select 0x50 to 0x57).

Definition at line 85 of file AT24C32.h.

Referenced by at24c32Init().

◆ AT24C32_PAGE_SIZE

#define AT24C32_PAGE_SIZE   32U

Size of one write page in bytes. A page write never crosses a page boundary.

Definition at line 82 of file AT24C32.h.

Referenced by at24c32Write().

◆ AT24C32_SIZE_BYTES

#define AT24C32_SIZE_BYTES   4096U

Size of the memory in bytes (32 Kbit).

Definition at line 79 of file AT24C32.h.

Referenced by at24c32Read(), and at24c32Write().

◆ AT24C32_WRITE_TIMEOUT_MS

#define AT24C32_WRITE_TIMEOUT_MS   20U

Longest time, in milliseconds, to wait for a page write to finish. The datasheet gives 5 ms maximum (AT24C32D); older AT24C32 revisions give 10 ms.

Definition at line 97 of file AT24C32.h.

Enumeration Type Documentation

◆ AT24C32_Status_t

Result of a driver function.

Enumerator
AT24C32_OK 

The call succeeded.

AT24C32_ERR_PARAM 

A pointer was NULL, or a value or address range was invalid.

AT24C32_ERR_NOT_FOUND 

Nothing answered at the EEPROM address.

AT24C32_ERR_BUS 

An I2C transfer failed for good. Only returned if Error_Handler() returns.

Definition at line 100 of file AT24C32.h.

Function Documentation

◆ at24c32Init()

AT24C32_Status_t at24c32Init ( AT24C32_t * dev,
I2C_HandleTypeDef * hi2c,
uint8_t addressPins,
uint8_t maxAttempts )

Set up a driver handle and check that an AT24C32 answers on the bus.

Call it after MX_I2Cx_Init(). It only checks that something acknowledges the EEPROM address; it does not read or change the memory.

Parameters
devThe handle to fill in.
hi2cThe HAL I2C handle the chip is on, for example &hi2c1.
addressPinsThe level of the chip's A2 A1 A0 pins as a number 0 to 7 (7 on a ZS-042 module, whose address pins are pulled up).
maxAttemptsAttempts per transaction before Error_Handler() is called; 0 selects AT24C32_DEFAULT_MAX_ATTEMPTS.
Returns
AT24C32_OK; AT24C32_ERR_PARAM if dev or hi2c is NULL or addressPins is above 7; AT24C32_ERR_NOT_FOUND if nothing acknowledged the address (AT24C32_t::lastStatus holds the HAL status).

Definition at line 131 of file AT24C32.c.

References AT24C32_DEFAULT_MAX_ATTEMPTS, AT24C32_ERR_NOT_FOUND, AT24C32_ERR_PARAM, AT24C32_I2C_TIMEOUT_MS, AT24C32_MAX_ADDRESS_PINS, AT24C32_OK, at24c32Init(), AT24C32_t::deviceAddress, AT24C32_t::hi2c, AT24C32_t::lastStatus, and AT24C32_t::maxAttempts.

Referenced by at24c32Init(), and main().

◆ at24c32Read()

AT24C32_Status_t at24c32Read ( AT24C32_t * dev,
uint16_t memAddress,
uint8_t * data,
uint16_t length )

Read bytes from the memory.

Uses a random read followed by a sequential read, so one call can read any length. A range that would run past the end of the memory is rejected rather than letting the chip wrap around to address 0.

Parameters
devThe driver handle, set up with at24c32Init().
memAddressFirst address to read, 0 to 4095.
dataReceives the bytes.
lengthNumber of bytes to read.
Returns
AT24C32_OK; AT24C32_ERR_PARAM if a pointer is NULL, length is 0, or the range memAddress to memAddress + length - 1 is not inside 0 to 4095.

Definition at line 166 of file AT24C32.c.

References AT24C32_ERR_PARAM, AT24C32_SIZE_BYTES, and at24c32Read().

Referenced by at24c32Read(), and readClockMarker().

◆ at24c32Write()

AT24C32_Status_t at24c32Write ( AT24C32_t * dev,
uint16_t memAddress,
const uint8_t * data,
uint16_t length )

Write bytes to the memory.

The data is split at page boundaries (32 bytes), because a page write that crosses a boundary wraps around inside the page and overwrites the start of that page. Each page is written, then the function waits for the chip's internal write cycle to finish (acknowledge polling) before the next one, so when the function returns the data is stored. A range that would run past the end of the memory is rejected before anything is written.

Parameters
devThe driver handle, set up with at24c32Init().
memAddressFirst address to write, 0 to 4095.
dataThe bytes to write.
lengthNumber of bytes to write.
Returns
AT24C32_OK; AT24C32_ERR_PARAM if a pointer is NULL, length is 0, or the range memAddress to memAddress + length - 1 is not inside 0 to 4095.

Definition at line 192 of file AT24C32.c.

References AT24C32_ERR_BUS, AT24C32_ERR_PARAM, AT24C32_OK, AT24C32_PAGE_SIZE, AT24C32_SIZE_BYTES, and at24c32Write().

Referenced by at24c32Write(), and writeClockMarker().