瀏覽代碼

Implemended UI and preferences

Aleksandr Nagaev 2 年之前
父節點
當前提交
2826edcf69

+ 4 - 3
stm32workspace/dosim-v1/.cproject

@@ -23,7 +23,8 @@
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board.1426940695" name="Board" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.target_board" useByScannerDiscovery="false" value="genericBoard" valueType="string"/>
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults.567196427" name="Defaults" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.defaults" useByScannerDiscovery="false" value="com.st.stm32cube.ide.common.services.build.inputs.revA.1.0.5 || Debug || true || Executable || com.st.stm32cube.ide.mcu.gnu.managedbuild.option.toolchain.value.workspace || STM32L151CBTxA || 0 || 0 || arm-none-eabi- || ${gnu_tools_for_stm32_compiler_path} || ../USB_DEVICE/Target | ../Drivers/CMSIS/Include | ../Core/Inc | ../Drivers/STM32L1xx_HAL_Driver/Inc | ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc | ../Drivers/CMSIS/Device/ST/STM32L1xx/Include | ../USB_DEVICE/App | ../Drivers/STM32L1xx_HAL_Driver/Inc/Legacy | ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc ||  ||  || USE_HAL_DRIVER | STM32L151xBA ||  || Drivers | Core/Startup | Middlewares | Core | USB_DEVICE ||  ||  || ${workspace_loc:/${ProjName}/STM32L151CBTXA_FLASH.ld} || true || NonSecure ||  || secure_nsclib.o ||  || None || " valueType="string"/>
 							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat.198395130" name="Use float with printf from newlib-nano (-u _printf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoprintffloat" useByScannerDiscovery="false" value="true" valueType="boolean"/>
-							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.runtimelibrary_c.112572928" name="Runtime library" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.runtimelibrary_c" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.runtimelibrary_c.value.nano_c" valueType="enumerated"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.runtimelibrary_c.112572928" name="Runtime library" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.runtimelibrary_c" useByScannerDiscovery="true" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.runtimelibrary_c.value.standard_c" valueType="enumerated"/>
+							<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoscanffloat.1515808708" name="Use float with scanf from newlib-nano (-u _scanf_float)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.option.nanoscanffloat" useByScannerDiscovery="false" value="false" valueType="boolean"/>
 							<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform.2086352505" isAbstract="false" osList="all" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.targetplatform"/>
 							<builder buildPath="${workspace_loc:/dosim-v1}/Debug" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder.323666062" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.builder"/>
 							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.1928633960" name="MCU GCC Assembler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler">
@@ -34,8 +35,8 @@
 								<inputType id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input.885004739" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.assembler.input"/>
 							</tool>
 							<tool id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.1791648462" name="MCU GCC Compiler" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler">
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1502785008" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g3" valueType="enumerated"/>
-								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.1171980655" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false"/>
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.1502785008" name="Debug level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.debuglevel.value.g0" valueType="enumerated"/>
+								<option id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.1171980655" name="Optimization level" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level" useByScannerDiscovery="false" value="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.optimization.level.value.os" valueType="enumerated"/>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols.1001817415" name="Define symbols (-D)" superClass="com.st.stm32cube.ide.mcu.gnu.managedbuild.tool.c.compiler.option.definedsymbols" useByScannerDiscovery="false" valueType="definedSymbols">
 									<listOptionValue builtIn="false" value="DEBUG"/>
 									<listOptionValue builtIn="false" value="USE_HAL_DRIVER"/>

File diff suppressed because it is too large
+ 0 - 0
stm32workspace/dosim-v1/.mxproject


+ 20 - 0
stm32workspace/dosim-v1/Core/Inc/main.h

@@ -65,6 +65,26 @@ void Error_Handler(void);
 #define COMP_THRESHOLD_VOLTAGE		135
 
 typedef enum { OFF = 0, ON = 1 } OnOff_t;
+
+typedef struct {
+  struct {
+    int Volume;
+    int Tone;
+    int Buttons;
+  } Sound;
+  struct {
+    int DoseRate;
+    int TotalDose;
+    int SoundType;
+    int Volume;
+  } Alarm;
+  struct {
+    int Brightness;
+    int DispOffMin;
+    int ShutdownMin;
+  } Energy;
+} Settings_td;
+
 /* USER CODE END Private defines */
 
 #ifdef __cplusplus

+ 22 - 14
stm32workspace/dosim-v1/Core/Inc/menu.h

@@ -1,26 +1,34 @@
 /*
  * menu.h
  *
- *  Created on: Jan 26, 2022
+ *  Created on: 1 февр. 2022 г.
  *      Author: radioman
  */
 
-#ifndef INC_MENU_H_
-#define INC_MENU_H_
+#ifndef MENU_H_
+#define MENU_H_
 
 #include <stdint.h>
 
-typedef enum { ENTRY_DIR, ENTRY_DISPLAY, ENTRY_NUMBER, ENTRY_CHECKBOX } entry_type;
+typedef enum { ENTRY_DIR = 'D', ENTRY_ACTION = 'A', ENTRY_PREF = 'P', ENTRY_CHECK = 'C',
+         ENTRY_RADIO = 'R', ENTRY_BACK = 'B' } entry_type;
 
-typedef struct {
-	uint8_t id;
-	entry_type type;
-	uint8_t selected;
-	uint8_t active;
-	uint8_t parent_id;
-	char *title;
-} menu_entry_td;
+typedef struct itemDesc {
+  uint8_t id;
+  entry_type type;
+  uint8_t checked;
+  uint8_t pref;
+  uint8_t level;
+  struct itemDesc *prev;
+  struct itemDesc *next;
+  struct itemDesc *child;
+  struct itemDesc *parent;
+  char title[20];
+} menu_td;
 
-void MenuShow(uint8_t id);
+void MenuShow();
+void MenuInit();
+void MenuScroll();
+void MenuEnter();
 
-#endif /* INC_MENU_H_ */
+#endif /* MENU_H_ */

+ 47 - 0
stm32workspace/dosim-v1/Core/Inc/preferences.h

@@ -0,0 +1,47 @@
+/*
+ * preferences.h
+ *
+ *  Created on: Feb 22, 2022
+ *      Author: radioman
+ */
+
+#ifndef INC_PREFERENCES_H_
+#define INC_PREFERENCES_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define PREF_COUNT 12
+
+#define PREF_DEFAULT_VALUES { \
+/* PREF_NAME          VALUE, STEP, MAX_VAL, UNSAVED */ \
+/* Placeholder      */  { 0, 0, 0, 0 }, \
+/* SOUND_VOLUME     */  { 5, 1, 9, 0 }, \
+/* SOUND_TONE       */  { 5, 1, 9, 0 }, \
+/* SOUND_BUTTONS    */  { 0, 1, 1, 0 }, \
+/* ALARM_DOSERATE   */  { 0, 0, 0, 0 }, \
+/* ALARM_TOTALDOSE  */  { 0, 0, 0, 0 }, \
+/* ALARM_SOUNDTYPE  */  { 0, 1, 4, 0 }, \
+/* ALARM_VOLUME     */  { 5, 1, 9, 0 }, \
+/* ENERGY_BRIGHT    */  { 5, 1, 9, 0 }, \
+/* ENERGY_DISPOFF   */  { 0, 1, 20, 0 },\
+/* ENERGY_SHUTDOWN  */  { 0, 5, 60, 0 } }
+
+typedef struct {
+  int value;
+  int step;
+  int max_val;
+  bool unsaved;
+} Pref_td;
+
+typedef enum { PREF_SOUND_VOLUME = 1, PREF_SOUND_TONE, PREF_SOUND_BUTTONS,
+               PREF_ALARM_DOSERATE, PREF_ALARM_TOTALDOSE, PREF_ALARM_SOUNDTYPE, PREF_ALARM_VOLUME,
+               PREF_ENERGY_BRIGHT, PREF_ENERGY_DISPOFF, PREF_ENERGY_SHUTDOWN } PrefNames_t;
+
+void PrefIncValue(PrefNames_t PrefName);
+void PrefSetValue(PrefNames_t PrefName, int value);
+int PrefGetValue(PrefNames_t PrefName);
+void PrefSaveToFlash();
+void PrefLoadFromFlash();
+
+#endif /* INC_PREFERENCES_H_ */

+ 161 - 104
stm32workspace/dosim-v1/Core/Src/main.c

@@ -27,6 +27,7 @@
 #include "uartio.h"
 #include "commprt.h"
 #include "menu.h"
+#include "preferences.h"
 #include "ssd1306_tests.h"
 #include <stdlib.h>
 #include <stdio.h>
@@ -61,6 +62,7 @@ DAC_HandleTypeDef hdac;
 I2C_HandleTypeDef hi2c1;
 I2C_HandleTypeDef hi2c2;
 
+TIM_HandleTypeDef htim2;
 TIM_HandleTypeDef htim3;
 TIM_HandleTypeDef htim4;
 TIM_HandleTypeDef htim6;
@@ -87,41 +89,7 @@ volatile struct {
 } Flags;
 
 volatile uint32_t pulses = 0;
-
-uint32_t Wave_LUT[] = {
-		0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,
-		0x98,0x9b,0x9e,0xa2,0xa5,0xa7,0xaa,0xad,
-		0xb0,0xb3,0xb6,0xb9,0xbc,0xbe,0xc1,0xc4,
-		0xc6,0xc9,0xcb,0xce,0xd0,0xd3,0xd5,0xd7,
-		0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,
-		0xea,0xeb,0xed,0xee,0xf0,0xf1,0xf3,0xf4,
-		0xf5,0xf6,0xf8,0xf9,0xfa,0xfa,0xfb,0xfc,
-		0xfd,0xfd,0xfe,0xfe,0xfe,0xff,0xff,0xff,
-		0xff,0xff,0xff,0xff,0xfe,0xfe,0xfe,0xfd,
-		0xfd,0xfc,0xfb,0xfa,0xfa,0xf9,0xf8,0xf6,
-		0xf5,0xf4,0xf3,0xf1,0xf0,0xee,0xed,0xeb,
-		0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
-		0xda,0xd7,0xd5,0xd3,0xd0,0xce,0xcb,0xc9,
-		0xc6,0xc4,0xc1,0xbe,0xbc,0xb9,0xb6,0xb3,
-		0xb0,0xad,0xaa,0xa7,0xa5,0xa2,0x9e,0x9b,
-		0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
-		0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,
-		0x67,0x64,0x61,0x5d,0x5a,0x58,0x55,0x52,
-		0x4f,0x4c,0x49,0x46,0x43,0x41,0x3e,0x3b,
-		0x39,0x36,0x34,0x31,0x2f,0x2c,0x2a,0x28,
-		0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,
-		0x15,0x14,0x12,0x11,0xf,0xe,0xc,0xb,
-		0xa,0x9,0x7,0x6,0x5,0x5,0x4,0x3,
-		0x2,0x2,0x1,0x1,0x1,0x0,0x0,0x0,
-		0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x2,
-		0x2,0x3,0x4,0x5,0x5,0x6,0x7,0x9,
-		0xa,0xb,0xc,0xe,0xf,0x11,0x12,0x14,
-		0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
-		0x25,0x28,0x2a,0x2c,0x2f,0x31,0x34,0x36,
-		0x39,0x3b,0x3e,0x41,0x43,0x46,0x49,0x4c,
-		0x4f,0x52,0x55,0x58,0x5a,0x5d,0x61,0x64,
-		0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c,
-};
+uint8_t screen = 0;
 
 /* USER CODE END PV */
 
@@ -139,6 +107,7 @@ static void MX_TIM4_Init(void);
 static void MX_TIM3_Init(void);
 static void MX_I2C1_Init(void);
 static void MX_CRC_Init(void);
+static void MX_TIM2_Init(void);
 /* USER CODE BEGIN PFP */
 
 /* USER CODE END PFP */
@@ -194,11 +163,16 @@ void SwitchPeriphSupply(OnOff_t state)
     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
 }
 
-void Beep()
+void Beep(uint8_t tone, uint8_t volume, uint8_t duration)
 {
-	//HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_4, Wave_LUT, sizeof(Wave_LUT) / 4);
-    //HAL_TIM_Base_Stop(&htim2);
-    //HAL_TIM_Base_Start(&htim2);
+  HAL_TIM_OC_Stop(&htim3, TIM_CHANNEL_4);
+  HAL_TIM_Base_Stop(&htim2);
+
+  htim3.Instance->CCR4 = volume * 5;
+  htim3.Instance->ARR = 2000 / (1 + tone);
+
+  HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_4);
+  HAL_TIM_Base_Start(&htim2);
 }
 
 /* USER CODE END 0 */
@@ -242,6 +216,7 @@ int main(void)
   MX_I2C1_Init();
   MX_USB_DEVICE_Init();
   MX_CRC_Init();
+  MX_TIM2_Init();
   /* USER CODE BEGIN 2 */
 
   Switch3V3Regulator(ON);
@@ -268,89 +243,120 @@ int main(void)
   HAL_COMP_Start_IT(&hcomp2);
   HAL_TIM_Base_Start_IT(&htim6);
   HAL_TIM_Base_Start_IT(&htim4);
-  //HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_4);
+  HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_4);
 
   UARTIO_Init(&huart1);
 
+  MenuInit();
+  PrefLoadFromFlash();
+
   /* USER CODE END 2 */
 
   /* Infinite loop */
   /* USER CODE BEGIN WHILE */
   char tempstr[32];
 
-  uint8_t imgbuffer[172];
-
   uint32_t pps = 0;
   uint32_t pps_avg = 0;
   uint32_t total_dose = 0;
   uint8_t pwdn_cnt = 0;
-  uint8_t window = 0;
 
   Flags.Exti = 0;
 
-  //ssd1306_SetContrast(60);
-  //ssd1306_TestAll();
-  Beep();
-
   while (1)
   {
-	  if(window == 1)
-	  {
-		  if(COMM_Receive(imgbuffer, COMM_USB, 200) == COMM_OK)
-		  {
-			  ssd1306_Fill(Black);
-			  for(int y = 0; y < 32; y++)
-			  {
-				  for(int x = 0; x < 43; x++)
-				  {
-					  uint16_t pos = (y * 43) + x;
-					  if(imgbuffer[pos / 8] & (1 << (pos % 8)))
-						  ssd1306_DrawPixel(x + 43, y, White);
-				  }
-			  }
-			  ssd1306_UpdateScreen();
-		  }
-	  }
-
     if(Flags.Exti)
     {
     	uint16_t btn = Flags.Exti;
     	Flags.Exti = 0;
+    	if(btn == GPIO_PIN_14)
+    	{
+    	  if(screen == 50)
+    	    MenuScroll();
+    	}
+
     	if(btn == GPIO_PIN_15)
     	{
-    		window ^= 1;
-    		ssd1306_Fill(Black);
-    		ssd1306_UpdateScreen();
+    	  if(screen == 50)
+    	    MenuEnter();
+        else
+          screen = 50;
     	}
     }
 
+    switch(screen)
+    {
+      case 0:
+        ssd1306_Fill(Black);
+        ssd1306_DrawRectangle(0, 0, SSD1306_WIDTH - 1, SSD1306_HEIGHT - 1, White);
+        ssd1306_SetCursor(1, 7);
+        sprintf(tempstr, "%5.2f uSv/h", (float)pps_avg / 100.0);
+        ssd1306_WriteString(tempstr, Font_11x18, White);
+        ssd1306_UpdateScreen();
+        break;
+
+      case 1:
+        ssd1306_Fill(Black);
+        ssd1306_DrawRectangle(0, 0, SSD1306_WIDTH - 1, SSD1306_HEIGHT - 1, White);
+        ssd1306_SetCursor(1, 7);
+        sprintf(tempstr, "%5.2f uSv", (float)total_dose / 360000.0);
+        ssd1306_WriteString(tempstr, Font_11x18, White);
+        ssd1306_UpdateScreen();
+        break;
+
+      case 2:
+        ssd1306_Fill(Black);
+        ssd1306_DrawRectangle(0, 0, SSD1306_WIDTH - 1, SSD1306_HEIGHT - 1, White);
+        ssd1306_SetCursor(1, 7);
+        sprintf(tempstr, "00:00:00");
+        ssd1306_WriteString(tempstr, Font_11x18, White);
+        ssd1306_UpdateScreen();
+        break;
+
+      case 3: // < DEBUG SCREEN >
+        ssd1306_Fill(Black);
+        ssd1306_DrawRectangle(0, 0, SSD1306_WIDTH - 1, SSD1306_HEIGHT - 1, White);
+        ssd1306_SetCursor(1, 7);
+        //sprintf(tempstr, "%lx", (uint32_t)&saved_settings);
+        ssd1306_WriteString(tempstr, Font_7x10, White);
+        ssd1306_UpdateScreen();
+        break;
+
+      case 44:
+        ssd1306_Fill(Black);
+        ssd1306_DrawRectangle(0, 0, SSD1306_WIDTH - 1, SSD1306_HEIGHT - 1, White);
+        ssd1306_SetCursor(1, 7);
+        sprintf(tempstr, "Balaboliya");
+        ssd1306_WriteString(tempstr, Font_11x18, White);
+        ssd1306_UpdateScreen();
+        break;
+
+      default:
+        MenuShow();
+        break;
+    }
+
     if(Flags.Tim6)
     {
-      int rcvlen = CDC_ReadData(imgbuffer, sizeof(imgbuffer));
-      if(rcvlen > 0)
-    	  UARTIO_Transmit(imgbuffer, rcvlen);
+      Flags.Tim6 = 0;
 
-      rcvlen = UARTIO_Receive(imgbuffer, sizeof(imgbuffer));
-      if(rcvlen > 0)
-    	  CDC_WriteData(imgbuffer, rcvlen);
+      ssd1306_SetContrast((PrefGetValue(PREF_ENERGY_BRIGHT) + 1) * 23);
 
-      Flags.Tim6 = 0;
       HAL_ADC_Stop_DMA(&hadc);
 
       if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14) == GPIO_PIN_RESET)
       {
-		if(++pwdn_cnt > 10)
-		{
-		  ssd1306_Reset();
-		  SwitchPeriphSupply(OFF);
-		  HAL_I2C_DeInit(&hi2c1);
-		  HAL_I2C_DeInit(&hi2c2);
-		  HAL_UART_DeInit(&huart1);
-		  HAL_GPIO_DeInit(GPIOB, GPIO_PIN_All);
-		  HAL_GPIO_DeInit(GPIOA, GPIO_PIN_All);
-		  HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
-
-		}
+        if(++pwdn_cnt > 10)
+        {
+          ssd1306_Reset();
+          SwitchPeriphSupply(OFF);
+          HAL_I2C_DeInit(&hi2c1);
+          HAL_I2C_DeInit(&hi2c2);
+          HAL_UART_DeInit(&huart1);
+          HAL_GPIO_DeInit(GPIOB, GPIO_PIN_All);
+          HAL_GPIO_DeInit(GPIOA, GPIO_PIN_All);
+          HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_STOPENTRY_WFI);
+        }
       }
       else
       {
@@ -366,19 +372,13 @@ int main(void)
         pps_avg = (pps + pps_avg) / 2;
       }
 
-      if(window == 0)
-      {
-    	  ssd1306_DrawRectangle(0, 0, SSD1306_WIDTH - 1, SSD1306_HEIGHT - 1, White);
-    	  ssd1306_SetCursor(1, 7);
-		  sprintf(tempstr, "%5.2f uSv/h", (float)pps_avg / 100.0);
-		  ssd1306_WriteString(tempstr, Font_11x18, White);
-		  ssd1306_UpdateScreen();
-      }
-      else
-      {
-    	  //ssd1306_SetCursor(2, 2);
-    	  //ssd1306_WriteString(tempstr, Font_7x10, White);
-      }
+      /*
+      ssd1306_DrawRectangle(0, 0, SSD1306_WIDTH - 1, SSD1306_HEIGHT - 1, White);
+      ssd1306_SetCursor(1, 7);
+      sprintf(tempstr, "%5.2f uSv/h", (float)pps_avg / 100.0);
+      ssd1306_WriteString(tempstr, Font_11x18, White);
+      ssd1306_UpdateScreen();
+       */
 
       SetDACVoltage(DAC_CHANNEL_1, SIPM_BIAS_VOLTAGE_OFFSET);
       SetDACVoltage(DAC_CHANNEL_2, COMP_THRESHOLD_VOLTAGE);
@@ -395,13 +395,14 @@ int main(void)
 
       pps = (pulses * 100000) / elapsed;
 
+      total_dose += pulses;
+
       pulses = 0;
       Flags.Tim4 = 0;
       htim4.Instance->CNT = 0;
       HAL_TIM_Base_Start(&htim4);
 
-      //if(window == 0)
-    	//  Beep();
+      Beep(PrefGetValue(PREF_SOUND_TONE), PrefGetValue(PREF_SOUND_VOLUME), 100);
     }
 
     /* USER CODE END WHILE */
@@ -693,6 +694,55 @@ static void MX_I2C2_Init(void)
 
 }
 
+/**
+  * @brief TIM2 Initialization Function
+  * @param None
+  * @retval None
+  */
+static void MX_TIM2_Init(void)
+{
+
+  /* USER CODE BEGIN TIM2_Init 0 */
+
+  /* USER CODE END TIM2_Init 0 */
+
+  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
+  TIM_MasterConfigTypeDef sMasterConfig = {0};
+
+  /* USER CODE BEGIN TIM2_Init 1 */
+
+  /* USER CODE END TIM2_Init 1 */
+  htim2.Instance = TIM2;
+  htim2.Init.Prescaler = 600;
+  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
+  htim2.Init.Period = 1000;
+  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
+  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
+  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
+  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  if (HAL_TIM_OnePulse_Init(&htim2, TIM_OPMODE_SINGLE) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;
+  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
+  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
+  {
+    Error_Handler();
+  }
+  /* USER CODE BEGIN TIM2_Init 2 */
+
+  /* USER CODE END TIM2_Init 2 */
+
+}
+
 /**
   * @brief TIM3 Initialization Function
   * @param None
@@ -706,6 +756,7 @@ static void MX_TIM3_Init(void)
   /* USER CODE END TIM3_Init 0 */
 
   TIM_ClockConfigTypeDef sClockSourceConfig = {0};
+  TIM_SlaveConfigTypeDef sSlaveConfig = {0};
   TIM_MasterConfigTypeDef sMasterConfig = {0};
   TIM_OC_InitTypeDef sConfigOC = {0};
 
@@ -713,9 +764,9 @@ static void MX_TIM3_Init(void)
 
   /* USER CODE END TIM3_Init 1 */
   htim3.Instance = TIM3;
-  htim3.Init.Prescaler = 0;
+  htim3.Init.Prescaler = 48;
   htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
-  htim3.Init.Period = 255;
+  htim3.Init.Period = 1000;
   htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
   htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
   if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
@@ -731,6 +782,12 @@ static void MX_TIM3_Init(void)
   {
     Error_Handler();
   }
+  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_GATED;
+  sSlaveConfig.InputTrigger = TIM_TS_ITR1;
+  if (HAL_TIM_SlaveConfigSynchro(&htim3, &sSlaveConfig) != HAL_OK)
+  {
+    Error_Handler();
+  }
   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
   if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)

+ 235 - 69
stm32workspace/dosim-v1/Core/Src/menu.c

@@ -1,90 +1,256 @@
 /*
  * menu.c
  *
- *  Created on: Jan 26, 2022
+ *  Created on: 1 февр. 2022 г.
  *      Author: radioman
  */
 
-/*
-Menu Structure:
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "menu.h"
+#include "ssd1306.h"
+#include "preferences.h"
 
-Dose rate measure
+static const char *menu_template[] = {\
+"A, 0, 0, Dose rate",
+"A, 0, 0, Total dose",
+"A, 0, 0, Up time",
+"A, 0, 0, Debug",
+"D, 0, 0, Settings",
+  "D, 0, 1, Sound",
+    "P, 1, 2, Volume",
+    "P, 2, 2, Tone",
+    "P, 3, 2, Buttons",
+    "B, 0, 2, Back",
+  "D, 0, 1, Alarm",
+    "D, 0, 2, Dose rate alarm",
+      "R, 4, 3, OFF",
+      "R, 4, 3, 0.5 uSv/h",
+      "R, 4, 3, 1 uSv/h",
+      "R, 4, 3, 10 uSv/h",
+      "R, 4, 3, 100 uSv/h",
+      "R, 4, 3, 1 mSv/h",
+      "R, 4, 3, 10 mSv/h",
+      "R, 4, 3, 100 mSv/h",
+      "R, 4, 3, 1 Sv/h",
+      "B, 0, 3, Back",
+    "D, 0, 2, Total dose alarm",
+      "R, 5, 3, OFF",
+      "R, 5, 3, 1 uSv",
+      "R, 5, 3, 10 uSv",
+      "R, 5, 3, 100 uSv",
+      "R, 5, 3, 1 mSv",
+      "R, 5, 3, 10 uSv",
+      "R, 5, 3, 100 uSv",
+      "R, 5, 3, 1 Sv",
+      "R, 5, 3, 10 Sv",
+      "R, 5, 3, 100 Sv",
+      "B, 0, 3, Back",
+    "P, 6, 2, Sound type",
+    "P, 7, 2, Volume",
+    "B, 0, 2, Back",
+  "D, 0, 1, Energy saving",
+    "P, 8, 2, Brightness",
+    "P, 9, 2, Disp.off min",
+    "P, 10, 2, Shutdown min",
+    "B, 0, 2, Back",
+  "B, 0, 1, Back",
+"A, 0, 0, Info" };
 
-Total dose measure
-	Reset total dose
+static menu_td menu_items[sizeof(menu_template) / sizeof(char*)];
+static menu_td *menu = &menu_items[0];
+static uint8_t scroll = 0;
 
-Time
-	Reset timer
+extern uint8_t screen;
 
-Settings:
-	Measurement settings:
-		Reset total dose
+char * capstring(char *dest, const char *source)
+{
+  while(*source)
+  {
+    unsigned char c = *source++;
+    // ASCII & CP1251 Cyrillic
+    if((c >= 'a' && c <= 'z') || (c >= 0xe0 && c <= 0xff))
+      c -= 32;
+    *dest++ = c;
+  }
+  *dest = 0;
+  return dest;
+}
 
-	Sound settings:
-		Sound volume
-		Sound type
-		Buttons volume
-		Back
+void MenuInit()
+{
+  uint8_t items_total = sizeof(menu_template) / sizeof(char*);
+  char type;
+  int max_level = 0;
 
-	Alarm settings:
-		Alarm at dose rate
-		Alarm at dose
-		Alarm sound type
-		Alarm volume
-		Back
+  for(int i = 0; i < items_total; i++)
+  {
+    menu_items[i].id = i;
+    sscanf(menu_template[i], "%c, %hhu, %hhu, %[^\n]",
+        &type, &(menu_items[i].pref), &(menu_items[i].level), menu_items[i].title);
+    menu_items[i].type = (entry_type)type;
 
-	Energy-saving settings
-		Display auto-shutdown
-		Device auto-shutdown
-		Back
+    if(menu_items[i].level > max_level)
+      max_level = menu_items[i].level;
+  }
 
-About
-*/
+  /* Iterating through menu levels (complicated algorithm)*/
+  for(int lvl = 0; lvl <= max_level; lvl++)
+  {
+    /* prev - previous entry ID on current level,
+     * first - ID of first entry on current level */
+    int prev = 0, first = -1;
+    for(int i = 0; i < items_total; i++)
+    {
+      if(menu_items[i].level == lvl)
+      {
+        if(first < 0)
+        {
+          prev = first = i;
+        }
+        else
+        {
+          menu_items[prev].next = &menu_items[i];
+          menu_items[i].prev = &menu_items[prev];
+          prev = i;
+        }
 
-#include "menu.h"
-#include "ssd1306.h"
+        /* At levels higher than 0 we assign parent and child pointers
+         * All children have the same parent at one level
+         * Parent always is the closest entry on lower level */
+        if(lvl > 0)
+        {
+          menu_items[i].parent = &menu_items[first - 1];
+          menu_items[first - 1].child = &menu_items[first];
+        }
+      }
+      /* When we reaching entry that have lower level than our last entry
+       * we need to close scroll loop by assigning 'next' pointer of last entry
+       * to first entry on current level and reset 'first' variable
+       * Also we need to do this if it is the last cycle of whole loop */
+      if((first >= 0) && ((menu_items[i].level < menu_items[prev].level) || (i == (items_total - 1))))
+      {
+        menu_items[first].prev = &menu_items[prev];
+        menu_items[prev].next = &menu_items[first];
+        first = -1;
+      }
+    }
+  }
+}
+
+void MenuScroll()
+{
+  scroll = 1;
+  menu = menu->next;
+}
+
+void MenuEnter()
+{
+  switch(menu->type)
+  {
+    case ENTRY_DIR:
+      menu = menu->child;
+      break;
+    case ENTRY_ACTION:
+      screen = menu->id;
+      //PrefSetValue(menu->pref, menu->id);
+      //*(prefs[menu->pref].prefptr) = menu->id;
+      break;
+    case ENTRY_PREF:
+      PrefIncValue(menu->pref);
+      // *(prefs[menu->pref].prefptr) = (*(prefs[menu->pref].prefptr) +
+      //    prefs[menu->pref].step) % (prefs[menu->pref].max_val + 1);
+      break;
+    case ENTRY_BACK:
+      menu = menu->parent;
+      break;
+    case ENTRY_CHECK:
+      PrefSetValue(menu->pref, PrefGetValue(menu->pref) ^ 1);
+      //*(prefs[menu->pref].prefptr) ^= 1;
+      break;
+    case ENTRY_RADIO:
+      PrefSetValue(menu->pref, menu->id - menu->parent->child->id);
+      //*(prefs[menu->pref].prefptr) = menu->id - menu->parent->child->id;
+      break;
+  }
+}
 
-static menu_entry_td menu[] = { \
-	{ .title = "Dose rate measure",  .id = 1, .parent_id = 0 },
-	{ .title = "Total dose measure", .id = 2, .parent_id = 0 },
-	{ .title = "Up Time",            .id = 3, .parent_id = 0 },
-	{ .title = "Settings",			 .id = 4, .parent_id = 0 },
-		{ .title = "Sound",				.id = 5, .parent_id = 3 },
-			{ .title = "Sound volume",		 .id = 6, .parent_id = 4 },
-			{ .title = "Sound type",		 .id = 7, .parent_id = 4 },
-			{ .title = "Button sound",		 .id = 8, .parent_id = 4 },
-			{ .title = "Back",				 .id = 9, .parent_id = 4 },
-		{ .title = "Alarm",				.id = 10, .parent_id = 3 },
-			{ .title = "Alarm at dose rate", .id = 11, .parent_id = 9 },
-			{ .title = "Alarm at dose",		 .id = 12, .parent_id = 9 },
-			{ .title = "Alarm sound type",	 .id = 13, .parent_id = 9 },
-			{ .title = "Alarm volume",		 .id = 14, .parent_id = 9 },
-			{ .title = "Back",				 .id = 15, .parent_id = 9 },
-		{ .title = "Energy-saving",		.id = 16, .parent_id = 3 },
-			{ .title = "Display auto-shutdown", .id = 17, .parent_id = 15 },
-			{ .title = "Device auto-shutdown",	.id = 18, .parent_id = 15 },
-			{ .title = "Back",					.id = 19, .parent_id = 15 },
-	{ .title = "Information",		.id = 20, .parent_id = 0 }
-};
-
-menu_entry_td* GetMenuEntry(uint8_t id)
+void PrintMenuHeader()
 {
-	return &menu[id];
+  char tempstr[30];
+  if(menu->parent == NULL)
+    strcpy(tempstr, "MAIN MENU");
+  else
+    capstring(tempstr, menu->parent->title);
+
+  ssd1306_Line(0, 0, 127, 0, White);
+  ssd1306_SetCursor(0, 1);
+  ssd1306_WriteString("                   ", Font_7x10, Black);
+  ssd1306_SetCursor(64 - ((strlen(tempstr) * 7) / 2), 1);
+  ssd1306_WriteString(tempstr, Font_7x10, Black);
+  ssd1306_Line(0, 10, 127, 10, Black);
+}
+
+char * FormatEntryText(menu_td *mn, char * buf)
+{
+  if(mn->type == ENTRY_PREF)
+  {
+    sprintf(buf, "%-12s -%.2d-", mn->title, PrefGetValue(mn->pref));
+  }
+  else if(mn->type == ENTRY_RADIO)
+  {
+    if(PrefGetValue(mn->pref) == (mn->id - mn->parent->child->id))
+      sprintf(buf, "[%s]", mn->title);
+    else
+      sprintf(buf, "%s", mn->title);
+  }
+  else
+  {
+    strcpy(buf, mn->title);
+  }
+
+  return buf;
 }
 
-void MenuShow(uint8_t id)
+void MenuShow()
 {
-	int x = 0, y = 0;
-	SSD1306_COLOR color = White;
-	menu[1].selected = 1;
-	for(int i = 0; i < (sizeof(menu) / sizeof(menu_entry_td)); i++)
-	{
-		if(menu[i].parent_id == 0)
-		{
-			ssd1306_SetCursor(x, y);
-			(menu[i].selected) ? (color = Black) : (color = White);
-			ssd1306_WriteString(menu[i].title, Font_7x10, color);
-			y += 11;
-		}
-	}
+  static int x = 0, y = 0, an_steps = 0;
+  char tempstr[30];
+
+  ssd1306_Fill(Black);
+/*
+  ssd1306_SetCursor(1, 1);
+  menu = &menu_items[1];
+  sprintf(tempstr, "id: %s", menu->next->title);
+  ssd1306_WriteString(tempstr, Font_7x10, White);
+*/
+
+  if(scroll)
+  {
+    y = 11;
+    an_steps = 5;
+    scroll = 0;
+  }
+
+  if(an_steps > 0)
+  {
+    an_steps--;
+    y = (an_steps * 11) / 5;
+  }
+
+  ssd1306_SetCursor(x + 8, y + 1);
+  ssd1306_WriteString(FormatEntryText(menu->prev, tempstr), Font_7x10, White);
+  ssd1306_SetCursor(x + 8, y + 12);
+  ssd1306_WriteString(FormatEntryText(menu, tempstr), Font_7x10, White);
+  ssd1306_SetCursor(x + 8, y + 23);
+  ssd1306_WriteString(FormatEntryText(menu->next, tempstr), Font_7x10, White);
+  ssd1306_SetCursor(0, 12);
+  if(menu->type == ENTRY_BACK)
+    ssd1306_WriteChar('<', Font_7x10, White);
+  else
+    ssd1306_WriteChar('>', Font_7x10, White);
+  PrintMenuHeader();
+
+  ssd1306_UpdateScreen();
 }

+ 53 - 0
stm32workspace/dosim-v1/Core/Src/preferences.c

@@ -0,0 +1,53 @@
+/*
+ * preferences.c
+ *
+ *  Created on: Feb 22, 2022
+ *      Author: radioman
+ */
+
+#include "preferences.h"
+#include "stm32l1xx_hal.h"
+
+static Pref_td Preferences[PREF_COUNT];
+
+static const Pref_td SavedPreferences[PREF_COUNT] = PREF_DEFAULT_VALUES;
+
+void PrefIncValue(PrefNames_t PrefName)
+{
+  Preferences[PrefName].value = (Preferences[PrefName].value +
+      Preferences[PrefName].step) % (Preferences[PrefName].max_val + 1);
+  Preferences[PrefName].unsaved = true;
+}
+
+void PrefSetValue(PrefNames_t PrefName, int val)
+{
+  Preferences[PrefName].value = val;
+  Preferences[PrefName].unsaved = true;
+}
+
+int PrefGetValue(PrefNames_t PrefName)
+{
+  return Preferences[PrefName].value;
+}
+
+void PrefLoadFromFlash()
+{
+  for(int i = 0; i < PREF_COUNT; i++)
+  {
+    Preferences[i] = SavedPreferences[i];
+  }
+}
+
+void PrefSaveToFlash()
+{
+  HAL_FLASH_Unlock();
+  for(int i = 0; i < PREF_COUNT; i++)
+  {
+    if(Preferences[i].unsaved)
+    {
+      if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (uint32_t)(&(SavedPreferences[i].value)), Preferences[i].value) == HAL_OK)
+        Preferences[i].unsaved = false;
+    }
+  }
+  HAL_FLASH_Lock();
+}

+ 24 - 2
stm32workspace/dosim-v1/Core/Src/stm32l1xx_hal_msp.c

@@ -455,7 +455,18 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
 */
 void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
 {
-  if(htim_base->Instance==TIM3)
+  if(htim_base->Instance==TIM2)
+  {
+  /* USER CODE BEGIN TIM2_MspInit 0 */
+
+  /* USER CODE END TIM2_MspInit 0 */
+    /* Peripheral clock enable */
+    __HAL_RCC_TIM2_CLK_ENABLE();
+  /* USER CODE BEGIN TIM2_MspInit 1 */
+
+  /* USER CODE END TIM2_MspInit 1 */
+  }
+  else if(htim_base->Instance==TIM3)
   {
   /* USER CODE BEGIN TIM3_MspInit 0 */
 
@@ -552,7 +563,18 @@ void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim)
 */
 void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
 {
-  if(htim_base->Instance==TIM3)
+  if(htim_base->Instance==TIM2)
+  {
+  /* USER CODE BEGIN TIM2_MspDeInit 0 */
+
+  /* USER CODE END TIM2_MspDeInit 0 */
+    /* Peripheral clock disable */
+    __HAL_RCC_TIM2_CLK_DISABLE();
+  /* USER CODE BEGIN TIM2_MspDeInit 1 */
+
+  /* USER CODE END TIM2_MspDeInit 1 */
+  }
+  else if(htim_base->Instance==TIM3)
   {
   /* USER CODE BEGIN TIM3_MspDeInit 0 */
 

+ 14 - 13
stm32workspace/dosim-v1/Drivers/ssd1306/ssd1306.c

@@ -202,21 +202,21 @@ void ssd1306_UpdateScreen(void) {
 //    X => X Coordinate
 //    Y => Y Coordinate
 //    color => Pixel color
-void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) {
-    if(x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT) {
+void ssd1306_DrawPixel(int x, int y, SSD1306_COLOR color) {
+    if(x >= SSD1306_WIDTH || y >= SSD1306_HEIGHT || x < 0 || y < 0) {
         // Don't write outside the buffer
         return;
     }
-    
+
     // Check if pixel should be inverted
     if(SSD1306.Inverted) {
         color = (SSD1306_COLOR)!color;
     }
-    
+
     // Draw in the right color
     if(color == White) {
         SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] |= 1 << (y % 8);
-    } else { 
+    } else {
         SSD1306_Buffer[x + (y / 8) * SSD1306_WIDTH] &= ~(1 << (y % 8));
     }
 }
@@ -227,19 +227,20 @@ void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color) {
 // color    => Black or White
 char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color) {
     uint32_t i, b, j;
-    
+
     // Check if character is valid
     if (ch < 32 || ch > 126)
         return 0;
-    
+
     // Check remaining space on current line
+    /*
     if (SSD1306_WIDTH < (SSD1306.CurrentX + Font.FontWidth) ||
         SSD1306_HEIGHT < (SSD1306.CurrentY + Font.FontHeight))
     {
         // Not enough space on current line
         return 0;
     }
-    
+*/
     // Use the font to write
     for(i = 0; i < Font.FontHeight; i++) {
         b = Font.data[(ch - 32) * Font.FontHeight + i];
@@ -251,10 +252,10 @@ char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color) {
             }
         }
     }
-    
+
     // The current space is now taken
     SSD1306.CurrentX += Font.FontWidth;
-    
+
     // Return written char for validation
     return ch;
 }
@@ -267,17 +268,17 @@ char ssd1306_WriteString(char* str, FontDef Font, SSD1306_COLOR color) {
             // Char could not be written
             return *str;
         }
-        
+
         // Next char
         str++;
     }
-    
+
     // Everything ok
     return *str;
 }
 
 // Position the cursor
-void ssd1306_SetCursor(uint8_t x, uint8_t y) {
+void ssd1306_SetCursor(int x, int y) {
     SSD1306.CurrentX = x;
     SSD1306.CurrentY = y;
 }

+ 5 - 4
stm32workspace/dosim-v1/Drivers/ssd1306/ssd1306.h

@@ -118,12 +118,13 @@ typedef enum {
 
 // Struct to store transformations
 typedef struct {
-    uint16_t CurrentX;
-    uint16_t CurrentY;
+    int CurrentX;
+    int CurrentY;
     uint8_t Inverted;
     uint8_t Initialized;
     uint8_t DisplayOn;
 } SSD1306_t;
+
 typedef struct {
     uint8_t x;
     uint8_t y;
@@ -133,10 +134,10 @@ typedef struct {
 void ssd1306_Init(void);
 void ssd1306_Fill(SSD1306_COLOR color);
 void ssd1306_UpdateScreen(void);
-void ssd1306_DrawPixel(uint8_t x, uint8_t y, SSD1306_COLOR color);
+void ssd1306_DrawPixel(int x, int y, SSD1306_COLOR color);
 char ssd1306_WriteChar(char ch, FontDef Font, SSD1306_COLOR color);
 char ssd1306_WriteString(char* str, FontDef Font, SSD1306_COLOR color);
-void ssd1306_SetCursor(uint8_t x, uint8_t y);
+void ssd1306_SetCursor(int x, int y);
 void ssd1306_Line(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2, SSD1306_COLOR color);
 void ssd1306_DrawArc(uint8_t x, uint8_t y, uint8_t radius, uint16_t start_angle, uint16_t sweep, SSD1306_COLOR color);
 void ssd1306_DrawCircle(uint8_t par_x, uint8_t par_y, uint8_t par_r, SSD1306_COLOR color);

+ 32 - 15
stm32workspace/dosim-v1/dosim-v1.ioc

@@ -72,12 +72,13 @@ KeepUserPlacement=false
 Mcu.Family=STM32L1
 Mcu.IP0=ADC
 Mcu.IP1=COMP2
-Mcu.IP10=TIM3
-Mcu.IP11=TIM4
-Mcu.IP12=TIM6
-Mcu.IP13=USART1
-Mcu.IP14=USB
-Mcu.IP15=USB_DEVICE
+Mcu.IP10=TIM2
+Mcu.IP11=TIM3
+Mcu.IP12=TIM4
+Mcu.IP13=TIM6
+Mcu.IP14=USART1
+Mcu.IP15=USB
+Mcu.IP16=USB_DEVICE
 Mcu.IP2=CRC
 Mcu.IP3=DAC
 Mcu.IP4=DMA
@@ -86,7 +87,7 @@ Mcu.IP6=I2C2
 Mcu.IP7=NVIC
 Mcu.IP8=RCC
 Mcu.IP9=SYS
-Mcu.IPNb=16
+Mcu.IPNb=17
 Mcu.Name=STM32L151C(6-8-B)TxA
 Mcu.Package=LQFP48
 Mcu.Pin0=PH0-OSC_IN
@@ -108,18 +109,22 @@ Mcu.Pin22=VP_ADC_Vref_Input
 Mcu.Pin23=VP_COMP2_VS_DACOUT2
 Mcu.Pin24=VP_CRC_VS_CRC
 Mcu.Pin25=VP_SYS_VS_Systick
-Mcu.Pin26=VP_TIM3_VS_ClockSourceINT
-Mcu.Pin27=VP_TIM4_VS_ClockSourceINT
-Mcu.Pin28=VP_TIM6_VS_ClockSourceINT
-Mcu.Pin29=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
+Mcu.Pin26=VP_TIM2_VS_ClockSourceINT
+Mcu.Pin27=VP_TIM2_VS_OPM
+Mcu.Pin28=VP_TIM3_VS_ControllerModeGated
+Mcu.Pin29=VP_TIM3_VS_ClockSourceINT
 Mcu.Pin3=PA4
+Mcu.Pin30=VP_TIM3_VS_ClockSourceITR
+Mcu.Pin31=VP_TIM4_VS_ClockSourceINT
+Mcu.Pin32=VP_TIM6_VS_ClockSourceINT
+Mcu.Pin33=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
 Mcu.Pin4=PA5
 Mcu.Pin5=PA7
 Mcu.Pin6=PB0
 Mcu.Pin7=PB1
 Mcu.Pin8=PB10
 Mcu.Pin9=PB11
-Mcu.PinsNb=30
+Mcu.PinsNb=34
 Mcu.ThirdPartyNb=0
 Mcu.UserConstants=
 Mcu.UserName=STM32L151CBTxA
@@ -226,7 +231,7 @@ ProjectManager.StackSize=0x400
 ProjectManager.TargetToolchain=STM32CubeIDE
 ProjectManager.ToolChainLocation=
 ProjectManager.UnderRoot=true
-ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_DMA_Init-DMA-false-HAL-true,3-MX_GPIO_Init-GPIO-false-HAL-true,4-MX_ADC_Init-ADC-false-HAL-true,5-MX_DAC_Init-DAC-false-HAL-true,6-MX_I2C2_Init-I2C2-true-HAL-true,7-MX_COMP2_Init-COMP2-false-HAL-true,8-MX_USART1_UART_Init-USART1-false-HAL-true,9-MX_TIM6_Init-TIM6-false-HAL-true,10-MX_TIM4_Init-TIM4-false-HAL-true,11-MX_TIM3_Init-TIM3-false-HAL-true,12-MX_I2C1_Init-I2C1-false-HAL-true,13-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,14-MX_CRC_Init-CRC-false-HAL-true
+ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_DMA_Init-DMA-false-HAL-true,3-MX_GPIO_Init-GPIO-false-HAL-true,4-MX_ADC_Init-ADC-false-HAL-true,5-MX_DAC_Init-DAC-false-HAL-true,6-MX_I2C2_Init-I2C2-true-HAL-true,7-MX_COMP2_Init-COMP2-false-HAL-true,8-MX_USART1_UART_Init-USART1-false-HAL-true,9-MX_TIM6_Init-TIM6-false-HAL-true,10-MX_TIM4_Init-TIM4-false-HAL-true,11-MX_TIM3_Init-TIM3-false-HAL-true,12-MX_I2C1_Init-I2C1-false-HAL-true,13-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,14-MX_CRC_Init-CRC-false-HAL-true,15-MX_TIM2_Init-TIM2-false-HAL-true
 RCC.48MHZClocksFreq_Value=48000000
 RCC.AHBFreq_Value=24000000
 RCC.APB1Freq_Value=24000000
@@ -265,13 +270,17 @@ SH.GPXTI15.0=GPIO_EXTI15
 SH.GPXTI15.ConfNb=1
 SH.S_TIM3_CH4.0=TIM3_CH4,PWM Generation4 CH4
 SH.S_TIM3_CH4.ConfNb=1
+TIM2.IPParameters=Prescaler,Period,TIM_MasterOutputTrigger
+TIM2.Period=1000
+TIM2.Prescaler=600
+TIM2.TIM_MasterOutputTrigger=TIM_TRGO_ENABLE
 TIM3.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4
 TIM3.IPParameters=Prescaler,Period,Channel-PWM Generation4 CH4,Pulse-PWM Generation4 CH4,OCMode_PWM-PWM Generation4 CH4,TIM_MasterSlaveMode,OC4Preload_PWM,OCPolarity_4
 TIM3.OC4Preload_PWM=ENABLE
 TIM3.OCMode_PWM-PWM\ Generation4\ CH4=TIM_OCMODE_PWM1
 TIM3.OCPolarity_4=TIM_OCPOLARITY_HIGH
-TIM3.Period=255
-TIM3.Prescaler=0
+TIM3.Period=1000
+TIM3.Prescaler=48
 TIM3.Pulse-PWM\ Generation4\ CH4=10
 TIM3.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE
 TIM4.IPParameters=Prescaler,TIM_MasterOutputTrigger,Period
@@ -303,8 +312,16 @@ VP_CRC_VS_CRC.Mode=CRC_Activate
 VP_CRC_VS_CRC.Signal=CRC_VS_CRC
 VP_SYS_VS_Systick.Mode=SysTick
 VP_SYS_VS_Systick.Signal=SYS_VS_Systick
+VP_TIM2_VS_ClockSourceINT.Mode=Internal
+VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
+VP_TIM2_VS_OPM.Mode=OPM_bit
+VP_TIM2_VS_OPM.Signal=TIM2_VS_OPM
 VP_TIM3_VS_ClockSourceINT.Mode=Internal
 VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT
+VP_TIM3_VS_ClockSourceITR.Mode=TriggerSource_ITR1
+VP_TIM3_VS_ClockSourceITR.Signal=TIM3_VS_ClockSourceITR
+VP_TIM3_VS_ControllerModeGated.Mode=Gated Mode
+VP_TIM3_VS_ControllerModeGated.Signal=TIM3_VS_ControllerModeGated
 VP_TIM4_VS_ClockSourceINT.Mode=Internal
 VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT
 VP_TIM6_VS_ClockSourceINT.Mode=Enable_Timer

Some files were not shown because too many files changed in this diff