|
| 1 | + |
| 2 | +#include<stdint.h> |
| 3 | +#include<string.h> |
| 4 | + |
| 5 | +#include "ds1307.h" |
| 6 | + |
| 7 | + |
| 8 | +static void ds1307_i2c_pin_config(void); |
| 9 | +static void ds1307_i2c_config(void); |
| 10 | +static uint8_t ds1307_read(uint8_t reg_addr); |
| 11 | +static void ds1307_write(uint8_t value,uint8_t reg_addr); |
| 12 | +static uint8_t bcd_to_binary(uint8_t value); |
| 13 | +static uint8_t binary_to_bcd(uint8_t value); |
| 14 | + |
| 15 | +I2C_Handle_t g_ds1307I2cHandle; |
| 16 | + |
| 17 | +//returns 1 : CH = 1 ; init failed |
| 18 | +//returns 0 : CH = 0 ; init success |
| 19 | +uint8_t ds1307_init(void) |
| 20 | +{ |
| 21 | + |
| 22 | + //1. init the i2c pins |
| 23 | + ds1307_i2c_pin_config(); |
| 24 | + |
| 25 | + //2. initialize the i2c peripheral |
| 26 | + ds1307_i2c_config(); |
| 27 | + |
| 28 | + //3. Enable the I2C peripheral |
| 29 | + I2C_PeripheralControl(DS1307_I2C, ENABLE); |
| 30 | + |
| 31 | + //4. Make clock halt = 0; |
| 32 | + ds1307_write(0x00,DS1307_ADDR_SEC); |
| 33 | + |
| 34 | + //5. Read back clock halt bit |
| 35 | + uint8_t clock_state = ds1307_read(DS1307_ADDR_SEC); |
| 36 | + |
| 37 | + return ((clock_state >> 7 ) & 0x1); |
| 38 | + |
| 39 | +} |
| 40 | + |
| 41 | + |
| 42 | +void ds1307_set_current_time(RTC_time_t *rtc_time) |
| 43 | +{ |
| 44 | + uint8_t seconds, hrs; |
| 45 | + seconds = binary_to_bcd(rtc_time->seconds); |
| 46 | + seconds &= ~( 1 << 7); |
| 47 | + ds1307_write(seconds, DS1307_ADDR_SEC); |
| 48 | + |
| 49 | + ds1307_write(binary_to_bcd(rtc_time->minutes), DS1307_ADDR_MIN); |
| 50 | + |
| 51 | + hrs = binary_to_bcd(rtc_time->hours); |
| 52 | + |
| 53 | + if(rtc_time->time_format == TIME_FORMAT_24HRS){ |
| 54 | + hrs &= ~(1 << 6); |
| 55 | + }else{ |
| 56 | + hrs |= (1 << 6); |
| 57 | + hrs = (rtc_time->time_format == TIME_FORMAT_12HRS_PM) ? hrs | ( 1 << 5) : hrs & ~( 1 << 5) ; |
| 58 | + } |
| 59 | + |
| 60 | + ds1307_write(hrs,DS1307_ADDR_HRS); |
| 61 | + |
| 62 | +} |
| 63 | + |
| 64 | +void ds1307_set_current_date(RTC_date_t *rtc_date) |
| 65 | +{ |
| 66 | + ds1307_write(binary_to_bcd(rtc_date->date),DS1307_ADDR_DATE); |
| 67 | + |
| 68 | + ds1307_write(binary_to_bcd(rtc_date->month),DS1307_ADDR_MONTH); |
| 69 | + |
| 70 | + ds1307_write(binary_to_bcd(rtc_date->year),DS1307_ADDR_YEAR); |
| 71 | + |
| 72 | + ds1307_write(binary_to_bcd(rtc_date->day),DS1307_ADDR_DAY); |
| 73 | + |
| 74 | +} |
| 75 | + |
| 76 | +void ds1307_get_current_time(RTC_time_t *rtc_time) |
| 77 | +{ |
| 78 | + |
| 79 | + uint8_t seconds,hrs; |
| 80 | + |
| 81 | + seconds = ds1307_read(DS1307_ADDR_SEC); |
| 82 | + |
| 83 | + seconds &= ~( 1 << 7); |
| 84 | + |
| 85 | + rtc_time->seconds = bcd_to_binary(seconds); |
| 86 | + rtc_time->minutes = bcd_to_binary(ds1307_read(DS1307_ADDR_MIN)); |
| 87 | + |
| 88 | + hrs = ds1307_read(DS1307_ADDR_HRS); |
| 89 | + if(hrs & ( 1 << 6)){ |
| 90 | + //12 hr format |
| 91 | + rtc_time->time_format = !((hrs & ( 1 << 5)) == 0) ; |
| 92 | + hrs &= ~(0x3 << 5);//Clear 6 and 5 |
| 93 | + }else{ |
| 94 | + //24 hr format |
| 95 | + rtc_time->time_format = TIME_FORMAT_24HRS; |
| 96 | + } |
| 97 | + |
| 98 | + rtc_time->hours = bcd_to_binary(hrs); |
| 99 | +} |
| 100 | + |
| 101 | +void ds1307_get_current_date(RTC_date_t *rtc_date) |
| 102 | +{ |
| 103 | + rtc_date->day = bcd_to_binary(ds1307_read(DS1307_ADDR_DAY)); |
| 104 | + rtc_date->date = bcd_to_binary(ds1307_read(DS1307_ADDR_DATE)); |
| 105 | + rtc_date->month = bcd_to_binary(ds1307_read(DS1307_ADDR_MONTH)); |
| 106 | + rtc_date->year = bcd_to_binary(ds1307_read(DS1307_ADDR_YEAR)); |
| 107 | + |
| 108 | +} |
| 109 | + |
| 110 | +static void ds1307_i2c_pin_config(void) |
| 111 | +{ |
| 112 | + GPIO_Handle_t i2c_sda,i2c_scl; |
| 113 | + |
| 114 | + memset(&i2c_sda,0,sizeof(i2c_sda)); |
| 115 | + memset(&i2c_scl,0,sizeof(i2c_scl)); |
| 116 | + |
| 117 | + /* |
| 118 | + * I2C1_SCL ==> PB6 |
| 119 | + * I2C1_SDA ==> PB7 |
| 120 | + */ |
| 121 | + |
| 122 | + i2c_sda.pGPIOx = DS1307_I2C_GPIO_PORT; |
| 123 | + i2c_sda.GPIO_PinConfig.GPIO_PinAltFunMode = 4; |
| 124 | + i2c_sda.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_ALTFN; |
| 125 | + i2c_sda.GPIO_PinConfig.GPIO_PinNumber = DS1307_I2C_SDA_PIN; |
| 126 | + i2c_sda.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_OD; |
| 127 | + i2c_sda.GPIO_PinConfig.GPIO_PinPuPdControl = DS1307_I2C_PUPD; |
| 128 | + i2c_sda.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_FAST; |
| 129 | + |
| 130 | + GPIO_Init(&i2c_sda); |
| 131 | + |
| 132 | + |
| 133 | + i2c_scl.pGPIOx = DS1307_I2C_GPIO_PORT; |
| 134 | + i2c_scl.GPIO_PinConfig.GPIO_PinAltFunMode = 4; |
| 135 | + i2c_scl.GPIO_PinConfig.GPIO_PinMode = GPIO_MODE_ALTFN; |
| 136 | + i2c_scl.GPIO_PinConfig.GPIO_PinNumber = DS1307_I2C_SCL_PIN; |
| 137 | + i2c_scl.GPIO_PinConfig.GPIO_PinOPType = GPIO_OP_TYPE_OD; |
| 138 | + i2c_scl.GPIO_PinConfig.GPIO_PinPuPdControl = DS1307_I2C_PUPD; |
| 139 | + i2c_scl.GPIO_PinConfig.GPIO_PinSpeed = GPIO_SPEED_FAST; |
| 140 | + |
| 141 | + GPIO_Init(&i2c_scl); |
| 142 | + |
| 143 | +} |
| 144 | + |
| 145 | + |
| 146 | +static void ds1307_i2c_config(void) |
| 147 | +{ |
| 148 | + g_ds1307I2cHandle.pI2Cx = DS1307_I2C; |
| 149 | + g_ds1307I2cHandle.I2C_Config.I2C_AckControl = I2C_ACK_ENABLE; |
| 150 | + g_ds1307I2cHandle.I2C_Config.I2C_SCLSpeed = DS1307_I2C_SPEED; |
| 151 | + I2C_Init(&g_ds1307I2cHandle); |
| 152 | +} |
| 153 | + |
| 154 | + |
| 155 | +static void ds1307_write(uint8_t value,uint8_t reg_addr) |
| 156 | +{ |
| 157 | + uint8_t tx[2]; |
| 158 | + tx[0] = reg_addr; |
| 159 | + tx[1] = value; |
| 160 | + I2C_MasterSendData(&g_ds1307I2cHandle, tx, 2, DS1307_I2C_ADDRESS, 0); |
| 161 | +} |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | +static uint8_t ds1307_read(uint8_t reg_addr) |
| 166 | +{ |
| 167 | + uint8_t data; |
| 168 | + I2C_MasterSendData(&g_ds1307I2cHandle, ®_addr, 1, DS1307_I2C_ADDRESS, 0); |
| 169 | + I2C_MasterReceiveData(&g_ds1307I2cHandle, &data, 1, DS1307_I2C_ADDRESS, 0); |
| 170 | + |
| 171 | + return data; |
| 172 | +} |
| 173 | + |
| 174 | + |
| 175 | + |
| 176 | +static uint8_t binary_to_bcd(uint8_t value) |
| 177 | +{ |
| 178 | + uint8_t m , n; |
| 179 | + uint8_t bcd; |
| 180 | + |
| 181 | + bcd = value; |
| 182 | + if(value >= 10) |
| 183 | + { |
| 184 | + m = value /10; |
| 185 | + n = value % 10; |
| 186 | + bcd = (m << 4) | n ; |
| 187 | + } |
| 188 | + |
| 189 | + return bcd; |
| 190 | +} |
| 191 | + |
| 192 | +static uint8_t bcd_to_binary(uint8_t value) |
| 193 | +{ |
| 194 | + uint8_t m , n; |
| 195 | + m = (uint8_t) ((value >> 4 ) * 10); |
| 196 | + n = value & (uint8_t)0x0F; |
| 197 | + return (m+n); |
| 198 | +} |
| 199 | + |
0 commit comments