Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Flipper-Zero/STM32CubeWB.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Projects/P-NUCLEO-WB55.Nucleo/Examples_LL/I2C/I2C_OneBoard_AdvCommunication_DMAAndIT_Init/Src/main.c')
-rw-r--r--Projects/P-NUCLEO-WB55.Nucleo/Examples_LL/I2C/I2C_OneBoard_AdvCommunication_DMAAndIT_Init/Src/main.c990
1 files changed, 990 insertions, 0 deletions
diff --git a/Projects/P-NUCLEO-WB55.Nucleo/Examples_LL/I2C/I2C_OneBoard_AdvCommunication_DMAAndIT_Init/Src/main.c b/Projects/P-NUCLEO-WB55.Nucleo/Examples_LL/I2C/I2C_OneBoard_AdvCommunication_DMAAndIT_Init/Src/main.c
new file mode 100644
index 000000000..5355dd141
--- /dev/null
+++ b/Projects/P-NUCLEO-WB55.Nucleo/Examples_LL/I2C/I2C_OneBoard_AdvCommunication_DMAAndIT_Init/Src/main.c
@@ -0,0 +1,990 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file Examples_LL/I2C/I2C_OneBoard_AdvCommunication_DMAAndIT_Init/Src/main.c
+ * @author MCD Application Team
+ * @brief This example describes how to send/receive bytes over I2C IP using
+ * the STM32WBxx I2C LL API.
+ * Peripheral initialization done using LL unitary services functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+/**
+ * @brief Timeout value
+ */
+#if (USE_TIMEOUT == 1)
+#define DMA_SEND_TIMEOUT_TC_MS 5
+#define I2C_SEND_TIMEOUT_TC_MS 2
+#define I2C_SEND_TIMEOUT_STOP_MS 5
+#endif /* USE_TIMEOUT */
+
+/**
+ * @brief I2C devices settings
+ */
+/* Timing register value is computed with the STM32CubeMX Tool,
+ * Fast Mode @400kHz with I2CCLK = 64 MHz,
+ * rise time = 100ns, fall time = 10ns
+ * Timing Value = (uint32_t)0x00C0216C
+ */
+#define I2C_TIMING 0x00C0216C
+
+#define SLAVE_CHIP_NAME 0
+#define SLAVE_CHIP_REVISION 1
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+
+/* USER CODE BEGIN PV */
+#if (USE_TIMEOUT == 1)
+uint32_t Timeout = 0; /* Variable used for Timeout management */
+#endif /* USE_TIMEOUT */
+__IO uint8_t ubButtonPress = 0;
+
+/**
+ * @brief Variables related to Master process
+ */
+/* aCommandCode declaration array */
+/* [CommandCode][RequestSlaveAnswer] */
+/* {CODE, YES/NO} */
+const char* aCommandCode[4][4] = {
+ {"CHIP NAME", "YES"},
+ {"CHIP REVISION", "YES"},
+ {"LOW POWER", "NO"},
+ {"WAKE UP", "NO"}
+ };
+
+uint32_t* pMasterTransmitBuffer = (uint32_t*)(&aCommandCode[0][0]);
+uint8_t ubMasterNbCommandCode = sizeof(aCommandCode[0][0]);
+uint8_t aMasterReceiveBuffer[0xF] = {0};
+__IO uint8_t ubMasterNbDataToReceive = sizeof(aMasterReceiveBuffer);
+__IO uint8_t ubMasterNbDataToTransmit = 0;
+uint8_t ubMasterCommandIndex = 0;
+__IO uint8_t ubMasterReceiveIndex = 0;
+__IO uint8_t ubMasterTransferComplete = 0;
+
+/**
+ * @brief Variables related to Slave process
+ */
+const char* aSlaveInfo[] = {
+ "STM32WB55RG",
+ "1.2.3"};
+
+uint8_t aSlaveReceiveBuffer[0xF] = {0};
+uint8_t* pSlaveTransmitBuffer = 0;
+uint8_t ubSlaveInfoIndex = 0xFF;
+__IO uint8_t ubSlaveReceiveIndex = 0;
+__IO uint8_t ubSlaveReceiveComplete = 0;
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+void SystemClock_Config(void);
+static void MX_GPIO_Init(void);
+static void MX_DMA_Init(void);
+static void MX_I2C1_Init(void);
+static void MX_I2C3_Init(void);
+/* USER CODE BEGIN PFP */
+uint8_t Buffercmp8(uint8_t* pBuffer1, uint8_t* pBuffer2, uint8_t BufferLength);
+void FlushBuffer8(uint8_t* pBuffer1);
+void LED_On(void);
+void LED_Off(void);
+void LED_Blinking(uint32_t Period);
+void WaitForUserButtonPress(void);
+void Handle_I2C_Master_Transmit(void);
+void Handle_I2C_Master_TransmitReceive(void);
+#if defined(__GNUC__)
+extern void initialise_monitor_handles(void); /*rtt*/
+#endif
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+ * @brief The application entry point.
+ * @retval int
+ */
+int main(void)
+{
+ /* USER CODE BEGIN 1 */
+
+ /* USER CODE END 1 */
+
+ /* MCU Configuration--------------------------------------------------------*/
+
+ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+
+ NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
+
+ /* System interrupt init*/
+
+ /* USER CODE BEGIN Init */
+
+ /* USER CODE END Init */
+
+ /* Configure the system clock */
+ SystemClock_Config();
+
+ /* USER CODE BEGIN SysInit */
+
+ /* USER CODE END SysInit */
+
+ /* Initialize all configured peripherals */
+ MX_GPIO_Init();
+ MX_DMA_Init();
+ MX_I2C1_Init();
+ MX_I2C3_Init();
+ /* USER CODE BEGIN 2 */
+#if defined(__GNUC__)
+ initialise_monitor_handles(); /*rtt*/
+#endif
+
+ /* Set LED2 Off */
+ LED_Off();
+
+
+ /* USER CODE END 2 */
+
+ /* Infinite loop */
+ /* USER CODE BEGIN WHILE */
+ while (1)
+ {
+ /* USER CODE END WHILE */
+
+ /* USER CODE BEGIN 3 */
+
+ /* Wait for User push-button (SW1) press to start transfer */
+ WaitForUserButtonPress();
+
+ /* Clear User push-button (SW1) related variable */
+ ubButtonPress = 0;
+
+ if(strncmp(aCommandCode[ubMasterCommandIndex][1], "NO", 2) == 0)
+ {
+ /* Handle I2C3 events (Master Transmit only) */
+ Handle_I2C_Master_Transmit();
+ }
+ else
+ {
+ /* Handle I2C3 events (Master Transmit then Receive) */
+ Handle_I2C_Master_TransmitReceive();
+ }
+
+ /* Prepare Index to send next command code */
+ ubMasterCommandIndex++;
+ if(ubMasterCommandIndex >= ubMasterNbCommandCode)
+ {
+ ubMasterCommandIndex = 0;
+ }
+ }
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief System Clock Configuration
+ * @retval None
+ */
+void SystemClock_Config(void)
+{
+ LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
+
+ /* MSI configuration and activation */
+ LL_RCC_MSI_Enable();
+ while(LL_RCC_MSI_IsReady() != 1)
+ {
+ }
+
+ /* Main PLL configuration and activation */
+ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 32, LL_RCC_PLLR_DIV_2);
+ LL_RCC_PLL_Enable();
+ LL_RCC_PLL_EnableDomain_SYS();
+ while(LL_RCC_PLL_IsReady() != 1)
+ {
+ }
+
+ /* Sysclk activation on the main PLL */
+ /* Set CPU1 prescaler*/
+ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
+
+ /* Set CPU2 prescaler*/
+ LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2);
+
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
+ while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
+ {
+ }
+
+ /* Set AHB SHARED prescaler*/
+ LL_RCC_SetAHB4Prescaler(LL_RCC_SYSCLK_DIV_1);
+
+ /* Set APB1 prescaler*/
+ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
+
+ /* Set APB2 prescaler*/
+ LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
+
+ LL_Init1msTick(64000000);
+
+ /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */
+ LL_SetSystemCoreClock(64000000);
+ /* USER CODE BEGIN Smps */
+
+ /* USER CODE END Smps */
+}
+
+/**
+ * @brief I2C1 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_I2C1_Init(void)
+{
+
+ /* USER CODE BEGIN I2C1_Init 0 */
+
+ /* USER CODE END I2C1_Init 0 */
+
+ LL_I2C_InitTypeDef I2C_InitStruct = {0};
+
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
+ /**I2C1 GPIO Configuration
+ PB8 ------> I2C1_SCL
+ PB9 ------> I2C1_SDA
+ */
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_8|LL_GPIO_PIN_9;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
+ LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ LL_SYSCFG_EnableFastModePlus(LL_SYSCFG_I2C_FASTMODEPLUS_PB8);
+
+ LL_SYSCFG_EnableFastModePlus(LL_SYSCFG_I2C_FASTMODEPLUS_PB9);
+
+ /* Peripheral clock enable */
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
+
+ /* USER CODE BEGIN I2C1_Init 1 */
+ /* Configure Event IT:
+ * - Set priority for I2C1_EV_IRQn
+ * - Enable I2C1_EV_IRQn
+ */
+ NVIC_SetPriority(I2C1_EV_IRQn, 0xF);
+ NVIC_EnableIRQ(I2C1_EV_IRQn);
+
+ /* Configure Error IT:
+ * - Set priority for I2C1_ER_IRQn
+ * - Enable I2C1_ER_IRQn
+ */
+ NVIC_SetPriority(I2C1_ER_IRQn, 0xF);
+ NVIC_EnableIRQ(I2C1_ER_IRQn);
+ /* USER CODE END I2C1_Init 1 */
+ /** I2C Initialization
+ */
+ I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
+ I2C_InitStruct.Timing = 0x00000102;
+ I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
+ I2C_InitStruct.DigitalFilter = 0;
+ I2C_InitStruct.OwnAddress1 = 180;
+ I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
+ I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
+ LL_I2C_Init(I2C1, &I2C_InitStruct);
+ LL_I2C_EnableAutoEndMode(I2C1);
+ LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK);
+ LL_I2C_DisableOwnAddress2(I2C1);
+ LL_I2C_DisableGeneralCall(I2C1);
+ LL_I2C_EnableClockStretching(I2C1);
+ /* USER CODE BEGIN I2C1_Init 2 */
+ LL_I2C_EnableIT_ADDR(I2C1);
+ LL_I2C_EnableIT_NACK(I2C1);
+ LL_I2C_EnableIT_ERR(I2C1);
+ LL_I2C_EnableIT_STOP(I2C1);
+ /* USER CODE END I2C1_Init 2 */
+
+}
+
+/**
+ * @brief I2C3 Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_I2C3_Init(void)
+{
+
+ /* USER CODE BEGIN I2C3_Init 0 */
+
+ /* USER CODE END I2C3_Init 0 */
+
+ LL_I2C_InitTypeDef I2C_InitStruct = {0};
+
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
+ /**I2C3 GPIO Configuration
+ PC0 ------> I2C3_SCL
+ PC1 ------> I2C3_SDA
+ */
+ GPIO_InitStruct.Pin = LL_GPIO_PIN_0|LL_GPIO_PIN_1;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
+ GPIO_InitStruct.Alternate = LL_GPIO_AF_4;
+ LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ /* Peripheral clock enable */
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
+
+ /* I2C3 DMA Init */
+
+ /* I2C3_TX Init */
+ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_2, LL_DMAMUX_REQ_I2C3_TX);
+
+ LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
+
+ LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PRIORITY_HIGH);
+
+ LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MODE_NORMAL);
+
+ LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PERIPH_NOINCREMENT);
+
+ LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MEMORY_INCREMENT);
+
+ LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_PDATAALIGN_BYTE);
+
+ LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_2, LL_DMA_MDATAALIGN_BYTE);
+
+ /* I2C3_RX Init */
+ LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_3, LL_DMAMUX_REQ_I2C3_RX);
+
+ LL_DMA_SetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3, LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
+
+ LL_DMA_SetChannelPriorityLevel(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PRIORITY_HIGH);
+
+ LL_DMA_SetMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MODE_NORMAL);
+
+ LL_DMA_SetPeriphIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PERIPH_NOINCREMENT);
+
+ LL_DMA_SetMemoryIncMode(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MEMORY_INCREMENT);
+
+ LL_DMA_SetPeriphSize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_PDATAALIGN_BYTE);
+
+ LL_DMA_SetMemorySize(DMA1, LL_DMA_CHANNEL_3, LL_DMA_MDATAALIGN_BYTE);
+
+ /* USER CODE BEGIN I2C3_Init 1 */
+ LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_2, (uint32_t)(*pMasterTransmitBuffer), (uint32_t)LL_I2C_DMA_GetRegAddr(I2C3, LL_I2C_DMA_REG_DATA_TRANSMIT), LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2));
+ LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_3, (uint32_t)LL_I2C_DMA_GetRegAddr(I2C3, LL_I2C_DMA_REG_DATA_RECEIVE), (uint32_t)&(aMasterReceiveBuffer), LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3));
+ LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2);
+ LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2);
+ LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_3);
+ LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_3);
+
+ /* USER CODE END I2C3_Init 1 */
+ /** I2C Initialization
+ */
+ I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;
+ I2C_InitStruct.Timing = 0x00000102;
+ I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE;
+ I2C_InitStruct.DigitalFilter = 0;
+ I2C_InitStruct.OwnAddress1 = 0;
+ I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;
+ I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;
+ LL_I2C_Init(I2C3, &I2C_InitStruct);
+ LL_I2C_EnableAutoEndMode(I2C3);
+ LL_I2C_SetOwnAddress2(I2C3, 0, LL_I2C_OWNADDRESS2_NOMASK);
+ LL_I2C_DisableOwnAddress2(I2C3);
+ LL_I2C_DisableGeneralCall(I2C3);
+ LL_I2C_EnableClockStretching(I2C3);
+ /* USER CODE BEGIN I2C3_Init 2 */
+ LL_I2C_EnableDMAReq_RX(I2C3);
+ LL_I2C_EnableDMAReq_TX(I2C3);
+ LL_I2C_Enable(I2C3);
+ /* USER CODE END I2C3_Init 2 */
+
+}
+
+/**
+ * Enable DMA controller clock
+ */
+static void MX_DMA_Init(void)
+{
+
+ /* Init with LL driver */
+ /* DMA controller clock enable */
+ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);
+ LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
+
+ /* DMA interrupt init */
+ /* DMA1_Channel2_IRQn interrupt configuration */
+ NVIC_SetPriority(DMA1_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
+ NVIC_EnableIRQ(DMA1_Channel2_IRQn);
+ /* DMA1_Channel3_IRQn interrupt configuration */
+ NVIC_SetPriority(DMA1_Channel3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
+ NVIC_EnableIRQ(DMA1_Channel3_IRQn);
+
+}
+
+/**
+ * @brief GPIO Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_GPIO_Init(void)
+{
+ LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
+ LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
+
+ /* GPIO Ports Clock Enable */
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
+ LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
+
+ /**/
+ LL_GPIO_ResetOutputPin(LED2_GPIO_Port, LED2_Pin);
+
+ /**/
+ LL_SYSCFG_SetEXTISource(LL_SYSCFG_EXTI_PORTC, LL_SYSCFG_EXTI_LINE4);
+
+ /**/
+ EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_4;
+ EXTI_InitStruct.Line_32_63 = LL_EXTI_LINE_NONE;
+ EXTI_InitStruct.LineCommand = ENABLE;
+ EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
+ EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_FALLING;
+ LL_EXTI_Init(&EXTI_InitStruct);
+
+ /**/
+ LL_GPIO_SetPinPull(User_button_GPIO_Port, User_button_Pin, LL_GPIO_PULL_UP);
+
+ /**/
+ LL_GPIO_SetPinMode(User_button_GPIO_Port, User_button_Pin, LL_GPIO_MODE_INPUT);
+
+ /**/
+ GPIO_InitStruct.Pin = LED2_Pin;
+ GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
+ GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
+ GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
+ GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
+ LL_GPIO_Init(LED2_GPIO_Port, &GPIO_InitStruct);
+
+ /* EXTI interrupt init*/
+ NVIC_SetPriority(EXTI4_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
+ NVIC_EnableIRQ(EXTI4_IRQn);
+
+}
+
+/* USER CODE BEGIN 4 */
+
+/**
+ * @brief Flush 8-bit buffer.
+ * @param pBuffer1: pointer to the buffer to be flushed.
+ * @retval None
+ */
+void FlushBuffer8(uint8_t* pBuffer1)
+{
+ uint8_t Index = 0;
+
+ for (Index = 0; Index < sizeof(pBuffer1); Index++)
+ {
+ pBuffer1[Index] = 0;
+ }
+}
+
+/**
+ * @brief Compares two 8-bit buffers and returns the comparison result.
+ * @param pBuffer1: pointer to the source buffer to be compared to.
+ * @param pBuffer2: pointer to the second source buffer to be compared to the first.
+ * @param BufferLength: buffer's length.
+ * @retval 0: Comparison is OK (the two Buffers are identical)
+ * Value different from 0: Comparison is NOK (Buffers are different)
+ */
+uint8_t Buffercmp8(uint8_t* pBuffer1, uint8_t* pBuffer2, uint8_t BufferLength)
+{
+ while (BufferLength--)
+ {
+ if (*pBuffer1 != *pBuffer2)
+ {
+ return 1;
+ }
+
+ pBuffer1++;
+ pBuffer2++;
+ }
+
+ return 0;
+}
+/**
+ * @brief Turn-on LED2.
+ * @param None
+ * @retval None
+ */
+void LED_On(void)
+{
+ /* Turn LED2 on */
+ LL_GPIO_SetOutputPin(LED2_GPIO_Port, LED2_Pin);
+}
+
+/**
+ * @brief Turn-off LED2.
+ * @param None
+ * @retval None
+ */
+void LED_Off(void)
+{
+ /* Turn LED2 off */
+ LL_GPIO_ResetOutputPin(LED2_GPIO_Port, LED2_Pin);
+}
+
+/**
+ * @brief Set LED2 to Blinking mode for an infinite loop (toggle period based on value provided as input parameter).
+ * @param Period : Period of time (in ms) between each toggling of LED
+ * This parameter can be user defined values. Pre-defined values used in that example are :
+ * @arg LED_BLINK_FAST : Fast Blinking
+ * @arg LED_BLINK_SLOW : Slow Blinking
+ * @arg LED_BLINK_ERROR : Error specific Blinking
+ * @retval None
+ */
+void LED_Blinking(uint32_t Period)
+{
+ /* Turn LED2 on */
+ LL_GPIO_SetOutputPin(LED2_GPIO_Port, LED2_Pin);
+
+ /* Toggle IO in an infinite loop */
+ while (1)
+ {
+ LL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
+ LL_mDelay(Period);
+ }
+}
+
+
+/**
+ * @brief Wait for User push-button (SW1) press to start transfer.
+ * @param None
+ * @retval None
+ */
+ /* */
+void WaitForUserButtonPress(void)
+{
+ while (ubButtonPress == 0)
+ {
+ LL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
+ LL_mDelay(LED_BLINK_FAST);
+ }
+ /* Turn LED2 off */
+ LL_GPIO_ResetOutputPin(LED2_GPIO_Port, LED2_Pin);
+}
+
+/**
+ * @brief This Function handle Master events to perform a transmission process
+ * @note This function is composed in different steps :
+ * -1- Configure DMA parameters for Command Code transfer.
+ * -2- Enable DMA transfer.
+ * -3- Initiate a Start condition to the Slave device.
+ * -4- Loop until end of DMA transfer completed (DMA TC raised).
+ * -5- Loop until end of master transfer completed (STOP flag raised).
+ * -6- Clear pending flags, Data Command Code are checking into Slave process.
+ * @param None
+ * @retval None
+ */
+void Handle_I2C_Master_Transmit(void)
+{
+ /* (1) Configure DMA parameters for Command Code transfer *******************/
+ pMasterTransmitBuffer = (uint32_t*)(&aCommandCode[ubMasterCommandIndex][0]);
+ ubMasterNbDataToTransmit = strlen((char *)pMasterTransmitBuffer[0]);
+
+ LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)(*pMasterTransmitBuffer));
+ LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, ubMasterNbDataToTransmit);
+
+ /* (2) Enable DMA transfer **************************************************/
+ LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
+ /* (3) Initiate a Start condition to the Slave device ***********************/
+
+ /* Master Generate Start condition for a write request:
+ * - to the Slave with a 7-Bit SLAVE_OWN_ADDRESS
+ * - with a auto stop condition generation when transmit all bytes
+ * - No specific answer is needed from Slave Device, configure auto-stop condition
+ */
+ LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, ubMasterNbDataToTransmit, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
+
+ /* (4) Loop until end of transfer completed (DMA TC raised) *****************/
+
+#if (USE_TIMEOUT == 1)
+ Timeout = DMA_SEND_TIMEOUT_TC_MS;
+#endif /* USE_TIMEOUT */
+
+ /* Loop until DMA transfer complete event */
+ while(!ubMasterTransferComplete)
+ {
+#if (USE_TIMEOUT == 1)
+ /* Check Systick counter flag to decrement the time-out value */
+ if (LL_SYSTICK_IsActiveCounterFlag())
+ {
+ if(Timeout-- == 0)
+ {
+ /* Time-out occurred. Set LED to blinking mode */
+ LED_Blinking(LED_BLINK_SLOW);
+ }
+ }
+#endif /* USE_TIMEOUT */
+ }
+
+ /* (5) Loop until end of master process completed (STOP flag raised) ********/
+#if (USE_TIMEOUT == 1)
+ Timeout = I2C_SEND_TIMEOUT_STOP_MS;
+#endif /* USE_TIMEOUT */
+
+ /* Loop until STOP flag is raised */
+ while(!LL_I2C_IsActiveFlag_STOP(I2C3))
+ {
+#if (USE_TIMEOUT == 1)
+ /* Check Systick counter flag to decrement the time-out value */
+ if (LL_SYSTICK_IsActiveCounterFlag())
+ {
+ if(Timeout-- == 0)
+ {
+ /* Time-out occurred. Set LED2 to blinking mode */
+ LED_Blinking(LED_BLINK_SLOW);
+ }
+ }
+#endif /* USE_TIMEOUT */
+ }
+
+ /* (6) Clear pending flags, Data Command Code are checking into Slave process */
+ /* End of Master Process */
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
+ LL_I2C_ClearFlag_STOP(I2C3);
+
+ /* Display through external Terminal IO the Slave Answer received */
+ printf("%s : %s\n\r", (char*)(aCommandCode[ubMasterCommandIndex][0]), (char*)aMasterReceiveBuffer);
+
+ /* Turn LED2 On */
+ /* Master sequence completed successfully*/
+ LED_On();
+ /* Keep LED2 On, 500 MilliSeconds */
+ LL_mDelay(500);
+ LED_Off();
+
+ /* Clear and Reset process variables and arrays */
+ ubMasterTransferComplete = 0;
+ ubMasterNbDataToTransmit = 0;
+ ubMasterReceiveIndex = 0;
+ FlushBuffer8(aMasterReceiveBuffer);
+}
+
+/**
+ * @brief This Function handle Master events to perform a transmission then a reception process
+ * @note This function is composed in different steps :
+ * -1- Configure DMA parameters for Command Code transfer.
+ * -2- Enable DMA transfer.
+ * -3- Initiate a Start condition to the Slave device.
+ * -4- Loop until end of DMA transfer completed (DMA TC raised).
+ * -5- Loop until end of master transfer completed (TC flag raised).
+ * -6- Configure DMA to receive data from slave.
+ * -7- Initiate a ReStart condition to the Slave device.
+ * -8- Loop until end of master process completed (STOP flag raised).
+ * -9- Clear pending flags, Data Command Code are checking into Slave process.
+ * @param None
+ * @retval None
+ */
+void Handle_I2C_Master_TransmitReceive(void)
+{
+ /* (1) Configure DMA parameters for Command Code transfer *******************/
+ pMasterTransmitBuffer = (uint32_t*)(&aCommandCode[ubMasterCommandIndex][0]);
+ ubMasterNbDataToTransmit = strlen((char *)pMasterTransmitBuffer[0]);
+
+ LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)(*pMasterTransmitBuffer));
+ LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, ubMasterNbDataToTransmit);
+
+ /* (2) Enable DMA transfer **************************************************/
+ LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
+ /* (3) Initiate a Start condition to the Slave device ***********************/
+
+ /* Master Generate Start condition for a write request:
+ * - to the Slave with a 7-Bit SLAVE_OWN_ADDRESS
+ * - with a no stop condition generation when transmit all bytes
+ * - A specific answer is needed from Slave Device, configure no-stop condition
+ */
+ LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, ubMasterNbDataToTransmit, LL_I2C_MODE_SOFTEND, LL_I2C_GENERATE_START_WRITE);
+
+ /* (4) Loop until end of transfer completed (DMA TC raised) *****************/
+
+#if (USE_TIMEOUT == 1)
+ Timeout = DMA_SEND_TIMEOUT_TC_MS;
+#endif /* USE_TIMEOUT */
+
+ /* Loop until DMA transfer complete event */
+ while(!ubMasterTransferComplete)
+ {
+#if (USE_TIMEOUT == 1)
+ /* Check Systick counter flag to decrement the time-out value */
+ if (LL_SYSTICK_IsActiveCounterFlag())
+ {
+ if(Timeout-- == 0)
+ {
+ /* Time-out occurred. Set LED to blinking mode */
+ LED_Blinking(LED_BLINK_SLOW);
+ }
+ }
+#endif /* USE_TIMEOUT */
+ }
+
+ /* Reset ubMasterTransferComplete flag */
+ ubMasterTransferComplete = 0;
+
+ /* (5) Loop until end of master transfer completed (TC flag raised) *********/
+ /* Wait Master Transfer completed */
+#if (USE_TIMEOUT == 1)
+ Timeout = I2C_SEND_TIMEOUT_TC_MS;
+#endif /* USE_TIMEOUT */
+
+ while(LL_I2C_IsActiveFlag_TC(I2C3) != 1)
+ {
+#if (USE_TIMEOUT == 1)
+ /* Check Systick counter flag to decrement the time-out value */
+ if (LL_SYSTICK_IsActiveCounterFlag())
+ {
+ if(Timeout-- == 0)
+ {
+ /* Time-out occurred. Set LED to blinking mode */
+ LED_Blinking(LED_BLINK_SLOW);
+ }
+ }
+#endif /* USE_TIMEOUT */
+ }
+
+
+ /* (6) Configure DMA to receive data from slave *****************************/
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
+ LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, ubMasterNbDataToReceive);
+ LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);
+
+ /* (7) Initiate a ReStart condition to the Slave device *********************/
+ /* Master Generate Start condition for a write request:
+ * - to the Slave with a 7-Bit SLAVE_OWN_ADDRESS
+ * - with a auto stop condition generation when transmit all bytes
+ */
+ LL_I2C_HandleTransfer(I2C3, SLAVE_OWN_ADDRESS, LL_I2C_ADDRSLAVE_7BIT, ubMasterNbDataToReceive, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_RESTART_7BIT_READ);
+
+ /* (8) Loop until end of master process completed (STOP flag raised) ********/
+#if (USE_TIMEOUT == 1)
+ Timeout = I2C_SEND_TIMEOUT_STOP_MS;
+#endif /* USE_TIMEOUT */
+
+ /* Loop until STOP flag is raised */
+ while(!LL_I2C_IsActiveFlag_STOP(I2C3))
+ {
+#if (USE_TIMEOUT == 1)
+ /* Check Systick counter flag to decrement the time-out value */
+ if (LL_SYSTICK_IsActiveCounterFlag())
+ {
+ if(Timeout-- == 0)
+ {
+ /* Time-out occurred. Set LED2 to blinking mode */
+ LED_Blinking(LED_BLINK_SLOW);
+ }
+ }
+#endif /* USE_TIMEOUT */
+ }
+
+ /* (9) Clear pending flags, Data Command Code are checking into Slave process */
+ /* End of Master Process */
+ LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_3);
+ LL_I2C_ClearFlag_STOP(I2C3);
+
+ /* Display through external Terminal IO the Slave Answer received */
+ printf("%s : %s\n\r", (char*)(aCommandCode[ubMasterCommandIndex][0]), (char*)aMasterReceiveBuffer);
+
+ /* Turn LED2 On */
+ /* Master sequence completed successfully*/
+ LED_On();
+ /* Keep LED2 On, 500 MilliSeconds */
+ LL_mDelay(500);
+ LED_Off();
+
+ /* Clear and Reset process variables and arrays */
+ ubMasterTransferComplete = 0;
+ ubMasterNbDataToTransmit = 0;
+ ubMasterReceiveIndex = 0;
+ FlushBuffer8(aMasterReceiveBuffer);
+}
+/******************************************************************************/
+/* IRQ HANDLER TREATMENT Functions */
+/******************************************************************************/
+/**
+ * @brief Function to manage User push-button (SW1)
+ * @param None
+ * @retval None
+ */
+void UserButton_Callback(void)
+{
+ /* Update User push-button (SW1) variable : to be checked in waiting loop in main program */
+ ubButtonPress = 1;
+}
+
+/**
+ * @brief Function called from I2C IRQ Handler when TXIS flag is set
+ * Function is in charge of transmit a byte on I2C lines.
+ * @param None
+ * @retval None
+ */
+void Slave_Ready_To_Transmit_Callback(void)
+{
+ /* Send the Byte requested by the Master */
+ LL_I2C_TransmitData8(I2C1, (uint8_t)(*pSlaveTransmitBuffer++));
+}
+
+/**
+ * @brief Function called from I2C IRQ Handler when RXNE flag is set
+ * Function is in charge of retrieving received byte on I2C lines.
+ * @param None
+ * @retval None
+ */
+void Slave_Reception_Callback(void)
+{
+ /* Read character in Receive Data register.
+ RXNE flag is cleared by reading data in RXDR register */
+ aSlaveReceiveBuffer[ubSlaveReceiveIndex++] = LL_I2C_ReceiveData8(I2C1);
+
+ /* Check Command code */
+ if(Buffercmp8((uint8_t*)aSlaveReceiveBuffer, (uint8_t*)(aCommandCode[0][0]), (ubSlaveReceiveIndex-1)) == 0)
+ {
+ ubSlaveInfoIndex = SLAVE_CHIP_NAME;
+ pSlaveTransmitBuffer = (uint8_t*)(aSlaveInfo[ubSlaveInfoIndex]);
+ }
+ else if(Buffercmp8((uint8_t*)aSlaveReceiveBuffer, (uint8_t*)(aCommandCode[1][0]), (ubSlaveReceiveIndex-1)) == 0)
+ {
+ ubSlaveInfoIndex = SLAVE_CHIP_REVISION;
+ pSlaveTransmitBuffer = (uint8_t*)(aSlaveInfo[ubSlaveInfoIndex]);
+ }
+}
+
+/**
+ * @brief Function called from I2C IRQ Handler when STOP flag is set
+ * Function is in charge of checking data received,
+ * LED2 is On if data are correct.
+ * @param None
+ * @retval None
+ */
+void Slave_Complete_Callback(void)
+{
+ /* Clear and Reset process variables and arrays */
+ ubSlaveReceiveIndex = 0;
+ ubSlaveReceiveComplete = 0;
+ FlushBuffer8(aSlaveReceiveBuffer);
+}
+
+/**
+ * @brief DMA transfer complete callback
+ * @note This function is executed when the transfer complete interrupt
+ * is generated
+ * @retval None
+ */
+void Transfer_Complete_Callback()
+{
+ /* DMA transfer completed */
+ ubMasterTransferComplete = 1;
+}
+
+/**
+ * @brief DMA transfer error callback
+ * @note This function is executed when the transfer error interrupt
+ * is generated during DMA transfer
+ * @retval None
+ */
+void Transfer_Error_Callback()
+{
+ /* Disable DMA1_Channel2_IRQn */
+ NVIC_DisableIRQ(DMA1_Channel2_IRQn);
+
+ /* Error detected during DMA transfer */
+ LED_Blinking(LED_BLINK_ERROR);
+}
+
+/**
+ * @brief Function called in case of error detected in I2C IT Handler
+ * @param None
+ * @retval None
+ */
+void Error_Callback(void)
+{
+ /* Disable I2C1_EV_IRQn */
+ NVIC_DisableIRQ(I2C1_EV_IRQn);
+
+ /* Disable I2C1_ER_IRQn */
+ NVIC_DisableIRQ(I2C1_ER_IRQn);
+
+ /* Unexpected event : Set LED2 to Blinking mode to indicate error occurs */
+ LED_Blinking(LED_BLINK_ERROR);
+}
+
+/* USER CODE END 4 */
+
+/**
+ * @brief This function is executed in case of error occurrence.
+ * @retval None
+ */
+void Error_Handler(void)
+{
+ /* USER CODE BEGIN Error_Handler_Debug */
+ /* User can add his own implementation to report the HAL error return state */
+
+ /* USER CODE END Error_Handler_Debug */
+}
+
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief Reports the name of the source file and the source line number
+ * where the assert_param error has occurred.
+ * @param file: pointer to the source file name
+ * @param line: assert_param error line source number
+ * @retval None
+ */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+ /* USER CODE BEGIN 6 */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END 6 */
+}
+#endif /* USE_FULL_ASSERT */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/