Эх сурвалжийг харах

Added button handler, man creen begin.

Vladimir N. Shilov 1 жил өмнө
parent
commit
e2e445ff3e
6 өөрчлөгдсөн 279 нэмэгдсэн , 23 устгасан
  1. 93 0
      lib/buttons/buttons.c
  2. 42 0
      lib/buttons/buttons.h
  3. 4 3
      lib/lib.mk
  4. 44 0
      lib/main.h
  5. 19 0
      lib/st7735/st7735.c
  6. 77 20
      main.c

+ 93 - 0
lib/buttons/buttons.c

@@ -0,0 +1,93 @@
+#include <ch.h>
+#include <hal.h>
+#include "buttons.h"
+
+static btn_hndlr btnh[Button_Num];
+
+/* Constants */
+static const ioline_t button_Lines[Button_Num] = {
+  LINE_BTN_1, LINE_BTN_2, LINE_BTN_3, LINE_BTN_4
+}; /* from board.h */
+
+/* Variables */
+static binary_semaphore_t btn_bsem;
+static virtual_timer_t button_vt;
+static button_state_t button_States[Button_Num] = {0};
+static uint8_t button_Time[Button_Num] = {0};
+
+/* Functions */
+static void button_Process(virtual_timer_t *vtp, void *p) {
+  (void)vtp;
+  (void)p;
+
+  /* Entering I-Locked state and signaling the semaphore.*/
+  chSysLockFromISR();
+  chBSemSignalI(&btn_bsem);
+  chSysUnlockFromISR();
+}
+
+/*
+ * BTN serving thread.
+ */
+static THD_WORKING_AREA(waBTNThread, 256);
+static THD_FUNCTION(BTNThread, arg) {
+  (void)arg;
+  static int pause = 0;
+
+  while (true) {
+    /* Waiting for an binary semaphore. */
+    chBSemWait(&btn_bsem);
+
+    if (pause != 0) {
+      pause --;
+    } else {
+
+      int i;
+      for (i=0; i<Button_Num; i++) {
+
+        if (palReadLine(button_Lines[(button_num_t)i]) == BUTTON_PRESSED) {
+        /* button pressed */
+          button_Time[i] ++;
+          if (button_Time[i] >= BTN_TIME_HOLDED) {
+            /* process long press */
+            button_Time[i] -= BTN_TIME_REPEATED;
+            button_States[i] = BTN_st_Holded;
+            btnh[i](BTN_st_Pressed); // autorepeat
+          }
+
+        } else if (button_Time[i] != 0) {
+        /* button released */
+          if (button_Time[i] >= BTN_TIME_PRESSED) {
+            /* process short press */
+            button_States[i] = BTN_st_Pressed;
+            btnh[i](BTN_st_Pressed);
+          }
+          button_Time[i] = 0;
+          button_States[i] = BTN_st_Released;
+          pause = BTN_SCAN_PAUSE;
+          //btnh[i](BTN_st_Released);
+        }
+      } /* end FOR */
+    } /* end Pause check */
+  } /* end WHILE */
+}
+
+void buttons_Init(btn_hndlr ha[]) {
+  btnh[Button1] = ha[Button1];
+  btnh[Button2] = ha[Button2];
+  btnh[Button3] = ha[Button3];
+  btnh[Button4] = ha[Button4];
+
+  /* Initializing the Button semaphore in the "taken" state. */
+  chBSemObjectInit(&btn_bsem, true);
+
+  /* Starting the Button thread. */
+  chThdCreateStatic(waBTNThread, sizeof(waBTNThread), NORMALPRIO, BTNThread, NULL);
+
+  /* Starting a virtual timer ticking the thread. */
+  chVTSetContinuous(&button_vt, TIME_MS2I(BTN_SCAN_PERIOD), button_Process, NULL);
+}
+
+button_state_t buttons_GetState(const button_num_t btn) {
+  return button_States[btn];
+}

+ 42 - 0
lib/buttons/buttons.h

@@ -0,0 +1,42 @@
+#pragma once
+#ifndef _BUTTONS_H_
+#define _BUTTONS_H_
+
+/* time constant in ms */
+#define BTN_SCAN_PERIOD     10
+#define BTN_SCAN_PAUSE      (200/BTN_SCAN_PERIOD)
+#define BTN_TIME_PRESSED    (30/BTN_SCAN_PERIOD)
+#define BTN_TIME_HOLDED     (500/BTN_SCAN_PERIOD)
+#define BTN_TIME_REPEATED   (50/BTN_SCAN_PERIOD)
+#define BUTTON_PRESSED      PAL_LOW
+
+/* type defs */
+typedef enum btn_num {
+  Button1 = 0,
+  Button2 = 1,
+  Button3 = 2,
+  Button4 = 3,
+  Button_Num = 4
+} button_num_t;
+
+typedef enum btn_state {
+  BTN_st_Clear = 0,
+  BTN_st_Pressed,
+  BTN_st_Holded,
+  BTN_st_Released
+} button_state_t;
+
+/* Handler function type */
+typedef void (*btn_hndlr)(const button_state_t);
+
+/* function prototypes */
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void buttons_Init(btn_hndlr ha[]);
+  button_state_t buttons_GetState(const button_num_t btn);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _BUTTONS_H_ */

+ 4 - 3
lib/lib.mk

@@ -4,13 +4,14 @@ USERLIB = ./lib
 # List of all the Userlib files
 # List of all the Userlib files
 USERSRC =  $(USERLIB)/st7735/st7735.c \
 USERSRC =  $(USERLIB)/st7735/st7735.c \
 	$(USERLIB)/st7735/fonts.c \
 	$(USERLIB)/st7735/fonts.c \
-	$(USERLIB)/st7735/liberation_mono_7x10.c
-#	$(USERLIB)/eeprom/eeprom.c
+	$(USERLIB)/st7735/liberation_mono_7x10.c \
+	$(USERLIB)/buttons/buttons.c
           
           
 # Required include directories
 # Required include directories
 USERINC =  $(USERLIB) \
 USERINC =  $(USERLIB) \
            $(USERLIB)/st7735 \
            $(USERLIB)/st7735 \
-           $(USERLIB)/eeprom
+           $(USERLIB)/eeprom \
+           $(USERLIB)/buttons
 
 
 # Shared variables
 # Shared variables
 ALLCSRC += $(USERSRC)
 ALLCSRC += $(USERSRC)

+ 44 - 0
lib/main.h

@@ -0,0 +1,44 @@
+#pragma once
+#ifndef __MAIN_H__
+#define __MAIN_H__
+
+#include "buttons.h"
+
+/* Private defines */
+#define TOP_INFO_1_X  0
+#define TOP_INFO_1_Y  0
+#define TOP_INFO_2_X  120
+#define TOP_INFO_2_Y  0
+
+/* Private variables */
+
+/*
+ * SPI configuration structure.
+ * Speed 12 MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
+ * Soft slave select.
+ */
+static const SPIConfig spi1cfg = {
+  .circular         = false,
+  .slave            = false,
+  .data_cb          = NULL,
+  .error_cb         = NULL,
+  .cr1              = 0U,
+  .cr2              = 0U
+};
+
+/* Private function prototypes */
+static void btn1_handler(const button_state_t);
+static void btn2_handler(const button_state_t);
+static void btn3_handler(const button_state_t);
+static void btn4_handler(const button_state_t);
+static btn_hndlr bha[Button_Num] = {
+  btn1_handler,
+  btn2_handler,
+  btn3_handler,
+  btn4_handler
+};
+
+static void lcd_MainScreen(void);
+static void lcd_ClearMain(void);
+
+#endif /* __MAIN_H__ */

+ 19 - 0
lib/st7735/st7735.c

@@ -261,6 +261,16 @@ static void ST7735_WriteChar(uint16_t x, uint16_t y, char ch, FontDef font, uint
   SPI1->CR1 &= ~(SPI_CR1_DFF);
   SPI1->CR1 &= ~(SPI_CR1_DFF);
 }
 }
 
 
+/**
+ * @brief 
+ * 
+ * @param x from ST7735_XSTART to ST7735_WIDTH
+ * @param y from ST7735_YSTART to ST7735_HEIGHT
+ * @param str string to output
+ * @param font 
+ * @param color 
+ * @param bgcolor 
+ */
 void ST7735_WriteString(uint16_t x, uint16_t y, const char* str, FontDef font, uint16_t color, uint16_t bgcolor) {
 void ST7735_WriteString(uint16_t x, uint16_t y, const char* str, FontDef font, uint16_t color, uint16_t bgcolor) {
   ST7735_Select();
   ST7735_Select();
 
 
@@ -341,6 +351,15 @@ void ST7735_WriteString(uint16_t x, uint16_t y, const char* str, FontDef font, u
   ST7735_Unselect();
   ST7735_Unselect();
 }
 }
 
 
+/**
+ * @brief Draw line or filled rectangle
+ * 
+ * @param x from ST7735_XSTART to ST7735_WIDTH
+ * @param y from ST7735_YSTART to ST7735_HEIGHT
+ * @param w from 1 to ST7735_WIDTH
+ * @param h from 1 to ST7735_HEIGHT
+ * @param color 16-bit RGB565
+ */
 void ST7735_FillRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) {
 void ST7735_FillRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color) {
   // clipping
   // clipping
   if ((x >= ST7735_WIDTH) || (y >= ST7735_HEIGHT)) {
   if ((x >= ST7735_WIDTH) || (y >= ST7735_HEIGHT)) {

+ 77 - 20
main.c

@@ -22,24 +22,9 @@
 
 
 #include "chprintf.h"
 #include "chprintf.h"
 
 
+#include "main.h"
 #include "st7735.h"
 #include "st7735.h"
 
 
-/* Private variables */
-
-/*
- * SPI configuration structure.
- * Speed 12 MHz, CPHA=0, CPOL=0, 8bits frames, MSb transmitted first.
- * Soft slave select.
- */
-static const SPIConfig spi1cfg = {
-  .circular         = false,
-  .slave            = false,
-  .data_cb          = NULL,
-  .error_cb         = NULL,
-  .cr1              = 0U,
-  .cr2              = 0U
-};
-
 /*===========================================================================*/
 /*===========================================================================*/
 /* Generic code.                                                             */
 /* Generic code.                                                             */
 /*===========================================================================*/
 /*===========================================================================*/
@@ -89,10 +74,8 @@ int main(void) {
    * LCD
    * LCD
    */
    */
   ST7735_Init();
   ST7735_Init();
-  // draw tests
-  ST7735_FillScreen(Black);
-  ST7735_FillRectangle(ST7735_XSTART, ST7735_HEIGHT/2, ST7735_WIDTH, 1, Green);
-  ST7735_FillRectangle(ST7735_WIDTH/2, ST7735_YSTART, 1, ST7735_HEIGHT, Yellow);
+  lcd_MainScreen();
+  lcd_ClearMain();
 
 
   /*
   /*
    * Normal main() thread activity.
    * Normal main() thread activity.
@@ -101,3 +84,77 @@ int main(void) {
     chThdSleepMilliseconds(500);
     chThdSleepMilliseconds(500);
   }
   }
 }
 }
+
+/*
+ * Private functions
+ */
+/* numbers for screen 160x128 
+ * btn1 - 118, 1..38-FontWidh
+ * btn2 - 118, 40..78-FontWidh
+ * btn3 - 118, 80..118-FontWidh
+ * btn4 - 118, 120..158-FontWidh
+ * 
+ * main screen 0,20 .. 159,117
+ */
+static void lcd_MainScreen(void) {
+  ST7735_FillScreen(Black);
+
+  ST7735_WriteString(47, 48, "Heater", Font_11x18, Yellow, Black);
+  ST7735_WriteString(52, 68, "Power", Font_11x18, Yellow, Black);
+  ST7735_WriteString(25, 88, "Stabilizer", Font_11x18, Yellow, Black);
+  chThdSleepMilliseconds(2000);
+
+  /* top info line */
+  ST7735_FillRectangle(0, 18, ST7735_WIDTH, 1, White);
+  ST7735_FillRectangle( 119, 0, 1, 18, White); // separator
+
+  ST7735_WriteString(0, 0, "Line V", Font_11x18, Red, Black);
+  ST7735_WriteString(120, 0, "Heater W", Font_11x18, Red, Black);
+
+  /* bottom status line */
+  ST7735_FillRectangle(0, 117, ST7735_WIDTH, 1, White);
+  ST7735_FillRectangle( 39, 117, 1, 11, White); // separator btn1/btn2
+  ST7735_FillRectangle( 79, 117, 1, 11, White); // separator btn2/btn3
+  ST7735_FillRectangle(119, 117, 1, 11, White); // separator btn3/btn4
+
+  ST7735_WriteString(0, 118, "  +  ", LiberM_7x10, Silver, Black);
+  ST7735_WriteString(40, 118, "  -  ", LiberM_7x10, Silver, Black);
+  ST7735_WriteString(80, 118, "  R  ", LiberM_7x10, Silver, Black);
+  ST7735_WriteString(120, 118, "  S  ", LiberM_7x10, Silver, Black);
+}
+
+static void lcd_ClearMain(void) {
+  ST7735_FillRectangle(0, 20, ST7735_WIDTH, 97, Black);
+}
+
+static void btn1_handler(const button_state_t) {
+  if (state == BTN_st_Pressed) {
+    ST7735_WriteString(0, 118, "  +  ", LiberM_7x10, Black, Grey);
+    chThdSleepMilliseconds(500);
+    ST7735_WriteString(0, 118, "  +  ", LiberM_7x10, Silver, Black);
+  }
+}
+
+static void btn2_handler(const button_state_t) {
+  if (state == BTN_st_Pressed) {
+    ST7735_WriteString(40, 118, "  -  ", LiberM_7x10, Black, Grey);
+    chThdSleepMilliseconds(500);
+    ST7735_WriteString(40, 118, "  -  ", LiberM_7x10, Silver, Black);
+  }
+}
+
+static void btn3_handler(const button_state_t) {
+  if (state == BTN_st_Pressed) {
+    ST7735_WriteString(80, 118, "  R  ", LiberM_7x10, Black, Grey);
+    chThdSleepMilliseconds(500);
+    ST7735_WriteString(80, 118, "  R  ", LiberM_7x10, Silver, Black);
+  }
+}
+
+static void btn4_handler(const button_state_t) {
+  if (state == BTN_st_Pressed) {
+    ST7735_WriteString(120, 118, "  S  ", LiberM_7x10, Black, Grey);
+    chThdSleepMilliseconds(500);
+    ST7735_WriteString(120, 118, "  S  ", LiberM_7x10, Silver, Black);
+  }
+}