my fork

Dependencies:   mbed

Revision:
4:987b201ec4b1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/stm32f4xx_nucleo.c	Wed Apr 08 14:17:20 2015 +0000
@@ -0,0 +1,801 @@
+/**
+  ******************************************************************************
+  * @file    stm32f4xx_nucleo.c
+  * @author  MCD Application Team
+  * @version V1.1.0
+  * @date    19-June-2014
+  * @cond DOXYGEN_EXCLUDE
+  * @brief   This file provides set of firmware functions to manage:
+  *          + LEDs and push-button available on STM32F4XX-Nucleo Kit 
+  *            from STMicroelectronics.
+  *          + LCD, joystick and microSD available on Adafruit 1.8" TFT LCD 
+  *            Expansion Board (reference ID 802).
+  * @endcond
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
+  *
+  * Redistribution and use in source and binary forms, with or without modification,
+  * are permitted provided that the following conditions are met:
+  *   1. Redistributions of source code must retain the above copyright notice,
+  *      this list of conditions and the following disclaimer.
+  *   2. Redistributions in binary form must reproduce the above copyright notice,
+  *      this list of conditions and the following disclaimer in the documentation
+  *      and/or other materials provided with the distribution.
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */ 
+  
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_nucleo.h"
+
+/** @addtogroup BSP
+  * @{
+  */ 
+
+/** @addtogroup STM32F4XX_NUCLEO
+  * @{
+  */   
+    
+/** @addtogroup STM32F4XX_NUCLEO_LOW_LEVEL 
+  * @brief This file provides set of firmware functions to manage Leds and push-button
+  *        available on STM32F4xx-Nucleo Kit from STMicroelectronics.
+  * @{
+  */ 
+
+/** @defgroup STM32F4XX_NUCLEO_LOW_LEVEL_Private_TypesDefinitions
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+
+/** @defgroup STM32F4XX_NUCLEO_LOW_LEVEL_Private_Defines
+  * @{
+  */ 
+
+/**
+  * @brief STM32F4xx NUCLEO BSP Driver version number V1.1.0
+  */
+#define __STM32F4xx_NUCLEO_BSP_VERSION_MAIN   (0x01) /*!< [31:24] main version */
+#define __STM32F4xx_NUCLEO_BSP_VERSION_SUB1   (0x01) /*!< [23:16] sub1 version */
+#define __STM32F4xx_NUCLEO_BSP_VERSION_SUB2   (0x00) /*!< [15:8]  sub2 version */
+#define __STM32F4xx_NUCLEO_BSP_VERSION_RC     (0x00) /*!< [7:0]  release candidate */ 
+#define __STM32F4xx_NUCLEO_BSP_VERSION        ((__STM32F4xx_NUCLEO_BSP_VERSION_MAIN << 24)\
+                                             |(__STM32F4xx_NUCLEO_BSP_VERSION_SUB1 << 16)\
+                                             |(__STM32F4xx_NUCLEO_BSP_VERSION_SUB2 << 8 )\
+                                             |(__STM32F4xx_NUCLEO_BSP_VERSION_RC))   
+
+/**
+  * @brief LINK SD Card
+  */
+#define SD_DUMMY_BYTE            0xFF    
+#define SD_NO_RESPONSE_EXPECTED  0x80
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32F4XX_NUCLEO_LOW_LEVEL_Private_Macros
+  * @{
+  */ 
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32F4XX_NUCLEO_LOW_LEVEL_Private_Variables
+  * @{
+  */ 
+GPIO_TypeDef* GPIO_PORT[LEDn] = {LED2_GPIO_PORT};
+
+const uint16_t GPIO_PIN[LEDn] = {LED2_PIN};
+
+GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {KEY_BUTTON_GPIO_PORT}; 
+const uint16_t BUTTON_PIN[BUTTONn] = {KEY_BUTTON_PIN}; 
+const uint8_t BUTTON_IRQn[BUTTONn] = {KEY_BUTTON_EXTI_IRQn};
+
+/**
+ * @brief BUS variables
+ */
+
+uint32_t SpixTimeout = NUCLEO_SPIx_TIMEOUT_MAX; /*<! Value of Timeout when SPI communication fails */
+static SPI_HandleTypeDef hnucleo_Spi;
+static ADC_HandleTypeDef hnucleo_Adc;
+
+/* ADC channel configuration structure declaration */
+static ADC_ChannelConfTypeDef sConfig;
+
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32F4XX_NUCLEO_LOW_LEVEL_Private_FunctionPrototypes
+  * @{
+  */
+static void       SPIx_Init(void);
+static void       SPIx_Write(uint8_t Value);
+static uint32_t   SPIx_Read(void);
+static void       SPIx_Error(void);
+static void       SPIx_MspInit(SPI_HandleTypeDef *hspi);
+
+static void       ADCx_Init(void);
+static void       ADCx_MspInit(ADC_HandleTypeDef *hadc);
+
+/* SD IO functions */
+void              SD_IO_Init(void);
+HAL_StatusTypeDef SD_IO_WriteCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response);
+HAL_StatusTypeDef SD_IO_WaitResponse(uint8_t Response);
+void              SD_IO_WriteDummy(void);
+void              SD_IO_WriteByte(uint8_t Data);
+uint8_t           SD_IO_ReadByte(void);
+
+/* LCD IO functions */
+void              LCD_IO_Init(void);
+void              LCD_IO_WriteData(uint8_t Data);
+void              LCD_IO_WriteReg(uint8_t LCDReg);
+void              LCD_Delay(uint32_t delay);
+/**
+  * @}
+  */ 
+
+/** @defgroup STM32F4XX_NUCLEO_LOW_LEVEL_Private_Functions
+  * @{
+  */ 
+
+/**
+  * @brief  This method returns the STM32F4xx NUCLEO BSP Driver revision
+  * @param  None
+  * @retval version: 0xXYZR (8bits for each decimal, R for RC)
+  */
+uint32_t BSP_GetVersion(void)
+{
+  return __STM32F4xx_NUCLEO_BSP_VERSION;
+}
+
+/**
+  * @brief  Configures LED GPIO.
+  * @param  Led: Specifies the Led to be configured. 
+  *   This parameter can be one of following parameters:
+  *     @arg LED2
+  * @retval None
+  */
+void BSP_LED_Init(Led_TypeDef Led)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+  
+  /* Enable the GPIO_LED Clock */
+  LEDx_GPIO_CLK_ENABLE(Led);
+  
+  /* Configure the GPIO_LED pin */
+  GPIO_InitStruct.Pin = GPIO_PIN[Led];
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
+  
+  HAL_GPIO_Init(GPIO_PORT[Led], &GPIO_InitStruct);
+  
+  HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_RESET); 
+}
+
+/**
+  * @brief  Turns selected LED On.
+  * @param  Led: Specifies the Led to be set on. 
+  *   This parameter can be one of following parameters:
+  *     @arg LED2
+  * @retval None
+  */
+void BSP_LED_On(Led_TypeDef Led)
+{
+  HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_SET); 
+}
+
+/**
+  * @brief  Turns selected LED Off.
+  * @param  Led: Specifies the Led to be set off. 
+  *   This parameter can be one of following parameters:
+  *     @arg LED2
+  * @retval None
+  */
+void BSP_LED_Off(Led_TypeDef Led)
+{
+  HAL_GPIO_WritePin(GPIO_PORT[Led], GPIO_PIN[Led], GPIO_PIN_RESET); 
+}
+
+/**
+  * @brief  Toggles the selected LED.
+  * @param  Led: Specifies the Led to be toggled. 
+  *   This parameter can be one of following parameters:
+  *     @arg LED2  
+  * @retval None
+  */
+void BSP_LED_Toggle(Led_TypeDef Led)
+{
+  HAL_GPIO_TogglePin(GPIO_PORT[Led], GPIO_PIN[Led]);
+}
+
+/**
+  * @brief  Configures Button GPIO and EXTI Line.
+  * @param  Button: Specifies the Button to be configured.
+  *   This parameter should be: BUTTON_KEY
+  * @param  ButtonMode: Specifies Button mode.
+  *   This parameter can be one of following parameters:   
+  *     @arg BUTTON_MODE_GPIO: Button will be used as simple IO 
+  *     @arg BUTTON_MODE_EXTI: Button will be connected to EXTI line with interrupt
+  *                            generation capability  
+  * @retval None
+  */
+void BSP_PB_Init(Button_TypeDef Button, ButtonMode_TypeDef ButtonMode)
+{
+  GPIO_InitTypeDef GPIO_InitStruct;
+  
+  /* Enable the BUTTON Clock */
+  BUTTONx_GPIO_CLK_ENABLE(Button);
+  
+  if(ButtonMode == BUTTON_MODE_GPIO)
+  {
+    /* Configure Button pin as input */
+    GPIO_InitStruct.Pin = BUTTON_PIN[Button];
+    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
+    HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
+  }
+  
+  if(ButtonMode == BUTTON_MODE_EXTI)
+  {
+    /* Configure Button pin as input with External interrupt */
+    GPIO_InitStruct.Pin = BUTTON_PIN[Button];
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; 
+    HAL_GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStruct);
+    
+    /* Enable and set Button EXTI Interrupt to the lowest priority */
+    HAL_NVIC_SetPriority((IRQn_Type)(BUTTON_IRQn[Button]), 0x0F, 0x00);
+    HAL_NVIC_EnableIRQ((IRQn_Type)(BUTTON_IRQn[Button]));
+  }
+}
+
+/**
+  * @brief  Returns the selected Button state.
+  * @param  Button: Specifies the Button to be checked.
+  *   This parameter should be: BUTTON_KEY  
+  * @retval The Button GPIO pin value.
+  */
+uint32_t BSP_PB_GetState(Button_TypeDef Button)
+{
+  return HAL_GPIO_ReadPin(BUTTON_PORT[Button], BUTTON_PIN[Button]);
+}
+
+/******************************************************************************
+                            BUS OPERATIONS
+*******************************************************************************/
+/**
+  * @brief  Initializes SPI MSP.
+  * @param  None
+  * @retval None
+  */
+static void SPIx_MspInit(SPI_HandleTypeDef *hspi)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;  
+  
+  /*** Configure the GPIOs ***/  
+  /* Enable GPIO clock */
+  NUCLEO_SPIx_SCK_GPIO_CLK_ENABLE();
+  NUCLEO_SPIx_MISO_MOSI_GPIO_CLK_ENABLE();
+  
+  /* Configure SPI SCK */
+  GPIO_InitStruct.Pin = NUCLEO_SPIx_SCK_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+  GPIO_InitStruct.Pull  = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+  GPIO_InitStruct.Alternate = NUCLEO_SPIx_SCK_AF;
+  HAL_GPIO_Init(NUCLEO_SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
+
+  /* Configure SPI MISO and MOSI */ 
+  GPIO_InitStruct.Pin = NUCLEO_SPIx_MOSI_PIN;
+  GPIO_InitStruct.Alternate = NUCLEO_SPIx_MISO_MOSI_AF;
+  GPIO_InitStruct.Pull  = GPIO_PULLDOWN;
+  HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &GPIO_InitStruct);
+  
+  GPIO_InitStruct.Pin = NUCLEO_SPIx_MISO_PIN;
+  HAL_GPIO_Init(NUCLEO_SPIx_MISO_MOSI_GPIO_PORT, &GPIO_InitStruct);
+
+  /*** Configure the SPI peripheral ***/ 
+  /* Enable SPI clock */
+  NUCLEO_SPIx_CLK_ENABLE();
+}
+
+/**
+  * @brief  Initializes SPI HAL.
+  * @param  None
+  * @retval None
+  */
+static void SPIx_Init(void)
+{
+  if(HAL_SPI_GetState(&hnucleo_Spi) == HAL_SPI_STATE_RESET)
+  {
+    /* SPI Config */
+    hnucleo_Spi.Instance = NUCLEO_SPIx;
+      /* SPI baudrate is set to 12,5 MHz maximum (PCLK2/SPI_BaudRatePrescaler = 100/8 = 12,5 MHz) 
+       to verify these constraints:
+          - ST7735 LCD SPI interface max baudrate is 15MHz for write and 6.66MHz for read
+            Since the provided driver doesn't use read capability from LCD, only constraint 
+            on write baudrate is considered.
+          - SD card SPI interface max baudrate is 25MHz for write/read
+          - PCLK2 max frequency is 100 MHz 
+       */ 
+    hnucleo_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
+    hnucleo_Spi.Init.Direction = SPI_DIRECTION_2LINES;
+    hnucleo_Spi.Init.CLKPhase = SPI_PHASE_2EDGE;
+    hnucleo_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH;
+    hnucleo_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
+    hnucleo_Spi.Init.CRCPolynomial = 7;
+    hnucleo_Spi.Init.DataSize = SPI_DATASIZE_8BIT;
+    hnucleo_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
+    hnucleo_Spi.Init.NSS = SPI_NSS_SOFT;
+    hnucleo_Spi.Init.TIMode = SPI_TIMODE_DISABLED;
+    hnucleo_Spi.Init.Mode = SPI_MODE_MASTER;
+
+    SPIx_MspInit(&hnucleo_Spi);
+    HAL_SPI_Init(&hnucleo_Spi);
+  }
+}
+
+/**
+  * @brief  SPI Read 4 bytes from device.
+  * @param  None
+  * @retval Read data
+*/
+static uint32_t SPIx_Read(void)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+  uint32_t readvalue = 0;
+  uint32_t writevalue = 0xFFFFFFFF;
+  
+  status = HAL_SPI_TransmitReceive(&hnucleo_Spi, (uint8_t*) &writevalue, (uint8_t*) &readvalue, 1, SpixTimeout);
+  
+  /* Check the communication status */
+  if(status != HAL_OK)
+  {
+    /* Execute user timeout callback */
+    SPIx_Error();
+  }
+
+  return readvalue;
+}
+
+/**
+  * @brief  SPI Write a byte to device.
+  * @param  Value: value to be written
+  * @retval None
+  */
+static void SPIx_Write(uint8_t Value)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  status = HAL_SPI_Transmit(&hnucleo_Spi, (uint8_t*) &Value, 1, SpixTimeout);
+    
+  /* Check the communication status */
+  if(status != HAL_OK)
+  {
+    /* Execute user timeout callback */
+    SPIx_Error();
+  }
+}
+
+/**
+  * @brief  SPI error treatment function.
+  * @param  None
+  * @retval None
+  */
+static void SPIx_Error (void)
+{
+  /* De-initialize the SPI communication BUS */
+  HAL_SPI_DeInit(&hnucleo_Spi);
+  
+  /* Re-Initiaize the SPI communication BUS */
+  SPIx_Init();
+}
+
+/******************************************************************************
+                            LINK OPERATIONS
+*******************************************************************************/
+
+/********************************* LINK SD ************************************/
+/**
+  * @brief  Initializes the SD Card and put it into StandBy State (Ready for 
+  *         data transfer).
+  * @param  None
+  * @retval None
+  */
+void SD_IO_Init(void)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+  uint8_t counter;
+
+  /* SD_CS_GPIO Periph clock enable */
+  SD_CS_GPIO_CLK_ENABLE();
+
+  /* Configure SD_CS_PIN pin: SD Card CS pin */
+  GPIO_InitStruct.Pin = SD_CS_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_PULLUP;
+  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+  HAL_GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStruct);
+
+  /*------------Put SD in SPI mode--------------*/
+  /* SD SPI Config */
+  SPIx_Init();
+  
+  /* SD chip select high */
+  SD_CS_HIGH();
+  
+  /* Send dummy byte 0xFF, 10 times with CS high */
+  /* Rise CS and MOSI for 80 clocks cycles */
+  for (counter = 0; counter <= 9; counter++)
+  {
+    /* Send dummy byte 0xFF */
+    SD_IO_WriteByte(SD_DUMMY_BYTE);
+  }
+}
+
+/**
+  * @brief  Writes a byte on the SD.
+  * @param  Data: byte to send.
+  * @retval None
+  */
+void SD_IO_WriteByte(uint8_t Data)
+{
+  /* Send the byte */
+  SPIx_Write(Data);
+}
+
+/**
+  * @brief  Reads a byte from the SD.
+  * @param  None
+  * @retval The received byte.
+  */
+uint8_t SD_IO_ReadByte(void)
+{
+  uint8_t data = 0;
+  
+  /* Get the received data */
+  data = SPIx_Read();
+
+  /* Return the shifted data */
+  return data;
+}
+
+/**
+  * @brief  Sends 5 bytes command to the SD card and get response.
+  * @param  Cmd: The user expected command to send to SD card.
+  * @param  Arg: The command argument
+  * @param  Crc: The CRC
+  * @param  Response: Expected response from the SD card
+  * @retval HAL_StatusTypeDef HAL Status
+  */
+HAL_StatusTypeDef SD_IO_WriteCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response)
+{
+  uint32_t counter = 0x00;
+  uint8_t frame[6];
+
+  /* Prepare Frame to send */
+  frame[0] = (Cmd | 0x40);         /* Construct byte 1 */
+  frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */
+  frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */
+  frame[3] = (uint8_t)(Arg >> 8);  /* Construct byte 4 */
+  frame[4] = (uint8_t)(Arg);       /* Construct byte 5 */
+  frame[5] = (Crc);                /* Construct byte 6 */
+  
+  /* SD chip select low */
+  SD_CS_LOW();
+    
+  /* Send Frame */
+  for (counter = 0; counter < 6; counter++)
+  {
+    SD_IO_WriteByte(frame[counter]); /* Send the Cmd bytes */
+  }
+
+  if(Response != SD_NO_RESPONSE_EXPECTED)
+  {
+    return SD_IO_WaitResponse(Response);
+  }
+  
+  return HAL_OK;
+}
+
+/**
+  * @brief  Waits response from the SD card
+  * @param  Response: Expected response from the SD card
+  * @retval HAL_StatusTypeDef HAL Status
+  */
+HAL_StatusTypeDef SD_IO_WaitResponse(uint8_t Response)
+{
+  uint32_t timeout = 0xFFFF;
+
+  /* Check if response is got or a timeout is happen */
+  while ((SD_IO_ReadByte() != Response) && timeout)
+  {
+    timeout--;
+  }
+
+  if (timeout == 0)
+  {
+    /* After time out */
+    return HAL_TIMEOUT;
+  }
+  else
+  {
+    /* Right response got */
+    return HAL_OK;
+  }
+}
+
+/**
+  * @brief  Sends dummy byte with CS High.
+  * @param  None
+  * @retval None
+  */
+void SD_IO_WriteDummy(void)
+{
+  /* SD chip select high */
+  SD_CS_HIGH();
+  
+  /* Send Dummy byte 0xFF */
+  SD_IO_WriteByte(SD_DUMMY_BYTE);
+}
+
+/********************************* LINK LCD ***********************************/
+/**
+  * @brief  Initializes the LCD.
+  * @param  None
+  * @retval None
+  */
+void LCD_IO_Init(void)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+   
+  /* LCD_CS_GPIO and LCD_DC_GPIO Periph clock enable */
+  LCD_CS_GPIO_CLK_ENABLE();
+  LCD_DC_GPIO_CLK_ENABLE();
+  
+  /* Configure LCD_CS_PIN pin: LCD Card CS pin */
+  GPIO_InitStruct.Pin = LCD_CS_PIN;
+  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+  HAL_GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStruct);
+
+  /* Configure LCD_DC_PIN pin: LCD Card DC pin */
+  GPIO_InitStruct.Pin = LCD_DC_PIN;
+  HAL_GPIO_Init(LCD_DC_GPIO_PORT, &GPIO_InitStruct);
+  
+  /* LCD chip select high */
+  LCD_CS_HIGH();
+  
+  /* LCD SPI Config */
+  SPIx_Init();
+}
+
+/**
+  * @brief  Writes command to select the LCD register.
+  * @param  LCDReg: Address of the selected register.
+  * @retval None
+  */
+void LCD_IO_WriteReg(uint8_t LCDReg)
+{
+  /* Reset LCD control line CS */
+  LCD_CS_LOW();
+  
+  /* Set LCD data/command line DC to Low */
+  LCD_DC_LOW();
+    
+  /* Send Command */
+  SPIx_Write(LCDReg);
+  
+  /* Deselect : Chip Select high */
+  LCD_CS_HIGH();
+}
+
+/**
+  * @brief  Writes data to select the LCD register.
+  *         This function must be used after st7735_WriteReg() function
+  * @param  Data: data to write to the selected register.
+  * @retval None
+  */
+void LCD_IO_WriteData(uint8_t Data)
+{
+  /* Reset LCD control line CS */
+  LCD_CS_LOW();
+  
+  /* Set LCD data/command line DC to High */
+  LCD_DC_HIGH();
+
+  /* Send Data */
+  SPIx_Write(Data);
+  
+  /* Deselect : Chip Select high */
+  LCD_CS_HIGH();
+}
+
+/**
+  * @brief  Wait for loop in ms.
+  * @param  Delay in ms.
+  * @retval None
+  */
+void LCD_Delay(uint32_t Delay)
+{
+  HAL_Delay(Delay);
+}
+
+/******************************* LINK JOYSTICK ********************************/
+/**
+  * @brief  Initializes ADC MSP.
+  * @param  None
+  * @retval None
+  */
+static void ADCx_MspInit(ADC_HandleTypeDef *hadc)
+{
+  GPIO_InitTypeDef  GPIO_InitStruct;
+  
+  /*** Configure the GPIOs ***/  
+  /* Enable GPIO clock */
+  NUCLEO_ADCx_GPIO_CLK_ENABLE();
+  
+  /* Configure the selected ADC Channel as analog input */
+  GPIO_InitStruct.Pin = NUCLEO_ADCx_GPIO_PIN ;
+  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
+  GPIO_InitStruct.Pull = GPIO_NOPULL;
+  HAL_GPIO_Init(NUCLEO_ADCx_GPIO_PORT, &GPIO_InitStruct);
+  
+  /*** Configure the ADC peripheral ***/ 
+  /* Enable ADC clock */
+  NUCLEO_ADCx_CLK_ENABLE(); 
+}
+
+/**
+  * @brief  Initializes ADC HAL.
+  * @param  None
+  * @retval None
+  */
+static void ADCx_Init(void)
+{
+  if(HAL_ADC_GetState(&hnucleo_Adc) == HAL_ADC_STATE_RESET)
+  {
+    /* ADC Config */
+    hnucleo_Adc.Instance                   = NUCLEO_ADCx;
+    hnucleo_Adc.Init.ClockPrescaler        = ADC_CLOCKPRESCALER_PCLK_DIV4; /* (must not exceed 36MHz) */
+    hnucleo_Adc.Init.Resolution            = ADC_RESOLUTION12b;
+    hnucleo_Adc.Init.DataAlign             = ADC_DATAALIGN_RIGHT;
+    hnucleo_Adc.Init.ContinuousConvMode    = DISABLE;
+    hnucleo_Adc.Init.DiscontinuousConvMode = DISABLE;
+    hnucleo_Adc.Init.ExternalTrigConvEdge  = ADC_EXTERNALTRIGCONVEDGE_NONE;
+    hnucleo_Adc.Init.EOCSelection          = EOC_SINGLE_CONV;
+    hnucleo_Adc.Init.NbrOfConversion       = 1;
+    hnucleo_Adc.Init.DMAContinuousRequests = DISABLE;    
+    
+    ADCx_MspInit(&hnucleo_Adc);
+    HAL_ADC_Init(&hnucleo_Adc);
+  }
+}
+
+/**
+  * @brief  Configures joystick available on adafruit 1.8" TFT shield 
+  *         managed through ADC to detect motion.
+  * @param  None
+  * @retval Joystickstatus (0=> success, 1=> fail) 
+  */
+uint8_t BSP_JOY_Init(void)
+{
+  uint8_t status = 1;
+   
+  ADCx_Init();
+   
+  /* Select the ADC Channel to be converted */
+  sConfig.Channel = NUCLEO_ADCx_CHANNEL;
+  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
+  sConfig.Rank = 1;
+  status = HAL_ADC_ConfigChannel(&hnucleo_Adc, &sConfig);
+  
+  /* Return Joystick initialization status */
+  return status;
+}
+
+/**
+  * @brief  Returns the Joystick key pressed.
+  * @note   To know which Joystick key is pressed we need to detect the voltage
+  *         level on each key output
+  *           - None  : 3.3 V / 4095
+  *           - SEL   : 1.055 V / 1308
+  *           - DOWN  : 0.71 V / 88
+  *           - LEFT  : 3.0 V / 3720 
+  *           - RIGHT : 0.595 V / 737
+  *           - UP    : 1.65 V / 2046
+  * @retval JOYState_TypeDef: Code of the Joystick key pressed.
+  */
+JOYState_TypeDef BSP_JOY_GetState(void)
+{
+  JOYState_TypeDef state;
+  uint16_t  keyconvertedvalue = 0;
+  
+  /* Start the conversion process */
+  HAL_ADC_Start(&hnucleo_Adc);
+  
+  /* Wait for the end of conversion */
+  HAL_ADC_PollForConversion(&hnucleo_Adc, 10);
+  
+  /* Check if the continous conversion of regular channel is finished */
+  if(HAL_ADC_GetState(&hnucleo_Adc) == HAL_ADC_STATE_EOC_REG)
+  {
+    /* Get the converted value of regular channel */
+    keyconvertedvalue = HAL_ADC_GetValue(&hnucleo_Adc);
+  }
+  
+  if((keyconvertedvalue > 2010) && (keyconvertedvalue < 2090))
+  {
+    state = JOY_UP;
+  }
+  else if((keyconvertedvalue > 680) && (keyconvertedvalue < 780))
+  {
+    state = JOY_RIGHT;
+  }
+  else if((keyconvertedvalue > 1270) && (keyconvertedvalue < 1350))
+  {
+    state = JOY_SEL;
+  }
+  else if((keyconvertedvalue > 50) && (keyconvertedvalue < 130))
+  {
+    state = JOY_DOWN;
+  }
+  else if((keyconvertedvalue > 3680) && (keyconvertedvalue < 3760))
+  {
+    state = JOY_LEFT;
+  }
+  else
+  {
+    state = JOY_NONE;
+  }
+  
+  /* Loop while a key is pressed */
+  if(state != JOY_NONE)
+  { 
+    keyconvertedvalue = HAL_ADC_GetValue(&hnucleo_Adc);  
+  }
+  /* Return the code of the Joystick key pressed */
+  return state;
+}
+
+/**
+  * @}
+  */ 
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */    
+
+/**
+  * @}
+  */ 
+    
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+