1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  *
4  *
5  */
6 
7 #include "rx8130ce.h"
8 #include "aos/kernel.h"
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 
13 static i2c_dev_t rx8130ce_i2c = {
14     .port = RX8130CE_I2C,
15     .config.address_width = 8,
16     .config.freq = RX8130CE_I2C_CLOCK,
17     .config.dev_addr = RX8130CE_I2C_ADDR,
18 };
19 
rx8130ce_bcd2bin(uint8_t bcd)20 static uint8_t rx8130ce_bcd2bin(uint8_t bcd)
21 {
22     uint8_t dec;
23 
24     dec = (10 * (bcd >> 4)) + (bcd & 0x0F);
25 
26     return dec;
27 }
28 
rx8130ce_bin2bcd(uint8_t bin)29 static uint8_t rx8130ce_bin2bcd(uint8_t bin)
30 {
31     uint8_t bcd;
32 
33     bcd = ((bin / 10) << 4) | (bin % 10);
34 
35     return bcd;
36 }
37 
rx8130ce_checkminmax(uint8_t val,uint8_t min,uint8_t max)38 static uint8_t rx8130ce_checkminmax(uint8_t val, uint8_t min, uint8_t max)
39 {
40     if (val < min) {
41         return min;
42     } else if (val > max) {
43         return max;
44     }
45     return val;
46 }
47 
48 /*********************************************************
49  * @fun    rx8130ce_init
50  * @breif  rx8130ce initialization
51  * @param  none
52  * @rtn    0 : on success, EIO : error
53  *********************************************************/
rx8130ce_init(void)54 int rx8130ce_init(void)
55 {
56     int ret = 0;
57 
58     ret = rtc_i2c_init(&rx8130ce_i2c);
59     if (ret) {
60         printf("rtc i2c init fail\r\n");
61         return -1;
62     }
63 
64     return 0;
65 }
66 
67 /*********************************************************
68  * @fun    rx8130ce_set_time
69  * @param[in]  buf      the pointer for rx8130ce time
70  * @param[in]  len      the length of time
71  * @rtn    0 : on success, EIO : error
72  *********************************************************/
rx8130ce_set_time(const void * buf,uint8_t len)73 int rx8130ce_set_time(const void *buf, uint8_t len)
74 {
75     int ret = 0;
76     uint8_t size;
77     uint8_t data[7];
78     uint16_t reg_addr = RX8130CE_SECONDS;
79 
80     const RX8130CE_TIME_T *time = (RX8130CE_TIME_T *)buf;
81 
82     if (buf == NULL) {
83         return -1;
84     }
85 
86     size = sizeof(RX8130CE_TIME_T);
87 
88     if (len < size) {
89         return -1;
90     }
91 
92     /* Format data */
93     data[0] = rx8130ce_bin2bcd(rx8130ce_checkminmax(time->seconds, 0, 59)) & 0x7F;
94     data[1] = rx8130ce_bin2bcd(rx8130ce_checkminmax(time->minutes, 0, 59)) & 0x7F;
95     data[2] = rx8130ce_bin2bcd(rx8130ce_checkminmax(time->hours, 0, 23)) & 0x3F;
96     data[3] = rx8130ce_checkminmax(time->week, 1, 7) & 0x7F;
97     data[4] = rx8130ce_bin2bcd(rx8130ce_checkminmax(time->day, 1, 31)) & 0x3F;
98     data[5] = rx8130ce_bin2bcd(rx8130ce_checkminmax(time->month, 1, 12)) & 0x1F;
99     data[6] = rx8130ce_bin2bcd(rx8130ce_checkminmax(time->year, 0, 99)) & 0xFF;
100 
101     for (uint8_t i = 0; i < 7; i++) {
102         ret = rtc_i2c_write(&rx8130ce_i2c, RX8130CE_I2C_ADDR, reg_addr++, 1,
103                 &data[i], 1, 1000);
104         if (ret) {
105             printf("RX8310CE set time fail\r\n");
106             return -1;
107         }
108     }
109 
110     return 0;
111 }
112 
113 /*********************************************************
114  * @fun    rx8130ce_get_time
115  * @param[in]  buf      the pointer for rx8130ce time
116  * @param[in]  len      the length of time
117  * @rtn    0 : on success, EIO : error
118  *********************************************************/
rx8130ce_get_time(void * buf,uint8_t len)119 int rx8130ce_get_time(void *buf, uint8_t len)
120 {
121     int ret = 0;
122     uint8_t size;
123     uint8_t data[7];
124     uint16_t reg_addr = RX8130CE_SECONDS;
125 
126     RX8130CE_TIME_T *time = (RX8130CE_TIME_T *)buf;
127 
128     if (buf == NULL) {
129         return -1;
130     }
131 
132     size = sizeof(RX8130CE_TIME_T);
133 
134     if (len < size) {
135         return -1;
136     }
137 
138     for (uint8_t i = 0; i < 7; i++) {
139         ret = rtc_i2c_read(&rx8130ce_i2c, RX8130CE_I2C_ADDR, reg_addr++, 1,
140                 &data[i], 1, 1000);
141         if (ret) {
142             printf("RX8310CE read time fail\r\n");
143             return -1;
144         }
145     }
146 
147     /* Fill data */
148     time->seconds = rx8130ce_bcd2bin(data[0]);
149     time->minutes = rx8130ce_bcd2bin(data[1]);
150     time->hours = rx8130ce_bcd2bin(data[2]);
151     time->week = (data[3]) & 0x7F;
152     time->day = rx8130ce_bcd2bin(data[4]);
153     time->month = rx8130ce_bcd2bin(data[5]);
154     time->year = rx8130ce_bcd2bin(data[6]);
155 
156     return 0;
157 }
158