Subversion Repositories DashDisplay

Rev

Rev 3 | Rev 5 | 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 "dials.h"
  41. #include "switches.h"
  42. #include <math.h>
  43. #include "plx.h"
  44.  
  45. /* USER CODE END Includes */
  46.  
  47. /* Private variables ---------------------------------------------------------*/
  48. ADC_HandleTypeDef hadc1;
  49.  
  50. SPI_HandleTypeDef hspi1;
  51.  
  52. UART_HandleTypeDef huart1;
  53. UART_HandleTypeDef huart2;
  54.  
  55. /* USER CODE BEGIN PV */
  56. /* Private variables ---------------------------------------------------------*/
  57.  
  58. /* USER CODE END PV */
  59.  
  60. /* Private function prototypes -----------------------------------------------*/
  61. void SystemClock_Config(void);
  62. static void MX_GPIO_Init(void);
  63. static void MX_ADC1_Init(void);
  64. static void MX_SPI1_Init(void);
  65. static void MX_USART2_UART_Init(void);
  66. static void MX_USART1_UART_Init(void);
  67.  
  68. /* USER CODE BEGIN PFP */
  69. /* Private function prototypes -----------------------------------------------*/
  70.  
  71. /* USER CODE END PFP */
  72.  
  73. /* USER CODE BEGIN 0 */
  74. /* dummy function */
  75. void _init(void) {
  76.  
  77. }
  78.  
  79. /* USER CODE END 0 */
  80.  
  81. int main(void) {
  82.  
  83.         /* USER CODE BEGIN 1 */
  84.  
  85.         GPIO_InitTypeDef GPIO_InitStruct;
  86.  
  87.         __HAL_RCC_SPI1_CLK_ENABLE()
  88.         ;
  89.         __HAL_RCC_USART1_CLK_ENABLE()
  90.         ; // PLX main port
  91.         __HAL_RCC_USART2_CLK_ENABLE()
  92.         ; // debug port
  93.         /* USER CODE END 1 */
  94.  
  95.         /* MCU Configuration----------------------------------------------------------*/
  96.  
  97.         /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  98.         HAL_Init();
  99.  
  100.         /* Configure the system clock */
  101.         SystemClock_Config();
  102.  
  103.         /* Initialize all configured peripherals */
  104.         MX_GPIO_Init();
  105.         MX_ADC1_Init();
  106.         MX_SPI1_Init();
  107.         MX_USART2_UART_Init();
  108.         MX_USART1_UART_Init();
  109.  
  110.         /* USER CODE BEGIN 2 */
  111.         /* Need to set AF mode for output pins DURR. */
  112.         /* SPI bus AF pin selects */
  113.         GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  114.  
  115.         GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7;
  116.         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  117.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  118.  
  119.         /* USART2 AF pin selects */
  120.         GPIO_InitStruct.Pin = GPIO_PIN_2;
  121.         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  122.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  123.  
  124.         /* USART1 AF pin selects */
  125.         GPIO_InitStruct.Pin = GPIO_PIN_9;
  126.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  127.  
  128.         /* Turn on USART2 IRQ  */
  129.         HAL_NVIC_SetPriority(USART2_IRQn, 4, 0);
  130.         HAL_NVIC_EnableIRQ(USART2_IRQn);
  131.  
  132.         /* Turn on USART1 IRQ */
  133.         HAL_NVIC_SetPriority(USART1_IRQn, 2, 0);
  134.         HAL_NVIC_EnableIRQ(USART1_IRQn);
  135.  
  136.         /* setup the USART control blocks */
  137.         init_usart_ctl(&uc1, huart1.Instance);
  138.         init_usart_ctl(&uc2, huart2.Instance);
  139.  
  140.         EnableSerialRxInterrupt(&uc1);
  141.         EnableSerialRxInterrupt(&uc2);
  142.  
  143.         ap_init(); // set up the approximate math library
  144.  
  145.         ssd1306_begin(1, 0);
  146.         clearDisplay();
  147.         dim(0);
  148.         //font_puts(
  149.         //              "Hello world !!\rThis text is a test of the text rendering library in a 5*7 font");
  150.  
  151.         static const xp = 128 - 42;
  152.         dial_origin(xp, 40);
  153.         dial_size(40);
  154.         dial_draw_scale(10, 20, 16, 2);
  155.  
  156.         display();
  157.  
  158.         InitSwitches();
  159.  
  160.         /* USER CODE END 2 */
  161.  
  162.         /* Infinite loop */
  163.         /* USER CODE BEGIN WHILE */
  164.         uint32_t Ticks = HAL_GetTick() + 100;
  165.         int16_t dial0 = 0;
  166.         int16_t dial1 = -1;
  167.  
  168.         int c = 0;
  169.         int i;
  170.         char buff[10];
  171.  
  172.         // PLX decoder protocol
  173. #define MAXRDG 10
  174.         char PLXPacket = 0;
  175.         union {
  176.                 PLX_SensorInfo Sensor[MAXRDG];
  177.                 char Bytes[MAXRDG * sizeof(PLX_SensorInfo)];
  178.  
  179.         } Data;
  180.         int Max[MAXRDG];
  181.         int Min[MAXRDG];
  182.         for (i = 0; i < MAXRDG; i++) {
  183.                 Max[i] = 0;
  184.                 Min[i] = 0xFFF; // 12 bit max value
  185.         }
  186.  
  187.         int PLXPtr;
  188.         int PLXItems;
  189.  
  190.         int OldObservation = -1; // illegal initial value
  191.         int OldObservationIndex = -1; // if more than one sensor this will be printed
  192.         while (1) {
  193. // poll switches
  194.                 HandleSwitches();
  195.                 int ItemIndex  = dial_pos[0];
  196.  
  197.                 uint16_t cc = SerialCharsReceived(&uc1);
  198.                 for (i = 0; i < cc; i++) {
  199.                         char c = GetCharSerial(&uc1);
  200.                         if (c == PLX_Start) // at any time if the start byte appears, reset the pointers
  201.                                         {
  202.                                 PLXPtr = 0;    // reset the pointer
  203.                                 PLXPacket = 1;
  204.                                 continue;
  205.                         }
  206.  
  207.                         if (c == PLX_Stop) {
  208.                                 // we can now decode the selected parameter
  209.                                 PLXPacket = 0;
  210.                                 PLXItems = PLXPtr / sizeof(PLX_SensorInfo);
  211.                                 // saturate the rotary switch position
  212.                 if(ItemIndex > PLXItems)
  213.                 {
  214.                         dial_pos[0]= PLXItems;
  215.                         ItemIndex = PLXItems;
  216.                 }
  217.  
  218.                                 int DataVal;
  219.                                 // process min/max
  220.                                 for (i = 0; i < PLXItems; i++) {
  221.                                         DataVal = ConvPLX(Data.Sensor[i].ObsH, Data.Sensor[i].ObsL);
  222.                                         if (DataVal > Max[i]) {
  223.                                                 Max[i] = DataVal;
  224.                                         }
  225.                                         if (DataVal < Min[i]) {
  226.                                                 Min[i] = DataVal;
  227.                                         }
  228.                                 }
  229.  
  230.                                 DataVal = ConvPLX(Data.Sensor[ItemIndex].ObsH,
  231.                                                 Data.Sensor[ItemIndex].ObsL);
  232.                                 int Observation = ConvPLX(Data.Sensor[ItemIndex].ObsH,
  233.                                                 Data.Sensor[ItemIndex].ObsL);
  234.                                 int ObservationIndex = ConvPLX(0, Data.Sensor[index].ObsIndex);
  235.                                 // now to convert the readings and format strings
  236.                                 // find out limits
  237.                                 if (Observation != OldObservation
  238.                                                 || ObservationIndex != OldObservationIndex) {
  239.  
  240.                                         dial_draw_scale(
  241.                                                         DisplayInfo[Observation].Low
  242.                                                                         / DisplayInfo[Observation].TickScale,
  243.                                                         DisplayInfo[Observation].High
  244.                                                                         / DisplayInfo[Observation].TickScale, 16,
  245.                                                         1);
  246.                                         int len;
  247.                                         if (ObservationIndex > 0) {
  248.                                                 len=4;
  249.                                                 buff[5] = ObservationIndex + '1';
  250.                                         } else {
  251.                                                 len=5;
  252.                                         }
  253.                                         for(i=0;i<len;i++)
  254.                                         {
  255.                                                 buff[i] = DisplayInfo[Observation].name;
  256.                                         }
  257.                                         print_large_string(buff, 0, 0, 5); // this prints spaces for \0 at end of string
  258.  
  259.                                         OldObservation = Observation;
  260.                                         OldObservationIndex = ObservationIndex;
  261.                                 }
  262.                                 //
  263.  
  264.                                 double  max_rdg;
  265.                                 double  min_rdg;
  266.                                 double  cur_rdg;
  267.  
  268.                                 max_rdg = ConveriMFDRaw2Data(Observation, DisplayInfo[Observation].Units, Max[ItemIndex]);
  269.                                 min_rdg = ConveriMFDRaw2Data(Observation, DisplayInfo[Observation].Units, Min[ItemIndex]);
  270.                                 cur_rdg = ConveriMFDRaw2Data(Observation, DisplayInfo[Observation].Units, DataVal);
  271.  
  272.  
  273.  
  274.  
  275.  
  276.                         }
  277.                         if (c > PLX_Stop) // illegal char, restart reading
  278.                                         {
  279.                                 PLXPacket = 0;
  280.                         }
  281.                         if (PLXPtr < sizeof(Data.Bytes)) {
  282.                                 Data.Bytes[PLXPtr++] = c;
  283.                         }
  284.                 }
  285.  
  286.                 HAL_Delay(1);
  287.  
  288.  
  289.                 /* now scale and decode the dial position etc .
  290.                  *
  291.                  */
  292.                 uint32_t CurrTicks = HAL_GetTick();
  293.                 if (CurrTicks > Ticks) {
  294.                     /* Lookup the dial etc . */
  295.  
  296.  
  297.                         Ticks = CurrTicks + 100;
  298.                         /* old needle un-draw */
  299.                         if (dial1 >= 0) {
  300.                                 dial_draw_needle(dial1);
  301.                         }
  302.                         // print value overlaid by needle
  303.                         // this is actual reading
  304.                         print_digits(xp - 16, 48, 4, 3, c);
  305.  
  306.                         dial_draw_needle(dial0);
  307.                         dial1 = dial0;
  308.  
  309.                         c++;
  310.                         //font_gotoxy(0, 2);
  311.                         //font_puts("baud\r\n");
  312.                         //char buff[10];
  313.                         //itoa(hirda3.Init.BaudRate, buff, 10);
  314.                         //char l = 6 - strlen(buff);
  315.                         /* pad with leading spaces */
  316.                         //while (l > 0) {
  317.                         //      font_putchar(' ');
  318.                         //      l--;
  319.                         //}
  320.                         //font_puts(itoa(hirda3.Init.BaudRate, buff, 10));
  321.                         display();
  322.                 }
  323.                 /* USER CODE END WHILE */
  324.  
  325.                 /* USER CODE BEGIN 3 */
  326.  
  327.         }
  328.         /* USER CODE END 3 */
  329.  
  330. }
  331.  
  332. /** System Clock Configuration
  333.  */
  334. void SystemClock_Config(void) {
  335.  
  336.         RCC_OscInitTypeDef RCC_OscInitStruct;
  337.         RCC_ClkInitTypeDef RCC_ClkInitStruct;
  338.         RCC_PeriphCLKInitTypeDef PeriphClkInit;
  339.  
  340.         RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  341.         RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  342.         RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  343.         RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  344.         RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  345.         RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  346.         HAL_RCC_OscConfig(&RCC_OscInitStruct);
  347.  
  348.         RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  349.                         | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  350.         RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  351.         RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  352.         RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  353.         RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  354.         HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
  355.  
  356.         PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  357.         PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
  358.         HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
  359.  
  360.         HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);
  361.  
  362.         HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  363.  
  364.         /* SysTick_IRQn interrupt configuration */
  365.         HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  366. }
  367.  
  368. /* ADC1 init function */
  369. void MX_ADC1_Init(void) {
  370.  
  371.         ADC_ChannelConfTypeDef sConfig;
  372.  
  373.         /**Common config
  374.          */
  375.         hadc1.Instance = ADC1;
  376.         hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  377.         hadc1.Init.ContinuousConvMode = DISABLE;
  378.         hadc1.Init.DiscontinuousConvMode = DISABLE;
  379.         hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  380.         hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  381.         hadc1.Init.NbrOfConversion = 1;
  382.         HAL_ADC_Init(&hadc1);
  383.  
  384.         /**Configure Regular Channel
  385.          */
  386.         sConfig.Channel = ADC_CHANNEL_0;
  387.         sConfig.Rank = 1;
  388.         sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  389.         HAL_ADC_ConfigChannel(&hadc1, &sConfig);
  390.  
  391. }
  392.  
  393. /* SPI1 init function */
  394. void MX_SPI1_Init(void) {
  395.  
  396.         hspi1.Instance = SPI1;
  397.         hspi1.Init.Mode = SPI_MODE_MASTER;
  398.         hspi1.Init.Direction = SPI_DIRECTION_1LINE;
  399.         hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  400.         hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
  401.         hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  402.         hspi1.Init.NSS = SPI_NSS_SOFT;
  403.         hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  404.         hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  405.         hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  406.         hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  407.         hspi1.Init.CRCPolynomial = 10;
  408.         HAL_SPI_Init(&hspi1);
  409.  
  410. }
  411.  
  412. /* USART1 init function */
  413. void MX_USART1_UART_Init(void) {
  414.  
  415.         huart1.Instance = USART1;
  416.         huart1.Init.BaudRate = 115200;
  417.         huart1.Init.WordLength = UART_WORDLENGTH_8B;
  418.         huart1.Init.StopBits = UART_STOPBITS_1;
  419.         huart1.Init.Parity = UART_PARITY_NONE;
  420.         huart1.Init.Mode = UART_MODE_TX_RX;
  421.         huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  422.         huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  423.         HAL_UART_Init(&huart1);
  424.  
  425. }
  426.  
  427. /* USART2 init function */
  428. void MX_USART2_UART_Init(void) {
  429.  
  430.         huart2.Instance = USART2;
  431.         huart2.Init.BaudRate = 115200;
  432.         huart2.Init.WordLength = UART_WORDLENGTH_8B;
  433.         huart2.Init.StopBits = UART_STOPBITS_1;
  434.         huart2.Init.Parity = UART_PARITY_NONE;
  435.         huart2.Init.Mode = UART_MODE_TX_RX;
  436.         huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  437.         huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  438.         HAL_UART_Init(&huart2);
  439.  
  440. }
  441.  
  442. /** Configure pins as
  443.  * Analog
  444.  * Input
  445.  * Output
  446.  * EVENT_OUT
  447.  * EXTI
  448.  */
  449. void MX_GPIO_Init(void) {
  450.  
  451.         GPIO_InitTypeDef GPIO_InitStruct;
  452.  
  453.         /* GPIO Ports Clock Enable */
  454.         __HAL_RCC_GPIOD_CLK_ENABLE()
  455.         ;
  456.         __HAL_RCC_GPIOA_CLK_ENABLE()
  457.         ;
  458.         __HAL_RCC_GPIOC_CLK_ENABLE()
  459.         ;
  460.         __HAL_RCC_GPIOB_CLK_ENABLE()
  461.         ;
  462.  
  463.         /*Configure GPIO pin Output Level */
  464.         HAL_GPIO_WritePin(GPIOA, SPI1_NSS1_Pin | SPI1CD_Pin, GPIO_PIN_RESET);
  465.  
  466.         /*Configure GPIO pin Output Level */
  467.         HAL_GPIO_WritePin(GPIOC,
  468.                         SPI_RESET_Pin | SPI_NSS2_Pin | USART3_INVERT_Pin | USB_PWR_Pin,
  469.                         GPIO_PIN_RESET);
  470.  
  471.         /*Configure GPIO pins : SPI1_NSS1_Pin SPI1CD_Pin */
  472.         GPIO_InitStruct.Pin = SPI1_NSS1_Pin | SPI1CD_Pin;
  473.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  474.         GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  475.         HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  476.  
  477.         /*Configure GPIO pins : SPI_RESET_Pin SPI_NSS2_Pin USART3_INVERT_Pin USB_PWR_Pin */
  478.         GPIO_InitStruct.Pin = SPI_RESET_Pin | SPI_NSS2_Pin | USART3_INVERT_Pin
  479.                         | USB_PWR_Pin;
  480.         GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  481.         GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  482.         HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  483.  
  484.         /*Configure GPIO pins : SW1_PUSH_Pin SW1_I_Pin SW1_Q_Pin SW2_PUSH_Pin */
  485.         GPIO_InitStruct.Pin = SW1_PUSH_Pin | SW1_I_Pin | SW1_Q_Pin | SW2_PUSH_Pin;
  486.         GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  487.         GPIO_InitStruct.Pull = GPIO_PULLUP;
  488.         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  489.  
  490.         /*Configure GPIO pins : SW2_I_Pin SW2_Q_Pin */
  491.         GPIO_InitStruct.Pin = SW2_I_Pin | SW2_Q_Pin;
  492.         GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  493.         GPIO_InitStruct.Pull = GPIO_PULLUP;
  494.         HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  495.  
  496. }
  497.  
  498. /* USER CODE BEGIN 4 */
  499.  
  500. /* USER CODE END 4 */
  501.  
  502. #ifdef USE_FULL_ASSERT
  503.  
  504. /**
  505.  * @brief Reports the name of the source file and the source line number
  506.  * where the assert_param error has occurred.
  507.  * @param file: pointer to the source file name
  508.  * @param line: assert_param error line source number
  509.  * @retval None
  510.  */
  511. void assert_failed(uint8_t* file, uint32_t line)
  512. {
  513.         /* USER CODE BEGIN 6 */
  514.         /* User can add his own implementation to report the file name and line number,
  515.          ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  516.         /* USER CODE END 6 */
  517.  
  518. }
  519.  
  520. #endif
  521.  
  522. /**
  523.  * @}
  524.  */
  525.  
  526. /**
  527.  * @}
  528.  */
  529.  
  530. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  531.