Jelajahi Sumber

Hardwarise display of runnig string.

Vladimir N. Shilov 2 tahun lalu
induk
melakukan
566aa8cc7f
4 mengubah file dengan 73 tambahan dan 19 penghapusan
  1. 3 1
      inc/display.h
  2. 2 1
      inc/main.h
  3. 18 2
      src/board.c
  4. 50 15
      src/display.c

+ 3 - 1
inc/display.h

@@ -6,7 +6,8 @@
 #include "main.h"
 
 /* Exported constants */
-#define DISPLAY_COLUMNS   24
+#define DISPLAY_COLUMNS       24
+#define DISPLAY_REFRESH_MS    50
 
 /* Variables */
 extern uint8_t display_Buffer[];
@@ -22,5 +23,6 @@ void display_LedState(dis_en_t state);
 void display_Fill(uint8_t pattern);
 void display_Char(const uint8_t symb, uint8_t column);
 void display_String(const char * string, uint8_t repeat);
+void TIM16_IRQHandler(void);
 
 #endif /* _DISPLAY_H_ */

+ 2 - 1
inc/main.h

@@ -46,7 +46,8 @@ typedef struct t_flag {
   uint32_t I2C_TX_End:  1;
   uint32_t I2C_RX_Err:  1;
   uint32_t I2C_RX_End:  1;
-  uint32_t _reserv:    27;
+  uint32_t DISP_BSY:    1;
+  uint32_t _reserv:    26;
 } flag_t;
 extern volatile flag_t Flag;
 

+ 18 - 2
src/board.c

@@ -8,7 +8,7 @@ static void SPI1_Init(void);
 static void TIM1_Init(void);
 //static void TIM3_Init(void);
 //static void TIM14_Init(void);
-//static void TIM16_Init(void);
+static void TIM16_Init(void);
 static void TIM17_Init(void);
 //static void USART1_UART_Init(void);
 
@@ -56,7 +56,7 @@ void Board_Init(void)
   TIM1_Init();
 //  TIM3_Init();
 //  TIM14_Init();
-//  TIM16_Init();
+  TIM16_Init();
   TIM17_Init();
 //  USART1_UART_Init();
 }
@@ -204,6 +204,22 @@ static void TIM1_Init(void)
   TIM1->CCER = TIM_CCER_CC1E;
 }
 
+/**
+  * @brief TIM16 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void TIM16_Init(void)
+{
+  /* setup clock */
+  TIM16->PSC = (48000-1); // prescaler for 1 mS
+  TIM16->ARR = DISPLAY_REFRESH_MS; // auto reload value, mS
+  TIM16->CR1 = TIM_CR1_ARPE;
+  TIM16->BDTR = TIM_BDTR_MOE; // enable main output
+  TIM16->EGR = TIM_EGR_UG; // force timer update
+  TIM16->DIER = TIM_DIER_UIE; // Update interrupt enable
+}
+
 /**
   * @brief TIM17 Initialization Function
   * @param None

+ 50 - 15
src/display.c

@@ -2,6 +2,7 @@
 #include "font.h"
 #include "digits.h"
 
+/* Private typedefs */
 /* Private defines */
 #define FRAMEBUFFER_ROTATE
 
@@ -15,6 +16,14 @@
 /* private macros */
 /* Private variables */
 uint8_t display_Buffer[DISPLAY_COLUMNS] = {0};
+static struct Running_Sring {
+  uint8_t Buf[STR_BUF_SIZE];
+  int Repeat;
+  int k;
+  int j;
+} String = {0};
+
+uint32_t str_Repeat = 0;
 
 /* Privae fuctions */
 static void _display_WriteBits(uint16_t data, uint16_t nbits);
@@ -26,6 +35,10 @@ static void _delay_c(uint32_t cycle);
  * @brief Initialization HT1632C
  */
 void display_Init(void) {
+  /* stop display if running */
+  TIM16->CR1 &= ~(TIM_CR1_CEN);
+  Flag.DISP_BSY = 0;
+
   /* Wait for SPI */
   while ((SPI1->SR & SPI_SR_BSY) != 0) { __NOP(); }
 
@@ -72,26 +85,25 @@ void display_String(const char * string, uint8_t repeat) {
   if (repeat == 0) { return; }
   if (string[0] == 0) { return; }
 
-  uint8_t str_buf[STR_BUF_SIZE] = {0};
-  int i = 0, j = DISPLAY_COLUMNS, k=0;
+  /* wait if display is busy */
+  while (Flag.DISP_BSY != 0) { __NOP(); }
+  
+  String.Repeat = repeat; // charge global counter
+  String.j = DISPLAY_COLUMNS;
+
+  int i = 0, k=0;
   while ((string[i] != '\0') && (i < STR_BUF_SYM)) {
     for(k=0; k<FONT_WIDTH; k++) {
-      str_buf[j] = Font_6x8[(uint8_t)string[i]][k];
-      j ++;
+      String.Buf[String.j] = Font_6x8[(uint8_t)string[i]][k];
+      String.j ++;
     }
     i ++;
   }
-  
-  while (repeat) {
-    for (k=0; k<=j; k++) {
-      display_WriteBuf(&str_buf[k]);
-      tdelay_ms(50);
-    }
-    tdelay_ms(200);
 
-    /* End of man loop */
-    repeat --;
-  }
+  String.k = 0;
+  String.j ++;
+  Flag.DISP_BSY = 1;
+  TIM16->CR1 |= TIM_CR1_CEN; // start tim16 counter
 }
 
 /**
@@ -316,7 +328,7 @@ void display_WriteBuf(const uint8_t * buf) {
   DMA1_Channel3->CMAR = (uint32_t)&spi_buf[0];
 #else
   /* DMA Source addr: Address of the SPI buffer. */
-  DMA1_Channel3->CMAR = (uint32_t)&display_Buffer[0];
+  DMA1_Channel3->CMAR = (uint32_t)&buf[0];
 #endif /* FRAMEBUFFER_ROTATE */
 
   /* Set DMA data transfer length (SPI buffer length). */
@@ -346,3 +358,26 @@ void display_Fill(uint8_t pattern) {
   }
   display_WriteBuffer();
 }
+
+/**
+  * @brief This function handles TIM16 global interrupt.
+  */
+void TIM16_IRQHandler(void) {
+  if (TIM16->SR & TIM_SR_UIF) {
+    TIM16->SR = 0; // reset flag
+
+    display_WriteBuf(&String.Buf[String.k]);
+
+    String.k ++;
+    if (String.k > String.j) {
+      String.k = 0;
+
+      String.Repeat --;
+      if (String.Repeat == 0) {
+        Flag.DISP_BSY = 0;
+        TIM16->CR1 &= ~(TIM_CR1_CEN);
+      }
+
+    }
+  }
+}