diff --git a/bsps/include/libchip/abeoz9-rtc.h b/bsps/include/libchip/abeoz9-rtc.h index 87884709a7..c0e0037ec7 100644 --- a/bsps/include/libchip/abeoz9-rtc.h +++ b/bsps/include/libchip/abeoz9-rtc.h @@ -75,6 +75,7 @@ int abeoz9_rtc_hw_init(struct i2c_rtc_base *base); i2c_path, \ i2c_address, \ 8, \ + I2C_RTC_ORDER_sec_min_hour_day_wkday_month_year, \ "abeoz9", \ abeoz9_rtc_hw_init), \ } diff --git a/bsps/include/libchip/i2c-rtc.h b/bsps/include/libchip/i2c-rtc.h index 6718071f4b..5eeffc8139 100644 --- a/bsps/include/libchip/i2c-rtc.h +++ b/bsps/include/libchip/i2c-rtc.h @@ -54,26 +54,26 @@ extern "C" { * * Expects a register block with the following time format: * - * * +0: + * * +off.second: * * Bit 0 to 6: Seconds (BCD encoded) * * Bit 7: Don't care - * * +1: + * * +off.minute: * * Bit 0 to 6: Minutes (BCD encoded) * * Bit 7: Don't care - * * +2: + * * +off.hour: * * Bit 0 to 5: Hours (BCD encoded); Bit 5 indicates AM (0) and PM (1) in 12 * hour mode * * Bit 6: 0 for 24 hour mode; 1 for 12 hour mode - * * +3: - * * Bit 0 to 5: Day (BCD encoded) - * * Bit 6 and 7: Don't care - * * +4: + * * +off.wkday: * * Bit 0 to 2: Day of Week * * Bit 3 to 7: Don't care - * * +5: + * * +off.day: + * * Bit 0 to 5: Day (BCD encoded) + * * Bit 6 and 7: Don't care + * * +off.month: * * Bit 0 to 4: Month (BCD encoded) * * Bit 5 to 7: Don't care - * * +6: + * * +off.year: * * Bit 0 to 6: Year (BCD encoded) * * Bit 7: Don't care * @@ -115,8 +115,19 @@ struct i2c_rtc_base { */ int (*hw_init) (struct i2c_rtc_base *ctx); - /** Offset of the clock register block. */ + /** Offset of the start of the clock register block. */ size_t clock_offset; + + /** Order of the fields of the date. */ + struct { + size_t year; + size_t month; + size_t wkday; + size_t day; + size_t hour; + size_t min; + size_t sec; + } order; }; /** @@ -135,7 +146,14 @@ int i2c_rtc_read(struct i2c_rtc_base *ctx, uint8_t addr, uint8_t *buf, int i2c_rtc_write(struct i2c_rtc_base *ctx, uint8_t addr, const uint8_t *buf, size_t len); -#define I2C_RTC_INITIALIZER(i2c_path, i2c_address, offset, driver_name, hwinit)\ +#define I2C_RTC_ORDER_sec_min_hour_wkday_day_month_year \ + { .sec = 0, .min = 1, .hour = 2, .day = 4, .wkday = 3, .month = 5, .year = 6 } + +#define I2C_RTC_ORDER_sec_min_hour_day_wkday_month_year \ + { .sec = 0, .min = 1, .hour = 2, .day = 3, .wkday = 4, .month = 5, .year = 6 } + +#define I2C_RTC_INITIALIZER(i2c_path, i2c_address, offset, reg_order, \ + driver_name, hwinit)\ { \ .mutex = RTEMS_MUTEX_INITIALIZER(driver_name), \ .i2c_bus_path = i2c_path, \ @@ -143,6 +161,7 @@ int i2c_rtc_write(struct i2c_rtc_base *ctx, uint8_t addr, const uint8_t *buf, .initialized = false, \ .hw_init = hwinit, \ .clock_offset = offset, \ + .order = reg_order, \ } #define I2C_RTC_TBL_ENTRY(dev_name, i2c_rtc_ctx) \ diff --git a/bsps/include/libchip/mcp7940m-rtc.h b/bsps/include/libchip/mcp7940m-rtc.h index 07461045da..c5b3f79457 100644 --- a/bsps/include/libchip/mcp7940m-rtc.h +++ b/bsps/include/libchip/mcp7940m-rtc.h @@ -78,6 +78,7 @@ int mcp7940m_hw_init(struct i2c_rtc_base *base); i2c_path, \ i2c_address, \ 0, \ + I2C_RTC_ORDER_sec_min_hour_wkday_day_month_year, \ "mcp7940", \ mcp7940m_hw_init), \ .crystal = has_crystal, \ diff --git a/bsps/shared/dev/rtc/i2c-rtc.c b/bsps/shared/dev/rtc/i2c-rtc.c index 8d5ad59872..ce63e6c367 100644 --- a/bsps/shared/dev/rtc/i2c-rtc.c +++ b/bsps/shared/dev/rtc/i2c-rtc.c @@ -43,22 +43,16 @@ #include #include -#define REG_RTCSEC 0x00u - #define RTCSEC_SECBCD_SHIFT 0u #define RTCSEC_SECBCD_MASK (0x7fu << RTCSEC_SECBCD_SHIFT) #define RTCSEC_SECBCD(x) (((x) << RTCSEC_SECBCD_SHIFT) & RTCSEC_SECBCD_MASK) #define RTCSEC_SECBCD_GET(x) (((x) & RTCSEC_SECBCD_MASK) >> RTCSEC_SECBCD_SHIFT) -#define REG_RTCMIN 0x01u - #define RTCMIN_MINBCD_SHIFT 0u #define RTCMIN_MINBCD_MASK (0x7fu << RTCMIN_MINBCD_SHIFT) #define RTCMIN_MINBCD(x) (((x) << RTCMIN_MINBCD_SHIFT) & RTCMIN_MINBCD_MASK) #define RTCMIN_MINBCD_GET(x) (((x) & RTCMIN_MINBCD_MASK) >> RTCMIN_MINBCD_SHIFT) -#define REG_RTCHOUR 0x02u - #define RTCHOUR_HRBCD12_SHIFT 0u #define RTCHOUR_HRBCD12_MASK (0x1fu << RTCHOUR_HRBCD12_SHIFT) #define RTCHOUR_HRBCD12(x) (((x) << RTCHOUR_HRBCD12_SHIFT) & RTCHOUR_HRBCD12_MASK) @@ -72,34 +66,28 @@ #define RTCHOUR_AMPM (0x01u << 5) #define RTCHOUR_1224 (0x01u << 6) -#define REG_RTCWKDAY 0x03u - #define RTCWKDAY_WKDAY_SHIFT 0u #define RTCWKDAY_WKDAY_MASK (0x7u << RTCWKDAY_WKDAY_SHIFT) #define RTCWKDAY_WKDAY(x) (((x) << RTCWKDAY_WKDAY_SHIFT) & RTCWKDAY_WKDAY_MASK) #define RTCWKDAY_WKDAY_GET(x) (((x) & RTCWKDAY_WKDAY_MASK) >> RTCWKDAY_WKDAY_SHIFT) -#define REG_RTCDATE 0x04u - #define RTCDATE_DATEBCD_SHIFT 0u #define RTCDATE_DATEBCD_MASK (0x3fu << RTCDATE_DATEBCD_SHIFT) #define RTCDATE_DATEBCD(x) (((x) << RTCDATE_DATEBCD_SHIFT) & RTCDATE_DATEBCD_MASK) #define RTCDATE_DATEBCD_GET(x) (((x) & RTCDATE_DATEBCD_MASK) >> RTCDATE_DATEBCD_SHIFT) -#define REG_RTCMTH 0x05u - #define RTCMTH_MTHBCD_SHIFT 0u #define RTCMTH_MTHBCD_MASK (0x1fu << RTCMTH_MTHBCD_SHIFT) #define RTCMTH_MTHBCD(x) (((x) << RTCMTH_MTHBCD_SHIFT) & RTCMTH_MTHBCD_MASK) #define RTCMTH_MTHBCD_GET(x) (((x) & RTCMTH_MTHBCD_MASK) >> RTCMTH_MTHBCD_SHIFT) -#define REG_RTCYEAR 0x06u - #define RTCYEAR_YRBCD_SHIFT 0u #define RTCYEAR_YRBCD_MASK (0xffu << RTCYEAR_YRBCD_SHIFT) #define RTCYEAR_YRBCD(x) (((x) << RTCYEAR_YRBCD_SHIFT) & RTCYEAR_YRBCD_MASK) #define RTCYEAR_YRBCD_GET(x) (((x) & RTCYEAR_YRBCD_MASK) >> RTCYEAR_YRBCD_SHIFT) +#define NR_RTC_REGISTERS 0x07u + static inline uint8_t bcd_to_bin(uint8_t bcd) { uint8_t bin; @@ -214,7 +202,7 @@ static int i2c_rtc_initialize_once(struct i2c_rtc_base *ctx) static int i2c_rtc_get_time(int minor, rtems_time_of_day *time) { int rv = 0; - uint8_t buf[REG_RTCYEAR + 1]; + uint8_t buf[NR_RTC_REGISTERS]; struct i2c_rtc_base *ctx = i2c_rtc_get_context(minor); if (!_System_state_Is_up(_System_state_Get())) { @@ -226,21 +214,21 @@ static int i2c_rtc_get_time(int minor, rtems_time_of_day *time) rv = i2c_rtc_initialize_once(ctx); if (rv == 0) { - rv = i2c_rtc_read(ctx, REG_RTCSEC + ctx->clock_offset, buf, sizeof(buf)); + rv = i2c_rtc_read(ctx, ctx->clock_offset, buf, sizeof(buf)); } if (rv == 0) { - unsigned year = bcd_to_bin(RTCYEAR_YRBCD_GET(buf[REG_RTCYEAR])) + + unsigned year = bcd_to_bin(RTCYEAR_YRBCD_GET(buf[ctx->order.year])) + (TOD_BASE_YEAR / 100 * 100); if (year < TOD_BASE_YEAR) { year += 100; } time->year = year; - time->month = bcd_to_bin(RTCMTH_MTHBCD_GET(buf[REG_RTCMTH])); - time->day = bcd_to_bin(RTCDATE_DATEBCD_GET(buf[REG_RTCDATE])); - time->hour = bcd_to_bin(RTCHOUR_HRBCD24_GET(buf[REG_RTCHOUR])); - time->minute = bcd_to_bin(RTCMIN_MINBCD_GET(buf[REG_RTCMIN])); - time->second = bcd_to_bin(RTCSEC_SECBCD_GET(buf[REG_RTCSEC])); + time->month = bcd_to_bin(RTCMTH_MTHBCD_GET(buf[ctx->order.month])); + time->day = bcd_to_bin(RTCDATE_DATEBCD_GET(buf[ctx->order.day])); + time->hour = bcd_to_bin(RTCHOUR_HRBCD24_GET(buf[ctx->order.hour])); + time->minute = bcd_to_bin(RTCMIN_MINBCD_GET(buf[ctx->order.min])); + time->second = bcd_to_bin(RTCSEC_SECBCD_GET(buf[ctx->order.sec])); time->ticks = 0; } @@ -252,7 +240,7 @@ static int i2c_rtc_get_time(int minor, rtems_time_of_day *time) static int i2c_rtc_set_time(int minor, const rtems_time_of_day *time) { int rv = 0; - uint8_t buf[REG_RTCYEAR + 1]; + uint8_t buf[NR_RTC_REGISTERS]; struct i2c_rtc_base *ctx = i2c_rtc_get_context(minor); if (!_System_state_Is_up(_System_state_Get())) { @@ -264,35 +252,35 @@ static int i2c_rtc_set_time(int minor, const rtems_time_of_day *time) rv = i2c_rtc_initialize_once(ctx); if (rv == 0) { - rv = i2c_rtc_read(ctx, REG_RTCSEC + ctx->clock_offset, buf, sizeof(buf)); + rv = i2c_rtc_read(ctx, ctx->clock_offset, buf, sizeof(buf)); } if (rv == 0) { /* Make sure weekday is not 0 (out of range). Otherwise it's not used. */ - if (RTCWKDAY_WKDAY_GET(buf[REG_RTCWKDAY]) < 1) { - buf[REG_RTCWKDAY] &= ~RTCWKDAY_WKDAY_MASK; - buf[REG_RTCWKDAY] |= RTCWKDAY_WKDAY(1); + if (RTCWKDAY_WKDAY_GET(buf[ctx->order.wkday]) < 1) { + buf[ctx->order.wkday] &= ~RTCWKDAY_WKDAY_MASK; + buf[ctx->order.wkday] |= RTCWKDAY_WKDAY(1); } - buf[REG_RTCYEAR] &= ~RTCYEAR_YRBCD_MASK; - buf[REG_RTCYEAR] |= RTCYEAR_YRBCD(bin_to_bcd(time->year % 100)); + buf[ctx->order.year] &= ~RTCYEAR_YRBCD_MASK; + buf[ctx->order.year] |= RTCYEAR_YRBCD(bin_to_bcd(time->year % 100)); - buf[REG_RTCMTH] &= ~RTCMTH_MTHBCD_MASK; - buf[REG_RTCMTH] |= RTCMTH_MTHBCD(bin_to_bcd(time->month)); + buf[ctx->order.month] &= ~RTCMTH_MTHBCD_MASK; + buf[ctx->order.month] |= RTCMTH_MTHBCD(bin_to_bcd(time->month)); - buf[REG_RTCDATE] &= ~RTCDATE_DATEBCD_MASK; - buf[REG_RTCDATE] |= RTCDATE_DATEBCD(bin_to_bcd(time->day)); + buf[ctx->order.day] &= ~RTCDATE_DATEBCD_MASK; + buf[ctx->order.day] |= RTCDATE_DATEBCD(bin_to_bcd(time->day)); - buf[REG_RTCHOUR] &= ~(RTCHOUR_HRBCD24_MASK | RTCHOUR_1224); - buf[REG_RTCHOUR] |= RTCHOUR_HRBCD24(bin_to_bcd(time->hour)); + buf[ctx->order.hour] &= ~(RTCHOUR_HRBCD24_MASK | RTCHOUR_1224); + buf[ctx->order.hour] |= RTCHOUR_HRBCD24(bin_to_bcd(time->hour)); - buf[REG_RTCMIN] &= ~RTCMIN_MINBCD_MASK; - buf[REG_RTCMIN] |= RTCMIN_MINBCD(bin_to_bcd(time->minute)); + buf[ctx->order.min] &= ~RTCMIN_MINBCD_MASK; + buf[ctx->order.min] |= RTCMIN_MINBCD(bin_to_bcd(time->minute)); - buf[REG_RTCSEC] &= ~RTCSEC_SECBCD_MASK; - buf[REG_RTCSEC] |= RTCSEC_SECBCD(bin_to_bcd(time->second)); + buf[ctx->order.sec] &= ~RTCSEC_SECBCD_MASK; + buf[ctx->order.sec] |= RTCSEC_SECBCD(bin_to_bcd(time->second)); - rv = i2c_rtc_write(ctx, REG_RTCSEC + ctx->clock_offset, buf, sizeof(buf)); + rv = i2c_rtc_write(ctx, ctx->clock_offset, buf, sizeof(buf)); } rtems_mutex_unlock(&ctx->mutex);