STM32F3xx-Nucleo BSP User Manual: stm32f3xx_nucleo.c Source File

STM32F3xx-Nucleo BSP Drivers

stm32f3xx_nucleo.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f3xx_nucleo.c
00004   * @author  MCD Application Team
00005   * @brief   This file provides set of firmware functions to manage:
00006   *          - LEDs and push-button available on STM32F3XX-Nucleo Kit 
00007   *            from STMicroelectronics
00008   *          - LCD, joystick and microSD available on Adafruit 1.8" TFT LCD 
00009   *            shield (reference ID 802)
00010   ******************************************************************************
00011   * @attention
00012   *
00013   * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
00014   *
00015   * Redistribution and use in source and binary forms, with or without modification,
00016   * are permitted provided that the following conditions are met:
00017   *   1. Redistributions of source code must retain the above copyright notice,
00018   *      this list of conditions and the following disclaimer.
00019   *   2. Redistributions in binary form must reproduce the above copyright notice,
00020   *      this list of conditions and the following disclaimer in the documentation
00021   *      and/or other materials provided with the distribution.
00022   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00023   *      may be used to endorse or promote products derived from this software
00024   *      without specific prior written permission.
00025   *
00026   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00029   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00030   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00031   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00032   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00033   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00034   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00035   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036   *
00037   ******************************************************************************
00038   */ 
00039   
00040 /* Includes ------------------------------------------------------------------*/
00041 #include "stm32f3xx_nucleo.h"
00042 
00043 /** @addtogroup BSP
00044   * @{
00045   */ 
00046 
00047 /** @addtogroup STM32F3XX_NUCLEO
00048   * @brief This file provides set of firmware functions to manage Leds and push-button
00049   *        available on STM32F3XX-NUCLEO Kit from STMicroelectronics.
00050   * @{
00051   */ 
00052 /** @addtogroup STM32F3XX_NUCLEO_Common
00053   * @{
00054   */ 
00055 
00056 /** @addtogroup STM32F3XX_NUCLEO_Private_Constants
00057   * @{
00058   */ 
00059 
00060 /**
00061  * @brief STM32F3XX NUCLEO BSP Driver version number V1.1.4
00062    */
00063 #define __STM32F3XX_NUCLEO_BSP_VERSION_MAIN   (0x01) /*!< [31:24] main version */
00064 #define __STM32F3XX_NUCLEO_BSP_VERSION_SUB1   (0x01) /*!< [23:16] sub1 version */
00065 #define __STM32F3XX_NUCLEO_BSP_VERSION_SUB2   (0x04) /*!< [15:8]  sub2 version */
00066 #define __STM32F3XX_NUCLEO_BSP_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
00067 #define __STM32F3XX_NUCLEO_BSP_VERSION        ((__STM32F3XX_NUCLEO_BSP_VERSION_MAIN << 24)\
00068                                               |(__STM32F3XX_NUCLEO_BSP_VERSION_SUB1 << 16)\
00069                                               |(__STM32F3XX_NUCLEO_BSP_VERSION_SUB2 << 8 )\
00070                                               |(__STM32F3XX_NUCLEO_BSP_VERSION_RC))
00071   
00072 /**
00073   * @brief LINK SD Card
00074   */
00075 #define SD_DUMMY_BYTE            0xFF    
00076 #define SD_NO_RESPONSE_EXPECTED  0x80
00077 
00078 /**
00079   * @}
00080   */ 
00081 
00082   /** @addtogroup STM32F3XX_NUCLEO_Private_Variables
00083   * @{
00084   */ 
00085 /**
00086  * @brief LED variables
00087   */ 
00088 
00089 GPIO_TypeDef* LED_PORT[LEDn] = {LED2_GPIO_PORT};
00090 const uint16_t LED_PIN[LEDn] = {LED2_PIN};
00091 
00092 /**
00093  * @brief BUTTON variables
00094  */
00095 GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT }; 
00096 const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN }; 
00097 const uint8_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
00098 
00099 /**
00100  * @brief BUS variables
00101  */
00102 
00103 #ifdef HAL_SPI_MODULE_ENABLED
00104 uint32_t SpixTimeout = NUCLEO_SPIx_TIMEOUT_MAX; /*<! Value of Timeout when SPI communication fails */
00105 static SPI_HandleTypeDef hnucleo_Spi;
00106 #endif /* HAL_SPI_MODULE_ENABLED */
00107 
00108 #ifdef HAL_ADC_MODULE_ENABLED
00109 static ADC_HandleTypeDef hnucleo_Adc;
00110 /* ADC channel configuration structure declaration */
00111 static ADC_ChannelConfTypeDef sConfig;
00112 #endif /* HAL_ADC_MODULE_ENABLED */
00113 /**
00114   * @}
00115   */ 
00116 
00117 /** @defgroup STM32F3XX_NUCLEO_BUS Bus Operation functions
00118   * @{
00119   */
00120 #ifdef HAL_SPI_MODULE_ENABLED
00121 static void       SPIx_Init(void);
00122 static void       SPIx_Write(uint8_t Value);
00123 static uint32_t           SPIx_Read(void);
00124 static void       SPIx_Error(void);
00125 static void       SPIx_MspInit(SPI_HandleTypeDef *hspi);
00126 
00127 /* SD IO functions */
00128 void              SD_IO_Init(void);
00129 HAL_StatusTypeDef SD_IO_WriteCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response);
00130 HAL_StatusTypeDef SD_IO_WaitResponse(uint8_t Response);
00131 void              SD_IO_WriteDummy(void);
00132 void              SD_IO_CSState(uint8_t state);
00133 void              SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength);
00134 uint8_t           SD_IO_WriteByte(uint8_t Data);
00135 uint8_t           SD_IO_ReadByte(void);
00136 
00137 /* LCD IO functions */
00138 void              LCD_IO_Init(void);
00139 void              LCD_IO_WriteData(uint8_t Data);
00140 void              LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size);
00141 void              LCD_IO_WriteReg(uint8_t LCDReg);
00142 void              LCD_Delay(uint32_t delay);
00143 #endif /* HAL_SPI_MODULE_ENABLED */
00144 
00145 #ifdef HAL_ADC_MODULE_ENABLED
00146 static HAL_StatusTypeDef  ADCx_Init(void);
00147 static void               ADCx_DeInit(void);
00148 static void               ADCx_MspInit(ADC_HandleTypeDef *hadc);
00149 static void               ADCx_MspDeInit(ADC_HandleTypeDef *hadc);
00150 #endif /* HAL_ADC_MODULE_ENABLED */
00151 
00152 /**
00153   * @}
00154   */ 
00155 
00156 /** @addtogroup STM32F3XX_NUCLEO_Exported_Functions
00157   * @{
00158   */ 
00159 
00160 /**
00161 * @brief  This method returns the STM32F3XX NUCLEO BSP Driver revision
00162   * @retval version : 0xXYZR (8bits for each decimal, R for RC)
00163   */
00164 
00165 uint32_t BSP_GetVersion(void)
00166 {
00167   return __STM32F3XX_NUCLEO_BSP_VERSION;
00168 }
00169 
00170 /**
00171   * @brief  Configures LED GPIO.
00172   * @param  Led Specifies the Led to be configured. 
00173   *   This parameter can be one of following parameters:
00174   *     @arg LED2
00175   * @retval None
00176   */
00177 void BSP_LED_Init(Led_TypeDef Led)
00178 {
00179   GPIO_InitTypeDef  GPIO_InitStruct;
00180   
00181   /* Enable the GPIO_LED Clock */
00182   LEDx_GPIO_CLK_ENABLE(Led);
00183 
00184   /* Configure the GPIO_LED pin */
00185   GPIO_InitStruct.Pin = LED_PIN[Led];
00186   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00187   GPIO_InitStruct.Pull = GPIO_NOPULL;
00188   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
00189   
00190   HAL_GPIO_Init(LED_PORT[Led], &GPIO_InitStruct);
00191   HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET); 
00192 }
00193 
00194 /**
00195   * @brief  DeInit LEDs.
00196   * @param  Led LED to be de-init. 
00197   *   This parameter can be one of the following values:
00198   *     @arg  LED1
00199   *     @arg  LED2
00200   *     @arg  LED3
00201   * @note Led DeInit does not disable the GPIO clock nor disable the Mfx 
00202   * @retval None
00203   */
00204 void BSP_LED_DeInit(Led_TypeDef Led)
00205 {
00206   GPIO_InitTypeDef  gpio_init_structure;
00207 
00208   /* Turn off LED */
00209   HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
00210   /* DeInit the GPIO_LED pin */
00211   gpio_init_structure.Pin = LED_PIN[Led];
00212   HAL_GPIO_DeInit(LED_PORT[Led], gpio_init_structure.Pin);
00213 }
00214 
00215 /**
00216   * @brief  Turns selected LED On.
00217   * @param  Led Specifies the Led to be set on. 
00218   *   This parameter can be one of following parameters:
00219   *     @arg LED2
00220   * @retval None
00221   */
00222 void BSP_LED_On(Led_TypeDef Led)
00223 {
00224   HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET); 
00225 }
00226 
00227 /**
00228   * @brief  Turns selected LED Off.
00229   * @param  Led Specifies the Led to be set off. 
00230   *   This parameter can be one of following parameters:
00231   *     @arg LED2
00232   * @retval None
00233   */
00234 void BSP_LED_Off(Led_TypeDef Led)
00235 {
00236   HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET); 
00237 }
00238 
00239 /**
00240   * @brief  Toggles the selected LED.
00241   * @param  Led Specifies the Led to be toggled. 
00242   *   This parameter can be one of following parameters:
00243   *     @arg LED2
00244   * @retval None
00245   */
00246 void BSP_LED_Toggle(Led_TypeDef Led)
00247 {
00248   HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
00249 }
00250 
00251 /**
00252   * @brief  Configures Button GPIO and EXTI Line.
00253   * @param  Button Specifies the Button to be configured.
00254   *   This parameter should be: BUTTON_USER
00255   * @param  ButtonMode Specifies Button mode.
00256   *   This parameter can be one of following parameters:   
00257   *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO
00258   *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
00259   *                            generation capability  
00260   * @retval None
00261   */
00262 void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
00263 {
00264   GPIO_InitTypeDef GPIO_InitStruct;
00265 
00266   /* Enable the BUTTON Clock */
00267   BUTTONx_GPIO_CLK_ENABLE(Button);
00268 
00269   if(ButtonMode == BUTTON_MODE_GPIO)
00270   {
00271     /* Configure Button pin as input */
00272     GPIO_InitStruct.Pin = BUTTON_PIN[Button];
00273     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
00274     GPIO_InitStruct.Pull = GPIO_PULLDOWN;
00275     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
00276     HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
00277   }
00278  
00279   if(ButtonMode == BUTTON_MODE_EXTI)
00280   {
00281     /* Configure Button pin as input with External interrupt */
00282     GPIO_InitStruct.Pin = BUTTON_PIN[Button];
00283     GPIO_InitStruct.Pull = GPIO_NOPULL;
00284     GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; 
00285     HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
00286 
00287     /* Enable and set Button EXTI Interrupt to the lowest priority */
00288     HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0x00);
00289     HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
00290   }
00291 }
00292 
00293 /**
00294   * @brief  Push Button DeInit.
00295   * @param  Button Button to be configured
00296   *   This parameter should be: BUTTON_USER
00297   * @note PB DeInit does not disable the GPIO clock
00298   * @retval None
00299   */
00300 void BSP_PB_DeInit(Button_TypeDef Button)
00301 {
00302     GPIO_InitTypeDef gpio_init_structure;
00303 
00304     gpio_init_structure.Pin = BUTTON_PIN[Button];
00305     HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
00306     HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin);
00307 }
00308 
00309 /**
00310   * @brief  Returns the selected Button state.
00311   * @param  Button Specifies the Button to be checked.
00312   *   This parameter should be: BUTTON_USER
00313   * @retval The Button GPIO pin value.
00314   */
00315 uint32_t BSP_PB_GetState(Button_TypeDef Button)
00316 {
00317   return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
00318 }
00319 
00320 /**
00321   * @}
00322   */ 
00323 
00324 /** @addtogroup STM32F3XX_NUCLEO_BUS
00325   * @{
00326   */ 
00327 #ifdef HAL_SPI_MODULE_ENABLED
00328 /******************************************************************************
00329                             BUS OPERATIONS
00330 *******************************************************************************/
00331 /**
00332   * @brief  Initializes SPI MSP.
00333   * @retval None
00334   */
00335 static void SPIx_MspInit(SPI_HandleTypeDef *hspi)
00336 {
00337   GPIO_InitTypeDef  GPIO_InitStruct;  
00338   
00339   /*** Configure the GPIOs ***/  
00340   /* Enable GPIO clock */
00341   NUCLEO_SPIx_SCK_GPIO_CLK_ENABLE();
00342   NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_ENABLE();
00343   
00344   /* Configure SPI SCK */
00345   GPIO_InitStruct.Pin = NUCLEO_SPIx_SCK_PIN;
00346   GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00347   GPIO_InitStruct.Pull  = GPIO_PULLUP;
00348   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
00349   GPIO_InitStruct.Alternate = NUCLEO_SPIx_SCK_AF;
00350   HAL_GPIO_Init(NUCLEO_SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
00351 
00352   /* Configure SPI MISO and MOSI */ 
00353   GPIO_InitStruct.Pin = NUCLEO_SPIx_MOSI_PIN;
00354   GPIO_InitStruct.Alternate = NUCLEO_SPIx_MISO_MOSI_AF;
00355   GPIO_InitStruct.Pull  = GPIO_PULLDOWN;
00356   HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &GPIO_InitStruct);
00357   
00358   GPIO_InitStruct.Pin = NUCLEO_SPIx_MISO_PIN;
00359   HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &GPIO_InitStruct);
00360 
00361   /*** Configure the SPI peripheral ***/ 
00362   /* Enable SPI clock */
00363   NUCLEO_SPIx_CLK_ENABLE();
00364 }
00365 
00366 
00367 /**
00368   * @brief  Initializes SPI HAL.
00369   * @retval None
00370   */
00371 static void SPIx_Init(void)
00372 {
00373   if(HAL_SPI_GetState(&hnucleo_Spi) == HAL_SPI_STATE_RESET)
00374   {
00375     /* SPI Config */
00376     hnucleo_Spi.Instance = NUCLEO_SPIx;
00377       /* SPI baudrate is set to 8 MHz maximum (PCLKx/SPI_BaudRatePrescaler = 32/4 = 8 MHz) 
00378        to verify these constraints:
00379           - ST7735 LCD SPI interface max baudrate is 15MHz for write and 6.66MHz for read
00380             Since the provided driver doesn't use read capability from LCD, only constraint 
00381             on write baudrate is considered.
00382           - SD card SPI interface max baudrate is 25MHz for write/read
00383           - PCLK1 max frequency is 32 MHz 
00384           - PCLK2 max frequency is 64 MHz 
00385        */ 
00386     hnucleo_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
00387     hnucleo_Spi.Init.Direction = SPI_DIRECTION_2LINES;
00388     hnucleo_Spi.Init.CLKPhase = SPI_PHASE_2EDGE;
00389     hnucleo_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH;
00390     hnucleo_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
00391     hnucleo_Spi.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
00392     hnucleo_Spi.Init.CRCPolynomial = 7;
00393     hnucleo_Spi.Init.DataSize = SPI_DATASIZE_8BIT;
00394     hnucleo_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
00395     hnucleo_Spi.Init.NSS = SPI_NSS_SOFT;
00396     hnucleo_Spi.Init.TIMode = SPI_TIMODE_DISABLE;
00397     hnucleo_Spi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
00398     hnucleo_Spi.Init.Mode = SPI_MODE_MASTER;
00399 
00400     SPIx_MspInit(&hnucleo_Spi);
00401     HAL_SPI_Init(&hnucleo_Spi);
00402   }
00403 }
00404 
00405 /**
00406   * @brief  SPI Write a byte to device
00407   * @param  DataIn value to be written
00408   * @param  DataOut read value
00409   * @param  DataLegnth length of data value
00410   * @retval None
00411   */
00412 static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)
00413 {
00414   HAL_StatusTypeDef status = HAL_OK;
00415 
00416   status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) DataIn, DataOut, DataLegnth, SpixTimeout);
00417 
00418   /* Check the communication status */
00419   if(status != HAL_OK)
00420   {
00421     /* Execute user timeout callback */
00422     SPIx_Error();
00423   }
00424 }
00425 
00426 /**
00427   * @brief  SPI Read 4 bytes from device
00428   * @retval Read data
00429 */
00430 static uint32_t SPIx_Read(void)
00431 {
00432   HAL_StatusTypeDef status = HAL_OK;
00433   uint32_t readvalue = 0;
00434   uint32_t writevalue = 0xFFFFFFFF;
00435   
00436   status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) &writevalue, (uint8_t*) &readvalue, 1, SpixTimeout);
00437   
00438   /* Check the communication status */
00439   if(status != HAL_OK)
00440   {
00441     /* Execute user timeout callback */
00442     SPIx_Error();
00443   }
00444 
00445   return readvalue;
00446 }
00447 
00448 /**
00449   * @brief  SPI Write a byte to device.
00450   * @param  Value value to be written
00451   * @retval None
00452   */
00453 static void SPIx_Write(uint8_t Value)
00454 {
00455   HAL_StatusTypeDef status = HAL_OK;
00456   uint8_t data;
00457 
00458   status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) &Value, &data, 1, SpixTimeout);
00459   
00460   /* Check the communication status */
00461   if(status != HAL_OK)
00462   {
00463     /* Execute user timeout callback */
00464     SPIx_Error();
00465   }
00466 }
00467 
00468 /**
00469   * @brief  SPI error treatment function
00470   * @retval None
00471   */
00472 static void SPIx_Error (void)
00473 {
00474   /* De-initialize the SPI communication BUS */
00475   HAL_SPI_DeInit(&hnucleo_Spi);
00476   
00477   /* Re-Initiaize the SPI communication BUS */
00478   SPIx_Init();
00479 }
00480 /**
00481   * @}
00482   */ 
00483 
00484 /** @defgroup STM32F3XX_NUCLEO_LINK_OPERATIONS Link Operation functions
00485   * @{
00486   */
00487 
00488 /******************************************************************************
00489                             LINK OPERATIONS
00490 *******************************************************************************/
00491 
00492 /********************************* LINK SD ************************************/
00493 /**
00494   * @brief  Initializes the SD Card and put it into StandBy State (Ready for 
00495   *         data transfer).
00496   * @retval None
00497   */
00498 void SD_IO_Init(void)
00499 {
00500   GPIO_InitTypeDef  GPIO_InitStruct;
00501   uint8_t counter;
00502 
00503   /* SD_CS_GPIO Periph clock enable */
00504   SD_CS_GPIO_CLK_ENABLE();
00505 
00506   /* Configure SD_CS_PIN pin: SD Card CS pin */
00507   GPIO_InitStruct.Pin = SD_CS_PIN;
00508   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00509   GPIO_InitStruct.Pull = GPIO_PULLUP;
00510   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
00511   HAL_GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStruct);
00512 
00513   /*------------Put SD in SPI mode--------------*/
00514   /* SD SPI Config */
00515   SPIx_Init();
00516   
00517   /* SD chip select high */
00518   SD_CS_HIGH();
00519   
00520   /* Send dummy byte 0xFF, 10 times with CS high */
00521   /* Rise CS and MOSI for 80 clocks cycles */
00522   for (counter = 0; counter <= 9; counter++)
00523   {
00524     /* Send dummy byte 0xFF */
00525     SD_IO_WriteByte(SD_DUMMY_BYTE);
00526   }
00527 }
00528 
00529 /**
00530   * @brief  Set the SD_CS pin.
00531   * @param  val pin value.
00532   * @retval None
00533   */
00534 void SD_IO_CSState(uint8_t val)
00535 {
00536   if(val == 1) 
00537   {
00538     SD_CS_HIGH();
00539   }
00540   else
00541   {
00542     SD_CS_LOW();
00543   }
00544 }
00545 
00546 /**
00547   * @brief  Write a byte on the SD.
00548   * @param  DataIn byte to be written
00549   * @param  DataOut read value
00550   * @param  DataLength length of data value
00551   * @retval None
00552   */
00553 void SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength)
00554 {
00555 //  /* SD chip select low */
00556 //  SD_CS_LOW();
00557   /* Send the byte */
00558   SPIx_WriteReadData(DataIn, DataOut, DataLength);
00559 }
00560 
00561 /**
00562   * @brief  Reads a byte from the SD.
00563   * @retval The received byte.
00564   */
00565 uint8_t SD_IO_ReadByte(void)
00566 {
00567   uint8_t data = 0;
00568   
00569   /* Get the received data */
00570   data = SPIx_Read();
00571 
00572   /* Return the shifted data */
00573   return data;
00574 }
00575 
00576 /**
00577   * @brief  Sends 5 bytes command to the SD card and get response
00578   * @param  Cmd The user expected command to send to SD card.
00579   * @param  Arg The command argument.
00580   * @param  Crc The CRC.
00581   * @param  Response Expected response from the SD card
00582   * @retval HAL_StatusTypeDef HAL Status
00583   */
00584 HAL_StatusTypeDef SD_IO_WriteCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response)
00585 {
00586   uint32_t counter = 0x00;
00587   uint8_t frame[6];
00588 
00589   /* Prepare Frame to send */
00590   frame[0] = (Cmd | 0x40);         /* Construct byte 1 */
00591   frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */
00592   frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */
00593   frame[3] = (uint8_t)(Arg >> 8);  /* Construct byte 4 */
00594   frame[4] = (uint8_t)(Arg);       /* Construct byte 5 */
00595   frame[5] = (Crc);                /* Construct byte 6 */
00596   
00597   /* SD chip select low */
00598   SD_CS_LOW();
00599     
00600   /* Send Frame */
00601   for (counter = 0; counter < 6; counter++)
00602   {
00603     SD_IO_WriteByte(frame[counter]); /* Send the Cmd bytes */
00604   }
00605 
00606   if(Response != SD_NO_RESPONSE_EXPECTED)
00607   {
00608     return SD_IO_WaitResponse(Response);
00609   }
00610   
00611   return HAL_OK;
00612 }
00613 
00614 /**
00615   * @brief  Waits response from the SD card
00616   * @param  Response Expected response from the SD card
00617   * @retval HAL_StatusTypeDef HAL Status
00618   */
00619 HAL_StatusTypeDef SD_IO_WaitResponse(uint8_t Response)
00620 {
00621   uint32_t timeout = 0xFFFF;
00622 
00623   /* Check if response is got or a timeout is happen */
00624   while ((SD_IO_ReadByte() != Response) && timeout)
00625   {
00626     timeout--;
00627   }
00628 
00629   if (timeout == 0)
00630   {
00631     /* After time out */
00632     return HAL_TIMEOUT;
00633   }
00634   else
00635   {
00636     /* Right response got */
00637     return HAL_OK;
00638   }
00639 }
00640 
00641 /**
00642   * @brief  Writes a byte on the SD.
00643   * @param  Data byte to send.
00644   * @retval None
00645   */
00646 uint8_t SD_IO_WriteByte(uint8_t Data)
00647 {
00648   uint8_t tmp;
00649   /* Send the byte */
00650   SPIx_WriteReadData(&Data,&tmp,1);
00651   return tmp;
00652 }
00653 
00654 /**
00655   * @brief  Sends dummy byte with CS High
00656   * @retval None
00657   */
00658 void SD_IO_WriteDummy(void)
00659 {
00660   /* SD chip select high */
00661   SD_CS_HIGH();
00662   
00663   /* Send Dummy byte 0xFF */
00664   SD_IO_WriteByte(SD_DUMMY_BYTE);
00665 }
00666 
00667 /********************************* LINK LCD ***********************************/
00668 /**
00669   * @brief  Initializes the LCD
00670   * @retval None
00671   */
00672 void LCD_IO_Init(void)
00673 {
00674   GPIO_InitTypeDef  GPIO_InitStruct;
00675    
00676   /* LCD_CS_GPIO and LCD_DC_GPIO Periph clock enable */
00677   LCD_CS_GPIO_CLK_ENABLE();
00678   LCD_DC_GPIO_CLK_ENABLE();
00679   
00680   /* Configure LCD_CS_PIN pin: LCD Card CS pin */
00681   GPIO_InitStruct.Pin = LCD_CS_PIN;
00682   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
00683   GPIO_InitStruct.Pull = GPIO_NOPULL;
00684   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
00685   HAL_GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStruct);
00686 
00687   /* Configure LCD_DC_PIN pin: LCD Card DC pin */
00688   GPIO_InitStruct.Pin = LCD_DC_PIN;
00689   HAL_GPIO_Init(LCD_DC_GPIO_PORT, &GPIO_InitStruct);
00690   
00691   /* LCD chip select high */
00692   LCD_CS_HIGH();
00693   
00694   /* LCD SPI Config */
00695   SPIx_Init();
00696 }
00697 
00698 /**
00699   * @brief  Writes command to select the LCD register.
00700   * @param  LCDReg Address of the selected register.
00701   * @retval None
00702   */
00703 void LCD_IO_WriteReg(uint8_t LCDReg)
00704 {
00705   /* Reset LCD control line CS */
00706   LCD_CS_LOW();
00707   
00708   /* Set LCD data/command line DC to Low */
00709   LCD_DC_LOW();
00710     
00711   /* Send Command */
00712   SPIx_Write(LCDReg);
00713   
00714   /* Deselect : Chip Select high */
00715   LCD_CS_HIGH();
00716 }
00717 
00718 /**
00719   * @brief  Writes data to select the LCD register.
00720   *         This function must be used after st7735_WriteReg() function
00721   * @param  Data data to write to the selected register.
00722   * @retval None
00723   */
00724 void LCD_IO_WriteData(uint8_t Data)
00725 {
00726   /* Reset LCD control line CS */
00727   LCD_CS_LOW();
00728   
00729   /* Set LCD data/command line DC to High */
00730   LCD_DC_HIGH();
00731 
00732   /* Send Data */
00733   SPIx_Write(Data);
00734   
00735   /* Deselect : Chip Select high */
00736   LCD_CS_HIGH();
00737 }
00738 
00739 /**
00740 * @brief  Write register value.
00741 * @param  pData Pointer on the register value
00742 * @param  Size Size of byte to transmit to the register
00743 * @retval None
00744 */
00745 void LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size)
00746 {
00747   uint32_t counter = 0;
00748   __IO uint32_t data = 0;
00749   
00750   /* Reset LCD control line CS */
00751   LCD_CS_LOW();
00752   
00753   /* Set LCD data/command line DC to High */
00754   LCD_DC_HIGH();
00755 
00756   if (Size == 1)
00757   {
00758     /* Only 1 byte to be sent to LCD - general interface can be used */
00759     /* Send Data */
00760     SPIx_Write(*pData);
00761   }
00762   else
00763   {
00764     /* Several data should be sent in a raw */
00765     /* Direct SPI accesses for optimization */
00766     for (counter = Size; counter != 0; counter--)
00767     {
00768       while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
00769       {
00770       }  
00771       /* Need to invert bytes for LCD*/
00772       *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *(pData+1);
00773       
00774       while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
00775       {
00776       }  
00777       *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *pData;
00778       counter--;
00779       pData += 2;
00780     }
00781     
00782     /* Wait until the bus is ready before releasing Chip select */ 
00783     while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_BSY) != RESET)
00784     {
00785     }  
00786   } 
00787 
00788   /* Empty the Rx fifo */
00789   data = *(&hnucleo_Spi.Instance->DR);
00790   UNUSED(data);
00791 
00792   /* Deselect : Chip Select high */
00793   LCD_CS_HIGH();
00794 }
00795 
00796 /**
00797   * @brief  Wait for loop in ms.
00798   * @param  Delay in ms.
00799   * @retval None
00800   */
00801 void LCD_Delay(uint32_t Delay)
00802 {
00803   HAL_Delay(Delay);
00804 }
00805 #endif /* HAL_SPI_MODULE_ENABLED */
00806 
00807 /******************************* LINK JOYSTICK ********************************/
00808 #ifdef HAL_ADC_MODULE_ENABLED
00809 /**
00810   * @brief  Initializes ADC MSP.
00811   * @retval None
00812   */
00813 static void ADCx_MspInit(ADC_HandleTypeDef *hadc)
00814 {
00815   GPIO_InitTypeDef  GPIO_InitStruct;
00816   
00817   /*** Configure the GPIOs ***/  
00818   /* Enable GPIO clock */
00819   NUCLEO_ADCx_GPIO_CLK_ENABLE();
00820   
00821 #if defined(STM32F302x8) || defined(STM32F334x8)
00822   /* Configure ADC1 Channel11 as analog input */
00823 #elif defined(STM32F303xE)
00824   /* Configure ADC3 Channel12 as analog input */
00825 #endif
00826   GPIO_InitStruct.Pin = NUCLEO_ADCx_GPIO_PIN ;
00827   GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
00828   HAL_GPIO_Init(NUCLEO_ADCx_GPIO_PORT, &GPIO_InitStruct);
00829 
00830   /*** Configure the ADC peripheral ***/ 
00831   /* Enable ADC clock */
00832   NUCLEO_ADCx_CLK_ENABLE(); 
00833 }
00834 
00835 /**
00836   * @brief  DeInitializes ADC MSP.
00837   * @note ADC DeInit does not disable the GPIO clock
00838   * @retval None
00839   */
00840 static void ADCx_MspDeInit(ADC_HandleTypeDef *hadc)
00841 {
00842   GPIO_InitTypeDef  GPIO_InitStruct;
00843 
00844   /*** DeInit the ADC peripheral ***/ 
00845   /* Disable ADC clock */
00846   NUCLEO_ADCx_CLK_DISABLE(); 
00847 
00848   /* Configure the selected ADC Channel as analog input */
00849   GPIO_InitStruct.Pin = NUCLEO_ADCx_GPIO_PIN ;
00850   HAL_GPIO_DeInit(NUCLEO_ADCx_GPIO_PORT, GPIO_InitStruct.Pin);
00851 
00852   /* Disable GPIO clock has to be done by the application*/
00853   /* NUCLEO_ADCx_GPIO_CLK_DISABLE(); */
00854 }
00855 
00856 /**
00857   * @brief  Initializes ADC HAL.
00858   * @retval None
00859   */
00860 static HAL_StatusTypeDef  ADCx_Init(void)
00861 {
00862   /* Set ADC instance */
00863   hnucleo_Adc.Instance                   = NUCLEO_ADCx;
00864   
00865   if(HAL_ADC_GetState(&hnucleo_Adc) == HAL_ADC_STATE_RESET)
00866   {
00867 #if !defined (STM32F373xC) && !defined (STM32F378xx)
00868     /* ADC Config */
00869     hnucleo_Adc.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV4;      /* ADC clock of STM32F37x devices must not exceed 16MHz (ADC clock of other STMF3 devices can be set up to 72MHz) */
00870     hnucleo_Adc.Init.Resolution            = ADC_RESOLUTION_12B;
00871     hnucleo_Adc.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
00872     hnucleo_Adc.Init.ScanConvMode          = ADC_SCAN_DISABLE;              /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
00873     hnucleo_Adc.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
00874     hnucleo_Adc.Init.LowPowerAutoWait      = DISABLE;
00875     hnucleo_Adc.Init.ContinuousConvMode    = DISABLE;                       /* Continuous mode disabled to have only 1 conversion at each conversion trig */
00876     hnucleo_Adc.Init.NbrOfConversion       = 1;                             /* Parameter discarded because sequencer is disabled */
00877     hnucleo_Adc.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
00878     hnucleo_Adc.Init.NbrOfDiscConversion   = 1;                             /* Parameter discarded because sequencer is disabled */
00879     hnucleo_Adc.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
00880     hnucleo_Adc.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because trig by software start */
00881     hnucleo_Adc.Init.DMAContinuousRequests = DISABLE;
00882     hnucleo_Adc.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;
00883 #else
00884     /* ADC Config */
00885     hnucleo_Adc.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
00886     hnucleo_Adc.Init.ScanConvMode          = ADC_SCAN_DISABLE;              /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
00887     hnucleo_Adc.Init.ContinuousConvMode    = DISABLE;                       /* Continuous mode disabled to have only 1 conversion at each conversion trig */
00888     hnucleo_Adc.Init.NbrOfConversion       = 1;                             /* Parameter discarded because sequencer is disabled */
00889     hnucleo_Adc.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
00890     hnucleo_Adc.Init.NbrOfDiscConversion   = 1;                             /* Parameter discarded because sequencer is disabled */
00891     hnucleo_Adc.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
00892 #endif
00893     
00894     /* Initialize MSP related to ADC */
00895     ADCx_MspInit(&hnucleo_Adc);
00896     
00897     /* Initialize ADC */
00898     if (HAL_ADC_Init(&hnucleo_Adc) != HAL_OK)
00899     {
00900       return HAL_ERROR;
00901     }
00902     
00903 #if !defined (STM32F373xC) && !defined (STM32F378xx)
00904     /* Run ADC calibration */
00905     if (HAL_ADCEx_Calibration_Start(&hnucleo_Adc, ADC_SINGLE_ENDED) != HAL_OK)
00906     {
00907       return HAL_ERROR;
00908     }
00909   }
00910 #endif
00911   
00912   return HAL_OK;
00913 }
00914 
00915 /**
00916   * @brief  Initializes ADC HAL.
00917   * @retval None
00918   */
00919 static void ADCx_DeInit(void)
00920 {
00921     hnucleo_Adc.Instance   = NUCLEO_ADCx;
00922     
00923     HAL_ADC_DeInit(&hnucleo_Adc);
00924     ADCx_MspDeInit(&hnucleo_Adc);
00925 }
00926 
00927 /******************************* LINK JOYSTICK ********************************/
00928 
00929 /**
00930   * @brief  Configures joystick available on adafruit 1.8" TFT shield 
00931   *         managed through ADC to detect motion.
00932   * @retval Joystickstatus (0=> success, 1=> fail) 
00933   */
00934 uint8_t BSP_JOY_Init(void)
00935 {
00936   if (ADCx_Init() != HAL_OK)
00937   {
00938     return (uint8_t)HAL_ERROR; 
00939   }
00940   
00941 #if defined(STM32F302x8) || defined(STM32F334x8)
00942   /* Select Channel 11 to be converted */
00943   sConfig.Channel      = ADC_CHANNEL_11;
00944 #elif defined(STM32F303xE)
00945   /* Select Channel 12 to be converted */
00946   sConfig.Channel      = ADC_CHANNEL_12;
00947 #endif
00948   sConfig.Rank         = ADC_REGULAR_RANK_1;
00949   sConfig.SamplingTime = ADC_SAMPLETIME_19CYCLES_5;
00950   sConfig.SingleDiff   = ADC_SINGLE_ENDED;
00951   sConfig.OffsetNumber = ADC_OFFSET_NONE;
00952   sConfig.Offset       = 0;
00953   
00954   /* Return Joystick initialization status */
00955   return (uint8_t)HAL_ADC_ConfigChannel(&hnucleo_Adc, &sConfig);
00956 }
00957 
00958 /**
00959   * @brief  DeInit joystick GPIOs.
00960   * @note   JOY DeInit does not disable the Mfx, just set the Mfx pins in Off mode
00961   * @retval None.
00962   */
00963 void BSP_JOY_DeInit(void)
00964 {
00965     ADCx_DeInit();
00966 }
00967 
00968 /**
00969   * @brief  Returns the Joystick key pressed.
00970   * @note   To know which Joystick key is pressed we need to detect the voltage
00971   *         level on each key output
00972   *           - None  : 3.3 V / 4095
00973   *           - SEL   : 1.055 V / 1308
00974   *           - DOWN  : 0.71 V / 88
00975   *           - LEFT  : 3.0 V / 3720 
00976   *           - RIGHT : 0.595 V / 737
00977   *           - UP    : 1.65 V / 2046
00978   * @retval JOYState_TypeDef: Code of the Joystick key pressed.
00979   */
00980 JOYState_TypeDef BSP_JOY_GetState(void)
00981 {
00982   JOYState_TypeDef state;
00983   uint16_t  KeyConvertedValue = 0;
00984   
00985  /* Start the conversion process */
00986   HAL_ADC_Start(&hnucleo_Adc);
00987   
00988   /* Wait for the end of conversion */
00989   if (HAL_ADC_PollForConversion(&hnucleo_Adc, 10) != HAL_TIMEOUT)
00990   {
00991     /* Get the converted value of regular channel */
00992     KeyConvertedValue = HAL_ADC_GetValue(&hnucleo_Adc);
00993   }
00994   
00995   if((KeyConvertedValue > 2010) && (KeyConvertedValue < 2090))
00996   {
00997     state = JOY_UP;
00998   }
00999   else if((KeyConvertedValue > 680) && (KeyConvertedValue < 780))
01000   {
01001     state = JOY_RIGHT;
01002   }
01003   else if((KeyConvertedValue > 1270) && (KeyConvertedValue < 1350))
01004   {
01005     state = JOY_SEL;
01006   }
01007   else if((KeyConvertedValue > 50) && (KeyConvertedValue < 130))
01008   {
01009     state = JOY_DOWN;
01010   }
01011   else if((KeyConvertedValue > 3680) && (KeyConvertedValue < 3760))
01012   {
01013     state = JOY_LEFT;
01014   }
01015   else
01016   {
01017     state = JOY_NONE;
01018   }
01019   
01020   /* Return the code of the Joystick key pressed */
01021   return state;
01022 }
01023 #endif /* HAL_ADC_MODULE_ENABLED */
01024 
01025 /**
01026   * @}
01027   */ 
01028 
01029 /**
01030   * @}
01031   */
01032 
01033 /**
01034   * @}
01035   */    
01036 
01037 /**
01038   * @}
01039   */ 
01040 
01041 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Wed May 31 2017 10:59:20 for STM32F3xx-Nucleo BSP User Manual by   doxygen 1.7.6.1