diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2017-01-25 22:24:18 +0100 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2017-01-25 22:29:25 +0100 |
commit | 40e04e3772726829d66c12e69f24b03920d79c67 (patch) | |
tree | 636811bad956798c9d5d22de9e7ba8c799b8d791 /thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL | |
parent | 2fff65aed2477a503c72629d27e2a330d30c02d1 (diff) | |
download | stm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.tar.gz stm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.tar.bz2 stm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.tar.xz stm32f103-playground-40e04e3772726829d66c12e69f24b03920d79c67.zip |
o Moving tinyprintf and stm libraries under thirdparty.
Diffstat (limited to 'thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL')
8 files changed, 4957 insertions, 0 deletions
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.c new file mode 100644 index 0000000..37cba19 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.c @@ -0,0 +1,762 @@ +/** + ****************************************************************************** + * @file stm32303c_eval.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file provides: a set of firmware functions to manage Leds, + * push-button and COM ports + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @defgroup STM32303C_EVAL_LOW_LEVEL + * @brief This file provides firmware functions to manage Leds, push-buttons, + * COM ports, SD card on SPI and temperature sensor (TS751) available on + * STM32303C-EVAL evaluation board from STMicroelectronics. + * @{ + */ + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Private_Variables + * @{ + */ +GPIO_TypeDef* GPIO_PORT[LEDn] = {LED1_GPIO_PORT, LED2_GPIO_PORT, LED3_GPIO_PORT, + LED4_GPIO_PORT}; +const uint16_t GPIO_PIN[LEDn] = {LED1_PIN, LED2_PIN, LED3_PIN, + LED4_PIN}; +const uint32_t GPIO_CLK[LEDn] = {LED1_GPIO_CLK, LED2_GPIO_CLK, LED3_GPIO_CLK, + LED4_GPIO_CLK}; + +GPIO_TypeDef* BUTTON_PORT[BUTTONn] = {KEY_BUTTON_GPIO_PORT, RIGHT_BUTTON_GPIO_PORT, + LEFT_BUTTON_GPIO_PORT, UP_BUTTON_GPIO_PORT, + DOWN_BUTTON_GPIO_PORT, SEL_BUTTON_GPIO_PORT}; + +const uint16_t BUTTON_PIN[BUTTONn] = {KEY_BUTTON_PIN, RIGHT_BUTTON_PIN, LEFT_BUTTON_PIN, + UP_BUTTON_PIN, DOWN_BUTTON_PIN, SEL_BUTTON_PIN}; + +const uint32_t BUTTON_CLK[BUTTONn] = {KEY_BUTTON_GPIO_CLK, RIGHT_BUTTON_GPIO_CLK, + LEFT_BUTTON_GPIO_CLK, UP_BUTTON_GPIO_CLK, + DOWN_BUTTON_GPIO_CLK, SEL_BUTTON_GPIO_CLK}; + +const uint16_t BUTTON_EXTI_LINE[BUTTONn] = {KEY_BUTTON_EXTI_LINE, + RIGHT_BUTTON_EXTI_LINE, + LEFT_BUTTON_EXTI_LINE, + UP_BUTTON_EXTI_LINE, + DOWN_BUTTON_EXTI_LINE, + SEL_BUTTON_EXTI_LINE}; + +const uint8_t BUTTON_PORT_SOURCE[BUTTONn] = {KEY_BUTTON_EXTI_PORT_SOURCE, + RIGHT_BUTTON_EXTI_PORT_SOURCE, + LEFT_BUTTON_EXTI_PORT_SOURCE, + UP_BUTTON_EXTI_PORT_SOURCE, + DOWN_BUTTON_EXTI_PORT_SOURCE, + SEL_BUTTON_EXTI_PORT_SOURCE}; + +const uint8_t BUTTON_PIN_SOURCE[BUTTONn] = {KEY_BUTTON_EXTI_PIN_SOURCE, + RIGHT_BUTTON_EXTI_PIN_SOURCE, + LEFT_BUTTON_EXTI_PIN_SOURCE, + UP_BUTTON_EXTI_PIN_SOURCE, + DOWN_BUTTON_EXTI_PIN_SOURCE, + SEL_BUTTON_EXTI_PIN_SOURCE}; + +const uint8_t BUTTON_IRQn[BUTTONn] = {KEY_BUTTON_EXTI_IRQn, + RIGHT_BUTTON_EXTI_IRQn, LEFT_BUTTON_EXTI_IRQn, + UP_BUTTON_EXTI_IRQn, DOWN_BUTTON_EXTI_IRQn, + SEL_BUTTON_EXTI_IRQn}; + +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 uint32_t COM_USART_CLK[COMn] = {EVAL_COM1_CLK}; + +const uint32_t COM_TX_PORT_CLK[COMn] = {EVAL_COM1_TX_GPIO_CLK}; + +const uint32_t COM_RX_PORT_CLK[COMn] = {EVAL_COM1_RX_GPIO_CLK}; + +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_PIN_SOURCE[COMn] = {EVAL_COM1_TX_SOURCE}; + +const uint16_t COM_RX_PIN_SOURCE[COMn] = {EVAL_COM1_RX_SOURCE}; + +const uint8_t COM_TX_AF[COMn] = {EVAL_COM1_TX_AF}; + +const uint8_t COM_RX_AF[COMn] = {EVAL_COM1_RX_AF}; + + +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Private_Functions + * @{ + */ + +/** + * @brief Configures LED GPIO. + * @param Led: Specifies the Led to be configured. + * This parameter can be one of following parameters: + * @arg LED1 + * @arg LED2 + * @arg LED3 + * @arg LED4 + * @retval None + */ +void STM_EVAL_LEDInit(Led_TypeDef Led) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable the GPIO_LED Clock */ + RCC_AHBPeriphClockCmd(GPIO_CLK[Led], ENABLE); + + /* Configure the GPIO_LED pin */ + GPIO_InitStructure.GPIO_Pin = GPIO_PIN[Led]; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIO_PORT[Led], &GPIO_InitStructure); + GPIO_PORT[Led]->BSRR = GPIO_PIN[Led]; +} + +/** + * @brief Turns selected LED On. + * @param Led: Specifies the Led to be set on. + * This parameter can be one of following parameters: + * @arg LED1 + * @arg LED2 + * @arg LED3 + * @arg LED4 + * @retval None + */ +void STM_EVAL_LEDOn(Led_TypeDef Led) +{ + GPIO_PORT[Led]->BRR = GPIO_PIN[Led]; +} + +/** + * @brief Turns selected LED Off. + * @param Led: Specifies the Led to be set off. + * This parameter can be one of following parameters: + * @arg LED1 + * @arg LED2 + * @arg LED3 + * @arg LED4 + * @retval None + */ +void STM_EVAL_LEDOff(Led_TypeDef Led) +{ + GPIO_PORT[Led]->BSRR = GPIO_PIN[Led]; +} + +/** + * @brief Toggles the selected LED. + * @param Led: Specifies the Led to be toggled. + * This parameter can be one of following parameters: + * @arg LED1 + * @arg LED2 + * @arg LED3 + * @arg LED4 + * @retval None + */ +void STM_EVAL_LEDToggle(Led_TypeDef Led) +{ + GPIO_PORT[Led]->ODR ^= GPIO_PIN[Led]; +} + +/** + * @brief Configures Button GPIO and EXTI Line. + * @param Button: Specifies the Button to be configured. + * This parameter can be one of following parameters: + * @arg BUTTON_KEY: Key Push Button + * @arg BUTTON_RIGHT: Joystick Right Push Button + * @arg BUTTON_LEFT: Joystick Left Push Button + * @arg BUTTON_UP: Joystick Up Push Button + * @arg BUTTON_DOWN: Joystick Down Push Button + * @arg BUTTON_SEL: Joystick Sel Push Button + * @param Button_Mode: 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 STM_EVAL_PBInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode) +{ + GPIO_InitTypeDef GPIO_InitStructure; + EXTI_InitTypeDef EXTI_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + + /* There is no Wakeup button on STM32303C_EVAL-EVAL, the Button value should + be greater than 0. */ + if(Button > 0) + { + Button = (Button_TypeDef) (Button - 1); + + /* Enable the BUTTON Clock */ + RCC_AHBPeriphClockCmd(BUTTON_CLK[Button], ENABLE); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); + + /* Configure Button pin as input */ + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_InitStructure.GPIO_Pin = BUTTON_PIN[Button]; + GPIO_Init(BUTTON_PORT[Button], &GPIO_InitStructure); + + + if (Button_Mode == BUTTON_MODE_EXTI) + { + /* Connect Button EXTI Line to Button GPIO Pin */ + SYSCFG_EXTILineConfig(BUTTON_PORT_SOURCE[Button], BUTTON_PIN_SOURCE[Button]); + + /* Configure Button EXTI line */ + EXTI_InitStructure.EXTI_Line = BUTTON_EXTI_LINE[Button]; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + + if(Button != BUTTON_KEY) + { + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; + } + else + { + EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; + } + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + /* Enable and set Button EXTI Interrupt to the lowest priority */ + NVIC_InitStructure.NVIC_IRQChannel = BUTTON_IRQn[Button]; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + + NVIC_Init(&NVIC_InitStructure); + } + } +} + +/** + * @brief Returns the selected Button state. + * @param Button: Specifies the Button to be checked. + * This parameter can be one of following parameters: + * @arg BUTTON_KEY: Key Push Button + * @arg BUTTON_RIGHT: Joystick Right Push Button + * @arg BUTTON_LEFT: Joystick Left Push Button + * @arg BUTTON_UP: Joystick Up Push Button + * @arg BUTTON_DOWN: Joystick Down Push Button + * @arg BUTTON_SEL: Joystick Sel Push Button + * @retval - When Button > 0, the Button GPIO pin value is returned. + * - When Button = 0 , error code (0xFF) is returned. + */ +uint32_t STM_EVAL_PBGetState(Button_TypeDef Button) +{ + /* There is no Wakeup button on STM32303C_EVAL-EVAL, the Button value should + be greater than 0. */ + if(Button > 0) + { + Button = (Button_TypeDef) (Button - 1); + return GPIO_ReadInputDataBit(BUTTON_PORT[Button], BUTTON_PIN[Button]); + } + else + { + return 0xFF; /* Error Code */ + } +} + +/** + * @brief Configures COM port. + * @param COM: Specifies the COM port to be configured. + * This parameter can be one of following parameters: + * @arg COM1 + * @param USART_InitStruct: pointer to a USART_InitTypeDef structure that + * contains the configuration information for the specified USART peripheral. + * @retval None + */ +void STM_EVAL_COMInit(COM_TypeDef COM, USART_InitTypeDef* USART_InitStruct) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable GPIO clock */ + RCC_AHBPeriphClockCmd(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM], ENABLE); + + /* Enable USART clock */ + RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE); + + /* Connect PXx to USARTx_Tx */ + GPIO_PinAFConfig(COM_TX_PORT[COM], COM_TX_PIN_SOURCE[COM], COM_TX_AF[COM]); + + /* Connect PXx to USARTx_Rx */ + GPIO_PinAFConfig(COM_RX_PORT[COM], COM_RX_PIN_SOURCE[COM], COM_RX_AF[COM]); + + /* Configure USART Tx as alternate function push-pull */ + GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM]; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(COM_TX_PORT[COM], &GPIO_InitStructure); + + /* Configure USART Rx as alternate function push-pull */ + GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM]; + GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure); + + /* USART configuration */ + USART_Init(COM_USART[COM], USART_InitStruct); + + /* Enable USART */ + USART_Cmd(COM_USART[COM], ENABLE); +} + +/** + * @brief DeInitializes the SPI interface. + * @param None + * @retval None + */ +void SD_LowLevel_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + SPI_Cmd(SD_SPI, DISABLE); /* SD_SPI disable */ + SPI_I2S_DeInit(SD_SPI); /* DeInitializes the SD_SPI */ + + /* SD_SPI Periph clock disable */ + RCC_APB1PeriphClockCmd(SD_SPI_CLK, DISABLE); + + /*Configure SD_SPI pins: SCK */ + GPIO_InitStructure.GPIO_Pin = SD_SPI_SCK_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(SD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI pins: MISO */ + GPIO_InitStructure.GPIO_Pin = SD_SPI_MISO_PIN; + GPIO_Init(SD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI pins: MOSI */ + GPIO_InitStructure.GPIO_Pin = SD_SPI_MOSI_PIN; + GPIO_Init(SD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI_CS_PIN pin: SD Card CS pin */ + GPIO_InitStructure.GPIO_Pin = SD_CS_PIN; + GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */ + GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN; + GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief Initializes the SD Card and put it into StandBy State (Ready for + * data transfer). + * @param None + * @retval None + */ +void SD_LowLevel_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + SPI_InitTypeDef SPI_InitStructure; + + /* SD_SPI_CS_GPIO, SD_SPI_MOSI_GPIO, SD_SPI_MISO_GPIO, SD_SPI_DETECT_GPIO + and SD_SPI_SCK_GPIO Periph clock enable */ + RCC_AHBPeriphClockCmd(SD_CS_GPIO_CLK | SD_SPI_MOSI_GPIO_CLK | SD_SPI_MISO_GPIO_CLK | + SD_SPI_SCK_GPIO_CLK | SD_DETECT_GPIO_CLK, ENABLE); + + /* SD_SPI Periph clock enable */ + RCC_APB1PeriphClockCmd(SD_SPI_CLK, ENABLE); + + /* Configure SD_SPI pins: SCK */ + GPIO_InitStructure.GPIO_Pin = SD_SPI_SCK_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(SD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI pins: MISO */ + GPIO_InitStructure.GPIO_Pin = SD_SPI_MISO_PIN; + GPIO_Init(SD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI pins: MOSI */ + GPIO_InitStructure.GPIO_Pin = SD_SPI_MOSI_PIN; + GPIO_Init(SD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI_CS_PIN pin: SD Card CS pin */ + GPIO_InitStructure.GPIO_Pin = SD_CS_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(SD_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */ + GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(SD_DETECT_GPIO_PORT, &GPIO_InitStructure); + + /* Connect PXx to SD_SPI_SCK */ + GPIO_PinAFConfig(SD_SPI_SCK_GPIO_PORT, SD_SPI_SCK_SOURCE, SD_SPI_SCK_AF); + + /* Connect PXx to SD_SPI_MISO */ + GPIO_PinAFConfig(SD_SPI_MISO_GPIO_PORT, SD_SPI_MISO_SOURCE, SD_SPI_MISO_AF); + + /* Connect PXx to SD_SPI_MOSI */ + GPIO_PinAFConfig(SD_SPI_MOSI_GPIO_PORT, SD_SPI_MOSI_SOURCE, SD_SPI_MOSI_AF); + + /* SD_SPI Config */ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; + + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + SPI_Init(SD_SPI, &SPI_InitStructure); + + SPI_RxFIFOThresholdConfig(SD_SPI, SPI_RxFIFOThreshold_QF); + + SPI_Cmd(SD_SPI, ENABLE); /* SD_SPI enable */ +} + +/** + * @brief DeInitializes the TS751_I2C. + * @param None + * @retval None + */ +void TS751_LowLevel_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Disable TS751_I2C */ + I2C_Cmd(TS751_I2C, DISABLE); + + /* DeInitializes the TS751_I2C */ + I2C_DeInit(TS751_I2C); + + /* TS751_I2C Periph clock disable */ + RCC_APB1PeriphClockCmd(TS751_I2C_CLK, DISABLE); + + /* Configure TS751_I2C pins: SCL */ + GPIO_InitStructure.GPIO_Pin = TS751_I2C_SCL_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(TS751_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); + + /* Configure TS751_I2C pins: SDA */ + GPIO_InitStructure.GPIO_Pin = TS751_I2C_SDA_PIN; + GPIO_Init(TS751_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); + + /* Configure TS751_I2C pin: SMBUS ALERT */ + GPIO_InitStructure.GPIO_Pin = TS751_I2C_SMBUSALERT_PIN; + GPIO_Init(TS751_I2C_SMBUSALERT_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief Initializes the TS751_I2C.. + * @param None + * @retval None + */ +void TS751_LowLevel_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* TS751_I2C Periph clock enable */ + RCC_APB1PeriphClockCmd(TS751_I2C_CLK, ENABLE); + + /* Configure the I2C clock source. The clock is derived from the SYSCLK */ + RCC_I2CCLKConfig(RCC_I2C2CLK_SYSCLK); + + /* TS751_I2C_SCL_GPIO_CLK, TS751_I2C_SDA_GPIO_CLK + and TS751_I2C_SMBUSALERT_GPIO_CLK Periph clock enable */ + RCC_AHBPeriphClockCmd(TS751_I2C_SCL_GPIO_CLK | TS751_I2C_SDA_GPIO_CLK | + TS751_I2C_SMBUSALERT_GPIO_CLK, ENABLE); + + /* Connect PXx to I2C_SCL */ + GPIO_PinAFConfig(TS751_I2C_SCL_GPIO_PORT, TS751_I2C_SCL_SOURCE, TS751_I2C_SCL_AF); + + /* Connect PXx to I2C_SDA */ + GPIO_PinAFConfig(TS751_I2C_SDA_GPIO_PORT, TS751_I2C_SDA_SOURCE, TS751_I2C_SDA_AF); + + /* Connect PXx to I2C_SMBUSALER */ + GPIO_PinAFConfig(TS751_I2C_SMBUSALERT_GPIO_PORT, TS751_I2C_SMBUSALERT_SOURCE, TS751_I2C_SMBUSALERT_AF); + + /* Configure TS751_I2C pins: SCL */ + GPIO_InitStructure.GPIO_Pin = TS751_I2C_SCL_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(TS751_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); + + /* Configure TS751_I2C pins: SDA */ + GPIO_InitStructure.GPIO_Pin = TS751_I2C_SDA_PIN; + GPIO_Init(TS751_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); + + /* Configure TS751_I2C pin: SMBUS ALERT */ + GPIO_InitStructure.GPIO_Pin = TS751_I2C_SMBUSALERT_PIN; + GPIO_Init(TS751_I2C_SMBUSALERT_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief DeInitializes peripherals used by the I2C EEPROM driver. + * @param None + * @retval None + */ +void sEE_I2C_LowLevel_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* sEE_I2C Peripheral Disable */ + I2C_Cmd(sEE_I2C, DISABLE); + + /* sEE_I2C DeInit */ + I2C_DeInit(sEE_I2C); + + /* sEE_I2C Periph clock disable */ + RCC_APB1PeriphClockCmd(sEE_I2C_CLK, DISABLE); + + /* GPIO configuration */ + /* Configure sEE_I2C pins: SCL */ + GPIO_InitStructure.GPIO_Pin = sEE_I2C_SCL_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(sEE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE_I2C pins: SDA */ + GPIO_InitStructure.GPIO_Pin = sEE_I2C_SDA_PIN; + GPIO_Init(sEE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief Initializes peripherals used by the I2C EEPROM driver. + * @param None + * @retval None + */ +void sEE_I2C_LowLevel_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Configure the I2C clock source. The clock is derived from the SYSCLK */ + RCC_I2CCLKConfig(RCC_I2C2CLK_SYSCLK); + + /* sEE_I2C_SCL_GPIO_CLK and sEE_I2C_SDA_GPIO_CLK Periph clock enable */ + RCC_AHBPeriphClockCmd(sEE_I2C_SCL_GPIO_CLK | sEE_I2C_SDA_GPIO_CLK, ENABLE); + + /* sEE_I2C Periph clock enable */ + RCC_APB1PeriphClockCmd(sEE_I2C_CLK, ENABLE); + + /* Connect PXx to I2C_SCL*/ + GPIO_PinAFConfig(sEE_I2C_SCL_GPIO_PORT, sEE_I2C_SCL_SOURCE, sEE_I2C_SCL_AF); + + /* Connect PXx to I2C_SDA*/ + GPIO_PinAFConfig(sEE_I2C_SDA_GPIO_PORT, sEE_I2C_SDA_SOURCE, sEE_I2C_SDA_AF); + + /* GPIO configuration */ + /* Configure sEE_I2C pins: SCL */ + GPIO_InitStructure.GPIO_Pin = sEE_I2C_SCL_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_Init(sEE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE_I2C pins: SDA */ + GPIO_InitStructure.GPIO_Pin = sEE_I2C_SDA_PIN; + GPIO_Init(sEE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief DeInitializes the SPI interface. + * @param None + * @retval None + */ +void sEE_SPI_LowLevel_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + SPI_Cmd(sEE_SPI, DISABLE); /* sEE_SPI disable */ + SPI_I2S_DeInit(sEE_SPI); /* DeInitializes the sEE_SPI */ + + /* sEE_SPI Periph clock disable */ + RCC_APB1PeriphClockCmd(sEE_SPI_CLK, DISABLE); + + /* Configure sEE_SPI pins: SCK */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_SCK_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(sEE_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE pins: MISO */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_MISO_PIN; + GPIO_Init(sEE_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE pins: MOSI */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_MOSI_PIN; + GPIO_Init(sEE_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE_CS_PIN pin: sEE Card CS pin */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_CS_PIN; + GPIO_Init(sEE_SPI_CS_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief Initializes the SPI interface for EEPROM + * @param None + * @retval None + */ +void sEE_SPI_LowLevel_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + SPI_InitTypeDef SPI_InitStructure; + + /* sEE_CS_GPIO, sEE_MOSI_GPIO, sEE_MISO_GPIO and sEE_SCK_GPIO + Periph clock enable */ + RCC_AHBPeriphClockCmd(sEE_SPI_CS_GPIO_CLK | sEE_SPI_MOSI_GPIO_CLK | sEE_SPI_MISO_GPIO_CLK | + sEE_SPI_SCK_GPIO_CLK , ENABLE); + + /* sEE Periph clock enable */ + RCC_APB1PeriphClockCmd(sEE_SPI_CLK, ENABLE); + + /* Configure sEE pins: SCK */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_SCK_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(sEE_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE pins: MISO */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_MISO_PIN; + GPIO_Init(sEE_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE pins: MOSI */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_MOSI_PIN; + GPIO_Init(sEE_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); + + /* Configure sEE_CS_PIN pin: sEE Card CS pin */ + GPIO_InitStructure.GPIO_Pin = sEE_SPI_CS_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(sEE_SPI_CS_GPIO_PORT, &GPIO_InitStructure); + + /* Connect PXx to sEE_SCK */ + GPIO_PinAFConfig(sEE_SPI_SCK_GPIO_PORT, sEE_SPI_SCK_SOURCE, sEE_SPI_SCK_AF); + + /* Connect PXx to sEE_MISO */ + GPIO_PinAFConfig(sEE_SPI_MISO_GPIO_PORT, sEE_SPI_MISO_SOURCE, sEE_SPI_MISO_AF); + + /* Connect PXx to sEE_MOSI */ + GPIO_PinAFConfig(sEE_SPI_MOSI_GPIO_PORT, sEE_SPI_MOSI_SOURCE, sEE_SPI_MOSI_AF); + + /* sEE SPI Config */ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64; + + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + SPI_Init(sEE_SPI, &SPI_InitStructure); + + SPI_RxFIFOThresholdConfig(sEE_SPI, SPI_RxFIFOThreshold_QF); + + SPI_Cmd(sEE_SPI, ENABLE); /* sEE_SPI enable */ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.h new file mode 100644 index 0000000..82a2749 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.h @@ -0,0 +1,442 @@ +/** + ****************************************************************************** + * @file stm32303c_eval.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains definitions for STM32303C_EVAL's Leds, push-buttons + * and COM ports hardware resources. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_H +#define __STM32303C_EVAL_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f30x.h" +#include "stm32_eval_legacy.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL + * @{ + */ + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Exported_Types + * @{ + */ +typedef enum +{ + LED1 = 0, + LED2 = 1, + LED3 = 2, + LED4 = 3 +} Led_TypeDef; + +typedef enum +{ + BUTTON_NONE = 0, + BUTTON_KEY = 1, + BUTTON_RIGHT = 2, + BUTTON_LEFT = 3, + BUTTON_UP = 4, + BUTTON_DOWN = 5, + BUTTON_SEL = 6 +} Button_TypeDef; + +typedef enum +{ + BUTTON_MODE_GPIO = 0, + BUTTON_MODE_EXTI = 1 +} ButtonMode_TypeDef; + +typedef enum +{ + JOY_NONE = 0, + JOY_SEL = 1, + JOY_DOWN = 2, + JOY_LEFT = 3, + JOY_RIGHT = 4, + JOY_UP = 5 +} JOYState_TypeDef +; + +typedef enum +{ + COM1 = 0, + COM2 = 1 +} COM_TypeDef; +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Exported_Constants + * @{ + */ + +/** + * @brief Define for STM32303C_EVAL board + */ +#if !defined (USE_STM32303C_EVAL) + #define USE_STM32303C_EVAL +#endif + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL_LED + * @{ + */ +#define LEDn 4 + +#define LED1_PIN GPIO_Pin_8 +#define LED1_GPIO_PORT GPIOE +#define LED1_GPIO_CLK RCC_AHBPeriph_GPIOE + +#define LED2_PIN GPIO_Pin_9 +#define LED2_GPIO_PORT GPIOE +#define LED2_GPIO_CLK RCC_AHBPeriph_GPIOE + +#define LED3_PIN GPIO_Pin_10 +#define LED3_GPIO_PORT GPIOE +#define LED3_GPIO_CLK RCC_AHBPeriph_GPIOE + +#define LED4_PIN GPIO_Pin_11 +#define LED4_GPIO_PORT GPIOE +#define LED4_GPIO_CLK RCC_AHBPeriph_GPIOE + +/** + * @} + */ + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL_BUTTON + * @{ + */ +#define BUTTONn 6 + +/** + * @brief Key push-button + */ +#define KEY_BUTTON_PIN GPIO_Pin_6 +#define KEY_BUTTON_GPIO_PORT GPIOE +#define KEY_BUTTON_GPIO_CLK RCC_AHBPeriph_GPIOE +#define KEY_BUTTON_EXTI_LINE EXTI_Line6 +#define KEY_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE +#define KEY_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource6 +#define KEY_BUTTON_EXTI_IRQn EXTI9_5_IRQn + +/** + * @brief Joystick Right push-button + */ +#define RIGHT_BUTTON_PIN GPIO_Pin_6 +#define RIGHT_BUTTON_GPIO_PORT GPIOD +#define RIGHT_BUTTON_GPIO_CLK RCC_AHBPeriph_GPIOD +#define RIGHT_BUTTON_EXTI_LINE EXTI_Line6 +#define RIGHT_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOD +#define RIGHT_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource6 +#define RIGHT_BUTTON_EXTI_IRQn EXTI9_5_IRQn + +/** + * @brief Joystick Left push-button + */ +#define LEFT_BUTTON_PIN GPIO_Pin_5 +#define LEFT_BUTTON_GPIO_PORT GPIOB +#define LEFT_BUTTON_GPIO_CLK RCC_AHBPeriph_GPIOB +#define LEFT_BUTTON_EXTI_LINE EXTI_Line5 +#define LEFT_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOB +#define LEFT_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource5 +#define LEFT_BUTTON_EXTI_IRQn EXTI9_5_IRQn + +/** + * @brief Joystick Up push-button + */ +#define UP_BUTTON_PIN GPIO_Pin_7 +#define UP_BUTTON_GPIO_PORT GPIOE +#define UP_BUTTON_GPIO_CLK RCC_AHBPeriph_GPIOE +#define UP_BUTTON_EXTI_LINE EXTI_Line7 +#define UP_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOE +#define UP_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource7 +#define UP_BUTTON_EXTI_IRQn EXTI9_5_IRQn + +/** + * @brief Joystick Down push-button + */ +#define DOWN_BUTTON_PIN GPIO_Pin_5 +#define DOWN_BUTTON_GPIO_PORT GPIOD +#define DOWN_BUTTON_GPIO_CLK RCC_AHBPeriph_GPIOD +#define DOWN_BUTTON_EXTI_LINE EXTI_Line5 +#define DOWN_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOD +#define DOWN_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource5 +#define DOWN_BUTTON_EXTI_IRQn EXTI9_5_IRQn + +/** + * @brief Joystick Sel push-button + */ +#define SEL_BUTTON_PIN GPIO_Pin_13 +#define SEL_BUTTON_GPIO_PORT GPIOC +#define SEL_BUTTON_GPIO_CLK RCC_AHBPeriph_GPIOC +#define SEL_BUTTON_EXTI_LINE EXTI_Line13 +#define SEL_BUTTON_EXTI_PORT_SOURCE EXTI_PortSourceGPIOC +#define SEL_BUTTON_EXTI_PIN_SOURCE EXTI_PinSource13 +#define SEL_BUTTON_EXTI_IRQn EXTI15_10_IRQn + +/** + * @} + */ + + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL_COM + * @{ + */ +#define COMn 1 + +/** + * @brief Definition for COM port1, connected to USART1 + */ +#define EVAL_COM1 USART1 +#define EVAL_COM1_CLK RCC_APB2Periph_USART1 + +#define EVAL_COM1_TX_PIN GPIO_Pin_4 +#define EVAL_COM1_TX_GPIO_PORT GPIOC +#define EVAL_COM1_TX_GPIO_CLK RCC_AHBPeriph_GPIOC +#define EVAL_COM1_TX_SOURCE GPIO_PinSource4 +#define EVAL_COM1_TX_AF GPIO_AF_7 + +#define EVAL_COM1_RX_PIN GPIO_Pin_1 +#define EVAL_COM1_RX_GPIO_PORT GPIOE +#define EVAL_COM1_RX_GPIO_CLK RCC_AHBPeriph_GPIOE +#define EVAL_COM1_RX_SOURCE GPIO_PinSource1 +#define EVAL_COM1_RX_AF GPIO_AF_7 + +#define EVAL_COM1_CTS_PIN GPIO_Pin_11 +#define EVAL_COM1_CTS_GPIO_PORT GPIOA +#define EVAL_COM1_CTS_GPIO_CLK RCC_AHBPeriph_GPIOA +#define EVAL_COM1_CTS_SOURCE GPIO_PinSource11 +#define EVAL_COM1_CTS_AF GPIO_AF_7 + +#define EVAL_COM1_RTS_PIN GPIO_Pin_12 +#define EVAL_COM1_RTS_GPIO_PORT GPIOA +#define EVAL_COM1_RTS_GPIO_CLK RCC_AHBPeriph_GPIOA +#define EVAL_COM1_RTS_SOURCE GPIO_PinSource12 +#define EVAL_COM1_RTS_AF GPIO_AF_7 + +#define EVAL_COM1_IRQn USART1_IRQn + +/** + * @} + */ + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL_SD_SPI + * @{ + */ +/** + * @brief SD SPI Interface pins + */ +#define SD_SPI SPI2 +#define SD_SPI_CLK RCC_APB1Periph_SPI2 + +#define SD_SPI_SCK_PIN GPIO_Pin_9 /* PF.09 */ +#define SD_SPI_SCK_GPIO_PORT GPIOF /* GPIOF */ +#define SD_SPI_SCK_GPIO_CLK RCC_AHBPeriph_GPIOF +#define SD_SPI_SCK_SOURCE GPIO_PinSource9 +#define SD_SPI_SCK_AF GPIO_AF_5 + +#define SD_SPI_MISO_PIN GPIO_Pin_14 /* PB.14 */ +#define SD_SPI_MISO_GPIO_PORT GPIOB /* GPIOB */ +#define SD_SPI_MISO_GPIO_CLK RCC_AHBPeriph_GPIOB +#define SD_SPI_MISO_SOURCE GPIO_PinSource14 +#define SD_SPI_MISO_AF GPIO_AF_5 + +#define SD_SPI_MOSI_PIN GPIO_Pin_15 /* PB.15 */ +#define SD_SPI_MOSI_GPIO_PORT GPIOB /* GPIOB */ +#define SD_SPI_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOB +#define SD_SPI_MOSI_SOURCE GPIO_PinSource15 +#define SD_SPI_MOSI_AF GPIO_AF_5 + +#define SD_CS_PIN GPIO_Pin_15 /* PE.15 */ +#define SD_CS_GPIO_PORT GPIOE /* GPIOE */ +#define SD_CS_GPIO_CLK RCC_AHBPeriph_GPIOF + + +#define SD_DETECT_PIN GPIO_Pin_6 /* PC.06 */ +#define SD_DETECT_EXTI_LINE EXTI_Line6 +#define SD_DETECT_EXTI_PIN_SOURCE EXTI_PinSource6 +#define SD_DETECT_GPIO_PORT GPIOC /* GPIOC */ +#define SD_DETECT_GPIO_CLK RCC_AHBPeriph_GPIOC +#define SD_DETECT_EXTI_PORT_SOURCE EXTI_PortSourceGPIOC +#define SD_DETECT_EXTI_IRQn EXTI9_5_IRQn + +/** + * @} + */ + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL_sEE_SPI + * @{ + */ +/** + * @brief sEE SPI Interface pins + */ +#define sEE_SPI SPI2 +#define sEE_SPI_CLK RCC_APB1Periph_SPI2 + +#define sEE_SPI_SCK_PIN GPIO_Pin_9 /* PF.09 */ +#define sEE_SPI_SCK_GPIO_PORT GPIOF /* GPIOF */ +#define sEE_SPI_SCK_GPIO_CLK RCC_AHBPeriph_GPIOF +#define sEE_SPI_SCK_SOURCE GPIO_PinSource9 +#define sEE_SPI_SCK_AF GPIO_AF_5 + +#define sEE_SPI_MISO_PIN GPIO_Pin_14 /* PB.14 */ +#define sEE_SPI_MISO_GPIO_PORT GPIOB /* GPIOB */ +#define sEE_SPI_MISO_GPIO_CLK RCC_AHBPeriph_GPIOB +#define sEE_SPI_MISO_SOURCE GPIO_PinSource14 +#define sEE_SPI_MISO_AF GPIO_AF_5 + +#define sEE_SPI_MOSI_PIN GPIO_Pin_15 /* PB.15 */ +#define sEE_SPI_MOSI_GPIO_PORT GPIOB /* GPIOB */ +#define sEE_SPI_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOB +#define sEE_SPI_MOSI_SOURCE GPIO_PinSource15 +#define sEE_SPI_MOSI_AF GPIO_AF_5 + +#define sEE_SPI_CS_PIN GPIO_Pin_7 /* PD.07 */ +#define sEE_SPI_CS_GPIO_PORT GPIOD /* GPIOD */ +#define sEE_SPI_CS_GPIO_CLK RCC_AHBPeriph_GPIOD + +/** + * @brief sEE SPI Interface Type + */ +#define sEE_M95M01 + +/** + * @} + */ + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL_TSENSOR_I2C + * @{ + */ +/** + * @brief TS751 Temperature Sensor I2C Interface pins + */ +#define TS751_I2C I2C2 +#define TS751_I2C_CLK RCC_APB1Periph_I2C2 + +#define TS751_I2C_SCL_PIN GPIO_Pin_6 /* PF.06 */ +#define TS751_I2C_SCL_GPIO_PORT GPIOF /* GPIOF */ +#define TS751_I2C_SCL_GPIO_CLK RCC_AHBPeriph_GPIOF +#define TS751_I2C_SCL_SOURCE GPIO_PinSource6 +#define TS751_I2C_SCL_AF GPIO_AF_4 + +#define TS751_I2C_SDA_PIN GPIO_Pin_10 /* PA.10 */ +#define TS751_I2C_SDA_GPIO_PORT GPIOA /* GPIOA */ +#define TS751_I2C_SDA_GPIO_CLK RCC_AHBPeriph_GPIOA +#define TS751_I2C_SDA_SOURCE GPIO_PinSource10 +#define TS751_I2C_SDA_AF GPIO_AF_4 + +#define TS751_I2C_SMBUSALERT_PIN GPIO_Pin_8 /* PA.08 */ +#define TS751_I2C_SMBUSALERT_GPIO_PORT GPIOA /* GPIOA */ +#define TS751_I2C_SMBUSALERT_GPIO_CLK RCC_AHBPeriph_GPIOA +#define TS751_I2C_SMBUSALERT_SOURCE GPIO_PinSource8 +#define TS751_I2C_SMBUSALERT_AF GPIO_AF_4 + +/** + * @} + */ + +/** @addtogroup STM32303C_EVAL_LOW_LEVEL_I2C_EE + * @{ + */ +/** + * @brief I2C EEPROM Interface pins + */ +#define sEE_I2C I2C2 +#define sEE_I2C_CLK RCC_APB1Periph_I2C2 + +#define sEE_I2C_SCL_PIN GPIO_Pin_6 /* PF.06 */ +#define sEE_I2C_SCL_GPIO_PORT GPIOF /* GPIOF */ +#define sEE_I2C_SCL_GPIO_CLK RCC_AHBPeriph_GPIOF +#define sEE_I2C_SCL_SOURCE GPIO_PinSource6 +#define sEE_I2C_SCL_AF GPIO_AF_4 + +#define sEE_I2C_SDA_PIN GPIO_Pin_10 /* PA.10 */ +#define sEE_I2C_SDA_GPIO_PORT GPIOA /* GPIOA */ +#define sEE_I2C_SDA_GPIO_CLK RCC_AHBPeriph_GPIOA +#define sEE_I2C_SDA_SOURCE GPIO_PinSource10 +#define sEE_I2C_SDA_AF GPIO_AF_4 + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LOW_LEVEL_Exported_Functions + * @{ + */ +void STM_EVAL_LEDInit(Led_TypeDef Led); +void STM_EVAL_LEDOn(Led_TypeDef Led); +void STM_EVAL_LEDOff(Led_TypeDef Led); +void STM_EVAL_LEDToggle(Led_TypeDef Led); +void STM_EVAL_PBInit(Button_TypeDef Button, ButtonMode_TypeDef Button_Mode); +uint32_t STM_EVAL_PBGetState(Button_TypeDef Button); +void STM_EVAL_COMInit(COM_TypeDef COM, USART_InitTypeDef* USART_InitStruct); +void SD_LowLevel_DeInit(void); +void SD_LowLevel_Init(void); +void TS751_LowLevel_DeInit(void); +void TS751_LowLevel_Init(void); +void sEE_SPI_LowLevel_DeInit(void); +void sEE_SPI_LowLevel_Init(void); +void sEE_I2C_LowLevel_DeInit(void); +void sEE_I2C_LowLevel_Init(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.c new file mode 100644 index 0000000..9d0991d --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.c @@ -0,0 +1,1597 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_audio_codec.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file includes the low layer driver for CS42L52 Audio Codec + * available on STM32303C_EVAL evaluation board(MB1019). + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/*============================================================================================================================== + User NOTES +1. How To use this driver: +-------------------------- + - This driver supports STM32F30x devices on STM32303C_EVAL (MB1019) Evaluation boards. + + - Configure the options in file stm32303c_eval_audio_codec.h in the section CONFIGURATION. + Refer to the sections 2 and 3 to have more details on the possible configurations. + + - Call the function EVAL_AUDIO_Init( + OutputDevice: physical output mode (OUTPUT_DEVICE_SPEAKER, + OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_AUTO or + OUTPUT_DEVICE_BOTH) + Volume: initial volume to be set (0 is min (mute), 100 is max (100%) + AudioFreq: Audio frequency in Hz (8000, 16000, 22500, 32000 ...) + this parameter is relative to the audio file/stream type. + ) + This function configures all the hardware required for the audio application (codec, I2C, I2S, + GPIOs, DMA and interrupt if needed). This function returns 0 if configuration is OK. + if the returned value is different from 0 or the function is stuck then the communication with + the codec has failed (try to un-plug the power or reset device in this case). + + OUTPUT_DEVICE_SPEAKER: only speaker will be set as output for the audio stream. + + OUTPUT_DEVICE_HEADPHONE: only headphones will be set as output for the audio stream. + + OUTPUT_DEVICE_AUTO: Selection of output device is made through external switch (implemented + into the audio jack on the evaluation board). When the Headphone is connected it is used + as output. When the headphone is disconnected from the audio jack, the output is + automatically switched to Speaker. + + OUTPUT_DEVICE_BOTH: both Speaker and Headphone are used as outputs for the audio stream + at the same time. + + - Call the function EVAL_AUDIO_Play( + pBuffer: pointer to the audio data file address + Size: size of the buffer to be sent in Bytes + ) + to start playing (for the first time) from the audio file/stream. + + - Call the function EVAL_AUDIO_PauseResume( + Cmd: AUDIO_PAUSE (or 0) to pause playing or AUDIO_RESUME (or + any value different from 0) to resume playing. + ) + Note. After calling EVAL_AUDIO_PauseResume() function for pause, only EVAL_AUDIO_PauseResume() should be called + for resume (it is not allowed to call EVAL_AUDIO_Play() in this case). + Note. This function should be called only when the audio file is played or paused (not stopped). + + - For each mode, you may need to implement the relative callback functions into your code. + The Callback functions are named EVAL_AUDIO_XXX_CallBack() and only their prototypes are declared in + the stm32303c_eval_audio_codec.h file. (refer to the example for more details on the callbacks implementations) + + - To Stop playing, to modify the volume level or to mute, use the functions + EVAL_AUDIO_Stop(), EVAL_AUDIO_VolumeCtl() and EVAL_AUDIO_Mute(). + + - The driver API and the callback functions are at the end of the stm32303c_eval_audio_codec.h file. + + + Driver architecture: + -------------------- + This driver is composed of three main layers: + o High Audio Layer: consists of the function API exported in the stm32303c_eval_audio_codec.h file + (EVAL_AUDIO_Init(), EVAL_AUDIO_Play() ...) + o Codec Control layer: consists of the functions API controlling the audio codec (CS42L52) and + included as local functions in file stm32303c_eval_audio_codec.c (Codec_Init(), Codec_Play() ...) + o Media Access Layer (MAL): which consists of functions allowing to access the media containing/ + providing the audio file/stream. These functions are also included as local functions into + the stm32303c_eval_audio_codec.c file (Audio_MAL_Init(), Audio_MAL_Play() ...) + Each set of functions (layer) may be implemented independently of the others and customized when + needed. + +2. Modes description: +--------------------- + + AUDIO_MAL_MODE_NORMAL : is suitable when the audio file is in a memory location. + + AUDIO_MAL_MODE_CIRCULAR: is suitable when the audio data are read either from a + memory location or from a device at real time (double buffer could be used). + +3. DMA interrupts description: +------------------------------ + + EVAL_AUDIO_IT_TC_ENABLE: Enable this define to use the DMA end of transfer interrupt. + then, a callback should be implemented by user to perform specific actions + when the DMA has finished the transfer. + + EVAL_AUDIO_IT_HT_ENABLE: Enable this define to use the DMA end of half transfer interrupt. + then, a callback should be implemented by user to perform specific actions + when the DMA has reached the half of the buffer transfer (generally, it is useful + to load the first half of buffer while DMA is loading from the second half). + + EVAL_AUDIO_IT_ER_ENABLE: Enable this define to manage the cases of error on DMA transfer. + +4. Known Limitations: +--------------------- + 1- When using the Speaker, if the audio file quality is not high enough, the speaker output + may produce high and uncomfortable noise level. To avoid this issue, to use speaker + output properly, try to increase audio file sampling rate (typically higher than 48KHz). + This operation will lead to larger file size. + 2- Communication with the audio codec (through I2C) may be corrupted if it is interrupted by some + user interrupt routines (in this case, interrupts could be disabled just before the start of + communication then re-enabled when it is over). Note that this communication is only done at + the configuration phase (EVAL_AUDIO_Init() or EVAL_AUDIO_Stop()) and when Volume control modification is + performed (EVAL_AUDIO_VolumeCtl() or EVAL_AUDIO_Mute()). When the audio data is played, no communication is + required with the audio codec. + 3- Parsing of audio file is not implemented (in order to determine audio file properties: Mono/Stereo, Data size, + File size, Audio Frequency, Audio Data header size ...). The configuration is fixed for the given audio file. + 4- Mono audio streaming is not supported (in order to play mono audio streams, each data should be sent twice + on the I2S or should be duplicated on the source buffer. Or convert the stream in stereo before playing). + 5- Supports only 16-bit audio data size. +===============================================================================================================================*/ + + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval_audio_codec.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_AUDIO_CODEC + * @brief This file includes the low layer driver for CS42L52 Audio Codec + * available on STM32303C_EVAL evaluation board(MB1019). + * @{ + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Private_Types + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Private_Defines + * @{ + */ + +/* Mask for the bit EN of the I2S CFGR register */ +#define I2S_ENABLE_MASK 0x0400 + +/* Delay for the Codec to be correctly reset */ +#define CODEC_RESET_DELAY 0x4FFF + +/* Codec audio Standards */ +#ifdef I2S_STANDARD_PHILLIPS + #define CODEC_STANDARD 0x04 + #define I2S_STANDARD I2S_Standard_Phillips +#elif defined(I2S_STANDARD_MSB) + #define CODEC_STANDARD 0x00 + #define I2S_STANDARD I2S_Standard_MSB +#elif defined(I2S_STANDARD_LSB) + #define CODEC_STANDARD 0x08 + #define I2S_STANDARD I2S_Standard_LSB +#else + #error "Error: No audio communication standard selected !" +#endif /* I2S_STANDARD */ + +/* The 7 bits Codec address (sent through I2C interface) */ +#define CODEC_ADDRESS 0x94 /* b1001010. */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Private_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Private_Variables + * @{ + */ +/* This structure is declared global because it is handled by two different functions */ +DMA_InitTypeDef DMA_InitStructure; +DMA_InitTypeDef AUDIO_MAL_DMA_InitStructure; + +uint32_t AudioTotalSize = 0xFFFF; /* This variable holds the total size of the audio file */ +uint32_t AudioRemSize = 0xFFFF; /* This variable holds the remaining data in audio file */ +uint16_t *CurrentPos; /* This variable holds the current position of audio pointer */ + +__IO uint32_t CODECTimeout = CODEC_LONG_TIMEOUT; +__IO uint8_t OutputDev = 0; + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Private_Function_Prototypes + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Private_Functions + * @{ + */ + +/*---------------------------------------------------------------------------- + Audio Codec functions + ----------------------------------------------------------------------------*/ +/* High Layer codec functions */ +static uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq); +static uint32_t Codec_DeInit(void); +static uint32_t Codec_Play(void); +static uint32_t Codec_PauseResume(uint32_t Cmd); +static uint32_t Codec_Stop(uint32_t Cmd); +static uint32_t Codec_VolumeCtrl(uint8_t Volume); +static uint32_t Codec_Mute(uint32_t Cmd); +/* Low layer codec functions */ +static void Codec_CtrlInterface_Init(void); +static void Codec_CtrlInterface_DeInit(void); +static void Codec_AudioInterface_Init(uint32_t AudioFreq); +static void Codec_AudioInterface_DeInit(void); +uint32_t Codec_ReadRegister(uint8_t RegisterAddr); +static void Codec_GPIO_Init(void); +static void Codec_GPIO_Recorder_Init(void); +static void Codec_GPIO_DeInit(void); +static void Delay(__IO uint32_t nCount); +/*----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + MAL (Media Access Layer) functions + ----------------------------------------------------------------------------*/ +/* Peripherals configuration functions */ +static void Audio_MAL_Init(void); +static void Audio_MAL_DeInit(void); +static void Audio_MAL_PauseResume(uint32_t Cmd, uint32_t Addr); +static void Audio_MAL_Stop(void); +/*----------------------------------------------------------------------------*/ + +/** + * @brief Configure the audio peripherals. + * @param OutputDevice: OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, + * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . + * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) + * @param AudioFreq: Audio frequency used to play the audio stream. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t EVAL_AUDIO_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) +{ + /* Perform low layer Codec initialization */ + if (Codec_Init(OutputDevice, VOLUME_CONVERT(Volume), AudioFreq) != 0) + { + return 1; + } + else + { + /* I2S data transfer preparation: + Prepare the Media to be used for the audio transfer from memory to I2S peripheral */ + Audio_MAL_Init(); + + /* Return 0 when all operations are OK */ + return 0; + } +} + +/** + * @brief Deinitializes all the resources used by the codec (those initialized + * by EVAL_AUDIO_Init() function). + * @param None + * @retval 0 if correct communication, else wrong communication + */ +uint32_t EVAL_AUDIO_DeInit(void) +{ + /* DeInitialize Codec */ + Codec_DeInit(); + + /* DeInitialize the Media layer */ + Audio_MAL_DeInit(); + + return 0; +} + +/** + * @brief Starts playing audio stream from a data buffer for a determined size. + * @param pBuffer: Pointer to the buffer + * @param Size: Number of audio data BYTES. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t EVAL_AUDIO_Play(uint16_t* pBuffer, uint32_t Size) +{ + /* Set the total number of data to be played (count in half-word) */ + AudioTotalSize = Size/2; + + /* Call the audio Codec Play function */ + Codec_Play(); + + /* Update the Media layer and enable it for play */ + Audio_MAL_Play((uint32_t)pBuffer, (uint32_t)(DMA_MAX(AudioTotalSize / 2))); + + /* Update the remaining number of data to be played */ + AudioRemSize = (Size/2) - DMA_MAX(AudioTotalSize); + + /* Update the current audio pointer position */ + CurrentPos = pBuffer + DMA_MAX(AudioTotalSize); + + return 0; +} + +/** + * @brief This function Pauses or Resumes the audio file stream. In case + * of using DMA, the DMA Pause feature is used. In all cases the I2S + * peripheral is disabled. + * + * @WARNING When calling EVAL_AUDIO_PauseResume() function for pause, only + * this function should be called for resume (use of EVAL_AUDIO_Play() + * function for resume could lead to unexpected behavior). + * + * @param Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different + * from 0) to resume. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t EVAL_AUDIO_PauseResume(uint32_t Cmd) +{ + /* Call the Audio Codec Pause/Resume function */ + if (Codec_PauseResume(Cmd) != 0) + { + return 1; + } + else + { + /* Call the Media layer pause/resume function */ + Audio_MAL_PauseResume(Cmd, 0); + + /* Return 0 if all operations are OK */ + return 0; + } +} + +/** + * @brief Stops audio playing and Power down the Audio Codec. + * @param Option: could be one of the following parameters + * - CODEC_PDWN_SW: for software power off (by writing registers). + * Then no need to reconfigure the Codec after power on. + * - CODEC_PDWN_HW: completely shut down the codec (physically). + * Then need to reconfigure the Codec after power on. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t EVAL_AUDIO_Stop(uint32_t Option) +{ + /* Call Audio Codec Stop function */ + if (Codec_Stop(Option) != 0) + { + return 1; + } + else + { + /* Call Media layer Stop function */ + Audio_MAL_Stop(); + + /* Update the remaining data number */ + AudioRemSize = AudioTotalSize; + + /* Return 0 when all operations are correctly done */ + return 0; + } +} + +/** + * @brief Controls the current audio volume level. + * @param Volume: Volume level to be set in percentage from 0% to 100% (0 for + * Mute and 100 for Max volume level). + * @retval 0 if correct communication, else wrong communication + */ +uint32_t EVAL_AUDIO_VolumeCtl(uint8_t Volume) +{ + /* Call the codec volume control function with converted volume value */ + return (Codec_VolumeCtrl(VOLUME_CONVERT(Volume))); +} + +/** + * @brief Enables or disables the MUTE mode by software + * @param Command: could be AUDIO_MUTE_ON to mute sound or AUDIO_MUTE_OFF to + * unmute the codec and restore previous volume level. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t EVAL_AUDIO_Mute(uint32_t Cmd) +{ + /* Call the Codec Mute function */ + return (Codec_Mute(Cmd)); +} + +/** + * @brief This function handles main Media layer interrupt. + * @param None + * @retval 0 if correct communication, else wrong communication + */ +void Audio_MAL_IRQHandler(void) +{ +#ifndef AUDIO_MAL_MODE_NORMAL + uint16_t *pAddr = (uint16_t *)CurrentPos; + uint32_t Size = AudioRemSize; +#endif /* AUDIO_MAL_MODE_NORMAL */ + +#ifdef AUDIO_MAL_DMA_IT_TC_EN + /* Transfer complete interrupt */ + if (DMA_GetFlagStatus(AUDIO_MAL_DMA_FLAG_TC) != RESET) + { + #ifdef AUDIO_MAL_MODE_NORMAL + /* Check if the end of file has been reached */ + if (AudioRemSize > 0) + { + /* Wait the DMA Channel to be effectively disabled */ + while (DMA_GetFlagStatus(AUDIO_MAL_DMA_FLAG_TC) != SET) + {} + + /* Clear the Interrupt flag */ + DMA_ClearFlag(AUDIO_MAL_DMA_FLAG_TC); + + /* Re-Configure the buffer address and size */ + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) CurrentPos; + DMA_InitStructure.DMA_BufferSize = (uint32_t) (DMA_MAX(AudioRemSize)); + + /* Configure the DMA Channel with the new parameters */ + DMA_Init(AUDIO_MAL_DMA_CHANNEL , &DMA_InitStructure); + + /* Enable the I2S DMA Channel */ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL , ENABLE); + + /* Update the current pointer position */ + CurrentPos += DMA_MAX(AudioRemSize); + + /* Update the remaining number of data to be played */ + AudioRemSize -= DMA_MAX(AudioRemSize); + } + else + { + /* Disable the I2S DMA Channel */ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL , DISABLE); + + /* Clear the Interrupt flag */ + DMA_ClearFlag(AUDIO_MAL_DMA_FLAG_TC); + + /* Manage the remaining file size and new address offset: This function + should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ + EVAL_AUDIO_TransferComplete_CallBack((uint32_t)CurrentPos, 0); + } + + #elif defined(AUDIO_MAL_MODE_CIRCULAR) + /* Manage the remaining file size and new address offset: This function + should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ + EVAL_AUDIO_TransferComplete_CallBack(pAddr, Size); + + /* Clear the Interrupt flag */ + DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC); + #endif /* AUDIO_MAL_MODE_NORMAL */ + } +#endif /* AUDIO_MAL_DMA_IT_TC_EN */ + +#ifdef AUDIO_MAL_DMA_IT_HT_EN + /* Half Transfer complete interrupt */ + if (DMA_GetFlagStatus(AUDIO_MAL_DMA_CHANNEL, AUDIO_MAL_DMA_FLAG_HT) != RESET) + { + /* Manage the remaining file size and new address offset: This function + should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ + EVAL_AUDIO_HalfTransfer_CallBack((uint32_t)pAddr, Size); + + /* Clear the Interrupt flag */ + DMA_ClearFlag(AUDIO_MAL_DMA_CHANNEL, AUDIO_MAL_DMA_FLAG_HT); + } +#endif /* AUDIO_MAL_DMA_IT_HT_EN */ + +#ifdef AUDIO_MAL_DMA_IT_TE_EN + /* FIFO Error interrupt */ + if ((DMA_GetFlagStatus(AUDIO_MAL_DMA_CHANNEL, AUDIO_MAL_DMA_FLAG_TE) != RESET) || \ + (DMA_GetFlagStatus(AUDIO_MAL_DMA_CHANNEL, AUDIO_MAL_DMA_FLAG_FE) != RESET) || \ + (DMA_GetFlagStatus(AUDIO_MAL_DMA_CHANNEL, AUDIO_MAL_DMA_FLAG_DME) != RESET)) + + { + /* Manage the error generated on DMA FIFO: This function + should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ + EVAL_AUDIO_Error_CallBack((uint32_t*)&pAddr); + + /* Clear the Interrupt flag */ + DMA_ClearFlag(AUDIO_MAL_DMA_CHANNEL, AUDIO_MAL_DMA_FLAG_TE | AUDIO_MAL_DMA_FLAG_FE | \ + AUDIO_MAL_DMA_FLAG_DME); + } +#endif /* AUDIO_MAL_DMA_IT_TE_EN */ +} + +/*============================================================================ + CS42L52 Audio Codec Control Functions + ============================================================================*/ +/** + * @brief Initializes the audio codec and all related interfaces (control + * interface: I2C and audio interface: I2S) + * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, + * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . + * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) + * @param AudioFreq: Audio frequency used to play the audio stream. + * @retval 0 if correct communication, else wrong communication + */ +static uint32_t Codec_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq) +{ + uint32_t counter = 0; + + /* Configure the Codec related IOs */ + Codec_GPIO_Init(); + + /* Initialize the Control interface of the Audio Codec */ + Codec_CtrlInterface_Init(); + + /* Keep Codec powered OFF */ + counter += Codec_WriteRegister(0x02, 0x9E/*0x01*/); + + switch (OutputDevice) + { + case OUTPUT_DEVICE_SPEAKER: + counter += Codec_WriteRegister(0x04, 0xFA); /* SPK always ON & HP always OFF */ + OutputDev = 0xFA; + break; + + case OUTPUT_DEVICE_HEADPHONE: + counter += Codec_WriteRegister(0x04, 0xAF); /* SPK always OFF & HP always ON */ + OutputDev = 0xAF; + break; + + case OUTPUT_DEVICE_BOTH: + counter += Codec_WriteRegister(0x04, 0xAA); /* SPK always ON & HP always ON */ + OutputDev = 0xAA; + break; + + case OUTPUT_DEVICE_AUTO: + counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ + OutputDev = 0x05; + break; + + default: + counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ + OutputDev = 0x05; + break; + } + + /* Clock configuration: Auto detection */ + counter += Codec_WriteRegister(0x05, 0x80); + /* Set the Slave Mode and the audio Standard */ + counter += Codec_WriteRegister(0x06, 0x03/*CODEC_STANDARD*/); + /* Interface Control 2: SCLK is Re-timed signal from MCLK*/ + counter +=Codec_WriteRegister(0x07, 0x00); + /* ADCA and PGAA Select: no input selected*/ + counter +=Codec_WriteRegister(0x08, 0x00); + /* ADCB and PGAB Select: no input selected*/ + counter +=Codec_WriteRegister(0x09, 0x00); + /*Play Back Control 1: headphone gain is 0.4, PCM not inverted, Master not mute*/ + counter +=Codec_WriteRegister(0x0D, 0x10);/* CS42L52 has different config than CS42L52*/ + /* Miscellaneous Controls: Passthrough Analog & Passthrough Mute off, Soft Ramp on @0x0E*/ + counter +=Codec_WriteRegister(0x0E, 0x02); + /* Play Back Control 2: Headphone Mute off, speaker mute off, mono enabled */ + counter +=Codec_WriteRegister(0x0F, 0x32); + /* PCM A Volume: PCM Mute disabled, Volume is 0db(default) */ + counter +=Codec_WriteRegister(0x1A, 0x00); + /* PCM B Volume: PCM Mute disabled, Volume is 0db(default) */ + counter +=Codec_WriteRegister(0x1B, 0x00); + /* Headphone A Volume: Headphone Volume is -6db */ + counter +=Codec_WriteRegister(0x22, (u8)(0-12)); + /* Headphone B Volume: Headphone Volume is -6db */ + counter +=Codec_WriteRegister(0x23, (u8)(0-12)); + /* Speaker A Volume: Speaker Volume is 0db (default) */ + counter +=Codec_WriteRegister(0x24, 0x00); + /* Speaker B Volume: Speaker Volume is 0db (default) */ + counter +=Codec_WriteRegister(0x25, 0x00); + /* Charge Pump Frequency: 5 (default) */ + counter +=Codec_WriteRegister(0x34, 5<<4); + /* Power Control 1: power up */ + counter += Codec_WriteRegister(0x02, 0x00); + counter += Codec_WriteRegister(0x20, 0xff); + counter += Codec_WriteRegister(0x21, 0xff); + + /* Configure the I2S peripheral */ + Codec_AudioInterface_Init(AudioFreq); + + /* Return communication control value */ + return counter; +} + +/** + * @brief Initializes the audio codec and all related interfaces (control + * interface: I2C and audio interface: I2S) + * @param OutputDevice: can be OUTPUT_DEVICE_SPEAKER, OUTPUT_DEVICE_HEADPHONE, + * OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO . + * @param Volume: Initial volume level (from 0 (Mute) to 100 (Max)) + * @param AudioFreq: Audio frequency used to play the audio stream. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t Codec_Record_Init(void) +{ + uint32_t counter = 0; + + /* Configure the Codec related IOs */ + Codec_GPIO_Recorder_Init(); + + /* Initialize the Control interface of the Audio Codec */ + Codec_CtrlInterface_Init(); + + /* Mono Record @ MIC1+ with Bias */ + /* Power Control 2[@03h]: MICB Off, MIC A & Bias On */ + counter += Codec_WriteRegister(0x03, 0x04); + /* Power Control 3[@04h]: headphone A/B Off, speaker A & B Off */ + counter += Codec_WriteRegister(0x04, 0xFF); + /* Clocking Control: auto sample rate(Fs) */ + counter += Codec_WriteRegister(0x05, 0x80); + /* Interface Control 1: slave, LeftJustified, 16-bit data */ + counter += Codec_WriteRegister(0x06, 0x03); + /* Interface Control 2: SCLK is Re-timed signal from MCLK, BIAS: 0.5*VA */ + counter += Codec_WriteRegister(0x07, 0x00); + /* ADCA and PGAA Select: MICx selected */ + counter += Codec_WriteRegister(0x08, 0x90); + /* ADCB and PGAB Select: MICx selected */ + counter += Codec_WriteRegister(0x09, 0x90); + /* Misc ADC Control: SDOUT Signal Source is ADC_or_DSP */ + counter += Codec_WriteRegister(0x0C, 0x00); + /* Play Back Control 1: headphone gain is 0.4, PCM not inverted, Master not mute */ + counter += Codec_WriteRegister(0x0D, 0x00); + /* Miscellaneous Controls: Passthrough Analog & Passthrough Mute off, Soft Ramp on @0x0E */ + counter += Codec_WriteRegister(0x0E, 0x02); + /* Play Back Control 2: Headphone Mute on, speaker mute off, mono enabled */ + counter += Codec_WriteRegister(0x0F, 0xC2); + /* MICA Amp Control: select MIC 2x, Single-Ended, Gain=16db */ + counter += Codec_WriteRegister(0x10, 0x2E); + /* MICB Amp Control: select MIC 2x, Single-Ended, Gain=16db */ + counter += Codec_WriteRegister(0x11, 0x40); + /* MICB Amp Control: try with Differential, Gain=16db */ + counter += Codec_WriteRegister(0x11, 0x20); + /* PGA Volume ALC Control: Gain=0db */ + counter += Codec_WriteRegister(0x12, 0x00); + /* PGA Volume ALC Control: Gain=0db */ + counter += Codec_WriteRegister(0x13, 0x00); + counter += Codec_WriteRegister(0x34, 5<<4); + + counter += Codec_WriteRegister(0x02, 0x14); + + /* Return communication control value */ + return counter; + +} + +/** + * @brief Restore the audio codec state to default state and free all used + * resources. + * @param None + * @retval 0 if correct communication, else wrong communication + */ +static uint32_t Codec_DeInit(void) +{ + uint32_t counter = 0; + uint16_t i = 0; + uint8_t tmp = 0; + + /* Enable Master Playback Mute @0x0D */ + counter += Codec_WriteRegister(0x02, 0x03); + /* Power down CS42L52 @0x03 */ + counter += Codec_WriteRegister(0x03, 0x07); + /* Power down CS42L52 @0x04 */ + counter += Codec_WriteRegister(0x04, 0xFF); + /* config interface @0x06 */ + counter += Codec_WriteRegister(0x06, 0x03); + /* Disable Analog (Soft Ramp & Zero Cross) and HighPassFilter @0x0A */ + counter += Codec_WriteRegister(0x0A, 0x00); + /* Digital Soft Ramp on & Zero Cross off @0x0E */ + counter += Codec_WriteRegister(0x0E, 0x02); + /* Headphone Mute, Speaker Mute @0x0F */ + counter += Codec_WriteRegister(0x0F, 0xF2); + /* PCM A Volume: Mute @0x1A */ + counter += Codec_WriteRegister(0x1A, 0x80); + /* PCM B Volume: Mute @0x1B */ + counter += Codec_WriteRegister(0x1B, 0x80); + /* Limiter Attack Rate: 0x00 @0x29 */ + counter += Codec_WriteRegister(0x29, 0x00); + + i = 0; + do{ + // Power down CS42L52 @0x02 + counter += Codec_WriteRegister(0x02, 0x9F); + tmp = Codec_ReadRegister(0x02); + i++; + } + while (((tmp & 0x01) == 0) && (i < 10)); + + Delay(CODEC_RESET_DELAY); + + /* Deinitialize all use GPIOs */ + Codec_GPIO_DeInit(); + + /* Deinitialize the Codec audio interface (I2S) */ + Codec_AudioInterface_DeInit(); + /* Disable the Codec control interface */ + Codec_CtrlInterface_DeInit(); + + /* Return communication control value */ + return counter; +} + +/** + * @brief Start the audio Codec play feature. + * @note For this codec no Play options are required. + * @param None + * @retval 0 if correct communication, else wrong communication + */ +static uint32_t Codec_Play(void) +{ + /* + No actions required on Codec level for play command + */ + + /* Return communication control value */ + return 0; +} + +/** + * @brief Pauses and resumes playing on the audio codec. + * @param Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different + * from 0) to resume. + * @retval 0 if correct communication, else wrong communication + */ +static uint32_t Codec_PauseResume(uint32_t Cmd) +{ + uint32_t counter = 0; + + /* Pause the audio file playing */ + if (Cmd == AUDIO_PAUSE) + { + /* Mute the output first */ + counter += Codec_Mute(AUDIO_MUTE_ON); + + /* Put the Codec in Power save mode */ + counter += Codec_WriteRegister(0x02, 0x01); + } + else /* AUDIO_RESUME */ + { + /* Unmute the output first */ + counter += Codec_Mute(AUDIO_MUTE_OFF); + + counter += Codec_WriteRegister(0x04, OutputDev); + + /* Exit the Power save mode */ + counter += Codec_WriteRegister(0x02, 0x9E); + + } + + return counter; +} + +/** + * @brief Stops audio Codec playing. It powers down the codec. + * @param CodecPdwnMode: selects the power down mode. + * - CODEC_PDWN_SW: only mutes the audio codec. When resuming from this + * mode the codec keeps the previous initialization + * (no need to re-Initialize the codec registers). + * - CODEC_PDWN_HW: Physically power down the codec. When resuming from this + * mode, the codec is set to default configuration + * (user should re-Initialize the codec in order to + * play again the audio stream). + * @retval 0 if correct communication, else wrong communication + */ +static uint32_t Codec_Stop(uint32_t CodecPdwnMode) +{ + uint32_t counter = 0; + + /* Mute the output first */ + Codec_Mute(AUDIO_MUTE_ON); + + if (CodecPdwnMode == CODEC_PDWN_SW) + { + /* Power down the DAC and the speaker (PMDAC and PMSPK bits)*/ + counter += Codec_WriteRegister(0x02, 0x9F); + } + else /* CODEC_PDWN_HW */ + { + /* Power down the components */ + counter += Codec_WriteRegister(0x02, 0x9F); + + /* Wait at least 100us */ + Delay(0xFFF); + } + return counter; +} + +/** + * @brief Sets higher or lower the codec volume level. + * @param Volume: a byte value from 0 to 255 (refer to codec registers + * description for more details). + * @retval 0 if correct communication, else wrong communication + */ +static uint32_t Codec_VolumeCtrl(uint8_t Volume) +{ + uint32_t counter = 0; + + if (Volume > 0xE6) + { + /* Set the Master volume */ + counter += Codec_WriteRegister(0x20, Volume - 0xE7); + counter += Codec_WriteRegister(0x21, Volume - 0xE7); + } + else + { + /* Set the Master volume */ + counter += Codec_WriteRegister(0x20, Volume + 0x19); + counter += Codec_WriteRegister(0x21, Volume + 0x19); + } + + return counter; +} + +/** + * @brief Enables or disables the mute feature on the audio codec. + * @param Cmd: AUDIO_MUTE_ON to enable the mute or AUDIO_MUTE_OFF to disable the + * mute mode. + * @retval 0 if correct communication, else wrong communication + */ +static uint32_t Codec_Mute(uint32_t Cmd) +{ + uint32_t counter = 0; + + /* Set the Mute mode */ + if (Cmd == AUDIO_MUTE_ON) + { + counter += Codec_WriteRegister(0x04, 0xFF); + counter += Codec_WriteRegister(0x0F, 0xF0); + } + else /* AUDIO_MUTE_OFF Disable the Mute */ + { + counter += Codec_WriteRegister(0x04, 0x05); + counter += Codec_WriteRegister(0x0F, 0x02); + } + + return counter; +} + +/** + * @brief Switch dynamically (while audio file is played) the output target + * (speaker or headphone). + * @note This function modifies a global variable of the audio codec driver: OutputDev. + * @param Output: specifies the audio output target: OUTPUT_DEVICE_SPEAKER, + * OUTPUT_DEVICE_HEADPHONE, OUTPUT_DEVICE_BOTH or OUTPUT_DEVICE_AUTO + * @retval 0 if correct communication, else wrong communication + */ +uint32_t Codec_SwitchOutput(uint8_t Output) +{ + uint8_t counter = 0; + + switch (Output) + { + case OUTPUT_DEVICE_SPEAKER: + counter += Codec_WriteRegister(0x04, 0xFA); /* SPK always ON & HP always OFF */ + OutputDev = 0xFA; + break; + + case OUTPUT_DEVICE_HEADPHONE: + counter += Codec_WriteRegister(0x04, 0xAF); /* SPK always OFF & HP always ON */ + OutputDev = 0xAF; + break; + + case OUTPUT_DEVICE_BOTH: + counter += Codec_WriteRegister(0x04, 0xAA); /* SPK always ON & HP always ON */ + OutputDev = 0xAA; + break; + + case OUTPUT_DEVICE_AUTO: + counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ + OutputDev = 0x05; + break; + + default: + counter += Codec_WriteRegister(0x04, 0x05); /* Detect the HP or the SPK automatically */ + OutputDev = 0x05; + break; + } + + return counter; +} + +/** + * @brief Writes a Byte to a given register into the audio codec through the + control interface (I2C) + * @param RegisterAddr: The address (location) of the register to be written. + * @param RegisterValue: the Byte value to be written into destination register. + * @retval 0 if correct communication, else wrong communication + */ +uint32_t Codec_WriteRegister(uint8_t RegisterAddr, uint8_t RegisterValue) +{ + uint32_t result = 0; + + /* Test on BUSY Flag */ + CODECTimeout = CODEC_FLAG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_BUSY) != RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(CODEC_I2C, CODEC_ADDRESS, 2, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + CODECTimeout = CODEC_FLAG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_TXIS) == RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(CODEC_I2C, (uint8_t)RegisterAddr ); + + /* Wait until TXIS flag is set */ + CODECTimeout = CODEC_FLAG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_TXIS) == RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Write data to TXDR */ + I2C_SendData(CODEC_I2C, (uint8_t)RegisterValue); + + /* Wait until STOPF flag is set */ + CODECTimeout = CODEC_FLAG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_STOPF) == RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(CODEC_I2C, I2C_ICR_STOPCF); + +#ifdef VERIFY_WRITTENDATA + /* Verify that the data has been correctly written */ + result = (Codec_ReadRegister(RegisterAddr) == RegisterValue)? 0:1; +#endif /* VERIFY_WRITTENDATA */ + + /* Return the verifying value: 0 (Passed) or 1 (Failed) */ + return result; +} + +/** + * @brief Reads and returns the value of an audio codec register through the + * control interface (I2C). + * @param RegisterAddr: Address of the register to be read. + * @retval Value of the register to be read or dummy value if the communication + * fails. + */ +uint32_t Codec_ReadRegister(uint8_t RegisterAddr) +{ + uint32_t result = 0; + + /* Test on BUSY Flag */ + CODECTimeout = CODEC_LONG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_BUSY) != RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(CODEC_I2C, CODEC_ADDRESS, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + CODECTimeout = CODEC_LONG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_TXIS) == RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(CODEC_I2C, (uint8_t)RegisterAddr); + + /* Wait until TC flag is set */ + CODECTimeout = CODEC_LONG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_TC) == RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(CODEC_I2C, CODEC_ADDRESS, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + + /* Wait until RXNE flag is set */ + CODECTimeout = CODEC_LONG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_RXNE) == RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Read data from RXDR */ + result = I2C_ReceiveData(CODEC_I2C); + + /* Wait until STOPF flag is set */ + CODECTimeout = CODEC_LONG_TIMEOUT; + while(I2C_GetFlagStatus(CODEC_I2C, I2C_ISR_STOPF) == RESET) + { + if((CODECTimeout--) == 0) return Codec_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(CODEC_I2C, I2C_ICR_STOPCF); + + /* Return the byte read from Codec */ + return result; +} + +/** + * @brief Initializes the Audio Codec control interface (I2C). + * @param None + * @retval None + */ +static void Codec_CtrlInterface_Init(void) +{ + I2C_InitTypeDef I2C_InitStructure; + + /* Configure the I2C clock source. The clock is derived from the SYSCLK */ + RCC_I2CCLKConfig(RCC_I2C2CLK_SYSCLK); + + /* Enable the CODEC_I2C peripheral clock */ + RCC_APB1PeriphClockCmd(CODEC_I2C_CLK, ENABLE); + + /* CODEC_I2C configuration */ + I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; + I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; + I2C_InitStructure.I2C_DigitalFilter = 0x00; + I2C_InitStructure.I2C_OwnAddress1 = 0x00; + I2C_InitStructure.I2C_Ack = I2C_Ack_Disable; + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_InitStructure.I2C_Timing = CODEC_I2C_TIMING; + + /* Enable the I2C peripheral */ + I2C_Init(CODEC_I2C, &I2C_InitStructure); + I2C_Cmd(CODEC_I2C, ENABLE); + +} + +/** + * @brief Restore the Audio Codec control interface to its default state. + * This function doesn't de-initialize the I2C because the I2C peripheral + * may be used by other modules. + * @param None + * @retval None + */ +static void Codec_CtrlInterface_DeInit(void) +{ + /* Disable the I2C peripheral */ /* This step is not done here because + the I2C interface can be used by other modules */ + /*I2C_DeInit(CODEC_I2C); */ +} + +/** + * @brief Initializes the Audio Codec audio interface (I2S) + * @note This function assumes that the I2S input clock (through PLL_R in + * Devices RevA/Z and through dedicated PLLI2S_R in Devices RevB/Y) + * is already configured and ready to be used. + * @param AudioFreq: Audio frequency to be configured for the I2S peripheral. + * @retval None + */ +static void Codec_AudioInterface_Init(uint32_t AudioFreq) +{ + I2S_InitTypeDef I2S_InitStructure; + + /* Enable the CODEC_I2S peripheral clock */ + RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, ENABLE); + + /* Deinitialize SPI3_I2S3 peripheral */ + SPI_I2S_DeInit(CODEC_I2S); + + /* CODEC_I2S peripheral configuration */ + SPI_I2S_DeInit(CODEC_I2S); + I2S_InitStructure.I2S_AudioFreq = AudioFreq; + I2S_InitStructure.I2S_Standard = I2S_Standard_MSB; + I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; + I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; + I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; +#ifdef CODEC_MCLK_ENABLED + I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; +#elif defined(CODEC_MCLK_DISABLED) + I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; +#else + #error "No selection for the MCLK output has been defined !" +#endif /* CODEC_MCLK_ENABLED */ + + /* Initialize the I2S peripheral with the structure above */ + I2S_Init(CODEC_I2S, &I2S_InitStructure); + + /* The I2S peripheral will be enabled only in the EVAL_AUDIO_Play() function + or by user functions if DMA mode not enabled */ +} + +/** + * @brief Restores the Audio Codec audio interface to its default state. + * @param None + * @retval None + */ +static void Codec_AudioInterface_DeInit(void) +{ + /* Disable the CODEC_I2S peripheral (in case it hasn't already been disabled) */ + I2S_Cmd(CODEC_I2S, DISABLE); + + /* Deinitialize the CODEC_I2S peripheral */ + SPI_I2S_DeInit(CODEC_I2S); + + /* Disable the CODEC_I2S peripheral clock */ + RCC_APB1PeriphClockCmd(CODEC_I2S_CLK, DISABLE); +} + +/** + * @brief Initializes IOs used by the Audio Codec (on the control and audio + * interfaces). + * @param None + * @retval None + */ +static void Codec_GPIO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + I2S_InitTypeDef I2S_InitStructure; + + /* Enable I2S and I2C GPIO clocks */ + RCC_AHBPeriphClockCmd(CODEC_I2C_GPIO_CLOCK | CODEC_I2S_GPIO_CLOCK, ENABLE); + + /* Connect pins to I2C peripheral */ + GPIO_PinAFConfig(CODEC_I2C_SCL_GPIO, CODEC_I2S_SCL_PINSRC, CODEC_I2C_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2C_SDA_GPIO, CODEC_I2S_SDA_PINSRC, CODEC_I2C_GPIO_AF); + + /* CODEC_I2C SCL and SDA pins configuration ----------------------------------*/ + GPIO_InitStructure.GPIO_Pin = CODEC_I2C_SDA_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(CODEC_I2C_SDA_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = CODEC_I2C_SCL_PIN ; + GPIO_Init(CODEC_I2C_SCL_GPIO, &GPIO_InitStructure); + + /* Connect pins to I2S peripheral */ + GPIO_PinAFConfig(CODEC_I2S_MCK_WS_GPIO, CODEC_I2S_WS_PINSRC, CODEC_I2S_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, CODEC_I2S_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_DIN_PINSRC, CODEC_I2S_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_DOUT_PINSRC, CODEC_I2S_GPIO_AF); + + /* CODEC_I2S pins configuration: WS, SCK, DIN and DOUT pins -------------------------*/ + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN | CODEC_I2S_DIN_PIN | CODEC_I2S_DOUT_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN; + GPIO_Init(CODEC_I2S_MCK_WS_GPIO, &GPIO_InitStructure); + + #ifdef CODEC_MCLK_ENABLED + /* CODEC_I2S pins configuration: MCK pin */ + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(CODEC_I2S_MCK_WS_GPIO, &GPIO_InitStructure); + /* Connect pins to I2S peripheral */ + GPIO_PinAFConfig(CODEC_I2S_MCK_WS_GPIO, CODEC_I2S_MCK_PINSRC, CODEC_I2S_MCK_GPIO_AF); + #endif /* CODEC_MCLK_ENABLED */ + + /* SPI3/I2S3 IRQ Channel configuration */ + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); + + NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); + + /* Deinitialize SPI3_I2S3 peripheral */ + SPI_I2S_DeInit(CODEC_I2S); + /* I2S3 configuration ---------------------------------------// + SPI3_I2S3 - configured as follow: + - Work as Master & (transmiter) Rx + - 16bit data + - (Disable) Output MCLK + - Audio sample rate: 11kHz(have to use 8k/24k for CS42L52 ?) + - Default clock polarity: low level */ + I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; + I2S_InitStructure.I2S_Standard = I2S_Standard_MSB; + I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; + I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; + I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_32k; + I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; + I2S_Init(CODEC_I2S, &I2S_InitStructure); + /* Disable the I2S3 TXE Interrupt */ + SPI_I2S_ITConfig(CODEC_I2S, SPI_I2S_IT_TXE, DISABLE); + /* Enable the SPI3/I2S3 peripheral */ + I2S_Cmd(CODEC_I2S, ENABLE); + +} + +/** + * @brief Initializes IOs used by the Audio Codec (on the control and audio + * interfaces). + * @param None + * @retval None + */ +static void Codec_GPIO_Recorder_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + NVIC_InitTypeDef NVIC_InitStructure; + I2S_InitTypeDef I2S_InitStructure; + + /* Enable I2S and I2C GPIO clocks */ + RCC_AHBPeriphClockCmd(CODEC_I2C_GPIO_CLOCK | CODEC_I2S_GPIO_CLOCK, ENABLE); + + /* Connect pins to I2C peripheral */ + GPIO_PinAFConfig(CODEC_I2C_SCL_GPIO, CODEC_I2S_SCL_PINSRC, CODEC_I2C_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2C_SDA_GPIO, CODEC_I2S_SDA_PINSRC, CODEC_I2C_GPIO_AF); + + /* CODEC_I2C SCL and SDA pins configuration ----------------------------------*/ + GPIO_InitStructure.GPIO_Pin = CODEC_I2C_SDA_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(CODEC_I2C_SDA_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = CODEC_I2C_SCL_PIN ; + GPIO_Init(CODEC_I2C_SCL_GPIO, &GPIO_InitStructure); + + /* Connect pins to I2S peripheral */ + GPIO_PinAFConfig(CODEC_I2S_MCK_WS_GPIO, CODEC_I2S_WS_PINSRC, CODEC_I2S_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, CODEC_I2S_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_DIN_PINSRC, CODEC_I2S_GPIO_AF); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_DOUT_PINSRC, CODEC_I2S_GPIO_AF); + + /* CODEC_I2S pins configuration: WS, SCK, DIN and DOUT pins -------------------------*/ + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN | CODEC_I2S_DIN_PIN | CODEC_I2S_DOUT_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN; + GPIO_Init(CODEC_I2S_MCK_WS_GPIO, &GPIO_InitStructure); + + #ifdef CODEC_MCLK_ENABLED + /* CODEC_I2S pins configuration: MCK pin */ + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(CODEC_I2S_MCK_WS_GPIO, &GPIO_InitStructure); + /* Connect pins to I2S peripheral */ + GPIO_PinAFConfig(CODEC_I2S_MCK_WS_GPIO, CODEC_I2S_MCK_PINSRC, CODEC_I2S_MCK_GPIO_AF); + #endif /* CODEC_MCLK_ENABLED */ + + + /* SPI3/I2S3 IRQ Channel configuration */ + NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); + + NVIC_InitStructure.NVIC_IRQChannel = SPI3_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + + RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE); + + /* Deinitialize SPI3_I2S3 peripheral */ + SPI_I2S_DeInit(CODEC_I2S); + /* I2S3 configuration ---------------------------------------// + SPI3_I2S3 - configured as follow: + - Work as Master & (transmiter) Rx + - 16bit data + - (Disable) Output MCLK + - Audio sample rate: 11kHz(have to use 8k/24k for CS42L52) + - Default clock polarity: low level */ + I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; + I2S_InitStructure.I2S_Standard = I2S_Standard_MSB; + I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b; + I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; + I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_8k; + I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; + I2S_Init(CODEC_I2S, &I2S_InitStructure); + /* configure Full Duplex */ + I2S_FullDuplexConfig(I2S3ext, &I2S_InitStructure); + /* Disable the I2S3 TXE Interrupt */ + SPI_I2S_ITConfig(CODEC_I2S, SPI_I2S_IT_TXE, DISABLE); + /* Enable the SPI3/I2S3 peripheral */ + I2S_Cmd(CODEC_I2S, ENABLE); + I2S_Cmd(I2S3ext, ENABLE); +} + +/** + * @brief Restores the IOs used by the Audio Codec interface to their default state. + * @param None + * @retval None + */ +static void Codec_GPIO_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /* Deinitialize all the GPIOs used by the driver (EXCEPT the I2C IOs since + they are used by the IOExpander as well) */ + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN | CODEC_I2S_DIN_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN; + GPIO_Init(CODEC_I2S_MCK_WS_GPIO, &GPIO_InitStructure); + +#ifdef CODEC_MCLK_ENABLED + /* CODEC_I2S pins deinitialization: MCK pin */ + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; + GPIO_Init(CODEC_I2S_MCK_WS_GPIO, &GPIO_InitStructure); + /* Disconnect pins from I2S peripheral */ + GPIO_PinAFConfig(CODEC_I2S_MCK_WS_GPIO, CODEC_I2S_MCK_PINSRC, 0x00); +#endif /* CODEC_MCLK_ENABLED */ + + GPIO_InitStructure.GPIO_Pin = CODEC_I2S_DOUT_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure); + + /* Disconnect pins from I2S peripheral */ + GPIO_PinAFConfig(CODEC_I2S_MCK_WS_GPIO, CODEC_I2S_WS_PINSRC, 0x00); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, 0x00); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_DIN_PINSRC, 0x00); + GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_DOUT_PINSRC, 0x00); +} + +/** + * @brief Inserts a delay time (not accurate timing). + * @param nCount: specifies the delay time length. + * @retval None + */ +void Delay( __IO uint32_t nCount) +{ + for (; nCount != 0; nCount--); +} + +#ifdef USE_DEFAULT_TIMEOUT_CALLBACK +/** + * @brief Basic management of the timeout situation. + * @param None + * @retval None + */ +uint32_t Codec_TIMEOUT_UserCallback(void) +{ + /* The following code allows I2C error recovery and return to normal communication + if the error source doesn’t still exist (ie. hardware issue..) */ + I2C_InitTypeDef I2C_InitStructure; + + + /* LCD_ErrLog("> I2C Timeout error occurred\n"); */ + I2C_GenerateSTOP(CODEC_I2C, ENABLE); + /* Generated a Software reset */ + I2C_SoftwareResetCmd(CODEC_I2C); + + /* CODEC_I2C configuration */ + I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; + I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; + I2C_InitStructure.I2C_DigitalFilter = 0x00; + I2C_InitStructure.I2C_OwnAddress1 = 0x00; + I2C_InitStructure.I2C_Ack = I2C_Ack_Disable; + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_InitStructure.I2C_Timing = CODEC_I2C_TIMING; + + /* Enable the I2C peripheral */ + I2C_Init(CODEC_I2C, &I2C_InitStructure); + I2C_Cmd(CODEC_I2C, ENABLE); + + /* At this stage the I2C error should be recovered and device can communicate + again (except if the error source still exist). + User can implement mechanism (ex. test on max trial number) to manage situation + when the I2C can't recover from current error. */ + + /* LCD_UsrLog("> I2C error recovered.\n"); */ + + return 0; +} +#endif /* USE_DEFAULT_TIMEOUT_CALLBACK */ + +/*============================================================================ + Audio MAL Interface Control Functions + ============================================================================*/ + +/** + * @brief Initializes and prepares the Media to perform audio data transfer + * from Media to the I2S peripheral. + * @param None + * @retval None + */ +static void Audio_MAL_Init(void) +{ +#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN) + NVIC_InitTypeDef NVIC_InitStructure; +#endif + + /* Enable the DMA clock */ + RCC_AHBPeriphClockCmd(AUDIO_MAL_DMA_CLOCK, ENABLE); + + /* Configure the DMA Channel */ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL, DISABLE); + DMA_DeInit(AUDIO_MAL_DMA_CHANNEL); + /* Set the parameters to be configured */ + + DMA_InitStructure.DMA_PeripheralBaseAddr = CODEC_I2S_ADDRESS; + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)0; /* This field will be configured in play function */ + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE; /* This field will be configured in play function */ + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = AUDIO_MAL_DMA_PERIPH_DATA_SIZE; + DMA_InitStructure.DMA_MemoryDataSize = AUDIO_MAL_DMA_MEM_DATA_SIZE; +#ifdef AUDIO_MAL_MODE_NORMAL + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; +#elif defined(AUDIO_MAL_MODE_CIRCULAR) + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; +#else + #error "AUDIO_MAL_MODE_NORMAL or AUDIO_MAL_MODE_CIRCULAR should be selected !!" +#endif /* AUDIO_MAL_MODE_NORMAL */ + DMA_Init(AUDIO_MAL_DMA_CHANNEL, &DMA_InitStructure); + + /* Enable the selected DMA interrupts (selected in "stm32_eval_audio_codec.h" defines) */ +#ifdef AUDIO_MAL_DMA_IT_TC_EN + DMA_ITConfig(AUDIO_MAL_DMA_CHANNEL, DMA_IT_TC, ENABLE); +#endif /* AUDIO_MAL_DMA_IT_TC_EN */ +#ifdef AUDIO_MAL_DMA_IT_HT_EN + DMA_ITConfig(AUDIO_MAL_DMA_CHANNEL, DMA_IT_HT, ENABLE); +#endif /* AUDIO_MAL_DMA_IT_HT_EN */ +#ifdef AUDIO_MAL_DMA_IT_TE_EN + DMA_ITConfig(AUDIO_MAL_DMA_CHANNEL, DMA_IT_TE | DMA_IT_FE | DMA_IT_DME, ENABLE); +#endif /* AUDIO_MAL_DMA_IT_TE_EN */ + + /* Enable the I2S DMA request */ + SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, ENABLE); + +#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN) + /* I2S DMA IRQ Channel configuration */ + NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); +#endif +} + +/** + * @brief Restore default state of the used Media. + * @param None + * @retval None + */ +static void Audio_MAL_DeInit(void) +{ +#if defined(AUDIO_MAL_DMA_IT_TC_EN) || defined(AUDIO_MAL_DMA_IT_HT_EN) || defined(AUDIO_MAL_DMA_IT_TE_EN) + NVIC_InitTypeDef NVIC_InitStructure; + + /* Deinitialize the NVIC interrupt for the I2S DMA Channel */ + NVIC_InitStructure.NVIC_IRQChannel = AUDIO_MAL_DMA_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EVAL_AUDIO_IRQ_PREPRIO; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = EVAL_AUDIO_IRQ_SUBRIO; + NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&NVIC_InitStructure); +#endif + + /* Disable the DMA before the deinit */ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL, DISABLE); + + /* Dinitialize the DMA Channel */ + DMA_DeInit(AUDIO_MAL_DMA_CHANNEL); + + /* The DMA clock is not disabled */ +} + +/** + * @brief Starts playing audio stream from the audio Media. + * @param None + * @retval None + */ +void Audio_MAL_Play(uint32_t Addr, uint32_t Size) +{ + /* Configure the buffer address and size */ + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Addr; + DMA_InitStructure.DMA_BufferSize = (uint32_t)Size/2; + + /* Configure the DMA Channel with the new parameters */ + DMA_Init(AUDIO_MAL_DMA_CHANNEL, &DMA_InitStructure); + + /* Enable the I2S DMA Channel */ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL, ENABLE); +} + +/** + * @brief Pauses or Resumes the audio stream playing from the Media. + * @param Cmd: AUDIO_PAUSE (or 0) to pause, AUDIO_RESUME (or any value different + * from 0) to resume. + * @param Addr: Address from/at which the audio stream should resume/pause. + * @retval None + */ +static void Audio_MAL_PauseResume(uint32_t Cmd, uint32_t Addr) +{ + /* Pause the audio file playing */ + if (Cmd == AUDIO_PAUSE) + { + /* Disable the I2S DMA request */ + SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, DISABLE); + + /* Pause the I2S DMA Channel + Note. For the STM32F30x devices, the DMA implements a pause feature, + by disabling the channel, all configuration is preserved and data + transfer is paused till the next enable of the channel.*/ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL, DISABLE); + } + else /* AUDIO_RESUME */ + { + /* Enable the I2S DMA request */ + SPI_I2S_DMACmd(CODEC_I2S, SPI_I2S_DMAReq_Tx, ENABLE); + + /* Resume the I2S DMA Channel + Note. For the STM32F30x devices, the DMA implements a pause feature, + by disabling the channel, all configuration is preserved and data + transfer is paused till the next enable of the channel.*/ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL, ENABLE); + + /* If the I2S peripheral is still not enabled, enable it */ + if ((CODEC_I2S->I2SCFGR & I2S_ENABLE_MASK) == 0) + { + I2S_Cmd(CODEC_I2S, ENABLE); + } + } +} + +/** + * @brief Stops audio stream playing on the used Media. + * @param None + * @retval None + */ +static void Audio_MAL_Stop(void) +{ + /* Stop the Transfer on the I2S side: Stop and disable the DMA channel */ + DMA_Cmd(AUDIO_MAL_DMA_CHANNEL, DISABLE); + + /* Clear all the DMA flags for the next transfer */ + DMA_ClearFlag(AUDIO_MAL_DMA_FLAG_TC|AUDIO_MAL_DMA_FLAG_HT|AUDIO_MAL_DMA_FLAG_TE); + + /* The I2S DMA requests are not disabled here. */ + + /* In all modes, disable the I2S peripheral */ + I2S_Cmd(CODEC_I2S, DISABLE); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.h new file mode 100644 index 0000000..0e0f44c --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.h @@ -0,0 +1,302 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_audio_codec.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains all the functions prototypes for the + * stm32303c_eval_audio_codec.c driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_AUDIOCODEC_H +#define __STM32303C_EVAL_AUDIOCODEC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f30x.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_AUDIO_CODEC + * @{ + */ + + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Exported_Constants + * @{ + */ + +/*---------------------------------------------------------------------------- + CONFIGURATION: Audio Codec Driver Configuration parameters + ----------------------------------------------------------------------------*/ +/* Audio Transfer mode (DMA, Interrupt or Polling) */ +#define AUDIO_MAL_MODE_NORMAL /* Uncomment this line to enable the audio + Transfer using DMA */ +/* #define AUDIO_MAL_MODE_CIRCULAR */ /* Uncomment this line to enable the audio + Transfer using DMA */ + +/* For the DMA modes select the interrupt that will be used */ +#define AUDIO_MAL_DMA_IT_TC_EN /* Uncomment this line to enable DMA Transfer Complete interrupt */ +/* #define AUDIO_MAL_DMA_IT_HT_EN */ /* Uncomment this line to enable DMA Half Transfer Complete interrupt */ +/* #define AUDIO_MAL_DMA_IT_TE_EN */ /* Uncomment this line to enable DMA Transfer Error interrupt */ + +/* Select the interrupt preemption priority and subpriority for the DMA interrupt */ +#define EVAL_AUDIO_IRQ_PREPRIO 0 /* Select the preemption priority level(0 is the highest) */ +#define EVAL_AUDIO_IRQ_SUBRIO 0 /* Select the sub-priority level (0 is the highest) */ + +/* Uncomment the following line to use the default Codec_TIMEOUT_UserCallback() + function implemented in stm32303c_eval_audio_codec.c file. + Codec_TIMEOUT_UserCallback() function is called whenever a timeout condition + occurs during communication (waiting on an event that doesn't occur, bus + errors, busy devices ...). */ +/* #define USE_DEFAULT_TIMEOUT_CALLBACK */ +/*----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + OPTIONAL Configuration defines parameters + ----------------------------------------------------------------------------*/ +/* I2C clock speed configuration (in Hz) + WARNING: + Make sure that this define is not already declared in other files (ie. + stm32303c_eval.h file). It can be used in parallel by other modules. */ + +/* I2C TIMING Register define when I2C clock source is SYSCLK */ +/* set TIMING to 0xC062121F to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */ + +#define CODEC_I2C_TIMING 0xC062121F + +/* Uncomment defines below to select standard for audio communication between + Codec and I2S peripheral */ +#define I2S_STANDARD_PHILLIPS +/* #define I2S_STANDARD_MSB */ +/* #define I2S_STANDARD_LSB */ + +/* Uncomment the defines below to select if the Master clock mode should be + enabled or not */ +#define CODEC_MCLK_ENABLED +/* #define CODEC_MCLK_DISABLED */ + +/* Uncomment this line to enable verifying data sent to codec after each write + operation */ +#define VERIFY_WRITTENDATA +/*----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Hardware Configuration defines parameters + ----------------------------------------------------------------------------*/ +/* Audio Reset Pin definition */ +#define AUDIO_RESET_GPIO_CLK RCC_AHBPeriph_GPIOD +#define AUDIO_RESET_PIN GPIO_Pin_11 +#define AUDIO_RESET_GPIO GPIOD + +/* I2S peripheral configuration defines */ +#define CODEC_I2S SPI3 +#define CODEC_I2S_CLK RCC_APB1Periph_SPI3 +#define CODEC_I2S_ADDRESS 0x40003C0C +#define CODEC_I2S_GPIO_AF GPIO_AF_6 +#define CODEC_I2S_MCK_GPIO_AF GPIO_AF_5 +#define CODEC_I2S_IRQ SPI3_IRQn +#define CODEC_I2S_GPIO_CLOCK (RCC_AHBPeriph_GPIOA)|(RCC_AHBPeriph_GPIOC) +#define CODEC_I2S_WS_PIN GPIO_Pin_4 +#define CODEC_I2S_SCK_PIN GPIO_Pin_10 +#define CODEC_I2S_DOUT_PIN GPIO_Pin_11 +#define CODEC_I2S_DIN_PIN GPIO_Pin_12 +#define CODEC_I2S_MCK_PIN GPIO_Pin_9 +#define CODEC_I2S_WS_PINSRC GPIO_PinSource4 +#define CODEC_I2S_SCK_PINSRC GPIO_PinSource10 +#define CODEC_I2S_DOUT_PINSRC GPIO_PinSource11 +#define CODEC_I2S_DIN_PINSRC GPIO_PinSource12 +#define CODEC_I2S_MCK_PINSRC GPIO_PinSource9 +#define CODEC_I2S_GPIO GPIOC +#define CODEC_I2S_MCK_WS_GPIO GPIOA +#define Audio_I2S_IRQHandler SPI3_IRQHandler + + /* I2S DMA Channel definitions */ +#define AUDIO_MAL_DMA_CLOCK RCC_AHBPeriph_DMA2 +#define AUDIO_MAL_DMA_CHANNEL DMA2_Channel2 +#define AUDIO_MAL_DMA_IRQ DMA2_Channel2_IRQn +#define AUDIO_MAL_DMA_FLAG_TC DMA2_FLAG_TC2 +#define AUDIO_MAL_DMA_FLAG_HT DMA2_FLAG_HT2 +#define AUDIO_MAL_DMA_FLAG_TE DMA2_FLAG_TE2 + +#define Audio_MAL_IRQHandler DMA2_Channel2_IRQHandler +#define AUDIO_MAL_DMA_PERIPH_DATA_SIZE DMA_PeripheralDataSize_HalfWord +#define AUDIO_MAL_DMA_MEM_DATA_SIZE DMA_MemoryDataSize_HalfWord +#define DMA_MAX_SZE 0xFFFF + +/* I2C peripheral configuration defines (control interface of the audio codec) */ +#define CODEC_I2C I2C2 +#define CODEC_I2C_CLK RCC_APB1Periph_I2C2 +#define CODEC_I2C_GPIO_CLOCK (RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOF) +#define CODEC_I2C_GPIO_AF GPIO_AF_4 +#define CODEC_I2C_SCL_GPIO GPIOF +#define CODEC_I2C_SDA_GPIO GPIOA +#define CODEC_I2C_SCL_PIN GPIO_Pin_6 +#define CODEC_I2C_SDA_PIN GPIO_Pin_10 +#define CODEC_I2S_SCL_PINSRC GPIO_PinSource6 +#define CODEC_I2S_SDA_PINSRC GPIO_PinSource10 + +/* Maximum Timeout values for flags and events waiting loops. These timeouts are + not based on accurate values, they just guarantee that the application will + not remain stuck if the I2C communication is corrupted. + You may modify these timeout values depending on CPU frequency and application + conditions (interrupts routines ...). */ +#define CODEC_FLAG_TIMEOUT ((uint32_t)0x1000) +#define CODEC_LONG_TIMEOUT ((uint32_t)(300 * CODEC_FLAG_TIMEOUT)) +/*----------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------- + Audio Codec User defines + ----------------------------------------------------------------------------*/ +/* Codec output DEVICE */ +#define OUTPUT_DEVICE_SPEAKER 1 +#define OUTPUT_DEVICE_HEADPHONE 2 +#define OUTPUT_DEVICE_BOTH 3 +#define OUTPUT_DEVICE_AUTO 4 + +/* Volume Levels values */ +#define DEFAULT_VOLMIN 0x00 +#define DEFAULT_VOLMAX 0xFF +#define DEFAULT_VOLSTEP 0x04 + +#define AUDIO_PAUSE 0 +#define AUDIO_RESUME 1 + +/* Codec POWER DOWN modes */ +#define CODEC_PDWN_HW 1 +#define CODEC_PDWN_SW 2 + +/* MUTE commands */ +#define AUDIO_MUTE_ON 1 +#define AUDIO_MUTE_OFF 0 +/*----------------------------------------------------------------------------*/ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Exported_Macros + * @{ + */ +#define VOLUME_CONVERT(x) ((Volume > 100)? 100:((uint8_t)((Volume * 255) / 100))) +#define DMA_MAX(x) (((x) <= DMA_MAX_SZE)? (x):DMA_MAX_SZE) + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_AUDIO_CODEC_Exported_Functions + * @{ + */ +uint32_t EVAL_AUDIO_Init(uint16_t OutputDevice, uint8_t Volume, uint32_t AudioFreq); +uint32_t EVAL_AUDIO_DeInit(void); +uint32_t EVAL_AUDIO_Play(uint16_t* pBuffer, uint32_t Size); +uint32_t EVAL_AUDIO_PauseResume(uint32_t Cmd); +uint32_t EVAL_AUDIO_Stop(uint32_t CodecPowerDown_Mode); +uint32_t EVAL_AUDIO_VolumeCtl(uint8_t Volume); +uint32_t EVAL_AUDIO_Mute(uint32_t Command); + +uint32_t Codec_SwitchOutput(uint8_t Output); +uint32_t Codec_Record_Init(void); +uint32_t Codec_ReadRegister(uint8_t RegisterAddr); + +uint32_t Codec_WriteRegister(uint8_t RegisterAddr, uint8_t RegisterValue); + + + +/* User Callbacks: user has to implement these functions in his code if + they are needed. -----------------------------------------------------------*/ + +/* This function is called when the requested data has been completely transferred. + In Normal mode (when the define AUDIO_MAL_MODE_NORMAL is enabled) this function + is called at the end of the whole audio file. + In circular mode (when the define AUDIO_MAL_MODE_CIRCULAR is enabled) this + function is called at the end of the current buffer transmission. */ +void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size); + +/* This function is called when half of the requested buffer has been transferred + This callback is useful in Circular mode only (when AUDIO_MAL_MODE_CIRCULAR + define is enabled)*/ +void EVAL_AUDIO_HalfTransfer_CallBack(uint32_t pBuffer, uint32_t Size); + +/* This function is called when an Interrupt due to transfer error on or peripheral + error occurs. */ +void EVAL_AUDIO_Error_CallBack(void* pData); + +/* Codec_TIMEOUT_UserCallback() function is called whenever a timeout condition + occurs during communication (waiting on an event that doesn't occur, bus + errors, busy devices ...) on the Codec control interface (I2C). + You can use the default timeout callback implementation by uncommenting the + define USE_DEFAULT_TIMEOUT_CALLBACK in stm32303c_eval_audio_codec.h file. + Typically the user implementation of this callback should reset I2C peripheral + and re-initialize communication or in worst case reset all the application. */ +uint32_t Codec_TIMEOUT_UserCallback(void); +void Audio_MAL_IRQHandler(void); +void Audio_MAL_Play(uint32_t Addr, uint32_t Size); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_AUDIOCODEC_H */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************* (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.c new file mode 100644 index 0000000..fe89465 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.c @@ -0,0 +1,717 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_i2c_ee.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file provides a set of functions needed to manage an I2C M24LR64 + * and M24M01 EEPROM memory. + * + * It implements a high level communication layer for read and write + * from/to this memory. The needed STM32F30x hardware resources (I2C and + * GPIO) are defined in stm32303c_eval.h file, and the initialization is + * performed in sEE_LowLevel_Init() function declared in stm32303c_eval.c + * file. + * You can easily tailor this driver to any other development board, + * by just adapting the defines for hardware resources and + * sEE_LowLevel_Init() function. + * + * @note In this driver, basic read and write functions (sEE_ReadBuffer() + * and sEE_WritePage()) use Polling mode to perform the data transfer + * to/from EEPROM memory. + * + * +-----------------------------------------------------------------+ + * | Pin assignment for M24M01 EEPROM | + * +---------------------------------------+-----------+-------------+ + * | STM32F30x I2C Pins | sEE | Pin | + * +---------------------------------------+-----------+-------------+ + * | . | NC | 1 | + * | . | E1(VDD) | 2 (3.3V) | + * | . | E2(GND) | 3 (0V) | + * | . | VSS | 4 (0V) | + * | sEE_I2C_SDA_PIN/ SDA | SDA | 5 | + * | sEE_I2C_SCL_PIN/ SCL | SCL | 6 | + * | . | /WC(VSS)| 7 (0V) | + * | . | VDD | 8 (3.3V) | + * +---------------------------------------+-----------+-------------+ + * +-----------------------------------------------------------------+ + * | Pin assignment for M24LR64 EEPROM | + * +---------------------------------------+-----------+-------------+ + * | STM32F30x I2C Pins | sEE | Pin | + * +---------------------------------------+-----------+-------------+ + * | . | E0(GND) | 1 (0V) | + * | . | AC0 | 2 | + * | . | AC1 | 3 | + * | . | VSS | 4 (0V) | + * | sEE_I2C_SDA_PIN/ SDA | SDA | 5 | + * | sEE_I2C_SCL_PIN/ SCL | SCL | 6 | + * | . | E1(GND) | 7 (0V) | + * | . | VDD | 8 (3.3V) | + * +---------------------------------------+-----------+-------------+ * + * + * * * + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval_i2c_ee.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_I2C_EE + * @brief This file includes the I2C EEPROM driver of STM32303C-EVAL board. + * @{ + */ + +/** @defgroup STM32303C_EVAL_I2C_EE_Private_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_I2C_EE_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_I2C_EE_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_I2C_EE_Private_Variables + * @{ + */ +__IO uint16_t sEEAddress = 0; +__IO uint32_t sEETimeout = sEE_LONG_TIMEOUT; +__IO uint16_t sEEDataNum; +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_I2C_EE_Private_Function_Prototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_I2C_EE_Private_Functions + * @{ + */ + +/** + * @brief DeInitializes peripherals used by the I2C EEPROM driver. + * @param None + * @retval None + */ +void sEE_DeInit(void) +{ + sEE_I2C_LowLevel_DeInit(); +} + +/** + * @brief Initializes peripherals used by the I2C EEPROM driver. + * @param None + * @retval None + */ +void sEE_Init(void) +{ + I2C_InitTypeDef I2C_InitStructure; + + sEE_I2C_LowLevel_Init(); + + /*!< I2C configuration */ + /* sEE_I2C configuration */ + I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; + I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; + I2C_InitStructure.I2C_DigitalFilter = 0x00; + I2C_InitStructure.I2C_OwnAddress1 = 0x00; + I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_InitStructure.I2C_Timing = sEE_I2C_TIMING; + + /* Apply sEE_I2C configuration after enabling it */ + I2C_Init(sEE_I2C, &I2C_InitStructure); + + /* sEE_I2C Peripheral Enable */ + I2C_Cmd(sEE_I2C, ENABLE); + + /*!< Select the EEPROM address */ + sEEAddress = sEE_HW_ADDRESS; +} + +/** + * @brief Reads a block of data from the EEPROM. + * @param pBuffer : pointer to the buffer that receives the data read from + * the EEPROM. + * @param ReadAddr : EEPROM's internal address to start reading from. + * @param NumByteToRead : pointer to the variable holding number of bytes to + * be read from the EEPROM. + * + * @retval sEE_OK (0) if operation is correctly performed, else return value + * different from sEE_OK (0) or the timeout user callback. + */ +uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead) +{ + uint32_t NumbOfSingle = 0, Count = 0, DataNum = 0, StartCom = 0; + + /* Get number of reload cycles */ + Count = (*NumByteToRead) / 255; + NumbOfSingle = (*NumByteToRead) % 255; + +#ifdef sEE_M24C08 + + /* Configure slave address, nbytes, reload and generate start */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Send memory address */ + I2C_SendData(sEE_I2C, (uint8_t)ReadAddr); + +#elif defined(sEE_M24M01) || defined(sEE_M24C64_32) || defined (sEE_M24LR64) + + /* Configure slave address, nbytes, reload and generate start */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 2, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Send MSB of memory address */ + I2C_SendData(sEE_I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8)); + + /* Wait until TXIS flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Send LSB of memory address */ + I2C_SendData(sEE_I2C, (uint8_t)(ReadAddr & 0x00FF)); + +#endif /*!< sEE_M24C08 */ + + /* Wait until TC flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TC) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* If number of Reload cycles is not equal to 0 */ + if (Count != 0) + { + /* Starting communication */ + StartCom = 1; + + /* Wait until all reload cycles are performed */ + while( Count != 0) + { + /* If a read transfer is performed */ + if (StartCom == 0) + { + /* Wait until TCR flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + } + + /* if remains one read cycle */ + if ((Count == 1) && (NumbOfSingle == 0)) + { + /* if starting communication */ + if (StartCom != 0) + { + /* Configure slave address, end mode and start condition */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + } + else + { + /* Configure slave address, end mode */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_AutoEnd_Mode, I2C_No_StartStop); + } + } + else + { + /* if starting communication */ + if (StartCom != 0) + { + /* Configure slave address, end mode and start condition */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_Reload_Mode, I2C_Generate_Start_Read); + } + else + { + /* Configure slave address, end mode */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_Reload_Mode, I2C_No_StartStop); + } + } + + /* Update local variable */ + StartCom = 0; + DataNum = 0; + + /* Wait until all data are received */ + while (DataNum != 255) + { + /* Wait until RXNE flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Read data from RXDR */ + pBuffer[DataNum]= I2C_ReceiveData(sEE_I2C); + + /* Update number of received data */ + DataNum++; + (*NumByteToRead)--; + } + /* Update Pointer of received buffer */ + pBuffer += DataNum; + + /* update number of reload cycle */ + Count--; + } + + /* If number of single data is not equal to 0 */ + if (NumbOfSingle != 0) + { + /* Wait until TCR flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Update CR2 : set Nbytes and end mode */ + I2C_TransferHandling(sEE_I2C, sEEAddress, (uint8_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_No_StartStop); + + /* Reset local variable */ + DataNum = 0; + + /* Wait until all data are received */ + while (DataNum != NumbOfSingle) + { + /* Wait until RXNE flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Read data from RXDR */ + pBuffer[DataNum]= I2C_ReceiveData(sEE_I2C); + + /* Update number of received data */ + DataNum++; + (*NumByteToRead)--; + } + } + } + else + { + /* Update CR2 : set Slave Address , set read request, generate Start and set end mode */ + I2C_TransferHandling(sEE_I2C, sEEAddress, (uint32_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + + /* Reset local variable */ + DataNum = 0; + + /* Wait until all data are received */ + while (DataNum != NumbOfSingle) + { + /* Wait until RXNE flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Read data from RXDR */ + pBuffer[DataNum]= I2C_ReceiveData(sEE_I2C); + + /* Update number of received data */ + DataNum++; + (*NumByteToRead)--; + } + } + + /* Wait until STOPF flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF); + + /* If all operations OK, return sEE_OK (0) */ + return sEE_OK; +} + +/** + * @brief Writes more than one byte to the EEPROM with a single WRITE cycle. + * + * @note The number of bytes (combined to write start address) must not + * cross the EEPROM page boundary. This function can only write into + * the boundaries of an EEPROM page. + * This function doesn't check on boundaries condition (in this driver + * the function sEE_WriteBuffer() which calls sEE_WritePage() is + * responsible of checking on Page boundaries). + * + * @param pBuffer : pointer to the buffer containing the data to be written to + * the EEPROM. + * @param WriteAddr : EEPROM's internal address to write to. + * @param NumByteToWrite : pointer to the variable holding number of bytes to + * be written into the EEPROM. + * + * @retval sEE_OK (0) if operation is correctly performed, else return value + * different from sEE_OK (0) or the timeout user callback. + */ +uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite) +{ + uint32_t DataNum = 0; + +#ifdef sEE_M24C08 + + /* Configure slave address, nbytes, reload and generate start */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Send memory address */ + I2C_SendData(sEE_I2C, (uint8_t)WriteAddr); + +#elif defined(sEE_M24M01) || defined(sEE_M24C64_32) || defined (sEE_M24LR64) + + /* Configure slave address, nbytes, reload and generate start */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 2, I2C_Reload_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Send MSB of memory address */ + I2C_SendData(sEE_I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8)); + + /* Wait until TXIS flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Send LSB of memory address */ + I2C_SendData(sEE_I2C, (uint8_t)(WriteAddr & 0x00FF)); + +#endif /*!< sEE_M24C08 */ + + /* Wait until TCR flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Update CR2 : set Slave Address , set write request, generate Start and set end mode */ + I2C_TransferHandling(sEE_I2C, sEEAddress, (uint8_t)(*NumByteToWrite), I2C_AutoEnd_Mode, I2C_No_StartStop); + + while (DataNum != (*NumByteToWrite)) + { + /* Wait until TXIS flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Write data to TXDR */ + I2C_SendData(sEE_I2C, (uint8_t)(pBuffer[DataNum])); + + /* Update number of transmitted data */ + DataNum++; + } + + /* Wait until STOPF flag is set */ + sEETimeout = sEE_LONG_TIMEOUT; + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET) + { + if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF); + + /* If all operations OK, return sEE_OK (0) */ + return sEE_OK; +} + +/** + * @brief Writes buffer of data to the I2C EEPROM. + * @param pBuffer : pointer to the buffer containing the data to be written + * to the EEPROM. + * @param WriteAddr : EEPROM's internal address to write to. + * @param NumByteToWrite : number of bytes to write to the EEPROM. + * @retval None + */ +void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite) +{ + uint16_t NumOfPage = 0, NumOfSingle = 0, count = 0; + uint16_t Addr = 0; + + Addr = WriteAddr % sEE_PAGESIZE; + count = sEE_PAGESIZE - Addr; + NumOfPage = NumByteToWrite / sEE_PAGESIZE; + NumOfSingle = NumByteToWrite % sEE_PAGESIZE; + + /*!< If WriteAddr is sEE_PAGESIZE aligned */ + if(Addr == 0) + { + /*!< If NumByteToWrite < sEE_PAGESIZE */ + if(NumOfPage == 0) + { + /* Store the number of data to be written */ + sEEDataNum = NumOfSingle; + /* Start writing data */ + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + } + /*!< If NumByteToWrite > sEE_PAGESIZE */ + else + { + while(NumOfPage--) + { + /* Store the number of data to be written */ + sEEDataNum = sEE_PAGESIZE; + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + WriteAddr += sEE_PAGESIZE; + pBuffer += sEE_PAGESIZE; + } + + if(NumOfSingle!=0) + { + /* Store the number of data to be written */ + sEEDataNum = NumOfSingle; + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + } + } + } + /*!< If WriteAddr is not sEE_PAGESIZE aligned */ + else + { + /*!< If NumByteToWrite < sEE_PAGESIZE */ + if(NumOfPage== 0) + { + /*!< If the number of data to be written is more than the remaining space + in the current page: */ + if (NumByteToWrite > count) + { + /* Store the number of data to be written */ + sEEDataNum = count; + /*!< Write the data contained in same page */ + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + + /* Store the number of data to be written */ + sEEDataNum = (NumByteToWrite - count); + /*!< Write the remaining data in the following page */ + sEE_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + } + else + { + /* Store the number of data to be written */ + sEEDataNum = NumOfSingle; + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + } + } + /*!< If NumByteToWrite > sEE_PAGESIZE */ + else + { + NumByteToWrite -= count; + NumOfPage = NumByteToWrite / sEE_PAGESIZE; + NumOfSingle = NumByteToWrite % sEE_PAGESIZE; + + if(count != 0) + { + /* Store the number of data to be written */ + sEEDataNum = count; + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + WriteAddr += count; + pBuffer += count; + } + + while(NumOfPage--) + { + /* Store the number of data to be written */ + sEEDataNum = sEE_PAGESIZE; + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEETimeout = sEE_LONG_TIMEOUT; + sEE_WaitEepromStandbyState(); + WriteAddr += sEE_PAGESIZE; + pBuffer += sEE_PAGESIZE; + } + if(NumOfSingle != 0) + { + /* Store the number of data to be written */ + sEEDataNum = NumOfSingle; + sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum)); + sEE_WaitEepromStandbyState(); + } + } + } +} + +/** + * @brief Wait for EEPROM Standby state. + * + * @note This function allows to wait and check that EEPROM has finished the + * last operation. It is mostly used after Write operation: after receiving + * the buffer to be written, the EEPROM may need additional time to actually + * perform the write operation. During this time, it doesn't answer to + * I2C packets addressed to it. Once the write operation is complete + * the EEPROM responds to its address. + * + * @param None + * + * @retval sEE_OK (0) if operation is correctly performed, else return value + * different from sEE_OK (0) or the timeout user callback. + */ +uint32_t sEE_WaitEepromStandbyState(void) +{ + __IO uint32_t sEETrials = 0; + + /* Keep looping till the slave acknowledge his address or maximum number + of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define + in stm32303c_eval_i2c_ee.h file) */ + + /* Configure CR2 register : set Slave Address and end mode */ + I2C_TransferHandling(sEE_I2C, sEEAddress, 0, I2C_AutoEnd_Mode, I2C_No_StartStop); + + do + { + /* Initialize sEETimeout */ + sEETimeout = sEE_FLAG_TIMEOUT; + + /* Clear NACKF */ + I2C_ClearFlag(sEE_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF); + + /* Generate start */ + I2C_GenerateSTART(sEE_I2C, ENABLE); + + /* Wait until timeout elapsed */ + while (sEETimeout-- != 0); + + /* Check if the maximum allowed numbe of trials has bee reached */ + if (sEETrials++ == sEE_MAX_TRIALS_NUMBER) + { + /* If the maximum number of trials has been reached, exit the function */ + return sEE_TIMEOUT_UserCallback(); + } + } + while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_NACKF) != RESET); + + /* Clear STOPF */ + I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF); + + /* Return sEE_OK if device is ready */ + return sEE_OK; +} + +#ifdef USE_DEFAULT_TIMEOUT_CALLBACK +/** + * @brief Basic management of the timeout situation. + * @param None. + * @retval None. + */ +uint32_t sEE_TIMEOUT_UserCallback(void) +{ + return 0; +} +#endif /* USE_DEFAULT_TIMEOUT_CALLBACK */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.h new file mode 100644 index 0000000..00a799a --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.h @@ -0,0 +1,206 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_i2c_ee.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains all the functions prototypes for + * the stm32303c_eval_i2c_ee.c firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_I2C_EE_H +#define __STM32303C_EVAL_I2C_EE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_I2C_EE + * @{ + */ + +/** @defgroup STM32303C_EVAL_I2C_EE_Exported_Types + * @{ + */ + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_EE_Exported_Constants + * @{ + */ + +/* Select which EEPROM will be used with this driver */ +#define sEE_M24LR64 +/* #define sEE_M24M01 */ + +/* Uncomment the following line to use the default sEE_TIMEOUT_UserCallback() + function implemented in stm32303c_eval_i2c_ee.c file. + sEE_TIMEOUT_UserCallback() function is called whenever a timeout condition + occure during communication (waiting on an event that doesn't occur, bus + errors, busy devices ...). */ +/* #define USE_DEFAULT_TIMEOUT_CALLBACK */ + +#if !defined (sEE_M24C08) && !defined (sEE_M24C64_32) && !defined (sEE_M24LR64) && !defined (sEE_M24M01) +/* Use the defines below the choose the EEPROM type */ +#define sEE_M24M01 /* Support the device: M24M01. */ +/* #define sEE_M24C08*/ /* Support the device: M24C08. */ +/* note: Could support: M24C01, M24C02, M24C04 and M24C16 if the blocks and + HW address are correctly defined*/ +/*#define sEE_M24C64_32*/ /* Support the devices: M24C32 and M24C64 */ +/*#define sEE_M24LR64*/ /*Support the devices: M24LR64 */ +#endif + +#ifdef sEE_M24C64_32 +/* For M24C32 and M24C64 devices, E0,E1 and E2 pins are all used for device + address selection (ne need for additional address lines). According to the + Harware connection on the board. */ + + #define sEE_HW_ADDRESS 0xA0 /* E0 = E1 = E2 = 0 */ + +#elif defined (sEE_M24C08) +/* The M24C08W contains 4 blocks (128byte each) with the adresses below: E2 = 0 + EEPROM Addresses defines */ + #define sEE_HW_ADDRESS 0xA0 /* E2 = 0 */ + /*#define sEE_HW_ADDRESS 0xA2*/ /* E2 = 0 */ + /*#define sEE_HW_ADDRESS 0xA4*/ /* E2 = 0 */ + /*#define sEE_HW_ADDRESS 0xA6*/ /* E2 = 0 */ + +#elif defined (sEE_M24LR64) + #define sEE_HW_ADDRESS 0xA0 + +#elif defined (sEE_M24M01) +/* The sEE_M24M01 contains 2 blocks (64Kbytes each) with the adresses below + EEPROM Addresses defines */ + #define sEE_HW_ADDRESS 0xA4 /* Block 1 : E1= 1; E2 = 0; A16 = 0 */ + /*#define sEE_HW_ADDRESS 0xA6*/ /* Block 2 : E1= 1; E2 = 0; A16 = 1 */ + +#endif /* sEE_M24C64_32 */ + +/* I2C TIMING Register define when I2C clock source is SYSCLK */ +/* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 72 MHz */ +/* When using sEE_M24M01 set TIMING to 0x00C4092A to reach 1 MHz speed (Rise time = 26ns, Fall time = 2ns) */ +/* When using sEE_M24LR64 set TIMING to 0xC062121F to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */ + +#define sEE_I2C_TIMING 0xC062121F + + +#if defined (sEE_M24C08) + #define sEE_PAGESIZE 16 +#elif defined (sEE_M24C64_32) + #define sEE_PAGESIZE 32 +#elif defined (sEE_M24LR64) + #define sEE_PAGESIZE 4 +#elif defined (sEE_M24M01) + #define sEE_PAGESIZE 128 +#endif + +/* Maximum Timeout values for flags and events waiting loops. These timeouts are + not based on accurate values, they just guarantee that the application will + not remain stuck if the I2C communication is corrupted. + You may modify these timeout values depending on CPU frequency and application + conditions (interrupts routines ...). */ +#define sEE_FLAG_TIMEOUT ((uint32_t)0x1000) +#define sEE_LONG_TIMEOUT ((uint32_t)(10 * sEE_FLAG_TIMEOUT)) + +/* Maximum number of trials for sEE_WaitEepromStandbyState() function */ +#define sEE_MAX_TRIALS_NUMBER 300 + +#define sEE_OK 0 +#define sEE_FAIL 1 + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_EE_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_EE_Exported_Functions + * @{ + */ +void sEE_DeInit(void); +void sEE_Init(void); +uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead); +uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite); +void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite); +uint32_t sEE_WaitEepromStandbyState(void); + +/* USER Callbacks: These are functions for which prototypes only are declared in + EEPROM driver and that should be implemented into user applicaiton. */ +/* sEE_TIMEOUT_UserCallback() function is called whenever a timeout condition + occure during communication (waiting on an event that doesn't occur, bus + errors, busy devices ...). + You can use the default timeout callback implementation by uncommenting the + define USE_DEFAULT_TIMEOUT_CALLBACK in stm32303c_eval_i2c_ee.h file. + Typically the user implementation of this callback should reset I2C peripheral + and re-initialize communication or in worst case reset all the application. */ +uint32_t sEE_TIMEOUT_UserCallback(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_I2C_EE_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.c new file mode 100644 index 0000000..54476df --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.c @@ -0,0 +1,754 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_i2c_tsensor.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file provides a set of functions needed to manage the I2C TS751 + * temperature sensor mounted on STM32303C-EVAL board . + * It implements a high level communication layer for read and write + * from/to this sensor. The needed STM323F30x hardware resources (I2C and + * GPIO) are defined in stm32303c_eval.h file, and the initialization is + * performed in TS751_LowLevel_Init() function declared in stm32303c_eval.c + * file. + * You can easily tailor this driver to any other development board, + * by just adapting the defines for hardware resources and + * TS751_LowLevel_Init() function. + * + * +--------------------------------------------------------------------+ + * | Pin assignment | + * +---------------------------------------+-----------+----------------+ + * | STM32F30x I2C Pins | STTS751 | Pin | + * +---------------------------------------+-----------+----------------+ + * | TS751_I2C_SDA_PIN/ SDA | Addr/Therm | 1 | + * | TS751_I2C_SCL_PIN/ SCL | GND | 2 (0V) | + * | TS751_I2C_SMBUSALERT_PIN/ SMBUS ALERT | VDD | 3 (3.3V)| + * | Addr/Therm pin | SCL | 4 | + * | . | SMBUS ALERT| 5 | + * | . | SDA | 6 | + * +---------------------------------------+-----------+----------------+ + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval_i2c_tsensor.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup Common + * @{ + */ + +/** @addtogroup STM32303C_EVAL_I2C_TSENSOR + * @brief This file includes the TS751 Temperature Sensor driver of + * STM32303C-EVAL boards. + * @{ + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Private_Types + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Private_Defines + * @{ + */ +#define TS751_SD_SET 0x01 /*!< Set SD bit in the configuration register */ +#define TS751_SD_RESET 0xFE /*!< Reset SD bit in the configuration register */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Private_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Private_Variables + * @{ + */ + +__IO uint32_t TS751_Timeout = TS751_LONG_TIMEOUT; +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Private_Function_Prototypes + * @{ + */ + +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Private_Functions + * @{ + */ + +/** + * @brief DeInitializes the TS751_I2C. + * @param None + * @retval None + */ +void TS751_DeInit(void) +{ + TS751_LowLevel_DeInit(); +} + +/** + * @brief Initializes the TS751_I2C. + * @param None + * @retval None + */ +void TS751_Init(void) +{ + I2C_InitTypeDef I2C_InitStructure; + + TS751_LowLevel_Init(); + + /* TS751_I2C configuration */ + I2C_InitStructure.I2C_Mode = I2C_Mode_SMBusHost; + I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; + I2C_InitStructure.I2C_DigitalFilter = 0x00; + I2C_InitStructure.I2C_OwnAddress1 = 0x00; + I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; + I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; + I2C_InitStructure.I2C_Timing = TS751_I2C_TIMING; + + /* Apply TS751_I2C configuration after enabling it */ + I2C_Init(TS751_I2C, &I2C_InitStructure); + + /* TS751_I2C Peripheral Enable */ + I2C_Cmd(TS751_I2C, ENABLE); +} + +/** + * @brief Checks the TS751 status. + * @param None + * @retval ErrorStatus: TS751 Status (ERROR or SUCCESS). + */ +ErrorStatus TS751_GetStatus(void) +{ + uint32_t I2C_TimeOut = I2C_TIMEOUT; + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 0, I2C_AutoEnd_Mode, I2C_No_StartStop); + + /* Clear NACKF and STOPF */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF); + + /* Generate start */ + I2C_GenerateSTART(TS751_I2C, ENABLE); + + /* Wait until timeout elapsed */ + while ((I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) && (I2C_TimeOut-- != 0)); + + /* Check if Temp sensor is ready for use */ + if ((I2C_GetFlagStatus(TS751_I2C, I2C_ISR_NACKF) != RESET) || (I2C_TimeOut == 0)) + { + /* Clear NACKF and STOPF */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF); + + return ERROR; + } + else + { + /* Clear STOPF */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + return SUCCESS; + } +} + +/** + * @brief Read the specified register from the TS751. + * @param RegName: specifies the TS751 register to be read. + * This member can be one of the following values: + * - TS751_REG_TEMP: temperature register + * - TS751_REG_TOS: Over-limit temperature register + * - TS751_REG_THYS: Hysteresis temperature register + * @retval TS751 register value. + */ +uint8_t TS751_ReadReg(uint8_t RegName) +{ + uint8_t TS751_BufferRX[1] ={0}; + + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)RegName); + + /* Wait until TC flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TC) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + + /* Wait until RXNE flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_RXNE) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Read data from RXDR */ + TS751_BufferRX[0]= I2C_ReceiveData(TS751_I2C); + + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + /* return a Reg value */ + return TS751_BufferRX[0]; +} + +/** + * @brief Write to the specified register of the TS751. + * @param RegName: specifies the TS751 register to be written. + * This member can be one of the following values: + * - TS751_REG_TOS: Over-limit temperature register + * - TS751_REG_THYS: Hysteresis temperature register + * @param RegValue: value to be written to TS751 register. + * @retval None + */ +uint8_t TS751_WriteReg(uint8_t RegName, uint16_t RegValue) +{ + uint8_t TS751_BufferTX[1] ={0}; + + TS751_BufferTX[0] = (uint8_t)(RegValue); + + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)RegName); + + /* Wait until TCR flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TCR) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Write data to TXDR */ + I2C_SendData(TS751_I2C, (TS751_BufferTX[0])); + + + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + return TS751_OK; +} +/** + * @brief Read Temperature register of TS751: double temperature value. + * @param None + * @retval TS751 measured temperature value. + */ +uint8_t TS751_AlerteResponseAddressRead(void) +{ + uint8_t TS751_BufferRX[1] ={0}; + + /**************** Read Alerte Response Address ***********************/ + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Configure slave address, nbytes, reload, end mode and start generation */ + I2C_TransferHandling(TS751_I2C, 0x18, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + /* Wait until RXNE flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_RXNE) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Read data from RXDR */ + TS751_BufferRX[0]= I2C_ReceiveData(TS751_I2C); + + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF | I2C_ICR_NACKCF); + + /* return ARA value */ + return TS751_BufferRX[0]; +} + + +/** + * @brief Read Temperature register of TS751: double temperature value. + * @param None + * @retval TS751 measured temperature value. + */ +uint16_t TS751_ReadTemp(void) +{ + uint8_t TS751_BufferRX[2] ={0,0}; + uint16_t tmp = 0; + + /**************** Read Temperature value high Register ***********************/ + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_REG_TEMPH); + /* Wait until TC flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TC) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + /* Wait until RXNE flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_RXNE) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Read data from RXDR */ + TS751_BufferRX[0]= I2C_ReceiveData(TS751_I2C); + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + + /****************** Read Temperature value low Register ************************/ + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_REG_TEMPL); + + /* Wait until TC flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TC) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + + /* Wait until RXNE flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_RXNE) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Read data from RXDR */ + TS751_BufferRX[1]= I2C_ReceiveData(TS751_I2C); + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + /*************************** Store Data ******************************/ + /*!< Store TS751_I2C received data */ + tmp = (uint16_t)(TS751_BufferRX[0] << 8); + tmp |= TS751_BufferRX[1]; + /*!< Return Temperature value */ + return (uint16_t)(tmp >> 4); +} + +/** + * @brief Read the configuration register from the TS751. + * @param None + * @retval TS751 configuration register value. + */ +uint8_t TS751_ReadConfReg(void) +{ + uint8_t TS751_BufferRX[1] ={0}; + + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_REG_CONF); + + /* Wait until TC flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TC) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + + /* Wait until RXNE flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_RXNE) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Read data from RXDR */ + TS751_BufferRX[0]= I2C_ReceiveData(TS751_I2C); + + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + /*!< Return Register value */ + return (uint8_t)TS751_BufferRX[0]; +} + +/** + * @brief Write to the configuration register of the TS751. + * @param RegValue: specifies the value to be written to TS751 configuration + * register. + * @retval None + */ +uint8_t TS751_WriteConfReg(uint8_t RegValue) +{ + uint8_t TS751_BufferTX = 0; + + TS751_BufferTX = (uint8_t)(RegValue); + + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_REG_CONF); + + /* Wait until TCR flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TCR) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Write data to TXDR */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_BufferTX); + + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + return TS751_OK; +} + +/** + * @brief Enables or disables the TS751. + * @param NewState: specifies the TS751 new status. This parameter can be ENABLE + * or DISABLE. + * @retval None + */ +uint8_t TS751_ShutDown(FunctionalState NewState) +{ + uint8_t TS751_BufferRX[2] ={0,0}; + uint8_t TS751_BufferTX = 0; + __IO uint8_t RegValue = 0; + + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_REG_CONF); + + /* Wait until TC flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TC) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); + + /* Wait until RXNE flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_RXNE) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Read data from RXDR */ + TS751_BufferRX[0]= I2C_ReceiveData(TS751_I2C); + + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + /*!< Get received data */ + RegValue = (uint8_t)TS751_BufferRX[0]; + + /*---------------------------- Transmission Phase ---------------------------*/ + + /*!< Enable or disable SD bit */ + if (NewState != DISABLE) + { + /*!< Enable TS751 */ + TS751_BufferTX = RegValue & TS751_SD_RESET; + } + else + { + /*!< Disable TS751 */ + TS751_BufferTX = RegValue | TS751_SD_SET; + } + + /* Test on BUSY Flag */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_BUSY) != RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Send Register address */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_REG_CONF); + + /* Wait until TCR flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TCR) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Configure slave address, nbytes, reload, end mode and start or stop generation */ + I2C_TransferHandling(TS751_I2C, TS751_ADDR, 1, I2C_AutoEnd_Mode, I2C_No_StartStop); + + /* Wait until TXIS flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_TXIS) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Write data to TXDR */ + I2C_SendData(TS751_I2C, (uint8_t)TS751_BufferTX); + + /* Wait until STOPF flag is set */ + TS751_Timeout = TS751_LONG_TIMEOUT; + while(I2C_GetFlagStatus(TS751_I2C, I2C_ISR_STOPF) == RESET) + { + if((TS751_Timeout--) == 0) return TS751_TIMEOUT_UserCallback(); + } + + /* Clear STOPF flag */ + I2C_ClearFlag(TS751_I2C, I2C_ICR_STOPCF); + + return TS751_OK; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.h new file mode 100644 index 0000000..af5ff97 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.h @@ -0,0 +1,177 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_i2c_tsensor.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains all the functions prototypes for the + * stm32303c_eval_i2c_tsensor.c firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_I2C_TSENSOR_H +#define __STM32303C_EVAL_I2C_TSENSOR_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup Common + * @{ + */ + +/** @addtogroup STM32303C_EVAL_I2C_TSENSOR + * @{ + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Exported_Types + * @{ + */ + +/** + * @brief TSENSOR Status + */ +typedef enum +{ + TS751_OK = 0, + TS751_FAIL +}TS751_Status_TypDef; + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Exported_Constants + * @{ + */ + +/* Uncomment the following line to use Timeout_User_Callback TS751_TimeoutUserCallback(). + If This Callback is enabled, it should be implemented by user in main function . + TS751_TimeoutUserCallback() function is called whenever a timeout condition + occure during communication (waiting on an event that doesn't occur, bus + errors, busy devices ...). */ +/*#define USE_TIMEOUT_USER_CALLBACK*/ + +/* Maximum Timeout values for flags and events waiting loops. These timeouts are + not based on accurate values, they just guarantee that the application will + not remain stuck if the I2C communication is corrupted. + You may modify these timeout values depending on CPU frequency and application + conditions (interrupts routines ...). */ +#define TS751_FLAG_TIMEOUT ((uint32_t)0x1000) +#define TS751_LONG_TIMEOUT ((uint32_t)(10 * TS751_FLAG_TIMEOUT)) + + +/** + * @brief Block Size + */ +#define TS751_REG_TEMPH 0x00 /*!< Temperature Register of TS751 */ +#define TS751_REG_TEMPL 0x02 /*!< Temperature Register of TS751 */ +#define TS751_REG_CONF 0x03 /*!< Configuration Register of TS751 */ +#define TS751_REG_THYS 0x21 /*!< Temperature Register of TS751 */ +#define TS751_REG_TOS 0x20 /*!< Over-temp Shutdown threshold Register of TS751 */ +#define I2C_TIMEOUT ((uint32_t)0x3FFFF) /*!< I2C Time out */ +#define TS751_ADDR 0x90 /*!< TS751 address */ + + +/* I2C TIMING Register define when I2C clock source is SYSCLK */ +/* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 72 MHz */ +/* set TIMING to 0xC062121F to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */ + +#define TS751_I2C_TIMING 0xC062121F + + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_I2C_TSENSOR_Exported_Functions + * @{ + */ +void TS751_DeInit(void); +void TS751_Init(void); +ErrorStatus TS751_GetStatus(void); +uint8_t TS751_AlerteResponseAddressRead(void); +uint16_t TS751_ReadTemp(void); +uint8_t TS751_ReadReg(uint8_t RegName); +uint8_t TS751_WriteReg(uint8_t RegName, uint16_t RegValue); +uint8_t TS751_ReadConfReg(void); +uint8_t TS751_WriteConfReg(uint8_t RegValue); +uint8_t TS751_ShutDown(FunctionalState NewState); + +/** + * @brief Timeout user callback function. This function is called when a timeout + * condition occurs during communication with TS751. Only protoype + * of this function is decalred in TS751 driver. Its implementation + * may be done into user application. This function may typically stop + * current operations and reset the I2C peripheral and TS751. + * To enable this function use uncomment the define USE_TIMEOUT_USER_CALLBACK + * at the top of this file. + */ +#ifdef USE_TIMEOUT_USER_CALLBACK + uint8_t TS751_TIMEOUT_UserCallback(void); +#else + #define TS751_TIMEOUT_UserCallback() TS751_FAIL +#endif /* USE_TIMEOUT_USER_CALLBACK */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_I2C_TSENSOR_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |