/**
******************************************************************************
* @file stm32g0c1e_eval.c
* @author MCD Application Team
* @brief This file provides: a set of firmware functions to manage Leds,
* push-button and COM ports
******************************************************************************
* @attention
*
*
© COPYRIGHT(c) 2020 STMicroelectronics
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32g0c1e_eval.h"
/** @addtogroup BSP
* @{
*/
/** @addtogroup STM32G0C1E_EVAL
* @brief This file provides firmware functions to manage Leds, push-buttons,
* COM ports, SD card on SPI and temperature sensor (LM75) available on
* STM32G0C1E-EV evaluation board from STMicroelectronics.
* @{
*/
/** @addtogroup STM32G0C1E_EVAL_Common
* @{
*/
/** @addtogroup STM32G0C1E_EVAL_Private_Constants
* @{
*/
/* LINK LCD */
#define START_BYTE 0x70
#define SET_INDEX 0x00
#define READ_STATUS 0x01
#define LCD_WRITE_REG 0x02
#define LCD_READ_REG 0x03
/* LINK SD Card */
#define SD_DUMMY_BYTE 0xFF
#define SD_NO_RESPONSE_EXPECTED 0x80
/* Vref voltage level (in mV) */
#define VREFANALOG_VOLTAGE 3300
/* Legacy daughter board detection voltage level (in mV) */
#define DB_LEGACY_DETECT_VOLTAGE 1100
/* UCPD daughter board revB detection voltage level (in mV) */
#define DB_UCPD_A_B_DETECT_VOLTAGE 1650
/* UCPD daughter board rev C detection voltage level (in mV) */
#define DB_UCPD_C_DETECT_VOLTAGE 1320
/**
* @brief STM32G0C1E EVAL BSP Driver version number
*/
#define __STM32G0C1E_EVAL_BSP_VERSION_MAIN (0x01U) /*!< [31:24] main version */
#define __STM32G0C1E_EVAL_BSP_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
#define __STM32G0C1E_EVAL_BSP_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
#define __STM32G0C1E_EVAL_BSP_VERSION_RC (0x00U) /*!< [7:0] release candidate */
#define __STM32G0C1E_EVAL_BSP_VERSION ((__STM32G0C1E_EVAL_BSP_VERSION_MAIN << 24) |\
(__STM32G0C1E_EVAL_BSP_VERSION_SUB1 << 16) |\
(__STM32G0C1E_EVAL_BSP_VERSION_SUB2 << 8 ) |\
(__STM32G0C1E_EVAL_BSP_VERSION_RC))
#if defined(_GUI_INTERFACE)
const uint8_t HWBoardVersionName[] = "STM32G0C1E-EV";
const uint8_t PDTypeName[] = "MB1581B";
#endif /* _GUI_INTERFACE */
/**
* @}
*/
/** @addtogroup STM32G0C1E_EVAL_Private_Variables
* @{
*/
/**
* @brief LED variables
*/
GPIO_TypeDef* LED_PORT[LEDn] = {
LED1_GPIO_PORT,
LED2_GPIO_PORT,
LED3_GPIO_PORT,
LED4_GPIO_PORT
};
const uint16_t LED_PIN[LEDn] = {
LED1_PIN,
LED2_PIN,
LED3_PIN,
LED4_PIN
};
/**
* @brief BUTTON variables
*/
GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {TAMPER_BUTTON_GPIO_PORT};
const uint16_t BUTTON_PIN[BUTTONn] = {TAMPER_BUTTON_PIN};
const uint8_t BUTTON_IRQn[BUTTONn] = {TAMPER_BUTTON_EXTI_IRQn};
/**
* @brief JOYSTICK variables
*/
GPIO_TypeDef* JOY_PORT[JOYn] = {
SEL_JOY_GPIO_PORT,
DOWN_JOY_GPIO_PORT,
LEFT_JOY_GPIO_PORT,
RIGHT_JOY_GPIO_PORT,
UP_JOY_GPIO_PORT
};
const uint16_t JOY_PIN[JOYn] = {
SEL_JOY_PIN,
DOWN_JOY_PIN,
LEFT_JOY_PIN,
RIGHT_JOY_PIN,
UP_JOY_PIN
};
const uint8_t JOY_IRQn[JOYn] = {
SEL_JOY_EXTI_IRQn,
DOWN_JOY_EXTI_IRQn,
LEFT_JOY_EXTI_IRQn,
RIGHT_JOY_EXTI_IRQn,
UP_JOY_EXTI_IRQn
};
/**
* @brief COM variables
*/
#ifdef HAL_UART_MODULE_ENABLED
USART_TypeDef* COM_USART[COMn] = {EVAL_COM1};
GPIO_TypeDef* COM_TX_PORT[COMn] = {EVAL_COM1_TX_GPIO_PORT};
GPIO_TypeDef* COM_RX_PORT[COMn] = {EVAL_COM1_RX_GPIO_PORT};
const uint16_t COM_TX_PIN[COMn] = {EVAL_COM1_TX_PIN};
const uint16_t COM_RX_PIN[COMn] = {EVAL_COM1_RX_PIN};
const uint16_t COM_TX_AF[COMn] = {EVAL_COM1_TX_AF};
const uint16_t COM_RX_AF[COMn] = {EVAL_COM1_RX_AF};
#endif /*HAL_UART_MODULE_ENABLED*/
/**
* @brief BUS variables
*/
#if defined(HAL_I2C_MODULE_ENABLED)
uint32_t I2c1Timeout = EVAL_I2C1_TIMEOUT_MAX; /*Instance = COM_USART[COM];
HAL_UART_Init(huart);
}
#endif /* HAL_UART_MODULE_ENABLED */
#if defined(HAL_ADC_MODULE_ENABLED)
/**
* @brief Identifies of the daughter baord connected to the daughter board connectors.
* @note The voltage level measured at PB11 (ADC_IN15 ) determines the type of
* daughter board connected to the daughter board connectors.
* 0 V on ADC_IN15: There is no daughter board.
* 1.1 V on ADC_IN15: Legacy daughter board
* 1.65 V on ADC_IN15: USB daughter board
* @note A 1% margin is applied to voltage level detection
* @param pDaughterBoardId : pointer to the daughter board identifier
* This parameter can be one of the following values:
* DB_ID_NONE
* DB_ID_LEGACY
* DB_ID_UCPD
* @retval Result 0 : execution successful
* else : execution failed
*/
uint8_t BSP_DB_GetId(DBId_TypeDef *pDaughterBoardId)
{
uint8_t error = 0;
GPIO_InitTypeDef gpio_config = {0};
ADC_HandleTypeDef hadc = {0};
ADC_ChannelConfTypeDef adc_channel_config = {0};
uint32_t voltage;
/* Initialize output argument */
*pDaughterBoardId = DB_ID_NONE;
/* Enable GPIO clock */
DB_DETECT_GPIO_CLK_ENABLE();
/* Configure GPIO pin of the selected ADC channel */
gpio_config.Pin = DB_DETECT_PIN;
gpio_config.Mode = GPIO_MODE_ANALOG;
gpio_config.Pull = GPIO_NOPULL;
HAL_GPIO_Init(DB_DETECT_GPIO_PORT, &gpio_config);
/* Enable ADC clock */
DB_ADC_CLK_ENABLE();
/* Initialize ADC */
hadc.Instance = DB_ADC;
if (HAL_ADC_DeInit(&hadc) != HAL_OK)
{
/* ADC de-initialization Error */
error++;
}
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_39CYCLES_5;
hadc.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
error++;
}
/* Run the ADC calibration */
if (HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK)
{
error++;
}
/* Configure the ADC channel used to identify the daughter board */
adc_channel_config.Channel = DB_ADC_CHANNEL;
adc_channel_config.Rank = ADC_RANK_CHANNEL_NUMBER;
adc_channel_config.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc, &adc_channel_config) != HAL_OK)
{
error++;
}
/* Start conversion */
if (HAL_ADC_Start(&hadc) != HAL_OK)
{
error++;
}
/* Wait for conversion completion */
if (HAL_ADC_PollForConversion(&hadc, 10) != HAL_OK)
{
error++;
}
/* Translate ADC conversion into voltage level */
voltage = __HAL_ADC_CALC_DATA_TO_VOLTAGE(VREFANALOG_VOLTAGE,
HAL_ADC_GetValue(&hadc),
hadc.Init.Resolution);
/* Set output argument according to measured voltage level */
if (voltage < (DB_LEGACY_DETECT_VOLTAGE - DB_LEGACY_DETECT_VOLTAGE/100))
{
*pDaughterBoardId = DB_ID_NONE;
}
else if (voltage < (DB_UCPD_C_DETECT_VOLTAGE - DB_UCPD_C_DETECT_VOLTAGE/100))
{
*pDaughterBoardId = DB_ID_LEGACY;
}
else if (voltage < (DB_UCPD_A_B_DETECT_VOLTAGE - DB_UCPD_A_B_DETECT_VOLTAGE/100))
{
*pDaughterBoardId = DB_ID_UCPD_C;
}
else
{
*pDaughterBoardId = DB_ID_UCPD_AB;
}
/* Reset GPIO configuration */
HAL_GPIO_DeInit(DB_DETECT_GPIO_PORT, gpio_config.Pin);
/* De-initialize ADC& */
HAL_ADC_DeInit(&hadc);
/* Disable ADC clock */
DB_ADC_CLK_DISABLE();
return error;
}
#endif /* HAL_ADC_MODULE_ENABLED */
/**
* @}
*/
/** @addtogroup STM32G0C1E_EVAL_BUS_Operations_Functions
* @{
*/
/*******************************************************************************
BUS OPERATIONS
*******************************************************************************/
#if defined(HAL_I2C_MODULE_ENABLED)
/******************************* I2C Routines *********************************/
/**
* @brief I2C1 Bus initialization
* @retval None
*/
static HAL_StatusTypeDef I2C1_Init(void)
{
HAL_StatusTypeDef result = HAL_OK;
if(HAL_I2C_GetState(&heval_I2c1) == HAL_I2C_STATE_RESET)
{
heval_I2c1.Instance = EVAL_I2C1;
heval_I2c1.Init.Timing = I2C1_TIMING;
heval_I2c1.Init.OwnAddress1 = 0;
heval_I2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
heval_I2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
heval_I2c1.Init.OwnAddress2 = 0;
heval_I2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
heval_I2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
heval_I2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
/* Init the I2C */
I2C1_MspInit(&heval_I2c1);
result = HAL_I2C_Init(&heval_I2c1);
}
/* Increment I2C1 reference counter */
I2c1RefCounter++;
return result;
}
/**
* @brief I2C1 Bus De-initialization
* @retval None
*/
static void I2C1_DeInit(void)
{
I2c1RefCounter--;
/* De-initialize I2C1 (if not used for any other device */
if (I2c1RefCounter == 0)
{
HAL_I2C_DeInit(&heval_I2c1);
}
}
/**
* @brief Reads multiple data on the BUS.
* @param Addr : I2C Address
* @param Reg : Reg Address
* @param RegSize : The target register size (can be 8BIT or 16BIT)
* @param pBuffer : pointer to read data buffer
* @param Length : length of the data
* @retval 0 if no problems to read multiple data
*/
static HAL_StatusTypeDef I2C1_ReadBuffer(uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Read(&heval_I2c1, Addr, Reg, RegSize, pBuffer, Length, I2c1Timeout);
/* Check the communication status */
if(status != HAL_OK)
{
/* Re-Initiaize the BUS */
I2C1_Error();
}
return status;
}
/**
* @brief Checks if target device is ready for communication.
* @note This function is used with Memory devices
* @param DevAddress: Target device address
* @param Trials: Number of trials
* @retval HAL status
*/
static HAL_StatusTypeDef I2C1_IsDeviceReady(uint16_t DevAddress, uint32_t Trials)
{
return (HAL_I2C_IsDeviceReady(&heval_I2c1, DevAddress, Trials, I2c1Timeout));
}
/**
* @brief Write a value in a register of the device through BUS.
* @param Addr: Device address on BUS Bus.
* @param Reg: The target register address to write
* @param RegSize: The target register size (can be 8BIT or 16BIT)
* @param pBuffer: The target register value to be written
* @param Length: buffer size to be written
* @retval None
*/
static HAL_StatusTypeDef I2C1_WriteBuffer(uint16_t Addr, uint8_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&heval_I2c1, Addr, Reg, RegSize, pBuffer, Length, I2c1Timeout);
/* Check the communication status */
if(status != HAL_OK)
{
/* Re-Initiaize the BUS */
I2C1_Error();
}
return status;
}
/**
* @brief Write buffer through I2C.
* @param pBuffer: The address of the data to be written
* @param Length: buffer size to be written
* @retval None
*/
static HAL_StatusTypeDef I2C1_TransmitData(uint8_t *pBuffer, uint16_t Length)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Slave_Transmit(&heval_I2c1, pBuffer, Length, I2c1Timeout);
/* Check the communication status */
if(status != HAL_OK)
{
/* Execute user timeout callback */
I2C1_Error();
return HAL_ERROR;
}
return HAL_OK;
}
/**
* @brief Manages error callback by re-initializing I2C.
* @retval None
*/
static void I2C1_Error(void)
{
/* De-initialize the I2C communication BUS */
HAL_I2C_DeInit(&heval_I2c1);
/* Re-Initiaize the I2C communication BUS */
I2C1_Init();
}
/**
* @brief I2C MSP Initialization
* @param hi2c: I2C handle
* @retval None
*/
static void I2C1_MspInit(I2C_HandleTypeDef *hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
/*##-1- Set source clock to SYSCLK for I2C1 ################################################*/
RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C1;
RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_SYSCLK;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
/*##-2- Configure the GPIOs ################################################*/
/* Enable GPIO clock */
EVAL_I2C1_GPIO_CLK_ENABLE();
/* Configure I2C SCL & SDA as alternate function */
GPIO_InitStruct.Pin = (EVAL_I2C1_SCL_PIN| EVAL_I2C1_SDA_PIN);
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = EVAL_I2C1_SCL_SDA_AF;
HAL_GPIO_Init(EVAL_I2C1_GPIO_PORT, &GPIO_InitStruct);
/*##-3- Configure the Eval I2C peripheral #######################################*/
/* Enable I2C clock */
EVAL_I2C1_CLK_ENABLE();
/* Force the I2C peripheral clock reset */
EVAL_I2C1_FORCE_RESET();
/* Release the I2C peripheral clock reset */
EVAL_I2C1_RELEASE_RESET();
}
/**
* @brief I2C Bus initialization
* @retval None
*/
static void I2C2_Init(void)
{
if(HAL_I2C_GetState(&heval_I2c2) == HAL_I2C_STATE_RESET)
{
heval_I2c2.Instance = EVAL_I2C2;
heval_I2c2.Init.Timing = I2C2_TIMING;
heval_I2c2.Init.OwnAddress1 = 0;
heval_I2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
heval_I2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
heval_I2c2.Init.OwnAddress2 = 0;
heval_I2c2.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
heval_I2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
heval_I2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
/* Init the I2C */
I2C2_MspInit(&heval_I2c2);
HAL_I2C_Init(&heval_I2c2);
}
}
/**
* @brief Read a register of the device through I2C.
* @param Addr: Device address on I2C Bus.
* @param pBuffer: The address to store the read data
* @param Length: buffer size to be read
* @retval None
*/
static HAL_StatusTypeDef I2C2_ReceiveData(uint16_t Addr, uint8_t * pBuffer, uint16_t Length)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Master_Receive(&heval_I2c2, Addr, pBuffer, Length, I2c2Timeout);
/* Check the communication status */
if(status != HAL_OK)
{
/* Execute user timeout callback */
I2C2_Error();
}
return status;
}
/**
* @brief Discovery I2C2 error treatment function
* @retval None
*/
static void I2C2_Error(void)
{
/* De-initialize the I2C communication BUS */
HAL_I2C_DeInit(&heval_I2c2);
/* Re-Initiaize the I2C communication BUS */
I2C2_Init();
}
/**
* @brief I2C MSP Initialization
* @param hi2c: I2C handle
* @retval None
*/
static void I2C2_MspInit(I2C_HandleTypeDef *hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable GPIO clock */
EVAL_I2C2_GPIO_CLK_ENABLE();
/* Configure I2C SCL and SDA as alternate function */
GPIO_InitStruct.Pin = (EVAL_I2C2_SCL_PIN | EVAL_I2C2_SDA_PIN);
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = EVAL_I2C2_AF;
HAL_GPIO_Init(EVAL_I2C2_GPIO_PORT, &GPIO_InitStruct);
/* Enable I2C clock */
EVAL_I2C2_CLK_ENABLE();
/* Force the I2C peripheral clock reset */
EVAL_I2C2_FORCE_RESET();
/* Release the I2C peripheral clock reset */
EVAL_I2C2_RELEASE_RESET();
}
#endif /*HAL_I2C_MODULE_ENABLED*/
#if defined(HAL_SPI_MODULE_ENABLED)
/******************************* SPI Routines *********************************/
/**
* @brief SPIx Bus initialization
* @retval None
*/
static void SPIx_Init(void)
{
if(HAL_SPI_GetState(&heval_Spi) == HAL_SPI_STATE_RESET)
{
/* SPI Config */
heval_Spi.Instance = EVAL_SPIx;
/* SPI baudrate is set to 12 MHz (PCLK1/SPI_BaudRatePrescaler = 48/4 = 12 MHz)
to verify these constraints:
HX8347D LCD SPI interface max baudrate is 50MHz for write and 6.66MHz for read
PCLK1 frequency is set to 48 MHz
- SD card SPI interface max baudrate is 25MHz for write/read
*/
heval_Spi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
heval_Spi.Init.Direction = SPI_DIRECTION_2LINES;
heval_Spi.Init.CLKPhase = SPI_PHASE_2EDGE;
heval_Spi.Init.CLKPolarity = SPI_POLARITY_HIGH;
heval_Spi.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
heval_Spi.Init.CRCPolynomial = 7;
heval_Spi.Init.DataSize = SPI_DATASIZE_8BIT;
heval_Spi.Init.FirstBit = SPI_FIRSTBIT_MSB;
heval_Spi.Init.NSS = SPI_NSS_SOFT;
heval_Spi.Init.TIMode = SPI_TIMODE_DISABLE;
heval_Spi.Init.Mode = SPI_MODE_MASTER;
SPIx_MspInit(&heval_Spi);
HAL_SPI_Init(&heval_Spi);
}
}
/**
* @brief SPI Read 4 bytes from device
* @retval Read data
*/
static uint32_t SPIx_Read(void)
{
HAL_StatusTypeDef status;
uint32_t readvalue = 0x0;
uint32_t writevalue = 0xFFFFFFFF;
status = HAL_SPI_TransmitReceive(&heval_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 DataIn: value to be written
* @param DataOut: read value
* @param DataLegnth: data length
* @retval None
*/
static void SPIx_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLegnth)
{
HAL_StatusTypeDef status;
status = HAL_SPI_TransmitReceive(&heval_Spi, (uint8_t*) DataIn, DataOut, DataLegnth, SpixTimeout);
/* Check the communication status */
if(status != HAL_OK)
{
/* Execute user timeout callback */
SPIx_Error();
}
}
/**
* @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;
status = HAL_SPI_Transmit(&heval_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
* @retval None
*/
static void SPIx_Error (void)
{
/* De-initialize the SPI communication BUS */
HAL_SPI_DeInit(&heval_Spi);
/* Re- Initiaize the SPI communication BUS */
SPIx_Init();
}
/**
* @brief SPI MSP Init
* @param hspi: SPI handle
* @retval None
*/
static void SPIx_MspInit(SPI_HandleTypeDef *hspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable SPI clock */
EVAL_SPIx_CLK_ENABLE();
/* enable EVAL_SPI gpio clocks */
EVAL_SPIx_SCK_GPIO_CLK_ENABLE();
EVAL_SPIx_MISO_GPIO_CLK_ENABLE();
EVAL_SPIx_MOSI_GPIO_CLK_ENABLE();
EVAL_SPIx_MOSI_DIR_GPIO_CLK_ENABLE();
/* configure SPI SCK */
GPIO_InitStruct.Pin = EVAL_SPIx_SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = EVAL_SPIx_SCK_AF;
HAL_GPIO_Init(EVAL_SPIx_SCK_GPIO_PORT, &GPIO_InitStruct);
/* configure SPI MOSI */
GPIO_InitStruct.Pin = EVAL_SPIx_MOSI_PIN;
GPIO_InitStruct.Alternate = EVAL_SPIx_MOSI_AF;
HAL_GPIO_Init(EVAL_SPIx_MOSI_GPIO_PORT, &GPIO_InitStruct);
/* configure SPI MISO */
GPIO_InitStruct.Pin = EVAL_SPIx_MISO_PIN;
GPIO_InitStruct.Alternate = EVAL_SPIx_MISO_AF;
HAL_GPIO_Init(EVAL_SPIx_MISO_GPIO_PORT, &GPIO_InitStruct);
/* configure direction pin for MOSI */
GPIO_InitStruct.Pin = EVAL_SPIx_MOSI_DIR_PIN;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(EVAL_SPIx_MOSI_DIR_GPIO_PORT, &GPIO_InitStruct);
/* MOSI DIRECTION as output */
HAL_GPIO_WritePin(EVAL_SPIx_MOSI_DIR_GPIO_PORT, EVAL_SPIx_MOSI_DIR_PIN, GPIO_PIN_SET);
/* Force the SPI peripheral clock reset */
EVAL_SPIx_FORCE_RESET();
/* Release the SPI peripheral clock reset */
EVAL_SPIx_RELEASE_RESET();
}
#endif /*HAL_SPI_MODULE_ENABLED*/
/**
* @}
*/
/** @addtogroup STM32G0C1E_EVAL_LINK_Operations_Functions
* @{
*/
/******************************************************************************
LINK OPERATIONS
*******************************************************************************/
#if defined(HAL_SPI_MODULE_ENABLED)
/********************************* LINK LCD ***********************************/
/**
* @brief Configures the LCD_SPI interface.
* @retval None
*/
void LCD_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Configure the LCD Control pins */
LCD_NCS_GPIO_CLK_ENABLE();
SD_CS_GPIO_CLK_ENABLE();
/* Set chip selects to high before IO init in order to be sure no transition to 0 occurs */
SD_CS_HIGH();
LCD_CS_HIGH();
/* Configure SD_CS_PIN pin: SD Card CS pin */
GPIO_InitStruct.Pin = SD_CS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStruct);
/* Configure NCS in Output Push-Pull mode */
GPIO_InitStruct.Pin = LCD_NCS_PIN;
HAL_GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStruct);
SPIx_Init();
}
/**
* @brief Write 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) and Send data */
LCD_CS_LOW();
/* Send Start Byte */
SPIx_Write(START_BYTE | LCD_WRITE_REG);
if (Size == 1)
{
/* Only 1 byte to be sent to LCD - general interface can be used */
/* Send Data */
SPIx_Write(*pData);
}
else
{
for (counter = Size; counter != 0; counter--)
{
while(((heval_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
{
}
/* Need to invert bytes for LCD*/
*((__IO uint8_t*)&heval_Spi.Instance->DR) = *(pData+1);
while(((heval_Spi.Instance->SR) & SPI_FLAG_TXE) != SPI_FLAG_TXE)
{
}
*((__IO uint8_t*)&heval_Spi.Instance->DR) = *pData;
counter--;
pData += 2;
}
/* Wait until the bus is ready before releasing Chip select */
while(((heval_Spi.Instance->SR) & SPI_FLAG_BSY) != RESET)
{
}
}
/* Reset LCD control line(/CS) and Send data */
LCD_CS_HIGH();
SPIx_Write(0xFF);
}
/**
* @brief Writes address on LCD register.
* @param Reg: Register to be written
* @retval None
*/
void LCD_IO_WriteReg(uint8_t Reg)
{
/* Reset LCD control line(/CS) and Send command */
LCD_CS_LOW();
/* Send Start Byte */
SPIx_Write(START_BYTE | SET_INDEX);
/* Write 16-bit Reg Index (High Byte is 0) */
SPIx_Write(0x00);
SPIx_Write(Reg);
/* Deselect : Chip Select high */
LCD_CS_HIGH();
}
/**
* @brief Read data from LCD data register.
* @param Reg: Register to be read
* @retval readvalue
*/
uint16_t LCD_IO_ReadData(uint16_t Reg)
{
uint32_t readvalue = 0;
/* Send Reg value to Read */
LCD_IO_WriteReg(Reg);
/* Reset LCD control line(/CS) and Send command */
LCD_CS_LOW();
/* Send Start Byte */
SPIx_Write(START_BYTE | LCD_READ_REG);
/* Read Upper Byte */
SPIx_Write(0xFF);
readvalue = SPIx_Read();
readvalue = readvalue << 8;
readvalue |= SPIx_Read();
HAL_Delay(10);
/* Deselect : Chip Select high */
LCD_CS_HIGH();
return readvalue;
}
/**
* @brief Wait for loop in ms.
* @param Delay in ms.
*/
void LCD_Delay (uint32_t Delay)
{
HAL_Delay(Delay);
}
/******************************** LINK SD Card ********************************/
/**
* @brief Initializes the SD Card and put it into StandBy State (Ready for
* data transfer).
* @retval None
*/
void SD_IO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
uint8_t counter;
/* LCD_NCS_PIN, SD_CS_GPIO and SD_DETECT_GPIO Periph clock enable */
SD_CS_GPIO_CLK_ENABLE();
SD_DETECT_GPIO_CLK_ENABLE();
LCD_NCS_GPIO_CLK_ENABLE();
/* Set chip selects to high before IO init in order to be sure no transition to 0 occurs */
SD_CS_HIGH();
LCD_CS_HIGH();
/* Configure LCD_NCS_PIN pin: LCD CS pin */
GPIO_InitStruct.Pin = LCD_NCS_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStruct);
/* Configure SD_CS_PIN pin: SD Card CS pin */
GPIO_InitStruct.Pin = SD_CS_PIN;
HAL_GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStruct);
/* Configure SD_DETECT_PIN pin: SD Card detect pin */
GPIO_InitStruct.Pin = SD_DETECT_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStruct);
/* Enable and set SD EXTI Interrupt to the lowest priority */
HAL_NVIC_SetPriority(SD_DETECT_EXTI_IRQn, 0x03, 0);
HAL_NVIC_EnableIRQ(SD_DETECT_EXTI_IRQn);
/* SD SPI Config */
SPIx_Init();
/* 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);
}
}
void SD_IO_CSState(uint8_t val)
{
if(val == 1)
{
SD_CS_HIGH();
}
else
{
SD_CS_LOW();
}
}
/**
* @brief Write a byte on the SD.
* @param DataIn: byte to send.
* @param DataOut: read byte.
* @param DataLength: data length.
* @retval None
*/
void SD_IO_WriteReadData(const uint8_t *DataIn, uint8_t *DataOut, uint16_t DataLength)
{
/* Send the byte */
SPIx_WriteReadData(DataIn, DataOut, DataLength);
}
/**
* @brief Writes a byte on the SD.
* @param Data: byte to send.
* @retval None
*/
uint8_t SD_IO_WriteByte(uint8_t Data)
{
uint8_t tmp;
/* Send the byte */
SPIx_WriteReadData(&Data,&tmp,1);
return tmp;
}
#endif /* HAL_SPI_MODULE_ENABLED */
#if defined(HAL_I2C_MODULE_ENABLED)
/********************************* LINK I2C TEMPERATURE SENSOR *****************************/
/**
* @brief Initializes peripherals used by the I2C Temperature Sensor driver.
* @retval None
*/
void TSENSOR_IO_Init(void)
{
I2C1_Init();
}
/**
* @brief Writes one byte to the TSENSOR.
* @param DevAddress: Target device address
* @param pBuffer: Pointer to data buffer
* @param WriteAddr: TSENSOR's internal address to write to.
* @param Length: Number of data to write
* @retval None
*/
void TSENSOR_IO_Write(uint16_t DevAddress, uint8_t* pBuffer, uint8_t WriteAddr, uint16_t Length)
{
I2C1_WriteBuffer(DevAddress, WriteAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, Length);
}
/**
* @brief Reads one byte from the TSENSOR.
* @param DevAddress: Target device address
* @param pBuffer : pointer to the buffer that receives the data read from the TSENSOR.
* @param ReadAddr : TSENSOR's internal address to read from.
* @param Length: Number of data to read
* @retval None
*/
void TSENSOR_IO_Read(uint16_t DevAddress, uint8_t* pBuffer, uint8_t ReadAddr, uint16_t Length)
{
I2C1_ReadBuffer(DevAddress, ReadAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, Length);
}
/**
* @brief Checks if Temperature Sensor is ready for communication.
* @param DevAddress: Target device address
* @param Trials: Number of trials
* @retval HAL status
*/
uint16_t TSENSOR_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials)
{
return (I2C1_IsDeviceReady(DevAddress, Trials));
}
/****************************** LINK HDMI CEC *********************************/
/**
* @brief Initializes CEC low level.
* @retval None
*/
void HDMI_CEC_IO_Init (void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* Enable CEC clock */
__HAL_RCC_CEC_CLK_ENABLE();
/* Enable CEC LINE GPIO clock */
HDMI_CEC_LINE_CLK_ENABLE();
/* Configure CEC LINE GPIO as alternate function open drain */
GPIO_InitStruct.Pin = HDMI_CEC_LINE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = HDMI_CEC_LINE_AF;
HAL_GPIO_Init(HDMI_CEC_LINE_GPIO_PORT, &GPIO_InitStruct);
/* CEC IRQ Channel configuration */
HAL_NVIC_SetPriority((IRQn_Type)HDMI_CEC_IRQn, 0x3, 0x0);
HAL_NVIC_EnableIRQ((IRQn_Type)HDMI_CEC_IRQn);
/* Enable CEC HPD SINK GPIO clock */
HDMI_CEC_HPD_SINK_CLK_ENABLE();
/* Configure CEC HPD SINK GPIO as output push pull */
GPIO_InitStruct.Pin = HDMI_CEC_HPD_SINK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(HDMI_CEC_HPD_SINK_GPIO_PORT, &GPIO_InitStruct);
I2C1_Init();
/* Enable CEC HPD SOURCE GPIO clock */
HDMI_CEC_HPD_SOURCE_CLK_ENABLE();
/* Configure CEC HPD SOURCE GPIO as output push pull */
GPIO_InitStruct.Pin = HDMI_CEC_HPD_SOURCE_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(HDMI_CEC_HPD_SOURCE_GPIO_PORT, &GPIO_InitStruct);
I2C2_Init();
}
/**
* @brief Write data to I2C HDMI CEC driver
* @param pBuffer: Pointer to data buffer
* @param BufferSize: Amount of data to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HDMI_CEC_IO_WriteData(uint8_t * pBuffer, uint16_t BufferSize)
{
return (I2C1_TransmitData(pBuffer, BufferSize));
}
/**
* @brief Read data to I2C HDMI CEC driver
* @param DevAddress: Target device address
* @param pBuffer: Pointer to data buffer
* @param BufferSize: Amount of data to be sent
* @retval HAL status
*/
HAL_StatusTypeDef HDMI_CEC_IO_ReadData(uint16_t DevAddress, uint8_t * pBuffer, uint16_t BufferSize)
{
return (I2C2_ReceiveData(DevAddress, pBuffer, BufferSize));
}
/**************************** LINK USB Type-C MUX *****************************/
/**
* @brief Initializes peripherals used by the USB Type-C MUX driver.
* @retval 0: success, else failed
*/
uint8_t MUX_IO_Init(void)
{
uint8_t ret;
ret = (I2C1_Init() == HAL_OK) ? 0 : 1;
return ret;
}
/**
* @brief Release peripherals used by the USB Type-C MUX driver.
* @retval None
*/
void MUX_IO_DeInit(void)
{
I2C1_DeInit();
}
/**
* @brief Writes a single data.
* @param Addr: I2C address
* @param Reg: Reg address
* @param Data: pointer to the data to be written
* @retval 0: success, else failed
*/
uint8_t MUX_IO_Write(uint16_t Addr, uint16_t Reg, uint8_t Data)
{
uint8_t ret;
ret = (I2C1_WriteBuffer(Addr, Reg, I2C_MEMADD_SIZE_8BIT, &Data, 1) == HAL_OK) ? 0 : 1;
return ret;
}
/**
* @brief Reads a single data.
* @param Addr: I2C address
* @param Reg: Reg address
* @param pData: pointer to the data
* @retval 0: success, else failed
*/
uint8_t MUX_IO_Read(uint16_t Addr, uint16_t Reg, uint8_t *pData)
{
uint8_t ret;
ret = (I2C1_ReadBuffer(Addr, Reg, I2C_MEMADD_SIZE_8BIT, pData, 1) == HAL_OK) ? 0 : 1;
return ret;
}
/**
* @brief Checks if USB Type-C MUX is ready for communication.
* @param DevAddress: Target device address
* @param Trials: Number of trials
* @retval HAL status
*/
uint32_t MUX_IO_IsDeviceReady(uint16_t DevAddress, uint32_t Trials)
{
return (I2C1_IsDeviceReady(DevAddress, Trials));
}
#endif /* HAL_I2C_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/