Vladimir N. Shilov 2 роки тому
батько
коміт
3ec8e8999d
6 змінених файлів з 151 додано та 66 видалено
  1. 7 14
      inc/ds3231.h
  2. 5 5
      inc/i2c.h
  3. 20 5
      src/board.c
  4. 27 31
      src/ds3231.c
  5. 24 4
      src/i2c.c
  6. 68 7
      src/main.c

+ 7 - 14
inc/ds3231.h

@@ -2,13 +2,6 @@
 #ifndef DS3231_H
 #define DS3231_H
 
-/* RTC Status */
-typedef enum {
-  RTC_OK  = 0x00,
-  RTC_TWI_TimeOut,
-  RTC_TWI_Error
-} rtc_status_t;
-
 /**
  * @brief   Clock sructure.
  * @note    structure of ds3231 data.
@@ -92,13 +85,13 @@ typedef struct {
   uint8_t TempL;
 } rtc_t;
 
-void RTC_Init(void);
-void RTC_ReadAll(rtc_t * data);
-void RTC_ReadTime(rtc_t * data);
-void RTC_WriteTimeCalendar(rtc_t * data);
-void RTC_WriteTime(rtc_t * data);
-void RTC_WriteHHMM(rtc_t * data);
-void RTC_WriteCalendar(rtc_t * data);
+i2c_status_t RTC_Init(void);
+i2c_status_t RTC_ReadAll(rtc_t * data);
+i2c_status_t RTC_ReadTime(rtc_t * data);
+i2c_status_t RTC_WriteTimeCalendar(rtc_t * data);
+i2c_status_t RTC_WriteTime(rtc_t * data);
+i2c_status_t RTC_WriteHHMM(rtc_t * data);
+i2c_status_t RTC_WriteCalendar(rtc_t * data);
 
 uint8_t bcd2bin(uint8_t bcd);
 uint8_t bin2bcd(uint8_t bin);

+ 5 - 5
inc/i2c.h

@@ -7,12 +7,12 @@
 
 /* Exported typedefs */
 /** @brief I2C return Status */
-typedef enum i2c_status {
+typedef enum t_i2c_status {
   I2C_Ret_OK  = 0,
-  I2C_Ret_NACK = 1,
-  I2C_Ret_Bsy  = 2,
-  I2C_Ret_Tout = 3,
-  I2C_Ret_Err = 4
+  I2C_Ret_NACK,
+  I2C_Ret_Bsy,
+  I2C_Ret_Tout,
+  I2C_Ret_Err
 } i2c_status_t;
 
 /* Exported variabless */

+ 20 - 5
src/board.c

@@ -26,7 +26,7 @@ static void TIM1_Init(void);
 //static void TIM3_Init(void);
 //static void TIM14_Init(void);
 //static void TIM16_Init(void);
-//static void TIM17_Init(void);
+static void TIM17_Init(void);
 //static void USART1_UART_Init(void);
 static void _display_WriteBits(uint16_t data, uint16_t nbits);
 static void _delay_c(uint32_t cycle);
@@ -44,7 +44,7 @@ void Board_Init(void)
   /* Main peripheral clock enable */
   RCC->AHBENR |= (RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_DMAEN);
   RCC->APB1ENR = (RCC_APB1ENR_PWREN | RCC_APB1ENR_I2C1EN); // | RCC_APB1ENR_TIM14EN| RCC_APB1ENR_TIM3EN);
-  RCC->APB2ENR = (RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_SPI1EN | RCC_APB2ENR_TIM1EN); // | RCC_APB2ENR_TIM16EN | RCC_APB2ENR_TIM17EN);
+  RCC->APB2ENR = (RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_SPI1EN | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_TIM17EN); // | RCC_APB2ENR_TIM16EN
 
   /* Peripheral interrupt init*/
   /* RCC_IRQn interrupt configuration */
@@ -76,7 +76,7 @@ void Board_Init(void)
 //  TIM3_Init();
 //  TIM14_Init();
 //  TIM16_Init();
-//  TIM17_Init();
+  TIM17_Init();
 //  USART1_UART_Init();
 
   display_Init();
@@ -138,12 +138,12 @@ static void GPIO_Init(void)
   NVIC_EnableIRQ(EXTI4_15_IRQn);
 
   /* Select output mode (01) PP+PU, High Speed
-   PA8  - Buzzer (AF2 for TIM1_CH1)
+   PA8  - Buzzer (AF2 for TIM1_CH1), Pull-Down
    PA15 - ~CS / SPI_NSS (AF0)
    * Select output mode (10) AF+PP, High Speed
    PB3  - ~WR / SPI_SCK (AF0)
    PB5  - Data / SPI_MOSI (AF0)
-   * Select output mode (10) AF+OD, High Speed
+   * Select output mode (10) AF+OD, High Speed, Pull-Up
    PB6  - SCL (AF1)
    PB7  - SDA (AF1)
   */
@@ -289,6 +289,21 @@ static void TIM1_Init(void)
   TIM1->CCER = TIM_CCER_CC1E;
 }
 
+/**
+  * @brief TIM17 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void TIM17_Init(void)
+{
+  /* setup clock */
+  TIM17->PSC = 47; // prescaler for 1uS
+  TIM17->ARR = 1000; // auto reload value for 1 mS
+  TIM17->CR1 = (TIM_CR1_ARPE | TIM_CR1_OPM); // one pulse mode
+  TIM17->BDTR = TIM_BDTR_MOE; // enable main output
+  TIM17->EGR = TIM_EGR_UG; // force timer update
+}
+
 /**
  * @brief Set HT1632C PWM Value
  * @param pwm value in 0-15

+ 27 - 31
src/ds3231.c

@@ -48,10 +48,13 @@
 #define DS3231_SIZE_TEMPERATURE     2
 #define DS3231_SIZE_ALL             19
 
+/* Private variables */
+static i2c_status_t status = I2C_Ret_OK;
+
 /**
  * @brief Initialization DS3231
  */
-void RTC_Init(void) {
+i2c_status_t RTC_Init(void) {
   uint8_t buf[3] = {0};
 
   /* Clear flags */
@@ -60,71 +63,64 @@ void RTC_Init(void) {
   buf[0] = DS3231_1HZ; // set 1 Hz output squware
   buf[1] = 0x0; // disable 32 kHz output
 
-  user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_CONTROL, buf, 2);
+  status = user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_CONTROL, buf, 2);
+  return status;
 }
 
 /**
  * @brief Reading all registers DS3231
  */
-void RTC_ReadAll(rtc_t * data) {
-  Flag.I2C_RX_End = 0;
-  Flag.I2C_TX_End = 0;
-
-  user_i2c_read(DS3231_I2C_ADDR, DS3231_ADDR_TIME, (uint8_t *)data, DS3231_SIZE_ALL);
+i2c_status_t RTC_ReadAll(rtc_t * data) {
+  status = user_i2c_read(DS3231_I2C_ADDR, DS3231_ADDR_TIME, (uint8_t *)data, DS3231_SIZE_ALL);
+  return status;
 }
 
 /**
  * @brief Read Time "SS:MM:HH"
  */
-void RTC_ReadTime(rtc_t * data) {
-  Flag.I2C_TX_End = 0;
-
-  user_i2c_read(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), DS3231_SIZE_TIME);
+i2c_status_t RTC_ReadTime(rtc_t * data) {
+  status = user_i2c_read(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), DS3231_SIZE_TIME);
+  return status;
 }
 
 /**
  * @brief Save time and calendar "SS:MM:HH wd dd/mm/yy"
  */
-void RTC_WriteTimeCalendar(rtc_t * data) {
-  Flag.I2C_TX_End = 0;
-
-  user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), (DS3231_SIZE_TIME + DS3231_SIZE_CALENDAR));
+i2c_status_t RTC_WriteTimeCalendar(rtc_t * data) {
+  status = user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), (DS3231_SIZE_TIME + DS3231_SIZE_CALENDAR));
+  return status;
 }
 
 /**
  * @brief Save Time "SS:MM:HH"
  */
-void RTC_WriteTime(rtc_t * data) {
-  Flag.I2C_TX_End = 0;
-
-  user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), DS3231_SIZE_TIME);
+i2c_status_t RTC_WriteTime(rtc_t * data) {
+  status = user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_TIME, &(data->Sec), DS3231_SIZE_TIME);
+  return status;
 }
 
 /**
  * @brief Save hours "HH"
  */
-void RTC_WriteHH(rtc_t * data) {
-  Flag.I2C_TX_End = 0;
-
-  user_i2c_write(DS3231_I2C_ADDR, (DS3231_ADDR_TIME + 2), &(data->Hr), 1);
+i2c_status_t RTC_WriteHH(rtc_t * data) {
+  status = user_i2c_write(DS3231_I2C_ADDR, (DS3231_ADDR_TIME + 2), &(data->Hr), 1);
+  return status;
 }
 
 /**
  * @brief Save hours & minutes "MM:HH"
  */
-void RTC_WriteHHMM(rtc_t * data) {
-  Flag.I2C_TX_End = 0;
-
-  user_i2c_write(DS3231_I2C_ADDR, (DS3231_ADDR_TIME + 1), &(data->Min), 2);
+i2c_status_t RTC_WriteHHMM(rtc_t * data) {
+  status = user_i2c_write(DS3231_I2C_ADDR, (DS3231_ADDR_TIME + 1), &(data->Min), 2);
+  return status;
 }
 
 /**
  * @brief Save calendar "wd dd/mm/yy"
  */
-void RTC_WriteCalendar(rtc_t * data) {
-  Flag.I2C_TX_End = 0;
-
-  user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_CALENDAR, &(data->WD), DS3231_SIZE_CALENDAR);
+i2c_status_t RTC_WriteCalendar(rtc_t * data) {
+  status = user_i2c_write(DS3231_I2C_ADDR, DS3231_ADDR_CALENDAR, &(data->WD), DS3231_SIZE_CALENDAR);
+  return status;
 }
 
 /**

+ 24 - 4
src/i2c.c

@@ -7,6 +7,10 @@
 
 #include "main.h"
 
+/* Private macros */
+#define ENABLE_TIM  TIM17->CNT=1; TIM17->CR1 |= TIM_CR1_CEN
+#define TIM_CNT     TIM17->CNT
+
 /* Private variables */
 uint32_t I2C_tout = 0;
 static i2c_status_t st_Read = I2C_Ret_OK;
@@ -63,7 +67,12 @@ i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *da
   I2C1->CR2 |= I2C_CR2_START;
 
   /* wait for byte request or any error */
-  while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); };
+  ENABLE_TIM;
+  while ((I2C1->ISR & (I2C_ISR_TIMEOUT | I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) {
+    if (TIM_CNT == 0) {
+      return I2C_Ret_Tout;
+    }
+  }
 
   if ((I2C1->ISR & I2C_ISR_TXE) != 0) {
   /* device ok, send reg addr */
@@ -87,6 +96,7 @@ i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *da
   int cnt = 0;
   // Read data while no TC flag set.
   // Если взлетит NACK-флаг, приём прекращаем.
+  ENABLE_TIM;
   while ((((I2C1->ISR & I2C_ISR_TC)==0) && ((I2C1->ISR & I2C_ISR_NACKF)==0)) && (I2C1->ISR & I2C_ISR_BUSY)) {
     if (I2C1->ISR & I2C_ISR_RXNE) { // Reading data
       *data = I2C1->RXDR;
@@ -97,6 +107,10 @@ i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *da
         break;
       }
     }
+    if (TIM_CNT == 0) {
+      st_Read = I2C_Ret_Tout;
+      break;
+    }
   }
 
   /* wait for receiving data */
@@ -117,6 +131,8 @@ i2c_status_t user_i2c_read(const uint8_t id, const uint8_t reg_addr, uint8_t *da
 i2c_status_t user_i2c_write(const uint8_t id, const uint8_t reg_addr, uint8_t *data, const uint16_t len) {
   i2c_status_t r = I2C_Ret_OK;
 
+  while ( I2C1->ISR & I2C_ISR_BUSY );
+
   Flag.I2C_TX_End = 0;
   Flag.I2C_TX_Err = 0;
 
@@ -124,13 +140,17 @@ i2c_status_t user_i2c_write(const uint8_t id, const uint8_t reg_addr, uint8_t *d
   DMA1_Channel2->CPAR = (uint32_t)&(I2C1->TXDR);
   DMA1_Channel2->CNDTR = len;
 
-  while ( I2C1->ISR & I2C_ISR_BUSY );
-
   I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RD_WRN);
   I2C1->CR2 |= ( id | (len + 1) << I2C_CR2_NBYTES_Pos );
   I2C1->CR2 |= ( I2C_CR2_START );
 
-  while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE)) == 0) { __NOP(); };
+  ENABLE_TIM;
+  while ((I2C1->ISR & (I2C_ISR_ARLO | I2C_ISR_BERR | I2C_ISR_NACKF | I2C_ISR_TXE | I2C_ISR_TIMEOUT)) == 0) {
+    if (TIM_CNT == 0) {
+      return I2C_Ret_Tout;
+    }
+  }
+
   if ((I2C1->ISR & I2C_ISR_TXE) != 0) {
     I2C1->TXDR = reg_addr;
   } else {

+ 68 - 7
src/main.c

@@ -22,8 +22,7 @@ static rtc_t Clock;
 /* Private function prototypes -----------------------------------------------*/
 static void Show_MMSS(void);
 static void dots_Off(void);
-
-/* Private functions ---------------------------------------------------------*/
+void bip_Bip(void);
 
 /**
   * @brief  Main program.
@@ -32,6 +31,8 @@ static void dots_Off(void);
   */
 int main(void)
 {
+  i2c_status_t i2c_status;
+
   /* Initialize onBoard Hardware */
   Board_Init();
 
@@ -39,12 +40,20 @@ int main(void)
   RTOS_Init();
 
   buzer_On();
-  tdelay_ms(100);
+  tdelay_ms(50);
   buzer_Off();
 
   /* Real-Time clock */
-  RTC_Init();
-  RTC_ReadTime(&Clock);
+  i2c_status = RTC_Init();
+  if (i2c_status != I2C_Ret_OK) {
+    buzer_On();
+    tdelay_ms(500);
+    buzer_Off();
+  }
+  i2c_status = RTC_ReadTime(&Clock);
+  if (i2c_status != I2C_Ret_OK) {
+    bip_Bip();
+  }
 
   display_Init();
   Show_MMSS();
@@ -54,8 +63,10 @@ int main(void)
   {
     if (Flag.RTC_IRQ != 0) {
       Flag.RTC_IRQ = 0;
-      RTC_ReadTime(&Clock);
-      Show_MMSS();
+      i2c_status = RTC_ReadTime(&Clock);
+      display_Buffer[0] = (uint8_t)i2c_status;
+      display_WriteBuffer();
+      //Show_MMSS();
     }
 
     RTOS_DispatchTask();
@@ -64,6 +75,10 @@ int main(void)
   }
 }
 
+/* Private functions ---------------------------------------------------------*/
+/**
+ * @brief Show MM:SS use 4x7 digits
+ */
 static void Show_MMSS(void) {
   uint8_t t;
   // dots on
@@ -90,6 +105,52 @@ static void dots_Off(void) {
   display_Buffer[12] = 0x0;
   display_WriteBuffer();
 }
+
+/**
+ * @brief 
+ * Звук "пи-пи...пи-пи...":
+ *  - две посылки по 125 мс,
+ *  - пауза внутри посылки 63 мс,
+ *  - пауза между посылками 689 мс,
+ *  - частота заполнения 4 кГц,
+ *  - период 1 секунда.
+ * 
+ */
+void bip_Bip(void) {
+  static int stat = 0;
+
+  switch (stat) {
+  case 0:
+    stat = 1;
+    BUZER_ON;
+    RTOS_SetTask(bip_Bip, 100, 0);
+    break;
+
+  case 1:
+    stat = 2;
+    BUZER_OFF;
+    RTOS_SetTask(bip_Bip, 75, 0);
+    break;
+
+  case 2:
+    stat = 3;
+    BUZER_ON;
+    RTOS_SetTask(bip_Bip, 150, 0);
+    break;
+
+  case 3:
+    stat = 0;
+    BUZER_OFF;
+    //RTOS_SetTask(bip_Bip, 675, 0);
+    break;
+
+  default:
+    BUZER_OFF;
+    stat = 0;
+    break;
+  }
+}
+
 /******************************************************************************/
 /*            Cortex-M0 Processor Exceptions Handlers                         */
 /******************************************************************************/