|
@@ -1,17 +1,14 @@
|
|
|
#include "main.h"
|
|
|
|
|
|
-#define RTC_TX_BUF_SIZE 4
|
|
|
-
|
|
|
extern int8_t user_i2c_read(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
|
|
extern int8_t user_i2c_write(uint8_t id, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
|
|
|
|
|
-static uint8_t i2cBufTX[RTC_TX_BUF_SIZE] = {0};
|
|
|
-
|
|
|
/**
|
|
|
* @brief Инициализация RTC
|
|
|
*/
|
|
|
void RTC_Init(void) {
|
|
|
uint8_t buf[3] = {0};
|
|
|
+
|
|
|
/* Clear flags */
|
|
|
Flag.I2C_TX_End = 0;
|
|
|
|
|
@@ -21,35 +18,6 @@ void RTC_Init(void) {
|
|
|
user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_CONTROL, buf, 2);
|
|
|
}
|
|
|
|
|
|
-void test_w(rtc_t * data) {
|
|
|
-
|
|
|
- /* Source: Address of the I2C TX buffer. */
|
|
|
- DMA1_Channel3->CMAR = (uint32_t)&i2cBufTX;
|
|
|
- /* Destination: I2C TX data register. */
|
|
|
- DMA1_Channel3->CPAR = (uint32_t)&(I2C1->TXDR);
|
|
|
- /* Set DMA data transfer length (I2C TX buffer length). */
|
|
|
- DMA1_Channel3->CNDTR = 3; // hardcode / magic number
|
|
|
- /* Enable DMA channels for I2C */
|
|
|
- DMA1_Channel3->CCR |= DMA_CCR_EN;
|
|
|
-
|
|
|
- /* Fill buffer with register address and register value */
|
|
|
- i2cBufTX[0] = DS3231_ADDR_CONTROL;
|
|
|
- i2cBufTX[1] = DS3231_1HZ; // set 1 Hz output squware
|
|
|
- i2cBufTX[2] = 0x0; // disable 32 kHz output
|
|
|
-
|
|
|
- /* Wait for I2C */
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- /* Set the device address and number bytes to send. */
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | 3 << I2C_CR2_NBYTES_Pos );
|
|
|
- /* Enable I2C DMA requests. */
|
|
|
- I2C1->CR1 |= ( I2C_CR1_TXDMAEN );
|
|
|
- /* Send a start signal. */
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
- /* (DMA is now running.) */
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* @brief Чтение всех регистров DS3231
|
|
|
*/
|
|
@@ -60,150 +28,49 @@ void RTC_ReadAll(rtc_t * data) {
|
|
|
user_i2c_read(DS3231_I2C_ADDR, DS3231_ADDR_TIME, (uint8_t *)data, DS3231_SIZE_ALL);
|
|
|
}
|
|
|
|
|
|
-void test_r(rtc_t * data) {
|
|
|
-
|
|
|
- /* Source: Address of the I2C RX buffer. */
|
|
|
- DMA1_Channel2->CMAR = (uint32_t)data;
|
|
|
- /* Destination: I2C RX data register. */
|
|
|
- DMA1_Channel2->CPAR = (uint32_t)&(I2C1->RXDR);
|
|
|
- /* Set DMA data transfer length (I2C RX buffer length). */
|
|
|
- DMA1_Channel2->CNDTR = DS3231_SIZE_ALL;
|
|
|
- /* Enable DMA channels for I2C RX */
|
|
|
- DMA1_Channel2->CCR |= DMA_CCR_EN;
|
|
|
-
|
|
|
- /* wait for i2c */
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- /* send first register address 00h */
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | 1 << I2C_CR2_NBYTES_Pos );
|
|
|
-
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
-
|
|
|
- while ( !( I2C1->CR2 & I2C_CR2_START ) ) {};
|
|
|
- I2C1->TXDR = DS3231_ADDR_TIME;
|
|
|
-
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- /* Reading all */
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | DS3231_SIZE_ALL << I2C_CR2_NBYTES_Pos | I2C_CR2_RD_WRN);
|
|
|
-
|
|
|
- I2C1->CR1 |= ( I2C_CR1_RXDMAEN );
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
- * @brief Запись времени и календаря
|
|
|
+ * @brief Запись времени и календаря "SS:MM:HH wd dd/mm/yy"
|
|
|
*/
|
|
|
void RTC_WriteTimeCalendar(rtc_t * data) {
|
|
|
Flag.I2C_TX_End = 0;
|
|
|
|
|
|
- DMA1_Channel3->CCR &= ~DMA_CCR_EN;
|
|
|
- DMA1_Channel3->CMAR = (uint32_t)data;
|
|
|
- DMA1_Channel3->CPAR = (uint32_t)&(I2C1->TXDR);
|
|
|
- DMA1_Channel3->CNDTR = DS3231_SIZE_TIME + DS3231_SIZE_CALENDAR;
|
|
|
-
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | (DS3231_SIZE_TIME + DS3231_SIZE_CALENDAR + 1) << I2C_CR2_NBYTES_Pos );
|
|
|
- I2C1->CR1 |= ( I2C_CR1_TXDMAEN );
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
-
|
|
|
- while ( !( I2C1->CR2 & I2C_CR2_START ) ) {};
|
|
|
- I2C1->TXDR = DS3231_ADDR_TIME; // send reg addr when START finish
|
|
|
-
|
|
|
- DMA1_Channel3->CCR |= DMA_CCR_EN; // and launch DMA for data to transfer
|
|
|
+ user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), (DS3231_SIZE_TIME + DS3231_SIZE_CALENDAR));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Запись времени
|
|
|
+ * @brief Запись времени "SS:MM:HH"
|
|
|
*/
|
|
|
void RTC_WriteTime(rtc_t * data) {
|
|
|
Flag.I2C_TX_End = 0;
|
|
|
|
|
|
- DMA1_Channel3->CMAR = (uint32_t)data;
|
|
|
- DMA1_Channel3->CPAR = (uint32_t)&(I2C1->TXDR);
|
|
|
- DMA1_Channel3->CNDTR = DS3231_SIZE_TIME;
|
|
|
-
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | (DS3231_SIZE_TIME + 1) << I2C_CR2_NBYTES_Pos );
|
|
|
- I2C1->CR1 |= ( I2C_CR1_TXDMAEN );
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
-
|
|
|
- while ( !( I2C1->CR2 & I2C_CR2_START ) ) {};
|
|
|
- I2C1->TXDR = DS3231_ADDR_TIME;
|
|
|
-
|
|
|
- DMA1_Channel3->CCR |= DMA_CCR_EN;
|
|
|
+ user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), DS3231_SIZE_TIME);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Запись часов
|
|
|
+ * @brief Запись часов "HH"
|
|
|
*/
|
|
|
void RTC_WriteHH(rtc_t * data) {
|
|
|
- Flag.I2C_TX_End = 0; // некому установить этот флаг в 1
|
|
|
-
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | 2 << I2C_CR2_NBYTES_Pos );
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
-
|
|
|
- while ( !( I2C1->CR2 & I2C_CR2_START ) ) {};
|
|
|
- I2C1->TXDR = (DS3231_ADDR_TIME + 2);
|
|
|
+ Flag.I2C_TX_End = 0;
|
|
|
|
|
|
- while ((I2C1->ISR & I2C_ISR_TXE) == 0) { __NOP(); };
|
|
|
- I2C1->TXDR = data->Hr;
|
|
|
+ user_i2c_write(DS3231_I2C_ADDR, (DS3231_ADDR_TIME + 2), &(data->Hr), 1);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Запись часов и минут
|
|
|
+ * @brief Запись часов и минут "MM:HH"
|
|
|
*/
|
|
|
void RTC_WriteHHMM(rtc_t * data) {
|
|
|
Flag.I2C_TX_End = 0;
|
|
|
|
|
|
- DMA1_Channel3->CMAR = (uint32_t)&i2cBufTX;
|
|
|
- DMA1_Channel3->CPAR = (uint32_t)&(I2C1->TXDR);
|
|
|
- DMA1_Channel3->CNDTR = 3; // addr + mm + hh
|
|
|
- DMA1_Channel3->CCR |= DMA_CCR_EN;
|
|
|
-
|
|
|
- /* Fill buffer with register address and register value */
|
|
|
- i2cBufTX[0] = DS3231_ADDR_TIME + 1; // skip seconds
|
|
|
- i2cBufTX[1] = data->Min;
|
|
|
- i2cBufTX[2] = data->Hr;
|
|
|
-
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | 3 << I2C_CR2_NBYTES_Pos );
|
|
|
- I2C1->CR1 |= ( I2C_CR1_TXDMAEN );
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
+ user_i2c_write(DS3231_I2C_ADDR, (DS3231_ADDR_TIME + 1), &(data->Min), 2);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * @brief Запись календаря
|
|
|
+ * @brief Запись календаря "wd dd/mm/yy"
|
|
|
*/
|
|
|
void RTC_WriteCalendar(rtc_t * data) {
|
|
|
Flag.I2C_TX_End = 0;
|
|
|
|
|
|
- DMA1_Channel3->CMAR = (uint32_t)&(data->WD);
|
|
|
- DMA1_Channel3->CPAR = (uint32_t)&(I2C1->TXDR);
|
|
|
- DMA1_Channel3->CNDTR = DS3231_SIZE_CALENDAR;
|
|
|
-
|
|
|
- while ( I2C1->ISR & I2C_ISR_BUSY ) {};
|
|
|
-
|
|
|
- I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
|
|
|
- I2C1->CR2 |= ( DS3231_I2C_ADDR | (DS3231_SIZE_CALENDAR + 1) << I2C_CR2_NBYTES_Pos );
|
|
|
- I2C1->CR1 |= ( I2C_CR1_TXDMAEN );
|
|
|
- I2C1->CR2 |= ( I2C_CR2_START );
|
|
|
-
|
|
|
- while ( !( I2C1->CR2 & I2C_CR2_START ) ) {};
|
|
|
- I2C1->TXDR = DS3231_ADDR_CALENDAR;
|
|
|
-
|
|
|
- DMA1_Channel3->CCR |= DMA_CCR_EN;
|
|
|
+ user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_CALENDAR, &(data->WD), DS3231_SIZE_CALENDAR);
|
|
|
}
|
|
|
|
|
|
/**
|