STM32F3xx_Nucleo BSP User Manual: stm32f3xx_nucleo.c Source File

STM32F3xx_Nucleo BSP Driver

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