Subversion Repositories DashDisplay

Rev

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