STM32L4xx_Nucleo BSP User Manual: stm32l4xx_nucleo.c Source File

STM32L4xx Nucleo

stm32l4xx_nucleo.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_nucleo.c
00004   * @author  MCD Application Team
00005   * @version $VERSION$
00006   * @date    $DATE$
00007   * @brief   This file provides set of firmware functions to manage:
00008   *          - LEDs and push-button available on STM32L4XX-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) 2015 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 "stm32l4xx_nucleo.h"
00044 
00045 /** @addtogroup BSP
00046   * @{
00047   */ 
00048 
00049 /** @defgroup STM32L4XX_NUCLEO STM32L476RG-Nucleo
00050   * @brief This file provides set of firmware functions to manage Leds and push-button
00051   *        available on STM32L4XX-Nucleo Kit from STMicroelectronics.
00052   *        It provides also LCD, joystick and uSD functions to communicate with 
00053   *        Adafruit 1.8" TFT LCD shield (reference ID 802)
00054   * @{
00055   */ 
00056 
00057 
00058 /** @defgroup STM32L4XX_NUCLEO_Private_Defines Private Defines
00059   * @{
00060   */ 
00061   
00062 /**
00063   * @brief STM32L476RG NUCLEO BSP Driver version
00064   */
00065 #define __STM32L4XX_NUCLEO_BSP_VERSION_MAIN   (0x01) /*!< [31:24] main version */
00066 #define __STM32L4XX_NUCLEO_BSP_VERSION_SUB1   (0x00) /*!< [23:16] sub1 version */
00067 #define __STM32L4XX_NUCLEO_BSP_VERSION_SUB2   (0x00) /*!< [15:8]  sub2 version */
00068 #define __STM32L4XX_NUCLEO_BSP_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
00069 #define __STM32L4XX_NUCLEO_BSP_VERSION       ((__STM32L4XX_NUCLEO_BSP_VERSION_MAIN << 24)\
00070                                              |(__STM32L4XX_NUCLEO_BSP_VERSION_SUB1 << 16)\
00071                                              |(__STM32L4XX_NUCLEO_BSP_VERSION_SUB2 << 8 )\
00072                                              |(__STM32L4XX_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 
00085 /** @defgroup STM32L4XX_NUCLEO_Private_Variables Exported Variables
00086   * @{
00087   */ 
00088 GPIO_TypeDef* GPIO_PORT[LEDn] = {LED2_GPIO_PORT};
00089 
00090 const uint16_t GPIO_PIN[LEDn] = {LED2_PIN};
00091 
00092 GPIO_TypeDef*  BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT};
00093 const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN};
00094 const uint16_t BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn};
00095 
00096 /**
00097  * @brief BUS variables
00098  */
00099 
00100 #ifdef HAL_SPI_MODULE_ENABLED
00101 uint32_t hnucleo_SpixTimeout = NUCLEO_SPIx_TIMEOUT_MAX;        /*<! Value of Timeout when SPI communication fails */
00102 static SPI_HandleTypeDef hnucleo_Spi;
00103 #endif /* HAL_SPI_MODULE_ENABLED */
00104 
00105 #ifdef HAL_ADC_MODULE_ENABLED
00106 static ADC_HandleTypeDef hnucleo_Adc;
00107 /* ADC channel configuration structure declaration */
00108 static ADC_ChannelConfTypeDef hnucleo_AdcChannelConfig;
00109 #endif /* HAL_ADC_MODULE_ENABLED */
00110 
00111 /**
00112   * @}
00113   */ 
00114 
00115 /** @defgroup STM32L4XX_NUCLEO_Private_Functions Private Functions
00116   * @{
00117   */ 
00118 #ifdef HAL_SPI_MODULE_ENABLED
00119 static void               SPIx_Init(void);
00120 static void               SPIx_Write(uint8_t Value);
00121 static uint32_t           SPIx_Read(void);
00122 static void               SPIx_Error (void);
00123 static void               SPIx_MspInit(void);
00124 #endif /* HAL_SPI_MODULE_ENABLED */
00125 
00126 #ifdef HAL_ADC_MODULE_ENABLED
00127 static HAL_StatusTypeDef  ADCx_Init(void);
00128 static void               ADCx_MspInit(ADC_HandleTypeDef *hadc);
00129 #endif /* HAL_ADC_MODULE_ENABLED */
00130 
00131 #ifdef HAL_SPI_MODULE_ENABLED
00132 /* SD IO functions */
00133 void                      SD_IO_Init(void);
00134 HAL_StatusTypeDef         SD_IO_WriteCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response);
00135 HAL_StatusTypeDef         SD_IO_WaitResponse(uint8_t Response);
00136 void                      SD_IO_WriteDummy(void);
00137 void                      SD_IO_WriteByte(uint8_t Data);
00138 uint8_t                   SD_IO_ReadByte(void);
00139 
00140 /* LCD IO functions */
00141 void                      LCD_IO_Init(void);
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   * @}
00148   */ 
00149 
00150 /** @defgroup STM32L4XX_NUCLEO_Exported_Functions Exported Functions
00151   * @{
00152   */ 
00153 
00154 /**
00155   * @brief  This method returns the STM32L4XX NUCLEO BSP Driver revision
00156   * @retval version : 0xXYZR (8bits for each decimal, R for RC)
00157   */
00158 uint32_t BSP_GetVersion(void)
00159 {
00160   return __STM32L4XX_NUCLEO_BSP_VERSION;
00161 }
00162 
00163 /** @defgroup STM32L4XX_NUCLEO_LED_Functions LED Functions
00164   * @{
00165   */ 
00166 
00167 /**
00168   * @brief  Configures LED GPIO.
00169   * @param  Led: LED to be configured. 
00170   *          This parameter can be one of the following values:
00171   *            @arg  LED2
00172   * @retval None
00173   */
00174 void BSP_LED_Init(Led_TypeDef Led)
00175 {
00176   GPIO_InitTypeDef  gpioinitstruct = {0};
00177   
00178   /* Enable the GPIO_LED Clock */
00179   LEDx_GPIO_CLK_ENABLE(Led);
00180 
00181   /* Configure the GPIO_LED pin */
00182   gpioinitstruct.Pin    = GPIO_PIN[Led];
00183   gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
00184   gpioinitstruct.Pull   = GPIO_PULLUP;
00185   gpioinitstruct.Speed  = GPIO_SPEED_FAST;
00186   HAL_GPIO_Init(GPIO_PORT[Led], &gpioinitstruct);
00187 }
00188 
00189 /**
00190   * @brief  Turns selected LED On.
00191   * @param  Led: Specifies the Led to be set on. 
00192   *   This parameter can be one of following parameters:
00193   *            @arg  LED2
00194   * @retval None
00195   */
00196 void BSP_LED_On(Led_TypeDef Led)
00197 {
00198   HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_SET); 
00199 }
00200 
00201 /**
00202   * @brief  Turns selected LED Off.
00203   * @param  Led: Specifies the Led to be set off. 
00204   *   This parameter can be one of following parameters:
00205   *            @arg  LED2
00206   * @retval None
00207   */
00208 void BSP_LED_Off(Led_TypeDef Led)
00209 {
00210   HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_RESET); 
00211 }
00212 
00213 /**
00214   * @brief  Toggles the selected LED.
00215   * @param  Led: Specifies the Led to be toggled. 
00216   *   This parameter can be one of following parameters:
00217   *            @arg  LED2
00218   * @retval None
00219   */
00220 void BSP_LED_Toggle(Led_TypeDef Led)
00221 {
00222   HAL_GPIO_TogglePin(GPIO_PORT[Led], GPIO_PIN[Led]);
00223 }
00224 
00225 /**
00226   * @}
00227   */ 
00228 
00229 /** @defgroup STM32L4XX_NUCLEO_BUTTON_Functions BUTTON Functions
00230   * @{
00231   */ 
00232 
00233 /**
00234   * @brief  Configures Button GPIO and EXTI Line.
00235   * @param  Button: Specifies the Button to be configured.
00236   *   This parameter should be: BUTTON_USER
00237   * @param  ButtonMode: Specifies Button mode.
00238   *   This parameter can be one of following parameters:   
00239   *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO
00240   *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
00241   *                            generation capability  
00242   * @retval None
00243   */
00244 void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
00245 {
00246   GPIO_InitTypeDef gpioinitstruct = {0};
00247 
00248   /* Enable the BUTTON Clock */
00249   BUTTONx_GPIO_CLK_ENABLE(Button);
00250 
00251   if (ButtonMode == BUTTON_MODE_GPIO)
00252   {
00253     /* Configure Button pin as input */
00254     gpioinitstruct.Pin    = BUTTON_PIN[Button];
00255     gpioinitstruct.Mode   = GPIO_MODE_INPUT;
00256     gpioinitstruct.Pull   = GPIO_NOPULL;
00257     gpioinitstruct.Speed  = GPIO_SPEED_FAST;
00258     
00259     HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
00260   }
00261   else if(ButtonMode == BUTTON_MODE_EXTI)
00262   {
00263     /* Configure Button pin as input with External interrupt */
00264     gpioinitstruct.Pin    = BUTTON_PIN[Button];
00265     gpioinitstruct.Pull   = GPIO_NOPULL;
00266     gpioinitstruct.Speed  = GPIO_SPEED_FAST;
00267     gpioinitstruct.Mode   = GPIO_MODE_IT_FALLING; 
00268     HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
00269 
00270     /* Enable and set Button EXTI Interrupt to the lowest priority */
00271     HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0);
00272     HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
00273   }
00274 }
00275 
00276 /**
00277   * @brief  Returns the selected Button state.
00278   * @param  Button: Specifies the Button to be checked.
00279   *   This parameter should be: BUTTON_USER  
00280   * @retval Button state.
00281   */
00282 uint32_t BSP_PB_GetState(Button_TypeDef Button)
00283 {
00284   return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
00285 }
00286 
00287 #ifdef HAL_ADC_MODULE_ENABLED
00288 /**
00289   * @brief  Configures joystick available on adafruit 1.8" TFT shield 
00290   *         managed through ADC to detect motion.
00291   * @retval Joystickstatus (0=> success, 1=> fail) 
00292   */
00293 uint8_t BSP_JOY_Init(void)
00294 {
00295   if (ADCx_Init() != HAL_OK)
00296   {
00297     return (uint8_t) HAL_ERROR; 
00298   }
00299 
00300   /* Select Channel 15 to be converted */
00301   hnucleo_AdcChannelConfig.Channel       = ADC_CHANNEL_15;
00302   hnucleo_AdcChannelConfig.SamplingTime  = ADC_SAMPLETIME_24CYCLES_5;
00303   hnucleo_AdcChannelConfig.Rank          = 1;
00304   hnucleo_AdcChannelConfig.SingleDiff    = ADC_SINGLE_ENDED;
00305   hnucleo_AdcChannelConfig.OffsetNumber  = ADC_OFFSET_NONE;
00306   
00307   /* Return Joystick initialization status */
00308   return (uint8_t) HAL_ADC_ConfigChannel(&hnucleo_Adc, &hnucleo_AdcChannelConfig);
00309 }
00310 
00311 /**
00312   * @brief  Returns the Joystick key pressed.
00313   * @note   To know which Joystick key is pressed we need to detect the voltage
00314   *         level on each key output
00315   *           - None  : 3.3 V / 4095
00316   *           - SEL   : 1.055 V / 1308
00317   *           - DOWN  : 0.71 V / 88
00318   *           - LEFT  : 3.0 V / 3720 
00319   *           - RIGHT : 0.595 V / 737
00320   *           - UP    : 1.65 V / 2046
00321   * @retval JOYState_TypeDef: Code of the Joystick key pressed.
00322   */
00323 JOYState_TypeDef BSP_JOY_GetState(void)
00324 {
00325   JOYState_TypeDef state = JOY_NONE;
00326   uint16_t  keyconvertedvalue = 0; 
00327 
00328  /* Start the conversion process */
00329   HAL_ADC_Start(&hnucleo_Adc);
00330   
00331   /* Wait for the end of conversion */
00332   HAL_ADC_PollForConversion(&hnucleo_Adc, 10);
00333   
00334   /* Check if the continous conversion of regular channel is finished */
00335   if(HAL_ADC_GetState(&hnucleo_Adc) & HAL_ADC_STATE_REG_EOC)
00336   {
00337     /* Get the converted value of regular channel */
00338     keyconvertedvalue = HAL_ADC_GetValue(&hnucleo_Adc);
00339   }
00340   
00341   if((keyconvertedvalue > 1980) && (keyconvertedvalue < 2120))
00342   {
00343     state = JOY_UP;
00344   }
00345   else if((keyconvertedvalue > 630) && (keyconvertedvalue < 830))
00346   {
00347     state = JOY_RIGHT;
00348   }
00349   else if((keyconvertedvalue > 1210) && (keyconvertedvalue < 1410))
00350   {
00351     state = JOY_SEL;
00352   }
00353   else if((keyconvertedvalue > 20) && (keyconvertedvalue < 160))
00354   {
00355     state = JOY_DOWN;
00356   }
00357   else if((keyconvertedvalue > 3620) && (keyconvertedvalue < 3820))
00358   {
00359     state = JOY_LEFT;
00360   }
00361   else
00362   {
00363     state = JOY_NONE;
00364   }
00365   
00366   /* Return the code of the Joystick key pressed*/
00367   return state;
00368 }
00369 
00370 #endif /* HAL_ADC_MODULE_ENABLED */
00371 
00372 /**
00373   * @}
00374   */ 
00375 
00376 /**
00377   * @}
00378   */
00379 
00380 /** @addtogroup STM32L4XX_NUCLEO_Private_Functions
00381   * @{
00382   */ 
00383   
00384 #ifdef HAL_SPI_MODULE_ENABLED
00385 /******************************************************************************
00386                             BUS OPERATIONS
00387 *******************************************************************************/
00388 /**
00389   * @brief  Initializes SPI MSP.
00390   * @retval None
00391   */
00392 static void SPIx_MspInit(void)
00393 {
00394   GPIO_InitTypeDef  gpioinitstruct = {0};
00395   
00396   /*** Configure the GPIOs ***/  
00397   /* Enable GPIO clock */
00398   NUCLEO_SPIx_SCK_GPIO_CLK_ENABLE();
00399   NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_ENABLE();
00400 
00401   /* Configure SPI SCK */
00402   gpioinitstruct.Pin        = NUCLEO_SPIx_SCK_PIN;
00403   gpioinitstruct.Mode       = GPIO_MODE_AF_PP;
00404   gpioinitstruct.Pull       = GPIO_PULLUP;
00405   gpioinitstruct.Speed      = GPIO_SPEED_HIGH;
00406   gpioinitstruct.Alternate  = NUCLEO_SPIx_SCK_AF;
00407   HAL_GPIO_Init(NUCLEO_SPIx_SCK_GPIO_PORT, &gpioinitstruct);
00408 
00409   /* Configure SPI MISO and MOSI */ 
00410   gpioinitstruct.Pin        = NUCLEO_SPIx_MOSI_PIN;
00411   gpioinitstruct.Alternate  = NUCLEO_SPIx_MISO_MOSI_AF;
00412   gpioinitstruct.Pull       = GPIO_PULLDOWN;
00413   HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &gpioinitstruct);
00414   
00415   gpioinitstruct.Pin        = NUCLEO_SPIx_MISO_PIN;
00416   HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &gpioinitstruct);
00417 
00418   /*** Configure the SPI peripheral ***/ 
00419   /* Enable SPI clock */
00420   NUCLEO_SPIx_CLK_ENABLE();
00421 }
00422 
00423 /**
00424   * @brief  Initializes SPI HAL.
00425   * @retval None
00426   */
00427 static void SPIx_Init(void)
00428 {
00429   if(HAL_SPI_GetState(&hnucleo_Spi) == HAL_SPI_STATE_RESET)
00430   {
00431     /* SPI Config */
00432     hnucleo_Spi.Instance = NUCLEO_SPIx;
00433       /* SPI baudrate is set to 8 MHz maximum (PCLK2/SPI_BaudRatePrescaler = 32/4 = 8 MHz) 
00434        to verify these constraints:
00435           - ST7735 LCD SPI interface max baudrate is 15MHz for write and 6.66MHz for read
00436             Since the provided driver doesn't use read capability from LCD, only constraint 
00437             on write baudrate is considered.
00438           - SD card SPI interface max baudrate is 25MHz for write/read
00439           - PCLK2 max frequency is 32 MHz 
00440        */
00441     hnucleo_Spi.Init.BaudRatePrescaler  = SPI_BAUDRATEPRESCALER_4;
00442     hnucleo_Spi.Init.Direction          = SPI_DIRECTION_2LINES;
00443     hnucleo_Spi.Init.CLKPhase           = SPI_PHASE_2EDGE;
00444     hnucleo_Spi.Init.CLKPolarity        = SPI_POLARITY_HIGH;
00445     hnucleo_Spi.Init.CRCCalculation     = SPI_CRCCALCULATION_DISABLE;
00446     hnucleo_Spi.Init.CRCPolynomial      = 7;
00447     hnucleo_Spi.Init.CRCLength          = SPI_CRC_LENGTH_DATASIZE;
00448     hnucleo_Spi.Init.DataSize           = SPI_DATASIZE_8BIT;
00449     hnucleo_Spi.Init.FirstBit           = SPI_FIRSTBIT_MSB;
00450     hnucleo_Spi.Init.NSS                = SPI_NSS_SOFT;
00451     hnucleo_Spi.Init.NSSPMode           = SPI_NSS_PULSE_DISABLE;
00452     hnucleo_Spi.Init.TIMode             = SPI_TIMODE_DISABLE;
00453     hnucleo_Spi.Init.Mode               = SPI_MODE_MASTER;
00454     
00455     SPIx_MspInit();
00456     HAL_SPI_Init(&hnucleo_Spi);
00457   }
00458 }
00459 
00460 /**
00461   * @brief  SPI Read 4 bytes from device
00462   * @retval Read data
00463 */
00464 static uint32_t SPIx_Read(void)
00465 {
00466   HAL_StatusTypeDef status = HAL_OK;
00467   uint32_t readvalue = 0;
00468   uint32_t writevalue = 0xFFFFFFFF;
00469   
00470   status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) &writevalue, (uint8_t*) &readvalue, 1, hnucleo_SpixTimeout);
00471   
00472   /* Check the communication status */
00473   if(status != HAL_OK)
00474   {
00475     /* Execute user timeout callback */
00476     SPIx_Error();
00477   }
00478 
00479   return readvalue;
00480 }
00481 
00482 /**
00483   * @brief  SPI Write a byte to device
00484   * @param  Value: value to be written
00485   * @retval None
00486   */
00487 static void SPIx_Write(uint8_t Value)
00488 {
00489   HAL_StatusTypeDef status = HAL_OK;
00490 
00491   status = HAL_SPI_Transmit(&hnucleo_Spi, (uint8_t*) &Value, 1, hnucleo_SpixTimeout);
00492 
00493   /* Check the communication status */
00494   if(status != HAL_OK)
00495   {
00496     /* Execute user timeout callback */
00497     SPIx_Error();
00498   }
00499 }
00500 
00501 /**
00502   * @brief  SPI error treatment function
00503   * @retval None
00504   */
00505 static void SPIx_Error (void)
00506 {
00507   /* De-initialize the SPI communication BUS */
00508   HAL_SPI_DeInit(&hnucleo_Spi);
00509 
00510   /* Re-Initiaize the SPI communication BUS */
00511   SPIx_Init();
00512 }
00513 
00514 /******************************************************************************
00515                             LINK OPERATIONS
00516 *******************************************************************************/
00517 
00518 /********************************* LINK SD ************************************/
00519 /**
00520   * @brief  Initializes the SD Card and put it into StandBy State (Ready for 
00521   *         data transfer).
00522   * @retval None
00523   */
00524 void SD_IO_Init(void)
00525 {
00526   GPIO_InitTypeDef  gpioinitstruct = {0};
00527   uint8_t counter = 0;
00528 
00529   /* SD_CS_GPIO Periph clock enable */
00530   SD_CS_GPIO_CLK_ENABLE();
00531 
00532   /* Configure SD_CS_PIN pin: SD Card CS pin */
00533   gpioinitstruct.Pin    = SD_CS_PIN;
00534   gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
00535   gpioinitstruct.Pull   = GPIO_PULLUP;
00536   gpioinitstruct.Speed  = GPIO_SPEED_HIGH;
00537   HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
00538 
00539   /*------------Put SD in SPI mode--------------*/
00540   /* SD SPI Config */
00541   SPIx_Init();
00542 
00543   /* SD chip select high */
00544   SD_CS_HIGH();
00545   
00546   /* Send dummy byte 0xFF, 10 times with CS high */
00547   /* Rise CS and MOSI for 80 clocks cycles */
00548   for (counter = 0; counter <= 9; counter++)
00549   {
00550     /* Send dummy byte 0xFF */
00551     SD_IO_WriteByte(SD_DUMMY_BYTE);
00552   }
00553 }
00554 
00555 /**
00556   * @brief  Writes a byte on the SD.
00557   * @param  Data: byte to send.
00558   * @retval None
00559   */
00560 void SD_IO_WriteByte(uint8_t Data)
00561 {
00562   /* Send the byte */
00563   SPIx_Write(Data);
00564 }
00565  
00566 /**
00567   * @brief  Reads a byte from the SD.
00568   * @retval The received byte.
00569   */
00570 uint8_t SD_IO_ReadByte(void)
00571   {
00572   uint8_t data = 0;
00573   
00574   /* Get the received data */
00575   data = SPIx_Read();
00576 
00577   /* Return the shifted data */
00578   return data;
00579 }
00580 
00581 /**
00582   * @brief  Sends 5 bytes command to the SD card and get response
00583   * @param  Cmd: The user expected command to send to SD card.
00584   * @param  Arg: The command argument.
00585   * @param  Crc: The CRC.
00586   * @param  Response: Expected response from the SD card
00587   * @retval HAL_StatusTypeDef HAL Status
00588   */
00589 HAL_StatusTypeDef SD_IO_WriteCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response)
00590 {
00591   uint32_t counter = 0x00;
00592   uint8_t frame[6] = {0};
00593 
00594   /* Prepare Frame to send */
00595   frame[0] = (Cmd | 0x40);         /* Construct byte 1 */
00596   frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */
00597   frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */
00598   frame[3] = (uint8_t)(Arg >> 8);  /* Construct byte 4 */
00599   frame[4] = (uint8_t)(Arg);       /* Construct byte 5 */
00600   frame[5] = (Crc);                /* Construct byte 6 */
00601   
00602   /* SD chip select low */
00603   SD_CS_LOW();
00604     
00605   /* Send Frame */
00606   for (counter = 0; counter < 6; counter++)
00607   {
00608     SD_IO_WriteByte(frame[counter]); /* Send the Cmd bytes */
00609   }
00610 
00611   if(Response != SD_NO_RESPONSE_EXPECTED)
00612   {
00613     return SD_IO_WaitResponse(Response);
00614   }  
00615   
00616   return HAL_OK;
00617 }
00618 
00619 /**
00620   * @brief  Waits response from the SD card
00621   * @param  Response: Expected response from the SD card
00622   * @retval HAL_StatusTypeDef HAL Status
00623   */
00624 HAL_StatusTypeDef SD_IO_WaitResponse(uint8_t Response)
00625 {
00626   uint32_t timeout = 0xFFFF;
00627 
00628   /* Check if response is got or a timeout is happen */
00629   while ((SD_IO_ReadByte() != Response) && timeout)
00630   {
00631     timeout--;
00632   }
00633 
00634   if (timeout == 0)
00635   {
00636     /* After time out */
00637     return HAL_TIMEOUT;
00638   }   
00639   else
00640   {
00641     /* Right response got */
00642     return HAL_OK;
00643   }
00644   }  
00645  
00646 /**
00647   * @brief  Sends dummy byte with CS High
00648   * @retval None
00649   */
00650 void SD_IO_WriteDummy(void)
00651 {
00652   /* SD chip select high */
00653   SD_CS_HIGH();
00654   
00655   /* Send Dummy byte 0xFF */
00656   SD_IO_WriteByte(SD_DUMMY_BYTE);
00657 }
00658 
00659 /********************************* LINK LCD ***********************************/
00660 /**
00661   * @brief  Initializes the LCD
00662   * @retval None
00663   */
00664 void LCD_IO_Init(void)
00665 {
00666   GPIO_InitTypeDef  gpioinitstruct = {0};
00667 
00668   /* LCD_CS_GPIO and LCD_DC_GPIO Periph clock enable */
00669   LCD_CS_GPIO_CLK_ENABLE();
00670   LCD_DC_GPIO_CLK_ENABLE();
00671   
00672   /* Configure LCD_CS_PIN pin: LCD Card CS pin */
00673   gpioinitstruct.Pin    = LCD_CS_PIN;
00674   gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
00675   gpioinitstruct.Pull   = GPIO_NOPULL;
00676   gpioinitstruct.Speed  = GPIO_SPEED_HIGH;
00677   HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
00678       
00679   /* Configure LCD_DC_PIN pin: LCD Card DC pin */
00680   gpioinitstruct.Pin    = LCD_DC_PIN;
00681   HAL_GPIO_Init(LCD_DC_GPIO_PORT, &gpioinitstruct);
00682 
00683   /* LCD chip select high */
00684   LCD_CS_HIGH();
00685   
00686   /* LCD SPI Config */
00687   SPIx_Init();
00688 }
00689 
00690 /**
00691   * @brief  Writes command to select the LCD register.
00692   * @param  LCDReg: Address of the selected register.
00693   * @retval None
00694   */
00695 void LCD_IO_WriteReg(uint8_t LCDReg)
00696 {
00697   /* Reset LCD control line CS */
00698   LCD_CS_LOW();
00699   
00700   /* Set LCD data/command line DC to Low */
00701   LCD_DC_LOW();
00702     
00703   /* Send Command */
00704   SPIx_Write(LCDReg);
00705   
00706   /* Deselect : Chip Select high */
00707   LCD_CS_HIGH();
00708 }
00709 
00710 /**
00711 * @brief  Write register value.
00712 * @param  pData Pointer on the register value
00713 * @param  Size Size of byte to transmit to the register
00714 * @retval None
00715 */
00716 void LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size)
00717 {
00718   uint32_t counter = 0;
00719   
00720   /* Reset LCD control line CS */
00721   LCD_CS_LOW();
00722   
00723   /* Set LCD data/command line DC to High */
00724   LCD_DC_HIGH();
00725 
00726   if (Size == 1)
00727   {
00728     /* Only 1 byte to be sent to LCD - general interface can be used */
00729     /* Send Data */
00730     SPIx_Write(*pData);
00731   }
00732   else
00733   {
00734     /* Several data should be sent in a raw */
00735     /* Direct SPI accesses for optimization */
00736     for (counter = Size; counter != 0; counter--)
00737     {
00738       while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
00739       {
00740       }
00741       /* Need to invert bytes for LCD*/
00742       *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *(pData+1);
00743       
00744       while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
00745       {
00746       }
00747       *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *pData;
00748       counter--;
00749       pData += 2;
00750     }
00751     
00752     /* Wait until the bus is ready before releasing Chip select */ 
00753     while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_BSY) != RESET)
00754     {
00755     }  
00756   } 
00757   /* Deselect : Chip Select high */
00758   LCD_CS_HIGH();
00759 }
00760 
00761 /**
00762   * @brief  Wait for loop in ms.
00763   * @param  Delay in ms.
00764   * @retval None
00765   */
00766 void LCD_Delay(uint32_t Delay)
00767 {
00768   HAL_Delay(Delay);
00769 }
00770 
00771 #endif /* HAL_SPI_MODULE_ENABLED */
00772 
00773 #ifdef HAL_ADC_MODULE_ENABLED
00774 /******************************* LINK JOYSTICK ********************************/
00775 /**
00776   * @brief  Initializes ADC MSP.
00777   * @retval None
00778   */
00779 static void ADCx_MspInit(ADC_HandleTypeDef *hadc)
00780 {
00781   GPIO_InitTypeDef  gpioinitstruct = {0};
00782   RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
00783   
00784   /*** Configure the GPIOs ***/  
00785   /* Enable GPIO clock */
00786   NUCLEO_ADCx_GPIO_CLK_ENABLE();
00787   
00788   /* Configure ADC1 Channel8 as analog input */
00789   gpioinitstruct.Pin    = NUCLEO_ADCx_GPIO_PIN ;
00790   gpioinitstruct.Mode   = GPIO_MODE_ANALOG_ADC_CONTROL;
00791   gpioinitstruct.Pull   = GPIO_NOPULL;
00792   gpioinitstruct.Speed  = GPIO_SPEED_FAST;
00793   HAL_GPIO_Init(NUCLEO_ADCx_GPIO_PORT, &gpioinitstruct);
00794 
00795   /*** Configure the ADC peripheral ***/ 
00796   /* Enable ADC clock */
00797   NUCLEO_ADCx_CLK_ENABLE();
00798   
00799   /* Configure SYSCLK as source clock for ADC */
00800   RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
00801   RCC_PeriphCLKInitStruct.AdcClockSelection    = RCC_ADCCLKSOURCE_SYSCLK;
00802   HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
00803 }
00804 
00805 /**
00806   * @brief  Initializes ADC HAL.
00807   * @retval None
00808   */
00809 static HAL_StatusTypeDef ADCx_Init(void)
00810 {
00811   if(HAL_ADC_GetState(&hnucleo_Adc) == HAL_ADC_STATE_RESET)
00812   {
00813     /* ADC Config */
00814     hnucleo_Adc.Instance                    = NUCLEO_ADCx;
00815     hnucleo_Adc.Init.ClockPrescaler         = ADC_CLOCK_ASYNC_DIV8; /* (must not exceed 16MHz) */
00816     hnucleo_Adc.Init.Resolution             = ADC_RESOLUTION_12B;
00817     hnucleo_Adc.Init.DataAlign              = ADC_DATAALIGN_RIGHT;
00818     hnucleo_Adc.Init.ScanConvMode           = DISABLE;
00819     hnucleo_Adc.Init.EOCSelection           = ADC_EOC_SINGLE_CONV;
00820     hnucleo_Adc.Init.LowPowerAutoWait       = ENABLE;
00821     hnucleo_Adc.Init.ContinuousConvMode     = DISABLE;
00822     hnucleo_Adc.Init.NbrOfConversion        = 1;
00823     hnucleo_Adc.Init.DiscontinuousConvMode  = DISABLE;
00824     hnucleo_Adc.Init.NbrOfDiscConversion    = 1;
00825     hnucleo_Adc.Init.ExternalTrigConv       = ADC_SOFTWARE_START;
00826     hnucleo_Adc.Init.ExternalTrigConvEdge   = ADC_EXTERNALTRIGCONVEDGE_NONE;
00827     hnucleo_Adc.Init.DMAContinuousRequests  = DISABLE;
00828     hnucleo_Adc.Init.Overrun                = ADC_OVR_DATA_PRESERVED;
00829     hnucleo_Adc.Init.OversamplingMode       = DISABLE;
00830     
00831     ADCx_MspInit(&hnucleo_Adc);
00832     if (HAL_ADC_Init(&hnucleo_Adc) != HAL_OK)
00833     {
00834       return HAL_ERROR;
00835     }
00836     
00837     if (HAL_ADCEx_Calibration_Start(&hnucleo_Adc,ADC_SINGLE_ENDED) != HAL_OK)
00838     {
00839       return HAL_ERROR;
00840     }
00841   }
00842 
00843   return HAL_OK;
00844 }  
00845 
00846 #endif /* HAL_ADC_MODULE_ENABLED */
00847 
00848 /**
00849   * @}
00850   */
00851 
00852 /**
00853   * @}
00854   */
00855 
00856 /**
00857   * @}
00858   */    
00859 
00860 /**
00861   * @}
00862   */ 
00863     
00864 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Jun 19 2015 16:52:00 for STM32L4xx_Nucleo BSP User Manual by   doxygen 1.7.6.1