Vladimir N. Shilov 4 жил өмнө
parent
commit
ecef047092
4 өөрчлөгдсөн 118 нэмэгдсэн , 30 устгасан
  1. 15 7
      Inc/main.h
  2. 1 0
      MNC-IN12x5.cbp
  3. 94 21
      Src/main.c
  4. 8 2
      Src/stm32g0xx_it.c

+ 15 - 7
Inc/main.h

@@ -49,6 +49,7 @@ extern "C" {
 /* Private includes ----------------------------------------------------------*/
 /* USER CODE BEGIN Includes */
 #include "gpio.h"
+#include "ds3231.h"
 
 /* USER CODE END Includes */
 
@@ -64,6 +65,14 @@ typedef enum {
   ON = 1
 } onoff_t;
 
+volatile struct {
+  uint32_t RTC_IRQ:     1;
+  uint32_t SPI_TX_End:  1;
+  uint32_t I2C_TX_End:  1;
+  uint32_t I2C_RX_End:  1;
+  uint32_t _reserv:    28;
+} Flag;
+
 /* USER CODE END ET */
 
 /* Exported constants --------------------------------------------------------*/
@@ -132,13 +141,12 @@ void Error_Handler(void);
 #define IRQ_GPIO_Port GPIOB
 #define IRQ_EXTI_IRQn EXTI4_15_IRQn
 /* USER CODE BEGIN Private defines */
-static volatile struct {
-  uint32_t RTC_IRQ:     1;
-  uint32_t SPI_TX_End:  1;
-  uint32_t I2C_TX_End:  1;
-  uint32_t I2C_RX_End:  1;
-  uint32_t _reserv:    28;
-} Flag;
+#define USE_FULL_LL_DRIVER 1
+
+/* 0xd0 */
+#define I2C_ADDR_RTC      0x68
+/* 0x76 */
+#define I2C_ADDR_BME      0x3b
 
 /* USER CODE END Private defines */
 

+ 1 - 0
MNC-IN12x5.cbp

@@ -93,6 +93,7 @@
 			<Option compilerVar="CC" />
 		</Unit>
 		<Unit filename="Drivers/startup_stm32g030xx.s" />
+		<Unit filename="Inc/ds3231.h" />
 		<Unit filename="Inc/gpio.h" />
 		<Unit filename="Inc/main.h" />
 		<Unit filename="Inc/stm32_assert.h" />

+ 94 - 21
Src/main.c

@@ -42,6 +42,9 @@ typedef enum {
 /* Private macro -------------------------------------------------------------*/
 /* USER CODE BEGIN PM */
 #define SPI_BUFFER_SIZE  5
+
+#define I2C_RX_BUF_SIZE  18
+#define I2C_TX_BUF_SIZE  7
 /* USER CODE END PM */
 
 /* Private variables ---------------------------------------------------------*/
@@ -70,6 +73,8 @@ static const uint16_t nixieCathodeMap[4][10] = {
 };
 static const uint8_t nixieCathodeMask[4][2] = {{0x00, 0x3f}, {0xc0, 0x0f}, {0xf0, 0x03}, {0xc0, 0x00}};
 static uint8_t tubesBuffer[SPI_BUFFER_SIZE];
+static uint8_t i2cBufTX[I2C_TX_BUF_SIZE];
+static uint8_t i2cBufRX[I2C_RX_BUF_SIZE];
 
 /* USER CODE END PV */
 
@@ -86,6 +91,8 @@ static void MX_TIM17_Init(void);
 /* USER CODE BEGIN PFP */
 static void showDigit(tube_pos_t pos, uint8_t dig);
 static void SPI_StartTX(void);
+static void RTC_Init(void);
+static void RTC_ReadAll(void);
 /* USER CODE END PFP */
 
 /* Private user code ---------------------------------------------------------*/
@@ -140,7 +147,8 @@ int main(void)
   MX_TIM16_Init();
   MX_TIM17_Init();
   /* USER CODE BEGIN 2 */
-  __enable_irq();
+  RTC_Init();
+  // __enable_irq();
   //LL_Init1msTick(rcc_clocks.HCLK_Frequency);
   //LL_mDelay(1);
 
@@ -158,56 +166,74 @@ int main(void)
   TUBE_PWR_ON;
 
   /* Set DMA source and destination addresses. */
-  /* Source: Address of the framebuffer. */
-  DMA1_Channel1->CMAR  = (uint32_t)&tubesBuffer;
+  /* Source: Address of the SPI buffer. */
+  DMA1_Channel1->CMAR = (uint32_t)&tubesBuffer;
   /* Destination: SPI1 data register. */
-  DMA1_Channel1->CPAR  = (uint32_t)&( SPI1->DR );
-  /* Set DMA data transfer length (framebuffer length). */
+  DMA1_Channel1->CPAR = (uint32_t)&(SPI1->DR);
+  /* Set DMA data transfer length (SPI buffer length). */
   DMA1_Channel1->CNDTR = SPI_BUFFER_SIZE;
 
-#ifdef USE_LL_DRV
-  /* Set DMA transfer addresses of source and destination */
-  LL_DMA_ConfigAddresses(DMA1,
-                         LL_DMA_CHANNEL_1,
-                         (uint32_t)&tubesBuffer,
-                         (uint32_t)&(SPI1->DR),
-                         LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
-  /* Set DMA transfer size */
-  LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, SPI_BUFFER_SIZE);
-#endif // USE_LL_DRV
-
-  /* Start SPI transfer */
+  /* Source: Address of the I2C RX buffer. */
+  DMA1_Channel2->CMAR = (uint32_t)&i2cBufRX;
+  /* Destination: I2C RX data register. */
+  DMA1_Channel2->CPAR = (uint32_t)&(I2C1->RXDR);
+  /* Set DMA data transfer length (I2C RX buffer length). */
+  DMA1_Channel2->CNDTR = I2C_RX_BUF_SIZE; //?
+
+  /* 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 = I2C_TX_BUF_SIZE; //?
+
+  /* Enable SPI+DMA transfer */
   SPI1->CR2 |= SPI_CR2_TXDMAEN;
   SPI1->CR1 |= SPI_CR1_SPE;
 
+  /* Enable DMA channels for I2C */
+  DMA1_Channel2->CCR |= DMA_CCR_EN; // LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
+  DMA1_Channel3->CCR |= DMA_CCR_EN; // LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);
 
+  /* */
   IN15_OFF;
   /* USER CODE END 2 */
 
-  /* Infinite loop */
   /* USER CODE BEGIN WHILE */
+  /* Infinite loop */
   while (1)
   {
-    IN15_Plus;
+    IN15_OFF;
     COLOR_RGB(0, 0, 0);
     LL_mDelay(500);
-
+/*
     showDigit(Tube_A, 1);
     showDigit(Tube_B, 2);
     showDigit(Tube_D, 3);
     showDigit(Tube_E, 4);
     SPI_StartTX();
+*/
+    RTC_ReadAll();
 
-    IN15_OFF;
+    if (Flag.RTC_IRQ != 0) {
+      Flag.RTC_IRQ = 0;
+      IN15_Minus;
+    }
     COLOR_RGB(0xFF, 0x12, 0x0); // FF7E00 or FFBF00
     LL_mDelay(500);
     /* USER CODE END WHILE */
 
     /* USER CODE BEGIN 3 */
+/*
     showDigit(Tube_A, 5);
     showDigit(Tube_B, 6);
     showDigit(Tube_D, 7);
     showDigit(Tube_E, 8);
+*/
+    showDigit(Tube_A, i2cBufRX[1] >> 4);
+    showDigit(Tube_B, i2cBufRX[1] & 0xf);
+    showDigit(Tube_D, i2cBufRX[0] >> 4);
+    showDigit(Tube_E, i2cBufRX[0] & 0xf);
     SPI_StartTX();
 
     //__WFI();
@@ -220,6 +246,48 @@ static void SPI_StartTX(void) {
   LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
 }
 
+static void RTC_Init(void) {
+  /* Clear flags */
+  Flag.I2C_RX_End = 0;
+  Flag.I2C_TX_End = 0;
+
+  /* Wait for I2C */
+  while ( I2C1->ISR & I2C_ISR_BUSY ) {};
+
+  /* Fill buffer with register address and register value */
+  i2cBufTX[0] = DS3231_CONTROL_ADDR;
+  i2cBufTX[1] = DS3231_CONV;
+
+  /* Set AUTOEND mode, the device address and number bytes to send. */
+//  I2C1->CR2 &= ~( I2C_CR2_SADD | I2C_CR2_NBYTES | AUTOEND );
+  I2C1->CR2 = ( I2C_CR2_AUTOEND | I2C_ADDR_RTC << I2C_CR2_SADD_Pos | 2 << 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.) */
+}
+
+static void RTC_ReadAll(void) {
+  while ( I2C1->ISR & I2C_ISR_BUSY ) {};
+
+  LL_I2C_SetSlaveAddr(I2C1, I2C_ADDR_RTC);
+  LL_I2C_SetTransferRequest(I2C1, LL_I2C_REQUEST_WRITE);
+  LL_I2C_SetTransferSize(I2C1, 1);
+  i2cBufTX[0] = DS3231_CALENDAR_ADDR;
+  LL_I2C_EnableDMAReq_TX(I2C1);
+  LL_I2C_GenerateStartCondition(I2C1);
+
+  while ( I2C1->ISR & I2C_ISR_BUSY ) {};
+
+  Flag.I2C_RX_End = 0;
+  Flag.I2C_TX_End = 0;
+
+  LL_I2C_SetTransferRequest(I2C1, LL_I2C_REQUEST_READ);
+  LL_I2C_SetTransferSize(I2C1, 7); // Clock + Calendar = 7 bytes
+  LL_I2C_EnableDMAReq_RX(I2C1);
+  LL_I2C_GenerateStartCondition(I2C1);
+}
 
 /**
   * @brief System Clock Configuration
@@ -337,6 +405,11 @@ static void MX_I2C1_Init(void)
   LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE);
 
   /* USER CODE BEGIN I2C1_Init 1 */
+  /* Enable DMA transfer complete/error interrupts */
+  LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2);
+  LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2);
+  LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_3);
+  LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_3);
 
   /* USER CODE END I2C1_Init 1 */
   /** I2C Initialization

+ 8 - 2
Src/stm32g0xx_it.c

@@ -209,11 +209,17 @@ void DMA1_Channel1_IRQHandler(void)
 void DMA1_Channel2_3_IRQHandler(void)
 {
   /* USER CODE BEGIN DMA1_Channel2_3_IRQn 0 */
-
+  if (LL_DMA_IsActiveFlag_TC2(DMA1) != 0) {
+    DMA1->IFCR |= DMA_IFCR_CTCIF2; // reset IRQ flag
+    Flag.I2C_RX_End = 1;
+  }
   /* USER CODE END DMA1_Channel2_3_IRQn 0 */
 
   /* USER CODE BEGIN DMA1_Channel2_3_IRQn 1 */
-
+  if (LL_DMA_IsActiveFlag_TC3(DMA1) != 0) {
+    DMA1->IFCR |= DMA_IFCR_CTCIF3; // reset IRQ flag
+    Flag.I2C_TX_End = 1;
+  }
   /* USER CODE END DMA1_Channel2_3_IRQn 1 */
 }