Subversion Repositories DashDisplay

Rev

Rev 15 | Rev 17 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * File Name          : main.c
  4.   * Description        : Main program body
  5.   ******************************************************************************
  6.   *
  7.   * COPYRIGHT(c) 2016 STMicroelectronics
  8.   *
  9.   * Redistribution and use in source and binary forms, with or without modification,
  10.   * are permitted provided that the following conditions are met:
  11.   *   1. Redistributions of source code must retain the above copyright notice,
  12.   *      this list of conditions and the following disclaimer.
  13.   *   2. Redistributions in binary form must reproduce the above copyright notice,
  14.   *      this list of conditions and the following disclaimer in the documentation
  15.   *      and/or other materials provided with the distribution.
  16.   *   3. Neither the name of STMicroelectronics nor the names of its contributors
  17.   *      may be used to endorse or promote products derived from this software
  18.   *      without specific prior written permission.
  19.   *
  20.   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  21.   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  22.   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23.   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  24.   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  25.   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  26.   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  27.   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28.   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29.   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30.   *
  31.   ******************************************************************************
  32.   */
  33. /* Includes ------------------------------------------------------------------*/
  34. #include "stm32f1xx_hal.h"
  35.  
  36. /* USER CODE BEGIN Includes */
  37. #include "ap_math.h"
  38. #include "serial.h"
  39. #include "SSD1306.h"
  40. #include "Font.h"
  41. #include "dials.h"
  42. #include "switches.h"
  43. #include <math.h>
  44. #include "plx.h"
  45. #include "eeprom.h"
  46.  
  47. /* USER CODE END Includes */
  48.  
  49. /* Private variables ---------------------------------------------------------*/
  50. SPI_HandleTypeDef hspi1;
  51.  
  52. UART_HandleTypeDef huart1;
  53. UART_HandleTypeDef huart2;
  54.  
  55. /* USER CODE BEGIN PV */
  56. /* Private variables ---------------------------------------------------------*/
  57. #define MAXRDG 10
  58.  
  59. int OldObservation[2] =
  60. { -1, -1 }; // illegal initial value
  61. int OldObservationIndex[2] =
  62. { -1, -1 }; // if more than one sensor this will be printed
  63. int16_t dial0[2] =
  64. { 0, 0 };
  65. int16_t dial1[2] =
  66. { -1, -1 };
  67.  
  68. /* Virtual address defined by the user: 0xFFFF value is prohibited */
  69. uint16_t VirtAddVarTab[NumbOfVar] = {0x5555, 0x6666, 0x7777};
  70.  
  71. union
  72. {
  73.         PLX_SensorInfo Sensor[MAXRDG];
  74.         char Bytes[MAXRDG * sizeof(PLX_SensorInfo)];
  75. } Data;
  76. int Max[MAXRDG];
  77. int Min[MAXRDG];
  78. int PLXItems;
  79. /* USER CODE END PV */
  80.  
  81. /* Private function prototypes -----------------------------------------------*/
  82. void SystemClock_Config(void);
  83. void Error_Handler(void);
  84. static void MX_GPIO_Init(void);
  85. static void MX_SPI1_Init(void);
  86. static void MX_USART2_UART_Init(void);
  87. static void MX_USART1_UART_Init(void);
  88.  
  89. /* USER CODE BEGIN PFP */
  90. /* Private function prototypes -----------------------------------------------*/
  91.  
  92. /* USER CODE END PFP */
  93.  
  94. /* USER CODE BEGIN 0 */
  95. /* dummy function */
  96. void _init(void)
  97. {
  98.  
  99. }
  100. // the dial is the switch number we are using.
  101. // suppress is the ItemIndex we wish to suppress on this display
  102. int  DisplayCurrent(int dial,int suppress)
  103. {
  104.         char buff[10];
  105.         int i;
  106.         select_display(dial); // pick the display we are using
  107.         int ItemIndex = dial_pos[dial]/4;
  108.  
  109.         // wrap around count if dial too far to the right
  110.         if (ItemIndex >= PLXItems)
  111.         {
  112.                 dial_pos[dial] = 0;
  113.                 ItemIndex = 0;
  114.         }
  115.         if (ItemIndex < 0)
  116.         {
  117.                 ItemIndex = PLXItems-1;
  118.                 dial_pos[dial] = (PLXItems-1)*4;
  119.         }
  120.  
  121.  
  122.  
  123.         // check for item suppression
  124.         if(ItemIndex == suppress)
  125.         {
  126.                 dial1[dial] = -1;
  127.                 OldObservation[dial] = -1;
  128.                 OldObservationIndex[dial] = -1;
  129.  
  130.                 clearDisplay();
  131.                 display();
  132.                 return -1; // we suppressed this display
  133.         }
  134.         // do not try to convert if no items in buffer
  135.         if (PLXItems > 0)
  136.         {
  137.                 int DataVal = ConvPLX(Data.Sensor[ItemIndex].ReadingH,
  138.                                 Data.Sensor[ItemIndex].ReadingL); // data reading
  139.                 int Observation = ConvPLX(Data.Sensor[ItemIndex].AddrH,
  140.                                 Data.Sensor[ItemIndex].AddrL);
  141.                 int ObservationIndex = ConvPLX(0, Data.Sensor[ItemIndex].Instance);
  142.                 // now to convert the readings and format strings
  143.                 // find out limits
  144.                 char * msg;
  145.                 int len;
  146.  
  147.                 // if the user presses the dial then reset min/max to current value
  148.                 if(push_pos[dial] == 1)
  149.                 {
  150.                                 Max[ItemIndex] = DataVal;
  151.                                 Min[ItemIndex] = DataVal; // 12 bit max value
  152.                 }
  153.  
  154.  
  155.  
  156.                 if (Observation < PLX_MAX_OBS)
  157.                 {
  158.                         if (Observation != OldObservation[dial]
  159.                                         || ObservationIndex != OldObservationIndex[dial])
  160.                         {
  161.  
  162.  
  163.                                 dial1[dial] = -1;
  164.                                 clearDisplay();
  165.                                 dial_draw_scale(
  166.                                                 DisplayInfo[Observation].Low,
  167.                                                 DisplayInfo[Observation].High,
  168.                                             12, 1,DisplayInfo[Observation].TickScale);
  169.  
  170.                                 msg = DisplayInfo[Observation].name;
  171.                                 len = 7;
  172.                                 int len1  = ObservationIndex > 0 ? len-1: len;
  173.                                 for (i = 0; i < len1 && msg[i]; i++)
  174.                                 {
  175.                                         buff[i] = msg[i];
  176.                                 }
  177.                                 if (ObservationIndex > 0 && i<len)
  178.                                 {
  179.                                         buff[i++] = ObservationIndex + '1';
  180.                                 }
  181.  
  182.                                 print_large_string(buff, 64-i*4, 48, i); // this prints spaces for \0 at end of string
  183.  
  184.                                 OldObservation[dial] = Observation;
  185.                                 OldObservationIndex[dial] = ObservationIndex;
  186.                                 //
  187.                                 display();
  188.  
  189.                         }
  190.  
  191.                         double max_rdg;
  192.                         double min_rdg;
  193.                         double cur_rdg;
  194.                         int int_rdg;
  195.                         int int_max;
  196.                         int int_min;
  197.  
  198.                         max_rdg = ConveriMFDRaw2Data(Observation,
  199.                                         DisplayInfo[Observation].Units, Max[ItemIndex]);
  200.                         min_rdg = ConveriMFDRaw2Data(Observation,
  201.                                         DisplayInfo[Observation].Units, Min[ItemIndex]);
  202.                         cur_rdg = ConveriMFDRaw2Data(Observation,
  203.                                         DisplayInfo[Observation].Units, DataVal);
  204.  
  205.                         int dp_pos;  // where to print the decimal place
  206.                         switch (DisplayInfo[Observation].DP)
  207.                         {
  208.                         case 0:
  209.                                 int_rdg = (int) (cur_rdg);
  210.                                 int_max = (int) (max_rdg);
  211.                                 int_min = (int) (min_rdg);
  212.                                 dp_pos = 100;
  213.                                 break;
  214.                         case 1:
  215.                                 int_rdg = (int) (cur_rdg * 10.0);
  216.                                 int_max = (int) (max_rdg * 10.0);
  217.                                 int_min = (int) (min_rdg * 10.0);
  218.                                 dp_pos = 3;
  219.                                 break;
  220.                         case 2:
  221.                                 int_rdg = (int) (cur_rdg * 100.0);
  222.                                 int_max = (int) (max_rdg * 100.0);
  223.                                 int_min = (int) (min_rdg * 100.0);
  224.                                 dp_pos = 2;
  225.                                 break;
  226.                         }
  227.  
  228.                         cur_rdg -= DisplayInfo[Observation].Low;
  229.                         cur_rdg = 100 * cur_rdg
  230.                                         / (DisplayInfo[Observation].High
  231.                                                         - DisplayInfo[Observation].Low);
  232.  
  233.                         dial0[dial] = (int) cur_rdg  ;
  234.  
  235.                         /* old needle un-draw */
  236.                         if (dial1[dial] >= 0)
  237.                         {
  238.                                 dial_draw_needle(dial1[dial]);
  239.                         }
  240.                         dial_draw_needle(dial0[dial]);
  241.                         // print value overlaid by needle
  242.                         // this is actual reading
  243.                         print_digits(20, 30, 5, dp_pos, int_rdg);
  244.                         font_gotoxy(0,0);
  245.                         font_digits(5,dp_pos,int_min);
  246.  
  247.                         font_gotoxy(0,1);
  248.                         font_puts("Min");
  249.  
  250.                         font_gotoxy(15,0);
  251.                         font_digits(5,dp_pos,int_max);
  252.                         font_gotoxy(18,1);
  253.                         font_puts("Max");
  254.  
  255.                         dial1[dial] = dial0[dial];
  256.  
  257.                         display();
  258.  
  259.                 }
  260.         }
  261.         return ItemIndex;
  262. }
  263. /* USER CODE END 0 */
  264.  
  265. int main(void)
  266. {
  267.  
  268.   /* USER CODE BEGIN 1 */
  269.  
  270.         GPIO_InitTypeDef GPIO_InitStruct;
  271.  
  272.         __HAL_RCC_SPI1_CLK_ENABLE()
  273.         ;
  274.         __HAL_RCC_USART1_CLK_ENABLE()
  275.         ; // PLX main port
  276.         __HAL_RCC_USART2_CLK_ENABLE()
  277.         ; // debug port
  278.   /* USER CODE END 1 */
  279.  
  280.   /* MCU Configuration----------------------------------------------------------*/
  281.  
  282.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  283.   HAL_Init();
  284.  
  285.   /* Configure the system clock */
  286.   SystemClock_Config();
  287.  
  288.   /* Initialize all configured peripherals */
  289.   MX_GPIO_Init();
  290.   MX_SPI1_Init();
  291.   MX_USART2_UART_Init();
  292.   MX_USART1_UART_Init();
  293.  
  294.   /* USER CODE BEGIN 2 */
  295.         /* SPI bus AF pin selects */
  296.  
  297.  
  298.   /* Turn on USART2 IRQ  */
  299.         HAL_NVIC_SetPriority(USART2_IRQn, 4, 0);
  300.         HAL_NVIC_EnableIRQ(USART2_IRQn);
  301.  
  302.         /* Turn on USART1 IRQ */
  303.         HAL_NVIC_SetPriority(USART1_IRQn, 2, 0);
  304.         HAL_NVIC_EnableIRQ(USART1_IRQn);
  305.  
  306.         /* setup the USART control blocks */
  307.         init_usart_ctl(&uc1, huart1.Instance);
  308.         init_usart_ctl(&uc2, huart2.Instance);
  309.  
  310.         EnableSerialRxInterrupt(&uc1);
  311.         EnableSerialRxInterrupt(&uc2);
  312.  
  313.         EE_Init();
  314.  
  315.         ap_init(); // set up the approximate math library
  316.  
  317.         int disp;
  318.  
  319.         ssd1306_begin(1, 0);
  320.         dial_origin(64, 60);
  321.         dial_size(60);
  322.  
  323.  
  324.  
  325.         for (disp = 0; disp < 2; disp++)
  326.         {
  327.                 select_display(disp);
  328.                 clearDisplay();
  329.                 dim(0);
  330.                 //font_puts(
  331.                 //              "Hello world !!\rThis text is a test of the text rendering library in a 5*7 font");
  332.  
  333.                 dial_draw_scale(0, 10, 12, 5,1);
  334.                 char  buffer[] = "Display  ";
  335.                 buffer[8] = disp+'1';
  336.                 print_large_string(buffer, 20,30, 9);
  337.  
  338.                 display();
  339.  
  340.         }
  341.  
  342.  
  343.         InitSwitches();
  344.  
  345.   /* USER CODE END 2 */
  346.  
  347.   /* Infinite loop */
  348.   /* USER CODE BEGIN WHILE */
  349.         uint32_t Ticks = HAL_GetTick() + 100;
  350.  
  351.         int i;
  352.  
  353.         // PLX decoder protocol
  354.         char PLXPacket = 0;
  355.         for (i = 0; i < MAXRDG; i++)
  356.         {
  357.                 Max[i] = 0;
  358.                 Min[i] = 0xFFF; // 12 bit max value
  359.         }
  360.  
  361.         int PLXPtr = 0;
  362.  
  363.         while (1)
  364.         {
  365. // poll switches
  366.                 HandleSwitches();
  367.  
  368.  
  369.  
  370.  
  371.                 uint16_t cc = SerialCharsReceived(&uc1);
  372.                 int chr;
  373.                 for (chr = 0; chr < cc; chr++)
  374.                 {
  375.                         char c = GetCharSerial(&uc1);
  376.                         if (c == PLX_Start) // at any time if the start byte appears, reset the pointers
  377.                         {
  378.                                 PLXPtr = 0;    // reset the pointer
  379.                                 PLXPacket = 1;
  380.                         }
  381.                         else if (c == PLX_Stop)
  382.                         {
  383.                                 if (PLXPacket)
  384.                                 {
  385.                                         // we can now decode the selected parameter
  386.                                         PLXItems = PLXPtr / sizeof(PLX_SensorInfo); // total
  387.                                         // saturate the rotary switch position
  388.  
  389.                                         int DataVal;
  390.                                         // process min/max
  391.                                         for (i = 0; i < PLXItems; i++)
  392.                                         {
  393.                                                 DataVal = ConvPLX(Data.Sensor[i].ReadingH,
  394.                                                                 Data.Sensor[i].ReadingL);
  395.                                                 if (DataVal > Max[i])
  396.                                                 {
  397.                                                         Max[i] = DataVal;
  398.                                                 }
  399.                                                 if (DataVal < Min[i])
  400.                                                 {
  401.                                                         Min[i] = DataVal;
  402.                                                 }
  403.                                         }
  404.  
  405.                                         // now to display the information
  406.                                     int suppress = DisplayCurrent(0,-1);
  407.                                         DisplayCurrent(1, suppress);
  408.                                 }
  409.                                 PLXPtr = 0;
  410.                                 PLXPacket = 0;
  411.                         }
  412.                         else if (c > PLX_Stop) // illegal char, restart reading
  413.                         {
  414.                                 PLXPacket = 0;
  415.                                 PLXPtr = 0;
  416.                         }
  417.                         else if (PLXPtr < sizeof(Data.Bytes))
  418.                         {
  419.                                 Data.Bytes[PLXPtr++] = c;
  420.                         }
  421.                 }
  422.  
  423.                 HAL_Delay(1);
  424.         }
  425.   /* USER CODE END WHILE */
  426.  
  427.   /* USER CODE BEGIN 3 */
  428.  
  429.  
  430.   /* USER CODE END 3 */
  431.  
  432. }
  433.  
  434. /** System Clock Configuration
  435. */
  436. void SystemClock_Config(void)
  437. {
  438.  
  439.   RCC_OscInitTypeDef RCC_OscInitStruct;
  440.   RCC_ClkInitTypeDef RCC_ClkInitStruct;
  441.  
  442.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  443.   RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  444.   RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  445.   RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  446.   RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  447.   RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  448.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  449.   {
  450.     Error_Handler();
  451.   }
  452.  
  453.   RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  454.                               |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  455.   RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  456.   RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  457.   RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  458.   RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  459.   if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  460.   {
  461.     Error_Handler();
  462.   }
  463.  
  464.   HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  465.  
  466.   HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  467.  
  468.   /* SysTick_IRQn interrupt configuration */
  469.   HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  470. }
  471.  
  472. /* SPI1 init function */
  473. static void MX_SPI1_Init(void)
  474. {
  475.  
  476.   hspi1.Instance = SPI1;
  477.   hspi1.Init.Mode = SPI_MODE_MASTER;
  478.   hspi1.Init.Direction = SPI_DIRECTION_1LINE;
  479.   hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  480.   hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  481.   hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  482.   hspi1.Init.NSS = SPI_NSS_SOFT;
  483.   hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  484.   hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  485.   hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  486.   hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  487.   hspi1.Init.CRCPolynomial = 10;
  488.   if (HAL_SPI_Init(&hspi1) != HAL_OK)
  489.   {
  490.     Error_Handler();
  491.   }
  492.  
  493. }
  494.  
  495. /* USART1 init function */
  496. static void MX_USART1_UART_Init(void)
  497. {
  498.  
  499.   huart1.Instance = USART1;
  500.   huart1.Init.BaudRate = 19200;
  501.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
  502.   huart1.Init.StopBits = UART_STOPBITS_1;
  503.   huart1.Init.Parity = UART_PARITY_NONE;
  504.   huart1.Init.Mode = UART_MODE_TX_RX;
  505.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  506.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  507.   if (HAL_UART_Init(&huart1) != HAL_OK)
  508.   {
  509.     Error_Handler();
  510.   }
  511.  
  512. }
  513.  
  514. /* USART2 init function */
  515. static void MX_USART2_UART_Init(void)
  516. {
  517.  
  518.   huart2.Instance = USART2;
  519.   huart2.Init.BaudRate = 115200;
  520.   huart2.Init.WordLength = UART_WORDLENGTH_8B;
  521.   huart2.Init.StopBits = UART_STOPBITS_1;
  522.   huart2.Init.Parity = UART_PARITY_NONE;
  523.   huart2.Init.Mode = UART_MODE_TX_RX;
  524.   huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  525.   huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  526.   if (HAL_UART_Init(&huart2) != HAL_OK)
  527.   {
  528.     Error_Handler();
  529.   }
  530.  
  531. }
  532.  
  533. /** Configure pins as
  534.         * Analog
  535.         * Input
  536.         * Output
  537.         * EVENT_OUT
  538.         * EXTI
  539. */
  540. static void MX_GPIO_Init(void)
  541. {
  542.  
  543.   GPIO_InitTypeDef GPIO_InitStruct;
  544.  
  545.   /* GPIO Ports Clock Enable */
  546.   __HAL_RCC_GPIOD_CLK_ENABLE();
  547.   __HAL_RCC_GPIOA_CLK_ENABLE();
  548.   __HAL_RCC_GPIOC_CLK_ENABLE();
  549.   __HAL_RCC_GPIOB_CLK_ENABLE();
  550.  
  551.   /*Configure GPIO pin Output Level */
  552.   HAL_GPIO_WritePin(SPI_NSS1_GPIO_Port, SPI_NSS1_Pin, GPIO_PIN_SET);
  553.  
  554.   /*Configure GPIO pin Output Level */
  555.   HAL_GPIO_WritePin(SPI1CD_GPIO_Port, SPI1CD_Pin, GPIO_PIN_RESET);
  556.  
  557.   /*Configure GPIO pin Output Level */
  558.   HAL_GPIO_WritePin(GPIOC, SPI_RESET_Pin|USART3_INVERT_Pin|USB_PWR_Pin, GPIO_PIN_RESET);
  559.  
  560.   /*Configure GPIO pin Output Level */
  561.   HAL_GPIO_WritePin(SPI_NSS2_GPIO_Port, SPI_NSS2_Pin, GPIO_PIN_SET);
  562.  
  563.   /*Configure GPIO pins : SPI_NSS1_Pin SPI1CD_Pin */
  564.   GPIO_InitStruct.Pin = SPI_NSS1_Pin|SPI1CD_Pin;
  565.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  566.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  567.   HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  568.  
  569.   /*Configure GPIO pins : SPI_RESET_Pin SPI_NSS2_Pin USART3_INVERT_Pin USB_PWR_Pin */
  570.   GPIO_InitStruct.Pin = SPI_RESET_Pin|SPI_NSS2_Pin|USART3_INVERT_Pin|USB_PWR_Pin;
  571.   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  572.   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  573.   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  574.  
  575.   /*Configure GPIO pins : SW1_PUSH_Pin SW1_I_Pin SW1_Q_Pin SW2_PUSH_Pin */
  576.   GPIO_InitStruct.Pin = SW1_PUSH_Pin|SW1_I_Pin|SW1_Q_Pin|SW2_PUSH_Pin;
  577.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  578.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  579.   HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  580.  
  581.   /*Configure GPIO pins : SW2_I_Pin SW2_Q_Pin */
  582.   GPIO_InitStruct.Pin = SW2_I_Pin|SW2_Q_Pin;
  583.   GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  584.   GPIO_InitStruct.Pull = GPIO_PULLUP;
  585.   HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  586.  
  587. }
  588.  
  589. /* USER CODE BEGIN 4 */
  590.  
  591. /* USER CODE END 4 */
  592.  
  593. /**
  594.   * @brief  This function is executed in case of error occurrence.
  595.   * @param  None
  596.   * @retval None
  597.   */
  598. void Error_Handler(void)
  599. {
  600.   /* USER CODE BEGIN Error_Handler */
  601. /* User can add his own implementation to report the HAL error return state */
  602. while (1)
  603. {
  604. }
  605.   /* USER CODE END Error_Handler */
  606. }
  607.  
  608. #ifdef USE_FULL_ASSERT
  609.  
  610. /**
  611.    * @brief Reports the name of the source file and the source line number
  612.    * where the assert_param error has occurred.
  613.    * @param file: pointer to the source file name
  614.    * @param line: assert_param error line source number
  615.    * @retval None
  616.    */
  617. void assert_failed(uint8_t* file, uint32_t line)
  618. {
  619.   /* USER CODE BEGIN 6 */
  620. /* User can add his own implementation to report the file name and line number,
  621.  ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  622.   /* USER CODE END 6 */
  623.  
  624. }
  625.  
  626. #endif
  627.  
  628. /**
  629.   * @}
  630.   */
  631.  
  632. /**
  633.   * @}
  634. */
  635.  
  636. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  637.