/**
******************************************************************************
* @file stm32f4xx_nucleo.c
* @author MCD Application Team
* @version V1.2.2
* @date 14-August-2015
* @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
* shield (reference ID 802)
******************************************************************************
* @attention
*
*
© COPYRIGHT(c) 2015 STMicroelectronics
*
* 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.2.2
*/
#define __STM32F4xx_NUCLEO_BSP_VERSION_MAIN (0x01) /*!< [31:24] main version */
#define __STM32F4xx_NUCLEO_BSP_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */
#define __STM32F4xx_NUCLEO_BSP_VERSION_SUB2 (0x02) /*!< [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
*/
#if 0
uint32_t SpixTimeout = NUCLEO_SPIx_TIMEOUT_MAX; /*> 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 Writes register value.
* @param pData: Pointer on the register value
* @param Size: Size of byte to transmit to the register
* @retval None
*/
void LCD_IO_WriteMultipleData(uint8_t *pData, uint32_t Size)
{
uint32_t counter = 0;
/* Reset LCD control line CS */
LCD_CS_LOW();
/* Set LCD data/command line DC to High */
LCD_DC_HIGH();
if (Size == 1)
{
/* Only 1 byte to be sent to LCD - general interface can be used */
/* Send Data */
SPIx_Write(*pData);
}
else
{
/* Several data should be sent in a raw */
/* Direct SPI accesses for optimization */
for (counter = Size; counter != 0; counter--)
{
while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
{
}
/* Need to invert bytes for LCD*/
*((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *(pData+1);
while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
{
}
*((__IO uint8_t*)&hnucleo_Spi.Instance->DR) = *pData;
counter--;
pData += 2;
}
/* Wait until the bus is ready before releasing Chip select */
while(((hnucleo_Spi.Instance->SR) & SPI_FLAG_BSY) != RESET)
{
}
}
/* 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 continuous 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****/
#endif