STM32F0xx-Nucleo BSP User Manual: stm32f0xx_nucleo.c Source File

STM32F0xx Nucleo BSP Drivers

stm32f0xx_nucleo.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f0xx_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 STM32F0XX-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 "stm32f0xx_nucleo.h"
00042 
00043 /** @addtogroup BSP
00044   * @{
00045   */ 
00046 
00047 /** @addtogroup STM32F0XX_NUCLEO
00048   * @{
00049   */   
00050 
00051 /** @defgroup STM32F0XX_NUCLEO_Private_Defines Private Defines
00052   * @{
00053   */ 
00054 
00055 /**
00056   * @brief STM32F0XX NUCLEO BSP Driver version number V1.1.6
00057   */
00058 #define __STM32F0XX_NUCLEO_BSP_VERSION_MAIN   (0x01) /*!< [31:24] main version */
00059 #define __STM32F0XX_NUCLEO_BSP_VERSION_SUB1   (0x01) /*!< [23:16] sub1 version */
00060 #define __STM32F0XX_NUCLEO_BSP_VERSION_SUB2   (0x06) /*!< [15:8]  sub2 version */
00061 #define __STM32F0XX_NUCLEO_BSP_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
00062 #define __STM32F0XX_NUCLEO_BSP_VERSION        ((__STM32F0XX_NUCLEO_BSP_VERSION_MAIN << 24)\
00063                                               |(__STM32F0XX_NUCLEO_BSP_VERSION_SUB1 << 16)\
00064                                               |(__STM32F0XX_NUCLEO_BSP_VERSION_SUB2 << 8 )\
00065                                               |(__STM32F0XX_NUCLEO_BSP_VERSION_RC))
00066 
00067 /**
00068   * @brief LINK SD Card
00069   */
00070 #define SD_DUMMY_BYTE            0xFF    
00071 #define SD_NO_RESPONSE_EXPECTED  0x80
00072 
00073 /**
00074   * @}
00075   */ 
00076 
00077 /** @defgroup STM32F0XX_NUCLEO_Private_Variables Private Variables
00078   * @{
00079   */ 
00080 GPIO_TypeDef*  LED_PORT[LEDn] = {LED2_GPIO_PORT};
00081 const uint16_t LED_PIN[LEDn] = {LED2_PIN};
00082 
00083 GPIO_TypeDef*  BUTTON_PORT[BUTTONn] = {USER_BUTTON_GPIO_PORT};
00084 const uint16_t BUTTON_PIN[BUTTONn] = {USER_BUTTON_PIN};
00085 const uint8_t  BUTTON_IRQn[BUTTONn] = {USER_BUTTON_EXTI_IRQn };
00086 
00087 /**
00088  * @brief BUS variables
00089  */
00090 
00091 #ifdef HAL_SPI_MODULE_ENABLED
00092 uint32_t SpixTimeout = NUCLEO_SPIx_TIMEOUT_MAX; /*<! Value of Timeout when SPI communication fails */
00093 static SPI_HandleTypeDef hnucleo_Spi;
00094 #endif /* HAL_SPI_MODULE_ENABLED */
00095 
00096 #ifdef HAL_ADC_MODULE_ENABLED
00097 static ADC_HandleTypeDef hnucleo_Adc;
00098 /* ADC channel configuration structure declaration */
00099 static ADC_ChannelConfTypeDef sConfig;
00100 #endif /* HAL_ADC_MODULE_ENABLED */
00101 /**
00102   * @}
00103   */ 
00104 
00105 /** @defgroup STM32F0XX_NUCLEO_Private_Functions Private Functions
00106   * @{
00107   */
00108 #ifdef HAL_SPI_MODULE_ENABLED
00109 static void       SPIx_Init(void);
00110 static void       SPIx_Write(uint8_t Value);
00111 static void       SPIx_WriteData(uint8_t *DataIn, uint16_t DataLength);
00112 static void       SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth);
00113 static void       SPIx_FlushFifo(void);
00114 static void       SPIx_Error(void);
00115 static void       SPIx_MspInit(void);
00116 
00117 /* SD IO functions */
00118 void              SD_IO_Init(void);
00119 void              SD_IO_CSState(uint8_t state);
00120 void              SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength);
00121 void              SD_IO_ReadData(uint8_t *DataOut, uint16_t DataLength);
00122 void              SD_IO_WriteData(const uint8_t *Data, uint16_t DataLength);
00123 uint8_t           SD_IO_WriteByte(uint8_t Data);
00124 uint8_t           SD_IO_ReadByte(void);
00125 
00126 /* LCD IO functions */
00127 void              LCD_IO_Init(void);
00128 void              LCD_IO_WriteData(uint8_t Data);
00129 void              LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size);
00130 void              LCD_IO_WriteReg(uint8_t LCDReg);
00131 void              LCD_Delay(uint32_t delay);
00132 #endif /* HAL_SPI_MODULE_ENABLED */
00133 
00134 #ifdef HAL_ADC_MODULE_ENABLED
00135 static HAL_StatusTypeDef  ADCx_Init(void);
00136 static void               ADCx_DeInit(void);
00137 static void               ADCx_MspInit(ADC_HandleTypeDef *hadc);
00138 static void               ADCx_MspDeInit(ADC_HandleTypeDef *hadc);
00139 #endif /* HAL_ADC_MODULE_ENABLED */
00140 /**
00141   * @}
00142   */ 
00143 
00144 /** @defgroup STM32F0XX_NUCLEO_Exported_Functions Exported Functions
00145   * @{
00146   */ 
00147 
00148 /**
00149   * @brief  This method returns the STM32F0XX NUCLEO BSP Driver revision
00150   * @retval version : 0xXYZR (8bits for each decimal, R for RC)
00151   */
00152 uint32_t BSP_GetVersion(void)
00153 {
00154   return __STM32F0XX_NUCLEO_BSP_VERSION;
00155 }
00156 
00157 /** @addtogroup STM32F0XX_NUCLEO_LED_Functions
00158   * @{
00159   */ 
00160 
00161 /**
00162   * @brief  Configures LED GPIO.
00163   * @param  Led Led to be configured. 
00164   *         This parameter can be one of the following values:
00165   * @arg LED2
00166   * @retval None
00167   */
00168 void BSP_LED_Init(Led_TypeDef Led)
00169 {
00170   GPIO_InitTypeDef  gpioinitstruct;
00171   
00172   /* Enable the GPIO_LED Clock */
00173   LEDx_GPIO_CLK_ENABLE(Led);
00174 
00175   /* Configure the GPIO_LED pin */
00176   gpioinitstruct.Pin = LED_PIN[Led];
00177   gpioinitstruct.Mode = GPIO_MODE_OUTPUT_PP;
00178   gpioinitstruct.Pull = GPIO_NOPULL;
00179   gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH;
00180   
00181   HAL_GPIO_Init(LED_PORT[Led], &gpioinitstruct);
00182 }
00183 
00184 /**
00185   * @brief  DeInit LEDs.
00186   * @param  Led LED to be de-init. 
00187   *   This parameter can be one of the following values:
00188   *     @arg  LED2
00189   * @note Led DeInit does not disable the GPIO clock nor disable the Mfx 
00190   * @retval None
00191   */
00192 void BSP_LED_DeInit(Led_TypeDef Led)
00193 {
00194   GPIO_InitTypeDef  gpio_init_structure;
00195 
00196   /* Turn off LED */
00197   HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET);
00198   /* DeInit the GPIO_LED pin */
00199   gpio_init_structure.Pin = LED_PIN[Led];
00200   HAL_GPIO_DeInit(LED_PORT[Led], gpio_init_structure.Pin);
00201 }
00202 
00203 /**
00204   * @brief  Turns selected LED On.
00205   * @param  Led Specifies the Led to be set on. 
00206   *   This parameter can be one of following parameters:
00207   *     @arg LED2
00208   * @retval None
00209   */
00210 void BSP_LED_On(Led_TypeDef Led)
00211 {
00212   HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET); 
00213 }
00214 
00215 /**
00216   * @brief  Turns selected LED Off.
00217   * @param  Led Specifies the Led to be set off. 
00218   *   This parameter can be one of following parameters:
00219   *     @arg LED2
00220   * @retval None
00221   */
00222 void BSP_LED_Off(Led_TypeDef Led)
00223 {
00224   HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_RESET); 
00225 }
00226 
00227 /**
00228   * @brief  Toggles the selected LED.
00229   * @param  Led Specifies the Led to be toggled. 
00230   *   This parameter can be one of following parameters:
00231   *     @arg LED2
00232   * @retval None
00233   */
00234 void BSP_LED_Toggle(Led_TypeDef Led)
00235 {
00236   HAL_GPIO_TogglePin(LED_PORT[Led], LED_PIN[Led]);
00237 }
00238 
00239 /**
00240   * @}
00241   */ 
00242 
00243 /** @defgroup STM32F0XX_NUCLEO_BUTTON_Functions BUTTON Functions
00244   * @{
00245   */ 
00246 
00247 /**
00248   * @brief  Configures Button GPIO and EXTI Line.
00249   * @param  Button Specifies the Button to be configured.
00250   *   This parameter should be: BUTTON_USER
00251   * @param  ButtonMode Specifies Button mode.
00252   *   This parameter can be one of following parameters:   
00253   *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO
00254   *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
00255   *                            generation capability  
00256   * @retval None
00257   */
00258 void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
00259 {
00260   GPIO_InitTypeDef gpioinitstruct;
00261 
00262   /* Enable the BUTTON Clock */
00263   BUTTONx_GPIO_CLK_ENABLE(Button);
00264 
00265   gpioinitstruct.Pin = BUTTON_PIN[Button];
00266   gpioinitstruct.Pull = GPIO_NOPULL;
00267   gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH;
00268 
00269   if(ButtonMode == BUTTON_MODE_GPIO)
00270   {
00271     /* Configure Button pin as input */
00272     gpioinitstruct.Mode = GPIO_MODE_INPUT;
00273 
00274     HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
00275   }
00276 
00277   if(ButtonMode == BUTTON_MODE_EXTI)
00278   {
00279     /* Configure Button pin as input with External interrupt */
00280     gpioinitstruct.Mode = GPIO_MODE_IT_FALLING;
00281 
00282     HAL_GPIO_Init(BUTTON_PORT[Button], &gpioinitstruct);
00283 
00284     /* Enable and set Button EXTI Interrupt to the lowest priority */
00285     HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x03, 0x00);
00286     HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
00287   }
00288 }
00289 
00290 /**
00291   * @brief  Push Button DeInit.
00292   * @param  Button Button to be configured
00293   *   This parameter should be: BUTTON_USER
00294   * @note PB DeInit does not disable the GPIO clock
00295   * @retval None
00296   */
00297 void BSP_PB_DeInit(Button_TypeDef Button)
00298 {
00299   GPIO_InitTypeDef gpio_init_structure;
00300 
00301   gpio_init_structure.Pin = BUTTON_PIN[Button];
00302   HAL_NVIC_DisableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
00303   HAL_GPIO_DeInit(BUTTON_PORT[Button], gpio_init_structure.Pin);
00304 }
00305 
00306 /**
00307   * @brief  Returns the selected Button state.
00308   * @param  Button Specifies the Button to be checked.
00309   *   This parameter should be: BUTTON_USER
00310   * @retval Button state.
00311   */
00312 uint32_t BSP_PB_GetState(Button_TypeDef Button)
00313 {
00314   return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
00315 }
00316 /**
00317   * @}
00318   */ 
00319 
00320 /**
00321   * @}
00322   */
00323 
00324 /** @addtogroup STM32F0XX_NUCLEO_Private_Functions
00325   * @{
00326   */ 
00327 
00328 #ifdef HAL_SPI_MODULE_ENABLED
00329 /******************************************************************************
00330                             BUS OPERATIONS
00331 *******************************************************************************/
00332 /**
00333   * @brief  Initialize SPI MSP.
00334   * @retval None
00335   */
00336 static void SPIx_MspInit(void)
00337 {
00338   GPIO_InitTypeDef  gpioinitstruct = {0};
00339   
00340   /*** Configure the GPIOs ***/  
00341   /* Enable GPIO clock */
00342   NUCLEO_SPIx_SCK_GPIO_CLK_ENABLE();
00343   NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_ENABLE();
00344 
00345   /* Configure SPI SCK */
00346   gpioinitstruct.Pin = NUCLEO_SPIx_SCK_PIN;
00347   gpioinitstruct.Mode = GPIO_MODE_AF_PP;
00348   gpioinitstruct.Pull  = GPIO_PULLUP;
00349   gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH;
00350   gpioinitstruct.Alternate = NUCLEO_SPIx_SCK_AF;
00351   HAL_GPIO_Init(NUCLEO_SPIx_SCK_GPIO_PORT, &gpioinitstruct);
00352 
00353   /* Configure SPI MISO and MOSI */ 
00354   gpioinitstruct.Pin = NUCLEO_SPIx_MOSI_PIN;
00355   gpioinitstruct.Alternate = NUCLEO_SPIx_MISO_MOSI_AF;
00356   gpioinitstruct.Pull  = GPIO_PULLDOWN;
00357   HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &gpioinitstruct);
00358   
00359   gpioinitstruct.Pin = NUCLEO_SPIx_MISO_PIN;
00360   HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &gpioinitstruct);
00361 
00362   /*** Configure the SPI peripheral ***/ 
00363   /* Enable SPI clock */
00364   NUCLEO_SPIx_CLK_ENABLE();
00365 }
00366 
00367 /**
00368   * @brief  Initialize 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 12 MHz maximum (PCLK1/SPI_BaudRatePrescaler = 48/4 = 12 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 48 MHz 
00384        */ 
00385     hnucleo_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
00386     hnucleo_Spi.Init.Direction = SPI_DIRECTION_2LINES;
00387     hnucleo_Spi.Init.CLKPhase = SPI_PHASE_2EDGE;
00388     hnucleo_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH;
00389     hnucleo_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
00390     hnucleo_Spi.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
00391     hnucleo_Spi.Init.CRCPolynomial = 7;
00392     hnucleo_Spi.Init.DataSize = SPI_DATASIZE_8BIT;
00393     hnucleo_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
00394     hnucleo_Spi.Init.NSS = SPI_NSS_SOFT;
00395     hnucleo_Spi.Init.TIMode = SPI_TIMODE_DISABLE;
00396     hnucleo_Spi.Init.NSSPMode = SPI_NSS_PULSE_DISABLE;
00397     hnucleo_Spi.Init.Mode = SPI_MODE_MASTER;
00398 
00399     SPIx_MspInit();
00400     HAL_SPI_Init(&hnucleo_Spi);
00401   }
00402 }
00403 
00404 /**
00405   * @brief  SPI Write a byte to device
00406   * @param  DataIn value to be written
00407   * @param  DataOut read value
00408   * @param  DataLength value data length
00409   * @retval None
00410   */
00411 static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength)
00412 {
00413   HAL_StatusTypeDef status = HAL_OK;
00414 
00415   status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) DataIn, DataOut, DataLength, SpixTimeout);
00416 
00417   /* Check the communication status */
00418   if(status != HAL_OK)
00419   {
00420     /* Execute user timeout callback */
00421     SPIx_Error();
00422   }
00423 }
00424 
00425 /**
00426   * @brief  SPI Write an amount of data to device
00427   * @param  DataIn value to be written
00428   * @param  DataLength number of bytes to write
00429   * @retval None
00430   */
00431 static void SPIx_WriteData(uint8_t *DataIn, uint16_t DataLength)
00432 {
00433   HAL_StatusTypeDef status = HAL_OK;
00434   
00435   status = HAL_SPI_Transmit(&hnucleo_Spi, DataIn, DataLength, SpixTimeout);
00436   
00437   /* Check the communication status */
00438   if(status != HAL_OK)
00439   {
00440     /* Execute user timeout callback */
00441     SPIx_Error();
00442   }
00443 }
00444 
00445 /**
00446   * @brief  SPI Write a byte to device
00447   * @param  Value value to be written
00448   * @retval None
00449   */
00450 static void SPIx_Write(uint8_t Value)
00451 {
00452   HAL_StatusTypeDef status = HAL_OK;
00453   uint8_t data;
00454 
00455   status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) &Value, &data, 1, SpixTimeout);
00456   
00457   /* Check the communication status */
00458   if(status != HAL_OK)
00459   {
00460     /* Execute user timeout callback */
00461     SPIx_Error();
00462   }
00463 }
00464 
00465 /**
00466   * @brief  SPIx_FlushFifo
00467   * @retval None
00468   */
00469 static void SPIx_FlushFifo(void)
00470 {
00471 
00472   HAL_SPIEx_FlushRxFifo(&hnucleo_Spi);
00473 }
00474 
00475 /**
00476   * @brief  SPI error treatment function
00477   * @retval None
00478   */
00479 static void SPIx_Error (void)
00480 {
00481   /* De-initialize the SPI communication BUS */
00482   HAL_SPI_DeInit(&hnucleo_Spi);
00483 
00484   /* Re-Initiaize the SPI communication BUS */
00485   SPIx_Init();
00486 }
00487 
00488 /******************************************************************************
00489                             LINK OPERATIONS
00490 *******************************************************************************/
00491 
00492 /********************************* LINK SD ************************************/
00493 /**
00494   * @brief  Initialize 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  gpioinitstruct = {0};
00501   uint8_t counter = 0;
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   gpioinitstruct.Pin = SD_CS_PIN;
00508   gpioinitstruct.Mode = GPIO_MODE_OUTPUT_PP;
00509   gpioinitstruct.Pull = GPIO_PULLUP;
00510   gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH;
00511   HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
00512 
00513   /* Configure LCD_CS_PIN pin: LCD Card CS pin */
00514   gpioinitstruct.Pin   = LCD_CS_PIN;
00515   gpioinitstruct.Mode  = GPIO_MODE_OUTPUT_PP;
00516   gpioinitstruct.Pull  = GPIO_NOPULL;
00517   gpioinitstruct.Speed = GPIO_SPEED_FREQ_HIGH;
00518   HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
00519   LCD_CS_HIGH();
00520 
00521   /*------------Put SD in SPI mode--------------*/
00522   /* SD SPI Config */
00523   SPIx_Init();
00524 
00525   /* SD chip select high */
00526   SD_CS_HIGH();
00527   
00528   /* Send dummy byte 0xFF, 10 times with CS high */
00529   /* Rise CS and MOSI for 80 clocks cycles */
00530   for (counter = 0; counter <= 9; counter++)
00531   {
00532     /* Send dummy byte 0xFF */
00533     SD_IO_WriteByte(SD_DUMMY_BYTE);
00534   }
00535 }
00536 
00537 /**
00538   * @brief  Set the SD_CS pin.
00539   * @param  val pin value.
00540   * @retval None
00541   */
00542 void SD_IO_CSState(uint8_t val)
00543 {
00544   if(val == 1) 
00545   {
00546     SD_CS_HIGH();
00547   }
00548   else
00549   {
00550     SD_CS_LOW();
00551   }
00552 }
00553 
00554 /**
00555   * @brief  Write byte(s) on the SD
00556   * @param  DataIn Pointer to data buffer to write
00557   * @param  DataOut Pointer to data buffer for read data
00558   * @param  DataLength number of bytes to write
00559   * @retval None
00560   */
00561 void SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength)
00562 {
00563   /* Send the byte */
00564   SPIx_WriteReadData(DataIn, DataOut, DataLength);
00565 }
00566 
00567 /**
00568   * @brief  Write a byte on the SD.
00569   * @param  Data byte to send.
00570   * @retval Data written
00571   */
00572 uint8_t SD_IO_WriteByte(uint8_t Data)
00573 {
00574   uint8_t tmp;
00575 
00576   /* Send the byte */
00577   SPIx_WriteReadData(&Data,&tmp,1);
00578   return tmp;
00579 }
00580 
00581 /**
00582   * @brief  Write an amount of data on the SD.
00583   * @param  DataOut byte to send.
00584   * @param  DataLength number of bytes to write
00585   * @retval none
00586   */
00587 void SD_IO_ReadData(uint8_t *DataOut, uint16_t DataLength)
00588 {
00589   /* Send the byte */
00590   SD_IO_WriteReadData(DataOut, DataOut, DataLength);
00591 }
00592 
00593 /**
00594   * @brief  Write an amount of data on the SD.
00595   * @param  Data byte to send.
00596   * @param  DataLength number of bytes to write
00597   * @retval none
00598   */
00599 void SD_IO_WriteData(const uint8_t *Data, uint16_t DataLength)
00600 {
00601   /* Send the byte */
00602   SPIx_WriteData((uint8_t *)Data, DataLength);
00603   SPIx_FlushFifo();
00604 }
00605 
00606 /********************************* LINK LCD ***********************************/
00607 /**
00608   * @brief  Initialize the LCD
00609   * @retval None
00610   */
00611 void LCD_IO_Init(void)
00612 {
00613   GPIO_InitTypeDef  gpioinitstruct;
00614 
00615   /* LCD_CS_GPIO and LCD_DC_GPIO Periph clock enable */
00616   LCD_CS_GPIO_CLK_ENABLE();
00617   LCD_DC_GPIO_CLK_ENABLE();
00618   
00619   /* Configure LCD_CS_PIN pin: LCD Card CS pin */
00620   gpioinitstruct.Pin    = LCD_CS_PIN;
00621   gpioinitstruct.Mode   = GPIO_MODE_OUTPUT_PP;
00622   gpioinitstruct.Pull   = GPIO_NOPULL;
00623   gpioinitstruct.Speed  = GPIO_SPEED_FREQ_HIGH;
00624   HAL_GPIO_Init(SD_CS_GPIO_PORT, &gpioinitstruct);
00625 
00626   /* Configure LCD_DC_PIN pin: LCD Card DC pin */
00627   gpioinitstruct.Pin    = LCD_DC_PIN;
00628   HAL_GPIO_Init(LCD_DC_GPIO_PORT, &gpioinitstruct);
00629 
00630   /* LCD chip select high */
00631   LCD_CS_HIGH();
00632   
00633   /* LCD SPI Config */
00634   SPIx_Init();
00635 }
00636 
00637 /**
00638   * @brief  Write command to select the LCD register.
00639   * @param  LCDReg Address of the selected register.
00640   * @retval None
00641   */
00642 void LCD_IO_WriteReg(uint8_t LCDReg)
00643 {
00644   /* Reset LCD control line CS */
00645   LCD_CS_LOW();
00646   
00647   /* Set LCD data/command line DC to Low */
00648   LCD_DC_LOW();
00649     
00650   /* Send Command */
00651   SPIx_Write(LCDReg);
00652   
00653   /* Deselect : Chip Select high */
00654   LCD_CS_HIGH();
00655 }
00656 
00657 /**
00658 * @brief  Write register value.
00659 * @param  pData Pointer on the register value
00660 * @param  Size Size of byte to transmit to the register
00661 * @retval None
00662 */
00663 void LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size)
00664 {
00665   uint32_t counter = 0;
00666   
00667   /* Reset LCD control line CS */
00668   LCD_CS_LOW();
00669   
00670   /* Set LCD data/command line DC to High */
00671   LCD_DC_HIGH();
00672 
00673   if (Size == 1)
00674   {
00675     /* Only 1 byte to be sent to LCD - general interface can be used */
00676     /* Send Data */
00677     SPIx_Write(*pData);
00678   }
00679   else
00680   {
00681     /* Several data should be sent in a raw */
00682     /* Direct SPI accesses for optimization */
00683     for (counter = Size; counter != 0; counter--)
00684     {
00685       while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
00686       {
00687       }
00688       /* Need to invert bytes for LCD*/
00689       *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *(pData+1);
00690       
00691       while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
00692       {
00693       }
00694       *((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *pData;
00695       counter--;
00696       pData += 2;
00697     }
00698   
00699     /* Wait until the bus is ready before releasing Chip select */ 
00700     while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_BSY) != RESET)
00701     {
00702     } 
00703   } 
00704 
00705   /* Empty the Rx fifo */
00706   SPIx_FlushFifo();
00707   
00708   /* Deselect : Chip Select high */
00709   LCD_CS_HIGH();
00710 }
00711 
00712 /**
00713   * @brief  Wait for loop in ms.
00714   * @param  Delay in ms.
00715   * @retval None
00716   */
00717 void LCD_Delay(uint32_t Delay)
00718 {
00719   HAL_Delay(Delay);
00720 }
00721 
00722 #endif /* HAL_SPI_MODULE_ENABLED */
00723 
00724 #ifdef HAL_ADC_MODULE_ENABLED
00725 /******************************* LINK JOYSTICK ********************************/
00726 /**
00727   * @brief  Initialize ADC MSP.
00728   * @retval None
00729   */
00730 static void ADCx_MspInit(ADC_HandleTypeDef *hadc)
00731 {
00732   GPIO_InitTypeDef  gpioinitstruct;
00733   
00734   /*** Configure the GPIOs ***/  
00735   /* Enable GPIO clock */
00736   NUCLEO_ADCx_GPIO_CLK_ENABLE();
00737   
00738   /* Configure ADC1 Channel8 as analog input */
00739   gpioinitstruct.Pin = NUCLEO_ADCx_GPIO_PIN ;
00740   gpioinitstruct.Mode = GPIO_MODE_ANALOG;
00741   HAL_GPIO_Init(NUCLEO_ADCx_GPIO_PORT, &gpioinitstruct);
00742 
00743   /*** Configure the ADC peripheral ***/ 
00744   /* Enable ADC clock */
00745   NUCLEO_ADCx_CLK_ENABLE();
00746 }
00747 
00748 /**
00749   * @brief  DeInitializes ADC MSP.
00750   * @note ADC DeInit does not disable the GPIO clock
00751   * @retval None
00752   */
00753 static void ADCx_MspDeInit(ADC_HandleTypeDef *hadc)
00754 {
00755   GPIO_InitTypeDef  gpioinitstruct;
00756 
00757   /*** DeInit the ADC peripheral ***/ 
00758   /* Disable ADC clock */
00759   NUCLEO_ADCx_CLK_DISABLE(); 
00760 
00761   /* Configure the selected ADC Channel as analog input */
00762   gpioinitstruct.Pin = NUCLEO_ADCx_GPIO_PIN ;
00763   HAL_GPIO_DeInit(NUCLEO_ADCx_GPIO_PORT, gpioinitstruct.Pin);
00764 
00765   /* Disable GPIO clock has to be done by the application*/
00766   /* NUCLEO_ADCx_GPIO_CLK_DISABLE(); */
00767 }
00768 
00769 /**
00770   * @brief  Initializes ADC HAL.
00771   * @retval None
00772   */
00773 static HAL_StatusTypeDef ADCx_Init(void)
00774 {
00775   /* Set ADC instance */
00776   hnucleo_Adc.Instance                   = NUCLEO_ADCx;
00777   
00778   if(HAL_ADC_GetState(&hnucleo_Adc) == HAL_ADC_STATE_RESET)
00779   {
00780     /* ADC Config */
00781     hnucleo_Adc.Init.ClockPrescaler        = ADC_CLOCK_SYNC_PCLK_DIV4;      /* ADC clock of STM32F0 must not exceed 14MHz */
00782     hnucleo_Adc.Init.Resolution            = ADC_RESOLUTION_12B;
00783     hnucleo_Adc.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
00784     hnucleo_Adc.Init.ScanConvMode          = ADC_SCAN_DIRECTION_FORWARD;    /* Sequencer will convert the number of channels configured below, successively from the lowest to the highest channel number */
00785     hnucleo_Adc.Init.EOCSelection          = ADC_EOC_SINGLE_CONV;
00786     hnucleo_Adc.Init.LowPowerAutoWait      = DISABLE;
00787     hnucleo_Adc.Init.LowPowerAutoPowerOff  = DISABLE;
00788     hnucleo_Adc.Init.ContinuousConvMode    = DISABLE;                       /* Continuous mode disabled to have only 1 conversion at each conversion trig */
00789     hnucleo_Adc.Init.DiscontinuousConvMode = DISABLE;                       /* Parameter discarded because sequencer is disabled */
00790     hnucleo_Adc.Init.ExternalTrigConv      = ADC_SOFTWARE_START;            /* Software start to trig the 1st conversion manually, without external event */
00791     hnucleo_Adc.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE; /* Parameter discarded because trig by software start */
00792     hnucleo_Adc.Init.DMAContinuousRequests = DISABLE;
00793     hnucleo_Adc.Init.Overrun               = ADC_OVR_DATA_OVERWRITTEN;
00794     hnucleo_Adc.Init.SamplingTimeCommon    = ADC_SAMPLETIME_41CYCLES_5;
00795     
00796     /* Initialize MSP related to ADC */
00797     ADCx_MspInit(&hnucleo_Adc);
00798     
00799     /* Initialize ADC */
00800     if (HAL_ADC_Init(&hnucleo_Adc) != HAL_OK)
00801     {
00802       return HAL_ERROR;
00803     }
00804 
00805     /* Run ADC calibration */
00806     if (HAL_ADCEx_Calibration_Start(&hnucleo_Adc) != HAL_OK)
00807     {
00808       return HAL_ERROR;
00809     }
00810   }
00811   
00812   return HAL_OK;
00813 }
00814 
00815 /**
00816   * @brief  Initializes ADC HAL.
00817   * @retval None
00818   */
00819 static void ADCx_DeInit(void)
00820 {
00821     hnucleo_Adc.Instance   = NUCLEO_ADCx;
00822     
00823     HAL_ADC_DeInit(&hnucleo_Adc);
00824     ADCx_MspDeInit(&hnucleo_Adc);
00825 }
00826 
00827 /******************************* LINK JOYSTICK ********************************/
00828 
00829 /**
00830   * @brief  Configures joystick available on adafruit 1.8" TFT shield 
00831   *         managed through ADC to detect motion.
00832   * @retval Joystickstatus (0=> success, 1=> fail) 
00833   */
00834 uint8_t BSP_JOY_Init(void)
00835 {
00836   if (ADCx_Init() != HAL_OK)
00837   {
00838     return (uint8_t) HAL_ERROR; 
00839   }
00840   
00841   /* Select Channel 8 to be converted */
00842   sConfig.Channel = ADC_CHANNEL_8;
00843   sConfig.Rank    = ADC_RANK_CHANNEL_NUMBER;
00844 
00845   /* Return Joystick initialization status */
00846   return (uint8_t)HAL_ADC_ConfigChannel(&hnucleo_Adc, &sConfig);
00847 }
00848 
00849 /**
00850   * @brief  DeInit joystick GPIOs.
00851   * @note   JOY DeInit does not disable the Mfx, just set the Mfx pins in Off mode
00852   * @retval None.
00853   */
00854 void BSP_JOY_DeInit(void)
00855 {
00856     ADCx_DeInit();
00857 }
00858 
00859 /**
00860   * @brief  Returns the Joystick key pressed.
00861   * @note   To know which Joystick key is pressed we need to detect the voltage
00862   *         level on each key output
00863   *           - None  : 3.3 V / 4095
00864   *           - SEL   : 1.055 V / 1308
00865   *           - DOWN  : 0.71 V / 88
00866   *           - LEFT  : 3.0 V / 3720 
00867   *           - RIGHT : 0.595 V / 737
00868   *           - UP    : 1.65 V / 2046
00869   * @retval JOYState_TypeDef: Code of the Joystick key pressed.
00870   */
00871 JOYState_TypeDef BSP_JOY_GetState(void)
00872 {
00873   JOYState_TypeDef state;
00874   uint16_t  KeyConvertedValue = 0;
00875   
00876  /* Start the conversion process */
00877   HAL_ADC_Start(&hnucleo_Adc);
00878   
00879   /* Wait for the end of conversion */
00880   if (HAL_ADC_PollForConversion(&hnucleo_Adc, 10) != HAL_TIMEOUT)
00881   {
00882     /* Get the converted value of regular channel */
00883     KeyConvertedValue = HAL_ADC_GetValue(&hnucleo_Adc);
00884   }
00885   
00886   if((KeyConvertedValue > 2010) && (KeyConvertedValue < 2090))
00887   {
00888     state = JOY_UP;
00889   }
00890   else if((KeyConvertedValue > 680) && (KeyConvertedValue < 780))
00891   {
00892     state = JOY_RIGHT;
00893   }
00894   else if((KeyConvertedValue > 1270) && (KeyConvertedValue < 1350))
00895   {
00896     state = JOY_SEL;
00897   }
00898   else if((KeyConvertedValue > 50) && (KeyConvertedValue < 130))
00899   {
00900     state = JOY_DOWN;
00901   }
00902   else if((KeyConvertedValue > 3680) && (KeyConvertedValue < 3760))
00903   {
00904     state = JOY_LEFT;
00905   }
00906   else
00907   {
00908     state = JOY_NONE;
00909   }
00910   
00911   /* Return the code of the Joystick key pressed */
00912   return state;
00913 }
00914 #endif /* HAL_ADC_MODULE_ENABLED */
00915 
00916 /**
00917   * @}
00918   */
00919 
00920 /**
00921   * @}
00922   */
00923 
00924 /**
00925   * @}
00926   */    
00927 
00928 /**
00929   * @}
00930   */ 
00931 
00932 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Wed Jul 5 2017 09:45:49 for STM32F0xx-Nucleo BSP User Manual by   doxygen 1.7.6.1