/** ****************************************************************************** * @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