aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL
diff options
context:
space:
mode:
authorTrygve Laugstøl <trygvis@inamo.no>2017-01-25 22:24:18 +0100
committerTrygve Laugstøl <trygvis@inamo.no>2017-01-25 22:29:25 +0100
commit40e04e3772726829d66c12e69f24b03920d79c67 (patch)
tree636811bad956798c9d5d22de9e7ba8c799b8d791 /thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL
parent2fff65aed2477a503c72629d27e2a330d30c02d1 (diff)
downloadstm32f103-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')
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.c762
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval.h442
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.c1597
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_audio_codec.h302
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.c717
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee.h206
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.c754
-rw-r--r--thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_tsensor.h177
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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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>&copy; 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****/