From 57d3836d938c246061e311aaafa6645ccc0d7ebb Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 23 Oct 2018 21:18:33 -0400 Subject: [PATCH 01/40] Change TIM_1_8_PERIOD_CLOCKS and add RCR --- Firmware/Board/v3/Inc/main.h | 3 ++- Firmware/Board/v3/Src/tim.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Firmware/Board/v3/Inc/main.h b/Firmware/Board/v3/Inc/main.h index 0a307122..ec9aa17d 100644 --- a/Firmware/Board/v3/Inc/main.h +++ b/Firmware/Board/v3/Inc/main.h @@ -67,12 +67,13 @@ /* Private define ------------------------------------------------------------*/ #define TIM_1_8_CLOCK_HZ 168000000 -#define TIM_1_8_PERIOD_CLOCKS 10192 +#define TIM_1_8_PERIOD_CLOCKS 3500 #define TIM_1_8_DEADTIME_CLOCKS 20 #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 #define configAPPLICATION_ALLOCATED_HEAP 1 +#define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 #define M0_nCS_GPIO_Port GPIOC diff --git a/Firmware/Board/v3/Src/tim.c b/Firmware/Board/v3/Src/tim.c index 7b159ea5..a909cf2a 100644 --- a/Firmware/Board/v3/Src/tim.c +++ b/Firmware/Board/v3/Src/tim.c @@ -94,7 +94,7 @@ void MX_TIM1_Init(void) htim1.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3; htim1.Init.Period = TIM_1_8_PERIOD_CLOCKS; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim1.Init.RepetitionCounter = 0; + htim1.Init.RepetitionCounter = TIM_1_8_RCR; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); @@ -324,7 +324,7 @@ void MX_TIM8_Init(void) htim8.Init.CounterMode = TIM_COUNTERMODE_CENTERALIGNED3; htim8.Init.Period = TIM_1_8_PERIOD_CLOCKS; htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; - htim8.Init.RepetitionCounter = 0; + htim8.Init.RepetitionCounter = TIM_1_8_RCR; if (HAL_TIM_PWM_Init(&htim8) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); From 074b04243c176062e14b7cd81e61f0733964301f Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 23 Oct 2018 21:35:04 -0400 Subject: [PATCH 02/40] Update the current control loop speed --- Firmware/Board/v3/Inc/main.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Board/v3/Inc/main.h b/Firmware/Board/v3/Inc/main.h index ec9aa17d..6dfbd301 100644 --- a/Firmware/Board/v3/Inc/main.h +++ b/Firmware/Board/v3/Inc/main.h @@ -169,8 +169,8 @@ //TODO: make this come automatically out of CubeMX somehow #define TIM_TIME_BASE TIM14 -#define CURRENT_MEAS_PERIOD ((float)(2*TIM_1_8_PERIOD_CLOCKS)/(float)TIM_1_8_CLOCK_HZ) -#define CURRENT_MEAS_HZ (TIM_1_8_CLOCK_HZ/(2*TIM_1_8_PERIOD_CLOCKS)) +#define CURRENT_MEAS_PERIOD ((float)(2.0f*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)/(float)TIM_1_8_CLOCK_HZ)) +#define CURRENT_MEAS_HZ ((float)(TIM_1_8_CLOCK_HZ/(2.0f*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)))) #if HW_VERSION_VOLTAGE == 48 #define VBUS_S_DIVIDER_RATIO 19.0f From b8b41867316ad2d8768ba4d658e85a42d7af570c Mon Sep 17 00:00:00 2001 From: Unknown Date: Tue, 23 Oct 2018 21:43:58 -0400 Subject: [PATCH 03/40] Make sure old board revs use the same defines --- Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h | 3 ++- Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h | 3 ++- Firmware/Board/v3/Odrive.ioc | 12 ++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h index bd3f6305..567fe028 100644 --- a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h +++ b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h @@ -1,12 +1,13 @@ /* Private define ------------------------------------------------------------*/ #define TIM_1_8_CLOCK_HZ 168000000 -#define TIM_1_8_PERIOD_CLOCKS 10192 +#define TIM_1_8_PERIOD_CLOCKS 3500 #define TIM_1_8_DEADTIME_CLOCKS 20 #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 #define configAPPLICATION_ALLOCATED_HEAP 1 +#define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 #define M0_nCS_GPIO_Port GPIOC diff --git a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h index 19428406..5695d700 100644 --- a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h +++ b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h @@ -1,12 +1,13 @@ /* Private define ------------------------------------------------------------*/ #define TIM_1_8_CLOCK_HZ 168000000 -#define TIM_1_8_PERIOD_CLOCKS 10192 +#define TIM_1_8_PERIOD_CLOCKS 3500 #define TIM_1_8_DEADTIME_CLOCKS 20 #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 #define configAPPLICATION_ALLOCATED_HEAP 1 +#define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 #define M0_nCS_GPIO_Port GPIOC diff --git a/Firmware/Board/v3/Odrive.ioc b/Firmware/Board/v3/Odrive.ioc index fa9ca5ac..707c3f2a 100644 --- a/Firmware/Board/v3/Odrive.ioc +++ b/Firmware/Board/v3/Odrive.ioc @@ -76,7 +76,7 @@ ADC3.SamplingTime-7\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES ADC3.SamplingTime-8\#ChannelInjectedConversion=ADC_SAMPLETIME_3CYCLES ADC3.ScanConvMode=DISABLE CAN1.AutoWakeUp=ENABLE -CAN1.CalculateTimeBit=2000 +CAN1.CalculateTimeBit=500 CAN1.CalculateTimeQuantum=166.66666666666669 CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,Prescaler,TimeSeg1,TimeSeg2,AutoWakeUp CAN1.Prescaler=7 @@ -207,7 +207,7 @@ Mcu.Pin8=PC3 Mcu.Pin9=PA0-WKUP Mcu.PinsNb=56 Mcu.ThirdPartyNb=0 -Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,10192;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;configAPPLICATION_ALLOCATED_HEAP,1 +Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;configAPPLICATION_ALLOCATED_HEAP,1;TIM_1_8_RCR,2 Mcu.UserName=STM32F405RGTx MxCube.Version=4.24.0 MxDb.Version=DB.4.0.240 @@ -450,6 +450,8 @@ ProjectManager.HeapSize=0x3C00 ProjectManager.KeepUserCode=true ProjectManager.LastFirmware=true ProjectManager.LibraryCopy=1 +ProjectManager.MainLocation=Src +ProjectManager.NoMain=false ProjectManager.PreviousToolchain=SW4STM32 ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=Odrive.ioc @@ -576,7 +578,7 @@ TIM1.Channel-PWM\ Generation2\ CH2\ CH2N=TIM_CHANNEL_2 TIM1.Channel-PWM\ Generation3\ CH3\ CH3N=TIM_CHANNEL_3 TIM1.CounterMode=TIM_COUNTERMODE_CENTERALIGNED3 TIM1.DeadTime=TIM_1_8_DEADTIME_CLOCKS -TIM1.IPParameters=Channel-PWM Generation2 CH2 CH2N,Channel-PWM Generation3 CH3 CH3N,OCNPolarity_1,OCNPolarity_2,OCNPolarity_3,CounterMode,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Period,DeadTime,OffStateRunMode,OffStateIDLEMode,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N +TIM1.IPParameters=Channel-PWM Generation2 CH2 CH2N,Channel-PWM Generation3 CH3 CH3N,OCNPolarity_1,OCNPolarity_2,OCNPolarity_3,CounterMode,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Period,DeadTime,OffStateRunMode,OffStateIDLEMode,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N,RepetitionCounter TIM1.OCMode_PWM-PWM\ Generation1\ CH1\ CH1N=TIM_OCMODE_PWM2 TIM1.OCMode_PWM-PWM\ Generation2\ CH2\ CH2N=TIM_OCMODE_PWM2 TIM1.OCMode_PWM-PWM\ Generation3\ CH3\ CH3N=TIM_OCMODE_PWM2 @@ -586,6 +588,7 @@ TIM1.OCNPolarity_3=TIM_OCNPOLARITY_HIGH TIM1.OffStateIDLEMode=TIM_OSSI_ENABLE TIM1.OffStateRunMode=TIM_OSSR_ENABLE TIM1.Period=TIM_1_8_PERIOD_CLOCKS +TIM1.RepetitionCounter=TIM_1_8_RCR TIM1.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 TIM2.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 @@ -624,13 +627,14 @@ TIM8.Channel-PWM\ Generation2\ CH2\ CH2N=TIM_CHANNEL_2 TIM8.Channel-PWM\ Generation3\ CH3\ CH3N=TIM_CHANNEL_3 TIM8.CounterMode=TIM_COUNTERMODE_CENTERALIGNED3 TIM8.DeadTime=TIM_1_8_DEADTIME_CLOCKS -TIM8.IPParameters=Channel-PWM Generation3 CH3 CH3N,Channel-PWM Generation2 CH2 CH2N,CounterMode,Period,OffStateRunMode,OffStateIDLEMode,DeadTime,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N +TIM8.IPParameters=Channel-PWM Generation3 CH3 CH3N,Channel-PWM Generation2 CH2 CH2N,CounterMode,Period,OffStateRunMode,OffStateIDLEMode,DeadTime,OCMode_PWM-PWM Generation1 CH1 CH1N,OCMode_PWM-PWM Generation2 CH2 CH2N,OCMode_PWM-PWM Generation3 CH3 CH3N,Channel-Output Compare4 No Output,TIM_MasterOutputTrigger,Channel-PWM Generation1 CH1 CH1N,RepetitionCounter TIM8.OCMode_PWM-PWM\ Generation1\ CH1\ CH1N=TIM_OCMODE_PWM2 TIM8.OCMode_PWM-PWM\ Generation2\ CH2\ CH2N=TIM_OCMODE_PWM2 TIM8.OCMode_PWM-PWM\ Generation3\ CH3\ CH3N=TIM_OCMODE_PWM2 TIM8.OffStateIDLEMode=TIM_OSSI_ENABLE TIM8.OffStateRunMode=TIM_OSSR_ENABLE TIM8.Period=TIM_1_8_PERIOD_CLOCKS +TIM8.RepetitionCounter=TIM_1_8_RCR TIM8.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE UART4.IPParameters=VirtualMode UART4.VirtualMode=Asynchronous From a3b6c6ea3ebbe40bdf170e37cd6fe5deac334163 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 19:29:17 -0700 Subject: [PATCH 04/40] Update main.h --- Firmware/Board/v3/Inc/main.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Board/v3/Inc/main.h b/Firmware/Board/v3/Inc/main.h index 6dfbd301..8a2bba13 100644 --- a/Firmware/Board/v3/Inc/main.h +++ b/Firmware/Board/v3/Inc/main.h @@ -169,8 +169,8 @@ //TODO: make this come automatically out of CubeMX somehow #define TIM_TIME_BASE TIM14 -#define CURRENT_MEAS_PERIOD ((float)(2.0f*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)/(float)TIM_1_8_CLOCK_HZ)) -#define CURRENT_MEAS_HZ ((float)(TIM_1_8_CLOCK_HZ/(2.0f*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)))) +#define CURRENT_MEAS_PERIOD ((float)(2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)/(float)TIM_1_8_CLOCK_HZ)) +#define CURRENT_MEAS_HZ ((float)(TIM_1_8_CLOCK_HZ/(2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)))) #if HW_VERSION_VOLTAGE == 48 #define VBUS_S_DIVIDER_RATIO 19.0f From 89f00992cbac105681122aa8df6ca48d8e7ebf5c Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 19:38:24 -0700 Subject: [PATCH 05/40] add the pc sampling profiler script --- Firmware/sampler.py | 124 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 Firmware/sampler.py diff --git a/Firmware/sampler.py b/Firmware/sampler.py new file mode 100644 index 00000000..08dc126e --- /dev/null +++ b/Firmware/sampler.py @@ -0,0 +1,124 @@ +#!/usr/bin/python2 + +# run openocd (0.9.0) with : +# $ openocd -f stlink-v2-1.cfg -f stm32f4x.cfg &> /dev/null" +# then run +# $ python2 sampler.py path_to_myelf_with_symbols + +import sys +import time +import telnetlib +import subprocess +from bisect import bisect_right +import operator + +class OpenOCDCMSampler(object): + + def __init__(self, host='localhost', port=4444): + + self.net = telnetlib.Telnet(host, port) + self.net.read_very_eager() + + self.table = [] + self.indexes = set() + + def __del__(self): + self.net.write(b'exit\r\n') + self.net.read_until(b'exit\r\n', 1) + self.net.close() + + def getpc(self): + + self.net.write(b'mrw 0xE000101C\r\n') + res = self.net.read_until(b'\r\n\r> ', 1) + + if res: + prefix = res[0:16] + num = res[16:-5] + res = res[-15:0] + + if prefix == b'mrw 0xE000101C\r\n': + return int(num) + + return 0 + + + def initSymbols(self, elf, readelf='arm-none-eabi-readelf'): + proc = subprocess.Popen([readelf, '-s', elf], stdout=subprocess.PIPE) + for line in proc.stdout.readlines(): + field = line.split() + # for i,txt in enumerate(field): + # print("{}, {}".format(i, txt)) + try: + if field[3] == b'FUNC': + addr = int(field[1], 16) - 1 # For some reason readelf dumps the func addr off by 1 + func = field[7] + size = int(field[2]) + if addr not in self.indexes: + self.table.append((addr, func, size)) + self.indexes.add(addr) + except IndexError: + pass + + self.table.sort() + self.addrs = [ x for (x, y, z) in self.table ] + + + def func(self, pc): + + if pc == 0 or pc == 0xFFFFFFFF: + return ('', 0) + + i = bisect_right(self.addrs, pc) + if i: + addr, symb, size = self.table[i-1] + if pc >= addr and pc <= addr + size: + return (symb, addr) + + return ('', 0) + + +if __name__ == '__main__': + + sampler = OpenOCDCMSampler('localhost', 4444) + sampler.initSymbols(sys.argv[1]) + + total = 0 + countmap = { } + pcmap = { } + start = time.time() + + try: + while True: + pc = sampler.getpc() + + if pc in pcmap: + pcmap[pc] += 1 + else: + pcmap[pc] = 1 + + func, addr = sampler.func(pc) + + if not addr: + continue + + if func in countmap: + countmap[func] += 1 + total += 1 + else: + countmap[func] = 1 + total += 1 + + cur = time.time() + if cur - start > 1.0: + tmp = sorted(countmap.items(), key=operator.itemgetter(1), reverse=True) + for k, v in tmp: + # print('{:05.2f}% {}'.format((v * 100.) / total, k)) + print('{:06.2f} clocks : {}'.format((v * 8192) / total, k)) + start = cur + print('{} Samples'.format(total)) + print('') + + except KeyboardInterrupt: + pcmap = sorted(pcmap.items(), key=operator.itemgetter(1), reverse=True) + pcmap = [(hex(addr), count) for addr, count in pcmap] From afce08b3ca931c42c143f67386891f7d4a1916f0 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 22:03:14 -0700 Subject: [PATCH 06/40] Update main.h --- Firmware/Board/v3/Inc/main.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Board/v3/Inc/main.h b/Firmware/Board/v3/Inc/main.h index 8a2bba13..1e76830d 100644 --- a/Firmware/Board/v3/Inc/main.h +++ b/Firmware/Board/v3/Inc/main.h @@ -169,8 +169,8 @@ //TODO: make this come automatically out of CubeMX somehow #define TIM_TIME_BASE TIM14 -#define CURRENT_MEAS_PERIOD ((float)(2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)/(float)TIM_1_8_CLOCK_HZ)) -#define CURRENT_MEAS_HZ ((float)(TIM_1_8_CLOCK_HZ/(2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)))) +#define CURRENT_MEAS_PERIOD ( (float)2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1) / (float)TIM_1_8_CLOCK_HZ ) +#define CURRENT_MEAS_HZ ( (float)(TIM_1_8_CLOCK_HZ) / (float)(2*TIM_1_8_PERIOD_CLOCKS*(TIM_1_8_RCR+1)) ) #if HW_VERSION_VOLTAGE == 48 #define VBUS_S_DIVIDER_RATIO 19.0f From 0c7171be72f6a07c36fcf68f631e2f4b71c7f220 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 22:14:25 -0700 Subject: [PATCH 07/40] update changelog --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 742c5300..2d918843 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,12 @@ # Unreleased Features Please add a note of your changes below this heading if you make a Pull Request. -## Fixed -* Would ERROR_CONTROL_DEADLINE_MISSED along with every ERROR_PHASE_RESISTANCE_OUT_OF_RANGE. - ### Changed -* renamed `axis.enable_step_dir` to `axis.step_dir_active` +* Increased switching frequency from around 8kHz to 24kHz. Control loops still run at 8kHz. +* Renamed `axis.enable_step_dir` to `axis.step_dir_active` + +## Fixed +* Would get ERROR_CONTROL_DEADLINE_MISSED along with every ERROR_PHASE_RESISTANCE_OUT_OF_RANGE. # Releases ## [0.4.6] - 2018-10-07 From 0f2d0deba8654f77cb9dbca67b60a4ffe176c9bd Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:16:26 -0700 Subject: [PATCH 08/40] Run STM32CubeMX v1.21 --- .../Inc/stm32f4xx_hal_def.h | 17 +- .../Inc/stm32f4xx_hal_flash_ramfunc.h | 8 +- .../Inc/stm32f4xx_hal_i2c.h | 649 -- .../Inc/stm32f4xx_hal_i2c_ex.h | 137 - .../STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c | 4 +- .../Src/stm32f4xx_hal_flash_ramfunc.c | 16 +- .../Src/stm32f4xx_hal_i2c.c | 5494 ----------------- .../Src/stm32f4xx_hal_i2c_ex.c | 204 - Firmware/Board/v3/Inc/FreeRTOSConfig.h | 3 +- Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h | 7 +- Firmware/Board/v3/Inc/tim.h | 5 +- Firmware/Board/v3/Inc/usbd_cdc_if.h | 2 +- Firmware/Board/v3/Inc/usbd_conf.h | 3 +- Firmware/Board/v3/Inc/usbd_desc.h | 3 +- .../Class/CDC/Inc/usbd_cdc.h | 39 +- .../Class/CDC/Src/usbd_cdc.c | 567 +- .../Core/Inc/usbd_def.h | 4 +- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c | 4 +- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 10 +- Firmware/Board/v3/Odrive.ioc | 10 +- Firmware/Board/v3/Src/can.c | 2 +- Firmware/Board/v3/Src/dma.c | 6 +- Firmware/Board/v3/Src/freertos.c | 52 +- Firmware/Board/v3/Src/main.c | 1 + Firmware/Board/v3/Src/stm32f4xx_hal_msp.c | 4 +- Firmware/Board/v3/Src/usbd_cdc_if.c | 12 +- Firmware/Board/v3/Src/usbd_conf.c | 24 +- Firmware/Board/v3/Src/usbd_desc.c | 25 +- 28 files changed, 352 insertions(+), 6960 deletions(-) delete mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h delete mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h delete mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c delete mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h index 06414648..6d5e5b22 100644 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_def.h @@ -70,6 +70,9 @@ typedef enum } HAL_LockTypeDef; /* Exported macro ------------------------------------------------------------*/ + +#define UNUSED(X) (void)X /* To avoid gcc/g++ warnings */ + #define HAL_MAX_DELAY 0xFFFFFFFFU #define HAL_IS_BIT_SET(REG, BIT) (((REG) & (BIT)) != RESET) @@ -79,9 +82,7 @@ typedef enum do{ \ (__HANDLE__)->__PPP_DMA_FIELD__ = &(__DMA_HANDLE__); \ (__DMA_HANDLE__).Parent = (__HANDLE__); \ - } while(0) - -#define UNUSED(x) ((void)(x)) + } while(0U) /** @brief Reset the Handle's State field. * @param __HANDLE__ specifies the Peripheral Handle. @@ -135,7 +136,7 @@ typedef enum /* Macro to get variable aligned on 4-bytes, for __ICCARM__ the directive "#pragma data_alignment=4" must be used instead */ #if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */ #ifndef __ALIGN_END - #define __ALIGN_END __attribute__ ((aligned (4))) +#define __ALIGN_END __attribute__ ((aligned (4))) #endif /* __ALIGN_END */ #ifndef __ALIGN_BEGIN #define __ALIGN_BEGIN @@ -146,7 +147,7 @@ typedef enum #endif /* __ALIGN_END */ #ifndef __ALIGN_BEGIN #if defined (__CC_ARM) /* ARM Compiler */ - #define __ALIGN_BEGIN __align(4) +#define __ALIGN_BEGIN __align(4) #elif defined (__ICCARM__) /* IAR Compiler */ #define __ALIGN_BEGIN #endif /* __CC_ARM */ @@ -167,14 +168,14 @@ typedef enum Available memory areas are declared in the 'Target' tab of the 'Options for Target' dialog. */ -#define __RAM_FUNC HAL_StatusTypeDef +#define __RAM_FUNC #elif defined ( __ICCARM__ ) /* ICCARM Compiler --------------- RAM functions are defined using a specific toolchain keyword "__ramfunc". */ -#define __RAM_FUNC __ramfunc HAL_StatusTypeDef +#define __RAM_FUNC __ramfunc #elif defined ( __GNUC__ ) /* GNU Compiler @@ -182,7 +183,7 @@ typedef enum RAM functions are defined using a specific toolchain attribute "__attribute__((section(".RamFunc")))". */ -#define __RAM_FUNC HAL_StatusTypeDef __attribute__((section(".RamFunc"))) +#define __RAM_FUNC __attribute__((section(".RamFunc"))) #endif diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h index 500d33ad..fa7e4906 100644 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_flash_ramfunc.h @@ -64,10 +64,10 @@ /** @addtogroup FLASH_RAMFUNC_Exported_Functions_Group1 * @{ */ -__RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void); -__RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void); -__RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void); -__RAM_FUNC HAL_FLASHEx_DisableFlashSleepMode(void); +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StopFlashInterfaceClk(void); +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StartFlashInterfaceClk(void); +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableFlashSleepMode(void); +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableFlashSleepMode(void); /** * @} */ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h deleted file mode 100644 index 5452a507..00000000 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h +++ /dev/null @@ -1,649 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_hal_i2c.h - * @author MCD Application Team - * @brief Header file of I2C HAL module. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_HAL_I2C_H -#define __STM32F4xx_HAL_I2C_H - -#ifdef __cplusplus - extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hal_def.h" - -/** @addtogroup STM32F4xx_HAL_Driver - * @{ - */ - -/** @addtogroup I2C - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/** @defgroup I2C_Exported_Types I2C Exported Types - * @{ - */ - -/** - * @brief I2C Configuration Structure definition - */ -typedef struct -{ - uint32_t ClockSpeed; /*!< Specifies the clock frequency. - This parameter must be set to a value lower than 400kHz */ - - uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle. - This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ - - uint32_t OwnAddress1; /*!< Specifies the first device own address. - This parameter can be a 7-bit or 10-bit address. */ - - uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. - This parameter can be a value of @ref I2C_addressing_mode */ - - uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. - This parameter can be a value of @ref I2C_dual_addressing_mode */ - - uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected - This parameter can be a 7-bit address. */ - - uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. - This parameter can be a value of @ref I2C_general_call_addressing_mode */ - - uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. - This parameter can be a value of @ref I2C_nostretch_mode */ - -}I2C_InitTypeDef; - -/** - * @brief HAL State structure definition - * @note HAL I2C State value coding follow below described bitmap : - * b7-b6 Error information - * 00 : No Error - * 01 : Abort (Abort user request on going) - * 10 : Timeout - * 11 : Error - * b5 IP initilisation status - * 0 : Reset (IP not initialized) - * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called) - * b4 (not used) - * x : Should be set to 0 - * b3 - * 0 : Ready or Busy (No Listen mode ongoing) - * 1 : Listen (IP in Address Listen Mode) - * b2 Intrinsic process state - * 0 : Ready - * 1 : Busy (IP busy with some configuration or internal operations) - * b1 Rx state - * 0 : Ready (no Rx operation ongoing) - * 1 : Busy (Rx operation ongoing) - * b0 Tx state - * 0 : Ready (no Tx operation ongoing) - * 1 : Busy (Tx operation ongoing) - */ -typedef enum -{ - HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ - HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ - HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ - HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ - HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ - HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ - HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission - process is ongoing */ - HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception - process is ongoing */ - HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ - HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ - HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ - -}HAL_I2C_StateTypeDef; - -/** - * @brief HAL Mode structure definition - * @note HAL I2C Mode value coding follow below described bitmap : - * b7 (not used) - * x : Should be set to 0 - * b6 - * 0 : None - * 1 : Memory (HAL I2C communication is in Memory Mode) - * b5 - * 0 : None - * 1 : Slave (HAL I2C communication is in Slave Mode) - * b4 - * 0 : None - * 1 : Master (HAL I2C communication is in Master Mode) - * b3-b2-b1-b0 (not used) - * xxxx : Should be set to 0000 - */ -typedef enum -{ - HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ - HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ - HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ - HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ - -}HAL_I2C_ModeTypeDef; - -/** - * @brief I2C handle Structure definition - */ -typedef struct -{ - I2C_TypeDef *Instance; /*!< I2C registers base address */ - - I2C_InitTypeDef Init; /*!< I2C communication parameters */ - - uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ - - uint16_t XferSize; /*!< I2C transfer size */ - - __IO uint16_t XferCount; /*!< I2C transfer counter */ - - __IO uint32_t XferOptions; /*!< I2C transfer options */ - - __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode - context for internal usage */ - - DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ - - DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ - - HAL_LockTypeDef Lock; /*!< I2C locking object */ - - __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ - - __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ - - __IO uint32_t ErrorCode; /*!< I2C Error code */ - - __IO uint32_t Devaddress; /*!< I2C Target device address */ - - __IO uint32_t Memaddress; /*!< I2C Target memory address */ - - __IO uint32_t MemaddSize; /*!< I2C Target memory address size */ - - __IO uint32_t EventCount; /*!< I2C Event counter */ - -}I2C_HandleTypeDef; - -/** - * @} - */ - -/* Exported constants --------------------------------------------------------*/ -/** @defgroup I2C_Exported_Constants I2C Exported Constants - * @{ - */ - -/** @defgroup I2C_Error_Code I2C Error Code - * @brief I2C Error Code - * @{ - */ -#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */ -#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */ -#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */ -#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */ -#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */ -#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */ -#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */ -/** - * @} - */ - -/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode - * @{ - */ -#define I2C_DUTYCYCLE_2 0x00000000U -#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY -/** - * @} - */ - -/** @defgroup I2C_addressing_mode I2C addressing mode - * @{ - */ -#define I2C_ADDRESSINGMODE_7BIT 0x00004000U -#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U) -/** - * @} - */ - -/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode - * @{ - */ -#define I2C_DUALADDRESS_DISABLE 0x00000000U -#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL -/** - * @} - */ - -/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode - * @{ - */ -#define I2C_GENERALCALL_DISABLE 0x00000000U -#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC -/** - * @} - */ - -/** @defgroup I2C_nostretch_mode I2C nostretch mode - * @{ - */ -#define I2C_NOSTRETCH_DISABLE 0x00000000U -#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH -/** - * @} - */ - -/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size - * @{ - */ -#define I2C_MEMADD_SIZE_8BIT 0x00000001U -#define I2C_MEMADD_SIZE_16BIT 0x00000010U -/** - * @} - */ - -/** @defgroup I2C_XferDirection_definition I2C XferDirection definition - * @{ - */ -#define I2C_DIRECTION_RECEIVE 0x00000000U -#define I2C_DIRECTION_TRANSMIT 0x00000001U -/** - * @} - */ - -/** @defgroup I2C_XferOptions_definition I2C XferOptions definition - * @{ - */ -#define I2C_FIRST_FRAME 0x00000001U -#define I2C_NEXT_FRAME 0x00000002U -#define I2C_FIRST_AND_LAST_FRAME 0x00000004U -#define I2C_LAST_FRAME 0x00000008U -/** - * @} - */ - -/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition - * @{ - */ -#define I2C_IT_BUF I2C_CR2_ITBUFEN -#define I2C_IT_EVT I2C_CR2_ITEVTEN -#define I2C_IT_ERR I2C_CR2_ITERREN -/** - * @} - */ - -/** @defgroup I2C_Flag_definition I2C Flag definition - * @{ - */ -#define I2C_FLAG_SMBALERT 0x00018000U -#define I2C_FLAG_TIMEOUT 0x00014000U -#define I2C_FLAG_PECERR 0x00011000U -#define I2C_FLAG_OVR 0x00010800U -#define I2C_FLAG_AF 0x00010400U -#define I2C_FLAG_ARLO 0x00010200U -#define I2C_FLAG_BERR 0x00010100U -#define I2C_FLAG_TXE 0x00010080U -#define I2C_FLAG_RXNE 0x00010040U -#define I2C_FLAG_STOPF 0x00010010U -#define I2C_FLAG_ADD10 0x00010008U -#define I2C_FLAG_BTF 0x00010004U -#define I2C_FLAG_ADDR 0x00010002U -#define I2C_FLAG_SB 0x00010001U -#define I2C_FLAG_DUALF 0x00100080U -#define I2C_FLAG_SMBHOST 0x00100040U -#define I2C_FLAG_SMBDEFAULT 0x00100020U -#define I2C_FLAG_GENCALL 0x00100010U -#define I2C_FLAG_TRA 0x00100004U -#define I2C_FLAG_BUSY 0x00100002U -#define I2C_FLAG_MSL 0x00100001U -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/** @defgroup I2C_Exported_Macros I2C Exported Macros - * @{ - */ - -/** @brief Reset I2C handle state - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. - * @retval None - */ -#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) - -/** @brief Enable or disable the specified I2C interrupts. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. - * @param __INTERRUPT__ specifies the interrupt source to enable or disable. - * This parameter can be one of the following values: - * @arg I2C_IT_BUF: Buffer interrupt enable - * @arg I2C_IT_EVT: Event interrupt enable - * @arg I2C_IT_ERR: Error interrupt enable - * @retval None - */ -#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) -#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) - -/** @brief Checks if the specified I2C interrupt source is enabled or disabled. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. - * @param __INTERRUPT__ specifies the I2C interrupt source to check. - * This parameter can be one of the following values: - * @arg I2C_IT_BUF: Buffer interrupt enable - * @arg I2C_IT_EVT: Event interrupt enable - * @arg I2C_IT_ERR: Error interrupt enable - * @retval The new state of __INTERRUPT__ (TRUE or FALSE). - */ -#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) - -/** @brief Checks whether the specified I2C flag is set or not. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. - * @param __FLAG__ specifies the flag to check. - * This parameter can be one of the following values: - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag - * @arg I2C_FLAG_BERR: Bus error flag - * @arg I2C_FLAG_TXE: Data register empty flag - * @arg I2C_FLAG_RXNE: Data register not empty flag - * @arg I2C_FLAG_STOPF: Stop detection flag - * @arg I2C_FLAG_ADD10: 10-bit header sent flag - * @arg I2C_FLAG_BTF: Byte transfer finished flag - * @arg I2C_FLAG_ADDR: Address sent flag - * Address matched flag - * @arg I2C_FLAG_SB: Start bit flag - * @arg I2C_FLAG_DUALF: Dual flag - * @arg I2C_FLAG_SMBHOST: SMBus host header - * @arg I2C_FLAG_SMBDEFAULT: SMBus default header - * @arg I2C_FLAG_GENCALL: General call header flag - * @arg I2C_FLAG_TRA: Transmitter/Receiver flag - * @arg I2C_FLAG_BUSY: Bus busy flag - * @arg I2C_FLAG_MSL: Master/Slave flag - * @retval The new state of __FLAG__ (TRUE or FALSE). - */ -#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \ - ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) - -/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. - * @param __FLAG__ specifies the flag to clear. - * This parameter can be any combination of the following values: - * @arg I2C_FLAG_SMBALERT: SMBus Alert flag - * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag - * @arg I2C_FLAG_PECERR: PEC error in reception flag - * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) - * @arg I2C_FLAG_AF: Acknowledge failure flag - * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) - * @arg I2C_FLAG_BERR: Bus error flag - * @retval None - */ -#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK)) - -/** @brief Clears the I2C ADDR pending flag. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. - * @retval None - */ -#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \ - do{ \ - __IO uint32_t tmpreg = 0x00U; \ - tmpreg = (__HANDLE__)->Instance->SR1; \ - tmpreg = (__HANDLE__)->Instance->SR2; \ - UNUSED(tmpreg); \ - } while(0) - -/** @brief Clears the I2C STOPF pending flag. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. - * @retval None - */ -#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \ - do{ \ - __IO uint32_t tmpreg = 0x00U; \ - tmpreg = (__HANDLE__)->Instance->SR1; \ - (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \ - UNUSED(tmpreg); \ - } while(0) - -/** @brief Enable the I2C peripheral. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. - * @retval None - */ -#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) - -/** @brief Disable the I2C peripheral. - * @param __HANDLE__ specifies the I2C Handle. - * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. - * @retval None - */ -#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE) - -/** - * @} - */ - -/* Include I2C HAL Extension module */ -#include "stm32f4xx_hal_i2c_ex.h" - -/* Exported functions --------------------------------------------------------*/ -/** @addtogroup I2C_Exported_Functions - * @{ - */ - -/** @addtogroup I2C_Exported_Functions_Group1 - * @{ - */ -/* Initialization/de-initialization functions **********************************/ -HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); -HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c); -void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); -void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); -/** - * @} - */ - -/** @addtogroup I2C_Exported_Functions_Group2 - * @{ - */ -/* I/O operation functions *****************************************************/ -/******* Blocking mode: Polling */ -HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); -HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); - -/******* Non-Blocking mode: Interrupt */ -HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); - -HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); -HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); -HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); - -/******* Non-Blocking mode: DMA */ -HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); - -/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ -void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); -void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); -void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); -void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); -void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); -/** - * @} - */ - -/** @addtogroup I2C_Exported_Functions_Group3 - * @{ - */ -/* Peripheral State, Mode and Errors functions *********************************/ -HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c); -HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c); -uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); - -/** - * @} - */ - -/** - * @} - */ -/* Private types -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private constants ---------------------------------------------------------*/ -/** @defgroup I2C_Private_Constants I2C Private Constants - * @{ - */ -#define I2C_FLAG_MASK 0x0000FFFFU -/** - * @} - */ - -/* Private macros ------------------------------------------------------------*/ -/** @defgroup I2C_Private_Macros I2C Private Macros - * @{ - */ - -#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U) -#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U)) -#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) -#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__PCLK__) / ((__SPEED__) * 25U)) | I2C_DUTYCYCLE_16_9)) -#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \ - ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \ - ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS)) - -#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0))) -#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0)) - -#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) -#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0))) -#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1)))) - -#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8))) -#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) - -/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters - * @{ - */ -#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \ - ((CYCLE) == I2C_DUTYCYCLE_16_9)) -#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \ - ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT)) -#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ - ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) -#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ - ((CALL) == I2C_GENERALCALL_ENABLE)) -#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ - ((STRETCH) == I2C_NOSTRETCH_ENABLE)) -#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ - ((SIZE) == I2C_MEMADD_SIZE_16BIT)) -#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0U) && ((SPEED) <= 400000U)) -#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & 0xFFFFFC00U) == 0U) -#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & 0xFFFFFF01U) == 0U) -#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ - ((REQUEST) == I2C_NEXT_FRAME) || \ - ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ - ((REQUEST) == I2C_LAST_FRAME)) -/** - * @} - */ - -/** - * @} - */ - -/* Private functions ---------------------------------------------------------*/ -/** @defgroup I2C_Private_Functions I2C Private Functions - * @{ - */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - - -#endif /* __STM32F4xx_HAL_I2C_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h deleted file mode 100644 index ff47d5cc..00000000 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h +++ /dev/null @@ -1,137 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_hal_i2c_ex.h - * @author MCD Application Team - * @brief Header file of I2C HAL Extension module. - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32F4xx_HAL_I2C_EX_H -#define __STM32F4xx_HAL_I2C_EX_H - -#ifdef __cplusplus - extern "C" { -#endif - -#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ - defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ - defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hal_def.h" - -/** @addtogroup STM32F4xx_HAL_Driver - * @{ - */ - -/** @addtogroup I2CEx - * @{ - */ - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ -/** @defgroup I2CEx_Exported_Constants I2C Exported Constants - * @{ - */ - -/** @defgroup I2CEx_Analog_Filter I2C Analog Filter - * @{ - */ -#define I2C_ANALOGFILTER_ENABLE 0x00000000U -#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF -/** - * @} - */ - -/** - * @} - */ - -/* Exported macro ------------------------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ -/** @addtogroup I2CEx_Exported_Functions - * @{ - */ - -/** @addtogroup I2CEx_Exported_Functions_Group1 - * @{ - */ -/* Peripheral Control functions ************************************************/ -HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); -HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); -/** - * @} - */ - -/** - * @} - */ -/* Private types -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private constants ---------------------------------------------------------*/ -/** @defgroup I2CEx_Private_Constants I2C Private Constants - * @{ - */ - -/** - * @} - */ - -/* Private macros ------------------------------------------------------------*/ -/** @defgroup I2CEx_Private_Macros I2C Private Macros - * @{ - */ -#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ - ((FILTER) == I2C_ANALOGFILTER_DISABLE)) -#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ - STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx ||\ - STM32F413xx || STM32F423xx */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32F4xx_HAL_I2C_EX_H */ - - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c index bf966f9a..1d6da26b 100644 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c @@ -66,11 +66,11 @@ * @{ */ /** - * @brief STM32F4xx HAL Driver version number V1.7.3 + * @brief STM32F4xx HAL Driver version number V1.7.4 */ #define __STM32F4xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */ #define __STM32F4xx_HAL_VERSION_SUB1 (0x07U) /*!< [23:16] sub1 version */ -#define __STM32F4xx_HAL_VERSION_SUB2 (0x03U) /*!< [15:8] sub2 version */ +#define __STM32F4xx_HAL_VERSION_SUB2 (0x04U) /*!< [15:8] sub2 version */ #define __STM32F4xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */ #define __STM32F4xx_HAL_VERSION ((__STM32F4xx_HAL_VERSION_MAIN << 24U)\ |(__STM32F4xx_HAL_VERSION_SUB1 << 16U)\ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c index fab41154..b896d072 100644 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ramfunc.c @@ -107,9 +107,9 @@ * @note This mode is only available for STM32F41xxx/STM32F446xx devices. * @note This mode couldn't be set while executing with the flash itself. * It should be done with specific routine executed from RAM. - * @retval None + * @retval HAL status */ -__RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void) +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StopFlashInterfaceClk(void) { /* Enable Power ctrl clock */ __HAL_RCC_PWR_CLK_ENABLE(); @@ -124,9 +124,9 @@ __RAM_FUNC HAL_FLASHEx_StopFlashInterfaceClk(void) * @note This mode is only available for STM32F411xx/STM32F446xx devices. * @note This mode couldn't be set while executing with the flash itself. * It should be done with specific routine executed from RAM. - * @retval None + * @retval HAL status */ -__RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void) +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_StartFlashInterfaceClk(void) { /* Enable Power ctrl clock */ __HAL_RCC_PWR_CLK_ENABLE(); @@ -141,9 +141,9 @@ __RAM_FUNC HAL_FLASHEx_StartFlashInterfaceClk(void) * @note This mode is only available for STM32F41xxx/STM32F446xx devices. * @note This mode could n't be set while executing with the flash itself. * It should be done with specific routine executed from RAM. - * @retval None + * @retval HAL status */ -__RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void) +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_EnableFlashSleepMode(void) { /* Enable Power ctrl clock */ __HAL_RCC_PWR_CLK_ENABLE(); @@ -158,9 +158,9 @@ __RAM_FUNC HAL_FLASHEx_EnableFlashSleepMode(void) * @note This mode is only available for STM32F41xxx/STM32F446xx devices. * @note This mode couldn't be set while executing with the flash itself. * It should be done with specific routine executed from RAM. - * @retval None + * @retval HAL status */ -__RAM_FUNC HAL_FLASHEx_DisableFlashSleepMode(void) +__RAM_FUNC HAL_StatusTypeDef HAL_FLASHEx_DisableFlashSleepMode(void) { /* Enable Power ctrl clock */ __HAL_RCC_PWR_CLK_ENABLE(); diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c deleted file mode 100644 index da185200..00000000 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c +++ /dev/null @@ -1,5494 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_hal_i2c.c - * @author MCD Application Team - * @brief I2C HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of the Inter Integrated Circuit (I2C) peripheral: - * + Initialization and de-initialization functions - * + IO operation functions - * + Peripheral State, Mode and Error functions - * - @verbatim - ============================================================================== - ##### How to use this driver ##### - ============================================================================== - [..] - The I2C HAL driver can be used as follows: - - (#) Declare a I2C_HandleTypeDef handle structure, for example: - I2C_HandleTypeDef hi2c; - - (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API: - (##) Enable the I2Cx interface clock - (##) I2C pins configuration - (+++) Enable the clock for the I2C GPIOs - (+++) Configure I2C pins as alternate function open-drain - (##) NVIC configuration if you need to use interrupt process - (+++) Configure the I2Cx interrupt priority - (+++) Enable the NVIC I2C IRQ Channel - (##) DMA Configuration if you need to use DMA process - (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream - (+++) Enable the DMAx interface clock using - (+++) Configure the DMA handle parameters - (+++) Configure the DMA Tx or Rx Stream - (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle - (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on - the DMA Tx or Rx Stream - - (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1, - Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure. - - (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware - (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API. - - (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady() - - (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : - - *** Polling mode IO operation *** - ================================= - [..] - (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit() - (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive() - (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit() - (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive() - - *** Polling mode IO MEM operation *** - ===================================== - [..] - (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write() - (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read() - - - *** Interrupt mode IO operation *** - =================================== - [..] - (+) Transmit in master mode an amount of data in non blocking mode using HAL_I2C_Master_Transmit_IT() - (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback - (+) Receive in master mode an amount of data in non blocking mode using HAL_I2C_Master_Receive_IT() - (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback - (+) Transmit in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Transmit_IT() - (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback - (+) Receive in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Receive_IT() - (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback - (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_I2C_ErrorCallback - (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() - (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() - - *** Interrupt mode IO sequential operation *** - ============================================== - [..] - (@) These interfaces allow to manage a sequential transfer with a repeated start condition - when a direction change during transfer - [..] - (+) A specific option field manage the different steps of a sequential transfer - (+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below: - (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode - (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address - and data to transfer without a final stop condition - (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address - and with new data to transfer if the direction change or manage only the new data to transfer - if no direction change and without a final stop condition in both cases - (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address - and with new data to transfer if the direction change or manage only the new data to transfer - if no direction change and with a final stop condition in both cases - - (+) Differents sequential I2C interfaces are listed below: - (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT() - (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() - (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Receive_IT() - (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() - (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() - (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() - (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT() - (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can - add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). - (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_ListenCpltCallback() - (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Transmit_IT() - (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() - (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Receive_IT() - (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() - (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_I2C_ErrorCallback() - (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() - (++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() - - *** Interrupt mode IO MEM operation *** - ======================================= - [..] - (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using - HAL_I2C_Mem_Write_IT() - (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback - (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using - HAL_I2C_Mem_Read_IT() - (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback - (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_I2C_ErrorCallback - - *** DMA mode IO operation *** - ============================== - [..] - (+) Transmit in master mode an amount of data in non blocking mode (DMA) using - HAL_I2C_Master_Transmit_DMA() - (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback - (+) Receive in master mode an amount of data in non blocking mode (DMA) using - HAL_I2C_Master_Receive_DMA() - (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback - (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using - HAL_I2C_Slave_Transmit_DMA() - (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback - (+) Receive in slave mode an amount of data in non blocking mode (DMA) using - HAL_I2C_Slave_Receive_DMA() - (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback - (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_I2C_ErrorCallback - (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() - (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can - add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() - - *** DMA mode IO MEM operation *** - ================================= - [..] - (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using - HAL_I2C_Mem_Write_DMA() - (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback - (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using - HAL_I2C_Mem_Read_DMA() - (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can - add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback - (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can - add his own code by customization of function pointer HAL_I2C_ErrorCallback - - - *** I2C HAL driver macros list *** - ================================== - [..] - Below the list of most used macros in I2C HAL driver. - - (+) __HAL_I2C_ENABLE: Enable the I2C peripheral - (+) __HAL_I2C_DISABLE: Disable the I2C peripheral - (+) __HAL_I2C_GET_FLAG : Checks whether the specified I2C flag is set or not - (+) __HAL_I2C_CLEAR_FLAG : Clear the specified I2C pending flag - (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt - (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt - - [..] - (@) You can refer to the I2C HAL driver header file for more useful macros - - - @endverbatim - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hal.h" - -/** @addtogroup STM32F4xx_HAL_Driver - * @{ - */ - -/** @defgroup I2C I2C - * @brief I2C HAL module driver - * @{ - */ - -#ifdef HAL_I2C_MODULE_ENABLED - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/** @addtogroup I2C_Private_Define - * @{ - */ -#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */ -#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */ -#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ - -/* Private define for @ref PreviousState usage */ -#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(uint32_t)HAL_I2C_STATE_READY))) /*!< Mask State define, keep only RX and TX bits */ -#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */ -#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ -#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ -#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ -#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ - -/** - * @} - */ - -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/** @addtogroup I2C_Private_Functions - * @{ - */ -/* Private functions to handle DMA transfer */ -static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma); -static void I2C_DMAError(DMA_HandleTypeDef *hdma); -static void I2C_DMAAbort(DMA_HandleTypeDef *hdma); - -static void I2C_ITError(I2C_HandleTypeDef *hi2c); - -static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c); - -/* Private functions for I2C transfer IRQ handler */ -static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c); - -static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); -static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c); -/** - * @} - */ - -/* Exported functions --------------------------------------------------------*/ -/** @defgroup I2C_Exported_Functions I2C Exported Functions - * @{ - */ - -/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions - * @brief Initialization and Configuration functions - * -@verbatim - =============================================================================== - ##### Initialization and de-initialization functions ##### - =============================================================================== - [..] This subsection provides a set of functions allowing to initialize and - de-initialize the I2Cx peripheral: - - (+) User must Implement HAL_I2C_MspInit() function in which he configures - all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC). - - (+) Call the function HAL_I2C_Init() to configure the selected device with - the selected configuration: - (++) Communication Speed - (++) Duty cycle - (++) Addressing mode - (++) Own Address 1 - (++) Dual Addressing mode - (++) Own Address 2 - (++) General call mode - (++) Nostretch mode - - (+) Call the function HAL_I2C_DeInit() to restore the default configuration - of the selected I2Cx peripheral. - -@endverbatim - * @{ - */ - -/** - * @brief Initializes the I2C according to the specified parameters - * in the I2C_InitTypeDef and create the associated handle. - * @param hi2c pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) -{ - uint32_t freqrange = 0U; - uint32_t pclk1 = 0U; - - /* Check the I2C handle allocation */ - if(hi2c == NULL) - { - return HAL_ERROR; - } - - /* Check the parameters */ - assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); - assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed)); - assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle)); - assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); - assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); - assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); - assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); - assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); - assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); - - if(hi2c->State == HAL_I2C_STATE_RESET) - { - /* Allocate lock resource and initialize it */ - hi2c->Lock = HAL_UNLOCKED; - /* Init the low level hardware : GPIO, CLOCK, NVIC */ - HAL_I2C_MspInit(hi2c); - } - - hi2c->State = HAL_I2C_STATE_BUSY; - - /* Disable the selected I2C peripheral */ - __HAL_I2C_DISABLE(hi2c); - - /* Get PCLK1 frequency */ - pclk1 = HAL_RCC_GetPCLK1Freq(); - - /* Calculate frequency range */ - freqrange = I2C_FREQRANGE(pclk1); - - /*---------------------------- I2Cx CR2 Configuration ----------------------*/ - /* Configure I2Cx: Frequency range */ - hi2c->Instance->CR2 = freqrange; - - /*---------------------------- I2Cx TRISE Configuration --------------------*/ - /* Configure I2Cx: Rise Time */ - hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); - - /*---------------------------- I2Cx CCR Configuration ----------------------*/ - /* Configure I2Cx: Speed */ - hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); - - /*---------------------------- I2Cx CR1 Configuration ----------------------*/ - /* Configure I2Cx: Generalcall and NoStretch mode */ - hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); - - /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ - /* Configure I2Cx: Own Address1 and addressing mode */ - hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); - - /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ - /* Configure I2Cx: Dual mode and Own Address2 */ - hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2); - - /* Enable the selected I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - hi2c->State = HAL_I2C_STATE_READY; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->Mode = HAL_I2C_MODE_NONE; - - return HAL_OK; -} - -/** - * @brief DeInitializes the I2C peripheral. - * @param hi2c pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) -{ - /* Check the I2C handle allocation */ - if(hi2c == NULL) - { - return HAL_ERROR; - } - - /* Check the parameters */ - assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); - - hi2c->State = HAL_I2C_STATE_BUSY; - - /* Disable the I2C Peripheral Clock */ - __HAL_I2C_DISABLE(hi2c); - - /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ - HAL_I2C_MspDeInit(hi2c); - - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - hi2c->State = HAL_I2C_STATE_RESET; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Release Lock */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; -} - -/** - * @brief I2C MSP Init. - * @param hi2c pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval None - */ - __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_I2C_MspInit could be implemented in the user file - */ -} - -/** - * @brief I2C MSP DeInit - * @param hi2c pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval None - */ - __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - /* NOTE : This function Should not be modified, when the callback is needed, - the HAL_I2C_MspDeInit could be implemented in the user file - */ -} - -/** - * @} - */ - -/** @defgroup I2C_Exported_Functions_Group2 IO operation functions - * @brief Data transfers functions - * -@verbatim - =============================================================================== - ##### IO operation functions ##### - =============================================================================== - [..] - This subsection provides a set of functions allowing to manage the I2C data - transfers. - - (#) There are two modes of transfer: - (++) Blocking mode : The communication is performed in the polling mode. - The status of all data processing is returned by the same function - after finishing transfer. - (++) No-Blocking mode : The communication is performed using Interrupts - or DMA. These functions return the status of the transfer startup. - The end of the data processing will be indicated through the - dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when - using DMA mode. - - (#) Blocking mode functions are : - (++) HAL_I2C_Master_Transmit() - (++) HAL_I2C_Master_Receive() - (++) HAL_I2C_Slave_Transmit() - (++) HAL_I2C_Slave_Receive() - (++) HAL_I2C_Mem_Write() - (++) HAL_I2C_Mem_Read() - (++) HAL_I2C_IsDeviceReady() - - (#) No-Blocking mode functions with Interrupt are : - (++) HAL_I2C_Master_Transmit_IT() - (++) HAL_I2C_Master_Receive_IT() - (++) HAL_I2C_Slave_Transmit_IT() - (++) HAL_I2C_Slave_Receive_IT() - (++) HAL_I2C_Master_Sequential_Transmit_IT() - (++) HAL_I2C_Master_Sequential_Receive_IT() - (++) HAL_I2C_Slave_Sequential_Transmit_IT() - (++) HAL_I2C_Slave_Sequential_Receive_IT() - (++) HAL_I2C_Mem_Write_IT() - (++) HAL_I2C_Mem_Read_IT() - - (#) No-Blocking mode functions with DMA are : - (++) HAL_I2C_Master_Transmit_DMA() - (++) HAL_I2C_Master_Receive_DMA() - (++) HAL_I2C_Slave_Transmit_DMA() - (++) HAL_I2C_Slave_Receive_DMA() - (++) HAL_I2C_Mem_Write_DMA() - (++) HAL_I2C_Mem_Read_DMA() - - (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: - (++) HAL_I2C_MemTxCpltCallback() - (++) HAL_I2C_MemRxCpltCallback() - (++) HAL_I2C_MasterTxCpltCallback() - (++) HAL_I2C_MasterRxCpltCallback() - (++) HAL_I2C_SlaveTxCpltCallback() - (++) HAL_I2C_SlaveRxCpltCallback() - (++) HAL_I2C_ErrorCallback() - (++) HAL_I2C_AbortCpltCallback() - -@endverbatim - * @{ - */ - -/** - * @brief Transmits in master mode an amount of data in blocking mode. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_BUSY; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Send Slave Address */ - if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - while(hi2c->XferSize > 0U) - { - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - hi2c->XferSize--; - - if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - hi2c->XferSize--; - } - - /* Wait until BTF flag is set */ - if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - } - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receives in master mode an amount of data in blocking mode. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_BUSY; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Send Slave Address */ - if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - if(hi2c->XferSize == 0U) - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - else if(hi2c->XferSize == 1U) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - else if(hi2c->XferSize == 2U) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Enable Pos */ - hi2c->Instance->CR1 |= I2C_CR1_POS; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - else - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - - while(hi2c->XferSize > 0U) - { - if(hi2c->XferSize <= 3U) - { - /* One byte */ - if(hi2c->XferSize == 1U) - { - /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) - { - return HAL_TIMEOUT; - } - else - { - return HAL_ERROR; - } - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - /* Two bytes */ - else if(hi2c->XferSize == 2U) - { - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - /* 3 Last bytes */ - else - { - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - } - else - { - /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) - { - return HAL_TIMEOUT; - } - else - { - return HAL_ERROR; - } - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - } - } - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Transmits in slave mode an amount of data in blocking mode. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Enable Address Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* If 10bit addressing mode is selected */ - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) - { - /* Wait until ADDR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - - while(hi2c->XferSize > 0U) - { - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - /* Disable Address Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - hi2c->XferSize--; - - if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - hi2c->XferSize--; - } - } - - /* Wait until AF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Clear AF flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - /* Disable Address Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive in slave mode an amount of data in blocking mode - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if((pData == NULL) || (Size == 0)) - { - return HAL_ERROR; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Enable Address Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - while(hi2c->XferSize > 0U) - { - /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - /* Disable Address Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) - { - return HAL_TIMEOUT; - } - else - { - return HAL_ERROR; - } - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - } - - /* Wait until STOP flag is set */ - if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - /* Disable Address Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Clear STOP flag */ - __HAL_I2C_CLEAR_STOPFLAG(hi2c); - - /* Disable Address Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - hi2c->Devaddress = DevAddress; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - hi2c->Devaddress = DevAddress; - - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Sequential transmit in master mode an amount of data in non-blocking mode with Interrupt - * @note This interface allow to manage repeated start condition when a direction change during transfer - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -{ - __IO uint32_t Prev_State = 0x00U; - __IO uint32_t count = 0x00U; - - /* Check the parameters */ - assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Check Busy Flag only if FIRST call of Master interface */ - if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = XferOptions; - hi2c->XferSize = hi2c->XferCount; - hi2c->Devaddress = DevAddress; - - Prev_State = hi2c->PreviousState; - - /* Generate Start */ - if((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) - { - /* Generate Start condition if first transfer */ - if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) - { - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else - { - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - } - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Sequential receive in master mode an amount of data in non-blocking mode with Interrupt - * @note This interface allow to manage repeated start condition when a direction change during transfer - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -{ - __IO uint32_t count = 0U; - - /* Check the parameters */ - assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Check Busy Flag only if FIRST call of Master interface */ - if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = XferOptions; - hi2c->XferSize = hi2c->XferCount; - hi2c->Devaddress = DevAddress; - - if((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) - { - /* Generate Start condition if first transfer */ - if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - } - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Enable Address Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferSize = Size; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - - /* Enable Address Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Sequential transmit in slave mode an amount of data in no-blocking mode with Interrupt - * @note This interface allow to manage repeated start condition when a direction change during transfer - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -{ - /* Check the parameters */ - assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - - if(hi2c->State == HAL_I2C_STATE_LISTEN) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = XferOptions; - hi2c->XferSize = hi2c->XferCount; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Sequential receive in slave mode an amount of data in non-blocking mode with Interrupt - * @note This interface allow to manage repeated start condition when a direction change during transfer - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -{ - /* Check the parameters */ - assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); - - if(hi2c->State == HAL_I2C_STATE_LISTEN) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = XferOptions; - hi2c->XferSize = hi2c->XferCount; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Enable the Address listen mode with Interrupt. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) -{ - if(hi2c->State == HAL_I2C_STATE_READY) - { - hi2c->State = HAL_I2C_STATE_LISTEN; - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Enable Address Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Enable EVT and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Disable the Address listen mode with Interrupt. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of tmp to prevent undefined behavior of volatile usage */ - uint32_t tmp; - - /* Disable Address listen mode only if a transfer is not ongoing */ - if(hi2c->State == HAL_I2C_STATE_LISTEN) - { - tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; - hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Disable Address Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Disable EVT and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Transmit in master mode an amount of data in non-blocking mode with DMA - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - hi2c->Devaddress = DevAddress; - - if(hi2c->XferSize > 0U) - { - /* Set the I2C DMA transfer complete callback */ - hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; - - /* Set the DMA error callback */ - hi2c->hdmatx->XferErrorCallback = I2C_DMAError; - - /* Set the unused DMA callbacks to NULL */ - hi2c->hdmatx->XferHalfCpltCallback = NULL; - hi2c->hdmatx->XferM1CpltCallback = NULL; - hi2c->hdmatx->XferM1HalfCpltCallback = NULL; - hi2c->hdmatx->XferAbortCallback = NULL; - - /* Enable the DMA Stream */ - HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); - - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - - /* Enable DMA Request */ - hi2c->Instance->CR2 |= I2C_CR2_DMAEN; - } - else - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - } - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive in master mode an amount of data in non-blocking mode with DMA - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MASTER; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - hi2c->Devaddress = DevAddress; - - if(hi2c->XferSize > 0U) - { - /* Set the I2C DMA transfer complete callback */ - hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; - - /* Set the DMA error callback */ - hi2c->hdmarx->XferErrorCallback = I2C_DMAError; - - /* Set the unused DMA callbacks to NULL */ - hi2c->hdmarx->XferHalfCpltCallback = NULL; - hi2c->hdmarx->XferM1CpltCallback = NULL; - hi2c->hdmarx->XferM1HalfCpltCallback = NULL; - hi2c->hdmarx->XferAbortCallback = NULL; - - /* Enable the DMA Stream */ - HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); - - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - - /* Enable DMA Request */ - hi2c->Instance->CR2 |= I2C_CR2_DMAEN; - } - else - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - } - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Abort a master I2C process communication with Interrupt. - * @note This abort can be called only if state is ready - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(DevAddress); - - /* Abort Master transfer during Receive or Transmit process */ - if(hi2c->Mode == HAL_I2C_MODE_MASTER) - { - /* Process Locked */ - __HAL_LOCK(hi2c); - - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_ABORT; - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - hi2c->XferCount = 0U; - - /* Disable EVT, BUF and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Call the corresponding callback to inform upper layer of End of Transfer */ - I2C_ITError(hi2c); - - return HAL_OK; - } - else - { - /* Wrong usage of abort function */ - /* This function should be used only in case of abort monitored by master device */ - return HAL_ERROR; - } -} - -/** - * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Set the I2C DMA transfer complete callback */ - hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; - - /* Set the DMA error callback */ - hi2c->hdmatx->XferErrorCallback = I2C_DMAError; - - /* Set the unused DMA callbacks to NULL */ - hi2c->hdmatx->XferHalfCpltCallback = NULL; - hi2c->hdmatx->XferM1CpltCallback = NULL; - hi2c->hdmatx->XferM1HalfCpltCallback = NULL; - hi2c->hdmatx->XferAbortCallback = NULL; - - /* Enable the DMA Stream */ - HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); - - /* Enable Address Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - /* Enable EVT and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - - /* Enable DMA Request */ - hi2c->Instance->CR2 |= I2C_CR2_DMAEN; - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Receive in slave mode an amount of data in non-blocking mode with DMA - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - if(hi2c->State == HAL_I2C_STATE_READY) - { - if((pData == NULL) || (Size == 0U)) - { - return HAL_ERROR; - } - - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_SLAVE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Set the I2C DMA transfer complete callback */ - hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; - - /* Set the DMA error callback */ - hi2c->hdmarx->XferErrorCallback = I2C_DMAError; - - /* Set the unused DMA callbacks to NULL */ - hi2c->hdmarx->XferHalfCpltCallback = NULL; - hi2c->hdmarx->XferM1CpltCallback = NULL; - hi2c->hdmarx->XferM1HalfCpltCallback = NULL; - hi2c->hdmarx->XferAbortCallback = NULL; - - /* Enable the DMA Stream */ - HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); - - /* Enable Address Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - /* Enable EVT and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - - /* Enable DMA Request */ - hi2c->Instance->CR2 |= I2C_CR2_DMAEN; - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} -/** - * @brief Write an amount of data in blocking mode to a specific memory address - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - /* Check the parameters */ - assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_BUSY; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MEM; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - while(hi2c->XferSize > 0U) - { - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferSize--; - hi2c->XferCount--; - - if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferSize--; - hi2c->XferCount--; - } - } - - /* Wait until BTF flag is set */ - if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Read an amount of data in blocking mode from a specific memory address - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) -{ - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - /* Check the parameters */ - assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_BUSY; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MEM; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - if(hi2c->XferSize == 0U) - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - else if(hi2c->XferSize == 1U) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - else if(hi2c->XferSize == 2U) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Enable Pos */ - hi2c->Instance->CR1 |= I2C_CR1_POS; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - else - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - - while(hi2c->XferSize > 0U) - { - if(hi2c->XferSize <= 3U) - { - /* One byte */ - if(hi2c->XferSize== 1U) - { - /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) - { - return HAL_TIMEOUT; - } - else - { - return HAL_ERROR; - } - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - /* Two bytes */ - else if(hi2c->XferSize == 2U) - { - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - /* 3 Last bytes */ - else - { - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - /* Wait until BTF flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - } - else - { - /* Wait until RXNE flag is set */ - if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) - { - return HAL_TIMEOUT; - } - else - { - return HAL_ERROR; - } - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferSize--; - hi2c->XferCount--; - } - } - } - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - /* Check the parameters */ - assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MEM; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferSize = Size; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->Devaddress = DevAddress; - hi2c->Memaddress = MemAddress; - hi2c->MemaddSize = MemAddSize; - hi2c->EventCount = 0U; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - /* Check the parameters */ - assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MEM; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferSize = Size; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->Devaddress = DevAddress; - hi2c->Memaddress = MemAddress; - hi2c->MemaddSize = MemAddSize; - hi2c->EventCount = 0U; - - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - if(hi2c->XferSize > 0U) - { - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - - /* Enable EVT, BUF and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - } - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param pData Pointer to data buffer - * @param Size Amount of data to be sent - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -{ - __IO uint32_t count = 0U; - - uint32_t tickstart = 0x00U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - /* Check the parameters */ - assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_MEM; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferSize = Size; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - - if(hi2c->XferSize > 0U) - { - /* Set the I2C DMA transfer complete callback */ - hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; - - /* Set the DMA error callback */ - hi2c->hdmatx->XferErrorCallback = I2C_DMAError; - - /* Set the unused DMA callbacks to NULL */ - hi2c->hdmatx->XferHalfCpltCallback = NULL; - hi2c->hdmatx->XferM1CpltCallback = NULL; - hi2c->hdmatx->XferM1HalfCpltCallback = NULL; - hi2c->hdmatx->XferAbortCallback = NULL; - - /* Enable the DMA Stream */ - HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); - - /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - /* Enable ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); - - /* Enable DMA Request */ - hi2c->Instance->CR2 |= I2C_CR2_DMAEN; - } - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param pData Pointer to data buffer - * @param Size Amount of data to be read - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -{ - uint32_t tickstart = 0x00U; - __IO uint32_t count = 0U; - - /* Init tickstart for timeout management*/ - tickstart = HAL_GetTick(); - - /* Check the parameters */ - assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); - do - { - if(count-- == 0U) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY_RX; - hi2c->Mode = HAL_I2C_MODE_MEM; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Prepare transfer parameters */ - hi2c->pBuffPtr = pData; - hi2c->XferCount = Size; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->XferSize = hi2c->XferCount; - - if(hi2c->XferSize > 0U) - { - /* Set the I2C DMA transfer complete callback */ - hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; - - /* Set the DMA error callback */ - hi2c->hdmarx->XferErrorCallback = I2C_DMAError; - - /* Set the unused DMA callbacks to NULL */ - hi2c->hdmarx->XferHalfCpltCallback = NULL; - hi2c->hdmarx->XferM1CpltCallback = NULL; - hi2c->hdmarx->XferM1HalfCpltCallback = NULL; - hi2c->hdmarx->XferAbortCallback = NULL; - - /* Enable the DMA Stream */ - HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); - - /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - if(Size == 1U) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - } - else - { - /* Enable Last DMA bit */ - hi2c->Instance->CR2 |= I2C_CR2_LAST; - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - /* Note : The I2C interrupts must be enabled after unlocking current process - to avoid the risk of I2C interrupt handle execution before current - process unlock */ - /* Enable ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); - - /* Enable DMA Request */ - hi2c->Instance->CR2 |= I2C_CR2_DMAEN; - } - else - { - /* Send Slave Address and Memory Address */ - if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_ERROR; - } - else - { - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - hi2c->State = HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - } - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Checks if target device is ready for communication. - * @note This function is used with Memory devices - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param DevAddress Target device address - * @param Trials Number of trials - * @param Timeout Timeout duration - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) -{ - uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U; - - /* Get tick */ - tickstart = HAL_GetTick(); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_BUSY; - } - - /* Process Locked */ - __HAL_LOCK(hi2c); - - /* Check if the I2C is already enabled */ - if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) - { - /* Enable I2C peripheral */ - __HAL_I2C_ENABLE(hi2c); - } - - /* Disable Pos */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - hi2c->State = HAL_I2C_STATE_BUSY; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - - do - { - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); - - /* Wait until ADDR or AF flag are set */ - /* Get tick */ - tickstart = HAL_GetTick(); - - tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); - tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); - tmp3 = hi2c->State; - while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) - { - if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) - { - hi2c->State = HAL_I2C_STATE_TIMEOUT; - } - tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); - tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); - tmp3 = hi2c->State; - } - - hi2c->State = HAL_I2C_STATE_READY; - - /* Check if the ADDR flag has been set */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Clear ADDR Flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - hi2c->State = HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_OK; - } - else - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Clear AF Flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - /* Wait until BUSY flag is reset */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - } - }while(I2C_Trials++ < Trials); - - hi2c->State = HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_ERROR; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief This function handles I2C event interrupt request. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) -{ - uint32_t sr2itflags = READ_REG(hi2c->Instance->SR2); - uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); - uint32_t itsources = READ_REG(hi2c->Instance->CR2); - - uint32_t CurrentMode = hi2c->Mode; - - /* Master or Memory mode selected */ - if((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) - { - /* SB Set ----------------------------------------------------------------*/ - if(((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_Master_SB(hi2c); - } - /* ADD10 Set -------------------------------------------------------------*/ - else if(((sr1itflags & I2C_FLAG_ADD10) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_Master_ADD10(hi2c); - } - /* ADDR Set --------------------------------------------------------------*/ - else if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_Master_ADDR(hi2c); - } - - /* I2C in mode Transmitter -----------------------------------------------*/ - if((sr2itflags & I2C_FLAG_TRA) != RESET) - { - /* TXE set and BTF reset -----------------------------------------------*/ - if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) - { - I2C_MasterTransmit_TXE(hi2c); - } - /* BTF set -------------------------------------------------------------*/ - else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_MasterTransmit_BTF(hi2c); - } - } - /* I2C in mode Receiver --------------------------------------------------*/ - else - { - /* RXNE set and BTF reset -----------------------------------------------*/ - if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) - { - I2C_MasterReceive_RXNE(hi2c); - } - /* BTF set -------------------------------------------------------------*/ - else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_MasterReceive_BTF(hi2c); - } - } - } - /* Slave mode selected */ - else - { - /* ADDR set --------------------------------------------------------------*/ - if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_Slave_ADDR(hi2c); - } - /* STOPF set --------------------------------------------------------------*/ - else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_Slave_STOPF(hi2c); - } - /* I2C in mode Transmitter -----------------------------------------------*/ - else if((sr2itflags & I2C_FLAG_TRA) != RESET) - { - /* TXE set and BTF reset -----------------------------------------------*/ - if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) - { - I2C_SlaveTransmit_TXE(hi2c); - } - /* BTF set -------------------------------------------------------------*/ - else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_SlaveTransmit_BTF(hi2c); - } - } - /* I2C in mode Receiver --------------------------------------------------*/ - else - { - /* RXNE set and BTF reset ----------------------------------------------*/ - if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) - { - I2C_SlaveReceive_RXNE(hi2c); - } - /* BTF set -------------------------------------------------------------*/ - else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) - { - I2C_SlaveReceive_BTF(hi2c); - } - } - } -} - -/** - * @brief This function handles I2C error interrupt request. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) -{ - uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U; - uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); - uint32_t itsources = READ_REG(hi2c->Instance->CR2); - - /* I2C Bus error interrupt occurred ----------------------------------------*/ - if(((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; - - /* Clear BERR flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); - } - - /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ - if(((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; - - /* Clear ARLO flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); - } - - /* I2C Acknowledge failure error interrupt occurred ------------------------*/ - if(((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) - { - tmp1 = hi2c->Mode; - tmp2 = hi2c->XferCount; - tmp3 = hi2c->State; - tmp4 = hi2c->PreviousState; - if((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) && \ - ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || \ - ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) - { - I2C_Slave_AF(hi2c); - } - else - { - hi2c->ErrorCode |= HAL_I2C_ERROR_AF; - - /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */ - if(hi2c->Mode == HAL_I2C_MODE_MASTER) - { - /* Generate Stop */ - SET_BIT(hi2c->Instance->CR1,I2C_CR1_STOP); - } - - /* Clear AF flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - } - } - - /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ - if(((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; - /* Clear OVR flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); - } - - /* Call the Error Callback in case of Error detected -----------------------*/ - if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) - { - I2C_ITError(hi2c); - } -} - -/** - * @brief Master Tx Transfer completed callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_MasterTxCpltCallback can be implemented in the user file - */ -} - -/** - * @brief Master Rx Transfer completed callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_MasterRxCpltCallback can be implemented in the user file - */ -} - -/** @brief Slave Tx Transfer completed callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_SlaveTxCpltCallback can be implemented in the user file - */ -} - -/** - * @brief Slave Rx Transfer completed callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_SlaveRxCpltCallback can be implemented in the user file - */ -} - -/** - * @brief Slave Address Match callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferOptions_definition - * @param AddrMatchCode Address Match Code - * @retval None - */ -__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - UNUSED(TransferDirection); - UNUSED(AddrMatchCode); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_AddrCallback can be implemented in the user file - */ -} - -/** - * @brief Listen Complete callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_ListenCpltCallback can be implemented in the user file - */ -} - -/** - * @brief Memory Tx Transfer completed callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_MemTxCpltCallback can be implemented in the user file - */ -} - -/** - * @brief Memory Rx Transfer completed callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_MemRxCpltCallback can be implemented in the user file - */ -} - -/** - * @brief I2C error callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_ErrorCallback can be implemented in the user file - */ -} - -/** - * @brief I2C abort callback. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval None - */ -__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) -{ - /* Prevent unused argument(s) compilation warning */ - UNUSED(hi2c); - - /* NOTE : This function should not be modified, when the callback is needed, - the HAL_I2C_AbortCpltCallback could be implemented in the user file - */ -} - -/** - * @} - */ - -/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions - * @brief Peripheral State and Errors functions - * -@verbatim - =============================================================================== - ##### Peripheral State, Mode and Error functions ##### - =============================================================================== - [..] - This subsection permits to get in run-time the status of the peripheral - and the data flow. - -@endverbatim - * @{ - */ - -/** - * @brief Return the I2C handle state. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval HAL state - */ -HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) -{ - /* Return I2C handle state */ - return hi2c->State; -} - -/** - * @brief Return the I2C Master, Slave, Memory or no mode. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL mode - */ -HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c) -{ - return hi2c->Mode; -} - -/** - * @brief Return the I2C error code - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval I2C Error Code - */ -uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) -{ - return hi2c->ErrorCode; -} - -/** - * @} - */ - -/** - * @brief Handle TXE flag for Master - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ - uint32_t CurrentState = hi2c->State; - uint32_t CurrentMode = hi2c->Mode; - uint32_t CurrentXferOptions = hi2c->XferOptions; - - if((hi2c->XferSize == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX)) - { - /* Call TxCpltCallback() directly if no stop mode is set */ - if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) - { - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - - HAL_I2C_MasterTxCpltCallback(hi2c); - } - else /* Generate Stop condition then Call TxCpltCallback() */ - { - /* Disable EVT, BUF and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - - if(hi2c->Mode == HAL_I2C_MODE_MEM) - { - hi2c->Mode = HAL_I2C_MODE_NONE; - HAL_I2C_MemTxCpltCallback(hi2c); - } - else - { - hi2c->Mode = HAL_I2C_MODE_NONE; - HAL_I2C_MasterTxCpltCallback(hi2c); - } - } - } - else if((CurrentState == HAL_I2C_STATE_BUSY_TX) || \ - ((CurrentMode == HAL_I2C_MODE_MEM) && (CurrentState == HAL_I2C_STATE_BUSY_RX))) - { - if(hi2c->XferCount == 0U) - { - /* Disable BUF interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); - } - else - { - if(hi2c->Mode == HAL_I2C_MODE_MEM) - { - if(hi2c->EventCount == 0) - { - /* If Memory address size is 8Bit */ - if(hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT) - { - /* Send Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); - - hi2c->EventCount += 2; - } - /* If Memory address size is 16Bit */ - else - { - /* Send MSB of Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress); - - hi2c->EventCount++; - } - } - else if(hi2c->EventCount == 1) - { - /* Send LSB of Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); - - hi2c->EventCount++; - } - else if(hi2c->EventCount == 2) - { - if(hi2c->State == HAL_I2C_STATE_BUSY_RX) - { - /* Generate Restart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - } - } - } - else - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - } - } - } - return HAL_OK; -} - -/** - * @brief Handle BTF flag for Master transmitter - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ - uint32_t CurrentXferOptions = hi2c->XferOptions; - - if(hi2c->State == HAL_I2C_STATE_BUSY_TX) - { - if(hi2c->XferCount != 0U) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - } - else - { - /* Call TxCpltCallback() directly if no stop mode is set */ - if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) - { - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; - hi2c->Mode = HAL_I2C_MODE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - - HAL_I2C_MasterTxCpltCallback(hi2c); - } - else /* Generate Stop condition then Call TxCpltCallback() */ - { - /* Disable EVT, BUF and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - - if(hi2c->Mode == HAL_I2C_MODE_MEM) - { - hi2c->Mode = HAL_I2C_MODE_NONE; - - HAL_I2C_MemTxCpltCallback(hi2c); - } - else - { - hi2c->Mode = HAL_I2C_MODE_NONE; - - HAL_I2C_MasterTxCpltCallback(hi2c); - } - } - } - } - return HAL_OK; -} - -/** - * @brief Handle RXNE flag for Master - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) -{ - if(hi2c->State == HAL_I2C_STATE_BUSY_RX) - { - uint32_t tmp = 0U; - - tmp = hi2c->XferCount; - if(tmp > 3U) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - - if(hi2c->XferCount == 3) - { - /* Disable BUF interrupt, this help to treat correctly the last 4 bytes - on BTF subroutine */ - /* Disable BUF interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); - } - } - else if((tmp == 1U) || (tmp == 0U)) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Disable EVT, BUF and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->PreviousState = I2C_STATE_NONE; - - if(hi2c->Mode == HAL_I2C_MODE_MEM) - { - hi2c->Mode = HAL_I2C_MODE_NONE; - HAL_I2C_MemRxCpltCallback(hi2c); - } - else - { - hi2c->Mode = HAL_I2C_MODE_NONE; - HAL_I2C_MasterRxCpltCallback(hi2c); - } - } - } - return HAL_OK; -} - -/** - * @brief Handle BTF flag for Master receiver - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ - uint32_t CurrentXferOptions = hi2c->XferOptions; - - if(hi2c->XferCount == 4U) - { - /* Disable BUF interrupt, this help to treat correctly the last 2 bytes - on BTF subroutine if there is a reception delay between N-1 and N byte */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - } - else if(hi2c->XferCount == 3U) - { - /* Disable BUF interrupt, this help to treat correctly the last 2 bytes - on BTF subroutine if there is a reception delay between N-1 and N byte */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - } - else if(hi2c->XferCount == 2U) - { - /* Prepare next transfer or stop current transfer */ - if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - - /* Disable EVT and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->PreviousState = I2C_STATE_NONE; - - if(hi2c->Mode == HAL_I2C_MODE_MEM) - { - hi2c->Mode = HAL_I2C_MODE_NONE; - - HAL_I2C_MemRxCpltCallback(hi2c); - } - else - { - hi2c->Mode = HAL_I2C_MODE_NONE; - - HAL_I2C_MasterRxCpltCallback(hi2c); - } - } - else - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - } - return HAL_OK; -} - -/** - * @brief Handle SB flag for Master - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c) -{ - if(hi2c->Mode == HAL_I2C_MODE_MEM) - { - if(hi2c->EventCount == 0U) - { - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); - } - else - { - hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); - } - } - else - { - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) - { - /* Send slave 7 Bits address */ - if(hi2c->State == HAL_I2C_STATE_BUSY_TX) - { - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); - } - else - { - hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); - } - } - else - { - if(hi2c->EventCount == 0U) - { - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress); - } - else if(hi2c->EventCount == 1U) - { - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress); - } - } - } - - return HAL_OK; -} - -/** - * @brief Handle ADD10 flag for Master - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c) -{ - /* Send slave address */ - hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress); - - return HAL_OK; -} - -/** - * @brief Handle ADDR flag for Master - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentMode = hi2c->Mode; - uint32_t CurrentXferOptions = hi2c->XferOptions; - uint32_t Prev_State = hi2c->PreviousState; - - if(hi2c->State == HAL_I2C_STATE_BUSY_RX) - { - if((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM)) - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - else if((hi2c->EventCount == 0U) && (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)) - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Restart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - hi2c->EventCount++; - } - else - { - if(hi2c->XferCount == 0U) - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - else if(hi2c->XferCount == 1U) - { - if(CurrentXferOptions == I2C_NO_OPTION_FRAME) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - else - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - } - /* Prepare next transfer or stop current transfer */ - else if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) \ - && (Prev_State != I2C_STATE_MASTER_BUSY_RX)) - { - if(hi2c->XferOptions != I2C_NEXT_FRAME) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - } - else - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - else - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - } - } - else if(hi2c->XferCount == 2U) - { - if(hi2c->XferOptions != I2C_NEXT_FRAME) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Enable Pos */ - hi2c->Instance->CR1 |= I2C_CR1_POS; - } - else - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - } - - if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) - { - /* Enable Last DMA bit */ - hi2c->Instance->CR2 |= I2C_CR2_LAST; - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - else - { - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) - { - /* Enable Last DMA bit */ - hi2c->Instance->CR2 |= I2C_CR2_LAST; - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - - /* Reset Event counter */ - hi2c->EventCount = 0U; - } - } - else - { - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - } - - return HAL_OK; -} - -/** - * @brief Handle TXE flag for Slave - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ - uint32_t CurrentState = hi2c->State; - - if(hi2c->XferCount != 0U) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - - if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) - { - /* Last Byte is received, disable Interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); - - /* Set state at HAL_I2C_STATE_LISTEN */ - hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; - hi2c->State = HAL_I2C_STATE_LISTEN; - - /* Call the Tx complete callback to inform upper layer of the end of receive process */ - HAL_I2C_SlaveTxCpltCallback(hi2c); - } - } - return HAL_OK; -} - -/** - * @brief Handle BTF flag for Slave transmitter - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) -{ - if(hi2c->XferCount != 0U) - { - /* Write data to DR */ - hi2c->Instance->DR = (*hi2c->pBuffPtr++); - hi2c->XferCount--; - } - return HAL_OK; -} - -/** - * @brief Handle RXNE flag for Slave - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ - uint32_t CurrentState = hi2c->State; - - if(hi2c->XferCount != 0U) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - - if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) - { - /* Last Byte is received, disable Interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); - - /* Set state at HAL_I2C_STATE_LISTEN */ - hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; - hi2c->State = HAL_I2C_STATE_LISTEN; - - /* Call the Rx complete callback to inform upper layer of the end of receive process */ - HAL_I2C_SlaveRxCpltCallback(hi2c); - } - } - return HAL_OK; -} - -/** - * @brief Handle BTF flag for Slave receiver - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) -{ - if(hi2c->XferCount != 0U) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - } - return HAL_OK; -} - -/** - * @brief Handle ADD flag for Slave - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) -{ - uint8_t TransferDirection = I2C_DIRECTION_RECEIVE; - uint16_t SlaveAddrCode = 0U; - - /* Transfer Direction requested by Master */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == RESET) - { - TransferDirection = I2C_DIRECTION_TRANSMIT; - } - - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DUALF) == RESET) - { - SlaveAddrCode = hi2c->Init.OwnAddress1; - } - else - { - SlaveAddrCode = hi2c->Init.OwnAddress2; - } - - /* Call Slave Addr callback */ - HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode); - - return HAL_OK; -} - -/** - * @brief Handle STOPF flag for Slave - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentState = hi2c->State; - - /* Disable EVT, BUF and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - /* Clear STOPF flag */ - __HAL_I2C_CLEAR_STOPFLAG(hi2c); - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* If a DMA is ongoing, Update handle size context */ - if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) - { - if((hi2c->State == HAL_I2C_STATE_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) - { - hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmarx); - } - else - { - hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmatx); - } - } - - /* All data are not transferred, so set error code accordingly */ - if(hi2c->XferCount != 0U) - { - /* Store Last receive data if any */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - } - - /* Store Last receive data if any */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - hi2c->XferCount--; - } - - /* Set ErrorCode corresponding to a Non-Acknowledge */ - //hi2c->ErrorCode |= HAL_I2C_ERROR_AF; - } - - if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) - { - /* Call the corresponding callback to inform upper layer of End of Transfer */ - I2C_ITError(hi2c); - } - else - { - if((CurrentState == HAL_I2C_STATE_LISTEN ) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN) || \ - (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) - { - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ - HAL_I2C_ListenCpltCallback(hi2c); - } - else - { - if((hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_RX) || (CurrentState == HAL_I2C_STATE_BUSY_RX)) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - HAL_I2C_SlaveRxCpltCallback(hi2c); - } - } - } - return HAL_OK; -} - -/** - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ - uint32_t CurrentState = hi2c->State; - uint32_t CurrentXferOptions = hi2c->XferOptions; - - if(((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME)) && \ - (CurrentState == HAL_I2C_STATE_LISTEN)) - { - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - - /* Disable EVT, BUF and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - /* Clear AF flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ - HAL_I2C_ListenCpltCallback(hi2c); - } - else if(CurrentState == HAL_I2C_STATE_BUSY_TX) - { - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Disable EVT, BUF and ERR interrupt */ - __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); - - /* Clear AF flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - HAL_I2C_SlaveTxCpltCallback(hi2c); - } - else - { - /* Clear AF flag only */ - /* State Listen, but XferOptions == FIRST or NEXT */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - } - - return HAL_OK; -} - -/** - * @brief I2C interrupts error process - * @param hi2c I2C handle. - * @retval None - */ -static void I2C_ITError(I2C_HandleTypeDef *hi2c) -{ - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentState = hi2c->State; - - if((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) - { - /* keep HAL_I2C_STATE_LISTEN */ - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_LISTEN; - } - else - { - /* If state is an abort treatment on going, don't change state */ - /* This change will be do later */ - if((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) - { - hi2c->State = HAL_I2C_STATE_READY; - } - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->Mode = HAL_I2C_MODE_NONE; - } - - /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ - hi2c->Instance->CR1 &= ~I2C_CR1_POS; - - /* Abort DMA transfer */ - if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) - { - hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; - - if(hi2c->hdmatx->State != HAL_DMA_STATE_READY) - { - /* Set the DMA Abort callback : - will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ - hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; - - if(HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) - { - /* Disable I2C peripheral to prevent dummy data in buffer */ - __HAL_I2C_DISABLE(hi2c); - - hi2c->State = HAL_I2C_STATE_READY; - - /* Call Directly XferAbortCallback function in case of error */ - hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); - } - } - else - { - /* Set the DMA Abort callback : - will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ - hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; - - if(HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) - { - /* Store Last receive data if any */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - } - - /* Disable I2C peripheral to prevent dummy data in buffer */ - __HAL_I2C_DISABLE(hi2c); - - hi2c->State = HAL_I2C_STATE_READY; - - /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ - hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); - } - } - } - else if(hi2c->State == HAL_I2C_STATE_ABORT) - { - hi2c->State = HAL_I2C_STATE_READY; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Store Last receive data if any */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - } - - /* Disable I2C peripheral to prevent dummy data in buffer */ - __HAL_I2C_DISABLE(hi2c); - - /* Call the corresponding callback to inform upper layer of End of Transfer */ - HAL_I2C_AbortCpltCallback(hi2c); - } - else - { - /* Store Last receive data if any */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) - { - /* Read data from DR */ - (*hi2c->pBuffPtr++) = hi2c->Instance->DR; - } - - /* Call user error callback */ - HAL_I2C_ErrorCallback(hi2c); - } - /* STOP Flag is not set after a NACK reception */ - /* So may inform upper layer that listen phase is stopped */ - /* during NACK error treatment */ - if((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) - { - hi2c->XferOptions = I2C_NO_OPTION_FRAME; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ - HAL_I2C_ListenCpltCallback(hi2c); - } -} - -/** - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -{ - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentXferOptions = hi2c->XferOptions; - - /* Generate Start condition if first transfer */ - if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) - { - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) - { - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) - { - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); - } - else - { - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); - - /* Wait until ADD10 flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); - } - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - return HAL_OK; -} - -/** - * @brief Master sends target device address for read request. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param DevAddress Target device address The device 7 bits address value - * in datasheet must be shifted to the left before calling the interface - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -{ - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentXferOptions = hi2c->XferOptions; - - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start condition if first transfer */ - if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) - { - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) - { - /* Generate ReStart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - } - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) - { - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); - } - else - { - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); - - /* Wait until ADD10 flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Generate Restart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Send header of slave address */ - hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); - } - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - return HAL_OK; -} - -/** - * @brief Master sends target device address followed by internal memory address for write request. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) -{ - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* If Memory address size is 8Bit */ - if(MemAddSize == I2C_MEMADD_SIZE_8BIT) - { - /* Send Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); - } - /* If Memory address size is 16Bit */ - else - { - /* Send MSB of Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); - - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Send LSB of Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); - } - - return HAL_OK; -} - -/** - * @brief Master sends target device address followed by internal memory address for read request. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param DevAddress Target device address - * @param MemAddress Internal memory address - * @param MemAddSize Size of internal memory address - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) -{ - /* Enable Acknowledge */ - hi2c->Instance->CR1 |= I2C_CR1_ACK; - - /* Generate Start */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Clear ADDR flag */ - __HAL_I2C_CLEAR_ADDRFLAG(hi2c); - - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* If Memory address size is 8Bit */ - if(MemAddSize == I2C_MEMADD_SIZE_8BIT) - { - /* Send Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); - } - /* If Memory address size is 16Bit */ - else - { - /* Send MSB of Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); - - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Send LSB of Memory Address */ - hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); - } - - /* Wait until TXE flag is set */ - if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - /* Generate Restart */ - hi2c->Instance->CR1 |= I2C_CR1_START; - - /* Wait until SB flag is set */ - if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) - { - return HAL_TIMEOUT; - } - - /* Send slave address */ - hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); - - /* Wait until ADDR flag is set */ - if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) - { - if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) - { - return HAL_ERROR; - } - else - { - return HAL_TIMEOUT; - } - } - - return HAL_OK; -} - -/** - * @brief DMA I2C process complete callback. - * @param hdma DMA handle - * @retval None - */ -static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma) -{ - I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; - - /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ - uint32_t CurrentState = hi2c->State; - uint32_t CurrentMode = hi2c->Mode; - - if((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) - { - /* Disable DMA Request */ - hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; - - hi2c->XferCount = 0U; - - /* Enable EVT and ERR interrupt */ - __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); - } - else - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Disable Last DMA */ - hi2c->Instance->CR2 &= ~I2C_CR2_LAST; - - /* Disable DMA Request */ - hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; - - hi2c->XferCount = 0U; - - /* Check if Errors has been detected during transfer */ - if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) - { - HAL_I2C_ErrorCallback(hi2c); - } - else - { - hi2c->State = HAL_I2C_STATE_READY; - - if(hi2c->Mode == HAL_I2C_MODE_MEM) - { - hi2c->Mode = HAL_I2C_MODE_NONE; - - HAL_I2C_MemRxCpltCallback(hi2c); - } - else - { - hi2c->Mode = HAL_I2C_MODE_NONE; - - HAL_I2C_MasterRxCpltCallback(hi2c); - } - } - } -} - -/** - * @brief DMA I2C communication error callback. - * @param hdma DMA handle - * @retval None - */ -static void I2C_DMAError(DMA_HandleTypeDef *hdma) -{ - I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; - - /* Ignore DMA FIFO error */ - if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) - { - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - hi2c->XferCount = 0U; - - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; - - HAL_I2C_ErrorCallback(hi2c); - } -} - -/** - * @brief DMA I2C communication abort callback - * (To be called at end of DMA Abort procedure). - * @param hdma DMA handle. - * @retval None - */ -static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) -{ - I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; - - /* Disable Acknowledge */ - hi2c->Instance->CR1 &= ~I2C_CR1_ACK; - - hi2c->XferCount = 0U; - - /* Reset XferAbortCallback */ - hi2c->hdmatx->XferAbortCallback = NULL; - hi2c->hdmarx->XferAbortCallback = NULL; - - /* Check if come from abort from user */ - if(hi2c->State == HAL_I2C_STATE_ABORT) - { - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - - /* Disable I2C peripheral to prevent dummy data in buffer */ - __HAL_I2C_DISABLE(hi2c); - - /* Call the corresponding callback to inform upper layer of End of Transfer */ - HAL_I2C_AbortCpltCallback(hi2c); - } - else - { - hi2c->State = HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Disable I2C peripheral to prevent dummy data in buffer */ - __HAL_I2C_DISABLE(hi2c); - - /* Call the corresponding callback to inform upper layer of End of Transfer */ - HAL_I2C_ErrorCallback(hi2c); - } -} - -/** - * @brief This function handles I2C Communication Timeout. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param Flag specifies the I2C flag to check. - * @param Status The new Flag status (SET or RESET). - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) -{ - /* Wait until flag is set */ - while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) - { - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - hi2c->Mode = HAL_I2C_MODE_NONE; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - } - - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for Master addressing phase. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for I2C module - * @param Flag specifies the I2C flag to check. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) - { - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) - { - /* Generate Stop */ - hi2c->Instance->CR1 |= I2C_CR1_STOP; - - /* Clear AF Flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - hi2c->ErrorCode = HAL_I2C_ERROR_AF; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_ERROR; - } - - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) - { - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - } - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for specific usage of TXE flag. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) - { - /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) - { - return HAL_ERROR; - } - - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - } - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for specific usage of BTF flag. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) - { - /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) - { - return HAL_ERROR; - } - - /* Check for the Timeout */ - if(Timeout != HAL_MAX_DELAY) - { - if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - } - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for specific usage of STOP flag. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -{ - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) - { - /* Check if a NACK is detected */ - if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) - { - return HAL_ERROR; - } - - /* Check for the Timeout */ - if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - return HAL_OK; -} - -/** - * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @param Timeout Timeout duration - * @param Tickstart Tick start value - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -{ - - while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) - { - /* Check if a STOPF is detected */ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) - { - /* Clear STOP Flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); - - hi2c->ErrorCode = HAL_I2C_ERROR_NONE; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_ERROR; - } - - /* Check for the Timeout */ - if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) - { - hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_TIMEOUT; - } - } - return HAL_OK; -} - -/** - * @brief This function handles Acknowledge failed detection during an I2C Communication. - * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2C. - * @retval HAL status - */ -static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) -{ - if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) - { - /* Clear NACKF Flag */ - __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); - - hi2c->ErrorCode = HAL_I2C_ERROR_AF; - hi2c->PreviousState = I2C_STATE_NONE; - hi2c->State= HAL_I2C_STATE_READY; - - /* Process Unlocked */ - __HAL_UNLOCK(hi2c); - - return HAL_ERROR; - } - return HAL_OK; -} -/** - * @} - */ - -#endif /* HAL_I2C_MODULE_ENABLED */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c deleted file mode 100644 index de8f1602..00000000 --- a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c +++ /dev/null @@ -1,204 +0,0 @@ -/** - ****************************************************************************** - * @file stm32f4xx_hal_i2c_ex.c - * @author MCD Application Team - * @brief I2C Extension HAL module driver. - * This file provides firmware functions to manage the following - * functionalities of I2C extension peripheral: - * + Extension features functions - * - @verbatim - ============================================================================== - ##### I2C peripheral extension features ##### - ============================================================================== - - [..] Comparing to other previous devices, the I2C interface for STM32F427xx/437xx/ - 429xx/439xx devices contains the following additional features : - - (+) Possibility to disable or enable Analog Noise Filter - (+) Use of a configured Digital Noise Filter - - ##### How to use this driver ##### - ============================================================================== - [..] This driver provides functions to configure Noise Filter - (#) Configure I2C Analog noise filter using the function HAL_I2C_AnalogFilter_Config() - (#) Configure I2C Digital noise filter using the function HAL_I2C_DigitalFilter_Config() - - @endverbatim - ****************************************************************************** - * @attention - * - *

© COPYRIGHT(c) 2017 STMicroelectronics

- * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************** - */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32f4xx_hal.h" - -/** @addtogroup STM32F4xx_HAL_Driver - * @{ - */ - -/** @defgroup I2CEx I2CEx - * @brief I2C HAL module driver - * @{ - */ - -#ifdef HAL_I2C_MODULE_ENABLED - -#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ - defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ - defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -/* Private function prototypes -----------------------------------------------*/ -/* Exported functions --------------------------------------------------------*/ -/** @defgroup I2CEx_Exported_Functions I2C Exported Functions - * @{ - */ - - -/** @defgroup I2CEx_Exported_Functions_Group1 Extension features functions - * @brief Extension features functions - * -@verbatim - =============================================================================== - ##### Extension features functions ##### - =============================================================================== - [..] This section provides functions allowing to: - (+) Configure Noise Filters - -@endverbatim - * @{ - */ - -/** - * @brief Configures I2C Analog noise filter. - * @param hi2c pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2Cx peripheral. - * @param AnalogFilter new state of the Analog filter. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) -{ - /* Check the parameters */ - assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); - assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - hi2c->State = HAL_I2C_STATE_BUSY; - - /* Disable the selected I2C peripheral */ - __HAL_I2C_DISABLE(hi2c); - - /* Reset I2Cx ANOFF bit */ - hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF); - - /* Disable the analog filter */ - hi2c->Instance->FLTR |= AnalogFilter; - - __HAL_I2C_ENABLE(hi2c); - - hi2c->State = HAL_I2C_STATE_READY; - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @brief Configures I2C Digital noise filter. - * @param hi2c pointer to a I2C_HandleTypeDef structure that contains - * the configuration information for the specified I2Cx peripheral. - * @param DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) -{ - uint16_t tmpreg = 0; - - /* Check the parameters */ - assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); - assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); - - if(hi2c->State == HAL_I2C_STATE_READY) - { - hi2c->State = HAL_I2C_STATE_BUSY; - - /* Disable the selected I2C peripheral */ - __HAL_I2C_DISABLE(hi2c); - - /* Get the old register value */ - tmpreg = hi2c->Instance->FLTR; - - /* Reset I2Cx DNF bit [3:0] */ - tmpreg &= ~(I2C_FLTR_DNF); - - /* Set I2Cx DNF coefficient */ - tmpreg |= DigitalFilter; - - /* Store the new register value */ - hi2c->Instance->FLTR = tmpreg; - - __HAL_I2C_ENABLE(hi2c); - - hi2c->State = HAL_I2C_STATE_READY; - - return HAL_OK; - } - else - { - return HAL_BUSY; - } -} - -/** - * @} - */ - -/** - * @} - */ -#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ - STM32F401xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx ||\ - STM32F423xx */ - -#endif /* HAL_I2C_MODULE_ENABLED */ -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Inc/FreeRTOSConfig.h b/Firmware/Board/v3/Inc/FreeRTOSConfig.h index 53280d99..90e233b3 100644 --- a/Firmware/Board/v3/Inc/FreeRTOSConfig.h +++ b/Firmware/Board/v3/Inc/FreeRTOSConfig.h @@ -89,7 +89,6 @@ /* Ensure stdint is only used by the compiler, and not the assembler. */ #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) #include - #include "main.h" extern uint32_t SystemCoreClock; #endif @@ -153,7 +152,7 @@ See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ /* Normal assert() semantics without relying on the provision of an assert.h header file. */ -/* USER CODE BEGIN 1 */ +/* USER CODE BEGIN 1 */ #define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );} /* USER CODE END 1 */ diff --git a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h index b3ef59aa..e518489f 100644 --- a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h +++ b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h @@ -65,7 +65,7 @@ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ -#define HAL_I2C_MODULE_ENABLED +/* #define HAL_I2C_MODULE_ENABLED */ /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ @@ -91,6 +91,7 @@ /* #define HAL_SPDIFRX_MODULE_ENABLED */ /* #define HAL_DFSDM_MODULE_ENABLED */ /* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_EXTI_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_DMA_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED @@ -244,6 +245,10 @@ #include "stm32f4xx_hal_rcc.h" #endif /* HAL_RCC_MODULE_ENABLED */ +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + #ifdef HAL_GPIO_MODULE_ENABLED #include "stm32f4xx_hal_gpio.h" #endif /* HAL_GPIO_MODULE_ENABLED */ diff --git a/Firmware/Board/v3/Inc/tim.h b/Firmware/Board/v3/Inc/tim.h index 7006b95a..ba58367a 100644 --- a/Firmware/Board/v3/Inc/tim.h +++ b/Firmware/Board/v3/Inc/tim.h @@ -80,10 +80,9 @@ void MX_TIM3_Init(void); void MX_TIM4_Init(void); void MX_TIM5_Init(void); void MX_TIM8_Init(void); - + void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); - - + /* USER CODE BEGIN Prototypes */ void OC4_PWM_Override(TIM_HandleTypeDef* htim); diff --git a/Firmware/Board/v3/Inc/usbd_cdc_if.h b/Firmware/Board/v3/Inc/usbd_cdc_if.h index ed1d6705..c15e8b91 100644 --- a/Firmware/Board/v3/Inc/usbd_cdc_if.h +++ b/Firmware/Board/v3/Inc/usbd_cdc_if.h @@ -132,7 +132,7 @@ extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; * @{ */ -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t endpoint_pair); +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); /* USER CODE BEGIN EXPORTED_FUNCTIONS */ /* USER CODE END EXPORTED_FUNCTIONS */ diff --git a/Firmware/Board/v3/Inc/usbd_conf.h b/Firmware/Board/v3/Inc/usbd_conf.h index fe7867dd..bf276186 100644 --- a/Firmware/Board/v3/Inc/usbd_conf.h +++ b/Firmware/Board/v3/Inc/usbd_conf.h @@ -89,7 +89,6 @@ * @brief Defines for configuration of the Usb device. * @{ */ -#define MS_VendorCode 'P' /*---------- -----------*/ #define USBD_MAX_NUM_INTERFACES 1 @@ -98,7 +97,7 @@ /*---------- -----------*/ #define USBD_MAX_STR_DESC_SIZ 512 /*---------- -----------*/ -#define USBD_SUPPORT_USER_STRING 1 +#define USBD_SUPPORT_USER_STRING 0 /*---------- -----------*/ #define USBD_DEBUG_LEVEL 0 /*---------- -----------*/ diff --git a/Firmware/Board/v3/Inc/usbd_desc.h b/Firmware/Board/v3/Inc/usbd_desc.h index 2a74de31..18d1f34e 100644 --- a/Firmware/Board/v3/Inc/usbd_desc.h +++ b/Firmware/Board/v3/Inc/usbd_desc.h @@ -2,7 +2,7 @@ ****************************************************************************** * @file : usbd_desc.h * @version : v1.0_Cube - * @brief : Header for usbd_desc.c file. + * @brief : Header for usbd_conf.c file. ****************************************************************************** * This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and @@ -46,7 +46,6 @@ * ****************************************************************************** */ - /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __USBD_DESC__H__ #define __USBD_DESC__H__ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h index c029e22a..d937b2e8 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -52,15 +52,13 @@ #define CDC_IN_EP 0x81 /* EP1 for data IN */ #define CDC_OUT_EP 0x01 /* EP1 for data OUT */ #define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ -#define ODRIVE_IN_EP 0x83 /* EP3 IN: ODrive device TX endpoint */ -#define ODRIVE_OUT_EP 0x03 /* EP3 OUT: ODrive device RX endpoint */ /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ -#define CDC_DATA_HS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_HS_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */ #define CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ #define CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */ -#define USB_CDC_CONFIG_DESC_SIZ (67 + 39) +#define USB_CDC_CONFIG_DESC_SIZ 67 #define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE #define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE @@ -105,29 +103,23 @@ typedef struct _USBD_CDC_Itf int8_t (* Init) (void); int8_t (* DeInit) (void); int8_t (* Control) (uint8_t, uint8_t * , uint16_t); - int8_t (* Receive) (uint8_t *, uint32_t *, uint8_t); + int8_t (* Receive) (uint8_t *, uint32_t *); }USBD_CDC_ItfTypeDef; -typedef struct -{ - uint8_t* Buffer; - uint32_t Length; - volatile uint8_t State; -} -USBD_CDC_EP_HandleTypeDef; typedef struct { uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */ uint8_t CmdOpCode; - uint8_t CmdLength; - - USBD_CDC_EP_HandleTypeDef CDC_Tx; - USBD_CDC_EP_HandleTypeDef CDC_Rx; - - USBD_CDC_EP_HandleTypeDef ODRIVE_Tx; - USBD_CDC_EP_HandleTypeDef ODRIVE_Rx; + uint8_t CmdLength; + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; } USBD_CDC_HandleTypeDef; @@ -159,15 +151,14 @@ uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint16_t length, - uint8_t endpoint_pair); + uint16_t length); uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, - uint8_t *pbuff, uint8_t endpoint_pair); + uint8_t *pbuff); -uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev, uint8_t endpoint_pair); +uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev); -uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev, uint8_t endpoint_pair); +uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev); /** * @} */ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index 73313522..b2ca5f16 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -62,8 +62,7 @@ #include "usbd_cdc.h" #include "usbd_desc.h" #include "usbd_ctlreq.h" -#include -#include + /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ @@ -132,9 +131,6 @@ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length); uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length); -static uint8_t USBD_WinUSBComm_SetupVendor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); -//static uint8_t * USBD_GetUsrStrDescriptor(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); - /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -176,37 +172,24 @@ USBD_ClassTypeDef USBD_CDC = USBD_CDC_GetFSCfgDesc, USBD_CDC_GetOtherSpeedCfgDesc, USBD_CDC_GetDeviceQualifierDescriptor, - USBD_UsrStrDescriptor }; /* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { /*Configuration Descriptor*/ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ 0x00, - 0x03, /* bNumInterfaces: 3 interfaces (2 for CDC, 1 custom) */ + 0x02, /* bNumInterfaces: 2 interface */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0xC0, /* bmAttributes: self powered */ 0x32, /* MaxPower 0 mA */ - - /////////////////////////////////////////////////////////////////////////////// - - /* Interface Association Descriptor: CDC device (virtual com port) */ - 0x08, /* bLength: IAD size */ - 0x0B, /* bDescriptorType: Interface Association Descriptor */ - 0x00, /* bFirstInterface */ - 0x02, /* bInterfaceCount */ - 0x02, /* bFunctionClass: Communication Interface Class */ - 0x02, /* bFunctionSubClass: Abstract Control Model */ - 0x01, /* bFunctionProtocol: Common AT commands */ - 0x00, /* iFunction */ /*---------------------------------------------------------------------------*/ - + /*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ @@ -218,7 +201,7 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ 0x00, /* iInterface: */ - + /*Header Functional Descriptor*/ 0x05, /* bLength: Endpoint Descriptor size */ 0x24, /* bDescriptorType: CS_INTERFACE */ @@ -245,7 +228,7 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x06, /* bDescriptorSubtype: Union func desc */ 0x00, /* bMasterInterface: Communication class interface */ 0x01, /* bSlaveInterface0: Data Class Interface */ - + /*Endpoint 2 Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ @@ -283,52 +266,196 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ + 0x00 /* bInterval: ignore for Bulk transfer */ +} ; - /////////////////////////////////////////////////////////////////////////////// + +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 mA */ - /* Interface Association Descriptor: custom device */ - 0x08, /* bLength: IAD size */ - 0x0B, /* bDescriptorType: Interface Association Descriptor */ - 0x02, /* bFirstInterface */ - 0x01, /* bInterfaceCount */ - 0x00, /* bFunctionClass: */ - 0x00, /* bFunctionSubClass: */ - 0x00, /* bFunctionProtocol: */ - 0x06, /* iFunction */ - + /*---------------------------------------------------------------------------*/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0x10, /* bInterval: */ /*---------------------------------------------------------------------------*/ /*Data class interface descriptor*/ 0x09, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x02, /* bInterfaceNumber: Number of Interface */ + 0x01, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ - 0x00, /* bInterfaceClass: vendor specific */ - 0x01, /* bInterfaceSubClass: ODrive Communication */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ 0x00, /* bInterfaceProtocol: */ 0x00, /* iInterface: */ /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - ODRIVE_OUT_EP, /* bEndpointAddress */ + CDC_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - ODRIVE_IN_EP, /* bEndpointAddress */ + CDC_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00, /* bInterval: ignore for Bulk transfer */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00 /* bInterval: ignore for Bulk transfer */ } ; +__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, + USB_CDC_CONFIG_DESC_SIZ, + 0x00, + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT , /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0xFF, /* bInterval: */ + + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00 /* bInterval */ +}; /** * @} @@ -380,19 +507,6 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, USBD_EP_TYPE_BULK, CDC_DATA_FS_OUT_PACKET_SIZE); } - - /* Open ODrive IN endpoint */ - USBD_LL_OpenEP(pdev, - ODRIVE_IN_EP, - USBD_EP_TYPE_BULK, - pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_IN_PACKET_SIZE : CDC_DATA_FS_IN_PACKET_SIZE); - - /* Open ODrive OUT endpoint */ - USBD_LL_OpenEP(pdev, - ODRIVE_OUT_EP, - USBD_EP_TYPE_BULK, - pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_OUT_PACKET_SIZE : CDC_DATA_FS_OUT_PACKET_SIZE); - /* Open Command IN EP */ USBD_LL_OpenEP(pdev, CDC_CMD_EP, @@ -414,17 +528,15 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); /* Init Xfer states */ - hcdc->CDC_Tx.State =0; - hcdc->CDC_Rx.State =0; - hcdc->ODRIVE_Tx.State =0; - hcdc->ODRIVE_Rx.State =0; + hcdc->TxState =0; + hcdc->RxState =0; if(pdev->dev_speed == USBD_SPEED_HIGH ) { /* Prepare Out endpoint to receive next packet */ USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, - hcdc->CDC_Rx.Buffer, + hcdc->RxBuffer, CDC_DATA_HS_OUT_PACKET_SIZE); } else @@ -432,15 +544,11 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, /* Prepare Out endpoint to receive next packet */ USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, - hcdc->CDC_Rx.Buffer, + hcdc->RxBuffer, CDC_DATA_FS_OUT_PACKET_SIZE); } - /* Prepare ODrive Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - ODRIVE_OUT_EP, - hcdc->ODRIVE_Rx.Buffer, - CDC_DATA_FS_OUT_PACKET_SIZE); + } return ret; } @@ -457,25 +565,17 @@ static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, { uint8_t ret = 0; - /* Close EP IN */ + /* Open EP IN */ USBD_LL_CloseEP(pdev, CDC_IN_EP); - /* Close EP OUT */ + /* Open EP OUT */ USBD_LL_CloseEP(pdev, CDC_OUT_EP); - /* Close Command IN EP */ + /* Open Command IN EP */ USBD_LL_CloseEP(pdev, CDC_CMD_EP); - - /* Close EP IN */ - USBD_LL_CloseEP(pdev, - ODRIVE_IN_EP); - - /* Close EP OUT */ - USBD_LL_CloseEP(pdev, - ODRIVE_OUT_EP); /* DeInit physical Interface components */ @@ -547,9 +647,6 @@ static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, case USB_REQ_SET_INTERFACE : break; } - - case USB_REQ_TYPE_VENDOR: - return USBD_WinUSBComm_SetupVendor(pdev, req); default: break; @@ -570,13 +667,9 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) if(pdev->pClassData != NULL) { - // NOTE: We would logically expect xx_IN_EP here, but we actually get the xx_OUT_EP - if (epnum == CDC_OUT_EP) - hcdc->CDC_Tx.State = 0; - if (epnum == ODRIVE_OUT_EP) - hcdc->ODRIVE_Tx.State = 0; - //Note: We could use independent semaphores for simoultainous USB transmission. - osSemaphoreRelease(sem_usb_tx); + + hcdc->TxState = 0; + return USBD_OK; } else @@ -595,24 +688,15 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; - - USBD_CDC_EP_HandleTypeDef* hEP_Rx; - if (epnum == CDC_OUT_EP) { - hEP_Rx = &hcdc->CDC_Rx; - } else if (epnum == ODRIVE_OUT_EP) { - hEP_Rx = &hcdc->ODRIVE_Rx; - } else { - return USBD_FAIL; - } /* Get the received data length */ - hEP_Rx->Length = USBD_LL_GetRxDataSize (pdev, epnum); + hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum); /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ if(pdev->pClassData != NULL) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hEP_Rx->Buffer, &hEP_Rx->Length, epnum); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); return USBD_OK; } @@ -655,8 +739,8 @@ static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_CfgDesc); - return USBD_CDC_CfgDesc; + *length = sizeof (USBD_CDC_CfgFSDesc); + return USBD_CDC_CfgFSDesc; } /** @@ -668,8 +752,8 @@ static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) */ static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_CfgDesc); - return USBD_CDC_CfgDesc; + *length = sizeof (USBD_CDC_CfgHSDesc); + return USBD_CDC_CfgHSDesc; } /** @@ -681,8 +765,8 @@ static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) */ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_CfgDesc); - return USBD_CDC_CfgDesc; + *length = sizeof (USBD_CDC_OtherSpeedCfgDesc); + return USBD_CDC_OtherSpeedCfgDesc; } /** @@ -725,22 +809,12 @@ uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, */ uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint16_t length, - uint8_t endpoint_pair) + uint16_t length) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; - USBD_CDC_EP_HandleTypeDef* hEP_Tx; - if (endpoint_pair == CDC_OUT_EP) { - hEP_Tx = &hcdc->CDC_Tx; - } else if (endpoint_pair == ODRIVE_OUT_EP) { - hEP_Tx = &hcdc->ODRIVE_Tx; - } else { - return USBD_FAIL; - } - - hEP_Tx->Buffer = pbuff; - hEP_Tx->Length = length; + hcdc->TxBuffer = pbuff; + hcdc->TxLength = length; return USBD_OK; } @@ -753,20 +827,11 @@ uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, * @retval status */ uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, - uint8_t *pbuff, uint8_t endpoint_pair) + uint8_t *pbuff) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; - - USBD_CDC_EP_HandleTypeDef* hEP_Rx; - if (endpoint_pair == CDC_OUT_EP) { - hEP_Rx = &hcdc->CDC_Rx; - } else if (endpoint_pair == ODRIVE_OUT_EP) { - hEP_Rx = &hcdc->ODRIVE_Rx; - } else { - return USBD_FAIL; - } - hEP_Rx->Buffer = pbuff; + hcdc->RxBuffer = pbuff; return USBD_OK; } @@ -778,36 +843,23 @@ uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, * @param epnum: endpoint number * @retval status */ -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair) +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; if(pdev->pClassData != NULL) { - // Select Endpoint - USBD_CDC_EP_HandleTypeDef* hEP_Tx; - uint8_t in_ep; - if (endpoint_pair == CDC_OUT_EP) { - hEP_Tx = &hcdc->CDC_Tx; - in_ep = CDC_IN_EP; - } else if (endpoint_pair == ODRIVE_OUT_EP) { - hEP_Tx = &hcdc->ODRIVE_Tx; - in_ep = ODRIVE_IN_EP; - } else { - return USBD_FAIL; - } - - if(hEP_Tx->State == 0) + if(hcdc->TxState == 0) { /* Tx Transfer in progress */ - hEP_Tx->State = 1; + hcdc->TxState = 1; /* Transmit next packet */ USBD_LL_Transmit(pdev, - in_ep, - hEP_Tx->Buffer, - hEP_Tx->Length); - + CDC_IN_EP, + hcdc->TxBuffer, + hcdc->TxLength); + return USBD_OK; } else @@ -828,32 +880,29 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair * @param pdev: device instance * @retval status */ -uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair) +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; /* Suspend or Resume USB Out process */ if(pdev->pClassData != NULL) { - // Select Endpoint - USBD_CDC_EP_HandleTypeDef* hEP_Rx; - uint8_t out_ep; - if (endpoint_pair == CDC_OUT_EP) { - hEP_Rx = &hcdc->CDC_Rx; - out_ep = CDC_OUT_EP; - } else if (endpoint_pair == ODRIVE_OUT_EP) { - hEP_Rx = &hcdc->ODRIVE_Rx; - out_ep = ODRIVE_OUT_EP; - } else { - return USBD_FAIL; + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); } - - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - out_ep, - hEP_Rx->Buffer, - pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_OUT_PACKET_SIZE : CDC_DATA_FS_OUT_PACKET_SIZE); - return USBD_OK; } else @@ -861,184 +910,6 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair) return USBD_FAIL; } } - - -/* WinUSB support ------------------------------------------------------------*/ -/* -* This section tells Windows that it should automatically load the WinUSB driver -* for the device (more specifically, interface 2 because it's a composite device). -* This allows for driverless communication with the device. -*/ - -#define NUM_INTERFACES 1 - -#if NUM_INTERFACES == 2 -#define USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ (16 + 24 + 24) -#else -#define USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ (16 + 24) -#endif - - -// This associates winusb driver with the device -__ALIGN_BEGIN uint8_t USBD_WinUSBComm_Extended_Compat_ID_OS_Desc[USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ] __ALIGN_END = -{ - // +-- Offset in descriptor - // | +-- Size - // v v - USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ, 0, 0, 0, // 0 dwLength 4 DWORD The length, in bytes, of the complete extended compat ID descriptor - 0x00, 0x01, // 4 bcdVersion 2 BCD The descriptor’s version number, in binary coded decimal (BCD) format - 0x04, 0x00, // 6 wIndex 2 WORD An index that identifies the particular OS feature descriptor - NUM_INTERFACES, // 8 bCount 1 BYTE The number of custom property sections - 0, 0, 0, 0, 0, 0, 0, // 9 RESERVED 7 BYTEs Reserved - // ===================== - // 16 - - // +-- Offset from function section start - // | +-- Size - // v v - 2, // 0 bFirstInterfaceNumber 1 BYTE The interface or function number - 0, // 1 RESERVED 1 BYTE Reserved - 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // 2 compatibleID 8 BYTEs The function’s compatible ID ("WINUSB") - 0, 0, 0, 0, 0, 0, 0, 0, // 10 subCompatibleID 8 BYTEs The function’s subcompatible ID - 0, 0, 0, 0, 0, 0, // 18 RESERVED 6 BYTEs Reserved - // ================================= - // 24 -#if NUM_INTERFACES == 2 - // +-- Offset from function section start - // | +-- Size - // v v - 2, // 0 bFirstInterfaceNumber 1 BYTE The interface or function number - 0, // 1 RESERVED 1 BYTE Reserved - 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // 2 compatibleID 8 BYTEs The function’s compatible ID ("WINUSB") - 0, 0, 0, 0, 0, 0, 0, 0, // 10 subCompatibleID 8 BYTEs The function’s subcompatible ID - 0, 0, 0, 0, 0, 0, // 18 RESERVED 6 BYTEs Reserved - // ================================= - // 24 -#endif -}; - - -// Properties are added to: -// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx\sssssssss\Device Parameters -// Use USBDeview or similar to uninstall - -__ALIGN_BEGIN uint8_t USBD_WinUSBComm_Extended_Properties_OS_Desc[0xB6] __ALIGN_END = -{ - 0xB6, 0x00, 0x00, 0x00, // 0 dwLength 4 DWORD The length, in bytes, of the complete extended properties descriptor - 0x00, 0x01, // 4 bcdVersion 2 BCD The descriptor’s version number, in binary coded decimal (BCD) format - 0x05, 0x00, // 6 wIndex 2 WORD The index for extended properties OS descriptors - 0x02, 0x00, // 8 wCount 2 WORD The number of custom property sections that follow the header section - // ==================== - // 10 -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - 0x84, 0x00, 0x00, 0x00, // 0 dwSize 4 DWORD The size of this custom properties section - 0x01, 0x00, 0x00, 0x00, // 4 dwPropertyDataType 4 DWORD Property data format - 0x28, 0x00, // 8 wPropertyNameLength 2 DWORD Property name length - // ======================================== - // 10 - // 10 bPropertyName PNL WCHAR[] The property name - 'D',0, 'e',0, 'v',0, 'i',0, 'c',0, 'e',0, 'I',0, 'n',0, - 't',0, 'e',0, 'r',0, 'f',0, 'a',0, 'c',0, 'e',0, 'G',0, - 'U',0, 'I',0, 'D',0, 0,0, - // ======================================== - // 40 (0x28) - - 0x4E, 0x00, 0x00, 0x00, // 10 + PNL dwPropertyDataLength 4 DWORD Length of the buffer holding the property data - // ======================================== - // 4 - // 14 + PNL bPropertyData PDL Format-dependent Property data - '{',0, 'E',0, 'A',0, '0',0, 'B',0, 'D',0, '5',0, 'C',0, - '3',0, '-',0, '5',0, '0',0, 'F',0, '3',0, '-',0, '4',0, - '8',0, '8',0, '8',0, '-',0, '8',0, '4',0, 'B',0, '4',0, - '-',0, '7',0, '4',0, 'E',0, '5',0, '0',0, 'E',0, '1',0, - '6',0, '4',0, '9',0, 'D',0, 'B',0, '}',0, 0 ,0, - // ======================================== - // 78 (0x4E) -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - 0x3E, 0x00, 0x00, 0x00, // 0 dwSize 0x00000030 (62 bytes) - 0x01, 0x00, 0x00, 0x00, // 4 dwPropertyDataType 0x00000001 (Unicode string) - 0x0C, 0x00, // 8 wPropertyNameLength 0x000C (12 bytes) - // ======================================== - // 10 - 'L',0, 'a',0, 'b',0, 'e',0, 'l',0, 0,0, - // 10 bPropertyName “Label” - // ======================================== - // 12 - 0x24, 0x00, 0x00, 0x00, // 22 dwPropertyDataLength 0x00000016 (36 bytes) - // ======================================== - // 4 - 'O',0, 'D',0, 'r',0, 'i',0, 'v',0, 'e',0, 0,0 - // 26 bPropertyData “ODrive” - // ======================================== - // 14 - -}; - - - -static uint8_t USBD_WinUSBComm_GetMSExtendedCompatIDOSDescriptor (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ - switch (req->wIndex) - { - case 0x04: - USBD_CtlSendData (pdev, USBD_WinUSBComm_Extended_Compat_ID_OS_Desc, req->wLength); - break; - default: - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - return USBD_OK; -} -static uint8_t USBD_WinUSBComm_GetMSExtendedPropertiesOSDescriptor (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ - uint8_t byInterfaceIndex = (uint8_t)req->wValue; - if ( req->wIndex != 0x05 ) - { - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - switch ( byInterfaceIndex ) - { - case 0: -#if NUM_INTERFACES == 2 - case 1: -#endif - USBD_CtlSendData (pdev, USBD_WinUSBComm_Extended_Properties_OS_Desc, req->wLength); - break; - default: - USBD_CtlError(pdev , req); - return USBD_FAIL; - } - return USBD_OK; -} -static uint8_t USBD_WinUSBComm_SetupVendorDevice(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ - USBD_CtlError(pdev , req); - return USBD_FAIL; -} -static uint8_t USBD_WinUSBComm_SetupVendorInterface(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ - USBD_CtlError(pdev , req); - // TODO: check if this is important - return USBD_FAIL; -} -static uint8_t USBD_WinUSBComm_SetupVendor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) -{ - switch ( req->bmRequest & USB_REQ_RECIPIENT_MASK ) - { - case USB_REQ_RECIPIENT_DEVICE: - return ( MS_VendorCode == req->bRequest ) ? USBD_WinUSBComm_GetMSExtendedCompatIDOSDescriptor(pdev, req) : USBD_WinUSBComm_SetupVendorDevice(pdev, req); - case USB_REQ_RECIPIENT_INTERFACE: - return ( MS_VendorCode == req->bRequest ) ? USBD_WinUSBComm_GetMSExtendedPropertiesOSDescriptor(pdev, req) : USBD_WinUSBComm_SetupVendorInterface(pdev, req); - case USB_REQ_RECIPIENT_ENDPOINT: - // fall through - default: - break; - } - USBD_CtlError(pdev , req); - return USBD_FAIL; -} - /** * @} */ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h index f259b51d..8fbe81e4 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -68,9 +68,7 @@ #define USBD_IDX_PRODUCT_STR 0x02 #define USBD_IDX_SERIAL_STR 0x03 #define USBD_IDX_CONFIG_STR 0x04 -#define USBD_IDX_INTERFACE_STR 0x05 -#define USBD_IDX_ODRIVE_INTF_STR 0x06 -#define USBD_IDX_MICROSOFT_DESC_STR 0xEE +#define USBD_IDX_INTERFACE_STR 0x05 #define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_CLASS 0x20 diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c index 7828403b..d0e0fd76 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c @@ -816,10 +816,10 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t * @brief Wait until a Semaphore token becomes available * @param semaphore_id semaphore object referenced with \ref osSemaphore. * @param millisec timeout value or 0 in case of no time-out. -* @retval status code that indicates the execution status of the function. +* @retval number of available tokens, or -1 in case of incorrect parameters. * @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. */ -osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { TickType_t ticks; portBASE_TYPE taskWoken = pdFALSE; diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h index 754be245..15e25b96 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h @@ -270,11 +270,11 @@ typedef enum { /// Entry point of a thread. /// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. -typedef void (*os_pthread) (void *argument); +typedef void (*os_pthread) (void const *argument); /// Entry point of a timer call back function. /// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. -typedef void (*os_ptimer) (void *argument); +typedef void (*os_ptimer) (void const *argument); // >>> the following data type definitions may shall adapted towards a specific RTOS @@ -323,7 +323,7 @@ typedef StaticQueue_t osStaticMessageQDef_t; /// Thread Definition structure contains startup information of a thread. /// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. typedef struct os_thread_def { - const char *name; ///< Thread name + char *name; ///< Thread name os_pthread pthread; ///< start address of thread function osPriority tpriority; ///< initial thread priority uint32_t instances; ///< maximum number of instances of that thread function @@ -719,9 +719,9 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t /// Wait until a Semaphore token becomes available. /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. /// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return status code that indicates the execution status of the function. +/// \return number of available tokens, or -1 in case of incorrect parameters. /// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); +int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); /// Release a Semaphore token. /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. diff --git a/Firmware/Board/v3/Odrive.ioc b/Firmware/Board/v3/Odrive.ioc index 707c3f2a..0652d4df 100644 --- a/Firmware/Board/v3/Odrive.ioc +++ b/Firmware/Board/v3/Odrive.ioc @@ -76,9 +76,11 @@ ADC3.SamplingTime-7\#ChannelRegularConversion=ADC_SAMPLETIME_3CYCLES ADC3.SamplingTime-8\#ChannelInjectedConversion=ADC_SAMPLETIME_3CYCLES ADC3.ScanConvMode=DISABLE CAN1.AutoWakeUp=ENABLE +CAN1.BS1=CAN_BS1_6TQ +CAN1.BS2=CAN_BS2_5TQ CAN1.CalculateTimeBit=500 CAN1.CalculateTimeQuantum=166.66666666666669 -CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,Prescaler,TimeSeg1,TimeSeg2,AutoWakeUp +CAN1.IPParameters=CalculateTimeQuantum,CalculateTimeBit,Prescaler,TimeSeg1,TimeSeg2,AutoWakeUp,BS1,BS2 CAN1.Prescaler=7 CAN1.TimeSeg1=CAN_BS1_6TQ CAN1.TimeSeg2=CAN_BS2_5TQ @@ -209,8 +211,8 @@ Mcu.PinsNb=56 Mcu.ThirdPartyNb=0 Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;configAPPLICATION_ALLOCATED_HEAP,1;TIM_1_8_RCR,2 Mcu.UserName=STM32F405RGTx -MxCube.Version=4.24.0 -MxDb.Version=DB.4.0.240 +MxCube.Version=4.27.0 +MxDb.Version=DB.4.0.270 NVIC.ADC_IRQn=true\:5\:0\:false\:false\:true\:true\:true NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:true NVIC.CAN1_RX0_IRQn=true\:6\:0\:true\:false\:true\:true\:true @@ -443,7 +445,7 @@ ProjectManager.CustomerFirmwarePackage= ProjectManager.DefaultFWLocation=true ProjectManager.DeletePrevious=true ProjectManager.DeviceId=STM32F405RGTx -ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.19.0 +ProjectManager.FirmwarePackage=STM32Cube FW_F4 V1.21.0 ProjectManager.FreePins=false ProjectManager.HalAssertFull=false ProjectManager.HeapSize=0x3C00 diff --git a/Firmware/Board/v3/Src/can.c b/Firmware/Board/v3/Src/can.c index fc7bf388..2171691a 100644 --- a/Firmware/Board/v3/Src/can.c +++ b/Firmware/Board/v3/Src/can.c @@ -70,7 +70,7 @@ void MX_CAN1_Init(void) hcan1.Init.TimeSeg2 = CAN_BS2_5TQ; hcan1.Init.TimeTriggeredMode = DISABLE; hcan1.Init.AutoBusOff = DISABLE; - hcan1.Init.AutoWakeUp = ENABLE; + hcan1.Init.AutoWakeUp = DISABLE; hcan1.Init.AutoRetransmission = DISABLE; hcan1.Init.ReceiveFifoLocked = DISABLE; hcan1.Init.TransmitFifoPriority = DISABLE; diff --git a/Firmware/Board/v3/Src/dma.c b/Firmware/Board/v3/Src/dma.c index 3de873ad..55d5e034 100644 --- a/Firmware/Board/v3/Src/dma.c +++ b/Firmware/Board/v3/Src/dma.c @@ -78,10 +78,8 @@ void MX_DMA_Init(void) HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); /* DMA2_Stream0_IRQn interrupt configuration */ - // Dear STM, no we _don't_ want to fire an interrupt for this DMA - // (it's not possible to deselect this in CubeMX) - //HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); - //HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); + HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); + HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); } diff --git a/Firmware/Board/v3/Src/freertos.c b/Firmware/Board/v3/Src/freertos.c index 524cd6cb..0865d714 100644 --- a/Firmware/Board/v3/Src/freertos.c +++ b/Firmware/Board/v3/Src/freertos.c @@ -1,3 +1,4 @@ +/* USER CODE BEGIN Header */ /** ****************************************************************************** * File Name : freertos.c @@ -45,12 +46,15 @@ * ****************************************************************************** */ +/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "FreeRTOS.h" #include "task.h" +#include "main.h" #include "cmsis_os.h" +/* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "freertos_vars.h" #include "usb_device.h" @@ -58,9 +62,22 @@ extern PCD_HandleTypeDef hpcd_USB_OTG_FS; int odrive_main(void); /* USER CODE END Includes */ -/* Variables -----------------------------------------------------------------*/ -osThreadId defaultTaskHandle; +/* Private typedef -----------------------------------------------------------*/ +/* USER CODE BEGIN PTD */ +/* USER CODE END PTD */ + +/* Private define ------------------------------------------------------------*/ +/* USER CODE BEGIN PD */ + +/* USER CODE END PD */ + +/* Private macro -------------------------------------------------------------*/ +/* USER CODE BEGIN PM */ + +/* USER CODE END PM */ + +/* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ // List of semaphores osSemaphoreId sem_usb_irq; @@ -74,17 +91,18 @@ osThreadId usb_irq_thread; __attribute__((section(".ccmram"))) uint8_t ucHeap[configTOTAL_HEAP_SIZE]; /* USER CODE END Variables */ +osThreadId defaultTaskHandle; -/* Function prototypes -------------------------------------------------------*/ -void StartDefaultTask(void * argument); - -extern void MX_USB_DEVICE_Init(void); -void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ - +/* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN FunctionPrototypes */ /* USER CODE END FunctionPrototypes */ +void StartDefaultTask(void const * argument); + +extern void MX_USB_DEVICE_Init(void); +void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ + /* Hook prototypes */ void vApplicationIdleHook(void); void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName); @@ -135,8 +153,11 @@ void init_deferred_interrupts(void) { /* USER CODE END 4 */ -/* Init FreeRTOS */ - +/** + * @brief FreeRTOS initialization + * @param None + * @retval None + */ void MX_FREERTOS_Init(void) { /* USER CODE BEGIN Init */ @@ -186,8 +207,14 @@ void MX_FREERTOS_Init(void) { /* USER CODE END RTOS_QUEUES */ } -/* StartDefaultTask function */ -void StartDefaultTask(void * argument) +/* USER CODE BEGIN Header_StartDefaultTask */ +/** + * @brief Function implementing the defaultTask thread. + * @param argument: Not used + * @retval None + */ +/* USER CODE END Header_StartDefaultTask */ +void StartDefaultTask(void const * argument) { /* init code for USB_DEVICE */ MX_USB_DEVICE_Init(); @@ -202,6 +229,7 @@ void StartDefaultTask(void * argument) /* USER CODE END StartDefaultTask */ } +/* Private application code --------------------------------------------------*/ /* USER CODE BEGIN Application */ /* USER CODE END Application */ diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index b71d6416..1a930e60 100644 --- a/Firmware/Board/v3/Src/main.c +++ b/Firmware/Board/v3/Src/main.c @@ -1,3 +1,4 @@ + /** ****************************************************************************** * @file : main.c diff --git a/Firmware/Board/v3/Src/stm32f4xx_hal_msp.c b/Firmware/Board/v3/Src/stm32f4xx_hal_msp.c index fac7e341..e49480c0 100644 --- a/Firmware/Board/v3/Src/stm32f4xx_hal_msp.c +++ b/Firmware/Board/v3/Src/stm32f4xx_hal_msp.c @@ -48,7 +48,6 @@ */ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" - extern void _Error_Handler(char *, int); /* USER CODE BEGIN 0 */ @@ -62,6 +61,9 @@ void HAL_MspInit(void) /* USER CODE END MspInit 0 */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); /* System interrupt init*/ diff --git a/Firmware/Board/v3/Src/usbd_cdc_if.c b/Firmware/Board/v3/Src/usbd_cdc_if.c index b8cb6e6c..fcc712a3 100644 --- a/Firmware/Board/v3/Src/usbd_cdc_if.c +++ b/Firmware/Board/v3/Src/usbd_cdc_if.c @@ -117,12 +117,10 @@ /* Create buffer for reception and transmission */ /* It's up to user to redefine and/or remove those define */ /** Received data over USB are stored in this buffer */ -uint8_t CDCRxBufferFS[APP_RX_DATA_SIZE]; -uint8_t ODRIVERxBufferFS[APP_RX_DATA_SIZE]; +uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; /** Data to send over USB CDC are stored in this buffer */ -uint8_t CDCTxBufferFS[APP_TX_DATA_SIZE]; -uint8_t ODRIVETxBufferFS[APP_TX_DATA_SIZE]; +uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; /* USER CODE BEGIN PRIVATE_VARIABLES */ /* USER CODE END PRIVATE_VARIABLES */ @@ -153,7 +151,7 @@ extern USBD_HandleTypeDef hUsbDeviceFS; static int8_t CDC_Init_FS(void); static int8_t CDC_DeInit_FS(void); static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); -static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len, uint8_t endpoint_pair); +static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ @@ -291,7 +289,7 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len, uint8_t endpoint_pair) +static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ usb_rx_process_packet(Buf, *Len, endpoint_pair); @@ -311,7 +309,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len, uint8_t endpoint_pair) * @param Len: Number of data to be sent (in bytes) * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY */ -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t endpoint_pair) +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) { uint8_t result = USBD_OK; /* USER CODE BEGIN 7 */ diff --git a/Firmware/Board/v3/Src/usbd_conf.c b/Firmware/Board/v3/Src/usbd_conf.c index 2d66d4a1..7046dc96 100644 --- a/Firmware/Board/v3/Src/usbd_conf.c +++ b/Firmware/Board/v3/Src/usbd_conf.c @@ -66,7 +66,7 @@ /* USER CODE END PV */ -PCD_HandleTypeDef hpcd_USB_OTG_FS; + PCD_HandleTypeDef hpcd_USB_OTG_FS; void _Error_Handler(char * file, int line); /* External functions --------------------------------------------------------*/ @@ -154,23 +154,6 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) */ void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { - USBD_StatusTypeDef ret = USBD_OK; - USBD_HandleTypeDef *pdev = hpcd->pData; - USBD_SetupReqTypedef *req = &pdev->request; - USBD_ParseSetupRequest(req, (uint8_t *)hpcd->Setup); - if ( ( USB_REQ_TYPE_VENDOR == (req->bmRequest & USB_REQ_TYPE_MASK) ) && ( MS_VendorCode == req->bRequest ) ) - { - pdev->ep0_state = USBD_EP0_SETUP; - pdev->ep0_data_len = pdev->request.wLength; - - ret = pdev->pClass->Setup(pdev, req); - - if( (req->wLength == 0) && (ret == USBD_OK) ) - { - USBD_CtlSendStatus(pdev); - } - return; - } USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); } @@ -329,7 +312,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) pdev->pData = &hpcd_USB_OTG_FS; hpcd_USB_OTG_FS.Instance = USB_OTG_FS; - hpcd_USB_OTG_FS.Init.dev_endpoints = 6; + hpcd_USB_OTG_FS.Init.dev_endpoints = 4; hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL; hpcd_USB_OTG_FS.Init.dma_enable = DISABLE; hpcd_USB_OTG_FS.Init.ep0_mps = DEP0CTL_MPS_64; @@ -346,8 +329,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80); HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40); - HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40); // CDC IN endpoint - HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40); // ODrive IN endpoint + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); } return USBD_OK; } diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c index d213f64a..2e139e50 100644 --- a/Firmware/Board/v3/Src/usbd_desc.c +++ b/Firmware/Board/v3/Src/usbd_desc.c @@ -95,10 +95,7 @@ #define USBD_LANGID_STRING 1033 #define USBD_MANUFACTURER_STRING "ODrive Robotics" #define USBD_PID_FS 0x0D32 -#define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) -#define USBD_PRODUCT_STR(s) #s -#define USBD_PRODUCT_STRING_FS ODrive HW_VERSION_MAJOR.HW_VERSION_MINOR CDC Interface -#define NATIVE_STRING ODrive HW_VERSION_MAJOR.HW_VERSION_MINOR Native Interface +#define USBD_PRODUCT_STRING_FS "ODrive v3.3" #define USBD_SERIALNUMBER_STRING_FS "000000000001" #define USBD_CONFIGURATION_STRING_FS "CDC Config" #define USBD_INTERFACE_STRING_FS "CDC Interface" @@ -234,17 +231,16 @@ __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = 0x00, /*bcdUSB */ #endif /* (USBD_LPM_ENABLED == 1) */ 0x02, - // Notify OS that this is a composite device - 0xEF, /*bDeviceClass*/ + 0x02, /*bDeviceClass*/ 0x02, /*bDeviceSubClass*/ - 0x01, /*bDeviceProtocol*/ + 0x00, /*bDeviceProtocol*/ USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID_FS), /*idProduct*/ HIBYTE(USBD_PID_FS), /*idProduct*/ 0x00, /*bcdDevice rel. 2.00*/ - 0x03, /* bNumInterfaces */ + 0x02, USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ @@ -346,11 +342,11 @@ uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length { if(speed == 0) { - USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); + USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); } else { - USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); + USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); } return USBD_StrDesc; } @@ -375,7 +371,14 @@ uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *l */ uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { - USBD_GetString ((uint8_t *)serial_number_str, USBD_StrDesc, length); + if(speed == USBD_SPEED_HIGH) + { + USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); + } return USBD_StrDesc; } From 3850ce260fcc8effd87ca65b575f43fcc7769bc9 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 19:00:53 -0700 Subject: [PATCH 09/40] STM32CubeMX run to add TIM13 synced to RCRd TIM1 --- Firmware/Board/v3/Inc/tim.h | 2 ++ Firmware/Board/v3/Odrive.ioc | 20 +++++++----- Firmware/Board/v3/Src/main.c | 1 + Firmware/Board/v3/Src/tim.c | 61 +++++++++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/Firmware/Board/v3/Inc/tim.h b/Firmware/Board/v3/Inc/tim.h index ba58367a..a4585c53 100644 --- a/Firmware/Board/v3/Inc/tim.h +++ b/Firmware/Board/v3/Inc/tim.h @@ -67,6 +67,7 @@ extern TIM_HandleTypeDef htim3; extern TIM_HandleTypeDef htim4; extern TIM_HandleTypeDef htim5; extern TIM_HandleTypeDef htim8; +extern TIM_HandleTypeDef htim13; /* USER CODE BEGIN Private defines */ @@ -80,6 +81,7 @@ void MX_TIM3_Init(void); void MX_TIM4_Init(void); void MX_TIM5_Init(void); void MX_TIM8_Init(void); +void MX_TIM13_Init(void); void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); diff --git a/Firmware/Board/v3/Odrive.ioc b/Firmware/Board/v3/Odrive.ioc index 0652d4df..c9bbdc7f 100644 --- a/Firmware/Board/v3/Odrive.ioc +++ b/Firmware/Board/v3/Odrive.ioc @@ -137,9 +137,10 @@ Mcu.IP12=TIM3 Mcu.IP13=TIM4 Mcu.IP14=TIM5 Mcu.IP15=TIM8 -Mcu.IP16=UART4 -Mcu.IP17=USB_DEVICE -Mcu.IP18=USB_OTG_FS +Mcu.IP16=TIM13 +Mcu.IP17=UART4 +Mcu.IP18=USB_DEVICE +Mcu.IP19=USB_OTG_FS Mcu.IP2=ADC3 Mcu.IP3=CAN1 Mcu.IP4=DMA @@ -148,7 +149,7 @@ Mcu.IP6=NVIC Mcu.IP7=RCC Mcu.IP8=SPI3 Mcu.IP9=SYS -Mcu.IPNb=19 +Mcu.IPNb=20 Mcu.Name=STM32F405RGTx Mcu.Package=LQFP64 Mcu.Pin0=PC13-ANTI_TAMP @@ -202,12 +203,13 @@ Mcu.Pin51=VP_FREERTOS_VS_ENABLE Mcu.Pin52=VP_SYS_VS_tim14 Mcu.Pin53=VP_TIM1_VS_ClockSourceINT Mcu.Pin54=VP_TIM1_VS_no_output4 -Mcu.Pin55=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS +Mcu.Pin55=VP_TIM13_VS_ClockSourceINT +Mcu.Pin56=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS Mcu.Pin6=PC1 Mcu.Pin7=PC2 Mcu.Pin8=PC3 Mcu.Pin9=PA0-WKUP -Mcu.PinsNb=56 +Mcu.PinsNb=57 Mcu.ThirdPartyNb=0 Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;configAPPLICATION_ALLOCATED_HEAP,1;TIM_1_8_RCR,2 Mcu.UserName=STM32F405RGTx @@ -462,7 +464,7 @@ ProjectManager.StackSize=0x800 ProjectManager.TargetToolchain=Makefile ProjectManager.ToolChainLocation= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_ADC2_Init-ADC2-false-HAL-true,5-MX_CAN1_Init-CAN1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM8_Init-TIM8-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_TIM4_Init-TIM4-false-HAL-true,10-MX_SPI3_Init-SPI3-false-HAL-true,11-MX_ADC3_Init-ADC3-false-HAL-true,12-SystemClock_Config-RCC-false-HAL-true,13-MX_TIM2_Init-TIM2-false-HAL-true,14-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-true,15-MX_UART4_Init-UART4-false-HAL-true,16-MX_TIM5_Init-TIM5-false-HAL-true +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-MX_DMA_Init-DMA-false-HAL-true,3-MX_ADC1_Init-ADC1-false-HAL-true,4-MX_ADC2_Init-ADC2-false-HAL-true,5-MX_CAN1_Init-CAN1-false-HAL-true,6-MX_TIM1_Init-TIM1-false-HAL-true,7-MX_TIM8_Init-TIM8-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true,9-MX_TIM4_Init-TIM4-false-HAL-true,10-MX_SPI3_Init-SPI3-false-HAL-true,11-MX_ADC3_Init-ADC3-false-HAL-true,12-SystemClock_Config-RCC-false-HAL-true,13-MX_TIM2_Init-TIM2-false-HAL-true,14-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-true,15-MX_UART4_Init-UART4-false-HAL-true,16-MX_TIM5_Init-TIM5-false-HAL-true,17-MX_TIM13_Init-TIM13-false-HAL-true RCC.48MHZClocksFreq_Value=48000000 RCC.AHBFreq_Value=168000000 RCC.APB1CLKDivider=RCC_HCLK_DIV4 @@ -592,6 +594,8 @@ TIM1.OffStateRunMode=TIM_OSSR_ENABLE TIM1.Period=TIM_1_8_PERIOD_CLOCKS TIM1.RepetitionCounter=TIM_1_8_RCR TIM1.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE +TIM13.IPParameters=Period +TIM13.Period=(2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1) * TIM_APB1_CLOCK_HZ) / TIM_1_8_CLOCK_HZ TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 TIM2.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 TIM2.CounterMode=TIM_COUNTERMODE_CENTERALIGNED3 @@ -658,6 +662,8 @@ VP_FREERTOS_VS_ENABLE.Mode=Enabled VP_FREERTOS_VS_ENABLE.Signal=FREERTOS_VS_ENABLE VP_SYS_VS_tim14.Mode=TIM14 VP_SYS_VS_tim14.Signal=SYS_VS_tim14 +VP_TIM13_VS_ClockSourceINT.Mode=Enable_Timer +VP_TIM13_VS_ClockSourceINT.Signal=TIM13_VS_ClockSourceINT VP_TIM1_VS_ClockSourceINT.Mode=Internal VP_TIM1_VS_ClockSourceINT.Signal=TIM1_VS_ClockSourceINT VP_TIM1_VS_no_output4.Mode=Output Compare4 No Output diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index 1a930e60..e390af58 100644 --- a/Firmware/Board/v3/Src/main.c +++ b/Firmware/Board/v3/Src/main.c @@ -190,6 +190,7 @@ int main(void) MX_TIM2_Init(); MX_UART4_Init(); MX_TIM5_Init(); + MX_TIM13_Init(); /* USER CODE BEGIN 2 */ //Required to use OC4 for ADC triggering. diff --git a/Firmware/Board/v3/Src/tim.c b/Firmware/Board/v3/Src/tim.c index a909cf2a..b68a5894 100644 --- a/Firmware/Board/v3/Src/tim.c +++ b/Firmware/Board/v3/Src/tim.c @@ -80,6 +80,7 @@ TIM_HandleTypeDef htim3; TIM_HandleTypeDef htim4; TIM_HandleTypeDef htim5; TIM_HandleTypeDef htim8; +TIM_HandleTypeDef htim13; /* TIM1 init function */ void MX_TIM1_Init(void) @@ -373,6 +374,21 @@ void MX_TIM8_Init(void) HAL_TIM_MspPostInit(&htim8); +} +/* TIM13 init function */ +void MX_TIM13_Init(void) +{ + + htim13.Instance = TIM13; + htim13.Init.Prescaler = 0; + htim13.Init.CounterMode = TIM_COUNTERMODE_UP; + htim13.Init.Period = (2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1) * TIM_APB1_CLOCK_HZ) / TIM_1_8_CLOCK_HZ; + htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + if (HAL_TIM_Base_Init(&htim13) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + } void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) @@ -393,6 +409,21 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) /* USER CODE END TIM1_MspInit 1 */ } + else if(tim_baseHandle->Instance==TIM13) + { + /* USER CODE BEGIN TIM13_MspInit 0 */ + + /* USER CODE END TIM13_MspInit 0 */ + /* TIM13 clock enable */ + __HAL_RCC_TIM13_CLK_ENABLE(); + + /* TIM13 interrupt Init */ + HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn); + /* USER CODE BEGIN TIM13_MspInit 1 */ + + /* USER CODE END TIM13_MspInit 1 */ + } } void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef* tim_pwmHandle) @@ -626,6 +657,27 @@ void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) /* USER CODE END TIM1_MspDeInit 1 */ } + else if(tim_baseHandle->Instance==TIM13) + { + /* USER CODE BEGIN TIM13_MspDeInit 0 */ + + /* USER CODE END TIM13_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM13_CLK_DISABLE(); + + /* TIM13 interrupt Deinit */ + /* USER CODE BEGIN TIM13:TIM8_UP_TIM13_IRQn disable */ + /** + * Uncomment the line below to disable the "TIM8_UP_TIM13_IRQn" interrupt + * Be aware, disabling shared interrupt may affect other IPs + */ + /* HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn); */ + /* USER CODE END TIM13:TIM8_UP_TIM13_IRQn disable */ + + /* USER CODE BEGIN TIM13_MspDeInit 1 */ + + /* USER CODE END TIM13_MspDeInit 1 */ + } } void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle) @@ -651,7 +703,14 @@ void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef* tim_pwmHandle) __HAL_RCC_TIM8_CLK_DISABLE(); /* TIM8 interrupt Deinit */ - HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn); + /* USER CODE BEGIN TIM8:TIM8_UP_TIM13_IRQn disable */ + /** + * Uncomment the line below to disable the "TIM8_UP_TIM13_IRQn" interrupt + * Be aware, disabling shared interrupt may affect other IPs + */ + /* HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn); */ + /* USER CODE END TIM8:TIM8_UP_TIM13_IRQn disable */ + HAL_NVIC_DisableIRQ(TIM8_TRG_COM_TIM14_IRQn); /* USER CODE BEGIN TIM8_MspDeInit 1 */ From a7b7814fcecb9fe44d18b44837cfc4cf9739ea5f Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:23:46 -0700 Subject: [PATCH 10/40] bake patch: display correct ODrive version in USB descriptor --- ...ect-ODrive-version-in-USB-descriptor.patch | 41 ------------------- Firmware/Board/v3/Src/usbd_desc.c | 8 ++-- 2 files changed, 5 insertions(+), 44 deletions(-) delete mode 100644 Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch diff --git a/Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch b/Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch deleted file mode 100644 index 0b031242..00000000 --- a/Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b7ea3f500fbfc187a0a7112282ae6b1eee4555d0 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Tue, 13 Mar 2018 20:05:07 -0700 -Subject: [PATCH] display correct ODrive version in USB descriptor - ---- - Firmware/Board/v3/Src/usbd_desc.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c -index 94dc49b..37b4302 100644 ---- a/Firmware/Board/v3/Src/usbd_desc.c -+++ b/Firmware/Board/v3/Src/usbd_desc.c -@@ -96,7 +96,9 @@ - #define USBD_LANGID_STRING 1033 - #define USBD_MANUFACTURER_STRING "ODrive Robotics" - #define USBD_PID_FS 0x0D32 --#define USBD_PRODUCT_STRING_FS "ODrive v3.3" -+#define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) -+#define USBD_PRODUCT_STR(s) #s -+#define USBD_PRODUCT_STRING_FS ODrive version HW_VERSION_MAJOR.HW_VERSION_MINOR - #define USBD_SERIALNUMBER_STRING_FS "000000000001" - #define USBD_CONFIGURATION_STRING_FS "CDC Config" - #define USBD_INTERFACE_STRING_FS "CDC Interface" -@@ -299,11 +301,11 @@ uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length - { - if(speed == 0) - { -- USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); -+ USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); - } - else - { -- USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); -+ USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); - } - return USBD_StrDesc; - } --- -2.16.2 - diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c index 2e139e50..973b0ae2 100644 --- a/Firmware/Board/v3/Src/usbd_desc.c +++ b/Firmware/Board/v3/Src/usbd_desc.c @@ -95,7 +95,9 @@ #define USBD_LANGID_STRING 1033 #define USBD_MANUFACTURER_STRING "ODrive Robotics" #define USBD_PID_FS 0x0D32 -#define USBD_PRODUCT_STRING_FS "ODrive v3.3" +#define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) +#define USBD_PRODUCT_STR(s) #s +#define USBD_PRODUCT_STRING_FS ODrive version HW_VERSION_MAJOR.HW_VERSION_MINOR #define USBD_SERIALNUMBER_STRING_FS "000000000001" #define USBD_CONFIGURATION_STRING_FS "CDC Config" #define USBD_INTERFACE_STRING_FS "CDC Interface" @@ -342,11 +344,11 @@ uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length { if(speed == 0) { - USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); } else { - USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); } return USBD_StrDesc; } From 60dc428f2e00020822c0e0cb6c9ea013b0ce945a Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:27:56 -0700 Subject: [PATCH 11/40] bake patch: expose correct serial number on USB --- ...-expose-correct-serial-number-on-USB.patch | 32 ------------------- Firmware/Board/v3/Src/usbd_desc.c | 9 +----- 2 files changed, 1 insertion(+), 40 deletions(-) delete mode 100644 Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch diff --git a/Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch b/Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch deleted file mode 100644 index b9fef648..00000000 --- a/Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0867a92f742b312a0ebaafe94cade6f57be22170 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 12 Mar 2018 23:49:32 -0700 -Subject: [PATCH] expose correct serial number on USB - ---- - Firmware/Board/v3/Src/usbd_desc.c | 9 +++++++++------- - 1 file changed, 1 insertions(+), 8 deletions(-) - -diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c -index b9c7bd0..94dc49b 100644 ---- a/Firmware/Board/v3/Src/usbd_desc.c -+++ b/Firmware/Board/v3/Src/usbd_desc.c -@@ -327,14 +327,7 @@ uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *l - */ - uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) - { -- if(speed == USBD_SPEED_HIGH) -- { -- USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); -- } -- else -- { -- USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); -- } -+ USBD_GetString ((uint8_t *)serial_number_str, USBD_StrDesc, length); - return USBD_StrDesc; - } - --- -2.16.2 - diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c index 973b0ae2..b0906144 100644 --- a/Firmware/Board/v3/Src/usbd_desc.c +++ b/Firmware/Board/v3/Src/usbd_desc.c @@ -373,14 +373,7 @@ uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *l */ uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { - if(speed == USBD_SPEED_HIGH) - { - USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); - } - else - { - USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); - } + USBD_GetString ((uint8_t *)serial_number_str, USBD_StrDesc, length); return USBD_StrDesc; } From a385c0b4d37d0576853e3ffb649221330228893d Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:29:43 -0700 Subject: [PATCH 12/40] bake patch: fix return type of osSemaphoreWait --- ...1-fix-return-type-of-osSemaphoreWait.patch | 46 ------------------- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c | 4 +- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 4 +- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch diff --git a/Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch b/Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch deleted file mode 100644 index 53760fa1..00000000 --- a/Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 49353ccb7023c02c2bc6e3b6f14fac02a13fe599 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Feb 2018 14:55:17 -0800 -Subject: [PATCH] fix return type of osSemaphoreWait - ---- - .../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c | 6 +++--- - .../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 6 +++--- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c -index d0e0fd7..e764cbc 100644 ---- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c -+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c -@@ -816,10 +816,10 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t - * @brief Wait until a Semaphore token becomes available - * @param semaphore_id semaphore object referenced with \ref osSemaphore. - * @param millisec timeout value or 0 in case of no time-out. --* @retval number of available tokens, or -1 in case of incorrect parameters. -+* @retval status code that indicates the execution status of the function. - * @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. - */ --int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) -+osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) - { - TickType_t ticks; - portBASE_TYPE taskWoken = pdFALSE; -diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -index 15e25b9..5223f8e 100644 ---- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -@@ -719,9 +719,9 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t - /// Wait until a Semaphore token becomes available. - /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. - /// \param[in] millisec timeout value or 0 in case of no time-out. --/// \return number of available tokens, or -1 in case of incorrect parameters. -+/// \return status code that indicates the execution status of the function. - /// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. --int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); -+osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); - - /// Release a Semaphore token. - /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. --- -2.16.1 - diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c index d0e0fd76..7828403b 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c @@ -816,10 +816,10 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t * @brief Wait until a Semaphore token becomes available * @param semaphore_id semaphore object referenced with \ref osSemaphore. * @param millisec timeout value or 0 in case of no time-out. -* @retval number of available tokens, or -1 in case of incorrect parameters. +* @retval status code that indicates the execution status of the function. * @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. */ -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) +osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { TickType_t ticks; portBASE_TYPE taskWoken = pdFALSE; diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h index 15e25b96..09cdf273 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h @@ -719,9 +719,9 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t /// Wait until a Semaphore token becomes available. /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. /// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \return status code that indicates the execution status of the function. /// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); +osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); /// Release a Semaphore token. /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. From 94701cec99b730fddbb3583e19d5e8867d4c4c65 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:31:41 -0700 Subject: [PATCH 13/40] bake patch: release sem_usb_tx in usb_cdc.c --- ...001-release-sem_usb_tx-in-usbd_cdc.c.patch | 35 ------------------- .../Class/CDC/Src/usbd_cdc.c | 5 +-- 2 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch diff --git a/Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch b/Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch deleted file mode 100644 index b69370f5..00000000 --- a/Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 965f7f2c80e30d7a66dcac7abaa9bdc371d9ea51 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Feb 2018 14:53:52 -0800 -Subject: [PATCH] release sem_usb_tx in usbd_cdc.c - ---- - .../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c -index b2ca5f1..6ae33e8 100644 ---- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c -+++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c -@@ -62,7 +62,8 @@ - #include "usbd_cdc.h" - #include "usbd_desc.h" - #include "usbd_ctlreq.h" -- -+#include -+#include - - /** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ -@@ -669,7 +670,7 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) - { - - hcdc->TxState = 0; -- -+ osSemaphoreRelease(sem_usb_tx); - return USBD_OK; - } - else --- -2.16.1 - diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index b2ca5f16..24465641 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -62,7 +62,8 @@ #include "usbd_cdc.h" #include "usbd_desc.h" #include "usbd_ctlreq.h" - +#include +#include /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ @@ -669,7 +670,7 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) { hcdc->TxState = 0; - + osSemaphoreRelease(sem_usb_tx); return USBD_OK; } else From 96006286c0ef55d2b65f6aed16c11ab14345cf9f Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:43:04 -0700 Subject: [PATCH 14/40] bake patch: FreeRTOS constness fixes --- .../v3/0002-FreeRTOS-constness-fixes.patch | 64 ------------------- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 8 +-- Firmware/Board/v3/Src/freertos.c | 4 +- 3 files changed, 6 insertions(+), 70 deletions(-) delete mode 100644 Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch diff --git a/Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch b/Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch deleted file mode 100644 index afe0326e..00000000 --- a/Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 510ead2b159e1d8116e5241066c54a7bf8b7bfbe Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Mar 2018 15:29:44 -0700 -Subject: [PATCH] FreeRTOS constness fixes - - - make thread names const char * - - make thread argument non-const void* ---- - .../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 6 +++--- - Firmware/Board/v3/Src/freertos.c | 4 ++-- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -index 09cdf27..754be24 100644 ---- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -@@ -270,11 +270,11 @@ typedef enum { - - /// Entry point of a thread. - /// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. --typedef void (*os_pthread) (void const *argument); -+typedef void (*os_pthread) (void *argument); - - /// Entry point of a timer call back function. - /// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. --typedef void (*os_ptimer) (void const *argument); -+typedef void (*os_ptimer) (void *argument); - - // >>> the following data type definitions may shall adapted towards a specific RTOS - -@@ -323,7 +323,7 @@ typedef StaticQueue_t osStaticMessageQDef_t; - /// Thread Definition structure contains startup information of a thread. - /// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. - typedef struct os_thread_def { -- char *name; ///< Thread name -+ const char *name; ///< Thread name - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t instances; ///< maximum number of instances of that thread function -diff --git a/Firmware/Board/v3/Src/freertos.c b/Firmware/Board/v3/Src/freertos.c -index 6eaea82..b247994 100644 ---- a/Firmware/Board/v3/Src/freertos.c -+++ b/Firmware/Board/v3/Src/freertos.c -@@ -75,7 +75,7 @@ uint8_t ucHeap[configTOTAL_HEAP_SIZE]; - /* USER CODE END Variables */ - - /* Function prototypes -------------------------------------------------------*/ --void StartDefaultTask(void const * argument); -+void StartDefaultTask(void * argument); - - extern void MX_USB_DEVICE_Init(void); - void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ -@@ -147,7 +147,7 @@ void MX_FREERTOS_Init(void) { - } - - /* StartDefaultTask function */ --void StartDefaultTask(void const * argument) -+void StartDefaultTask(void * argument) - { - /* init code for USB_DEVICE */ - MX_USB_DEVICE_Init(); --- -2.16.2 - diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h index 09cdf273..89a105dc 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h @@ -26,7 +26,7 @@ * *---------------------------------------------------------------------------- * - * Portions Copyright 2016 STMicroelectronics International N.V. All rights reserved. + * Portions Copyright � 2016 STMicroelectronics International N.V. All rights reserved. * Portions Copyright (c) 2013 ARM LIMITED * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -270,11 +270,11 @@ typedef enum { /// Entry point of a thread. /// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. -typedef void (*os_pthread) (void const *argument); +typedef void (*os_pthread) (void *argument); /// Entry point of a timer call back function. /// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. -typedef void (*os_ptimer) (void const *argument); +typedef void (*os_ptimer) (void *argument); // >>> the following data type definitions may shall adapted towards a specific RTOS @@ -323,7 +323,7 @@ typedef StaticQueue_t osStaticMessageQDef_t; /// Thread Definition structure contains startup information of a thread. /// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. typedef struct os_thread_def { - char *name; ///< Thread name + const char *name; ///< Thread name os_pthread pthread; ///< start address of thread function osPriority tpriority; ///< initial thread priority uint32_t instances; ///< maximum number of instances of that thread function diff --git a/Firmware/Board/v3/Src/freertos.c b/Firmware/Board/v3/Src/freertos.c index 0865d714..11154587 100644 --- a/Firmware/Board/v3/Src/freertos.c +++ b/Firmware/Board/v3/Src/freertos.c @@ -98,7 +98,7 @@ osThreadId defaultTaskHandle; /* USER CODE END FunctionPrototypes */ -void StartDefaultTask(void const * argument); +void StartDefaultTask(void * argument); extern void MX_USB_DEVICE_Init(void); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ @@ -214,7 +214,7 @@ void MX_FREERTOS_Init(void) { * @retval None */ /* USER CODE END Header_StartDefaultTask */ -void StartDefaultTask(void const * argument) +void StartDefaultTask(void * argument) { /* init code for USB_DEVICE */ MX_USB_DEVICE_Init(); From 68e1715962842f7f9542c18fefe63f983e8ee8be Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:45:30 -0700 Subject: [PATCH 15/40] bake patch: disable IRQ for DMA2_Stream0 --- .../0003-disable-IRQ-for-DMA2_Stream0.patch | 33 ------------------- Firmware/Board/v3/Src/dma.c | 6 ++-- 2 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch diff --git a/Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch b/Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch deleted file mode 100644 index 282317d1..00000000 --- a/Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ab5ca860b3729d76a9c43c485776147ab69d2342 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Mar 2018 19:02:45 -0700 -Subject: [PATCH] disable IRQ for DMA2_Stream0 - -This DMA stream is used to read values from ADC1 -while ADC1 cycles through it's sequence of input -channels. No interrupts are required to make -this work. ---- - Firmware/Board/v3/Src/dma.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/Firmware/Board/v3/Src/dma.c b/Firmware/Board/v3/Src/dma.c -index 55d5e03..3de873a 100644 ---- a/Firmware/Board/v3/Src/dma.c -+++ b/Firmware/Board/v3/Src/dma.c -@@ -78,8 +78,10 @@ void MX_DMA_Init(void) - HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); - /* DMA2_Stream0_IRQn interrupt configuration */ -- HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); -- HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); -+ // Dear STM, no we _don't_ want to fire an interrupt for this DMA -+ // (it's not possible to deselect this in CubeMX) -+ //HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); -+ //HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); - - } - --- -2.16.2 - diff --git a/Firmware/Board/v3/Src/dma.c b/Firmware/Board/v3/Src/dma.c index 55d5e034..3de873ad 100644 --- a/Firmware/Board/v3/Src/dma.c +++ b/Firmware/Board/v3/Src/dma.c @@ -78,8 +78,10 @@ void MX_DMA_Init(void) HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); /* DMA2_Stream0_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); + // Dear STM, no we _don't_ want to fire an interrupt for this DMA + // (it's not possible to deselect this in CubeMX) + //HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); + //HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); } From fa44bc8f340e2e46556079335b043c18f6140930 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:57:44 -0700 Subject: [PATCH 16/40] bake patch: Add I2C files and settings --- .../v3/0002-Add-I2C-files-and-settings.patch | 6860 ----------------- .../Inc/stm32f4xx_hal_i2c.h | 649 ++ .../Inc/stm32f4xx_hal_i2c_ex.h | 137 + .../Src/stm32f4xx_hal_i2c.c | 5494 +++++++++++++ .../Src/stm32f4xx_hal_i2c_ex.c | 204 + Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h | 2 +- Firmware/Board/v3/Src/main.c | 2 +- 7 files changed, 6486 insertions(+), 6862 deletions(-) delete mode 100644 Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c diff --git a/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch b/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch deleted file mode 100644 index aae18bf4..00000000 --- a/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch +++ /dev/null @@ -1,6860 +0,0 @@ -From b45bdbbbfe3d084d069da99b98116991923f5eb6 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Thu, 26 Apr 2018 13:20:38 -0700 -Subject: [PATCH] Add I2C files and settings - ---- - .../Inc/stm32f4xx_hal_i2c.h | 649 ++ - .../Inc/stm32f4xx_hal_i2c_ex.h | 137 + - .../Src/stm32f4xx_hal_i2c.c | 5494 +++++++++++++++++ - .../Src/stm32f4xx_hal_i2c_ex.c | 204 + - Firmware/Board/v3/Inc/i2c.h | 91 + - Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h | 2 +- - Firmware/Board/v3/Odrive.ioc | 5 + - Firmware/Board/v3/Src/i2c.c | 198 + - Firmware/Board/v3/Src/main.c | 1 - - 11 files changed, 6811 insertions(+), 2 deletions(-) - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c - create mode 100644 Firmware/Board/v3/Inc/i2c.h - create mode 100644 Firmware/Board/v3/Src/i2c.c - -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h -new file mode 100644 -index 0000000..5452a50 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h -@@ -0,0 +1,649 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c.h -+ * @author MCD Application Team -+ * @brief Header file of I2C HAL module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __STM32F4xx_HAL_I2C_H -+#define __STM32F4xx_HAL_I2C_H -+ -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal_def.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @addtogroup I2C -+ * @{ -+ */ -+ -+/* Exported types ------------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Types I2C Exported Types -+ * @{ -+ */ -+ -+/** -+ * @brief I2C Configuration Structure definition -+ */ -+typedef struct -+{ -+ uint32_t ClockSpeed; /*!< Specifies the clock frequency. -+ This parameter must be set to a value lower than 400kHz */ -+ -+ uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle. -+ This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ -+ -+ uint32_t OwnAddress1; /*!< Specifies the first device own address. -+ This parameter can be a 7-bit or 10-bit address. */ -+ -+ uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. -+ This parameter can be a value of @ref I2C_addressing_mode */ -+ -+ uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. -+ This parameter can be a value of @ref I2C_dual_addressing_mode */ -+ -+ uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected -+ This parameter can be a 7-bit address. */ -+ -+ uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. -+ This parameter can be a value of @ref I2C_general_call_addressing_mode */ -+ -+ uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. -+ This parameter can be a value of @ref I2C_nostretch_mode */ -+ -+}I2C_InitTypeDef; -+ -+/** -+ * @brief HAL State structure definition -+ * @note HAL I2C State value coding follow below described bitmap : -+ * b7-b6 Error information -+ * 00 : No Error -+ * 01 : Abort (Abort user request on going) -+ * 10 : Timeout -+ * 11 : Error -+ * b5 IP initilisation status -+ * 0 : Reset (IP not initialized) -+ * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called) -+ * b4 (not used) -+ * x : Should be set to 0 -+ * b3 -+ * 0 : Ready or Busy (No Listen mode ongoing) -+ * 1 : Listen (IP in Address Listen Mode) -+ * b2 Intrinsic process state -+ * 0 : Ready -+ * 1 : Busy (IP busy with some configuration or internal operations) -+ * b1 Rx state -+ * 0 : Ready (no Rx operation ongoing) -+ * 1 : Busy (Rx operation ongoing) -+ * b0 Tx state -+ * 0 : Ready (no Tx operation ongoing) -+ * 1 : Busy (Tx operation ongoing) -+ */ -+typedef enum -+{ -+ HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ -+ HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ -+ HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ -+ HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ -+ HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ -+ HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ -+ HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission -+ process is ongoing */ -+ HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception -+ process is ongoing */ -+ HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ -+ HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ -+ HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ -+ -+}HAL_I2C_StateTypeDef; -+ -+/** -+ * @brief HAL Mode structure definition -+ * @note HAL I2C Mode value coding follow below described bitmap : -+ * b7 (not used) -+ * x : Should be set to 0 -+ * b6 -+ * 0 : None -+ * 1 : Memory (HAL I2C communication is in Memory Mode) -+ * b5 -+ * 0 : None -+ * 1 : Slave (HAL I2C communication is in Slave Mode) -+ * b4 -+ * 0 : None -+ * 1 : Master (HAL I2C communication is in Master Mode) -+ * b3-b2-b1-b0 (not used) -+ * xxxx : Should be set to 0000 -+ */ -+typedef enum -+{ -+ HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ -+ HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ -+ HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ -+ HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ -+ -+}HAL_I2C_ModeTypeDef; -+ -+/** -+ * @brief I2C handle Structure definition -+ */ -+typedef struct -+{ -+ I2C_TypeDef *Instance; /*!< I2C registers base address */ -+ -+ I2C_InitTypeDef Init; /*!< I2C communication parameters */ -+ -+ uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ -+ -+ uint16_t XferSize; /*!< I2C transfer size */ -+ -+ __IO uint16_t XferCount; /*!< I2C transfer counter */ -+ -+ __IO uint32_t XferOptions; /*!< I2C transfer options */ -+ -+ __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode -+ context for internal usage */ -+ -+ DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ -+ -+ DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ -+ -+ HAL_LockTypeDef Lock; /*!< I2C locking object */ -+ -+ __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ -+ -+ __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ -+ -+ __IO uint32_t ErrorCode; /*!< I2C Error code */ -+ -+ __IO uint32_t Devaddress; /*!< I2C Target device address */ -+ -+ __IO uint32_t Memaddress; /*!< I2C Target memory address */ -+ -+ __IO uint32_t MemaddSize; /*!< I2C Target memory address size */ -+ -+ __IO uint32_t EventCount; /*!< I2C Event counter */ -+ -+}I2C_HandleTypeDef; -+ -+/** -+ * @} -+ */ -+ -+/* Exported constants --------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Constants I2C Exported Constants -+ * @{ -+ */ -+ -+/** @defgroup I2C_Error_Code I2C Error Code -+ * @brief I2C Error Code -+ * @{ -+ */ -+#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */ -+#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */ -+#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */ -+#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */ -+#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */ -+#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */ -+#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */ -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode -+ * @{ -+ */ -+#define I2C_DUTYCYCLE_2 0x00000000U -+#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_addressing_mode I2C addressing mode -+ * @{ -+ */ -+#define I2C_ADDRESSINGMODE_7BIT 0x00004000U -+#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U) -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode -+ * @{ -+ */ -+#define I2C_DUALADDRESS_DISABLE 0x00000000U -+#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode -+ * @{ -+ */ -+#define I2C_GENERALCALL_DISABLE 0x00000000U -+#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_nostretch_mode I2C nostretch mode -+ * @{ -+ */ -+#define I2C_NOSTRETCH_DISABLE 0x00000000U -+#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size -+ * @{ -+ */ -+#define I2C_MEMADD_SIZE_8BIT 0x00000001U -+#define I2C_MEMADD_SIZE_16BIT 0x00000010U -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_XferDirection_definition I2C XferDirection definition -+ * @{ -+ */ -+#define I2C_DIRECTION_RECEIVE 0x00000000U -+#define I2C_DIRECTION_TRANSMIT 0x00000001U -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_XferOptions_definition I2C XferOptions definition -+ * @{ -+ */ -+#define I2C_FIRST_FRAME 0x00000001U -+#define I2C_NEXT_FRAME 0x00000002U -+#define I2C_FIRST_AND_LAST_FRAME 0x00000004U -+#define I2C_LAST_FRAME 0x00000008U -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition -+ * @{ -+ */ -+#define I2C_IT_BUF I2C_CR2_ITBUFEN -+#define I2C_IT_EVT I2C_CR2_ITEVTEN -+#define I2C_IT_ERR I2C_CR2_ITERREN -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Flag_definition I2C Flag definition -+ * @{ -+ */ -+#define I2C_FLAG_SMBALERT 0x00018000U -+#define I2C_FLAG_TIMEOUT 0x00014000U -+#define I2C_FLAG_PECERR 0x00011000U -+#define I2C_FLAG_OVR 0x00010800U -+#define I2C_FLAG_AF 0x00010400U -+#define I2C_FLAG_ARLO 0x00010200U -+#define I2C_FLAG_BERR 0x00010100U -+#define I2C_FLAG_TXE 0x00010080U -+#define I2C_FLAG_RXNE 0x00010040U -+#define I2C_FLAG_STOPF 0x00010010U -+#define I2C_FLAG_ADD10 0x00010008U -+#define I2C_FLAG_BTF 0x00010004U -+#define I2C_FLAG_ADDR 0x00010002U -+#define I2C_FLAG_SB 0x00010001U -+#define I2C_FLAG_DUALF 0x00100080U -+#define I2C_FLAG_SMBHOST 0x00100040U -+#define I2C_FLAG_SMBDEFAULT 0x00100020U -+#define I2C_FLAG_GENCALL 0x00100010U -+#define I2C_FLAG_TRA 0x00100004U -+#define I2C_FLAG_BUSY 0x00100002U -+#define I2C_FLAG_MSL 0x00100001U -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Exported macro ------------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Macros I2C Exported Macros -+ * @{ -+ */ -+ -+/** @brief Reset I2C handle state -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) -+ -+/** @brief Enable or disable the specified I2C interrupts. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __INTERRUPT__ specifies the interrupt source to enable or disable. -+ * This parameter can be one of the following values: -+ * @arg I2C_IT_BUF: Buffer interrupt enable -+ * @arg I2C_IT_EVT: Event interrupt enable -+ * @arg I2C_IT_ERR: Error interrupt enable -+ * @retval None -+ */ -+#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) -+#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) -+ -+/** @brief Checks if the specified I2C interrupt source is enabled or disabled. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __INTERRUPT__ specifies the I2C interrupt source to check. -+ * This parameter can be one of the following values: -+ * @arg I2C_IT_BUF: Buffer interrupt enable -+ * @arg I2C_IT_EVT: Event interrupt enable -+ * @arg I2C_IT_ERR: Error interrupt enable -+ * @retval The new state of __INTERRUPT__ (TRUE or FALSE). -+ */ -+#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) -+ -+/** @brief Checks whether the specified I2C flag is set or not. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __FLAG__ specifies the flag to check. -+ * This parameter can be one of the following values: -+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag -+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag -+ * @arg I2C_FLAG_PECERR: PEC error in reception flag -+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag -+ * @arg I2C_FLAG_AF: Acknowledge failure flag -+ * @arg I2C_FLAG_ARLO: Arbitration lost flag -+ * @arg I2C_FLAG_BERR: Bus error flag -+ * @arg I2C_FLAG_TXE: Data register empty flag -+ * @arg I2C_FLAG_RXNE: Data register not empty flag -+ * @arg I2C_FLAG_STOPF: Stop detection flag -+ * @arg I2C_FLAG_ADD10: 10-bit header sent flag -+ * @arg I2C_FLAG_BTF: Byte transfer finished flag -+ * @arg I2C_FLAG_ADDR: Address sent flag -+ * Address matched flag -+ * @arg I2C_FLAG_SB: Start bit flag -+ * @arg I2C_FLAG_DUALF: Dual flag -+ * @arg I2C_FLAG_SMBHOST: SMBus host header -+ * @arg I2C_FLAG_SMBDEFAULT: SMBus default header -+ * @arg I2C_FLAG_GENCALL: General call header flag -+ * @arg I2C_FLAG_TRA: Transmitter/Receiver flag -+ * @arg I2C_FLAG_BUSY: Bus busy flag -+ * @arg I2C_FLAG_MSL: Master/Slave flag -+ * @retval The new state of __FLAG__ (TRUE or FALSE). -+ */ -+#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \ -+ ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) -+ -+/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __FLAG__ specifies the flag to clear. -+ * This parameter can be any combination of the following values: -+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag -+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag -+ * @arg I2C_FLAG_PECERR: PEC error in reception flag -+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) -+ * @arg I2C_FLAG_AF: Acknowledge failure flag -+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) -+ * @arg I2C_FLAG_BERR: Bus error flag -+ * @retval None -+ */ -+#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK)) -+ -+/** @brief Clears the I2C ADDR pending flag. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \ -+ do{ \ -+ __IO uint32_t tmpreg = 0x00U; \ -+ tmpreg = (__HANDLE__)->Instance->SR1; \ -+ tmpreg = (__HANDLE__)->Instance->SR2; \ -+ UNUSED(tmpreg); \ -+ } while(0) -+ -+/** @brief Clears the I2C STOPF pending flag. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \ -+ do{ \ -+ __IO uint32_t tmpreg = 0x00U; \ -+ tmpreg = (__HANDLE__)->Instance->SR1; \ -+ (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \ -+ UNUSED(tmpreg); \ -+ } while(0) -+ -+/** @brief Enable the I2C peripheral. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) -+ -+/** @brief Disable the I2C peripheral. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE) -+ -+/** -+ * @} -+ */ -+ -+/* Include I2C HAL Extension module */ -+#include "stm32f4xx_hal_i2c_ex.h" -+ -+/* Exported functions --------------------------------------------------------*/ -+/** @addtogroup I2C_Exported_Functions -+ * @{ -+ */ -+ -+/** @addtogroup I2C_Exported_Functions_Group1 -+ * @{ -+ */ -+/* Initialization/de-initialization functions **********************************/ -+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); -+HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); -+/** -+ * @} -+ */ -+ -+/** @addtogroup I2C_Exported_Functions_Group2 -+ * @{ -+ */ -+/* I/O operation functions *****************************************************/ -+/******* Blocking mode: Polling */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); -+ -+/******* Non-Blocking mode: Interrupt */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+ -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); -+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); -+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); -+ -+/******* Non-Blocking mode: DMA */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+ -+/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ -+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); -+void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); -+/** -+ * @} -+ */ -+ -+/** @addtogroup I2C_Exported_Functions_Group3 -+ * @{ -+ */ -+/* Peripheral State, Mode and Errors functions *********************************/ -+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c); -+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c); -+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+/* Private types -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private constants ---------------------------------------------------------*/ -+/** @defgroup I2C_Private_Constants I2C Private Constants -+ * @{ -+ */ -+#define I2C_FLAG_MASK 0x0000FFFFU -+/** -+ * @} -+ */ -+ -+/* Private macros ------------------------------------------------------------*/ -+/** @defgroup I2C_Private_Macros I2C Private Macros -+ * @{ -+ */ -+ -+#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U) -+#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U)) -+#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) -+#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__PCLK__) / ((__SPEED__) * 25U)) | I2C_DUTYCYCLE_16_9)) -+#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \ -+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \ -+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS)) -+ -+#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0))) -+#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0)) -+ -+#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) -+#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0))) -+#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1)))) -+ -+#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8))) -+#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) -+ -+/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters -+ * @{ -+ */ -+#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \ -+ ((CYCLE) == I2C_DUTYCYCLE_16_9)) -+#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \ -+ ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT)) -+#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ -+ ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) -+#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ -+ ((CALL) == I2C_GENERALCALL_ENABLE)) -+#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ -+ ((STRETCH) == I2C_NOSTRETCH_ENABLE)) -+#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ -+ ((SIZE) == I2C_MEMADD_SIZE_16BIT)) -+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0U) && ((SPEED) <= 400000U)) -+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & 0xFFFFFC00U) == 0U) -+#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & 0xFFFFFF01U) == 0U) -+#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ -+ ((REQUEST) == I2C_NEXT_FRAME) || \ -+ ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ -+ ((REQUEST) == I2C_LAST_FRAME)) -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Private functions ---------------------------------------------------------*/ -+/** @defgroup I2C_Private_Functions I2C Private Functions -+ * @{ -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+ -+#endif /* __STM32F4xx_HAL_I2C_H */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h -new file mode 100644 -index 0000000..ff47d5c ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h -@@ -0,0 +1,137 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c_ex.h -+ * @author MCD Application Team -+ * @brief Header file of I2C HAL Extension module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __STM32F4xx_HAL_I2C_EX_H -+#define __STM32F4xx_HAL_I2C_EX_H -+ -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ -+ defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ -+ defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal_def.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @addtogroup I2CEx -+ * @{ -+ */ -+ -+/* Exported types ------------------------------------------------------------*/ -+/* Exported constants --------------------------------------------------------*/ -+/** @defgroup I2CEx_Exported_Constants I2C Exported Constants -+ * @{ -+ */ -+ -+/** @defgroup I2CEx_Analog_Filter I2C Analog Filter -+ * @{ -+ */ -+#define I2C_ANALOGFILTER_ENABLE 0x00000000U -+#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Exported macro ------------------------------------------------------------*/ -+/* Exported functions --------------------------------------------------------*/ -+/** @addtogroup I2CEx_Exported_Functions -+ * @{ -+ */ -+ -+/** @addtogroup I2CEx_Exported_Functions_Group1 -+ * @{ -+ */ -+/* Peripheral Control functions ************************************************/ -+HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); -+HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+/* Private types -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private constants ---------------------------------------------------------*/ -+/** @defgroup I2CEx_Private_Constants I2C Private Constants -+ * @{ -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Private macros ------------------------------------------------------------*/ -+/** @defgroup I2CEx_Private_Macros I2C Private Macros -+ * @{ -+ */ -+#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ -+ ((FILTER) == I2C_ANALOGFILTER_DISABLE)) -+#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ -+ STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx ||\ -+ STM32F413xx || STM32F423xx */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* __STM32F4xx_HAL_I2C_EX_H */ -+ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c -new file mode 100644 -index 0000000..da18520 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c -@@ -0,0 +1,5494 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c.c -+ * @author MCD Application Team -+ * @brief I2C HAL module driver. -+ * This file provides firmware functions to manage the following -+ * functionalities of the Inter Integrated Circuit (I2C) peripheral: -+ * + Initialization and de-initialization functions -+ * + IO operation functions -+ * + Peripheral State, Mode and Error functions -+ * -+ @verbatim -+ ============================================================================== -+ ##### How to use this driver ##### -+ ============================================================================== -+ [..] -+ The I2C HAL driver can be used as follows: -+ -+ (#) Declare a I2C_HandleTypeDef handle structure, for example: -+ I2C_HandleTypeDef hi2c; -+ -+ (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API: -+ (##) Enable the I2Cx interface clock -+ (##) I2C pins configuration -+ (+++) Enable the clock for the I2C GPIOs -+ (+++) Configure I2C pins as alternate function open-drain -+ (##) NVIC configuration if you need to use interrupt process -+ (+++) Configure the I2Cx interrupt priority -+ (+++) Enable the NVIC I2C IRQ Channel -+ (##) DMA Configuration if you need to use DMA process -+ (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream -+ (+++) Enable the DMAx interface clock using -+ (+++) Configure the DMA handle parameters -+ (+++) Configure the DMA Tx or Rx Stream -+ (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle -+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on -+ the DMA Tx or Rx Stream -+ -+ (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1, -+ Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure. -+ -+ (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware -+ (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API. -+ -+ (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady() -+ -+ (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : -+ -+ *** Polling mode IO operation *** -+ ================================= -+ [..] -+ (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit() -+ (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive() -+ (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit() -+ (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive() -+ -+ *** Polling mode IO MEM operation *** -+ ===================================== -+ [..] -+ (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write() -+ (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read() -+ -+ -+ *** Interrupt mode IO operation *** -+ =================================== -+ [..] -+ (+) Transmit in master mode an amount of data in non blocking mode using HAL_I2C_Master_Transmit_IT() -+ (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback -+ (+) Receive in master mode an amount of data in non blocking mode using HAL_I2C_Master_Receive_IT() -+ (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback -+ (+) Transmit in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Transmit_IT() -+ (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback -+ (+) Receive in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Receive_IT() -+ (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ -+ *** Interrupt mode IO sequential operation *** -+ ============================================== -+ [..] -+ (@) These interfaces allow to manage a sequential transfer with a repeated start condition -+ when a direction change during transfer -+ [..] -+ (+) A specific option field manage the different steps of a sequential transfer -+ (+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below: -+ (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode -+ (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address -+ and data to transfer without a final stop condition -+ (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address -+ and with new data to transfer if the direction change or manage only the new data to transfer -+ if no direction change and without a final stop condition in both cases -+ (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address -+ and with new data to transfer if the direction change or manage only the new data to transfer -+ if no direction change and with a final stop condition in both cases -+ -+ (+) Differents sequential I2C interfaces are listed below: -+ (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT() -+ (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() -+ (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Receive_IT() -+ (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() -+ (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT() -+ (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can -+ add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). -+ (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ListenCpltCallback() -+ (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Transmit_IT() -+ (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() -+ (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Receive_IT() -+ (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() -+ (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback() -+ (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ -+ *** Interrupt mode IO MEM operation *** -+ ======================================= -+ [..] -+ (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using -+ HAL_I2C_Mem_Write_IT() -+ (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback -+ (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using -+ HAL_I2C_Mem_Read_IT() -+ (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ -+ *** DMA mode IO operation *** -+ ============================== -+ [..] -+ (+) Transmit in master mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Master_Transmit_DMA() -+ (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback -+ (+) Receive in master mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Master_Receive_DMA() -+ (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback -+ (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Slave_Transmit_DMA() -+ (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback -+ (+) Receive in slave mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Slave_Receive_DMA() -+ (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ -+ *** DMA mode IO MEM operation *** -+ ================================= -+ [..] -+ (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using -+ HAL_I2C_Mem_Write_DMA() -+ (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback -+ (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using -+ HAL_I2C_Mem_Read_DMA() -+ (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ -+ -+ *** I2C HAL driver macros list *** -+ ================================== -+ [..] -+ Below the list of most used macros in I2C HAL driver. -+ -+ (+) __HAL_I2C_ENABLE: Enable the I2C peripheral -+ (+) __HAL_I2C_DISABLE: Disable the I2C peripheral -+ (+) __HAL_I2C_GET_FLAG : Checks whether the specified I2C flag is set or not -+ (+) __HAL_I2C_CLEAR_FLAG : Clear the specified I2C pending flag -+ (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt -+ (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt -+ -+ [..] -+ (@) You can refer to the I2C HAL driver header file for more useful macros -+ -+ -+ @endverbatim -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @defgroup I2C I2C -+ * @brief I2C HAL module driver -+ * @{ -+ */ -+ -+#ifdef HAL_I2C_MODULE_ENABLED -+ -+/* Private typedef -----------------------------------------------------------*/ -+/* Private define ------------------------------------------------------------*/ -+/** @addtogroup I2C_Private_Define -+ * @{ -+ */ -+#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */ -+#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */ -+#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ -+ -+/* Private define for @ref PreviousState usage */ -+#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(uint32_t)HAL_I2C_STATE_READY))) /*!< Mask State define, keep only RX and TX bits */ -+#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */ -+#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ -+ -+/** -+ * @} -+ */ -+ -+/* Private macro -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private function prototypes -----------------------------------------------*/ -+/** @addtogroup I2C_Private_Functions -+ * @{ -+ */ -+/* Private functions to handle DMA transfer */ -+static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma); -+static void I2C_DMAError(DMA_HandleTypeDef *hdma); -+static void I2C_DMAAbort(DMA_HandleTypeDef *hdma); -+ -+static void I2C_ITError(I2C_HandleTypeDef *hi2c); -+ -+static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c); -+ -+/* Private functions for I2C transfer IRQ handler */ -+static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c); -+ -+static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c); -+/** -+ * @} -+ */ -+ -+/* Exported functions --------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Functions I2C Exported Functions -+ * @{ -+ */ -+ -+/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions -+ * @brief Initialization and Configuration functions -+ * -+@verbatim -+ =============================================================================== -+ ##### Initialization and de-initialization functions ##### -+ =============================================================================== -+ [..] This subsection provides a set of functions allowing to initialize and -+ de-initialize the I2Cx peripheral: -+ -+ (+) User must Implement HAL_I2C_MspInit() function in which he configures -+ all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC). -+ -+ (+) Call the function HAL_I2C_Init() to configure the selected device with -+ the selected configuration: -+ (++) Communication Speed -+ (++) Duty cycle -+ (++) Addressing mode -+ (++) Own Address 1 -+ (++) Dual Addressing mode -+ (++) Own Address 2 -+ (++) General call mode -+ (++) Nostretch mode -+ -+ (+) Call the function HAL_I2C_DeInit() to restore the default configuration -+ of the selected I2Cx peripheral. -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Initializes the I2C according to the specified parameters -+ * in the I2C_InitTypeDef and create the associated handle. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) -+{ -+ uint32_t freqrange = 0U; -+ uint32_t pclk1 = 0U; -+ -+ /* Check the I2C handle allocation */ -+ if(hi2c == NULL) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed)); -+ assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle)); -+ assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); -+ assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); -+ assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); -+ assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); -+ assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); -+ assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); -+ -+ if(hi2c->State == HAL_I2C_STATE_RESET) -+ { -+ /* Allocate lock resource and initialize it */ -+ hi2c->Lock = HAL_UNLOCKED; -+ /* Init the low level hardware : GPIO, CLOCK, NVIC */ -+ HAL_I2C_MspInit(hi2c); -+ } -+ -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the selected I2C peripheral */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Get PCLK1 frequency */ -+ pclk1 = HAL_RCC_GetPCLK1Freq(); -+ -+ /* Calculate frequency range */ -+ freqrange = I2C_FREQRANGE(pclk1); -+ -+ /*---------------------------- I2Cx CR2 Configuration ----------------------*/ -+ /* Configure I2Cx: Frequency range */ -+ hi2c->Instance->CR2 = freqrange; -+ -+ /*---------------------------- I2Cx TRISE Configuration --------------------*/ -+ /* Configure I2Cx: Rise Time */ -+ hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); -+ -+ /*---------------------------- I2Cx CCR Configuration ----------------------*/ -+ /* Configure I2Cx: Speed */ -+ hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); -+ -+ /*---------------------------- I2Cx CR1 Configuration ----------------------*/ -+ /* Configure I2Cx: Generalcall and NoStretch mode */ -+ hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); -+ -+ /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ -+ /* Configure I2Cx: Own Address1 and addressing mode */ -+ hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); -+ -+ /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ -+ /* Configure I2Cx: Dual mode and Own Address2 */ -+ hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2); -+ -+ /* Enable the selected I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief DeInitializes the I2C peripheral. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) -+{ -+ /* Check the I2C handle allocation */ -+ if(hi2c == NULL) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the I2C Peripheral Clock */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ -+ HAL_I2C_MspDeInit(hi2c); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->State = HAL_I2C_STATE_RESET; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Release Lock */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief I2C MSP Init. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval None -+ */ -+ __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ /* NOTE : This function Should not be modified, when the callback is needed, -+ the HAL_I2C_MspInit could be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief I2C MSP DeInit -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval None -+ */ -+ __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ /* NOTE : This function Should not be modified, when the callback is needed, -+ the HAL_I2C_MspDeInit could be implemented in the user file -+ */ -+} -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Exported_Functions_Group2 IO operation functions -+ * @brief Data transfers functions -+ * -+@verbatim -+ =============================================================================== -+ ##### IO operation functions ##### -+ =============================================================================== -+ [..] -+ This subsection provides a set of functions allowing to manage the I2C data -+ transfers. -+ -+ (#) There are two modes of transfer: -+ (++) Blocking mode : The communication is performed in the polling mode. -+ The status of all data processing is returned by the same function -+ after finishing transfer. -+ (++) No-Blocking mode : The communication is performed using Interrupts -+ or DMA. These functions return the status of the transfer startup. -+ The end of the data processing will be indicated through the -+ dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when -+ using DMA mode. -+ -+ (#) Blocking mode functions are : -+ (++) HAL_I2C_Master_Transmit() -+ (++) HAL_I2C_Master_Receive() -+ (++) HAL_I2C_Slave_Transmit() -+ (++) HAL_I2C_Slave_Receive() -+ (++) HAL_I2C_Mem_Write() -+ (++) HAL_I2C_Mem_Read() -+ (++) HAL_I2C_IsDeviceReady() -+ -+ (#) No-Blocking mode functions with Interrupt are : -+ (++) HAL_I2C_Master_Transmit_IT() -+ (++) HAL_I2C_Master_Receive_IT() -+ (++) HAL_I2C_Slave_Transmit_IT() -+ (++) HAL_I2C_Slave_Receive_IT() -+ (++) HAL_I2C_Master_Sequential_Transmit_IT() -+ (++) HAL_I2C_Master_Sequential_Receive_IT() -+ (++) HAL_I2C_Slave_Sequential_Transmit_IT() -+ (++) HAL_I2C_Slave_Sequential_Receive_IT() -+ (++) HAL_I2C_Mem_Write_IT() -+ (++) HAL_I2C_Mem_Read_IT() -+ -+ (#) No-Blocking mode functions with DMA are : -+ (++) HAL_I2C_Master_Transmit_DMA() -+ (++) HAL_I2C_Master_Receive_DMA() -+ (++) HAL_I2C_Slave_Transmit_DMA() -+ (++) HAL_I2C_Slave_Receive_DMA() -+ (++) HAL_I2C_Mem_Write_DMA() -+ (++) HAL_I2C_Mem_Read_DMA() -+ -+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: -+ (++) HAL_I2C_MemTxCpltCallback() -+ (++) HAL_I2C_MemRxCpltCallback() -+ (++) HAL_I2C_MasterTxCpltCallback() -+ (++) HAL_I2C_MasterRxCpltCallback() -+ (++) HAL_I2C_SlaveTxCpltCallback() -+ (++) HAL_I2C_SlaveRxCpltCallback() -+ (++) HAL_I2C_ErrorCallback() -+ (++) HAL_I2C_AbortCpltCallback() -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Transmits in master mode an amount of data in blocking mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address */ -+ if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ } -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receives in master mode an amount of data in blocking mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address */ -+ if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(hi2c->XferSize == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ if(hi2c->XferSize <= 3U) -+ { -+ /* One byte */ -+ if(hi2c->XferSize == 1U) -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* Two bytes */ -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* 3 Last bytes */ -+ else -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ else -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmits in slave mode an amount of data in blocking mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* If 10bit addressing mode is selected */ -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) -+ { -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ } -+ } -+ -+ /* Wait until AF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in slave mode an amount of data in blocking mode -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ -+ /* Wait until STOP flag is set */ -+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear STOP flag */ -+ __HAL_I2C_CLEAR_STOPFLAG(hi2c); -+ -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential transmit in master mode an amount of data in non-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ __IO uint32_t Prev_State = 0x00U; -+ __IO uint32_t count = 0x00U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Check Busy Flag only if FIRST call of Master interface */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ Prev_State = hi2c->PreviousState; -+ -+ /* Generate Start */ -+ if((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) -+ { -+ /* Generate Start condition if first transfer */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ } -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential receive in master mode an amount of data in non-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ __IO uint32_t count = 0U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Check Busy Flag only if FIRST call of Master interface */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) -+ { -+ /* Generate Start condition if first transfer */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ } -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential transmit in slave mode an amount of data in no-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_LISTEN) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential receive in slave mode an amount of data in non-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_LISTEN) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Enable the Address listen mode with Interrupt. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Disable the Address listen mode with Interrupt. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of tmp to prevent undefined behavior of volatile usage */ -+ uint32_t tmp; -+ -+ /* Disable Address listen mode only if a transfer is not ongoing */ -+ if(hi2c->State == HAL_I2C_STATE_LISTEN) -+ { -+ tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; -+ hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Disable EVT and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmit in master mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmatx->XferHalfCpltCallback = NULL; -+ hi2c->hdmatx->XferM1CpltCallback = NULL; -+ hi2c->hdmatx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ } -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in master mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmarx->XferHalfCpltCallback = NULL; -+ hi2c->hdmarx->XferM1CpltCallback = NULL; -+ hi2c->hdmarx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ } -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Abort a master I2C process communication with Interrupt. -+ * @note This abort can be called only if state is ready -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(DevAddress); -+ -+ /* Abort Master transfer during Receive or Transmit process */ -+ if(hi2c->Mode == HAL_I2C_MODE_MASTER) -+ { -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_ABORT; -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ I2C_ITError(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ /* Wrong usage of abort function */ -+ /* This function should be used only in case of abort monitored by master device */ -+ return HAL_ERROR; -+ } -+} -+ -+/** -+ * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmatx->XferHalfCpltCallback = NULL; -+ hi2c->hdmatx->XferM1CpltCallback = NULL; -+ hi2c->hdmatx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in slave mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmarx->XferHalfCpltCallback = NULL; -+ hi2c->hdmarx->XferM1CpltCallback = NULL; -+ hi2c->hdmarx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+/** -+ * @brief Write an amount of data in blocking mode to a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Read an amount of data in blocking mode from a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(hi2c->XferSize == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ if(hi2c->XferSize <= 3U) -+ { -+ /* One byte */ -+ if(hi2c->XferSize== 1U) -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* Two bytes */ -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* 3 Last bytes */ -+ else -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ else -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->Devaddress = DevAddress; -+ hi2c->Memaddress = MemAddress; -+ hi2c->MemaddSize = MemAddSize; -+ hi2c->EventCount = 0U; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->Devaddress = DevAddress; -+ hi2c->Memaddress = MemAddress; -+ hi2c->MemaddSize = MemAddSize; -+ hi2c->EventCount = 0U; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ } -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmatx->XferHalfCpltCallback = NULL; -+ hi2c->hdmatx->XferM1CpltCallback = NULL; -+ hi2c->hdmatx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be read -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ uint32_t tickstart = 0x00U; -+ __IO uint32_t count = 0U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmarx->XferHalfCpltCallback = NULL; -+ hi2c->hdmarx->XferM1CpltCallback = NULL; -+ hi2c->hdmarx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(Size == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ } -+ else -+ { -+ /* Enable Last DMA bit */ -+ hi2c->Instance->CR2 |= I2C_CR2_LAST; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ } -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Checks if target device is ready for communication. -+ * @note This function is used with Memory devices -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param Trials Number of trials -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U; -+ -+ /* Get tick */ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ do -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ -+ /* Wait until ADDR or AF flag are set */ -+ /* Get tick */ -+ tickstart = HAL_GetTick(); -+ -+ tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); -+ tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); -+ tmp3 = hi2c->State; -+ while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) -+ { -+ hi2c->State = HAL_I2C_STATE_TIMEOUT; -+ } -+ tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); -+ tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); -+ tmp3 = hi2c->State; -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Check if the ADDR flag has been set */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Clear ADDR Flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Clear AF Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ }while(I2C_Trials++ < Trials); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief This function handles I2C event interrupt request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) -+{ -+ uint32_t sr2itflags = READ_REG(hi2c->Instance->SR2); -+ uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); -+ uint32_t itsources = READ_REG(hi2c->Instance->CR2); -+ -+ uint32_t CurrentMode = hi2c->Mode; -+ -+ /* Master or Memory mode selected */ -+ if((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) -+ { -+ /* SB Set ----------------------------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_SB(hi2c); -+ } -+ /* ADD10 Set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_ADD10) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_ADD10(hi2c); -+ } -+ /* ADDR Set --------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_ADDR(hi2c); -+ } -+ -+ /* I2C in mode Transmitter -----------------------------------------------*/ -+ if((sr2itflags & I2C_FLAG_TRA) != RESET) -+ { -+ /* TXE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_MasterTransmit_TXE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_MasterTransmit_BTF(hi2c); -+ } -+ } -+ /* I2C in mode Receiver --------------------------------------------------*/ -+ else -+ { -+ /* RXNE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_MasterReceive_RXNE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_MasterReceive_BTF(hi2c); -+ } -+ } -+ } -+ /* Slave mode selected */ -+ else -+ { -+ /* ADDR set --------------------------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Slave_ADDR(hi2c); -+ } -+ /* STOPF set --------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Slave_STOPF(hi2c); -+ } -+ /* I2C in mode Transmitter -----------------------------------------------*/ -+ else if((sr2itflags & I2C_FLAG_TRA) != RESET) -+ { -+ /* TXE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_SlaveTransmit_TXE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_SlaveTransmit_BTF(hi2c); -+ } -+ } -+ /* I2C in mode Receiver --------------------------------------------------*/ -+ else -+ { -+ /* RXNE set and BTF reset ----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_SlaveReceive_RXNE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_SlaveReceive_BTF(hi2c); -+ } -+ } -+ } -+} -+ -+/** -+ * @brief This function handles I2C error interrupt request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) -+{ -+ uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U; -+ uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); -+ uint32_t itsources = READ_REG(hi2c->Instance->CR2); -+ -+ /* I2C Bus error interrupt occurred ----------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; -+ -+ /* Clear BERR flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); -+ } -+ -+ /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ -+ if(((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; -+ -+ /* Clear ARLO flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); -+ } -+ -+ /* I2C Acknowledge failure error interrupt occurred ------------------------*/ -+ if(((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ tmp1 = hi2c->Mode; -+ tmp2 = hi2c->XferCount; -+ tmp3 = hi2c->State; -+ tmp4 = hi2c->PreviousState; -+ if((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) && \ -+ ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || \ -+ ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) -+ { -+ I2C_Slave_AF(hi2c); -+ } -+ else -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF; -+ -+ /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */ -+ if(hi2c->Mode == HAL_I2C_MODE_MASTER) -+ { -+ /* Generate Stop */ -+ SET_BIT(hi2c->Instance->CR1,I2C_CR1_STOP); -+ } -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ } -+ } -+ -+ /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; -+ /* Clear OVR flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); -+ } -+ -+ /* Call the Error Callback in case of Error detected -----------------------*/ -+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ I2C_ITError(hi2c); -+ } -+} -+ -+/** -+ * @brief Master Tx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MasterTxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Master Rx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MasterRxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** @brief Slave Tx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_SlaveTxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Slave Rx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_SlaveRxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Slave Address Match callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferOptions_definition -+ * @param AddrMatchCode Address Match Code -+ * @retval None -+ */ -+__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ UNUSED(TransferDirection); -+ UNUSED(AddrMatchCode); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_AddrCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Listen Complete callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_ListenCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Memory Tx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MemTxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Memory Rx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MemRxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief I2C error callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_ErrorCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief I2C abort callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_AbortCpltCallback could be implemented in the user file -+ */ -+} -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions -+ * @brief Peripheral State and Errors functions -+ * -+@verbatim -+ =============================================================================== -+ ##### Peripheral State, Mode and Error functions ##### -+ =============================================================================== -+ [..] -+ This subsection permits to get in run-time the status of the peripheral -+ and the data flow. -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Return the I2C handle state. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL state -+ */ -+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) -+{ -+ /* Return I2C handle state */ -+ return hi2c->State; -+} -+ -+/** -+ * @brief Return the I2C Master, Slave, Memory or no mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL mode -+ */ -+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c) -+{ -+ return hi2c->Mode; -+} -+ -+/** -+ * @brief Return the I2C error code -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval I2C Error Code -+ */ -+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) -+{ -+ return hi2c->ErrorCode; -+} -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @brief Handle TXE flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t CurrentMode = hi2c->Mode; -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if((hi2c->XferSize == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX)) -+ { -+ /* Call TxCpltCallback() directly if no stop mode is set */ -+ if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) -+ { -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ else /* Generate Stop condition then Call TxCpltCallback() */ -+ { -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MemTxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ } -+ } -+ else if((CurrentState == HAL_I2C_STATE_BUSY_TX) || \ -+ ((CurrentMode == HAL_I2C_MODE_MEM) && (CurrentState == HAL_I2C_STATE_BUSY_RX))) -+ { -+ if(hi2c->XferCount == 0U) -+ { -+ /* Disable BUF interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ } -+ else -+ { -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ if(hi2c->EventCount == 0) -+ { -+ /* If Memory address size is 8Bit */ -+ if(hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT) -+ { -+ /* Send Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); -+ -+ hi2c->EventCount += 2; -+ } -+ /* If Memory address size is 16Bit */ -+ else -+ { -+ /* Send MSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress); -+ -+ hi2c->EventCount++; -+ } -+ } -+ else if(hi2c->EventCount == 1) -+ { -+ /* Send LSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); -+ -+ hi2c->EventCount++; -+ } -+ else if(hi2c->EventCount == 2) -+ { -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ } -+ } -+ else -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Master transmitter -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_TX) -+ { -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ else -+ { -+ /* Call TxCpltCallback() directly if no stop mode is set */ -+ if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) -+ { -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ else /* Generate Stop condition then Call TxCpltCallback() */ -+ { -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemTxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle RXNE flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ uint32_t tmp = 0U; -+ -+ tmp = hi2c->XferCount; -+ if(tmp > 3U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ if(hi2c->XferCount == 3) -+ { -+ /* Disable BUF interrupt, this help to treat correctly the last 4 bytes -+ on BTF subroutine */ -+ /* Disable BUF interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ } -+ } -+ else if((tmp == 1U) || (tmp == 0U)) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Master receiver -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if(hi2c->XferCount == 4U) -+ { -+ /* Disable BUF interrupt, this help to treat correctly the last 2 bytes -+ on BTF subroutine if there is a reception delay between N-1 and N byte */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ else if(hi2c->XferCount == 3U) -+ { -+ /* Disable BUF interrupt, this help to treat correctly the last 2 bytes -+ on BTF subroutine if there is a reception delay between N-1 and N byte */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ else if(hi2c->XferCount == 2U) -+ { -+ /* Prepare next transfer or stop current transfer */ -+ if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ /* Disable EVT and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ else -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle SB flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ if(hi2c->EventCount == 0U) -+ { -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); -+ } -+ else -+ { -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); -+ } -+ } -+ else -+ { -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) -+ { -+ /* Send slave 7 Bits address */ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_TX) -+ { -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); -+ } -+ else -+ { -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); -+ } -+ } -+ else -+ { -+ if(hi2c->EventCount == 0U) -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress); -+ } -+ else if(hi2c->EventCount == 1U) -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress); -+ } -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADD10 flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c) -+{ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADDR flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentMode = hi2c->Mode; -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ uint32_t Prev_State = hi2c->PreviousState; -+ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ if((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM)) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else if((hi2c->EventCount == 0U) && (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ hi2c->EventCount++; -+ } -+ else -+ { -+ if(hi2c->XferCount == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferCount == 1U) -+ { -+ if(CurrentXferOptions == I2C_NO_OPTION_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ } -+ /* Prepare next transfer or stop current transfer */ -+ else if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) \ -+ && (Prev_State != I2C_STATE_MASTER_BUSY_RX)) -+ { -+ if(hi2c->XferOptions != I2C_NEXT_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ } -+ else if(hi2c->XferCount == 2U) -+ { -+ if(hi2c->XferOptions != I2C_NEXT_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ } -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Enable Last DMA bit */ -+ hi2c->Instance->CR2 |= I2C_CR2_LAST; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Enable Last DMA bit */ -+ hi2c->Instance->CR2 |= I2C_CR2_LAST; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ /* Reset Event counter */ -+ hi2c->EventCount = 0U; -+ } -+ } -+ else -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle TXE flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ -+ if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) -+ { -+ /* Last Byte is received, disable Interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Set state at HAL_I2C_STATE_LISTEN */ -+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ -+ /* Call the Tx complete callback to inform upper layer of the end of receive process */ -+ HAL_I2C_SlaveTxCpltCallback(hi2c); -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Slave transmitter -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle RXNE flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) -+ { -+ /* Last Byte is received, disable Interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Set state at HAL_I2C_STATE_LISTEN */ -+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ -+ /* Call the Rx complete callback to inform upper layer of the end of receive process */ -+ HAL_I2C_SlaveRxCpltCallback(hi2c); -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Slave receiver -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADD flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) -+{ -+ uint8_t TransferDirection = I2C_DIRECTION_RECEIVE; -+ uint16_t SlaveAddrCode = 0U; -+ -+ /* Transfer Direction requested by Master */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == RESET) -+ { -+ TransferDirection = I2C_DIRECTION_TRANSMIT; -+ } -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DUALF) == RESET) -+ { -+ SlaveAddrCode = hi2c->Init.OwnAddress1; -+ } -+ else -+ { -+ SlaveAddrCode = hi2c->Init.OwnAddress2; -+ } -+ -+ /* Call Slave Addr callback */ -+ HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle STOPF flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Clear STOPF flag */ -+ __HAL_I2C_CLEAR_STOPFLAG(hi2c); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* If a DMA is ongoing, Update handle size context */ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ if((hi2c->State == HAL_I2C_STATE_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) -+ { -+ hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmarx); -+ } -+ else -+ { -+ hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmatx); -+ } -+ } -+ -+ /* All data are not transferred, so set error code accordingly */ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ -+ /* Set ErrorCode corresponding to a Non-Acknowledge */ -+ //hi2c->ErrorCode |= HAL_I2C_ERROR_AF; -+ } -+ -+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ I2C_ITError(hi2c); -+ } -+ else -+ { -+ if((CurrentState == HAL_I2C_STATE_LISTEN ) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN) || \ -+ (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+ else -+ { -+ if((hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_RX) || (CurrentState == HAL_I2C_STATE_BUSY_RX)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_SlaveRxCpltCallback(hi2c); -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if(((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME)) && \ -+ (CurrentState == HAL_I2C_STATE_LISTEN)) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+ else if(CurrentState == HAL_I2C_STATE_BUSY_TX) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ HAL_I2C_SlaveTxCpltCallback(hi2c); -+ } -+ else -+ { -+ /* Clear AF flag only */ -+ /* State Listen, but XferOptions == FIRST or NEXT */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief I2C interrupts error process -+ * @param hi2c I2C handle. -+ * @retval None -+ */ -+static void I2C_ITError(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) -+ { -+ /* keep HAL_I2C_STATE_LISTEN */ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ } -+ else -+ { -+ /* If state is an abort treatment on going, don't change state */ -+ /* This change will be do later */ -+ if((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ } -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ } -+ -+ /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ /* Abort DMA transfer */ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ if(hi2c->hdmatx->State != HAL_DMA_STATE_READY) -+ { -+ /* Set the DMA Abort callback : -+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ -+ hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; -+ -+ if(HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) -+ { -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Call Directly XferAbortCallback function in case of error */ -+ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); -+ } -+ } -+ else -+ { -+ /* Set the DMA Abort callback : -+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ -+ hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; -+ -+ if(HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) -+ { -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ } -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ -+ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); -+ } -+ } -+ } -+ else if(hi2c->State == HAL_I2C_STATE_ABORT) -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ } -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ HAL_I2C_AbortCpltCallback(hi2c); -+ } -+ else -+ { -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ } -+ -+ /* Call user error callback */ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+ /* STOP Flag is not set after a NACK reception */ -+ /* So may inform upper layer that listen phase is stopped */ -+ /* during NACK error treatment */ -+ if((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+} -+ -+/** -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ /* Generate Start condition if first transfer */ -+ if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) -+ { -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ } -+ else -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); -+ -+ /* Wait until ADD10 flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); -+ } -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Master sends target device address for read request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start condition if first transfer */ -+ if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) -+ { -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); -+ } -+ else -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); -+ -+ /* Wait until ADD10 flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); -+ } -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Master sends target device address followed by internal memory address for write request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* If Memory address size is 8Bit */ -+ if(MemAddSize == I2C_MEMADD_SIZE_8BIT) -+ { -+ /* Send Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ /* If Memory address size is 16Bit */ -+ else -+ { -+ /* Send MSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send LSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Master sends target device address followed by internal memory address for read request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* If Memory address size is 8Bit */ -+ if(MemAddSize == I2C_MEMADD_SIZE_8BIT) -+ { -+ /* Send Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ /* If Memory address size is 16Bit */ -+ else -+ { -+ /* Send MSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send LSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief DMA I2C process complete callback. -+ * @param hdma DMA handle -+ * @retval None -+ */ -+static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma) -+{ -+ I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; -+ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t CurrentMode = hi2c->Mode; -+ -+ if((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) -+ { -+ /* Disable DMA Request */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ } -+ else -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Disable Last DMA */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_LAST; -+ -+ /* Disable DMA Request */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Check if Errors has been detected during transfer */ -+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+ else -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ } -+} -+ -+/** -+ * @brief DMA I2C communication error callback. -+ * @param hdma DMA handle -+ * @retval None -+ */ -+static void I2C_DMAError(DMA_HandleTypeDef *hdma) -+{ -+ I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; -+ -+ /* Ignore DMA FIFO error */ -+ if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->XferCount = 0U; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; -+ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+} -+ -+/** -+ * @brief DMA I2C communication abort callback -+ * (To be called at end of DMA Abort procedure). -+ * @param hdma DMA handle. -+ * @retval None -+ */ -+static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) -+{ -+ I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Reset XferAbortCallback */ -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Check if come from abort from user */ -+ if(hi2c->State == HAL_I2C_STATE_ABORT) -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ HAL_I2C_AbortCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param Flag specifies the I2C flag to check. -+ * @param Status The new Flag status (SET or RESET). -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Wait until flag is set */ -+ while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) -+ { -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for Master addressing phase. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param Flag specifies the I2C flag to check. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) -+ { -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Clear AF Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_AF; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of TXE flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) -+ { -+ /* Check if a NACK is detected */ -+ if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of BTF flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) -+ { -+ /* Check if a NACK is detected */ -+ if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of STOP flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) -+ { -+ /* Check if a NACK is detected */ -+ if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) -+ { -+ /* Check if a STOPF is detected */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) -+ { -+ /* Clear STOP Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles Acknowledge failed detection during an I2C Communication. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) -+{ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) -+ { -+ /* Clear NACKF Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_AF; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ return HAL_OK; -+} -+/** -+ * @} -+ */ -+ -+#endif /* HAL_I2C_MODULE_ENABLED */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c -new file mode 100644 -index 0000000..de8f160 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c -@@ -0,0 +1,204 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c_ex.c -+ * @author MCD Application Team -+ * @brief I2C Extension HAL module driver. -+ * This file provides firmware functions to manage the following -+ * functionalities of I2C extension peripheral: -+ * + Extension features functions -+ * -+ @verbatim -+ ============================================================================== -+ ##### I2C peripheral extension features ##### -+ ============================================================================== -+ -+ [..] Comparing to other previous devices, the I2C interface for STM32F427xx/437xx/ -+ 429xx/439xx devices contains the following additional features : -+ -+ (+) Possibility to disable or enable Analog Noise Filter -+ (+) Use of a configured Digital Noise Filter -+ -+ ##### How to use this driver ##### -+ ============================================================================== -+ [..] This driver provides functions to configure Noise Filter -+ (#) Configure I2C Analog noise filter using the function HAL_I2C_AnalogFilter_Config() -+ (#) Configure I2C Digital noise filter using the function HAL_I2C_DigitalFilter_Config() -+ -+ @endverbatim -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @defgroup I2CEx I2CEx -+ * @brief I2C HAL module driver -+ * @{ -+ */ -+ -+#ifdef HAL_I2C_MODULE_ENABLED -+ -+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ -+ defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ -+ defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -+/* Private typedef -----------------------------------------------------------*/ -+/* Private define ------------------------------------------------------------*/ -+/* Private macro -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private function prototypes -----------------------------------------------*/ -+/* Exported functions --------------------------------------------------------*/ -+/** @defgroup I2CEx_Exported_Functions I2C Exported Functions -+ * @{ -+ */ -+ -+ -+/** @defgroup I2CEx_Exported_Functions_Group1 Extension features functions -+ * @brief Extension features functions -+ * -+@verbatim -+ =============================================================================== -+ ##### Extension features functions ##### -+ =============================================================================== -+ [..] This section provides functions allowing to: -+ (+) Configure Noise Filters -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Configures I2C Analog noise filter. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2Cx peripheral. -+ * @param AnalogFilter new state of the Analog filter. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) -+{ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the selected I2C peripheral */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Reset I2Cx ANOFF bit */ -+ hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF); -+ -+ /* Disable the analog filter */ -+ hi2c->Instance->FLTR |= AnalogFilter; -+ -+ __HAL_I2C_ENABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Configures I2C Digital noise filter. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2Cx peripheral. -+ * @param DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) -+{ -+ uint16_t tmpreg = 0; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the selected I2C peripheral */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Get the old register value */ -+ tmpreg = hi2c->Instance->FLTR; -+ -+ /* Reset I2Cx DNF bit [3:0] */ -+ tmpreg &= ~(I2C_FLTR_DNF); -+ -+ /* Set I2Cx DNF coefficient */ -+ tmpreg |= DigitalFilter; -+ -+ /* Store the new register value */ -+ hi2c->Instance->FLTR = tmpreg; -+ -+ __HAL_I2C_ENABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ -+ STM32F401xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx ||\ -+ STM32F423xx */ -+ -+#endif /* HAL_I2C_MODULE_ENABLED */ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Inc/i2c.h b/Firmware/Board/v3/Inc/i2c.h -new file mode 100644 -index 0000000..f449b88 ---- /dev/null -+++ b/Firmware/Board/v3/Inc/i2c.h -@@ -0,0 +1,91 @@ -+/** -+ ****************************************************************************** -+ * File Name : I2C.h -+ * Description : This file provides code for the configuration -+ * of the I2C instances. -+ ****************************************************************************** -+ * This notice applies to any and all portions of this file -+ * that are not between comment pairs USER CODE BEGIN and -+ * USER CODE END. Other portions of this file, whether -+ * inserted by the user or by software development tools -+ * are owned by their respective copyright owners. -+ * -+ * Copyright (c) 2018 STMicroelectronics International N.V. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted, provided that the following conditions are met: -+ * -+ * 1. Redistribution of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of other -+ * contributors to this software may be used to endorse or promote products -+ * derived from this software without specific written permission. -+ * 4. This software, including modifications and/or derivative works of this -+ * software, must execute solely and exclusively on microcontroller or -+ * microprocessor devices manufactured by or for STMicroelectronics. -+ * 5. Redistribution and use of this software other than as permitted under -+ * this license is void and will automatically terminate your rights under -+ * this license. -+ * -+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY -+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT -+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __i2c_H -+#define __i2c_H -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+#include "main.h" -+ -+/* USER CODE BEGIN Includes */ -+ -+/* USER CODE END Includes */ -+ -+extern I2C_HandleTypeDef hi2c1; -+ -+/* USER CODE BEGIN Private defines */ -+ -+/* USER CODE END Private defines */ -+ -+extern void _Error_Handler(char *, int); -+ -+void MX_I2C1_Init(uint8_t addr); -+ -+/* USER CODE BEGIN Prototypes */ -+ -+/* USER CODE END Prototypes */ -+ -+#ifdef __cplusplus -+} -+#endif -+#endif /*__ i2c_H */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -index d0f48f5..b3ef59a 100644 ---- a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -+++ b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -@@ -65,7 +65,7 @@ - /* #define HAL_SRAM_MODULE_ENABLED */ - /* #define HAL_SDRAM_MODULE_ENABLED */ - /* #define HAL_HASH_MODULE_ENABLED */ --/* #define HAL_I2C_MODULE_ENABLED */ -+#define HAL_I2C_MODULE_ENABLED - /* #define HAL_I2S_MODULE_ENABLED */ - /* #define HAL_IWDG_MODULE_ENABLED */ - /* #define HAL_LTDC_MODULE_ENABLED */ -diff --git a/Firmware/Board/v3/Src/i2c.c b/Firmware/Board/v3/Src/i2c.c -new file mode 100644 -index 0000000..bae77f1 ---- /dev/null -+++ b/Firmware/Board/v3/Src/i2c.c -@@ -0,0 +1,198 @@ -+/** -+ ****************************************************************************** -+ * File Name : I2C.c -+ * Description : This file provides code for the configuration -+ * of the I2C instances. -+ ****************************************************************************** -+ * This notice applies to any and all portions of this file -+ * that are not between comment pairs USER CODE BEGIN and -+ * USER CODE END. Other portions of this file, whether -+ * inserted by the user or by software development tools -+ * are owned by their respective copyright owners. -+ * -+ * Copyright (c) 2018 STMicroelectronics International N.V. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted, provided that the following conditions are met: -+ * -+ * 1. Redistribution of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of other -+ * contributors to this software may be used to endorse or promote products -+ * derived from this software without specific written permission. -+ * 4. This software, including modifications and/or derivative works of this -+ * software, must execute solely and exclusively on microcontroller or -+ * microprocessor devices manufactured by or for STMicroelectronics. -+ * 5. Redistribution and use of this software other than as permitted under -+ * this license is void and will automatically terminate your rights under -+ * this license. -+ * -+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY -+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT -+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "i2c.h" -+ -+#include "gpio.h" -+#include "dma.h" -+ -+/* USER CODE BEGIN 0 */ -+ -+/* USER CODE END 0 */ -+ -+I2C_HandleTypeDef hi2c1; -+DMA_HandleTypeDef hdma_i2c1_rx; -+DMA_HandleTypeDef hdma_i2c1_tx; -+ -+/* I2C1 init function */ -+void MX_I2C1_Init(uint8_t addr) -+{ -+ -+ hi2c1.Instance = I2C1; -+ hi2c1.Init.ClockSpeed = 100000; -+ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; -+ hi2c1.Init.OwnAddress1 = addr << 1; -+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; -+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; -+ hi2c1.Init.OwnAddress2 = 0; -+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; -+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; -+ if (HAL_I2C_Init(&hi2c1) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+} -+ -+void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) -+{ -+ -+ GPIO_InitTypeDef GPIO_InitStruct; -+ if(i2cHandle->Instance==I2C1) -+ { -+ /* USER CODE BEGIN I2C1_MspInit 0 */ -+ -+ /* USER CODE END I2C1_MspInit 0 */ -+ -+ /**I2C1 GPIO Configuration -+ PB8 ------> I2C1_SCL -+ PB9 ------> I2C1_SDA -+ */ -+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; -+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; -+ GPIO_InitStruct.Pull = GPIO_PULLUP; -+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; -+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; -+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); -+ -+ /* I2C1 clock enable */ -+ __HAL_RCC_I2C1_CLK_ENABLE(); -+ -+ /* I2C1 DMA Init */ -+ /* I2C1_RX Init */ -+ hdma_i2c1_rx.Instance = DMA1_Stream0; -+ hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1; -+ hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; -+ hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE; -+ hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE; -+ hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; -+ hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; -+ hdma_i2c1_rx.Init.Mode = DMA_CIRCULAR; -+ hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW; -+ hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; -+ if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+ __HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c1_rx); -+ -+ /* I2C1_TX Init */ -+ hdma_i2c1_tx.Instance = DMA1_Stream6; -+ hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_1; -+ hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; -+ hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE; -+ hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE; -+ hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; -+ hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; -+ hdma_i2c1_tx.Init.Mode = DMA_NORMAL; -+ hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW; -+ hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; -+ if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+ __HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c1_tx); -+ -+ /* I2C1 interrupt Init */ -+ HAL_NVIC_SetPriority(I2C1_EV_IRQn, 5, 0); -+ HAL_NVIC_EnableIRQ(I2C1_EV_IRQn); -+ HAL_NVIC_SetPriority(I2C1_ER_IRQn, 5, 0); -+ HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); -+ /* USER CODE BEGIN I2C1_MspInit 1 */ -+ -+ /* USER CODE END I2C1_MspInit 1 */ -+ } -+} -+ -+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle) -+{ -+ -+ if(i2cHandle->Instance==I2C1) -+ { -+ /* USER CODE BEGIN I2C1_MspDeInit 0 */ -+ -+ /* USER CODE END I2C1_MspDeInit 0 */ -+ /* Peripheral clock disable */ -+ __HAL_RCC_I2C1_CLK_DISABLE(); -+ -+ /**I2C1 GPIO Configuration -+ PB8 ------> I2C1_SCL -+ PB9 ------> I2C1_SDA -+ */ -+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9); -+ -+ /* I2C1 DMA DeInit */ -+ HAL_DMA_DeInit(i2cHandle->hdmarx); -+ HAL_DMA_DeInit(i2cHandle->hdmatx); -+ -+ /* I2C1 interrupt Deinit */ -+ HAL_NVIC_DisableIRQ(I2C1_EV_IRQn); -+ HAL_NVIC_DisableIRQ(I2C1_ER_IRQn); -+ /* USER CODE BEGIN I2C1_MspDeInit 1 */ -+ -+ /* USER CODE END I2C1_MspDeInit 1 */ -+ } -+} -+ -+/* USER CODE BEGIN 1 */ -+ -+/* USER CODE END 1 */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c -index 987e0bd..efaeef1 100644 ---- a/Firmware/Board/v3/Src/main.c -+++ b/Firmware/Board/v3/Src/main.c -@@ -187,7 +187,6 @@ int main(void) - MX_ADC3_Init(); - MX_TIM2_Init(); - MX_UART4_Init(); -- MX_CAN1_Init(); - /* USER CODE BEGIN 2 */ - - //Required to use OC4 for ADC triggering. --- -2.17.0 - diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h new file mode 100644 index 00000000..5452a507 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h @@ -0,0 +1,649 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c.h + * @author MCD Application Team + * @brief Header file of I2C HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_I2C_H +#define __STM32F4xx_HAL_I2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Types I2C Exported Types + * @{ + */ + +/** + * @brief I2C Configuration Structure definition + */ +typedef struct +{ + uint32_t ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set to a value lower than 400kHz */ + + uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle. + This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. + This parameter can be a value of @ref I2C_addressing_mode */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref I2C_dual_addressing_mode */ + + uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref I2C_general_call_addressing_mode */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref I2C_nostretch_mode */ + +}I2C_InitTypeDef; + +/** + * @brief HAL State structure definition + * @note HAL I2C State value coding follow below described bitmap : + * b7-b6 Error information + * 00 : No Error + * 01 : Abort (Abort user request on going) + * 10 : Timeout + * 11 : Error + * b5 IP initilisation status + * 0 : Reset (IP not initialized) + * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called) + * b4 (not used) + * x : Should be set to 0 + * b3 + * 0 : Ready or Busy (No Listen mode ongoing) + * 1 : Listen (IP in Address Listen Mode) + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (IP busy with some configuration or internal operations) + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + */ +typedef enum +{ + HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ + HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ + HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ + HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ + HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission + process is ongoing */ + HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception + process is ongoing */ + HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ + HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ + HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ + +}HAL_I2C_StateTypeDef; + +/** + * @brief HAL Mode structure definition + * @note HAL I2C Mode value coding follow below described bitmap : + * b7 (not used) + * x : Should be set to 0 + * b6 + * 0 : None + * 1 : Memory (HAL I2C communication is in Memory Mode) + * b5 + * 0 : None + * 1 : Slave (HAL I2C communication is in Slave Mode) + * b4 + * 0 : None + * 1 : Master (HAL I2C communication is in Master Mode) + * b3-b2-b1-b0 (not used) + * xxxx : Should be set to 0000 + */ +typedef enum +{ + HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ + HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ + HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ + HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ + +}HAL_I2C_ModeTypeDef; + +/** + * @brief I2C handle Structure definition + */ +typedef struct +{ + I2C_TypeDef *Instance; /*!< I2C registers base address */ + + I2C_InitTypeDef Init; /*!< I2C communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ + + uint16_t XferSize; /*!< I2C transfer size */ + + __IO uint16_t XferCount; /*!< I2C transfer counter */ + + __IO uint32_t XferOptions; /*!< I2C transfer options */ + + __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode + context for internal usage */ + + DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< I2C locking object */ + + __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ + + __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ + + __IO uint32_t ErrorCode; /*!< I2C Error code */ + + __IO uint32_t Devaddress; /*!< I2C Target device address */ + + __IO uint32_t Memaddress; /*!< I2C Target memory address */ + + __IO uint32_t MemaddSize; /*!< I2C Target memory address size */ + + __IO uint32_t EventCount; /*!< I2C Event counter */ + +}I2C_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_Error_Code I2C Error Code + * @brief I2C Error Code + * @{ + */ +#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */ +#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */ +#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */ +#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */ +#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */ +#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */ +/** + * @} + */ + +/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode + * @{ + */ +#define I2C_DUTYCYCLE_2 0x00000000U +#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY +/** + * @} + */ + +/** @defgroup I2C_addressing_mode I2C addressing mode + * @{ + */ +#define I2C_ADDRESSINGMODE_7BIT 0x00004000U +#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U) +/** + * @} + */ + +/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode + * @{ + */ +#define I2C_DUALADDRESS_DISABLE 0x00000000U +#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL +/** + * @} + */ + +/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode + * @{ + */ +#define I2C_GENERALCALL_DISABLE 0x00000000U +#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC +/** + * @} + */ + +/** @defgroup I2C_nostretch_mode I2C nostretch mode + * @{ + */ +#define I2C_NOSTRETCH_DISABLE 0x00000000U +#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH +/** + * @} + */ + +/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size + * @{ + */ +#define I2C_MEMADD_SIZE_8BIT 0x00000001U +#define I2C_MEMADD_SIZE_16BIT 0x00000010U +/** + * @} + */ + +/** @defgroup I2C_XferDirection_definition I2C XferDirection definition + * @{ + */ +#define I2C_DIRECTION_RECEIVE 0x00000000U +#define I2C_DIRECTION_TRANSMIT 0x00000001U +/** + * @} + */ + +/** @defgroup I2C_XferOptions_definition I2C XferOptions definition + * @{ + */ +#define I2C_FIRST_FRAME 0x00000001U +#define I2C_NEXT_FRAME 0x00000002U +#define I2C_FIRST_AND_LAST_FRAME 0x00000004U +#define I2C_LAST_FRAME 0x00000008U +/** + * @} + */ + +/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition + * @{ + */ +#define I2C_IT_BUF I2C_CR2_ITBUFEN +#define I2C_IT_EVT I2C_CR2_ITEVTEN +#define I2C_IT_ERR I2C_CR2_ITERREN +/** + * @} + */ + +/** @defgroup I2C_Flag_definition I2C Flag definition + * @{ + */ +#define I2C_FLAG_SMBALERT 0x00018000U +#define I2C_FLAG_TIMEOUT 0x00014000U +#define I2C_FLAG_PECERR 0x00011000U +#define I2C_FLAG_OVR 0x00010800U +#define I2C_FLAG_AF 0x00010400U +#define I2C_FLAG_ARLO 0x00010200U +#define I2C_FLAG_BERR 0x00010100U +#define I2C_FLAG_TXE 0x00010080U +#define I2C_FLAG_RXNE 0x00010040U +#define I2C_FLAG_STOPF 0x00010010U +#define I2C_FLAG_ADD10 0x00010008U +#define I2C_FLAG_BTF 0x00010004U +#define I2C_FLAG_ADDR 0x00010002U +#define I2C_FLAG_SB 0x00010001U +#define I2C_FLAG_DUALF 0x00100080U +#define I2C_FLAG_SMBHOST 0x00100040U +#define I2C_FLAG_SMBDEFAULT 0x00100020U +#define I2C_FLAG_GENCALL 0x00100010U +#define I2C_FLAG_TRA 0x00100004U +#define I2C_FLAG_BUSY 0x00100002U +#define I2C_FLAG_MSL 0x00100001U +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) + +/** @brief Enable or disable the specified I2C interrupts. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __INTERRUPT__ specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg I2C_IT_BUF: Buffer interrupt enable + * @arg I2C_IT_EVT: Event interrupt enable + * @arg I2C_IT_ERR: Error interrupt enable + * @retval None + */ +#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) +#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) + +/** @brief Checks if the specified I2C interrupt source is enabled or disabled. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __INTERRUPT__ specifies the I2C interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_BUF: Buffer interrupt enable + * @arg I2C_IT_EVT: Event interrupt enable + * @arg I2C_IT_ERR: Error interrupt enable + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks whether the specified I2C flag is set or not. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag + * @arg I2C_FLAG_BERR: Bus error flag + * @arg I2C_FLAG_TXE: Data register empty flag + * @arg I2C_FLAG_RXNE: Data register not empty flag + * @arg I2C_FLAG_STOPF: Stop detection flag + * @arg I2C_FLAG_ADD10: 10-bit header sent flag + * @arg I2C_FLAG_BTF: Byte transfer finished flag + * @arg I2C_FLAG_ADDR: Address sent flag + * Address matched flag + * @arg I2C_FLAG_SB: Start bit flag + * @arg I2C_FLAG_DUALF: Dual flag + * @arg I2C_FLAG_SMBHOST: SMBus host header + * @arg I2C_FLAG_SMBDEFAULT: SMBus default header + * @arg I2C_FLAG_GENCALL: General call header flag + * @arg I2C_FLAG_TRA: Transmitter/Receiver flag + * @arg I2C_FLAG_BUSY: Bus busy flag + * @arg I2C_FLAG_MSL: Master/Slave flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \ + ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) + +/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * @retval None + */ +#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK)) + +/** @brief Clears the I2C ADDR pending flag. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg = 0x00U; \ + tmpreg = (__HANDLE__)->Instance->SR1; \ + tmpreg = (__HANDLE__)->Instance->SR2; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clears the I2C STOPF pending flag. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg = 0x00U; \ + tmpreg = (__HANDLE__)->Instance->SR1; \ + (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Enable the I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) + +/** @brief Disable the I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE) + +/** + * @} + */ + +/* Include I2C HAL Extension module */ +#include "stm32f4xx_hal_i2c_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2C_Exported_Functions + * @{ + */ + +/** @addtogroup I2C_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions *****************************************************/ +/******* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); + +/******* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); + +/******* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); +void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State, Mode and Errors functions *********************************/ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c); +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c); +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Constants I2C Private Constants + * @{ + */ +#define I2C_FLAG_MASK 0x0000FFFFU +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macros I2C Private Macros + * @{ + */ + +#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U) +#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U)) +#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) +#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__PCLK__) / ((__SPEED__) * 25U)) | I2C_DUTYCYCLE_16_9)) +#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \ + ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \ + ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS)) + +#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0))) +#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0)) + +#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) +#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0))) +#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1)))) + +#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8))) +#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) + +/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters + * @{ + */ +#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \ + ((CYCLE) == I2C_DUTYCYCLE_16_9)) +#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \ + ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT)) +#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) +#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ + ((CALL) == I2C_GENERALCALL_ENABLE)) +#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ + ((STRETCH) == I2C_NOSTRETCH_ENABLE)) +#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ + ((SIZE) == I2C_MEMADD_SIZE_16BIT)) +#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0U) && ((SPEED) <= 400000U)) +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & 0xFFFFFC00U) == 0U) +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & 0xFFFFFF01U) == 0U) +#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ + ((REQUEST) == I2C_NEXT_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME)) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_I2C_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h new file mode 100644 index 00000000..ff47d5cc --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h @@ -0,0 +1,137 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c_ex.h + * @author MCD Application Team + * @brief Header file of I2C HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_I2C_EX_H +#define __STM32F4xx_HAL_I2C_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2CEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2CEx_Analog_Filter I2C Analog Filter + * @{ + */ +#define I2C_ANALOGFILTER_ENABLE 0x00000000U +#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2CEx_Exported_Functions + * @{ + */ + +/** @addtogroup I2CEx_Exported_Functions_Group1 + * @{ + */ +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Constants I2C Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Macros I2C Private Macros + * @{ + */ +#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ + ((FILTER) == I2C_ANALOGFILTER_DISABLE)) +#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ + STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx ||\ + STM32F413xx || STM32F423xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_I2C_EX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c new file mode 100644 index 00000000..da185200 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c @@ -0,0 +1,5494 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c.c + * @author MCD Application Team + * @brief I2C HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Inter Integrated Circuit (I2C) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State, Mode and Error functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The I2C HAL driver can be used as follows: + + (#) Declare a I2C_HandleTypeDef handle structure, for example: + I2C_HandleTypeDef hi2c; + + (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API: + (##) Enable the I2Cx interface clock + (##) I2C pins configuration + (+++) Enable the clock for the I2C GPIOs + (+++) Configure I2C pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the I2Cx interrupt priority + (+++) Enable the NVIC I2C IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream + (+++) Enable the DMAx interface clock using + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx Stream + (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on + the DMA Tx or Rx Stream + + (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1, + Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure. + + (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware + (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API. + + (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady() + + (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit() + (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive() + (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit() + (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive() + + *** Polling mode IO MEM operation *** + ===================================== + [..] + (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write() + (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read() + + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode using HAL_I2C_Master_Transmit_IT() + (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode using HAL_I2C_Master_Receive_IT() + (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Transmit_IT() + (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Receive_IT() + (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + + *** Interrupt mode IO sequential operation *** + ============================================== + [..] + (@) These interfaces allow to manage a sequential transfer with a repeated start condition + when a direction change during transfer + [..] + (+) A specific option field manage the different steps of a sequential transfer + (+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below: + (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode + (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address + and data to transfer without a final stop condition + (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to transfer + if no direction change and without a final stop condition in both cases + (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to transfer + if no direction change and with a final stop condition in both cases + + (+) Differents sequential I2C interfaces are listed below: + (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT() + (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() + (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Receive_IT() + (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() + (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT() + (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can + add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). + (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_ListenCpltCallback() + (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Transmit_IT() + (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() + (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Receive_IT() + (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() + (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback() + (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + + *** Interrupt mode IO MEM operation *** + ======================================= + [..] + (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using + HAL_I2C_Mem_Write_IT() + (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using + HAL_I2C_Mem_Read_IT() + (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Master_Transmit_DMA() + (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Master_Receive_DMA() + (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Slave_Transmit_DMA() + (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Slave_Receive_DMA() + (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + + *** DMA mode IO MEM operation *** + ================================= + [..] + (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using + HAL_I2C_Mem_Write_DMA() + (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using + HAL_I2C_Mem_Read_DMA() + (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + + *** I2C HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in I2C HAL driver. + + (+) __HAL_I2C_ENABLE: Enable the I2C peripheral + (+) __HAL_I2C_DISABLE: Disable the I2C peripheral + (+) __HAL_I2C_GET_FLAG : Checks whether the specified I2C flag is set or not + (+) __HAL_I2C_CLEAR_FLAG : Clear the specified I2C pending flag + (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt + (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt + + [..] + (@) You can refer to the I2C HAL driver header file for more useful macros + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup I2C I2C + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup I2C_Private_Define + * @{ + */ +#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */ +#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */ +#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ + +/* Private define for @ref PreviousState usage */ +#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(uint32_t)HAL_I2C_STATE_READY))) /*!< Mask State define, keep only RX and TX bits */ +#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */ +#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup I2C_Private_Functions + * @{ + */ +/* Private functions to handle DMA transfer */ +static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAError(DMA_HandleTypeDef *hdma); +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma); + +static void I2C_ITError(I2C_HandleTypeDef *hi2c); + +static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c); + +/* Private functions for I2C transfer IRQ handler */ +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c); + +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Functions I2C Exported Functions + * @{ + */ + +/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the I2Cx peripheral: + + (+) User must Implement HAL_I2C_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC). + + (+) Call the function HAL_I2C_Init() to configure the selected device with + the selected configuration: + (++) Communication Speed + (++) Duty cycle + (++) Addressing mode + (++) Own Address 1 + (++) Dual Addressing mode + (++) Own Address 2 + (++) General call mode + (++) Nostretch mode + + (+) Call the function HAL_I2C_DeInit() to restore the default configuration + of the selected I2Cx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the I2C according to the specified parameters + * in the I2C_InitTypeDef and create the associated handle. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) +{ + uint32_t freqrange = 0U; + uint32_t pclk1 = 0U; + + /* Check the I2C handle allocation */ + if(hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed)); + assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle)); + assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); + assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); + assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); + assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); + assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); + assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); + + if(hi2c->State == HAL_I2C_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2c->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_I2C_MspInit(hi2c); + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get PCLK1 frequency */ + pclk1 = HAL_RCC_GetPCLK1Freq(); + + /* Calculate frequency range */ + freqrange = I2C_FREQRANGE(pclk1); + + /*---------------------------- I2Cx CR2 Configuration ----------------------*/ + /* Configure I2Cx: Frequency range */ + hi2c->Instance->CR2 = freqrange; + + /*---------------------------- I2Cx TRISE Configuration --------------------*/ + /* Configure I2Cx: Rise Time */ + hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); + + /*---------------------------- I2Cx CCR Configuration ----------------------*/ + /* Configure I2Cx: Speed */ + hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); + + /*---------------------------- I2Cx CR1 Configuration ----------------------*/ + /* Configure I2Cx: Generalcall and NoStretch mode */ + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + + /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ + /* Configure I2Cx: Own Address1 and addressing mode */ + hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); + + /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ + /* Configure I2Cx: Dual mode and Own Address2 */ + hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2); + + /* Enable the selected I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + return HAL_OK; +} + +/** + * @brief DeInitializes the I2C peripheral. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) +{ + /* Check the I2C handle allocation */ + if(hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the I2C Peripheral Clock */ + __HAL_I2C_DISABLE(hi2c); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_I2C_MspDeInit(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_RESET; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief I2C MSP Init. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_MspInit could be implemented in the user file + */ +} + +/** + * @brief I2C MSP DeInit + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2C data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2C_Master_Transmit() + (++) HAL_I2C_Master_Receive() + (++) HAL_I2C_Slave_Transmit() + (++) HAL_I2C_Slave_Receive() + (++) HAL_I2C_Mem_Write() + (++) HAL_I2C_Mem_Read() + (++) HAL_I2C_IsDeviceReady() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2C_Master_Transmit_IT() + (++) HAL_I2C_Master_Receive_IT() + (++) HAL_I2C_Slave_Transmit_IT() + (++) HAL_I2C_Slave_Receive_IT() + (++) HAL_I2C_Master_Sequential_Transmit_IT() + (++) HAL_I2C_Master_Sequential_Receive_IT() + (++) HAL_I2C_Slave_Sequential_Transmit_IT() + (++) HAL_I2C_Slave_Sequential_Receive_IT() + (++) HAL_I2C_Mem_Write_IT() + (++) HAL_I2C_Mem_Read_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2C_Master_Transmit_DMA() + (++) HAL_I2C_Master_Receive_DMA() + (++) HAL_I2C_Slave_Transmit_DMA() + (++) HAL_I2C_Slave_Receive_DMA() + (++) HAL_I2C_Mem_Write_DMA() + (++) HAL_I2C_Mem_Read_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2C_MemTxCpltCallback() + (++) HAL_I2C_MemRxCpltCallback() + (++) HAL_I2C_MasterTxCpltCallback() + (++) HAL_I2C_MasterRxCpltCallback() + (++) HAL_I2C_SlaveTxCpltCallback() + (++) HAL_I2C_SlaveRxCpltCallback() + (++) HAL_I2C_ErrorCallback() + (++) HAL_I2C_AbortCpltCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + while(hi2c->XferSize > 0U) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + } + + /* Wait until BTF flag is set */ + if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferSize == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 2U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(hi2c->XferSize > 0U) + { + if(hi2c->XferSize <= 3U) + { + /* One byte */ + if(hi2c->XferSize == 1U) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* Two bytes */ + else if(hi2c->XferSize == 2U) + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* 3 Last bytes */ + else + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* If 10bit addressing mode is selected */ + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(hi2c->XferSize > 0U) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + } + } + + /* Wait until AF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in blocking mode + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + while(hi2c->XferSize > 0U) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + + /* Wait until STOP flag is set */ + if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in master mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + __IO uint32_t Prev_State = 0x00U; + __IO uint32_t count = 0x00U; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Check Busy Flag only if FIRST call of Master interface */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + Prev_State = hi2c->PreviousState; + + /* Generate Start */ + if((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) + { + /* Generate Start condition if first transfer */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential receive in master mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + __IO uint32_t count = 0U; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Check Busy Flag only if FIRST call of Master interface */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) + { + /* Generate Start condition if first transfer */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in slave mode an amount of data in no-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_LISTEN) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential receive in slave mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_LISTEN) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Enable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_LISTEN; + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Disable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + uint32_t tmp; + + /* Disable Address listen mode only if a transfer is not ongoing */ + if(hi2c->State == HAL_I2C_STATE_LISTEN) + { + tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; + hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Disable EVT and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferM1CpltCallback = NULL; + hi2c->hdmatx->XferM1HalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferM1CpltCallback = NULL; + hi2c->hdmarx->XferM1HalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Abort a master I2C process communication with Interrupt. + * @note This abort can be called only if state is ready + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(DevAddress); + + /* Abort Master transfer during Receive or Transmit process */ + if(hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_ABORT; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->XferCount = 0U; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c); + + return HAL_OK; + } + else + { + /* Wrong usage of abort function */ + /* This function should be used only in case of abort monitored by master device */ + return HAL_ERROR; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferM1CpltCallback = NULL; + hi2c->hdmatx->XferM1HalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferM1CpltCallback = NULL; + hi2c->hdmarx->XferM1HalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in blocking mode to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + while(hi2c->XferSize > 0U) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferSize--; + hi2c->XferCount--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferSize--; + hi2c->XferCount--; + } + } + + /* Wait until BTF flag is set */ + if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in blocking mode from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferSize == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 2U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(hi2c->XferSize > 0U) + { + if(hi2c->XferSize <= 3U) + { + /* One byte */ + if(hi2c->XferSize== 1U) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* Two bytes */ + else if(hi2c->XferSize == 2U) + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* 3 Last bytes */ + else + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->Devaddress = DevAddress; + hi2c->Memaddress = MemAddress; + hi2c->MemaddSize = MemAddSize; + hi2c->EventCount = 0U; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->Devaddress = DevAddress; + hi2c->Memaddress = MemAddress; + hi2c->MemaddSize = MemAddSize; + hi2c->EventCount = 0U; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + if(hi2c->XferSize > 0U) + { + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferM1CpltCallback = NULL; + hi2c->hdmatx->XferM1HalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + uint32_t tickstart = 0x00U; + __IO uint32_t count = 0U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferM1CpltCallback = NULL; + hi2c->hdmarx->XferM1HalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(Size == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Checks if target device is ready for communication. + * @note This function is used with Memory devices + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param Trials Number of trials + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) +{ + uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U; + + /* Get tick */ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + do + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR or AF flag are set */ + /* Get tick */ + tickstart = HAL_GetTick(); + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp3 = hi2c->State; + while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) + { + if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hi2c->State = HAL_I2C_STATE_TIMEOUT; + } + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp3 = hi2c->State; + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if the ADDR flag has been set */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear ADDR Flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + } + }while(I2C_Trials++ < Trials); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles I2C event interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t sr2itflags = READ_REG(hi2c->Instance->SR2); + uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); + uint32_t itsources = READ_REG(hi2c->Instance->CR2); + + uint32_t CurrentMode = hi2c->Mode; + + /* Master or Memory mode selected */ + if((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) + { + /* SB Set ----------------------------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_SB(hi2c); + } + /* ADD10 Set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_ADD10) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_ADD10(hi2c); + } + /* ADDR Set --------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_ADDR(hi2c); + } + + /* I2C in mode Transmitter -----------------------------------------------*/ + if((sr2itflags & I2C_FLAG_TRA) != RESET) + { + /* TXE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_MasterTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_MasterTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + /* RXNE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_MasterReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_MasterReceive_BTF(hi2c); + } + } + } + /* Slave mode selected */ + else + { + /* ADDR set --------------------------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Slave_ADDR(hi2c); + } + /* STOPF set --------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Slave_STOPF(hi2c); + } + /* I2C in mode Transmitter -----------------------------------------------*/ + else if((sr2itflags & I2C_FLAG_TRA) != RESET) + { + /* TXE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_SlaveTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_SlaveTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + /* RXNE set and BTF reset ----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_SlaveReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_SlaveReceive_BTF(hi2c); + } + } + } +} + +/** + * @brief This function handles I2C error interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U; + uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); + uint32_t itsources = READ_REG(hi2c->Instance->CR2); + + /* I2C Bus error interrupt occurred ----------------------------------------*/ + if(((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); + } + + /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ + if(((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); + } + + /* I2C Acknowledge failure error interrupt occurred ------------------------*/ + if(((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + tmp1 = hi2c->Mode; + tmp2 = hi2c->XferCount; + tmp3 = hi2c->State; + tmp4 = hi2c->PreviousState; + if((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) && \ + ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || \ + ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) + { + I2C_Slave_AF(hi2c); + } + else + { + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */ + if(hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Generate Stop */ + SET_BIT(hi2c->Instance->CR1,I2C_CR1_STOP); + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + + /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ + if(((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; + /* Clear OVR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); + } + + /* Call the Error Callback in case of Error detected -----------------------*/ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + I2C_ITError(hi2c); + } +} + +/** + * @brief Master Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterTxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Master Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterRxCpltCallback can be implemented in the user file + */ +} + +/** @brief Slave Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveTxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Slave Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveRxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Slave Address Match callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferOptions_definition + * @param AddrMatchCode Address Match Code + * @retval None + */ +__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + UNUSED(TransferDirection); + UNUSED(AddrMatchCode); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AddrCallback can be implemented in the user file + */ +} + +/** + * @brief Listen Complete callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ListenCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Memory Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemTxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Memory Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemRxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief I2C error callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ErrorCallback can be implemented in the user file + */ +} + +/** + * @brief I2C abort callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AbortCpltCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions + * @brief Peripheral State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State, Mode and Error functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the I2C handle state. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL state + */ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) +{ + /* Return I2C handle state */ + return hi2c->State; +} + +/** + * @brief Return the I2C Master, Slave, Memory or no mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL mode + */ +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c) +{ + return hi2c->Mode; +} + +/** + * @brief Return the I2C error code + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval I2C Error Code + */ +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) +{ + return hi2c->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief Handle TXE flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t CurrentMode = hi2c->Mode; + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if((hi2c->XferSize == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX)) + { + /* Call TxCpltCallback() directly if no stop mode is set */ + if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) + { + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + else /* Generate Stop condition then Call TxCpltCallback() */ + { + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MemTxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MasterTxCpltCallback(hi2c); + } + } + } + else if((CurrentState == HAL_I2C_STATE_BUSY_TX) || \ + ((CurrentMode == HAL_I2C_MODE_MEM) && (CurrentState == HAL_I2C_STATE_BUSY_RX))) + { + if(hi2c->XferCount == 0U) + { + /* Disable BUF interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + } + else + { + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + if(hi2c->EventCount == 0) + { + /* If Memory address size is 8Bit */ + if(hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); + + hi2c->EventCount += 2; + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress); + + hi2c->EventCount++; + } + } + else if(hi2c->EventCount == 1) + { + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); + + hi2c->EventCount++; + } + else if(hi2c->EventCount == 2) + { + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + } + } + else + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master transmitter + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + else + { + /* Call TxCpltCallback() directly if no stop mode is set */ + if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) + { + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + else /* Generate Stop condition then Call TxCpltCallback() */ + { + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemTxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + } + } + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + uint32_t tmp = 0U; + + tmp = hi2c->XferCount; + if(tmp > 3U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + if(hi2c->XferCount == 3) + { + /* Disable BUF interrupt, this help to treat correctly the last 4 bytes + on BTF subroutine */ + /* Disable BUF interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + } + } + else if((tmp == 1U) || (tmp == 0U)) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master receiver + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if(hi2c->XferCount == 4U) + { + /* Disable BUF interrupt, this help to treat correctly the last 2 bytes + on BTF subroutine if there is a reception delay between N-1 and N byte */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + else if(hi2c->XferCount == 3U) + { + /* Disable BUF interrupt, this help to treat correctly the last 2 bytes + on BTF subroutine if there is a reception delay between N-1 and N byte */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + else if(hi2c->XferCount == 2U) + { + /* Prepare next transfer or stop current transfer */ + if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Disable EVT and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + else + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle SB flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + if(hi2c->EventCount == 0U) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); + } + else + { + hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); + } + } + else + { + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave 7 Bits address */ + if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); + } + else + { + hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); + } + } + else + { + if(hi2c->EventCount == 0U) + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress); + } + else if(hi2c->EventCount == 1U) + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress); + } + } + } + + return HAL_OK; +} + +/** + * @brief Handle ADD10 flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c) +{ + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress); + + return HAL_OK; +} + +/** + * @brief Handle ADDR flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentMode = hi2c->Mode; + uint32_t CurrentXferOptions = hi2c->XferOptions; + uint32_t Prev_State = hi2c->PreviousState; + + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + if((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM)) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else if((hi2c->EventCount == 0U) && (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + hi2c->EventCount++; + } + else + { + if(hi2c->XferCount == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferCount == 1U) + { + if(CurrentXferOptions == I2C_NO_OPTION_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + } + /* Prepare next transfer or stop current transfer */ + else if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) \ + && (Prev_State != I2C_STATE_MASTER_BUSY_RX)) + { + if(hi2c->XferOptions != I2C_NEXT_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + } + else if(hi2c->XferCount == 2U) + { + if(hi2c->XferOptions != I2C_NEXT_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + } + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + /* Reset Event counter */ + hi2c->EventCount = 0U; + } + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + return HAL_OK; +} + +/** + * @brief Handle TXE flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + + if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) + { + /* Last Byte is received, disable Interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Set state at HAL_I2C_STATE_LISTEN */ + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + hi2c->State = HAL_I2C_STATE_LISTEN; + + /* Call the Tx complete callback to inform upper layer of the end of receive process */ + HAL_I2C_SlaveTxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave transmitter + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if(hi2c->XferCount != 0U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + /* Last Byte is received, disable Interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Set state at HAL_I2C_STATE_LISTEN */ + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; + hi2c->State = HAL_I2C_STATE_LISTEN; + + /* Call the Rx complete callback to inform upper layer of the end of receive process */ + HAL_I2C_SlaveRxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave receiver + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle ADD flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) +{ + uint8_t TransferDirection = I2C_DIRECTION_RECEIVE; + uint16_t SlaveAddrCode = 0U; + + /* Transfer Direction requested by Master */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == RESET) + { + TransferDirection = I2C_DIRECTION_TRANSMIT; + } + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DUALF) == RESET) + { + SlaveAddrCode = hi2c->Init.OwnAddress1; + } + else + { + SlaveAddrCode = hi2c->Init.OwnAddress2; + } + + /* Call Slave Addr callback */ + HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode); + + return HAL_OK; +} + +/** + * @brief Handle STOPF flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear STOPF flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* If a DMA is ongoing, Update handle size context */ + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + if((hi2c->State == HAL_I2C_STATE_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmarx); + } + else + { + hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmatx); + } + } + + /* All data are not transferred, so set error code accordingly */ + if(hi2c->XferCount != 0U) + { + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + //hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c); + } + else + { + if((CurrentState == HAL_I2C_STATE_LISTEN ) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN) || \ + (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + HAL_I2C_ListenCpltCallback(hi2c); + } + else + { + if((hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_RX) || (CurrentState == HAL_I2C_STATE_BUSY_RX)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_SlaveRxCpltCallback(hi2c); + } + } + } + return HAL_OK; +} + +/** + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if(((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME)) && \ + (CurrentState == HAL_I2C_STATE_LISTEN)) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + HAL_I2C_ListenCpltCallback(hi2c); + } + else if(CurrentState == HAL_I2C_STATE_BUSY_TX) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + HAL_I2C_SlaveTxCpltCallback(hi2c); + } + else + { + /* Clear AF flag only */ + /* State Listen, but XferOptions == FIRST or NEXT */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + + return HAL_OK; +} + +/** + * @brief I2C interrupts error process + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ITError(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + /* keep HAL_I2C_STATE_LISTEN */ + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_LISTEN; + } + else + { + /* If state is an abort treatment on going, don't change state */ + /* This change will be do later */ + if((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) + { + hi2c->State = HAL_I2C_STATE_READY; + } + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + } + + /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + /* Abort DMA transfer */ + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + if(hi2c->hdmatx->State != HAL_DMA_STATE_READY) + { + /* Set the DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + if(HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + else + { + /* Set the DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + if(HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + } + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + else if(hi2c->State == HAL_I2C_STATE_ABORT) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + } + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + HAL_I2C_AbortCpltCallback(hi2c); + } + else + { + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + } + + /* Call user error callback */ + HAL_I2C_ErrorCallback(hi2c); + } + /* STOP Flag is not set after a NACK reception */ + /* So may inform upper layer that listen phase is stopped */ + /* during NACK error treatment */ + if((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + HAL_I2C_ListenCpltCallback(hi2c); + } +} + +/** + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + /* Generate Start condition if first transfer */ + if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + } + else + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + } + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address for read request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start condition if first transfer */ + if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); + } + else + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); + } + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for write request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) +{ + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for read request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) +{ + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief DMA I2C process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t CurrentMode = hi2c->Mode; + + if((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) + { + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0U; + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + } + else + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Disable Last DMA */ + hi2c->Instance->CR2 &= ~I2C_CR2_LAST; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0U; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + } +} + +/** + * @brief DMA I2C communication error callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAError(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Ignore DMA FIFO error */ + if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->XferCount = 0U; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + HAL_I2C_ErrorCallback(hi2c); + } +} + +/** + * @brief DMA I2C communication abort callback + * (To be called at end of DMA Abort procedure). + * @param hdma DMA handle. + * @retval None + */ +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->XferCount = 0U; + + /* Reset XferAbortCallback */ + hi2c->hdmatx->XferAbortCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Check if come from abort from user */ + if(hi2c->State == HAL_I2C_STATE_ABORT) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + HAL_I2C_AbortCpltCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + HAL_I2C_ErrorCallback(hi2c); + } +} + +/** + * @brief This function handles I2C Communication Timeout. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag specifies the I2C flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) +{ + /* Wait until flag is set */ + while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for Master addressing phase. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag specifies the I2C flag to check. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) + { + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of TXE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) + { + /* Check if a NACK is detected */ + if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of BTF flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) + { + /* Check if a NACK is detected */ + if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of STOP flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + { + /* Check if a NACK is detected */ + if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) + { + /* Check if a STOPF is detected */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + { + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief This function handles Acknowledge failed detection during an I2C Communication. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) +{ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + /* Clear NACKF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + return HAL_OK; +} +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c new file mode 100644 index 00000000..de8f1602 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c @@ -0,0 +1,204 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c_ex.c + * @author MCD Application Team + * @brief I2C Extension HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of I2C extension peripheral: + * + Extension features functions + * + @verbatim + ============================================================================== + ##### I2C peripheral extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the I2C interface for STM32F427xx/437xx/ + 429xx/439xx devices contains the following additional features : + + (+) Possibility to disable or enable Analog Noise Filter + (+) Use of a configured Digital Noise Filter + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure Noise Filter + (#) Configure I2C Analog noise filter using the function HAL_I2C_AnalogFilter_Config() + (#) Configure I2C Digital noise filter using the function HAL_I2C_DigitalFilter_Config() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup I2CEx I2CEx + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Functions I2C Exported Functions + * @{ + */ + + +/** @defgroup I2CEx_Exported_Functions_Group1 Extension features functions + * @brief Extension features functions + * +@verbatim + =============================================================================== + ##### Extension features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Noise Filters + +@endverbatim + * @{ + */ + +/** + * @brief Configures I2C Analog noise filter. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param AnalogFilter new state of the Analog filter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Reset I2Cx ANOFF bit */ + hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF); + + /* Disable the analog filter */ + hi2c->Instance->FLTR |= AnalogFilter; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configures I2C Digital noise filter. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) +{ + uint16_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get the old register value */ + tmpreg = hi2c->Instance->FLTR; + + /* Reset I2Cx DNF bit [3:0] */ + tmpreg &= ~(I2C_FLTR_DNF); + + /* Set I2Cx DNF coefficient */ + tmpreg |= DigitalFilter; + + /* Store the new register value */ + hi2c->Instance->FLTR = tmpreg; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ + STM32F401xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx ||\ + STM32F423xx */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h index e518489f..ed26bf39 100644 --- a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h +++ b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h @@ -65,7 +65,7 @@ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ -/* #define HAL_I2C_MODULE_ENABLED */ +#define HAL_I2C_MODULE_ENABLED /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index e390af58..154c98af 100644 --- a/Firmware/Board/v3/Src/main.c +++ b/Firmware/Board/v3/Src/main.c @@ -180,7 +180,7 @@ int main(void) MX_DMA_Init(); MX_ADC1_Init(); MX_ADC2_Init(); - MX_CAN1_Init(); + // MX_CAN1_Init(); // CAN or I2C called in main.cpp instead MX_TIM1_Init(); MX_TIM8_Init(); MX_TIM3_Init(); From 2e78432fed97837563a436c216ba07cc0788dd6b Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 00:08:08 -0700 Subject: [PATCH 17/40] Cube: Notify OS that we are a composite device --- Firmware/Board/v3/Src/usbd_desc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c index b0906144..d213f64a 100644 --- a/Firmware/Board/v3/Src/usbd_desc.c +++ b/Firmware/Board/v3/Src/usbd_desc.c @@ -97,7 +97,8 @@ #define USBD_PID_FS 0x0D32 #define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) #define USBD_PRODUCT_STR(s) #s -#define USBD_PRODUCT_STRING_FS ODrive version HW_VERSION_MAJOR.HW_VERSION_MINOR +#define USBD_PRODUCT_STRING_FS ODrive HW_VERSION_MAJOR.HW_VERSION_MINOR CDC Interface +#define NATIVE_STRING ODrive HW_VERSION_MAJOR.HW_VERSION_MINOR Native Interface #define USBD_SERIALNUMBER_STRING_FS "000000000001" #define USBD_CONFIGURATION_STRING_FS "CDC Config" #define USBD_INTERFACE_STRING_FS "CDC Interface" @@ -233,16 +234,17 @@ __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = 0x00, /*bcdUSB */ #endif /* (USBD_LPM_ENABLED == 1) */ 0x02, - 0x02, /*bDeviceClass*/ + // Notify OS that this is a composite device + 0xEF, /*bDeviceClass*/ 0x02, /*bDeviceSubClass*/ - 0x00, /*bDeviceProtocol*/ + 0x01, /*bDeviceProtocol*/ USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID_FS), /*idProduct*/ HIBYTE(USBD_PID_FS), /*idProduct*/ 0x00, /*bcdDevice rel. 2.00*/ - 0x02, + 0x03, /* bNumInterfaces */ USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ From 484654fc7db3bce24c74601a4484dd8fb20aadde Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 00:51:04 -0700 Subject: [PATCH 18/40] cube: apply canges to USB --- Firmware/Board/v3/Inc/usbd_cdc_if.h | 2 +- Firmware/Board/v3/Inc/usbd_conf.h | 1 + Firmware/Board/v3/Inc/usbd_desc.h | 3 +- .../Class/CDC/Inc/usbd_cdc.h | 39 +- .../Class/CDC/Src/usbd_cdc.c | 562 +++++++++++------- .../Core/Inc/usbd_def.h | 4 +- Firmware/Board/v3/Src/usbd_cdc_if.c | 12 +- Firmware/Board/v3/Src/usbd_conf.c | 24 +- 8 files changed, 404 insertions(+), 243 deletions(-) diff --git a/Firmware/Board/v3/Inc/usbd_cdc_if.h b/Firmware/Board/v3/Inc/usbd_cdc_if.h index c15e8b91..ed1d6705 100644 --- a/Firmware/Board/v3/Inc/usbd_cdc_if.h +++ b/Firmware/Board/v3/Inc/usbd_cdc_if.h @@ -132,7 +132,7 @@ extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; * @{ */ -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t endpoint_pair); /* USER CODE BEGIN EXPORTED_FUNCTIONS */ /* USER CODE END EXPORTED_FUNCTIONS */ diff --git a/Firmware/Board/v3/Inc/usbd_conf.h b/Firmware/Board/v3/Inc/usbd_conf.h index bf276186..a897ba43 100644 --- a/Firmware/Board/v3/Inc/usbd_conf.h +++ b/Firmware/Board/v3/Inc/usbd_conf.h @@ -89,6 +89,7 @@ * @brief Defines for configuration of the Usb device. * @{ */ + #define MS_VendorCode 'P' /*---------- -----------*/ #define USBD_MAX_NUM_INTERFACES 1 diff --git a/Firmware/Board/v3/Inc/usbd_desc.h b/Firmware/Board/v3/Inc/usbd_desc.h index 18d1f34e..2a74de31 100644 --- a/Firmware/Board/v3/Inc/usbd_desc.h +++ b/Firmware/Board/v3/Inc/usbd_desc.h @@ -2,7 +2,7 @@ ****************************************************************************** * @file : usbd_desc.h * @version : v1.0_Cube - * @brief : Header for usbd_conf.c file. + * @brief : Header for usbd_desc.c file. ****************************************************************************** * This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and @@ -46,6 +46,7 @@ * ****************************************************************************** */ + /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __USBD_DESC__H__ #define __USBD_DESC__H__ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h index d937b2e8..c029e22a 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -52,13 +52,15 @@ #define CDC_IN_EP 0x81 /* EP1 for data IN */ #define CDC_OUT_EP 0x01 /* EP1 for data OUT */ #define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ +#define ODRIVE_IN_EP 0x83 /* EP3 IN: ODrive device TX endpoint */ +#define ODRIVE_OUT_EP 0x03 /* EP3 OUT: ODrive device RX endpoint */ /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ -#define CDC_DATA_HS_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_HS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ #define CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ #define CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */ -#define USB_CDC_CONFIG_DESC_SIZ 67 +#define USB_CDC_CONFIG_DESC_SIZ (67 + 39) #define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE #define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE @@ -103,23 +105,29 @@ typedef struct _USBD_CDC_Itf int8_t (* Init) (void); int8_t (* DeInit) (void); int8_t (* Control) (uint8_t, uint8_t * , uint16_t); - int8_t (* Receive) (uint8_t *, uint32_t *); + int8_t (* Receive) (uint8_t *, uint32_t *, uint8_t); }USBD_CDC_ItfTypeDef; +typedef struct +{ + uint8_t* Buffer; + uint32_t Length; + volatile uint8_t State; +} +USBD_CDC_EP_HandleTypeDef; typedef struct { uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */ uint8_t CmdOpCode; - uint8_t CmdLength; - uint8_t *RxBuffer; - uint8_t *TxBuffer; - uint32_t RxLength; - uint32_t TxLength; - - __IO uint32_t TxState; - __IO uint32_t RxState; + uint8_t CmdLength; + + USBD_CDC_EP_HandleTypeDef CDC_Tx; + USBD_CDC_EP_HandleTypeDef CDC_Rx; + + USBD_CDC_EP_HandleTypeDef ODRIVE_Tx; + USBD_CDC_EP_HandleTypeDef ODRIVE_Rx; } USBD_CDC_HandleTypeDef; @@ -151,14 +159,15 @@ uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint16_t length); + uint16_t length, + uint8_t endpoint_pair); uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, - uint8_t *pbuff); + uint8_t *pbuff, uint8_t endpoint_pair); -uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev, uint8_t endpoint_pair); -uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev, uint8_t endpoint_pair); /** * @} */ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index 24465641..73313522 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -132,6 +132,9 @@ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length); uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length); +static uint8_t USBD_WinUSBComm_SetupVendor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +//static uint8_t * USBD_GetUsrStrDescriptor(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); + /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -173,24 +176,37 @@ USBD_ClassTypeDef USBD_CDC = USBD_CDC_GetFSCfgDesc, USBD_CDC_GetOtherSpeedCfgDesc, USBD_CDC_GetDeviceQualifierDescriptor, + USBD_UsrStrDescriptor }; /* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { /*Configuration Descriptor*/ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ 0x00, - 0x02, /* bNumInterfaces: 2 interface */ + 0x03, /* bNumInterfaces: 3 interfaces (2 for CDC, 1 custom) */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0xC0, /* bmAttributes: self powered */ 0x32, /* MaxPower 0 mA */ + + /////////////////////////////////////////////////////////////////////////////// + + /* Interface Association Descriptor: CDC device (virtual com port) */ + 0x08, /* bLength: IAD size */ + 0x0B, /* bDescriptorType: Interface Association Descriptor */ + 0x00, /* bFirstInterface */ + 0x02, /* bInterfaceCount */ + 0x02, /* bFunctionClass: Communication Interface Class */ + 0x02, /* bFunctionSubClass: Abstract Control Model */ + 0x01, /* bFunctionProtocol: Common AT commands */ + 0x00, /* iFunction */ /*---------------------------------------------------------------------------*/ - + /*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ @@ -202,7 +218,7 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ 0x00, /* iInterface: */ - + /*Header Functional Descriptor*/ 0x05, /* bLength: Endpoint Descriptor size */ 0x24, /* bDescriptorType: CS_INTERFACE */ @@ -229,7 +245,7 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x06, /* bDescriptorSubtype: Union func desc */ 0x00, /* bMasterInterface: Communication class interface */ 0x01, /* bSlaveInterface0: Data Class Interface */ - + /*Endpoint 2 Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ @@ -267,196 +283,52 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ -} ; + 0x00, /* bInterval: ignore for Bulk transfer */ + /////////////////////////////////////////////////////////////////////////////// + + /* Interface Association Descriptor: custom device */ + 0x08, /* bLength: IAD size */ + 0x0B, /* bDescriptorType: Interface Association Descriptor */ + 0x02, /* bFirstInterface */ + 0x01, /* bInterfaceCount */ + 0x00, /* bFunctionClass: */ + 0x00, /* bFunctionSubClass: */ + 0x00, /* bFunctionProtocol: */ + 0x06, /* iFunction */ -/* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - /*Configuration Descriptor*/ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ - 0x00, - 0x02, /* bNumInterfaces: 2 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ - - /*---------------------------------------------------------------------------*/ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SIZE), - 0x10, /* bInterval: */ /*---------------------------------------------------------------------------*/ /*Data class interface descriptor*/ 0x09, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ + 0x02, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceClass: vendor specific */ + 0x01, /* bInterfaceSubClass: ODrive Communication */ 0x00, /* bInterfaceProtocol: */ 0x00, /* iInterface: */ /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ + ODRIVE_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ + ODRIVE_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ } ; -__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_CDC_CONFIG_DESC_SIZ, - 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT , /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SIZE), - 0xFF, /* bInterval: */ - - /*---------------------------------------------------------------------------*/ - - /*Data class interface descriptor*/ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00, /* bInterval: ignore for Bulk transfer */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00 /* bInterval */ -}; /** * @} @@ -508,6 +380,19 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, USBD_EP_TYPE_BULK, CDC_DATA_FS_OUT_PACKET_SIZE); } + + /* Open ODrive IN endpoint */ + USBD_LL_OpenEP(pdev, + ODRIVE_IN_EP, + USBD_EP_TYPE_BULK, + pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_IN_PACKET_SIZE : CDC_DATA_FS_IN_PACKET_SIZE); + + /* Open ODrive OUT endpoint */ + USBD_LL_OpenEP(pdev, + ODRIVE_OUT_EP, + USBD_EP_TYPE_BULK, + pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_OUT_PACKET_SIZE : CDC_DATA_FS_OUT_PACKET_SIZE); + /* Open Command IN EP */ USBD_LL_OpenEP(pdev, CDC_CMD_EP, @@ -529,15 +414,17 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); /* Init Xfer states */ - hcdc->TxState =0; - hcdc->RxState =0; + hcdc->CDC_Tx.State =0; + hcdc->CDC_Rx.State =0; + hcdc->ODRIVE_Tx.State =0; + hcdc->ODRIVE_Rx.State =0; if(pdev->dev_speed == USBD_SPEED_HIGH ) { /* Prepare Out endpoint to receive next packet */ USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, - hcdc->RxBuffer, + hcdc->CDC_Rx.Buffer, CDC_DATA_HS_OUT_PACKET_SIZE); } else @@ -545,11 +432,15 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, /* Prepare Out endpoint to receive next packet */ USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, - hcdc->RxBuffer, + hcdc->CDC_Rx.Buffer, CDC_DATA_FS_OUT_PACKET_SIZE); } - + /* Prepare ODrive Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + ODRIVE_OUT_EP, + hcdc->ODRIVE_Rx.Buffer, + CDC_DATA_FS_OUT_PACKET_SIZE); } return ret; } @@ -566,17 +457,25 @@ static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, { uint8_t ret = 0; - /* Open EP IN */ + /* Close EP IN */ USBD_LL_CloseEP(pdev, CDC_IN_EP); - /* Open EP OUT */ + /* Close EP OUT */ USBD_LL_CloseEP(pdev, CDC_OUT_EP); - /* Open Command IN EP */ + /* Close Command IN EP */ USBD_LL_CloseEP(pdev, CDC_CMD_EP); + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, + ODRIVE_IN_EP); + + /* Close EP OUT */ + USBD_LL_CloseEP(pdev, + ODRIVE_OUT_EP); /* DeInit physical Interface components */ @@ -648,6 +547,9 @@ static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, case USB_REQ_SET_INTERFACE : break; } + + case USB_REQ_TYPE_VENDOR: + return USBD_WinUSBComm_SetupVendor(pdev, req); default: break; @@ -668,8 +570,12 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) if(pdev->pClassData != NULL) { - - hcdc->TxState = 0; + // NOTE: We would logically expect xx_IN_EP here, but we actually get the xx_OUT_EP + if (epnum == CDC_OUT_EP) + hcdc->CDC_Tx.State = 0; + if (epnum == ODRIVE_OUT_EP) + hcdc->ODRIVE_Tx.State = 0; + //Note: We could use independent semaphores for simoultainous USB transmission. osSemaphoreRelease(sem_usb_tx); return USBD_OK; } @@ -689,15 +595,24 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + USBD_CDC_EP_HandleTypeDef* hEP_Rx; + if (epnum == CDC_OUT_EP) { + hEP_Rx = &hcdc->CDC_Rx; + } else if (epnum == ODRIVE_OUT_EP) { + hEP_Rx = &hcdc->ODRIVE_Rx; + } else { + return USBD_FAIL; + } /* Get the received data length */ - hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + hEP_Rx->Length = USBD_LL_GetRxDataSize (pdev, epnum); /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ if(pdev->pClassData != NULL) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hEP_Rx->Buffer, &hEP_Rx->Length, epnum); return USBD_OK; } @@ -740,8 +655,8 @@ static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_CfgFSDesc); - return USBD_CDC_CfgFSDesc; + *length = sizeof (USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -753,8 +668,8 @@ static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) */ static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_CfgHSDesc); - return USBD_CDC_CfgHSDesc; + *length = sizeof (USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -766,8 +681,8 @@ static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) */ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_OtherSpeedCfgDesc); - return USBD_CDC_OtherSpeedCfgDesc; + *length = sizeof (USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -810,12 +725,22 @@ uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, */ uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint16_t length) + uint16_t length, + uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; - hcdc->TxBuffer = pbuff; - hcdc->TxLength = length; + USBD_CDC_EP_HandleTypeDef* hEP_Tx; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Tx = &hcdc->CDC_Tx; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Tx = &hcdc->ODRIVE_Tx; + } else { + return USBD_FAIL; + } + + hEP_Tx->Buffer = pbuff; + hEP_Tx->Length = length; return USBD_OK; } @@ -828,11 +753,20 @@ uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, * @retval status */ uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, - uint8_t *pbuff) + uint8_t *pbuff, uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + USBD_CDC_EP_HandleTypeDef* hEP_Rx; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Rx = &hcdc->CDC_Rx; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Rx = &hcdc->ODRIVE_Rx; + } else { + return USBD_FAIL; + } - hcdc->RxBuffer = pbuff; + hEP_Rx->Buffer = pbuff; return USBD_OK; } @@ -844,23 +778,36 @@ uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, * @param epnum: endpoint number * @retval status */ -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; if(pdev->pClassData != NULL) { - if(hcdc->TxState == 0) + // Select Endpoint + USBD_CDC_EP_HandleTypeDef* hEP_Tx; + uint8_t in_ep; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Tx = &hcdc->CDC_Tx; + in_ep = CDC_IN_EP; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Tx = &hcdc->ODRIVE_Tx; + in_ep = ODRIVE_IN_EP; + } else { + return USBD_FAIL; + } + + if(hEP_Tx->State == 0) { /* Tx Transfer in progress */ - hcdc->TxState = 1; + hEP_Tx->State = 1; /* Transmit next packet */ USBD_LL_Transmit(pdev, - CDC_IN_EP, - hcdc->TxBuffer, - hcdc->TxLength); - + in_ep, + hEP_Tx->Buffer, + hEP_Tx->Length); + return USBD_OK; } else @@ -881,29 +828,32 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; /* Suspend or Resume USB Out process */ if(pdev->pClassData != NULL) { - if(pdev->dev_speed == USBD_SPEED_HIGH ) - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - CDC_OUT_EP, - hcdc->RxBuffer, - CDC_DATA_HS_OUT_PACKET_SIZE); - } - else - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - CDC_OUT_EP, - hcdc->RxBuffer, - CDC_DATA_FS_OUT_PACKET_SIZE); + // Select Endpoint + USBD_CDC_EP_HandleTypeDef* hEP_Rx; + uint8_t out_ep; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Rx = &hcdc->CDC_Rx; + out_ep = CDC_OUT_EP; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Rx = &hcdc->ODRIVE_Rx; + out_ep = ODRIVE_OUT_EP; + } else { + return USBD_FAIL; } + + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + out_ep, + hEP_Rx->Buffer, + pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_OUT_PACKET_SIZE : CDC_DATA_FS_OUT_PACKET_SIZE); + return USBD_OK; } else @@ -911,6 +861,184 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) return USBD_FAIL; } } + + +/* WinUSB support ------------------------------------------------------------*/ +/* +* This section tells Windows that it should automatically load the WinUSB driver +* for the device (more specifically, interface 2 because it's a composite device). +* This allows for driverless communication with the device. +*/ + +#define NUM_INTERFACES 1 + +#if NUM_INTERFACES == 2 +#define USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ (16 + 24 + 24) +#else +#define USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ (16 + 24) +#endif + + +// This associates winusb driver with the device +__ALIGN_BEGIN uint8_t USBD_WinUSBComm_Extended_Compat_ID_OS_Desc[USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ] __ALIGN_END = +{ + // +-- Offset in descriptor + // | +-- Size + // v v + USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ, 0, 0, 0, // 0 dwLength 4 DWORD The length, in bytes, of the complete extended compat ID descriptor + 0x00, 0x01, // 4 bcdVersion 2 BCD The descriptor’s version number, in binary coded decimal (BCD) format + 0x04, 0x00, // 6 wIndex 2 WORD An index that identifies the particular OS feature descriptor + NUM_INTERFACES, // 8 bCount 1 BYTE The number of custom property sections + 0, 0, 0, 0, 0, 0, 0, // 9 RESERVED 7 BYTEs Reserved + // ===================== + // 16 + + // +-- Offset from function section start + // | +-- Size + // v v + 2, // 0 bFirstInterfaceNumber 1 BYTE The interface or function number + 0, // 1 RESERVED 1 BYTE Reserved + 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // 2 compatibleID 8 BYTEs The function’s compatible ID ("WINUSB") + 0, 0, 0, 0, 0, 0, 0, 0, // 10 subCompatibleID 8 BYTEs The function’s subcompatible ID + 0, 0, 0, 0, 0, 0, // 18 RESERVED 6 BYTEs Reserved + // ================================= + // 24 +#if NUM_INTERFACES == 2 + // +-- Offset from function section start + // | +-- Size + // v v + 2, // 0 bFirstInterfaceNumber 1 BYTE The interface or function number + 0, // 1 RESERVED 1 BYTE Reserved + 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // 2 compatibleID 8 BYTEs The function’s compatible ID ("WINUSB") + 0, 0, 0, 0, 0, 0, 0, 0, // 10 subCompatibleID 8 BYTEs The function’s subcompatible ID + 0, 0, 0, 0, 0, 0, // 18 RESERVED 6 BYTEs Reserved + // ================================= + // 24 +#endif +}; + + +// Properties are added to: +// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx\sssssssss\Device Parameters +// Use USBDeview or similar to uninstall + +__ALIGN_BEGIN uint8_t USBD_WinUSBComm_Extended_Properties_OS_Desc[0xB6] __ALIGN_END = +{ + 0xB6, 0x00, 0x00, 0x00, // 0 dwLength 4 DWORD The length, in bytes, of the complete extended properties descriptor + 0x00, 0x01, // 4 bcdVersion 2 BCD The descriptor’s version number, in binary coded decimal (BCD) format + 0x05, 0x00, // 6 wIndex 2 WORD The index for extended properties OS descriptors + 0x02, 0x00, // 8 wCount 2 WORD The number of custom property sections that follow the header section + // ==================== + // 10 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + 0x84, 0x00, 0x00, 0x00, // 0 dwSize 4 DWORD The size of this custom properties section + 0x01, 0x00, 0x00, 0x00, // 4 dwPropertyDataType 4 DWORD Property data format + 0x28, 0x00, // 8 wPropertyNameLength 2 DWORD Property name length + // ======================================== + // 10 + // 10 bPropertyName PNL WCHAR[] The property name + 'D',0, 'e',0, 'v',0, 'i',0, 'c',0, 'e',0, 'I',0, 'n',0, + 't',0, 'e',0, 'r',0, 'f',0, 'a',0, 'c',0, 'e',0, 'G',0, + 'U',0, 'I',0, 'D',0, 0,0, + // ======================================== + // 40 (0x28) + + 0x4E, 0x00, 0x00, 0x00, // 10 + PNL dwPropertyDataLength 4 DWORD Length of the buffer holding the property data + // ======================================== + // 4 + // 14 + PNL bPropertyData PDL Format-dependent Property data + '{',0, 'E',0, 'A',0, '0',0, 'B',0, 'D',0, '5',0, 'C',0, + '3',0, '-',0, '5',0, '0',0, 'F',0, '3',0, '-',0, '4',0, + '8',0, '8',0, '8',0, '-',0, '8',0, '4',0, 'B',0, '4',0, + '-',0, '7',0, '4',0, 'E',0, '5',0, '0',0, 'E',0, '1',0, + '6',0, '4',0, '9',0, 'D',0, 'B',0, '}',0, 0 ,0, + // ======================================== + // 78 (0x4E) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + 0x3E, 0x00, 0x00, 0x00, // 0 dwSize 0x00000030 (62 bytes) + 0x01, 0x00, 0x00, 0x00, // 4 dwPropertyDataType 0x00000001 (Unicode string) + 0x0C, 0x00, // 8 wPropertyNameLength 0x000C (12 bytes) + // ======================================== + // 10 + 'L',0, 'a',0, 'b',0, 'e',0, 'l',0, 0,0, + // 10 bPropertyName “Label” + // ======================================== + // 12 + 0x24, 0x00, 0x00, 0x00, // 22 dwPropertyDataLength 0x00000016 (36 bytes) + // ======================================== + // 4 + 'O',0, 'D',0, 'r',0, 'i',0, 'v',0, 'e',0, 0,0 + // 26 bPropertyData “ODrive” + // ======================================== + // 14 + +}; + + + +static uint8_t USBD_WinUSBComm_GetMSExtendedCompatIDOSDescriptor (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch (req->wIndex) + { + case 0x04: + USBD_CtlSendData (pdev, USBD_WinUSBComm_Extended_Compat_ID_OS_Desc, req->wLength); + break; + default: + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + return USBD_OK; +} +static uint8_t USBD_WinUSBComm_GetMSExtendedPropertiesOSDescriptor (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + uint8_t byInterfaceIndex = (uint8_t)req->wValue; + if ( req->wIndex != 0x05 ) + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + switch ( byInterfaceIndex ) + { + case 0: +#if NUM_INTERFACES == 2 + case 1: +#endif + USBD_CtlSendData (pdev, USBD_WinUSBComm_Extended_Properties_OS_Desc, req->wLength); + break; + default: + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + return USBD_OK; +} +static uint8_t USBD_WinUSBComm_SetupVendorDevice(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_CtlError(pdev , req); + return USBD_FAIL; +} +static uint8_t USBD_WinUSBComm_SetupVendorInterface(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_CtlError(pdev , req); + // TODO: check if this is important + return USBD_FAIL; +} +static uint8_t USBD_WinUSBComm_SetupVendor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch ( req->bmRequest & USB_REQ_RECIPIENT_MASK ) + { + case USB_REQ_RECIPIENT_DEVICE: + return ( MS_VendorCode == req->bRequest ) ? USBD_WinUSBComm_GetMSExtendedCompatIDOSDescriptor(pdev, req) : USBD_WinUSBComm_SetupVendorDevice(pdev, req); + case USB_REQ_RECIPIENT_INTERFACE: + return ( MS_VendorCode == req->bRequest ) ? USBD_WinUSBComm_GetMSExtendedPropertiesOSDescriptor(pdev, req) : USBD_WinUSBComm_SetupVendorInterface(pdev, req); + case USB_REQ_RECIPIENT_ENDPOINT: + // fall through + default: + break; + } + USBD_CtlError(pdev , req); + return USBD_FAIL; +} + /** * @} */ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h index 8fbe81e4..f259b51d 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -68,7 +68,9 @@ #define USBD_IDX_PRODUCT_STR 0x02 #define USBD_IDX_SERIAL_STR 0x03 #define USBD_IDX_CONFIG_STR 0x04 -#define USBD_IDX_INTERFACE_STR 0x05 +#define USBD_IDX_INTERFACE_STR 0x05 +#define USBD_IDX_ODRIVE_INTF_STR 0x06 +#define USBD_IDX_MICROSOFT_DESC_STR 0xEE #define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_CLASS 0x20 diff --git a/Firmware/Board/v3/Src/usbd_cdc_if.c b/Firmware/Board/v3/Src/usbd_cdc_if.c index fcc712a3..b8cb6e6c 100644 --- a/Firmware/Board/v3/Src/usbd_cdc_if.c +++ b/Firmware/Board/v3/Src/usbd_cdc_if.c @@ -117,10 +117,12 @@ /* Create buffer for reception and transmission */ /* It's up to user to redefine and/or remove those define */ /** Received data over USB are stored in this buffer */ -uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; +uint8_t CDCRxBufferFS[APP_RX_DATA_SIZE]; +uint8_t ODRIVERxBufferFS[APP_RX_DATA_SIZE]; /** Data to send over USB CDC are stored in this buffer */ -uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; +uint8_t CDCTxBufferFS[APP_TX_DATA_SIZE]; +uint8_t ODRIVETxBufferFS[APP_TX_DATA_SIZE]; /* USER CODE BEGIN PRIVATE_VARIABLES */ /* USER CODE END PRIVATE_VARIABLES */ @@ -151,7 +153,7 @@ extern USBD_HandleTypeDef hUsbDeviceFS; static int8_t CDC_Init_FS(void); static int8_t CDC_DeInit_FS(void); static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); -static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); +static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len, uint8_t endpoint_pair); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ @@ -289,7 +291,7 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) +static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len, uint8_t endpoint_pair) { /* USER CODE BEGIN 6 */ usb_rx_process_packet(Buf, *Len, endpoint_pair); @@ -309,7 +311,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) * @param Len: Number of data to be sent (in bytes) * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY */ -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t endpoint_pair) { uint8_t result = USBD_OK; /* USER CODE BEGIN 7 */ diff --git a/Firmware/Board/v3/Src/usbd_conf.c b/Firmware/Board/v3/Src/usbd_conf.c index 7046dc96..2d66d4a1 100644 --- a/Firmware/Board/v3/Src/usbd_conf.c +++ b/Firmware/Board/v3/Src/usbd_conf.c @@ -66,7 +66,7 @@ /* USER CODE END PV */ - PCD_HandleTypeDef hpcd_USB_OTG_FS; +PCD_HandleTypeDef hpcd_USB_OTG_FS; void _Error_Handler(char * file, int line); /* External functions --------------------------------------------------------*/ @@ -154,6 +154,23 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) */ void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { + USBD_StatusTypeDef ret = USBD_OK; + USBD_HandleTypeDef *pdev = hpcd->pData; + USBD_SetupReqTypedef *req = &pdev->request; + USBD_ParseSetupRequest(req, (uint8_t *)hpcd->Setup); + if ( ( USB_REQ_TYPE_VENDOR == (req->bmRequest & USB_REQ_TYPE_MASK) ) && ( MS_VendorCode == req->bRequest ) ) + { + pdev->ep0_state = USBD_EP0_SETUP; + pdev->ep0_data_len = pdev->request.wLength; + + ret = pdev->pClass->Setup(pdev, req); + + if( (req->wLength == 0) && (ret == USBD_OK) ) + { + USBD_CtlSendStatus(pdev); + } + return; + } USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); } @@ -312,7 +329,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) pdev->pData = &hpcd_USB_OTG_FS; hpcd_USB_OTG_FS.Instance = USB_OTG_FS; - hpcd_USB_OTG_FS.Init.dev_endpoints = 4; + hpcd_USB_OTG_FS.Init.dev_endpoints = 6; hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL; hpcd_USB_OTG_FS.Init.dma_enable = DISABLE; hpcd_USB_OTG_FS.Init.ep0_mps = DEP0CTL_MPS_64; @@ -329,7 +346,8 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80); HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40); - HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40); // CDC IN endpoint + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40); // ODrive IN endpoint } return USBD_OK; } From 631b563bb432ab71d57c2aad12e9db2929352208 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 00:52:53 -0700 Subject: [PATCH 19/40] cube: can auto wake up --- Firmware/Board/v3/Src/can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Board/v3/Src/can.c b/Firmware/Board/v3/Src/can.c index 2171691a..fc7bf388 100644 --- a/Firmware/Board/v3/Src/can.c +++ b/Firmware/Board/v3/Src/can.c @@ -70,7 +70,7 @@ void MX_CAN1_Init(void) hcan1.Init.TimeSeg2 = CAN_BS2_5TQ; hcan1.Init.TimeTriggeredMode = DISABLE; hcan1.Init.AutoBusOff = DISABLE; - hcan1.Init.AutoWakeUp = DISABLE; + hcan1.Init.AutoWakeUp = ENABLE; hcan1.Init.AutoRetransmission = DISABLE; hcan1.Init.ReceiveFifoLocked = DISABLE; hcan1.Init.TransmitFifoPriority = DISABLE; From 26e98d5f336a9068b1f480d813a0bdba47ebe28a Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 01:25:50 -0700 Subject: [PATCH 20/40] move configAPPLICATION_ALLOCATED_HEAP to FreeRTOSconfig.h --- Firmware/Board/v3/Inc/FreeRTOSConfig.h | 1 + Firmware/Board/v3/Inc/main.h | 1 - Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h | 1 - Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h | 1 - Firmware/Board/v3/Odrive.ioc | 2 +- 5 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Firmware/Board/v3/Inc/FreeRTOSConfig.h b/Firmware/Board/v3/Inc/FreeRTOSConfig.h index 90e233b3..715b0e67 100644 --- a/Firmware/Board/v3/Inc/FreeRTOSConfig.h +++ b/Firmware/Board/v3/Inc/FreeRTOSConfig.h @@ -167,6 +167,7 @@ standard names. */ /* USER CODE BEGIN Defines */ /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ +#define configAPPLICATION_ALLOCATED_HEAP 1 // ucHeap allocated in freertos.c /* USER CODE END Defines */ #endif /* FREERTOS_CONFIG_H */ diff --git a/Firmware/Board/v3/Inc/main.h b/Firmware/Board/v3/Inc/main.h index 1e76830d..d41b19ee 100644 --- a/Firmware/Board/v3/Inc/main.h +++ b/Firmware/Board/v3/Inc/main.h @@ -72,7 +72,6 @@ #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 -#define configAPPLICATION_ALLOCATED_HEAP 1 #define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 diff --git a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h index 567fe028..65f45efd 100644 --- a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h +++ b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h @@ -6,7 +6,6 @@ #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 -#define configAPPLICATION_ALLOCATED_HEAP 1 #define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 diff --git a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h index 5695d700..64daaa4f 100644 --- a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h +++ b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h @@ -6,7 +6,6 @@ #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 -#define configAPPLICATION_ALLOCATED_HEAP 1 #define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 diff --git a/Firmware/Board/v3/Odrive.ioc b/Firmware/Board/v3/Odrive.ioc index c9bbdc7f..4d1ce2f2 100644 --- a/Firmware/Board/v3/Odrive.ioc +++ b/Firmware/Board/v3/Odrive.ioc @@ -211,7 +211,7 @@ Mcu.Pin8=PC3 Mcu.Pin9=PA0-WKUP Mcu.PinsNb=57 Mcu.ThirdPartyNb=0 -Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;configAPPLICATION_ALLOCATED_HEAP,1;TIM_1_8_RCR,2 +Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;TIM_1_8_RCR,2 Mcu.UserName=STM32F405RGTx MxCube.Version=4.27.0 MxDb.Version=DB.4.0.270 From 69bac45db2fe8596d2ba2f0d289fb2daf5159668 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 01:32:54 -0700 Subject: [PATCH 21/40] cube: support user string --- Firmware/Board/v3/Inc/usbd_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Board/v3/Inc/usbd_conf.h b/Firmware/Board/v3/Inc/usbd_conf.h index a897ba43..dbf800b3 100644 --- a/Firmware/Board/v3/Inc/usbd_conf.h +++ b/Firmware/Board/v3/Inc/usbd_conf.h @@ -98,7 +98,7 @@ /*---------- -----------*/ #define USBD_MAX_STR_DESC_SIZ 512 /*---------- -----------*/ -#define USBD_SUPPORT_USER_STRING 0 +#define USBD_SUPPORT_USER_STRING 1 /*---------- -----------*/ #define USBD_DEBUG_LEVEL 0 /*---------- -----------*/ From fcdb6b3bf10a0a3e24cca5d4a62d52d420d6c71a Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 19:49:16 -0700 Subject: [PATCH 22/40] update STM32CubeMX instructions to new rebasing style --- docs/developer-guide.md | 59 ++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 30a20543..d6243b5b 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -144,33 +144,54 @@ For working with the ODrive code you don't need an IDE, but the open-source IDE

## STM32CubeMX - This project uses the STM32CubeMX tool to generate startup code and to ease the configuration of the peripherals. You can download it from [here](http://www2.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html?icmp=stm32cubemx_pron_pr-stm32cubef2_apr2014&sc=stm32cube-pr2). All CubeMX related files are in `Firmware/Board/v3`. You will likely want the pinout for this process. It is available [here](https://docs.google.com/spreadsheets/d/1QXDCs1IRtUyG__M_9WruWOheywb-GhOwFtfPcHuN2Fg/edit#gid=404444347). -### Generate code +### Maintaining modified generated code +When generating the code, STM32CubeMX will nuke everything except some special sections that they provide. These sections are marked like `USER CODE BEGIN`...`USER CODE END`. +We used to try to make sure all edits we made to the generated code would only go in these sections, so some code structrure may reflect that. +However over time we realized this will not be tenable, so instead we use git to rebase all changes of the generated code whenever we need to regenerate it. +We use two special branches that will help us to do this, they are `STM32CubeMX-start` and `STM32CubeMX-end`. +How to use these is shown in the following example. + +**Note**: Due to how this rebasing is done, all development that changes the generated code should be done directly on `STM32CubeMX-end`, and not based on `devel`, then follow step 4 below to carry them over to your feature branch. If you did some changes to the generated code based from `devel`, you need to cherry pick just those changes over to `STM32CubeMX-end`. + +### 1. Ensuring a clean slate +* We do all changes to the STM32CubeMX config and regenerate the code on top of `STM32CubeMX-start`. + * `git checkout STM32CubeMX-start` * Run stm32cubeMX and load the `Firmware/Board/v3/Odrive.ioc` project file. -* Press `Project -> Generate code` + * If the tool asks if you wish to migrate to a new version, choose to migrate. +* Without changing any settings, press `Project -> Generate code`. * You may need to let it download some drivers and such. -* After generating/updating the code, some minor patches need to be applied. To do this, run: - `git apply Firmware/Board/v3/*.patch` -* Run `git config --local core.autocrlf input`. This will tell git that all files should be checked in with LF endings (CubeMX generates CRLF endings). -* `git status` will still claim that many files are modified but the actual diff (using `git diff`) is empty (apart from all the line ending warnings). +* STM32CubeMX may now have a newer version of some of the libraries, so there may be changes to the generated code even though we didn't change any settings. We need to check that everything is still working, and hence check in the changes: +* `git config --local core.autocrlf input` - This will tell git that all files should be checked in with LF endings (CubeMX generates CRLF endings). +* `git diff` - Ignore the pile of line ending warnings. +* If you feel qualified: you can now ispect if CubeMX introduced something stupid. If there were any changes, and they look acceptable, we should commit them: + * `git commit -am "Run STM32CubeMX v1.21"` - Replace with actual version of CubeMX -### Generating patchfiles -If you made changes to CubeMX generated files outside of the `USER CODE BEGIN`...`USER CODE END` sections and contribute them back, please add a patch file so that the next person who runs CubeMX doesn't run into problems. +### 2. Making changes to the STM32CubeMX config +* After completing the above steps, make sure the working directory is clean: + * `git status` should include "nothing to commit, working tree clean" +* Make your changes in STM32CubeMX, save the project and generate the code. (`Project -> Generate code`) +* `git diff` - Check that the introduced changes are as expected +* If everything looks ok, you can commit your changes. -CubeMX will reset everything outside these sections to the original state; we will capturing into a patch file the changes required to undo this resetting. -* Make sure your current desired state is committed. -* Make a new temporary branch: `git checkout -b cubemx_temp` -* Run the CubeMX code generation as described in the previous section, including applying previous patches. -* The diff will now _not_ be empty since CubeMX reset your changes. -* Stage this state and commit it with a message like "CubeMX reset my changes". -* Run `git revert HEAD` to undo the resetting action CubeMX's regeneration had. This is the commit which you will export, so write a meaningful commit message. -* Run `git format-patch HEAD~1` to export the commit as patch file. -* Check out your previous branch and then force-delete the temporary branch: `git branch -D cubemx_temp` -* Move the patch file to `Firmware/Board/v3/` and add it in a new commit. +### 3. Rebasing the modifications to the generated code +* `git checkout STM32CubeMX-end` +* `git rebase STM32CubeMX-start` +* Make sure the rebase finishes, fixing any conflicts that may arise + +### 4. Merge new STM32CubeMX code to your feature branch +**TODO: Nobody has done this yet, these instructions are new. Please verify that this works as intended.** +Simply merge the new state at `STM32CubeMX-end` into your feature branch. +* `git checkout your-feature` +* `git merge STM32CubeMX-end` + +### 5. Pushing back upstream +* Generate a PR like normal for your feature. +* Make sure youhave pushed to the `STM32CubeMX-start` and `STM32CubeMX-end` branches on your fork. +* Make a note in your PR to the maintainer that they need to update the STM32CubeMX branches when they merge the PR.

## Troubleshooting From e9a5c4af1fbadc2b65a5a4b5d9a030da872d35c1 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 19:49:16 -0700 Subject: [PATCH 23/40] update STM32CubeMX instructions to new rebasing style --- docs/developer-guide.md | 59 ++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/docs/developer-guide.md b/docs/developer-guide.md index 30a20543..d6243b5b 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -144,33 +144,54 @@ For working with the ODrive code you don't need an IDE, but the open-source IDE

## STM32CubeMX - This project uses the STM32CubeMX tool to generate startup code and to ease the configuration of the peripherals. You can download it from [here](http://www2.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-configurators-and-code-generators/stm32cubemx.html?icmp=stm32cubemx_pron_pr-stm32cubef2_apr2014&sc=stm32cube-pr2). All CubeMX related files are in `Firmware/Board/v3`. You will likely want the pinout for this process. It is available [here](https://docs.google.com/spreadsheets/d/1QXDCs1IRtUyG__M_9WruWOheywb-GhOwFtfPcHuN2Fg/edit#gid=404444347). -### Generate code +### Maintaining modified generated code +When generating the code, STM32CubeMX will nuke everything except some special sections that they provide. These sections are marked like `USER CODE BEGIN`...`USER CODE END`. +We used to try to make sure all edits we made to the generated code would only go in these sections, so some code structrure may reflect that. +However over time we realized this will not be tenable, so instead we use git to rebase all changes of the generated code whenever we need to regenerate it. +We use two special branches that will help us to do this, they are `STM32CubeMX-start` and `STM32CubeMX-end`. +How to use these is shown in the following example. + +**Note**: Due to how this rebasing is done, all development that changes the generated code should be done directly on `STM32CubeMX-end`, and not based on `devel`, then follow step 4 below to carry them over to your feature branch. If you did some changes to the generated code based from `devel`, you need to cherry pick just those changes over to `STM32CubeMX-end`. + +### 1. Ensuring a clean slate +* We do all changes to the STM32CubeMX config and regenerate the code on top of `STM32CubeMX-start`. + * `git checkout STM32CubeMX-start` * Run stm32cubeMX and load the `Firmware/Board/v3/Odrive.ioc` project file. -* Press `Project -> Generate code` + * If the tool asks if you wish to migrate to a new version, choose to migrate. +* Without changing any settings, press `Project -> Generate code`. * You may need to let it download some drivers and such. -* After generating/updating the code, some minor patches need to be applied. To do this, run: - `git apply Firmware/Board/v3/*.patch` -* Run `git config --local core.autocrlf input`. This will tell git that all files should be checked in with LF endings (CubeMX generates CRLF endings). -* `git status` will still claim that many files are modified but the actual diff (using `git diff`) is empty (apart from all the line ending warnings). +* STM32CubeMX may now have a newer version of some of the libraries, so there may be changes to the generated code even though we didn't change any settings. We need to check that everything is still working, and hence check in the changes: +* `git config --local core.autocrlf input` - This will tell git that all files should be checked in with LF endings (CubeMX generates CRLF endings). +* `git diff` - Ignore the pile of line ending warnings. +* If you feel qualified: you can now ispect if CubeMX introduced something stupid. If there were any changes, and they look acceptable, we should commit them: + * `git commit -am "Run STM32CubeMX v1.21"` - Replace with actual version of CubeMX -### Generating patchfiles -If you made changes to CubeMX generated files outside of the `USER CODE BEGIN`...`USER CODE END` sections and contribute them back, please add a patch file so that the next person who runs CubeMX doesn't run into problems. +### 2. Making changes to the STM32CubeMX config +* After completing the above steps, make sure the working directory is clean: + * `git status` should include "nothing to commit, working tree clean" +* Make your changes in STM32CubeMX, save the project and generate the code. (`Project -> Generate code`) +* `git diff` - Check that the introduced changes are as expected +* If everything looks ok, you can commit your changes. -CubeMX will reset everything outside these sections to the original state; we will capturing into a patch file the changes required to undo this resetting. -* Make sure your current desired state is committed. -* Make a new temporary branch: `git checkout -b cubemx_temp` -* Run the CubeMX code generation as described in the previous section, including applying previous patches. -* The diff will now _not_ be empty since CubeMX reset your changes. -* Stage this state and commit it with a message like "CubeMX reset my changes". -* Run `git revert HEAD` to undo the resetting action CubeMX's regeneration had. This is the commit which you will export, so write a meaningful commit message. -* Run `git format-patch HEAD~1` to export the commit as patch file. -* Check out your previous branch and then force-delete the temporary branch: `git branch -D cubemx_temp` -* Move the patch file to `Firmware/Board/v3/` and add it in a new commit. +### 3. Rebasing the modifications to the generated code +* `git checkout STM32CubeMX-end` +* `git rebase STM32CubeMX-start` +* Make sure the rebase finishes, fixing any conflicts that may arise + +### 4. Merge new STM32CubeMX code to your feature branch +**TODO: Nobody has done this yet, these instructions are new. Please verify that this works as intended.** +Simply merge the new state at `STM32CubeMX-end` into your feature branch. +* `git checkout your-feature` +* `git merge STM32CubeMX-end` + +### 5. Pushing back upstream +* Generate a PR like normal for your feature. +* Make sure youhave pushed to the `STM32CubeMX-start` and `STM32CubeMX-end` branches on your fork. +* Make a note in your PR to the maintainer that they need to update the STM32CubeMX branches when they merge the PR.

## Troubleshooting From 9e02d194f9fd333e56c00ec3ab4102b183859227 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 19:56:18 -0700 Subject: [PATCH 24/40] fix integer overflow in TIM expression --- Firmware/Board/v3/Odrive.ioc | 2 +- Firmware/Board/v3/Src/tim.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/Board/v3/Odrive.ioc b/Firmware/Board/v3/Odrive.ioc index c9bbdc7f..d18c5f86 100644 --- a/Firmware/Board/v3/Odrive.ioc +++ b/Firmware/Board/v3/Odrive.ioc @@ -595,7 +595,7 @@ TIM1.Period=TIM_1_8_PERIOD_CLOCKS TIM1.RepetitionCounter=TIM_1_8_RCR TIM1.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE TIM13.IPParameters=Period -TIM13.Period=(2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1) * TIM_APB1_CLOCK_HZ) / TIM_1_8_CLOCK_HZ +TIM13.Period=(2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1)) * (TIM_APB1_CLOCK_HZ / TIM_1_8_CLOCK_HZ) TIM2.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 TIM2.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 TIM2.CounterMode=TIM_COUNTERMODE_CENTERALIGNED3 diff --git a/Firmware/Board/v3/Src/tim.c b/Firmware/Board/v3/Src/tim.c index b68a5894..bd27e5f5 100644 --- a/Firmware/Board/v3/Src/tim.c +++ b/Firmware/Board/v3/Src/tim.c @@ -382,7 +382,7 @@ void MX_TIM13_Init(void) htim13.Instance = TIM13; htim13.Init.Prescaler = 0; htim13.Init.CounterMode = TIM_COUNTERMODE_UP; - htim13.Init.Period = (2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1) * TIM_APB1_CLOCK_HZ) / TIM_1_8_CLOCK_HZ; + htim13.Init.Period = (2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1)) * (TIM_APB1_CLOCK_HZ / TIM_1_8_CLOCK_HZ); htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim13) != HAL_OK) { From 9dc33ad54553492319e3eba8025e3cf0086d14db Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:23:46 -0700 Subject: [PATCH 25/40] bake patch: display correct ODrive version in USB descriptor --- ...ect-ODrive-version-in-USB-descriptor.patch | 41 ------------------- Firmware/Board/v3/Src/usbd_desc.c | 8 ++-- 2 files changed, 5 insertions(+), 44 deletions(-) delete mode 100644 Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch diff --git a/Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch b/Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch deleted file mode 100644 index 0b031242..00000000 --- a/Firmware/Board/v3/0001-display-correct-ODrive-version-in-USB-descriptor.patch +++ /dev/null @@ -1,41 +0,0 @@ -From b7ea3f500fbfc187a0a7112282ae6b1eee4555d0 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Tue, 13 Mar 2018 20:05:07 -0700 -Subject: [PATCH] display correct ODrive version in USB descriptor - ---- - Firmware/Board/v3/Src/usbd_desc.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c -index 94dc49b..37b4302 100644 ---- a/Firmware/Board/v3/Src/usbd_desc.c -+++ b/Firmware/Board/v3/Src/usbd_desc.c -@@ -96,7 +96,9 @@ - #define USBD_LANGID_STRING 1033 - #define USBD_MANUFACTURER_STRING "ODrive Robotics" - #define USBD_PID_FS 0x0D32 --#define USBD_PRODUCT_STRING_FS "ODrive v3.3" -+#define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) -+#define USBD_PRODUCT_STR(s) #s -+#define USBD_PRODUCT_STRING_FS ODrive version HW_VERSION_MAJOR.HW_VERSION_MINOR - #define USBD_SERIALNUMBER_STRING_FS "000000000001" - #define USBD_CONFIGURATION_STRING_FS "CDC Config" - #define USBD_INTERFACE_STRING_FS "CDC Interface" -@@ -299,11 +301,11 @@ uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length - { - if(speed == 0) - { -- USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); -+ USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); - } - else - { -- USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); -+ USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); - } - return USBD_StrDesc; - } --- -2.16.2 - diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c index 2e139e50..973b0ae2 100644 --- a/Firmware/Board/v3/Src/usbd_desc.c +++ b/Firmware/Board/v3/Src/usbd_desc.c @@ -95,7 +95,9 @@ #define USBD_LANGID_STRING 1033 #define USBD_MANUFACTURER_STRING "ODrive Robotics" #define USBD_PID_FS 0x0D32 -#define USBD_PRODUCT_STRING_FS "ODrive v3.3" +#define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) +#define USBD_PRODUCT_STR(s) #s +#define USBD_PRODUCT_STRING_FS ODrive version HW_VERSION_MAJOR.HW_VERSION_MINOR #define USBD_SERIALNUMBER_STRING_FS "000000000001" #define USBD_CONFIGURATION_STRING_FS "CDC Config" #define USBD_INTERFACE_STRING_FS "CDC Interface" @@ -342,11 +344,11 @@ uint8_t * USBD_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length { if(speed == 0) { - USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); } else { - USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_FS, USBD_StrDesc, length); + USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(USBD_PRODUCT_STRING_FS), USBD_StrDesc, length); } return USBD_StrDesc; } From ba77fc79dccfa06db545fd1da88a083bb9864d6b Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:27:56 -0700 Subject: [PATCH 26/40] bake patch: expose correct serial number on USB --- ...-expose-correct-serial-number-on-USB.patch | 32 ------------------- Firmware/Board/v3/Src/usbd_desc.c | 9 +----- 2 files changed, 1 insertion(+), 40 deletions(-) delete mode 100644 Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch diff --git a/Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch b/Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch deleted file mode 100644 index b9fef648..00000000 --- a/Firmware/Board/v3/0001-expose-correct-serial-number-on-USB.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0867a92f742b312a0ebaafe94cade6f57be22170 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 12 Mar 2018 23:49:32 -0700 -Subject: [PATCH] expose correct serial number on USB - ---- - Firmware/Board/v3/Src/usbd_desc.c | 9 +++++++++------- - 1 file changed, 1 insertions(+), 8 deletions(-) - -diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c -index b9c7bd0..94dc49b 100644 ---- a/Firmware/Board/v3/Src/usbd_desc.c -+++ b/Firmware/Board/v3/Src/usbd_desc.c -@@ -327,14 +327,7 @@ uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *l - */ - uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) - { -- if(speed == USBD_SPEED_HIGH) -- { -- USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); -- } -- else -- { -- USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); -- } -+ USBD_GetString ((uint8_t *)serial_number_str, USBD_StrDesc, length); - return USBD_StrDesc; - } - --- -2.16.2 - diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c index 973b0ae2..b0906144 100644 --- a/Firmware/Board/v3/Src/usbd_desc.c +++ b/Firmware/Board/v3/Src/usbd_desc.c @@ -373,14 +373,7 @@ uint8_t * USBD_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *l */ uint8_t * USBD_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) { - if(speed == USBD_SPEED_HIGH) - { - USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); - } - else - { - USBD_GetString((uint8_t *)USBD_SERIALNUMBER_STRING_FS, USBD_StrDesc, length); - } + USBD_GetString ((uint8_t *)serial_number_str, USBD_StrDesc, length); return USBD_StrDesc; } From ce872275be9dea74eb8fe3f7d18f0c0de03b9d77 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:29:43 -0700 Subject: [PATCH 27/40] bake patch: fix return type of osSemaphoreWait --- ...1-fix-return-type-of-osSemaphoreWait.patch | 46 ------------------- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c | 4 +- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 4 +- 3 files changed, 4 insertions(+), 50 deletions(-) delete mode 100644 Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch diff --git a/Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch b/Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch deleted file mode 100644 index 53760fa1..00000000 --- a/Firmware/Board/v3/0001-fix-return-type-of-osSemaphoreWait.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 49353ccb7023c02c2bc6e3b6f14fac02a13fe599 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Feb 2018 14:55:17 -0800 -Subject: [PATCH] fix return type of osSemaphoreWait - ---- - .../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c | 6 +++--- - .../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 6 +++--- - 2 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c -index d0e0fd7..e764cbc 100644 ---- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c -+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c -@@ -816,10 +816,10 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t - * @brief Wait until a Semaphore token becomes available - * @param semaphore_id semaphore object referenced with \ref osSemaphore. - * @param millisec timeout value or 0 in case of no time-out. --* @retval number of available tokens, or -1 in case of incorrect parameters. -+* @retval status code that indicates the execution status of the function. - * @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. - */ --int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) -+osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) - { - TickType_t ticks; - portBASE_TYPE taskWoken = pdFALSE; -diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -index 15e25b9..5223f8e 100644 ---- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -@@ -719,9 +719,9 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t - /// Wait until a Semaphore token becomes available. - /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. - /// \param[in] millisec timeout value or 0 in case of no time-out. --/// \return number of available tokens, or -1 in case of incorrect parameters. -+/// \return status code that indicates the execution status of the function. - /// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. --int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); -+osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); - - /// Release a Semaphore token. - /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. --- -2.16.1 - diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c index d0e0fd76..7828403b 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c @@ -816,10 +816,10 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t * @brief Wait until a Semaphore token becomes available * @param semaphore_id semaphore object referenced with \ref osSemaphore. * @param millisec timeout value or 0 in case of no time-out. -* @retval number of available tokens, or -1 in case of incorrect parameters. +* @retval status code that indicates the execution status of the function. * @note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. */ -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) +osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec) { TickType_t ticks; portBASE_TYPE taskWoken = pdFALSE; diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h index 15e25b96..09cdf273 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h @@ -719,9 +719,9 @@ osSemaphoreId osSemaphoreCreate (const osSemaphoreDef_t *semaphore_def, int32_t /// Wait until a Semaphore token becomes available. /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. /// \param[in] millisec timeout value or 0 in case of no time-out. -/// \return number of available tokens, or -1 in case of incorrect parameters. +/// \return status code that indicates the execution status of the function. /// \note MUST REMAIN UNCHANGED: \b osSemaphoreWait shall be consistent in every CMSIS-RTOS. -int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); +osStatus osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec); /// Release a Semaphore token. /// \param[in] semaphore_id semaphore object referenced with \ref osSemaphoreCreate. From 019a71eb14238d5387117abb64d39ea5d4b90eaa Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:31:41 -0700 Subject: [PATCH 28/40] bake patch: release sem_usb_tx in usb_cdc.c --- ...001-release-sem_usb_tx-in-usbd_cdc.c.patch | 35 ------------------- .../Class/CDC/Src/usbd_cdc.c | 5 +-- 2 files changed, 3 insertions(+), 37 deletions(-) delete mode 100644 Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch diff --git a/Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch b/Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch deleted file mode 100644 index b69370f5..00000000 --- a/Firmware/Board/v3/0001-release-sem_usb_tx-in-usbd_cdc.c.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 965f7f2c80e30d7a66dcac7abaa9bdc371d9ea51 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Feb 2018 14:53:52 -0800 -Subject: [PATCH] release sem_usb_tx in usbd_cdc.c - ---- - .../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3.3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c -index b2ca5f1..6ae33e8 100644 ---- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c -+++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c -@@ -62,7 +62,8 @@ - #include "usbd_cdc.h" - #include "usbd_desc.h" - #include "usbd_ctlreq.h" -- -+#include -+#include - - /** @addtogroup STM32_USB_DEVICE_LIBRARY - * @{ -@@ -669,7 +670,7 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) - { - - hcdc->TxState = 0; -- -+ osSemaphoreRelease(sem_usb_tx); - return USBD_OK; - } - else --- -2.16.1 - diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index b2ca5f16..24465641 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -62,7 +62,8 @@ #include "usbd_cdc.h" #include "usbd_desc.h" #include "usbd_ctlreq.h" - +#include +#include /** @addtogroup STM32_USB_DEVICE_LIBRARY * @{ @@ -669,7 +670,7 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) { hcdc->TxState = 0; - + osSemaphoreRelease(sem_usb_tx); return USBD_OK; } else From 1ccf17b36af91674b612aeeb9a76bb4c659b4b45 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:43:04 -0700 Subject: [PATCH 29/40] bake patch: FreeRTOS constness fixes --- .../v3/0002-FreeRTOS-constness-fixes.patch | 64 ------------------- .../FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 8 +-- Firmware/Board/v3/Src/freertos.c | 4 +- 3 files changed, 6 insertions(+), 70 deletions(-) delete mode 100644 Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch diff --git a/Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch b/Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch deleted file mode 100644 index afe0326e..00000000 --- a/Firmware/Board/v3/0002-FreeRTOS-constness-fixes.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 510ead2b159e1d8116e5241066c54a7bf8b7bfbe Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Mar 2018 15:29:44 -0700 -Subject: [PATCH] FreeRTOS constness fixes - - - make thread names const char * - - make thread argument non-const void* ---- - .../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h | 6 +++--- - Firmware/Board/v3/Src/freertos.c | 4 ++-- - 2 files changed, 5 insertions(+), 5 deletions(-) - -diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -index 09cdf27..754be24 100644 ---- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -+++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h -@@ -270,11 +270,11 @@ typedef enum { - - /// Entry point of a thread. - /// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. --typedef void (*os_pthread) (void const *argument); -+typedef void (*os_pthread) (void *argument); - - /// Entry point of a timer call back function. - /// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. --typedef void (*os_ptimer) (void const *argument); -+typedef void (*os_ptimer) (void *argument); - - // >>> the following data type definitions may shall adapted towards a specific RTOS - -@@ -323,7 +323,7 @@ typedef StaticQueue_t osStaticMessageQDef_t; - /// Thread Definition structure contains startup information of a thread. - /// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. - typedef struct os_thread_def { -- char *name; ///< Thread name -+ const char *name; ///< Thread name - os_pthread pthread; ///< start address of thread function - osPriority tpriority; ///< initial thread priority - uint32_t instances; ///< maximum number of instances of that thread function -diff --git a/Firmware/Board/v3/Src/freertos.c b/Firmware/Board/v3/Src/freertos.c -index 6eaea82..b247994 100644 ---- a/Firmware/Board/v3/Src/freertos.c -+++ b/Firmware/Board/v3/Src/freertos.c -@@ -75,7 +75,7 @@ uint8_t ucHeap[configTOTAL_HEAP_SIZE]; - /* USER CODE END Variables */ - - /* Function prototypes -------------------------------------------------------*/ --void StartDefaultTask(void const * argument); -+void StartDefaultTask(void * argument); - - extern void MX_USB_DEVICE_Init(void); - void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ -@@ -147,7 +147,7 @@ void MX_FREERTOS_Init(void) { - } - - /* StartDefaultTask function */ --void StartDefaultTask(void const * argument) -+void StartDefaultTask(void * argument) - { - /* init code for USB_DEVICE */ - MX_USB_DEVICE_Init(); --- -2.16.2 - diff --git a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h index 09cdf273..89a105dc 100644 --- a/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h +++ b/Firmware/Board/v3/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h @@ -26,7 +26,7 @@ * *---------------------------------------------------------------------------- * - * Portions Copyright 2016 STMicroelectronics International N.V. All rights reserved. + * Portions Copyright � 2016 STMicroelectronics International N.V. All rights reserved. * Portions Copyright (c) 2013 ARM LIMITED * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -270,11 +270,11 @@ typedef enum { /// Entry point of a thread. /// \note MUST REMAIN UNCHANGED: \b os_pthread shall be consistent in every CMSIS-RTOS. -typedef void (*os_pthread) (void const *argument); +typedef void (*os_pthread) (void *argument); /// Entry point of a timer call back function. /// \note MUST REMAIN UNCHANGED: \b os_ptimer shall be consistent in every CMSIS-RTOS. -typedef void (*os_ptimer) (void const *argument); +typedef void (*os_ptimer) (void *argument); // >>> the following data type definitions may shall adapted towards a specific RTOS @@ -323,7 +323,7 @@ typedef StaticQueue_t osStaticMessageQDef_t; /// Thread Definition structure contains startup information of a thread. /// \note CAN BE CHANGED: \b os_thread_def is implementation specific in every CMSIS-RTOS. typedef struct os_thread_def { - char *name; ///< Thread name + const char *name; ///< Thread name os_pthread pthread; ///< start address of thread function osPriority tpriority; ///< initial thread priority uint32_t instances; ///< maximum number of instances of that thread function diff --git a/Firmware/Board/v3/Src/freertos.c b/Firmware/Board/v3/Src/freertos.c index 0865d714..11154587 100644 --- a/Firmware/Board/v3/Src/freertos.c +++ b/Firmware/Board/v3/Src/freertos.c @@ -98,7 +98,7 @@ osThreadId defaultTaskHandle; /* USER CODE END FunctionPrototypes */ -void StartDefaultTask(void const * argument); +void StartDefaultTask(void * argument); extern void MX_USB_DEVICE_Init(void); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ @@ -214,7 +214,7 @@ void MX_FREERTOS_Init(void) { * @retval None */ /* USER CODE END Header_StartDefaultTask */ -void StartDefaultTask(void const * argument) +void StartDefaultTask(void * argument) { /* init code for USB_DEVICE */ MX_USB_DEVICE_Init(); From fe068005875d388a2a779770974e74904174e1fc Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:45:30 -0700 Subject: [PATCH 30/40] bake patch: disable IRQ for DMA2_Stream0 --- .../0003-disable-IRQ-for-DMA2_Stream0.patch | 33 ------------------- Firmware/Board/v3/Src/dma.c | 6 ++-- 2 files changed, 4 insertions(+), 35 deletions(-) delete mode 100644 Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch diff --git a/Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch b/Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch deleted file mode 100644 index 282317d1..00000000 --- a/Firmware/Board/v3/0003-disable-IRQ-for-DMA2_Stream0.patch +++ /dev/null @@ -1,33 +0,0 @@ -From ab5ca860b3729d76a9c43c485776147ab69d2342 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Mon, 26 Mar 2018 19:02:45 -0700 -Subject: [PATCH] disable IRQ for DMA2_Stream0 - -This DMA stream is used to read values from ADC1 -while ADC1 cycles through it's sequence of input -channels. No interrupts are required to make -this work. ---- - Firmware/Board/v3/Src/dma.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/Firmware/Board/v3/Src/dma.c b/Firmware/Board/v3/Src/dma.c -index 55d5e03..3de873a 100644 ---- a/Firmware/Board/v3/Src/dma.c -+++ b/Firmware/Board/v3/Src/dma.c -@@ -78,8 +78,10 @@ void MX_DMA_Init(void) - HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); - /* DMA2_Stream0_IRQn interrupt configuration */ -- HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); -- HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); -+ // Dear STM, no we _don't_ want to fire an interrupt for this DMA -+ // (it's not possible to deselect this in CubeMX) -+ //HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); -+ //HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); - - } - --- -2.16.2 - diff --git a/Firmware/Board/v3/Src/dma.c b/Firmware/Board/v3/Src/dma.c index 55d5e034..3de873ad 100644 --- a/Firmware/Board/v3/Src/dma.c +++ b/Firmware/Board/v3/Src/dma.c @@ -78,8 +78,10 @@ void MX_DMA_Init(void) HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); /* DMA2_Stream0_IRQn interrupt configuration */ - HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); + // Dear STM, no we _don't_ want to fire an interrupt for this DMA + // (it's not possible to deselect this in CubeMX) + //HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 5, 0); + //HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn); } From 8db7eff380d4b8b3091952d802de79bc3ffa6296 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Tue, 23 Oct 2018 23:57:44 -0700 Subject: [PATCH 31/40] bake patch: Add I2C files and settings --- .../v3/0002-Add-I2C-files-and-settings.patch | 6860 ----------------- .../Inc/stm32f4xx_hal_i2c.h | 649 ++ .../Inc/stm32f4xx_hal_i2c_ex.h | 137 + .../Src/stm32f4xx_hal_i2c.c | 5494 +++++++++++++ .../Src/stm32f4xx_hal_i2c_ex.c | 204 + Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h | 2 +- Firmware/Board/v3/Src/main.c | 2 +- 7 files changed, 6486 insertions(+), 6862 deletions(-) delete mode 100644 Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c diff --git a/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch b/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch deleted file mode 100644 index aae18bf4..00000000 --- a/Firmware/Board/v3/0002-Add-I2C-files-and-settings.patch +++ /dev/null @@ -1,6860 +0,0 @@ -From b45bdbbbfe3d084d069da99b98116991923f5eb6 Mon Sep 17 00:00:00 2001 -From: Samuel Sadok -Date: Thu, 26 Apr 2018 13:20:38 -0700 -Subject: [PATCH] Add I2C files and settings - ---- - .../Inc/stm32f4xx_hal_i2c.h | 649 ++ - .../Inc/stm32f4xx_hal_i2c_ex.h | 137 + - .../Src/stm32f4xx_hal_i2c.c | 5494 +++++++++++++++++ - .../Src/stm32f4xx_hal_i2c_ex.c | 204 + - Firmware/Board/v3/Inc/i2c.h | 91 + - Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h | 2 +- - Firmware/Board/v3/Odrive.ioc | 5 + - Firmware/Board/v3/Src/i2c.c | 198 + - Firmware/Board/v3/Src/main.c | 1 - - 11 files changed, 6811 insertions(+), 2 deletions(-) - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c - create mode 100644 Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c - create mode 100644 Firmware/Board/v3/Inc/i2c.h - create mode 100644 Firmware/Board/v3/Src/i2c.c - -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h -new file mode 100644 -index 0000000..5452a50 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h -@@ -0,0 +1,649 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c.h -+ * @author MCD Application Team -+ * @brief Header file of I2C HAL module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __STM32F4xx_HAL_I2C_H -+#define __STM32F4xx_HAL_I2C_H -+ -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal_def.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @addtogroup I2C -+ * @{ -+ */ -+ -+/* Exported types ------------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Types I2C Exported Types -+ * @{ -+ */ -+ -+/** -+ * @brief I2C Configuration Structure definition -+ */ -+typedef struct -+{ -+ uint32_t ClockSpeed; /*!< Specifies the clock frequency. -+ This parameter must be set to a value lower than 400kHz */ -+ -+ uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle. -+ This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ -+ -+ uint32_t OwnAddress1; /*!< Specifies the first device own address. -+ This parameter can be a 7-bit or 10-bit address. */ -+ -+ uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. -+ This parameter can be a value of @ref I2C_addressing_mode */ -+ -+ uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. -+ This parameter can be a value of @ref I2C_dual_addressing_mode */ -+ -+ uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected -+ This parameter can be a 7-bit address. */ -+ -+ uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. -+ This parameter can be a value of @ref I2C_general_call_addressing_mode */ -+ -+ uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. -+ This parameter can be a value of @ref I2C_nostretch_mode */ -+ -+}I2C_InitTypeDef; -+ -+/** -+ * @brief HAL State structure definition -+ * @note HAL I2C State value coding follow below described bitmap : -+ * b7-b6 Error information -+ * 00 : No Error -+ * 01 : Abort (Abort user request on going) -+ * 10 : Timeout -+ * 11 : Error -+ * b5 IP initilisation status -+ * 0 : Reset (IP not initialized) -+ * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called) -+ * b4 (not used) -+ * x : Should be set to 0 -+ * b3 -+ * 0 : Ready or Busy (No Listen mode ongoing) -+ * 1 : Listen (IP in Address Listen Mode) -+ * b2 Intrinsic process state -+ * 0 : Ready -+ * 1 : Busy (IP busy with some configuration or internal operations) -+ * b1 Rx state -+ * 0 : Ready (no Rx operation ongoing) -+ * 1 : Busy (Rx operation ongoing) -+ * b0 Tx state -+ * 0 : Ready (no Tx operation ongoing) -+ * 1 : Busy (Tx operation ongoing) -+ */ -+typedef enum -+{ -+ HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ -+ HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ -+ HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ -+ HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ -+ HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ -+ HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ -+ HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission -+ process is ongoing */ -+ HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception -+ process is ongoing */ -+ HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ -+ HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ -+ HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ -+ -+}HAL_I2C_StateTypeDef; -+ -+/** -+ * @brief HAL Mode structure definition -+ * @note HAL I2C Mode value coding follow below described bitmap : -+ * b7 (not used) -+ * x : Should be set to 0 -+ * b6 -+ * 0 : None -+ * 1 : Memory (HAL I2C communication is in Memory Mode) -+ * b5 -+ * 0 : None -+ * 1 : Slave (HAL I2C communication is in Slave Mode) -+ * b4 -+ * 0 : None -+ * 1 : Master (HAL I2C communication is in Master Mode) -+ * b3-b2-b1-b0 (not used) -+ * xxxx : Should be set to 0000 -+ */ -+typedef enum -+{ -+ HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ -+ HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ -+ HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ -+ HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ -+ -+}HAL_I2C_ModeTypeDef; -+ -+/** -+ * @brief I2C handle Structure definition -+ */ -+typedef struct -+{ -+ I2C_TypeDef *Instance; /*!< I2C registers base address */ -+ -+ I2C_InitTypeDef Init; /*!< I2C communication parameters */ -+ -+ uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ -+ -+ uint16_t XferSize; /*!< I2C transfer size */ -+ -+ __IO uint16_t XferCount; /*!< I2C transfer counter */ -+ -+ __IO uint32_t XferOptions; /*!< I2C transfer options */ -+ -+ __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode -+ context for internal usage */ -+ -+ DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ -+ -+ DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ -+ -+ HAL_LockTypeDef Lock; /*!< I2C locking object */ -+ -+ __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ -+ -+ __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ -+ -+ __IO uint32_t ErrorCode; /*!< I2C Error code */ -+ -+ __IO uint32_t Devaddress; /*!< I2C Target device address */ -+ -+ __IO uint32_t Memaddress; /*!< I2C Target memory address */ -+ -+ __IO uint32_t MemaddSize; /*!< I2C Target memory address size */ -+ -+ __IO uint32_t EventCount; /*!< I2C Event counter */ -+ -+}I2C_HandleTypeDef; -+ -+/** -+ * @} -+ */ -+ -+/* Exported constants --------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Constants I2C Exported Constants -+ * @{ -+ */ -+ -+/** @defgroup I2C_Error_Code I2C Error Code -+ * @brief I2C Error Code -+ * @{ -+ */ -+#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */ -+#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */ -+#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */ -+#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */ -+#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */ -+#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */ -+#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */ -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode -+ * @{ -+ */ -+#define I2C_DUTYCYCLE_2 0x00000000U -+#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_addressing_mode I2C addressing mode -+ * @{ -+ */ -+#define I2C_ADDRESSINGMODE_7BIT 0x00004000U -+#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U) -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode -+ * @{ -+ */ -+#define I2C_DUALADDRESS_DISABLE 0x00000000U -+#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode -+ * @{ -+ */ -+#define I2C_GENERALCALL_DISABLE 0x00000000U -+#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_nostretch_mode I2C nostretch mode -+ * @{ -+ */ -+#define I2C_NOSTRETCH_DISABLE 0x00000000U -+#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size -+ * @{ -+ */ -+#define I2C_MEMADD_SIZE_8BIT 0x00000001U -+#define I2C_MEMADD_SIZE_16BIT 0x00000010U -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_XferDirection_definition I2C XferDirection definition -+ * @{ -+ */ -+#define I2C_DIRECTION_RECEIVE 0x00000000U -+#define I2C_DIRECTION_TRANSMIT 0x00000001U -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_XferOptions_definition I2C XferOptions definition -+ * @{ -+ */ -+#define I2C_FIRST_FRAME 0x00000001U -+#define I2C_NEXT_FRAME 0x00000002U -+#define I2C_FIRST_AND_LAST_FRAME 0x00000004U -+#define I2C_LAST_FRAME 0x00000008U -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition -+ * @{ -+ */ -+#define I2C_IT_BUF I2C_CR2_ITBUFEN -+#define I2C_IT_EVT I2C_CR2_ITEVTEN -+#define I2C_IT_ERR I2C_CR2_ITERREN -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Flag_definition I2C Flag definition -+ * @{ -+ */ -+#define I2C_FLAG_SMBALERT 0x00018000U -+#define I2C_FLAG_TIMEOUT 0x00014000U -+#define I2C_FLAG_PECERR 0x00011000U -+#define I2C_FLAG_OVR 0x00010800U -+#define I2C_FLAG_AF 0x00010400U -+#define I2C_FLAG_ARLO 0x00010200U -+#define I2C_FLAG_BERR 0x00010100U -+#define I2C_FLAG_TXE 0x00010080U -+#define I2C_FLAG_RXNE 0x00010040U -+#define I2C_FLAG_STOPF 0x00010010U -+#define I2C_FLAG_ADD10 0x00010008U -+#define I2C_FLAG_BTF 0x00010004U -+#define I2C_FLAG_ADDR 0x00010002U -+#define I2C_FLAG_SB 0x00010001U -+#define I2C_FLAG_DUALF 0x00100080U -+#define I2C_FLAG_SMBHOST 0x00100040U -+#define I2C_FLAG_SMBDEFAULT 0x00100020U -+#define I2C_FLAG_GENCALL 0x00100010U -+#define I2C_FLAG_TRA 0x00100004U -+#define I2C_FLAG_BUSY 0x00100002U -+#define I2C_FLAG_MSL 0x00100001U -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Exported macro ------------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Macros I2C Exported Macros -+ * @{ -+ */ -+ -+/** @brief Reset I2C handle state -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) -+ -+/** @brief Enable or disable the specified I2C interrupts. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __INTERRUPT__ specifies the interrupt source to enable or disable. -+ * This parameter can be one of the following values: -+ * @arg I2C_IT_BUF: Buffer interrupt enable -+ * @arg I2C_IT_EVT: Event interrupt enable -+ * @arg I2C_IT_ERR: Error interrupt enable -+ * @retval None -+ */ -+#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) -+#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) -+ -+/** @brief Checks if the specified I2C interrupt source is enabled or disabled. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __INTERRUPT__ specifies the I2C interrupt source to check. -+ * This parameter can be one of the following values: -+ * @arg I2C_IT_BUF: Buffer interrupt enable -+ * @arg I2C_IT_EVT: Event interrupt enable -+ * @arg I2C_IT_ERR: Error interrupt enable -+ * @retval The new state of __INTERRUPT__ (TRUE or FALSE). -+ */ -+#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) -+ -+/** @brief Checks whether the specified I2C flag is set or not. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __FLAG__ specifies the flag to check. -+ * This parameter can be one of the following values: -+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag -+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag -+ * @arg I2C_FLAG_PECERR: PEC error in reception flag -+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag -+ * @arg I2C_FLAG_AF: Acknowledge failure flag -+ * @arg I2C_FLAG_ARLO: Arbitration lost flag -+ * @arg I2C_FLAG_BERR: Bus error flag -+ * @arg I2C_FLAG_TXE: Data register empty flag -+ * @arg I2C_FLAG_RXNE: Data register not empty flag -+ * @arg I2C_FLAG_STOPF: Stop detection flag -+ * @arg I2C_FLAG_ADD10: 10-bit header sent flag -+ * @arg I2C_FLAG_BTF: Byte transfer finished flag -+ * @arg I2C_FLAG_ADDR: Address sent flag -+ * Address matched flag -+ * @arg I2C_FLAG_SB: Start bit flag -+ * @arg I2C_FLAG_DUALF: Dual flag -+ * @arg I2C_FLAG_SMBHOST: SMBus host header -+ * @arg I2C_FLAG_SMBDEFAULT: SMBus default header -+ * @arg I2C_FLAG_GENCALL: General call header flag -+ * @arg I2C_FLAG_TRA: Transmitter/Receiver flag -+ * @arg I2C_FLAG_BUSY: Bus busy flag -+ * @arg I2C_FLAG_MSL: Master/Slave flag -+ * @retval The new state of __FLAG__ (TRUE or FALSE). -+ */ -+#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \ -+ ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) -+ -+/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @param __FLAG__ specifies the flag to clear. -+ * This parameter can be any combination of the following values: -+ * @arg I2C_FLAG_SMBALERT: SMBus Alert flag -+ * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag -+ * @arg I2C_FLAG_PECERR: PEC error in reception flag -+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) -+ * @arg I2C_FLAG_AF: Acknowledge failure flag -+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) -+ * @arg I2C_FLAG_BERR: Bus error flag -+ * @retval None -+ */ -+#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK)) -+ -+/** @brief Clears the I2C ADDR pending flag. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \ -+ do{ \ -+ __IO uint32_t tmpreg = 0x00U; \ -+ tmpreg = (__HANDLE__)->Instance->SR1; \ -+ tmpreg = (__HANDLE__)->Instance->SR2; \ -+ UNUSED(tmpreg); \ -+ } while(0) -+ -+/** @brief Clears the I2C STOPF pending flag. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \ -+ do{ \ -+ __IO uint32_t tmpreg = 0x00U; \ -+ tmpreg = (__HANDLE__)->Instance->SR1; \ -+ (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \ -+ UNUSED(tmpreg); \ -+ } while(0) -+ -+/** @brief Enable the I2C peripheral. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) -+ -+/** @brief Disable the I2C peripheral. -+ * @param __HANDLE__ specifies the I2C Handle. -+ * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. -+ * @retval None -+ */ -+#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE) -+ -+/** -+ * @} -+ */ -+ -+/* Include I2C HAL Extension module */ -+#include "stm32f4xx_hal_i2c_ex.h" -+ -+/* Exported functions --------------------------------------------------------*/ -+/** @addtogroup I2C_Exported_Functions -+ * @{ -+ */ -+ -+/** @addtogroup I2C_Exported_Functions_Group1 -+ * @{ -+ */ -+/* Initialization/de-initialization functions **********************************/ -+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); -+HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); -+/** -+ * @} -+ */ -+ -+/** @addtogroup I2C_Exported_Functions_Group2 -+ * @{ -+ */ -+/* I/O operation functions *****************************************************/ -+/******* Blocking mode: Polling */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); -+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); -+ -+/******* Non-Blocking mode: Interrupt */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+ -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); -+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); -+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); -+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); -+ -+/******* Non-Blocking mode: DMA */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); -+ -+/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ -+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); -+void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); -+void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); -+/** -+ * @} -+ */ -+ -+/** @addtogroup I2C_Exported_Functions_Group3 -+ * @{ -+ */ -+/* Peripheral State, Mode and Errors functions *********************************/ -+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c); -+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c); -+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+/* Private types -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private constants ---------------------------------------------------------*/ -+/** @defgroup I2C_Private_Constants I2C Private Constants -+ * @{ -+ */ -+#define I2C_FLAG_MASK 0x0000FFFFU -+/** -+ * @} -+ */ -+ -+/* Private macros ------------------------------------------------------------*/ -+/** @defgroup I2C_Private_Macros I2C Private Macros -+ * @{ -+ */ -+ -+#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U) -+#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U)) -+#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) -+#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__PCLK__) / ((__SPEED__) * 25U)) | I2C_DUTYCYCLE_16_9)) -+#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \ -+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \ -+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS)) -+ -+#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0))) -+#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0)) -+ -+#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) -+#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0))) -+#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1)))) -+ -+#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8))) -+#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) -+ -+/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters -+ * @{ -+ */ -+#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \ -+ ((CYCLE) == I2C_DUTYCYCLE_16_9)) -+#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \ -+ ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT)) -+#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ -+ ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) -+#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ -+ ((CALL) == I2C_GENERALCALL_ENABLE)) -+#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ -+ ((STRETCH) == I2C_NOSTRETCH_ENABLE)) -+#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ -+ ((SIZE) == I2C_MEMADD_SIZE_16BIT)) -+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0U) && ((SPEED) <= 400000U)) -+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & 0xFFFFFC00U) == 0U) -+#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & 0xFFFFFF01U) == 0U) -+#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ -+ ((REQUEST) == I2C_NEXT_FRAME) || \ -+ ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ -+ ((REQUEST) == I2C_LAST_FRAME)) -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Private functions ---------------------------------------------------------*/ -+/** @defgroup I2C_Private_Functions I2C Private Functions -+ * @{ -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+ -+#endif /* __STM32F4xx_HAL_I2C_H */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h -new file mode 100644 -index 0000000..ff47d5c ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h -@@ -0,0 +1,137 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c_ex.h -+ * @author MCD Application Team -+ * @brief Header file of I2C HAL Extension module. -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __STM32F4xx_HAL_I2C_EX_H -+#define __STM32F4xx_HAL_I2C_EX_H -+ -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ -+ defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ -+ defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal_def.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @addtogroup I2CEx -+ * @{ -+ */ -+ -+/* Exported types ------------------------------------------------------------*/ -+/* Exported constants --------------------------------------------------------*/ -+/** @defgroup I2CEx_Exported_Constants I2C Exported Constants -+ * @{ -+ */ -+ -+/** @defgroup I2CEx_Analog_Filter I2C Analog Filter -+ * @{ -+ */ -+#define I2C_ANALOGFILTER_ENABLE 0x00000000U -+#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Exported macro ------------------------------------------------------------*/ -+/* Exported functions --------------------------------------------------------*/ -+/** @addtogroup I2CEx_Exported_Functions -+ * @{ -+ */ -+ -+/** @addtogroup I2CEx_Exported_Functions_Group1 -+ * @{ -+ */ -+/* Peripheral Control functions ************************************************/ -+HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); -+HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+/* Private types -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private constants ---------------------------------------------------------*/ -+/** @defgroup I2CEx_Private_Constants I2C Private Constants -+ * @{ -+ */ -+ -+/** -+ * @} -+ */ -+ -+/* Private macros ------------------------------------------------------------*/ -+/** @defgroup I2CEx_Private_Macros I2C Private Macros -+ * @{ -+ */ -+#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ -+ ((FILTER) == I2C_ANALOGFILTER_DISABLE)) -+#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ -+ STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx ||\ -+ STM32F413xx || STM32F423xx */ -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* __STM32F4xx_HAL_I2C_EX_H */ -+ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c -new file mode 100644 -index 0000000..da18520 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c -@@ -0,0 +1,5494 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c.c -+ * @author MCD Application Team -+ * @brief I2C HAL module driver. -+ * This file provides firmware functions to manage the following -+ * functionalities of the Inter Integrated Circuit (I2C) peripheral: -+ * + Initialization and de-initialization functions -+ * + IO operation functions -+ * + Peripheral State, Mode and Error functions -+ * -+ @verbatim -+ ============================================================================== -+ ##### How to use this driver ##### -+ ============================================================================== -+ [..] -+ The I2C HAL driver can be used as follows: -+ -+ (#) Declare a I2C_HandleTypeDef handle structure, for example: -+ I2C_HandleTypeDef hi2c; -+ -+ (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API: -+ (##) Enable the I2Cx interface clock -+ (##) I2C pins configuration -+ (+++) Enable the clock for the I2C GPIOs -+ (+++) Configure I2C pins as alternate function open-drain -+ (##) NVIC configuration if you need to use interrupt process -+ (+++) Configure the I2Cx interrupt priority -+ (+++) Enable the NVIC I2C IRQ Channel -+ (##) DMA Configuration if you need to use DMA process -+ (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream -+ (+++) Enable the DMAx interface clock using -+ (+++) Configure the DMA handle parameters -+ (+++) Configure the DMA Tx or Rx Stream -+ (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle -+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on -+ the DMA Tx or Rx Stream -+ -+ (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1, -+ Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure. -+ -+ (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware -+ (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API. -+ -+ (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady() -+ -+ (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : -+ -+ *** Polling mode IO operation *** -+ ================================= -+ [..] -+ (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit() -+ (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive() -+ (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit() -+ (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive() -+ -+ *** Polling mode IO MEM operation *** -+ ===================================== -+ [..] -+ (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write() -+ (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read() -+ -+ -+ *** Interrupt mode IO operation *** -+ =================================== -+ [..] -+ (+) Transmit in master mode an amount of data in non blocking mode using HAL_I2C_Master_Transmit_IT() -+ (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback -+ (+) Receive in master mode an amount of data in non blocking mode using HAL_I2C_Master_Receive_IT() -+ (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback -+ (+) Transmit in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Transmit_IT() -+ (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback -+ (+) Receive in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Receive_IT() -+ (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ -+ *** Interrupt mode IO sequential operation *** -+ ============================================== -+ [..] -+ (@) These interfaces allow to manage a sequential transfer with a repeated start condition -+ when a direction change during transfer -+ [..] -+ (+) A specific option field manage the different steps of a sequential transfer -+ (+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below: -+ (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode -+ (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address -+ and data to transfer without a final stop condition -+ (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address -+ and with new data to transfer if the direction change or manage only the new data to transfer -+ if no direction change and without a final stop condition in both cases -+ (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address -+ and with new data to transfer if the direction change or manage only the new data to transfer -+ if no direction change and with a final stop condition in both cases -+ -+ (+) Differents sequential I2C interfaces are listed below: -+ (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT() -+ (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() -+ (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Receive_IT() -+ (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() -+ (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT() -+ (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can -+ add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). -+ (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ListenCpltCallback() -+ (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Transmit_IT() -+ (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() -+ (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Receive_IT() -+ (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() -+ (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback() -+ (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ -+ *** Interrupt mode IO MEM operation *** -+ ======================================= -+ [..] -+ (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using -+ HAL_I2C_Mem_Write_IT() -+ (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback -+ (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using -+ HAL_I2C_Mem_Read_IT() -+ (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ -+ *** DMA mode IO operation *** -+ ============================== -+ [..] -+ (+) Transmit in master mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Master_Transmit_DMA() -+ (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback -+ (+) Receive in master mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Master_Receive_DMA() -+ (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback -+ (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Slave_Transmit_DMA() -+ (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback -+ (+) Receive in slave mode an amount of data in non blocking mode (DMA) using -+ HAL_I2C_Slave_Receive_DMA() -+ (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() -+ (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can -+ add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() -+ -+ *** DMA mode IO MEM operation *** -+ ================================= -+ [..] -+ (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using -+ HAL_I2C_Mem_Write_DMA() -+ (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback -+ (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using -+ HAL_I2C_Mem_Read_DMA() -+ (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can -+ add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback -+ (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can -+ add his own code by customization of function pointer HAL_I2C_ErrorCallback -+ -+ -+ *** I2C HAL driver macros list *** -+ ================================== -+ [..] -+ Below the list of most used macros in I2C HAL driver. -+ -+ (+) __HAL_I2C_ENABLE: Enable the I2C peripheral -+ (+) __HAL_I2C_DISABLE: Disable the I2C peripheral -+ (+) __HAL_I2C_GET_FLAG : Checks whether the specified I2C flag is set or not -+ (+) __HAL_I2C_CLEAR_FLAG : Clear the specified I2C pending flag -+ (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt -+ (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt -+ -+ [..] -+ (@) You can refer to the I2C HAL driver header file for more useful macros -+ -+ -+ @endverbatim -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @defgroup I2C I2C -+ * @brief I2C HAL module driver -+ * @{ -+ */ -+ -+#ifdef HAL_I2C_MODULE_ENABLED -+ -+/* Private typedef -----------------------------------------------------------*/ -+/* Private define ------------------------------------------------------------*/ -+/** @addtogroup I2C_Private_Define -+ * @{ -+ */ -+#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */ -+#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */ -+#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ -+ -+/* Private define for @ref PreviousState usage */ -+#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(uint32_t)HAL_I2C_STATE_READY))) /*!< Mask State define, keep only RX and TX bits */ -+#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */ -+#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ -+#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ -+ -+/** -+ * @} -+ */ -+ -+/* Private macro -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private function prototypes -----------------------------------------------*/ -+/** @addtogroup I2C_Private_Functions -+ * @{ -+ */ -+/* Private functions to handle DMA transfer */ -+static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma); -+static void I2C_DMAError(DMA_HandleTypeDef *hdma); -+static void I2C_DMAAbort(DMA_HandleTypeDef *hdma); -+ -+static void I2C_ITError(I2C_HandleTypeDef *hi2c); -+ -+static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); -+static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c); -+ -+/* Private functions for I2C transfer IRQ handler */ -+static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c); -+ -+static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); -+static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c); -+/** -+ * @} -+ */ -+ -+/* Exported functions --------------------------------------------------------*/ -+/** @defgroup I2C_Exported_Functions I2C Exported Functions -+ * @{ -+ */ -+ -+/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions -+ * @brief Initialization and Configuration functions -+ * -+@verbatim -+ =============================================================================== -+ ##### Initialization and de-initialization functions ##### -+ =============================================================================== -+ [..] This subsection provides a set of functions allowing to initialize and -+ de-initialize the I2Cx peripheral: -+ -+ (+) User must Implement HAL_I2C_MspInit() function in which he configures -+ all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC). -+ -+ (+) Call the function HAL_I2C_Init() to configure the selected device with -+ the selected configuration: -+ (++) Communication Speed -+ (++) Duty cycle -+ (++) Addressing mode -+ (++) Own Address 1 -+ (++) Dual Addressing mode -+ (++) Own Address 2 -+ (++) General call mode -+ (++) Nostretch mode -+ -+ (+) Call the function HAL_I2C_DeInit() to restore the default configuration -+ of the selected I2Cx peripheral. -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Initializes the I2C according to the specified parameters -+ * in the I2C_InitTypeDef and create the associated handle. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) -+{ -+ uint32_t freqrange = 0U; -+ uint32_t pclk1 = 0U; -+ -+ /* Check the I2C handle allocation */ -+ if(hi2c == NULL) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed)); -+ assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle)); -+ assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); -+ assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); -+ assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); -+ assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); -+ assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); -+ assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); -+ -+ if(hi2c->State == HAL_I2C_STATE_RESET) -+ { -+ /* Allocate lock resource and initialize it */ -+ hi2c->Lock = HAL_UNLOCKED; -+ /* Init the low level hardware : GPIO, CLOCK, NVIC */ -+ HAL_I2C_MspInit(hi2c); -+ } -+ -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the selected I2C peripheral */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Get PCLK1 frequency */ -+ pclk1 = HAL_RCC_GetPCLK1Freq(); -+ -+ /* Calculate frequency range */ -+ freqrange = I2C_FREQRANGE(pclk1); -+ -+ /*---------------------------- I2Cx CR2 Configuration ----------------------*/ -+ /* Configure I2Cx: Frequency range */ -+ hi2c->Instance->CR2 = freqrange; -+ -+ /*---------------------------- I2Cx TRISE Configuration --------------------*/ -+ /* Configure I2Cx: Rise Time */ -+ hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); -+ -+ /*---------------------------- I2Cx CCR Configuration ----------------------*/ -+ /* Configure I2Cx: Speed */ -+ hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); -+ -+ /*---------------------------- I2Cx CR1 Configuration ----------------------*/ -+ /* Configure I2Cx: Generalcall and NoStretch mode */ -+ hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); -+ -+ /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ -+ /* Configure I2Cx: Own Address1 and addressing mode */ -+ hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); -+ -+ /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ -+ /* Configure I2Cx: Dual mode and Own Address2 */ -+ hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2); -+ -+ /* Enable the selected I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief DeInitializes the I2C peripheral. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) -+{ -+ /* Check the I2C handle allocation */ -+ if(hi2c == NULL) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the I2C Peripheral Clock */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ -+ HAL_I2C_MspDeInit(hi2c); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->State = HAL_I2C_STATE_RESET; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Release Lock */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief I2C MSP Init. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval None -+ */ -+ __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ /* NOTE : This function Should not be modified, when the callback is needed, -+ the HAL_I2C_MspInit could be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief I2C MSP DeInit -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval None -+ */ -+ __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ /* NOTE : This function Should not be modified, when the callback is needed, -+ the HAL_I2C_MspDeInit could be implemented in the user file -+ */ -+} -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Exported_Functions_Group2 IO operation functions -+ * @brief Data transfers functions -+ * -+@verbatim -+ =============================================================================== -+ ##### IO operation functions ##### -+ =============================================================================== -+ [..] -+ This subsection provides a set of functions allowing to manage the I2C data -+ transfers. -+ -+ (#) There are two modes of transfer: -+ (++) Blocking mode : The communication is performed in the polling mode. -+ The status of all data processing is returned by the same function -+ after finishing transfer. -+ (++) No-Blocking mode : The communication is performed using Interrupts -+ or DMA. These functions return the status of the transfer startup. -+ The end of the data processing will be indicated through the -+ dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when -+ using DMA mode. -+ -+ (#) Blocking mode functions are : -+ (++) HAL_I2C_Master_Transmit() -+ (++) HAL_I2C_Master_Receive() -+ (++) HAL_I2C_Slave_Transmit() -+ (++) HAL_I2C_Slave_Receive() -+ (++) HAL_I2C_Mem_Write() -+ (++) HAL_I2C_Mem_Read() -+ (++) HAL_I2C_IsDeviceReady() -+ -+ (#) No-Blocking mode functions with Interrupt are : -+ (++) HAL_I2C_Master_Transmit_IT() -+ (++) HAL_I2C_Master_Receive_IT() -+ (++) HAL_I2C_Slave_Transmit_IT() -+ (++) HAL_I2C_Slave_Receive_IT() -+ (++) HAL_I2C_Master_Sequential_Transmit_IT() -+ (++) HAL_I2C_Master_Sequential_Receive_IT() -+ (++) HAL_I2C_Slave_Sequential_Transmit_IT() -+ (++) HAL_I2C_Slave_Sequential_Receive_IT() -+ (++) HAL_I2C_Mem_Write_IT() -+ (++) HAL_I2C_Mem_Read_IT() -+ -+ (#) No-Blocking mode functions with DMA are : -+ (++) HAL_I2C_Master_Transmit_DMA() -+ (++) HAL_I2C_Master_Receive_DMA() -+ (++) HAL_I2C_Slave_Transmit_DMA() -+ (++) HAL_I2C_Slave_Receive_DMA() -+ (++) HAL_I2C_Mem_Write_DMA() -+ (++) HAL_I2C_Mem_Read_DMA() -+ -+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: -+ (++) HAL_I2C_MemTxCpltCallback() -+ (++) HAL_I2C_MemRxCpltCallback() -+ (++) HAL_I2C_MasterTxCpltCallback() -+ (++) HAL_I2C_MasterRxCpltCallback() -+ (++) HAL_I2C_SlaveTxCpltCallback() -+ (++) HAL_I2C_SlaveRxCpltCallback() -+ (++) HAL_I2C_ErrorCallback() -+ (++) HAL_I2C_AbortCpltCallback() -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Transmits in master mode an amount of data in blocking mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address */ -+ if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ } -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receives in master mode an amount of data in blocking mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address */ -+ if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(hi2c->XferSize == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ if(hi2c->XferSize <= 3U) -+ { -+ /* One byte */ -+ if(hi2c->XferSize == 1U) -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* Two bytes */ -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* 3 Last bytes */ -+ else -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ else -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmits in slave mode an amount of data in blocking mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* If 10bit addressing mode is selected */ -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) -+ { -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ hi2c->XferSize--; -+ } -+ } -+ -+ /* Wait until AF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in slave mode an amount of data in blocking mode -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ -+ /* Wait until STOP flag is set */ -+ if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear STOP flag */ -+ __HAL_I2C_CLEAR_STOPFLAG(hi2c); -+ -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential transmit in master mode an amount of data in non-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ __IO uint32_t Prev_State = 0x00U; -+ __IO uint32_t count = 0x00U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Check Busy Flag only if FIRST call of Master interface */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ Prev_State = hi2c->PreviousState; -+ -+ /* Generate Start */ -+ if((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) -+ { -+ /* Generate Start condition if first transfer */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ } -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential receive in master mode an amount of data in non-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ __IO uint32_t count = 0U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Check Busy Flag only if FIRST call of Master interface */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) -+ { -+ /* Generate Start condition if first transfer */ -+ if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ } -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential transmit in slave mode an amount of data in no-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_LISTEN) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Sequential receive in slave mode an amount of data in non-blocking mode with Interrupt -+ * @note This interface allow to manage repeated start condition when a direction change during transfer -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) -+{ -+ /* Check the parameters */ -+ assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); -+ -+ if(hi2c->State == HAL_I2C_STATE_LISTEN) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = XferOptions; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Enable the Address listen mode with Interrupt. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Disable the Address listen mode with Interrupt. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of tmp to prevent undefined behavior of volatile usage */ -+ uint32_t tmp; -+ -+ /* Disable Address listen mode only if a transfer is not ongoing */ -+ if(hi2c->State == HAL_I2C_STATE_LISTEN) -+ { -+ tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; -+ hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Disable Address Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Disable EVT and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Transmit in master mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmatx->XferHalfCpltCallback = NULL; -+ hi2c->hdmatx->XferM1CpltCallback = NULL; -+ hi2c->hdmatx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ } -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in master mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MASTER; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ hi2c->Devaddress = DevAddress; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmarx->XferHalfCpltCallback = NULL; -+ hi2c->hdmarx->XferM1CpltCallback = NULL; -+ hi2c->hdmarx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ } -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Abort a master I2C process communication with Interrupt. -+ * @note This abort can be called only if state is ready -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(DevAddress); -+ -+ /* Abort Master transfer during Receive or Transmit process */ -+ if(hi2c->Mode == HAL_I2C_MODE_MASTER) -+ { -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_ABORT; -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ I2C_ITError(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ /* Wrong usage of abort function */ -+ /* This function should be used only in case of abort monitored by master device */ -+ return HAL_ERROR; -+ } -+} -+ -+/** -+ * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmatx->XferHalfCpltCallback = NULL; -+ hi2c->hdmatx->XferM1CpltCallback = NULL; -+ hi2c->hdmatx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Receive in slave mode an amount of data in non-blocking mode with DMA -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ if((pData == NULL) || (Size == 0U)) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_SLAVE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmarx->XferHalfCpltCallback = NULL; -+ hi2c->hdmarx->XferM1CpltCallback = NULL; -+ hi2c->hdmarx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Enable Address Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+/** -+ * @brief Write an amount of data in blocking mode to a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Read an amount of data in blocking mode from a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(hi2c->XferSize == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ while(hi2c->XferSize > 0U) -+ { -+ if(hi2c->XferSize <= 3U) -+ { -+ /* One byte */ -+ if(hi2c->XferSize== 1U) -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* Two bytes */ -+ else if(hi2c->XferSize == 2U) -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ /* 3 Last bytes */ -+ else -+ { -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Wait until BTF flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ else -+ { -+ /* Wait until RXNE flag is set */ -+ if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) -+ { -+ return HAL_TIMEOUT; -+ } -+ else -+ { -+ return HAL_ERROR; -+ } -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferSize--; -+ hi2c->XferCount--; -+ } -+ } -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->Devaddress = DevAddress; -+ hi2c->Memaddress = MemAddress; -+ hi2c->MemaddSize = MemAddSize; -+ hi2c->EventCount = 0U; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->Devaddress = DevAddress; -+ hi2c->Memaddress = MemAddress; -+ hi2c->MemaddSize = MemAddSize; -+ hi2c->EventCount = 0U; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ -+ /* Enable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ } -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be sent -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ __IO uint32_t count = 0U; -+ -+ uint32_t tickstart = 0x00U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferSize = Size; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmatx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmatx->XferHalfCpltCallback = NULL; -+ hi2c->hdmatx->XferM1CpltCallback = NULL; -+ hi2c->hdmatx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param pData Pointer to data buffer -+ * @param Size Amount of data to be read -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) -+{ -+ uint32_t tickstart = 0x00U; -+ __IO uint32_t count = 0U; -+ -+ /* Init tickstart for timeout management*/ -+ tickstart = HAL_GetTick(); -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); -+ do -+ { -+ if(count-- == 0U) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY_RX; -+ hi2c->Mode = HAL_I2C_MODE_MEM; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Prepare transfer parameters */ -+ hi2c->pBuffPtr = pData; -+ hi2c->XferCount = Size; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->XferSize = hi2c->XferCount; -+ -+ if(hi2c->XferSize > 0U) -+ { -+ /* Set the I2C DMA transfer complete callback */ -+ hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; -+ -+ /* Set the DMA error callback */ -+ hi2c->hdmarx->XferErrorCallback = I2C_DMAError; -+ -+ /* Set the unused DMA callbacks to NULL */ -+ hi2c->hdmarx->XferHalfCpltCallback = NULL; -+ hi2c->hdmarx->XferM1CpltCallback = NULL; -+ hi2c->hdmarx->XferM1HalfCpltCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Enable the DMA Stream */ -+ HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); -+ -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ if(Size == 1U) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ } -+ else -+ { -+ /* Enable Last DMA bit */ -+ hi2c->Instance->CR2 |= I2C_CR2_LAST; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ /* Note : The I2C interrupts must be enabled after unlocking current process -+ to avoid the risk of I2C interrupt handle execution before current -+ process unlock */ -+ /* Enable ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); -+ -+ /* Enable DMA Request */ -+ hi2c->Instance->CR2 |= I2C_CR2_DMAEN; -+ } -+ else -+ { -+ /* Send Slave Address and Memory Address */ -+ if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_ERROR; -+ } -+ else -+ { -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ } -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Checks if target device is ready for communication. -+ * @note This function is used with Memory devices -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param DevAddress Target device address -+ * @param Trials Number of trials -+ * @param Timeout Timeout duration -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) -+{ -+ uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U; -+ -+ /* Get tick */ -+ tickstart = HAL_GetTick(); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_BUSY; -+ } -+ -+ /* Process Locked */ -+ __HAL_LOCK(hi2c); -+ -+ /* Check if the I2C is already enabled */ -+ if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) -+ { -+ /* Enable I2C peripheral */ -+ __HAL_I2C_ENABLE(hi2c); -+ } -+ -+ /* Disable Pos */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ do -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ -+ /* Wait until ADDR or AF flag are set */ -+ /* Get tick */ -+ tickstart = HAL_GetTick(); -+ -+ tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); -+ tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); -+ tmp3 = hi2c->State; -+ while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) -+ { -+ hi2c->State = HAL_I2C_STATE_TIMEOUT; -+ } -+ tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); -+ tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); -+ tmp3 = hi2c->State; -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Check if the ADDR flag has been set */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Clear ADDR Flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_OK; -+ } -+ else -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Clear AF Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Wait until BUSY flag is reset */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ }while(I2C_Trials++ < Trials); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief This function handles I2C event interrupt request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) -+{ -+ uint32_t sr2itflags = READ_REG(hi2c->Instance->SR2); -+ uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); -+ uint32_t itsources = READ_REG(hi2c->Instance->CR2); -+ -+ uint32_t CurrentMode = hi2c->Mode; -+ -+ /* Master or Memory mode selected */ -+ if((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) -+ { -+ /* SB Set ----------------------------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_SB(hi2c); -+ } -+ /* ADD10 Set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_ADD10) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_ADD10(hi2c); -+ } -+ /* ADDR Set --------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Master_ADDR(hi2c); -+ } -+ -+ /* I2C in mode Transmitter -----------------------------------------------*/ -+ if((sr2itflags & I2C_FLAG_TRA) != RESET) -+ { -+ /* TXE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_MasterTransmit_TXE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_MasterTransmit_BTF(hi2c); -+ } -+ } -+ /* I2C in mode Receiver --------------------------------------------------*/ -+ else -+ { -+ /* RXNE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_MasterReceive_RXNE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_MasterReceive_BTF(hi2c); -+ } -+ } -+ } -+ /* Slave mode selected */ -+ else -+ { -+ /* ADDR set --------------------------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Slave_ADDR(hi2c); -+ } -+ /* STOPF set --------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_Slave_STOPF(hi2c); -+ } -+ /* I2C in mode Transmitter -----------------------------------------------*/ -+ else if((sr2itflags & I2C_FLAG_TRA) != RESET) -+ { -+ /* TXE set and BTF reset -----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_SlaveTransmit_TXE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_SlaveTransmit_BTF(hi2c); -+ } -+ } -+ /* I2C in mode Receiver --------------------------------------------------*/ -+ else -+ { -+ /* RXNE set and BTF reset ----------------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) -+ { -+ I2C_SlaveReceive_RXNE(hi2c); -+ } -+ /* BTF set -------------------------------------------------------------*/ -+ else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) -+ { -+ I2C_SlaveReceive_BTF(hi2c); -+ } -+ } -+ } -+} -+ -+/** -+ * @brief This function handles I2C error interrupt request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) -+{ -+ uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U; -+ uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); -+ uint32_t itsources = READ_REG(hi2c->Instance->CR2); -+ -+ /* I2C Bus error interrupt occurred ----------------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; -+ -+ /* Clear BERR flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); -+ } -+ -+ /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ -+ if(((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; -+ -+ /* Clear ARLO flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); -+ } -+ -+ /* I2C Acknowledge failure error interrupt occurred ------------------------*/ -+ if(((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ tmp1 = hi2c->Mode; -+ tmp2 = hi2c->XferCount; -+ tmp3 = hi2c->State; -+ tmp4 = hi2c->PreviousState; -+ if((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) && \ -+ ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || \ -+ ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) -+ { -+ I2C_Slave_AF(hi2c); -+ } -+ else -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_AF; -+ -+ /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */ -+ if(hi2c->Mode == HAL_I2C_MODE_MASTER) -+ { -+ /* Generate Stop */ -+ SET_BIT(hi2c->Instance->CR1,I2C_CR1_STOP); -+ } -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ } -+ } -+ -+ /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ -+ if(((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; -+ /* Clear OVR flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); -+ } -+ -+ /* Call the Error Callback in case of Error detected -----------------------*/ -+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ I2C_ITError(hi2c); -+ } -+} -+ -+/** -+ * @brief Master Tx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MasterTxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Master Rx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MasterRxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** @brief Slave Tx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_SlaveTxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Slave Rx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_SlaveRxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Slave Address Match callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferOptions_definition -+ * @param AddrMatchCode Address Match Code -+ * @retval None -+ */ -+__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ UNUSED(TransferDirection); -+ UNUSED(AddrMatchCode); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_AddrCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Listen Complete callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_ListenCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Memory Tx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MemTxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief Memory Rx Transfer completed callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_MemRxCpltCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief I2C error callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_ErrorCallback can be implemented in the user file -+ */ -+} -+ -+/** -+ * @brief I2C abort callback. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval None -+ */ -+__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) -+{ -+ /* Prevent unused argument(s) compilation warning */ -+ UNUSED(hi2c); -+ -+ /* NOTE : This function should not be modified, when the callback is needed, -+ the HAL_I2C_AbortCpltCallback could be implemented in the user file -+ */ -+} -+ -+/** -+ * @} -+ */ -+ -+/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions -+ * @brief Peripheral State and Errors functions -+ * -+@verbatim -+ =============================================================================== -+ ##### Peripheral State, Mode and Error functions ##### -+ =============================================================================== -+ [..] -+ This subsection permits to get in run-time the status of the peripheral -+ and the data flow. -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Return the I2C handle state. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL state -+ */ -+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) -+{ -+ /* Return I2C handle state */ -+ return hi2c->State; -+} -+ -+/** -+ * @brief Return the I2C Master, Slave, Memory or no mode. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL mode -+ */ -+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c) -+{ -+ return hi2c->Mode; -+} -+ -+/** -+ * @brief Return the I2C error code -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval I2C Error Code -+ */ -+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) -+{ -+ return hi2c->ErrorCode; -+} -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @brief Handle TXE flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t CurrentMode = hi2c->Mode; -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if((hi2c->XferSize == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX)) -+ { -+ /* Call TxCpltCallback() directly if no stop mode is set */ -+ if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) -+ { -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ else /* Generate Stop condition then Call TxCpltCallback() */ -+ { -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MemTxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ } -+ } -+ else if((CurrentState == HAL_I2C_STATE_BUSY_TX) || \ -+ ((CurrentMode == HAL_I2C_MODE_MEM) && (CurrentState == HAL_I2C_STATE_BUSY_RX))) -+ { -+ if(hi2c->XferCount == 0U) -+ { -+ /* Disable BUF interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ } -+ else -+ { -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ if(hi2c->EventCount == 0) -+ { -+ /* If Memory address size is 8Bit */ -+ if(hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT) -+ { -+ /* Send Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); -+ -+ hi2c->EventCount += 2; -+ } -+ /* If Memory address size is 16Bit */ -+ else -+ { -+ /* Send MSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress); -+ -+ hi2c->EventCount++; -+ } -+ } -+ else if(hi2c->EventCount == 1) -+ { -+ /* Send LSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); -+ -+ hi2c->EventCount++; -+ } -+ else if(hi2c->EventCount == 2) -+ { -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ } -+ } -+ else -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Master transmitter -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_TX) -+ { -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ else -+ { -+ /* Call TxCpltCallback() directly if no stop mode is set */ -+ if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) -+ { -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ else /* Generate Stop condition then Call TxCpltCallback() */ -+ { -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemTxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterTxCpltCallback(hi2c); -+ } -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle RXNE flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ uint32_t tmp = 0U; -+ -+ tmp = hi2c->XferCount; -+ if(tmp > 3U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ if(hi2c->XferCount == 3) -+ { -+ /* Disable BUF interrupt, this help to treat correctly the last 4 bytes -+ on BTF subroutine */ -+ /* Disable BUF interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ } -+ } -+ else if((tmp == 1U) || (tmp == 0U)) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Master receiver -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if(hi2c->XferCount == 4U) -+ { -+ /* Disable BUF interrupt, this help to treat correctly the last 2 bytes -+ on BTF subroutine if there is a reception delay between N-1 and N byte */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ else if(hi2c->XferCount == 3U) -+ { -+ /* Disable BUF interrupt, this help to treat correctly the last 2 bytes -+ on BTF subroutine if there is a reception delay between N-1 and N byte */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ else if(hi2c->XferCount == 2U) -+ { -+ /* Prepare next transfer or stop current transfer */ -+ if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ /* Disable EVT and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ else -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle SB flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ if(hi2c->EventCount == 0U) -+ { -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); -+ } -+ else -+ { -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); -+ } -+ } -+ else -+ { -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) -+ { -+ /* Send slave 7 Bits address */ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_TX) -+ { -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); -+ } -+ else -+ { -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); -+ } -+ } -+ else -+ { -+ if(hi2c->EventCount == 0U) -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress); -+ } -+ else if(hi2c->EventCount == 1U) -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress); -+ } -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADD10 flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c) -+{ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADDR flag for Master -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentMode = hi2c->Mode; -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ uint32_t Prev_State = hi2c->PreviousState; -+ -+ if(hi2c->State == HAL_I2C_STATE_BUSY_RX) -+ { -+ if((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM)) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else if((hi2c->EventCount == 0U) && (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ hi2c->EventCount++; -+ } -+ else -+ { -+ if(hi2c->XferCount == 0U) -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ else if(hi2c->XferCount == 1U) -+ { -+ if(CurrentXferOptions == I2C_NO_OPTION_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ } -+ /* Prepare next transfer or stop current transfer */ -+ else if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) \ -+ && (Prev_State != I2C_STATE_MASTER_BUSY_RX)) -+ { -+ if(hi2c->XferOptions != I2C_NEXT_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ } -+ } -+ else if(hi2c->XferCount == 2U) -+ { -+ if(hi2c->XferOptions != I2C_NEXT_FRAME) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Enable Pos */ -+ hi2c->Instance->CR1 |= I2C_CR1_POS; -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ } -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Enable Last DMA bit */ -+ hi2c->Instance->CR2 |= I2C_CR2_LAST; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ else -+ { -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ /* Enable Last DMA bit */ -+ hi2c->Instance->CR2 |= I2C_CR2_LAST; -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ /* Reset Event counter */ -+ hi2c->EventCount = 0U; -+ } -+ } -+ else -+ { -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle TXE flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ -+ if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) -+ { -+ /* Last Byte is received, disable Interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Set state at HAL_I2C_STATE_LISTEN */ -+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ -+ /* Call the Tx complete callback to inform upper layer of the end of receive process */ -+ HAL_I2C_SlaveTxCpltCallback(hi2c); -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Slave transmitter -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Write data to DR */ -+ hi2c->Instance->DR = (*hi2c->pBuffPtr++); -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle RXNE flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ -+ if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) -+ { -+ /* Last Byte is received, disable Interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); -+ -+ /* Set state at HAL_I2C_STATE_LISTEN */ -+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ -+ /* Call the Rx complete callback to inform upper layer of the end of receive process */ -+ HAL_I2C_SlaveRxCpltCallback(hi2c); -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle BTF flag for Slave receiver -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) -+{ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle ADD flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) -+{ -+ uint8_t TransferDirection = I2C_DIRECTION_RECEIVE; -+ uint16_t SlaveAddrCode = 0U; -+ -+ /* Transfer Direction requested by Master */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == RESET) -+ { -+ TransferDirection = I2C_DIRECTION_TRANSMIT; -+ } -+ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DUALF) == RESET) -+ { -+ SlaveAddrCode = hi2c->Init.OwnAddress1; -+ } -+ else -+ { -+ SlaveAddrCode = hi2c->Init.OwnAddress2; -+ } -+ -+ /* Call Slave Addr callback */ -+ HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode); -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Handle STOPF flag for Slave -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Clear STOPF flag */ -+ __HAL_I2C_CLEAR_STOPFLAG(hi2c); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* If a DMA is ongoing, Update handle size context */ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ if((hi2c->State == HAL_I2C_STATE_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) -+ { -+ hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmarx); -+ } -+ else -+ { -+ hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmatx); -+ } -+ } -+ -+ /* All data are not transferred, so set error code accordingly */ -+ if(hi2c->XferCount != 0U) -+ { -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ hi2c->XferCount--; -+ } -+ -+ /* Set ErrorCode corresponding to a Non-Acknowledge */ -+ //hi2c->ErrorCode |= HAL_I2C_ERROR_AF; -+ } -+ -+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ I2C_ITError(hi2c); -+ } -+ else -+ { -+ if((CurrentState == HAL_I2C_STATE_LISTEN ) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN) || \ -+ (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+ else -+ { -+ if((hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_RX) || (CurrentState == HAL_I2C_STATE_BUSY_RX)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_SlaveRxCpltCallback(hi2c); -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ if(((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME)) && \ -+ (CurrentState == HAL_I2C_STATE_LISTEN)) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+ else if(CurrentState == HAL_I2C_STATE_BUSY_TX) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Disable EVT, BUF and ERR interrupt */ -+ __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); -+ -+ /* Clear AF flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ HAL_I2C_SlaveTxCpltCallback(hi2c); -+ } -+ else -+ { -+ /* Clear AF flag only */ -+ /* State Listen, but XferOptions == FIRST or NEXT */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief I2C interrupts error process -+ * @param hi2c I2C handle. -+ * @retval None -+ */ -+static void I2C_ITError(I2C_HandleTypeDef *hi2c) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ -+ if((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) -+ { -+ /* keep HAL_I2C_STATE_LISTEN */ -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_LISTEN; -+ } -+ else -+ { -+ /* If state is an abort treatment on going, don't change state */ -+ /* This change will be do later */ -+ if((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ } -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ } -+ -+ /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_POS; -+ -+ /* Abort DMA transfer */ -+ if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) -+ { -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ if(hi2c->hdmatx->State != HAL_DMA_STATE_READY) -+ { -+ /* Set the DMA Abort callback : -+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ -+ hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; -+ -+ if(HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) -+ { -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Call Directly XferAbortCallback function in case of error */ -+ hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); -+ } -+ } -+ else -+ { -+ /* Set the DMA Abort callback : -+ will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ -+ hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; -+ -+ if(HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) -+ { -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ } -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ -+ hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); -+ } -+ } -+ } -+ else if(hi2c->State == HAL_I2C_STATE_ABORT) -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ } -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ HAL_I2C_AbortCpltCallback(hi2c); -+ } -+ else -+ { -+ /* Store Last receive data if any */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) -+ { -+ /* Read data from DR */ -+ (*hi2c->pBuffPtr++) = hi2c->Instance->DR; -+ } -+ -+ /* Call user error callback */ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+ /* STOP Flag is not set after a NACK reception */ -+ /* So may inform upper layer that listen phase is stopped */ -+ /* during NACK error treatment */ -+ if((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) -+ { -+ hi2c->XferOptions = I2C_NO_OPTION_FRAME; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ -+ HAL_I2C_ListenCpltCallback(hi2c); -+ } -+} -+ -+/** -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ /* Generate Start condition if first transfer */ -+ if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) -+ { -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ } -+ else -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); -+ -+ /* Wait until ADD10 flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); -+ } -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Master sends target device address for read request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address The device 7 bits address value -+ * in datasheet must be shifted to the left before calling the interface -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentXferOptions = hi2c->XferOptions; -+ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start condition if first transfer */ -+ if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) -+ { -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) -+ { -+ /* Generate ReStart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ } -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) -+ { -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); -+ } -+ else -+ { -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); -+ -+ /* Wait until ADD10 flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send header of slave address */ -+ hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); -+ } -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Master sends target device address followed by internal memory address for write request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* If Memory address size is 8Bit */ -+ if(MemAddSize == I2C_MEMADD_SIZE_8BIT) -+ { -+ /* Send Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ /* If Memory address size is 16Bit */ -+ else -+ { -+ /* Send MSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send LSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief Master sends target device address followed by internal memory address for read request. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param DevAddress Target device address -+ * @param MemAddress Internal memory address -+ * @param MemAddSize Size of internal memory address -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Enable Acknowledge */ -+ hi2c->Instance->CR1 |= I2C_CR1_ACK; -+ -+ /* Generate Start */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Clear ADDR flag */ -+ __HAL_I2C_CLEAR_ADDRFLAG(hi2c); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* If Memory address size is 8Bit */ -+ if(MemAddSize == I2C_MEMADD_SIZE_8BIT) -+ { -+ /* Send Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ /* If Memory address size is 16Bit */ -+ else -+ { -+ /* Send MSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Send LSB of Memory Address */ -+ hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); -+ } -+ -+ /* Wait until TXE flag is set */ -+ if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ /* Generate Restart */ -+ hi2c->Instance->CR1 |= I2C_CR1_START; -+ -+ /* Wait until SB flag is set */ -+ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) -+ { -+ return HAL_TIMEOUT; -+ } -+ -+ /* Send slave address */ -+ hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); -+ -+ /* Wait until ADDR flag is set */ -+ if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) -+ { -+ if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) -+ { -+ return HAL_ERROR; -+ } -+ else -+ { -+ return HAL_TIMEOUT; -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief DMA I2C process complete callback. -+ * @param hdma DMA handle -+ * @retval None -+ */ -+static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma) -+{ -+ I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; -+ -+ /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ -+ uint32_t CurrentState = hi2c->State; -+ uint32_t CurrentMode = hi2c->Mode; -+ -+ if((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) -+ { -+ /* Disable DMA Request */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Enable EVT and ERR interrupt */ -+ __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); -+ } -+ else -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Disable Last DMA */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_LAST; -+ -+ /* Disable DMA Request */ -+ hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Check if Errors has been detected during transfer */ -+ if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) -+ { -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+ else -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ if(hi2c->Mode == HAL_I2C_MODE_MEM) -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MemRxCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ HAL_I2C_MasterRxCpltCallback(hi2c); -+ } -+ } -+ } -+} -+ -+/** -+ * @brief DMA I2C communication error callback. -+ * @param hdma DMA handle -+ * @retval None -+ */ -+static void I2C_DMAError(DMA_HandleTypeDef *hdma) -+{ -+ I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; -+ -+ /* Ignore DMA FIFO error */ -+ if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) -+ { -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->XferCount = 0U; -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; -+ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+} -+ -+/** -+ * @brief DMA I2C communication abort callback -+ * (To be called at end of DMA Abort procedure). -+ * @param hdma DMA handle. -+ * @retval None -+ */ -+static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) -+{ -+ I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; -+ -+ /* Disable Acknowledge */ -+ hi2c->Instance->CR1 &= ~I2C_CR1_ACK; -+ -+ hi2c->XferCount = 0U; -+ -+ /* Reset XferAbortCallback */ -+ hi2c->hdmatx->XferAbortCallback = NULL; -+ hi2c->hdmarx->XferAbortCallback = NULL; -+ -+ /* Check if come from abort from user */ -+ if(hi2c->State == HAL_I2C_STATE_ABORT) -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ HAL_I2C_AbortCpltCallback(hi2c); -+ } -+ else -+ { -+ hi2c->State = HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Disable I2C peripheral to prevent dummy data in buffer */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Call the corresponding callback to inform upper layer of End of Transfer */ -+ HAL_I2C_ErrorCallback(hi2c); -+ } -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param Flag specifies the I2C flag to check. -+ * @param Status The new Flag status (SET or RESET). -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) -+{ -+ /* Wait until flag is set */ -+ while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) -+ { -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ hi2c->Mode = HAL_I2C_MODE_NONE; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for Master addressing phase. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for I2C module -+ * @param Flag specifies the I2C flag to check. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) -+ { -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) -+ { -+ /* Generate Stop */ -+ hi2c->Instance->CR1 |= I2C_CR1_STOP; -+ -+ /* Clear AF Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_AF; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) -+ { -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of TXE flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) -+ { -+ /* Check if a NACK is detected */ -+ if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of BTF flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) -+ { -+ /* Check if a NACK is detected */ -+ if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if(Timeout != HAL_MAX_DELAY) -+ { -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of STOP flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) -+ { -+ /* Check if a NACK is detected */ -+ if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) -+ { -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @param Timeout Timeout duration -+ * @param Tickstart Tick start value -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) -+{ -+ -+ while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) -+ { -+ /* Check if a STOPF is detected */ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) -+ { -+ /* Clear STOP Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_NONE; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ -+ /* Check for the Timeout */ -+ if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) -+ { -+ hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_TIMEOUT; -+ } -+ } -+ return HAL_OK; -+} -+ -+/** -+ * @brief This function handles Acknowledge failed detection during an I2C Communication. -+ * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2C. -+ * @retval HAL status -+ */ -+static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) -+{ -+ if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) -+ { -+ /* Clear NACKF Flag */ -+ __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); -+ -+ hi2c->ErrorCode = HAL_I2C_ERROR_AF; -+ hi2c->PreviousState = I2C_STATE_NONE; -+ hi2c->State= HAL_I2C_STATE_READY; -+ -+ /* Process Unlocked */ -+ __HAL_UNLOCK(hi2c); -+ -+ return HAL_ERROR; -+ } -+ return HAL_OK; -+} -+/** -+ * @} -+ */ -+ -+#endif /* HAL_I2C_MODULE_ENABLED */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c -new file mode 100644 -index 0000000..de8f160 ---- /dev/null -+++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c -@@ -0,0 +1,204 @@ -+/** -+ ****************************************************************************** -+ * @file stm32f4xx_hal_i2c_ex.c -+ * @author MCD Application Team -+ * @brief I2C Extension HAL module driver. -+ * This file provides firmware functions to manage the following -+ * functionalities of I2C extension peripheral: -+ * + Extension features functions -+ * -+ @verbatim -+ ============================================================================== -+ ##### I2C peripheral extension features ##### -+ ============================================================================== -+ -+ [..] Comparing to other previous devices, the I2C interface for STM32F427xx/437xx/ -+ 429xx/439xx devices contains the following additional features : -+ -+ (+) Possibility to disable or enable Analog Noise Filter -+ (+) Use of a configured Digital Noise Filter -+ -+ ##### How to use this driver ##### -+ ============================================================================== -+ [..] This driver provides functions to configure Noise Filter -+ (#) Configure I2C Analog noise filter using the function HAL_I2C_AnalogFilter_Config() -+ (#) Configure I2C Digital noise filter using the function HAL_I2C_DigitalFilter_Config() -+ -+ @endverbatim -+ ****************************************************************************** -+ * @attention -+ * -+ *

© COPYRIGHT(c) 2017 STMicroelectronics

-+ * -+ * Redistribution and use in source and binary forms, with or without modification, -+ * are permitted provided that the following conditions are met: -+ * 1. Redistributions of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+ -+/** @addtogroup STM32F4xx_HAL_Driver -+ * @{ -+ */ -+ -+/** @defgroup I2CEx I2CEx -+ * @brief I2C HAL module driver -+ * @{ -+ */ -+ -+#ifdef HAL_I2C_MODULE_ENABLED -+ -+#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ -+ defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ -+ defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) -+/* Private typedef -----------------------------------------------------------*/ -+/* Private define ------------------------------------------------------------*/ -+/* Private macro -------------------------------------------------------------*/ -+/* Private variables ---------------------------------------------------------*/ -+/* Private function prototypes -----------------------------------------------*/ -+/* Exported functions --------------------------------------------------------*/ -+/** @defgroup I2CEx_Exported_Functions I2C Exported Functions -+ * @{ -+ */ -+ -+ -+/** @defgroup I2CEx_Exported_Functions_Group1 Extension features functions -+ * @brief Extension features functions -+ * -+@verbatim -+ =============================================================================== -+ ##### Extension features functions ##### -+ =============================================================================== -+ [..] This section provides functions allowing to: -+ (+) Configure Noise Filters -+ -+@endverbatim -+ * @{ -+ */ -+ -+/** -+ * @brief Configures I2C Analog noise filter. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2Cx peripheral. -+ * @param AnalogFilter new state of the Analog filter. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) -+{ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the selected I2C peripheral */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Reset I2Cx ANOFF bit */ -+ hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF); -+ -+ /* Disable the analog filter */ -+ hi2c->Instance->FLTR |= AnalogFilter; -+ -+ __HAL_I2C_ENABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @brief Configures I2C Digital noise filter. -+ * @param hi2c pointer to a I2C_HandleTypeDef structure that contains -+ * the configuration information for the specified I2Cx peripheral. -+ * @param DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F. -+ * @retval HAL status -+ */ -+HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) -+{ -+ uint16_t tmpreg = 0; -+ -+ /* Check the parameters */ -+ assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); -+ assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); -+ -+ if(hi2c->State == HAL_I2C_STATE_READY) -+ { -+ hi2c->State = HAL_I2C_STATE_BUSY; -+ -+ /* Disable the selected I2C peripheral */ -+ __HAL_I2C_DISABLE(hi2c); -+ -+ /* Get the old register value */ -+ tmpreg = hi2c->Instance->FLTR; -+ -+ /* Reset I2Cx DNF bit [3:0] */ -+ tmpreg &= ~(I2C_FLTR_DNF); -+ -+ /* Set I2Cx DNF coefficient */ -+ tmpreg |= DigitalFilter; -+ -+ /* Store the new register value */ -+ hi2c->Instance->FLTR = tmpreg; -+ -+ __HAL_I2C_ENABLE(hi2c); -+ -+ hi2c->State = HAL_I2C_STATE_READY; -+ -+ return HAL_OK; -+ } -+ else -+ { -+ return HAL_BUSY; -+ } -+} -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ -+ STM32F401xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx ||\ -+ STM32F423xx */ -+ -+#endif /* HAL_I2C_MODULE_ENABLED */ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Inc/i2c.h b/Firmware/Board/v3/Inc/i2c.h -new file mode 100644 -index 0000000..f449b88 ---- /dev/null -+++ b/Firmware/Board/v3/Inc/i2c.h -@@ -0,0 +1,91 @@ -+/** -+ ****************************************************************************** -+ * File Name : I2C.h -+ * Description : This file provides code for the configuration -+ * of the I2C instances. -+ ****************************************************************************** -+ * This notice applies to any and all portions of this file -+ * that are not between comment pairs USER CODE BEGIN and -+ * USER CODE END. Other portions of this file, whether -+ * inserted by the user or by software development tools -+ * are owned by their respective copyright owners. -+ * -+ * Copyright (c) 2018 STMicroelectronics International N.V. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted, provided that the following conditions are met: -+ * -+ * 1. Redistribution of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of other -+ * contributors to this software may be used to endorse or promote products -+ * derived from this software without specific written permission. -+ * 4. This software, including modifications and/or derivative works of this -+ * software, must execute solely and exclusively on microcontroller or -+ * microprocessor devices manufactured by or for STMicroelectronics. -+ * 5. Redistribution and use of this software other than as permitted under -+ * this license is void and will automatically terminate your rights under -+ * this license. -+ * -+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY -+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT -+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+/* Define to prevent recursive inclusion -------------------------------------*/ -+#ifndef __i2c_H -+#define __i2c_H -+#ifdef __cplusplus -+ extern "C" { -+#endif -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "stm32f4xx_hal.h" -+#include "main.h" -+ -+/* USER CODE BEGIN Includes */ -+ -+/* USER CODE END Includes */ -+ -+extern I2C_HandleTypeDef hi2c1; -+ -+/* USER CODE BEGIN Private defines */ -+ -+/* USER CODE END Private defines */ -+ -+extern void _Error_Handler(char *, int); -+ -+void MX_I2C1_Init(uint8_t addr); -+ -+/* USER CODE BEGIN Prototypes */ -+ -+/* USER CODE END Prototypes */ -+ -+#ifdef __cplusplus -+} -+#endif -+#endif /*__ i2c_H */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -index d0f48f5..b3ef59a 100644 ---- a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -+++ b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h -@@ -65,7 +65,7 @@ - /* #define HAL_SRAM_MODULE_ENABLED */ - /* #define HAL_SDRAM_MODULE_ENABLED */ - /* #define HAL_HASH_MODULE_ENABLED */ --/* #define HAL_I2C_MODULE_ENABLED */ -+#define HAL_I2C_MODULE_ENABLED - /* #define HAL_I2S_MODULE_ENABLED */ - /* #define HAL_IWDG_MODULE_ENABLED */ - /* #define HAL_LTDC_MODULE_ENABLED */ -diff --git a/Firmware/Board/v3/Src/i2c.c b/Firmware/Board/v3/Src/i2c.c -new file mode 100644 -index 0000000..bae77f1 ---- /dev/null -+++ b/Firmware/Board/v3/Src/i2c.c -@@ -0,0 +1,198 @@ -+/** -+ ****************************************************************************** -+ * File Name : I2C.c -+ * Description : This file provides code for the configuration -+ * of the I2C instances. -+ ****************************************************************************** -+ * This notice applies to any and all portions of this file -+ * that are not between comment pairs USER CODE BEGIN and -+ * USER CODE END. Other portions of this file, whether -+ * inserted by the user or by software development tools -+ * are owned by their respective copyright owners. -+ * -+ * Copyright (c) 2018 STMicroelectronics International N.V. -+ * All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted, provided that the following conditions are met: -+ * -+ * 1. Redistribution of source code must retain the above copyright notice, -+ * this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright notice, -+ * this list of conditions and the following disclaimer in the documentation -+ * and/or other materials provided with the distribution. -+ * 3. Neither the name of STMicroelectronics nor the names of other -+ * contributors to this software may be used to endorse or promote products -+ * derived from this software without specific written permission. -+ * 4. This software, including modifications and/or derivative works of this -+ * software, must execute solely and exclusively on microcontroller or -+ * microprocessor devices manufactured by or for STMicroelectronics. -+ * 5. Redistribution and use of this software other than as permitted under -+ * this license is void and will automatically terminate your rights under -+ * this license. -+ * -+ * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" -+ * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT -+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -+ * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY -+ * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT -+ * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, -+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ ****************************************************************************** -+ */ -+ -+/* Includes ------------------------------------------------------------------*/ -+#include "i2c.h" -+ -+#include "gpio.h" -+#include "dma.h" -+ -+/* USER CODE BEGIN 0 */ -+ -+/* USER CODE END 0 */ -+ -+I2C_HandleTypeDef hi2c1; -+DMA_HandleTypeDef hdma_i2c1_rx; -+DMA_HandleTypeDef hdma_i2c1_tx; -+ -+/* I2C1 init function */ -+void MX_I2C1_Init(uint8_t addr) -+{ -+ -+ hi2c1.Instance = I2C1; -+ hi2c1.Init.ClockSpeed = 100000; -+ hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; -+ hi2c1.Init.OwnAddress1 = addr << 1; -+ hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; -+ hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; -+ hi2c1.Init.OwnAddress2 = 0; -+ hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; -+ hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; -+ if (HAL_I2C_Init(&hi2c1) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+} -+ -+void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle) -+{ -+ -+ GPIO_InitTypeDef GPIO_InitStruct; -+ if(i2cHandle->Instance==I2C1) -+ { -+ /* USER CODE BEGIN I2C1_MspInit 0 */ -+ -+ /* USER CODE END I2C1_MspInit 0 */ -+ -+ /**I2C1 GPIO Configuration -+ PB8 ------> I2C1_SCL -+ PB9 ------> I2C1_SDA -+ */ -+ GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9; -+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; -+ GPIO_InitStruct.Pull = GPIO_PULLUP; -+ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; -+ GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; -+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); -+ -+ /* I2C1 clock enable */ -+ __HAL_RCC_I2C1_CLK_ENABLE(); -+ -+ /* I2C1 DMA Init */ -+ /* I2C1_RX Init */ -+ hdma_i2c1_rx.Instance = DMA1_Stream0; -+ hdma_i2c1_rx.Init.Channel = DMA_CHANNEL_1; -+ hdma_i2c1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; -+ hdma_i2c1_rx.Init.PeriphInc = DMA_PINC_DISABLE; -+ hdma_i2c1_rx.Init.MemInc = DMA_MINC_ENABLE; -+ hdma_i2c1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; -+ hdma_i2c1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; -+ hdma_i2c1_rx.Init.Mode = DMA_CIRCULAR; -+ hdma_i2c1_rx.Init.Priority = DMA_PRIORITY_LOW; -+ hdma_i2c1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; -+ if (HAL_DMA_Init(&hdma_i2c1_rx) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+ __HAL_LINKDMA(i2cHandle,hdmarx,hdma_i2c1_rx); -+ -+ /* I2C1_TX Init */ -+ hdma_i2c1_tx.Instance = DMA1_Stream6; -+ hdma_i2c1_tx.Init.Channel = DMA_CHANNEL_1; -+ hdma_i2c1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; -+ hdma_i2c1_tx.Init.PeriphInc = DMA_PINC_DISABLE; -+ hdma_i2c1_tx.Init.MemInc = DMA_MINC_ENABLE; -+ hdma_i2c1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; -+ hdma_i2c1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; -+ hdma_i2c1_tx.Init.Mode = DMA_NORMAL; -+ hdma_i2c1_tx.Init.Priority = DMA_PRIORITY_LOW; -+ hdma_i2c1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; -+ if (HAL_DMA_Init(&hdma_i2c1_tx) != HAL_OK) -+ { -+ _Error_Handler(__FILE__, __LINE__); -+ } -+ -+ __HAL_LINKDMA(i2cHandle,hdmatx,hdma_i2c1_tx); -+ -+ /* I2C1 interrupt Init */ -+ HAL_NVIC_SetPriority(I2C1_EV_IRQn, 5, 0); -+ HAL_NVIC_EnableIRQ(I2C1_EV_IRQn); -+ HAL_NVIC_SetPriority(I2C1_ER_IRQn, 5, 0); -+ HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); -+ /* USER CODE BEGIN I2C1_MspInit 1 */ -+ -+ /* USER CODE END I2C1_MspInit 1 */ -+ } -+} -+ -+void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle) -+{ -+ -+ if(i2cHandle->Instance==I2C1) -+ { -+ /* USER CODE BEGIN I2C1_MspDeInit 0 */ -+ -+ /* USER CODE END I2C1_MspDeInit 0 */ -+ /* Peripheral clock disable */ -+ __HAL_RCC_I2C1_CLK_DISABLE(); -+ -+ /**I2C1 GPIO Configuration -+ PB8 ------> I2C1_SCL -+ PB9 ------> I2C1_SDA -+ */ -+ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8|GPIO_PIN_9); -+ -+ /* I2C1 DMA DeInit */ -+ HAL_DMA_DeInit(i2cHandle->hdmarx); -+ HAL_DMA_DeInit(i2cHandle->hdmatx); -+ -+ /* I2C1 interrupt Deinit */ -+ HAL_NVIC_DisableIRQ(I2C1_EV_IRQn); -+ HAL_NVIC_DisableIRQ(I2C1_ER_IRQn); -+ /* USER CODE BEGIN I2C1_MspDeInit 1 */ -+ -+ /* USER CODE END I2C1_MspDeInit 1 */ -+ } -+} -+ -+/* USER CODE BEGIN 1 */ -+ -+/* USER CODE END 1 */ -+ -+/** -+ * @} -+ */ -+ -+/** -+ * @} -+ */ -+ -+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ -diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c -index 987e0bd..efaeef1 100644 ---- a/Firmware/Board/v3/Src/main.c -+++ b/Firmware/Board/v3/Src/main.c -@@ -187,7 +187,6 @@ int main(void) - MX_ADC3_Init(); - MX_TIM2_Init(); - MX_UART4_Init(); -- MX_CAN1_Init(); - /* USER CODE BEGIN 2 */ - - //Required to use OC4 for ADC triggering. --- -2.17.0 - diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h new file mode 100644 index 00000000..5452a507 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h @@ -0,0 +1,649 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c.h + * @author MCD Application Team + * @brief Header file of I2C HAL module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_I2C_H +#define __STM32F4xx_HAL_I2C_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2C + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Types I2C Exported Types + * @{ + */ + +/** + * @brief I2C Configuration Structure definition + */ +typedef struct +{ + uint32_t ClockSpeed; /*!< Specifies the clock frequency. + This parameter must be set to a value lower than 400kHz */ + + uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle. + This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */ + + uint32_t OwnAddress1; /*!< Specifies the first device own address. + This parameter can be a 7-bit or 10-bit address. */ + + uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected. + This parameter can be a value of @ref I2C_addressing_mode */ + + uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected. + This parameter can be a value of @ref I2C_dual_addressing_mode */ + + uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected + This parameter can be a 7-bit address. */ + + uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected. + This parameter can be a value of @ref I2C_general_call_addressing_mode */ + + uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected. + This parameter can be a value of @ref I2C_nostretch_mode */ + +}I2C_InitTypeDef; + +/** + * @brief HAL State structure definition + * @note HAL I2C State value coding follow below described bitmap : + * b7-b6 Error information + * 00 : No Error + * 01 : Abort (Abort user request on going) + * 10 : Timeout + * 11 : Error + * b5 IP initilisation status + * 0 : Reset (IP not initialized) + * 1 : Init done (IP initialized and ready to use. HAL I2C Init function called) + * b4 (not used) + * x : Should be set to 0 + * b3 + * 0 : Ready or Busy (No Listen mode ongoing) + * 1 : Listen (IP in Address Listen Mode) + * b2 Intrinsic process state + * 0 : Ready + * 1 : Busy (IP busy with some configuration or internal operations) + * b1 Rx state + * 0 : Ready (no Rx operation ongoing) + * 1 : Busy (Rx operation ongoing) + * b0 Tx state + * 0 : Ready (no Tx operation ongoing) + * 1 : Busy (Tx operation ongoing) + */ +typedef enum +{ + HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */ + HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */ + HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */ + HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */ + HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */ + HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */ + HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission + process is ongoing */ + HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception + process is ongoing */ + HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */ + HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */ + HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */ + +}HAL_I2C_StateTypeDef; + +/** + * @brief HAL Mode structure definition + * @note HAL I2C Mode value coding follow below described bitmap : + * b7 (not used) + * x : Should be set to 0 + * b6 + * 0 : None + * 1 : Memory (HAL I2C communication is in Memory Mode) + * b5 + * 0 : None + * 1 : Slave (HAL I2C communication is in Slave Mode) + * b4 + * 0 : None + * 1 : Master (HAL I2C communication is in Master Mode) + * b3-b2-b1-b0 (not used) + * xxxx : Should be set to 0000 + */ +typedef enum +{ + HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */ + HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */ + HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */ + HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */ + +}HAL_I2C_ModeTypeDef; + +/** + * @brief I2C handle Structure definition + */ +typedef struct +{ + I2C_TypeDef *Instance; /*!< I2C registers base address */ + + I2C_InitTypeDef Init; /*!< I2C communication parameters */ + + uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */ + + uint16_t XferSize; /*!< I2C transfer size */ + + __IO uint16_t XferCount; /*!< I2C transfer counter */ + + __IO uint32_t XferOptions; /*!< I2C transfer options */ + + __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode + context for internal usage */ + + DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */ + + DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */ + + HAL_LockTypeDef Lock; /*!< I2C locking object */ + + __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */ + + __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */ + + __IO uint32_t ErrorCode; /*!< I2C Error code */ + + __IO uint32_t Devaddress; /*!< I2C Target device address */ + + __IO uint32_t Memaddress; /*!< I2C Target memory address */ + + __IO uint32_t MemaddSize; /*!< I2C Target memory address size */ + + __IO uint32_t EventCount; /*!< I2C Event counter */ + +}I2C_HandleTypeDef; + +/** + * @} + */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2C_Error_Code I2C Error Code + * @brief I2C Error Code + * @{ + */ +#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */ +#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */ +#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */ +#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */ +#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */ +#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */ +#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */ +/** + * @} + */ + +/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode + * @{ + */ +#define I2C_DUTYCYCLE_2 0x00000000U +#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY +/** + * @} + */ + +/** @defgroup I2C_addressing_mode I2C addressing mode + * @{ + */ +#define I2C_ADDRESSINGMODE_7BIT 0x00004000U +#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U) +/** + * @} + */ + +/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode + * @{ + */ +#define I2C_DUALADDRESS_DISABLE 0x00000000U +#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL +/** + * @} + */ + +/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode + * @{ + */ +#define I2C_GENERALCALL_DISABLE 0x00000000U +#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC +/** + * @} + */ + +/** @defgroup I2C_nostretch_mode I2C nostretch mode + * @{ + */ +#define I2C_NOSTRETCH_DISABLE 0x00000000U +#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH +/** + * @} + */ + +/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size + * @{ + */ +#define I2C_MEMADD_SIZE_8BIT 0x00000001U +#define I2C_MEMADD_SIZE_16BIT 0x00000010U +/** + * @} + */ + +/** @defgroup I2C_XferDirection_definition I2C XferDirection definition + * @{ + */ +#define I2C_DIRECTION_RECEIVE 0x00000000U +#define I2C_DIRECTION_TRANSMIT 0x00000001U +/** + * @} + */ + +/** @defgroup I2C_XferOptions_definition I2C XferOptions definition + * @{ + */ +#define I2C_FIRST_FRAME 0x00000001U +#define I2C_NEXT_FRAME 0x00000002U +#define I2C_FIRST_AND_LAST_FRAME 0x00000004U +#define I2C_LAST_FRAME 0x00000008U +/** + * @} + */ + +/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition + * @{ + */ +#define I2C_IT_BUF I2C_CR2_ITBUFEN +#define I2C_IT_EVT I2C_CR2_ITEVTEN +#define I2C_IT_ERR I2C_CR2_ITERREN +/** + * @} + */ + +/** @defgroup I2C_Flag_definition I2C Flag definition + * @{ + */ +#define I2C_FLAG_SMBALERT 0x00018000U +#define I2C_FLAG_TIMEOUT 0x00014000U +#define I2C_FLAG_PECERR 0x00011000U +#define I2C_FLAG_OVR 0x00010800U +#define I2C_FLAG_AF 0x00010400U +#define I2C_FLAG_ARLO 0x00010200U +#define I2C_FLAG_BERR 0x00010100U +#define I2C_FLAG_TXE 0x00010080U +#define I2C_FLAG_RXNE 0x00010040U +#define I2C_FLAG_STOPF 0x00010010U +#define I2C_FLAG_ADD10 0x00010008U +#define I2C_FLAG_BTF 0x00010004U +#define I2C_FLAG_ADDR 0x00010002U +#define I2C_FLAG_SB 0x00010001U +#define I2C_FLAG_DUALF 0x00100080U +#define I2C_FLAG_SMBHOST 0x00100040U +#define I2C_FLAG_SMBDEFAULT 0x00100020U +#define I2C_FLAG_GENCALL 0x00100010U +#define I2C_FLAG_TRA 0x00100004U +#define I2C_FLAG_BUSY 0x00100002U +#define I2C_FLAG_MSL 0x00100001U +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup I2C_Exported_Macros I2C Exported Macros + * @{ + */ + +/** @brief Reset I2C handle state + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET) + +/** @brief Enable or disable the specified I2C interrupts. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __INTERRUPT__ specifies the interrupt source to enable or disable. + * This parameter can be one of the following values: + * @arg I2C_IT_BUF: Buffer interrupt enable + * @arg I2C_IT_EVT: Event interrupt enable + * @arg I2C_IT_ERR: Error interrupt enable + * @retval None + */ +#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 |= (__INTERRUPT__)) +#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->CR2 &= (~(__INTERRUPT__))) + +/** @brief Checks if the specified I2C interrupt source is enabled or disabled. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __INTERRUPT__ specifies the I2C interrupt source to check. + * This parameter can be one of the following values: + * @arg I2C_IT_BUF: Buffer interrupt enable + * @arg I2C_IT_EVT: Event interrupt enable + * @arg I2C_IT_ERR: Error interrupt enable + * @retval The new state of __INTERRUPT__ (TRUE or FALSE). + */ +#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Checks whether the specified I2C flag is set or not. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__ specifies the flag to check. + * This parameter can be one of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag + * @arg I2C_FLAG_BERR: Bus error flag + * @arg I2C_FLAG_TXE: Data register empty flag + * @arg I2C_FLAG_RXNE: Data register not empty flag + * @arg I2C_FLAG_STOPF: Stop detection flag + * @arg I2C_FLAG_ADD10: 10-bit header sent flag + * @arg I2C_FLAG_BTF: Byte transfer finished flag + * @arg I2C_FLAG_ADDR: Address sent flag + * Address matched flag + * @arg I2C_FLAG_SB: Start bit flag + * @arg I2C_FLAG_DUALF: Dual flag + * @arg I2C_FLAG_SMBHOST: SMBus host header + * @arg I2C_FLAG_SMBDEFAULT: SMBus default header + * @arg I2C_FLAG_GENCALL: General call header flag + * @arg I2C_FLAG_TRA: Transmitter/Receiver flag + * @arg I2C_FLAG_BUSY: Bus busy flag + * @arg I2C_FLAG_MSL: Master/Slave flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U)?((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)): \ + ((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK))) + +/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @param __FLAG__ specifies the flag to clear. + * This parameter can be any combination of the following values: + * @arg I2C_FLAG_SMBALERT: SMBus Alert flag + * @arg I2C_FLAG_TIMEOUT: Timeout or Tlow error flag + * @arg I2C_FLAG_PECERR: PEC error in reception flag + * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode) + * @arg I2C_FLAG_AF: Acknowledge failure flag + * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode) + * @arg I2C_FLAG_BERR: Bus error flag + * @retval None + */ +#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK)) + +/** @brief Clears the I2C ADDR pending flag. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg = 0x00U; \ + tmpreg = (__HANDLE__)->Instance->SR1; \ + tmpreg = (__HANDLE__)->Instance->SR2; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Clears the I2C STOPF pending flag. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \ + do{ \ + __IO uint32_t tmpreg = 0x00U; \ + tmpreg = (__HANDLE__)->Instance->SR1; \ + (__HANDLE__)->Instance->CR1 |= I2C_CR1_PE; \ + UNUSED(tmpreg); \ + } while(0) + +/** @brief Enable the I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= I2C_CR1_PE) + +/** @brief Disable the I2C peripheral. + * @param __HANDLE__ specifies the I2C Handle. + * This parameter can be I2Cx where x: 1 or 2 to select the I2C peripheral. + * @retval None + */ +#define __HAL_I2C_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 &= ~I2C_CR1_PE) + +/** + * @} + */ + +/* Include I2C HAL Extension module */ +#include "stm32f4xx_hal_i2c_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2C_Exported_Functions + * @{ + */ + +/** @addtogroup I2C_Exported_Functions_Group1 + * @{ + */ +/* Initialization/de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DeInit (I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group2 + * @{ + */ +/* I/O operation functions *****************************************************/ +/******* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout); +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout); + +/******* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions); +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress); +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c); +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c); + +/******* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size); + +/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); +void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c); +void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/** @addtogroup I2C_Exported_Functions_Group3 + * @{ + */ +/* Peripheral State, Mode and Errors functions *********************************/ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c); +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c); +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c); + +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Constants I2C Private Constants + * @{ + */ +#define I2C_FLAG_MASK 0x0000FFFFU +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2C_Private_Macros I2C Private Macros + * @{ + */ + +#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U) +#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U)) +#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) (((((__PCLK__)/((__SPEED__) << 1U)) & I2C_CCR_CCR) < 4U)? 4U:((__PCLK__) / ((__SPEED__) << 1U))) +#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? ((__PCLK__) / ((__SPEED__) * 3U)) : (((__PCLK__) / ((__SPEED__) * 25U)) | I2C_DUTYCYCLE_16_9)) +#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \ + ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \ + ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS)) + +#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (~I2C_OAR1_ADD0))) +#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0)) + +#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) +#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0))) +#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1)))) + +#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8))) +#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF))) + +/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters + * @{ + */ +#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \ + ((CYCLE) == I2C_DUTYCYCLE_16_9)) +#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \ + ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT)) +#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \ + ((ADDRESS) == I2C_DUALADDRESS_ENABLE)) +#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \ + ((CALL) == I2C_GENERALCALL_ENABLE)) +#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \ + ((STRETCH) == I2C_NOSTRETCH_ENABLE)) +#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \ + ((SIZE) == I2C_MEMADD_SIZE_16BIT)) +#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0U) && ((SPEED) <= 400000U)) +#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & 0xFFFFFC00U) == 0U) +#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & 0xFFFFFF01U) == 0U) +#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \ + ((REQUEST) == I2C_NEXT_FRAME) || \ + ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \ + ((REQUEST) == I2C_LAST_FRAME)) +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup I2C_Private_Functions I2C Private Functions + * @{ + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F4xx_HAL_I2C_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h new file mode 100644 index 00000000..ff47d5cc --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h @@ -0,0 +1,137 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c_ex.h + * @author MCD Application Team + * @brief Header file of I2C HAL Extension module. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_I2C_EX_H +#define __STM32F4xx_HAL_I2C_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal_def.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @addtogroup I2CEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Constants I2C Exported Constants + * @{ + */ + +/** @defgroup I2CEx_Analog_Filter I2C Analog Filter + * @{ + */ +#define I2C_ANALOGFILTER_ENABLE 0x00000000U +#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF +/** + * @} + */ + +/** + * @} + */ + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup I2CEx_Exported_Functions + * @{ + */ + +/** @addtogroup I2CEx_Exported_Functions_Group1 + * @{ + */ +/* Peripheral Control functions ************************************************/ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter); +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter); +/** + * @} + */ + +/** + * @} + */ +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private constants ---------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Constants I2C Private Constants + * @{ + */ + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup I2CEx_Private_Macros I2C Private Macros + * @{ + */ +#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \ + ((FILTER) == I2C_ANALOGFILTER_DISABLE)) +#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU) +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ + STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx ||\ + STM32F413xx || STM32F423xx */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_I2C_EX_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c new file mode 100644 index 00000000..da185200 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c @@ -0,0 +1,5494 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c.c + * @author MCD Application Team + * @brief I2C HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Inter Integrated Circuit (I2C) peripheral: + * + Initialization and de-initialization functions + * + IO operation functions + * + Peripheral State, Mode and Error functions + * + @verbatim + ============================================================================== + ##### How to use this driver ##### + ============================================================================== + [..] + The I2C HAL driver can be used as follows: + + (#) Declare a I2C_HandleTypeDef handle structure, for example: + I2C_HandleTypeDef hi2c; + + (#)Initialize the I2C low level resources by implementing the HAL_I2C_MspInit() API: + (##) Enable the I2Cx interface clock + (##) I2C pins configuration + (+++) Enable the clock for the I2C GPIOs + (+++) Configure I2C pins as alternate function open-drain + (##) NVIC configuration if you need to use interrupt process + (+++) Configure the I2Cx interrupt priority + (+++) Enable the NVIC I2C IRQ Channel + (##) DMA Configuration if you need to use DMA process + (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream + (+++) Enable the DMAx interface clock using + (+++) Configure the DMA handle parameters + (+++) Configure the DMA Tx or Rx Stream + (+++) Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle + (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on + the DMA Tx or Rx Stream + + (#) Configure the Communication Speed, Duty cycle, Addressing mode, Own Address1, + Dual Addressing mode, Own Address2, General call and Nostretch mode in the hi2c Init structure. + + (#) Initialize the I2C registers by calling the HAL_I2C_Init(), configures also the low level Hardware + (GPIO, CLOCK, NVIC...etc) by calling the customized HAL_I2C_MspInit(&hi2c) API. + + (#) To check if target device is ready for communication, use the function HAL_I2C_IsDeviceReady() + + (#) For I2C IO and IO MEM operations, three operation modes are available within this driver : + + *** Polling mode IO operation *** + ================================= + [..] + (+) Transmit in master mode an amount of data in blocking mode using HAL_I2C_Master_Transmit() + (+) Receive in master mode an amount of data in blocking mode using HAL_I2C_Master_Receive() + (+) Transmit in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Transmit() + (+) Receive in slave mode an amount of data in blocking mode using HAL_I2C_Slave_Receive() + + *** Polling mode IO MEM operation *** + ===================================== + [..] + (+) Write an amount of data in blocking mode to a specific memory address using HAL_I2C_Mem_Write() + (+) Read an amount of data in blocking mode from a specific memory address using HAL_I2C_Mem_Read() + + + *** Interrupt mode IO operation *** + =================================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode using HAL_I2C_Master_Transmit_IT() + (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode using HAL_I2C_Master_Receive_IT() + (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Transmit_IT() + (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode using HAL_I2C_Slave_Receive_IT() + (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + + *** Interrupt mode IO sequential operation *** + ============================================== + [..] + (@) These interfaces allow to manage a sequential transfer with a repeated start condition + when a direction change during transfer + [..] + (+) A specific option field manage the different steps of a sequential transfer + (+) Option field values are defined through @ref I2C_XFEROPTIONS and are listed below: + (++) I2C_FIRST_AND_LAST_FRAME: No sequential usage, functionnal is same as associated interfaces in no sequential mode + (++) I2C_FIRST_FRAME: Sequential usage, this option allow to manage a sequence with start condition, address + and data to transfer without a final stop condition + (++) I2C_NEXT_FRAME: Sequential usage, this option allow to manage a sequence with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to transfer + if no direction change and without a final stop condition in both cases + (++) I2C_LAST_FRAME: Sequential usage, this option allow to manage a sequance with a restart condition, address + and with new data to transfer if the direction change or manage only the new data to transfer + if no direction change and with a final stop condition in both cases + + (+) Differents sequential I2C interfaces are listed below: + (++) Sequential transmit in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Transmit_IT() + (+++) At transmission end of current frame transfer, HAL_I2C_MasterTxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback() + (++) Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_Master_Sequential_Receive_IT() + (+++) At reception end of current frame transfer, HAL_I2C_MasterRxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback() + (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + (++) Enable/disable the Address listen mode in slave I2C mode using HAL_I2C_EnableListen_IT() HAL_I2C_DisableListen_IT() + (+++) When address slave I2C match, HAL_I2C_AddrCallback() is executed and user can + add his own code to check the Address Match Code and the transmission direction request by master (Write/Read). + (+++) At Listen mode end HAL_I2C_ListenCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_ListenCpltCallback() + (++) Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Transmit_IT() + (+++) At transmission end of current frame transfer, HAL_I2C_SlaveTxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback() + (++) Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_Slave_Sequential_Receive_IT() + (+++) At reception end of current frame transfer, HAL_I2C_SlaveRxCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback() + (++) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback() + (++) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (++) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + + *** Interrupt mode IO MEM operation *** + ======================================= + [..] + (+) Write an amount of data in no-blocking mode with Interrupt to a specific memory address using + HAL_I2C_Mem_Write_IT() + (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with Interrupt from a specific memory address using + HAL_I2C_Mem_Read_IT() + (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + *** DMA mode IO operation *** + ============================== + [..] + (+) Transmit in master mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Master_Transmit_DMA() + (+) At transmission end of transfer HAL_I2C_MasterTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterTxCpltCallback + (+) Receive in master mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Master_Receive_DMA() + (+) At reception end of transfer HAL_I2C_MasterRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MasterRxCpltCallback + (+) Transmit in slave mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Slave_Transmit_DMA() + (+) At transmission end of transfer HAL_I2C_SlaveTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveTxCpltCallback + (+) Receive in slave mode an amount of data in non blocking mode (DMA) using + HAL_I2C_Slave_Receive_DMA() + (+) At reception end of transfer HAL_I2C_SlaveRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_SlaveRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + (+) Abort a master I2C process communication with Interrupt using HAL_I2C_Master_Abort_IT() + (+) End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can + add his own code by customization of function pointer HAL_I2C_AbortCpltCallback() + + *** DMA mode IO MEM operation *** + ================================= + [..] + (+) Write an amount of data in no-blocking mode with DMA to a specific memory address using + HAL_I2C_Mem_Write_DMA() + (+) At MEM end of write transfer HAL_I2C_MemTxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemTxCpltCallback + (+) Read an amount of data in no-blocking mode with DMA from a specific memory address using + HAL_I2C_Mem_Read_DMA() + (+) At MEM end of read transfer HAL_I2C_MemRxCpltCallback is executed and user can + add his own code by customization of function pointer HAL_I2C_MemRxCpltCallback + (+) In case of transfer Error, HAL_I2C_ErrorCallback() function is executed and user can + add his own code by customization of function pointer HAL_I2C_ErrorCallback + + + *** I2C HAL driver macros list *** + ================================== + [..] + Below the list of most used macros in I2C HAL driver. + + (+) __HAL_I2C_ENABLE: Enable the I2C peripheral + (+) __HAL_I2C_DISABLE: Disable the I2C peripheral + (+) __HAL_I2C_GET_FLAG : Checks whether the specified I2C flag is set or not + (+) __HAL_I2C_CLEAR_FLAG : Clear the specified I2C pending flag + (+) __HAL_I2C_ENABLE_IT: Enable the specified I2C interrupt + (+) __HAL_I2C_DISABLE_IT: Disable the specified I2C interrupt + + [..] + (@) You can refer to the I2C HAL driver header file for more useful macros + + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup I2C I2C + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @addtogroup I2C_Private_Define + * @{ + */ +#define I2C_TIMEOUT_FLAG 35U /*!< Timeout 35 ms */ +#define I2C_TIMEOUT_BUSY_FLAG 25U /*!< Timeout 25 ms */ +#define I2C_NO_OPTION_FRAME 0xFFFF0000U /*!< XferOptions default value */ + +/* Private define for @ref PreviousState usage */ +#define I2C_STATE_MSK ((uint32_t)((HAL_I2C_STATE_BUSY_TX | HAL_I2C_STATE_BUSY_RX) & (~(uint32_t)HAL_I2C_STATE_READY))) /*!< Mask State define, keep only RX and TX bits */ +#define I2C_STATE_NONE ((uint32_t)(HAL_I2C_MODE_NONE)) /*!< Default Value */ +#define I2C_STATE_MASTER_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_MASTER_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_MASTER)) /*!< Master Busy RX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_TX ((uint32_t)((HAL_I2C_STATE_BUSY_TX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy TX, combinaison of State LSB and Mode enum */ +#define I2C_STATE_SLAVE_BUSY_RX ((uint32_t)((HAL_I2C_STATE_BUSY_RX & I2C_STATE_MSK) | HAL_I2C_MODE_SLAVE)) /*!< Slave Busy RX, combinaison of State LSB and Mode enum */ + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup I2C_Private_Functions + * @{ + */ +/* Private functions to handle DMA transfer */ +static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma); +static void I2C_DMAError(DMA_HandleTypeDef *hdma); +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma); + +static void I2C_ITError(I2C_HandleTypeDef *hi2c); + +static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart); +static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c); + +/* Private functions for I2C transfer IRQ handler */ +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c); + +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c); +static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c); +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2C_Exported_Functions I2C Exported Functions + * @{ + */ + +/** @defgroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This subsection provides a set of functions allowing to initialize and + de-initialize the I2Cx peripheral: + + (+) User must Implement HAL_I2C_MspInit() function in which he configures + all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC). + + (+) Call the function HAL_I2C_Init() to configure the selected device with + the selected configuration: + (++) Communication Speed + (++) Duty cycle + (++) Addressing mode + (++) Own Address 1 + (++) Dual Addressing mode + (++) Own Address 2 + (++) General call mode + (++) Nostretch mode + + (+) Call the function HAL_I2C_DeInit() to restore the default configuration + of the selected I2Cx peripheral. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the I2C according to the specified parameters + * in the I2C_InitTypeDef and create the associated handle. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c) +{ + uint32_t freqrange = 0U; + uint32_t pclk1 = 0U; + + /* Check the I2C handle allocation */ + if(hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_CLOCK_SPEED(hi2c->Init.ClockSpeed)); + assert_param(IS_I2C_DUTY_CYCLE(hi2c->Init.DutyCycle)); + assert_param(IS_I2C_OWN_ADDRESS1(hi2c->Init.OwnAddress1)); + assert_param(IS_I2C_ADDRESSING_MODE(hi2c->Init.AddressingMode)); + assert_param(IS_I2C_DUAL_ADDRESS(hi2c->Init.DualAddressMode)); + assert_param(IS_I2C_OWN_ADDRESS2(hi2c->Init.OwnAddress2)); + assert_param(IS_I2C_GENERAL_CALL(hi2c->Init.GeneralCallMode)); + assert_param(IS_I2C_NO_STRETCH(hi2c->Init.NoStretchMode)); + + if(hi2c->State == HAL_I2C_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + hi2c->Lock = HAL_UNLOCKED; + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_I2C_MspInit(hi2c); + } + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get PCLK1 frequency */ + pclk1 = HAL_RCC_GetPCLK1Freq(); + + /* Calculate frequency range */ + freqrange = I2C_FREQRANGE(pclk1); + + /*---------------------------- I2Cx CR2 Configuration ----------------------*/ + /* Configure I2Cx: Frequency range */ + hi2c->Instance->CR2 = freqrange; + + /*---------------------------- I2Cx TRISE Configuration --------------------*/ + /* Configure I2Cx: Rise Time */ + hi2c->Instance->TRISE = I2C_RISE_TIME(freqrange, hi2c->Init.ClockSpeed); + + /*---------------------------- I2Cx CCR Configuration ----------------------*/ + /* Configure I2Cx: Speed */ + hi2c->Instance->CCR = I2C_SPEED(pclk1, hi2c->Init.ClockSpeed, hi2c->Init.DutyCycle); + + /*---------------------------- I2Cx CR1 Configuration ----------------------*/ + /* Configure I2Cx: Generalcall and NoStretch mode */ + hi2c->Instance->CR1 = (hi2c->Init.GeneralCallMode | hi2c->Init.NoStretchMode); + + /*---------------------------- I2Cx OAR1 Configuration ---------------------*/ + /* Configure I2Cx: Own Address1 and addressing mode */ + hi2c->Instance->OAR1 = (hi2c->Init.AddressingMode | hi2c->Init.OwnAddress1); + + /*---------------------------- I2Cx OAR2 Configuration ---------------------*/ + /* Configure I2Cx: Dual mode and Own Address2 */ + hi2c->Instance->OAR2 = (hi2c->Init.DualAddressMode | hi2c->Init.OwnAddress2); + + /* Enable the selected I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + return HAL_OK; +} + +/** + * @brief DeInitializes the I2C peripheral. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c) +{ + /* Check the I2C handle allocation */ + if(hi2c == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the I2C Peripheral Clock */ + __HAL_I2C_DISABLE(hi2c); + + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_I2C_MspDeInit(hi2c); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->State = HAL_I2C_STATE_RESET; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Release Lock */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; +} + +/** + * @brief I2C MSP Init. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_MspInit could be implemented in the user file + */ +} + +/** + * @brief I2C MSP DeInit + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval None + */ + __weak void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_I2C_MspDeInit could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group2 IO operation functions + * @brief Data transfers functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] + This subsection provides a set of functions allowing to manage the I2C data + transfers. + + (#) There are two modes of transfer: + (++) Blocking mode : The communication is performed in the polling mode. + The status of all data processing is returned by the same function + after finishing transfer. + (++) No-Blocking mode : The communication is performed using Interrupts + or DMA. These functions return the status of the transfer startup. + The end of the data processing will be indicated through the + dedicated I2C IRQ when using Interrupt mode or the DMA IRQ when + using DMA mode. + + (#) Blocking mode functions are : + (++) HAL_I2C_Master_Transmit() + (++) HAL_I2C_Master_Receive() + (++) HAL_I2C_Slave_Transmit() + (++) HAL_I2C_Slave_Receive() + (++) HAL_I2C_Mem_Write() + (++) HAL_I2C_Mem_Read() + (++) HAL_I2C_IsDeviceReady() + + (#) No-Blocking mode functions with Interrupt are : + (++) HAL_I2C_Master_Transmit_IT() + (++) HAL_I2C_Master_Receive_IT() + (++) HAL_I2C_Slave_Transmit_IT() + (++) HAL_I2C_Slave_Receive_IT() + (++) HAL_I2C_Master_Sequential_Transmit_IT() + (++) HAL_I2C_Master_Sequential_Receive_IT() + (++) HAL_I2C_Slave_Sequential_Transmit_IT() + (++) HAL_I2C_Slave_Sequential_Receive_IT() + (++) HAL_I2C_Mem_Write_IT() + (++) HAL_I2C_Mem_Read_IT() + + (#) No-Blocking mode functions with DMA are : + (++) HAL_I2C_Master_Transmit_DMA() + (++) HAL_I2C_Master_Receive_DMA() + (++) HAL_I2C_Slave_Transmit_DMA() + (++) HAL_I2C_Slave_Receive_DMA() + (++) HAL_I2C_Mem_Write_DMA() + (++) HAL_I2C_Mem_Read_DMA() + + (#) A set of Transfer Complete Callbacks are provided in non Blocking mode: + (++) HAL_I2C_MemTxCpltCallback() + (++) HAL_I2C_MemRxCpltCallback() + (++) HAL_I2C_MasterTxCpltCallback() + (++) HAL_I2C_MasterRxCpltCallback() + (++) HAL_I2C_SlaveTxCpltCallback() + (++) HAL_I2C_SlaveRxCpltCallback() + (++) HAL_I2C_ErrorCallback() + (++) HAL_I2C_AbortCpltCallback() + +@endverbatim + * @{ + */ + +/** + * @brief Transmits in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if(I2C_MasterRequestWrite(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + while(hi2c->XferSize > 0U) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + } + + /* Wait until BTF flag is set */ + if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receives in master mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address */ + if(I2C_MasterRequestRead(hi2c, DevAddress, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferSize == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 2U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(hi2c->XferSize > 0U) + { + if(hi2c->XferSize <= 3U) + { + /* One byte */ + if(hi2c->XferSize == 1U) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* Two bytes */ + else if(hi2c->XferSize == 2U) + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* 3 Last bytes */ + else + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmits in slave mode an amount of data in blocking mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* If 10bit addressing mode is selected */ + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT) + { + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(hi2c->XferSize > 0U) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + hi2c->XferSize--; + } + } + + /* Wait until AF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_AF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in blocking mode + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + while(hi2c->XferSize > 0U) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (Size != 0U)) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + + /* Wait until STOP flag is set */ + if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear STOP flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in master mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + __IO uint32_t Prev_State = 0x00U; + __IO uint32_t count = 0x00U; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Check Busy Flag only if FIRST call of Master interface */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + Prev_State = hi2c->PreviousState; + + /* Generate Start */ + if((Prev_State == I2C_STATE_MASTER_BUSY_RX) || (Prev_State == I2C_STATE_NONE)) + { + /* Generate Start condition if first transfer */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential receive in master mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + __IO uint32_t count = 0U; + + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Check Busy Flag only if FIRST call of Master interface */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME)) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if((hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) || (hi2c->PreviousState == I2C_STATE_NONE)) + { + /* Generate Start condition if first transfer */ + if((XferOptions == I2C_FIRST_AND_LAST_FRAME) || (XferOptions == I2C_FIRST_FRAME) || (XferOptions == I2C_NO_OPTION_FRAME)) + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + } + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with Interrupt + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential transmit in slave mode an amount of data in no-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_LISTEN) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Sequential receive in slave mode an amount of data in non-blocking mode with Interrupt + * @note This interface allow to manage repeated start condition when a direction change during transfer + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param XferOptions Options of Transfer, value of @ref I2C_XferOptions_definition + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Sequential_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions) +{ + /* Check the parameters */ + assert_param(IS_I2C_TRANSFER_OPTIONS_REQUEST(XferOptions)); + + if(hi2c->State == HAL_I2C_STATE_LISTEN) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX_LISTEN; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = XferOptions; + hi2c->XferSize = hi2c->XferCount; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Enable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_LISTEN; + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Disable the Address listen mode with Interrupt. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of tmp to prevent undefined behavior of volatile usage */ + uint32_t tmp; + + /* Disable Address listen mode only if a transfer is not ongoing */ + if(hi2c->State == HAL_I2C_STATE_LISTEN) + { + tmp = (uint32_t)(hi2c->State) & I2C_STATE_MSK; + hi2c->PreviousState = tmp | (uint32_t)(hi2c->Mode); + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Disable Address Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Disable EVT and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Transmit in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferM1CpltCallback = NULL; + hi2c->hdmatx->XferM1HalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in master mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MASTER; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + hi2c->Devaddress = DevAddress; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferM1CpltCallback = NULL; + hi2c->hdmarx->XferM1HalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Abort a master I2C process communication with Interrupt. + * @note This abort can be called only if state is ready + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(DevAddress); + + /* Abort Master transfer during Receive or Transmit process */ + if(hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Process Locked */ + __HAL_LOCK(hi2c); + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_ABORT; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->XferCount = 0U; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c); + + return HAL_OK; + } + else + { + /* Wrong usage of abort function */ + /* This function should be used only in case of abort monitored by master device */ + return HAL_ERROR; + } +} + +/** + * @brief Transmit in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferM1CpltCallback = NULL; + hi2c->hdmatx->XferM1HalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Receive in slave mode an amount of data in non-blocking mode with DMA + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + if(hi2c->State == HAL_I2C_STATE_READY) + { + if((pData == NULL) || (Size == 0U)) + { + return HAL_ERROR; + } + + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_SLAVE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferM1CpltCallback = NULL; + hi2c->hdmarx->XferM1HalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Enable Address Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} +/** + * @brief Write an amount of data in blocking mode to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + while(hi2c->XferSize > 0U) + { + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferSize--; + hi2c->XferCount--; + + if((__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) && (hi2c->XferSize != 0U)) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferSize--; + hi2c->XferCount--; + } + } + + /* Wait until BTF flag is set */ + if(I2C_WaitOnBTFFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in blocking mode from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout) +{ + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(hi2c->XferSize == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferSize == 2U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + while(hi2c->XferSize > 0U) + { + if(hi2c->XferSize <= 3U) + { + /* One byte */ + if(hi2c->XferSize== 1U) + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* Two bytes */ + else if(hi2c->XferSize == 2U) + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + /* 3 Last bytes */ + else + { + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Wait until BTF flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BTF, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + else + { + /* Wait until RXNE flag is set */ + if(I2C_WaitOnRXNEFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_TIMEOUT) + { + return HAL_TIMEOUT; + } + else + { + return HAL_ERROR; + } + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferSize--; + hi2c->XferCount--; + } + } + } + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Write an amount of data in non-blocking mode with Interrupt to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->Devaddress = DevAddress; + hi2c->Memaddress = MemAddress; + hi2c->MemaddSize = MemAddSize; + hi2c->EventCount = 0U; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Read an amount of data in non-blocking mode with Interrupt from a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->Devaddress = DevAddress; + hi2c->Memaddress = MemAddress; + hi2c->MemaddSize = MemAddSize; + hi2c->EventCount = 0U; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + if(hi2c->XferSize > 0U) + { + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + + /* Enable EVT, BUF and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Write an amount of data in non-blocking mode with DMA to a specific memory address + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be sent + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + __IO uint32_t count = 0U; + + uint32_t tickstart = 0x00U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferSize = Size; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmatx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmatx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmatx->XferHalfCpltCallback = NULL; + hi2c->hdmatx->XferM1CpltCallback = NULL; + hi2c->hdmatx->XferM1HalfCpltCallback = NULL; + hi2c->hdmatx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmatx, (uint32_t)hi2c->pBuffPtr, (uint32_t)&hi2c->Instance->DR, hi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryWrite(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Reads an amount of data in non-blocking mode with DMA from a specific memory address. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param pData Pointer to data buffer + * @param Size Amount of data to be read + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size) +{ + uint32_t tickstart = 0x00U; + __IO uint32_t count = 0U; + + /* Init tickstart for timeout management*/ + tickstart = HAL_GetTick(); + + /* Check the parameters */ + assert_param(IS_I2C_MEMADD_SIZE(MemAddSize)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + count = I2C_TIMEOUT_BUSY_FLAG * (SystemCoreClock /25U /1000U); + do + { + if(count-- == 0U) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) != RESET); + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY_RX; + hi2c->Mode = HAL_I2C_MODE_MEM; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Prepare transfer parameters */ + hi2c->pBuffPtr = pData; + hi2c->XferCount = Size; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->XferSize = hi2c->XferCount; + + if(hi2c->XferSize > 0U) + { + /* Set the I2C DMA transfer complete callback */ + hi2c->hdmarx->XferCpltCallback = I2C_DMAXferCplt; + + /* Set the DMA error callback */ + hi2c->hdmarx->XferErrorCallback = I2C_DMAError; + + /* Set the unused DMA callbacks to NULL */ + hi2c->hdmarx->XferHalfCpltCallback = NULL; + hi2c->hdmarx->XferM1CpltCallback = NULL; + hi2c->hdmarx->XferM1HalfCpltCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Enable the DMA Stream */ + HAL_DMA_Start_IT(hi2c->hdmarx, (uint32_t)&hi2c->Instance->DR, (uint32_t)hi2c->pBuffPtr, hi2c->XferSize); + + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + if(Size == 1U) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + /* Note : The I2C interrupts must be enabled after unlocking current process + to avoid the risk of I2C interrupt handle execution before current + process unlock */ + /* Enable ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_ERR); + + /* Enable DMA Request */ + hi2c->Instance->CR2 |= I2C_CR2_DMAEN; + } + else + { + /* Send Slave Address and Memory Address */ + if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, I2C_TIMEOUT_FLAG, tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_ERROR; + } + else + { + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + } + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Checks if target device is ready for communication. + * @note This function is used with Memory devices + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param DevAddress Target device address + * @param Trials Number of trials + * @param Timeout Timeout duration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout) +{ + uint32_t tickstart = 0U, tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, I2C_Trials = 1U; + + /* Get tick */ + tickstart = HAL_GetTick(); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_BUSY; + } + + /* Process Locked */ + __HAL_LOCK(hi2c); + + /* Check if the I2C is already enabled */ + if((hi2c->Instance->CR1 & I2C_CR1_PE) != I2C_CR1_PE) + { + /* Enable I2C peripheral */ + __HAL_I2C_ENABLE(hi2c); + } + + /* Disable Pos */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + hi2c->State = HAL_I2C_STATE_BUSY; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + do + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR or AF flag are set */ + /* Get tick */ + tickstart = HAL_GetTick(); + + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp3 = hi2c->State; + while((tmp1 == RESET) && (tmp2 == RESET) && (tmp3 != HAL_I2C_STATE_TIMEOUT)) + { + if((Timeout == 0U)||((HAL_GetTick() - tickstart ) > Timeout)) + { + hi2c->State = HAL_I2C_STATE_TIMEOUT; + } + tmp1 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR); + tmp2 = __HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF); + tmp3 = hi2c->State; + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Check if the ADDR flag has been set */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_ADDR) == SET) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear ADDR Flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_OK; + } + else + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Wait until BUSY flag is reset */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + } + }while(I2C_Trials++ < Trials); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief This function handles I2C event interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t sr2itflags = READ_REG(hi2c->Instance->SR2); + uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); + uint32_t itsources = READ_REG(hi2c->Instance->CR2); + + uint32_t CurrentMode = hi2c->Mode; + + /* Master or Memory mode selected */ + if((CurrentMode == HAL_I2C_MODE_MASTER) || (CurrentMode == HAL_I2C_MODE_MEM)) + { + /* SB Set ----------------------------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_SB) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_SB(hi2c); + } + /* ADD10 Set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_ADD10) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_ADD10(hi2c); + } + /* ADDR Set --------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Master_ADDR(hi2c); + } + + /* I2C in mode Transmitter -----------------------------------------------*/ + if((sr2itflags & I2C_FLAG_TRA) != RESET) + { + /* TXE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_MasterTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_MasterTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + /* RXNE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_MasterReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_MasterReceive_BTF(hi2c); + } + } + } + /* Slave mode selected */ + else + { + /* ADDR set --------------------------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_ADDR) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Slave_ADDR(hi2c); + } + /* STOPF set --------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_STOPF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_Slave_STOPF(hi2c); + } + /* I2C in mode Transmitter -----------------------------------------------*/ + else if((sr2itflags & I2C_FLAG_TRA) != RESET) + { + /* TXE set and BTF reset -----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_TXE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_SlaveTransmit_TXE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_SlaveTransmit_BTF(hi2c); + } + } + /* I2C in mode Receiver --------------------------------------------------*/ + else + { + /* RXNE set and BTF reset ----------------------------------------------*/ + if(((sr1itflags & I2C_FLAG_RXNE) != RESET) && ((itsources & I2C_IT_BUF) != RESET) && ((sr1itflags & I2C_FLAG_BTF) == RESET)) + { + I2C_SlaveReceive_RXNE(hi2c); + } + /* BTF set -------------------------------------------------------------*/ + else if(((sr1itflags & I2C_FLAG_BTF) != RESET) && ((itsources & I2C_IT_EVT) != RESET)) + { + I2C_SlaveReceive_BTF(hi2c); + } + } + } +} + +/** + * @brief This function handles I2C error interrupt request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c) +{ + uint32_t tmp1 = 0U, tmp2 = 0U, tmp3 = 0U, tmp4 = 0U; + uint32_t sr1itflags = READ_REG(hi2c->Instance->SR1); + uint32_t itsources = READ_REG(hi2c->Instance->CR2); + + /* I2C Bus error interrupt occurred ----------------------------------------*/ + if(((sr1itflags & I2C_FLAG_BERR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_BERR; + + /* Clear BERR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_BERR); + } + + /* I2C Arbitration Loss error interrupt occurred ---------------------------*/ + if(((sr1itflags & I2C_FLAG_ARLO) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_ARLO; + + /* Clear ARLO flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_ARLO); + } + + /* I2C Acknowledge failure error interrupt occurred ------------------------*/ + if(((sr1itflags & I2C_FLAG_AF) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + tmp1 = hi2c->Mode; + tmp2 = hi2c->XferCount; + tmp3 = hi2c->State; + tmp4 = hi2c->PreviousState; + if((tmp1 == HAL_I2C_MODE_SLAVE) && (tmp2 == 0U) && \ + ((tmp3 == HAL_I2C_STATE_BUSY_TX) || (tmp3 == HAL_I2C_STATE_BUSY_TX_LISTEN) || \ + ((tmp3 == HAL_I2C_STATE_LISTEN) && (tmp4 == I2C_STATE_SLAVE_BUSY_TX)))) + { + I2C_Slave_AF(hi2c); + } + else + { + hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + + /* Do not generate a STOP in case of Slave receive non acknowledge during transfer (mean not at the end of transfer) */ + if(hi2c->Mode == HAL_I2C_MODE_MASTER) + { + /* Generate Stop */ + SET_BIT(hi2c->Instance->CR1,I2C_CR1_STOP); + } + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + } + + /* I2C Over-Run/Under-Run interrupt occurred -------------------------------*/ + if(((sr1itflags & I2C_FLAG_OVR) != RESET) && ((itsources & I2C_IT_ERR) != RESET)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_OVR; + /* Clear OVR flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_OVR); + } + + /* Call the Error Callback in case of Error detected -----------------------*/ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + I2C_ITError(hi2c); + } +} + +/** + * @brief Master Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterTxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Master Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MasterRxCpltCallback can be implemented in the user file + */ +} + +/** @brief Slave Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveTxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Slave Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_SlaveRxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Slave Address Match callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param TransferDirection Master request Transfer Direction (Write/Read), value of @ref I2C_XferOptions_definition + * @param AddrMatchCode Address Match Code + * @retval None + */ +__weak void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + UNUSED(TransferDirection); + UNUSED(AddrMatchCode); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AddrCallback can be implemented in the user file + */ +} + +/** + * @brief Listen Complete callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ListenCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Memory Tx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemTxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief Memory Rx Transfer completed callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_MemRxCpltCallback can be implemented in the user file + */ +} + +/** + * @brief I2C error callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_ErrorCallback can be implemented in the user file + */ +} + +/** + * @brief I2C abort callback. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval None + */ +__weak void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hi2c); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_I2C_AbortCpltCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions + * @brief Peripheral State and Errors functions + * +@verbatim + =============================================================================== + ##### Peripheral State, Mode and Error functions ##### + =============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the I2C handle state. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL state + */ +HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c) +{ + /* Return I2C handle state */ + return hi2c->State; +} + +/** + * @brief Return the I2C Master, Slave, Memory or no mode. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL mode + */ +HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c) +{ + return hi2c->Mode; +} + +/** + * @brief Return the I2C error code + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval I2C Error Code + */ +uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c) +{ + return hi2c->ErrorCode; +} + +/** + * @} + */ + +/** + * @brief Handle TXE flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t CurrentMode = hi2c->Mode; + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if((hi2c->XferSize == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX)) + { + /* Call TxCpltCallback() directly if no stop mode is set */ + if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) + { + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + else /* Generate Stop condition then Call TxCpltCallback() */ + { + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MemTxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MasterTxCpltCallback(hi2c); + } + } + } + else if((CurrentState == HAL_I2C_STATE_BUSY_TX) || \ + ((CurrentMode == HAL_I2C_MODE_MEM) && (CurrentState == HAL_I2C_STATE_BUSY_RX))) + { + if(hi2c->XferCount == 0U) + { + /* Disable BUF interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + } + else + { + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + if(hi2c->EventCount == 0) + { + /* If Memory address size is 8Bit */ + if(hi2c->MemaddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); + + hi2c->EventCount += 2; + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(hi2c->Memaddress); + + hi2c->EventCount++; + } + } + else if(hi2c->EventCount == 1) + { + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(hi2c->Memaddress); + + hi2c->EventCount++; + } + else if(hi2c->EventCount == 2) + { + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + } + } + else + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master transmitter + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterTransmit_BTF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + else + { + /* Call TxCpltCallback() directly if no stop mode is set */ + if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) && (CurrentXferOptions != I2C_NO_OPTION_FRAME)) + { + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + hi2c->PreviousState = I2C_STATE_MASTER_BUSY_TX; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + else /* Generate Stop condition then Call TxCpltCallback() */ + { + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemTxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterTxCpltCallback(hi2c); + } + } + } + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + uint32_t tmp = 0U; + + tmp = hi2c->XferCount; + if(tmp > 3U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + if(hi2c->XferCount == 3) + { + /* Disable BUF interrupt, this help to treat correctly the last 4 bytes + on BTF subroutine */ + /* Disable BUF interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + } + } + else if((tmp == 1U) || (tmp == 0U)) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Master receiver + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterReceive_BTF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if(hi2c->XferCount == 4U) + { + /* Disable BUF interrupt, this help to treat correctly the last 2 bytes + on BTF subroutine if there is a reception delay between N-1 and N byte */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + else if(hi2c->XferCount == 3U) + { + /* Disable BUF interrupt, this help to treat correctly the last 2 bytes + on BTF subroutine if there is a reception delay between N-1 and N byte */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + else if(hi2c->XferCount == 2U) + { + /* Prepare next transfer or stop current transfer */ + if((CurrentXferOptions == I2C_NEXT_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME)) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + /* Disable EVT and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->PreviousState = I2C_STATE_NONE; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + else + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle SB flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_SB(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + if(hi2c->EventCount == 0U) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); + } + else + { + hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); + } + } + else + { + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave 7 Bits address */ + if(hi2c->State == HAL_I2C_STATE_BUSY_TX) + { + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(hi2c->Devaddress); + } + else + { + hi2c->Instance->DR = I2C_7BIT_ADD_READ(hi2c->Devaddress); + } + } + else + { + if(hi2c->EventCount == 0U) + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(hi2c->Devaddress); + } + else if(hi2c->EventCount == 1U) + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_READ(hi2c->Devaddress); + } + } + } + + return HAL_OK; +} + +/** + * @brief Handle ADD10 flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ADD10(I2C_HandleTypeDef *hi2c) +{ + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(hi2c->Devaddress); + + return HAL_OK; +} + +/** + * @brief Handle ADDR flag for Master + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Master_ADDR(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentMode = hi2c->Mode; + uint32_t CurrentXferOptions = hi2c->XferOptions; + uint32_t Prev_State = hi2c->PreviousState; + + if(hi2c->State == HAL_I2C_STATE_BUSY_RX) + { + if((hi2c->EventCount == 0U) && (CurrentMode == HAL_I2C_MODE_MEM)) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else if((hi2c->EventCount == 0U) && (hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_10BIT)) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + hi2c->EventCount++; + } + else + { + if(hi2c->XferCount == 0U) + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + else if(hi2c->XferCount == 1U) + { + if(CurrentXferOptions == I2C_NO_OPTION_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + } + /* Prepare next transfer or stop current transfer */ + else if((CurrentXferOptions != I2C_FIRST_AND_LAST_FRAME) && (CurrentXferOptions != I2C_LAST_FRAME) \ + && (Prev_State != I2C_STATE_MASTER_BUSY_RX)) + { + if(hi2c->XferOptions != I2C_NEXT_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + } + } + else if(hi2c->XferCount == 2U) + { + if(hi2c->XferOptions != I2C_NEXT_FRAME) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Enable Pos */ + hi2c->Instance->CR1 |= I2C_CR1_POS; + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + } + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + else + { + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + /* Enable Last DMA bit */ + hi2c->Instance->CR2 |= I2C_CR2_LAST; + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + /* Reset Event counter */ + hi2c->EventCount = 0U; + } + } + else + { + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + } + + return HAL_OK; +} + +/** + * @brief Handle TXE flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_TXE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + + if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) + { + /* Last Byte is received, disable Interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Set state at HAL_I2C_STATE_LISTEN */ + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + hi2c->State = HAL_I2C_STATE_LISTEN; + + /* Call the Tx complete callback to inform upper layer of the end of receive process */ + HAL_I2C_SlaveTxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave transmitter + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveTransmit_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0U) + { + /* Write data to DR */ + hi2c->Instance->DR = (*hi2c->pBuffPtr++); + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle RXNE flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_RXNE(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if(hi2c->XferCount != 0U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + + if((hi2c->XferCount == 0U) && (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + /* Last Byte is received, disable Interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_BUF); + + /* Set state at HAL_I2C_STATE_LISTEN */ + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_RX; + hi2c->State = HAL_I2C_STATE_LISTEN; + + /* Call the Rx complete callback to inform upper layer of the end of receive process */ + HAL_I2C_SlaveRxCpltCallback(hi2c); + } + } + return HAL_OK; +} + +/** + * @brief Handle BTF flag for Slave receiver + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_SlaveReceive_BTF(I2C_HandleTypeDef *hi2c) +{ + if(hi2c->XferCount != 0U) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + return HAL_OK; +} + +/** + * @brief Handle ADD flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_ADDR(I2C_HandleTypeDef *hi2c) +{ + uint8_t TransferDirection = I2C_DIRECTION_RECEIVE; + uint16_t SlaveAddrCode = 0U; + + /* Transfer Direction requested by Master */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TRA) == RESET) + { + TransferDirection = I2C_DIRECTION_TRANSMIT; + } + + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_DUALF) == RESET) + { + SlaveAddrCode = hi2c->Init.OwnAddress1; + } + else + { + SlaveAddrCode = hi2c->Init.OwnAddress2; + } + + /* Call Slave Addr callback */ + HAL_I2C_AddrCallback(hi2c, TransferDirection, SlaveAddrCode); + + return HAL_OK; +} + +/** + * @brief Handle STOPF flag for Slave + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_STOPF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear STOPF flag */ + __HAL_I2C_CLEAR_STOPFLAG(hi2c); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* If a DMA is ongoing, Update handle size context */ + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + if((hi2c->State == HAL_I2C_STATE_BUSY_RX) || (hi2c->State == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmarx); + } + else + { + hi2c->XferCount = __HAL_DMA_GET_COUNTER(hi2c->hdmatx); + } + } + + /* All data are not transferred, so set error code accordingly */ + if(hi2c->XferCount != 0U) + { + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + hi2c->XferCount--; + } + + /* Set ErrorCode corresponding to a Non-Acknowledge */ + //hi2c->ErrorCode |= HAL_I2C_ERROR_AF; + } + + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + /* Call the corresponding callback to inform upper layer of End of Transfer */ + I2C_ITError(hi2c); + } + else + { + if((CurrentState == HAL_I2C_STATE_LISTEN ) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN) || \ + (CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN)) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + HAL_I2C_ListenCpltCallback(hi2c); + } + else + { + if((hi2c->PreviousState == I2C_STATE_SLAVE_BUSY_RX) || (CurrentState == HAL_I2C_STATE_BUSY_RX)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_SlaveRxCpltCallback(hi2c); + } + } + } + return HAL_OK; +} + +/** + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_Slave_AF(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variables to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t CurrentXferOptions = hi2c->XferOptions; + + if(((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_LAST_FRAME)) && \ + (CurrentState == HAL_I2C_STATE_LISTEN)) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + HAL_I2C_ListenCpltCallback(hi2c); + } + else if(CurrentState == HAL_I2C_STATE_BUSY_TX) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_SLAVE_BUSY_TX; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Disable EVT, BUF and ERR interrupt */ + __HAL_I2C_DISABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_BUF | I2C_IT_ERR); + + /* Clear AF flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + HAL_I2C_SlaveTxCpltCallback(hi2c); + } + else + { + /* Clear AF flag only */ + /* State Listen, but XferOptions == FIRST or NEXT */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + } + + return HAL_OK; +} + +/** + * @brief I2C interrupts error process + * @param hi2c I2C handle. + * @retval None + */ +static void I2C_ITError(I2C_HandleTypeDef *hi2c) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + + if((CurrentState == HAL_I2C_STATE_BUSY_TX_LISTEN) || (CurrentState == HAL_I2C_STATE_BUSY_RX_LISTEN)) + { + /* keep HAL_I2C_STATE_LISTEN */ + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_LISTEN; + } + else + { + /* If state is an abort treatment on going, don't change state */ + /* This change will be do later */ + if((hi2c->State != HAL_I2C_STATE_ABORT) && ((hi2c->Instance->CR2 & I2C_CR2_DMAEN) != I2C_CR2_DMAEN)) + { + hi2c->State = HAL_I2C_STATE_READY; + } + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->Mode = HAL_I2C_MODE_NONE; + } + + /* Disable Pos bit in I2C CR1 when error occurred in Master/Mem Receive IT Process */ + hi2c->Instance->CR1 &= ~I2C_CR1_POS; + + /* Abort DMA transfer */ + if((hi2c->Instance->CR2 & I2C_CR2_DMAEN) == I2C_CR2_DMAEN) + { + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + if(hi2c->hdmatx->State != HAL_DMA_STATE_READY) + { + /* Set the DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmatx->XferAbortCallback = I2C_DMAAbort; + + if(HAL_DMA_Abort_IT(hi2c->hdmatx) != HAL_OK) + { + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Call Directly XferAbortCallback function in case of error */ + hi2c->hdmatx->XferAbortCallback(hi2c->hdmatx); + } + } + else + { + /* Set the DMA Abort callback : + will lead to call HAL_I2C_ErrorCallback() at end of DMA abort procedure */ + hi2c->hdmarx->XferAbortCallback = I2C_DMAAbort; + + if(HAL_DMA_Abort_IT(hi2c->hdmarx) != HAL_OK) + { + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + } + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + /* Call Directly hi2c->hdmarx->XferAbortCallback function in case of error */ + hi2c->hdmarx->XferAbortCallback(hi2c->hdmarx); + } + } + } + else if(hi2c->State == HAL_I2C_STATE_ABORT) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + } + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + HAL_I2C_AbortCpltCallback(hi2c); + } + else + { + /* Store Last receive data if any */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == SET) + { + /* Read data from DR */ + (*hi2c->pBuffPtr++) = hi2c->Instance->DR; + } + + /* Call user error callback */ + HAL_I2C_ErrorCallback(hi2c); + } + /* STOP Flag is not set after a NACK reception */ + /* So may inform upper layer that listen phase is stopped */ + /* during NACK error treatment */ + if((hi2c->State == HAL_I2C_STATE_LISTEN) && ((hi2c->ErrorCode & HAL_I2C_ERROR_AF) == HAL_I2C_ERROR_AF)) + { + hi2c->XferOptions = I2C_NO_OPTION_FRAME; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Call the Listen Complete callback, to inform upper layer of the end of Listen usecase */ + HAL_I2C_ListenCpltCallback(hi2c); + } +} + +/** + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterRequestWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + /* Generate Start condition if first transfer */ + if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_RX) + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + } + else + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + } + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address for read request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address The device 7 bits address value + * in datasheet must be shifted to the left before calling the interface + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_MasterRequestRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Timeout, uint32_t Tickstart) +{ + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentXferOptions = hi2c->XferOptions; + + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start condition if first transfer */ + if((CurrentXferOptions == I2C_FIRST_AND_LAST_FRAME) || (CurrentXferOptions == I2C_FIRST_FRAME) || (CurrentXferOptions == I2C_NO_OPTION_FRAME)) + { + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + else if(hi2c->PreviousState == I2C_STATE_MASTER_BUSY_TX) + { + /* Generate ReStart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + } + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + if(hi2c->Init.AddressingMode == I2C_ADDRESSINGMODE_7BIT) + { + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); + } + else + { + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_WRITE(DevAddress); + + /* Wait until ADD10 flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADD10, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_10BIT_ADDRESS(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send header of slave address */ + hi2c->Instance->DR = I2C_10BIT_HEADER_READ(DevAddress); + } + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for write request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryWrite(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) +{ + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + + return HAL_OK; +} + +/** + * @brief Master sends target device address followed by internal memory address for read request. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param DevAddress Target device address + * @param MemAddress Internal memory address + * @param MemAddSize Size of internal memory address + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_RequestMemoryRead(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint32_t Timeout, uint32_t Tickstart) +{ + /* Enable Acknowledge */ + hi2c->Instance->CR1 |= I2C_CR1_ACK; + + /* Generate Start */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_WRITE(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Clear ADDR flag */ + __HAL_I2C_CLEAR_ADDRFLAG(hi2c); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* If Memory address size is 8Bit */ + if(MemAddSize == I2C_MEMADD_SIZE_8BIT) + { + /* Send Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + /* If Memory address size is 16Bit */ + else + { + /* Send MSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_MSB(MemAddress); + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Send LSB of Memory Address */ + hi2c->Instance->DR = I2C_MEM_ADD_LSB(MemAddress); + } + + /* Wait until TXE flag is set */ + if(I2C_WaitOnTXEFlagUntilTimeout(hi2c, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + /* Generate Restart */ + hi2c->Instance->CR1 |= I2C_CR1_START; + + /* Wait until SB flag is set */ + if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_SB, RESET, Timeout, Tickstart) != HAL_OK) + { + return HAL_TIMEOUT; + } + + /* Send slave address */ + hi2c->Instance->DR = I2C_7BIT_ADD_READ(DevAddress); + + /* Wait until ADDR flag is set */ + if(I2C_WaitOnMasterAddressFlagUntilTimeout(hi2c, I2C_FLAG_ADDR, Timeout, Tickstart) != HAL_OK) + { + if(hi2c->ErrorCode == HAL_I2C_ERROR_AF) + { + return HAL_ERROR; + } + else + { + return HAL_TIMEOUT; + } + } + + return HAL_OK; +} + +/** + * @brief DMA I2C process complete callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAXferCplt(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Declaration of temporary variable to prevent undefined behavior of volatile usage */ + uint32_t CurrentState = hi2c->State; + uint32_t CurrentMode = hi2c->Mode; + + if((CurrentState == HAL_I2C_STATE_BUSY_TX) || ((CurrentState == HAL_I2C_STATE_BUSY_RX) && (CurrentMode == HAL_I2C_MODE_SLAVE))) + { + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0U; + + /* Enable EVT and ERR interrupt */ + __HAL_I2C_ENABLE_IT(hi2c, I2C_IT_EVT | I2C_IT_ERR); + } + else + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Disable Last DMA */ + hi2c->Instance->CR2 &= ~I2C_CR2_LAST; + + /* Disable DMA Request */ + hi2c->Instance->CR2 &= ~I2C_CR2_DMAEN; + + hi2c->XferCount = 0U; + + /* Check if Errors has been detected during transfer */ + if(hi2c->ErrorCode != HAL_I2C_ERROR_NONE) + { + HAL_I2C_ErrorCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + + if(hi2c->Mode == HAL_I2C_MODE_MEM) + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MemRxCpltCallback(hi2c); + } + else + { + hi2c->Mode = HAL_I2C_MODE_NONE; + + HAL_I2C_MasterRxCpltCallback(hi2c); + } + } + } +} + +/** + * @brief DMA I2C communication error callback. + * @param hdma DMA handle + * @retval None + */ +static void I2C_DMAError(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = (I2C_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; + + /* Ignore DMA FIFO error */ + if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) + { + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->XferCount = 0U; + + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + hi2c->ErrorCode |= HAL_I2C_ERROR_DMA; + + HAL_I2C_ErrorCallback(hi2c); + } +} + +/** + * @brief DMA I2C communication abort callback + * (To be called at end of DMA Abort procedure). + * @param hdma DMA handle. + * @retval None + */ +static void I2C_DMAAbort(DMA_HandleTypeDef *hdma) +{ + I2C_HandleTypeDef* hi2c = ( I2C_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Disable Acknowledge */ + hi2c->Instance->CR1 &= ~I2C_CR1_ACK; + + hi2c->XferCount = 0U; + + /* Reset XferAbortCallback */ + hi2c->hdmatx->XferAbortCallback = NULL; + hi2c->hdmarx->XferAbortCallback = NULL; + + /* Check if come from abort from user */ + if(hi2c->State == HAL_I2C_STATE_ABORT) + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + HAL_I2C_AbortCpltCallback(hi2c); + } + else + { + hi2c->State = HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Disable I2C peripheral to prevent dummy data in buffer */ + __HAL_I2C_DISABLE(hi2c); + + /* Call the corresponding callback to inform upper layer of End of Transfer */ + HAL_I2C_ErrorCallback(hi2c); + } +} + +/** + * @brief This function handles I2C Communication Timeout. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag specifies the I2C flag to check. + * @param Status The new Flag status (SET or RESET). + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, FlagStatus Status, uint32_t Timeout, uint32_t Tickstart) +{ + /* Wait until flag is set */ + while((__HAL_I2C_GET_FLAG(hi2c, Flag) ? SET : RESET) == Status) + { + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + hi2c->Mode = HAL_I2C_MODE_NONE; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for Master addressing phase. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for I2C module + * @param Flag specifies the I2C flag to check. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnMasterAddressFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Flag, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, Flag) == RESET) + { + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + /* Generate Stop */ + hi2c->Instance->CR1 |= I2C_CR1_STOP; + + /* Clear AF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U)||((HAL_GetTick() - Tickstart ) > Timeout)) + { + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of TXE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnTXEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) == RESET) + { + /* Check if a NACK is detected */ + if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of BTF flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnBTFFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BTF) == RESET) + { + /* Check if a NACK is detected */ + if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of STOP flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnSTOPFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == RESET) + { + /* Check if a NACK is detected */ + if(I2C_IsAcknowledgeFailed(hi2c) != HAL_OK) + { + return HAL_ERROR; + } + + /* Check for the Timeout */ + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief This function handles I2C Communication Timeout for specific usage of RXNE flag. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @param Timeout Timeout duration + * @param Tickstart Tick start value + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_WaitOnRXNEFlagUntilTimeout(I2C_HandleTypeDef *hi2c, uint32_t Timeout, uint32_t Tickstart) +{ + + while(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_RXNE) == RESET) + { + /* Check if a STOPF is detected */ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_STOPF) == SET) + { + /* Clear STOP Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF); + + hi2c->ErrorCode = HAL_I2C_ERROR_NONE; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + + /* Check for the Timeout */ + if((Timeout == 0U) || ((HAL_GetTick()-Tickstart) > Timeout)) + { + hi2c->ErrorCode |= HAL_I2C_ERROR_TIMEOUT; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_TIMEOUT; + } + } + return HAL_OK; +} + +/** + * @brief This function handles Acknowledge failed detection during an I2C Communication. + * @param hi2c Pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2C. + * @retval HAL status + */ +static HAL_StatusTypeDef I2C_IsAcknowledgeFailed(I2C_HandleTypeDef *hi2c) +{ + if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_AF) == SET) + { + /* Clear NACKF Flag */ + __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_AF); + + hi2c->ErrorCode = HAL_I2C_ERROR_AF; + hi2c->PreviousState = I2C_STATE_NONE; + hi2c->State= HAL_I2C_STATE_READY; + + /* Process Unlocked */ + __HAL_UNLOCK(hi2c); + + return HAL_ERROR; + } + return HAL_OK; +} +/** + * @} + */ + +#endif /* HAL_I2C_MODULE_ENABLED */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c new file mode 100644 index 00000000..de8f1602 --- /dev/null +++ b/Firmware/Board/v3/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c @@ -0,0 +1,204 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_i2c_ex.c + * @author MCD Application Team + * @brief I2C Extension HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of I2C extension peripheral: + * + Extension features functions + * + @verbatim + ============================================================================== + ##### I2C peripheral extension features ##### + ============================================================================== + + [..] Comparing to other previous devices, the I2C interface for STM32F427xx/437xx/ + 429xx/439xx devices contains the following additional features : + + (+) Possibility to disable or enable Analog Noise Filter + (+) Use of a configured Digital Noise Filter + + ##### How to use this driver ##### + ============================================================================== + [..] This driver provides functions to configure Noise Filter + (#) Configure I2C Analog noise filter using the function HAL_I2C_AnalogFilter_Config() + (#) Configure I2C Digital noise filter using the function HAL_I2C_DigitalFilter_Config() + + @endverbatim + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f4xx_hal.h" + +/** @addtogroup STM32F4xx_HAL_Driver + * @{ + */ + +/** @defgroup I2CEx I2CEx + * @brief I2C HAL module driver + * @{ + */ + +#ifdef HAL_I2C_MODULE_ENABLED + +#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ + defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) ||\ + defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F413xx) || defined(STM32F423xx) +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ +/** @defgroup I2CEx_Exported_Functions I2C Exported Functions + * @{ + */ + + +/** @defgroup I2CEx_Exported_Functions_Group1 Extension features functions + * @brief Extension features functions + * +@verbatim + =============================================================================== + ##### Extension features functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure Noise Filters + +@endverbatim + * @{ + */ + +/** + * @brief Configures I2C Analog noise filter. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param AnalogFilter new state of the Analog filter. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter) +{ + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_ANALOG_FILTER(AnalogFilter)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Reset I2Cx ANOFF bit */ + hi2c->Instance->FLTR &= ~(I2C_FLTR_ANOFF); + + /* Disable the analog filter */ + hi2c->Instance->FLTR |= AnalogFilter; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @brief Configures I2C Digital noise filter. + * @param hi2c pointer to a I2C_HandleTypeDef structure that contains + * the configuration information for the specified I2Cx peripheral. + * @param DigitalFilter Coefficient of digital noise filter between 0x00 and 0x0F. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter) +{ + uint16_t tmpreg = 0; + + /* Check the parameters */ + assert_param(IS_I2C_ALL_INSTANCE(hi2c->Instance)); + assert_param(IS_I2C_DIGITAL_FILTER(DigitalFilter)); + + if(hi2c->State == HAL_I2C_STATE_READY) + { + hi2c->State = HAL_I2C_STATE_BUSY; + + /* Disable the selected I2C peripheral */ + __HAL_I2C_DISABLE(hi2c); + + /* Get the old register value */ + tmpreg = hi2c->Instance->FLTR; + + /* Reset I2Cx DNF bit [3:0] */ + tmpreg &= ~(I2C_FLTR_DNF); + + /* Set I2Cx DNF coefficient */ + tmpreg |= DigitalFilter; + + /* Store the new register value */ + hi2c->Instance->FLTR = tmpreg; + + __HAL_I2C_ENABLE(hi2c); + + hi2c->State = HAL_I2C_STATE_READY; + + return HAL_OK; + } + else + { + return HAL_BUSY; + } +} + +/** + * @} + */ + +/** + * @} + */ +#endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F401xC ||\ + STM32F401xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F413xx ||\ + STM32F423xx */ + +#endif /* HAL_I2C_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h index e518489f..ed26bf39 100644 --- a/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h +++ b/Firmware/Board/v3/Inc/stm32f4xx_hal_conf.h @@ -65,7 +65,7 @@ /* #define HAL_SRAM_MODULE_ENABLED */ /* #define HAL_SDRAM_MODULE_ENABLED */ /* #define HAL_HASH_MODULE_ENABLED */ -/* #define HAL_I2C_MODULE_ENABLED */ +#define HAL_I2C_MODULE_ENABLED /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ /* #define HAL_LTDC_MODULE_ENABLED */ diff --git a/Firmware/Board/v3/Src/main.c b/Firmware/Board/v3/Src/main.c index e390af58..154c98af 100644 --- a/Firmware/Board/v3/Src/main.c +++ b/Firmware/Board/v3/Src/main.c @@ -180,7 +180,7 @@ int main(void) MX_DMA_Init(); MX_ADC1_Init(); MX_ADC2_Init(); - MX_CAN1_Init(); + // MX_CAN1_Init(); // CAN or I2C called in main.cpp instead MX_TIM1_Init(); MX_TIM8_Init(); MX_TIM3_Init(); From 9d4456eee6e4e9e8ff2d7307fe71e344e61fcd2c Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 00:08:08 -0700 Subject: [PATCH 32/40] Cube: Notify OS that we are a composite device --- Firmware/Board/v3/Src/usbd_desc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Firmware/Board/v3/Src/usbd_desc.c b/Firmware/Board/v3/Src/usbd_desc.c index b0906144..d213f64a 100644 --- a/Firmware/Board/v3/Src/usbd_desc.c +++ b/Firmware/Board/v3/Src/usbd_desc.c @@ -97,7 +97,8 @@ #define USBD_PID_FS 0x0D32 #define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) #define USBD_PRODUCT_STR(s) #s -#define USBD_PRODUCT_STRING_FS ODrive version HW_VERSION_MAJOR.HW_VERSION_MINOR +#define USBD_PRODUCT_STRING_FS ODrive HW_VERSION_MAJOR.HW_VERSION_MINOR CDC Interface +#define NATIVE_STRING ODrive HW_VERSION_MAJOR.HW_VERSION_MINOR Native Interface #define USBD_SERIALNUMBER_STRING_FS "000000000001" #define USBD_CONFIGURATION_STRING_FS "CDC Config" #define USBD_INTERFACE_STRING_FS "CDC Interface" @@ -233,16 +234,17 @@ __ALIGN_BEGIN uint8_t USBD_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = 0x00, /*bcdUSB */ #endif /* (USBD_LPM_ENABLED == 1) */ 0x02, - 0x02, /*bDeviceClass*/ + // Notify OS that this is a composite device + 0xEF, /*bDeviceClass*/ 0x02, /*bDeviceSubClass*/ - 0x00, /*bDeviceProtocol*/ + 0x01, /*bDeviceProtocol*/ USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ LOBYTE(USBD_VID), /*idVendor*/ HIBYTE(USBD_VID), /*idVendor*/ LOBYTE(USBD_PID_FS), /*idProduct*/ HIBYTE(USBD_PID_FS), /*idProduct*/ 0x00, /*bcdDevice rel. 2.00*/ - 0x02, + 0x03, /* bNumInterfaces */ USBD_IDX_MFC_STR, /*Index of manufacturer string*/ USBD_IDX_PRODUCT_STR, /*Index of product string*/ USBD_IDX_SERIAL_STR, /*Index of serial number string*/ From 9bd3d0b53c2adb9c03bae29e30fd32224ff3f6ea Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 00:51:04 -0700 Subject: [PATCH 33/40] cube: apply canges to USB --- Firmware/Board/v3/Inc/usbd_cdc_if.h | 2 +- Firmware/Board/v3/Inc/usbd_conf.h | 1 + Firmware/Board/v3/Inc/usbd_desc.h | 3 +- .../Class/CDC/Inc/usbd_cdc.h | 39 +- .../Class/CDC/Src/usbd_cdc.c | 562 +++++++++++------- .../Core/Inc/usbd_def.h | 4 +- Firmware/Board/v3/Src/usbd_cdc_if.c | 12 +- Firmware/Board/v3/Src/usbd_conf.c | 24 +- 8 files changed, 404 insertions(+), 243 deletions(-) diff --git a/Firmware/Board/v3/Inc/usbd_cdc_if.h b/Firmware/Board/v3/Inc/usbd_cdc_if.h index c15e8b91..ed1d6705 100644 --- a/Firmware/Board/v3/Inc/usbd_cdc_if.h +++ b/Firmware/Board/v3/Inc/usbd_cdc_if.h @@ -132,7 +132,7 @@ extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS; * @{ */ -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t endpoint_pair); /* USER CODE BEGIN EXPORTED_FUNCTIONS */ /* USER CODE END EXPORTED_FUNCTIONS */ diff --git a/Firmware/Board/v3/Inc/usbd_conf.h b/Firmware/Board/v3/Inc/usbd_conf.h index bf276186..a897ba43 100644 --- a/Firmware/Board/v3/Inc/usbd_conf.h +++ b/Firmware/Board/v3/Inc/usbd_conf.h @@ -89,6 +89,7 @@ * @brief Defines for configuration of the Usb device. * @{ */ + #define MS_VendorCode 'P' /*---------- -----------*/ #define USBD_MAX_NUM_INTERFACES 1 diff --git a/Firmware/Board/v3/Inc/usbd_desc.h b/Firmware/Board/v3/Inc/usbd_desc.h index 18d1f34e..2a74de31 100644 --- a/Firmware/Board/v3/Inc/usbd_desc.h +++ b/Firmware/Board/v3/Inc/usbd_desc.h @@ -2,7 +2,7 @@ ****************************************************************************** * @file : usbd_desc.h * @version : v1.0_Cube - * @brief : Header for usbd_conf.c file. + * @brief : Header for usbd_desc.c file. ****************************************************************************** * This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and @@ -46,6 +46,7 @@ * ****************************************************************************** */ + /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __USBD_DESC__H__ #define __USBD_DESC__H__ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h index d937b2e8..c029e22a 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc/usbd_cdc.h @@ -52,13 +52,15 @@ #define CDC_IN_EP 0x81 /* EP1 for data IN */ #define CDC_OUT_EP 0x01 /* EP1 for data OUT */ #define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ +#define ODRIVE_IN_EP 0x83 /* EP3 IN: ODrive device TX endpoint */ +#define ODRIVE_OUT_EP 0x03 /* EP3 OUT: ODrive device RX endpoint */ /* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ -#define CDC_DATA_HS_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_HS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ #define CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ #define CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */ -#define USB_CDC_CONFIG_DESC_SIZ 67 +#define USB_CDC_CONFIG_DESC_SIZ (67 + 39) #define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE #define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE @@ -103,23 +105,29 @@ typedef struct _USBD_CDC_Itf int8_t (* Init) (void); int8_t (* DeInit) (void); int8_t (* Control) (uint8_t, uint8_t * , uint16_t); - int8_t (* Receive) (uint8_t *, uint32_t *); + int8_t (* Receive) (uint8_t *, uint32_t *, uint8_t); }USBD_CDC_ItfTypeDef; +typedef struct +{ + uint8_t* Buffer; + uint32_t Length; + volatile uint8_t State; +} +USBD_CDC_EP_HandleTypeDef; typedef struct { uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */ uint8_t CmdOpCode; - uint8_t CmdLength; - uint8_t *RxBuffer; - uint8_t *TxBuffer; - uint32_t RxLength; - uint32_t TxLength; - - __IO uint32_t TxState; - __IO uint32_t RxState; + uint8_t CmdLength; + + USBD_CDC_EP_HandleTypeDef CDC_Tx; + USBD_CDC_EP_HandleTypeDef CDC_Rx; + + USBD_CDC_EP_HandleTypeDef ODRIVE_Tx; + USBD_CDC_EP_HandleTypeDef ODRIVE_Rx; } USBD_CDC_HandleTypeDef; @@ -151,14 +159,15 @@ uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint16_t length); + uint16_t length, + uint8_t endpoint_pair); uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, - uint8_t *pbuff); + uint8_t *pbuff, uint8_t endpoint_pair); -uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev, uint8_t endpoint_pair); -uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev); +uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev, uint8_t endpoint_pair); /** * @} */ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c index 24465641..73313522 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c @@ -132,6 +132,9 @@ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length); uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length); +static uint8_t USBD_WinUSBComm_SetupVendor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +//static uint8_t * USBD_GetUsrStrDescriptor(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length); + /* USB Standard Device Descriptor */ __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { @@ -173,24 +176,37 @@ USBD_ClassTypeDef USBD_CDC = USBD_CDC_GetFSCfgDesc, USBD_CDC_GetOtherSpeedCfgDesc, USBD_CDC_GetDeviceQualifierDescriptor, + USBD_UsrStrDescriptor }; /* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +__ALIGN_BEGIN uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = { /*Configuration Descriptor*/ 0x09, /* bLength: Configuration Descriptor size */ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ 0x00, - 0x02, /* bNumInterfaces: 2 interface */ + 0x03, /* bNumInterfaces: 3 interfaces (2 for CDC, 1 custom) */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0xC0, /* bmAttributes: self powered */ 0x32, /* MaxPower 0 mA */ + + /////////////////////////////////////////////////////////////////////////////// + + /* Interface Association Descriptor: CDC device (virtual com port) */ + 0x08, /* bLength: IAD size */ + 0x0B, /* bDescriptorType: Interface Association Descriptor */ + 0x00, /* bFirstInterface */ + 0x02, /* bInterfaceCount */ + 0x02, /* bFunctionClass: Communication Interface Class */ + 0x02, /* bFunctionSubClass: Abstract Control Model */ + 0x01, /* bFunctionProtocol: Common AT commands */ + 0x00, /* iFunction */ /*---------------------------------------------------------------------------*/ - + /*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ @@ -202,7 +218,7 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x01, /* bInterfaceProtocol: Common AT commands */ 0x00, /* iInterface: */ - + /*Header Functional Descriptor*/ 0x05, /* bLength: Endpoint Descriptor size */ 0x24, /* bDescriptorType: CS_INTERFACE */ @@ -229,7 +245,7 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x06, /* bDescriptorSubtype: Union func desc */ 0x00, /* bMasterInterface: Communication class interface */ 0x01, /* bSlaveInterface0: Data Class Interface */ - + /*Endpoint 2 Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ @@ -267,196 +283,52 @@ __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = 0x02, /* bmAttributes: Bulk */ LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ -} ; + 0x00, /* bInterval: ignore for Bulk transfer */ + /////////////////////////////////////////////////////////////////////////////// + + /* Interface Association Descriptor: custom device */ + 0x08, /* bLength: IAD size */ + 0x0B, /* bDescriptorType: Interface Association Descriptor */ + 0x02, /* bFirstInterface */ + 0x01, /* bInterfaceCount */ + 0x00, /* bFunctionClass: */ + 0x00, /* bFunctionSubClass: */ + 0x00, /* bFunctionProtocol: */ + 0x06, /* iFunction */ -/* USB CDC device Configuration Descriptor */ -__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - /*Configuration Descriptor*/ - 0x09, /* bLength: Configuration Descriptor size */ - USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ - USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ - 0x00, - 0x02, /* bNumInterfaces: 2 interface */ - 0x01, /* bConfigurationValue: Configuration value */ - 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ - 0xC0, /* bmAttributes: self powered */ - 0x32, /* MaxPower 0 mA */ - - /*---------------------------------------------------------------------------*/ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SIZE), - 0x10, /* bInterval: */ /*---------------------------------------------------------------------------*/ /*Data class interface descriptor*/ 0x09, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ + 0x02, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceClass: vendor specific */ + 0x01, /* bInterfaceSubClass: ODrive Communication */ 0x00, /* bInterfaceProtocol: */ 0x00, /* iInterface: */ /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ + ODRIVE_OUT_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ /*Endpoint IN Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ + ODRIVE_IN_EP, /* bEndpointAddress */ 0x02, /* bmAttributes: Bulk */ - LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), - 0x00 /* bInterval: ignore for Bulk transfer */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ } ; -__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = -{ - 0x09, /* bLength: Configuation Descriptor size */ - USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, - USB_CDC_CONFIG_DESC_SIZ, - 0x00, - 0x02, /* bNumInterfaces: 2 interfaces */ - 0x01, /* bConfigurationValue: */ - 0x04, /* iConfiguration: */ - 0xC0, /* bmAttributes: */ - 0x32, /* MaxPower 100 mA */ - - /*Interface Descriptor */ - 0x09, /* bLength: Interface Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ - /* Interface descriptor type */ - 0x00, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x01, /* bNumEndpoints: One endpoints used */ - 0x02, /* bInterfaceClass: Communication Interface Class */ - 0x02, /* bInterfaceSubClass: Abstract Control Model */ - 0x01, /* bInterfaceProtocol: Common AT commands */ - 0x00, /* iInterface: */ - - /*Header Functional Descriptor*/ - 0x05, /* bLength: Endpoint Descriptor size */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x00, /* bDescriptorSubtype: Header Func Desc */ - 0x10, /* bcdCDC: spec release number */ - 0x01, - - /*Call Management Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x01, /* bDescriptorSubtype: Call Management Func Desc */ - 0x00, /* bmCapabilities: D0+D1 */ - 0x01, /* bDataInterface: 1 */ - - /*ACM Functional Descriptor*/ - 0x04, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ - 0x02, /* bmCapabilities */ - - /*Union Functional Descriptor*/ - 0x05, /* bFunctionLength */ - 0x24, /* bDescriptorType: CS_INTERFACE */ - 0x06, /* bDescriptorSubtype: Union func desc */ - 0x00, /* bMasterInterface: Communication class interface */ - 0x01, /* bSlaveInterface0: Data Class Interface */ - - /*Endpoint 2 Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT , /* bDescriptorType: Endpoint */ - CDC_CMD_EP, /* bEndpointAddress */ - 0x03, /* bmAttributes: Interrupt */ - LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ - HIBYTE(CDC_CMD_PACKET_SIZE), - 0xFF, /* bInterval: */ - - /*---------------------------------------------------------------------------*/ - - /*Data class interface descriptor*/ - 0x09, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ - 0x01, /* bInterfaceNumber: Number of Interface */ - 0x00, /* bAlternateSetting: Alternate setting */ - 0x02, /* bNumEndpoints: Two endpoints used */ - 0x0A, /* bInterfaceClass: CDC */ - 0x00, /* bInterfaceSubClass: */ - 0x00, /* bInterfaceProtocol: */ - 0x00, /* iInterface: */ - - /*Endpoint OUT Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_OUT_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00, /* bInterval: ignore for Bulk transfer */ - - /*Endpoint IN Descriptor*/ - 0x07, /* bLength: Endpoint Descriptor size */ - USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ - CDC_IN_EP, /* bEndpointAddress */ - 0x02, /* bmAttributes: Bulk */ - 0x40, /* wMaxPacketSize: */ - 0x00, - 0x00 /* bInterval */ -}; /** * @} @@ -508,6 +380,19 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, USBD_EP_TYPE_BULK, CDC_DATA_FS_OUT_PACKET_SIZE); } + + /* Open ODrive IN endpoint */ + USBD_LL_OpenEP(pdev, + ODRIVE_IN_EP, + USBD_EP_TYPE_BULK, + pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_IN_PACKET_SIZE : CDC_DATA_FS_IN_PACKET_SIZE); + + /* Open ODrive OUT endpoint */ + USBD_LL_OpenEP(pdev, + ODRIVE_OUT_EP, + USBD_EP_TYPE_BULK, + pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_OUT_PACKET_SIZE : CDC_DATA_FS_OUT_PACKET_SIZE); + /* Open Command IN EP */ USBD_LL_OpenEP(pdev, CDC_CMD_EP, @@ -529,15 +414,17 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); /* Init Xfer states */ - hcdc->TxState =0; - hcdc->RxState =0; + hcdc->CDC_Tx.State =0; + hcdc->CDC_Rx.State =0; + hcdc->ODRIVE_Tx.State =0; + hcdc->ODRIVE_Rx.State =0; if(pdev->dev_speed == USBD_SPEED_HIGH ) { /* Prepare Out endpoint to receive next packet */ USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, - hcdc->RxBuffer, + hcdc->CDC_Rx.Buffer, CDC_DATA_HS_OUT_PACKET_SIZE); } else @@ -545,11 +432,15 @@ static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, /* Prepare Out endpoint to receive next packet */ USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, - hcdc->RxBuffer, + hcdc->CDC_Rx.Buffer, CDC_DATA_FS_OUT_PACKET_SIZE); } - + /* Prepare ODrive Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + ODRIVE_OUT_EP, + hcdc->ODRIVE_Rx.Buffer, + CDC_DATA_FS_OUT_PACKET_SIZE); } return ret; } @@ -566,17 +457,25 @@ static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, { uint8_t ret = 0; - /* Open EP IN */ + /* Close EP IN */ USBD_LL_CloseEP(pdev, CDC_IN_EP); - /* Open EP OUT */ + /* Close EP OUT */ USBD_LL_CloseEP(pdev, CDC_OUT_EP); - /* Open Command IN EP */ + /* Close Command IN EP */ USBD_LL_CloseEP(pdev, CDC_CMD_EP); + + /* Close EP IN */ + USBD_LL_CloseEP(pdev, + ODRIVE_IN_EP); + + /* Close EP OUT */ + USBD_LL_CloseEP(pdev, + ODRIVE_OUT_EP); /* DeInit physical Interface components */ @@ -648,6 +547,9 @@ static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, case USB_REQ_SET_INTERFACE : break; } + + case USB_REQ_TYPE_VENDOR: + return USBD_WinUSBComm_SetupVendor(pdev, req); default: break; @@ -668,8 +570,12 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) if(pdev->pClassData != NULL) { - - hcdc->TxState = 0; + // NOTE: We would logically expect xx_IN_EP here, but we actually get the xx_OUT_EP + if (epnum == CDC_OUT_EP) + hcdc->CDC_Tx.State = 0; + if (epnum == ODRIVE_OUT_EP) + hcdc->ODRIVE_Tx.State = 0; + //Note: We could use independent semaphores for simoultainous USB transmission. osSemaphoreRelease(sem_usb_tx); return USBD_OK; } @@ -689,15 +595,24 @@ static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + USBD_CDC_EP_HandleTypeDef* hEP_Rx; + if (epnum == CDC_OUT_EP) { + hEP_Rx = &hcdc->CDC_Rx; + } else if (epnum == ODRIVE_OUT_EP) { + hEP_Rx = &hcdc->ODRIVE_Rx; + } else { + return USBD_FAIL; + } /* Get the received data length */ - hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + hEP_Rx->Length = USBD_LL_GetRxDataSize (pdev, epnum); /* USB data will be immediately processed, this allow next USB traffic being NAKed till the end of the application Xfer */ if(pdev->pClassData != NULL) { - ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hEP_Rx->Buffer, &hEP_Rx->Length, epnum); return USBD_OK; } @@ -740,8 +655,8 @@ static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev) */ static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_CfgFSDesc); - return USBD_CDC_CfgFSDesc; + *length = sizeof (USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -753,8 +668,8 @@ static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) */ static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_CfgHSDesc); - return USBD_CDC_CfgHSDesc; + *length = sizeof (USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -766,8 +681,8 @@ static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) */ static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length) { - *length = sizeof (USBD_CDC_OtherSpeedCfgDesc); - return USBD_CDC_OtherSpeedCfgDesc; + *length = sizeof (USBD_CDC_CfgDesc); + return USBD_CDC_CfgDesc; } /** @@ -810,12 +725,22 @@ uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, */ uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, uint8_t *pbuff, - uint16_t length) + uint16_t length, + uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; - hcdc->TxBuffer = pbuff; - hcdc->TxLength = length; + USBD_CDC_EP_HandleTypeDef* hEP_Tx; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Tx = &hcdc->CDC_Tx; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Tx = &hcdc->ODRIVE_Tx; + } else { + return USBD_FAIL; + } + + hEP_Tx->Buffer = pbuff; + hEP_Tx->Length = length; return USBD_OK; } @@ -828,11 +753,20 @@ uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, * @retval status */ uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, - uint8_t *pbuff) + uint8_t *pbuff, uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + USBD_CDC_EP_HandleTypeDef* hEP_Rx; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Rx = &hcdc->CDC_Rx; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Rx = &hcdc->ODRIVE_Rx; + } else { + return USBD_FAIL; + } - hcdc->RxBuffer = pbuff; + hEP_Rx->Buffer = pbuff; return USBD_OK; } @@ -844,23 +778,36 @@ uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, * @param epnum: endpoint number * @retval status */ -uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; if(pdev->pClassData != NULL) { - if(hcdc->TxState == 0) + // Select Endpoint + USBD_CDC_EP_HandleTypeDef* hEP_Tx; + uint8_t in_ep; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Tx = &hcdc->CDC_Tx; + in_ep = CDC_IN_EP; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Tx = &hcdc->ODRIVE_Tx; + in_ep = ODRIVE_IN_EP; + } else { + return USBD_FAIL; + } + + if(hEP_Tx->State == 0) { /* Tx Transfer in progress */ - hcdc->TxState = 1; + hEP_Tx->State = 1; /* Transmit next packet */ USBD_LL_Transmit(pdev, - CDC_IN_EP, - hcdc->TxBuffer, - hcdc->TxLength); - + in_ep, + hEP_Tx->Buffer, + hEP_Tx->Length); + return USBD_OK; } else @@ -881,29 +828,32 @@ uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) * @param pdev: device instance * @retval status */ -uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev, uint8_t endpoint_pair) { USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; /* Suspend or Resume USB Out process */ if(pdev->pClassData != NULL) { - if(pdev->dev_speed == USBD_SPEED_HIGH ) - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - CDC_OUT_EP, - hcdc->RxBuffer, - CDC_DATA_HS_OUT_PACKET_SIZE); - } - else - { - /* Prepare Out endpoint to receive next packet */ - USBD_LL_PrepareReceive(pdev, - CDC_OUT_EP, - hcdc->RxBuffer, - CDC_DATA_FS_OUT_PACKET_SIZE); + // Select Endpoint + USBD_CDC_EP_HandleTypeDef* hEP_Rx; + uint8_t out_ep; + if (endpoint_pair == CDC_OUT_EP) { + hEP_Rx = &hcdc->CDC_Rx; + out_ep = CDC_OUT_EP; + } else if (endpoint_pair == ODRIVE_OUT_EP) { + hEP_Rx = &hcdc->ODRIVE_Rx; + out_ep = ODRIVE_OUT_EP; + } else { + return USBD_FAIL; } + + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + out_ep, + hEP_Rx->Buffer, + pdev->dev_speed == USBD_SPEED_HIGH ? CDC_DATA_HS_OUT_PACKET_SIZE : CDC_DATA_FS_OUT_PACKET_SIZE); + return USBD_OK; } else @@ -911,6 +861,184 @@ uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) return USBD_FAIL; } } + + +/* WinUSB support ------------------------------------------------------------*/ +/* +* This section tells Windows that it should automatically load the WinUSB driver +* for the device (more specifically, interface 2 because it's a composite device). +* This allows for driverless communication with the device. +*/ + +#define NUM_INTERFACES 1 + +#if NUM_INTERFACES == 2 +#define USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ (16 + 24 + 24) +#else +#define USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ (16 + 24) +#endif + + +// This associates winusb driver with the device +__ALIGN_BEGIN uint8_t USBD_WinUSBComm_Extended_Compat_ID_OS_Desc[USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ] __ALIGN_END = +{ + // +-- Offset in descriptor + // | +-- Size + // v v + USB_WINUSBCOMM_COMPAT_ID_OS_DESC_SIZ, 0, 0, 0, // 0 dwLength 4 DWORD The length, in bytes, of the complete extended compat ID descriptor + 0x00, 0x01, // 4 bcdVersion 2 BCD The descriptor’s version number, in binary coded decimal (BCD) format + 0x04, 0x00, // 6 wIndex 2 WORD An index that identifies the particular OS feature descriptor + NUM_INTERFACES, // 8 bCount 1 BYTE The number of custom property sections + 0, 0, 0, 0, 0, 0, 0, // 9 RESERVED 7 BYTEs Reserved + // ===================== + // 16 + + // +-- Offset from function section start + // | +-- Size + // v v + 2, // 0 bFirstInterfaceNumber 1 BYTE The interface or function number + 0, // 1 RESERVED 1 BYTE Reserved + 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // 2 compatibleID 8 BYTEs The function’s compatible ID ("WINUSB") + 0, 0, 0, 0, 0, 0, 0, 0, // 10 subCompatibleID 8 BYTEs The function’s subcompatible ID + 0, 0, 0, 0, 0, 0, // 18 RESERVED 6 BYTEs Reserved + // ================================= + // 24 +#if NUM_INTERFACES == 2 + // +-- Offset from function section start + // | +-- Size + // v v + 2, // 0 bFirstInterfaceNumber 1 BYTE The interface or function number + 0, // 1 RESERVED 1 BYTE Reserved + 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // 2 compatibleID 8 BYTEs The function’s compatible ID ("WINUSB") + 0, 0, 0, 0, 0, 0, 0, 0, // 10 subCompatibleID 8 BYTEs The function’s subcompatible ID + 0, 0, 0, 0, 0, 0, // 18 RESERVED 6 BYTEs Reserved + // ================================= + // 24 +#endif +}; + + +// Properties are added to: +// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USB\VID_xxxx&PID_xxxx\sssssssss\Device Parameters +// Use USBDeview or similar to uninstall + +__ALIGN_BEGIN uint8_t USBD_WinUSBComm_Extended_Properties_OS_Desc[0xB6] __ALIGN_END = +{ + 0xB6, 0x00, 0x00, 0x00, // 0 dwLength 4 DWORD The length, in bytes, of the complete extended properties descriptor + 0x00, 0x01, // 4 bcdVersion 2 BCD The descriptor’s version number, in binary coded decimal (BCD) format + 0x05, 0x00, // 6 wIndex 2 WORD The index for extended properties OS descriptors + 0x02, 0x00, // 8 wCount 2 WORD The number of custom property sections that follow the header section + // ==================== + // 10 +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + 0x84, 0x00, 0x00, 0x00, // 0 dwSize 4 DWORD The size of this custom properties section + 0x01, 0x00, 0x00, 0x00, // 4 dwPropertyDataType 4 DWORD Property data format + 0x28, 0x00, // 8 wPropertyNameLength 2 DWORD Property name length + // ======================================== + // 10 + // 10 bPropertyName PNL WCHAR[] The property name + 'D',0, 'e',0, 'v',0, 'i',0, 'c',0, 'e',0, 'I',0, 'n',0, + 't',0, 'e',0, 'r',0, 'f',0, 'a',0, 'c',0, 'e',0, 'G',0, + 'U',0, 'I',0, 'D',0, 0,0, + // ======================================== + // 40 (0x28) + + 0x4E, 0x00, 0x00, 0x00, // 10 + PNL dwPropertyDataLength 4 DWORD Length of the buffer holding the property data + // ======================================== + // 4 + // 14 + PNL bPropertyData PDL Format-dependent Property data + '{',0, 'E',0, 'A',0, '0',0, 'B',0, 'D',0, '5',0, 'C',0, + '3',0, '-',0, '5',0, '0',0, 'F',0, '3',0, '-',0, '4',0, + '8',0, '8',0, '8',0, '-',0, '8',0, '4',0, 'B',0, '4',0, + '-',0, '7',0, '4',0, 'E',0, '5',0, '0',0, 'E',0, '1',0, + '6',0, '4',0, '9',0, 'D',0, 'B',0, '}',0, 0 ,0, + // ======================================== + // 78 (0x4E) +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + 0x3E, 0x00, 0x00, 0x00, // 0 dwSize 0x00000030 (62 bytes) + 0x01, 0x00, 0x00, 0x00, // 4 dwPropertyDataType 0x00000001 (Unicode string) + 0x0C, 0x00, // 8 wPropertyNameLength 0x000C (12 bytes) + // ======================================== + // 10 + 'L',0, 'a',0, 'b',0, 'e',0, 'l',0, 0,0, + // 10 bPropertyName “Label” + // ======================================== + // 12 + 0x24, 0x00, 0x00, 0x00, // 22 dwPropertyDataLength 0x00000016 (36 bytes) + // ======================================== + // 4 + 'O',0, 'D',0, 'r',0, 'i',0, 'v',0, 'e',0, 0,0 + // 26 bPropertyData “ODrive” + // ======================================== + // 14 + +}; + + + +static uint8_t USBD_WinUSBComm_GetMSExtendedCompatIDOSDescriptor (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch (req->wIndex) + { + case 0x04: + USBD_CtlSendData (pdev, USBD_WinUSBComm_Extended_Compat_ID_OS_Desc, req->wLength); + break; + default: + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + return USBD_OK; +} +static uint8_t USBD_WinUSBComm_GetMSExtendedPropertiesOSDescriptor (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + uint8_t byInterfaceIndex = (uint8_t)req->wValue; + if ( req->wIndex != 0x05 ) + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + switch ( byInterfaceIndex ) + { + case 0: +#if NUM_INTERFACES == 2 + case 1: +#endif + USBD_CtlSendData (pdev, USBD_WinUSBComm_Extended_Properties_OS_Desc, req->wLength); + break; + default: + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + return USBD_OK; +} +static uint8_t USBD_WinUSBComm_SetupVendorDevice(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_CtlError(pdev , req); + return USBD_FAIL; +} +static uint8_t USBD_WinUSBComm_SetupVendorInterface(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_CtlError(pdev , req); + // TODO: check if this is important + return USBD_FAIL; +} +static uint8_t USBD_WinUSBComm_SetupVendor(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + switch ( req->bmRequest & USB_REQ_RECIPIENT_MASK ) + { + case USB_REQ_RECIPIENT_DEVICE: + return ( MS_VendorCode == req->bRequest ) ? USBD_WinUSBComm_GetMSExtendedCompatIDOSDescriptor(pdev, req) : USBD_WinUSBComm_SetupVendorDevice(pdev, req); + case USB_REQ_RECIPIENT_INTERFACE: + return ( MS_VendorCode == req->bRequest ) ? USBD_WinUSBComm_GetMSExtendedPropertiesOSDescriptor(pdev, req) : USBD_WinUSBComm_SetupVendorInterface(pdev, req); + case USB_REQ_RECIPIENT_ENDPOINT: + // fall through + default: + break; + } + USBD_CtlError(pdev , req); + return USBD_FAIL; +} + /** * @} */ diff --git a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h index 8fbe81e4..f259b51d 100644 --- a/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h +++ b/Firmware/Board/v3/Middlewares/ST/STM32_USB_Device_Library/Core/Inc/usbd_def.h @@ -68,7 +68,9 @@ #define USBD_IDX_PRODUCT_STR 0x02 #define USBD_IDX_SERIAL_STR 0x03 #define USBD_IDX_CONFIG_STR 0x04 -#define USBD_IDX_INTERFACE_STR 0x05 +#define USBD_IDX_INTERFACE_STR 0x05 +#define USBD_IDX_ODRIVE_INTF_STR 0x06 +#define USBD_IDX_MICROSOFT_DESC_STR 0xEE #define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_CLASS 0x20 diff --git a/Firmware/Board/v3/Src/usbd_cdc_if.c b/Firmware/Board/v3/Src/usbd_cdc_if.c index fcc712a3..b8cb6e6c 100644 --- a/Firmware/Board/v3/Src/usbd_cdc_if.c +++ b/Firmware/Board/v3/Src/usbd_cdc_if.c @@ -117,10 +117,12 @@ /* Create buffer for reception and transmission */ /* It's up to user to redefine and/or remove those define */ /** Received data over USB are stored in this buffer */ -uint8_t UserRxBufferFS[APP_RX_DATA_SIZE]; +uint8_t CDCRxBufferFS[APP_RX_DATA_SIZE]; +uint8_t ODRIVERxBufferFS[APP_RX_DATA_SIZE]; /** Data to send over USB CDC are stored in this buffer */ -uint8_t UserTxBufferFS[APP_TX_DATA_SIZE]; +uint8_t CDCTxBufferFS[APP_TX_DATA_SIZE]; +uint8_t ODRIVETxBufferFS[APP_TX_DATA_SIZE]; /* USER CODE BEGIN PRIVATE_VARIABLES */ /* USER CODE END PRIVATE_VARIABLES */ @@ -151,7 +153,7 @@ extern USBD_HandleTypeDef hUsbDeviceFS; static int8_t CDC_Init_FS(void); static int8_t CDC_DeInit_FS(void); static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length); -static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len); +static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len, uint8_t endpoint_pair); /* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */ /* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */ @@ -289,7 +291,7 @@ static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) * @param Len: Number of data received (in bytes) * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL */ -static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) +static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len, uint8_t endpoint_pair) { /* USER CODE BEGIN 6 */ usb_rx_process_packet(Buf, *Len, endpoint_pair); @@ -309,7 +311,7 @@ static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) * @param Len: Number of data to be sent (in bytes) * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY */ -uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len) +uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len, uint8_t endpoint_pair) { uint8_t result = USBD_OK; /* USER CODE BEGIN 7 */ diff --git a/Firmware/Board/v3/Src/usbd_conf.c b/Firmware/Board/v3/Src/usbd_conf.c index 7046dc96..2d66d4a1 100644 --- a/Firmware/Board/v3/Src/usbd_conf.c +++ b/Firmware/Board/v3/Src/usbd_conf.c @@ -66,7 +66,7 @@ /* USER CODE END PV */ - PCD_HandleTypeDef hpcd_USB_OTG_FS; +PCD_HandleTypeDef hpcd_USB_OTG_FS; void _Error_Handler(char * file, int line); /* External functions --------------------------------------------------------*/ @@ -154,6 +154,23 @@ void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) */ void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { + USBD_StatusTypeDef ret = USBD_OK; + USBD_HandleTypeDef *pdev = hpcd->pData; + USBD_SetupReqTypedef *req = &pdev->request; + USBD_ParseSetupRequest(req, (uint8_t *)hpcd->Setup); + if ( ( USB_REQ_TYPE_VENDOR == (req->bmRequest & USB_REQ_TYPE_MASK) ) && ( MS_VendorCode == req->bRequest ) ) + { + pdev->ep0_state = USBD_EP0_SETUP; + pdev->ep0_data_len = pdev->request.wLength; + + ret = pdev->pClass->Setup(pdev, req); + + if( (req->wLength == 0) && (ret == USBD_OK) ) + { + USBD_CtlSendStatus(pdev); + } + return; + } USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup); } @@ -312,7 +329,7 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) pdev->pData = &hpcd_USB_OTG_FS; hpcd_USB_OTG_FS.Instance = USB_OTG_FS; - hpcd_USB_OTG_FS.Init.dev_endpoints = 4; + hpcd_USB_OTG_FS.Init.dev_endpoints = 6; hpcd_USB_OTG_FS.Init.speed = PCD_SPEED_FULL; hpcd_USB_OTG_FS.Init.dma_enable = DISABLE; hpcd_USB_OTG_FS.Init.ep0_mps = DEP0CTL_MPS_64; @@ -329,7 +346,8 @@ USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80); HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40); - HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40); // CDC IN endpoint + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40); // ODrive IN endpoint } return USBD_OK; } From 47acbe3d30d965a5195cd9aac32408d9582fabbc Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 00:52:53 -0700 Subject: [PATCH 34/40] cube: can auto wake up --- Firmware/Board/v3/Src/can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Board/v3/Src/can.c b/Firmware/Board/v3/Src/can.c index 2171691a..fc7bf388 100644 --- a/Firmware/Board/v3/Src/can.c +++ b/Firmware/Board/v3/Src/can.c @@ -70,7 +70,7 @@ void MX_CAN1_Init(void) hcan1.Init.TimeSeg2 = CAN_BS2_5TQ; hcan1.Init.TimeTriggeredMode = DISABLE; hcan1.Init.AutoBusOff = DISABLE; - hcan1.Init.AutoWakeUp = DISABLE; + hcan1.Init.AutoWakeUp = ENABLE; hcan1.Init.AutoRetransmission = DISABLE; hcan1.Init.ReceiveFifoLocked = DISABLE; hcan1.Init.TransmitFifoPriority = DISABLE; From 536bfce2ed9ec76f1353eae8cb57dd3df6a0d878 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 01:25:50 -0700 Subject: [PATCH 35/40] move configAPPLICATION_ALLOCATED_HEAP to FreeRTOSconfig.h --- Firmware/Board/v3/Inc/FreeRTOSConfig.h | 1 + Firmware/Board/v3/Inc/main.h | 1 - Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h | 1 - Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h | 1 - Firmware/Board/v3/Odrive.ioc | 2 +- 5 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Firmware/Board/v3/Inc/FreeRTOSConfig.h b/Firmware/Board/v3/Inc/FreeRTOSConfig.h index 90e233b3..715b0e67 100644 --- a/Firmware/Board/v3/Inc/FreeRTOSConfig.h +++ b/Firmware/Board/v3/Inc/FreeRTOSConfig.h @@ -167,6 +167,7 @@ standard names. */ /* USER CODE BEGIN Defines */ /* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */ +#define configAPPLICATION_ALLOCATED_HEAP 1 // ucHeap allocated in freertos.c /* USER CODE END Defines */ #endif /* FREERTOS_CONFIG_H */ diff --git a/Firmware/Board/v3/Inc/main.h b/Firmware/Board/v3/Inc/main.h index 1e76830d..d41b19ee 100644 --- a/Firmware/Board/v3/Inc/main.h +++ b/Firmware/Board/v3/Inc/main.h @@ -72,7 +72,6 @@ #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 -#define configAPPLICATION_ALLOCATED_HEAP 1 #define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 diff --git a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h index 567fe028..65f45efd 100644 --- a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h +++ b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_2.h @@ -6,7 +6,6 @@ #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 -#define configAPPLICATION_ALLOCATED_HEAP 1 #define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 diff --git a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h index 5695d700..64daaa4f 100644 --- a/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h +++ b/Firmware/Board/v3/Inc/prev_board_ver/main_V3_4.h @@ -6,7 +6,6 @@ #define TIM_APB1_CLOCK_HZ 84000000 #define TIM_APB1_PERIOD_CLOCKS 4096 #define TIM_APB1_DEADTIME_CLOCKS 40 -#define configAPPLICATION_ALLOCATED_HEAP 1 #define TIM_1_8_RCR 2 #define M0_nCS_Pin GPIO_PIN_13 diff --git a/Firmware/Board/v3/Odrive.ioc b/Firmware/Board/v3/Odrive.ioc index d18c5f86..9f636781 100644 --- a/Firmware/Board/v3/Odrive.ioc +++ b/Firmware/Board/v3/Odrive.ioc @@ -211,7 +211,7 @@ Mcu.Pin8=PC3 Mcu.Pin9=PA0-WKUP Mcu.PinsNb=57 Mcu.ThirdPartyNb=0 -Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;configAPPLICATION_ALLOCATED_HEAP,1;TIM_1_8_RCR,2 +Mcu.UserConstants=TIM_1_8_CLOCK_HZ,168000000;TIM_1_8_PERIOD_CLOCKS,3500;TIM_1_8_DEADTIME_CLOCKS,20;TIM_APB1_CLOCK_HZ,84000000;TIM_APB1_PERIOD_CLOCKS,4096;TIM_APB1_DEADTIME_CLOCKS,40;TIM_1_8_RCR,2 Mcu.UserName=STM32F405RGTx MxCube.Version=4.27.0 MxDb.Version=DB.4.0.270 From c968f21f44735c59ec5a2a5b68480ff2df96be84 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 01:32:54 -0700 Subject: [PATCH 36/40] cube: support user string --- Firmware/Board/v3/Inc/usbd_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/Board/v3/Inc/usbd_conf.h b/Firmware/Board/v3/Inc/usbd_conf.h index a897ba43..dbf800b3 100644 --- a/Firmware/Board/v3/Inc/usbd_conf.h +++ b/Firmware/Board/v3/Inc/usbd_conf.h @@ -98,7 +98,7 @@ /*---------- -----------*/ #define USBD_MAX_STR_DESC_SIZ 512 /*---------- -----------*/ -#define USBD_SUPPORT_USER_STRING 0 +#define USBD_SUPPORT_USER_STRING 1 /*---------- -----------*/ #define USBD_DEBUG_LEVEL 0 /*---------- -----------*/ From f22199bf95f38592688201e2cecbe34e89c18905 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 19:58:41 -0700 Subject: [PATCH 37/40] merge is ugly but is confirmed working --- docs/developer-guide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/developer-guide.md b/docs/developer-guide.md index d6243b5b..ecf3e1ea 100644 --- a/docs/developer-guide.md +++ b/docs/developer-guide.md @@ -183,7 +183,6 @@ How to use these is shown in the following example. * Make sure the rebase finishes, fixing any conflicts that may arise ### 4. Merge new STM32CubeMX code to your feature branch -**TODO: Nobody has done this yet, these instructions are new. Please verify that this works as intended.** Simply merge the new state at `STM32CubeMX-end` into your feature branch. * `git checkout your-feature` * `git merge STM32CubeMX-end` From 1511ae1db79d8c8621e8082b2c8aea2aefd71f0c Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 21:56:02 -0700 Subject: [PATCH 38/40] use tim13 as realtime control diagnostic timebase --- Firmware/Board/v3/Src/tim.c | 2 +- Firmware/MotorControl/low_level.cpp | 25 ++++++++++++++++--------- Firmware/MotorControl/low_level.h | 3 ++- Firmware/MotorControl/motor.cpp | 9 ++------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/Firmware/Board/v3/Src/tim.c b/Firmware/Board/v3/Src/tim.c index bd27e5f5..97205c15 100644 --- a/Firmware/Board/v3/Src/tim.c +++ b/Firmware/Board/v3/Src/tim.c @@ -382,7 +382,7 @@ void MX_TIM13_Init(void) htim13.Instance = TIM13; htim13.Init.Prescaler = 0; htim13.Init.CounterMode = TIM_COUNTERMODE_UP; - htim13.Init.Period = (2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1)) * (TIM_APB1_CLOCK_HZ / TIM_1_8_CLOCK_HZ); + htim13.Init.Period = (2 * TIM_1_8_PERIOD_CLOCKS * (TIM_1_8_RCR+1)) * ((float)TIM_APB1_CLOCK_HZ / (float)TIM_1_8_CLOCK_HZ) - 1; htim13.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_Base_Init(&htim13) != HAL_OK) { diff --git a/Firmware/MotorControl/low_level.cpp b/Firmware/MotorControl/low_level.cpp index d807dc33..5bc256ae 100644 --- a/Firmware/MotorControl/low_level.cpp +++ b/Firmware/MotorControl/low_level.cpp @@ -216,7 +216,8 @@ void start_adc_pwm() { start_pwm(&htim1); start_pwm(&htim8); // TODO: explain why this offset - sync_timers(&htim1, &htim8, TIM_CLOCKSOURCE_ITR0, TIM_1_8_PERIOD_CLOCKS / 2 - 1 * 128); + sync_timers(&htim1, &htim8, TIM_CLOCKSOURCE_ITR0, TIM_1_8_PERIOD_CLOCKS / 2 - 1 * 128, + &htim13); // Motor output starts in the disabled state __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(&htim1); @@ -259,7 +260,8 @@ void start_pwm(TIM_HandleTypeDef* htim) { } void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b, - uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset) { + uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset, + TIM_HandleTypeDef* htim_refbase) { // Store intial timer configs uint16_t MOE_store_a = htim_a->Instance->BDTR & (TIM_BDTR_MOE); uint16_t MOE_store_b = htim_b->Instance->BDTR & (TIM_BDTR_MOE); @@ -294,6 +296,11 @@ void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b, // set counter offset htim_a->Instance->CNT = count_offset; htim_b->Instance->CNT = 0; + // Set and start reference timebase timer (if used) + if (htim_refbase) { + htim_refbase->Instance->CNT = count_offset; + htim_refbase->Instance->CR1 |= (TIM_CR1_CEN); // start + } // Start Timer a htim_a->Instance->CR1 |= (TIM_CR1_CEN); // Restore timer configs @@ -475,8 +482,14 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) { int axis_num = injected ? 0 : 1; Axis& other_axis = injected ? *axes[1] : *axes[0]; bool counting_down = axis.motor_.hw_config_.timer->Instance->CR1 & TIM_CR1_DIR; - bool current_meas_not_DC_CAL = !counting_down; + + // Check the timing of the sequencing + if (current_meas_not_DC_CAL) + axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_I); + else + axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_DC); + bool update_timings = false; if (hadc == &hadc2) { if (&axis == axes[1] && counting_down) @@ -503,12 +516,6 @@ void pwm_trig_adc_cb(ADC_HandleTypeDef* hadc, bool injected) { update_brake_current(); } - // Check the timing of the sequencing - if (current_meas_not_DC_CAL) - axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_I); - else - axis.motor_.log_timing(Motor::TIMING_LOG_ADC_CB_DC); - uint32_t ADCValue; if (injected) { ADCValue = HAL_ADCEx_InjectedGetValue(hadc, ADC_INJECTED_RANK_1); diff --git a/Firmware/MotorControl/low_level.h b/Firmware/MotorControl/low_level.h index 605db9ba..3a3225de 100644 --- a/Firmware/MotorControl/low_level.h +++ b/Firmware/MotorControl/low_level.h @@ -46,7 +46,8 @@ void pwm_in_cb(int channel, uint32_t timestamp); void start_adc_pwm(); void start_pwm(TIM_HandleTypeDef* htim); void sync_timers(TIM_HandleTypeDef* htim_a, TIM_HandleTypeDef* htim_b, - uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset); + uint16_t TIM_CLOCKSOURCE_ITRx, uint16_t count_offset, + TIM_HandleTypeDef* htim_refbase = nullptr); void start_general_purpose_adc(); float get_adc_voltage(GPIO_TypeDef* GPIO_port, uint16_t GPIO_pin); void pwm_in_init(); diff --git a/Firmware/MotorControl/motor.cpp b/Firmware/MotorControl/motor.cpp index 230f7f64..5585a862 100644 --- a/Firmware/MotorControl/motor.cpp +++ b/Firmware/MotorControl/motor.cpp @@ -149,13 +149,8 @@ bool Motor::do_checks() { } void Motor::log_timing(TimingLog_t log_idx) { - TIM_HandleTypeDef* htim = hw_config_.timer; - uint16_t timing = htim->Instance->CNT; - bool down = htim->Instance->CR1 & TIM_CR1_DIR; - if (down) { - uint16_t delta = TIM_1_8_PERIOD_CLOCKS - timing; - timing = TIM_1_8_PERIOD_CLOCKS + delta; - } + static const uint16_t clocks_per_cnt = (uint16_t)((float)TIM_1_8_CLOCK_HZ / (float)TIM_APB1_CLOCK_HZ); + uint16_t timing = clocks_per_cnt * htim13.Instance->CNT; // TODO: Use a hw_config if (log_idx < TIMING_LOG_NUM_SLOTS) { timing_log_[log_idx] = timing; From b4fcb290a450b5acf957e85049529a67d7554e18 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Wed, 24 Oct 2018 23:57:42 -0700 Subject: [PATCH 39/40] add overspeed fault --- CHANGELOG.md | 3 +++ Firmware/MotorControl/controller.cpp | 13 +++++++++++++ Firmware/MotorControl/controller.hpp | 16 ++++++++++++++-- Firmware/MotorControl/encoder.cpp | 2 +- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d918843..34e7ada3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # Unreleased Features Please add a note of your changes below this heading if you make a Pull Request. +### Added +* Overspeed fault + ### Changed * Increased switching frequency from around 8kHz to 24kHz. Control loops still run at 8kHz. * Renamed `axis.enable_step_dir` to `axis.step_dir_active` diff --git a/Firmware/MotorControl/controller.cpp b/Firmware/MotorControl/controller.cpp index bf50a15a..8c202ae0 100644 --- a/Firmware/MotorControl/controller.cpp +++ b/Firmware/MotorControl/controller.cpp @@ -13,6 +13,11 @@ void Controller::reset() { current_setpoint_ = 0.0f; } +void Controller::set_error(Error_t error) { + error_ |= error; + axis_->error_ |= Axis::ERROR_CONTROLLER_FAILED; +} + //-------------------------------- // Command Handling //-------------------------------- @@ -126,6 +131,14 @@ bool Controller::update(float pos_estimate, float vel_estimate, float* current_s if (vel_des > vel_lim) vel_des = vel_lim; if (vel_des < -vel_lim) vel_des = -vel_lim; + // Check for overspeed fault (done in this module (controller) for cohesion with vel_lim) + if (config_.vel_limit_tolerance > 0.0f) { // 0.0f to disable + if (fabsf(vel_estimate) > config_.vel_limit_tolerance * vel_lim) { + set_error(ERROR_OVERSPEED); + return false; + } + } + // Velocity control float Iq = current_setpoint_; diff --git a/Firmware/MotorControl/controller.hpp b/Firmware/MotorControl/controller.hpp index 3db712e4..f99f25d4 100644 --- a/Firmware/MotorControl/controller.hpp +++ b/Firmware/MotorControl/controller.hpp @@ -7,6 +7,11 @@ class Controller { public: + enum Error_t { + ERROR_NONE = 0, + ERROR_OVERSPEED = 0x01, + }; + // Note: these should be sorted from lowest level of control to // highest level of control, to allow "<" style comparisons. enum ControlMode_t{ @@ -23,11 +28,13 @@ public: float vel_gain = 5.0f / 10000.0f; // [A/(counts/s)] // float vel_gain = 5.0f / 200.0f, // [A/(rad/s)] float vel_integrator_gain = 10.0f / 10000.0f; // [A/(counts/s * s)] - float vel_limit = 20000.0f; // [counts/s] + float vel_limit = 20000.0f; // [counts/s] + float vel_limit_tolerance = 1.2f; // ratio to vel_lim. 0.0f to disable }; Controller(Config_t& config); void reset(); + void set_error(Error_t error); void set_pos_setpoint(float pos_setpoint, float vel_feed_forward, float current_feed_forward); void set_vel_setpoint(float vel_setpoint, float current_feed_forward); @@ -68,6 +75,7 @@ public: .calib_vel_threshold = 1.0f, }; + Error_t error_ = ERROR_NONE; // variables exposed on protocol float pos_setpoint_ = 0.0f; float vel_setpoint_ = 0.0f; @@ -80,6 +88,7 @@ public: // Communication protocol definitions auto make_protocol_definitions() { return make_protocol_member_list( + make_protocol_property("error", &error_), make_protocol_property("pos_setpoint", &pos_setpoint_), make_protocol_property("vel_setpoint", &vel_setpoint_), make_protocol_property("vel_integrator_current", &vel_integrator_current_), @@ -89,7 +98,8 @@ public: make_protocol_property("pos_gain", &config_.pos_gain), make_protocol_property("vel_gain", &config_.vel_gain), make_protocol_property("vel_integrator_gain", &config_.vel_integrator_gain), - make_protocol_property("vel_limit", &config_.vel_limit) + make_protocol_property("vel_limit", &config_.vel_limit), + make_protocol_property("vel_limit_tolerance", &config_.vel_limit_tolerance) ), make_protocol_function("set_pos_setpoint", *this, &Controller::set_pos_setpoint, "pos_setpoint", "vel_feed_forward", "current_feed_forward"), @@ -103,4 +113,6 @@ public: } }; +DEFINE_ENUM_FLAG_OPERATORS(Controller::Error_t) + #endif // __CONTROLLER_HPP diff --git a/Firmware/MotorControl/encoder.cpp b/Firmware/MotorControl/encoder.cpp index f8e1e530..58926958 100644 --- a/Firmware/MotorControl/encoder.cpp +++ b/Firmware/MotorControl/encoder.cpp @@ -24,7 +24,7 @@ void Encoder::setup() { enc_index_cb_wrapper, this); } -void Encoder::set_error(Encoder::Error_t error) { +void Encoder::set_error(Error_t error) { error_ |= error; axis_->error_ |= Axis::ERROR_ENCODER_FAILED; } From 138fd19d737e3f76155fc07ef957a26fdd176fe2 Mon Sep 17 00:00:00 2001 From: Oskar Weigl Date: Sun, 28 Oct 2018 14:59:18 -0700 Subject: [PATCH 40/40] update Cangelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34e7ada3..3167be4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Please add a note of your changes below this heading if you make a Pull Request. ### Changed * Increased switching frequency from around 8kHz to 24kHz. Control loops still run at 8kHz. * Renamed `axis.enable_step_dir` to `axis.step_dir_active` +* New process for working with STM32CubeMX. ## Fixed * Would get ERROR_CONTROL_DEADLINE_MISSED along with every ERROR_PHASE_RESISTANCE_OUT_OF_RANGE.