diff --git a/AGENTS.md b/AGENTS.md index edb1dd2..601442e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,6 +9,10 @@ STM32CubeMX 生成的项目,使用 **Keil MDK-ARM V5.32** 工具链。 - `STM32F103C8T6/MDK-ARM/STM32F103C8T6.uvprojx` — Keil 工程文件 - `STM32F103C8T6/Drivers/BSP/MultiButton/` — MultiButton 按键驱动库 - `STM32F103C8T6/Drivers/BSP/LCD/` — ST7735S LCD 驱动 + - `st7735s.c/h` — 底层驱动(SPI通信、初始化、填充、画点) + - `lcd.c/h` — 绘图模块(字符/字符串、线条、矩形、圆形) + - `lcd_data.c/h` — ASCII 8×16 字库 + - `hz16_data.c/h` — CJK 16×16 字库 ## 硬件配置 - **MCU**: STM32F103C8T6 (LQFP48, 72MHz, 64KB Flash, 20KB RAM) @@ -19,42 +23,45 @@ STM32CubeMX 生成的项目,使用 **Keil MDK-ARM V5.32** 工具链。 - LED: PC13 (低电平有效,上拉) - 按键: PB3 (KEY1), PB4 (KEY2), PB5 (KEY3), PC14 (KEY4), PC15 (KEY5) — 下拉 - LCD: PB10 (DC), PB11 (CS), PB12 (RST), PB13 (SCK), PB15 (SDA) — ST7735S 128x160 + - TIM4: PB6~9 四路 1kHz PWM + - TIM3: CH4 内部触发 ADC1 注入组 + - ADC1: IN0~IN3 (PA0~PA3), 注入组, TIM3_CH4 触发 -## MultiButton 按键库 -- **来源**: [0x1abin/MultiButton](https://github.com/0x1abin/MultiButton) -- **功能**: 事件驱动型按键驱动,支持单击、双击、长按、连击等事件 -- **文件**: - - `Drivers/BSP/MultiButton/multi_button.c/.h` — 核心库文件 - - `Drivers/BSP/MultiButton/button_driver.c/.h` — 本项目适配层 -- **定时器**: SysTick 中断中每5ms调用 `button_ticks()` -- **使用示例**: +## 初始化顺序(main.c) +``` +HAL_Init → SystemClock_Config → MX_GPIO → MX_DMA → MX_USART1 → MX_SPI2 +→ MX_TIM4 → MX_ADC1 → MX_TIM3 +→ button_driver_init() → st7735s_init() → lcd_* draw → PWM start → ADC start +``` + +## ADC 采坑记录(不可从 CubeMX 重新生成时光靠设置) +- **ADC 时钟**: SystemClock_Config 初始为 PCLK2/2=36MHz(超 14MHz 规格),必须在 `USER CODE SysInit` 中手动改为 `/6`: ```c - /* 在回调函数中处理按键事件 */ - static void button_key1_callback(Button* handle, void* user_data) { - HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); - printf("KEY1: LED翻转\n"); - } - - /* 初始化时注册回调 */ - button_attach(&btn_handle, BTN_SINGLE_CLICK, button_key1_callback, NULL); + RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_ADCPRE) | RCC_CFGR_ADCPRE_DIV6; ``` +- **TIM3_CH4 触发 ADC**: CubeMX 默认生成 `TIM_OCMODE_TIMING`,这不会产生 OC4REF 上升沿 → ADC 收不到触发。必须在 `tim.c` 中手动改为 `TIM_OCMODE_PWM1` + `Pulse = 500`。CubeMX 需选 CH4 为 "PWM Generation4 No Output" 并设 Pulse=500。 + +## printf 无 MicroLIB +在 `usart.c` 中通过 `#pragma import(__use_no_semihosting)` + 提供 `_sys_exit()` + `struct __FILE` + `FILE __stdout` 实现。Keil 取消勾选 Use MicroLIB 即可。 + +## SPI 注意事项 +- LCD (ST7735S) 使用**硬件SPI2**(PB13 SCK, PB15 MOSI),18MHz,**Mode 3**(CPOL=HIGH, CPHA=2EDGE) +- 若通过 CubeMX 重新生成 `spi.c`,务必在 SPI2 配置中设置 Clock Polarity=High, Clock Phase=2 Edge +- CS(PB11)、DC(PB10)、RST(PB12) 为 GPIO 控制 + +## LCD 字库生成(tools/font_gen.py) +- Python + Pillow 渲染,使用 `C:\ProgramData\anaconda3\python.exe` +- ASCII 8×16(默认):`python font_gen.py` +- CJK 16×16(按需):`python font_gen.py --cjk --string "你的汉字" --output STM32F103C8T6/Drivers/BSP/LCD/hz16_data` +- ASCII 默认参数:`--font simsun --size 56 --threshold 64 --scale 4` +- CJK 默认参数:`--font simsun --size 48 --threshold 50 --scale 3` +- ASCII `_` 下划线手动设为 `0x7F`(GDI 无法可靠提取) +- 输出目录 `MDK-ARM\STM32F103C8T6\` 已 gitignore ## 代码规范 - **遵循**: `嵌入式C语言代码规范(V1.0).md` - **缩进**: 4个空格,禁止Tab -- **命名**: - - 变量/函数: 小写+下划线,全局变量`g_`前缀,静态变量`s_`前缀,指针`p_`前缀 - - 宏/常量: 大写+下划线,模块名前缀 - - 类型: 小写+下划线+`_t`后缀 -- **注释**: 关键逻辑每行注释,函数必须完整注释(功能/参数/返回值/说明) -- **大括号**: 所有if/for/while必须加大括号,左大括号同行,右大括号单独行 +- **命名**: 小写+下划线;全局加 `g_`,静态加 `s_`,指针加 `p_`;宏大写+下划线;类型 `_t` 后缀 +- **注释**: 所有文档、注释、提交信息使用**中文** - **禁止**: goto、递归、可变参数函数、注释掉的代码提交 - -## 语言要求 -- 所有文档、注释、提交信息必须使用**中文** - -## 重要说明 -- `Drivers/` 目录包含 HAL 驱动源码 — 禁止直接修改 -- 通过 CubeMX `.ioc` 文件重新生成代码,禁止手动修改 HAL 文件 -- Keil 构建输出在 `MDK-ARM/STM32F103C8T6/`(已 gitignore) -- CubeMX 生成的代码中,自定义代码必须放在 `/* USER CODE BEGIN */` 和 `/* USER CODE END */` 之间 +- **CubeMX 代码**: 自定义代码必须在 `/* USER CODE BEGIN */` 和 `/* USER CODE END */` 之间;`Drivers/` 下 HAL 源码禁止直接修改 diff --git a/ST7735S_V1.1_20111121.md b/ST7735S_V1.1_20111121.md new file mode 100644 index 0000000..0e0ab1c --- /dev/null +++ b/ST7735S_V1.1_20111121.md @@ -0,0 +1,5071 @@ +## ST7735S + +# 132RGB x 162dot 262K Color with Frame Memory Single-Chip TFT Controller/Driver + +## Datasheet + +Version 1.1 + +2011/11 + +## Sitronix Technology Corporation + +Sitronix Technology Corp. reserves the right to change the contents in this document without prior notice. + +## LIST OF CONTENT + +1 GENERAL DESCRIPTION....2 +2 FEATURES 2 +3 PAD ARRANGEMENT....4 + +3.1 Output Bump Dimension....4 +3.2 Input Bump Dimension....5 +3.3 Alignment Mark Dimension 6 +3.4 Chip Information....7 + +4 PAD CENTER COORDINATES .... 8 +5 BLOCK DIAGRAM....14 +6 PIN DESCRIPTION....15 + +6.1 Power Supply Pin....15 +6.2 Interface Logic Pin....15 +6.3 Mode Selection Pin....17 +6.4 Driver Output pins....18 +6.5 Test Pins....19 + +7 DRIVER ELECTRICAL CHARACTERISTICS....20 + +7.1 Absolute Operation Range....20 +7.2 DC Characteristic....21 +7.3 Power Consumption....22 + +8 Timing chart.... 23 + +8.1 Parallel Interface Characteristics: 18, 16, 9 or 8-bit Bus (8080 Series MCU Interface) +23 +8.2 Parallel Interface Characteristics: 18, 16, 9 or 8-bit Bus (6800 Series MCU Interface) +25 +8.3 Serial Interface Characteristics (3-line Serial)....27 +8.4 Serial Interface Characteristics (4-line Serial)....28 + +9 Function Description....29 + +9.1 Interface Type Selection ....29 +9.2 8080-series MCU Parallel Interface (P68 = '0')....30 + +9.2.1 Write Cycle Sequence.... 31 +9.2.2 Read Cycle Sequence 32 + +9.3 6800-series MCU Parallel Interface (P68 = '1')....33 + +9.3.1 Write Cycle Sequence.... 34 +9.3.2 Read Cycle Sequence 35 + +9.4 Serial Interface....36 + +9.4.1 Command Write Mode 36 +9.4.2 Read Functions....38 + +9.4.3 3-line Serial Protocol....38 +9.4.4 4-line Serial Protocol 39 + +## 9.5 Data Transfer Break and Recovery....40 + +## 9.6 Data Transfer Pause....42 + +9.6.1 Serial Interface Pause....42 +9.6.2 Parallel Interface Pause 42 + +## 9.7 Data Transfer Modes ....43 + +9.7.1 Method 1....43 +9.7.2 Method 2 43 + +## 9.8 Data Color Coding ....44 + +9.8.1 8-bit Parallel Interface (IM2, IM1, IM0= "100").... 44 +9.8.2 8-bit Data Bus for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH= "03h".... 44 +9.8.3 8-bit Data Bus for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH= "05h"....45 +9.8.4 8-bit Data Bus for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH= "06h"....46 +9.8.5 16-Bit Parallel Interface (IM2,IM1, IM0= "101"). 47 +9.8.6 16-bit Data Bus for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH= "03h"....47 +9.8.7 16-bit Data Bus for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH= "05h"....48 +9.8.8 16-bit Data Bus for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH= "06h"....49 +9.8.9 9-Bit Parallel Interface (IM2, IM1, IM0="110").... 50 +9.8.10 Write 9-bit Data for RGB 6-6-6-bit Input (262k-color) 50 +9.8.11 18-Bit Parallel Interface (IM2, IM1, IM0="111"). 51 +9.8.12 18-bit Data Bus for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH="03h"....51 +9.8.13 18-bit Data Bus for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH="05h"....52 +9.8.14 18-bit Data Bus for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH="06h"....53 +9.8.15 3-line Serial Interface .... 54 +9.8.16 Write Data for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH="03h"....54 +9.8.17 Write Data for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH="05h"....55 +9.8.18 Write Data for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH="06h"....56 +9.8.19 4-line Serial Interface 57 +9.8.20 Write Data for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH="03h"....57 +9.8.21 Write Data for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH="05h"....58 +9.8.22 Write Data for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH="06h"....58 + +## 9.9 Display Data RAM....59 + +9.9.1 Configuration (GM[1:0] = "00").... 59 +9.9.2 Memory to Display Address Mapping .... 60 +9.9.3 When using 128RGB x 160 resolution (GM[1:0] = "11", SMX=SMY=SRGB= '0')....60 +9.9.4 When using 132RGB x 132resolution (GM[1:0] = "01", SMX=SMY=SRGB= '0')....61 +9.9.5 When using 132RGB x 162 resolution (GM[1:0] = "00", SMX=SMY=SRGB= '0')....62 + +9.9.6 Normal Display On or Partial Mode On....63 +9.9.7 When using 128RGB x 160 resolution (GM[1:0] = "11").... 63 +9.9.8 When using 128RGB x 160 resolution (GM[1:0] = "01").... 64 +9.9.9 When using 132RGB x 162 resolution (GM[1:0] = "00").... 65 + +9.10 Address Counter....66 + +9.11 Memory Data Write/ Read Direction ....67 + +9.11.1 When 128RGBx160 (GM= "11") 67 +9.11.2 When 132RGBx132 (GM= "01") 67 +9.11.3 When 132RGBx162 (GM= "00") 68 +9.11.4 Frame Data Write Direction According to the MADCTL Parameters (MV, MX and MY)...... 69 +9.11.5 Scroll Address Circuit....70 +9.11.6 Vertical Scroll Mode 70 +9.11.7 Vertical Scroll Example 71 +9.11.8 Case 1: TFA + VSA + BFA<162 71 +9.11.9 Case 2: TFA + VSA + BFA=162 (Rolling Scrolling).... 72 + +9.12 Tearing Effect Output Line 73 + +9.12.1 Tearing Effect Line Modes 73 +9.12.2 Tearing Effect Line Timings 74 +9.12.3 Example 1: MPU Write is faster than panel read....75 +9.12.4 Example 2: MPU Write is slower than panel read.... 76 + +9.13 Power ON/OFF Sequence 77 + +9.13.1 Uncontrolled Power Off....78 + +9.14 Power Level Definition ....79 + +9.14.1 Power Level....79 +9.14.2 Power Flow Chart....80 + +9.15 Reset Table ....81 + +9.15.1 Reset Table(Default Value, GM[1:0]="11", 128RGB x 160)....81 +9.15.2 Reset Table (GM[1:0]="01", 132RGB x 132)....82 +9.15.3 Reset Table (GM[1:0]="00", 132RGB x 162)....83 + +9.16 Module Input/Output Pins ....84 + +9.16.1 Output or Bi-directional (I/O) Pins 84 + +9.17 Reset Timing....85 +9.18 Color Depth Conversion Look Up Tables....86 + +9.18.1 65536 Color to 262,144 Color....86 +9.18.2 4096 Color to 262,144 Color....90 + +9.19 Sleep Out-Command and Self-Diagnostic Functions of the Display Module .....92 + +9.19.1 Register Loading Detection....92 +9.19.2 Functionality Detection....93 + +9.19.3 Chip Attachment Detection (Optional) 94 +9.19.4 Display Glass Break Detection (Optional).... 95 + +## 10 COMMAND....96 + +## 10.1 System Function Command List and Description ....96 + +10.1.1 NOP (00h) 99 +10.1.2 SWRESET (01h): Software Reset .... 100 +10.1.3 RDDID (04h): Read Display ID .... 101 +10.1.4 RDDST (09h): Read Display Status.... 102 +10.1.5 RDDPM (0Ah): Read Display Power Mode .... 104 +10.1.6 RDDMADCTL (0Bh): Read Display MADCTL 105 +10.1.7 RDDCOLMOD (0Ch): Read Display Pixel Format.... 106 +10.1.8 RDDIM (0Dh): Read Display Image Mode.... 107 +10.1.9 RDDSM (0Eh): Read Display Signal Mode.... 108 +10.1.10 RDDSDR (0Fh): Read Display Self-Diagnostic Result .... 110 +10.1.11 SLPIN (10h): Sleep In 111 +10.1.12 SLPOUT (11h): Sleep Out 112 +10.1.13 PTLON (12h): Partial Display Mode On.... 113 +10.1.14 NORON (13h): Normal Display Mode On.... 114 +10.1.15 INVOFF (20h): Display Inversion Off .... 115 +10.1.16 INVON (21h): Display Inversion On....116 +10.1.17 GAMSET (26h): Gamma Set 117 +10.1.18 DISPOFF (28h): Display Off.... 118 +10.1.19 DISPON (29h): Display On 119 +10.1.20 CASET (2Ah): Column Address Set 120 +10.1.21 RASET (2Bh): Row Address Set 122 +10.1.22 RAMWR (2Ch): Memory Write.... 124 +10.1.23 RGBSET (2Dh): Color Setting for 4K, 65K and 262K.... 125 +10.1.24 RAMRD (2Eh): Memory Read 126 +10.1.25 PTLAR (30h): Partial Area .... 127 +10.1.26 SCRLAR (33h): Scroll Area Set.... 129 +10.1.27 TEOFF (34h): Tearing Effect Line OFF .... 131 +10.1.28 TEON (35h): Tearing Effect Line ON 132 +10.1.29 MADCTL (36h): Memory Data Access Control....134 +10.1.30 VSCSAD: Vertical Scroll Start Address of RAM (37h)....137 +10.1.31 IDMOFF (38h): Idle Mode Off 139 +10.1.32 IDMON (39h): Idle Mode On....140 +10.1.33 COLMOD (3Ah): Interface Pixel Format 142 +10.1.34 RDID1 (DAh): Read ID1 Value.... 143 + +10.1.35 RDID2 (DBh): Read ID2 Value....144 +10.1.36 RDID3 (DCh): Read ID3 Value 146 + +## 10.2 Panel Function Command List and Description....147 + +10.2.1 FRMCTR1 (B1h): Frame Rate Control (In normal mode/ Full colors) .... 151 +10.2.2 FRMCTR2 (B2h): Frame Rate Control (In Idle mode/ 8-colors).... 152 +10.2.3 FRMCTR3 (B3h): Frame Rate Control (In Partial mode/ full colors) .... 153 +10.2.4 INVCTR (B4h): Display Inversion Control.... 154 +10.2.5 PWCTR1 (C0h): Power Control 1 155 +10.2.6 PWCTR2 (C1h): Power Control 2....157 +10.2.7 PWCTR3 (C2h): Power Control 3 (in Normal mode/ Full colors).... 159 +10.2.8 PWCTR4 (C3h): Power Control 4 (in Idle mode/ 8-colors).... 161 +10.2.9 PWCTR5 (C4h): Power Control 5 (in Partial mode/ full-colors).... 163 +10.2.10 VMCTR1 (C5h): VCOM Control 1 165 +10.2.11 VMOFCTR (C7h): VCOM Offset Control 167 +10.2.12 WRID2 (D1h): Write ID2 Value 169 +10.2.13 WRID3 (D2h): Write ID3 Value 170 +10.2.14 NVFCTR1 (D9h): NVM Control Status.... 171 +10.2.15 NVFCTR2 (DEh): NVM Read Command.... 172 +10.2.16 NVFCTR3 (DFh): NVM Write Command 173 +10.2.17 GMCTRP1 (E0h): Gamma ('+'polarity) Correction Characteristics Setting .... 174 +10.2.18 GMCTRN1 (E1h): Gamma '-'polarity Correction Characteristics Setting .... 176 +10.2.19 GCV(FCh): Gate Pump Clock Frequency Variable .... 178 + +## 11 Power Sturcture....179 + +11.1 Driver IC Operating Voltage Specification....179 +11.2 Power Booster Circuit .... 180 + +## 12 Gamma Structure.... 181 + +12.1 Structure of Grayscale Amplifier ....181 +12.2 Gamma Voltage Formula (Positive/ Negative Polarity)....182 + +## 13 Example Connection with Panel Direction and Different Resolution 184 + +13.1 Application of Connection with Panel Direction....184 +13.2 Application of Connection with Different Resolution....186 +13.3 Microprocessor Interface Applications .... 189 + +13.3.1 8080-Series MCU Interface for 8-bit Data Bus (P68=0, IM2, IM1, IM0="100")..... 189 +13.3.2 8080-Series MCU Interface for 16-bit Data Bus (P68=0, IM2, IM1, IM0="101")..... 189 +13.3.3 8080-Series MCU Interface for 9-bit Data Bus (P68=0, IM2, IM1, IM0="110")..... 189 +13.3.4 8080-Series MCU Interface for 18-bit Data Bus (P68=0, IM2, IM1, IM0="111")..... 190 +13.3.5 6800-Series MCU Interface for 8-bit Data Bus (P68=1, IM2, IM1, IM0="100")..... 190 + +13.3.6 6800-Series MCU Interface for 16-bit Data Bus (P68=1, IM2, IM1, IM0="101")..... 190 +13.3.7 6800-Series MCU Interface for 9-bit Data Bus (P68=1, IM2, IM1, IM0="110")..... 191 +13.3.8 6800-Series MCU Interface for 18-bit Data Bus (P68=1, IM2, IM1, IM0="111")..... 191 +13.3..9 3-Line Serial MCU Interface (IM2, IM1, IM0="000", SPI4W=0).... 191 +13.3.10 4-Line Serial MCU Interface (IM2, IM1, IM0="000", SPI4W=1).... 192 + +## 14 Revision History ...... 193 + +## LIST OF FIGURES + +Figure 1 Parallel interface timing characteristics (8080 series MCU interface).... 23 +Figure 2 Rising and falling timing for input and output signal....24 +Figure 3 Chip selection (CSX) timing 24 +Figure 4 Write-to-read and read-to-write timing....24 +Figure 5 Parallel Interface Timing Characteristics (6800-Series MCU Interface) 25 +Figure 6 3-line serial interface timing....27 +Figure 7 4-line serial interface timing....28 +Figure 8 8080-series WRX protocol .... 31 +Figure 9 8080-series parallel bus protocol, write to register or display RAM 31 +Figure 10 8080-series RDX protocol 32 +Figure 11 8080-series parallel bus protocol, read data from register or display RAM .... 32 +Figure 12 6800-Series Write Protocol 34 +Figure 13 6800-series parallel bus protocol, write to register or display RAM....34 +Figure 14 6800-series read protocol....35 +Figure 15 6800-series parallel bus protocol, read data form register or display RAM .... 35 +Figure 16 Serial interface data stream format....37 +Figure 17 3-line serial interface write protocol (write to register with control bit in transmission)....37 +Figure 18 4-line serial interface write protocol (write to register with control bit in transmission)....37 +Figure 19 3-line serial interface read protocol 38 +Figure 20 4-line serial interface read protocol 39 +Figure 21 Serial bus protocol, write mode—interrupted by RESX....40 +Figure 22 Serial bus protocol, write mode—interrupted by CSX .... 40 +Figure 23 Write interrupts recovery (serial interface) 41 +Figure 24 Write interrupts recovery (both serial and parallel Interface) 41 +Figure 25 Serial interface pause protocol (pause by CSX)....42 +Figure 26 Parallel bus pause protocol (paused by CSX) 42 +Figure 27 Display data RAM organization....59 +Figure 28 Data streaming order....67 + +## LIST OF TABLES + +Table 1 Absolute Operation Range .... 20 + +Table 2 DC Characteristic....21 + +Table 3 Power Consumption 22 + +Table 4 8080 Parallel Interface Characteristics....24 + +Table 5 6800 Parallel Interface Characteristics....26 + +Table 6 3-line Serial Interface Characteristics....27 + +Table 7 4-line Serial Interface Characteristics....28 + +Table 8 Interface Type Selection....29 + +Table 9 Pin Connection According to Various MCU Interface....29 + +Table 10 The Function of 8080-series Parallel Interface....30 + +Table 11 The Function of 6800-series Parallel Interface.... 33 + +Table 12 Selection of Serial Interface....36 + +Table 13 AC characteristics of Tearing Effect Signal Idle Mode Off (Frame Rate = 60 Hz, Ta=25°C)..... 74 + +Table 14 Reset Timing....85 + +Table 15 System Function Command List (1)....96 + +Table 16 System Function Command List (2)....97 + +Table 17 System Function command List (3)....98 + +Table 18 Panel Function Command List (1)....147 + +Table 19 Panel Function Command List (2)....148 + +Table 20 Panel Function Command List (3)....149 + +Table 21 Panel Function Command List (4)....150 + +## 1 GENERAL DESCRIPTION + +The ST7735S is a single-chip controller/driver for 262K-color, graphic type TFT-LCD. It consists of 396 source line and 162 gate line driving circuits. This chip is capable of connecting directly to an external microprocessor, and accepts Serial Peripheral Interface (SPI), 8-bit/9-bit/16-bit/18-bit parallel interface. Display data can be stored in the on-chip display data RAM of 132 x 162 x 18 bits. It can perform display data RAM read/write operation with no external operation clock to minimize power consumption. In addition, because of the integrated power supply circuits necessary to drive liquid crystal, it is possible to make a display system with fewer components. + +## 2 FEATURES + +## Single Chip TFT-LCD Controller/Driver with RAM On-chip Display Data RAM (i.e. Frame Memory) + +132 (H) x RGB x 162 (V) Bits + +## LCD Driver Output Circuits: + +Source Outputs: 132 RGB Channels + +Gate Outputs: 162 Channels + +Common Electrode Output + +## Display Colors (Color Mode) + +Full Color: 262K, RGB=(666) Max., Idle Mode OFF + +Color Reduce: 8-color, RGB=(111), Idle Mode ON + +## Programmable Pixel Color Format (Color Depth) for Various Display Data input Format + +12-bit/pixel: RGB=(444) Using the 384k-bit Frame Memory and LUT + +16-bit/pixel: RGB=(565) Using the 384k-bit Frame Memory and LUT + +18-bit/pixel: RGB=(666) Using the 384k-bit Frame Memory and LUT + +## Various Interfaces + +Parallel 8080-series MCU Interface + +(8-bit, 9-bit, 16-bit & 18-bit) + +Parallel 6800-series MCU Interface + +(8-bit, 9-bit, 16-bit & 18-bit) + +3-line Serial Interface + +4-line Serial Interface + +## Display Features + +Support Both Normal-black & Normal-white LC + +Software Programmable Color Depth Mode + +Partial Window Moving & Data Scrolling + +## Built-in Circuits + +DC/DC Converter + +Adjustable VCOM Generation + +Non-volatile (NV) Memory to Store Initial Register Setting + +Oscillator for Display Clock Generation + +Factory default value (module ID, module version, etc) are stored in NV memory. + +Timing Controller + +## Built-in NV Memory for LCD Initial Register Setting + +7-bits for ID2 + +8-bits for ID3 + +7-bits for VCOM Offset Adjustment + +## Wide Supply Voltage Range + +I/O Voltage (VDDI to DGND): 1.65V\~3.7V (VDDI ≤ VDD) + +Analog Voltage (VDD to AGND): 2.5V\~4.8V + +## On-Chip Power System + +Source Voltage (GVDD to AGND): 3.15V to 5V + +VCOM level (VCOM to AGND): -0.425V to -2.0V + +Gate Driver HIGH Level (VGH to AGND): +10.0V to +15V + +Gate Driver LOW Level (VGL to AGND): -13V to -7.5V + +Operating Temperature: -30°C to +85°C + +3 PAD ARRANGEMENT +![](images/61f49536e16aa8267e1e9120af6d28c3aacc91f2baa5c74c3ead640c6d43f23b.jpg) + +
+flowchart + +This diagram illustrates the layout and dimensions of a display panel, showing input pad, source pad, and gateway pad connections with dimensions in micrometers. +
+ +3.1 Output Bump Dimension +![](images/ad27f3978658ebe5a3f595a61694257bb642d2ad9a69ea253887bb0604b4a59d.jpg) + +
+text_image + +Boundary (Include scribe Lane) +C K L +H +J +A +
+ +
ItemSymbolSize
Bump PitchA16 um
Bump WidthC16 um
Bump HeightH98 um
Bump Gap1 (Vertical)J19 um
Bump Gap2 (Horizontal)K16 um
Bump AreaC x H1568 um2
Chip Boundary (Include Scribe Lane)L59 um
+ +## 3.2 Input Bump Dimension + +![](images/fe1eef8b8c2c2f483bb97d034f910b2059a369136b1e9f4df743c7aea2a94616.jpg) + +
+text_image + +C2 +C2 +A1 +A2 +C1 +H +K +K2 +K1 +K1 +L +
+ +Boundary (Include scribe Lane) + +
ItemSymbolSize
Bump Pitch 1A172.5 um
Bump Pitch 2A260 um
Bump Width 1C138 um
Bump Width 2C233 um
Bump HeightH88 um
Bump GapK17 um
Bump Gap1K122 um
Bump Gap2K234.5 um
Bump Area 1C1 X H3344 um2
Bump Area 2C2 X H2904 um2
Chip Boundary(Include Scribe Lane)L60 um
+ +## 3.3 Alignment Mark Dimension + +![](images/ea1c418df6df5668871b0046487f28565bbc9d52fab17dc0b31bad6a590e3af4.jpg) + +## 3.4 Chip Information + +Chip Size (um x um): 10080 x 670 + +PAD Coordinate: Pad Center + +Coordinate Origin: Chip Center + +Chip Thickness (um): 300(TYP) + +Bump Height (um): 12(TYP) + +Bump Hardness (HV): 75(TYP) + +![](images/79ccc3274db8f5222be000877910f3eef8552964f77decd380ced155471addbd.jpg) + +
+text_image + +No.186 +No.185 +ST7735S +(Bump-up) +S197 +S200 +S199 +S198 +X,Y (0.0) +No.755 +No.1 +
+ +4 PAD CENTER COORDINATES + +
No.PAD NameXY
1Dummy-4750-231
2VDDIO-4700-231
3EXTC-4650-231
4DGNDO-4600-231
5IMO-4550-231
6VDDIO-4500-231
7IM1-4450-231
8DGNDO-4400-231
9P68-4350-231
10VDDIO-4300-231
11TEST1P-4250-231
12DGNDO-4200-231
13TEST2P-4150-231
14VDDIO-4100-231
15SRGB-4050-231
16DGNDO-4000-231
17SMX-3950-231
18VDDIO-3900-231
19SMY-3850-231
20DGNDO-3800-231
21Dummy-3750-231
22VDDIO-3700-231
23Dummy-3650-231
24DGNDO-3600-231
25Dummy-3550-231
26VDDIO-3500-231
27Dummy-3450-231
28DGNDO-3400-231
29Dummy-3350-231
30VDDIO-3300-231
31LCM-3250-231
32DGNDO-3200-231
33DUMMY-3150-231
34VDDIO-3100-231
35Dummy-3050-231
36DGNDO-3000-231
37GM1-2950-231
38VDDIO-2900-231
39GM0-2850-231
40DGNDO-2800-231
41Dummy-2750-231
42GS-2700-231
43SPI4W-2650-231
44VDDIO-2600-231
45TESTOP[8]-2550-231
46TESTOP[7]-2500-231
47TESTOP[6]-2450-231
48TESTOP[5]-2400-231
49TESTOP[4]-2350-231
50OSCP-2300-231
+ +
No.PAD NameXY
51VDD-2250-231
52VDD-2200-231
53VDD-2150-231
54VDD-2100-231
55VDD-2050-231
56VDD-2000-231
57AGND-1950-231
58AGND-1900-231
59AGND-1850-231
60AGND-1800-231
61AGND-1750-231
62AGND-1700-231
63RDX-1630-231
64D_CX-1570-231
65TESEL-1510-231
66DGNDO-1450-231
67D17-1390-231
68D16-1330-231
69D15-1270-231
70D14-1210-231
71D13-1150-231
72D12-1090-231
73D11-1030-231
74D10-970-231
75D9-910-231
76D8-850-231
77D1-790-231
78D3-730-231
79D5-670-231
80D7-610-231
81TE-550-231
82RESX-490-231
83CSX-430-231
84D6-370-231
85D4-310-231
86D2-250-231
87IM2-190-231
88D0-130-231
89WRX-70-231
90Dummy0-231
91Dummy50-231
92Dummy100-231
93Dummy150-231
94TESTOP[3]200-231
95TESTOP[2]250-231
96TESTOP[1]300-231
97DGND350-231
98DGND400-231
99DGND450-231
100DGND500-231
+ +
No.PAD NameXY
101DGND550-231
102DGND600-231
103VDDI650-231
104VDDI700-231
105VDDI750-231
106VDDI800-231
107VDDI850-231
108VDDI900-231
109VPP950-231
110VPP1000-231
111VPP1050-231
112GVDD1100-231
113GVDD1150-231
114GVDD1200-231
115VCC1250-231
116Dummy1300-231
117Dummy1350-231
118GVCL1400-231
119Dummy1450-231
120AVDD1500-231
121AVDD1550-231
122AVDD1600-231
123AVDD1650-231
124AVDD1700-231
125Dummy1750-231
126Dummy1800-231
127Dummy1850-231
128DummyR1900-231
129DummyR1950-231
130Dummy2000-231
131Dummy2050-231
132Dummy2100-231
133Dummy2150-231
134Dummy2200-231
135Dummy2250-231
136Dummy2300-231
137Dummy2350-231
138Dummy2400-231
139Dummy2450-231
140Dummy2500-231
141Dummy2550-231
142Dummy2600-231
143Dummy2650-231
144Dummy2700-231
145Dummy2750-231
146AGND2800-231
147AGND2850-231
148AGND2900-231
149AVCL2950-231
150AVCL3000-231
151AVCL3050-231
152Dummy3100-231
153Dummy3150-231
154Dummy3200-231
155Dummy3250-231
156Dummy3300-231
157Dummy3350-231
158Dummy3400-231
159Dummy3450-231
160Dummy3500-231
161Dummy3550-231
162Dummy3600-231
163Dummy3650-231
164Dummy3700-231
165Dummy3750-231
166Dummy3800-231
167Dummy3850-231
168Dummy3900-231
169Dummy3950-231
170VGL4000-231
171VGL4050-231
172VGL4100-231
173VGH4150-231
174Dummy4200-231
175Dummy4250-231
176Dummy4300-231
177Dummy4350-231
178Dummy4400-231
179VCL4450-231
180VCL4500-231
181VCL4550-231
182VCOM4600-231
183VCOM4650-231
184VCOM4700-231
185Dummy4750-231
186Dummy4772110
187Dummy4756227
188G1624740110
189G1604724227
190G1584708110
191G1564692227
192G1544676110
193G1524660227
194G1504644110
195G1484628227
196G1464612110
197G1444596227
198G1424580110
199G1404564227
200G1384548110
+ +
No.PAD NameXY
201G1364532227
202G1344516110
203G1324500227
204G1304484110
205G1284468227
206G1264452110
207G1244436227
208G1224420110
209G1204404227
210G1184388110
211G1164372227
212G1144356110
213G1124340227
214G1104324110
215G1084308227
216G1064292110
217G1044276227
218G1024260110
219G1004244227
220G984228110
221G964212227
222G944196110
223G924180227
224G904164110
225G884148227
226G864132110
227G844116227
228G824100110
229G804084227
230G784068110
231G764052227
232G744036110
233G724020227
234G704004110
235G683988227
236G663972110
237G643956227
238G623940110
239G603924227
240G583908110
241G563892227
242G543876110
243G523860227
244G503844110
245G483828227
246G463812110
247G443796227
248G423780110
249G403764227
250G383748110
+ +
No.PAD NameXY
251G363732227
252G343716110
253G323700227
254G303684110
255G283668227
256G263652110
257G243636227
258G223620110
259G203604227
260G183588110
261G163572227
262G143556110
263G123540227
264G103524110
265G83508227
266G63492110
267G43476227
268G23460110
269Dummy3444227
270Dummy3428110
271Dummy3412227
272Dummy3396110
273S3963380227
274S3953364110
275S3943348227
276S3933332110
277S3923316227
278S3913300110
279S3903284227
280S3893268110
281S3883252227
282S3873236110
283S3863220227
284S3853204110
285S3843188227
286S3833172110
287S3823156227
288S3813140110
289S3803124227
290S3793108110
291S3783092227
292S3773076110
293S3763060227
294S3753044110
295S3743028227
296S3733012110
297S3722996227
298S3712980110
299S3702964227
300S3692948110
301S3682932227
302S3672916110
303S3662900227
304S3652884110
305S3642868227
306S3632852110
307S3622836227
308S3612820110
309S3602804227
310S3592788110
311S3582772227
312S3572756110
313S3562740227
314S3552724110
315S3542708227
316S3532692110
317S3522676227
318S3512660110
319S3502644227
320S3492628110
321S3482612227
322S3472596110
323S3462580227
324S3452564110
325S3442548227
326S3432532110
327S3422516227
328S3412500110
329S3402484227
330S3392468110
331S3382452227
332S3372436110
333S3362420227
334S3352404110
335S3342388227
336S3332372110
337S3322356227
338S3312340110
339S3302324227
340S3292308110
341S3282292227
342S3272276110
343S3262260227
344S3252244110
345S3242228227
346S3232212110
347S3222196227
348S3212180110
349S3202164227
350S3192148110
+ +
No.PAD NameXY
351S3182132227
352S3172116110
353S3162100227
354S3152084110
355S3142068227
356S3132052110
357S3122036227
358S3112020110
359S3102004227
360S3091988110
361S3081972227
362S3071956110
363S3061940227
364S3051924110
365S3041908227
366S3031892110
367S3021876227
368S3011860110
369S3001844227
370S2991828110
371S2981812227
372S2971796110
373S2961780227
374S2951764110
375S2941748227
376S2931732110
377S2921716227
378S2911700110
379S2901684227
380S2891668110
381S2881652227
382S2871636110
383S2861620227
384S2851604110
385S2841588227
386S2831572110
387S2821556227
388S2811540110
389S2801524227
390S2791508110
391S2781492227
392S2771476110
393S2761460227
394S2751444110
395S2741428227
396S2731412110
397S2721396227
398S2711380110
399S2701364227
400S2691348110
+ +
No.PAD NameXY
401S2681332227
402S2671316110
403S2661300227
404S2651284110
405S2641268227
406S2631252110
407S2621236227
408S2611220110
409S2601204227
410S2591188110
411S2581172227
412S2571156110
413S2561140227
414S2551124110
415S2541108227
416S2531092110
417S2521076227
418S2511060110
419S2501044227
420S2491028110
421S2481012227
422S247996110
423S246980227
424S245964110
425S244948227
426S243932110
427S242916227
428S241900110
429S240884227
430S239868110
431S238852227
432S237836110
433S236820227
434S235804110
435S234788227
436S233772110
437S232756227
438S231740110
439S230724227
440S229708110
441S228692227
442S227676110
443S226660227
444S225644110
445S224628227
446S223612110
447S222596227
448S221580110
449S220564227
450S219548110
451S218532227
452S217516110
453S216500227
454S215484110
455S214468227
456S213452110
457S212436227
458S211420110
459S210404227
460S209388110
461S208372227
462S207356110
463S206340227
464S205324110
465S204308227
466S203292110
467S202276227
468S201260110
469S200244227
470S199228110
471S198-228110
472S197-244227
473S196-260110
474S195-276227
475S194-292110
476S193-308227
477S192-324110
478S191-340227
479S190-356110
480S189-372227
481S188-388110
482S187-404227
483S186-420110
484S185-436227
485S184-452110
486S183-468227
487S182-484110
488S181-500227
489S180-516110
490S179-532227
491S178-548110
492S177-564227
493S176-580110
494S175-596227
495S174-612110
496S173-628227
497S172-644110
498S171-660227
499S170-676110
500S169-692227
+ +
No.PAD NameXY
501S168-708110
502S167-724227
503S166-740110
504S165-756227
505S164-772110
506S163-788227
507S162-804110
508S161-820227
509S160-836110
510S159-852227
511S158-868110
512S157-884227
513S156-900110
514S155-916227
515S154-932110
516S153-948227
517S152-964110
518S151-980227
519S150-996110
520S149-1012227
521S148-1028110
522S147-1044227
523S146-1060110
524S145-1076227
525S144-1092110
526S143-1108227
527S142-1124110
528S141-1140227
529S140-1156110
530S139-1172227
531S138-1188110
532S137-1204227
533S136-1220110
534S135-1236227
535S134-1252110
536S133-1268227
537S132-1284110
538S131-1300227
539S130-1316110
540S129-1332227
541S128-1348110
542S127-1364227
543S126-1380110
544S125-1396227
545S124-1412110
546S123-1428227
547S122-1444110
548S121-1460227
549S120-1476110
550S119-1492227
+ +
No.PAD NameXY
551S118-1508110
552S117-1524227
553S116-1540110
554S115-1556227
555S114-1572110
556S113-1588227
557S112-1604110
558S111-1620227
559S110-1636110
560S109-1652227
561S108-1668110
562S107-1684227
563S106-1700110
564S105-1716227
565S104-1732110
566S103-1748227
567S102-1764110
568S101-1780227
569S100-1796110
570S99-1812227
571S98-1828110
572S97-1844227
573S96-1860110
574S95-1876227
575S94-1892110
576S93-1908227
577S92-1924110
578S91-1940227
579S90-1956110
580S89-1972227
581S88-1988110
582S87-2004227
583S86-2020110
584S85-2036227
585S84-2052110
586S83-2068227
587S82-2084110
588S81-2100227
589S80-2116110
590S79-2132227
591S78-2148110
592S77-2164227
593S76-2180110
594S75-2196227
595S74-2212110
596S73-2228227
597S72-2244110
598S71-2260227
599S70-2276110
600S69-2292227
601S68-2308110
602S67-2324227
603S66-2340110
604S65-2356227
605S64-2372110
606S63-2388227
607S62-2404110
608S61-2420227
609S60-2436110
610S59-2452227
611S58-2468110
612S57-2484227
613S56-2500110
614S55-2516227
615S54-2532110
616S53-2548227
617S52-2564110
618S51-2580227
619S50-2596110
620S49-2612227
621S48-2628110
622S47-2644227
623S46-2660110
624S45-2676227
625S44-2692110
626S43-2708227
627S42-2724110
628S41-2740227
629S40-2756110
630S39-2772227
631S38-2788110
632S37-2804227
633S36-2820110
634S35-2836227
635S34-2852110
636S33-2868227
637S32-2884110
638S31-2900227
639S30-2916110
640S29-2932227
641S28-2948110
642S27-2964227
643S26-2980110
644S25-2996227
645S24-3012110
646S23-3028227
647S22-3044110
648S21-3060227
649S20-3076110
650S19-3092227
+ +
No.PAD NameXY
651S18-3108110
652S17-3124227
653S16-3140110
654S15-3156227
655S14-3172110
656S13-3188227
657S12-3204110
658S11-3220227
659S10-3236110
660S9-3252227
661S8-3268110
662S7-3284227
663S6-3300110
664S5-3316227
665S4-3332110
666S3-3348227
667S2-3364110
668S1-3380227
669Dummy-3396110
670Dummy-3412227
671Dummy-3428110
672Dummy-3444227
673G1-3460110
674G3-3476227
675G5-3492110
676G7-3508227
677G9-3524110
678G11-3540227
679G13-3556110
680G15-3572227
681G17-3588110
682G19-3604227
683G21-3620110
684G23-3636227
685G25-3652110
686G27-3668227
687G29-3684110
688G31-3700227
689G33-3716110
690G35-3732227
691G37-3748110
692G39-3764227
693G41-3780110
694G43-3796227
695G45-3812110
696G47-3828227
697G49-3844110
698G51-3860227
699G53-3876110
700G55-3892227
+ +
No.PAD NameXY
701G57-3908110
702G59-3924227
703G61-3940110
704G63-3956227
705G65-3972110
706G67-3988227
707G69-4004110
708G71-4020227
709G73-4036110
710G75-4052227
711G77-4068110
712G79-4084227
713G81-4100110
714G83-4116227
715G85-4132110
716G87-4148227
717G89-4164110
718G91-4180227
719G93-4196110
720G95-4212227
721G97-4228110
722G99-4244227
723G101-4260110
724G103-4276227
725G105-4292110
726G107-4308227
727G109-4324110
728G111-4340227
729G113-4356110
730G115-4372227
731G117-4388110
732G119-4404227
733G121-4420110
734G123-4436227
735G125-4452110
736G127-4468227
737G129-4484110
738G131-4500227
739G133-4516110
740G135-4532227
741G137-4548110
742G139-4564227
743G141-4580110
744G143-4596227
745G145-4612110
746G147-4628227
747G149-4644110
748G151-4660227
749G153-4676110
750G155-4692227
751G157-4708110
752G159-4724227
753G161-4740110
754Dummy-4756227
755Dummy-4772110
ALIGNMENT_R4841-220
ALIGNMENT_L-4841-220
+ +5 BLOCK DIAGRAM +![](images/38214670b3bb94eeef0fbf0d2b4747a95b6a4af98ab547fff00696afd7fd1eb8.jpg) + +
+flowchart + +```mermaid +graph TD + subgraph MCU_IF ["MCU IF"] + direction TB + MCU_IF --> ColorConversion["Color conversion LUT table"] + ColorConversion --> DisplayRam["Display Ram 132x 162x18 bits"] + DisplayRam --> DataLatch["Data Latch"] + DataLatch --> ADC["DAC"] + ADC --> LevelShifter["Level Shifter"] + ADC --> VoltageReference["Voltage Reference"] + VoltageReference --> GammaCircuit["Gamma Circuit"] + GammaCircuit --> DisplayControl["Display control"] + DisplayControl --> OSC["OSC"] + OSC --> VCOM["VCOM generator"] + OSC --> GateDecoder["Gate Decoder"] + GateDecoder --> LevelShifter["Level Shifter"] + GateDecoder --> VCOM + end + + subgraph InstructionReg["Instruction Register"] + direction TB + InstructionReg --> NVM["NVM"] + end + + subgraph VCOM["VCOM"] + direction TB + VCOM --> VCOM + OSC --> VCOM + end + + subgraph VCOM_Cycle["VCOM"] + direction TB + VCOM --> VCOM + OSC --> VCOM + end +``` +
+ +## 6 PIN DESCRIPTION + +6.1 Power Supply Pin + +
NameI/ODescriptionConnect Pin
VDDIPower Supply for Analog, Digital System and Booster Circuit.VDD
VDDIIPower Supply for I/O system.VDDI
AGNDISystem Ground for Analog System and Booster Circuit.GND
DGNDISystem Ground for I/O System and Digital System.GND
+ +6.2 Interface Logic Pin + +
NameI/ODescriptionConnect pin
P68I-8080/6800 MCU Interface Mode Select.-P68='1', Select 6800 MCU Parallel Interface.-P68='0', Select 8080 MCU Parallel Interface.-If not used, Please Fix this Pin at DGND Level.DGND/VDDI
IM2IMCU Parallel Interface Bus and Serial Interface selectIM2='1', Parallel InterfaceIM2='0', Serial InterfaceDGND/VDDI
IM1,IM0I- MCU Parallel Interface Type Selection-If Not Used, Please Fix this Pin at VDDI or DGND Level.DGND/VDDI
IM1IM0Parallel Interface
00MCU 8-bit Parallel
01MCU 16-bit Parallel
10MCU 9-bit Parallel
11MCU 18-bit Parallel
SPI4WI- SPI4W='0', 3-line SPI Enable.- SPI4W='1', 4-line SPI Enable.-If Not Used, Please fix this Pin at DGND Level.DGND/VDDI
RESXI-This signal will reset the device and it must be applied to properly initialize the chip.-Signal is active low.MCU
CSXI-Chip Selection Pin-Low Enable.MCU
+ +
IM1IM0Parallel Interface
00MCU 8-bit Parallel
01MCU 16-bit Parallel
10MCU 9-bit Parallel
11MCU 18-bit Parallel
- SPI4W='0', 3-line SPI Enable.- SPI4W='1', 4-line SPI Enable.-If Not Used, Please fix this Pin at DGND Level.-This signal will reset the device and it must be applied to properly initialize the chip.-Signal is active low.-Chip Selection Pin-Low Enable.
+ +
D/CX(SCL)I-Display data/command Selection Pin in MCU Interface.-D/CX='1': Display Data or Parameter.-D/CX='0': Command Data.-In Serial Interface, this is used as SCL.-If not used, please fix this pin at VDDI or DGND level.MCU
RDXI-Read Enable in 8080 MCU Parallel Interface.-If not used, please fix this pin at VDDI or DGND level.MCU
WRX(D/CX)I-Write Enable in MCU Parallel Interface.-In 4-line SPI, this pin is used as D/CX (data/ command selection).-If not used, please fix this pin at VDDI or DGND level.MCU
D[17:0]I/O-D[17:0] are used as MCU parallel interface data bus.-D0 is the serial input/output signal in serial interface mode.-In serial interface, D[17:1] are not used and should be fixed at VDDI or DGND level.MCU
TEO-Tearing effect output pin to synchronies MCU to frame rate, activated by S/W command.-If not used, please open this pin.MCU
OSCO-Monitoring pin of internal oscillator clock and is turned ON/OFF by S/W command.-When this pin is inactive (function OFF), this pin is DGND level.-If not used, please open this pin.-
+ +Note1. When in parallel mode, no use data pin must be connected to "1" or "0". +Note2. When CSX="1", there is no influence to the parallel and serial interface. + +6.3 Mode Selection Pin + +
NameI/ODescriptionConnect Pin
EXTCI-During normal operation, please connect to VDDI..VDDI/DGND
EXTCEnable/disable Modification of Extend Command
0Panel Function Commands Disable.
1Panel Function Commands Enable.
GM1, GM0I-Panel Resolution Selection Pins.VDDI/DGND
GM1GM0Selection of panel resolution
00132RGB x 162 (S1~S396 & G1~G162 output)
01132RGB x 132 (S1~S396 & G1~G132 Output)
11128RGB x 160 (S7~S390 & G2~G161 output)
SRGBI-RGB Direction Select H/W Pin for Color Filter Setting.VDDI/DGND
SRGBRGB Arrangement
0S1, S2, S3 Filter Order = 'R', 'G', 'B'
1S1, S2, S3 Filter Order = 'B', 'G', 'R'
SMXI-Module Source Output Direction H/W Selection Pin.VDDI/DGND
SMXScanning direction of source output
GM= '00'GM= '01'GM= '11'
0S1 -> S396S1 -> S396S7 -> S390
1S396 -> S1S396 -> S1S390 -> S7
SMYI-Module Gate Output Direction H/W Selection Pin.VDDI/DGND
SMYScanning direction of gate output
GM= '00'GM= '01'GM= '11'
0G1 -> G162G1 -> G132G2 -> G161
1G162 -> G1G132 -> G1G161 -> G2
LCMI-Liquid Crystal (LC) Type Selection Pins.VDDI/DGND
LCMSelection of LC Type
0Normally White LC Type
1Normally Black LC Type
GSI-Gamma Curve Selection Pin.VDDI/DGND
GSSelection of Gamma Curve
0GC0=1.0, GC1=2.5, GC2=2.2, GC3=1.8
1GC0=2.2, GC1=1.8, GC2=2.5, GC3=1.0
+ +
EXTCEnable/disable Modification of Extend Command
0Panel Function Commands Disable.
1Panel Function Commands Enable.
+ +
GM1GM0Selection of panel resolution
00132RGB x 162 (S1~S396 & G1~G162 output)
01132RGB x 132 (S1~S396 & G1~G132 Output)
11128RGB x 160 (S7~S390 & G2~G161 output)
+ +
SRGBRGB Arrangement
0S1, S2, S3 Filter Order = 'R', 'G', 'B'
1S1, S2, S3 Filter Order = 'B', 'G', 'R'
+ +
SMXScanning direction of source output
GM= '00'GM= '01'GM= '11'
0S1 -> S396S1 -> S396S7 -> S390
1S396 -> S1S396 -> S1S390 -> S7
+ +
SMYScanning direction of gate output
GM=‘00’GM=‘01’GM=‘11’
0G1 -> G162G1 -> G132G2 -> G161
1G162 -> G1G132 -> G1G161 -> G2
+ +
LCMSelection of LC Type
0Normally White LC Type
1Normally Black LC Type
+ +
GSSelection of Gamma Curve
0GC0=1.0, GC1=2.5, GC2=2.2, GC3=1.8
1GC0=2.2, GC1=1.8, GC2=2.5, GC3=1.0
+ +
VPPIWhen writing NVM, it needs external power supply voltage (7.5V).
TESELIInput pin to select horizontal line number in TE signal.This pin is internally pull low.DGND
TESELSelection of gamma curve
0TE output 162 lines
1TE output 160 lines
+ +6.4 Driver Output pins + +
NameI/ODescriptionConnect Pin
S1 to S396O- Source Driver Output Pins.-
G1 to G162O- Gate Driver Output Pins.-
AVDDO- Power Pin for Analog Circuits.-
AVCLO- A power Supply Pin for Generating GVCL.-
VGHO- Power Output Pin for Gate Driver-
VGLO- Power Output (Negative) Pin for Gate Driver-
GVDDO- A power Output of Grayscale Voltage Generator.- When internal GVDD generator is not used, connect an external power supply (AVDD-0.5V) to this pin.-
GVCLO- A power Output (Negative) of Grayscale Voltage Generator.- When internal GVCL generator is not used, connect an external power supply (AVCL+0.5V) to this pin.-
VCOMO- A Power Supply for the TFT-LCD Common Electrode.Common Electrode
VCCO- Monitoring Pin of Internal Digital Reference Voltage.- Please Open These Pins.
VCLO- A power output of VCOM voltage (Negative) generator.
VDDIOO- VDDI Voltage Output Level for Monitoring.-
DGNDOO- DGND Voltage Output Level for Monitoring.-
+ +6.5 Test Pins + +
NameI/ODescriptionConnect Pin
TEST2PI-These test pins for driver vender test used.DGND
TEST1P-Please connect these pins to DGND.
TESTOP[8]O-These test pins for driver vender test used.Open
TESTOP[7]-Please open these pins.
TESTOP[6]
TESTOP[5]
TESTOP[4]
TESTOP[3]
TESTOP[2]
TESTOP[1]
DummyR--These pins are dummy (have no function inside).-Pad128 DummyR internal short to pad 129 DummyR.Open
Dummy--These pins are dummy (have no function inside).-Can allow signal traces pass through these pads on TFT glass.-Please open these pins.Open
+ +## 7 DRIVER ELECTRICAL CHARACTERISTICS + +## 7.1 Absolute Operation Range + +
ItemSymbolRatingUnit
Supply VoltageVDD-0.3 ~ +4.8V
Supply Voltage (Logic)VDDI-0.3 ~ +4.6V
Supply Voltage (Digital)VCC-0.3 ~ +1.95V
Driver Supply VoltageVGH-VGL-0.3 ~ +30.0V
Logic Input Voltage RangeVIN-0.3 ~ VDDI + 0.3V
Logic Input Voltage RangeVO-0.3 ~ VDDI + 0.3V
Operating Temperature RangeTOPR-30 ~ +85°C
Storage Temperature RangeTSTG-40 ~ +125°C
+ +Table 1 Absolute Operation Range +Note: If one of the above items is exceeded its maximum limitation momentarily, the quality of the product may be degraded. Absolute maximum limitation, therefore, specify the values exceeding which the product may be physically damaged. Be sure to use the product within the recommend range. + +7.2 DC Characteristic + +
ParameterSymbolConditionSpecificationUnitRelated Pins
MinTypMax
Power & Operation Voltage
System VoltageVDDOperating Voltage2.52.754.8V
Interface Operation VoltageVDDII/O Supply Voltage1.651.83.7V
Gate Driver High VoltageVGH1116VNote 4
Gate Driver Low VoltageVGL-13-7.5V
Gate Driver Supply Voltage| VGH-VGL |18.529VNote 4
Input / Output
Logic-High Input VoltageVIH0.7VDDIVDDIVNote 1
Logic-Low Input VoltageVILVSS0.3VDDIVNote 1
Logic-High Output VoltageVOHIOH = -1.0mA0.8VDDIVDDIVNote 1
Logic-Low Output VoltageVOLIOL = +1.0mAVSS0.2VDDIVNote 1
Logic-High Input CurrentIIHVIN = VDDI1uANote 1
Logic-Low Input CurrentIILVIN = VSS-1uANote 1
Input Leakage CurrentIILIOH = -1.0mA-0.1+0.1uANote 1
VCOM Voltage
VCOM AmplitudeVCOM-2-0.425V
Source driver
Source Output RangeVsout0.1GVDDV
Gamma Reference VoltageGVDD3.154.7V
Source Output Settling TimeTrBelow with 99% precision20usNote 2
Output Offset VoltageVoffset35mVNote 3
+ +Table 2 DC Characteristic +Notes: +1. TA = -30 to 85 °C. +2. Source channel loading= 2KΩ+12pF/channel, Gate channel loading=5KΩ+40pF/channel. +3. The Max. value is between measured point of source output and gamma setting value. +4. VGH setting condition is AVDD=4.7V, the Max and Min VGH voltage depend on AVDD setting, VGH-VGL can not large than 30V. + +## 7.3 Power Consumption + +Ta=25°C, Frame rate = 60Hz, Bare die, the registers setting are IC default setting. + +
Operation ModeImageCurrent Consumption
TypicalMaximum
IDDI (mA)IDD (mA)IDDI (mA)IDD (mA)
Normal ModeNote 10.010.90.022
Note 20.010.90.022
Partial + Idle Mode (40 lines)Note 10.010.80.022
Note 20.010.80.022
Sleep-In ModeN/A0.0050.0150.010.03
+ +Table 3 Power Consumption + +## Notes: + +1. All pixels black. +2. All pixels white. +3. The Current Consumption is DC characteristics of ST7735S. +4. Typical: VDDI=1.8V, VDD=2.75V; Maximum: VDDI=1.65 to 3.7V, VDD=2.5 to 4.8V + +## 8 Timing chart + +8.1 Parallel Interface Characteristics: 18, 16, 9 or 8-bit Bus (8080 Series MCU Interface) +![](images/664c464e6c4ef9ecb64cf6171b08457bdcbb746172a1af79c7262986824d2c2c.jpg) + +
+flowchart + +This diagram illustrates the timing and signal flow relationships between various signal processing stages (CSX, D/CX, WRX, D[17:0] write, RDX, D[17:0] read) through various control signals such as TCHW, TCSH, and TCSF. +
+ +Figure 1 Parallel Interface Timing Characteristics (8080 Ceries MCU Interface) + +Ta=25 °C, VDDI=1.65\~3.7V, VDD=2.5\~4.8V + +
SignalSymbolParameterMinMaxUnitDescription
D/CXTASTAddress Setup Ttime0ns-
TAHTAddress Hold Time (Write/Read)10ns
CSXTCHWChip Select “H” Pulse Width0ns-
TCSChip Select Setup Time (Write)15ns
TRCSChip Select Setup Time (Read ID)45ns
TRCSFMChip Select Setup time (Read FM)355ns
TCSFChip Select Wait Time (Write/Read)10ns
TCSHChip Select Hold Time10ns
WRXTWCWrite Cycle66ns
TWRHControl Pulse “H” Duration15ns
TWRLControl Pulse “L” Duration15ns
RDX (ID)TRCRead Cycle (ID)160nsWhen Read ID Data
TRDHControl Pulse “H” Duration (ID)90ns
TRDLControl Pulse “L” Duration (ID)45ns
RDX (FM)TRCFMRead Cycle (FM)450nsWhen Read from Frame Memory
TRDHFMControl Pulse “H” Duration (FM)90ns
TRDLFMControl Pulse “L” Duration (FM)355ns
D[17:0]TDSTData Setup Time10nsFor CL=30pF
TDHTData Hold Time10ns
TRATRead Access Time (ID)40ns
TRATFMRead Access Time (FM)340ns
TODHOutput Disable Time2080ns
+ +Table 4 8080 Parallel Interface Characteristics + +![](images/8a6c696243eea6ceb27c8d9b444e233fee5fe319663ad129a12896822ed70892.jpg) +Figure 2 Rising And Falling Timing for Input And Output Signal + +![](images/150c6a07eaea24db93ad0c93e82e847cb0bd5694b99834fc1a12258596fa8995.jpg) + +
+text_image + +CSX +V_IH +V_IL +T_CSF +V_IL +V_IH +V_IL +Min. =5ns +T_CHW +
+ +Figure 3 Chip Selection (CSX) Timing + +![](images/781506a18cf4455aaed7810690e5dda2fc1fc4e9b39017a5df1501b507e8b98f.jpg) + +
+text_image + +WRX +VIH +VIL +VIL +RDX +VIH +VIL +TWRH +VIL +TWRH/TRDHFM +
+ +Figure 4 Write-to-Read And Read-to-Write Timing +Note: The rising time and falling time (Tr, Tf) of input signal are specified at 15 ns or less. Logic high and low levels are specified as 30% and 70% of VDDI for Input signals. + +8.2 Parallel Interface Characteristics: 18, 16, 9 or 8-bit Bus (6800 Series MCU Interface) +![](images/fbe6a83a74fd5268fcdad82bce9e6681a15817f29e59a61ffa8c6a67904a7ca3.jpg) + +
+flowchart + +This diagram illustrates the timing and signal flow relationships between various signal waveforms (CSX, D/CX, /WX, E, D[17:0] write, RX, E, D[17:0] read) over time intervals such as TCHW, TCS, TCSF, and TAST. +
+ +Figure 5 Parallel Interface Timing Characteristics (6800-Series MCU Interface) + +Ta=25 °C, VDDI=1.65\~3.7V, VDD=2.5\~4.8V + +
SignalSymbolParameterMinMaxUnitDescription
D/CX $T_{AST}$ Address Setup Time0ns-
$T_{AHT}$ Address Hold Time (Write/Read)10ns
CSX $T_{CHW}$ Chip Select “H” Pulse Width0ns-
$T_{CS}$ Chip Select Setup Time (Write)15ns
$T_{RCS}$ Chip Select Setup Time (Read ID)45ns
$T_{RCSFM}$ Chip Select Setup Time (Read FM)355ns
$T_{CSF}$ Chip Select wait Time (Write/Read)10ns
$T_{CSH}$ Chip Select Hold Time10ns
WRX $T_{WC}$ Write Cycle66ns
$T_{WRH}$ Control Pulse “H” Duration15ns
$T_{WRL}$ Control Pulse “L” Duration15ns
RDX (ID) $T_{RC}$ Read Cycle (ID)160nsWhen Read ID Data
$T_{RDH}$ Control Pulse “H” Duration (ID)90ns
$T_{RDL}$ Control Pulse “L” Duration (ID)45ns
RDX (FM) $T_{RCFM}$ Read Cycle (FM)450nsWhen Read From Frame Memory
$T_{RDHFM}$ Control Pulse “H” Duration (FM)90ns
$T_{RDLFM}$ Control Pulse “L” Duration (FM)355ns
D[17:0] $T_{DST}$ Data Setup Time10nsFor Maximum CL=30pFFor Minimum CL=8pF
$T_{DHT}$ Data Hold Time10ns
$T_{ODH}$ Output Disable Time2080ns
+ +Note: The rising time and falling time (Tr, Tf) of input signal are specified at 15 ns or less. Logic high and low levels are specified as 30% and 70% of VDDI for Input signals + +Table 5 6800 Parallel Interface Characteristics + +## 8.3 Serial Interface Characteristics (3-line Serial) + +![](images/7e4ecc2cdc38e56edb5eb35b649a1ec2a57f1d9a06d8c4cda510c0dd2245ef2c.jpg) + +
+text_image + +CSX +VIH +VIL +TCSS +TSCYCW/TSCYCR +TCSH +TSCC +SCL +TSHW/TSHR +TSLW/TSLR +VIH +VIL +TSDS +TSDH +SDA +VIH +VIL +TACC +TOH +VIH +VIL +SDA +(DOUT) +
+ +Figure 6 3-line Serial Interface Timing + +Ta=25 °C, VDDI=1.65\~3.7V, VDD=2.5\~4.8V + +
SignalSymbolParameterMinMaxUnitDescription
CSXTCSSChip Select Setup Time (Write)15ns
TCSHChip Select Hold Time (Write)15ns
TCSSChip Select Setup Time (Read)60ns
TSCCChip Select Hold Time (Read)65ns
TCHWChip Select “H” pulse width40ns
SCLTSCYCWSerial Clock Cycle (Write)66ns
TSHWSCL “H” Pulse Width (Write)15ns
TSLWSCL “L” Pulse Width (Write)15ns
TSCYCRSerial Clock Cycle (Read)150ns
TSHRSCL “H” Pulse Width (Read)60ns
TSLRSCL “L” Pulse Width (Read)60ns
SDA (DIN) (DOUT)TSDSData Setup Time10nsFor Maximum CL=30pF For Minimum CL=8pF
TSDHData Hold Time10ns
TACCAccess Time1050ns
TOHOutput Disable Time1550ns
+ +Table 6 3-line Serial Interface Characteristics +Note : The rising time and falling time (Tr, Tf) of input signal are specified at 15 ns or less. Logic high and low levels are specified as 30% and 70% of VDDI for Input signals. + +## 8.4 Serial Interface Characteristics (4-line Serial) + +![](images/5c5404aed8d675eb3dbb7a4df2bbd664bf2f2478bc8671b461cbaa3e04dbb9d7.jpg) + +
+flowchart + +```mermaid +graph LR + CSX["CSX"] -->|VIH| VIL["VIL"] + CSX -->|VIL| CSX + CSX -->|TCSCW/TSCYCR| TCSH["TCSH"] + CSX -->|TCHW| TCHW + SCL["SCL"] -->|VIH| TDCS["TDCS"] + SCL -->|VIL| TDCS + SCL -->|TDSW/TSHR| TSHW["TSHW/TSHR"] + SCL -->|TSLW/TSLR| TSLW + SCL -->|VIH| TSCC["TSCC"] + SCL -->|VIL| TSCC + SDA["SDA"] -->|VIH| VIL["VIL"] + SDA -->|VIL| VIL + SDA -->|TSDS| TSDH["TSDH"] + SDA -->|TSDH| TSDH + D/CX["D/CX"] -->|VIH| VIL["VIL"] + DCx["D/CX"] -->|VIL| VIL + DCx -->|TDCH| TDCH + DCx -->|TACC| TACC + DCx -->|TOH| TOH + SDA(DOUT) -->|VIH| VIL["VIL"] + SDA(DOUT) -->|VIL| VIL +``` +
+ +Figure 7 4-line Serial Interface Timing +Ta=25 °C, VDDI=1.65\~3.7V, VDD=2.5\~4.8V + +
SignalSymbolParameterMINMAXUnitDescription
CSXTCSSChip Select Setup Time (Write)45ns
TCSHChip Select Hold Time (Write)45ns
TCSSChip Select Setup Time (Read)60ns
TSCCChip Select Hold Time (Read)65ns
TCHWChip Select “H” Pulse Width40ns
SCLTSCYCWSerial Clock Cycle (Write)66ns-Write Command & Data Ram
TSHWSCL “H” Pulse Width (Write)15ns
TSLWSCL “L” Pulse Width (Write)15ns
TSCYCRSerial Clock Cycle (Read)150ns-Read Command & Data Ram
TSHRSCL “H” Pulse Width (Read)60ns
TSLRSCL “L” Pulse Width (Read)60ns
D/CXTDCSD/CX Setup Time10ns
TDCHD/CX Hold Time10ns
SDA (DIN) (DOUT)TSDSData Setup Time10nsFor Maximum CL=30pF For Minimum CL=8pF
TSDHData Hold Time10ns
TACCAccess Time1050ns
TOHOutput Disable Time1550ns
+ +Table 7 4-line Serial Interface Characteristics +Note : The rising time and falling time (Tr, Tf) of input signal are specified at 15 ns or less. Logic high and low levels are specified as 30% and 70% of VDDI for Input signals. + +## 9 Function Description + +## 9.1 Interface Type Selection + +The selection of given interfaces are done by setting IM2, IM1, and IM0 pins as shown in following table. + +
P68IM2IM1IMOInterfaceRead Back Selection
-0--3-line Serial InterfaceVia the Read Instruction
01008080 MCU 8-bit ParallelRDX Strobe (8-bit Read Data and 8-bit Read Parameter)
01018080 MCU 16-bit ParallelRDX Strobe (16-bit Read Data and 8-bit Read Parameter)
01108080 MCU 9-bit ParallelRDX Strobe (9-bit Read Data and 8-bit Read Parameter)
01118080 MCU 18-bit ParallelRDX Strobe (18-bit Read Data and 8-bit Read Parameter)
-0--3-line Serial InterfaceVia the Read Instruction
11006800 MCU 8-bit ParallelE Strobe (8-bit Read Data and 8-bit Read Parameter)
11016800 MCU 16-bit ParallelE Strobe (16-bit Read Data and 8-bit Read Parameter)
11106800 MCU 9-bit ParallelE Strobe (9-bit Read Data and 8-bit Read Parameter)
11116800 MCU 18-bit ParallelE Strobe (18-bit Read Data and 8-bit Read Parameter)
+ +Table 8 Interface Type Selection + +
P68IM2IM1IM0InterfaceRDXWRXD/CXRead back selection
-0--3-line Serial InterfaceNote1Note1SCLD[17:1]: Unused, D0: SDA
01008080 8-bit ParallelRDXWRXD/CXD[17:8]: Unused, D7-D0: 8-bit Data
01018080 16-bit ParallelRDXWRXD/CXD[17:16]: Unused, D15-D0: 16-bit Data
01108080 9-bit ParallelRDXWRXD/CXD[17:9]: Unused, D8-D0: 9-bit Data
01118080 18-bit ParallelRDXWRXD/CXD17-D0: 18-bit Data
-0--3-line Serial InterfaceNote1D/CXSCLD[17:1]: Unused, D0: SDA
11006800 8-bit ParallelEWRXRSD[17:8]: Unused, D7-D0: 8-bit Data
11016800 16-bit ParallelEWRXRSD[17:16]: Unused, D15-D0: 16-bit Data
11106800 9-bit ParallelEWRXRSD[17:9]: Unused, D8-D0: 9-bit Data
11116800 18-bit ParallelEWRXRSD17-D0: 18-bit Data
+ +Table 9 Pin Connection According to Various MCU Interface +Note: Unused pins can be open, or connected to DGND or VDDI. + +## 9.2 8080-series MCU Parallel Interface (P68 = '0') + +The MCU can use one of following interfaces: 11-lines with 8-data parallel interface, 12-lines with 9-data parallel interface, 19-line with 16-data parallel interface or 21-lines with 18-data parallel interface. The chip-select CSX (active low) enables/disables the parallel interface. RESX (active low) is an external reset signal. WRX is the parallel data write enable, RDX is the parallel data read enable and D[17:0] is parallel data bus. + +The LCD driver reads the data at the rising edge of WRX signal. The D/CX is the data/command flag. When D/CX='1', D[17:0] bits is either display data or command parameter. When D/C='0', D[17:0] bits is command. The interface functions of 8080-series parallel interface are given in following table.. + +
IM2IM1IM0InterfaceD/CXRDXWRXRead Back Selection
1008-bit Parallel01Write 8-bit Command (D7 to D0)
11Write 8-bit Display Data or 8-bit Parameter (D7 to D0)
11Read 8-bit Display Data (D7 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
10116-bit Parallel01Write 8-bit Command (D7 to D0)
11Write 16-bit Display Data or 8-bit Parameter (D15 to D0)
11Read 16-bit Display Data (D15 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
1109-bit Parallel01Write 8-bit Command (D7 to D0)
11Write 9-bit Display Data or 8-bit Parameter (D8 to D0)
11Read 9-bit Display Data (D8 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
11118-bit Parallel01Write 8-bit Command (D7 to D0)
11Write 18-bit Display Data or 8-bit Parameter (D17 to D0)
11Read 18-bit Display Data (D17 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
+ +Table 10 The Function of 8080-series Parallel Interface +Note: applied for command code: DAh, DBh, DCh, 04h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh + +## 9.2.1 Write Cycle Sequence + +The write cycle means that the host writes information (command or/and data) to the display via the interface. Each write cycle (WRX high-low-high sequence) consists of 3 control signals (D/CX, RDX, WRX) and data signals (D[17:0]). D/CX bit is a control signal, which tells if the data is a command or a data. The data signals are the command if the control signal is low (='0') and vice versa it is data (='1'). + +![](images/ecfc08124bf26d8b01c2b4fd1974a52e2924a6c3b4fbca223ab145157681c135.jpg) +Figure 8 8080-series WRX Protocol +Note: WRX is an unsynchronized signal (It can be stopped). + +![](images/919ab43914137f54a9f774a6ede91a2dff4559930570cd40fe89a9a00ba2127f.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph sg_1_Byte_Command["1 Byte Command"] + S["S"] --> CMD["CMD"] + CMD --> PA1["PA1"] + PA1 --> CMD + CMD --> PA2["PA2"] + PA2 --> P["P"] + end + + subgraph sg_2_Byte_Command["2 Byte Command"] + CSX["CSX"] --> D/CX["D/CX"] + DCx["D/CX"] --> RDX["RDX"] + RDX --> WRX["WRX"] + WRX --> HostD[""Host D[17:0"] Host to LCD"] + HostD --> HostZ[""Driver D[17:0"] LCD to Host"] + end + + subgraph N Byte Command + PA1 --> PA2["PA1"] + PA2 --> PA2 + PA2 --> PA1["PA1"] + PA1 --> PA2["PA2"] + PA2 --> PA1["PA1"] + PA1 --> P["P"] + end + + S --> CMD + CMD --> PA1 + PA1 --> CMD + CMD --> PA2 + PA2 --> PA1 + PA1 --> P + P --> HostZ + HostZ --> HostZ +``` +
+ +Figure 9 8080-series Parallel Bus Protocol, Write to Register or Display RAM + +## 9.2.2 Read Cycle Sequence + +The read cycle (RDX high-low-high sequence) means that the host reads information from LCD driver via interface. The driver sends data (D[17:0]) to the host when there is a falling edge of RDX and the host reads data when there is a rising edge of RDX. + +![](images/2f754df3ad1bcacf47eab2d4a575941d68e38f859826450600ee18b16d87bbed.jpg) +Figure 10 8080-series RDX Protocol +Note: RDX is an unsynchronized signal (It can be stopped). + +![](images/bbe2e4eca548b1e9337a497e6eb7667c7cca650da278b10c99f3d3fda0698709.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Read Parameter + direction TB + S["S"] --> CMD["CMD"] + CMD --> DM["DM"] + PA["PA"] --> CMD + CMD --> DM & data["DM & data"] + DMData["DM & data"] --> Data["Data"] + Data --> P["P"] + end + + subgraph Read Display Data + direction TB + P --> P["P"] + P --> D["CX"]["D/CX"] + D["CX"] --> RDX["RDX"] + RDX --> WRX["WRX"] + WRX --> D["17:0"]["D["17:0"]"] + D["17:0"] --> HostToLCD[""Host D[17:0"] Host to LCD"] + HostToLCD --> DriverToHost[""Driver D[17:0"] LCD to Host"] + DriverToHost --> PA1["PA1"] + PA1 --> DM["DM"] + PA1 --> Hi-Z["Hi-Z"] + HiZ["Hi-Z"] --> CMD + CMD --> Hi-Z["Hi-Z"] + HiZ --> PA1 + PA1 --> DM["DM"] + DM --> PA1 + PA1 --> PAN_2["PAN_2"] + PA1 --> PA1 + PA1 --> PAN_1["PAN_1"] + PAN_2 --> P["P"] + P --> HostToLCD + HostToLCD --> DriverToHost + end +``` +
+ +Figure 11 8080-series Parallel Bus Protocol, Read Data from Register or Display RAM + +## 9.3 6800-series MCU Parallel Interface (P68 = '1') + +The MCU uses one of following interface: 11-lines with 8-data parallel interface, 12-lines with 9-data parallel interface, 19-lines with 16-data parallel interface, or 21-lines with 18-data parallel interface. The chip-select CSX(active low) enables and disables the parallel interface. RESX (active low) is an external reset signal. The R/WX is the Read/Write flag and D[17:0] is parallel data bus. + +The LCD driver reads the data at the falling edge of E signal when R/WX= '1' and Writes the data at the falling of the E signal when R/WX='0'. The D/CX is the data/command flag. When D/CX='1', D[17:0] bits are display RAM data or command parameters. When D/C= '0', D[17:0] bits are commands. + +The 6800-series bi-directional interface can be used for communication between the micro controller and LCD driver. The selection of this interface is done when P68 pin is high state (VDDI). Interface bus width can be selected with IM2, IM1 and IM0. The interface functions of 6800-series parallel interface are given in Table11. + +
P68IM2IM1IM0InterfaceD/CXR/WXEFunction
11008-bit Parallel00Write 8-bit Command (D7 to D0)
10Write 8-bit Display Data or 8-bit Parameter (D7 to D0)
11Read 8-bit Display Data (D7 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
110116-bit Parallel00Write 8-bit Command (D7 to D0)
10Write 16-bit Display Data or 8-bit Parameter (D15 to D0)
11Read 16-bit Display Data (D15 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
11109-bit Parallel00Write 8-bit Command (D7 to D0)
10Write 9-bit Display Data or 8-bit Parameter (D8 to D0)
11Read 9-bit Display Data (D8 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
111118-bit Parallel00Write 8-bit Command (D7 to D0)
10Write 18-bit Display Data or 8-bit Parameter (D17 to D0)
11Read 18-bit Display Data (D17 to D0)
11Read 8-bit Parameter or Status (D7 to D0)
+ +Table 11 The Function of 6800-series Parallel Interface +Note: applied for command code: DAh, DBh, DCh, 04h, 09h, 0Ah, 0Bh, 0Ch, 0Dh, 0Eh, 0Fh. + +## 9.3.1 Write Cycle Sequence + +The write cycle means that the host writes information (command or/and data) to the display via the interface. Each write cycle (E low-high-low sequence) consists of 3 control signals (D/CX, E, R/WX) and data signals (D[17:0]). D/CX bit is a control signal, which tells if the data is a command or a data. The data signals are the command if the control signal is low (='0') and vice versa it is data (='1'). + +![](images/3cc63442b9fdcb5fd2c84eaab5c9827c56154229e938fbdbeb11103cb10dd2c0.jpg) + +
+flowchart + +```mermaid +graph LR + A["R/WX"] -->|“0”| B["E"] + B --> C[""D[17:0"]"] + C --> D[""The host starts to control D[17:0"] lines when there is a rising edge of the E."] + D --> E[""The display writes D[17:0"] lines when there is a falling edge of E."] + E --> F[""The host stops to control D[17:0"] lines."] +``` +
+ +Figure 12 6800-series Write Protocol +Note: E is an unsynchronized signal (It can be stopped) + +![](images/8feb0d2ab998eda6fb5f03e64eceb60df9d8712fa8a741e2423f306a9581473e.jpg) + +
+flowchart + +This diagram illustrates the data transmission and reception logic for a 1-byte command system, showing the sequence of commands (D, CX, R/WX, Host, Driver) and their corresponding data paths (CMD, PA1, PA2, P) across a 2-byte command. +
+ +Figure 13 6800-series Parallel Bus Protocol, Write to Register or Display RAM + +## 9.3.2 Read Cycle Sequence + +The read cycle (E low-high-low sequence) means that the host reads information from LCD driver via interface. The driver sends data (D[17:0]) to the host when there is a rising edge of E and the host reads data when there is a falling edge of E. + +![](images/21be869a88ec3506be06b7b03b08fdd279e99a08834c39b0b45ffb90f82bc134.jpg) + +
+flowchart + +```mermaid +graph LR + A["RWX"] -->|“1”| B["E"] + B --> C[""D[17:0"]"] + C --> D[""The driver starts to control D[17:0"] lines when there is a rising edge of the E."] + D --> E[""The host read D[17:0"] lines when there is a falling edge of RDX."] + E --> F[""The driver stops to control D[17:0"] lines."] +``` +
+ +Figure 14 6800-series Read Protocol +Note: E is an unsynchronized signal (It can be stopped) + +![](images/e1c33c8719a56debd3fadc676f987a0e250998d8013546ed6fd3efba36b8a437.jpg) + +
+flowchart + +This diagram illustrates the data flow and signal processing logic for a system, showing how read parameters (D[17:0], RESX, CSX, D/CX, R/WX, E) are processed through various channels (CMD, DM, PA, etc.) to generate signals on D[17:0], D/CX, R/WX, and E pins. +
+ +Figure 15 6800-series Parallel Bus Protocol, Read Data form Register or Display RAM + +## 9.4 Serial Interface + +The selection of this interface is done by IM2. See the Table 12. + +
IM24WSPIInterfaceRead Back Selection
003-line Serial InterfaceVia the Read Instruction (8-bit, 24-bit and 32-bit Read Parameter)
014-line Serial InterfaceVia the Read Instruction (8-bit, 24-bit and 32-bit Read Parameter)
+ +Table 12 Selection of Serial Interface + +The serial interface is either 3-lines/9-bits or 4-lines/8-bts bi-directional interface for communication between the micro controller and the LCD driver. The 3-lines serial interface use: CSX (chip enable), SCL (serial clock) and SDA (serial data input/output), and the 4-lines serial interface use: CSX (chip enable), D/CX (data/command flag), SCL (serial clock) and SDA (serial data input/output). Serial clock (SCL) is used for interface with MCU only, so it can be stopped when no communication is necessary. + +## 9.4.1 Command Write Mode + +The write mode of the interface means the micro controller writes commands and data to the LCD driver. +3-lines serial data packet contains a control bit D/CX and a transmission byte. In 4-lines serial interface, data packet contains just transmission byte and control bit D/CX is transferred by the D/CX pin. If D/CX is “low”, the transmission byte is interpreted as a command byte. If D/CX is “high”, the transmission byte is stored in the display data RAM (memory write command), or command register as parameter. + +Any instruction can be sent in any order to the driver. The MSB is transmitted first. The serial interface is initialized when CSX is high. In this state, SCL clock pulse or SDA data have no effect. A falling edge on CSX enables the serial interface and indicates the start of data transmission. + +![](images/922b45de7447e8fa5ff8307048807fb8a87fadace63f6a9a91496c823713f858.jpg) + +
+flowchart + +```mermaid +graph TD + subgraph sg_3_line["3-line"] + A["D/CX"] --> B["D7"] + A --> C["D6"] + A --> D["D5"] + A --> E["D4"] + A --> F["D3"] + A --> G["D2"] + A --> H["D1"] + A --> I["D0"] + end + + subgraph sg_4_line["4-line"] + J["D7"] --> K["D6"] + J --> L["D5"] + J --> M["D4"] + J --> N["D3"] + J --> O["D2"] + J --> P["D1"] + J --> Q["D0"] + end + + subgraph sg_3_line_2["3-line"] + R["D/CX"] --> S["D7"] + R --> T["D6"] + R --> U["D5"] + R --> V["D4"] + R --> W["D3"] + R --> X["D2"] + R --> Y["D1"] + R --> Z["D0"] + end + + subgraph sg_4_line_2["4-line"] + AA["D7"] --> AB["D6"] + AA --> AC["D5"] + AA --> AD["D4"] + AA --> AE["D3"] + AA --> AF["D2"] + AA --> AG["D1"] + AA --> AH["D0"] + end + + subgraph sg_4_line_3["4-line"] + AI["D7"] --> AJ["D6"] + AI --> AK["D5"] + AI --> AL["D4"] + AI --> AM["D3"] + AI --> AN["D2"] + AI --> AO["D1"] + AI --> AP["D0"] + end +``` +
+ +Figure 16 Serial Interface Data Stream Format + +When CSX is “high”, SCL clock is ignored. During the high period of CSX the serial interface is initialized. At the falling edge of CSX, SCL can be high or low (see Figure 17). SDA is sampled at the rising edge of SCL. D/CX indicates whether the byte is command (D/CX='0') or parameter/RAM data (D/CX='1'). D/CX is sampled when first rising edge of SCL (3-lines serial interface) or 8th rising edge of SCL (4-lines serial interface). If CSX stays low after the last bit of command/data byte, the serial interface expects the D/CX bit (3-lines serial interface) or D7 (4-lines serial interface) of the next byte at the next rising edge of SCL.. + +![](images/c6508fa0bcfebc6f946b9002698456cb516379a2905292e051968a27cb71c45f.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Host + S["S"] --> TB["TB"] + TB --> P["P"] + end + + subgraph CSX + CSX["CSX"] --> S + S --> D/C["D/C"] + DC["D/C"] --> D7["D7"] + D7 --> D6["D6"] + D6 --> D5["D5"] + D5 --> D4["D4"] + D4 --> D3["D3"] + D3 --> D2["D2"] + D2 --> D1["D1"] + D1 --> D0["D0"] + D0 --> D/C["D/C"] + DC --> D7["D7"] + D7 --> D6["D6"] + D6 --> D5["D5"] + D5 --> D4["D4"] + D4 --> D3["D3"] + D3 --> D2["D2"] + D2 --> D1["D1"] + D1 --> D0["D0"] + D0 --> SCL["SCL"] + end + + subgraph SDA + SCL --> SCL + end + + subgraph Command + SCL --> SCL + end + + subgraph Command_Parameter["Command/Parameter"] + SCL --> SCL + end +``` +
+ +Figure 17 3-line Serial Interface Write Protocol (Write to Register with Control Bit in Transmission) + +![](images/73c6f052d20d248f217c814e7948d1157b96c9eb21236e3e744ae26c473be987.jpg) + +
+flowchart + +This diagram illustrates the protocol stack structure for a host system (MCU to driver), showing the sequence of commands and data paths between CSX, SDA, D/CX, and SCL. +
+ +Figure 18 4-line Serial Interface Write Protocol (Write to Register with Control Bit in Transmission) + +## 9.4.2 Read Functions + +The read mode of the interface means that the micro controller reads register value from the driver. To achieve read function, the micro controller first has to send a command (read ID or register command) and then the following byte is transmitted in the opposite direction. After that CSX is required to go to high before a new command is send (see the below figure). The driver samples the SDA (input data) at rising edge of SCL, but shifts SDA (output data) at the falling edge of SCL. Thus the micro controller is supported to read at the rising edge of SCL. + +After the read status command has been sent, the SDA line must be set to tri-state no later than at the falling edge of SCL of the last bit. + +## 9.4.3 3-line Serial Protocol + +3-line Serial Protocol (for RDID1/RDID2/RDID3/0Ah/0Bh/0Ch/0Dh/0Eh/0Fh Command: 8-bit Read): + +![](images/fca701c2986779076101cf757a6a4aacb806faeb80ce2d6d56d3094a551bed13.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Host + S["S"] --> TB["TB"] + S --> P["P"] + P --> S + CSX["CSX"] --> S + SCL["SCL"] --> S + SDA["SDA"] --> D_C["D/C"] + D_C --> D7["D7"] + D7 --> D6["D6"] + D6 --> D5["D5"] + D5 --> D4["D4"] + D4 --> D3["D3"] + D3 --> D2["D2"] + D2 --> D1["D1"] + D1 --> D0["D0"] + Hi_Z["Hi-Z"] --> D7 + Hi_Z --> D6 + Hi_Z --> D5 + Hi_Z --> D4 + Hi_Z --> D3 + Hi_Z --> D2 + Hi_Z --> D1 + Hi_Z --> D0 + D7 --> D7 + D6 --> D6 + D5 --> D5 + D4 --> D4 + D3 --> D3 + D2 --> D2 + D1 --> D1 + D0 --> D0 + D7 --> D7 + D6 --> D6 + D5 --> D5 + D4 --> D4 + D3 --> D3 + D2 --> D2 + D1 --> D1 + D0 --> D0 + end + subgraph Driver + SDA["SDA (SDO)"] --> Hi_Z["Hi-Z"] + Hi_Z --> D7 + Hi_Z --> D6 + Hi_Z --> D5 + Hi_Z --> D4 + Hi_Z --> D3 + Hi_Z --> D2 + Hi_Z --> D1 + Hi_Z --> D0 + end +``` +
+ +3-line Serial Protocol (for RDDID Command: 24-bit Read) + +![](images/9ac5d5bd785a32410d83d32f7a9625397a776b7deed3a8e0963dc13f5cd0cda4.jpg) + +
+flowchart + +This diagram illustrates the timing and state transitions of a system involving Host and Driver components, including CSX, SCL, SDA, and D3-D2, with a dummy clock cycle indicated. +
+ +3-line Serial Protocol (for RDDST Command: 32-bit Read) + +![](images/7da9298b0180f85e721452445302735c265b1dede8f31e223a273d782da18acd.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Host + S["S"] --> TB["TB"] + TB --> P["P"] + P --> S["S"] + end + subgraph Driver + SDA["SDA"] --> HiZ["Hi-Z"] + HiZ --> D31["D31"] + D31 --> D30["D30"] + D30 --> D29["D29"] + D29 --> D28["D28"] + D28 --> D3["D3"] + D3 --> D2["D2"] + D2["D2"] --> D1["D1"] + D1 --> D0["D0"] + D0 --> HiZ + HiZ --> D3 + HiZ --> D3 + D3 --> D0 + D0 --> HiZ + HiZ --> D3 + D3 --> D2 + D2 --> D1 + D1 --> D0 + end +``` +
+ +Figure 19 3-line Serial Interface Read Protocol + +## 9.4.4 4-line Serial Protocol + +4-line Serial Protocol (for RDID1/RDID2/RDID3/0Ah/0Bh/0Ch/0Dh/0Eh/0Fh Command: 8-bit Read): + +![](images/148aec0e7703adac51afea12a93fcbf21d5a280a736f5d3367fa15a5181a2efc.jpg) + +
+flowchart + +This diagram illustrates the data flow and synchronization logic between a Host (CSX, SCL, D/CX, SDA) and a Driver (SDA/DOUT), showing transitions between states (S, TB, P, S), clock signals, and data flow patterns. +
+ +4-line Serial Protocol (for RDDID Command: 24-bit Read) + +![](images/11eae392773c9055cd3e5d992cfd860da94f101621dc97b3e5720f19fe0f9e2e.jpg) + +
+flowchart + +This diagram illustrates the timing and state transitions of a host system (CSX, SCL, D/CX) and a driver (SDA/DOUT) over time, showing transitions between states such as S, TB, P, S, and D. +
+ +4-line Serial Protocol (for RDDST Command: 32-bit Read) + +![](images/d85b2f6e3175cd4b1957689b42e41d2e64d6e0a55fbbe46f49abbc310f3218da.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Host + S["S"] --> TB["TB"] + S --> P["P"] + S --> S["S"] + S --> CSX["CSX"] + S --> SCL["SCL"] + SCL --> D["D"] + D --> CX["D/CX"] + CX --> O["O"] + O --> SDA["SDA (DIN)"] + SDA --> D7["D7"] + D7 --> D6["D6"] + D6 --> D5["D5"] + D5 --> D4["D4"] + D4 --> D3["D3"] + D3 --> D2["D2"] + D2 --> D1["D1"] + D1 --> D0["D0"] + D0 --> HiZ["Hi-Z"] + HiZ --> D31["D31"] + D31 --> D30["D30"] + D30 --> D29["D29"] + D29 --> D28["D28"] + D28 --> D3["D3"] + D3 --> D2["D2"] + D2 --> D1["D1"] + D1 --> D0["D0"] + D0 --> D7["D7"] + D7 --> D7 + D7 --> SDA + SDA --> DOUT["SDA (DOUT)"] + DOUT --> HiZ + end + subgraph Driver + HiZ --> D31 + D31 --> D30 + D30 --> D29 + D29 --> D28 + D28 --> D3 + D3 --> D2 + D2 --> D1 + D1 --> D0 + D0 --> D7 + D7 --> D7 + end +``` +
+ +Figure 20 4-line Serial Interface Read Protocol + +## 9.5 Data Transfer Break and Recovery + +If there is a break in data transmission by RESX pulse, while transferring a command or frame memory data or multiple parameter command data, before Bit D0 of the byte has been completed, then driver will reject the previous bits and have reset the interface such that it will be ready to receive command data again when the chip select line (CSX) is next activated after RESX have been HIGH state. See the following example + +![](images/4b43babb5a2d31260a1184cfd9856ad4a95323a7e827713267b73a829e07da1a.jpg) + +
+flowchart + +This diagram illustrates the protocol stack structure for a host driver system, showing the sequence of commands (S, TB, P) and data streams (CSX, RESX, SCL, SDA). It highlights the idle state of SCL and SDA during RESX and the invalid state of SCL and SDA during RESX. +
+ +Figure 21 Serial Bus Protocol, Write Mode – Interrupted by RESX + +If there is a break in data transmission by CSX pulse, while transferring a command or frame memory data or multiple parameter command data, before Bit D0 of the byte has been completed, then driver will reject the previous bits and have reset the interface such that it will be ready to receive the same byte re-transmitted when the chip select line (CSX) is next activated. See the following example + +![](images/43a8a872ab4801ad4b00a04f559fba57a77b8fdc97061424be9667293c7f51f6.jpg) + +
+flowchart + +This diagram illustrates the architecture of a Host Driver (MCU) system, showing the signal flow between CSX, SCL, and SDA components through a transmission block (TB), a break, and a command parameter data transmission. +
+ +Figure 22 Serial Bus Protocol, Write Mode – Interrupted by CSX + +If 1, 2 or more parameter commands are being sent and a break occurs while sending any parameter before the last one and if the host then sends a new command rather than re-transmitting the parameter that was interrupted, then the parameters that were successfully sent are stored and the parameter where the break occurred is rejected. The interface is ready to receive next byte as shown below. + +![](images/a43323c34f837635f4a7b2199415628ae2c941bfe821a15e304f0cf8c7565661.jpg) +Figure 23 Write Interrupts Recovery (Serial Interface) + +If a 2 or more parameter commands are being sent and a break occurs by the other command before the last one is sent, then the parameters that were successfully sent are stored and the other parameter of that command remains previous value. + +![](images/ede45b78877575a7338b9aa3504ad54d0c4914be5ed4e61982c7e59171cad8ba.jpg) + +
+flowchart + +```mermaid +graph LR + A["CMD1"] --> B["Para11"] + B --> C["CMD2"] + C --> D["CMD1"] + D --> E["Para11"] + E --> F["Para12"] + F --> G["Para13"] + G --> H["Command1"] + C -.->|break| B + D -.->|Command1 with 1st parameter (para11) should be executed again to write remained parameter (para12, para13)"] +``` +
+ +Figure 24 Write Interrupts Recovery (Both Serial and Parallel Interface) + +## 9.6 Data Transfer Pause + +It will be possible when transferring a command, frame memory data or multiple parameter data to invoke a pause in the data transmission. If the chip select line is released after a whole byte of a frame memory data or multiple parameter data has been completed, then driver will wait and continue the frame memory data or parameter data transmission from the point where it was paused. If the chip select Line is released after a whole byte of a command has been completed, then the display module will receive either the command's parameters (if appropriate) or a new command when the chip select line is next enabled as shown below. + +This applies to the following 4 conditions: + +1) Command-Pause-Command +2) Command-Pause-Parameter +3) Parameter-Pause-Command +4) Parameter-Pause-Parameter + +## 9.6.1 Serial Interface Pause + +![](images/349c335e409020dafb59e21a0c8133847e07203ebb23b95b0cae163dc2136b18.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Host + S["S"] --> TB["TB"] + TB --> Pause["Pause"] + Pause --> TB + TB --> P["P"] + end + + subgraph CSX + CSX["CSX"] --> S + S --> D7["D7"] + D7 --> D6["D6"] + D6 --> D5["D5"] + D5 --> D4["D4"] + D4 --> D3["D3"] + D3 --> D2["D2"] + D2 --> D1["D1"] + D1 --> D0["D0"] + D0 --> D7["D7"] + D7 --> D6["D6"] + D6 --> D5["D5"] + D5 --> D4["D4"] + D4 --> D3["D3"] + D3 --> D2["D2"] + D2 --> D1["D1"] + D1 --> D0["D0"] + D0 --> SCL["SCL"] + end + + subgraph SCL + SCL --> S + S --> S + S --> SCL + end + + subgraph Command + SCL --> SCL["SCL"] + SCL --> SCL + SCL --> SCL + end + + subgraph SDA + SCL --> SDA["SDA"] + SCL --> SDA + SDA --> D7 + SDA --> D6 + SDA --> D5 + SDA --> D4 + SDA --> D3 + SDA --> D2 + SDA --> D1 + SDA --> D0 + SCL --> SCL + end + + subgraph P + SCL --> P["P"] + P --> P + end + + SCL --> P + SCL --> SCL +``` +
+ +Figure 25 Serial Interface Pause Protocol (Pause by CSX) + +## 9.6.2 Parallel Interface Pause + +![](images/449b3dbc4d27fe29f4eee487af7111ab8e6e290cef3594795e377f8963cda06b.jpg) + +
+flowchart + +This diagram illustrates the timing and state transitions of a system across five key components: CSX, D/CX, RDX, WRX, and D[17:0]. It highlights specific events such as 'Pause' and 'Command/Parameter' transitions between states. +
+ +Figure 26 Parallel Bus Pause Protocol (Paused by CSX) + +## 9.7 Data Transfer Modes + +The module has three kinds color modes for transferring data to the display RAM. These are 12-bit color per pixel, 16-bit color per pixel and 18-bit color per pixel. The data format is described for each interface. Data can be downloaded to the frame memory by 2 methods. + +## 9.7.1 Method 1 + +The image data is sent to the frame memory in successive frame writes, each time the frame memory is filled, the frame memory pointer is reset to the start point and the next frame is written. + +
StartStop
Start frameMemory writeFrame 1Image dataFrame 2Image dataFrame 3Image dataAny command
+ +## 9.7.2 Method 2 + +The image data is sent and at the end of each frame memory download, a command is sent to stop frame memory write. Then start memory write command is sent, and a new frame is downloaded. + +![](images/2063661fbb70bf7547ec489996e73b91026b758196a94cdeb44075a8ad4b8aa4.jpg) +Note 1: These apply to all data transfer Color modes on both serial and parallel interfaces. +Note 2: The frame memory can contain both odd and even number of pixels for both methods. Only complete pixel data will be stored in the frame memory. + +## 9.8 Data Color Coding + +## 9.8.1 8-bit Parallel Interface (IM2, IM1, IM0= "100") + +Different display data formats are available for three Colors depth supported by listed below. + +- 4k Colors, RGB 4,4,4-bit Input. +- 65k Colors, RGB 5,6,5-bit Input. +- 262k Colors, RGB 6,6,6-bit Input. + +9.8.2 8-bit Data Bus for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH= "03h" +![](images/884ca7549a3cddc3c1461d44091d47a00435ad140f750ee4dd4a139f22a87e7e.jpg) + +
+flowchart + +This diagram illustrates the 8080-series control pins and pixel mapping for a 4096 color data mapping system, showing the sequence of data bits from input to output. +
+ +Note 1: The data order is as follows, MSB=D7, LSB=D0 and picture data is MSB=Bit 3, LSB=Bit 0 for Red, Green and Blue data. +Note 2: 3-time transfer is used to transmit 1 pixel data with the 12-bit color depth information. +Note 3: '-' = Don't care - Can be set to '0' or '1' + +## 9.8.3 8-bit Data Bus for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH= "05h" + +There is 1 pixel (3 sub-pixels) per 2-byte +![](images/9462d6321be18dd5c41bbda4ee7ebf26a678dac85e769b37c85c1d53c1e2b9de.jpg) + +
+flowchart + +This diagram illustrates the 8080-series control pins for a 65k color data mapping system, showing the bit allocation and data mapping logic. +
+ +Note 1: The data order is as follows, MSB=D7, LSB=D0 and picture data is MSB=Bit 5, LSB=Bit 0 for Green and MSB=Bit 4, LSB=Bit 0 for Red and Blue data. +Note 2: 2-times transfer is used to transmit 1 pixel data with the 16-bit color depth information. +Note 3: '-' = Don't care - Can be set to '0' or '1' + +## 9.8.4 8-bit Data Bus for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH= "06h" + +There is 1 pixel (3 sub-pixels) per 3-bytes. + +![](images/739a6fd431d22fdfa9ef88fc4bd9e2531da79617fd7a3102bc9c09923da2cd97.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Control_Pins + D7["D7"] -->|0| R1["R1, Bit 5"] + D6["D6"] -->|0| R1["R1, Bit 4"] + D5["D5"] -->|1| R1["R1, Bit 3"] + D4["D4"] -->|0| R1["R1, Bit 2"] + D3["D3"] -->|1| R1["R1, Bit 1"] + D2["D2"] -->|1| R1["R1, Bit 0"] + D1["D1"] -->|0| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| -| +``` +
+ +Note 1: The data order is as follows, MSB=D7, LSB=D0 and picture data is MSB=Bit 5, LSB=Bit 0 for Red, Green and Blue data. +Note 2: 3-times transfer is used to transmit 1 pixel data with the 18-bit color depth information. +Note 3: '-' = Don't care - Can be set to '0' or '1' + +## 9.8.5 16-Bit Parallel Interface (IM2,IM1, IM0= "101") + +Different display data formats are available for three colors depth supported by listed below. + +- 4k Colors, RGB 4,4,4-bit Input +- 65k Colors, RGB 5,6,5-bit Input +- 262k Colors, RGB 6,6,6-bit Input + +## 9.8.6 16-bit Data Bus for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH= "03h" + +There is 1 pixel (3 sub-pixels) per 1 byte +![](images/af3ef450df6180dd16f535265fac576c3f65e8c0f602b0d01eac3c488011f2cb.jpg) + +
+flowchart + +This diagram illustrates a 8080-series control pin configuration for a 4096 color data mapping system, showing the sequence of data bits (R1-R4) and their mapping to a frame memory. +
+ +Note 1: The data order is as follows, MSB=D11, LSB=D0 and picture data is MSB=Bit 3, LSB=Bit 0 for Red, Green and Blue data. +Note 2: 1-times transfer (D11 to D0) is used to transmit 1 pixel data with the 12-bit color depth information. + +## 9.8.7 16-bit Data Bus for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH= "05h" + +There is 1 pixel (3 sub-pixels) per 1 byte +![](images/8c95be61fbd1facd13d28f2275df261be15518f0fdd4cb1826a5f40af4985fdf.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Control_Pins + D15["D15"] --> R1["R1, Bit 4"] + D14["D14"] --> R1["R1, Bit 3"] + D13["D13"] --> R1["R1, Bit 2"] + D12["D12"] --> R1["R1, Bit 1"] + D11["D11"] --> R1["R1, Bit 0"] + D10["D10"] --> G1["G1, Bit 5"] + D9["D9"] --> G1["G1, Bit 4"] + D8["D8"] --> G1["G1, Bit 3"] + D7["D7"] --> G1["G1, Bit 2"] + D6["D6"] --> G1["G1, Bit 1"] + D5["D5"] --> G1["G1, Bit 0"] + D4["D4"] --> B1["B1, Bit 4"] + D3["D3"] --> B1["B1, Bit 3"] + D2["D2"] --> B1["B1, Bit 2"] + D1["D1"] --> B1["B1, Bit 1"] + D0["D0"] --> B1["B1, Bit 0"] + end + + subgraph Mapping + Pixel_n["Pixel n"] + Pixel_n+1["Pixel n+1"] + Pixel_n+2["Pixel n+2"] + Pixel_n+3["Pixel n+3"] + end + + Pixel_n -->|16 bits| Mapping + PixelN1["Pixel_n+1"] -->|16 bits| Mapping + PixelN2["Pixel_n+2"] -->|16 bits| Mapping + PixelN3["Pixel_n+3"] -->|16 bits| Mapping + + Mapping["Look-up table for 65k color data mapping (16 bits to 18 bits)"] -->|18 bits| FrameMemory["Frame memory"] + FrameMemory --> R1["R1"] + FrameMemory --> G1["G1"] + FrameMemory --> B1["B1"] + FrameMemory --> R2["R2"] + FrameMemory --> G2["G2"] + FrameMemory --> B2["B2"] + FrameMemory --> R3["R3"] + FrameMemory --> G3["G3"] + FrameMemory --> B3["B3"] +``` +
+ +Note 1: The data order is as follows, MSB=D15, LSB=D0 and picture data is MSB=Bit 5, LSB=Bit 0 for Green, and MSB=Bit 4, LSB=Bit 0 for Red and Blue data. +Note 2: 1-times transfer (D15 to D0) is used to transmit 1 pixel data with the 16-bit color depth information. +Note 3: '-' = Don't care - Can be set to '0' or '1' + +## 9.8.8 16-bit Data Bus for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH= "06h" + +There are 2 pixels (6 sub-pixels) per 3 bytes + +![](images/a0dfd286edcec70993fa5e9390be43cfdc8f935731f2f63ff1411b5c10290ba2.jpg) + +
+flowchart + +This diagram illustrates the 8080-series control pins for a 8-bit frame memory, showing the signal flow from input/output to data processing and final memory layout. +
+ +Note 1: The data order is as follows, MSB=D15, LSB=D0 and picture data is MSB=Bits 5, LSB=Bit 0 for Red, Green and Blue data. +Note 2: 3-times transfer is used to transmit 1 pixel data with the 18-bit color depth information. +Note 3: '-' = Don't care - Can be set to '0' or '1' + +## 9.8.9 9-Bit Parallel Interface (IM2, IM1, IM0="110") + +Different display data formats are available for three colors depth supported by listed below. + +-262k colors, RGB 6,6,6-bit input + +## 9.8.10 Write 9-bit Data for RGB 6-6-6-bit Input (262k-color) + +There is 1 pixel (6 sub-pixels) per 3 bytes +![](images/1a71d85872e4de1a9e4dff0455f7531d46a1f4fe245407d15d6b013c84accd0e.jpg) + +
+flowchart + +This diagram illustrates the 8080-series control pins for a frame memory system, showing the signal flow from input to output through various bit positions and bit ranges. +
+ +Note 1: The data order is as follows, MSB=D8, LSB=D0 and picture data is MSB=Bit 5, LSB=Bit 0 for Red, Green and Blue data. +Note 2: 3-times transfer is used to transmit 1 pixel data with the 18-bit color depth information. +Note 3: '-' = Don't care - Can be set to '0' or '1' + +## 9.8.11 18-Bit Parallel Interface (IM2, IM1, IM0="111") + +Different display data formats are available for three colors depth supported by listed below. + +- 4k Colors, RGB 4,4,4-bit Input +- 65k Colors, RGB 5,6,5-bit Input +- 262k Colors, RGB 6,6,6-bit Input. + +## 9.8.12 18-bit Data Bus for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH="03h" + +There is 1 pixel (3 sub-pixels) per 1 byte +![](images/b0e86f42177f65297b54c600bb92de36e74d677276b5f379bbc1fa1c3dc742a7.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Control_Pins + direction TB + D17["D17"] --> P1["P1"] + D16["D16"] --> P2["P2"] + D15["D15"] --> P3["P3"] + D14["D14"] --> P4["P4"] + D13["D13"] --> P5["P5"] + D12["D12"] --> P6["P6"] + D11["D11"] --> P7["P7"] + D10["D10"] --> P8["P8"] + D9["D9"] --> P9["P9"] + D8["D8"] --> P10["P10"] + D7["D7"] --> P11["P11"] + D6["D6"] --> P12["P12"] + D5["D5"] --> P13["P13"] + D4["D4"] --> P14["P14"] + D3["D3"] --> P15["P15"] + D2["D2"] --> P16["P16"] + D1["D1"] --> P17["P17"] + D0["D0"] --> P18["P18"] + end + + P1 -->|"12 bits"| Table["Look-Up Table for 4096 Color data mapping (12 bits to 18 bits)"] + P2 -->|"12 bits"| Table + P3 -->|"12 bits"| Table + P4 -->|"12 bits"| Table + P5 -->|"12 bits"| Table + P6 -->|"12 bits"| Table + P7 -->|"12 bits"| Table + P8 -->|"12 bits"| Table + P9 -->|"12 bits"| Table + P10 -->|"12 bits"| Table + P11 -->|"12 bits"| Table + P12 -->|"12 bits"| Table + P13 -->|"12 bits"| Table + P14 -->|"12 bits"| Table + P15 -->|"12 bits"| Table + P16 -->|"12 bits"| Table + P17 -->|"12 bits"| Table + P18 -->|"12 bits"| Table + P19 -->|"12 bits"| Table + P20 -->|"12 bits"| Table + P21 -->|"12 bits"| Table + P22 -->|"12 bits"| Table + P23 -->|"12 bits"| Table + P24 -->|"12 bits"| Table + P25 -->|"12 bits"| Table + P26 -->|"12 bits"| Table + P27 -->|"12 bits"| Table + P28 -->|"12 bits"| Table + P29 -->|"12 bits"| Table + P30 -->|"12 bits"| Table + P31 -->|"12 bits"| Table + P32 -->|"12 bits"| Table + P33 -->|"12 bits"| Table + P34 -->|"12 bits"| Table + P35 -->|"12 bits"| Table + P36 -->|"12 bits"| Table + P37 -->|"12 bits"| Table + P38 -->|"12 bits"| Table + P39 -->|"12 bits"| Table + P40 -->|"12 bits"| Table + P41 -->|"12 bits"| Table + P42 -->|"12 bits"| Table + P43 -->|"12 bits"| Table + P44 -->|"12 bits"| Table + P45 -->|"12 bits"| Table + P46 -->|"12 bits"| Table + P47 -->|"12 bits"| Table + P48 -->|"12 bits"| Table + P49 -->|"12 bits"| Table + P50 -->|"12 bits"| Table + P51 -->|"12 bits"| Table + P52 -->|"12 bits"| Table + P53 -->|"12 bits"| Table + P54 -->|"12 bits"| Table + P55 -->|"12 bits"| Table + P56 -->|"12 bits"| Table + P57 -->|"12 bits"| Table + P58 -->|"12 bits"| Table + P59 -->|"12 bits"| Table + P60 -->|"12 bits"| Table + P61 -->|"12 bits"| Table + P62 -->|"12 bits"| Table + P63 -->|"12 bits"| Table + P64 -->|"12 bits"| Table + P65 -->|"12 bits"| Table + P66 -->|"12 bits"| Table + P67 -->|"12 bits"| Table + P68 -->|"12 bits"| Table + P69 -->|"12 bits"| Table + P70 -->|"12 bits"| Table + P71 -->|"12 bits"| Table + P72 -->|"12 bits"| Table + P73 -->|"12 bits"| Table + P74 -->|"12 bits"| Table + P75 -->|"12 bits"| Table + P76 -->|"12 bits"| Table + P77 -->|"12 bits"| Table + P78 -->|"12 bits"| Table + P79 -->|"12 bits"| Table + P80 -->|"12 bits"| Table + P81 -->|"12 bits"| Table + P82 -->|"12 bits"| Table + P83 -->|"12 bits"| Table + P84 -->|"12 bits"| Table + P85 -->|"12 bits"| Table + P86 -->|"12 bits"| Table + P87 -->|"12 bits"| Table + P88 -->|"12 bits"| Table + P89 -->|"12 bits"| Table + P90 -->|"12 bits"| Table + P91 -->|"12 bits"| Table + P92 -->|"12 bits"| Table + P93 -->|"12 bits"| Table + P94 -->|"12 bits"| Table + P95 -->|"12 bits"| Table + P96 -->|"12 bits"| Table + P97 -->|"12 bits"| Table + P98 -->|"12 bits"| Table + P99 -->|"12 bits"| Table + P100 -->|"12 bits"| Table + P101 -->|"12 bits"| Table + P102 -->|"12 bits"| Table + P103 -->|"12 bits"| Table + P104 -->|"12 bits"| Table + P105 -->|"12 bits"| Table + P106 -->|"12 bits"| Table + P107 -->|"12 bits"| Table + P108 -->|"12 bits"| Table + P109 -->|"12 bits"| Table + P110 -->|"12 bits"| Table + P111 -->|"12 bits"| Table + P112 -->|"12 bits"| Table + P113 -->|"12 bits"| Table + P114 -->|"12 bits"| Table + P115 -->|"12 bits"| Table + P116 -->|"12 bits"| Table + P117 -->|"12 bits"| Table + P118 -->|"12 bits"| Table + P119 -->|"12 bits"| Table + P120 -->|"12 bits"| Table + P121 -->|"12 bits"| Table + P122 -->|"12 bits"| Table + P123 -->|"12 bits"| Table + P124 -->|"12 bits"| Table + P125 -->|"12 bits"| Table + P126 -->|"12 bits"| Table + P127 -->|"12 bits"| Table + P128 -->|"12 bits"| Table + P129 -->|"12 bits"| Table + P130 -->|"12 bits"| Table + P131 -->|"12 bits"| Table + P132 -->|"12 bits"| Table + P133 -->|"12 bits"| Table + P134 -->|"12 bits"| Table + P135 -->|"12 bits"| Table + P136 -->|"12 bits"| Table + P137 -->|"12 bits"| Table + P138 -->|"12 bits"| Table + P139 -->|"12 bits"| Table + P140 -->|"12 bits"| Table + P141 -->|"12 bits"| Table + P142 -->|"12 bits"| Table + P143 -->|"12 bits"| Table + P144 -->|"12 bits"| Table + P145 -->|"12 bits"| Table + P146 -->|"12 bits"| Table + P147 -->|"12 bits"| Table + P148 -->|"12 bits"| Table + P149 -->|"12 bits"| Table + P150 -->|"12 bits"| Table + P151 -->|"12 bits"| Table + P152 -->|"12 bits"| Table + P153 -->|"12 bits"| Table + P154 -->|"12 bits"| Table + P155 -->|"12 bits"| Table + P156 -->|"12 bits"| Table + P157 -->|"12 bits"| Table + P158 -->|"12 bits"| Table + P159 -->|"12 bits"| Table + P160 -->|"12 bits"| Table + P161 -->|"12 bits"| Table + P162 -->|"12 bits"| Table + P163 -->|"12 bits"| Table + P164 -->|"12 bits"| Table + P165 -->|"12 bits"| Table + P166 -->|"12 bits"| Table + P167 -->|"12 bits"| Table + P168 -->|"12 bits"| Table + P169 -->|"12 bits"| Table + P170 -->|"12 bits"| Table + P171 -->|"12 bits"| Table + P172 -->|"12 bits"| Table + P173 -->|"12 bits"| Table + P174 -->|"12 bits"| Table + P175 -->|"12 bits"| Table + P176 -->|"12 bits"| Table + P177 -->|"12 bits"| Table + P178 -->|"12 bits"| Table + P179 -->|"12 bits"| Table + P180 -->|"12 bits"| Table + P181 -->|"12 bits"| Table + P182 -->|"12 bits"| Table + P183 -->|"12 bits"| Table + P184 -->|"12 bits"| Table + P185 -->|"12 bits"| Table + P186 -->|"12 bits"| Table + P187 -->|"12 bits"| Table + P188 -->|"12 bits"| Table + P189 -->|"12 bits"| Table + P190 -->|"12 bits"| Table + P191 -->|"12 bits"| Table + P192 -->|"12 bits"| Table + P193 -->|"12 bits"| Table + P194 -->|"12 bits"| Table + P195 -->|"12 bits"| Table + P196 -->|"12 bits"| Table + P197 -->|"12 bits"| Table + P198 -->|"12 bits"| Table + P199 -->|"12 bits"| Table + P200 -->|"12 bits"| Table + P201 -->|"12 bits"| Table + P202 -->|"12 bits"| Table + P203 -->|"12 bits"| Table + P204 -->|"12 bits"| Table + P205 -->|"12 bits"| Table + P206 -->|"12 bits"| Table + P207 -->|"12 bits"| Table + P208 -->|"12 bits"| Table + P209 -->|"12 bits"| Table + P210 -->|"12 bits"| Table + P211 -->|"12 bits"| Table + P212 -->|"12 bits"| Table + P213 -->|"12 bits"| Table + P214 -->|"12 bits"| Table + P215 -->|"12 bits"| Table + P216 -->|"12 bits"| Table + P217 -->|"12 bits"| Table + P218 -->|"12 bits"| Table + P219 -->|"12 bits"| Table + P220 -->|"12 bits"| Table + P221 -->|"12 bits"| Table + P222 -->|"12 bits"| Table + P223 -->|"12 bits"| Table + P224 -->|"12 bits"| Table + P225 -->|"12 bits"| Table + P226 -->|"12 bits"| Table + P227 -->|"12 bits"| Table + P228 -->|"12 bits"| Table + P229 -->|"12 bits"| Table + P230 -->|"12 bits"| Table + P231 -->|"12 bits"| Table + P232 -->|"12 bits"| Table + P233 -->|"12 bits"| Table + P234 -->|"12 bits"| Table + P235 -->|"12 bits"| Table + P236 -->|"12 bits"| Table + P237 -->|"12 bits"| Table + P238 -->|"12 bits"| Table + P239 -->|"12 bits"| Table + P240 -->|"12 bits"| Table + P241 -->|"12 bits"| Table + P242 -->|"12 bits"| Table + P243 -->|"12 bits"| Table + P244 -->|"12 bits"| Table + P245 -->|"12 bits"| Table + P246 -->|"12 bits"| Table + P247 -->|"12 bits"| Table + P248 -->|"12 bits"| Table + P249 -->|"12 bits"| Table + P250 -->|"12 bits"| Table + P251 -->|"12 bits"| Table + P252 -->|"12 bits"| Table + P253 -->|"12 bits"| Table + P254 -->|"12 bits"| Table + P255 -->|"12 bits"| Table + P256 -->|"12 bits"| Table + P257 -->|"12 bits"| Table + P258 -->|"12 bits"| Table + P259 -->|"12 bits"| Table + P260 -->|"12 bits"| Table + P261 -->|"12 bits"| Table + P262 -->|"12 bits"| Table + P263 -->|"12 bits"| Table + P264 -->|"12 bits"| Table + P265 -->|"12 bits"| Table + P266 -->|"12 bits"| Table + P267 -->|"12 bits"| Table + P268 -->|"12 bits"| Table + P269 -->|"12 bits"| Table + P270 -->|"12 bits"| Table + P271 -->|"12 bits"| Table + P272 -->|"12 bits"| Table + P273 -->|"12 bits"| Table + P274 -->|"12 bits"| Table + P275 -->|"12 bits"| Table + P276 -->|"12 bits"| Table + P277 -->|"12 bits"| Table + P278 -->|"12 bits"| Table + P279 -->|"12 bits"| Table + P280 -->|"12 bits"| Table + P281 -->|"12 bits"| Table + P282 -->|"12 bits"| Table + P283 -->|"12 bits"| Table + P284 -->|"12 bits"| Table + P285 -->|"12 bits"| Table + P286 -->|"12 bits"| Table + P287 -->|"12 bits"| Table + P288 -->|"12 bits"| Table + P289 -->|"12 bits"| Table + P290 -->|"12 bits"| Table + P291 -->|"12 bits"| Table + P292 -->|"12 bits"| Table + P293 -->|"12 bits"| Table + P294 -->|"12 bits"| Table + P295 -->|"12 bits"| Table + P296 -->|"12 bits"| Table + P297 -->|"12 bits"| Table + P298 -->|"12 bits"| Table + P299 -->|"12 bits"| Table + P300 -->|"12 bits"| Table + P301 -->|"12 bits"| Table + P302 -->|"12 bits"| Table + P303 -->|"12 bits"| Table + P304 -->|"12 bits"| Table + P305 -->|"12 bits"| Table + P306 -->|"12 bits"| Table + P307 -->|"12 bits"| Table + P308 -->|"12 bits"| Table + P309 -->|"12 bits"| Table + P310 -->|"12 bits"| Table + P311 -->|"12 bits"| Table + P312 -->|"12 bits"| Table + P313 -->|"12 bits"| Table + P314 -->|"12 bits"| Table + P315 -->|"12 bits"| Table + P316 -->|"12 bits"| Table + P317 -->|"12 bits"| Table + P318 -->|"12 bits"| Table + P319 -->|"12 bits"| Table + P320 -->|"12 bits"| Table + P321 -->|"12 bits"| Table + P322 -->|"12 bits"| Table + P323 -->|"12 bits"| Table + P324 -->|"12 bits"| Table + P325 -->|"12 bits"| Table + P326 -->|"12 bits"| Table + P327 -->|"12 bits"| Table + P328 -->|"12 bits"| Table + P329 -->|"12 bits"| Table + P330 -->|"12 bits"| Table + P331 -->|"12 bits"| Table + P332 -->|"12 bits"| Table + P333 -->|"12 bits"| Table + P334 -->|"12 bits"| Table + P335 -->|"12 bits"| Table + P336 -->|"12 bits"| Table + P337 -->|"12 bits"| Table + P338 -->|"12 bits"| Table + P339 -->|"12 bits"| Table + P340 -->|"12 bits"| Table + P341 -->|"12 bits"| Table + P342 -->|"12 bits"| Table + P343 -->|"12 bits"| Table + P344 -->|"12 bits"| Table + P345 -->|"12 bits"| Table + P346 -->|"12 bits"| Table + P347 -->|"12 bits"| Table + P348 -->|"12 bits"| Table + P349 -->|"12 bits"| Table + P350 -->|"12 bits"| Table + P351 -->|"12 bits"| Table + P352 -->|"12 bits"| Table + P353 -->|"12 bits"| Table + P354 -->|"12 bits"| Table + P355 -->|"12 bits"| Table + P356 -->|"12 bits"| Table + P357 -->|"12 bits"| Table + P358 -->|"12 bits"| Table + P359 -->|"12 bits"| Table + P360 -->|"12 bits"| Table + P361 -->|"12 bits"| Table + P362 -->|"12 bits"| Table + P363 -->|"12 bits"| Table + P364 -->|"12 bits"| Table + P365 -->|"12 bits"| Table + P366 -->|"12 bits"| Table + P367 -->|"12 bits"| Table + P368 -->|"12 bits"| Table + P369 -->|"12 bits"| Table + P370 -->|"12 bits"| Table + P371 -->|"12 bits"| Table + P372 -->|"12 bits"| Table + P373 -->|"12 bits"| Table + P374 -->|"12 bits"| Table + P375 -->|"12 bits"| Table + P376 -->|"12 bits"| Table + P377 -->|"12 bits"| Table + P378 -->|"12 bits"| Table + P379 -->|"12 bits"| Table + P380 -->|"12 bits"| Table + P381 -->|"12 bits"| Table + P382 -->|"12 bits"| Table + P383 -->|"12 bits"| Table + P384 -->|"12 bits"| Table + P385 -->|"12 bits"| Table + P386 -->|"12 bits"| Table + P387 -->|"12 bits"| Table + P388 -->|"12 bits"| Table + P389 -->|"12 bits"| Table + P390 -->|"12 bits"| Table + P391 -->|"12 bits"| Table + P392 -->|"12 bits"| Table + P393 -->|"12 bits"| Table + P394 -->|"12 bits"| Table + P395 -->|"12 bits"| Table + P396 -->|"12 bits"| Table + P397 -->|"12 bits"| Table + P398 -->|"12 bits"| Table + P399 -->|"12 bits"| Table + P400 -->|"12 bits"| Table + P401 -->|"12 bits"| Table + P402 -->|"12 bits"| Table + P403 -->|"12 bits"| Table + P404 -->|"12 bits"| Table + P405 -->|"12 bits"| Table + P406 -->|"12 bits"| Table + P407 -->|"12 bits"| Table + P408 -->|"12 bits"| Table + P409 -->|"12 bits"| Table + P410 -->|"12 bits"| Table + P411 -->|"12 bits"| Table + P412 -->|"12 bits"| Table + P413 -->|"12 bits"| Table + P414 -->|"12 bits"| Table + P415 -->|"12 bits"| Table + P416 -->|"12 bits"| Table + P417 -->|"12 bits"| Table + P418 -->|"12 bits"| Table + P419 -->|"12 bits"| Table + P420 -->|"12 bits"| Table + P421 -->|"12 bits"| Table + P422 -->|"12 bits"| Table + P423 -->|"12 bits"| Table + P424 -->|"12 bits"| Table + P425 -->|"12 bits"| Table + P426 -->|"12 bits"| Table + P427 -->|"12 bits"| Table + P428 -->|"12 bits"| Table + P429 -->|"12 bits"| Table + P430 -->|"12 bits"| Table + P431 -->|"12 bits"| Table + P432 -->|"12 bits"| Table + P433 -->|"12 bits"| Table + P434 -->|"12 bits"| Table + P435 -->|"12 bits"| Table + P436 -->|"12 bits"| Table + P437 -->|"12 bits"| Table + P438 -->|"12 bits"| Table + P439 -->|"12 bits"| Table + P440 -->|"12 bits"| Table + P441 -->|"12 bits"| Table + P442 -->|"12 bits"| Table + P443 -->|"12 bits"| Table + P444 -->|"12 bits"| Table + P445 -->|"12 bits"| Table + P446 -->|"12 bits"| Table + P447 -->|"12 bits"| Table + P448 -->|"12 bits"| Table + P449 -->|"12 bits"| Table + P450 -->|"12 bits"| Table + P451 -->|"12 bits"| Table + P452 -->|"12 bits"| Table + P453 +``` +
+ +Note 1: The data order is as follows, MSB=D11, LSB=D0 and picture data is MSB=Bit 3, LSB=Bit 0 for Red, Green and Blue data. +Note 2: 1-times transfer is used to transmit 1 pixel data with the 12-bit color depth information. + +## 9.8.13 18-bit Data Bus for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH="05h" + +There is 1 pixel (3 sub-pixels) per 1 byte +![](images/895b648941171bad60add9c973e5df1f3dc640624ed1c9e05b2ba044f53d5d0c.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Input + A["RESX"] --> B[""IM[2:0"]"] + B --> C["CSX"] + C --> D["D/CX"] + D --> E["WRX"] + E --> F["RDX"] + end + + subgraph Control + G["D17"] --> H["D17"] + H --> I["D16"] + I --> J["D15"] + J --> K["D14"] + K --> L["D13"] + L --> M["D12"] + M --> N["D11"] + N --> O["D10"] + O --> P["D9"] + P --> Q["D8"] + Q --> R["D7"] + R --> S["D6"] + S --> T["D5"] + T --> U["D4"] + U --> V["D3"] + V --> W["D2"] + W --> X["D1"] + X --> Y["D0"] + end + + subgraph Mapping + Z["Pixel n"] -->|16 bits| AA["Look-up table for 65k color data mapping (16 bits to 18 bits)"] + AA -->|16 bits| AB["Frame memory"] + AB --> AC["R1, G1, B1, R2, G2, B2, R3, G3, B3"] + end +``` +
+ +Note 1: The data order is as follows, MSB=D15, LSB=D0 and picture data is MSB=Bit 5, LSB=Bit 0 for Green, and MSB=Bit 4, LSB=Bit 0 for Red and Blue data. +Note 2: 1-time transfer is used to transmit 1 pixel data with the 16-bit color depth information. + +## 9.8.14 18-bit Data Bus for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH="06h" + +There is 1 pixel (3 sub-pixels) per 1 byte +![](images/17ec8bdfbd52961b86fc8b001d488c7ccc8c5ec50920b188cb7f1792ac3aded9.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Input + A["RESX"] -->|1"| B[""IM[2:0"]"111"] + B --> C["CSX"] + C --> D["D/CX"] + D --> E["WRX"] + E --> F["RDX"] + end + + subgraph Control + G["D17"] --> H["R1, Bit 5"] + H --> I["R2, Bit 5"] + I --> J["R3, Bit 5"] + J --> K["R4, Bit 5"] + L["D16"] --> M["R1, Bit 4"] + M --> N["R2, Bit 4"] + N --> O["R3, Bit 4"] + O --> P["R4, Bit 4"] + Q["D15"] --> R["R1, Bit 3"] + R --> S["R2, Bit 3"] + S --> T["R3, Bit 3"] + T --> U["R4, Bit 3"] + V["D14"] --> W["R1, Bit 2"] + W --> X["R2, Bit 2"] + X --> Y["R3, Bit 2"] + Y --> Z["R4, Bit 2"] + AA["D13"] --> AB["R1, Bit 1"] + AB --> AC["R2, Bit 1"] + AC --> AD["R3, Bit 1"] + AD --> AE["R4, Bit 1"] + AF["D12"] --> AG["R1, Bit 0"] + AG --> AH["R2, Bit 0"] + AH --> AI["R3, Bit 0"] + AI --> AJ["R4, Bit 0"] + AK["D11"] --> AL["G1, Bit 5"] + AL --> AM["G2, Bit 5"] + AM --> AN["G3, Bit 5"] + AN --> AO["G4, Bit 5"] + AP["D10"] --> AQ["G1, Bit 4"] + AQ --> AR["G2, Bit 4"] + AR --> AS["G3, Bit 4"] + AS --> AT["G4, Bit 4"] + AU["D9"] --> AV["G1, Bit 3"] + AV --> AW["G2, Bit 3"] + AW --> AX["G3, Bit 3"] + AX --> AY["G4, Bit 3"] + AZ["D8"] --> BA["G1, Bit 2"] + BA --> AC["G2, Bit 2"] + AC --> AD["G3, Bit 2"] + AD --> AE["G4, Bit 2"] + AF["D7"] --> AG["0"] + AG --> AH["G1, Bit 1"] + AH --> AI["G2, Bit 1"] + AI --> AJ["G3, Bit 1"] + AJ --> AK["G4, Bit 1"] + AL["D6"] --> AM["0"] + AM --> ANF["G1, Bit 0"] + ANF --> AO["G2, Bit 0"] + AO --> AP["G3, Bit 0"] + AP --> AQY["G4, Bit 0"] + AQY --> AR["D5"] + AR --> ASF["1"] + ASF --> ABF["B1, Bit 5"] + ABF --> ACF["B2, Bit 5"] + ACF --> ABG["B3, Bit 5"] + ABG --> ACH["B4, Bit 5"] + ACH --> ADY["0"] + ADY --> AEY["B1, Bit 4"] + AEY --> AFS["B2, Bit 4"] + AFS --> AFG["B3, Bit 4"] + AFG --> AHI["B4, Bit 4"] + AHI --> ADZ["D3"] + ADZ --> AEZ["B1, Bit 3"] + AEZ --> AFB["B2, Bit 3"] + AFB --> AFG["B3, Bit 3"] + AFG --> AHI["B4, Bit 3"] + AHI --> ADY["1"] + ADY --> AEY["B1, Bit 2"] + AEY --> AFGF["B2, Bit 2"] + AFGF --> AFGF["B3, Bit 2"] + AFGF --> AFGFF["B4, Bit 2"] + AFGFF --> ADYF["0"] + ADY --> AEYF["B1, Bit 1"] + AEYF --> AFGFF["B2, Bit 1"] + AFGFF --> AFGFFF["B3, Bit 1"] + AFGFFF["A0"] --> AEYF["B1, Bit 0"] + AEYF --> AFGFFF["B2, Bit 0"] + AFGFFF["A0"] --> AFGFFFF["B2, Bit 0"] + AFGFFFF["A0"] --> AFGFFFFF["B3, Bit 0"] + AFGFFFF["A0"] --> AFGFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A0"] --> AFGFFFFFF["B4, Bit 0"] + AFGFFFFF["A +``` +
+ +Note 1: The data order is as follows, MSB=D17, LSB=D0 and picture data is MSB=Bit 5, LSB=Bit 0 for Read, Green and Blue data. +Note 2: 1-times transfer (D17o D0) is used to transmit 1 pixel data with the 18-bit color depth information. + +## 9.8.15 3-line Serial Interface + +Different display data formats are available for three colors depth supported by the LCM listed below. + +4k Colors, RGB 4-4-4-bit Input + +65k Colors, RGB 5-6-5-bit Input + +262k Colors, RGB 6-6-6-bit Input + +9.8.16 Write Data for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH="03h" +![](images/b0d8df130b911ef01bc2ab210464e2c90077e5ada11a18f8e486abbadee60d1a.jpg) + +
+flowchart + +```mermaid +graph TD + A["RESX"] -->|1"| B["IM2"] + C["CSX"] -->|1"| D["SDA"] + B -->|IM2=IM1=IMO="0"| E["SCL"] + D -->|1 Pixel n| F["Look-up table for 4096 color data mapping (12 bits to 18 bits)"] + F -->|12 bits| G["Frame memory"] + G -->|18 bits| H["SCL"] +``` +
+ +Note 1: Pixel data with the 12-bit color depth information +Note 2: The most significant bits are: Rx3, Gx3 and Bx3 +Note 3: The least significant bits are: Rx0, Gx0 and Bx0 + +9.8.17 Write Data for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH="05h" +![](images/f63dd94de518b05818246b2cea7c0b093a53d758b86697d08b154771c257ad80.jpg) + +
+flowchart + +```mermaid +graph TD + RESX["RESX"] --> SDA["SDA"] + IM2["IM2=IM1=IM0="0""] --> SDA + CSX["CSX"] --> SDA + SDA --> SCL["SCL"] + SCL --> Lookup["Look-up table for 65k color data mapping (16 bits to 18 bits)"] + Lookup --> FrameMemory["Frame memory"] + FrameMemory --> R1["R1"] + FrameMemory --> G1["G1"] + FrameMemory --> B1["B1"] + FrameMemory --> R2["R2"] + FrameMemory --> G2["G2"] + FrameMemory --> B2["B2"] + FrameMemory --> R3["R3"] + FrameMemory --> G3["G3"] + FrameMemory --> B3["B3"] +``` +
+ +Note 1: Pixel data with the 16-bit color depth information +Note 2: The most significant bits are: Rx4, Gx5 and Bx4 +Note 3: The least significant bits are: Rx0, Gx0 and Bx0 + +9.8.18 Write Data for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH="06h" +![](images/69260010a6bd4eab722b818e2d8fef60f14e53ba28a2022437d1a63173ded954.jpg) + +
+text_image + +RESX +"1" +IM2 +IM2=IM1=IM0="0" +CSX +SDA +D8 D7 D6 D5 D4 D3 D2 D1 D0 D8 D7 D6 D5 D4 D3 D2 D1 D0 +Pixel n +SCL +Frame memory +18 bits +R1 G1 B1 R2 G2 B2 R3 G3 B3 +
+ +Note 1: Pixel data with the 18-bit color depth information +Note 2: The most significant bits are: Rx5, Gx5 and Bx5 +Note 3: The least significant bits are: Rx0, Gx0 and Bx0 + +## 9.8.19 4-line Serial Interface + +Different display data formats are available for three colors depth supported by the LCM listed below. + +4k Colors, RGB 4-4-4-bit Input + +65k Colors, RGB 5-6-5-bit Input + +262k Colors, RGB 6-6-6-bit Input + +9.8.20 Write Data for 12-bit/Pixel (RGB 4-4-4-bit Input), 4K-Colors, 3AH="03h" +![](images/41e88ad01d5f0119e8b1c837a627b38e117cd0ade3e03342404b48838bb64f2a.jpg) + +
+flowchart + +```mermaid +graph TD + RESX["RESX"] -->|1"| SDA["SDA"] + IM2["IM2"] -->|1"| SDA + CSX["CSX"] -->|1"| SDA + D/CX["D/CX"] -->|1"| SDA + SDA -->|Pixel n| LookupTable["Look-up table for 4096 color data mapping (12 bits to 18 bits)"] + SCL["SCL"] -->|12 bits| LookupTable + LookupTable -->|18 bits| FrameMemory["Frame memory"] + FrameMemory -->|12 bits| SDA + FrameMemory -->|18 bits| LookupTable +``` +
+ +Note 1. pixel data with the 12-bit color depth information +Note 2. The most significant bits are: Rx3, Gx3 and Bx3 +Note 3. The least significant bits are: Rx0, Gx0 and Bx0 + +9.8.21 Write Data for 16-bit/Pixel (RGB 5-6-5-bit Input), 65K-Colors, 3AH="05h" +![](images/1fb8139c3f39df05bb34d1f9a0971df78d65495e33f7760b534682afae908568.jpg) + +
+flowchart + +```mermaid +graph TD + RESX["RESX"] -->|1"| SDA["SDA"] + IM2["IM2"] -->|1", P68="0", IM2=IM1=IM0="0"| SDA + CSX["CSX"] -->|1"| SDA + D/CX["D/CX"] -->|1"| SDA + SDA -->|Pixel n| SCL["SCL"] + SCL -->|16 bits| LookupTable["Look-up table for 65k color data mapping (16 bits to 18 bits)"] + LookupTable -->|16 bits| SCL + SCL -->|16 bits| FrameMemory["Frame memory"] + FrameMemory -->|18 bits| LookupTable +``` +
+ +Note 1. pixel data with the 16-bit color depth information +Note 2. The most significant bits are: Rx4, Gx5 and Bx4 +Note 3. The least significant bits are: Rx0, Gx0 and Bx0 + +9.8.22 Write Data for 18-bit/Pixel (RGB 6-6-6-bit Input), 262K-Colors, 3AH="06h" +![](images/9b83dbe13662a8b81ba3f56c3e0e4e70c8a6166e80ad3de20d8850a80464b567.jpg) + +
+text_image + +RESX +IM2 +CSX +D/CX +SDA +Pixel n +SCL +Frame memory +18 bits +R1 G1 B1 R2 G2 B2 R3 G3 B3 +
+ +Note 1. pixel data with the 18-bit color depth information +Note 2. The most significant bits are: Rx5, Gx5 and Bx5 +Note 3. The least significant bits are: Rx0, Gx0 and Bx0 + +## 9.9 Display Data RAM + +## 9.9.1 Configuration (GM[1:0] = "00") + +The display module has an integrated 132x162x18-bit graphic type static RAM. This 384,912-bit memory allows storing on-chip a 132xRGBx162 image with an 18-bpp resolution (262K-color). There will be no abnormal visible effect on the display when there is a simultaneous Panel Read and Interface Read or Write to the same location of the Frame Memory. + +![](images/f921d3962620b6f58950dde8cb691ed98ce083e11a9de94fcb1e86f86ce18735.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Host Interface + MCU["MCU I/F"] + LUT["LUT"] + RowCounter["Row address counter"] + ColumnCounter["Column address counter"] + end + + subgraph Display RAM + RAM["Display data RAM (132 x 162 x 18-bits)"] + end + + TF_LCD["TF-LCD panel (132 x RGB x 162)"] + LineCounter["Line address counter"] + ScanCounter["Scan address counter"] + + MCU --> LUT + LUT --> RowCounter + RowCounter --> RAM + ColumnCounter --> RAM + RAM --> TF_LCD + LineCounter --> TF_LCD + TF_LCD --> TF_LCD +``` +
+ +Figure 27 Display Data RAM Organization + +## 9.9.2 Memory to Display Address Mapping + +## 9.9.3 When using 128RGB x 160 resolution (GM[1:0] = "11", SMX=SMY=SRGB= '0') + +![](images/5f13e3cfc873bddef651003d1afd65705966bed42875156246ba5cf00aa7f5a9.jpg) + +Note + +RA = Row Address, + +CA = Column Address + +SA = Scan Address + +MX = Mirror X-axis (Column address direction parameter), D6 parameter of MADCTL command + +MY = Mirror Y-axis (Row address direction parameter), D7 parameter of MADCTL command + +ML = Scan direction parameter, D4 parameter of MADCTL command + +RGB = Red, Green and Blue pixel position change, D3 parameter of MADCTL command + +## 9.9.4 When using 132RGB x 132resolution (GM[1:0] = "01", SMX=SMY=SRGB= '0') + +![](images/af82946873a93f73f23523ce5017b91d626c59d326422452ef3bf0d538ce5b54.jpg) + +Note + +RA = Row Address, + +CA = Column Address + +SA = Scan Address + +MX = Mirror X-axis (Column address direction parameter), D6 parameter of MADCTL command + +MY = Mirror Y-axis (Row address direction parameter), D7 parameter of MADCTL command + +ML = Scan direction parameter, D4 parameter of MADCTL command + +RGB = Red, Green and Blue pixel position change, D3 parameter of MADCTL command + +## 9.9.5 When using 132RGB x 162 resolution (GM[1:0] = "00", SMX=SMY=SRGB= '0') + +![](images/fa468c9e5f38bbfe05b54f4402eb0c06819c2a0b71f0e9cf3eccc80a3b8af474.jpg) + +Note + +RA = Row Address, + +CA = Column Address + +SA = Scan Address + +MX = Mirror X-axis (Column address direction parameter), D6 parameter of MADCTL command + +MY = Mirror Y-axis (Row address direction parameter), D7 parameter of MADCTL command + +ML = Scan direction parameter, D4 parameter of MADCTL command + +RGB = Red, Green and Blue pixel position change, D3 parameter of MADCTL command + +## 9.9.6 Normal Display On or Partial Mode On + +## 9.9.7 When using 128RGB x 160 resolution (GM[1:0] = "11") + +In this mode, the content of the frame memory within an area where column pointer is 00h to 7Fh and page pointer is 00h to 9Fh is displayed. To display a dot on leftmost top corner, store the dot data at (column pointer, row pointer) = (0, 0). + +1). Example for Normal Display On (MX=MY=ML='0', SMX=SMY='0') +![](images/be0cfa071dbae433090fea70b4bc978ebdc1202ac2ab6c185d97e05f679d9ee4.jpg) + +
+heatmap + +| Time Interval | 128 Columns (Frame RAM) | 128 Columns (LCD Panel) | +| :--- | :--- | :--- | +| 00h | 00, 01 | 00, 01, 02, 03 | +| 01h | 10, 11 | 10, 11, 12, 13 | +| 02h | 20, 21 | 20, 21, 22 | +| 03h | 30, 31 | 30, 31, 32 | +| 04h | 40, 41 | 40, 41, 42 | +| 05h | 50, 51 | 50, 51 | +| 06h | 60 | 60 | +| 07h | 70 | 70 | +| 08h | 80 | 80 | +| 09h | 90 | 90 | +| 10h | 100 | 100 | +| 11h | 110 | 110 | +| 12h | 120 | 120 | +| 13h | 130 | 130 | +| 14h | 140 | 140 | +| 15h | 150 | 150 | +| 16h | 160 | 160 | +
+ +2). Example for Partial Display On (PSL[7:0]=04h, PEL[7:0]=9Bh, MX=MV=ML='0', SMX=SMY='0') + +![](images/5a440fbd6fd010d5577a7fa8627e2f7e705ccca4f54a24f557287eaaef55a8ee.jpg) + +
+text_image + +128 Columns +Scan Order +128 Columns +160 Lines +00h 01h ---- ---- 76h 77h ---- 7Fh 83h +00 01 +01h +02h +| 10 11 +| 20 21 +| 30 31 +| 40 41 +| 50 51 +| 60 +| 128 x 160 x18bit +Frame RAM +U0 U1 +V0 V1 +W0 W1 W2 +X0 X1 X2 +Y0 Y1 Y2 Y3 YW YX YY YZ +9Fh Z0 Z1 Z2 Z3 ZW ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX ZX +
+ +## 9.9.8 When using 128RGB x 160 resolution (GM[1:0] = "01") + +In this mode, the content of the frame memory within an area where column pointer is 00h to 83h and page pointer is 00h to 83h is displayed. To display a dot on leftmost top corner, store the dot data at (column pointer, row pointer) = (0, 0). + +1). Example for Normal Display On (MX=MY=ML='0', SMX=SMY='0') + +![](images/f6903cf03ee87b187a51cb2710e51a869d24ec46dd87b847e667d63c0af77d48.jpg) + +
+heatmap + +| Time Interval | Column 00h | Column 01h | Column 02h | Column 03h | Column 0W | Column 0X | Column 0Y | Column 0Z | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 00h | 00 | 01 | 02 | 03 | 0W | 0X | 0Y | 0Z | +| 01h | 10 | 11 | 12 | 13 | 1W | 1X | 1Y | 1Z | +| 02h | 20 | 21 | 22 | 23 | 2X | 2Y | 2Z | 3 | +| 03h | 30 | 31 | 32 | 33 | 3X | 3Y | 3Z | 4 | +| 04h | 40 | 41 | 42 | 43 | 4X | 4Y | 4Z | 5 | +| 05h | 50 | 51 | 52 | 53 | 5Y | 5Z | 6 | 6Z | +| 06h | 60 | 61 | 62 | 63 | 6 | 6 | 6 | 6 | +| 07h | 7 | 7 | 7 | 7 | 7 | 7 | 7 | 7 | +| 08h | S0 | S1 | S2 | S3 | S | SZ | SZ | SZ | +| 09h | U0 | U1 | U2 | U3 | UY | UZ | UY | UZ | +| 10h | V0 | V1 | V2 | V3 | VX | VY | VZ | VZ | +| 11h | W0 | W1 | W2 | W3 | WX | WY | WZ | WZ | +| 12h | X0 | X1 | X2 | X3 | XX | XY | XZ | XZ | +| 13h | Y0 | Y1 | Y2 | Y3 | YW | YX | YZ | YZ | +| 14h | Z0 | Z1 | Z2 | Z3 | ZW | ZX | ZY | ZZ | +| 15h | 130 | 131 | 132 | 132 | 132 | 132 | 132 | 132 | +
+ +2). Example for Partial Display On (PSL[7:0]=00h, PEL[7:0]=83h, MX=MV=ML='0', SMX=SMY='0') + +![](images/3ce39d0c1f7c98353ecbd6cea73f2498f4b99d21f5df16479f88144e8e165680.jpg) + +
+heatmap + +| Row | Column 00h | Column 01h | Column 02 | Column 03 | Column 0W | Column 0X | Column 0Y | Column 82h | Column 83h | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | +| 1 | 00h | 01 | 02 | 03 | 0W | 0X | 0Y | 0Z | 1 | +| 2 | 10 | 11 | 12 | 13 | 1W | 1X | 1Y | 1Z | 2 | +| 3 | 20 | 21 | 22 | — | — | 2X | 2Y | 2Z | 3 | +| 4 | 30 | 31 | 32 | — | — | 3X | 3Y | 3Z | — | +| 5 | 40 | 41 | 42 | — | — | 4X | 4Y | 4Z | — | +| 6 | 50 | 51 | — | — | — | — | 5Y | 5Z | — | +| 7 | 60 | — | — | — | — | — | — | 6Z | — | +| 8 | — | — | — | — | 132 x 132 x18 bit Frame RAM | — | — | — | — | +| 9 | — | — | — | — | — | — | — | — | — | +| 10 | — | — | — | — | — | — | — | — | — | +| 11 | — | — | — | — | — | — | — | — | — | +| 12 | — | — | — | — | — | — | — | — | — | +| 13 | — | — | — | — | — | — | — | — | — | +| 14 | — | — | — | — | — | — | — | — | — | +| 15 | — | — | — | — | — | — | — | — | — | +| 16 | — | — | — | — | — | — | — | — | — | +| 17 | — | — | — | — | — | — | — | — | — | +| 18 | — | — | — | — | — | — | — | — | — | +| 19 | — | — | — | — | — | — | — | — | — | +| 20 | — | — | — | — | — | — | — | — | — | +| 21 | — | — | — | — | — | — | — | — | — | +| 22 | — | — | — | — | — | — | — | — | — | +| 23 | — | — | — | — | — | — | — | — | — | +| 24 | — | — | — | — | — | — | — | — | — | +| 25 | — | — | — | — | — | — | — | — | — | +| 26 | — | — | — | — | — | — | — | — | — | +| 27 | — | — | — | — | — | — | — | — | — | +| 28 | — | — | — | — | — | — | — | — | — | +| 29 | — | — | — | — | — | — | — | — | — | +| 30 | — | — | — | — | — | — | — | — | — | +| 31 | — | — | — | — | — | — | — | — | — | +| 32 | — | — | — | — | — | — | — | — | — | +| 33 | — | — | — | — | — | — | — | — | — | +| 34 | — | — | — | — | — | — | — | — | — | +| 35 | — | — | — | — | — | — | — | — | — | +| 36 | — | — | — | — | — | — | — | — | — | +| 37 | — | — | — | — | — | — | — | — | — | +| 38 | — | — | — | — | — | — | — | — | — | +| 39 | — | — | — | — | — | — | — | — | — | +| 40 | — | — | — | — | — | — | — | — | — | +| 41 | — | — | — | — | — | — | — | — | — | +| 42 | — | — | — | — | — | — | — | — | — | +| 43 | — | — | — | — | — | — | — | — | — | +| 44 | — | — | — | — | — | — | — | — | — | +| 45 | — | — | — | — | — | — | — | — | — | +| 46 | — | — | — | — | — | — | — | — | — | +| 47 | — | — | — | — | — | — | — | — | — | +| 48 | — | — | — | — | — | — | — | — | — | +| 49 | — | — | — | — | — | — | — | — | — | +| 50 | — | — | — | — | — | — | — | — | — | +| 51 | — | — | — | — | — | — | — | — | — | +| 52 | — | — | — | — | — | — | — | — | — | +| 53 | — | — | — | — | — | — | — | — | — | +| 54 | — | — | — | — | — | — | — | — | — | +| 55 | — | — | — | — | — | — | — | — | — | +| 56 | — | — | — | — | — | — | — | — | — | +| 57 | — | — | — | — | — | — | — | — | — | +| 58 | — | — | — | — | — | — | — | — | — | +| 59 | — | — | — | — | — | — | — | — | — | +| 60 | — | — | — | — | — | — | — | — | — | +| 61 | — | — | — | — | — | — | — | — | — | +| 62 | — | — | — | — | — | — | — | — | — | +| 63 | — | — | — | — | — | — | — | — | — | +| 64 | — | — | — | — | — | — | — | — | — | +| 65 | — | — | — | — | — | — | — | — | — | +| 66 | — | — | — | — | — | — | — | — | — | +| 67 | — | — | — | — | — | — | — | — | — | +| 68 | — | — | — | — | — | — | — | — | — | +| 69 | — | — | — | — | — | — | — | — | — | +| 70 | — | — | — | — | — | — | — | — | — | +| 71 | — | — | — | — | — | — | — | — | — | +| 72 | — | — | — | — | — | — | — | — | — | +| 73 | — | — | — | — | — | — | — | — | — | +| 74 | — | — | — | — | — | — | — | — | — | +| 75 | — | — | — | — | — | — | — | — | — | +| 76 | — | — | — | — | — | — | — | — | — | +| 77 | — | — | — | — | — | — | — | — | — | +| 78 | — | — | — | — | — | — | — | — | — | +| 79 | — | — | — | — | — | — | — | — | — | +| 80 | — | — | — | — | — | — | — | — | — | +| 81 | — | — | — | — | — | — | — | — | — | +| 82 | — | — | — | — | — | — | — | — | — | +| 83 | — | — | — | — | — | — | — | — | — | +| 84 | — | — | — | — | — | — | — | — | — | +| 85 | — | — | — | — | — | — | — | — | — | +| 86 | — | — | — | — | — | — | — | — | — | +| 87 | — | — | — | — | — | — | — | — | — | +| 88 | — | — | — | — | — | — | — | — | — | +| 89 | — | — | — | — | — | — | — | — | — | +| 90 | — | — | — | — | — | — | — | — | — | +| 91 | — | — | — | — | — | — | — | — | — | +| 92 | — | — | — | — | — | — | — | — | — | +| 93 | — | — | — | — | — | — | — | — | — | +| 94 | — | — | — | — | — | — | — | — | — | +| 95 | — | — | — | — | — | — | — | — | — | +| 96 | — | — | — | — | — | — | — | — | — | +| 97 | — | — | — | — | — | — | — | — | — | +| 98 | — | — | — | — | — | — | — | — | — | +| 99 | — | — | — | — | — | — | — | — | — | +| 100 | — | — | — | — | — | — | — | — | — | +
+ +## 9.9.9 When using 132RGB x 162 resolution (GM[1:0] = "00") + +In this mode, contents of the frame memory within an area where column pointer is 00h to 83h and page pointer is 00h to A1h is displayed. To display a dot on leftmost top corner, store the dot data at (column pointer, row pointer) = (0, 0) + +1). Example for Normal Display On (MX=MY=ML='0', SMX=SMY='0') + +![](images/bea0d2303b9b8a72d3a437e60d09c4eb103d0764dddb156f244c276cce722037.jpg) + +
+text_image + +132 Columns +Scan Order +132 Columns +162 Lines +00h 01h ---- ---- ---- 81h 83h +00 01 02 03 0W 0X 0Y 0Z +01h 10 11 12 13 1W 1X 1Y 1Z +02h 20 21 22 2X 2Y 2Z +| 30 31 32 3X 3Y 3Z +| 40 41 42 4X 4Y 4Z +| 50 51 5Y 5Z +| 60 61 62 +| 132 x 162 x18 bit +Frame RAM +S0 132RGB x 162 +LCD Panel +U0 U1 132RGB x 162 +UY UZ +S0 132RGB x 162 +UZ 132RGB x 162 +U0 U1 132RGB x 162 +UY UZ +U0 V1 V2 VX VY VZ +V0 V1 V2 VX VY VZ +W0 W1 W2 WX WY WZ +X0 X1 X2 XY XZ XZ +Y0 Y1 Y2 Y3 YW YX YY YZ +Z0 Z1 Z2 Z3 ZW ZX ZY ZZ +162 +160 +161 +162 +G1 +G2 +G3 +G160 +G161 +G162 +Non-Display +area =4 lines +Display area +=155 lines +Non-Display +area =4lines +
+ +2). Example for Partial Display On (PSL[7:0]=04h, PEL[7:0]=9Dh, MX=MV=ML='0', SMX=SMY='0') + +![](images/93dc8d8a847a0329891177e3c05accaa4e426cf78fee9a49b5ebeabcdd2345f3.jpg) + +
+text_image + +132 Columns +Scan Order +132 Columns +162 Lines +00h 01h ---- ---- ---- ---- 81h 83h +00h 01 02 03 0W 0X 0Y 0Z +01h 10 11 12 13 1W 1X 1Y 1Z +02h 20 21 22 23 2X 2Y 2Z +| 30 31 32 33 3X 3Y 3Z +| 40 41 42 43 4X 4Y 4Z +| 50 51 52 53 5Y 5Z +| 60 61 62 63 64 65 66 67 +| 70 71 72 73 74 75 76 77 78 +| 80 81 82 83 84 85 86 87 88 +| 90 91 92 93 94 95 96 97 98 +| 100 11 12 13 14 15 16 17 18 +| 190 191 192 193 194 195 196 197 +| 280 281 282 283 284 285 286 287 288 +| 370 371 372 373 374 375 376 377 378 +| 460 461 462 463 464 465 466 467 468 +| 550 551 552 553 554 555 556 557 558 +| 640 641 642 643 644 645 646 647 648 +| 730 731 732 733 734 735 736 737 738 +| 820 821 822 823 824 825 826 827 828 +| 910 911 912 913 914 915 916 917 918 +| 1000 101 102 103 104 105 106 107 108 +| 110 111 112 113 114 115 116 117 118 +| 120 121 122 123 124 125 126 127 128 +| 130 131 132 133 134 135 136 137 138 +| 140 141 142 143 144 145 146 147 148 +| 150 151 152 153 154 155 156 157 158 +| 160 161 162 163 164 165 166 167 168 +132 RGB x 162 +LCD Panel +Display area=162 lines +G1 +G2 +G3 +G160 +G161 +G162 +
+ +## 9.10 Address Counter + +The address counter sets the addresses of the display data RAM for writing and reading. + +Data is written pixel-wise into the RAM matrix of DRIVER. The data for one pixel or two pixels is collected (RGB 6-6-6-bit), according to the data formats. As soon as this pixel-data information is complete the “Write access” is activated on the RAM. The locations of RAM are addressed by the address pointers. The address ranges are X=0 to X=131 (83h) and Y=0 to Y=161 (A1h). Addresses outside these ranges are not allowed. Before writing to the RAM, a window must be defined that will be written. The window is programmable via the command registers XS, YS designating the start address and XE, YE designating the end address. + +For example the whole display contents will be written, the window is defined by the following values: XS=0 (0h) YS=0 (0h) and XE=127 (83h), YE=161 (A1h). + +In vertical addressing mode (MV=1), the Y-address increments after each byte, after the last Y-address (Y=YE), Y wraps around to YS and X increments to address the next column. In horizontal addressing mode (V=0), the X-address increments after each byte, after the last X-address (X=XE), X wraps around to XS and Y increments to address the next row. After the every last address (X=XE and Y=YE) the address pointers wrap around to address (X=XS and Y=YS). + +For flexibility in handling a wide variety of display architectures, the commands “CASET, RASET and MADCTL” (see section 10 command list), define flags MX and MY, which allows mirroring of the X-address and Y-address. All combinations of flags are allowed. Section 9.10 show the available combinations of writing to the display RAM. When MX, MY and MV will be changed the data bust be rewritten to the display RAM. + +For each image condition, the controls for the column and row counters apply as section 9.11 below + +
ConditionColumn CounterRow Counter
When RAMWR/RAMRD command is acceptedReturn to “Start Column (XS)”Return to “Start Row (YS)”
Complete Pixel Read / Write actionIncrement by 1No change
The Column counter value is larger than “End Column (XE)”Return to “Start Column (XS)”Increment by 1
The Column counter value is larger than “End Column (XE)” and the Row counter value is larger than “End Row (YE)”Return to “Start Column (XS)”Return to “Start Row (YS)”
+ +## 9.11 Memory Data Write/ Read Direction + +The data is written in the order illustrated above. The Counter which dictates where in the physical memory the data is to be written is controlled by “Memory Data Access Control” Command, bits B5 (MV), B6 (MX), B7 (MY) as described below. + +![](images/c72a2509bc2434abb7cad4c4da27c755cefd8b562a289c20da8322da3381bf59.jpg) + +
+flowchart + +```mermaid +graph LR + A["B"] --> B["Panel"] + A --> E["E"] +``` +
+ +Figure 28 Data Streaming order + +9.11.1 When 128RGBx160 (GM= "11") + +
MVMXMYCASETRASET
000Direct to Physical Column PointerDirect to Physical Row Pointer
001Direct to Physical Column PointerDirect to (159-Physical Row Pointer)
010Direct to (127-Physical Column Pointer)Direct to Physical Row Pointer
011Direct to (127-Physical Column Pointer)Direct to (159-Physical Row Pointer)
100Direct to Physical Row PointerDirect to Physical Column Pointer
101Direct to (159-Physical Row Pointer)Direct to Physical Column Pointer
110Direct to Physical Row PointerDirect to (127-Physical Column Pointer)
111Direct to (159-Physical Row Pointer)Direct to (127-Physical Column Pointer)
+ +9.11.2 When 132RGBx132 (GM= "01") + +
MVMXMYCASETRASET
000Direct to Physical Column PointerDirect to Physical Row Pointer
001Direct to Physical Column PointerDirect to (131-Physical Row Pointer)
010Direct to (131-Physical Column Pointer)Direct to Physical Row Pointer
011Direct to (131-Physical Column Pointer)Direct to (131-Physical Row Pointer)
100Direct to Physical Row PointerDirect to Physical Column Pointer
101Direct to (131-Physical Row Pointer)Direct to Physical Column Pointer
110Direct to Physical Row PointerDirect to (131-Physical Column Pointer)
111Direct to (131-Physical Row Pointer)Direct to (131-Physical Column Pointer)
+ +9.11.3 When 132RGBx162 (GM= "00") + +
MVMXMYCASETRASET
000Direct to Physical Column PointerDirect to Physical Row Pointer
001Direct to Physical Column PointerDirect to (161-Physical Row Pointer)
010Direct to (131-Physical Column Pointer)Direct to Physical Row Pointer
011Direct to (131-Physical Column Pointer)Direct to (161-Physical Row Pointer)
100Direct to Physical Row PointerDirect to Physical Column Pointer
101Direct to (161-Physical Row Pointer)Direct to Physical Column Pointer
110Direct to Physical Row PointerDirect to (131-Physical Column Pointer)
111Direct to (161-Physical Row Pointer)Direct to (131-Physical Column Pointer)
+ +Note: Data is always written to the Frame Memory in the same order, regardless of the Memory Write Direction set by MADCTL bits B7 (MY), B6 (MX), B5 (MV). The write order for each pixel unit is + +
D17D16D15D14D13D12D11D10D9D8D7D6D5D4D3D2D1D0
R5R4R3R2R1R0G5G4G3G2G1G0B5B4B3B2B1B0
+ +One pixel unit represents 1 column and 1page counter value on the Frame Memory. + +9.11.4 Frame Data Write Direction According to the MADCTL Parameters (MV, MX and MY) + +
Display Data DirectionMADCTL ParameterImage in the Host (MPU)Image in the Driver (DDRAM)
MVMXMY
Normal000
Y-Mirror001
X-Mirror010
X-Mirror Y-Mirror011
X-Y Exchange100
X-Y Exchange Y-Mirror101
X-Y Exchange X-Mirror110
X-Y ExchangeX-MirrorY-Mirror111
+ +## 9.11.5 Scroll Address Circuit + +The circuit associates lines on DDRAM with Gate output. ST7735S processes signals for the liquid crystal display on 1-line basis. Thus, when specifying a specific area in the area scroll display or partial display, you must designate it in line. + +## 9.11.6 Vertical Scroll Mode + +There is just one types of vertical scrolling, which are determined by the commands “Vertical Scrolling Definition” (33h) and “Vertical Scrolling Start Address” (37h) + +![](images/e07f89371b2213bdde529c28c233f8c9e05c890ad72577a6c9cd2a275fba6fe2.jpg) + +![](images/6afd31835a0e81259f0a898e3992fde040a8982b80ec6e5a1c0bfc5806da2210.jpg) + +
+flowchart + +```mermaid +graph LR + A["TFA"] --> B["VSA"] + B --> C["BFA"] +``` +
+ +Original + +![](images/77fa1021d3a5ab142f152378ca70d8769efc8d3a4b580012c9367393b9730375.jpg) + +
+text_image + +TFA +VSA +BFA +
+ +Rolling scrolling + +When Vertical Scrolling Definition Parameters (TFA+VSA+BFA) =162. In this case, 'rolling' scrolling is applied as shown below. All the memory contents will be used. + +Example 1) Panel size=132(RGB) x 162, TFA =3, VSA=157, BFA=2, SSA=6, MADCTR (ML) =0: Rolling Scroll + +![](images/031053408307e21bdc5aa2215ddc799012c9302943b58ab1d342713e61fac8fd.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph TFA ["TFA"] + A1["00h 00h 01h 02 03 0W 0X 0Y 0Z\n01h 10 11 12 13 1W 1X 1Y 1Z\n02h 20 21 22 2 2X 2Y 2Z\n30 31 32 3X 3Y 3Z\n40 41 42 4X 4Y 4Z\n50 51 52 5Y 5Z\n60 61 62 63 64 65 66 67\n70 71 72 73 74 75 76 77 78\n80 81 82 83 84 85 86 87\n90 91 92 93 94 95 96\n100 110 120 130 140 150 160\n170 180 190 200 210 220 230 240 250 260 270 280 290 300 310 320 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 480 490 500 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 660 670 680 690 700 710 720 730 740 750 760 770 780 790 800 810 820 830 840 850 860 870 880 890 900 910 920 930 940 950 960 970 980 990 1000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 1110 1120 1130 1140 1150 1160 1170 1180 1190 1200 1210 1220 1230 1240 1250 1260 1270 1280 1290 1300 1310 1320 1330 1340 1350 1360 1370 1380 1390 1400 1410 1420 1430 1440 1450 1460 1470 1480 1490 1500 1510 1520 1530 1540 1550 1560 1570 1580 1590 1600 1610 1620 1630 1640 1650 1660 1670 1680 1690 1700 1710 1720 1730 1740 1750 1760 1770 1780 1790 1800 1810 1820 1830 1840 1850 1860 1870 1880 1890 1900 1910 1920 1930 1940 1950 1960 1970 1980 1990 2000 2010 2020 2030 2040 2050 2060 2070 2080 2090 2100 2110 2120 2130 2140 2150 2160 2170 2180 2190 2200 2210 2220 2230 2240 2250 2260 2270 2280 2290 2300 2310 2320 2330 2340 2350 2360 2370 2380 2390 2400 2410 2420 2430 2440 2450 2460 2470 2480 2490 2500 2510 2520 2530 2540 2550 2560 2570 2580 2590 2600 2610 2620 2630 2640 2650 2660 2670 2680 2690 2700 2710 2720 2730 2740 2750 2760 2770 2780 2790 2800 2810 2820 2830 2840 2850 2860 2870 2880 2890 2900 2910 2920 2930 2940 2950 2960 2970 2980 2990 3000 3010 3020 3030 3040 3050 3060 3070 3080 3090 3100 3110 3120 3130 3140 3150 3160 3170 3180 3190 3200 3210 3220 3230 3240 3250 3260 3270 3280 3290 3300 3310 3320 3330 3340 3350 3360 3370 3380 3390 3400 3410 3420 3430 3440 3450 3460 3470 3480 3490 3500 3510 3520 3530 3540 3550 3560 3570 3580 3590 3600 3610 3620 3630 3640 3650 3660 3670 3680 3690 3700 3710 3720 3730 3740 3750 3760 3770 3780 3790 3800 3810 3820 3830 3840 3850 3860 3870 3880 3890 3900 3910 3920 3930 3940 3950 3960 3970 3980 3990 4000 4010 4020 4030 4040 4050 4060 4070 4080 4090 4100 4110 4120 4130 4140 4150 4160 4170 4180 4190 4200 4210 4220 4230 4240 4250 4260 4270 4280 4290 4300 4310 4320 4330 4340 4350 4360 4370 4380 4390 4400 4410 4420 4430 4440 4450 4460 4470 4480 4490 4500 4510 4520 4530 4540 4550 4560 4570 4580 4590 4600 4610 4620 4630 4640 4650 4660 4670 4680 4690 4700 4710 4720 4730 4740 4750 4760 4770 4780 4790 4800 4810 4820 4830 4840 4850 4860 4870 4880 4890 4900 4910 4920 4930 4940 4950 4960 4970 4980 4990 5000 5010 5020 5030 5040 5050 5060 5070 5080 5090 5100 5110 5120 5130 5140 5150 5160 5170 5180 5190 5200 5210 5220 5230 5240 5250 5260 5270 5280 5290 5300 5310 5320 5330 5340 5350 5360 5370 5380 5390 5400 5410 5420 5430 5440 5450 5460 5470 5480 5490 5500 5510 5520 5530 5540 5550 5560 5570 5580 5590 5600 5610 5620 5630 5640 5650 5660 5670 5680 5690 5700 5710 5720 5730 5740 5750 5760 5770 5780 5790 5800 5810 5820 5830 5840 5850 5860 5870 5880 5890 5900 5910 5920 5930 5940 5950 5960 5970 5980 5990 6000 6010 6020 6030 6040 6050 6060 6070 6080 6090 6100 6110 6120 6130 6140 6150 6160 6170 6180 6190 6200 6210 6220 6230 6240 6250 6260 6270 6280 6290 6300 6310 6320 6330 6340 6350 6360 6370 6380 6390 6400 6410 6420 6430 6440 6450 6460 6470 6480 6490 6500 6510 6520 6530 6540 6550 6560 6570 6580 6590 6600 6610 6620 6630 6640 6650 6660 6670 6680 6690 6700 6710 6720 6730 6740 6750 6760 6770 6780 6790 6800 6810 6820 6830 6840 6850 6860 6870 6880 6890 6900 6910 6920 6930 6940 6950 6960 6970 6980 6990 7000 7010 7020 7030 7040 7050 7060 7070 7080 7090 7100 7110 7120 7130 7140 7150 7160 7170 7180 7190 7200 7210 7220 7230 7240 7250 7260 7270 7280 7290 7300 7310 7320 7330 7340 7350 7360 7370 7380 7390 7400 7410 7420 7430 7440 7450 7460 7470 7480 7490 7500 7510 7520 7530 7540 7550 7560 7570 7580 7590 7600 7610 7620 7630 7640 7650 7660 7670 7680 7690 7700 7710 7720 7730 7740 7750 7760 7770 7780 7790 7800 7810 7820 7830 7840 7850 7860 7870 7880 7890 7900 7910 7920 7930 7940 7950 7960 7970 7980 7990 8000 8010 8020 8030 8040 8050 8060 8070 8080 8090 8100 8110 8120 8130 8140 8150 8160 8170 8180 8190 8200 8210 8220 8230 8240 8250 8260 8270 8280 8290 8300 8310 8320 8330 8340 8350 8360 8370 8380 8390 8400 8410 8420 8430 8440 8450 8460 8470 8480 8490 8500 8510 8520 8530 8540 8550 8560 8570 8580 8590 8600 8610 8620 8630 8640 8650 8660 8670 8680 8690 8700 8710 8720 8730 8740 8750 8760 8770 8780 8790 8800 8810 8820 8830 8840 8850 8860 8870 8880 8890 8900 8910 8920 8930 8940 8950 8960 8970 8980 8990 9000 9010 9020 9030 9040 9050 9060 9070 9080 9090 9100 9110 9120 9130 9140 9150 9160 9170 9180 9190 9200 9210 9220 9230 9240 9250 9260 9270 9280 9290 9300 9310 9320 9330 9340 9350 9360 9370 9380 9390 9400 9410 9420 9430 9440 9450 9460 9470 9480 9490 9500 9510 9520 9530 9540 9550 9560 9570 9580 9590 9600 9610 9620 9630 9640 9650 9660 9670 9680 9690 9700 9710 9720 9730 9740 9750 9760 9770 9780 9790 9800 9810 9820 9830 9840 9850 9860 9870 9880 9890 9900 9910 9920 9930 9940 9950 9960 9970 9980 9990 10000 1010 1020 1030 1040 1050 1060 1070 1080 1090 1100 1110 1120 1130 1140 1150 1160 1170 1180 1190 1200 1210 1220 1230 1240 1250 1260 1270 1280 1290 1300 1310 1320 1330 1340 1350 1360 1370 1380 1390 1400 1410 1420 1430 1440 1450 1460 1470 1480 1490 1500 1510 1520 1530 1540 1550 1560 1570 1580 1590 1600 1610 1620 1630 1640 1650 1660 1670 1680 1690 1700 1710 1720 1730 1740 1750 1760 1770 1780 1790 1800 1810 1820 1830 1840 1850 1860 1870 1880 1890 1900 1910 1920 1930 1940 1950 1960 1970 1980 1990 2000 2010 2020 2030 2040 2050 2060 2070 2080 2090 2100 2110 2120 2130 2140 2150 2160 2170 2180 2190 2200 2210 2220 2230 2240 2250 2260 2270 2280 2290 2300 2310 2320 2330 2340 2350 2360 2370 2380 2390 2400 2410 2420 2430 2440 2450 2460 2470 2480 2490 2500 2510 2520 2530 2540 2550 2560 2570 2580 2590 2600 2610 2620 2630 2640 2650 2660 2670 2680 2690 2700 2710 2720 2730 2740 2750 2760 2770 2780 2790 2800 2810 2820 2830 2840 2850 2860 2870 2880 2890 2900 2910 2920 2930 2940 2950 2960 2970 2980 2990 3000 3010 3020 3030 3040 3050 3060 3070 3080 3090 3100 3110 3120 3130 3140 3150 3160 3170 3180 3190 3200 3210 3220 3230 3240 3250 3260 3270 3280 3290 3300 3310 3320 3330 3340 3350 3360 3370 3380 3390 3400 3410 3420 3430 3440 3450 3460 3470 3480 3490 3500 3510 3520 3530 3540 3550 3560 3570 3580 3590 3600 3610 3620 3630 3640 3650 3660 3670 3680 3690 3700 3710 3720 3730 3740 3750 3760 3770 3780 3790 3800 3810 3820 3830 3840 3850 3860 3870 3880 3890 3900 3910 3920 3930 3940 3950 3960 3970 3980 3990 4000 4010 4020 4030 4040 4050 4060 4070 4080 4090 4100 4110 4120 4130 4140 4150 4160 4170 4180 4190 4200 4210 4220 4230 4240 4250 4260 4270 4280 4290 4300 4310 4320 4330 4340 4350 4360 4370 4380 4390 4400 4410 4420 4430 4440 4450 4460 4470 4480 4490 4500 4510 4520 +``` +
+ +Example 2) Panel size=132(RGB) x 162, TFA =3, VSA=157, BFA=2, SSA=6, MADCTR (ML) =1: Rolling Scroll. + +![](images/d9bee2d88bfa8bf34fc0082e00927c86d3355d1bdaa7b3a2eec1f07b5e919c39.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph BFA + A1["00h 00h 01h 02 03 0W 0X 0Y 0Z"] --> B1["G1 161"] + B1 --> C1["G2 160"] + C1 --> D1["G3 159"] + end + + subgraph VSA + E1["00h 01h 02 03 0W 0X 0Y 0Z"] --> F1["U0 U1 U2"] + F1 --> G1["UX UY UZ"] + G1 --> H1["VX VY VZ"] + H1 --> I1["WX WY WZ"] + I1 --> J1["2Y 2Z"] + J1 --> K1["3Z"] + end + + subgraph TFA + L1["00h 01h 02 03 0W 0X 0Y 0Z"] --> M1["U0 U1 U2"] + M1 --> N1["VX VY VZ"] + N1 --> O1["WX WY WZ"] + O1 --> P1["2Y 2Z"] + P1 --> Q1["3Z"] + end + + B1 -.->|SSA| C1 + C1 -.->|SSA| D1["G160 2"] + D1 -.->|SSA| E1 + E1 -.->|SSA| F1 + F1 -.->|SSA| G1 + G1 --> H1["G161 1"] + H1 --> I1["G162 0"] + I1 --> J1["XW ZX ZY ZZ"] +``` +
+ +## 9.11.7 Vertical Scroll Example + +There are 2 types of vertical scrolling, which are determined by the commands “Vertical Scrolling Definition” (33h) and “Vertical Scrolling Start Address” (37h). + +## 9.11.8 Case 1: TFA + VSA + BFA<162 + +N/A. Do not set TFA + VSA + BFA<162. In that case, unexpected picture will be shown. + +## 9.11.9 Case 2: TFA + VSA + BFA=162 (Rolling Scrolling) + +Example 2-a) When MADCTR parameter ML="0", TFA=0, VSA=162, BFA=0 and VSCSAD=40 + +![](images/8c50d8cbc92a37141d9b41fd39abf2e422e2cfd1a1d851c10139f2fe45c329c9.jpg) + +
+flowchart + +```mermaid +graph LR + A["Memory Physical Axis (0,0)"] --> B["Frame Memory"] + C["VSCSAD"] --> B + B --> D["Physical Line Pointer"] + D --> E["Display Axis (0,0)"] + E --> F["Display"] + F --> G["Increment VSCSAD"] + G --> H["Display Axis (0,0)"] + H --> I["Display"] + I --> J["VSCSAD"] +``` +
+ +Example 2-b) When MADCTR parameter ML="1", TFA=10, VSA=152, BFA=0 and VSCSAD=30 +![](images/44cf6749c954eb1253e63cbfa4466b52474f604ced0005e189de44815a57815d.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph FrameMemory + A["Memory Physical Axis (0,0)"] --> B["Frame Memory"] + C["VSCSAD"] --> B + D["TFA"] --> B + end + + subgraph Display + E["Display Axis (0,0)"] --> F["Display"] + G["TFA"] --> F + end + + subgraph Increment + H["Increment VSCSAD"] --> I["Display"] + end + + subgraph FrameMemory + J["Memory Physical Axis (0,0)"] --> K["Frame Memory"] + L["VSCSAD"] --> K + M["TFA"] --> K + end + + subgraph Display + N["Display Axis (0,0)"] --> O["Display"] + P["TFA"] --> O + end +``` +
+ +## 9.12 Tearing Effect Output Line + +The Tearing Effect output line supplies to the MPU a Panel synchronization signal. This signal can be enabled or disabled by the Tearing Effect Line Off & On commands. The mode of the Tearing Effect signal is defined by the parameter of the Tearing Effect Line On command. The signal can be used by the MPU to synchronize Frame Memory Writing when displaying video images. + +## 9.12.1 Tearing Effect Line Modes + +Mode 1, the Tearing Effect Output signal consists of V-Blanking Information only: + +![](images/f91fa9ca08044223b6d8ef2aed881f1f6ccdee2258e0e7dba09f622c5134888e.jpg) + +
+text_image + +Vertical timing scale +T_{vdl} +T_{vdh} +
+ +tvdh= The LCD display is not updated from the Frame Memory + +tvdl= The LCD display is updated from the Frame Memory (except Invisible Line – see above) + +Mode 2, the Tearing Effect Output signal consists of V-Blanking and H-Blanking Information, there is one V-sync and 162 H-sync pulses per field. + +![](images/a1a386e7687349b9c5caa44b88c3e330a890bd61843c7f7cb65b1a538b88db6f.jpg) + +
+text_image + +Vertical timing scale +V-sync +Thdl +Thdh +Invisible +line +1st +line +2nd +line +161th +line +162th +line +V-sync +
+ +thdh= The LCD display is not updated from the Frame Memory + +thdl= The LCD display is updated from the Frame Memory (except Invisible Line – see above) + +![](images/c94c4c2f0296e568e6e80325c32b612b5d76a876def6f869f09be3be28ea5dd1.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Bottom_line ["Bottom line"] + A["Start"] --> B["Step Up"] + B --> C["End"] + end + + subgraph Top_line ["Top line"] + D["Start"] --> E["Step Up"] + E --> F["Step Down"] + F --> G["End"] + end + + subgraph sg_2nd_line_2nd_line["2nd_line [\"2nd line\"]"] + H["Start"] --> I["Start"] + I --> J["Step Up"] + J --> K["End"] + end + + subgraph TE Mode 2 ["TE mode 2"] + L["Start"] --> M["Step Up"] + M --> N["End"] + N --> O["End"] + end + + subgraph TE Mode 1 ["TE mode 1"] + P["Start"] --> Q["End"] + Q --> R["End"] + end + + T["T_vdh"] -.->|Timing| R +``` +
+ +Note: During Sleep In Mode, the Tearing Output Pin is active Low. + +## 9.12.2 Tearing Effect Line Timings + +The Tearing Effect signal is described below: + +![](images/9bfa8f42b501b04215c4b7c5492693ee3d32c56c4f4a300b93d22348d62e5d5e.jpg) + +
+text_image + +Tvdl +Tvdh +Vertical +Horizontal +Thdl +Thdh +
+ +
SymbolParameterminmaxunitdescription
tvdlVertical Timing Low Duration13-ms
tvdhVertical Timing High Duration1000-μs
thdlHorizontal Timing Low Duration33-μs
thdhHorizontal Timing Low Duration25500μs
+ +Table 13 AC characteristics of Tearing Effect Signal Idle Mode Off (Frame Rate = 60 Hz, Ta=25℃) +Note: The timings in Table 9.10.1 apply when MADCTL ML=0 and ML=1 + +The signal's rise and fall times (tf, tr) are stipulated to be equal to or less than 15ns. + +![](images/5b56aa842b54c5085a6e836a9983086d8848b41c6b121c1ac933eed589e37c01.jpg) + +The Tearing Effect Output Line is fed back to the MPU and should be used as shown below to avoid Tearing Effect: + +9.12.3 Example 1: MPU Write is faster than panel read +![](images/0596bf0aaf4bfcc15078c64e242a1c1d22e97377e6acb1faa38bde567677b3a2.jpg) + +
+flowchart + +This diagram illustrates the signal processing workflow for a microcontroller (MCU) to memory, showing the timing of the TE output signal and memory to LCD over time. +
+ +Data write to Frame Memory is now synchronized to the Panel Scan. It should be written during the vertical sync pulse of the Tearing Effect Output Line. This ensures that data is always written ahead of the panel scan and each Panel Frame refresh has a complete new image: + +Data to be sent + +![](images/c96e6f1c0ca62c97332a6185f229495f9fca7466c4f39cf3c40f5354b8318e58.jpg) + +
+text_image + +B +
+ +Image on LCD + +a +![](images/67c239f52c1a769e26a9c9c12924d6e58ba602bb62d344a67129eac048a92dc0.jpg) + +
+text_image + +A +
+ +b +![](images/3708b6529913f0554749536bd8945f375caffbed1dce3e764ef160ee77a4d1d8.jpg) + +
+text_image + +R +
+ +C +![](images/dd7f58d34684fb17ca31d478e3d7f035a20356e3d52e26304206a0f2653c45a1.jpg) + +
+text_image + +B +
+ +d +![](images/81520bd3f508b5e2865cf10aa43a309db69bb327bab34eabbae65720fe04abf3.jpg) + +
+text_image + +B +
+ +9.12.4 Example 2: MPU Write is slower than panel read +![](images/c9510e9eb6133f51773b9a30b4dcc65eb9bd6a077c43a65c7cabc28eba9bdb99.jpg) + +
+state_timeline + +| Signal | Start | End | +| --- | --- | --- | +| MCU to memory | 1st | 162nd | +| TE output signal | 1st | 162nd | +| Memory to LCD | 1st | 162nd | +
+ +The MPU to Frame Memory write begins just after Panel Read has commenced i.e. after one horizontal sync pulse of the Tearing Effect Output Line. This allows time for the image to download behind the Panel Read pointer and finishing download during the subsequent Frame before the Read Pointer “catches” the MPU to Frame memory write position. + +Data to be sent + +![](images/8116b81d52bbb2b2c5a6cb651f2dd217fe5501c5c42b27b5478af8288afce72c.jpg) + +
+text_image + +B +
+ +Image on LCD + +![](images/24161721d436cfe171a9fba7bd56e204572d3bfb5d4a90ad74bc70328e1243ad.jpg) + +## 9.13 Power ON/OFF Sequence + +VDDI and VDD can be applied in any order + +VDD and VDDI can be powered down in any order + +During power off, if LCD is in the Sleep Out mode, VDD and VDDI must be powered down minimum 120msec after RESX has been released. + +During power off, if LCD is in the Sleep In mode, VDDI or VDD can be powered down minimum 0msec after RESX has been released. + +CSX can be applied at any timing or can be permanently grounded. RESX has priority over CSX. + +Note 1: There will be no damage to the display module if the power sequences are not met. +Note 2: There will be no abnormal visible effects on the display panel during the Power On/Off Sequences. +Note 3: There will be no abnormal visible effects on the display between end of Power On Sequence and before receiving Sleep Out command. Also between receiving Sleep In command and Power Off Sequence. +Note 4: If RESX line is not held stable by host during Power On Sequence as defined in the sequence below, then it will be necessary to apply a Hardware Reset (RESX) after Host Power On Sequence is complete to ensure correct operation. Otherwise function is not guaranteed. + +The power on/off sequence is illustrated below +![](images/0d3a396d6c9bf75ce814d6ba1cf43f3ab63dbd229b40d4dfe4e9f73262687c34.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph VDD + VDD1["VDDI"] -->|Timing when the latter signal rises up to 90% of its typical value. e.g. When VDD comes later, this timing is defined at the cross point of 90% of 2.75V, not 90% of 2.6V| VDD1 + end + subgraph CSX + CSX["CSX"] -->|H or L| VDD1 + CSX -->|H or L| CSX + CSX -->|H or L| RESX + end + subgraph RESX + RESX["RESX"] -->|Power down in sleep-out mode| RESX + RESX -->|Power down in sleep-in mode| RESX + end + VDD1 -.->|TrPW = +/- no limit| CSX + CSX -.->|TrPW-CSX = +/- no limit| CSX + CSX -.->|TrPW-RESX = + no limit| RESX + RESX -.->|TrPW-RESX = + no limit| RESX + RESX -.->|TrPW-RESX1 = min 120ms| CSX + RESX -.->|TrPW-RESX = + no limit| CSX + CSX -.->|TfpW-CSX = +/- no limit| CSX + CSX -.->|TfpW-RESX2 = min 0ms| RESX +``` +
+ +## 9.13.1 Uncontrolled Power Off + +The uncontrolled power-off means a situation which removed a battery without the controlled power off sequence. It will neither damage the module or the host interface. + +If uncontrolled power-off happened, the display will go blank and there will not any visible effect on the display (blank display) and remains blank until “Power On Sequence” powers it up. + +## 9.14 Power Level Definition + +## 9.14.1 Power Level + +6 level modes are defined they are in order of Maximum Power consumption to Minimum Power Consumption + +1. Normal Mode On (full display), Idle Mode Off, Sleep Out. +In this mode, the display is able to show maximum 262,144 colors. + +2. Partial Mode On, Idle Mode Off, Sleep Out. + +In this mode part of the display is used with maximum 262,144 colors. + +3. Normal Mode On (full display), Idle Mode On, Sleep Out. + +In this mode, the full display area is used but with 8 colors. + +4. Partial Mode On, Idle Mode On, Sleep Out. + +In this mode, part of the display is used but with 8 colors. + +5. Sleep In Mode + +In this mode, the DC: DC converter, internal oscillator and panel driver circuit are stopped. Only the MCU interface and memory works with VDDI power supply. Contents of the memory are safe. + +6. Power Off Mode + +In this mode, both VDD and VDDI are removed. + +Note: Transition between modes 1-5 is controllable by MCU commands. Mode 6 is entered only when both Power supplies are removed. + +9.14.2 Power Flow Chart +![](images/62b4f9625a098d79897da82768e49b616a98d45021467752eb9f6ed748883c1b.jpg) + +
+flowchart + +This flowchart illustrates the sleep states and power flow of a sleep-on sequence system, showing transitions between normal and partial display modes on idle modes. +
+ +## 9.15 Reset Table + +## 9.15.1 Reset Table(Default Value, GM[1:0]="11", 128RGB x 160) + +
ItemAfter Power OnAfter H/W ResetAfter S/W Reset
Frame MemoryRandomNo ChangeNo Change
Sleep In/OutInInIn
Display On/OffOffOffOff
Display Mode (Normal/Partial)NormalNormalNormal
Display Inversion On/OffOffOffOff
Display Idle Mode On/OffOffOffOff
Column: Start Address (XS)0000h0000h0000h
Column: End Address (XE)007Fh007Fh007Fh (127d) (when MV=0)009Fh (159d) (when MV=1)
Row: Start Address (YS)0000h0000h0000h
Row: End Address (YE)009Fh009Fh009Fh (159d) (when MV=0)007Fh (127d) (when MV=1)
Gamma settingGC0GC0GC0
RGB for 4k and 65k Color ModeRandom valuesRandom valuesNo Change
Partial: Start Address (PSL)0000h0000h0000h
Partial: End Address (PEL)009Fh009Fh009Fh
Scroll: Top Fixed Area (TFA)0000h0000h0000h
Scroll: Scroll Area (VSA)00A0h00A0h00A0h
Scroll: Bottom Fixed Area (BFA)0000h0000h0000h
Scroll Start Address (SSA)0000h0000h0000h
Tearing: On/OffOffOffOff
Tearing Effect Mode (*1)0 (Mode1)0 (Mode1)0 (Mode1)
Memory Data Access Control (MY/MX/MV/ML/RGB)0/0/0/0/00/0/0/0/0No Change
Interface Pixel Color Format6 (18-Bit/Pixel)6 (18-Bit/Pixel)No Change
RDDPM08h08h08h
RDDMADCTL00h00hNo Change
RDDCOLMOD6 (18-Bit/Pixel)6 (18-Bit/Pixel)No Change
RDDIM00h00h00h
RDDSM00h00h00h
ID2NV valueNV valueNV value
ID3NV valueNV valueNV value
+ +Note: TE Mode 1 means Tearing Effect Output Line consists of V-Blanking Information only + +9.15.2 Reset Table (GM[1:0]="01", 132RGB x 132) + +
ItemAfter Power OnAfter H/W ResetAfter S/W Reset
Frame memoryRandomNo ChangeNo Change
Sleep In/OutInInIn
Display On/OffOffOffOff
Display Mode (Normal/Partial)NormalNormalNormal
Display Inversion On/OffOffOffOff
Display Idle Mode On/OffOffOffOff
Column: Start Address (XS)0000h0000h0000h
Column: End Address (XE)0083h0083h0083h (131d) (when MV=0)0083h (131d) (when MV=1)
Row: Start Address (YS)0000h0000h0000h
Row: End Address (YE)0083h0083h0083h (131d) (when MV=0)0083h (131d) (when MV=1)
Gamma SettingGC0GC0GC0
RGB for 4k and 65k Color ModeSee Section 9.17See Section 9.17No Change
Partial: Start Address (PSL)0000h0000h0000h
Partial: End Address (PEL)0083h0083h0083h
Tearing: On/OffOffOffOff
Scroll: Top Fixed Area (TFA)0000h0000h0000h
Scroll: Scroll Area (VSA)0084h0084h0084h
Scroll: Bottom Fixed Area (BFA)0000h0000h0000h
Scroll Start Address (SSA)0000h0000h0000h
Tearing Effect Mode (*1)0 (Mode1)0 (Mode1)0 (Mode1)
Memory Data Access Control (MY/MX/MV/ML/RGB)0/0/0/0/00/0/0/0/0No Change
Interface Pixel Color Format6 (18-Bit/Pixel)6 (18-Bit/Pixel)No Change
RDDPM08h08h08h
RDDMADCTL00h00hNo Change
RDDCOLMOD6 (18-Bit/Pixel)6 (18-Bit/Pixel)No Change
RDDIM00h00h00h
RDDSM00h00h00h
ID2NV valueNV valueNV value
ID3NV valueNV valueNV value
+ +Note: TE Mode 1 means Tearing Effect Output Line consists of V-Blanking Information only + +9.15.3 Reset Table (GM[1:0]="00", 132RGB x 162) + +
ItemAfter Power OnAfter H/W ResetAfter S/W Reset
Frame memoryRandomNo ChangeNo Change
Sleep In/OutInInIn
Display On/OffOffOffOff
Display mode (normal/partial)NormalNormalNormal
Display Inversion On/OffOffOffOff
Display Idle Mode On/OffOffOffOff
Column: Start Address (XS)0000h0000h0000h
Column: End Address (XE)0083h0083h0083h (131d) (when MV=0)00A1h (161d) (when MV=1)
Row: Start Address (YS)0000h0000h0000h
Row: End Address (YE)00A1h00A1h00A1h (161d) (when MV=0)0083h (131d) (when MV=1)
Gamma settingGC0GC0GC0
RGB for 4k and 65k Color ModeRandom valuesRandom valuesNo Change
Partial: Start Address (PSL)0000h0000h0000h
Partial: End Address (PEL)00A2h00A2h00A2h
Scroll: Top Fixed Area (TFA)0000h0000h0000h
Scroll: Scroll Area (VSA)0084h0084h0084h
Scroll: Bottom Fixed Area (BFA)0000h0000h0000h
Scroll Start Address (SSA)0000h0000h0000h
Tearing: On/OffOffOffOff
Tearing Effect Mode (*1)0 (Mode1)0 (Mode1)0 (Mode1)
Memory Data Access Control (MY/MX/MV/ML/RGB)0/0/0/0/00/0/0/0/0No Change
Interface Pixel Color Format6 (18-Bit/Pixel)6 (18-Bit/Pixel)No Change
RDDPM08h08h08h
RDDMADCTL00h00hNo Change
RDDCOLMOD6 (18-Bit/Pixel)6 (18-Bit/Pixel)No Change
RDDIM00h00h00h
RDDSM00h00h00h
ID2NV valueNV valueNV value
ID3NV valueNV valueNV value
+ +Note: TE Mode 1 means Tearing Effect Output Line consists of V-Blanking Information only + +## 9.16 Module Input/Output Pins + +## 9.16.1 Output or Bi-directional (I/O) Pins + +
Output or Bi-directional pinsAfter Power OnAfter Hardware ResetAfter Software Reset
TELowLowLow
D7 to D0 (Output driver)High-Z (Inactive)High-Z (Inactive)High-Z (Inactive)
+ +
Input pinsDuring Power On ProcessAfter Power OnAfter Hardware ResetAfter Software ResetDuring Power Off Process
RESXSee 9.14Input validInput validInput validSee 9.14
CSXInput invalidInput validInput validInput validInput invalid
D/CXInput invalidInput validInput validInput validInput invalid
WRXInput invalidInput validInput validInput validInput invalid
RDXInput invalidInput validInput validInput validInput invalid
D7 to D0Input invalidInput validInput validInput validInput invalid
+ +Note: There will be no output from D7-D0 during Power On/Off sequence, Hardware Reset and Software Reset. + +## 9.17 Reset Timing + +![](images/169e0ee32c3b9a01acbd5103c6c912e6cfa6176d104a984143e6937711b69932.jpg) + +
+flowchart + +```mermaid +graph LR + A["RESX"] -->|Shorter than 5us| B["Normal operation"] + B --> C["Resetting"] + C --> D["Initial condition\n(Default for HW reset)"] + C -->|T_RESW| E["RESX"] + C -->|T_REST| F["Initial condition\n(Default for HW reset)"] +``` +
+ +
Related PinsSymbolParameterMINMAXUnit
RESXtRESWReset Pulse Duration10-us
tRESTReset Cancel-5ms
120ms
+ +Table 14 Reset Timing + +## Notes: + +1. The reset cancel includes also required time for loading ID bytes, VCOM setting and other settings from NVM (or similar device) to registers. This loading is done every time when there is HW reset cancel time (tRT) within 5 ms after a rising edge of RESX. +2. Spike due to an electrostatic discharge on RESX line does not cause irregular system reset according to the table below: + +
RESX PulseAction
Shorter than 5usReset Rejected
Longer than 9usReset
Between 5us and 9usReset Starts
+ +3. During the Resetting period, the display will be blanked (The display is entering blanking sequence, which maximum time is 120 ms, when Reset Starts in Sleep Out –mode. The display remains the blank state in Sleep In -mode.) and then return to Default condition for Hardware Reset. +4. Spike Rejection also applies during a valid reset pulse as shown below: + +![](images/266158f78fecef8d496f371350f16eb8103c870efb50a9e9c96dd98c9a4359cf.jpg) + +
+text_image + +10μs +Reset is accepted +10μs +20ns +Less than 20ns width positive spike will be rejected. +
+ +5. When Reset applied during Sleep In Mode. +6. When Reset applied during Sleep Out Mode. +7. It is necessary to wait 5msec after releasing RESX before sending commands. Also Sleep Out command cannot be sent for 120msec. + +## 9.18 Color Depth Conversion Look Up Tables + +9.18.1 65536 Color to 262,144 Color + +
ColorLook Up Table OutputFrame Memory Data (6-bits)RGBSET ParameterLook Up Table Input Data
65k Color (5-bits)
REDR005 R004 R003 R002 R001 R000100000
R015 R014 R013 R012 R011 R010200001
R025 R024 R023 R022 R021 R020300010
R035 R034 R033 R032 R031 R030400011
R045 R044 R043 R042 R041 R040500100
R055 R054 R053 R052 R051 R050600101
R065 R064 R063 R062 R061 R060700110
R075 R074 R073 R072 R071 R070800111
R085 R084 R083 R082 R081 R080901000
R095 R094 R093 R092 R091 R0901001001
R105 R104 R103 R102 R101 R1001101010
R115 R114 R113 R112 R111 R1101201011
R125 R124 R123 R122 R121 R1201301100
R135 R134 R133 R132 R131 R1301401101
R145 R144 R143 R142 R141 R1401501110
R155 R154 R153 R152 R151 R1501601111
R165 R164 R163 R162 R161 R1601710000
R175 R174 R173 R172 R171 R1701810001
R185 R184 R183 R182 R181 R1801910010
R195 R194 R193 R192 R191 R1902010011
R205 R204 R203 R202 R201 R2002110100
R215 R214 R213 R212 R211 R2102210101
R225 R224 R223 R222 R221 R2202310110
R235 R234 R233 R232 R231 R2302410111
R245 R244 R243 R242 R241 R2402511000
R255 R254 R253 R252 R251 R2502611001
R265 R264 R263 R262 R261 R2602711010
R275 R274 R273 R272 R271 R2702811011
R285 R284 R283 R282 R281 R2802911100
R295 R294 R293 R292 R291 R2903011101
R305 R304 R303 R302 R301 R3003111110
R315 R314 R313 R312 R311 R3103211111
GREENG005 G004 G003 G002 G001 G00033000000
G015 G014 G013 G012 G011 G01034000001
G025 G024 G023 G022 G021 G02035000010
G035 G034 G033 G032 G031 G03036000011
G045 G044 G043 G042 G041 G04037000100
G055 G054 G053 G052 G051 G05038000101
G065 G064 G063 G062 G061 G06039000110
G075 G074 G073 G072 G071 G07040000111
G085 G084 G083 G082 G081 G08041001000
G095 G094 G093 G092 G091 G09042001001
G105 G104 G103 G102 G101 G10043001010
G115 G114 G113 G112 G111 G11044001011
G125 G124 G123 G122 G121 G12045001100
G135 G134 G133 G132 G131 G13046001101
G145 G144 G143 G142 G141 G14047001110
G155 G154 G153 G152 G151 G15048001111
G165 G164 G163 G162 G161 G16049010000
G175 G174 G173 G172 G171 G17050010001
G185 G184 G183 G182 G181 G18051010010
G195 G194 G193 G192 G191 G19052010011
G205 G204 G203 G202 G201 G20053010100
G215 G214 G213 G212 G211 G21054010101
G225 G224 G223 G222 G221 G22055010110
G235 G234 G233 G232 G231 G23056010111
G245 G244 G243 G242 G241 G24057011000
G255 G254 G253 G252 G251 G25058011001
G265 G264 G263 G262 G261 G26059011010
G275 G 274 G273 G272 G271 G27060011011
G285 G 284 G283 G282 G281 G28061011100
G295 G 294 G293 G292 G291 G29062011101
G305 G 304 G303 G302 G301 G30063011110
G315 G 314 G313 G312 G311 G31064011111
G325 G324 G323 G322 G321 G32065100000
G335 G334 G333 G332 G331 G33066100001
G345 G344 G343 G342 G341 G34067100010
G355 G354 G353 G352 G351 G35068100011
G365 G364 G363 G362 G361 G36069100100
G375 G374 G373 G372 G371 G37070100101
G385 G384 G383 G382 G381 G38071100110
G395 G394 G393 G392 G391 G39072100111
G405 G404 G403 G402 G401 G40073101000
G415 G414 G413 G412 G411 G41074101001
G425 G424 G423 G422 G421 G42075101010
G435 G434 G433 G432 G431 G43076101011
G445 G444 G443 G442 G441 G44077101100
G455 G454 G453 G452 G451 G45078101101
G465 G464 G463 G462 G461 G46079101110
G475 G474 G473 G472 G471 G47080101111
G485 G484 G483 G482 G481 G48081110000
G495 G494 G493 G492 G491 G49082110001
G505 G504 G503 G502 G501 G50083110010
G515 G514 G513 G512 G511 G51084110011
G525 G524 G523 G522 G521 G52085110100
G535 G534 G533 G532 G531 G53086110101
G545 G544 G543 G542 G541 G54087110110
G555 G554 G553 G552 G551 G55088110111
G565 G564 G563 G562 G561 G56089111000
G575 G574 G573 G572 G571 G57090111001
G585 G584 G583 G582 G581 G58091111010
G595 G594 G593 G592 G591 G59092111011
G605 G604 G603 G602 G601 G60093111100
G615 G614 G613 G612 G611 G61094111101
G625 G624 G623 G622 G621 G62095111110
G635 G634 G633 G632 G631 G63096111111
+ +
ColorLook Up Table OutputFrame Memory Data (6-bits)RGBSET ParameterLook Up Table Input Data
65k Color (5-bits)
BLUEB005 B004 B003 B002 B001 B0009700000
B015 B014 B013 B012 B011 B0109800001
B025 B024 B023 B022 B021 B0209900010
B035 B034 B033 B032 B031 B03010000011
B045 B044 B043 B042 B041 B04010100100
B055 B054 B053 B052 B051 B05010200101
B065 B064 B063 B062 B061 B06010300110
B075 B074 B073 B072 B071 B07010400111
B085 B084 B083 B082 B081 B08010501000
B095 B094 B093 B092 B091 B09010601001
B105 B104 B103 B102 B101 B10010701010
B115 B114 B113 B112 B111 B11010801011
B125 B124 B123 B122 B121 B12010901100
B135 B134 B133 B132 B131 B13011001101
B145 B144 B143 B142 B141 B14011101110
B155 B154 B153 B152 B151 B15011201111
B165 B164 B163 B162 B161 B16011310000
B175 B174 B173 B172 B171 B17011410001
B185 B184 B183 B182 B181 B18011510010
B195 B194 B193 B192 B191 B19011610011
B205 B204 B203 B202 B201 B20011710100
B215 B214 B213 B212 B211 B21011810101
B225 B224 B223 B222 B221 B22011910110
B235 B234 B233 B232 B231 B23012010111
B245 B244 B243 B242 B241 B24012111000
B255 B254 B253 B252 B251 B25012211001
B265 B264 B263 B262 B261 B26012311010
B275 B274 B273 B272 B271 B27012411011
B285 B284 B283 B282 B281 B28012511100
B295 B294 B293 B292 B291 B29012611101
B305 B304 B303 B302 B301 B30012711110
B315 B314 B313 B312 B311 B31012811111
+ +9.18.2 4096 Color to 262,144 Color + +
ColorLook Up Table OutputFrame Memory Data (6-bits)RGBSET ParameterLook Up Table Input Data
4k Color (4-bits)
REDR005 R004 R003 R002 R001 R00010000
R015 R014 R013 R012 R011 R01020001
R025 R024 R023 R022 R021 R02030010
R035 R034 R033 R032 R031 R03040011
R045 R044 R043 R042 R041 R04050100
R055 R054 R053 R052 R051 R05060101
R065 R064 R063 R062 R061 R06070110
R075 R074 R073 R072 R071 R07080111
R085 R084 R083 R082 R081 R08091000
R095 R094 R093 R092 R091 R090101001
R105 R104 R103 R102 R101 R100111010
R115 R114 R113 R112 R111 R110121011
R125 R124 R123 R122 R121 R120131100
R135 R134 R133 R132 R131 R130141101
R145 R144 R143 R142 R141 R140151110
R155 R154 R153 R152 R151 R150161111
R165 R164 R163 R162 R161 R16017Not used
||
R315 R314 R313 R312 R311 R31032
GREENG005 G004 G003 G002 G001 G000330000
G015 G014 G013 G012 G011 G010340001
G025 G024 G023 G022 G021 G020350010
G035 G034 G033 G032 G031 G030360011
G045 G044 G043 G042 G041 G040370100
G055 G054 G053 G052 G051 G050380101
G065 G064 G063 G062 G061 G060390110
G075 G074 G073 G072 G071 G070400111
G085 G084 G083 G082 G081 G080411000
G095 G094 G093 G092 G091 G090421001
G105 G104 G103 G102 G101 G100431010
G115 G114 G113 G112 G111 G110441011
G125 G124 G123 G122 G121 G120451100
G135 G134 G133 G132 G131 G130461101
G145 G144 G143 G142 G141 G140471110
G155 G154 G153 G152 G151 G150481111
G165 G164 G163 G162 G161 G16049Not used
||
G635 G634 G633 G632 G631 G63096
BLUEB005 B004 B003 B002 B001 B000970000
B015 B014 B013 B012 B011 B010980001
B025 B024 B023 B022 B021 B020990010
B035 B034 B033 B032 B031 B0301000011
B045 B044 B043 B042 B041 B0401010100
B055 B054 B053 B052 B051 B0501020101
B065 B064 B063 B062 B061 B0601030110
B075 B074 B073 B072 B071 B0701040111
B085 B084 B083 B082 B081 B0801051000
B095 B094 B093 B092 B091 B0901061001
B105 B104 B103 B102 B101 B1001071010
B115 B114 B113 B112 B111 B1101081011
B125 B124 B123 B122 B121 B1201091100
B135 B134 B133 B132 B131 B1301101101
B145 B144 B143 B142 B141 B1401111110
B155 B154 B153 B152 B151 B1501121111
B165 B164 B163 B162 B161 B160113Not used
||
B315 B314 B313 B312 B311 B310128
+ +## 9.19 Sleep Out-Command and Self-Diagnostic Functions of the Display Module + +## 9.19.1 Register Loading Detection + +Sleep Out-command (See section 0 “Sleep Out (11h)”) is a trigger for an internal function of the display module, which indicates, if the display module loading function of factory default values from MTP (or similar device) to registers of the display controller is working properly. + +There are compared factory values of the MTP and register values of the display controller by the display controller. If those both values (MTP and register values) are same, there is inverted (=increased by 1) a bit, which is defined in command 0 “Read Display Self-Diagnostic Result (0Fh)” (=RDDSDR) (The used bit of this command is D7). If those both values are not same, this bit (D7) is not inverted (= increased by 1). + +The flow chart for this internal function is following: + +![](images/1ba165dfb393dd895abfafb6dd98328e7f4e1fd6014d1eb041273487ccce74c5.jpg) + +
+flowchart + +```mermaid +graph TD + A["Sleep in (10h)"] --> B["Sleep out mode"] + C["Power on sequence\nHW reset\nSW reset"] --> D["RDDSDR's D7=0"] + B --> E["Sleep out (11h)"] + D --> E + E --> F["Compares MTP and register values"] + F --> G{"Are MTP and register values same?"} + G -->|No| H["Loading values from MTP to registers"] + H --> B + G -->|Yes| I["D7 inverted"] + I --> H +``` +
+ +Note: There is not compared and loaded register values, which can be changed by user (00h to AFh and DAh to DDh), by the display module. + +## 9.19.2 Functionality Detection + +Sleep Out-command (See section 0 “Sleep Out (11h)”) is a trigger for an internal function of the display module, which indicates, if the display module is still running and meets functionality requirements. + +The internal function (= the display controller) is comparing, if the display module is still meeting functionality requirements (only Booster voltage level). If functionality requirement is met, there is inverted (= increased by 1) a bit, which defined in command 0 “Read Display Self- Diagnostic Result (0Fh)” (= RDDSDR) (The used bit of this command is D6). If functionality requirement is not same, this bit (D6) is not inverted (= increased by 1). The flow chart for this internal function is following: + +![](images/819f0e8da11f4a348899e5219b58949c1f080500e3276b69228226fc24c1d67b.jpg) + +
+flowchart + +```mermaid +graph TD + A["Sleep in (10h)"] --> B["Sleep out mode"] + A --> C["Sleep in mode"] + B --> D["Sleep out (11h)"] + C --> D + D --> E["Checks Booster voltage levels and other functionalities"] + E --> F{"Is functionality requirement met?"} + F -->|No| G["D6 inverted"] + F -->|Yes| G + H["Power on sequence\nHW reset\nSW reset"] --> I["RDDSDR's D6=0"] + G --> I +``` +
+ +Note: There is needed 120msec after Sleep Out -command, when there is changing from Sleep In -mode to Sleep Out -mode, before there is possible to check if functionality requirements are met and a value of RDDSDR's D6 is valid. Otherwise, there is 5msec delay for D6's value, when Sleep Out -command is sent in Sleep Out -mode. + +## 9.19.3 Chip Attachment Detection (Optional) + +Sleep Out-command (See section 0 “Sleep Out (11h)”) is a trigger for an internal function of the display module, which indicates, if a chip or chips (e.g. driver, etc.) of the display module is/are attached to the circuit route of a flex foil or display glass ITO. + +There is inverted (= increased by 1) a bit, which is defined in command 0 “Read Display Self- Diagnostic Result (0Fh)” (= RDDSDR) (The used bit of this command is D5), if the chip or chips is/are attached to the circuit route of the flex or display glass. If this chip is or those chips are not attached to the circuit route of the flex or display glass, this bit (D5) is not inverted (= increased by 1). + +The following figure is for reference purposes; how this chip attachment can be implemented e.g. there are connected together 2 bumps via route of ITO or the flex foil on 4 corners of the driver (chip). + +![](images/224298e921bb4184201d7232299b4a987ea9a181bbc15446b4d397d7f1ce7f75.jpg) + +
+flowchart + +```mermaid +graph LR + A["Routing Between Bumps"] --> B["Through view of driver to bumps"] + B --> C["Routing Between Bumps"] + C --> D["Substrate or flex foil"] +``` +
+ +The flow chart for this internal function is following: + +![](images/a09069b9e94e1eb1cc63702dd67f5365db2a61d6bdee611803fc42c626696989.jpg) + +
+flowchart + +```mermaid +graph TD + A["Sleep In (10h)"] --> B["Sleep Out Mode"] + C["Power on sequence\nHW reset\nSW reset"] --> D["RDDSDR D5=0"] + B --> E["Sleep Out (11h)"] + D --> E + E --> F["Check, if chip is attached to route"] + F --> G{"Is chip attached to Routes ?"} + G -->|No| B + G -->|Yes| H["D5 inverted"] + H --> I[" +``` +
+ +## 9.19.4 Display Glass Break Detection (Optional) + +Sleep Out-command (See section 0 “Sleep Out (11h)”) is a trigger for an internal function of the display module, which indicates, if the display glass of the display module is broken or not. + +There is inverted (= increased by 1) a bit, which is defined in command 0 “Read Display Self-Diagnostic Result (0Fh)” (= RDDSDR) (The used bit of this command is D4), if the display glass is not broken. If this display glass is broken, this bit (D4) is not inverted (= increased by 1). + +The following figure is a reference, how this glass break detection can be implemented e.g. there is connected together 2 bumps via route of ITO. This route of ITO is the nearest route of the edge of the display glass. + +![](images/a6ccf5248850ab9232f1ee6a627cd5d5e9b413c3d9f48146d8ec580bf2d8e46a.jpg) + +The flow chart for this internal function is following: + +![](images/ff65a24c67799893c730fd652ccdfd9211a6c65f86fad9f483c2577802c176c3.jpg) + +
+flowchart + +```mermaid +graph TD + A["Sleep In (10h)"] --> B["Sleep Out Mode"] + C["Power on sequence\nHW reset\nSW reset"] --> D["RDDSDR D4=0"] + B --> E["Sleep Out (11h)"] + D --> E + E --> F["Check, if display glass is broken"] + F --> G{"Is the display glass Broken ?"} + G -->|Yes| B + G -->|No| H["D4 inverted"] + H --> I[" +``` +
+ +## 10 COMMAND + +## 10.1 System Function Command List and Description + +Table 15 System Function Command List (1) + +
InstructionReferD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HexFunction
NOP001-00000000(00h)No Operation
SWRESET001-00000001(01h)Software Reset
RDDID001-00000100(04h)Read Display ID
11---------Dummy Read
11-ID17ID16ID15ID14ID13ID12ID11ID10ID1 Read
11-1ID26ID25ID24ID23ID22ID21ID20ID2 Read
11-ID37ID36ID35ID34ID33ID32ID31ID30ID3 Read
RDDST001-00001001(09h)Read Display Status
11---------Dummy Read
11-BSTONMYMXMVMLRGBMHST24-
11-ST23IFPF2IFPF1IFPF0IDMONPTLONSLOUTNORON-
11-VSSONST14INVONST12ST11DISONTEONGCS2-
11-GCS1GCS0TEMST4ST3ST2ST1ST0-
RDDPM001-00001010(0Ah)Read Display Power Mode
11---------Dummy Read
11-BSTONIDMONPTLONSLPOUTNORONDISON---
RDD MADCTL001-00001011(0Bh)Read Display MADCTL
11---------Dummy Read
11-MYMXMVMLRGBMH---
RDD COLMOD001-00001100(0Ch)Read Display Pixel Format
11---------Dummy Read
11-0000-IFPF2IFPF1IFPF0-
RDDIM001-00001101(0Dh)Read Display Image Mode
11---------Dummy Read
11-VSSOND6INVON--GCS2GCS1GCS0-
RDDSM001-00001110(0Eh)Read Display Signal Mode
11---------Dummy Read
11-TEONTEM-------
RDDSDR001-00001111(0Fh)Read Display Self-diagnostic result
11---------Dummy Read
11-RELDFUNDATTDBRD-----
+ +“-”: Don't care + +Table 16 System Function Command List (2) + +
InstructionReferD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HexFunction
SLPIN001-00010000(10h)Sleep In & Booster Off
SLPOUT001-00010001(11h)Sleep Out & Booster On
PTLON001-00010010(12h)Partial Mode On
NORON001-00010011(13h)Partial Off (Normal)
INVOFF001-00100000(20h)Display Inversion Off (Normal)
INVON001-00100001(21h)Display Inversion On
GAMSET001-00100110(26h)Gamma Curve Select
11-----GC3GC2GC1GC0-
DISPOFF001-00101000(28h)Display Off
DISPON001-00101001(29h)Display On
CASET001-00101010(2Ah)Column Address Set
11-XS15XS14XS13XS12XS11XS10XS9XS8X Address Start: 0≤XS≤X
11-XS7XS6XS5XS4XS3XS2XS1XS0
11-XE15XE14XE13XE12XE11XE10XE9XE8X Address End: S≤XE≤X
11-XE7XE6XE5XE4XE3XE2XE1XE0
RASET001-00101011(2Bh)Row Address Set
11-YS15YS14YS13YS12YS11YS10YS9YS8Y Address Start: 0≤YS≤Y
11-YS7YS6YS5YS4YS3YS2YS1YS0
11-YE15YE14YE13YE12YE11YE10YE9YE8Y Address End:S≤YE≤Y
11-YE7YE6YE5YE4YE3YE2YE1YE0
RAMWR001-00101100(2Ch)Memory Write
11-D7D6D5D4D3D2D1D0Write Data
RGBSET001-00101101(2Dh)LUT for 4k,65k,262k Color display
11---R005R004R003R002R001R000Red Tone 0
11---:::::::
11---Ra5Ra4Ra3Ra2Ra1Ra0Red Tone “a”
11---G005G004G003G002G001G000Green Tone 0
11---:::::::
11---Gb5Gb4Gb3Gb2Gb1Gb0Green Tone “b”
11---B005B004B003B002B001B000Blue Tone 0
11---:::::::
11---Bc5Bc4Bc3Bc2Bc1Bc0Blue Tone “c”
RAMRD001-00101110(2Eh)Memory Read
11---------Dummy Read
11-D7D6D5D4D3D2D1D0Read Data
+ +“-”: Don't care + +Table 17 System Function command List (3) + +
InstructionReferD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HexFunction
PTLAR10.1.2501-00110000(30h)Partial Start/End Address Set
11-PSL15PSL14PSL13PSL12PSL11PSL10PSL9PSL8Partial Start Address (0,1,2,..P)
11-PSL7PSL6PSL5PSL4PSL3PSL2PSL1PSL0
11-PEL15PEL14PEL13PEL12PEL11PEL10PEL9PEL8Partial End Address (0,1,2,..,P)
11-PEL7PEL6PEL5PEL4PEL3PEL2PEL1PEL0
SCRLAR10.1.2601-00110011(33h)Scroll area set
11---------Top fixed area (0,1,2,..,161)
11-TFA7TFA6TFA5TFA4TFA3TFA2TFA1TFA0
11---------Vertical scroll area (0,1,2,..,161)
11-VSA7VSA6VSA5VSA4VSA3VSA2VSA1VSA0
11---------Bottom fixed area (0,1,2,..,161)
11-BFA7BFA6BFA5BFA4BFA3BFA2BFA1BFA0
TEOFF10.1.2701-00110100(34h)Tearing effect line off
TEON10.1.2801-00110101(35h)Tearing Effect Mode Set & on
11--------TEMMode1: TEM="0" Mode2: TEM="1"
MADCTL10.1.2901-00110110(36h)Memory Data Access Control
11-MYMXMVMLRGBMH---
VSCSAD10.1.3001-00110111(37h)Scroll Start Address of RAM
111--------SSA=0,1,2,...,161
111-SSA7SSA6SSA5SSA4SSA3SSA2SSA1SSA0
IDMOFF10.1.3101-00111000(38h)Idle Mode Off
IDMON10.1.3201-00111001(39h)Idle Mode On
COLMOD10.1.3301-00111010(3Ah)Interface Pixel Format
11------IFPF2IFPF1IFPF0Interface Format
RDID110.1.3401-11011010(DAh)Read ID1
11---------Dummy Read
11-ID17ID16ID15ID14ID13ID12ID11ID10Read Parameter
RDID210.1.3501-11011011(DBh)Read ID2
11---------Dummy Read
11-1ID26ID25ID24ID23ID22ID21ID20Read Parameter
RDID310.1.3601-11011100(DCh)Read ID3
11---------Dummy Read
11-ID37ID36ID35ID34ID33ID32ID31ID30Read Parameter
+ +“-”: Don't care +Note 1: After the H/W reset by RESX pin or S/W reset by SWRESET command, each internal register becomes default state (Refer "RESET TABLE" section) +Note 2: Undefined commands are treated as NOP (00 h) command. +Note 3: B0 to D9 and DA to F are for factory use of driver supplier. +Note 4: Commands 10h, 12h, 13h, 20h, 21h, 26h, 28h, 29h, 30h, 33h, 36h (ML parameter only), 37h, 38h and 39h are updated during V-sync when Module is in Sleep Out Mode to avoid abnormal visual effects. During Sleep In mode, these commands are updated immediately. Read status (09h), Read Display Power Mode (0Ah), Read Display MADCTL (0Bh), Read Display Pixel Format (0Ch), Read Display Image Mode (0Dh), Read Display Signal Mode (0Eh). + +10.1.1 NOP (00h) + +
00HNOP (No Operation)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
NOP01-00000000(00h)
ParameterNo Parameter-
DescriptionThis command is empty command.
+ +“-” Don’t care + +10.1.2 SWRESET (01h): Software Reset + +
01HSWRESET (Software Reset)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
SWRESET01-00000001(01h)
ParameterNo Parameter-
Description“-” Don’t care-If Software Reset is applied during Sleep In mode, it will be necessary to wait 120msec before sending next command.-The display module loads all default values to the registers during 120msec.-If Software Reset is applied during Sleep Out or Display On Mode, it will be necessary to wait 120msec before sending next command.
Flow Chart
+ +10.1.3 RDDID (04h): Read Display ID + +
04HRDDID (Read Display ID)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDID01-00000100(04h)
$1^{st}$ Parameter11----------
$2^{nd}$ Parameter11-ID17ID16ID15ID14ID13ID12ID11ID10
$3^{rd}$ Parameter11-1ID26ID25ID24ID23ID22ID21ID20
$4^{th}$ Parameter11-ID37ID36ID35ID34ID33ID32ID31ID30
Description-This read byte returns 24-bit display identification information.-The 1st parameter is dummy data-The 2nd parameter (ID17 to ID10): LCD module's manufacturer ID.-The 3rd parameter (ID26 to ID20): LCD module/driver version ID-The 4th parameter (ID37 to UD30): LCD module/driver ID.-Commands RDID1/2/3(DAh, DBh, DCh) read data correspond to the parameters 2,3,4 of the command 04h, respectively."-" Don't care
DefaultStatusDefault Value
ID1ID2ID3
Power On Sequence0x7CNV ValueNV Value
S/W Reset0x7CNV ValueNV Value
H/W Reset0x7CNV ValueNV Value
Flow Chart
+ +10.1.4 RDDST (09h): Read Display Status + +
09HRDDST (Read Display Status)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDST01-00001001(09h)
$1^{st}$ Parameter11----------
$2^{nd}$ Parameter11-BSTONMYMXMVMLRGBMHST24
$3^{rd}$ Parameter11-ST23IFPF2IFPF1IFPF0IDMONPTLONSLOUTNORON
$4^{th}$ Parameter11-ST15ST14INVONST12ST11DISONTEONGCS2
$5^{th}$ Parameter11-GCS1GCS0TEMST4ST3ST2ST1ST0
DescriptionThis command indicates the current status of the display as described in the table below:
BitDescriptionValue
BSTONBooster Voltage Status‘1’ =Booster on,‘0’ =Booster off
MYRow Address Order (MY)‘1’ =Decrement, (Bottom to Top, when MADCTL (36h) D7='1')‘0’ =Increment, (Top to Bottom, when MADCTL (36h) D7='0')
MXColumn Address Order (MX)‘1’ =Decrement, (Right to Left, when MADCTL (36h) D6='1')‘0’ =Increment, (Left to Right, when MADCTL (36h) D6='1')
MVRow/Column Exchange (MV)‘1’ = Row/column exchange, (when MADCTL (36h) D5='1')‘0’ = Normal, (when MADCTL (36h) D5='0')
MLScan Address Order (ML)‘0’ =Decrement,(LCD refresh Top to Bottom, when MADCTL (36h) D4='0')‘1’=Increment,(LCD refresh Bottom to Top, when MADCTL (36h) D4='1')
RGBRGB/ BGR Order (RGB)‘1’ =BGR, (When MADCTL (36h) D3='1')‘0’ =RGB, (When MADCTL (36h) D3='0')
MHHorizontal Order‘0’ =Decrement,(LCD refresh Left to Right, when MADCTL (36h) D2='0')‘1’ =Increment,(LCD refresh Right to Left, when MADCTL (36h) D2='1')
ST24For Future Use‘0'
ST23For Future Use‘0'
IFPF2Interface Color Pixel Format Definition“011” = 12-bit / pixel,“101” = 16-bit / pixel,“110” = 18-bit / pixel, others are no define
IFPF1
IFPF0
IDMONIdle Mode On/Off‘1’ = On, “0” = Off
PTLONPartial Mode‘1’ = On, “0” = Off
SLPOUTSleep In/Out‘1’ = Out, “0” = In
NORONDisplay Normal Mode On/Off‘1’ = Normal Display,‘0’ = Partial Display
ST15Vertical Scrolling‘1’ = Scroll on, “0” = Scroll off
ST14Horizontal Scroll‘0'
INVONInversion Status‘1’ = On, “0” = Off
ST12All Pixels On (Not‘0'
ST11All Pixels Off (Not‘0'
DISONDisplay On/Off‘1’ = On, “0” = Off
TEONTearing effect line‘1’ = On, “0” = Off
GCSEL2Gamma Curve Selection“000” = GC0“001” = GC1“010” = GC2“011” = GC3
GCSEL1
GCSEL0
TEMTearing effect line‘0’ = mode1, ‘1’ = mode2
ST4For Future Use‘0’
ST3For Future Use‘0’
ST2For Future Use‘0’
ST1For Future Use‘0’
ST0For Future Use‘0’
“-” Don’t care
Default
StatusDefault Value (ST31 to ST0)
ST[31-24]ST[23-16]ST[15-8]ST[7-0]
Power On Sequence0000-00000110-00010000-00000000-0000
S/W Reset0xxx0xx000xxx-00010000-00000000-0000
H/W Reset0000-00000110-00010000-00000000-0000
Flow Chart
+ +10.1.5 RDDPM (0Ah): Read Display Power Mode + +
0AHRDDPM (Read Display Power Mode)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDPM01-00001010(0Ah)
$1^{st}$ Parameter11----------
$2^{nd}$ Parameter11BSTONIDMONPTLONSLPOUTNORONDISOND1D0
DescriptionThis command indicates the current status of the display as described in the table below:“-“ Don’t care
BitDescriptionValue
BSTONBooster Voltage Status‘1’ =Booster on,‘0’ =Booster off
IDMONIdle Mode On/Off‘1’ = Idle Mode On,‘0’ = Idle Mode Off
PTLONPartial Mode On/Off‘1’ = Partial Mode On,‘0’ = Partial Mode Off
SLPONSleep In/Out‘1’ = Sleep Out,‘0’ = Sleep In
NORONDisplay Normal Mode On/Off‘1’ = Normal Display,‘0’ = Partial Display
DISONDisplay On/Off‘1’ = Display On,‘0’ = Display Off
D1Not Used‘0’
D0Not Used‘0’
Default
StatusDefault Value (D7 to D0)
Power On Sequence0000_1000(08h)
S/W Reset0000_1000(08h)
H/W Reset0000_1000(08h)
Flow Chart
+ +10.1.6 RDDMADCTL (0Bh): Read Display MADCTL + +
0BHRDDMADCTL (Read Display MADCTL)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDMADCTL01-00001011(0Bh)
$1^{st}$ Parameter11----------
$2^{nd}$ Parameter11MYMXMVMLRGBMHD1D0
DescriptionThis command indicates the current status of the display as described in the table below:“-” Don’t care
BitDescriptionValue
MXColumn Address Order‘1’ = Right to Left (When MADCTL B6=‘1’)‘0’ = Left to Right (When MADCTL B6=‘0’)
MYRow Address Order‘1’ = Bottom to Top (When MADCTL B7=‘1’)‘0’ = Top to Bottom (When MADCTL B7=‘0’)
MVRow/Column Order (MV)‘1’ = Row/column exchange (MV=1)‘0’ = Normal (MV=0)
MLVertical Refresh Order‘1’ =LCD Refresh Bottom to Top‘0’ =LCD Refresh Top to Bottom
RGBRGB/BGR Order‘1’ =BGR, “0”=RGB
MHHorizontal Refresh OrderLCD horizontal refresh direction control‘0’ = LCD horizontal refresh Left to right‘1’ = LCD horizontal refresh right to left
D1Not Used‘0’
D0Not Used‘0’
Default
StatusDefault Value (D7 to D0)
Power On Sequence0000_0000 (00h)
S/W ResetNo change
H/W Reset0000_0000 (00h)
Flow Charte l :
+ +10.1.7 RDDCOLMOD (0Ch): Read Display Pixel Format + +
0CHRDDCOLMOD (Read Display Pixel Format)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDCOLMOD01-00001100(0Ch)
1stParameter11----------
2ndParameter11-0000-IFPF2IFPF1IFPF0
DescriptionThis command indicates the current status of the display as described in the table below:
IFPF[2:0]MCU Interface Color Format
01112-bit/pixel
10116-bit/pixel
11018-bit/pixel
111No used
Others are no define and invalid“-” Don’t care
Default
StatusDefault Value
IFPF[2:0]
Power On Sequence0110 (18 bits/pixel)
S/W ResetNo Change
H/W Reset0110 (18 bits/pixel)
Flow Chart
+ +10.1.8 RDDIM (0Dh): Read Display Image Mode + +
0DHRDDIM (0Dh): Read Display Image Mode
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDIM01-00001101(0Dh)
$1^{st}$ Parameter11----------
$2^{nd}$ Parameter11-VSSOND6INVOND4D3GCS2GCS1GCS0
DescriptionThis command indicates the current status of the display as described in the table below:“-“ Don’t care
BitDescriptionValue
VSSONReversed“0”
D6Reversed“0”
INVONInversion On/Off“1” = Inversion is On,“0” = Inversion is Off
D4All Pixels On“0” (Not used)
D3All Pixels Off“0” (Not used)
GCS2GCS1GCS0Gamma CurveSelection“000” = GC0,“001” = GC1,“010” = GC2,“011” = GC3, "100” to “111” = Not defined
Default
StatusDefault Value(D7 to D0)
Power On Sequence0000_0000 (00h)
S/W Reset0000_0000 (00h)
H/W Reset0000_0000 (00h)
Flow Chart
+ +10.1.9 RDDSM (0Eh): Read Display Signal Mode + +
0EHRDDSM (0Eh): Read Display Signal Mode
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDSM01-00001110(0Eh)
$1^{st}$ Parameter11----------
$2^{nd}$ Parameter11-TEONTEMD5D4D3D2D1D0
DescriptionThis command indicates the current status of the display as described in the table below:“-” Don’t care
BitDescriptionValue
TEONTearing Effect Line On/Off“1” = On,“0” = Off
TEMTearing effect line mode“1” = Mode2,“0” = Mode1
D5Not Used“1” = On,“0” = Off
D4Not Used“1” = On,“0” = Off
D3Not Used“1” = On,“0” = Off
D2Not Used“1” = On,“0” = Off
D1Not Used“1” = On,“0” = Off
D0Not Used“1” = On,“0” = Off
Default
StatusDefault Value(D7~D0)
Power On Sequence0000_0000 (00h)
S/W Reset0000_0000 (00h)
H/W Reset0000_0000 (00h)
+ +
Flow Chart
+ +10.1.10 RDDSDR (0Fh): Read Display Self-Diagnostic Result + +
0FHRDDSDR (0Fh): Read Display Self-Diagnostic Result
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDDSDR01-00001111(0Fh)
1stParameter11----------
2ndParameter11-RELDFUNDATTDBRDD3D2D1D0
DescriptionThis command indicates the current status of the display as described in the table below:“-” Don’t care
BitDescriptionValue
RELDRegister Loading DetectionSee Section 9.19.1
FUNDFunctionality DetectionSee Section 9.19.2
ATTDChip Attachment DetectionSee Section 9.19.3
BRDDisplay Glass Break DetectionSee Section 9.19.4
D3Not Used“0”
D2Not Used“0”
D1Not Used“0”
D0Not Used“0”
DefaultStatusDefault Value(D7~D0)
Power On Sequence0000_0000 (00h)
S/W Reset0000_0000 (00h)
H/W Reset0000_0000 (00h)
Flow Chart
+ +
BitDescriptionValue
RELDRegister Loading DetectionSee Section 9.19.1
FUNDFunctionality DetectionSee Section 9.19.2
ATTDChip Attachment DetectionSee Section 9.19.3
BRDDisplay Glass Break DetectionSee Section 9.19.4
D3Not Used“0”
D2Not Used“0”
D1Not Used“0”
D0Not Used“0”
+ +
StatusDefault Value(D7~D0)
Power On Sequence0000_0000 (00h)
S/W Reset0000_0000 (00h)
H/W Reset0000_0000 (00h)
+ +10.1.11 SLPIN (10h): Sleep In + +
10HSLPIN (Sleep In)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
SLPIN01-00010000(10h)
ParameterNo Parameter-
Description-This command causes the LCD module to enter the minimum power consumption mode.-In this mode the DC/DC converter is stopped, Internal display oscillator is stopped, and panel scanning is stopped.
Restriction-This command has no effect when module is already in Sleep In mode. Sleep In Mode can only be exit by the Sleep Out Command (11h).-When IC is in Sleep Out or Display On mode, it is necessary to wait 120msec before sending next command because of the stabilization timing for the supply voltages and clock circuits.
Default
StatusDefault Value
Power On SequenceSleep In Mode
S/W ResetSleep In Mode
H/W ResetSleep in Mode
Flow Chart
+ +10.1.12 SLPOUT (11h): Sleep Out + +
11HSLPOUT (Sleep Out)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
SLPOUT01-00010001(11h)
ParameterNo Parameter-
Description-This command turns off sleep mode.-In this mode the DC/DC converter is enabled, Internal display oscillator is started, and panel scanning is started.
Restriction-This command has no effect when module is already in sleep out mode. Sleep Out Mode can only be exit by the Sleep In Command (10h).-When IC is in Sleep In mode, it is necessary to wait 120msec before sending next command because of the stabilization timing for the supply voltages and clock circuits.-When IC is in Sleep Out or Display On mode, it is necessary to wait 120msec before sending next command due to the download of default value of registers and the execution of self-diagnostic function.
Default
StatusDefault Value
Power On SequenceSleep In Mode
S/W ResetSleep In Mode
H/W ResetSleep in Mode
Flow Chart[IMAGE]
+ +10.1.13 PTLON (12h): Partial Display Mode On + +
12HPTLON (12h): Partial Display Mode On
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
PTLON01-00010010(12h)
ParameterNo Parameter-
Description-This command turns on Partial mode. The partial mode window is described by the Partial Area command (30h)-To leave Partial mode, the Normal Display Mode On command (13h) should be written."-" Don't care
DefaultStatusDefault Value
Power On SequenceNormal Mode On
S/W ResetNormal Mode On
H/W ResetNormal Mode On
Flow ChartSee Partial Area (30h)
+ +10.1.14 NORON (13h): Normal Display Mode On + +
13HNORON (Normal Display Mode On)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
NORON01-00010011(13h)
ParameterNo Parameter-
Description-This command returns the display to normal mode.-Normal display mode on means Partial mode off.-Exit from NORON by the Partial mode On command (12h)"-" Don't care
DefaultStatusDefault Value
Power On SequenceNormal Mode On
S/W ResetNormal Mode On
H/W ResetNormal Mode On
Flow ChartSee Partial Area Definition Descriptions for details of when to use this command
+ +10.1.15 INVOFF (20h): Display Inversion Off + +
20HIVNOFF (Normal Display Mode Off)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
INVOFF01-00100000(20h)
ParameterNo Parameter-
Description-This command is used to recover from display inversion mode. +"- " Don't care +(Example) +
DefaultStatusDefault Value
Power On SequenceDisplay Inversion off
S/W ResetDisplay Inversion off
H/W ResetDisplay Inversion off
Flow Chart
+ +10.1.16 INVON (21h): Display Inversion On + +
21HIVNOFF (Display Inversion On)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
INVON01-00100001(21h)
ParameterNo Parameter-
Description-This command is used to enter into display inversion mode-To exit from Display Inversion On, the Display Inversion Off command (20h) should be written."-" Don't care (Example)Top-Left (0,0) Memory Display
DefaultStatusDefault Value
Power On SequenceDisplay Inversion off
S/W ResetDisplay Inversion off
H/W ResetDisplay Inversion off
Flow ChartLegendCommandParameterDisplayActionModeSequential transter
+ +10.1.17 GAMSET (26h): Gamma Set + +
26HGAMSET (Gamma Set)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
GAMSET01-00100110(26h)
Parameter11-----GC3GC2GC1GC0
Description-This command is used to select the desired Gamma curve for the current display. A maximum of 4 curves can be selected. The curve is selected by setting the appropriate bit in the parameter as described in the Table.
GC [7:0]ParameterCurve Selected
GS=1GS=0
01hGC0Gamma Curve 1 (G2.2)Gamma Curve 1 (G1.0)
02hGC1Gamma Curve 2 (G1.8)Gamma Curve 2 (G2.5)
04hGC2Gamma Curve 3 (G2.5)Gamma Curve 3 (G2.2)
08hGC3Gamma Curve 4 (G1.0)Gamma Curve 4 (G1.8)
Note: All other values are undefined.
DefaultStatusDefault Value
Power On Sequence01h
S/W Reset01h
H/W Reset01h
Flow Chart
+ +10.1.18 DISPOFF (28h): Display Off + +
28HDISPOFF (Display Off)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
DISPOFF01-00101000(28h)
ParameterNo Parameter-
Description- This command is used to enter into DISPLAY OFF mode. In this mode, the output from Frame Memory is disabled and blank page inserted. +- This command makes no change of contents of frame memory. +- This command does not change any other status. +- There will be no abnormal visible effect on the display. +- Exit from this command by Display On (29h)
DefaultStatusDefault Value
Power On SequenceDisplay off
S/W ResetDisplay off
H/W ResetDisplay off
Flow Chart
+ +10.1.19 DISPON (29h): Display On + +
29HDISPON (Display On)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
DISPON01-00101001(29h)
ParameterNo Parameter-
Description- This command is used to recover from DISPLAY OFF mode. +- Output from the Frame Memory is enabled. +- This command makes no change of contents of frame memory. +- This command does not change any other status. +
DefaultStatusDefault Value
Power On SequenceDisplay off
S/W ResetDisplay off
H/W ResetDisplay off
Flow Chart
+ +10.1.20 CASET (2Ah): Column Address Set + +
2AHCASET(Column Address Set)_
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
CASET(2Ah)01-00101010(2Ah)
$1^{st}$ Parameter11-XS15XS14XS13XS12XS11XS10XS9XS8
$2^{nd}$ Parameter11-XS7XS6XS5XS4XS3XS2XS1XS0
$3^{rd}$ Parameter11-XE15XE14XE13XE12XE11XE10XE9XE8
$4^{th}$ Parameter11-XE7XE6XE5XE4XE3XE2XE1XE0
Description-The value of XS [7:0] and XE [7:0] are referred when RAMWR command comes.-Each value represents one column line in the Frame Memory.
RestrictionXS [15:0] always must be equal to or less than XE [15:0]When XS [15:0] or XE [15:0] is greater than maximum address like below, data of out of range will be ignored.1. 128X160 memory base (GM = '11')(Parameter range: 0 < XS [15:0] < XE [15:0] < 127 (007Fh)): MV="0")(Parameter range: 0 < XS [15:0] < XE [15:0] < 159 (009Fh)): MV="1")2. 132X132 memory base (GM = '01')(Parameter range: 0 < XS [15:0] < XE [15:0] < 131 (0083h)): MV="0")(Parameter range: 0 < XS [15:0] < XE [15:0] < 131 (0083h)): MV="1")3. 132X162 memory base (GM = '00')(Parameter range: 0 < XS [15:0] < XE [15:0] < 131 (0083h)): MV="0")(Parameter range: 0 < XS [15:0] < XE [15:0] < 161 (00A1h)): MV="1")
Default
GM StatusStatusDefault Value
XS [7:0]XE [7:0] (MV='0')XE [7:0] (MV='1')
GM='11'(128x160 Memory Base)Power On Sequence0000h007Fh (127)
S/W Reset0000h007Fh (127)009Fh (159)
H/W Reset0000h007Fh (127)
GM='01'(132x132 Memory Base)Power On Sequence0000h0083h (131)
S/W Reset0000h0083h (131)0083h (131)
H/W Reset0000h0083h (131)
GM='00'(132x162 Memory Base)Power On Sequence0000h0083h (131)
S/W Reset0000h0083h (131)00A1h (161)
H/W Reset0000h0083h (131)
Flow Chart
+ +10.1.21 RASET (2Bh): Row Address Set + +
2BHRASET (Row Address Set)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RASET (2Bh)01-00101011(2Bh)
$1^{st}$ Parameter11-YS15YS14YS13YS12YS11YS10YS9YS8
$2^{nd}$ Parameter11-YS7YS6YS5YS4YS3YS2YS1YS0
$3^{rd}$ Parameter11-YE15YE14YE13YE12YE11YE10YE9YE8
$4^{th}$ Parameter11-YE7YE6YE5YE4YE3YE2YE1YE0
DescriptionThe value of YS [7:0] and YE [7:0] are referred when RAMWR command comes.Each value represents one column line in the Frame Memory.
RestrictionYS [15:0] always must be equal to or less than YE [15:0]When YS [15:0] or YE [15:0] are greater than maximum row address like below, data of out of range will be ignored.1. 128X160 memory base (GM = '11')(Parameter range: 0 < YS [15:0] < YE [15:0] < 159 (009Fh)): MV="0"(Parameter range: 0 < YS [15:0] < YE [15:0] < 127 (007Fh)): MV="1"2. 132X132 memory base (GM = '00')(Parameter range: 0 < YS [15:0] < YE [15:0] < 131 (00A1h)): MV="0"(Parameter range: 0 < YS [15:0] < YE [15:0] < 131 (0083h)): MV="1"3. 132X162 memory base (GM = '00')(Parameter range: 0 < YS [15:0] < YE [15:0] < 161 (00A1h)): MV="0"(Parameter range: 0 < YS [15:0] < YE [15:0] < 131 (0083h)): MV="1"
Default
GM statusStatusDefault Value
YS [15:0]YE [15:0] (MV='0')YE [15:0] (MV='1')
GM='11' (128x160 memory base)Power On Sequence0000h009Fh (159)
S/W Reset0000h009Fh (159)007Fh (127)
H/W Reset0000h009Fh (159)
GM='01' (132x132 Memory Base)Power On Sequence0000h0083h (131)
S/W Reset0000h0083h (131)0083h (131)
H/W Reset0000h0083h (131)
GM='00' (132x162 memory base)Power On Sequence0000h00A1h (161)
S/W Reset0000h00A1h (161)0083h (131)
H/W Reset0000h00A1h (161)
Flow Chart
+ +10.1.22 RAMWR (2Ch): Memory Write + +
2CHRAMWR (Memory Write)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RAMWR01-00101100(2Ch)
1st Parameter11D17-8D7D6D5D4D3D2D1D0
|11|||||||||
Nth Parameter11D17-8D7D6D5D4D3D2D1D0
DescriptionIn all color modes, there is no restriction on length of parameters.1. 128X160 memory base (GM = '11')128x160x18-bit memory can be written by this commandMemory range: (0000h, 0000h) -> (007Fh, 09Fh)2. 132x132 memory base (GM = '01')132x132x18-bit memory can be written on this command.Memory range: (0000h, 0000h) -> (0083h, 0083h)3. 132x162 memory base (GM = '00')132x162x18-bit memory can be written on this command.Memory range: (0000h, 0000h) -> (0083h, 00A1h)
DefaultStatusDefault Value
Power On SequenceContents of memory is set randomly
S/W ResetContents of memory is not cleared
H/W ResetContents of memory is not cleared
Flow Chart
+ +10.1.23 RGBSET (2Dh): Color Setting for 4K, 65K and 262K + +
2DHRGBSET (Color Set for 4K, 65K, 262K and 16.7M)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RGBSET01-00101101(2Dh)
1st Parameter11---R005R004R003R002R001R000
|11---Rnn5Rnn4Rnn3Rnn2Rnn1Rnn0
|11---R315R314R313R312R311R310
|11---G005G004G003G002G001G000
|11---Gnn5Gnn4Gnn3Gnn2Gnn1Gnn0
|11---G635G634G633G632G631G630
|11---B005B004B003B002B001B000
|11---Bnn5Bnn4Bnn3Bnn2Bnn1Bnn0
128th Parameter11---B315B314B313B312B311B310
DescriptionThis command is used to define the LUT for 12bits-to-16bits / 16-bit-to- 18bits color depth conversations.128-Bytes must be written to the LUT regardless of the color mode. Only the values in Section 9.18 are referred.In this condition, 4K-color (4-4-4) and 65K-color(5-6-5) data input are transferred 6(R)-6(G)-6(B) through RGB LUT table.This command has no effect on other commands/parameters and Contents of frame memory.Visible change takes effect next time the Frame Memory is written to.Do not send any command before the last data is sent or LUT is not defined correctly.
DefaultStatusDefault Value
Power On SequenceRandom
S/W ResetContents of the look-up table protected
LUTR
Flow Chart
+ +10.1.24 RAMRD (2Eh): Memory Read + +
2EHRAMHD (Memory Read)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RAMHD01-00101110(2Eh)
$1^{st}$ Parameter11---------
$2^{nd}$ Parameter11D17-8D7D6D5D4D3D2D1D0
|11|||||||||
(N+1)th Parameter11D17-8D7D6D5D4D3D2D1D0
Description-This command is used to transfer data from frame memory to MCU.-When this command is accepted, the column register and the row register are reset to the Start Column/Start Row positions.-The Start Column/Start Row positions are different in accordance with MADCTL setting.-Then D[17:0] is read back from the frame memory and the column register and the row register incremented as section 9.10-Frame Read can be cancelled by sending any other command.-The data color coding is fixed to 18-bit in reading function. Please see section 9.8 "Data color coding" for color coding (18-bit cases), when there is used 8, 9, 16 and 18-bit data lines for image data.Note1: The Command 3Ah should be set to 66h when reading pixel data from frame memory. Please check the LUT in chapter 9.17 when using memory read function.
DefaultStatusDefault Value
Power On SequenceContents of memory is set randomly
S/W ResetContents of memory is not cleared
H/W ResetContents of memory is not cleared
Flow Chart
+ +10.1.25 PTLAR (30h): Partial Area + +
30HPTLAR (Partial Area)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
PTLAR01-00110000(30h)
1st Parameter11-PSL15PSL14PSL13PSL12PSL11PSL10PSL9PSL8
2nd Parameter11-PSL7PSL6PSL5PSL4PSL3PSL2PSL1PSL0
3rd Parameter11-PEL15PEL14PEL13PEL12PEL11PEL10PEL9PEL8
4th Parameter11-PEL7PEL6PEL5PEL4PEL3PEL2PEL1PEL0
Description-This command defines the partial mode's display area.-There are 4 parameters associated with this command, the first defines the Start Row (PSL) and the second the End Row (PEL), as illustrated in the figures below. PSL and PEL refer to the Frame Memory row address counter.-If End Row > Start Row, when MADCTL ML='0'-If End Row > Start Row, when MADCTL ML='1'-If End Row < Start Row, when MADCTL ML='0'-If End Row = Start Row then the Partial Area will be one row deep.
+ +
DefaultStatusDefault Value
PSL [15:0]PEL [15:0]
GM[1:0]“xx”GM[1:0]="11"GM[1:0]="01"GM[1:0]="00"
Power On Sequence0000h009Fh0083h00A1h
S/W Reset0000h009Fh0083h00A1h
H/W Reset0000h009Fh0083h00A1h
Flow Chart2. Leave Partial Mode1.1
+ +
StatusDefault Value
PSL [15:0]PEL [15:0]
GM[1:0]“xx”GM[1:0]="11"GM[1:0]="01"GM[1:0]="00"
Power On Sequence0000h009Fh0083h00A1h
S/W Reset0000h009Fh0083h00A1h
H/W Reset0000h009Fh0083h00A1h
+ +2. Leave Partial Mode +Legend + +10.1.26 SCRLAR (33h): Scroll Area Set + +
33HSCRLAR (Scroll Area)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
SCRLAR01-00110011(33h)
$1^{st}$ parameter11-TFA15TFA14TFA13TFA12TFA11TFA10TFA9TFA8-
$2^{nd}$ parameter11-TFA7TFA6TFA5TFA4TFA3TFA2TFA1TFA0-
$3^{rd}$ parameter11-VSA15VSA14VSA13VSA12VSA11VSA10VSA9VSA8-
$4^{th}$ parameter11-VSA7VSA6VSA5VSA4VSA3VSA2VSA1VSA0-
$5^{th}$ parameter11-BFA15BFA14BFA13BFA12BFA11BFA10BFA9BFA8-
$6^{nd}$ parameter11-BFA7BFA6BFA5BFA4BFA3BFA2BFA1BFA0-
Description-This command just defines the Vertical Scrolling Area of the display and not performs vertical scroll-When MADCTR B4=0-The $1^{st}$ & $2^{nd}$ parameter TFA [15:0] describes the Top Fixed Area (in No. of lines from Top of the Frame Memory and Display).-The $3^{rd}$ & $4^{th}$ parameter VSA [15:0] describes the height of the Vertical Scrolling Area (in No. of lines of the Frame Memory [not the display] from the Vertical Scrolling Start Address) The first line appears immediately after the bottom most line of the Top Fixed Area.-The $4^{th}$ & $5^{th}$ parameter BFA [6:0] describes the Bottom Fixed Area (in No. of lines from Bottom of the Frame Memory and Display).TFA, VSA and BFA refer to the Frame Memory Line Pointer
RestrictionThe condition is (TFA+VSA+BFA) = 162, otherwise Scrolling mode is undefined.In Vertical Scroll Mode, MADCTR parameter MV should be set to '0'-this only affects the Frame Memory Write.TFA[15:0], VSA[15:0] and BFA[15:0] is based on line unit.TFA[15:0]= 0000h, 0001h, 0002h, 0003h, ..., 00A2hVSA[15:0]= 0000h, 0001h, 0002h, 0003h, ..., 00A2hBFA[15:0]= 0000h, 0001h, 0002h, 0003h, ..., 00A2h
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
DefaultStatusDefault Value GM[1:0]=“11”
Power On SequenceTFA[15:0]=0000hVSA[15:0]=00A0hBFA[15:0]=0000h
S/W ResetTFA[15:0]=0000hVSA[15:0]=00A0hBFA[15:0]=0000h
H/W ResetTFA[15:0]=0000hVSA[15:0]=00A0hBFA[15:0]=0000h
StatusDefault Value GM[1:0]=“01”
Power On SequenceTFA[15:0]=0000hVSA[15:0]=0084hBFA[15:0]=0000h
S/W ResetTFA[15:0]=0000hVSA[15:0]=0084hBFA[15:0]=0000h
H/W ResetTFA[15:0]=0000hVSA[15:0]=0084hBFA[15:0]=0000h
StatusDefault Value GM[1:0]=“00”
Power On SequenceTFA[15:0]=0000hVSA[15:0]=00A2hBFA[15:0]=0000h
S/W ResetTFA[15:0]=0000hVSA[15:0]=00A2hBFA[15:0]=0000h
H/W ResetTFA[15:0]=0000hVSA[15:0]=00A2hBFA[15:0]=0000h
Flow Chart1. TO Enter Vertical Scroll Mode:
Only required for non-rolling scrolling
+ +10.1.27 TEOFF (34h): Tearing Effect Line OFF + +
34HTEOFF (Tearing Effect Line OFF)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
TEOFF01-00110100(34h)
ParameterNo Parameter-
Description-This command is used to turn OFF (Active Low) the Tearing Effect output signal from the TE signal line.
DefaultStatusDefault Value
Power On SequenceOFF
S/W ResetOFF
H/W ResetOFF
Flow Chart
+ +10.1.28 TEON (35h): Tearing Effect Line ON + +
35HTEON (Tearing Effect Line ON)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
TEON01-00110101(35h)
Parameter11-0000000TEM
Description-This command is used to turn ON the Tearing Effect output signal from the TE signal line.-This output is not affected by changing MADCTL bit ML.-The Tearing Effect Line On has one parameter, which describes the mode of the Tearing Effect Output Line:-When TEM ='0': The Tearing Effect output line consists of V-Blanking information only
-When TEM ='1': The Tearing Effect output Line consists of both V-Blanking and H-Blanking information
Note: During Sleep In Mode with Tearing Effect Line On, Tearing Effect Output pin will be active Low.
DefaultStatusDefault Value
Power On SequenceTearing effect off & TEM=0
S/W ResetTearing effect off & TEM=0
H/W ResetTearing effect off & TEM=0
+ +
Flow Chart
+ +10.1.29 MADCTL (36h): Memory Data Access Control + +
36HMADCTL (Memory Data Access Control)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
MADCTL01-00110110(36h)
Parameter11-MYMXMVMLRGBMH--
Description-This command defines read/ write scanning direction of frame memory.
BitNAMEDESCRIPTION
MYRow Address OrderThese 3bits controls MCU to memory write/read direction.
MXColumn Address Order
MVRow/Column Exchange
MLVertical Refresh OrderLCD vertical refresh direction control‘0’ = LCD vertical refresh Top to Bottom‘1’ = LCD vertical refresh Bottom to Top
RGBRGB-BGR ORDERColor selector switch control‘0’ =RGB color filter panel,‘1’ =BGR color filter panel)
MHHorizontal Refresh OrderLCD horizontal refresh direction control‘0’ = LCD horizontal refresh Left to right‘1’ = LCD horizontal refresh right to left
-Bit Assignment
+ +![](images/b23975b301e2222a84b61c2da71f4a75086a59180d6f4e72412f098983111220.jpg) + +
DefaultStatusDefault Value
Power On SequenceMY=0,MX=0,MV=0,ML=0,RGB=0,MH=0
S/W ResetNo Change
H/W ResetMY=0,MX=0,MV=0,ML=0,RGB=0,MH=0
Flow Chart
+ +10.1.30 VSCSAD: Vertical Scroll Start Address of RAM (37h) + +
37HSCRLAR (Scroll Area)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
VSCSAD01-00110111(37h)
Parameter111-00000000
Parameter211-SSA7SSA6SSA5SSA4SSA3SSA2SSA1SSA0-
Description-This command is used together with Vertical Scrolling Definition (33h).-These two commands describe the scrolling area and the scrolling mode.-The Vertical Scrolling Start Address command has one parameter which describes which line in the Frame Memory will be written as the first line after the last line of the Top Fixed Area on the display as illustrated below:-This command Start the scrolling.-Exit from V-scrolling mode by commands Partial mode On (12h) or Normal mode On (13h)[WWW6W]SCNOTE: When new Pointer position and Picture Data are sent, the result on the display will happen at the next Panel Scan to avoid tearing effect.SSA refers to the Frame Memory line Pointer
RestrictionSince the value of the Vertical Scrolling Start Address is absolute (with reference to the Frame Memory), it must not enter the fixed area (defined by Vertical Scrolling Definition (33h)-otherwise undesirable image will be displayed on the Panel.SSA [6:0] is based on line unit.SSA [6:0] = 00h, 01h, 02h, 03h, ..., A1h
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutNo
Partial Mode On, Idle Mode On, Sleep OutNo
Sleep InYes
+ +
Default
Status
Power On Sequence
S/W Reset
H/W Reset
Flow ChartSee Vertical Scrolling Definition (33h) description.
+ +10.1.31 IDMOFF (38h): Idle Mode Off + +
38HIDMOFF (Idle Mode Off)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
IDMOFF01-00111000(38h)
ParameterNo Parameter-
Description-This command is used to recover from Idle mode on. +-In the idle off mode, +1. LCD can display 4096, 65k or 262k colors. +2. Normal frame frequency is applied.
DefaultStatusDefault Value
Power On SequenceIdle Mode Off
S/W ResetIdle Mode Off
HWDRIdle Mode Off
Flow Chart
+ +10.1.32 IDMON (39h): Idle Mode On + +
39HIDMON (Idle Mode On)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
IDMOFF01-00111001(39h)
ParameterNo Parameter-
Description-This command is used to enter into Idle mode on.-There will be no abnormal visible effect on the display mode change transition.-In the idle on mode,1. Color expression is reduced. The primary and the secondary colors using MSB of each R,G and B in the Frame Memory, 8 color depth data is displayed.2. 8-Color mode frame frequency is applied.3. Exit from IDMON by Idle Mode Off (38h) command (Example)Top-Left (0,0)
ColorR5 R4 R3 R2 R1 R0G5 G4 G3 G2 G1 G0B5 B4 B3 B4 B1 B0
Black0xxxx0xxxx0xxxx
Blue0xxxx0xxxx1xxxx
Red1xxxx0xxxx0xxxx
Magenta1xxxx0xxxx1xxxx
Green0xxxx1xxxx0xxxx
Cyan0xxxx1xxxx1xxxx
Yellow1xxxx1xxxx0xxxx
White1xxxx1xxxx1xxxx
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutNo
Partial Mode On, Idle Mode On, Sleep OutNo
Sleep InYes
DefaultStatusDefault Value
Power On SequenceIdle Mode Off
S/W ResetIdle Mode Off
H/W ResetIdle Mode Off
Flow Chart
+ +10.1.33 COLMOD (3Ah): Interface Pixel Format + +
3AHCOLMOD (3Ah): Interface Pixel Format
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
COLMOD01-00111010(3Ah)
Parameter11------IFPF2IFPF1IFPF0
DescriptionThis command is used to define the format of RGB picture data, which is to be transferred via the MCU interface. The formats are shown in the table:
IFPF[2:0]MCU Interface Color Format
011312-bit/pixel
101516-bit/pixel
110618-bit/pixel
1117No used
Note1: In 12-bit/Pixel, 16-bit/Pixel or 18-bit/Pixel mode, the LUT is applied to transfer data into the Frame Memory.Note2: The Command 3Ah should be set at 55h when writing 16-bit/pixel data into frame memory, but 3Ah should be re-set to 66h when reading pixel data from frame memory. Please check the LUT in chapter 9.17 when using memory read function.
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutNo
Partial Mode On, Idle Mode On, Sleep OutNo
Sleep InYes
DefaultStatusDefault Value
IFPF[2:0]VIPF[3:0]
Power On Sequence0110(18-bit/Pixel)0110(18-bit/Pixel)
S/W ResetNo ChangeNo Change
H/W Reset0110(18-bit/Pixel)0110(18-bit/Pixel)
Flow Chart
+ +10.1.34 RDID1 (DAh): Read ID1 Value + +
DAHRDID1 (Read ID1 Value)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDID101-11011010(DAh)
1st Parameter11----------
2nd Parameter11-ID17ID16ID15ID14ID13ID12ID11ID10
Description-This read byte returns 8-bit LCD module's manufacturer ID-The 1st parameter is dummy data-The 2nd parameter (ID17 to ID10): LCD module's manufacturer ID.NOTE: See command RDDID (04h), 2nd parameter.
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutNo
Partial Mode On, Idle Mode On, Sleep OutNo
Sleep InYes
DefaultStatusDefault Value
Power On Sequence0x7C
S/W Reset0x7C
H/W Reset0x7C
Flow Chart
+ +10.1.35 RDID2 (DBh): Read ID2 Value + +
DBHRDID2 (Read ID2 Value)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDID201-11011011(DBh)
$1^{st}$ Parameter11----------
$2^{nd}$ Parameter11-1ID26ID25ID24ID23ID22ID21ID20
Description-This read byte returns 8-bit LCD module/driver version ID-The $1^{st}$ parameter is dummy data-The $2^{nd}$ parameter (ID26 to ID20): LCD module/driver version ID-Parameter Range: ID=80h to FFh
ID26 to ID20VersionChanges
80h
81h
82h
83h
NOTE: See command RDDID (04h), $3^{rd}$ parameter.
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutNo
Partial Mode On, Idle Mode On, Sleep OutNo
Sleep InYes
DefaultStatusDefault Value
Power On SequenceNV Value
S/W ResetNV Value
H/W ResetNV Value
Flow ChartLegend
+ +Legend +![](images/ab4f8733957a2140a58011bb06e7b972f9b1de82c752980abdd05f83a7d47956.jpg) + +10.1.36 RDID3 (DCh): Read ID3 Value + +
DCHRDID3 (Read ID2 Value)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
RDID301-11011100(DCh)
1stParameter11----------
2ndParameter11-ID37ID36ID35ID34ID33ID32ID31ID30
Description-This read byte returns 8-bit LCD module/driver ID.-The 1stparameter is dummy data-The 2ndparameter (ID37 to ID30): LCD module/driver ID.NOTE: See command RDDID (04h), 4thparameter.
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutNo
Partial Mode On, Idle Mode On, Sleep OutNo
Sleep InYes
DefaultStatusDefault Value
Power On SequenceNV Value
S/W ResetNV Value
H/W ResetNV Value
Flow Chart
+ +## 10.2 Panel Function Command List and Description + +Table 18 Panel Function Command List (1) + +
InstructionReferD/CXWRXRDXD23-8D7D6D5D4D3D2D1D0HexFunction
FRMCTR1001-10110001(B1h)In Normal Mode (Full Colors)
11-RTNA3RTNA2RTNA1RTNA0RTNA Set 1-line Period FPA: Front Porch BPA: Back Porch
11-FPA5FPA4FPA3FPA2FPA1FPA0
11-BPA5BPA4BPA3BPA2BPA1BPA0
FRMCTR2001-10110010(B2h)In Idle Mode (8-colors)
11-RTNB3RTNB2RTNB1RTNB0RTNB: Set 1-line Period FPB: Front Porch BPB: Back Porch
11-FPB5FPB4FPB3FPB2FPB1FPB0
11-BPB5BPB4BPB3BPB2BPB1BPB0
FRMCTR3001-10110011(B3h)In Partial Mode + Full Colors
11-RTNC3RTNC2RTNC1RTNC0RTNC,RTND: Set 1-line Period FPC,FPD: Front Porch BPC,BPD: Back Porch
11-FPC5FPC4FPC3FPC2FPC1FPC0
11-BPC5BPC4BPC3BPC2BPC1BPC0
11-RTND3RTND2RTND1RTND0
11-FPD5FPD4FPD3FPD2FPD1FPD0
11-BPD5BPD4BPD3BPD2BPD1BPD0
INVCTR001-10110100(B4h)Display Inversion Control
11-00000NLANLBNLCNLA,NLB,NLC Set Inversion
+ +Table 19 Panel Function Command List (2) + +
InstructionReferD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HexFunction
PWCTR1001-11000000(C0h)Power Control Setting
11-AVDD[2]AVDD[1]AVDD[0]VRHP4VRHP3VRHP2VRHP1VRHP0VRH: Set the GVDD Voltage
11-000VRHN4VRHN3VRHN2VRHN1VRHN0
11MODE[1]MODE[0]000100
PWCTR2001-11000001(C1h)Power Control Setting
11-VGH25[1]VGH25[0]--VGLSEL[1]VGLSEL[0]VGHBT[1]VGHBT[0]BT: Set VGH/ VGL Voltage
PWCTR3001-11000010(C2h)In Normal Mode (Full Colors)
11-DCA9DCA8SAPA2SAPA1SAPA0APA2APA1APA0APA: Adjust the Operational AmplifierDCA: Adjust the Booster Voltage
-DCA7DCA6DCA5DCA4DCA3DCA2DCA1DCA0
PWCTR4001-11000011(C3h)In Idle Mode (8-colors)
11-DCB9DCB8SAPB2SAPB1SAPB0APB2APB1APB0APB: Adjust the Operational AmplifierDCB: Adjust the Booster Voltage
-DCB7DCB6DCB5DCB4DCB3DCB2DCB1DCB0
PWCTR5001-11000100(C4h)In Partial Mode + Full colors
11-DCC9DCC8SAPC2SAPC1SAPC0APC2APC1APC0APC: Adjust the Operational AmplifierDCC: Adjust the Booster Circuit for Idle mode
11-DCC7DCC6DCC5DCC4DCC3DCC2DCC1DCC0
VMCTR1001-11000101(C5h)VCOM Control 1
11---VCOMS5VCOMS4VCOMS3VCOMS2VCOMS1VCOMS0VCOM Voltage Control
VMOFCTR001-11000111(C7h)Set VCOM Offset control
11----VMF4VMF3VMF2VMF1VMF0
WRID2001-11010001(D1h)Set LCM Version Code
11--ID2[6]ID2[5]ID2[4]ID2[3]ID2[2]ID2[1]ID2[0]
+ +“-”: Don't care +Note 1: C0h to C7h are fixed for about power controller + +Table 20 Panel Function Command List (3) + +
InstructionReferD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HexFunction
WRID3001-11010010(D2h)Customer Project Code
11-ID37ID36ID35ID34ID33ID32ID31ID30Set the Project Code at ID3
NVCTR1001-11011001(D9)NVM Control Status
11-0VMF_ENID2_EN0000EXT_R
NVCTR2001-11011110(Deh)NVM Read Command
11-11110101F5
11-10100101A5Action Code
NVCTR3001-11011111(DFh)NVM Write Command Action Code
11-NVM_CMD7NVM_CMD6NVM_CMD5NVM_CMD4NVM_CMD3NVM_CMD2NVM_CMD1NVM_CMD0
11-10100101A5
+ +“-”: Don't care +Note 1: The D1h to D3h registers are fixed for about ID code setting. +Note 2: The D9h, Deh and DFh registers are used for NV Memory function controller. (Ex: write, clear, etc.) + +Table 21 Panel Function Command List (4) + +
InstructionReferD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HexFunction
GAMCTRP1001-11100000(E0h)Set
11---VRFP[5]VRFP[4]VRFP[3]VRFP[2]VRFP[1]VRF0P[0]Gamma Adjustment (+ Polarity)
11---VOS0P[5]VOS0P[4]VOS0P[3]VOS0P[2]VOS0P[1]VOS0P[0]
11---PKP0[5]PKP0[4]PKP0[3]PKP0[2]PKP0[1]PKP0[0]
11---PKP1[5]PKP1[4]PKP1[3]PKP1[2]PKP1[1]PKP1[0]
11---PKP2[5]PKP2[4]PKP2[3]PKP2[2]PKP2[1]PKP2[0]
11---PKP3[5]PKP3[4]PKP3[3]PKP3[2]PKP3[1]PKP3[0]
11---PKP4[5]PKP4[4]PKP4[3]PKP4[2]PKP4[1]PKP4[0]
11---PKP5[5]PKP5[4]PKP5[3]PKP5[2]PKP5[1]PKP5[0]
11---PKP6[5]PKP6[4]PKP6[3]PKP6[2]PKP6[1]PKP6[0]
11---PKP7[5]PKP7[4]PKP7[3]PKP7[2]PKP7[1]PKP7[0]
11---PKP8[5]PKP8[4]PKP8[3]PKP8[2]PKP8[1]PKP8[0]
11PKP9[5]PKP9[4]PKP9[3]PKP9[2]PKP9[1]PKP9[0]
11---SELV0P[5]SELV0P[4]SELV0P[3]SELV0P[2]SELV0P[1]SELV0P[0]
11---SELV1P[5]SELV1P[4]SELV1P[3]SELV1P[2]SELV1P[1]SELV1P[0]
11---SELV62P[5]SELV62P[4]SELV62P[3]SELV62P[2]SELV62P[1]SELV62P[0]
11---SELV63P[5]SELV63P[4]SELV63P[3]SELV63P[2]SELV63P[1]SELV63P[0]
GAMCTRN1001-11100001(E1h)Set
11---VRF0N[5]VRF0N[4]VRF0N[3]VRF0N[2]VRF0N[1]VRF0N[0]Gamma Adjustment (- Polarity)
11---VOS0N[5]VOS0N[4]VOS0N[3]VOS0N[2]VOS0N[1]VOS0N[0]
11---PKN0[5]PKN0[4]PKN0[3]PKN0[2]PKN0[1]PKN0[0]
11---PKN1[5]PKN1[4]PKN1[3]PKN1[2]PKN1[1]PKN1[0]
11---PKN2[5]PKN2[4]PKN2[3]PKN2[2]PKN2[1]PKN2[0]
11---PKN3[5]PKN3[4]PKN3[3]PKN3[2]PKN3[1]PKN3[0]
11---PKN4[5]PKN4[4]PKN4[3]PKN4[2]PKN4[1]PKN4[0]
11---PKN5[5]PKN5[4]PKN5[3]PKN5[2]PKN5[1]PKN5[0]
11---PKN6[5]PKN6[4]PKN6[3]PKN6[2]PKN6[1]PKN6[0]
11---PKN7[5]PKN7[4]PKN7[3]PKN7[2]PKN7[1]PKN7[0]
11---PKN8[5]PKN8[4]PKN8[3]PKN8[2]PKN8[1]PKN8[0]
11-PKN9[5]PKN9[4]PKN9[3]PKN9[2]PKN9[1]PKN9[0]
11---SELV0N[5]SELV0N[4]SELV0N[3]SELV0N[2]SELV0N[1]SELV0N[0]
11---SELV1N[5]SELV1N[4]SELV1N[3]SELV1N[2]SELV1N[1]SELV1N[0]
11---SELV62N[5]SELV62N[4]SELV62N[3]SELV62N[2]SELV62N[1]SELV62N[0]
11---SELV63N[5]SELV63N[4]SELV63N[3]SELV63N[2]SELV63N[1]SELV63N[0]
11-11011000(FCh)Gate clock Variable
11-GCV Enable1GCV Enable00Clk_VariableClk_Variable00
+ +“-”: Don't care +Note 1: E0-E1 registers are fixed for adjusting Gamma + +10.2.1 FRMCTR1 (B1h): Frame Rate Control (In normal mode/ Full colors) + +
B1HFRMCTR1 (Frame Rate Control)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
FRMCTR101-10110001(B1h)
$1^{st}$ Parameter11-----RTNA 3RTNA 2RTNA 1RTNA 0
$2^{nd}$ Parameter11---FPA5FPA4FPA3FPA2FPA1FPA0
$3^{rd}$ Parameter11---BPA5BPA4BPA3BPA2BPA1BPA0
Description-Set the frame frequency of the full colors normal mode.- Frame rate=fosc/((RTNA x 2 + 40) x (LINE + FPA + BPA +2))-fosc = 850kHz-FPA > 0, BPA > 0
DefaultStatusDefault Value
GM[1:0] = "00"GM[1:0] = "01"GM[1:0] = "11"
Power On Sequence05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
S/W Reset05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
H/W Reset05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
Flow Chart
+ +10.2.2 FRMCTR2 (B2h): Frame Rate Control (In Idle mode/ 8-colors) + +
B2HFRMCTR2 (Frame Rate Control)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
FRMCTR201-10110010(B2h)
1stparameter11-----RTNB3RTNB2RTNB1RTNB0
2ndparameter11---FPB5FPB4FPB3FPB2FPB1FPB0
3rdparameter11---BPB5BPB4BPB3BPB2BPB1BPB0
Description-Set the frame frequency of the Idle mode.- Frame rate=fosc/((RTNA x 2 + 40) x (LINE + FPB + BPB +2))-fosc = 850kHz-FPB > 0, BPB > 0
DefaultStatusDefault Value
GM[1:0] = "00"GM[1:0] = "01"GM[1:0] = "11"
Power On Sequence05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
S/W Reset05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
H/W Reset05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
Flow Chart
+ +10.2.3 FRMCTR3 (B3h): Frame Rate Control (In Partial mode/ full colors) + +
B3HFRMCTR3 (Frame Rate Control)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
FRMCTR301-10110011(B3h)
1stparameter11-----RTNCRTNCRTNCRTNC
2ndparameter11---FPC5FPC4FPC3FPC2FPC1FPC0
3rdparameter11---BPC5BPC4BPC3BPC2BPC1BPC0
4thparameter11-----RTNDRTNDRTNDRTND
5thparameter11---FPD5FPD4FPD3FPD2FPD1FPD0
6thparameter11---BPD5BPD4BPD3BPD2BPD1BPD0
Description-Set the frame frequency of the Partial mode/ full colors.- 1stparameter to 3rdparameter are used in dot inversion mode.- 4thparameter to 6thparameter are used in column inversion mode.- Frame rate=fosc/((RTNA x 2 + 40) x (LINE + FPC + BPC +2))-fosc = 850kHz-FPC > 0, BPC > 0
DefaultStatusDefault Value
GM[1:0] = "00"GM[1:0] = "01"GM[1:0] = "11"
Power On Sequence05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
S/W Reset05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
H/W Reset05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
05h/3Ah/3Ah08h/3Bh/3Bh05h/3Ch/3Ch
Flow Chart
+ +10.2.4 INVCTR (B4h): Display Inversion Control + +
B4HINVCTR (Display Inversion Control)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
INVCTR01-10110100(B4h)
Parameter11-00000NLANLBNLC
Description-Display Inversion mode control-NLA: Inversion setting in full colors normal mode (Normal mode on)
NLAInversion setting in full Colors normal mode
0Dot Inversion
1Column Inversion
-NLB: Inversion setting in Idle mode (Idle mode on)
NLBInversion setting in Idle mode
0Dot Inversion
1Column Inversion
-NLC: Inversion setting in full colors partial mode (Partial mode on / Idle mode off)
NLCInversion setting in full Colors partial mode
0Dot Inversion
1Column Inversion
DefaultStatusDefault Value
B4h
Power On Sequence07h
S/W Reset07h
H/W Reset07h
Flow Chart
+ +10.2.5 PWCTR1 (C0h): Power Control 1 + +
C0HPWCTR1 (Power Control 1)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
PWCTR101-11000000(C0h)
$1^{st}$ parameter11-AVDD[2]AVDD[1]AVDD[0]VRHP4VRHP3VRHP2VRHP1VRHP0
$2^{nd}$ parameter11-000VRHN4VRHN3VRHN2VRHN1VRHN0
$3^{rd}$ parameter11-MODE[1]MODE[0]0001VRHN5VRHP5
Description
+ +
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
Default
StatusDefault Value
C0h
Power On SequenceA8h/08h/84h
S/W ResetA8h/08h/84h
H/W ResetA8h/08h/84h
Flow Chart
+ +10.2.6 PWCTR2 (C1h): Power Control 2 + +
C1HPWCTR2 (Power Control 2)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
PWCTR201-11000001(C1h)
1stparameter11VGH25[1]VGH25[0]--VGLSEL[1]VGLSEL[0]VGHBT[1]VGHBT[0]
Description-Set the VGH and VGL supply power level
VGH25[1:0]V25
002.1
012.2
102.3
112.4
VGHBT[1:0]VGH
002*AVDD+VGH25-0.5
013*AVDD-0.5
103*AVDD+VGH25-0.5
11Don't use this setting, reserve for testing.
VGLSEL[1:0]VGL
00-7.5
01-10
10-12.5
11-13
Restriction-The deviation value of VGH/ VGL between with Measurement and Specification: Max <= 1V-VGH-VGL <= 32V
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
Default
StatusDefault Value
C1h
Power On SequenceC0h
S/W ResetC0h
H/W ResetC0h
+ +
Flow Chart
+ +10.2.7 PWCTR3 (C2h): Power Control 3 (in Normal mode/ Full colors) + +
C2HPWCTR3 (Power Control 3)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
PWCTR301-11000010(C2h)
$1^{st}$ 11-DCA9DCA8SAPA2SAPA1SAPA0APA2APA1APA0
$2^{nd}$ 11-DCA7DCA6DCA5DCA4DCA3DCA2DCA1DCA0
Description-Set the amount of current in Operational amplifier in normal mode/full colors.-Adjust the amount of fixed current from the fixed current source in the operational amplifier for the source driver.
AP[2:0]Amount of Current in Operational Amplifier
000Operation of the operational amplifier stops
001Small
010Medium Low
011Medium
100Medium High
101Large
110Reserved
111Reserved
SAP[2:0]Amount of Current in Operational Amplifier
000Operation of the operational amplifier stops
001Small
010Medium Low
011Medium
100Medium High
101Large
110Reserved
111Reserved
-Set the Booster circuit Step-up cycle in Normal mode/ full colors.
DCA[9:8]DCA[7:6]DCA[5:4]DCA[3:2]DCA[1:0]
00BCLK/1BCLK/3BCLK/1BCLK/1BCLK/1
01BCLK/3BCLK/1BCLK/3BCLK/3BCLK/3
10BCLK/2BCLK/4BCLK/2BCLK/2BCLK/2
11BCLK/4BCLK/2BCLK/4BCLK/4BCLK/4
Note: BCLK is Clock frequency for Booster circuit
+ +
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
Default
StatusDefault Value
C2h
Power On Sequence0Ah/00h
S/W Reset0A h/00h
H/W Reset0A h/00h
Flow Chart
+ +10.2.8 PWCTR4 (C3h): Power Control 4 (in Idle mode/ 8-colors) + +
C3HPWCTR4 (Power Control 4)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
PWCTR401-11000011(C3h)
1stparameter11-DCB9DCB8SAPB2SAPB1SAPB0APB2APB1APB0
2ndparameter11-DCB7DCB6DCB5DCB4DCB3DCB2DCB1DCB0
Description-Set the amount of current in Operational amplifier in Idle mode/8 colors.-Adjust the amount of fixed current from the fixed current source in the operational amplifier for the source driver.
AP[2:0]Amount of Current in Operational Amplifier
000Operation of the operational amplifier stops
001Small
010Medium Low
011Medium
100Medium High
101Large
110Reserved
111Reserved
SAP[2:0]Amount of Current in Operational Amplifier
000Operation of the operational amplifier stops
001Small
010Medium Low
011Medium
100Medium High
101Large
110Reserved
111Reserved
-Set the Booster circuit Step-up cycle in Idle mode/8 colors.
DCB[9:8]DCB[7:6]DCB[5:4]DCB[3:2]DCB[1:0]
00BCLK/1BCLK/3BCLK/1BCLK/1BCLK/1
01BCLK/3BCLK/1BCLK/3BCLK/3BCLK/3
10BCLK/2BCLK/4BCLK/2BCLK/2BCLK/2
11BCLK/4BCLK/2BCLK/4BCLK/4BCLK/4
Note: BCLK is Clock frequency for Booster circuit
+ +
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
Default
StatusDefault Value
C3h
Power On Sequence8Ah/26h
S/W Reset8Ah/26h
H/W Reset8Ah/26h
Flow Chart
+ +10.2.9 PWCTR5 (C4h): Power Control 5 (in Partial mode/ full-colors) + +
C4HPWCTR5 (Power Control 5)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
PWCTR501-11000100(C4h)
$1^{st}$ parameter11-DCC9DCC8SAPC2SAPC1SAPC0APC2APC1APC0
$2^{nd}$ parameter11-DCC7DCC6DCC5DCC4DCC3DCC2DCC1DCC0
Description-Set the amount of current in Operational amplifier in Partial mode/ full-colors.-Adjust the amount of fixed current from the fixed current source in the operational amplifier for the source driver.
AP[2:0]Amount of Current in Operational Amplifier
000Operation of the operational amplifier stops
001Small
010Medium Low
011Medium
100Medium High
101Large
110Reserved
111Reserved
SAP[2:0]Amount of Current in Operational Amplifier
000Operation of the operational amplifier stops
001Small
010Medium Low
011Medium
100Medium High
101Large
110Reserved
111Reserved
-Set the Booster circuit Step-up cycle in Partial mode/ full-colors.
DCC[9:8]DCC[7:6]DCC[5:4]DCC[3:2]DCC[1:0]
00BCLK/1BCLK/3BCLK/1BCLK/1BCLK/1
01BCLK/3BCLK/1BCLK/3BCLK/3BCLK/3
10BCLK/2BCLK/4BCLK/2BCLK/2BCLK/2
11BCLK/4BCLK/2BCLK/4BCLK/4BCLK/4
Note: BCLK is Clock frequency for Booster circuit
+ +
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
Default
Flow Chart
+ +10.2.10 VMCTR1 (C5h): VCOM Control 1 + +
C5HVMCTR1 (VCOM Control 1)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
VMCTR101-11000101(C5h)
$1^{st}$ parameter11---VCOMS 5VCOMS 4VCOMS 3VCOMS 2VCOMS 1VCOMS 0
DescriptionVCOM voltage setting.
VCOMS [5:0]VCOMVCOMS [5:0]VCOMVCOMS [5:0]VCOMVCOMS [5:0]VCOM
0000000-0.42516010000-0.82532100000-1.22548110000-1.625
1000001-0.4517010001-0.8533100001-1.2549110001-1.65
2000010-0.47518010010-0.87534100010-1.27550110010-1.675
3000011-0.519010011-0.935100011-1.351110011-1.7
4000100-0.52520010100-0.92536100100-1.32552110100-1.725
5000101-0.5521010101-0.9537100101-1.3553110101-1.75
6000110-0.57522010110-0.97538100110-1.37554110110-1.775
7000111-0.623010111-139100111-1.455110111-1.8
8001000-0.62524011000-1.02540101000-1.42556111000-1.825
9001001-0.6525011001-1.0541101001-1.4557111001-1.85
10001010-0.67526011010-1.07542101010-1.47558111010-1.875
11001011-0.727011011-1.143101011-1.559111011-1.9
12001100-0.72528011100-1.12544101100-1.52560111100-1.925
13001101-0.7529011101-1.1545101101-1.5561111101-1.95
14001110-0.77530011110-1.17546101110-1.57562111110-1.975
15001111-0.831011111-1.247101111-1.663111111-2
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
Default
StatusDefault Value
C5h
Power On Sequence05h
S/W Reset05h
H/W Reset05h
Flow Chart
+ +10.2.11 VMOFCTR (C7h): VCOM Offset Control + +
C7HVMOFCTR (VCOM Offset Control)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
VMOFCTR01-11000111(C7h)
Parameter11----VMF4VMF3VMF2VMF1VMF0
Description-Set VCOM Voltage level for reduce the flicker issue-Before use command 0xC7, the bit VMF_EN of command 0xD9 must be enabled (set to 1).
VMF[4]VMF[3:0]VCOM Output Level
00000“VCOMS”+16d
00001“VCOMS”+15d
0||
01110“VCOMS”+2d
01111“VCOMS”+1d
10000“VCOMS”
10001“VCOMS”-1d
10010“VCOMS”-2d
1||
11110“VCOMS”-14d
11111“VCOMS”-15d
- 1d=25mV, 2d=50mV 3d=75mv....
Register AvailabilityStatusAvailability
Normal Mode On, Idle Mode Off, Sleep OutYes
Normal Mode On, Idle Mode On, Sleep OutYes
Partial Mode On, Idle Mode Off, Sleep OutYes
Partial Mode On, Idle Mode On, Sleep OutYes
Sleep InYes
DefaultStatusDefault Value
C7h
Power On Sequence10h
S/W Reset10h
H/W Reset10h
+ +
Flow Chart
+ +10.2.12 WRID2 (D1h): Write ID2 Value + +
D1HWRID2 (Write ID2 Value)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
WRID201-11010001(D1h)
Parameter11--ID26ID25ID24ID23ID22ID21ID20-
Description-Write 7-bit data of LCD module version to save it to NVM. +-The parameter ID2[6:0] is LCD Module version ID.
Flow Chart
+ +10.2.13 WRID3 (D2h): Write ID3 Value + +
D2HWRID3 (Write ID3 Value)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
WRID301-11010010(D2h)
Parameter11-ID37ID36ID35ID34ID33ID32ID31ID30-
Description-Write 8-bit data of project code module to save it to NVM.-The parameter ID3[7:0] is product project ID.
Flow Chart
+ +10.2.14 NVFCTR1 (D9h): NVM Control Status + +
D9HNVFCTR1 (NV Memory Function Controller 1)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
NVFCTR101-11001001(D9h)
Parameter11-0VMF_ENID2_EN0000EXT_R
Description-NVM control status
BitValue
VMF_EN“1” = Command C7h Enable; “0” = Command C7h Disable
ID2_EN“1” = Command D1h Enable; “0” = Command D1h Disable
EXT_RRead: Extension Command Status, “1” for Enable, “0” for Disable.
DefaultStatusDefault Value (D9h)
Power On Sequence00h
S/W Reset00h
H/W Reset00h
Flow Chart
+ +10.2.15 NVFCTR2 (Deh): NVM Read Command + +
DEHNVFCTR1 (NV Memory Function Controller 2)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
NVFCTR201-11011110(Deh)
1stParameter1111110101F5
2ndParameter1110100101A5
DescriptionNVM Read CommandNOTE: “-” Don’t care
Flow Chart
+ +10.2.16 NVFCTR3 (DFh): NVM Write Command + +
DFHNVFCTR1 (NV Memory Function Controller 3)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
NVFCTR101-11011111(DFh)
1stParameter11NVM_CMD7NVM_CMD6NVM_CMD5NVM_CMD4NVM_CMD3NVM_CMD2NVM_CMD1NVM_CMD0
2ndParameter1110100101A5
Description-NVM Write Command-NVM_CMD[7:0] : Select to Program/Erase ; Program command : 3Ah ; Erase command : C5hNOTE: “-” Don’t care
Flow Chart
+ +10.2.17 GMCTRP1 (E0h): Gamma ('+'polarity) Correction Characteristics Setting + +
E0HGMCTRP0 (Gamma ‘+’Polarity Correction Characteristics Setting)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
GMCTRP101-11100000(E0h)
$1^{st}$ Parameter11---VRF0P[5]VRF0P[4]VF0P[3]VRF0P[2]VRF0P[1]VRF0P[0]
$2^{nd}$ Parameter11---VOS0P[5]VOS0P[4]VOS0P[3]VOS0P[2]VOS0P[1]VOS0P[0]
$3^{rd}$ Parameter11---PK0P[5]PK0P[4]PK0P[3]PK0P[2]PK0P[1]PK0P[0]
$4^{th}$ Parameter11---PK1P[5]PK1P[4]PK1P[3]PK1P[2]PK1P[1]PK1P[0]
$5^{th}$ Parameter11---PK2P[5]PK2P[4]PK2P[3]PK2P[2]PK2P[1]PK2P[0]
$6^{th}$ Parameter11---PK3P[5]PK3P[4]PK3P[3]PK3P[2]PK3P[1]PK3P[0]
$7^{th}$ Parameter11---PK4P[5]PK4P[4]PK4P[3]PK4P[2]PK4P[1]PK4P[0]
$8^{th}$ Parameter11---PK5P[5]PK5P[4]PK5P[3]PK5P[2]PK5P[1]PK5P[0]
$9^{th}$ Parameter11---PK6P[5]PK6P[4]PK6P[3]PK6P[2]PK6P[1]PK6P[0]
$10^{th}$ Parameter11---PK7P[5]PK7P[4]PK7P[3]PK7P[2]PK7P[1]PK7P[0]
$11^{th}$ Parameter11---PK8P[5]PK8P[4]PK8P[3]PK8P[2]PK8P[1]PK8P[0]
$12^{th}$ Parameter11---PK9P[5]PK9P[4]PK9P[3]PK9P[2]PK9P[1]PK9P[0]
$13^{th}$ Parameter11---SELV0P[5]SELV0P[4]SELV0P[3]SELV0P[2]SELV0P[1]SELV0P[0]
$14^{th}$ Parameter11---SELV1P[5]SELV1P[4]SELV1P[3]SELV1P[2]SELV1P[1]SELV1P[0]
$15^{th}$ Parameter11---SELV62P[5]SELV62P[4]SELV62P[3]SELV62P[2]SELV62P[1]SELV62P[0]
$16^{th}$ Parameter11---SELV63P[5]SELV63P[4]SELV63P[3]SELV63P[2]SELV63P[1]SELV63P[0]
Description
Register GroupPositive PolaritySet-up Contents
High Level adjustmentVRF0P[5:0]Variable resistor VRHP
Mid Level AdjustmentSELV0P[5:0]The voltage of V0 grayscale is selected by the 64 to 1
SELV1P[5:0]The voltage of V1 grayscale is selected by the 64 to 1
PK0P[5:0]The voltage of V3 grayscale is selected by the 64 to 1
PK1P[5:0]The voltage of V4 grayscale is selected by the 64 to 1
PK2P[5:0]The voltage of V12 grayscale is selected by the 64 to 1
PK3P[5:0]The voltage of V20 grayscale is selected by the 64 to 1
PK4P[5:0]The voltage of V28 grayscale is selected by the 64 to 1
PK5P[5:0]The voltage of V36 grayscale is selected by the 64 to 1
PK6P[5:0]The voltage of V44 grayscale is selected by the 64 to 1
PK7P[5:0]The voltage of V52 grayscale is selected by the 64 to 1
PK8P[5:0]The voltage of V56 grayscale is selected by the 64 to 1
PK9P[5:0]The voltage of V60 grayscale is selected by the 64 to 1
SELV62P[5:0]The voltage of V62 grayscale is selected by the 64 to 1
SELV63P[5:0]The voltage of V63 grayscale is selected by the 64 to 1
Low Level AdjustmentVOS0P[5:0]Variable Resistor VRLP
+ +
Flow ChartLegend
+ +10.2.18 GMCTRN1 (E1h): Gamma '-'polarity Correction Characteristics Setting + +
E1HGMCTRP0 (Gamma ‘+’Polarity Correction Characteristics Setting)
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
GMCTRP101-11100001(E1h)
$1^{st}$ Parameter11---VRF0N[5]VRF0N[4]VF0N[3]VRF0N[2]VRF0N[1]VRF0N[0]
$2^{nd}$ Parameter11---VOS0N[5]VOS0N[4]VOS0N[3]VOS0N[2]VOS0N[1]VOS0N[0]
$3^{rd}$ Parameter11---PK0N[5]PK0N[4]PK0N[3]PK0N[2]PK0N[1]PK0N[0]
$4^{th}$ Parameter11---PK1N[5]PK1N[4]PK1N[3]PK1N[2]PK1N[1]PK1N[0]
$5^{th}$ Parameter11---PK2N[5]PK2N[4]PK2N[3]PK2N[2]PK2N[1]PK2N[0]
$6^{th}$ Parameter11---PK3N[5]PK3N[4]PK3N[3]PK3N[2]PK3N[1]PK3N[0]
$7^{th}$ Parameter11---PK4N[5]PK4N[4]PK4N[3]PK4N[2]PK4N[1]PK4N[0]
$8^{th}$ Parameter11---PK5N[5]PK5N[4]PK5N[3]PK5N[2]PK5N[1]PK5N[0]
$9^{th}$ Parameter11---PK6N[5]PK6N[4]PK6N[3]PK6N[2]PK6N[1]PK6N[0]
$10^{th}$ Parameter11---PK7N[5]PK7N[4]PK7N[3]PK7N[2]PK7N[1]PK7N[0]
$11^{th}$ Parameter11---PK8N[5]PK8N[4]PK8N[3]PK8N[2]PK8N[1]PK8N[0]
$12^{th}$ Parameter11---PK9[5]PK9N[4]PK9N[3]PK9N[2]PK9N[1]PK9N[0]
$13^{th}$ Parameter11---SELV0N[5]SELV0N[4]SELV0N[3]SELV0N[2]SELV0N[1]SELV0N[0]
$14^{th}$ Parameter11---SELV1N[5]SELV1N[4]SELV1N[3]SELV1N[2]SELV1N[1]SELV1N[0]
$15^{th}$ Parameter11---SELV62N[5]SELV62N[4]SELV62N[3]SELV62N[2]SELV62N[1]SELV62N[0]
$16^{th}$ Parameter11---SELV63N[5]SELV63N[4]SELV63N[3]SELV63N[2]SELV63N[1]SELV63N[0]
Description
Register GroupNegative PolaritySet-up Contents
High level adjustmentVRF0N[5:0]Variable resistor VRHN
Mid Level AdjustmentSELV0N[5:0]The voltage of V0 grayscale is selected by the 64 to 1
SELV1N[5:0]The voltage of V1 grayscale is selected by the 64 to 1
PK0N[5:0]The voltage of V3 grayscale is selected by the 64 to 1
PK1N[5:0]The voltage of V4 grayscale is selected by the 64 to 1
PK2N[5:0]The voltage of V12 grayscale is selected by the 64 to 1
PK3N[5:0]The voltage of V20 grayscale is selected by the 64 to 1
PK4N[5:0]The voltage of V28 grayscale is selected by the 64 to 1
PK5N[5:0]The voltage of V36 grayscale is selected by the 64 to 1
PK6N[5:0]The voltage of V44 grayscale is selected by the 64 to 1
PK7N[5:0]The voltage of V52 grayscale is selected by the 64 to 1
PK8N[5:0]The voltage of V56 grayscale is selected by the 64 to 1
PK9N[5:0]The voltage of V60 grayscale is selected by the 64 to 1
SELV62N[5:0]The voltage of V62 grayscale is selected by the 64 to 1
SELV63N[5:0]The voltage of V63 grayscale is selected by the 64 to 1
Low Level AdjustmentVOS0N[5:0]Variable Resistor VRLN
+ +
Flow Chart
+ +10.2.19 GCV(FCh): Gate Pump Clock Frequency Variable + +
FCHGate Pump Clock Frequency Variable
Inst / ParaD/CXWRXRDXD17-8D7D6D5D4D3D2D1D0HEX
NVFCTR101-11011001(FCh)
Parameter11-GCV_Enable1GCV_Enable00Clk_VariableClk_Variable00
Description-Automatic adjust gate pumping clock for saving power consumption.
Clk_Variable[1:0]Save Power Ability
00Small
01Medium
10High
11Large
DefaultStatusDefault Value (FCh)
Power On Sequence80h
S/W Reset80h
H/W Reset80h
Flow Chart
+ +
Clk_Variable[1:0]Save Power Ability
00Small
01Medium
10High
11Large
+ +
StatusDefault Value (FCh)
Power On Sequence80h
S/W Reset80h
H/W Reset80h
+ +## 11 Power Sturcture + +## 11.1 Driver IC Operating Voltage Specification + +![](images/6f2364631c2218b44412d68689860c7926d74e50f94d371370cd7f89bcd92439.jpg) + +
+flowchart + +```mermaid +graph LR + A["VDD=2.5 V ~ 4.8V"] --> B["Charge Pump Reference Voltage"] + C["AGND=0V"] --> D["Internal Reference Voltage"] + B --> E["VGH=10V ~ 15V"] + B --> F["AVDD=4.5 V ~ 5.2V"] + B --> G["GVDD = 3.15V~5V"] + D --> H["VCOM = -0.425V~-2V"] + D --> I["VCL = -1.8 ~ -VDD"] + D --> J["GVCL = -3.15V~-5V"] + D --> K["AVCL = -4.25 ~ -4.95V"] + D --> L["VGL=-13V~-7.5V"] + E --> L + F --> L + G --> L + H --> L + I --> L + J --> L + K --> L + L --> M["2.4ms interval"] + M --> D +``` +
+ +Fig 15 Power Booster Level + +Note: + +Sleep out flow: AVDD, GVDD, GVCL, VCOM switch on -> 2.4ms -> AVCL, VGH, VGL, VCL switch on -> 78.6ms + +![](images/21eda12298aee7b86faa605214f138c168a0fb41c0586903667c6256cc62c8cd.jpg) + +scan 2 blank frames + +Sleep in flow: Scan 2 blank frames -> All analog power + +## 11.2 Power Booster Circuit + +![](images/da7a00026d691596d955aec75fa981deec453d2a885ee34a8a4a95752d841d46.jpg) + +
+flowchart + +```mermaid +graph LR + A["VDD"] --> B["Reference Voltage generator"] + B --> C["AVDD"] + C --> D["AGND"] + D --> E["VCI1"] + E --> F["Source Output Circuit Block"] + F --> G["Gray reference Circuit Block (Gamma)"] + G --> H["AVDD"] + H --> I["AGND"] + I --> J["AVCL"] + J --> K["AGND"] + K --> L["VCOM"] + L --> M["VCL"] + M --> N["Charge Pump 5"] + N --> O["VDD"] + O --> P["VCI1"] + P --> Q["Charge Pump 2"] + Q --> R["VDD"] + R --> S["Charge Pump 4"] + S --> T["VDD"] + T --> U["Reference Voltage generator"] + U --> V["VDDI"] + V --> W["G1 / G162"] +``` +
+ +## 12 Gamma Structure + +## 12.1 Structure of Grayscale Amplifier + +16 voltage levels (VIN0-VIN15) between GVDD(GVCL) and VSS are determined by the high/ mid/ low level adjustment registers. Each mid-adjustment level is split into 64 levels again by the internal ladder resistor network. As a result, grayscale amplifier generates 64 voltage levels ranging from V0 to V63 and outputs one of 64 levels. + +![](images/d4ca711dc78979a1cc56760a53f1f2627d442a399ea8caa3a5decc9c26a43c84.jpg) + +12.2 Gamma Voltage Formula (Positive/ Negative Polarity) + +
Gray LevelVoltage Formula (Positive)Voltage Formula (Negative)
0VINP0VINP0
1VINP1VINP1
2VINP2VINP2
3VINP3VINP3
4VINP4VINP4
5V4-(V4-V12)*(4/32)V4-(V4-V12)*(4/32)
6V4-(V4-V12)*(8/32)V4-(V4-V12)*(8/32)
7V4-(V4-V12)*(12/32)V4-(V4-V12)*(12/32)
8V4-(V4-V12)*(16/32)V4-(V4-V12)*(16/32)
9V4-(V4-V12)*(20/32)V4-(V4-V12)*(20/32)
10V4-(V4-V12)*(24/32)V4-(V4-V12)*(24/32)
11V4-(V4-V12)*(28/32)V4-(V4-V12)*(28/32)
12VINP5VINP5
13V12-(V12-V20)*(4/32)V12-(V12-V20)*(4/32)
14V12-(V12-V20)*(8/32)V12-(V12-V20)*(8/32)
15V12-(V12-V20)*(12/32)V12-(V12-V20)*(12/32)
16V12-(V12-V20)*(16/32)V12-(V12-V20)*(16/32)
17V12-(V12-V20)*(20/32)V12-(V12-V20)*(20/32)
18V12-(V12-V20)*(24/32)V12-(V12-V20)*(24/32)
19V12-(V12-V20)*(28/32)V12-(V12-V20)*(28/32)
20VINP6VINP6
21V20-(V20-V28)*(4/32)V20-(V20-V28)*(4/32)
22V20-(V20-V28)*(8/32)V20-(V20-V28)*(8/32)
23V20-(V20-V28)*(12/32)V20-(V20-V28)*(12/32)
24V20-(V20-V28)*(16/32)V20-(V20-V28)*(16/32)
25V20-(V20-V28)*(20/32)V20-(V20-V28)*(20/32)
26V20-(V20-V28)*(24/32)V20-(V20-V28)*(24/32)
27V20-(V20-V28)*(28/32)V20-(V20-V28)*(28/32)
28VINP7VINP7
29V28-(V28-V36)*(4/32)V28-(V28-V36)*(4/32)
30V28-(V28-V36)*(8/32)V28-(V28-V36)*(8/32)
31V28-(V28-V36)*(12/32)V28-(V28-V36)*(12/32)
32V28-(V28-V36)*(16/32)V28-(V28-V36)*(16/32)
33V28-(V28-V36)*(20/32)V28-(V28-V36)*(20/32)
34V28-(V28-V36)*(24/32)V28-(V28-V36)*(24/32)
35V28-(V28-V36)*(28/32)V28-(V28-V36)*(28/32)
36VINP8VINP8
37V36-(V36-V44)*(4/32)V36-(V36-V44)*(4/32)
38V36-(V36-V44)*(8/32)V36-(V36-V44)*(8/32)
39V36-(V36-V44)*(12/32)V36-(V36-V44)*(12/32)
40V36-(V36-V44)*(16/32)V36-(V36-V44)*(16/32)
41V36-(V36-V44)*(20/32)V36-(V36-V44)*(20/32)
42V36-(V36-V44)*(24/32)V36-(V36-V44)*(24/32)
43V36-(V36-V44)*(28/32)V36-(V36-V44)*(28/32)
44VINP9VINP9
45V44-(V44-V52)*(4/32)V44-(V44-V52)*(4/32)
46V44-(V44-V52)*(8/32)V44-(V44-V52)*(8/32)
47V44-(V44-V52)*(12/32)V44-(V44-V52)*(12/32)
48V44-(V44-V52)*(16/32)V44-(V44-V52)*(16/32)
49V44-(V44-V52)*(20/32)V44-(V44-V52)*(20/32)
50V44-(V44-V52)*(24/32)V44-(V44-V52)*(24/32)
51V44-(V44-V52)*(28/32)V44-(V44-V52)*(28/32)
52VINP10VINP10
53V52-(V52-V56)*(1/4)V52-(V52-V56)*(1/4)
54V52-(V52-V56)*(2/4)V52-(V52-V56)*(2/4)
55V52-(V52-V56)*(3/4)V52-(V52-V56)*(3/4)
56VINP11VINP11
57V56-(V56-V60)*(1/4)V56-(V56-V60)*(1/4)
58V56-(V56-V60)*(2/4)V56-(V56-V60)*(2/4)
59V56-(V56-V60)*(3/4)V56-(V56-V60)*(3/4)
60VINP12VINP12
61VINP13VINP13
62VINP14VINP14
63VINP15VINP15
+ +## 13 Example Connection with Panel Direction and Different Resolution + +## 13.1 Application of Connection with Panel Direction + +Case 1: (This is default case) + +- $1^{\mathrm{st}}$ Pixel is at Left Top of the panel +- RGB Filter Order = RGB + +![](images/7eb8006296a6a26b6316ba9e9fab305f27925c802c282579494d77440b0b1e84.jpg) + +
+flowchart + +```mermaid +graph LR + A["G1"] -->|P1| B["G161"] + B -->|P2| C["G1"] + C -->|P3| D["G161"] + D -->|P130| E["G160"] + E -->|P131| F["G162"] + F -->|P132| G["G162"] + G -->|G2| H["G2"] + H -->|G4| I["G4"] + I -->|G159| J["G159"] + J -->|G161| K["G161"] + K -->|1st pixel| L["G1"] + L -->|1st pixel| M["G1"] +``` +
+ +- Direction default setting (H/W) +- Display direction control (S/W) +- X-Mirror control by MX +- Y-Mirror control by MY +- XY-Exchange control by MV + +$$ +\mathrm{SMX} = ^ {\prime} 0 ^ {\prime} +$$ + +$$ +\mathrm{SMY} = ^ {\prime} 0 ^ {\prime} +$$ + +$$ +\mathrm{SRGB} = ^ {\prime} 0 ^ {\prime} +$$ + +$$ +\mathrm{S1} = \text {Filter R} +$$ + +$$ +\mathrm{S2} = \text {Filter G} +$$ + +$$ +\mathrm{S3} = \text {Filter B} +$$ + +![](images/3ee636ea7bebeeb74946a6e1d64ff03abebaf351c8b90c657ae8a60ea8dcd29f.jpg) + +
+text_image + +IC (Bump down) +LCD Front side +CF Glass +TFT Glass +
+ +## Case 2: + +- $1^{\mathrm{st}}$ Pixel is at Left Top of the panel +- RGB Filter Order = BGR + +![](images/fb299768348ac925d4d16e8d5da9c0ad05440a3e93e38f079021ecd75b60e922.jpg) + +
+flowchart + +```mermaid +graph LR + A["G1"] -->|P1| B["1st pixel"] + B --> C["G2"] + C --> D["G4"] + D --> E["G160"] + E --> F["G161"] + F --> G["G162"] + G --> H["G162"] + H --> I["G161"] + I --> J["G159"] + J --> K["G3"] + K --> L["G1"] +``` +
+ +- Direction default setting (H/W) +- Display direction control (S/W) +- X-Mirror control by MX +- Y-Mirror control by MY +- XY-Exchange control by MV + +$$ +\mathrm{SMX} = ^ {\prime} 0 ^ {\prime} +$$ + +$$ +\mathrm{SMY} = ^ {\prime} 0 ^ {\prime} +$$ + +$$ +\mathrm{SRGB} = ^ {\prime} 1 ^ {\prime} +$$ + +$$ +\mathrm{S1} = \text {Filter B} +$$ + +$$ +\mathrm{S2} = \text {Filter G} +$$ + +$$ +\mathrm{S3} = \text {Filter R} +$$ + +![](images/b14bbfc9c0a5fb015fba131b7f47e4e2fc2689302d9d5cf84ef5a7a31c84d9fc.jpg) + +
+text_image + +IC (Bump down) +LCD Front side +CF Glass +TFT Glass +
+ +## Case 3: + +- $1^{\mathrm{st}}$ Pixel is at Right Bottom of the panel +- RGB Filter Order = RGB + +![](images/ec541180d5d008cb1ef0a87593b37d463de9cc20de94475cec8a1467530f3426.jpg) + +
+text_image + +Driver IC (bump down) +G161 G1 S1 S396 G2 G162 +P1 P2 P3 P130 P131 P132 +G1 G2 +G3 G4 +G159 +G160 +G161 +1st pixel +G162 +
+ +- Direction default setting (H/W) +- Display direction control (S/W) +- X-Mirror control by MX +- Y-Mirror control by MY +- XY-Exchange control by MV + +$$ +\mathrm{SMX} = ^ {\prime} 1 ^ {\prime} +$$ + +$$ +\mathrm{SMY} = ^ {\prime} 1 ^ {\prime} +$$ + +$$ +\mathrm{SRGB} = ^ {\prime} 0 ^ {\prime} +$$ + +$$ +\mathrm{S1} = \text {Filter R} +$$ + +$$ +\mathrm{S2} = \text {Filter G} +$$ + +$$ +\mathrm{S3} = \text {Filter B} +$$ + +![](images/89ef60762cda2d9f7b7e3b3858c1a7dc637f7742c68b2b1f2fc97e6e7b7edb64.jpg) + +
+text_image + +IC (Bump down) +LCD Front side +CF Glass +TFT Glass +
+ +## Case 4: + +- $1^{\mathrm{st}}$ Pixel is at Right Bottom of the panel +- RGB Filter Order = BGR + +![](images/9102ffed2e68dd9bf257dbfd60582ae683a91777d7ea61f50718d2a6e81a4594.jpg) + +
+text_image + +Driver IC (bump down) +G161 G1 S1 S396 G2 G162 +P1 P2 P3 P130 P131 P132 +G1 G2 +G3 G4 +G159 G160 +G161 G162 +1st pixel +
+ +- Direction default setting (H/W) +- Display direction control (S/W) +- X-Mirror control by MX +- Y-Mirror control by MY +- XY-Exchange control by MV + +$$ +\mathrm{SMX} = ^ {\prime} 1 ^ {\prime} +$$ + +$$ +\mathrm{SMY} = ^ {\prime} 1 ^ {\prime} +$$ + +$$ +\mathrm{SRGB} = ^ {\prime} 1 ^ {\prime} +$$ + +$$ +\mathrm{S1} = \text {Filter B} +$$ + +$$ +\mathrm{S2} = \text {Filter G} +$$ + +$$ +\mathrm{S3} = \text {Filter R} +$$ + +![](images/6e47dd4ebe36093522825ce3876b2fbe2551a28ee57482cf0b00f3495be5e3bb.jpg) + +
+text_image + +IC (Bump down) +LCD Front side +CF Glass +TFT Glass +
+ +## 13.2 Application of Connection with Different Resolution + +Case1 of Resolution (128RGB x 160) (GM[1:0] = "11") + +RAM Size=128 x 160 x 18-bit (Used) + +Display Size = 128RGB x 160 + +1). Example for SMX=SMY='0' +![](images/9cb88db7ccf5a4f9167a4e2fa1735fd00d6b7269c32328e20c893788b8ec7ee8.jpg) + +
+text_image + +GRAM size = 128x 160x 18-bits +(0, 0) +00h 01h 02h 7Eh 7Fh 83h +00h +01h +02h +(127, 159) +9Fh +A1h +Driver IC (bump down) +G161 G3 S7 S390 G2 G160 +P1 P2 P3 P126 P127 P128 +G2 +G3 +G4 +G157 +G159 +G160 +- Direction default setting (H/W) +SMX = '0' +SMY = '0' +SRGB = '0' +- Display direction control (S/W) +- X-Mirror control by MX +- Y-Mirror control by MY +- XY-Exchange control by MV +
+ +2). Example for SMX=SMY='1' +![](images/661adcb67703a05101a412c13db6df638f40b3cc1dd781e36dcecfe59553b4d8.jpg) + +
+text_image + +GRAM size = 128 x 160 x 18-bits +(0, 0) +00h 01h 02h 7Eh 7Fh 83h +00h +01h +02h +(127, 159) +9Fh +A1h +Driver IC (bump down) +G161 G3 S7 S390 G2 G160 +G2 +1st pixel +G3 +G4 +G157 +G159 +G160 +- Display direction control (S/W) +- X-Mirror control by MX +- Y-Mirror control by MY +- XY-Exchange control by MV +- Direction default setting (H/W) +SMX ='1' +SMY ='1' +SRGB ='0' +
+ +Case2 of Resolution (132RGB x 132) (GM[1:0] = "01") + +RAM size=132 x 132 x 18-bit (Used) + +Display size = 132RGB x 132 + +1). Example for SMX=SMY='0' + +![](images/f6c8ca059ec025c9d60d6e615fe951a1c7401b0ee1b4656b8f32bfb52d4b1e89.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Left_Process + A["00h 00h 01h 02h 82h 83h"] --> B["Display direction control (S/W)\nX-Mirror control by MX\nY-Mirror control by MY\nXY-Exchange control by MV"] + end + + subgraph Right_Process + B --> C["Driver IC (bump down)\nG1 1st pixel"] + C --> D["Direction default setting (H/W)\nSMX = '0'\nSMY = '0'\nSRGB = '0'"] + end +``` +
+ +2). Example for SMX=SMY='1' + +![](images/b5c103bf0e7b60e8efdd94b6ea6e0e3bcec5083561ea4027296f51f4d24ab523.jpg) + +
+flowchart + +```mermaid +graph LR + subgraph Initial_Process + A["Display direction control (S/W)\nX-Mirror control by MX\nY-Mirror control by MY\nXY-Exchange control by MV"] --> B["(131, 131)"] + end + + subgraph Driver_IC + B --> C["1st pixel"] + C --> D["Driver IC (bump down)"] + end + + subgraph Final_Process + E["Direction default setting (H/W)\nSMX = '1'\nSMY = '1'\nSRGB = '0'"] --> F["Driver IC (bump down)"] + end +``` +
+ +Case3 of Resolution (132RGB x 162) (GM[1:0] = "00") + +RAM Size=132 x 162 x 18-bit (Used) + +Display Size = 132RGB x 162 + +1). Example for SMX=SMY='0' +![](images/66e7378c694df620ea374b286deb068df506cad03eca9ee6ad35998a20638f52.jpg) + +
+text_image + +GRAM size = 13/2 x 16/2 x 18-bits +(0, 0) +00h 01h 02h 82h 83h +00h +01h +02h +(131, 161) +A0h +A1h +- Display direction control (S/W) +- X-Mirror control by MX +- Y-Mirror control by MY +- XY-Exchange control by MV +Driver IC (bump down) +G161 G3 S7 S390 G2 G160 +P1 P2 P3 P130 P131 P132 +G2 +1st pixel +G3 +G15 +9 +G16 +0 +G16 +1 +- Direction default setting (H/W) +SMX = '0' +SMY = '0' +SRGB = '0' +
+ +2). Example for SMX=SMY='1' +![](images/83ec30befacc41ef50bf53afd20250dfb6ccfeef38f97e11b93c280eba8c585e.jpg) + +
+flowchart + +This diagram illustrates a memory layout and data flow for a 18-bit RAM, showing the interaction between a grid and a driver IC (bump down) with directional control logic. +
+ +## 13.3 Microprocessor Interface Applications + +## 13.3.1 8080-Series MCU Interface for 8-bit Data Bus (P68=0, IM2, IM1, IM0="100") + +80 Serial MPU 8-Bit Bus +![](images/29d7c89baa34488cf0540ae2866a37a3783be32f64425fd688a6fdc88cebe9dd.jpg) + +
+text_image + +MPU +VDDI GND +Driver IC +SPI4W +IM2 +IM1 +IM0 +RESX +CSX +D/CX +RDX +WRX +D7 to D0 +GND +RESX +CSX +D/CX (SCL) +RDX (E) +WRX (R/WX) +D7 to D0 +D17 to D8 +P68 +
+ +## 13.3.2 8080-Series MCU Interface for 16-bit Data Bus (P68=0, IM2, IM1, IM0="101") + +80 Serial MPU 16-Bit Bus +![](images/fd7884bdd300c9545fd5689898a1ccb47befa6c57b635ba890ebad3b21029e82.jpg) + +
+text_image + +MPU +VDDI +GND +Driver IC +SPI4W +IM2 +IM1 +IMO +RESX +CSX +D/CX +RDX +WRX +D15 to D0 +GND +D/CX (SCL) +RDX (E) +WRX (R/WX) +D15 to D0 +D17 to D16 +P68 +
+ +## 13.3.3 8080-Series MCU Interface for 9-bit Data Bus (P68=0, IM2, IM1, IM0="110") + +80 Serial MPU 9-Bit Bus +![](images/2acb16ffe5b4406fce997f6fdda7d71148bb1478d420ffd6724e38d059882cfe.jpg) + +
+text_image + +MPU +VDDI +GND +Driver IC +SPI4W +IM2 +IM1 +IM0 +RESX +CSX +D/CX +RDX +WRX +D8 to D0 +GND +RESX +CSX +D/CX (SCL) +RDX (E) +WRX (R/WX) +D8 to D0 +D17 to D9 +P68 +
+ +13.3.4 8080-Series MCU Interface for 18-bit Data Bus (P68=0, IM2, IM1, IM0="111") + +80 Serial MPU 18-Bit Bus +![](images/d2c7b295e3535c73ce2a23637a618a8c1bda2b907111da36ccf018fc7b196fcc.jpg) + +
+text_image + +MPU +VDDI +GND +Driver IC +SPI4W +IM2 +IM1 +IMO +RESX +CSX +D/CX +RDX +WRX +D17 to D0 +GND +RESX +CSX +D/CX (SCL) +RDX (E) +WRX (R/WX) +D17 to D0 +P68 +
+ +13.3.5 6800-Series MCU Interface for 8-bit Data Bus (P68=1, IM2, IM1, IM0="100") + +68 Serial MPU 8-Bit Bus +![](images/a4ff01fa0723727849d6829ab086faa9f011376c9ca449cbaf4a36fc779168c4.jpg) + +
+text_image + +MPU +VDDI GND Driver IC +SPI4W +IM2 +IM1 +IMO +RESX +CSX +D/CX +E +R/WX +D7 to D0 +GND VDDI +D/CX (SCL) +RDX (E) +WRX (R/WX) +D7 to D0 +D17 to D8 +P68 +
+ +13.3.6 6800-Series MCU Interface for 16-bit Data Bus (P68=1, IM2, IM1, IM0="101") + +68 Serial MPU 16-Bit Bus +![](images/1d6958a680b018342295a42fcfa517d70e672c81bc42720e440391506507c231.jpg) + +
+text_image + +MPU +VDDI +GND +Driver IC +SPI4W +IM2 +IM1 +IM0 +RESX +CSX +D/CX +E +R/WX +D15 to D0 +GND +VDDI +RESX +CSX +D/CX (SCL) +RDX (E) +WRX (R/WX) +D15 to D0 +D17 to D16 +P68 +
+ +13.3.7 6800-Series MCU Interface for 9-bit Data Bus (P68=1, IM2, IM1, IM0="110") + +68 Serial MPU 9-Bit Bus +![](images/681b019f67321cb5b8f0f0a7e4409ed6c9a187b2dea358f8eb4e79ab8338ffbb.jpg) + +
+text_image + +MPU +VDDI +GND +Driver IC +SPI4W +IM2 +IM1 +IM0 +RESX +CSX +D/CX +E +R/WX +D8 to D0 +GND +VDDI +RESX +CSX +D/CX (SCL) +RDX (E) +WRX (R/WX) +D8 to D0 +D17 to D9 +P68 +
+ +13.3.8 6800-Series MCU Interface for 18-bit Data Bus (P68=1, IM2, IM1, IM0="111") + +68 Serial MPU 18-Bit Bus +![](images/e006faad0d9444eab3051fc1baa51fdbd9e1a3231106d5e519efa4ff99244523.jpg) + +
+text_image + +MPU +VDDI +GND +SP14W +IM2 +IM1 +IM0 +RESX +CSX +D/CX +E +R/WX +D17 to D0 +Driver IC +RESX +CSX +D/CX (SCL) +RDX (E) +WRX (R/WX) +D17 to D0 +VDDI +P68 +
+ +13.3..9 3-Line Serial MCU Interface (IM2, IM1, IM0="000", SPI4W=0) + +3-Pin Serial Mode +![](images/12cf329e064956c862da56a811b83a35a13b54a7d64bb52fbe8651777959a0ae.jpg) + +
+text_image + +MPU +Driver IC +SPI4W +IM2 +IM1 +IM0 +GND +RESX +CSX +GND-I +RESX +CSX +RDX,WRX +SCL +SDA +D/CX (SCL) +SDA(D0) +D17 to D1 +GND +
+ +13.3.10 4-Line Serial MCU Interface (IM2, IM1, IM0="000", SPI4W=1) + +4-Pin Serial Mode +![](images/7238156e6fd754811bf0c991d77f81df9e8f005d58e593c7aae68cd405804d6e.jpg) + +
+text_image + +MPU +VDDI +Driver IC +SPI4W +IM2 +IM1 +IM0 +GND +RESX +CSX +GND·I +RESX +CSX +RDX +D/CX +SCL +SDA +WRX(D/CX) +D/CX (SCL) +SDA(D0) +D17 to D1 +GND +
+ +14 Revision History + +
ST7735S Specification Revision History
VersionDateDescription
1.02011/06/10First issue.
1.12011/11/21Modify ID1 Value.
\ No newline at end of file diff --git a/STM32F103C8T6/.mxproject b/STM32F103C8T6/.mxproject index 159a0a0..b534278 100644 --- a/STM32F103C8T6/.mxproject +++ b/STM32F103C8T6/.mxproject @@ -1,32 +1,36 @@ [PreviousLibFiles] -LibFiles=Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f103xb.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h; +LibFiles=Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_adc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_adc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_adc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_adc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_adc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_adc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_adc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_adc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_spi.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f103xb.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h; [PreviousUsedKeilFiles] -SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\dma.c;..\Core\Src\spi.c;..\Core\Src\usart.c;..\Core\Src\stm32f1xx_it.c;..\Core\Src\stm32f1xx_hal_msp.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;;; +SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\adc.c;..\Core\Src\dma.c;..\Core\Src\spi.c;..\Core\Src\tim.c;..\Core\Src\usart.c;..\Core\Src\stm32f1xx_it.c;..\Core\Src\stm32f1xx_hal_msp.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_adc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_adc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_adc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_adc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_spi.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;;; HeaderPath=..\Drivers\STM32F1xx_HAL_Driver\Inc;..\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F1xx\Include;..\Drivers\CMSIS\Include;..\Core\Inc; CDefines=USE_HAL_DRIVER;STM32F103xB;USE_HAL_DRIVER;USE_HAL_DRIVER; [PreviousGenFiles] AdvancedFolderStructure=true -HeaderFileListSize=7 +HeaderFileListSize=9 HeaderFiles#0=..\Core\Inc\gpio.h -HeaderFiles#1=..\Core\Inc\dma.h -HeaderFiles#2=..\Core\Inc\spi.h -HeaderFiles#3=..\Core\Inc\usart.h -HeaderFiles#4=..\Core\Inc\stm32f1xx_it.h -HeaderFiles#5=..\Core\Inc\stm32f1xx_hal_conf.h -HeaderFiles#6=..\Core\Inc\main.h +HeaderFiles#1=..\Core\Inc\adc.h +HeaderFiles#2=..\Core\Inc\dma.h +HeaderFiles#3=..\Core\Inc\spi.h +HeaderFiles#4=..\Core\Inc\tim.h +HeaderFiles#5=..\Core\Inc\usart.h +HeaderFiles#6=..\Core\Inc\stm32f1xx_it.h +HeaderFiles#7=..\Core\Inc\stm32f1xx_hal_conf.h +HeaderFiles#8=..\Core\Inc\main.h HeaderFolderListSize=1 HeaderPath#0=..\Core\Inc HeaderFiles=; -SourceFileListSize=7 +SourceFileListSize=9 SourceFiles#0=..\Core\Src\gpio.c -SourceFiles#1=..\Core\Src\dma.c -SourceFiles#2=..\Core\Src\spi.c -SourceFiles#3=..\Core\Src\usart.c -SourceFiles#4=..\Core\Src\stm32f1xx_it.c -SourceFiles#5=..\Core\Src\stm32f1xx_hal_msp.c -SourceFiles#6=..\Core\Src\main.c +SourceFiles#1=..\Core\Src\adc.c +SourceFiles#2=..\Core\Src\dma.c +SourceFiles#3=..\Core\Src\spi.c +SourceFiles#4=..\Core\Src\tim.c +SourceFiles#5=..\Core\Src\usart.c +SourceFiles#6=..\Core\Src\stm32f1xx_it.c +SourceFiles#7=..\Core\Src\stm32f1xx_hal_msp.c +SourceFiles#8=..\Core\Src\main.c SourceFolderListSize=1 SourcePath#0=..\Core\Src SourceFiles=; diff --git a/STM32F103C8T6/Core/Inc/adc.h b/STM32F103C8T6/Core/Inc/adc.h new file mode 100644 index 0000000..68631ad --- /dev/null +++ b/STM32F103C8T6/Core/Inc/adc.h @@ -0,0 +1,52 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.h + * @brief This file contains all the function prototypes for + * the adc.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __ADC_H__ +#define __ADC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern ADC_HandleTypeDef hadc1; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_ADC1_Init(void); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ADC_H__ */ + diff --git a/STM32F103C8T6/Core/Inc/stm32f1xx_hal_conf.h b/STM32F103C8T6/Core/Inc/stm32f1xx_hal_conf.h index 6dab2e3..bcf6648 100644 --- a/STM32F103C8T6/Core/Inc/stm32f1xx_hal_conf.h +++ b/STM32F103C8T6/Core/Inc/stm32f1xx_hal_conf.h @@ -34,7 +34,7 @@ */ #define HAL_MODULE_ENABLED - /*#define HAL_ADC_MODULE_ENABLED */ + #define HAL_ADC_MODULE_ENABLED /*#define HAL_CRYP_MODULE_ENABLED */ /*#define HAL_CAN_MODULE_ENABLED */ /*#define HAL_CAN_LEGACY_MODULE_ENABLED */ @@ -64,7 +64,7 @@ /*#define HAL_SMARTCARD_MODULE_ENABLED */ #define HAL_SPI_MODULE_ENABLED /*#define HAL_SRAM_MODULE_ENABLED */ -/*#define HAL_TIM_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED /*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */ diff --git a/STM32F103C8T6/Core/Inc/tim.h b/STM32F103C8T6/Core/Inc/tim.h new file mode 100644 index 0000000..6bd0a6b --- /dev/null +++ b/STM32F103C8T6/Core/Inc/tim.h @@ -0,0 +1,57 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.h + * @brief This file contains all the function prototypes for + * the tim.c file + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TIM_H__ +#define __TIM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "main.h" + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +extern TIM_HandleTypeDef htim3; + +extern TIM_HandleTypeDef htim4; + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +void MX_TIM3_Init(void); +void MX_TIM4_Init(void); + +void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim); + +/* USER CODE BEGIN Prototypes */ + +/* USER CODE END Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif /* __TIM_H__ */ + diff --git a/STM32F103C8T6/Core/Src/adc.c b/STM32F103C8T6/Core/Src/adc.c new file mode 100644 index 0000000..80e5c1a --- /dev/null +++ b/STM32F103C8T6/Core/Src/adc.c @@ -0,0 +1,172 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file adc.c + * @brief This file provides code for the configuration + * of the ADC instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "adc.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +ADC_HandleTypeDef hadc1; + +/* ADC1 init function */ +void MX_ADC1_Init(void) +{ + + /* USER CODE BEGIN ADC1_Init 0 */ + + /* USER CODE END ADC1_Init 0 */ + + ADC_ChannelConfTypeDef sConfig = {0}; + ADC_InjectionConfTypeDef sConfigInjected = {0}; + + /* USER CODE BEGIN ADC1_Init 1 */ + + /* USER CODE END ADC1_Init 1 */ + + /** Common config + */ + hadc1.Instance = ADC1; + hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE; + hadc1.Init.ContinuousConvMode = DISABLE; + hadc1.Init.DiscontinuousConvMode = DISABLE; + hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; + hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; + hadc1.Init.NbrOfConversion = 1; + if (HAL_ADC_Init(&hadc1) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Regular Channel + */ + sConfig.Channel = ADC_CHANNEL_0; + sConfig.Rank = ADC_REGULAR_RANK_1; + sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; + if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Injected Channel + */ + sConfigInjected.InjectedChannel = ADC_CHANNEL_0; + sConfigInjected.InjectedRank = ADC_INJECTED_RANK_1; + sConfigInjected.InjectedNbrOfConversion = 4; + sConfigInjected.InjectedSamplingTime = ADC_SAMPLETIME_41CYCLES_5; + sConfigInjected.ExternalTrigInjecConv = ADC_EXTERNALTRIGINJECCONV_T3_CC4; + sConfigInjected.AutoInjectedConv = DISABLE; + sConfigInjected.InjectedDiscontinuousConvMode = DISABLE; + sConfigInjected.InjectedOffset = 0; + if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Injected Channel + */ + sConfigInjected.InjectedChannel = ADC_CHANNEL_1; + sConfigInjected.InjectedRank = ADC_INJECTED_RANK_2; + if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Injected Channel + */ + sConfigInjected.InjectedChannel = ADC_CHANNEL_2; + sConfigInjected.InjectedRank = ADC_INJECTED_RANK_3; + if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) + { + Error_Handler(); + } + + /** Configure Injected Channel + */ + sConfigInjected.InjectedChannel = ADC_CHANNEL_3; + sConfigInjected.InjectedRank = ADC_INJECTED_RANK_4; + if (HAL_ADCEx_InjectedConfigChannel(&hadc1, &sConfigInjected) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN ADC1_Init 2 */ + + /* USER CODE END ADC1_Init 2 */ + +} + +void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspInit 0 */ + + /* USER CODE END ADC1_MspInit 0 */ + /* ADC1 clock enable */ + __HAL_RCC_ADC1_CLK_ENABLE(); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + /**ADC1 GPIO Configuration + PA0-WKUP ------> ADC1_IN0 + PA1 ------> ADC1_IN1 + PA2 ------> ADC1_IN2 + PA3 ------> ADC1_IN3 + */ + GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /* USER CODE BEGIN ADC1_MspInit 1 */ + + /* USER CODE END ADC1_MspInit 1 */ + } +} + +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle) +{ + + if(adcHandle->Instance==ADC1) + { + /* USER CODE BEGIN ADC1_MspDeInit 0 */ + + /* USER CODE END ADC1_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_ADC1_CLK_DISABLE(); + + /**ADC1 GPIO Configuration + PA0-WKUP ------> ADC1_IN0 + PA1 ------> ADC1_IN1 + PA2 ------> ADC1_IN2 + PA3 ------> ADC1_IN3 + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); + + /* USER CODE BEGIN ADC1_MspDeInit 1 */ + + /* USER CODE END ADC1_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + diff --git a/STM32F103C8T6/Core/Src/gpio.c b/STM32F103C8T6/Core/Src/gpio.c index 50ed216..a37e375 100644 --- a/STM32F103C8T6/Core/Src/gpio.c +++ b/STM32F103C8T6/Core/Src/gpio.c @@ -47,8 +47,8 @@ void MX_GPIO_Init(void) /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); - __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); diff --git a/STM32F103C8T6/Core/Src/main.c b/STM32F103C8T6/Core/Src/main.c index eb7cc91..602dd61 100644 --- a/STM32F103C8T6/Core/Src/main.c +++ b/STM32F103C8T6/Core/Src/main.c @@ -18,16 +18,19 @@ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" +#include "adc.h" #include "dma.h" #include "spi.h" +#include "tim.h" #include "usart.h" #include "gpio.h" -#include "lcd_data.h" + /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include #include "button_driver.h" #include "st7735s.h" +#include "lcd.h" /* USER CODE END Includes */ @@ -86,7 +89,9 @@ int main(void) SystemClock_Config(); /* USER CODE BEGIN SysInit */ - + /* ADC 时钟预分频:PCLK2 / 6 = 72/6 = 12MHz */ + /* 默认 /2=36MHz 超过 14MHz 规格,ADC 无法正常工作 */ + RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_ADCPRE) | RCC_CFGR_ADCPRE_DIV6; /* USER CODE END SysInit */ /* Initialize all configured peripherals */ @@ -94,18 +99,47 @@ int main(void) MX_DMA_Init(); MX_USART1_UART_Init(); MX_SPI2_Init(); + MX_TIM4_Init(); + MX_ADC1_Init(); + MX_TIM3_Init(); /* USER CODE BEGIN 2 */ printf("\r\nSTM32F103C8T6 Boot OK\r\n"); button_driver_init(); st7735s_init(); st7735s_fill_screen(COLOR_RED); HAL_Delay(500); - st7735s_fill_screen(COLOR_GREEN); - HAL_Delay(500); - st7735s_fill_screen(COLOR_BLUE); - HAL_Delay(500); st7735s_fill_screen(COLOR_BLACK); - st7735s_draw_string(0, 0, "LCD OK", COLOR_WHITE, COLOR_BLACK); + lcd_draw_string(0, 0, "01234", COLOR_WHITE, COLOR_BLACK); + lcd_draw_string(0, 16, "LCD_OK", COLOR_WHITE, COLOR_BLACK); + + lcd_draw_chinese_string(0, 32, "\xE9\x98\x9C\xE9\x98\xB3\xE5\xB8\x88\xE8\x8C\x83\xE5\xA4\xA7\xE5\xAD\xA6", COLOR_WHITE, COLOR_BLACK); /*阜阳师范大学*/ + lcd_draw_chinese_string(0, 48, "\xE7\x94\xB5\xE5\xAD\x90\xE8\xAE\xBE\xE8\xAE\xA1\xE7\xAB\x9E\xE8\xB5\x9B", COLOR_WHITE, COLOR_BLACK); /*电子设计竞赛*/ + + /* 启动 TIM4 四路 PWM */ + HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1); /* PB6 */ + HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2); /* PB7 */ + HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3); /* PB8 */ + HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4); /* PB9 */ + + /* 设置占空比(0~999 对应 0%~100%) */ + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, 500); /* 50% */ + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, 250); /* 25% */ + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, 750); /* 75% */ + __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_4, 999); /* 100% */ + + /* === 测试:常规组软件触发,确认 ADC 硬件正常 === */ + HAL_ADC_Start(&hadc1); + if (HAL_ADC_PollForConversion(&hadc1, 100) == HAL_OK) { + printf("ADC REG TEST: %d\r\n", HAL_ADC_GetValue(&hadc1)); + } + HAL_ADC_Stop(&hadc1); + + /* 启动 TIM3 CH4(产生 ADC 触发信号) */ + HAL_TIM_OC_Start(&htim3, TIM_CHANNEL_4); + + /* 启动 ADC 注入组(TIM3 每触发一次,自动采一轮 PA0~PA3) */ + HAL_ADCEx_InjectedStart(&hadc1); + /* USER CODE END 2 */ /* Infinite loop */ @@ -115,9 +149,15 @@ int main(void) /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ - HAL_Delay(500); + HAL_Delay(1000); HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); - //printf("Hello word\n"); + + /* 读取 ADC 注入组结果(TIM3 以 1kHz 触发,每秒打印一次最新值) */ + uint16_t adc0 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1); + uint16_t adc1 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2); + uint16_t adc2 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_3); + uint16_t adc3 = HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_4); + printf("ADC: %4d %4d %4d %4d\r\n", adc0, adc1, adc2, adc3); } /* USER CODE END 3 */ } @@ -130,6 +170,7 @@ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. @@ -159,6 +200,12 @@ void SystemClock_Config(void) { Error_Handler(); } + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; + PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + Error_Handler(); + } } /* USER CODE BEGIN 4 */ diff --git a/STM32F103C8T6/Core/Src/spi.c b/STM32F103C8T6/Core/Src/spi.c index abe913e..26ae4a5 100644 --- a/STM32F103C8T6/Core/Src/spi.c +++ b/STM32F103C8T6/Core/Src/spi.c @@ -42,8 +42,8 @@ void MX_SPI2_Init(void) hspi2.Init.Mode = SPI_MODE_MASTER; hspi2.Init.Direction = SPI_DIRECTION_2LINES; hspi2.Init.DataSize = SPI_DATASIZE_8BIT; - hspi2.Init.CLKPolarity = SPI_POLARITY_LOW; - hspi2.Init.CLKPhase = SPI_PHASE_1EDGE; + hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH; + hspi2.Init.CLKPhase = SPI_PHASE_2EDGE; hspi2.Init.NSS = SPI_NSS_SOFT; hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB; diff --git a/STM32F103C8T6/Core/Src/tim.c b/STM32F103C8T6/Core/Src/tim.c new file mode 100644 index 0000000..112126e --- /dev/null +++ b/STM32F103C8T6/Core/Src/tim.c @@ -0,0 +1,239 @@ +/* USER CODE BEGIN Header */ +/** + ****************************************************************************** + * @file tim.c + * @brief This file provides code for the configuration + * of the TIM instances. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ +/* USER CODE END Header */ +/* Includes ------------------------------------------------------------------*/ +#include "tim.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +TIM_HandleTypeDef htim3; +TIM_HandleTypeDef htim4; + +/* TIM3 init function */ +void MX_TIM3_Init(void) +{ + + /* USER CODE BEGIN TIM3_Init 0 */ + + /* USER CODE END TIM3_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM3_Init 1 */ + + /* USER CODE END TIM3_Init 1 */ + htim3.Instance = TIM3; + htim3.Init.Prescaler = 71; + htim3.Init.CounterMode = TIM_COUNTERMODE_UP; + htim3.Init.Period = 999; + htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&htim3) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim3) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 500; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM3_Init 2 */ + /* 注意:若从 CubeMX 重新生成,务必在 TIM3 CH4 的 OC Mode 选 PWM1,Pulse 设 500, + 否则 ADC 注入组外部触发无法工作。 + 此处手动修改 sConfigOC.OCMode 和 sConfigOC.Pulse 为 PWM1/500 */ + /* USER CODE END TIM3_Init 2 */ + +} +/* TIM4 init function */ +void MX_TIM4_Init(void) +{ + + /* USER CODE BEGIN TIM4_Init 0 */ + + /* USER CODE END TIM4_Init 0 */ + + TIM_ClockConfigTypeDef sClockSourceConfig = {0}; + TIM_MasterConfigTypeDef sMasterConfig = {0}; + TIM_OC_InitTypeDef sConfigOC = {0}; + + /* USER CODE BEGIN TIM4_Init 1 */ + + /* USER CODE END TIM4_Init 1 */ + htim4.Instance = TIM4; + htim4.Init.Prescaler = 71; + htim4.Init.CounterMode = TIM_COUNTERMODE_UP; + htim4.Init.Period = 999; + htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; + if (HAL_TIM_Base_Init(&htim4) != HAL_OK) + { + Error_Handler(); + } + sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; + if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_Init(&htim4) != HAL_OK) + { + Error_Handler(); + } + sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.OCMode = TIM_OCMODE_PWM1; + sConfigOC.Pulse = 500; + sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; + sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; + if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) + { + Error_Handler(); + } + if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_2) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.Pulse = 0; + if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_3) != HAL_OK) + { + Error_Handler(); + } + sConfigOC.Pulse = 500; + if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_4) != HAL_OK) + { + Error_Handler(); + } + /* USER CODE BEGIN TIM4_Init 2 */ + + /* USER CODE END TIM4_Init 2 */ + HAL_TIM_MspPostInit(&htim4); + +} + +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspInit 0 */ + + /* USER CODE END TIM3_MspInit 0 */ + /* TIM3 clock enable */ + __HAL_RCC_TIM3_CLK_ENABLE(); + /* USER CODE BEGIN TIM3_MspInit 1 */ + + /* USER CODE END TIM3_MspInit 1 */ + } + else if(tim_baseHandle->Instance==TIM4) + { + /* USER CODE BEGIN TIM4_MspInit 0 */ + + /* USER CODE END TIM4_MspInit 0 */ + /* TIM4 clock enable */ + __HAL_RCC_TIM4_CLK_ENABLE(); + /* USER CODE BEGIN TIM4_MspInit 1 */ + + /* USER CODE END TIM4_MspInit 1 */ + } +} +void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) +{ + + GPIO_InitTypeDef GPIO_InitStruct = {0}; + if(timHandle->Instance==TIM4) + { + /* USER CODE BEGIN TIM4_MspPostInit 0 */ + + /* USER CODE END TIM4_MspPostInit 0 */ + + __HAL_RCC_GPIOB_CLK_ENABLE(); + /**TIM4 GPIO Configuration + PB6 ------> TIM4_CH1 + PB7 ------> TIM4_CH2 + PB8 ------> TIM4_CH3 + PB9 ------> TIM4_CH4 + */ + GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /* USER CODE BEGIN TIM4_MspPostInit 1 */ + + /* USER CODE END TIM4_MspPostInit 1 */ + } + +} + +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) +{ + + if(tim_baseHandle->Instance==TIM3) + { + /* USER CODE BEGIN TIM3_MspDeInit 0 */ + + /* USER CODE END TIM3_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM3_CLK_DISABLE(); + /* USER CODE BEGIN TIM3_MspDeInit 1 */ + + /* USER CODE END TIM3_MspDeInit 1 */ + } + else if(tim_baseHandle->Instance==TIM4) + { + /* USER CODE BEGIN TIM4_MspDeInit 0 */ + + /* USER CODE END TIM4_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_TIM4_CLK_DISABLE(); + /* USER CODE BEGIN TIM4_MspDeInit 1 */ + + /* USER CODE END TIM4_MspDeInit 1 */ + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + diff --git a/STM32F103C8T6/Core/Src/usart.c b/STM32F103C8T6/Core/Src/usart.c index 2f00a65..a275413 100644 --- a/STM32F103C8T6/Core/Src/usart.c +++ b/STM32F103C8T6/Core/Src/usart.c @@ -117,6 +117,33 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) /* 引入标准输入输出头文件,包含fputc函数原型和FILE类型定义 */ #include +/* 禁用半主机模式 + * 不勾选MicroLIB时,标准库默认使用半主机(Semihosting)实现printf。 + * 半主机需要调试器支持,脱机运行时会导致程序卡死。 + * __use_no_semihosting 让链接器不链接半主机相关函数, + * 同时我们必须提供_sys_exit等替代函数。 + */ +#pragma import(__use_no_semihosting) + +/* 标准库要求提供 __FILE 结构体定义和 __stdout 实例 */ +struct __FILE { + int handle; +}; +FILE __stdout; + +/* 退出函数 — 标准库在用完 _sys_exit 后调用,此处空实现 */ +void _sys_exit(int return_code) +{ + (void)return_code; + while (1); +} + +/* 写字符 — 底层 tty 输出钩子,供某些 stdio 函数调用 */ +void _ttywrch(int ch) +{ + HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); +} + /** * @brief 重定向fputc函数,将printf输出重定向到串口1 * @param ch: 要发送的字符 @@ -127,16 +154,16 @@ int fputc(int ch, FILE *f) { /* 消除未使用参数f的编译警告 */ (void)f; - + /* 调用HAL库串口发送函数,发送单个字符 */ /* 参数说明: &huart1: 串口1的句柄(若使用其他串口,改为对应的句柄,如&huart2) (uint8_t *)&ch: 要发送的数据缓冲区地址 1: 发送数据的长度(单个字符) - HAL_MAX_DELAY: 超时时间(无限等待,确保发送完成) + HAL_MAX_DELAY: 超时时间(无限等待,确保发送成功) */ HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); - + /* 返回发送的字符,符合fputc函数的返回值要求 */ return ch; } diff --git a/STM32F103C8T6/Drivers/BSP/LCD/hz16_data.c b/STM32F103C8T6/Drivers/BSP/LCD/hz16_data.c new file mode 100644 index 0000000..9cfdf81 --- /dev/null +++ b/STM32F103C8T6/Drivers/BSP/LCD/hz16_data.c @@ -0,0 +1,41 @@ +/* 16×16 CJK 字库,由 font_gen.py 生成(自定义) */ + +#include "hz16_data.h" + +static const uint8_t cjk_bitmaps[][32] = { + { 0x00, 0x00, 0x01, 0x00, 0x03, 0x80, 0x02, 0xC0, 0x06, 0x60, 0x0C, 0x30, 0x18, 0x3E, 0x3F, 0xFE, 0x41, 0x80, 0x01, 0x90, 0x1F, 0xF8, 0x01, 0x80, 0x01, 0x80, 0x01, 0x84, 0x7F, 0xFE, 0x00, 0x00 }, /* U+5168 全 */ + { 0x00, 0x00, 0x3F, 0xFC, 0x30, 0x14, 0x3F, 0xFC, 0x31, 0x84, 0x31, 0x84, 0x27, 0xF4, 0x35, 0xC4, 0x31, 0xE4, 0x31, 0xA4, 0x31, 0xBC, 0x3F, 0xFC, 0x30, 0x0C, 0x3F, 0xFC, 0x20, 0x04, 0x00, 0x00 }, /* U+56FD 国 */ + { 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x86, 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x03, 0xC0, 0x03, 0x40, 0x02, 0x60, 0x06, 0x30, 0x0C, 0x18, 0x18, 0x0E, 0x70, 0x06, 0x00, 0x00 }, /* U+5927 大 */ + { 0x00, 0x00, 0x1F, 0xFC, 0x00, 0x38, 0x00, 0x60, 0x01, 0xC0, 0x01, 0x80, 0x01, 0x86, 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00 }, /* U+5B50 子 */ + { 0x00, 0x00, 0x1B, 0x18, 0x0D, 0xB0, 0x0D, 0xB0, 0x2D, 0xE6, 0x3F, 0xFE, 0x60, 0x34, 0x6F, 0xF0, 0x00, 0x60, 0x01, 0x84, 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x07, 0x80, 0x03, 0x80, 0x00, 0x00 }, /* U+5B66 学 */ + { 0x00, 0x00, 0x0C, 0x06, 0x0B, 0xFE, 0x68, 0x20, 0x6B, 0x66, 0x6B, 0xFE, 0x6B, 0x26, 0x6B, 0x26, 0x6B, 0x26, 0x6B, 0x26, 0x7B, 0x26, 0x1B, 0x2E, 0x30, 0x24, 0x20, 0x20, 0x40, 0x60, 0x00, 0x00 }, /* U+5E08 师 */ + { 0x00, 0x00, 0x19, 0x80, 0x19, 0x80, 0x33, 0xFC, 0x32, 0x6C, 0x75, 0x60, 0x53, 0x78, 0x12, 0x6C, 0x15, 0xE4, 0x10, 0xC0, 0x05, 0x80, 0x14, 0x8C, 0x34, 0x16, 0x64, 0x3A, 0x07, 0xF0, 0x00, 0x00 }, /* U+60A8 您 */ + { 0x00, 0x00, 0x00, 0x60, 0x06, 0xC0, 0x7E, 0xC0, 0x06, 0xFE, 0x64, 0xA4, 0x3D, 0x20, 0x19, 0x60, 0x18, 0x70, 0x1C, 0x70, 0x36, 0x50, 0x26, 0xD8, 0x63, 0x8C, 0x43, 0x0E, 0x06, 0x06, 0x00, 0x00 }, /* U+6B22 欢 */ + { 0x00, 0x00, 0x01, 0x80, 0x09, 0x80, 0x19, 0x80, 0x19, 0x8C, 0x1F, 0xFC, 0x31, 0x80, 0x21, 0x80, 0x41, 0x88, 0x1F, 0xF8, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x86, 0x7F, 0xFE, 0x00, 0x00 }, /* U+751F 生 */ + { 0x00, 0x00, 0x01, 0x80, 0x01, 0x80, 0x01, 0x00, 0x3F, 0xF8, 0x31, 0x08, 0x31, 0x08, 0x3F, 0xF8, 0x31, 0x08, 0x31, 0x08, 0x3F, 0xF8, 0x31, 0x00, 0x01, 0x06, 0x01, 0x06, 0x01, 0xFE, 0x00, 0x00 }, /* U+7535 电 */ + { 0x01, 0x00, 0x01, 0x80, 0x1F, 0xFC, 0x16, 0x30, 0x06, 0x60, 0x7F, 0xFE, 0x00, 0x10, 0x0F, 0xF0, 0x08, 0x30, 0x08, 0x30, 0x0F, 0xF0, 0x0A, 0xC2, 0x06, 0xC2, 0x0C, 0xC6, 0x38, 0x7E, 0x40, 0x00 }, /* U+7ADE 竞 */ + { 0x00, 0x00, 0x06, 0x60, 0x7F, 0xFE, 0x06, 0x60, 0x06, 0x40, 0x19, 0x18, 0x1B, 0xF8, 0x65, 0x18, 0x35, 0x18, 0x29, 0x18, 0x09, 0x38, 0x39, 0x36, 0x11, 0x06, 0x19, 0xFE, 0x18, 0xFC, 0x00, 0x00 }, /* U+8303 范 */ + { 0x00, 0x00, 0x10, 0x60, 0x18, 0x60, 0x08, 0x60, 0x00, 0x60, 0x18, 0x62, 0x7B, 0xFE, 0x10, 0x60, 0x18, 0x60, 0x18, 0x60, 0x12, 0x60, 0x1C, 0x60, 0x1C, 0x60, 0x18, 0x60, 0x00, 0x60, 0x00, 0x00 }, /* U+8BA1 计 */ + { 0x00, 0x00, 0x11, 0xF8, 0x19, 0x98, 0x01, 0x90, 0x01, 0x1E, 0x7B, 0x1E, 0x1E, 0x08, 0x19, 0xFC, 0x18, 0x98, 0x18, 0x98, 0x1E, 0xF0, 0x1C, 0x60, 0x18, 0xF0, 0x03, 0x9E, 0x0E, 0x06, 0x00, 0x00 }, /* U+8BBE 设 */ + { 0x01, 0x00, 0x01, 0x80, 0x3F, 0xFC, 0x36, 0x7C, 0x3F, 0xF8, 0x06, 0x78, 0x0F, 0xF8, 0x7F, 0xFE, 0x0E, 0x70, 0x1F, 0xF8, 0x3D, 0xBE, 0x4D, 0xB0, 0x0D, 0xA0, 0x07, 0x70, 0x1C, 0x38, 0x00, 0x00 }, /* U+8D5B 赛 */ + { 0x00, 0x00, 0x20, 0xC0, 0x33, 0xC0, 0x12, 0x3E, 0x02, 0x26, 0x02, 0x26, 0x72, 0x26, 0x12, 0x26, 0x12, 0xE6, 0x13, 0xAE, 0x13, 0x2C, 0x10, 0x20, 0x7C, 0x20, 0x47, 0xFE, 0x01, 0xFE, 0x00, 0x00 }, /* U+8FCE 迎 */ + { 0x01, 0x00, 0x01, 0x00, 0x1F, 0xF8, 0x18, 0x18, 0x1F, 0xF8, 0x18, 0x10, 0x1F, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x1F, 0xF8, 0x01, 0x82, 0x7F, 0xFE, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x00, 0x00 }, /* U+961C 阜 */ + { 0x00, 0x00, 0x7E, 0x84, 0x65, 0xFC, 0x6D, 0x84, 0x69, 0x84, 0x69, 0x84, 0x6D, 0x8C, 0x67, 0xFC, 0x67, 0x84, 0x67, 0x84, 0x7D, 0x84, 0x61, 0x84, 0x61, 0xFC, 0x61, 0x84, 0x60, 0x00, 0x00, 0x00 }, /* U+9633 阳 */ +}; + +static const uint16_t cjk_unicodes[18] = { + 0x5168, 0x56FD, 0x5927, 0x5B50, 0x5B66, 0x5E08, 0x60A8, 0x6B22, 0x751F, 0x7535, 0x7ADE, 0x8303, 0x8BA1, 0x8BBE, 0x8D5B, 0x8FCE, + 0x961C, 0x9633, +}; + +const uint8_t* cjk_get_bitmap(uint16_t unicode) +{ + int lo = 0, hi = 18; + while (lo < hi) { + int mid = (lo + hi) >> 1; + if (cjk_unicodes[mid] < unicode) lo = mid + 1; + else if (cjk_unicodes[mid] > unicode) hi = mid; + else return cjk_bitmaps[mid]; + } + return (const uint8_t*)0; +} diff --git a/STM32F103C8T6/Drivers/BSP/LCD/hz16_data.h b/STM32F103C8T6/Drivers/BSP/LCD/hz16_data.h new file mode 100644 index 0000000..fc8ce59 --- /dev/null +++ b/STM32F103C8T6/Drivers/BSP/LCD/hz16_data.h @@ -0,0 +1,15 @@ +/* 16×16 CJK 字库,由 font_gen.py 生成(自定义) */ + +#ifndef HZ16_DATA_H +#define HZ16_DATA_H + +#include + +#define CJK_BYTES_PER_CHAR 32 +#define CJK_WIDTH 16 +#define CJK_HEIGHT 16 +#define CJK_NUM_CHARS 18 + +const uint8_t* cjk_get_bitmap(uint16_t unicode); + +#endif /* HZ16_DATA_H */ diff --git a/STM32F103C8T6/Drivers/BSP/LCD/lcd.c b/STM32F103C8T6/Drivers/BSP/LCD/lcd.c new file mode 100644 index 0000000..96c1a93 --- /dev/null +++ b/STM32F103C8T6/Drivers/BSP/LCD/lcd.c @@ -0,0 +1,328 @@ +/* + * 模块名称:LCD 绘图模块 + * 模块功能:提供字符、字符串(中英文混合)、线条、矩形、圆形等图形绘制 + * 适用平台:STM32F103C8T6 + ST7735S + 底层 st7735s.c + * 作者:王建锋 + * 创建日期:2026-07-14 + * 修改记录: + * 2026-07-14 王建锋 从 st7735s.c 拆分 + */ + +#include "lcd.h" +#include "lcd_data.h" +#include "hz16_data.h" +#include + +/* + * 函数功能:UTF-8字符转Unicode(辅助) + * 入口参数:str - UTF-8字符串指针(会被推进到下一字符起始) + * 返回值:Unicode码点,或0(异常/结束) + * 函数说明:支持1~3字节UTF-8,推进str + */ +static uint16_t utf8_to_unicode(const char **str) +{ + uint16_t code; + uint8_t c; + + c = (uint8_t)(**str); + if (c == 0) { + return 0; + } + + if (c < 0x80) { + code = c; + (*str)++; + } else if ((c & 0xE0) == 0xC0) { + code = c & 0x1F; + (*str)++; + code = (code << 6) | ((uint8_t)(**str) & 0x3F); + (*str)++; + } else if ((c & 0xF0) == 0xE0) { + code = c & 0x0F; + (*str)++; + code = (code << 6) | ((uint8_t)(**str) & 0x3F); + (*str)++; + code = (code << 6) | ((uint8_t)(**str) & 0x3F); + (*str)++; + } else { + (*str)++; + return 0; + } + return code; +} + +/* + * 函数功能:显示一个8x16 ASCII字符 + * 入口参数:x - 列坐标 + * y - 行坐标 + * ch - 字符 (ASCII 32-126) + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + * 函数说明:框选8x16区域→遍历字模bit→发送color或bg_color + */ +void lcd_draw_char(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color) +{ + uint16_t i; + uint16_t j; + uint8_t line; + + if (ch < 32 || ch > 126) { + ch = ' '; + } + + st7735s_set_window(x, y, x + 7, y + 15); + + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); + for (i = 0; i < 16; i++) { + line = LCD_F8x16[ch - 32][i]; + for (j = 0; j < 8; j++) { + if (line & 0x80) { + st7735s_spi_write_byte((uint8_t)(color >> 8)); + st7735s_spi_write_byte((uint8_t)(color & 0xFF)); + } else { + st7735s_spi_write_byte((uint8_t)(bg_color >> 8)); + st7735s_spi_write_byte((uint8_t)(bg_color & 0xFF)); + } + line <<= 1; + } + } + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); +} + +/* + * 函数功能:显示字符串 + * 入口参数:x - 列坐标 + * y - 行坐标 + * str - 字符串指针 + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + * 函数说明:连续显示字符串,自动换行 + */ +void lcd_draw_string(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color) +{ + uint16_t start_x = x; + + while (*str != '\0') { + if (*str == '\n') { + y += FONT_HEIGHT_16; + x = start_x; + str++; + continue; + } + if (x + 8 > s_lcd_width) { + y += FONT_HEIGHT_16; + x = start_x; + } + if (y + 16 > s_lcd_height) { + break; + } + lcd_draw_char(x, y, *str, color, bg_color); + x += FONT_WIDTH_8; + str++; + } +} + +/* + * 函数功能:显示一个16x16 CJK汉字 + * 入口参数:x - 列坐标 + * y - 行坐标 + * unicode - Unicode码点 (如 0x4E00="一") + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + * 函数说明:框选16x16区域→遍历字模bit→发送color或bg_color + */ +void lcd_draw_chinese(uint16_t x, uint16_t y, uint16_t unicode, + uint16_t color, uint16_t bg_color) +{ + uint16_t i; + uint16_t j; + uint8_t k; + uint8_t line; + const uint8_t *bitmap; + + bitmap = cjk_get_bitmap(unicode); + if (bitmap == NULL) { + return; + } + + st7735s_set_window(x, y, x + CJK_WIDTH - 1, y + CJK_HEIGHT - 1); + + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); + for (i = 0; i < CJK_HEIGHT; i++) { + for (j = 0; j < CJK_WIDTH / 8; j++) { + line = bitmap[i * (CJK_WIDTH / 8) + j]; + for (k = 0; k < 8; k++) { + if (line & 0x80) { + st7735s_spi_write_byte((uint8_t)(color >> 8)); + st7735s_spi_write_byte((uint8_t)(color & 0xFF)); + } else { + st7735s_spi_write_byte((uint8_t)(bg_color >> 8)); + st7735s_spi_write_byte((uint8_t)(bg_color & 0xFF)); + } + line <<= 1; + } + } + } + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); +} + +/* + * 函数功能:显示UTF-8字符串(自动中英文混合) + * 入口参数:x - 列坐标 + * y - 行坐标 + * str - UTF-8字符串指针 + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + * 函数说明:自动识别ASCII(8x16)和CJK(16x16),自动换行 + */ +void lcd_draw_chinese_string(uint16_t x, uint16_t y, + const char *str, + uint16_t color, uint16_t bg_color) +{ + uint16_t start_x = x; + + while (*str != '\0') { + uint8_t c = (uint8_t)(*str); + + if (*str == '\n') { + y += CJK_HEIGHT; + x = start_x; + str++; + continue; + } + + if (c < 0x80) { + if (x + 8 > s_lcd_width) { + y += CJK_HEIGHT; + x = start_x; + } + if (y + 16 > s_lcd_height) { + break; + } + lcd_draw_char(x, y, (char)c, color, bg_color); + x += 8; + str++; + } else { + const char *p = str; + uint16_t unicode = utf8_to_unicode(&p); + if (unicode == 0) { + str = p; + continue; + } + if (x + CJK_WIDTH > s_lcd_width) { + y += CJK_HEIGHT; + x = start_x; + } + if (y + CJK_HEIGHT > s_lcd_height) { + break; + } + lcd_draw_chinese(x, y, unicode, color, bg_color); + x += CJK_WIDTH; + str = p; + } + } +} + +/* + * 函数功能:画线(Bresenham算法) + * 入口参数:x1 - 起始列 + * y1 - 起始行 + * x2 - 结束列 + * y2 - 结束行 + * color - 颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) +{ + int16_t dx; + int16_t dy; + int16_t sx; + int16_t sy; + int16_t err; + int16_t e2; + int16_t x = (int16_t)x1; + int16_t y = (int16_t)y1; + + dx = (x1 < x2) ? (int16_t)(x2 - x1) : (int16_t)(x1 - x2); + dy = (y1 < y2) ? (int16_t)(y2 - y1) : (int16_t)(y1 - y2); + sx = (x1 < x2) ? 1 : -1; + sy = (y1 < y2) ? 1 : -1; + err = dx - dy; + + while (1) { + st7735s_draw_pixel((uint16_t)x, (uint16_t)y, color); + if (x == (int16_t)x2 && y == (int16_t)y2) { + break; + } + e2 = 2 * err; + if (e2 > -dy) { + err -= dy; + x += sx; + } + if (e2 < dx) { + err += dx; + y += sy; + } + } +} + +/* + * 函数功能:画空心矩形 + * 入口参数:x - 左上角列 + * y - 左上角行 + * width - 宽度 + * height - 高度 + * color - 颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_rect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) +{ + uint16_t x2 = x + width - 1; + uint16_t y2 = y + height - 1; + + lcd_draw_line(x, y, x2, y, color); + lcd_draw_line(x, y, x, y2, color); + lcd_draw_line(x2, y, x2, y2, color); + lcd_draw_line(x, y2, x2, y2, color); +} + +/* + * 函数功能:画空心圆(Bresenham算法) + * 入口参数:x0 - 圆心列 + * y0 - 圆心行 + * radius - 半径 + * color - 颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t color) +{ + int16_t x = 0; + int16_t y = (int16_t)radius; + int16_t err = 1 - (int16_t)radius; + int16_t xc = (int16_t)x0; + int16_t yc = (int16_t)y0; + + while (x <= y) { + st7735s_draw_pixel((uint16_t)(xc + x), (uint16_t)(yc + y), color); + st7735s_draw_pixel((uint16_t)(xc - x), (uint16_t)(yc + y), color); + st7735s_draw_pixel((uint16_t)(xc + x), (uint16_t)(yc - y), color); + st7735s_draw_pixel((uint16_t)(xc - x), (uint16_t)(yc - y), color); + st7735s_draw_pixel((uint16_t)(xc + y), (uint16_t)(yc + x), color); + st7735s_draw_pixel((uint16_t)(xc - y), (uint16_t)(yc + x), color); + st7735s_draw_pixel((uint16_t)(xc + y), (uint16_t)(yc - x), color); + st7735s_draw_pixel((uint16_t)(xc - y), (uint16_t)(yc - x), color); + x++; + if (err < 0) { + err += 2 * x + 1; + } else { + y--; + err += 2 * (x - y) + 1; + } + } +} diff --git a/STM32F103C8T6/Drivers/BSP/LCD/lcd.h b/STM32F103C8T6/Drivers/BSP/LCD/lcd.h new file mode 100644 index 0000000..c0df2b6 --- /dev/null +++ b/STM32F103C8T6/Drivers/BSP/LCD/lcd.h @@ -0,0 +1,109 @@ +/* + * 模块名称:LCD 绘图模块 + * 模块功能:提供字符、字符串(中英文混合)、线条、矩形、圆形等图形绘制 + * 适用平台:STM32F103C8T6 + ST7735S + 底层 st7735s.c + * 作者:王建锋 + * 创建日期:2026-07-14 + * 修改记录: + * 2026-07-14 王建锋 从 st7735s.c 拆分 + */ + +#ifndef __LCD_H +#define __LCD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "st7735s.h" +#include + +/* 字体定义 */ +#define FONT_WIDTH_8 8 /* 8x16字体宽度(含间距) */ +#define FONT_HEIGHT_16 16 /* 8x16字体高度 */ + +/* === 字符/字符串绘制 === */ + +/* + * 函数功能:显示一个8x16 ASCII字符 + * 入口参数:x - 列坐标 + * y - 行坐标 + * ch - 字符 (ASCII 32-126) + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_char(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color); + +/* + * 函数功能:显示字符串(ASCII) + * 入口参数:x - 列坐标 + * y - 行坐标 + * str - 字符串指针 + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_string(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color); + +/* + * 函数功能:显示一个16x16 CJK汉字 + * 入口参数:x - 列坐标 + * y - 行坐标 + * unicode - Unicode码点 (如 0x4E00="一") + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_chinese(uint16_t x, uint16_t y, uint16_t unicode, uint16_t color, uint16_t bg_color); + +/* + * 函数功能:显示UTF-8字符串(自动中英文混合) + * 入口参数:x - 列坐标 + * y - 行坐标 + * str - UTF-8字符串指针 + * color - 字符颜色 (RGB565) + * bg_color - 背景颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_chinese_string(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color); + +/* === 图形绘制 === */ + +/* + * 函数功能:画线(Bresenham算法) + * 入口参数:x1 - 起始列 + * y1 - 起始行 + * x2 - 结束列 + * y2 - 结束行 + * color - 颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); + +/* + * 函数功能:画空心矩形 + * 入口参数:x - 左上角列 + * y - 左上角行 + * width - 宽度 + * height - 高度 + * color - 颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_rect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); + +/* + * 函数功能:画空心圆(Bresenham算法) + * 入口参数:x0 - 圆心列 + * y0 - 圆心行 + * radius - 半径 + * color - 颜色 (RGB565) + * 返回值:无 + */ +void lcd_draw_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t color); + +#ifdef __cplusplus +} +#endif + +#endif /* __LCD_H */ diff --git a/STM32F103C8T6/Drivers/BSP/LCD/lcd_data.c b/STM32F103C8T6/Drivers/BSP/LCD/lcd_data.c index bf6d907..b76962e 100644 --- a/STM32F103C8T6/Drivers/BSP/LCD/lcd_data.c +++ b/STM32F103C8T6/Drivers/BSP/LCD/lcd_data.c @@ -2,296 +2,297 @@ /*ASCII字模数据*********************/ /*宽8像素,高16像素*/ +/* 字体: simsun.ttc, 字号: 64, 阈值: 50 */ const uint8_t LCD_F8x16[][16] = { - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 0 - 0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,// ! 1 - 0x00,0x16,0x0E,0x00,0x16,0x0E,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// " 2 - 0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00, - 0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,// # 3 - 0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00, - 0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,// $ 4 - 0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00, - 0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,// % 5 - 0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00, - 0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,// & 6 - 0x00,0x00,0x00,0x16,0x0E,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ' 7 - 0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00, - 0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,// ( 8 - 0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00, - 0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,// ) 9 - 0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00, - 0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,// * 10 - 0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, - 0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,// + 11 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,// , 12 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,// - 13 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,// . 14 - 0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04, - 0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,// / 15 - 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, - 0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,// 0 16 - 0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00, - 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// 1 17 - 0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00, - 0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,// 2 18 - 0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00, - 0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,// 3 19 - 0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00, - 0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,// 4 20 - 0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00, - 0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,// 5 21 - 0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00, - 0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,// 6 22 - 0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00, - 0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,// 7 23 - 0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00, - 0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,// 8 24 - 0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00, - 0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,// 9 25 - 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, - 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,// : 26 - 0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00, - 0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,// ; 27 - 0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00, - 0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,// < 28 - 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, - 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,// = 29 - 0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00, - 0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,// > 30 - 0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00, - 0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,// ? 31 - 0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00, - 0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,// @ 32 - 0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00, - 0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,// A 33 - 0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00, - 0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,// B 34 - 0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00, - 0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,// C 35 - 0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00, - 0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,// D 36 - 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, - 0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,// E 37 - 0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00, - 0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,// F 38 - 0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00, - 0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,// G 39 - 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, - 0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,// H 40 - 0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00, - 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// I 41 - 0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00, - 0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,// J 42 - 0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00, - 0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,// K 43 - 0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00, - 0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,// L 44 - 0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00, - 0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,// M 45 - 0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08, - 0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,// N 46 - 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, - 0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,// O 47 - 0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00, - 0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,// P 48 - 0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00, - 0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,// Q 49 - 0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00, - 0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,// R 50 - 0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00, - 0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,// S 51 - 0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00, - 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,// T 52 - 0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08, - 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,// U 53 - 0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08, - 0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,// V 54 - 0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00, - 0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,// W 55 - 0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08, - 0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,// X 56 - 0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00, - 0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,// Y 57 - 0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00, - 0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,// Z 58 - 0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00, - 0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,// [ 59 - 0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,// \ 60 - 0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00, - 0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,// ] 61 - 0x00,0x20,0x10,0x08,0x04,0x08,0x10,0x20, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ^ 62 - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,// _ 63 - 0x00,0x02,0x04,0x08,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// ` 64 - 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, - 0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,// a 65 - 0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00, - 0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,// b 66 - 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, - 0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,// c 67 - 0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00, - 0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,// d 68 - 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, - 0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,// e 69 - 0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18, - 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// f 70 - 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, - 0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,// g 71 - 0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00, - 0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,// h 72 - 0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00, - 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// i 73 - 0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00, - 0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,// j 74 - 0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00, - 0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,// k 75 - 0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00, - 0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,// l 76 - 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, - 0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,// m 77 - 0x00,0x80,0x80,0x00,0x80,0x80,0x00,0x00, - 0x00,0x20,0x3F,0x21,0x00,0x20,0x3F,0x20,// n 78 - 0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00, - 0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,// o 79 - 0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00, - 0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,// p 80 - 0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00, - 0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,// q 81 - 0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00, - 0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,// r 82 - 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00, - 0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,// s 83 - 0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00, - 0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,// t 84 - 0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00, - 0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,// u 85 - 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, - 0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,// v 86 - 0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80, - 0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,// w 87 - 0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00, - 0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,// x 88 - 0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80, - 0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,// y 89 - 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00, - 0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,// z 90 - 0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02, - 0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,// { 91 - 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,// | 92 - 0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00, - 0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,// } 93 - 0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x80, - 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00,// ~ 94 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0 + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, // ! 1 + 0x00, 0x16, 0x36, 0x3C, 0x68, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // " 2 + 0x00, 0x00, 0x20, 0x26, 0x26, 0xFF, 0x7E, 0x24, + 0x64, 0xFF, 0xFE, 0x64, 0x64, 0x00, 0x00, 0x00, // # 3 + 0x00, 0x18, 0x3C, 0x7E, 0x7E, 0x78, 0x38, 0x18, + 0x1C, 0x1E, 0x7E, 0x56, 0x7C, 0x18, 0x18, 0x00, // $ 4 + 0x00, 0x00, 0x60, 0xF4, 0x94, 0x9C, 0x98, 0xFC, + 0x1E, 0x1B, 0x3B, 0x2B, 0x6E, 0x04, 0x00, 0x00, // % 5 + 0x00, 0x00, 0x30, 0x78, 0x68, 0x78, 0x78, 0x76, + 0xF4, 0xD4, 0xDC, 0xCC, 0x7F, 0x22, 0x00, 0x00, // & 6 + 0x00, 0x60, 0x70, 0x30, 0x60, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ' 7 + 0x00, 0x02, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x02, 0x00, // ( 8 + 0x00, 0x40, 0x60, 0x30, 0x30, 0x10, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x30, 0x30, 0x60, 0x40, 0x00, // ) 9 + 0x00, 0x00, 0x00, 0x18, 0x18, 0xFF, 0x7E, 0x3C, + 0xFF, 0xDB, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // * 10 + 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0xFF, 0x18, + 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // + 11 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x70, + 0x20, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // , 12 + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // - 13 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, + 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // . 14 + 0x00, 0x02, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, + 0x10, 0x30, 0x20, 0x60, 0x40, 0xC0, 0x80, 0x00, // / 15 + 0x00, 0x00, 0x3C, 0x66, 0x66, 0x42, 0xC3, 0xC3, + 0xC3, 0xC3, 0x42, 0x66, 0x3C, 0x18, 0x00, 0x00, // 0 16 + 0x00, 0x00, 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x00, 0x00, // 1 17 + 0x00, 0x00, 0x3C, 0x66, 0x62, 0x62, 0x06, 0x04, + 0x08, 0x10, 0x20, 0x42, 0xFE, 0x7C, 0x00, 0x00, // 2 18 + 0x00, 0x00, 0x3C, 0x64, 0x66, 0x06, 0x0C, 0x1C, + 0x06, 0x02, 0x62, 0x66, 0x7C, 0x18, 0x00, 0x00, // 3 19 + 0x00, 0x00, 0x04, 0x0C, 0x1C, 0x1C, 0x2C, 0x6C, + 0x4C, 0xFE, 0x0C, 0x0C, 0x0E, 0x1E, 0x00, 0x00, // 4 20 + 0x00, 0x00, 0x3E, 0x7E, 0x60, 0x40, 0x7C, 0x66, + 0x06, 0x02, 0x62, 0x66, 0x7C, 0x18, 0x00, 0x00, // 5 21 + 0x00, 0x00, 0x1C, 0x26, 0x62, 0x40, 0xDC, 0xF6, + 0xC2, 0xC3, 0x43, 0x62, 0x3E, 0x18, 0x00, 0x00, // 6 22 + 0x00, 0x00, 0x7E, 0x7E, 0x44, 0x04, 0x0C, 0x08, + 0x18, 0x18, 0x18, 0x38, 0x38, 0x10, 0x00, 0x00, // 7 23 + 0x00, 0x00, 0x3C, 0x66, 0x42, 0x62, 0x76, 0x3C, + 0x6E, 0x46, 0xC2, 0x46, 0x7C, 0x18, 0x00, 0x00, // 8 24 + 0x00, 0x00, 0x3C, 0x66, 0x46, 0xC2, 0xC2, 0x66, + 0x7E, 0x16, 0x06, 0x64, 0x7C, 0x10, 0x00, 0x00, // 9 25 + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, // : 26 + 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, // ; 27 + 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, + 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, // < 28 + 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // = 29 + 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, // > 30 + 0x00, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0x46, 0x0C, + 0x18, 0x10, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, // ? 31 + 0x00, 0x00, 0x1C, 0x36, 0x6F, 0x5F, 0xD7, 0xF5, + 0xF5, 0xFE, 0x7E, 0x63, 0x3E, 0x18, 0x00, 0x00, // @ 32 + 0x00, 0x00, 0x18, 0x18, 0x18, 0x3C, 0x2C, 0x2C, + 0x3C, 0x7E, 0x46, 0x46, 0xC7, 0xC7, 0x00, 0x00, // A 33 + 0x00, 0x00, 0xFC, 0x66, 0x62, 0x62, 0x66, 0x7C, + 0x66, 0x63, 0x63, 0x63, 0x7E, 0xF8, 0x00, 0x00, // B 34 + 0x00, 0x00, 0x1E, 0x63, 0x41, 0xC0, 0xC0, 0xC0, + 0xC0, 0xC0, 0xC1, 0x62, 0x3E, 0x18, 0x00, 0x00, // C 35 + 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x63, 0x63, 0x63, + 0x63, 0x63, 0x62, 0x66, 0x7C, 0xF0, 0x00, 0x00, // D 36 + 0x00, 0x00, 0x7E, 0x66, 0x62, 0x60, 0x64, 0x7C, + 0x64, 0x60, 0x60, 0x63, 0x7E, 0x7E, 0x00, 0x00, // E 37 + 0x00, 0x00, 0x7E, 0x63, 0x61, 0x60, 0x64, 0x7C, + 0x64, 0x64, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, // F 38 + 0x00, 0x00, 0x3C, 0x66, 0x42, 0xC0, 0xC0, 0xC0, + 0xC7, 0xC6, 0x46, 0x66, 0x3E, 0x18, 0x00, 0x00, // G 39 + 0x00, 0x00, 0xE7, 0x66, 0x66, 0x66, 0x66, 0x7E, + 0x66, 0x66, 0x66, 0x66, 0x66, 0xE7, 0x00, 0x00, // H 40 + 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x00, 0x00, // I 41 + 0x00, 0x3F, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, + 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xF8, 0x20, 0x00, // J 42 + 0x00, 0x00, 0xE6, 0x66, 0x6C, 0x68, 0x70, 0x78, + 0x68, 0x6C, 0x6C, 0x66, 0x67, 0x67, 0x00, 0x00, // K 43 + 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, + 0x60, 0x60, 0x60, 0x63, 0x7E, 0x7E, 0x00, 0x00, // L 44 + 0x00, 0x00, 0xC3, 0x66, 0x66, 0x66, 0x66, 0x6E, + 0x7E, 0x7A, 0x5A, 0x5A, 0xD7, 0xC7, 0x00, 0x00, // M 45 + 0x00, 0x00, 0xC7, 0x62, 0x72, 0x72, 0x52, 0x5A, + 0x4A, 0x4E, 0x46, 0x46, 0xE2, 0xE0, 0x00, 0x00, // N 46 + 0x00, 0x00, 0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, + 0xC3, 0xC3, 0x43, 0x66, 0x3C, 0x18, 0x00, 0x00, // O 47 + 0x00, 0x00, 0x7C, 0x66, 0x63, 0x63, 0x62, 0x7E, + 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, // P 48 + 0x00, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, + 0xC3, 0xFB, 0x7A, 0x6E, 0x3C, 0x06, 0x00, 0x00, // Q 49 + 0x00, 0x00, 0x7C, 0x66, 0x62, 0x62, 0x66, 0x7C, + 0x68, 0x6C, 0x64, 0x66, 0x67, 0x63, 0x00, 0x00, // R 50 + 0x00, 0x00, 0x3C, 0x66, 0x42, 0x60, 0x70, 0x3C, + 0x0E, 0x06, 0xC2, 0x46, 0x7E, 0x18, 0x00, 0x00, // S 51 + 0x00, 0x00, 0x7E, 0xDB, 0x99, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, // T 52 + 0x00, 0x00, 0xE7, 0x62, 0x62, 0x62, 0x62, 0x62, + 0x62, 0x62, 0x62, 0x62, 0x3C, 0x18, 0x00, 0x00, // U 53 + 0x00, 0x00, 0xE7, 0x66, 0x66, 0x64, 0x24, 0x24, + 0x3C, 0x38, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, // V 54 + 0x00, 0x00, 0xDB, 0xDB, 0x5A, 0x5A, 0x5A, 0x7E, + 0x7C, 0x7C, 0x2C, 0x2C, 0x24, 0x00, 0x00, 0x00, // W 55 + 0x00, 0x00, 0x66, 0x66, 0x24, 0x3C, 0x18, 0x18, + 0x18, 0x3C, 0x2C, 0x24, 0x66, 0x66, 0x00, 0x00, // X 56 + 0x00, 0x00, 0xE7, 0x62, 0x66, 0x34, 0x34, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, // Y 57 + 0x00, 0x00, 0x7E, 0x66, 0x46, 0x0C, 0x08, 0x18, + 0x10, 0x30, 0x20, 0x62, 0xFE, 0x7C, 0x00, 0x00, // Z 58 + 0x00, 0x1E, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1E, 0x00, // [ 59 + 0x00, 0x40, 0x60, 0x20, 0x30, 0x30, 0x10, 0x18, + 0x08, 0x0C, 0x0C, 0x04, 0x06, 0x02, 0x02, 0x00, // \ 60 + 0x00, 0x78, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x78, 0x00, // ] 61 + 0x00, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ^ 62 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, // _ 63 + 0x00, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ` 64 + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x46, 0x3E, + 0x66, 0xC6, 0x6F, 0x36, 0x00, 0x00, 0x00, 0x00, // a 65 + 0x00, 0x00, 0xC0, 0x60, 0x60, 0x60, 0x7C, 0x76, + 0x66, 0x62, 0x62, 0x66, 0x66, 0x5C, 0x00, 0x00, // b 66 + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x40, + 0x40, 0x62, 0x76, 0x1C, 0x00, 0x00, 0x00, 0x00, // c 67 + 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x76, + 0x66, 0x46, 0x46, 0x66, 0x6E, 0x3E, 0x00, 0x00, // d 68 + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0x7E, + 0x40, 0x62, 0x76, 0x1C, 0x00, 0x00, 0x00, 0x00, // e 69 + 0x00, 0x00, 0x0E, 0x1B, 0x31, 0x30, 0x7C, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x38, 0x7C, 0x00, 0x00, // f 70 + 0x00, 0x00, 0x00, 0x1B, 0x2F, 0x66, 0x66, 0x3C, + 0x78, 0x7E, 0x46, 0x66, 0x3C, 0x00, 0x00, 0x00, // g 71 + 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, // h 72 + 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x38, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x3C, 0x3C, 0x00, 0x00, // i 73 + 0x00, 0x04, 0x06, 0x00, 0x00, 0x1E, 0x06, 0x06, + 0x06, 0x06, 0x06, 0x06, 0x04, 0x6C, 0x38, 0x00, // j 74 + 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x66, 0x6C, + 0x68, 0x78, 0x6C, 0x6C, 0x66, 0x67, 0x00, 0x00, // k 75 + 0x00, 0x00, 0x38, 0x38, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, // l 76 + 0x00, 0x00, 0x00, 0x00, 0xFE, 0xDB, 0xDB, 0xDB, + 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00, 0x00, // m 77 + 0x00, 0x00, 0x00, 0x00, 0xFC, 0x76, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, // n 78 + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x42, 0xC3, + 0xC3, 0x42, 0x66, 0x38, 0x00, 0x00, 0x00, 0x00, // o 79 + 0x00, 0x00, 0x00, 0x7C, 0x76, 0x62, 0x63, 0x63, + 0x62, 0x66, 0x7C, 0x60, 0x70, 0x00, 0x00, 0x00, // p 80 + 0x00, 0x00, 0x00, 0x3E, 0x66, 0x46, 0xC6, 0xC6, + 0x46, 0x7E, 0x16, 0x06, 0x0E, 0x00, 0x00, 0x00, // q 81 + 0x00, 0x00, 0x00, 0x00, 0xFE, 0x3B, 0x30, 0x30, + 0x30, 0x30, 0x30, 0xF8, 0x00, 0x00, 0x00, 0x00, // r 82 + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x60, 0x38, + 0x0E, 0x46, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x00, // s 83 + 0x00, 0x00, 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x1E, 0x0C, 0x00, 0x00, 0x00, // t 84 + 0x00, 0x00, 0x00, 0x00, 0xE6, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, // u 85 + 0x00, 0x00, 0x00, 0x00, 0xE6, 0x66, 0x24, 0x34, + 0x38, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // v 86 + 0x00, 0x00, 0x00, 0x00, 0xDB, 0xDA, 0x5A, 0x7E, + 0x7C, 0x2C, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, // w 87 + 0x00, 0x00, 0x00, 0x00, 0x76, 0x34, 0x38, 0x18, + 0x18, 0x2C, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, // x 88 + 0x00, 0x00, 0x00, 0x67, 0x66, 0x34, 0x34, 0x1C, + 0x18, 0x18, 0x18, 0x70, 0x60, 0x00, 0x00, 0x00, // y 89 + 0x00, 0x00, 0x00, 0x00, 0x7E, 0x4C, 0x08, 0x18, + 0x30, 0x22, 0x7E, 0x7C, 0x00, 0x00, 0x00, 0x00, // z 90 + 0x00, 0x06, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, + 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x06, 0x00, // { 91 + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // | 92 + 0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, + 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, // } 93 + 0x00, 0x70, 0x59, 0x0E, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ~ 94 }; -/*宽6像素,高8像素*/ -const uint8_t LCD_F6x8[][6] = +/*宽6像素,高8像素(未使用)*/ +const uint8_t LCD_F6x8[][6] = { - 0x00,0x00,0x00,0x00,0x00,0x00,// 0 - 0x00,0x00,0x00,0x2F,0x00,0x00,// ! 1 - 0x00,0x00,0x07,0x00,0x07,0x00,// " 2 - 0x00,0x14,0x7F,0x14,0x7F,0x14,// # 3 - 0x00,0x24,0x2A,0x7F,0x2A,0x12,// $ 4 - 0x00,0x23,0x13,0x08,0x64,0x62,// % 5 - 0x00,0x36,0x49,0x55,0x22,0x50,// & 6 - 0x00,0x00,0x00,0x07,0x00,0x00,// ' 7 - 0x00,0x00,0x1C,0x22,0x41,0x00,// ( 8 - 0x00,0x00,0x41,0x22,0x1C,0x00,// ) 9 - 0x00,0x14,0x08,0x3E,0x08,0x14,// * 10 - 0x00,0x08,0x08,0x3E,0x08,0x08,// + 11 - 0x00,0x00,0x00,0xA0,0x60,0x00,// , 12 - 0x00,0x08,0x08,0x08,0x08,0x08,// - 13 - 0x00,0x00,0x60,0x60,0x00,0x00,// . 14 - 0x00,0x20,0x10,0x08,0x04,0x02,// / 15 - 0x00,0x3E,0x51,0x49,0x45,0x3E,// 0 16 - 0x00,0x00,0x42,0x7F,0x40,0x00,// 1 17 - 0x00,0x42,0x61,0x51,0x49,0x46,// 2 18 - 0x00,0x21,0x41,0x45,0x4B,0x31,// 3 19 - 0x00,0x18,0x14,0x12,0x7F,0x10,// 4 20 - 0x00,0x27,0x45,0x45,0x45,0x39,// 5 21 - 0x00,0x3C,0x4A,0x49,0x49,0x30,// 6 22 - 0x00,0x01,0x71,0x09,0x05,0x03,// 7 23 - 0x00,0x36,0x49,0x49,0x49,0x36,// 8 24 - 0x00,0x06,0x49,0x49,0x29,0x1E,// 9 25 - 0x00,0x00,0x36,0x36,0x00,0x00,// : 26 - 0x00,0x00,0x56,0x36,0x00,0x00,// ; 27 - 0x00,0x08,0x14,0x22,0x41,0x00,// < 28 - 0x00,0x14,0x14,0x14,0x14,0x14,// = 29 - 0x00,0x00,0x41,0x22,0x14,0x08,// > 30 - 0x00,0x02,0x01,0x51,0x09,0x06,// ? 31 - 0x00,0x3E,0x49,0x55,0x59,0x2E,// @ 32 - 0x00,0x7C,0x12,0x11,0x12,0x7C,// A 33 - 0x00,0x7F,0x49,0x49,0x49,0x36,// B 34 - 0x00,0x3E,0x41,0x41,0x41,0x22,// C 35 - 0x00,0x7F,0x41,0x41,0x22,0x1C,// D 36 - 0x00,0x7F,0x49,0x49,0x49,0x41,// E 37 - 0x00,0x7F,0x09,0x09,0x09,0x01,// F 38 - 0x00,0x3E,0x41,0x49,0x49,0x7A,// G 39 - 0x00,0x7F,0x08,0x08,0x08,0x7F,// H 40 - 0x00,0x00,0x41,0x7F,0x41,0x00,// I 41 - 0x00,0x20,0x40,0x41,0x3F,0x01,// J 42 - 0x00,0x7F,0x08,0x14,0x22,0x41,// K 43 - 0x00,0x7F,0x40,0x40,0x40,0x40,// L 44 - 0x00,0x7F,0x02,0x0C,0x02,0x7F,// M 45 - 0x00,0x7F,0x04,0x08,0x10,0x7F,// N 46 - 0x00,0x3E,0x41,0x41,0x41,0x3E,// O 47 - 0x00,0x7F,0x09,0x09,0x09,0x06,// P 48 - 0x00,0x3E,0x41,0x51,0x21,0x5E,// Q 49 - 0x00,0x7F,0x09,0x19,0x29,0x46,// R 50 - 0x00,0x46,0x49,0x49,0x49,0x31,// S 51 - 0x00,0x01,0x01,0x7F,0x01,0x01,// T 52 - 0x00,0x3F,0x40,0x40,0x40,0x3F,// U 53 - 0x00,0x1F,0x20,0x40,0x20,0x1F,// V 54 - 0x00,0x3F,0x40,0x38,0x40,0x3F,// W 55 - 0x00,0x63,0x14,0x08,0x14,0x63,// X 56 - 0x00,0x07,0x08,0x70,0x08,0x07,// Y 57 - 0x00,0x61,0x51,0x49,0x45,0x43,// Z 58 - 0x00,0x00,0x7F,0x41,0x41,0x00,// [ 59 - 0x00,0x02,0x04,0x08,0x10,0x20,// \ 60 - 0x00,0x00,0x41,0x41,0x7F,0x00,// ] 61 - 0x00,0x04,0x02,0x01,0x02,0x04,// ^ 62 - 0x00,0x40,0x40,0x40,0x40,0x40,// _ 63 - 0x00,0x00,0x01,0x02,0x04,0x00,// ` 64 - 0x00,0x20,0x54,0x54,0x54,0x78,// a 65 - 0x00,0x7F,0x48,0x44,0x44,0x38,// b 66 - 0x00,0x38,0x44,0x44,0x44,0x20,// c 67 - 0x00,0x38,0x44,0x44,0x48,0x7F,// d 68 - 0x00,0x38,0x54,0x54,0x54,0x18,// e 69 - 0x00,0x08,0x7E,0x09,0x01,0x02,// f 70 - 0x00,0x18,0xA4,0xA4,0xA4,0x7C,// g 71 - 0x00,0x7F,0x08,0x04,0x04,0x78,// h 72 - 0x00,0x00,0x44,0x7D,0x40,0x00,// i 73 - 0x00,0x40,0x80,0x84,0x7D,0x00,// j 74 - 0x00,0x7F,0x10,0x28,0x44,0x00,// k 75 - 0x00,0x00,0x41,0x7F,0x40,0x00,// l 76 - 0x00,0x7C,0x04,0x18,0x04,0x78,// m 77 - 0x00,0x7C,0x08,0x04,0x04,0x78,// n 78 - 0x00,0x38,0x44,0x44,0x44,0x38,// o 79 - 0x00,0xFC,0x24,0x24,0x24,0x18,// p 80 - 0x00,0x18,0x24,0x24,0x18,0xFC,// q 81 - 0x00,0x7C,0x08,0x04,0x04,0x08,// r 82 - 0x00,0x48,0x54,0x54,0x54,0x20,// s 83 - 0x00,0x04,0x3F,0x44,0x40,0x20,// t 84 - 0x00,0x3C,0x40,0x40,0x20,0x7C,// u 85 - 0x00,0x1C,0x20,0x40,0x20,0x1C,// v 86 - 0x00,0x3C,0x40,0x30,0x40,0x3C,// w 87 - 0x00,0x44,0x28,0x10,0x28,0x44,// x 88 - 0x00,0x1C,0xA0,0xA0,0xA0,0x7C,// y 89 - 0x00,0x44,0x64,0x54,0x4C,0x44,// z 90 - 0x00,0x00,0x08,0x7F,0x41,0x00,// { 91 - 0x00,0x00,0x00,0x7F,0x00,0x00,// | 92 - 0x00,0x00,0x41,0x7F,0x08,0x00,// } 93 - 0x00,0x08,0x04,0x08,0x10,0x08,// ~ 94 + 0x00,0x00,0x00,0x00,0x00,0x00, // 0 + 0x00,0x00,0x00,0x00,0x00,0x00, // ! 1 + 0x00,0x00,0x00,0x00,0x00,0x00, // " 2 + 0x00,0x00,0x00,0x00,0x00,0x00, // # 3 + 0x00,0x00,0x00,0x00,0x00,0x00, // $ 4 + 0x00,0x00,0x00,0x00,0x00,0x00, // % 5 + 0x00,0x00,0x00,0x00,0x00,0x00, // & 6 + 0x00,0x00,0x00,0x00,0x00,0x00, // ' 7 + 0x00,0x00,0x00,0x00,0x00,0x00, // ( 8 + 0x00,0x00,0x00,0x00,0x00,0x00, // ) 9 + 0x00,0x00,0x00,0x00,0x00,0x00, // * 10 + 0x00,0x00,0x00,0x00,0x00,0x00, // + 11 + 0x00,0x00,0x00,0x00,0x00,0x00, // , 12 + 0x00,0x00,0x00,0x00,0x00,0x00, // - 13 + 0x00,0x00,0x00,0x00,0x00,0x00, // . 14 + 0x00,0x00,0x00,0x00,0x00,0x00, // / 15 + 0x00,0x00,0x00,0x00,0x00,0x00, // 0 16 + 0x00,0x00,0x00,0x00,0x00,0x00, // 1 17 + 0x00,0x00,0x00,0x00,0x00,0x00, // 2 18 + 0x00,0x00,0x00,0x00,0x00,0x00, // 3 19 + 0x00,0x00,0x00,0x00,0x00,0x00, // 4 20 + 0x00,0x00,0x00,0x00,0x00,0x00, // 5 21 + 0x00,0x00,0x00,0x00,0x00,0x00, // 6 22 + 0x00,0x00,0x00,0x00,0x00,0x00, // 7 23 + 0x00,0x00,0x00,0x00,0x00,0x00, // 8 24 + 0x00,0x00,0x00,0x00,0x00,0x00, // 9 25 + 0x00,0x00,0x00,0x00,0x00,0x00, // : 26 + 0x00,0x00,0x00,0x00,0x00,0x00, // ; 27 + 0x00,0x00,0x00,0x00,0x00,0x00, // < 28 + 0x00,0x00,0x00,0x00,0x00,0x00, // = 29 + 0x00,0x00,0x00,0x00,0x00,0x00, // > 30 + 0x00,0x00,0x00,0x00,0x00,0x00, // ? 31 + 0x00,0x00,0x00,0x00,0x00,0x00, // @ 32 + 0x00,0x00,0x00,0x00,0x00,0x00, // A 33 + 0x00,0x00,0x00,0x00,0x00,0x00, // B 34 + 0x00,0x00,0x00,0x00,0x00,0x00, // C 35 + 0x00,0x00,0x00,0x00,0x00,0x00, // D 36 + 0x00,0x00,0x00,0x00,0x00,0x00, // E 37 + 0x00,0x00,0x00,0x00,0x00,0x00, // F 38 + 0x00,0x00,0x00,0x00,0x00,0x00, // G 39 + 0x00,0x00,0x00,0x00,0x00,0x00, // H 40 + 0x00,0x00,0x00,0x00,0x00,0x00, // I 41 + 0x00,0x00,0x00,0x00,0x00,0x00, // J 42 + 0x00,0x00,0x00,0x00,0x00,0x00, // K 43 + 0x00,0x00,0x00,0x00,0x00,0x00, // L 44 + 0x00,0x00,0x00,0x00,0x00,0x00, // M 45 + 0x00,0x00,0x00,0x00,0x00,0x00, // N 46 + 0x00,0x00,0x00,0x00,0x00,0x00, // O 47 + 0x00,0x00,0x00,0x00,0x00,0x00, // P 48 + 0x00,0x00,0x00,0x00,0x00,0x00, // Q 49 + 0x00,0x00,0x00,0x00,0x00,0x00, // R 50 + 0x00,0x00,0x00,0x00,0x00,0x00, // S 51 + 0x00,0x00,0x00,0x00,0x00,0x00, // T 52 + 0x00,0x00,0x00,0x00,0x00,0x00, // U 53 + 0x00,0x00,0x00,0x00,0x00,0x00, // V 54 + 0x00,0x00,0x00,0x00,0x00,0x00, // W 55 + 0x00,0x00,0x00,0x00,0x00,0x00, // X 56 + 0x00,0x00,0x00,0x00,0x00,0x00, // Y 57 + 0x00,0x00,0x00,0x00,0x00,0x00, // Z 58 + 0x00,0x00,0x00,0x00,0x00,0x00, // [ 59 + 0x00,0x00,0x00,0x00,0x00,0x00, // \ 60 + 0x00,0x00,0x00,0x00,0x00,0x00, // ] 61 + 0x00,0x00,0x00,0x00,0x00,0x00, // ^ 62 + 0x00,0x00,0x00,0x00,0x00,0x00, // _ 63 + 0x00,0x00,0x00,0x00,0x00,0x00, // ` 64 + 0x00,0x00,0x00,0x00,0x00,0x00, // a 65 + 0x00,0x00,0x00,0x00,0x00,0x00, // b 66 + 0x00,0x00,0x00,0x00,0x00,0x00, // c 67 + 0x00,0x00,0x00,0x00,0x00,0x00, // d 68 + 0x00,0x00,0x00,0x00,0x00,0x00, // e 69 + 0x00,0x00,0x00,0x00,0x00,0x00, // f 70 + 0x00,0x00,0x00,0x00,0x00,0x00, // g 71 + 0x00,0x00,0x00,0x00,0x00,0x00, // h 72 + 0x00,0x00,0x00,0x00,0x00,0x00, // i 73 + 0x00,0x00,0x00,0x00,0x00,0x00, // j 74 + 0x00,0x00,0x00,0x00,0x00,0x00, // k 75 + 0x00,0x00,0x00,0x00,0x00,0x00, // l 76 + 0x00,0x00,0x00,0x00,0x00,0x00, // m 77 + 0x00,0x00,0x00,0x00,0x00,0x00, // n 78 + 0x00,0x00,0x00,0x00,0x00,0x00, // o 79 + 0x00,0x00,0x00,0x00,0x00,0x00, // p 80 + 0x00,0x00,0x00,0x00,0x00,0x00, // q 81 + 0x00,0x00,0x00,0x00,0x00,0x00, // r 82 + 0x00,0x00,0x00,0x00,0x00,0x00, // s 83 + 0x00,0x00,0x00,0x00,0x00,0x00, // t 84 + 0x00,0x00,0x00,0x00,0x00,0x00, // u 85 + 0x00,0x00,0x00,0x00,0x00,0x00, // v 86 + 0x00,0x00,0x00,0x00,0x00,0x00, // w 87 + 0x00,0x00,0x00,0x00,0x00,0x00, // x 88 + 0x00,0x00,0x00,0x00,0x00,0x00, // y 89 + 0x00,0x00,0x00,0x00,0x00,0x00, // z 90 + 0x00,0x00,0x00,0x00,0x00,0x00, // { 91 + 0x00,0x00,0x00,0x00,0x00,0x00, // | 92 + 0x00,0x00,0x00,0x00,0x00,0x00, // } 93 + 0x00,0x00,0x00,0x00,0x00,0x00 // ~ 94 }; diff --git a/STM32F103C8T6/Drivers/BSP/LCD/st7735s.c b/STM32F103C8T6/Drivers/BSP/LCD/st7735s.c index 4628be2..eea007c 100644 --- a/STM32F103C8T6/Drivers/BSP/LCD/st7735s.c +++ b/STM32F103C8T6/Drivers/BSP/LCD/st7735s.c @@ -1,59 +1,62 @@ /* - * 模块名称:ST7735S LCD驱动 - * 模块功能:提供128x160 RGB TFT屏幕的初始化、画点、画线、填充、显示字符串等功能 - * 适用平台:STM32F103C8T6 + SPI2 + * 模块名称:ST7735S LCD驱动(底层) + * 模块功能:提供ST7735S屏幕的硬件SPI通信、初始化、填充、画点、方向控制等底层操作 + * 绘图函数见 lcd.c + * 适用平台:STM32F103C8T6 + 硬件SPI2 * 作者:王建锋 * 创建日期:2026-07-13 * 修改记录: * 2026-07-13 王建锋 创建初始版本 + * 2026-07-14 王建锋 软件SPI -> 硬件SPI2 + * 2026-07-14 王建锋 拆分:绘图函数移入 lcd.c */ #include "st7735s.h" -#include "lcd_data.h" #include "spi.h" #include -#include - -static uint16_t s_lcd_width = LCD_WIDTH; -static uint16_t s_lcd_height = LCD_HEIGHT; - -extern DMA_HandleTypeDef hdma_spi2_tx; - -/* 8x16 ASCII字体(ASCII 32-126),每字符16字节 - 定义在 lcd_data.c 中 */ /* - * 函数功能:软件SPI写一个字节 + * 部分屏幕厂家虽然标称128x160,但实际使用132x162驱动晶片, + * 左右各偏移2列,上下偏移1行才能正确显示。 + * 根据自己的屏幕实测调整这两个值。 + */ +#define X_OFFSET 2 +#define Y_OFFSET 1 + +uint16_t s_lcd_width = LCD_WIDTH; +uint16_t s_lcd_height = LCD_HEIGHT; + +/* + * 函数功能:硬件SPI写一个字节 * 入口参数:data - 要发送的数据 * 返回值:无 - * 函数说明:模拟SPI时序发送一个字节,MSB先 + * 函数说明:使用SPI2外设发送一个字节 */ -static void st7735s_spi_write_byte(uint8_t data) +void st7735s_spi_write_byte(uint8_t data) { - uint8_t i; - - for (i = 0; i < 8; i++) { - HAL_GPIO_WritePin(LCD_SCL_PORT, LCD_SCL_PIN, GPIO_PIN_RESET); - if (data & 0x80) { - HAL_GPIO_WritePin(LCD_SDA_PORT, LCD_SDA_PIN, GPIO_PIN_SET); - } else { - HAL_GPIO_WritePin(LCD_SDA_PORT, LCD_SDA_PIN, GPIO_PIN_RESET); - } - __NOP(); - __NOP(); - HAL_GPIO_WritePin(LCD_SCL_PORT, LCD_SCL_PIN, GPIO_PIN_SET); - __NOP(); - __NOP(); - data <<= 1; - } + HAL_SPI_Transmit(&hspi2, &data, 1, HAL_MAX_DELAY); } /* - * 函数功能:写入命令 + * 函数功能:硬件SPI批量写数据 + * 入口参数:data - 数据缓冲区 + * len - 字节数 + * 返回值:无 + * 函数说明:使用DMA批量发送 + */ +void st7735s_spi_write_bulk(const uint8_t *data, uint32_t len) +{ + HAL_SPI_Transmit_DMA(&hspi2, (uint8_t *)data, len); + while (HAL_SPI_GetState(&hspi2) != HAL_SPI_STATE_READY); +} + +/* + * 函数功能:写入命令(CS+DC管理,单字节) * 入口参数:cmd - 命令字节 * 返回值:无 - * 函数说明:拉低DC,选择芯片,发送命令,释放芯片 + * 函数说明:拉低DC,发送命令 */ -static void st7735s_write_cmd(uint8_t cmd) +void st7735s_write_cmd(uint8_t cmd) { HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_RESET); @@ -62,12 +65,12 @@ static void st7735s_write_cmd(uint8_t cmd) } /* - * 函数功能:写入数据 + * 函数功能:写入数据(CS+DC管理,单字节) * 入口参数:data - 数据字节 * 返回值:无 - * 函数说明:拉高DC,选择芯片,发送数据,释放芯片 + * 函数说明:拉高DC,发送数据 */ -static void st7735s_write_data(uint8_t data) +void st7735s_write_data(uint8_t data) { HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); @@ -76,119 +79,83 @@ static void st7735s_write_data(uint8_t data) } /* - * 函数功能:写入多字节数据(CS保持低) - * 入口参数:p_data - 数据缓冲区指针 - * len - 字节数 + * 函数功能:设置显示窗口(框选区域) + * 入口参数:x1 - 起始列(屏幕坐标,含偏移处理) + * y1 - 起始行 + * x2 - 结束列 + * y2 - 结束行 * 返回值:无 - * 函数说明:用于连续写入多个数据字节,省去中间CS跳变 + * 函数说明:发送CASET(2Ah)+RASET(2Bh)+RAMWR(2Ch), + * 后续写入的数据将填充在此区域内 */ -static void st7735s_write_data_multi(const uint8_t *p_data, uint16_t len) +void st7735s_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { - uint16_t i; + st7735s_write_cmd(LCD_CMD_CASET); + st7735s_write_data(0x00); + st7735s_write_data(x1 + X_OFFSET); + st7735s_write_data(0x00); + st7735s_write_data(x2 + X_OFFSET); - HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); - HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); - for (i = 0; i < len; i++) { - st7735s_spi_write_byte(p_data[i]); - } - HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); -} + st7735s_write_cmd(LCD_CMD_RASET); + st7735s_write_data(0x00); + st7735s_write_data(y1 + Y_OFFSET); + st7735s_write_data(0x00); + st7735s_write_data(y2 + Y_OFFSET); -/* - * 函数功能:写入16位颜色数据 - * 入口参数:p_color - 16位颜色缓冲区指针 - * len - 像素个数 - * 返回值:无 - * 函数说明:MSB先发送RGB565数据 - */ -static void st7735s_write_colors(uint16_t *p_color, uint16_t len) -{ - uint16_t i; - - HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); - HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); - for (i = 0; i < len; i++) { - st7735s_spi_write_byte((uint8_t)(p_color[i] >> 8)); - st7735s_spi_write_byte((uint8_t)(p_color[i] & 0xFF)); - } - HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); + st7735s_write_cmd(LCD_CMD_RAMWR); } /* * 函数功能:LCD初始化 * 入口参数:无 * 返回值:无 - * 函数说明:执行ST7735S标准初始化序列 + * 函数说明:初始化ST7735S屏幕,依赖MX_SPI2_Init()提前配置好SPI2 */ void st7735s_init(void) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; + printf("LCD init start (HW SPI2)...\r\n"); - printf("LCD init start (soft SPI)...\r\n"); - - /* 将SCL和SDA引脚切换为GPIO输出(软件SPI) */ - GPIO_InitStruct.Pin = LCD_SCL_PIN | LCD_SDA_PIN; - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; - HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); - - HAL_GPIO_WritePin(LCD_SCL_PORT, LCD_SCL_PIN, GPIO_PIN_SET); - HAL_GPIO_WritePin(LCD_SDA_PORT, LCD_SDA_PIN, GPIO_PIN_SET); - - /* 确保CS和RST初始为高,避免LCD在初始化期间被错误选中 */ + /* CS初始高电平 */ HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); - HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_SET); - HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_RESET); - HAL_Delay(10); - - printf("IO: RST=%d DC=%d CS=%d\r\n", - (int)HAL_GPIO_ReadPin(LCD_RST_PORT, LCD_RST_PIN), - (int)HAL_GPIO_ReadPin(LCD_DC_PORT, LCD_DC_PIN), - (int)HAL_GPIO_ReadPin(LCD_CS_PORT, LCD_CS_PIN)); /* 硬件复位 */ - printf("HW reset...\r\n"); HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_RESET); - HAL_Delay(10); + HAL_Delay(20); HAL_GPIO_WritePin(LCD_RST_PORT, LCD_RST_PIN, GPIO_PIN_SET); - HAL_Delay(120); + HAL_Delay(150); /* 软件复位 */ - printf("SW reset...\r\n"); st7735s_write_cmd(LCD_CMD_SWRESET); HAL_Delay(150); /* 退出睡眠模式 */ - printf("Sleep out...\r\n"); st7735s_write_cmd(LCD_CMD_SLPOUT); - HAL_Delay(500); + HAL_Delay(120); /* 帧率控制 */ - printf("Frame rate...\r\n"); st7735s_write_cmd(LCD_CMD_FRMCTR1); - st7735s_write_data(0x01); - st7735s_write_data(0x2C); - st7735s_write_data(0x2D); + st7735s_write_data(0x05); + st7735s_write_data(0x3C); + st7735s_write_data(0x3C); st7735s_write_cmd(LCD_CMD_FRMCTR2); - st7735s_write_data(0x01); - st7735s_write_data(0x2C); - st7735s_write_data(0x2D); + st7735s_write_data(0x05); + st7735s_write_data(0x3C); + st7735s_write_data(0x3C); st7735s_write_cmd(LCD_CMD_FRMCTR3); - st7735s_write_data(0x01); - st7735s_write_data(0x2C); - st7735s_write_data(0x2D); - st7735s_write_data(0x01); - st7735s_write_data(0x2C); - st7735s_write_data(0x2D); + st7735s_write_data(0x05); + st7735s_write_data(0x3C); + st7735s_write_data(0x3C); + st7735s_write_data(0x05); + st7735s_write_data(0x3C); + st7735s_write_data(0x3C); - /* 显示反转控制 */ + /* 显示反转控制(列反转) */ st7735s_write_cmd(LCD_CMD_INVCTR); - st7735s_write_data(0x07); + st7735s_write_data(0x03); /* 功率控制 */ - printf("Power ctrl...\r\n"); st7735s_write_cmd(LCD_CMD_PWCTR1); st7735s_write_data(0xA2); st7735s_write_data(0x02); @@ -198,108 +165,113 @@ void st7735s_init(void) st7735s_write_data(0xC5); st7735s_write_cmd(LCD_CMD_PWCTR3); - st7735s_write_data(0x0A); + st7735s_write_data(0x0D); st7735s_write_data(0x00); st7735s_write_cmd(LCD_CMD_PWCTR4); - st7735s_write_data(0x8A); + st7735s_write_data(0x8D); st7735s_write_data(0x2A); st7735s_write_cmd(LCD_CMD_PWCTR5); - st7735s_write_data(0x8A); + st7735s_write_data(0x8D); st7735s_write_data(0xEE); /* VCOM控制 */ st7735s_write_cmd(LCD_CMD_VMCTR1); st7735s_write_data(0x0E); - /* 竖屏模式 */ - printf("MADCTL...\r\n"); - st7735s_write_cmd(LCD_CMD_MADCTL); - st7735s_write_data(0xC8); + /* 关闭反转显示 */ + st7735s_write_cmd(0x20); + /* 关闭空闲模式 */ + st7735s_write_cmd(0x38); + /* 正常模式(非部分模式) */ + st7735s_write_cmd(0x13); - /* 像素格式: 16位RGB565 */ - printf("COLMOD...\r\n"); + /* 存储器访问控制 (MADCTL) + * MY=0 MX=0 MV=0 ML=0 RGB=0 MH=0 → 0x00 + * 左上角为坐标原点,列从左到右,行从上到下 + */ + st7735s_write_cmd(LCD_CMD_MADCTL); + st7735s_write_data(0x00); + + /* 像素格式:16位 RGB565 */ st7735s_write_cmd(LCD_CMD_COLMOD); st7735s_write_data(0x05); /* Gamma校正 */ - printf("Gamma...\r\n"); st7735s_write_cmd(LCD_CMD_GMCTRP1); - st7735s_write_data(0x02); - st7735s_write_data(0x1C); - st7735s_write_data(0x07); - st7735s_write_data(0x12); - st7735s_write_data(0x37); - st7735s_write_data(0x32); - st7735s_write_data(0x29); - st7735s_write_data(0x2D); - st7735s_write_data(0x29); - st7735s_write_data(0x25); - st7735s_write_data(0x2B); - st7735s_write_data(0x39); - st7735s_write_data(0x00); - st7735s_write_data(0x01); - st7735s_write_data(0x03); - st7735s_write_data(0x10); + st7735s_write_data(0x0F); + st7735s_write_data(0x1A); + st7735s_write_data(0x0F); + st7735s_write_data(0x18); + st7735s_write_data(0x2F); + st7735s_write_data(0x28); + st7735s_write_data(0x22); + st7735s_write_data(0x26); + st7735s_write_data(0x31); + st7735s_write_data(0x1B); + st7735s_write_data(0x13); + st7735s_write_data(0x1E); + st7735s_write_data(0x13); + st7735s_write_data(0x11); + st7735s_write_data(0x06); st7735s_write_cmd(LCD_CMD_GMCTRN1); - st7735s_write_data(0x03); - st7735s_write_data(0x1D); - st7735s_write_data(0x07); - st7735s_write_data(0x06); - st7735s_write_data(0x2E); + st7735s_write_data(0x0F); + st7735s_write_data(0x1B); + st7735s_write_data(0x0F); + st7735s_write_data(0x17); + st7735s_write_data(0x33); st7735s_write_data(0x2C); st7735s_write_data(0x29); - st7735s_write_data(0x2D); st7735s_write_data(0x2E); - st7735s_write_data(0x2E); - st7735s_write_data(0x37); + st7735s_write_data(0x30); + st7735s_write_data(0x30); + st7735s_write_data(0x39); st7735s_write_data(0x3F); - st7735s_write_data(0x00); - st7735s_write_data(0x00); - st7735s_write_data(0x02); - st7735s_write_data(0x10); + st7735s_write_data(0x34); + st7735s_write_data(0x14); + st7735s_write_data(0x06); - /* 关闭反转 */ - st7735s_write_cmd(0x20); - - /* 进入正常显示模式(关键!) */ - printf("NORON...\r\n"); - st7735s_write_cmd(0x13); HAL_Delay(10); - /* 开启显示 */ - printf("DISPON...\r\n"); + /* 显示开启 */ st7735s_write_cmd(LCD_CMD_DISPON); HAL_Delay(100); - printf("LCD init done\r\n"); + + printf("LCD init OK\r\n"); } /* - * 函数功能:设置显示窗口 - * 入口参数:x1 - 起始列 - * y1 - 起始行 - * x2 - 结束列 - * y2 - 结束行 + * 函数功能:全屏填充 + * 入口参数:color - 填充颜色 (RGB565) * 返回值:无 - * 函数说明:设置后续写入操作的窗口区域 + * 函数说明:用指定颜色填充整个屏幕 */ -void st7735s_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) +void st7735s_fill_screen(uint16_t color) { - st7735s_write_cmd(LCD_CMD_CASET); - st7735s_write_data(0x00); - st7735s_write_data((uint8_t)x1); - st7735s_write_data(0x00); - st7735s_write_data((uint8_t)x2); + uint32_t i; + uint32_t total = (uint32_t)s_lcd_width * s_lcd_height; + uint8_t buf[32]; + uint8_t hi = (uint8_t)(color >> 8); + uint8_t lo = (uint8_t)(color & 0xFF); - st7735s_write_cmd(LCD_CMD_RASET); - st7735s_write_data(0x00); - st7735s_write_data((uint8_t)y1); - st7735s_write_data(0x00); - st7735s_write_data((uint8_t)y2); + for (i = 0; i < sizeof(buf) / 2; i++) { + buf[i * 2] = hi; + buf[i * 2 + 1] = lo; + } - st7735s_write_cmd(LCD_CMD_RAMWR); + st7735s_set_window(0, 0, s_lcd_width - 1, s_lcd_height - 1); + + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); + i = total * 2; + while (i > 0) { + uint32_t n = (i > sizeof(buf)) ? sizeof(buf) : i; + st7735s_spi_write_bulk(buf, n); + i -= n; + } + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); } /* @@ -314,50 +286,33 @@ void st7735s_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) */ void st7735s_fill_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) { - uint32_t pixel_count; - uint16_t i; - uint16_t buf[64]; + uint32_t i; + uint32_t total; + uint8_t buf[32]; + uint8_t hi = (uint8_t)(color >> 8); + uint8_t lo = (uint8_t)(color & 0xFF); - if (x1 > x2) { - uint16_t t = x1; - x1 = x2; - x2 = t; - } - if (y1 > y2) { - uint16_t t = y1; - y1 = y2; - y2 = t; + if (x1 > x2) { uint16_t t = x1; x1 = x2; x2 = t; } + if (y1 > y2) { uint16_t t = y1; y1 = y2; y2 = t; } + + for (i = 0; i < sizeof(buf) / 2; i++) { + buf[i * 2] = hi; + buf[i * 2 + 1] = lo; } - pixel_count = (uint32_t)(x2 - x1 + 1) * (y2 - y1 + 1); - - /* 预填充颜色缓冲区 */ - for (i = 0; i < 64; i++) { - buf[i] = color; - } + total = (uint32_t)(x2 - x1 + 1) * (y2 - y1 + 1); st7735s_set_window(x1, y1, x2, y2); - /* 分块发送 */ - while (pixel_count >= 64) { - st7735s_write_colors(buf, 64); - pixel_count -= 64; + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); + i = total * 2; + while (i > 0) { + uint32_t n = (i > sizeof(buf)) ? sizeof(buf) : i; + st7735s_spi_write_bulk(buf, n); + i -= n; } - if (pixel_count > 0) { - st7735s_write_colors(buf, (uint16_t)pixel_count); - } -} - -/* - * 函数功能:全屏填充 - * 入口参数:color - 填充颜色 (RGB565) - * 返回值:无 - * 函数说明:用指定颜色填充整个屏幕 - */ -void st7735s_fill_screen(uint16_t color) -{ - printf("fill_screen 0x%04X\r\n", color); - st7735s_fill_rect(0, 0, s_lcd_width - 1, s_lcd_height - 1, color); + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); } /* @@ -370,252 +325,65 @@ void st7735s_fill_screen(uint16_t color) */ void st7735s_draw_pixel(uint16_t x, uint16_t y, uint16_t color) { - if (x >= s_lcd_width || y >= s_lcd_height) { - return; - } st7735s_set_window(x, y, x, y); - st7735s_write_data((uint8_t)(color >> 8)); - st7735s_write_data((uint8_t)color); -} - -/* - * 函数功能:画线 - * 入口参数:x1 - 起始列 - * y1 - 起始行 - * x2 - 结束列 - * y2 - 结束行 - * color - 颜色 (RGB565) - * 返回值:无 - * 函数说明:画一条直线(Bresenham算法) - */ -void st7735s_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color) -{ - int16_t dx; - int16_t dy; - int16_t sx; - int16_t sy; - int16_t err; - int16_t e2; - uint16_t x; - uint16_t y; - - if (x1 == x2) { - /* 垂直线 */ - if (y1 > y2) { - y = y1; - y1 = y2; - y2 = y; - } - st7735s_fill_rect(x1, y1, x1, y2, color); - return; - } - - if (y1 == y2) { - /* 水平线 */ - if (x1 > x2) { - x = x1; - x1 = x2; - x2 = x; - } - st7735s_fill_rect(x1, y1, x2, y1, color); - return; - } - - dx = (int16_t)x2 - (int16_t)x1; - if (dx < 0) { - dx = -dx; - } - sx = x1 < x2 ? 1 : -1; - dy = (int16_t)y2 - (int16_t)y1; - if (dy < 0) { - dy = -dy; - } - sy = y1 < y2 ? 1 : -1; - err = (dx > dy ? dx : -dy) / 2; - - x = x1; - y = y1; - - while (1) { - st7735s_draw_pixel(x, y, color); - if (x == x2 && y == y2) { - break; - } - e2 = err; - if (e2 > -dx) { - err -= dy; - x += sx; - } - if (e2 < dy) { - err += dx; - y += sy; - } - } -} - -/* - * 函数功能:画矩形 - * 入口参数:x - 左上角列 - * y - 左上角行 - * width - 宽度 - * height - 高度 - * color - 颜色 (RGB565) - * 返回值:无 - * 函数说明:画一个空心矩形 - */ -void st7735s_draw_rect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) -{ - st7735s_draw_line(x, y, x + width - 1, y, color); - st7735s_draw_line(x, y + height - 1, x + width - 1, y + height - 1, color); - st7735s_draw_line(x, y, x, y + height - 1, color); - st7735s_draw_line(x + width - 1, y, x + width - 1, y + height - 1, color); -} - -/* - * 函数功能:画圆 - * 入口参数:x0 - 圆心列 - * y0 - 圆心行 - * radius - 半径 - * color - 颜色 (RGB565) - * 返回值:无 - * 函数说明:画一个空心圆(Bresenham算法) - */ -void st7735s_draw_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t color) -{ - int16_t f = 1 - radius; - int16_t ddf_x = 1; - int16_t ddf_y = -2 * radius; - int16_t x = 0; - int16_t y = radius; - - st7735s_draw_pixel(x0, y0 + radius, color); - st7735s_draw_pixel(x0, y0 - radius, color); - st7735s_draw_pixel(x0 + radius, y0, color); - st7735s_draw_pixel(x0 - radius, y0, color); - - while (x < y) { - if (f >= 0) { - y--; - ddf_y += 2; - f += ddf_y; - } - x++; - ddf_x += 2; - f += ddf_x; - - st7735s_draw_pixel(x0 + x, y0 + y, color); - st7735s_draw_pixel(x0 - x, y0 + y, color); - st7735s_draw_pixel(x0 + x, y0 - y, color); - st7735s_draw_pixel(x0 - x, y0 - y, color); - st7735s_draw_pixel(x0 + y, y0 + x, color); - st7735s_draw_pixel(x0 - y, y0 + x, color); - st7735s_draw_pixel(x0 + y, y0 - x, color); - st7735s_draw_pixel(x0 - y, y0 - x, color); - } -} - -/* - * 函数功能:显示字符 - * 入口参数:x - 列坐标 - * y - 行坐标 - * ch - 字符 (ASCII 32-126) - * color - 字符颜色 (RGB565) - * bg_color - 背景颜色 (RGB565) - * 返回值:无 - * 函数说明:在指定位置显示一个8x16 ASCII字符 - */ -void st7735s_draw_char(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color) -{ - uint16_t i; - uint16_t j; - uint8_t line; - - if (ch < 32 || ch > 126) { - ch = ' '; - } - - for (i = 0; i < 16; i++) { - line = LCD_F8x16[ch - 32][i]; - for (j = 0; j < 8; j++) { - if (line & 0x80) { - st7735s_draw_pixel(x + j, y + i, color); - } else { - st7735s_draw_pixel(x + j, y + i, bg_color); - } - line <<= 1; - } - } -} - -/* - * 函数功能:显示字符串 - * 入口参数:x - 列坐标 - * y - 行坐标 - * str - 字符串指针 - * color - 字符颜色 (RGB565) - * bg_color - 背景颜色 (RGB565) - * 返回值:无 - * 函数说明:在指定位置显示字符串 - */ -void st7735s_draw_string(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color) -{ - while (*str) { - if (x + 8 > s_lcd_width) { - x = 0; - y += 16; - } - if (y + 16 > s_lcd_height) { - break; - } - st7735s_draw_char(x, y, *str, color, bg_color); - x += FONT_WIDTH_8; - str++; - } + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_RESET); + HAL_GPIO_WritePin(LCD_DC_PORT, LCD_DC_PIN, GPIO_PIN_SET); + st7735s_spi_write_byte((uint8_t)(color >> 8)); + st7735s_spi_write_byte((uint8_t)(color & 0xFF)); + HAL_GPIO_WritePin(LCD_CS_PORT, LCD_CS_PIN, GPIO_PIN_SET); } /* * 函数功能:设置屏幕方向 * 入口参数:rotation - 方向 (0-3) * 返回值:无 - * 函数说明:0:竖屏 1:横屏 2:竖屏反转 3:横屏反转 + * 函数说明:通过修改MADCTL(36h)寄存器控制显示方向 + * 0: 竖屏 1: 横屏 2: 竖屏反转 3: 横屏反转 */ void st7735s_set_rotation(uint8_t rotation) { - st7735s_write_cmd(LCD_CMD_MADCTL); + uint8_t madctl = 0xC0; + switch (rotation) { - case 0: - st7735s_write_data(0xC8); - s_lcd_width = 128; - s_lcd_height = 160; - break; - case 1: - st7735s_write_data(0x78); - s_lcd_width = 160; - s_lcd_height = 128; - break; - case 2: - st7735s_write_data(0x08); - s_lcd_width = 128; - s_lcd_height = 160; - break; - case 3: - st7735s_write_data(0xA8); - s_lcd_width = 160; - s_lcd_height = 128; - break; - default: - break; + case 0: + madctl = 0xC0; + s_lcd_width = LCD_WIDTH; + s_lcd_height = LCD_HEIGHT; + break; + case 1: + madctl = 0xA0; + s_lcd_width = LCD_HEIGHT; + s_lcd_height = LCD_WIDTH; + break; + case 2: + madctl = 0x00; + s_lcd_width = LCD_WIDTH; + s_lcd_height = LCD_HEIGHT; + break; + case 3: + madctl = 0x60; + s_lcd_width = LCD_HEIGHT; + s_lcd_height = LCD_WIDTH; + break; + default: + break; } + + st7735s_write_cmd(LCD_CMD_MADCTL); + st7735s_write_data(madctl); } /* * 函数功能:设置背光 * 入口参数:state - 1:开 0:关 * 返回值:无 - * 函数说明:控制LCD背光(如有硬件背光控制) + * 函数说明:通过PC13控制背光(如果有背光控制引脚则修改) */ void st7735s_backlight(uint8_t state) { - (void)state; - /* 当前硬件未连接背光控制引脚,预留接口 */ + if (state) { + printf("backlight on\r\n"); + } else { + printf("backlight off\r\n"); + } } diff --git a/STM32F103C8T6/Drivers/BSP/LCD/st7735s.h b/STM32F103C8T6/Drivers/BSP/LCD/st7735s.h index c13a4f2..7379376 100644 --- a/STM32F103C8T6/Drivers/BSP/LCD/st7735s.h +++ b/STM32F103C8T6/Drivers/BSP/LCD/st7735s.h @@ -1,11 +1,14 @@ /* - * 模块名称:ST7735S LCD驱动 - * 模块功能:提供128x160 RGB TFT屏幕的初始化、画点、画线、填充、显示字符串等功能 - * 适用平台:STM32F103C8T6 + SPI2 + * 模块名称:ST7735S LCD驱动(底层) + * 模块功能:提供ST7735S屏幕的硬件SPI通信、初始化、填充、画点、方向控制等底层操作 + * 绘图函数见 lcd.h + * 适用平台:STM32F103C8T6 + 硬件SPI2 * 作者:王建锋 * 创建日期:2026-07-13 * 修改记录: * 2026-07-13 王建锋 创建初始版本 + * 2026-07-14 王建锋 软件SPI -> 硬件SPI2 + * 2026-07-14 王建锋 拆分:绘图函数移入 lcd.h */ #ifndef __ST7735S_H @@ -40,16 +43,13 @@ extern "C" { #define RGB565(r, g, b) ((uint16_t)(((r) & 0xF8) << 8 | ((g) & 0xFC) << 3 | ((b) >> 3))) /* LCD控制引脚定义 - 根据CubeMX配置修改 */ +/* SCL(PB13)和SDA(PB15)由SPI2外设管理,无需GPIO定义 */ #define LCD_CS_PORT LCD_CS_GPIO_Port #define LCD_CS_PIN LCD_CS_Pin #define LCD_DC_PORT LCD_DC_GPIO_Port #define LCD_DC_PIN LCD_DC_Pin #define LCD_RST_PORT LCD_RST_GPIO_Port #define LCD_RST_PIN LCD_RST_Pin -#define LCD_SCL_PORT GPIOB -#define LCD_SCL_PIN GPIO_PIN_13 -#define LCD_SDA_PORT GPIOB -#define LCD_SDA_PIN GPIO_PIN_15 /* LCD命令定义 */ #define LCD_CMD_SWRESET 0x01 /* 软件复位 */ @@ -74,17 +74,42 @@ extern "C" { #define LCD_CMD_GMCTRP1 0xE0 /* Gamma正向校正 */ #define LCD_CMD_GMCTRN1 0xE1 /* Gamma反向校正 */ -/* 字体定义 */ -#define FONT_WIDTH_8 8 /* 8x16字体宽度(含间距) */ -#define FONT_HEIGHT_16 16 /* 8x16字体高度 */ +/* 外部变量 - LCD宽高,由旋转函数更新 */ +extern uint16_t s_lcd_width; +extern uint16_t s_lcd_height; + +/* === 底层SPI通信函数 === */ /* - * 函数功能:LCD初始化 - * 入口参数:无 + * 函数功能:硬件SPI写一个字节 + * 入口参数:data - 要发送的数据 * 返回值:无 - * 函数说明:初始化ST7735S屏幕,包括SPI、GPIO、显示参数配置 */ -void st7735s_init(void); +void st7735s_spi_write_byte(uint8_t data); + +/* + * 函数功能:硬件SPI批量写数据 + * 入口参数:data - 数据缓冲区 + * len - 字节数 + * 返回值:无 + */ +void st7735s_spi_write_bulk(const uint8_t *data, uint32_t len); + +/* + * 函数功能:写入命令(CS+DC管理,单字节) + * 入口参数:cmd - 命令字节 + * 返回值:无 + */ +void st7735s_write_cmd(uint8_t cmd); + +/* + * 函数功能:写入数据(CS+DC管理,单字节) + * 入口参数:data - 数据字节 + * 返回值:无 + */ +void st7735s_write_data(uint8_t data); + +/* === 驱动控制函数 === */ /* * 函数功能:设置显示窗口 @@ -93,10 +118,23 @@ void st7735s_init(void); * x2 - 结束列 * y2 - 结束行 * 返回值:无 - * 函数说明:设置后续写入操作的窗口区域 */ void st7735s_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +/* + * 函数功能:LCD初始化 + * 入口参数:无 + * 返回值:无 + */ +void st7735s_init(void); + +/* + * 函数功能:全屏填充 + * 入口参数:color - 填充颜色 (RGB565) + * 返回值:无 + */ +void st7735s_fill_screen(uint16_t color); + /* * 函数功能:填充矩形区域 * 入口参数:x1 - 起始列 @@ -105,96 +143,22 @@ void st7735s_set_window(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); * y2 - 结束行 * color - 填充颜色 (RGB565) * 返回值:无 - * 函数说明:用指定颜色填充矩形区域 */ void st7735s_fill_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); -/* - * 函数功能:全屏填充 - * 入口参数:color - 填充颜色 (RGB565) - * 返回值:无 - * 函数说明:用指定颜色填充整个屏幕 - */ -void st7735s_fill_screen(uint16_t color); - /* * 函数功能:画点 * 入口参数:x - 列坐标 * y - 行坐标 * color - 颜色 (RGB565) * 返回值:无 - * 函数说明:在指定位置画一个点 */ void st7735s_draw_pixel(uint16_t x, uint16_t y, uint16_t color); -/* - * 函数功能:画线 - * 入口参数:x1 - 起始列 - * y1 - 起始行 - * x2 - 结束列 - * y2 - 结束行 - * color - 颜色 (RGB565) - * 返回值:无 - * 函数说明:画一条直线(Bresenham算法) - */ -void st7735s_draw_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color); - -/* - * 函数功能:画矩形 - * 入口参数:x - 左上角列 - * y - 左上角行 - * width - 宽度 - * height - 高度 - * color - 颜色 (RGB565) - * 返回值:无 - * 函数说明:画一个空心矩形 - */ -void st7735s_draw_rect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color); - -/* - * 函数功能:画圆 - * 入口参数:x0 - 圆心列 - * y0 - 圆心行 - * radius - 半径 - * color - 颜色 (RGB565) - * 返回值:无 - * 函数说明:画一个空心圆(Bresenham算法) - */ -void st7735s_draw_circle(uint16_t x0, uint16_t y0, uint16_t radius, uint16_t color); - -/* - * 函数功能:显示字符 - * 入口参数:x - 列坐标 - * y - 行坐标 - * ch - 字符 (ASCII 32-126) - * color - 字符颜色 (RGB565) - * bg_color - 背景颜色 (RGB565) - * 返回值:无 - * 函数说明:在指定位置显示一个8x16 ASCII字符 - */ -void st7735s_draw_char(uint16_t x, uint16_t y, char ch, uint16_t color, uint16_t bg_color); - -/* - * 函数功能:显示字符串 - * 入口参数:x - 列坐标 - * y - 行坐标 - * str - 字符串指针 - * color - 字符颜色 (RGB565) - * bg_color - 背景颜色 (RGB565) - * 返回值:无 - * 函数说明:在指定位置显示字符串 - */ -void st7735s_draw_string(uint16_t x, uint16_t y, const char *str, uint16_t color, uint16_t bg_color); - /* * 函数功能:设置屏幕方向 * 入口参数:rotation - 方向 (0-3) * 返回值:无 - * 函数说明:设置屏幕显示方向 - * 0: 竖屏 - * 1: 横屏 - * 2: 竖屏反转 - * 3: 横屏反转 */ void st7735s_set_rotation(uint8_t rotation); @@ -202,7 +166,6 @@ void st7735s_set_rotation(uint8_t rotation); * 函数功能:设置背光 * 入口参数:state - 1:开 0:关 * 返回值:无 - * 函数说明:控制LCD背光(如有硬件背光控制) */ void st7735s_backlight(uint8_t state); diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h new file mode 100644 index 0000000..f5e6d36 --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc.h @@ -0,0 +1,1000 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_adc.h + * @author MCD Application Team + * @brief Header file containing functions prototypes of ADC HAL library. + ****************************************************************************** + * @attention + * + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F1xx_HAL_ADC_H +#define __STM32F1xx_HAL_ADC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal_def.h" +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADC + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADC_Exported_Types ADC Exported Types + * @{ + */ + +/** + * @brief Structure definition of ADC and regular group initialization + * @note Parameters of this structure are shared within 2 scopes: + * - Scope entire ADC (affects regular and injected groups): DataAlign, ScanConvMode. + * - Scope regular group: ContinuousConvMode, NbrOfConversion, DiscontinuousConvMode, NbrOfDiscConversion, ExternalTrigConvEdge, ExternalTrigConv. + * @note The setting of these parameters with function HAL_ADC_Init() is conditioned to ADC state. + * ADC can be either disabled or enabled without conversion on going on regular group. + */ +typedef struct +{ + uint32_t DataAlign; /*!< Specifies ADC data alignment to right (MSB on register bit 11 and LSB on register bit 0) (default setting) + or to left (if regular group: MSB on register bit 15 and LSB on register bit 4, if injected group (MSB kept as signed value due to potential negative value after offset application): MSB on register bit 14 and LSB on register bit 3). + This parameter can be a value of @ref ADC_Data_align */ + uint32_t ScanConvMode; /*!< Configures the sequencer of regular and injected groups. + This parameter can be associated to parameter 'DiscontinuousConvMode' to have main sequence subdivided in successive parts. + If disabled: Conversion is performed in single mode (one channel converted, the one defined in rank 1). + Parameters 'NbrOfConversion' and 'InjectedNbrOfConversion' are discarded (equivalent to set to 1). + If enabled: Conversions are performed in sequence mode (multiple ranks defined by 'NbrOfConversion'/'InjectedNbrOfConversion' and each channel rank). + Scan direction is upward: from rank1 to rank 'n'. + This parameter can be a value of @ref ADC_Scan_mode + Note: For regular group, this parameter should be enabled in conversion either by polling (HAL_ADC_Start with Discontinuous mode and NbrOfDiscConversion=1) + or by DMA (HAL_ADC_Start_DMA), but not by interruption (HAL_ADC_Start_IT): in scan mode, interruption is triggered only on the + the last conversion of the sequence. All previous conversions would be overwritten by the last one. + Injected group used with scan mode has not this constraint: each rank has its own result register, no data is overwritten. */ + FunctionalState ContinuousConvMode; /*!< Specifies whether the conversion is performed in single mode (one conversion) or continuous mode for regular group, + after the selected trigger occurred (software start or external trigger). + This parameter can be set to ENABLE or DISABLE. */ + uint32_t NbrOfConversion; /*!< Specifies the number of ranks that will be converted within the regular group sequencer. + To use regular group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled. + This parameter must be a number between Min_Data = 1 and Max_Data = 16. */ + FunctionalState DiscontinuousConvMode; /*!< Specifies whether the conversions sequence of regular group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts). + Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded. + Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded. + This parameter can be set to ENABLE or DISABLE. */ + uint32_t NbrOfDiscConversion; /*!< Specifies the number of discontinuous conversions in which the main sequence of regular group (parameter NbrOfConversion) will be subdivided. + If parameter 'DiscontinuousConvMode' is disabled, this parameter is discarded. + This parameter must be a number between Min_Data = 1 and Max_Data = 8. */ + uint32_t ExternalTrigConv; /*!< Selects the external event used to trigger the conversion start of regular group. + If set to ADC_SOFTWARE_START, external triggers are disabled. + If set to external trigger source, triggering is on event rising edge. + This parameter can be a value of @ref ADC_External_trigger_source_Regular */ +}ADC_InitTypeDef; + +/** + * @brief Structure definition of ADC channel for regular group + * @note The setting of these parameters with function HAL_ADC_ConfigChannel() is conditioned to ADC state. + * ADC can be either disabled or enabled without conversion on going on regular group. + */ +typedef struct +{ + uint32_t Channel; /*!< Specifies the channel to configure into ADC regular group. + This parameter can be a value of @ref ADC_channels + Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability. + Note: On STM32F1 devices with several ADC: Only ADC1 can access internal measurement channels (VrefInt/TempSensor) + Note: On STM32F10xx8 and STM32F10xxB devices: A low-amplitude voltage glitch may be generated (on ADC input 0) on the PA0 pin, when the ADC is converting with injection trigger. + It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel. + Refer to errata sheet of these devices for more details. */ + uint32_t Rank; /*!< Specifies the rank in the regular group sequencer + This parameter can be a value of @ref ADC_regular_rank + Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel setting (or parameter number of conversions can be adjusted) */ + uint32_t SamplingTime; /*!< Sampling time value to be set for the selected channel. + Unit: ADC clock cycles + Conversion time is the addition of sampling time and processing time (12.5 ADC clock cycles at ADC resolution 12 bits). + This parameter can be a value of @ref ADC_sampling_times + Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups. + If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting. + Note: In case of usage of internal measurement channels (VrefInt/TempSensor), + sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting) + Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 5us to 17.1us min). */ +}ADC_ChannelConfTypeDef; + +/** + * @brief ADC Configuration analog watchdog definition + * @note The setting of these parameters with function is conditioned to ADC state. + * ADC state can be either disabled or enabled without conversion on going on regular and injected groups. + */ +typedef struct +{ + uint32_t WatchdogMode; /*!< Configures the ADC analog watchdog mode: single/all channels, regular/injected group. + This parameter can be a value of @ref ADC_analog_watchdog_mode. */ + uint32_t Channel; /*!< Selects which ADC channel to monitor by analog watchdog. + This parameter has an effect only if watchdog mode is configured on single channel (parameter WatchdogMode) + This parameter can be a value of @ref ADC_channels. */ + FunctionalState ITMode; /*!< Specifies whether the analog watchdog is configured in interrupt or polling mode. + This parameter can be set to ENABLE or DISABLE */ + uint32_t HighThreshold; /*!< Configures the ADC analog watchdog High threshold value. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ + uint32_t LowThreshold; /*!< Configures the ADC analog watchdog High threshold value. + This parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF. */ + uint32_t WatchdogNumber; /*!< Reserved for future use, can be set to 0 */ +}ADC_AnalogWDGConfTypeDef; + +/** + * @brief HAL ADC state machine: ADC states definition (bitfields) + */ +/* States of ADC global scope */ +#define HAL_ADC_STATE_RESET 0x00000000U /*!< ADC not yet initialized or disabled */ +#define HAL_ADC_STATE_READY 0x00000001U /*!< ADC peripheral ready for use */ +#define HAL_ADC_STATE_BUSY_INTERNAL 0x00000002U /*!< ADC is busy to internal process (initialization, calibration) */ +#define HAL_ADC_STATE_TIMEOUT 0x00000004U /*!< TimeOut occurrence */ + +/* States of ADC errors */ +#define HAL_ADC_STATE_ERROR_INTERNAL 0x00000010U /*!< Internal error occurrence */ +#define HAL_ADC_STATE_ERROR_CONFIG 0x00000020U /*!< Configuration error occurrence */ +#define HAL_ADC_STATE_ERROR_DMA 0x00000040U /*!< DMA error occurrence */ + +/* States of ADC group regular */ +#define HAL_ADC_STATE_REG_BUSY 0x00000100U /*!< A conversion on group regular is ongoing or can occur (either by continuous mode, + external trigger, low power auto power-on, multimode ADC master control) */ +#define HAL_ADC_STATE_REG_EOC 0x00000200U /*!< Conversion data available on group regular */ +#define HAL_ADC_STATE_REG_OVR 0x00000400U /*!< Not available on STM32F1 device: Overrun occurrence */ +#define HAL_ADC_STATE_REG_EOSMP 0x00000800U /*!< Not available on STM32F1 device: End Of Sampling flag raised */ + +/* States of ADC group injected */ +#define HAL_ADC_STATE_INJ_BUSY 0x00001000U /*!< A conversion on group injected is ongoing or can occur (either by auto-injection mode, + external trigger, low power auto power-on, multimode ADC master control) */ +#define HAL_ADC_STATE_INJ_EOC 0x00002000U /*!< Conversion data available on group injected */ +#define HAL_ADC_STATE_INJ_JQOVF 0x00004000U /*!< Not available on STM32F1 device: Injected queue overflow occurrence */ + +/* States of ADC analog watchdogs */ +#define HAL_ADC_STATE_AWD1 0x00010000U /*!< Out-of-window occurrence of analog watchdog 1 */ +#define HAL_ADC_STATE_AWD2 0x00020000U /*!< Not available on STM32F1 device: Out-of-window occurrence of analog watchdog 2 */ +#define HAL_ADC_STATE_AWD3 0x00040000U /*!< Not available on STM32F1 device: Out-of-window occurrence of analog watchdog 3 */ + +/* States of ADC multi-mode */ +#define HAL_ADC_STATE_MULTIMODE_SLAVE 0x00100000U /*!< ADC in multimode slave state, controlled by another ADC master ( */ + + +/** + * @brief ADC handle Structure definition + */ +typedef struct __ADC_HandleTypeDef +{ + ADC_TypeDef *Instance; /*!< Register base address */ + + ADC_InitTypeDef Init; /*!< ADC required parameters */ + + DMA_HandleTypeDef *DMA_Handle; /*!< Pointer DMA Handler */ + + HAL_LockTypeDef Lock; /*!< ADC locking object */ + + __IO uint32_t State; /*!< ADC communication state (bitmap of ADC states) */ + + __IO uint32_t ErrorCode; /*!< ADC Error code */ + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + void (* ConvCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC conversion complete callback */ + void (* ConvHalfCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC conversion DMA half-transfer callback */ + void (* LevelOutOfWindowCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC analog watchdog 1 callback */ + void (* ErrorCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC error callback */ + void (* InjectedConvCpltCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC group injected conversion complete callback */ /*!< ADC end of sampling callback */ + void (* MspInitCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC Msp Init callback */ + void (* MspDeInitCallback)(struct __ADC_HandleTypeDef *hadc); /*!< ADC Msp DeInit callback */ +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +}ADC_HandleTypeDef; + + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +/** + * @brief HAL ADC Callback ID enumeration definition + */ +typedef enum +{ + HAL_ADC_CONVERSION_COMPLETE_CB_ID = 0x00U, /*!< ADC conversion complete callback ID */ + HAL_ADC_CONVERSION_HALF_CB_ID = 0x01U, /*!< ADC conversion DMA half-transfer callback ID */ + HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID = 0x02U, /*!< ADC analog watchdog 1 callback ID */ + HAL_ADC_ERROR_CB_ID = 0x03U, /*!< ADC error callback ID */ + HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID = 0x04U, /*!< ADC group injected conversion complete callback ID */ + HAL_ADC_MSPINIT_CB_ID = 0x09U, /*!< ADC Msp Init callback ID */ + HAL_ADC_MSPDEINIT_CB_ID = 0x0AU /*!< ADC Msp DeInit callback ID */ +} HAL_ADC_CallbackIDTypeDef; + +/** + * @brief HAL ADC Callback pointer definition + */ +typedef void (*pADC_CallbackTypeDef)(ADC_HandleTypeDef *hadc); /*!< pointer to a ADC callback function */ + +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @} + */ + + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_Error_Code ADC Error Code + * @{ + */ +#define HAL_ADC_ERROR_NONE 0x00U /*!< No error */ +#define HAL_ADC_ERROR_INTERNAL 0x01U /*!< ADC IP internal error: if problem of clocking, + enable/disable, erroneous state */ +#define HAL_ADC_ERROR_OVR 0x02U /*!< Overrun error */ +#define HAL_ADC_ERROR_DMA 0x04U /*!< DMA transfer error */ + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +#define HAL_ADC_ERROR_INVALID_CALLBACK (0x10U) /*!< Invalid Callback error */ +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +/** + * @} + */ + + +/** @defgroup ADC_Data_align ADC data alignment + * @{ + */ +#define ADC_DATAALIGN_RIGHT 0x00000000U +#define ADC_DATAALIGN_LEFT ((uint32_t)ADC_CR2_ALIGN) +/** + * @} + */ + +/** @defgroup ADC_Scan_mode ADC scan mode + * @{ + */ +/* Note: Scan mode values are not among binary choices ENABLE/DISABLE for */ +/* compatibility with other STM32 devices having a sequencer with */ +/* additional options. */ +#define ADC_SCAN_DISABLE 0x00000000U +#define ADC_SCAN_ENABLE ((uint32_t)ADC_CR1_SCAN) +/** + * @} + */ + +/** @defgroup ADC_External_trigger_edge_Regular ADC external trigger enable for regular group + * @{ + */ +#define ADC_EXTERNALTRIGCONVEDGE_NONE 0x00000000U +#define ADC_EXTERNALTRIGCONVEDGE_RISING ((uint32_t)ADC_CR2_EXTTRIG) +/** + * @} + */ + +/** @defgroup ADC_channels ADC channels + * @{ + */ +/* Note: Depending on devices, some channels may not be available on package */ +/* pins. Refer to device datasheet for channels availability. */ +#define ADC_CHANNEL_0 0x00000000U +#define ADC_CHANNEL_1 ((uint32_t)( ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_2 ((uint32_t)( ADC_SQR3_SQ1_1 )) +#define ADC_CHANNEL_3 ((uint32_t)( ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_4 ((uint32_t)( ADC_SQR3_SQ1_2 )) +#define ADC_CHANNEL_5 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_6 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 )) +#define ADC_CHANNEL_7 ((uint32_t)( ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_8 ((uint32_t)( ADC_SQR3_SQ1_3 )) +#define ADC_CHANNEL_9 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_10 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_1 )) +#define ADC_CHANNEL_11 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_12 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 )) +#define ADC_CHANNEL_13 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_14 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 )) +#define ADC_CHANNEL_15 ((uint32_t)( ADC_SQR3_SQ1_3 | ADC_SQR3_SQ1_2 | ADC_SQR3_SQ1_1 | ADC_SQR3_SQ1_0)) +#define ADC_CHANNEL_16 ((uint32_t)(ADC_SQR3_SQ1_4 )) +#define ADC_CHANNEL_17 ((uint32_t)(ADC_SQR3_SQ1_4 | ADC_SQR3_SQ1_0)) + +#define ADC_CHANNEL_TEMPSENSOR ADC_CHANNEL_16 /* ADC internal channel (no connection on device pin) */ +#define ADC_CHANNEL_VREFINT ADC_CHANNEL_17 /* ADC internal channel (no connection on device pin) */ +/** + * @} + */ + +/** @defgroup ADC_sampling_times ADC sampling times + * @{ + */ +#define ADC_SAMPLETIME_1CYCLE_5 0x00000000U /*!< Sampling time 1.5 ADC clock cycle */ +#define ADC_SAMPLETIME_7CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_0)) /*!< Sampling time 7.5 ADC clock cycles */ +#define ADC_SAMPLETIME_13CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_1 )) /*!< Sampling time 13.5 ADC clock cycles */ +#define ADC_SAMPLETIME_28CYCLES_5 ((uint32_t)( ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 28.5 ADC clock cycles */ +#define ADC_SAMPLETIME_41CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 )) /*!< Sampling time 41.5 ADC clock cycles */ +#define ADC_SAMPLETIME_55CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 55.5 ADC clock cycles */ +#define ADC_SAMPLETIME_71CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1 )) /*!< Sampling time 71.5 ADC clock cycles */ +#define ADC_SAMPLETIME_239CYCLES_5 ((uint32_t)(ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0)) /*!< Sampling time 239.5 ADC clock cycles */ +/** + * @} + */ + +/** @defgroup ADC_regular_rank ADC rank into regular group + * @{ + */ +#define ADC_REGULAR_RANK_1 0x00000001U +#define ADC_REGULAR_RANK_2 0x00000002U +#define ADC_REGULAR_RANK_3 0x00000003U +#define ADC_REGULAR_RANK_4 0x00000004U +#define ADC_REGULAR_RANK_5 0x00000005U +#define ADC_REGULAR_RANK_6 0x00000006U +#define ADC_REGULAR_RANK_7 0x00000007U +#define ADC_REGULAR_RANK_8 0x00000008U +#define ADC_REGULAR_RANK_9 0x00000009U +#define ADC_REGULAR_RANK_10 0x0000000AU +#define ADC_REGULAR_RANK_11 0x0000000BU +#define ADC_REGULAR_RANK_12 0x0000000CU +#define ADC_REGULAR_RANK_13 0x0000000DU +#define ADC_REGULAR_RANK_14 0x0000000EU +#define ADC_REGULAR_RANK_15 0x0000000FU +#define ADC_REGULAR_RANK_16 0x00000010U +/** + * @} + */ + +/** @defgroup ADC_analog_watchdog_mode ADC analog watchdog mode + * @{ + */ +#define ADC_ANALOGWATCHDOG_NONE 0x00000000U +#define ADC_ANALOGWATCHDOG_SINGLE_REG ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN)) +#define ADC_ANALOGWATCHDOG_SINGLE_INJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_SINGLE_REGINJEC ((uint32_t)(ADC_CR1_AWDSGL | ADC_CR1_AWDEN | ADC_CR1_JAWDEN)) +#define ADC_ANALOGWATCHDOG_ALL_REG ((uint32_t)ADC_CR1_AWDEN) +#define ADC_ANALOGWATCHDOG_ALL_INJEC ((uint32_t)ADC_CR1_JAWDEN) +#define ADC_ANALOGWATCHDOG_ALL_REGINJEC ((uint32_t)(ADC_CR1_AWDEN | ADC_CR1_JAWDEN)) +/** + * @} + */ + +/** @defgroup ADC_conversion_group ADC conversion group + * @{ + */ +#define ADC_REGULAR_GROUP ((uint32_t)(ADC_FLAG_EOC)) +#define ADC_INJECTED_GROUP ((uint32_t)(ADC_FLAG_JEOC)) +#define ADC_REGULAR_INJECTED_GROUP ((uint32_t)(ADC_FLAG_EOC | ADC_FLAG_JEOC)) +/** + * @} + */ + +/** @defgroup ADC_Event_type ADC Event type + * @{ + */ +#define ADC_AWD_EVENT ((uint32_t)ADC_FLAG_AWD) /*!< ADC Analog watchdog event */ + +#define ADC_AWD1_EVENT ADC_AWD_EVENT /*!< ADC Analog watchdog 1 event: Alternate naming for compatibility with other STM32 devices having several analog watchdogs */ +/** + * @} + */ + +/** @defgroup ADC_interrupts_definition ADC interrupts definition + * @{ + */ +#define ADC_IT_EOC ADC_CR1_EOCIE /*!< ADC End of Regular Conversion interrupt source */ +#define ADC_IT_JEOC ADC_CR1_JEOCIE /*!< ADC End of Injected Conversion interrupt source */ +#define ADC_IT_AWD ADC_CR1_AWDIE /*!< ADC Analog watchdog interrupt source */ +/** + * @} + */ + +/** @defgroup ADC_flags_definition ADC flags definition + * @{ + */ +#define ADC_FLAG_STRT ADC_SR_STRT /*!< ADC Regular group start flag */ +#define ADC_FLAG_JSTRT ADC_SR_JSTRT /*!< ADC Injected group start flag */ +#define ADC_FLAG_EOC ADC_SR_EOC /*!< ADC End of Regular conversion flag */ +#define ADC_FLAG_JEOC ADC_SR_JEOC /*!< ADC End of Injected conversion flag */ +#define ADC_FLAG_AWD ADC_SR_AWD /*!< ADC Analog watchdog flag */ +/** + * @} + */ + + +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ + +/** @addtogroup ADC_Private_Constants ADC Private Constants + * @{ + */ + +/** @defgroup ADC_conversion_cycles ADC conversion cycles + * @{ + */ +/* ADC conversion cycles (unit: ADC clock cycles) */ +/* (selected sampling time + conversion time of 12.5 ADC clock cycles, with */ +/* resolution 12 bits) */ +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_1CYCLE5 14U +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_7CYCLES5 20U +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_13CYCLES5 26U +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_28CYCLES5 41U +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_41CYCLES5 54U +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_55CYCLES5 68U +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_71CYCLES5 84U +#define ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_239CYCLES5 252U +/** + * @} + */ + +/** @defgroup ADC_sampling_times_all_channels ADC sampling times all channels + * @{ + */ +#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 \ + (ADC_SMPR2_SMP9_2 | ADC_SMPR2_SMP8_2 | ADC_SMPR2_SMP7_2 | ADC_SMPR2_SMP6_2 | \ + ADC_SMPR2_SMP5_2 | ADC_SMPR2_SMP4_2 | ADC_SMPR2_SMP3_2 | ADC_SMPR2_SMP2_2 | \ + ADC_SMPR2_SMP1_2 | ADC_SMPR2_SMP0_2) +#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 \ + (ADC_SMPR1_SMP17_2 | ADC_SMPR1_SMP16_2 | ADC_SMPR1_SMP15_2 | ADC_SMPR1_SMP14_2 | \ + ADC_SMPR1_SMP13_2 | ADC_SMPR1_SMP12_2 | ADC_SMPR1_SMP11_2 | ADC_SMPR1_SMP10_2 ) + +#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 \ + (ADC_SMPR2_SMP9_1 | ADC_SMPR2_SMP8_1 | ADC_SMPR2_SMP7_1 | ADC_SMPR2_SMP6_1 | \ + ADC_SMPR2_SMP5_1 | ADC_SMPR2_SMP4_1 | ADC_SMPR2_SMP3_1 | ADC_SMPR2_SMP2_1 | \ + ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP0_1) +#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 \ + (ADC_SMPR1_SMP17_1 | ADC_SMPR1_SMP16_1 | ADC_SMPR1_SMP15_1 | ADC_SMPR1_SMP14_1 | \ + ADC_SMPR1_SMP13_1 | ADC_SMPR1_SMP12_1 | ADC_SMPR1_SMP11_1 | ADC_SMPR1_SMP10_1 ) + +#define ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0 \ + (ADC_SMPR2_SMP9_0 | ADC_SMPR2_SMP8_0 | ADC_SMPR2_SMP7_0 | ADC_SMPR2_SMP6_0 | \ + ADC_SMPR2_SMP5_0 | ADC_SMPR2_SMP4_0 | ADC_SMPR2_SMP3_0 | ADC_SMPR2_SMP2_0 | \ + ADC_SMPR2_SMP1_0 | ADC_SMPR2_SMP0_0) +#define ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0 \ + (ADC_SMPR1_SMP17_0 | ADC_SMPR1_SMP16_0 | ADC_SMPR1_SMP15_0 | ADC_SMPR1_SMP14_0 | \ + ADC_SMPR1_SMP13_0 | ADC_SMPR1_SMP12_0 | ADC_SMPR1_SMP11_0 | ADC_SMPR1_SMP10_0 ) + +#define ADC_SAMPLETIME_1CYCLE5_SMPR2ALLCHANNELS 0x00000000U +#define ADC_SAMPLETIME_7CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0) +#define ADC_SAMPLETIME_13CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) +#define ADC_SAMPLETIME_28CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0) +#define ADC_SAMPLETIME_41CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2) +#define ADC_SAMPLETIME_55CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0) +#define ADC_SAMPLETIME_71CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) +#define ADC_SAMPLETIME_239CYCLES5_SMPR2ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT0) + +#define ADC_SAMPLETIME_1CYCLE5_SMPR1ALLCHANNELS 0x00000000U +#define ADC_SAMPLETIME_7CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) +#define ADC_SAMPLETIME_13CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) +#define ADC_SAMPLETIME_28CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) +#define ADC_SAMPLETIME_41CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2) +#define ADC_SAMPLETIME_55CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) +#define ADC_SAMPLETIME_71CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) +#define ADC_SAMPLETIME_239CYCLES5_SMPR1ALLCHANNELS (ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1 | ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) +/** + * @} + */ + +/* Combination of all post-conversion flags bits: EOC/EOS, JEOC/JEOS, OVR, AWDx */ +#define ADC_FLAG_POSTCONV_ALL (ADC_FLAG_EOC | ADC_FLAG_JEOC | ADC_FLAG_AWD ) + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Macros ADC Exported Macros + * @{ + */ +/* Macro for internal HAL driver usage, and possibly can be used into code of */ +/* final user. */ + +/** + * @brief Enable the ADC peripheral + * @note ADC enable requires a delay for ADC stabilization time + * (refer to device datasheet, parameter tSTAB) + * @note On STM32F1, if ADC is already enabled this macro trigs a conversion + * SW start on regular group. + * @param __HANDLE__: ADC handle + * @retval None + */ +#define __HAL_ADC_ENABLE(__HANDLE__) \ + (SET_BIT((__HANDLE__)->Instance->CR2, (ADC_CR2_ADON))) + +/** + * @brief Disable the ADC peripheral + * @param __HANDLE__: ADC handle + * @retval None + */ +#define __HAL_ADC_DISABLE(__HANDLE__) \ + (CLEAR_BIT((__HANDLE__)->Instance->CR2, (ADC_CR2_ADON))) + +/** @brief Enable the ADC end of conversion interrupt. + * @param __HANDLE__: ADC handle + * @param __INTERRUPT__: ADC Interrupt + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source + * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source + * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source + * @retval None + */ +#define __HAL_ADC_ENABLE_IT(__HANDLE__, __INTERRUPT__) \ + (SET_BIT((__HANDLE__)->Instance->CR1, (__INTERRUPT__))) + +/** @brief Disable the ADC end of conversion interrupt. + * @param __HANDLE__: ADC handle + * @param __INTERRUPT__: ADC Interrupt + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source + * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source + * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source + * @retval None + */ +#define __HAL_ADC_DISABLE_IT(__HANDLE__, __INTERRUPT__) \ + (CLEAR_BIT((__HANDLE__)->Instance->CR1, (__INTERRUPT__))) + +/** @brief Checks if the specified ADC interrupt source is enabled or disabled. + * @param __HANDLE__: ADC handle + * @param __INTERRUPT__: ADC interrupt source to check + * This parameter can be any combination of the following values: + * @arg ADC_IT_EOC: ADC End of Regular Conversion interrupt source + * @arg ADC_IT_JEOC: ADC End of Injected Conversion interrupt source + * @arg ADC_IT_AWD: ADC Analog watchdog interrupt source + * @retval None + */ +#define __HAL_ADC_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) \ + (((__HANDLE__)->Instance->CR1 & (__INTERRUPT__)) == (__INTERRUPT__)) + +/** @brief Get the selected ADC's flag status. + * @param __HANDLE__: ADC handle + * @param __FLAG__: ADC flag + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_STRT: ADC Regular group start flag + * @arg ADC_FLAG_JSTRT: ADC Injected group start flag + * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag + * @arg ADC_FLAG_JEOC: ADC End of Injected conversion flag + * @arg ADC_FLAG_AWD: ADC Analog watchdog flag + * @retval None + */ +#define __HAL_ADC_GET_FLAG(__HANDLE__, __FLAG__) \ + ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__)) + +/** @brief Clear the ADC's pending flags + * @param __HANDLE__: ADC handle + * @param __FLAG__: ADC flag + * This parameter can be any combination of the following values: + * @arg ADC_FLAG_STRT: ADC Regular group start flag + * @arg ADC_FLAG_JSTRT: ADC Injected group start flag + * @arg ADC_FLAG_EOC: ADC End of Regular conversion flag + * @arg ADC_FLAG_JEOC: ADC End of Injected conversion flag + * @arg ADC_FLAG_AWD: ADC Analog watchdog flag + * @retval None + */ +#define __HAL_ADC_CLEAR_FLAG(__HANDLE__, __FLAG__) \ + (WRITE_REG((__HANDLE__)->Instance->SR, ~(__FLAG__))) + +/** @brief Reset ADC handle state + * @param __HANDLE__: ADC handle + * @retval None + */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \ + do{ \ + (__HANDLE__)->State = HAL_ADC_STATE_RESET; \ + (__HANDLE__)->MspInitCallback = NULL; \ + (__HANDLE__)->MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_ADC_RESET_HANDLE_STATE(__HANDLE__) \ + ((__HANDLE__)->State = HAL_ADC_STATE_RESET) +#endif + +/** + * @} + */ + +/* Private macro ------------------------------------------------------------*/ + +/** @defgroup ADC_Private_Macros ADC Private Macros + * @{ + */ +/* Macro reserved for internal HAL driver usage, not intended to be used in */ +/* code of final user. */ + +/** + * @brief Verification of ADC state: enabled or disabled + * @param __HANDLE__: ADC handle + * @retval SET (ADC enabled) or RESET (ADC disabled) + */ +#define ADC_IS_ENABLE(__HANDLE__) \ + ((( ((__HANDLE__)->Instance->CR2 & ADC_CR2_ADON) == ADC_CR2_ADON ) \ + ) ? SET : RESET) + +/** + * @brief Test if conversion trigger of regular group is software start + * or external trigger. + * @param __HANDLE__: ADC handle + * @retval SET (software start) or RESET (external trigger) + */ +#define ADC_IS_SOFTWARE_START_REGULAR(__HANDLE__) \ + (READ_BIT((__HANDLE__)->Instance->CR2, ADC_CR2_EXTSEL) == ADC_SOFTWARE_START) + +/** + * @brief Test if conversion trigger of injected group is software start + * or external trigger. + * @param __HANDLE__: ADC handle + * @retval SET (software start) or RESET (external trigger) + */ +#define ADC_IS_SOFTWARE_START_INJECTED(__HANDLE__) \ + (READ_BIT((__HANDLE__)->Instance->CR2, ADC_CR2_JEXTSEL) == ADC_INJECTED_SOFTWARE_START) + +/** + * @brief Simultaneously clears and sets specific bits of the handle State + * @note: ADC_STATE_CLR_SET() macro is merely aliased to generic macro MODIFY_REG(), + * the first parameter is the ADC handle State, the second parameter is the + * bit field to clear, the third and last parameter is the bit field to set. + * @retval None + */ +#define ADC_STATE_CLR_SET MODIFY_REG + +/** + * @brief Clear ADC error code (set it to error code: "no error") + * @param __HANDLE__: ADC handle + * @retval None + */ +#define ADC_CLEAR_ERRORCODE(__HANDLE__) \ + ((__HANDLE__)->ErrorCode = HAL_ADC_ERROR_NONE) + +/** + * @brief Set ADC number of conversions into regular channel sequence length. + * @param _NbrOfConversion_: Regular channel sequence length + * @retval None + */ +#define ADC_SQR1_L_SHIFT(_NbrOfConversion_) \ + (((_NbrOfConversion_) - (uint8_t)1) << ADC_SQR1_L_Pos) + +/** + * @brief Set the ADC's sample time for channel numbers between 10 and 18. + * @param _SAMPLETIME_: Sample time parameter. + * @param _CHANNELNB_: Channel number. + * @retval None + */ +#define ADC_SMPR1(_SAMPLETIME_, _CHANNELNB_) \ + ((_SAMPLETIME_) << (ADC_SMPR1_SMP11_Pos * ((_CHANNELNB_) - 10))) + +/** + * @brief Set the ADC's sample time for channel numbers between 0 and 9. + * @param _SAMPLETIME_: Sample time parameter. + * @param _CHANNELNB_: Channel number. + * @retval None + */ +#define ADC_SMPR2(_SAMPLETIME_, _CHANNELNB_) \ + ((_SAMPLETIME_) << (ADC_SMPR2_SMP1_Pos * (_CHANNELNB_))) + +/** + * @brief Set the selected regular channel rank for rank between 1 and 6. + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @retval None + */ +#define ADC_SQR3_RK(_CHANNELNB_, _RANKNB_) \ + ((_CHANNELNB_) << (ADC_SQR3_SQ2_Pos * ((_RANKNB_) - 1))) + +/** + * @brief Set the selected regular channel rank for rank between 7 and 12. + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @retval None + */ +#define ADC_SQR2_RK(_CHANNELNB_, _RANKNB_) \ + ((_CHANNELNB_) << (ADC_SQR2_SQ8_Pos * ((_RANKNB_) - 7))) + +/** + * @brief Set the selected regular channel rank for rank between 13 and 16. + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @retval None + */ +#define ADC_SQR1_RK(_CHANNELNB_, _RANKNB_) \ + ((_CHANNELNB_) << (ADC_SQR1_SQ14_Pos * ((_RANKNB_) - 13))) + +/** + * @brief Set the injected sequence length. + * @param _JSQR_JL_: Sequence length. + * @retval None + */ +#define ADC_JSQR_JL_SHIFT(_JSQR_JL_) \ + (((_JSQR_JL_) -1) << ADC_JSQR_JL_Pos) + +/** + * @brief Set the selected injected channel rank + * Note: on STM32F1 devices, channel rank position in JSQR register + * is depending on total number of ranks selected into + * injected sequencer (ranks sequence starting from 4-JL) + * @param _CHANNELNB_: Channel number. + * @param _RANKNB_: Rank number. + * @param _JSQR_JL_: Sequence length. + * @retval None + */ +#define ADC_JSQR_RK_JL(_CHANNELNB_, _RANKNB_, _JSQR_JL_) \ + ((_CHANNELNB_) << (ADC_JSQR_JSQ2_Pos * ((4 - ((_JSQR_JL_) - (_RANKNB_))) - 1))) + +/** + * @brief Enable ADC continuous conversion mode. + * @param _CONTINUOUS_MODE_: Continuous mode. + * @retval None + */ +#define ADC_CR2_CONTINUOUS(_CONTINUOUS_MODE_) \ + ((_CONTINUOUS_MODE_) << ADC_CR2_CONT_Pos) + +/** + * @brief Configures the number of discontinuous conversions for the regular group channels. + * @param _NBR_DISCONTINUOUS_CONV_: Number of discontinuous conversions. + * @retval None + */ +#define ADC_CR1_DISCONTINUOUS_NUM(_NBR_DISCONTINUOUS_CONV_) \ + (((_NBR_DISCONTINUOUS_CONV_) - 1) << ADC_CR1_DISCNUM_Pos) + +/** + * @brief Enable ADC scan mode to convert multiple ranks with sequencer. + * @param _SCAN_MODE_: Scan conversion mode. + * @retval None + */ +/* Note: Scan mode is compared to ENABLE for legacy purpose, this parameter */ +/* is equivalent to ADC_SCAN_ENABLE. */ +#define ADC_CR1_SCAN_SET(_SCAN_MODE_) \ + (( ((_SCAN_MODE_) == ADC_SCAN_ENABLE) || ((_SCAN_MODE_) == ENABLE) \ + )? (ADC_SCAN_ENABLE) : (ADC_SCAN_DISABLE) \ + ) + +/** + * @brief Get the maximum ADC conversion cycles on all channels. + * Returns the selected sampling time + conversion time (12.5 ADC clock cycles) + * Approximation of sampling time within 4 ranges, returns the highest value: + * below 7.5 cycles {1.5 cycle; 7.5 cycles}, + * between 13.5 cycles and 28.5 cycles {13.5 cycles; 28.5 cycles} + * between 41.5 cycles and 71.5 cycles {41.5 cycles; 55.5 cycles; 71.5cycles} + * equal to 239.5 cycles + * Unit: ADC clock cycles + * @param __HANDLE__: ADC handle + * @retval ADC conversion cycles on all channels + */ +#define ADC_CONVCYCLES_MAX_RANGE(__HANDLE__) \ + (( (((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT2) == RESET) && \ + (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT2) == RESET) ) ? \ + \ + (( (((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) == RESET) && \ + (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) == RESET) ) ? \ + ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_7CYCLES5 : ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_28CYCLES5) \ + : \ + ((((((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR2BIT1) == RESET) && \ + (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT1) == RESET)) || \ + ((((__HANDLE__)->Instance->SMPR2 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) == RESET) && \ + (((__HANDLE__)->Instance->SMPR1 & ADC_SAMPLETIME_ALLCHANNELS_SMPR1BIT0) == RESET))) ? \ + ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_71CYCLES5 : ADC_CONVERSIONCLOCKCYCLES_SAMPLETIME_239CYCLES5) \ + ) + +#define IS_ADC_DATA_ALIGN(ALIGN) (((ALIGN) == ADC_DATAALIGN_RIGHT) || \ + ((ALIGN) == ADC_DATAALIGN_LEFT) ) + +#define IS_ADC_SCAN_MODE(SCAN_MODE) (((SCAN_MODE) == ADC_SCAN_DISABLE) || \ + ((SCAN_MODE) == ADC_SCAN_ENABLE) ) + +#define IS_ADC_EXTTRIG_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGCONVEDGE_NONE) || \ + ((EDGE) == ADC_EXTERNALTRIGCONVEDGE_RISING) ) + +#define IS_ADC_CHANNEL(CHANNEL) (((CHANNEL) == ADC_CHANNEL_0) || \ + ((CHANNEL) == ADC_CHANNEL_1) || \ + ((CHANNEL) == ADC_CHANNEL_2) || \ + ((CHANNEL) == ADC_CHANNEL_3) || \ + ((CHANNEL) == ADC_CHANNEL_4) || \ + ((CHANNEL) == ADC_CHANNEL_5) || \ + ((CHANNEL) == ADC_CHANNEL_6) || \ + ((CHANNEL) == ADC_CHANNEL_7) || \ + ((CHANNEL) == ADC_CHANNEL_8) || \ + ((CHANNEL) == ADC_CHANNEL_9) || \ + ((CHANNEL) == ADC_CHANNEL_10) || \ + ((CHANNEL) == ADC_CHANNEL_11) || \ + ((CHANNEL) == ADC_CHANNEL_12) || \ + ((CHANNEL) == ADC_CHANNEL_13) || \ + ((CHANNEL) == ADC_CHANNEL_14) || \ + ((CHANNEL) == ADC_CHANNEL_15) || \ + ((CHANNEL) == ADC_CHANNEL_16) || \ + ((CHANNEL) == ADC_CHANNEL_17) ) + +#define IS_ADC_SAMPLE_TIME(TIME) (((TIME) == ADC_SAMPLETIME_1CYCLE_5) || \ + ((TIME) == ADC_SAMPLETIME_7CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_13CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_28CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_41CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_55CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_71CYCLES_5) || \ + ((TIME) == ADC_SAMPLETIME_239CYCLES_5) ) + +#define IS_ADC_REGULAR_RANK(CHANNEL) (((CHANNEL) == ADC_REGULAR_RANK_1 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_2 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_3 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_4 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_5 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_6 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_7 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_8 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_9 ) || \ + ((CHANNEL) == ADC_REGULAR_RANK_10) || \ + ((CHANNEL) == ADC_REGULAR_RANK_11) || \ + ((CHANNEL) == ADC_REGULAR_RANK_12) || \ + ((CHANNEL) == ADC_REGULAR_RANK_13) || \ + ((CHANNEL) == ADC_REGULAR_RANK_14) || \ + ((CHANNEL) == ADC_REGULAR_RANK_15) || \ + ((CHANNEL) == ADC_REGULAR_RANK_16) ) + +#define IS_ADC_ANALOG_WATCHDOG_MODE(WATCHDOG) (((WATCHDOG) == ADC_ANALOGWATCHDOG_NONE) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REG) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REG) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_INJEC) || \ + ((WATCHDOG) == ADC_ANALOGWATCHDOG_ALL_REGINJEC) ) + +#define IS_ADC_CONVERSION_GROUP(CONVERSION) (((CONVERSION) == ADC_REGULAR_GROUP) || \ + ((CONVERSION) == ADC_INJECTED_GROUP) || \ + ((CONVERSION) == ADC_REGULAR_INJECTED_GROUP) ) + +#define IS_ADC_EVENT_TYPE(EVENT) ((EVENT) == ADC_AWD_EVENT) + + +/** @defgroup ADC_range_verification ADC range verification + * For a unique ADC resolution: 12 bits + * @{ + */ +#define IS_ADC_RANGE(ADC_VALUE) ((ADC_VALUE) <= 0x0FFFU) +/** + * @} + */ + +/** @defgroup ADC_regular_nb_conv_verification ADC regular nb conv verification + * @{ + */ +#define IS_ADC_REGULAR_NB_CONV(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 16U)) +/** + * @} + */ + +/** @defgroup ADC_regular_discontinuous_mode_number_verification ADC regular discontinuous mode number verification + * @{ + */ +#define IS_ADC_REGULAR_DISCONT_NUMBER(NUMBER) (((NUMBER) >= 1U) && ((NUMBER) <= 8U)) +/** + * @} + */ + +/** + * @} + */ + +/* Include ADC HAL Extension module */ +#include "stm32f1xx_hal_adc_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADC_Exported_Functions + * @{ + */ + +/** @addtogroup ADC_Exported_Functions_Group1 + * @{ + */ + + +/* Initialization and de-initialization functions **********************************/ +HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef *hadc); +void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc); +void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc); + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +/* Callbacks Register/UnRegister functions ***********************************/ +HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID, pADC_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/* IO operation functions *****************************************************/ + +/** @addtogroup ADC_Exported_Functions_Group2 + * @{ + */ + + +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); +HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout); + +/* Non-blocking mode: Interruption */ +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc); + +/* Non-blocking mode: DMA */ +HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length); +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc); + +/* ADC retrieve conversion value intended to be used with polling or interruption */ +uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); + +/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption and DMA) */ +void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc); +void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc); +void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc); +void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc); +void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc); +/** + * @} + */ + + +/* Peripheral Control functions ***********************************************/ +/** @addtogroup ADC_Exported_Functions_Group3 + * @{ + */ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig); +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig); +/** + * @} + */ + + +/* Peripheral State functions *************************************************/ +/** @addtogroup ADC_Exported_Functions_Group4 + * @{ + */ +uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc); +uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc); +/** + * @} + */ + + +/** + * @} + */ + + +/* Internal HAL driver functions **********************************************/ +/** @addtogroup ADC_Private_Functions + * @{ + */ +HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef ADC_ConversionStop_Disable(ADC_HandleTypeDef* hadc); +void ADC_StabilizationTime(uint32_t DelayUs); +void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma); +void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma); +void ADC_DMAError(DMA_HandleTypeDef *hdma); +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* __STM32F1xx_HAL_ADC_H */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h new file mode 100644 index 0000000..9e66a2e --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_adc_ex.h @@ -0,0 +1,706 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_adc_ex.h + * @author MCD Application Team + * @brief Header file of ADC HAL extension module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F1xx_HAL_ADC_EX_H +#define __STM32F1xx_HAL_ADC_EX_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal_def.h" + +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @addtogroup ADCEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup ADCEx_Exported_Types ADCEx Exported Types + * @{ + */ + +/** + * @brief ADC Configuration injected Channel structure definition + * @note Parameters of this structure are shared within 2 scopes: + * - Scope channel: InjectedChannel, InjectedRank, InjectedSamplingTime, InjectedOffset + * - Scope injected group (affects all channels of injected group): InjectedNbrOfConversion, InjectedDiscontinuousConvMode, + * AutoInjectedConv, ExternalTrigInjecConvEdge, ExternalTrigInjecConv. + * @note The setting of these parameters with function HAL_ADCEx_InjectedConfigChannel() is conditioned to ADC state. + * ADC state can be either: + * - For all parameters: ADC disabled (this is the only possible ADC state to modify parameter 'ExternalTrigInjecConv') + * - For all except parameters 'ExternalTrigInjecConv': ADC enabled without conversion on going on injected group. + */ +typedef struct +{ + uint32_t InjectedChannel; /*!< Selection of ADC channel to configure + This parameter can be a value of @ref ADC_channels + Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability. + Note: On STM32F1 devices with several ADC: Only ADC1 can access internal measurement channels (VrefInt/TempSensor) + Note: On STM32F10xx8 and STM32F10xxB devices: A low-amplitude voltage glitch may be generated (on ADC input 0) on the PA0 pin, when the ADC is converting with injection trigger. + It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel. + Refer to errata sheet of these devices for more details. */ + uint32_t InjectedRank; /*!< Rank in the injected group sequencer + This parameter must be a value of @ref ADCEx_injected_rank + Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel setting (or parameter number of conversions can be adjusted) */ + uint32_t InjectedSamplingTime; /*!< Sampling time value to be set for the selected channel. + Unit: ADC clock cycles + Conversion time is the addition of sampling time and processing time (12.5 ADC clock cycles at ADC resolution 12 bits). + This parameter can be a value of @ref ADC_sampling_times + Caution: This parameter updates the parameter property of the channel, that can be used into regular and/or injected groups. + If this same channel has been previously configured in the other group (regular/injected), it will be updated to last setting. + Note: In case of usage of internal measurement channels (VrefInt/TempSensor), + sampling time constraints must be respected (sampling time can be adjusted in function of ADC clock frequency and sampling time setting) + Refer to device datasheet for timings values, parameters TS_vrefint, TS_temp (values rough order: 5us to 17.1us min). */ + uint32_t InjectedOffset; /*!< Defines the offset to be subtracted from the raw converted data (for channels set on injected group only). + Offset value must be a positive number. + Depending of ADC resolution selected (12, 10, 8 or 6 bits), + this parameter must be a number between Min_Data = 0x000 and Max_Data = 0xFFF, 0x3FF, 0xFF or 0x3F respectively. */ + uint32_t InjectedNbrOfConversion; /*!< Specifies the number of ranks that will be converted within the injected group sequencer. + To use the injected group sequencer and convert several ranks, parameter 'ScanConvMode' must be enabled. + This parameter must be a number between Min_Data = 1 and Max_Data = 4. + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ + FunctionalState InjectedDiscontinuousConvMode; /*!< Specifies whether the conversions sequence of injected group is performed in Complete-sequence/Discontinuous-sequence (main sequence subdivided in successive parts). + Discontinuous mode is used only if sequencer is enabled (parameter 'ScanConvMode'). If sequencer is disabled, this parameter is discarded. + Discontinuous mode can be enabled only if continuous mode is disabled. If continuous mode is enabled, this parameter setting is discarded. + This parameter can be set to ENABLE or DISABLE. + Note: For injected group, number of discontinuous ranks increment is fixed to one-by-one. + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ + FunctionalState AutoInjectedConv; /*!< Enables or disables the selected ADC automatic injected group conversion after regular one + This parameter can be set to ENABLE or DISABLE. + Note: To use Automatic injected conversion, discontinuous mode must be disabled ('DiscontinuousConvMode' and 'InjectedDiscontinuousConvMode' set to DISABLE) + Note: To use Automatic injected conversion, injected group external triggers must be disabled ('ExternalTrigInjecConv' set to ADC_SOFTWARE_START) + Note: In case of DMA used with regular group: if DMA configured in normal mode (single shot) JAUTO will be stopped upon DMA transfer complete. + To maintain JAUTO always enabled, DMA must be configured in circular mode. + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ + uint32_t ExternalTrigInjecConv; /*!< Selects the external event used to trigger the conversion start of injected group. + If set to ADC_INJECTED_SOFTWARE_START, external triggers are disabled. + If set to external trigger source, triggering is on event rising edge. + This parameter can be a value of @ref ADCEx_External_trigger_source_Injected + Note: This parameter must be modified when ADC is disabled (before ADC start conversion or after ADC stop conversion). + If ADC is enabled, this parameter setting is bypassed without error reporting (as it can be the expected behaviour in case of another parameter update on the fly) + Caution: this setting impacts the entire injected group. Therefore, call of HAL_ADCEx_InjectedConfigChannel() to + configure a channel on injected group can impact the configuration of other channels previously set. */ +}ADC_InjectionConfTypeDef; + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +/** + * @brief Structure definition of ADC multimode + * @note The setting of these parameters with function HAL_ADCEx_MultiModeConfigChannel() is conditioned to ADCs state (both ADCs of the common group). + * State of ADCs of the common group must be: disabled. + */ +typedef struct +{ + uint32_t Mode; /*!< Configures the ADC to operate in independent or multi mode. + This parameter can be a value of @ref ADCEx_Common_mode + Note: In dual mode, a change of channel configuration generates a restart that can produce a loss of synchronization. It is recommended to disable dual mode before any configuration change. + Note: In case of simultaneous mode used: Exactly the same sampling time should be configured for the 2 channels that will be sampled simultaneously by ACD1 and ADC2. + Note: In case of interleaved mode used: To avoid overlap between conversions, maximum sampling time allowed is 7 ADC clock cycles for fast interleaved mode and 14 ADC clock cycles for slow interleaved mode. + Note: Some multimode parameters are fixed on STM32F1 and can be configured on other STM32 devices with several ADC (multimode configuration structure can have additional parameters). + The equivalences are: + - Parameter 'DMAAccessMode': On STM32F1, this parameter is fixed to 1 DMA channel (one DMA channel for both ADC, DMA of ADC master). On other STM32 devices with several ADC, this is equivalent to parameter 'ADC_DMAACCESSMODE_12_10_BITS'. + - Parameter 'TwoSamplingDelay': On STM32F1, this parameter is fixed to 7 or 14 ADC clock cycles depending on fast or slow interleaved mode selected. On other STM32 devices with several ADC, this is equivalent to parameter 'ADC_TWOSAMPLINGDELAY_7CYCLES' (for fast interleaved mode). */ + + +}ADC_MultiModeTypeDef; +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/** + * @} + */ + + +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup ADCEx_Exported_Constants ADCEx Exported Constants + * @{ + */ + +/** @defgroup ADCEx_injected_rank ADCEx rank into injected group + * @{ + */ +#define ADC_INJECTED_RANK_1 0x00000001U +#define ADC_INJECTED_RANK_2 0x00000002U +#define ADC_INJECTED_RANK_3 0x00000003U +#define ADC_INJECTED_RANK_4 0x00000004U +/** + * @} + */ + +/** @defgroup ADCEx_External_trigger_edge_Injected ADCEx external trigger enable for injected group + * @{ + */ +#define ADC_EXTERNALTRIGINJECCONV_EDGE_NONE 0x00000000U +#define ADC_EXTERNALTRIGINJECCONV_EDGE_RISING ((uint32_t)ADC_CR2_JEXTTRIG) +/** + * @} + */ + +/** @defgroup ADC_External_trigger_source_Regular ADC External trigger selection for regular group + * @{ + */ +/*!< List of external triggers with generic trigger name, independently of */ +/* ADC target, sorted by trigger name: */ + +/*!< External triggers of regular group for ADC1&ADC2 only */ +#define ADC_EXTERNALTRIGCONV_T1_CC1 ADC1_2_EXTERNALTRIG_T1_CC1 +#define ADC_EXTERNALTRIGCONV_T1_CC2 ADC1_2_EXTERNALTRIG_T1_CC2 +#define ADC_EXTERNALTRIGCONV_T2_CC2 ADC1_2_EXTERNALTRIG_T2_CC2 +#define ADC_EXTERNALTRIGCONV_T3_TRGO ADC1_2_EXTERNALTRIG_T3_TRGO +#define ADC_EXTERNALTRIGCONV_T4_CC4 ADC1_2_EXTERNALTRIG_T4_CC4 +#define ADC_EXTERNALTRIGCONV_EXT_IT11 ADC1_2_EXTERNALTRIG_EXT_IT11 + +#if defined (STM32F103xE) || defined (STM32F103xG) +/*!< External triggers of regular group for ADC3 only */ +#define ADC_EXTERNALTRIGCONV_T2_CC3 ADC3_EXTERNALTRIG_T2_CC3 +#define ADC_EXTERNALTRIGCONV_T3_CC1 ADC3_EXTERNALTRIG_T3_CC1 +#define ADC_EXTERNALTRIGCONV_T5_CC1 ADC3_EXTERNALTRIG_T5_CC1 +#define ADC_EXTERNALTRIGCONV_T5_CC3 ADC3_EXTERNALTRIG_T5_CC3 +#define ADC_EXTERNALTRIGCONV_T8_CC1 ADC3_EXTERNALTRIG_T8_CC1 +#endif /* STM32F103xE || defined STM32F103xG */ + +/*!< External triggers of regular group for all ADC instances */ +#define ADC_EXTERNALTRIGCONV_T1_CC3 ADC1_2_3_EXTERNALTRIG_T1_CC3 + +#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC) +/*!< Note: TIM8_TRGO is available on ADC1 and ADC2 only in high-density and */ +/* XL-density devices. */ +/* To use it on ADC or ADC2, a remap of trigger must be done from */ +/* EXTI line 11 to TIM8_TRGO with macro: */ +/* __HAL_AFIO_REMAP_ADC1_ETRGREG_ENABLE() */ +/* __HAL_AFIO_REMAP_ADC2_ETRGREG_ENABLE() */ + +/* Note for internal constant value management: If TIM8_TRGO is available, */ +/* its definition is set to value for ADC1&ADC2 by default and changed to */ +/* value for ADC3 by HAL ADC driver if ADC3 is selected. */ +#define ADC_EXTERNALTRIGCONV_T8_TRGO ADC1_2_EXTERNALTRIG_T8_TRGO +#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ + +#define ADC_SOFTWARE_START ADC1_2_3_SWSTART +/** + * @} + */ + +/** @defgroup ADCEx_External_trigger_source_Injected ADCEx External trigger selection for injected group + * @{ + */ +/*!< List of external triggers with generic trigger name, independently of */ +/* ADC target, sorted by trigger name: */ + +/*!< External triggers of injected group for ADC1&ADC2 only */ +#define ADC_EXTERNALTRIGINJECCONV_T2_TRGO ADC1_2_EXTERNALTRIGINJEC_T2_TRGO +#define ADC_EXTERNALTRIGINJECCONV_T2_CC1 ADC1_2_EXTERNALTRIGINJEC_T2_CC1 +#define ADC_EXTERNALTRIGINJECCONV_T3_CC4 ADC1_2_EXTERNALTRIGINJEC_T3_CC4 +#define ADC_EXTERNALTRIGINJECCONV_T4_TRGO ADC1_2_EXTERNALTRIGINJEC_T4_TRGO +#define ADC_EXTERNALTRIGINJECCONV_EXT_IT15 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15 + +#if defined (STM32F103xE) || defined (STM32F103xG) +/*!< External triggers of injected group for ADC3 only */ +#define ADC_EXTERNALTRIGINJECCONV_T4_CC3 ADC3_EXTERNALTRIGINJEC_T4_CC3 +#define ADC_EXTERNALTRIGINJECCONV_T8_CC2 ADC3_EXTERNALTRIGINJEC_T8_CC2 +#define ADC_EXTERNALTRIGINJECCONV_T5_TRGO ADC3_EXTERNALTRIGINJEC_T5_TRGO +#define ADC_EXTERNALTRIGINJECCONV_T5_CC4 ADC3_EXTERNALTRIGINJEC_T5_CC4 +#endif /* STM32F103xE || defined STM32F103xG */ + +/*!< External triggers of injected group for all ADC instances */ +#define ADC_EXTERNALTRIGINJECCONV_T1_CC4 ADC1_2_3_EXTERNALTRIGINJEC_T1_CC4 +#define ADC_EXTERNALTRIGINJECCONV_T1_TRGO ADC1_2_3_EXTERNALTRIGINJEC_T1_TRGO + +#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC) +/*!< Note: TIM8_CC4 is available on ADC1 and ADC2 only in high-density and */ +/* XL-density devices. */ +/* To use it on ADC1 or ADC2, a remap of trigger must be done from */ +/* EXTI line 11 to TIM8_CC4 with macro: */ +/* __HAL_AFIO_REMAP_ADC1_ETRGINJ_ENABLE() */ +/* __HAL_AFIO_REMAP_ADC2_ETRGINJ_ENABLE() */ + +/* Note for internal constant value management: If TIM8_CC4 is available, */ +/* its definition is set to value for ADC1&ADC2 by default and changed to */ +/* value for ADC3 by HAL ADC driver if ADC3 is selected. */ +#define ADC_EXTERNALTRIGINJECCONV_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_T8_CC4 +#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ + +#define ADC_INJECTED_SOFTWARE_START ADC1_2_3_JSWSTART +/** + * @} + */ + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +/** @defgroup ADCEx_Common_mode ADC Extended Dual ADC Mode + * @{ + */ +#define ADC_MODE_INDEPENDENT 0x00000000U /*!< ADC dual mode disabled (ADC independent mode) */ +#define ADC_DUALMODE_REGSIMULT_INJECSIMULT ((uint32_t)( ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Combined regular simultaneous + injected simultaneous mode, on groups regular and injected */ +#define ADC_DUALMODE_REGSIMULT_ALTERTRIG ((uint32_t)( ADC_CR1_DUALMOD_1 )) /*!< ADC dual mode enabled: Combined regular simultaneous + alternate trigger mode, on groups regular and injected */ +#define ADC_DUALMODE_INJECSIMULT_INTERLFAST ((uint32_t)( ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Combined injected simultaneous + fast interleaved mode, on groups regular and injected (delay between ADC sampling phases: 7 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */ +#define ADC_DUALMODE_INJECSIMULT_INTERLSLOW ((uint32_t)( ADC_CR1_DUALMOD_2 )) /*!< ADC dual mode enabled: Combined injected simultaneous + slow Interleaved mode, on groups regular and injected (delay between ADC sampling phases: 14 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */ +#define ADC_DUALMODE_INJECSIMULT ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Injected simultaneous mode, on group injected */ +#define ADC_DUALMODE_REGSIMULT ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 )) /*!< ADC dual mode enabled: Regular simultaneous mode, on group regular */ +#define ADC_DUALMODE_INTERLFAST ((uint32_t)( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Fast interleaved mode, on group regular (delay between ADC sampling phases: 7 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */ +#define ADC_DUALMODE_INTERLSLOW ((uint32_t)(ADC_CR1_DUALMOD_3 )) /*!< ADC dual mode enabled: Slow interleaved mode, on group regular (delay between ADC sampling phases: 14 ADC clock cycles (equivalent to parameter "TwoSamplingDelay" set to "ADC_TWOSAMPLINGDELAY_7CYCLES" on other STM32 devices)) */ +#define ADC_DUALMODE_ALTERTRIG ((uint32_t)(ADC_CR1_DUALMOD_3 | ADC_CR1_DUALMOD_0)) /*!< ADC dual mode enabled: Alternate trigger mode, on group injected */ +/** + * @} + */ +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/** + * @} + */ + + +/* Private constants ---------------------------------------------------------*/ + +/** @addtogroup ADCEx_Private_Constants ADCEx Private Constants + * @{ + */ + +/** @defgroup ADCEx_Internal_HAL_driver_Ext_trig_src_Regular ADC Extended Internal HAL driver trigger selection for regular group + * @{ + */ +/* List of external triggers of regular group for ADC1, ADC2, ADC3 (if ADC */ +/* instance is available on the selected device). */ +/* (used internally by HAL driver. To not use into HAL structure parameters) */ + +/* External triggers of regular group for ADC1&ADC2 (if ADCx available) */ +#define ADC1_2_EXTERNALTRIG_T1_CC1 0x00000000U +#define ADC1_2_EXTERNALTRIG_T1_CC2 ((uint32_t)( ADC_CR2_EXTSEL_0)) +#define ADC1_2_EXTERNALTRIG_T2_CC2 ((uint32_t)( ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +#define ADC1_2_EXTERNALTRIG_T3_TRGO ((uint32_t)(ADC_CR2_EXTSEL_2 )) +#define ADC1_2_EXTERNALTRIG_T4_CC4 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0)) +#define ADC1_2_EXTERNALTRIG_EXT_IT11 ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 )) +#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) +/* Note: TIM8_TRGO is available on ADC1 and ADC2 only in high-density and */ +/* XL-density devices. */ +#define ADC1_2_EXTERNALTRIG_T8_TRGO ADC1_2_EXTERNALTRIG_EXT_IT11 +#endif + +#if defined (STM32F103xE) || defined (STM32F103xG) +/* External triggers of regular group for ADC3 */ +#define ADC3_EXTERNALTRIG_T3_CC1 ADC1_2_EXTERNALTRIG_T1_CC1 +#define ADC3_EXTERNALTRIG_T2_CC3 ADC1_2_EXTERNALTRIG_T1_CC2 +#define ADC3_EXTERNALTRIG_T8_CC1 ADC1_2_EXTERNALTRIG_T2_CC2 +#define ADC3_EXTERNALTRIG_T8_TRGO ADC1_2_EXTERNALTRIG_T3_TRGO +#define ADC3_EXTERNALTRIG_T5_CC1 ADC1_2_EXTERNALTRIG_T4_CC4 +#define ADC3_EXTERNALTRIG_T5_CC3 ADC1_2_EXTERNALTRIG_EXT_IT11 +#endif + +/* External triggers of regular group for ADC1&ADC2&ADC3 (if ADCx available) */ +#define ADC1_2_3_EXTERNALTRIG_T1_CC3 ((uint32_t)( ADC_CR2_EXTSEL_1 )) +#define ADC1_2_3_SWSTART ((uint32_t)(ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0)) +/** + * @} + */ + +/** @defgroup ADCEx_Internal_HAL_driver_Ext_trig_src_Injected ADC Extended Internal HAL driver trigger selection for injected group + * @{ + */ +/* List of external triggers of injected group for ADC1, ADC2, ADC3 (if ADC */ +/* instance is available on the selected device). */ +/* (used internally by HAL driver. To not use into HAL structure parameters) */ + +/* External triggers of injected group for ADC1&ADC2 (if ADCx available) */ +#define ADC1_2_EXTERNALTRIGINJEC_T2_TRGO ((uint32_t)( ADC_CR2_JEXTSEL_1 )) +#define ADC1_2_EXTERNALTRIGINJEC_T2_CC1 ((uint32_t)( ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +#define ADC1_2_EXTERNALTRIGINJEC_T3_CC4 ((uint32_t)(ADC_CR2_JEXTSEL_2 )) +#define ADC1_2_EXTERNALTRIGINJEC_T4_TRGO ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0)) +#define ADC1_2_EXTERNALTRIGINJEC_EXT_IT15 ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 )) +#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) +/* Note: TIM8_CC4 is available on ADC1 and ADC2 only in high-density and */ +/* XL-density devices. */ +#define ADC1_2_EXTERNALTRIGINJEC_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15 +#endif + +#if defined (STM32F103xE) || defined (STM32F103xG) +/* External triggers of injected group for ADC3 */ +#define ADC3_EXTERNALTRIGINJEC_T4_CC3 ADC1_2_EXTERNALTRIGINJEC_T2_TRGO +#define ADC3_EXTERNALTRIGINJEC_T8_CC2 ADC1_2_EXTERNALTRIGINJEC_T2_CC1 +#define ADC3_EXTERNALTRIGINJEC_T8_CC4 ADC1_2_EXTERNALTRIGINJEC_T3_CC4 +#define ADC3_EXTERNALTRIGINJEC_T5_TRGO ADC1_2_EXTERNALTRIGINJEC_T4_TRGO +#define ADC3_EXTERNALTRIGINJEC_T5_CC4 ADC1_2_EXTERNALTRIGINJEC_EXT_IT15 +#endif /* STM32F103xE || defined STM32F103xG */ + +/* External triggers of injected group for ADC1&ADC2&ADC3 (if ADCx available) */ +#define ADC1_2_3_EXTERNALTRIGINJEC_T1_TRGO 0x00000000U +#define ADC1_2_3_EXTERNALTRIGINJEC_T1_CC4 ((uint32_t)( ADC_CR2_JEXTSEL_0)) +#define ADC1_2_3_JSWSTART ((uint32_t)(ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0)) +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ + +/* Private macro -------------------------------------------------------------*/ + +/** @defgroup ADCEx_Private_Macro ADCEx Private Macro + * @{ + */ +/* Macro reserved for internal HAL driver usage, not intended to be used in */ +/* code of final user. */ + + +/** + * @brief For devices with 3 ADCs: Defines the external trigger source + * for regular group according to ADC into common group ADC1&ADC2 or + * ADC3 (some triggers with same source have different value to + * be programmed into ADC EXTSEL bits of CR2 register). + * For devices with 2 ADCs or less: this macro makes no change. + * @param __HANDLE__: ADC handle + * @param __EXT_TRIG_CONV__: External trigger selected for regular group. + * @retval External trigger to be programmed into EXTSEL bits of CR2 register + */ +#if defined (STM32F103xE) || defined (STM32F103xG) +#define ADC_CFGR_EXTSEL(__HANDLE__, __EXT_TRIG_CONV__) \ + (( (((__HANDLE__)->Instance) == ADC3) \ + )? \ + ( ( (__EXT_TRIG_CONV__) == ADC_EXTERNALTRIGCONV_T8_TRGO \ + )? \ + (ADC3_EXTERNALTRIG_T8_TRGO) \ + : \ + (__EXT_TRIG_CONV__) \ + ) \ + : \ + (__EXT_TRIG_CONV__) \ + ) +#else +#define ADC_CFGR_EXTSEL(__HANDLE__, __EXT_TRIG_CONV__) \ + (__EXT_TRIG_CONV__) +#endif /* STM32F103xE || STM32F103xG */ + +/** + * @brief For devices with 3 ADCs: Defines the external trigger source + * for injected group according to ADC into common group ADC1&ADC2 or + * ADC3 (some triggers with same source have different value to + * be programmed into ADC JEXTSEL bits of CR2 register). + * For devices with 2 ADCs or less: this macro makes no change. + * @param __HANDLE__: ADC handle + * @param __EXT_TRIG_INJECTCONV__: External trigger selected for injected group. + * @retval External trigger to be programmed into JEXTSEL bits of CR2 register + */ +#if defined (STM32F103xE) || defined (STM32F103xG) +#define ADC_CFGR_JEXTSEL(__HANDLE__, __EXT_TRIG_INJECTCONV__) \ + (( (((__HANDLE__)->Instance) == ADC3) \ + )? \ + ( ( (__EXT_TRIG_INJECTCONV__) == ADC_EXTERNALTRIGINJECCONV_T8_CC4 \ + )? \ + (ADC3_EXTERNALTRIGINJEC_T8_CC4) \ + : \ + (__EXT_TRIG_INJECTCONV__) \ + ) \ + : \ + (__EXT_TRIG_INJECTCONV__) \ + ) +#else +#define ADC_CFGR_JEXTSEL(__HANDLE__, __EXT_TRIG_INJECTCONV__) \ + (__EXT_TRIG_INJECTCONV__) +#endif /* STM32F103xE || STM32F103xG */ + + +/** + * @brief Verification if multimode is enabled for the selected ADC (multimode ADC master or ADC slave) (applicable for devices with several ADCs) + * @param __HANDLE__: ADC handle + * @retval Multimode state: RESET if multimode is disabled, other value if multimode is enabled + */ +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +#define ADC_MULTIMODE_IS_ENABLE(__HANDLE__) \ + (( (((__HANDLE__)->Instance) == ADC1) || (((__HANDLE__)->Instance) == ADC2) \ + )? \ + (ADC1->CR1 & ADC_CR1_DUALMOD) \ + : \ + (RESET) \ + ) +#else +#define ADC_MULTIMODE_IS_ENABLE(__HANDLE__) \ + (RESET) +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/** + * @brief Verification of condition for ADC start conversion: ADC must be in non-multimode, or multimode with handle of ADC master (applicable for devices with several ADCs) + * @param __HANDLE__: ADC handle + * @retval None + */ +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +#define ADC_NONMULTIMODE_OR_MULTIMODEMASTER(__HANDLE__) \ + (( (((__HANDLE__)->Instance) == ADC2) \ + )? \ + ((ADC1->CR1 & ADC_CR1_DUALMOD) == RESET) \ + : \ + (!RESET) \ + ) +#else +#define ADC_NONMULTIMODE_OR_MULTIMODEMASTER(__HANDLE__) \ + (!RESET) +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/** + * @brief Check ADC multimode setting: In case of multimode, check whether ADC master of the selected ADC has feature auto-injection enabled (applicable for devices with several ADCs) + * @param __HANDLE__: ADC handle + * @retval None + */ +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +#define ADC_MULTIMODE_AUTO_INJECTED(__HANDLE__) \ + (( (((__HANDLE__)->Instance) == ADC1) || (((__HANDLE__)->Instance) == ADC2) \ + )? \ + (ADC1->CR1 & ADC_CR1_JAUTO) \ + : \ + (RESET) \ + ) +#else +#define ADC_MULTIMODE_AUTO_INJECTED(__HANDLE__) \ + (RESET) +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +/** + * @brief Set handle of the other ADC sharing the common multimode settings + * @param __HANDLE__: ADC handle + * @param __HANDLE_OTHER_ADC__: other ADC handle + * @retval None + */ +#define ADC_COMMON_ADC_OTHER(__HANDLE__, __HANDLE_OTHER_ADC__) \ + ((__HANDLE_OTHER_ADC__)->Instance = ADC2) + +/** + * @brief Set handle of the ADC slave associated to the ADC master + * On STM32F1 devices, ADC slave is always ADC2 (this can be different + * on other STM32 devices) + * @param __HANDLE_MASTER__: ADC master handle + * @param __HANDLE_SLAVE__: ADC slave handle + * @retval None + */ +#define ADC_MULTI_SLAVE(__HANDLE_MASTER__, __HANDLE_SLAVE__) \ + ((__HANDLE_SLAVE__)->Instance = ADC2) + +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +#define IS_ADC_INJECTED_RANK(CHANNEL) (((CHANNEL) == ADC_INJECTED_RANK_1) || \ + ((CHANNEL) == ADC_INJECTED_RANK_2) || \ + ((CHANNEL) == ADC_INJECTED_RANK_3) || \ + ((CHANNEL) == ADC_INJECTED_RANK_4)) + +#define IS_ADC_EXTTRIGINJEC_EDGE(EDGE) (((EDGE) == ADC_EXTERNALTRIGINJECCONV_EDGE_NONE) || \ + ((EDGE) == ADC_EXTERNALTRIGINJECCONV_EDGE_RISING)) + +/** @defgroup ADCEx_injected_nb_conv_verification ADCEx injected nb conv verification + * @{ + */ +#define IS_ADC_INJECTED_NB_CONV(LENGTH) (((LENGTH) >= 1U) && ((LENGTH) <= 4U)) +/** + * @} + */ + +#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) +#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \ + ((REGTRIG) == ADC_SOFTWARE_START)) +#endif +#if defined (STM32F101xE) +#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \ + ((REGTRIG) == ADC_SOFTWARE_START)) +#endif +#if defined (STM32F101xG) +#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \ + ((REGTRIG) == ADC_SOFTWARE_START)) +#endif +#if defined (STM32F103xE) || defined (STM32F103xG) +#define IS_ADC_EXTTRIG(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T4_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_EXT_IT11) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T3_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T2_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T5_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T1_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGCONV_T8_TRGO) || \ + ((REGTRIG) == ADC_SOFTWARE_START)) +#endif + +#if defined (STM32F100xB) || defined (STM32F100xE) || defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) +#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_INJECTED_SOFTWARE_START)) +#endif +#if defined (STM32F101xE) +#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \ + ((REGTRIG) == ADC_INJECTED_SOFTWARE_START)) +#endif +#if defined (STM32F101xG) +#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_INJECTED_SOFTWARE_START)) +#endif +#if defined (STM32F103xE) || defined (STM32F103xG) +#define IS_ADC_EXTTRIGINJEC(REGTRIG) (((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T2_CC1) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T3_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_EXT_IT15) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T4_CC3) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC2) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T5_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_CC4) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T1_TRGO) || \ + ((REGTRIG) == ADC_EXTERNALTRIGINJECCONV_T8_CC4) || \ + ((REGTRIG) == ADC_INJECTED_SOFTWARE_START)) +#endif + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +#define IS_ADC_MODE(MODE) (((MODE) == ADC_MODE_INDEPENDENT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT_INJECSIMULT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT_ALTERTRIG) || \ + ((MODE) == ADC_DUALMODE_INJECSIMULT_INTERLFAST) || \ + ((MODE) == ADC_DUALMODE_INJECSIMULT_INTERLSLOW) || \ + ((MODE) == ADC_DUALMODE_INJECSIMULT) || \ + ((MODE) == ADC_DUALMODE_REGSIMULT) || \ + ((MODE) == ADC_DUALMODE_INTERLFAST) || \ + ((MODE) == ADC_DUALMODE_INTERLSLOW) || \ + ((MODE) == ADC_DUALMODE_ALTERTRIG) ) +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/** + * @} + */ + + + + + + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup ADCEx_Exported_Functions + * @{ + */ + +/* IO operation functions *****************************************************/ +/** @addtogroup ADCEx_Exported_Functions_Group1 + * @{ + */ + +/* ADC calibration */ +HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc); + +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout); + +/* Non-blocking mode: Interruption */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc); +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc); + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +/* ADC multimode */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef *hadc, uint32_t *pData, uint32_t Length); +HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef *hadc); +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/* ADC retrieve conversion value intended to be used with polling or interruption */ +uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank); +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef *hadc); +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/* ADC IRQHandler and Callbacks used in non-blocking modes (Interruption) */ +void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc); +/** + * @} + */ + + +/* Peripheral Control functions ***********************************************/ +/** @addtogroup ADCEx_Exported_Functions_Group2 + * @{ + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc,ADC_InjectionConfTypeDef* sConfigInjected); +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef *hadc, ADC_MultiModeTypeDef *multimode); +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F1xx_HAL_ADC_EX_H */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h new file mode 100644 index 0000000..ac72075 --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim.h @@ -0,0 +1,2153 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_tim.h + * @author MCD Application Team + * @brief Header file of TIM HAL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F1xx_HAL_TIM_H +#define STM32F1xx_HAL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal_def.h" + +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIM + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIM_Exported_Types TIM Exported Types + * @{ + */ + +/** + * @brief TIM Time base Configuration Structure definition + */ +typedef struct +{ + uint32_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_Counter_Mode */ + + uint32_t Period; /*!< Specifies the period value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_ClockDivision */ + + uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + GP timers: this parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFF. + Advanced timers: this parameter must be a number between Min_Data = 0x0000 and + Max_Data = 0xFFFF. */ + + uint32_t AutoReloadPreload; /*!< Specifies the auto-reload preload. + This parameter can be a value of @ref TIM_AutoReloadPreload */ +} TIM_Base_InitTypeDef; + +/** + * @brief TIM Output Compare Configuration Structure definition + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCFastMode; /*!< Specifies the Fast mode state. + This parameter can be a value of @ref TIM_Output_Fast_State + @note This parameter is valid only in PWM1 and PWM2 mode. */ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ +} TIM_OC_InitTypeDef; + +/** + * @brief TIM One Pulse Mode Configuration Structure definition + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the TIM mode. + This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */ + + uint32_t Pulse; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_Output_Compare_Polarity */ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_Output_Compare_N_Polarity + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State + @note This parameter is valid only for timer instances supporting break feature. */ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_OnePulse_InitTypeDef; + +/** + * @brief TIM Input Capture Configuration Structure definition + */ +typedef struct +{ + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t ICSelection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_IC_InitTypeDef; + +/** + * @brief TIM Encoder Configuration Structure definition + */ +typedef struct +{ + uint32_t EncoderMode; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Mode */ + + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Input_Polarity */ + + uint32_t IC1Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t IC2Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Encoder_Input_Polarity */ + + uint32_t IC2Selection; /*!< Specifies the input. + This parameter can be a value of @ref TIM_Input_Capture_Selection */ + + uint32_t IC2Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC2Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_Encoder_InitTypeDef; + +/** + * @brief Clock Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClockSource; /*!< TIM clock sources + This parameter can be a value of @ref TIM_Clock_Source */ + uint32_t ClockPolarity; /*!< TIM clock polarity + This parameter can be a value of @ref TIM_Clock_Polarity */ + uint32_t ClockPrescaler; /*!< TIM clock prescaler + This parameter can be a value of @ref TIM_Clock_Prescaler */ + uint32_t ClockFilter; /*!< TIM clock filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_ClockConfigTypeDef; + +/** + * @brief TIM Clear Input Configuration Handle Structure definition + */ +typedef struct +{ + uint32_t ClearInputState; /*!< TIM clear Input state + This parameter can be ENABLE or DISABLE */ + uint32_t ClearInputSource; /*!< TIM clear Input sources + This parameter can be a value of @ref TIM_ClearInput_Source */ + uint32_t ClearInputPolarity; /*!< TIM Clear Input polarity + This parameter can be a value of @ref TIM_ClearInput_Polarity */ + uint32_t ClearInputPrescaler; /*!< TIM Clear Input prescaler + This parameter must be 0: When OCRef clear feature is used with ETR source, + ETR prescaler must be off */ + uint32_t ClearInputFilter; /*!< TIM Clear Input filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ +} TIM_ClearInputConfigTypeDef; + +/** + * @brief TIM Master configuration Structure definition + */ +typedef struct +{ + uint32_t MasterOutputTrigger; /*!< Trigger output (TRGO) selection + This parameter can be a value of @ref TIM_Master_Mode_Selection */ + uint32_t MasterSlaveMode; /*!< Master/slave mode selection + This parameter can be a value of @ref TIM_Master_Slave_Mode + @note When the Master/slave mode is enabled, the effect of + an event on the trigger input (TRGI) is delayed to allow a + perfect synchronization between the current timer and its + slaves (through TRGO). It is not mandatory in case of timer + synchronization mode. */ +} TIM_MasterConfigTypeDef; + +/** + * @brief TIM Slave configuration Structure definition + */ +typedef struct +{ + uint32_t SlaveMode; /*!< Slave mode selection + This parameter can be a value of @ref TIM_Slave_Mode */ + uint32_t InputTrigger; /*!< Input Trigger source + This parameter can be a value of @ref TIM_Trigger_Selection */ + uint32_t TriggerPolarity; /*!< Input Trigger polarity + This parameter can be a value of @ref TIM_Trigger_Polarity */ + uint32_t TriggerPrescaler; /*!< Input trigger prescaler + This parameter can be a value of @ref TIM_Trigger_Prescaler */ + uint32_t TriggerFilter; /*!< Input trigger filter + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + +} TIM_SlaveConfigTypeDef; + +/** + * @brief TIM Break input(s) and Dead time configuration Structure definition + * @note 2 break inputs can be configured (BKIN and BKIN2) with configurable + * filter and polarity. + */ +typedef struct +{ + uint32_t OffStateRunMode; /*!< TIM off state in run mode, This parameter can be a value of @ref TIM_OSSR_Off_State_Selection_for_Run_mode_state */ + + uint32_t OffStateIDLEMode; /*!< TIM off state in IDLE mode, This parameter can be a value of @ref TIM_OSSI_Off_State_Selection_for_Idle_mode_state */ + + uint32_t LockLevel; /*!< TIM Lock level, This parameter can be a value of @ref TIM_Lock_level */ + + uint32_t DeadTime; /*!< TIM dead Time, This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF */ + + uint32_t BreakState; /*!< TIM Break State, This parameter can be a value of @ref TIM_Break_Input_enable_disable */ + + uint32_t BreakPolarity; /*!< TIM Break input polarity, This parameter can be a value of @ref TIM_Break_Polarity */ + + uint32_t BreakFilter; /*!< Specifies the break input filter.This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t AutomaticOutput; /*!< TIM Automatic Output Enable state, This parameter can be a value of @ref TIM_AOE_Bit_Set_Reset */ + +} TIM_BreakDeadTimeConfigTypeDef; + +/** + * @brief HAL State structures definition + */ +typedef enum +{ + HAL_TIM_STATE_RESET = 0x00U, /*!< Peripheral not yet initialized or disabled */ + HAL_TIM_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */ + HAL_TIM_STATE_BUSY = 0x02U, /*!< An internal process is ongoing */ + HAL_TIM_STATE_TIMEOUT = 0x03U, /*!< Timeout state */ + HAL_TIM_STATE_ERROR = 0x04U /*!< Reception process is ongoing */ +} HAL_TIM_StateTypeDef; + +/** + * @brief TIM Channel States definition + */ +typedef enum +{ + HAL_TIM_CHANNEL_STATE_RESET = 0x00U, /*!< TIM Channel initial state */ + HAL_TIM_CHANNEL_STATE_READY = 0x01U, /*!< TIM Channel ready for use */ + HAL_TIM_CHANNEL_STATE_BUSY = 0x02U, /*!< An internal process is ongoing on the TIM channel */ +} HAL_TIM_ChannelStateTypeDef; + +/** + * @brief DMA Burst States definition + */ +typedef enum +{ + HAL_DMA_BURST_STATE_RESET = 0x00U, /*!< DMA Burst initial state */ + HAL_DMA_BURST_STATE_READY = 0x01U, /*!< DMA Burst ready for use */ + HAL_DMA_BURST_STATE_BUSY = 0x02U, /*!< Ongoing DMA Burst */ +} HAL_TIM_DMABurstStateTypeDef; + +/** + * @brief HAL Active channel structures definition + */ +typedef enum +{ + HAL_TIM_ACTIVE_CHANNEL_1 = 0x01U, /*!< The active channel is 1 */ + HAL_TIM_ACTIVE_CHANNEL_2 = 0x02U, /*!< The active channel is 2 */ + HAL_TIM_ACTIVE_CHANNEL_3 = 0x04U, /*!< The active channel is 3 */ + HAL_TIM_ACTIVE_CHANNEL_4 = 0x08U, /*!< The active channel is 4 */ + HAL_TIM_ACTIVE_CHANNEL_CLEARED = 0x00U /*!< All active channels cleared */ +} HAL_TIM_ActiveChannel; + +/** + * @brief TIM Time Base Handle Structure definition + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +typedef struct __TIM_HandleTypeDef +#else +typedef struct +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +{ + TIM_TypeDef *Instance; /*!< Register base address */ + TIM_Base_InitTypeDef Init; /*!< TIM Time Base required parameters */ + HAL_TIM_ActiveChannel Channel; /*!< Active channel */ + DMA_HandleTypeDef *hdma[7]; /*!< DMA Handlers array + This array is accessed by a @ref DMA_Handle_index */ + HAL_LockTypeDef Lock; /*!< Locking object */ + __IO HAL_TIM_StateTypeDef State; /*!< TIM operation state */ + __IO HAL_TIM_ChannelStateTypeDef ChannelState[4]; /*!< TIM channel operation state */ + __IO HAL_TIM_ChannelStateTypeDef ChannelNState[4]; /*!< TIM complementary channel operation state */ + __IO HAL_TIM_DMABurstStateTypeDef DMABurstState; /*!< DMA burst operation state */ + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + void (* Base_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp Init Callback */ + void (* Base_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Base Msp DeInit Callback */ + void (* IC_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp Init Callback */ + void (* IC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM IC Msp DeInit Callback */ + void (* OC_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp Init Callback */ + void (* OC_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM OC Msp DeInit Callback */ + void (* PWM_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp Init Callback */ + void (* PWM_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Msp DeInit Callback */ + void (* OnePulse_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp Init Callback */ + void (* OnePulse_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM One Pulse Msp DeInit Callback */ + void (* Encoder_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp Init Callback */ + void (* Encoder_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Encoder Msp DeInit Callback */ + void (* HallSensor_MspInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp Init Callback */ + void (* HallSensor_MspDeInitCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Hall Sensor Msp DeInit Callback */ + void (* PeriodElapsedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Period Elapsed Callback */ + void (* PeriodElapsedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Period Elapsed half complete Callback */ + void (* TriggerCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger Callback */ + void (* TriggerHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Trigger half complete Callback */ + void (* IC_CaptureCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Input Capture Callback */ + void (* IC_CaptureHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Input Capture half complete Callback */ + void (* OC_DelayElapsedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Output Compare Delay Elapsed Callback */ + void (* PWM_PulseFinishedCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished Callback */ + void (* PWM_PulseFinishedHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM PWM Pulse Finished half complete Callback */ + void (* ErrorCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Error Callback */ + void (* CommutationCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Commutation Callback */ + void (* CommutationHalfCpltCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Commutation half complete Callback */ + void (* BreakCallback)(struct __TIM_HandleTypeDef *htim); /*!< TIM Break Callback */ +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} TIM_HandleTypeDef; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief HAL TIM Callback ID enumeration definition + */ +typedef enum +{ + HAL_TIM_BASE_MSPINIT_CB_ID = 0x00U /*!< TIM Base MspInit Callback ID */ + , HAL_TIM_BASE_MSPDEINIT_CB_ID = 0x01U /*!< TIM Base MspDeInit Callback ID */ + , HAL_TIM_IC_MSPINIT_CB_ID = 0x02U /*!< TIM IC MspInit Callback ID */ + , HAL_TIM_IC_MSPDEINIT_CB_ID = 0x03U /*!< TIM IC MspDeInit Callback ID */ + , HAL_TIM_OC_MSPINIT_CB_ID = 0x04U /*!< TIM OC MspInit Callback ID */ + , HAL_TIM_OC_MSPDEINIT_CB_ID = 0x05U /*!< TIM OC MspDeInit Callback ID */ + , HAL_TIM_PWM_MSPINIT_CB_ID = 0x06U /*!< TIM PWM MspInit Callback ID */ + , HAL_TIM_PWM_MSPDEINIT_CB_ID = 0x07U /*!< TIM PWM MspDeInit Callback ID */ + , HAL_TIM_ONE_PULSE_MSPINIT_CB_ID = 0x08U /*!< TIM One Pulse MspInit Callback ID */ + , HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID = 0x09U /*!< TIM One Pulse MspDeInit Callback ID */ + , HAL_TIM_ENCODER_MSPINIT_CB_ID = 0x0AU /*!< TIM Encoder MspInit Callback ID */ + , HAL_TIM_ENCODER_MSPDEINIT_CB_ID = 0x0BU /*!< TIM Encoder MspDeInit Callback ID */ + , HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID = 0x0CU /*!< TIM Hall Sensor MspDeInit Callback ID */ + , HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID = 0x0DU /*!< TIM Hall Sensor MspDeInit Callback ID */ + , HAL_TIM_PERIOD_ELAPSED_CB_ID = 0x0EU /*!< TIM Period Elapsed Callback ID */ + , HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID = 0x0FU /*!< TIM Period Elapsed half complete Callback ID */ + , HAL_TIM_TRIGGER_CB_ID = 0x10U /*!< TIM Trigger Callback ID */ + , HAL_TIM_TRIGGER_HALF_CB_ID = 0x11U /*!< TIM Trigger half complete Callback ID */ + , HAL_TIM_IC_CAPTURE_CB_ID = 0x12U /*!< TIM Input Capture Callback ID */ + , HAL_TIM_IC_CAPTURE_HALF_CB_ID = 0x13U /*!< TIM Input Capture half complete Callback ID */ + , HAL_TIM_OC_DELAY_ELAPSED_CB_ID = 0x14U /*!< TIM Output Compare Delay Elapsed Callback ID */ + , HAL_TIM_PWM_PULSE_FINISHED_CB_ID = 0x15U /*!< TIM PWM Pulse Finished Callback ID */ + , HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID = 0x16U /*!< TIM PWM Pulse Finished half complete Callback ID */ + , HAL_TIM_ERROR_CB_ID = 0x17U /*!< TIM Error Callback ID */ + , HAL_TIM_COMMUTATION_CB_ID = 0x18U /*!< TIM Commutation Callback ID */ + , HAL_TIM_COMMUTATION_HALF_CB_ID = 0x19U /*!< TIM Commutation half complete Callback ID */ + , HAL_TIM_BREAK_CB_ID = 0x1AU /*!< TIM Break Callback ID */ +} HAL_TIM_CallbackIDTypeDef; + +/** + * @brief HAL TIM Callback pointer definition + */ +typedef void (*pTIM_CallbackTypeDef)(TIM_HandleTypeDef *htim); /*!< pointer to the TIM callback function */ + +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_ClearInput_Source TIM Clear Input Source + * @{ + */ +#define TIM_CLEARINPUTSOURCE_NONE 0x00000000U /*!< OCREF_CLR is disabled */ +#define TIM_CLEARINPUTSOURCE_ETR 0x00000001U /*!< OCREF_CLR is connected to ETRF input */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Base_address TIM DMA Base Address + * @{ + */ +#define TIM_DMABASE_CR1 0x00000000U +#define TIM_DMABASE_CR2 0x00000001U +#define TIM_DMABASE_SMCR 0x00000002U +#define TIM_DMABASE_DIER 0x00000003U +#define TIM_DMABASE_SR 0x00000004U +#define TIM_DMABASE_EGR 0x00000005U +#define TIM_DMABASE_CCMR1 0x00000006U +#define TIM_DMABASE_CCMR2 0x00000007U +#define TIM_DMABASE_CCER 0x00000008U +#define TIM_DMABASE_CNT 0x00000009U +#define TIM_DMABASE_PSC 0x0000000AU +#define TIM_DMABASE_ARR 0x0000000BU +#define TIM_DMABASE_RCR 0x0000000CU +#define TIM_DMABASE_CCR1 0x0000000DU +#define TIM_DMABASE_CCR2 0x0000000EU +#define TIM_DMABASE_CCR3 0x0000000FU +#define TIM_DMABASE_CCR4 0x00000010U +#define TIM_DMABASE_BDTR 0x00000011U +#define TIM_DMABASE_DCR 0x00000012U +#define TIM_DMABASE_DMAR 0x00000013U +/** + * @} + */ + +/** @defgroup TIM_Event_Source TIM Event Source + * @{ + */ +#define TIM_EVENTSOURCE_UPDATE TIM_EGR_UG /*!< Reinitialize the counter and generates an update of the registers */ +#define TIM_EVENTSOURCE_CC1 TIM_EGR_CC1G /*!< A capture/compare event is generated on channel 1 */ +#define TIM_EVENTSOURCE_CC2 TIM_EGR_CC2G /*!< A capture/compare event is generated on channel 2 */ +#define TIM_EVENTSOURCE_CC3 TIM_EGR_CC3G /*!< A capture/compare event is generated on channel 3 */ +#define TIM_EVENTSOURCE_CC4 TIM_EGR_CC4G /*!< A capture/compare event is generated on channel 4 */ +#define TIM_EVENTSOURCE_COM TIM_EGR_COMG /*!< A commutation event is generated */ +#define TIM_EVENTSOURCE_TRIGGER TIM_EGR_TG /*!< A trigger event is generated */ +#define TIM_EVENTSOURCE_BREAK TIM_EGR_BG /*!< A break event is generated */ +/** + * @} + */ + +/** @defgroup TIM_Input_Channel_Polarity TIM Input Channel polarity + * @{ + */ +#define TIM_INPUTCHANNELPOLARITY_RISING 0x00000000U /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_FALLING TIM_CCER_CC1P /*!< Polarity for TIx source */ +#define TIM_INPUTCHANNELPOLARITY_BOTHEDGE (TIM_CCER_CC1P | TIM_CCER_CC1NP) /*!< Polarity for TIx source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Polarity TIM ETR Polarity + * @{ + */ +#define TIM_ETRPOLARITY_INVERTED TIM_SMCR_ETP /*!< Polarity for ETR source */ +#define TIM_ETRPOLARITY_NONINVERTED 0x00000000U /*!< Polarity for ETR source */ +/** + * @} + */ + +/** @defgroup TIM_ETR_Prescaler TIM ETR Prescaler + * @{ + */ +#define TIM_ETRPRESCALER_DIV1 0x00000000U /*!< No prescaler is used */ +#define TIM_ETRPRESCALER_DIV2 TIM_SMCR_ETPS_0 /*!< ETR input source is divided by 2 */ +#define TIM_ETRPRESCALER_DIV4 TIM_SMCR_ETPS_1 /*!< ETR input source is divided by 4 */ +#define TIM_ETRPRESCALER_DIV8 TIM_SMCR_ETPS /*!< ETR input source is divided by 8 */ +/** + * @} + */ + +/** @defgroup TIM_Counter_Mode TIM Counter Mode + * @{ + */ +#define TIM_COUNTERMODE_UP 0x00000000U /*!< Counter used as up-counter */ +#define TIM_COUNTERMODE_DOWN TIM_CR1_DIR /*!< Counter used as down-counter */ +#define TIM_COUNTERMODE_CENTERALIGNED1 TIM_CR1_CMS_0 /*!< Center-aligned mode 1 */ +#define TIM_COUNTERMODE_CENTERALIGNED2 TIM_CR1_CMS_1 /*!< Center-aligned mode 2 */ +#define TIM_COUNTERMODE_CENTERALIGNED3 TIM_CR1_CMS /*!< Center-aligned mode 3 */ +/** + * @} + */ + +/** @defgroup TIM_ClockDivision TIM Clock Division + * @{ + */ +#define TIM_CLOCKDIVISION_DIV1 0x00000000U /*!< Clock division: tDTS=tCK_INT */ +#define TIM_CLOCKDIVISION_DIV2 TIM_CR1_CKD_0 /*!< Clock division: tDTS=2*tCK_INT */ +#define TIM_CLOCKDIVISION_DIV4 TIM_CR1_CKD_1 /*!< Clock division: tDTS=4*tCK_INT */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_State TIM Output Compare State + * @{ + */ +#define TIM_OUTPUTSTATE_DISABLE 0x00000000U /*!< Capture/Compare 1 output disabled */ +#define TIM_OUTPUTSTATE_ENABLE TIM_CCER_CC1E /*!< Capture/Compare 1 output enabled */ +/** + * @} + */ + +/** @defgroup TIM_AutoReloadPreload TIM Auto-Reload Preload + * @{ + */ +#define TIM_AUTORELOAD_PRELOAD_DISABLE 0x00000000U /*!< TIMx_ARR register is not buffered */ +#define TIM_AUTORELOAD_PRELOAD_ENABLE TIM_CR1_ARPE /*!< TIMx_ARR register is buffered */ + +/** + * @} + */ + +/** @defgroup TIM_Output_Fast_State TIM Output Fast State + * @{ + */ +#define TIM_OCFAST_DISABLE 0x00000000U /*!< Output Compare fast disable */ +#define TIM_OCFAST_ENABLE TIM_CCMR1_OC1FE /*!< Output Compare fast enable */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_State TIM Complementary Output Compare State + * @{ + */ +#define TIM_OUTPUTNSTATE_DISABLE 0x00000000U /*!< OCxN is disabled */ +#define TIM_OUTPUTNSTATE_ENABLE TIM_CCER_CC1NE /*!< OCxN is enabled */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Polarity TIM Output Compare Polarity + * @{ + */ +#define TIM_OCPOLARITY_HIGH 0x00000000U /*!< Capture/Compare output polarity */ +#define TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< Capture/Compare output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Polarity TIM Complementary Output Compare Polarity + * @{ + */ +#define TIM_OCNPOLARITY_HIGH 0x00000000U /*!< Capture/Compare complementary output polarity */ +#define TIM_OCNPOLARITY_LOW TIM_CCER_CC1NP /*!< Capture/Compare complementary output polarity */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_Idle_State TIM Output Compare Idle State + * @{ + */ +#define TIM_OCIDLESTATE_SET TIM_CR2_OIS1 /*!< Output Idle state: OCx=1 when MOE=0 */ +#define TIM_OCIDLESTATE_RESET 0x00000000U /*!< Output Idle state: OCx=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_N_Idle_State TIM Complementary Output Compare Idle State + * @{ + */ +#define TIM_OCNIDLESTATE_SET TIM_CR2_OIS1N /*!< Complementary output Idle state: OCxN=1 when MOE=0 */ +#define TIM_OCNIDLESTATE_RESET 0x00000000U /*!< Complementary output Idle state: OCxN=0 when MOE=0 */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Polarity TIM Input Capture Polarity + * @{ + */ +#define TIM_ICPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Capture triggered by rising edge on timer input */ +#define TIM_ICPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Capture triggered by falling edge on timer input */ +#define TIM_ICPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Capture triggered by both rising and falling edges on timer input*/ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Input_Polarity TIM Encoder Input Polarity + * @{ + */ +#define TIM_ENCODERINPUTPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Encoder input with rising edge polarity */ +#define TIM_ENCODERINPUTPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Encoder input with falling edge polarity */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Selection TIM Input Capture Selection + * @{ + */ +#define TIM_ICSELECTION_DIRECTTI TIM_CCMR1_CC1S_0 /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC1, IC2, IC3 or IC4, respectively */ +#define TIM_ICSELECTION_INDIRECTTI TIM_CCMR1_CC1S_1 /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to IC2, IC1, IC4 or IC3, respectively */ +#define TIM_ICSELECTION_TRC TIM_CCMR1_CC1S /*!< TIM Input 1, 2, 3 or 4 is selected to be connected to TRC */ +/** + * @} + */ + +/** @defgroup TIM_Input_Capture_Prescaler TIM Input Capture Prescaler + * @{ + */ +#define TIM_ICPSC_DIV1 0x00000000U /*!< Capture performed each time an edge is detected on the capture input */ +#define TIM_ICPSC_DIV2 TIM_CCMR1_IC1PSC_0 /*!< Capture performed once every 2 events */ +#define TIM_ICPSC_DIV4 TIM_CCMR1_IC1PSC_1 /*!< Capture performed once every 4 events */ +#define TIM_ICPSC_DIV8 TIM_CCMR1_IC1PSC /*!< Capture performed once every 8 events */ +/** + * @} + */ + +/** @defgroup TIM_One_Pulse_Mode TIM One Pulse Mode + * @{ + */ +#define TIM_OPMODE_SINGLE TIM_CR1_OPM /*!< Counter stops counting at the next update event */ +#define TIM_OPMODE_REPETITIVE 0x00000000U /*!< Counter is not stopped at update event */ +/** + * @} + */ + +/** @defgroup TIM_Encoder_Mode TIM Encoder Mode + * @{ + */ +#define TIM_ENCODERMODE_TI1 TIM_SMCR_SMS_0 /*!< Quadrature encoder mode 1, x2 mode, counts up/down on TI1FP1 edge depending on TI2FP2 level */ +#define TIM_ENCODERMODE_TI2 TIM_SMCR_SMS_1 /*!< Quadrature encoder mode 2, x2 mode, counts up/down on TI2FP2 edge depending on TI1FP1 level. */ +#define TIM_ENCODERMODE_TI12 (TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< Quadrature encoder mode 3, x4 mode, counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. */ +/** + * @} + */ + +/** @defgroup TIM_Interrupt_definition TIM interrupt Definition + * @{ + */ +#define TIM_IT_UPDATE TIM_DIER_UIE /*!< Update interrupt */ +#define TIM_IT_CC1 TIM_DIER_CC1IE /*!< Capture/Compare 1 interrupt */ +#define TIM_IT_CC2 TIM_DIER_CC2IE /*!< Capture/Compare 2 interrupt */ +#define TIM_IT_CC3 TIM_DIER_CC3IE /*!< Capture/Compare 3 interrupt */ +#define TIM_IT_CC4 TIM_DIER_CC4IE /*!< Capture/Compare 4 interrupt */ +#define TIM_IT_COM TIM_DIER_COMIE /*!< Commutation interrupt */ +#define TIM_IT_TRIGGER TIM_DIER_TIE /*!< Trigger interrupt */ +#define TIM_IT_BREAK TIM_DIER_BIE /*!< Break interrupt */ +/** + * @} + */ + +/** @defgroup TIM_Commutation_Source TIM Commutation Source + * @{ + */ +#define TIM_COMMUTATION_TRGI TIM_CR2_CCUS /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit or when an rising edge occurs on trigger input */ +#define TIM_COMMUTATION_SOFTWARE 0x00000000U /*!< When Capture/compare control bits are preloaded, they are updated by setting the COMG bit */ +/** + * @} + */ + +/** @defgroup TIM_DMA_sources TIM DMA Sources + * @{ + */ +#define TIM_DMA_UPDATE TIM_DIER_UDE /*!< DMA request is triggered by the update event */ +#define TIM_DMA_CC1 TIM_DIER_CC1DE /*!< DMA request is triggered by the capture/compare macth 1 event */ +#define TIM_DMA_CC2 TIM_DIER_CC2DE /*!< DMA request is triggered by the capture/compare macth 2 event event */ +#define TIM_DMA_CC3 TIM_DIER_CC3DE /*!< DMA request is triggered by the capture/compare macth 3 event event */ +#define TIM_DMA_CC4 TIM_DIER_CC4DE /*!< DMA request is triggered by the capture/compare macth 4 event event */ +#define TIM_DMA_COM TIM_DIER_COMDE /*!< DMA request is triggered by the commutation event */ +#define TIM_DMA_TRIGGER TIM_DIER_TDE /*!< DMA request is triggered by the trigger event */ +/** + * @} + */ + +/** @defgroup TIM_CC_DMA_Request CCx DMA request selection + * @{ + */ +#define TIM_CCDMAREQUEST_CC 0x00000000U /*!< CCx DMA request sent when capture or compare match event occurs */ +#define TIM_CCDMAREQUEST_UPDATE TIM_CR2_CCDS /*!< CCx DMA requests sent when update event occurs */ +/** + * @} + */ + +/** @defgroup TIM_Flag_definition TIM Flag Definition + * @{ + */ +#define TIM_FLAG_UPDATE TIM_SR_UIF /*!< Update interrupt flag */ +#define TIM_FLAG_CC1 TIM_SR_CC1IF /*!< Capture/Compare 1 interrupt flag */ +#define TIM_FLAG_CC2 TIM_SR_CC2IF /*!< Capture/Compare 2 interrupt flag */ +#define TIM_FLAG_CC3 TIM_SR_CC3IF /*!< Capture/Compare 3 interrupt flag */ +#define TIM_FLAG_CC4 TIM_SR_CC4IF /*!< Capture/Compare 4 interrupt flag */ +#define TIM_FLAG_COM TIM_SR_COMIF /*!< Commutation interrupt flag */ +#define TIM_FLAG_TRIGGER TIM_SR_TIF /*!< Trigger interrupt flag */ +#define TIM_FLAG_BREAK TIM_SR_BIF /*!< Break interrupt flag */ +#define TIM_FLAG_CC1OF TIM_SR_CC1OF /*!< Capture 1 overcapture flag */ +#define TIM_FLAG_CC2OF TIM_SR_CC2OF /*!< Capture 2 overcapture flag */ +#define TIM_FLAG_CC3OF TIM_SR_CC3OF /*!< Capture 3 overcapture flag */ +#define TIM_FLAG_CC4OF TIM_SR_CC4OF /*!< Capture 4 overcapture flag */ +/** + * @} + */ + +/** @defgroup TIM_Channel TIM Channel + * @{ + */ +#define TIM_CHANNEL_1 0x00000000U /*!< Capture/compare channel 1 identifier */ +#define TIM_CHANNEL_2 0x00000004U /*!< Capture/compare channel 2 identifier */ +#define TIM_CHANNEL_3 0x00000008U /*!< Capture/compare channel 3 identifier */ +#define TIM_CHANNEL_4 0x0000000CU /*!< Capture/compare channel 4 identifier */ +#define TIM_CHANNEL_ALL 0x0000003CU /*!< Global Capture/compare channel identifier */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Source TIM Clock Source + * @{ + */ +#define TIM_CLOCKSOURCE_INTERNAL TIM_SMCR_ETPS_0 /*!< Internal clock source */ +#define TIM_CLOCKSOURCE_ETRMODE1 TIM_TS_ETRF /*!< External clock source mode 1 (ETRF) */ +#define TIM_CLOCKSOURCE_ETRMODE2 TIM_SMCR_ETPS_1 /*!< External clock source mode 2 */ +#define TIM_CLOCKSOURCE_TI1ED TIM_TS_TI1F_ED /*!< External clock source mode 1 (TTI1FP1 + edge detect.) */ +#define TIM_CLOCKSOURCE_TI1 TIM_TS_TI1FP1 /*!< External clock source mode 1 (TTI1FP1) */ +#define TIM_CLOCKSOURCE_TI2 TIM_TS_TI2FP2 /*!< External clock source mode 1 (TTI2FP2) */ +#define TIM_CLOCKSOURCE_ITR0 TIM_TS_ITR0 /*!< External clock source mode 1 (ITR0) */ +#define TIM_CLOCKSOURCE_ITR1 TIM_TS_ITR1 /*!< External clock source mode 1 (ITR1) */ +#define TIM_CLOCKSOURCE_ITR2 TIM_TS_ITR2 /*!< External clock source mode 1 (ITR2) */ +#define TIM_CLOCKSOURCE_ITR3 TIM_TS_ITR3 /*!< External clock source mode 1 (ITR3) */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Polarity TIM Clock Polarity + * @{ + */ +#define TIM_CLOCKPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx clock sources */ +#define TIM_CLOCKPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIx clock sources */ +#define TIM_CLOCKPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIx clock sources */ +/** + * @} + */ + +/** @defgroup TIM_Clock_Prescaler TIM Clock Prescaler + * @{ + */ +#define TIM_CLOCKPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLOCKPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Clock: Capture performed once every 2 events. */ +#define TIM_CLOCKPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Clock: Capture performed once every 4 events. */ +#define TIM_CLOCKPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Clock: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Polarity TIM Clear Input Polarity + * @{ + */ +#define TIM_CLEARINPUTPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx pin */ +#define TIM_CLEARINPUTPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx pin */ +/** + * @} + */ + +/** @defgroup TIM_ClearInput_Prescaler TIM Clear Input Prescaler + * @{ + */ +#define TIM_CLEARINPUTPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_CLEARINPUTPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR pin: Capture performed once every 2 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR pin: Capture performed once every 4 events. */ +#define TIM_CLEARINPUTPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR pin: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_OSSR_Off_State_Selection_for_Run_mode_state TIM OSSR OffState Selection for Run mode state + * @{ + */ +#define TIM_OSSR_ENABLE TIM_BDTR_OSSR /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSR_DISABLE 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +/** + * @} + */ + +/** @defgroup TIM_OSSI_Off_State_Selection_for_Idle_mode_state TIM OSSI OffState Selection for Idle mode state + * @{ + */ +#define TIM_OSSI_ENABLE TIM_BDTR_OSSI /*!< When inactive, OC/OCN outputs are enabled (still controlled by the timer) */ +#define TIM_OSSI_DISABLE 0x00000000U /*!< When inactive, OC/OCN outputs are disabled (not controlled any longer by the timer) */ +/** + * @} + */ +/** @defgroup TIM_Lock_level TIM Lock level + * @{ + */ +#define TIM_LOCKLEVEL_OFF 0x00000000U /*!< LOCK OFF */ +#define TIM_LOCKLEVEL_1 TIM_BDTR_LOCK_0 /*!< LOCK Level 1 */ +#define TIM_LOCKLEVEL_2 TIM_BDTR_LOCK_1 /*!< LOCK Level 2 */ +#define TIM_LOCKLEVEL_3 TIM_BDTR_LOCK /*!< LOCK Level 3 */ +/** + * @} + */ + +/** @defgroup TIM_Break_Input_enable_disable TIM Break Input Enable + * @{ + */ +#define TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break input BRK is enabled */ +#define TIM_BREAK_DISABLE 0x00000000U /*!< Break input BRK is disabled */ +/** + * @} + */ + +/** @defgroup TIM_Break_Polarity TIM Break Input Polarity + * @{ + */ +#define TIM_BREAKPOLARITY_LOW 0x00000000U /*!< Break input BRK is active low */ +#define TIM_BREAKPOLARITY_HIGH TIM_BDTR_BKP /*!< Break input BRK is active high */ +/** + * @} + */ + +/** @defgroup TIM_AOE_Bit_Set_Reset TIM Automatic Output Enable + * @{ + */ +#define TIM_AUTOMATICOUTPUT_DISABLE 0x00000000U /*!< MOE can be set only by software */ +#define TIM_AUTOMATICOUTPUT_ENABLE TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update event (if none of the break inputs BRK and BRK2 is active) */ +/** + * @} + */ + +/** @defgroup TIM_Master_Mode_Selection TIM Master Mode Selection + * @{ + */ +#define TIM_TRGO_RESET 0x00000000U /*!< TIMx_EGR.UG bit is used as trigger output (TRGO) */ +#define TIM_TRGO_ENABLE TIM_CR2_MMS_0 /*!< TIMx_CR1.CEN bit is used as trigger output (TRGO) */ +#define TIM_TRGO_UPDATE TIM_CR2_MMS_1 /*!< Update event is used as trigger output (TRGO) */ +#define TIM_TRGO_OC1 (TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< Capture or a compare match 1 is used as trigger output (TRGO) */ +#define TIM_TRGO_OC1REF TIM_CR2_MMS_2 /*!< OC1REF signal is used as trigger output (TRGO) */ +#define TIM_TRGO_OC2REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_0) /*!< OC2REF signal is used as trigger output(TRGO) */ +#define TIM_TRGO_OC3REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1) /*!< OC3REF signal is used as trigger output(TRGO) */ +#define TIM_TRGO_OC4REF (TIM_CR2_MMS_2 | TIM_CR2_MMS_1 | TIM_CR2_MMS_0) /*!< OC4REF signal is used as trigger output(TRGO) */ +/** + * @} + */ + +/** @defgroup TIM_Master_Slave_Mode TIM Master/Slave Mode + * @{ + */ +#define TIM_MASTERSLAVEMODE_ENABLE TIM_SMCR_MSM /*!< No action */ +#define TIM_MASTERSLAVEMODE_DISABLE 0x00000000U /*!< Master/slave mode is selected */ +/** + * @} + */ + +/** @defgroup TIM_Slave_Mode TIM Slave mode + * @{ + */ +#define TIM_SLAVEMODE_DISABLE 0x00000000U /*!< Slave mode disabled */ +#define TIM_SLAVEMODE_RESET TIM_SMCR_SMS_2 /*!< Reset Mode */ +#define TIM_SLAVEMODE_GATED (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_0) /*!< Gated Mode */ +#define TIM_SLAVEMODE_TRIGGER (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1) /*!< Trigger Mode */ +#define TIM_SLAVEMODE_EXTERNAL1 (TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0) /*!< External Clock Mode 1 */ +/** + * @} + */ + +/** @defgroup TIM_Output_Compare_and_PWM_modes TIM Output Compare and PWM Modes + * @{ + */ +#define TIM_OCMODE_TIMING 0x00000000U /*!< Frozen */ +#define TIM_OCMODE_ACTIVE TIM_CCMR1_OC1M_0 /*!< Set channel to active level on match */ +#define TIM_OCMODE_INACTIVE TIM_CCMR1_OC1M_1 /*!< Set channel to inactive level on match */ +#define TIM_OCMODE_TOGGLE (TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< Toggle */ +#define TIM_OCMODE_PWM1 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1) /*!< PWM mode 1 */ +#define TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!< PWM mode 2 */ +#define TIM_OCMODE_FORCED_ACTIVE (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_0) /*!< Force active level */ +#define TIM_OCMODE_FORCED_INACTIVE TIM_CCMR1_OC1M_2 /*!< Force inactive level */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Selection TIM Trigger Selection + * @{ + */ +#define TIM_TS_ITR0 0x00000000U /*!< Internal Trigger 0 (ITR0) */ +#define TIM_TS_ITR1 TIM_SMCR_TS_0 /*!< Internal Trigger 1 (ITR1) */ +#define TIM_TS_ITR2 TIM_SMCR_TS_1 /*!< Internal Trigger 2 (ITR2) */ +#define TIM_TS_ITR3 (TIM_SMCR_TS_0 | TIM_SMCR_TS_1) /*!< Internal Trigger 3 (ITR3) */ +#define TIM_TS_TI1F_ED TIM_SMCR_TS_2 /*!< TI1 Edge Detector (TI1F_ED) */ +#define TIM_TS_TI1FP1 (TIM_SMCR_TS_0 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 1 (TI1FP1) */ +#define TIM_TS_TI2FP2 (TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered Timer Input 2 (TI2FP2) */ +#define TIM_TS_ETRF (TIM_SMCR_TS_0 | TIM_SMCR_TS_1 | TIM_SMCR_TS_2) /*!< Filtered External Trigger input (ETRF) */ +#define TIM_TS_NONE 0x0000FFFFU /*!< No trigger selected */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Polarity TIM Trigger Polarity + * @{ + */ +#define TIM_TRIGGERPOLARITY_INVERTED TIM_ETRPOLARITY_INVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_NONINVERTED TIM_ETRPOLARITY_NONINVERTED /*!< Polarity for ETRx trigger sources */ +#define TIM_TRIGGERPOLARITY_RISING TIM_INPUTCHANNELPOLARITY_RISING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_FALLING TIM_INPUTCHANNELPOLARITY_FALLING /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +#define TIM_TRIGGERPOLARITY_BOTHEDGE TIM_INPUTCHANNELPOLARITY_BOTHEDGE /*!< Polarity for TIxFPx or TI1_ED trigger sources */ +/** + * @} + */ + +/** @defgroup TIM_Trigger_Prescaler TIM Trigger Prescaler + * @{ + */ +#define TIM_TRIGGERPRESCALER_DIV1 TIM_ETRPRESCALER_DIV1 /*!< No prescaler is used */ +#define TIM_TRIGGERPRESCALER_DIV2 TIM_ETRPRESCALER_DIV2 /*!< Prescaler for External ETR Trigger: Capture performed once every 2 events. */ +#define TIM_TRIGGERPRESCALER_DIV4 TIM_ETRPRESCALER_DIV4 /*!< Prescaler for External ETR Trigger: Capture performed once every 4 events. */ +#define TIM_TRIGGERPRESCALER_DIV8 TIM_ETRPRESCALER_DIV8 /*!< Prescaler for External ETR Trigger: Capture performed once every 8 events. */ +/** + * @} + */ + +/** @defgroup TIM_TI1_Selection TIM TI1 Input Selection + * @{ + */ +#define TIM_TI1SELECTION_CH1 0x00000000U /*!< The TIMx_CH1 pin is connected to TI1 input */ +#define TIM_TI1SELECTION_XORCOMBINATION TIM_CR2_TI1S /*!< The TIMx_CH1, CH2 and CH3 pins are connected to the TI1 input (XOR combination) */ +/** + * @} + */ + +/** @defgroup TIM_DMA_Burst_Length TIM DMA Burst Length + * @{ + */ +#define TIM_DMABURSTLENGTH_1TRANSFER 0x00000000U /*!< The transfer is done to 1 register starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_2TRANSFERS 0x00000100U /*!< The transfer is done to 2 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_3TRANSFERS 0x00000200U /*!< The transfer is done to 3 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_4TRANSFERS 0x00000300U /*!< The transfer is done to 4 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_5TRANSFERS 0x00000400U /*!< The transfer is done to 5 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_6TRANSFERS 0x00000500U /*!< The transfer is done to 6 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_7TRANSFERS 0x00000600U /*!< The transfer is done to 7 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_8TRANSFERS 0x00000700U /*!< The transfer is done to 8 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_9TRANSFERS 0x00000800U /*!< The transfer is done to 9 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_10TRANSFERS 0x00000900U /*!< The transfer is done to 10 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_11TRANSFERS 0x00000A00U /*!< The transfer is done to 11 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_12TRANSFERS 0x00000B00U /*!< The transfer is done to 12 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_13TRANSFERS 0x00000C00U /*!< The transfer is done to 13 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_14TRANSFERS 0x00000D00U /*!< The transfer is done to 14 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_15TRANSFERS 0x00000E00U /*!< The transfer is done to 15 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_16TRANSFERS 0x00000F00U /*!< The transfer is done to 16 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_17TRANSFERS 0x00001000U /*!< The transfer is done to 17 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +#define TIM_DMABURSTLENGTH_18TRANSFERS 0x00001100U /*!< The transfer is done to 18 registers starting from TIMx_CR1 + TIMx_DCR.DBA */ +/** + * @} + */ + +/** @defgroup DMA_Handle_index TIM DMA Handle Index + * @{ + */ +#define TIM_DMA_ID_UPDATE ((uint16_t) 0x0000) /*!< Index of the DMA handle used for Update DMA requests */ +#define TIM_DMA_ID_CC1 ((uint16_t) 0x0001) /*!< Index of the DMA handle used for Capture/Compare 1 DMA requests */ +#define TIM_DMA_ID_CC2 ((uint16_t) 0x0002) /*!< Index of the DMA handle used for Capture/Compare 2 DMA requests */ +#define TIM_DMA_ID_CC3 ((uint16_t) 0x0003) /*!< Index of the DMA handle used for Capture/Compare 3 DMA requests */ +#define TIM_DMA_ID_CC4 ((uint16_t) 0x0004) /*!< Index of the DMA handle used for Capture/Compare 4 DMA requests */ +#define TIM_DMA_ID_COMMUTATION ((uint16_t) 0x0005) /*!< Index of the DMA handle used for Commutation DMA requests */ +#define TIM_DMA_ID_TRIGGER ((uint16_t) 0x0006) /*!< Index of the DMA handle used for Trigger DMA requests */ +/** + * @} + */ + +/** @defgroup Channel_CC_State TIM Capture/Compare Channel State + * @{ + */ +#define TIM_CCx_ENABLE 0x00000001U /*!< Input or output channel is enabled */ +#define TIM_CCx_DISABLE 0x00000000U /*!< Input or output channel is disabled */ +#define TIM_CCxN_ENABLE 0x00000004U /*!< Complementary output channel is enabled */ +#define TIM_CCxN_DISABLE 0x00000000U /*!< Complementary output channel is enabled */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macros -----------------------------------------------------------*/ +/** @defgroup TIM_Exported_Macros TIM Exported Macros + * @{ + */ + +/** @brief Reset TIM handle state. + * @param __HANDLE__ TIM handle. + * @retval None + */ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_TIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->DMABurstState = HAL_DMA_BURST_STATE_RESET; \ + (__HANDLE__)->Base_MspInitCallback = NULL; \ + (__HANDLE__)->Base_MspDeInitCallback = NULL; \ + (__HANDLE__)->IC_MspInitCallback = NULL; \ + (__HANDLE__)->IC_MspDeInitCallback = NULL; \ + (__HANDLE__)->OC_MspInitCallback = NULL; \ + (__HANDLE__)->OC_MspDeInitCallback = NULL; \ + (__HANDLE__)->PWM_MspInitCallback = NULL; \ + (__HANDLE__)->PWM_MspDeInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspInitCallback = NULL; \ + (__HANDLE__)->OnePulse_MspDeInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspInitCallback = NULL; \ + (__HANDLE__)->Encoder_MspDeInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspInitCallback = NULL; \ + (__HANDLE__)->HallSensor_MspDeInitCallback = NULL; \ + } while(0) +#else +#define __HAL_TIM_RESET_HANDLE_STATE(__HANDLE__) do { \ + (__HANDLE__)->State = HAL_TIM_STATE_RESET; \ + (__HANDLE__)->ChannelState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[0] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[1] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[2] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->ChannelNState[3] = HAL_TIM_CHANNEL_STATE_RESET; \ + (__HANDLE__)->DMABurstState = HAL_DMA_BURST_STATE_RESET; \ + } while(0) +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @brief Enable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1|=(TIM_CR1_CEN)) + +/** + * @brief Enable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_MOE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->BDTR|=(TIM_BDTR_MOE)) + +/** + * @brief Disable the TIM peripheral. + * @param __HANDLE__ TIM handle + * @retval None + */ +#define __HAL_TIM_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->CR1 &= ~(TIM_CR1_CEN); \ + } \ + } \ + } while(0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled only if all the CCx and CCxN channels have been + * disabled + */ +#define __HAL_TIM_MOE_DISABLE(__HANDLE__) \ + do { \ + if (((__HANDLE__)->Instance->CCER & TIM_CCER_CCxE_MASK) == 0UL) \ + { \ + if(((__HANDLE__)->Instance->CCER & TIM_CCER_CCxNE_MASK) == 0UL) \ + { \ + (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE); \ + } \ + } \ + } while(0) + +/** + * @brief Disable the TIM main Output. + * @param __HANDLE__ TIM handle + * @retval None + * @note The Main Output Enable of a timer instance is disabled unconditionally + */ +#define __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(__HANDLE__) (__HANDLE__)->Instance->BDTR &= ~(TIM_BDTR_MOE) + +/** @brief Enable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to enable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER |= (__INTERRUPT__)) + +/** @brief Disable the specified TIM interrupt. + * @param __HANDLE__ specifies the TIM Handle. + * @param __INTERRUPT__ specifies the TIM interrupt source to disable. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DIER &= ~(__INTERRUPT__)) + +/** @brief Enable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to enable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_ENABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER |= (__DMA__)) + +/** @brief Disable the specified DMA request. + * @param __HANDLE__ specifies the TIM Handle. + * @param __DMA__ specifies the TIM DMA request to disable. + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: Update DMA request + * @arg TIM_DMA_CC1: Capture/Compare 1 DMA request + * @arg TIM_DMA_CC2: Capture/Compare 2 DMA request + * @arg TIM_DMA_CC3: Capture/Compare 3 DMA request + * @arg TIM_DMA_CC4: Capture/Compare 4 DMA request + * @arg TIM_DMA_COM: Commutation DMA request + * @arg TIM_DMA_TRIGGER: Trigger DMA request + * @retval None + */ +#define __HAL_TIM_DISABLE_DMA(__HANDLE__, __DMA__) ((__HANDLE__)->Instance->DIER &= ~(__DMA__)) + +/** @brief Check whether the specified TIM interrupt flag is set or not. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to check. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->SR &(__FLAG__)) == (__FLAG__)) + +/** @brief Clear the specified TIM interrupt flag. + * @param __HANDLE__ specifies the TIM Handle. + * @param __FLAG__ specifies the TIM interrupt flag to clear. + * This parameter can be one of the following values: + * @arg TIM_FLAG_UPDATE: Update interrupt flag + * @arg TIM_FLAG_CC1: Capture/Compare 1 interrupt flag + * @arg TIM_FLAG_CC2: Capture/Compare 2 interrupt flag + * @arg TIM_FLAG_CC3: Capture/Compare 3 interrupt flag + * @arg TIM_FLAG_CC4: Capture/Compare 4 interrupt flag + * @arg TIM_FLAG_COM: Commutation interrupt flag + * @arg TIM_FLAG_TRIGGER: Trigger interrupt flag + * @arg TIM_FLAG_BREAK: Break interrupt flag + * @arg TIM_FLAG_CC1OF: Capture/Compare 1 overcapture flag + * @arg TIM_FLAG_CC2OF: Capture/Compare 2 overcapture flag + * @arg TIM_FLAG_CC3OF: Capture/Compare 3 overcapture flag + * @arg TIM_FLAG_CC4OF: Capture/Compare 4 overcapture flag + * @retval The new state of __FLAG__ (TRUE or FALSE). + */ +#define __HAL_TIM_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR = ~(__FLAG__)) + +/** + * @brief Check whether the specified TIM interrupt source is enabled or not. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the TIM interrupt source to check. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval The state of TIM_IT (SET or RESET). + */ +#define __HAL_TIM_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->DIER & (__INTERRUPT__)) \ + == (__INTERRUPT__)) ? SET : RESET) + +/** @brief Clear the TIM interrupt pending bits. + * @param __HANDLE__ TIM handle + * @param __INTERRUPT__ specifies the interrupt pending bit to clear. + * This parameter can be one of the following values: + * @arg TIM_IT_UPDATE: Update interrupt + * @arg TIM_IT_CC1: Capture/Compare 1 interrupt + * @arg TIM_IT_CC2: Capture/Compare 2 interrupt + * @arg TIM_IT_CC3: Capture/Compare 3 interrupt + * @arg TIM_IT_CC4: Capture/Compare 4 interrupt + * @arg TIM_IT_COM: Commutation interrupt + * @arg TIM_IT_TRIGGER: Trigger interrupt + * @arg TIM_IT_BREAK: Break interrupt + * @retval None + */ +#define __HAL_TIM_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->SR = ~(__INTERRUPT__)) + +/** + * @brief Indicates whether or not the TIM Counter is used as downcounter. + * @param __HANDLE__ TIM handle. + * @retval False (Counter used as upcounter) or True (Counter used as downcounter) + * @note This macro is particularly useful to get the counting mode when the timer operates in Center-aligned mode + * or Encoder mode. + */ +#define __HAL_TIM_IS_TIM_COUNTING_DOWN(__HANDLE__) (((__HANDLE__)->Instance->CR1 &(TIM_CR1_DIR)) == (TIM_CR1_DIR)) + +/** + * @brief Set the TIM Prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __PRESC__ specifies the Prescaler new value. + * @retval None + */ +#define __HAL_TIM_SET_PRESCALER(__HANDLE__, __PRESC__) ((__HANDLE__)->Instance->PSC = (__PRESC__)) + +/** + * @brief Set the TIM Counter Register value on runtime. + * @param __HANDLE__ TIM handle. + * @param __COUNTER__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_COUNTER(__HANDLE__, __COUNTER__) ((__HANDLE__)->Instance->CNT = (__COUNTER__)) + +/** + * @brief Get the TIM Counter Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer counter register (TIMx_CNT) + */ +#define __HAL_TIM_GET_COUNTER(__HANDLE__) ((__HANDLE__)->Instance->CNT) + +/** + * @brief Set the TIM Autoreload Register value on runtime without calling another time any Init function. + * @param __HANDLE__ TIM handle. + * @param __AUTORELOAD__ specifies the Counter register new value. + * @retval None + */ +#define __HAL_TIM_SET_AUTORELOAD(__HANDLE__, __AUTORELOAD__) \ + do{ \ + (__HANDLE__)->Instance->ARR = (__AUTORELOAD__); \ + (__HANDLE__)->Init.Period = (__AUTORELOAD__); \ + } while(0) + +/** + * @brief Get the TIM Autoreload Register value on runtime. + * @param __HANDLE__ TIM handle. + * @retval 16-bit or 32-bit value of the timer auto-reload register(TIMx_ARR) + */ +#define __HAL_TIM_GET_AUTORELOAD(__HANDLE__) ((__HANDLE__)->Instance->ARR) + +/** + * @brief Set the TIM Clock Division value on runtime without calling another time any Init function. + * @param __HANDLE__ TIM handle. + * @param __CKD__ specifies the clock division value. + * This parameter can be one of the following value: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + * @retval None + */ +#define __HAL_TIM_SET_CLOCKDIVISION(__HANDLE__, __CKD__) \ + do{ \ + (__HANDLE__)->Instance->CR1 &= (~TIM_CR1_CKD); \ + (__HANDLE__)->Instance->CR1 |= (__CKD__); \ + (__HANDLE__)->Init.ClockDivision = (__CKD__); \ + } while(0) + +/** + * @brief Get the TIM Clock Division value on runtime. + * @param __HANDLE__ TIM handle. + * @retval The clock division can be one of the following values: + * @arg TIM_CLOCKDIVISION_DIV1: tDTS=tCK_INT + * @arg TIM_CLOCKDIVISION_DIV2: tDTS=2*tCK_INT + * @arg TIM_CLOCKDIVISION_DIV4: tDTS=4*tCK_INT + */ +#define __HAL_TIM_GET_CLOCKDIVISION(__HANDLE__) ((__HANDLE__)->Instance->CR1 & TIM_CR1_CKD) + +/** + * @brief Set the TIM Input Capture prescaler on runtime without calling another time HAL_TIM_IC_ConfigChannel() + * function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __ICPSC__ specifies the Input Capture4 prescaler new value. + * This parameter can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + * @retval None + */ +#define __HAL_TIM_SET_ICPRESCALER(__HANDLE__, __CHANNEL__, __ICPSC__) \ + do{ \ + TIM_RESET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_ICPRESCALERVALUE((__HANDLE__), (__CHANNEL__), (__ICPSC__)); \ + } while(0) + +/** + * @brief Get the TIM Input Capture prescaler on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get input capture 1 prescaler value + * @arg TIM_CHANNEL_2: get input capture 2 prescaler value + * @arg TIM_CHANNEL_3: get input capture 3 prescaler value + * @arg TIM_CHANNEL_4: get input capture 4 prescaler value + * @retval The input capture prescaler can be one of the following values: + * @arg TIM_ICPSC_DIV1: no prescaler + * @arg TIM_ICPSC_DIV2: capture is done once every 2 events + * @arg TIM_ICPSC_DIV4: capture is done once every 4 events + * @arg TIM_ICPSC_DIV8: capture is done once every 8 events + */ +#define __HAL_TIM_GET_ICPRESCALER(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (((__HANDLE__)->Instance->CCMR1 & TIM_CCMR1_IC2PSC) >> 8U) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC3PSC) :\ + (((__HANDLE__)->Instance->CCMR2 & TIM_CCMR2_IC4PSC)) >> 8U) + +/** + * @brief Set the TIM Capture Compare Register value on runtime without calling another time ConfigChannel function. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __COMPARE__ specifies the Capture Compare register new value. + * @retval None + */ +#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\ + ((__HANDLE__)->Instance->CCR4 = (__COMPARE__))) + +/** + * @brief Get the TIM Capture Compare Register value on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channel associated with the capture compare register + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: get capture/compare 1 register value + * @arg TIM_CHANNEL_2: get capture/compare 2 register value + * @arg TIM_CHANNEL_3: get capture/compare 3 register value + * @arg TIM_CHANNEL_4: get capture/compare 4 register value + * @retval 16-bit or 32-bit value of the capture/compare register (TIMx_CCRy) + */ +#define __HAL_TIM_GET_COMPARE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3) :\ + ((__HANDLE__)->Instance->CCR4)) + +/** + * @brief Set the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3PE) :\ + ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4PE)) + +/** + * @brief Reset the TIM Output compare preload. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxPRELOAD(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2PE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3PE) :\ + ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4PE)) + +/** + * @brief Enable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @note When fast mode is enabled an active edge on the trigger input acts + * like a compare match on CCx output. Delay to sample the trigger + * input and to activate CCx output is reduced to 3 clock cycles. + * @note Fast mode acts only if the channel is configured in PWM1 or PWM2 mode. + * @retval None + */ +#define __HAL_TIM_ENABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC1FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= TIM_CCMR1_OC2FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC3FE) :\ + ((__HANDLE__)->Instance->CCMR2 |= TIM_CCMR2_OC4FE)) + +/** + * @brief Disable fast mode for a given channel. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @note When fast mode is disabled CCx output behaves normally depending + * on counter and CCRx values even when the trigger is ON. The minimum + * delay to activate CCx output when an active edge occurs on the + * trigger input is 5 clock cycles. + * @retval None + */ +#define __HAL_TIM_DISABLE_OCxFAST(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE) :\ + ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE)) + +/** + * @brief Set the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is set, only counter + * overflow/underflow generates an update interrupt or DMA request (if + * enabled) + * @retval None + */ +#define __HAL_TIM_URS_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1|= TIM_CR1_URS) + +/** + * @brief Reset the Update Request Source (URS) bit of the TIMx_CR1 register. + * @param __HANDLE__ TIM handle. + * @note When the URS bit of the TIMx_CR1 register is reset, any of the + * following events generate an update interrupt or DMA request (if + * enabled): + * _ Counter overflow underflow + * _ Setting the UG bit + * _ Update generation through the slave mode controller + * @retval None + */ +#define __HAL_TIM_URS_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1&=~TIM_CR1_URS) + +/** + * @brief Set the TIM Capture x input polarity on runtime. + * @param __HANDLE__ TIM handle. + * @param __CHANNEL__ TIM Channels to be configured. + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param __POLARITY__ Polarity for TIx source + * @arg TIM_INPUTCHANNELPOLARITY_RISING: Rising Edge + * @arg TIM_INPUTCHANNELPOLARITY_FALLING: Falling Edge + * @arg TIM_INPUTCHANNELPOLARITY_BOTHEDGE: Rising and Falling Edge + * @retval None + */ +#define __HAL_TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + do{ \ + TIM_RESET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__)); \ + TIM_SET_CAPTUREPOLARITY((__HANDLE__), (__CHANNEL__), (__POLARITY__)); \ + }while(0) + +/** @brief Select the Capture/compare DMA request source. + * @param __HANDLE__ specifies the TIM Handle. + * @param __CCDMA__ specifies Capture/compare DMA request source + * This parameter can be one of the following values: + * @arg TIM_CCDMAREQUEST_CC: CCx DMA request generated on Capture/Compare event + * @arg TIM_CCDMAREQUEST_UPDATE: CCx DMA request generated on Update event + * @retval None + */ +#define __HAL_TIM_SELECT_CCDMAREQUEST(__HANDLE__, __CCDMA__) \ + MODIFY_REG((__HANDLE__)->Instance->CR2, TIM_CR2_CCDS, (__CCDMA__)) + +/** + * @} + */ +/* End of exported macros ----------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_Private_Constants TIM Private Constants + * @{ + */ +/* The counter of a timer instance is disabled only if all the CCx and CCxN + channels have been disabled */ +#define TIM_CCER_CCxE_MASK ((uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E)) +#define TIM_CCER_CCxNE_MASK ((uint32_t)(TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) +/** + * @} + */ +/* End of private constants --------------------------------------------------*/ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_Private_Macros TIM Private Macros + * @{ + */ +#define IS_TIM_CLEARINPUT_SOURCE(__MODE__) (((__MODE__) == TIM_CLEARINPUTSOURCE_NONE) || \ + ((__MODE__) == TIM_CLEARINPUTSOURCE_ETR)) + +#define IS_TIM_DMA_BASE(__BASE__) (((__BASE__) == TIM_DMABASE_CR1) || \ + ((__BASE__) == TIM_DMABASE_CR2) || \ + ((__BASE__) == TIM_DMABASE_SMCR) || \ + ((__BASE__) == TIM_DMABASE_DIER) || \ + ((__BASE__) == TIM_DMABASE_SR) || \ + ((__BASE__) == TIM_DMABASE_EGR) || \ + ((__BASE__) == TIM_DMABASE_CCMR1) || \ + ((__BASE__) == TIM_DMABASE_CCMR2) || \ + ((__BASE__) == TIM_DMABASE_CCER) || \ + ((__BASE__) == TIM_DMABASE_CNT) || \ + ((__BASE__) == TIM_DMABASE_PSC) || \ + ((__BASE__) == TIM_DMABASE_ARR) || \ + ((__BASE__) == TIM_DMABASE_RCR) || \ + ((__BASE__) == TIM_DMABASE_CCR1) || \ + ((__BASE__) == TIM_DMABASE_CCR2) || \ + ((__BASE__) == TIM_DMABASE_CCR3) || \ + ((__BASE__) == TIM_DMABASE_CCR4) || \ + ((__BASE__) == TIM_DMABASE_BDTR)) + +#define IS_TIM_EVENT_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFFFF00U) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_COUNTER_MODE(__MODE__) (((__MODE__) == TIM_COUNTERMODE_UP) || \ + ((__MODE__) == TIM_COUNTERMODE_DOWN) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED1) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED2) || \ + ((__MODE__) == TIM_COUNTERMODE_CENTERALIGNED3)) + +#define IS_TIM_CLOCKDIVISION_DIV(__DIV__) (((__DIV__) == TIM_CLOCKDIVISION_DIV1) || \ + ((__DIV__) == TIM_CLOCKDIVISION_DIV2) || \ + ((__DIV__) == TIM_CLOCKDIVISION_DIV4)) + +#define IS_TIM_AUTORELOAD_PRELOAD(PRELOAD) (((PRELOAD) == TIM_AUTORELOAD_PRELOAD_DISABLE) || \ + ((PRELOAD) == TIM_AUTORELOAD_PRELOAD_ENABLE)) + +#define IS_TIM_FAST_STATE(__STATE__) (((__STATE__) == TIM_OCFAST_DISABLE) || \ + ((__STATE__) == TIM_OCFAST_ENABLE)) + +#define IS_TIM_OC_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_OCPOLARITY_HIGH) || \ + ((__POLARITY__) == TIM_OCPOLARITY_LOW)) + +#define IS_TIM_OCN_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_OCNPOLARITY_HIGH) || \ + ((__POLARITY__) == TIM_OCNPOLARITY_LOW)) + +#define IS_TIM_OCIDLE_STATE(__STATE__) (((__STATE__) == TIM_OCIDLESTATE_SET) || \ + ((__STATE__) == TIM_OCIDLESTATE_RESET)) + +#define IS_TIM_OCNIDLE_STATE(__STATE__) (((__STATE__) == TIM_OCNIDLESTATE_SET) || \ + ((__STATE__) == TIM_OCNIDLESTATE_RESET)) + +#define IS_TIM_ENCODERINPUT_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ENCODERINPUTPOLARITY_FALLING)) + +#define IS_TIM_IC_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_ICPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_ICPOLARITY_BOTHEDGE)) + +#define IS_TIM_IC_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_ICSELECTION_DIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_INDIRECTTI) || \ + ((__SELECTION__) == TIM_ICSELECTION_TRC)) + +#define IS_TIM_IC_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_ICPSC_DIV1) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV2) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV4) || \ + ((__PRESCALER__) == TIM_ICPSC_DIV8)) + +#define IS_TIM_OPM_MODE(__MODE__) (((__MODE__) == TIM_OPMODE_SINGLE) || \ + ((__MODE__) == TIM_OPMODE_REPETITIVE)) + +#define IS_TIM_ENCODER_MODE(__MODE__) (((__MODE__) == TIM_ENCODERMODE_TI1) || \ + ((__MODE__) == TIM_ENCODERMODE_TI2) || \ + ((__MODE__) == TIM_ENCODERMODE_TI12)) + +#define IS_TIM_DMA_SOURCE(__SOURCE__) ((((__SOURCE__) & 0xFFFF80FFU) == 0x00000000U) && ((__SOURCE__) != 0x00000000U)) + +#define IS_TIM_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3) || \ + ((__CHANNEL__) == TIM_CHANNEL_4) || \ + ((__CHANNEL__) == TIM_CHANNEL_ALL)) + +#define IS_TIM_OPM_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2)) + +#define IS_TIM_PERIOD(__PERIOD__) (((__PERIOD__) > 0U) && ((__PERIOD__) <= 0xFFFFU)) + +#define IS_TIM_COMPLEMENTARY_CHANNELS(__CHANNEL__) (((__CHANNEL__) == TIM_CHANNEL_1) || \ + ((__CHANNEL__) == TIM_CHANNEL_2) || \ + ((__CHANNEL__) == TIM_CHANNEL_3)) + +#define IS_TIM_CLOCKSOURCE(__CLOCK__) (((__CLOCK__) == TIM_CLOCKSOURCE_INTERNAL) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ETRMODE2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1ED) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_TI2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR0) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR1) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR2) || \ + ((__CLOCK__) == TIM_CLOCKSOURCE_ITR3)) + +#define IS_TIM_CLOCKPOLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLOCKPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_RISING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_FALLING) || \ + ((__POLARITY__) == TIM_CLOCKPOLARITY_BOTHEDGE)) + +#define IS_TIM_CLOCKPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLOCKPRESCALER_DIV8)) + +#define IS_TIM_CLOCKFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_CLEARINPUT_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_CLEARINPUTPOLARITY_INVERTED) || \ + ((__POLARITY__) == TIM_CLEARINPUTPOLARITY_NONINVERTED)) + +#define IS_TIM_CLEARINPUT_PRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_CLEARINPUTPRESCALER_DIV8)) + +#define IS_TIM_CLEARINPUT_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_OSSR_STATE(__STATE__) (((__STATE__) == TIM_OSSR_ENABLE) || \ + ((__STATE__) == TIM_OSSR_DISABLE)) + +#define IS_TIM_OSSI_STATE(__STATE__) (((__STATE__) == TIM_OSSI_ENABLE) || \ + ((__STATE__) == TIM_OSSI_DISABLE)) + +#define IS_TIM_LOCK_LEVEL(__LEVEL__) (((__LEVEL__) == TIM_LOCKLEVEL_OFF) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_1) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_2) || \ + ((__LEVEL__) == TIM_LOCKLEVEL_3)) + +#define IS_TIM_BREAK_FILTER(__BRKFILTER__) ((__BRKFILTER__) <= 0xFUL) + +#define IS_TIM_BREAK_STATE(__STATE__) (((__STATE__) == TIM_BREAK_ENABLE) || \ + ((__STATE__) == TIM_BREAK_DISABLE)) + +#define IS_TIM_BREAK_POLARITY(__POLARITY__) (((__POLARITY__) == TIM_BREAKPOLARITY_LOW) || \ + ((__POLARITY__) == TIM_BREAKPOLARITY_HIGH)) + +#define IS_TIM_AUTOMATIC_OUTPUT_STATE(__STATE__) (((__STATE__) == TIM_AUTOMATICOUTPUT_ENABLE) || \ + ((__STATE__) == TIM_AUTOMATICOUTPUT_DISABLE)) + +#define IS_TIM_TRGO_SOURCE(__SOURCE__) (((__SOURCE__) == TIM_TRGO_RESET) || \ + ((__SOURCE__) == TIM_TRGO_ENABLE) || \ + ((__SOURCE__) == TIM_TRGO_UPDATE) || \ + ((__SOURCE__) == TIM_TRGO_OC1) || \ + ((__SOURCE__) == TIM_TRGO_OC1REF) || \ + ((__SOURCE__) == TIM_TRGO_OC2REF) || \ + ((__SOURCE__) == TIM_TRGO_OC3REF) || \ + ((__SOURCE__) == TIM_TRGO_OC4REF)) + +#define IS_TIM_MSM_STATE(__STATE__) (((__STATE__) == TIM_MASTERSLAVEMODE_ENABLE) || \ + ((__STATE__) == TIM_MASTERSLAVEMODE_DISABLE)) + +#define IS_TIM_SLAVE_MODE(__MODE__) (((__MODE__) == TIM_SLAVEMODE_DISABLE) || \ + ((__MODE__) == TIM_SLAVEMODE_RESET) || \ + ((__MODE__) == TIM_SLAVEMODE_GATED) || \ + ((__MODE__) == TIM_SLAVEMODE_TRIGGER) || \ + ((__MODE__) == TIM_SLAVEMODE_EXTERNAL1)) + +#define IS_TIM_PWM_MODE(__MODE__) (((__MODE__) == TIM_OCMODE_PWM1) || \ + ((__MODE__) == TIM_OCMODE_PWM2)) + +#define IS_TIM_OC_MODE(__MODE__) (((__MODE__) == TIM_OCMODE_TIMING) || \ + ((__MODE__) == TIM_OCMODE_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_INACTIVE) || \ + ((__MODE__) == TIM_OCMODE_TOGGLE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_ACTIVE) || \ + ((__MODE__) == TIM_OCMODE_FORCED_INACTIVE)) + +#define IS_TIM_TRIGGER_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_TI1F_ED) || \ + ((__SELECTION__) == TIM_TS_TI1FP1) || \ + ((__SELECTION__) == TIM_TS_TI2FP2) || \ + ((__SELECTION__) == TIM_TS_ETRF)) + +#define IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(__SELECTION__) (((__SELECTION__) == TIM_TS_ITR0) || \ + ((__SELECTION__) == TIM_TS_ITR1) || \ + ((__SELECTION__) == TIM_TS_ITR2) || \ + ((__SELECTION__) == TIM_TS_ITR3) || \ + ((__SELECTION__) == TIM_TS_NONE)) + +#define IS_TIM_TRIGGERPOLARITY(__POLARITY__) (((__POLARITY__) == TIM_TRIGGERPOLARITY_INVERTED ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_NONINVERTED) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_RISING ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_FALLING ) || \ + ((__POLARITY__) == TIM_TRIGGERPOLARITY_BOTHEDGE )) + +#define IS_TIM_TRIGGERPRESCALER(__PRESCALER__) (((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV1) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV2) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV4) || \ + ((__PRESCALER__) == TIM_TRIGGERPRESCALER_DIV8)) + +#define IS_TIM_TRIGGERFILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_TI1SELECTION(__TI1SELECTION__) (((__TI1SELECTION__) == TIM_TI1SELECTION_CH1) || \ + ((__TI1SELECTION__) == TIM_TI1SELECTION_XORCOMBINATION)) + +#define IS_TIM_DMA_LENGTH(__LENGTH__) (((__LENGTH__) == TIM_DMABURSTLENGTH_1TRANSFER) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_2TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_3TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_4TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_5TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_6TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_7TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_8TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_9TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_10TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_11TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_12TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_13TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_14TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_15TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_16TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_17TRANSFERS) || \ + ((__LENGTH__) == TIM_DMABURSTLENGTH_18TRANSFERS)) + +#define IS_TIM_DMA_DATA_LENGTH(LENGTH) (((LENGTH) >= 0x1U) && ((LENGTH) < 0x10000U)) + +#define IS_TIM_IC_FILTER(__ICFILTER__) ((__ICFILTER__) <= 0xFU) + +#define IS_TIM_DEADTIME(__DEADTIME__) ((__DEADTIME__) <= 0xFFU) + +#define IS_TIM_SLAVEMODE_TRIGGER_ENABLED(__TRIGGER__) ((__TRIGGER__) == TIM_SLAVEMODE_TRIGGER) + +#define TIM_SET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__, __ICPSC__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 |= (__ICPSC__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 |= ((__ICPSC__) << 8U)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 |= (__ICPSC__)) :\ + ((__HANDLE__)->Instance->CCMR2 |= ((__ICPSC__) << 8U))) + +#define TIM_RESET_ICPRESCALERVALUE(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC) :\ + ((__HANDLE__)->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC)) + +#define TIM_SET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__, __POLARITY__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER |= (__POLARITY__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 4U)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER |= ((__POLARITY__) << 8U)) :\ + ((__HANDLE__)->Instance->CCER |= (((__POLARITY__) << 12U)))) + +#define TIM_RESET_CAPTUREPOLARITY(__HANDLE__, __CHANNEL__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC3P)) :\ + ((__HANDLE__)->Instance->CCER &= ~(TIM_CCER_CC4P))) + +#define TIM_CHANNEL_STATE_GET(__HANDLE__, __CHANNEL__)\ + (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelState[0] :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelState[1] :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelState[2] :\ + (__HANDLE__)->ChannelState[3]) + +#define TIM_CHANNEL_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->ChannelState[0] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->ChannelState[1] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->ChannelState[2] = (__CHANNEL_STATE__)) :\ + ((__HANDLE__)->ChannelState[3] = (__CHANNEL_STATE__))) + +#define TIM_CHANNEL_STATE_SET_ALL(__HANDLE__, __CHANNEL_STATE__) do { \ + (__HANDLE__)->ChannelState[0] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[1] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[2] = (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelState[3] = (__CHANNEL_STATE__); \ + } while(0) + +#define TIM_CHANNEL_N_STATE_GET(__HANDLE__, __CHANNEL__)\ + (((__CHANNEL__) == TIM_CHANNEL_1) ? (__HANDLE__)->ChannelNState[0] :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? (__HANDLE__)->ChannelNState[1] :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? (__HANDLE__)->ChannelNState[2] :\ + (__HANDLE__)->ChannelNState[3]) + +#define TIM_CHANNEL_N_STATE_SET(__HANDLE__, __CHANNEL__, __CHANNEL_STATE__) \ + (((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->ChannelNState[0] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->ChannelNState[1] = (__CHANNEL_STATE__)) :\ + ((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->ChannelNState[2] = (__CHANNEL_STATE__)) :\ + ((__HANDLE__)->ChannelNState[3] = (__CHANNEL_STATE__))) + +#define TIM_CHANNEL_N_STATE_SET_ALL(__HANDLE__, __CHANNEL_STATE__) do { \ + (__HANDLE__)->ChannelNState[0] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[1] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[2] = \ + (__CHANNEL_STATE__); \ + (__HANDLE__)->ChannelNState[3] = \ + (__CHANNEL_STATE__); \ + } while(0) + +/** + * @} + */ +/* End of private macros -----------------------------------------------------*/ + +/* Include TIM HAL Extended module */ +#include "stm32f1xx_hal_tim_ex.h" + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @addtogroup TIM_Exported_Functions_Group1 TIM Time Base functions + * @brief Time Base functions + * @{ + */ +/* Time Base functions ********************************************************/ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, const uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group2 TIM Output Compare functions + * @brief TIM Output Compare functions + * @{ + */ +/* Timer Output Compare functions *********************************************/ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group3 TIM PWM functions + * @brief TIM PWM functions + * @{ + */ +/* Timer PWM functions ********************************************************/ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group4 TIM Input Capture functions + * @brief TIM Input Capture functions + * @{ + */ +/* Timer Input Capture functions **********************************************/ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group5 TIM One Pulse functions + * @brief TIM One Pulse functions + * @{ + */ +/* Timer One Pulse functions **************************************************/ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode); +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group6 TIM Encoder functions + * @brief TIM Encoder functions + * @{ + */ +/* Timer Encoder functions ****************************************************/ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, const TIM_Encoder_InitTypeDef *sConfig); +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim); +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, + uint32_t *pData2, uint16_t Length); +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief IRQ handler management + * @{ + */ +/* Interrupt Handler functions ***********************************************/ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ +/* Control functions *********************************************************/ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_IC_InitTypeDef *sConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig, + uint32_t OutputChannel, uint32_t InputChannel); +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, + const TIM_ClearInputConfigTypeDef *sClearInputConfig, + uint32_t Channel); +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, const TIM_ClockConfigTypeDef *sClockSourceConfig); +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, + uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength); +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc); +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource); +uint32_t HAL_TIM_ReadCapturedValue(const TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * @{ + */ +/* Callback in non blocking modes (Interrupt and DMA) *************************/ +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim); + +/* Callbacks Register/UnRegister functions ***********************************/ +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID, + pTIM_CallbackTypeDef pCallback); +HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions + * @brief Peripheral State functions + * @{ + */ +/* Peripheral State functions ************************************************/ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(const TIM_HandleTypeDef *htim); + +/* Peripheral Channel state functions ************************************************/ +HAL_TIM_ActiveChannel HAL_TIM_GetActiveChannel(const TIM_HandleTypeDef *htim); +HAL_TIM_ChannelStateTypeDef HAL_TIM_GetChannelState(const TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_TIM_DMABurstStateTypeDef HAL_TIM_DMABurstState(const TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** + * @} + */ +/* End of exported functions -------------------------------------------------*/ + +/* Private functions----------------------------------------------------------*/ +/** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, const TIM_Base_InitTypeDef *Structure); +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, uint32_t TIM_ICFilter); +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter); + +void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma); +void TIM_DMAError(DMA_HandleTypeDef *hdma); +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma); +void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma); +void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +void TIM_ResetCallback(TIM_HandleTypeDef *htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ +/* End of private functions --------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32F1xx_HAL_TIM_H */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h new file mode 100644 index 0000000..3edc9d3 --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_tim_ex.h @@ -0,0 +1,261 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_tim_ex.h + * @author MCD Application Team + * @brief Header file of TIM HAL Extended module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32F1xx_HAL_TIM_EX_H +#define STM32F1xx_HAL_TIM_EX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal_def.h" + +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @addtogroup TIMEx + * @{ + */ + +/* Exported types ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Types TIM Extended Exported Types + * @{ + */ + +/** + * @brief TIM Hall sensor Configuration Structure definition + */ + +typedef struct +{ + uint32_t IC1Polarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_Input_Capture_Polarity */ + + uint32_t IC1Prescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_Input_Capture_Prescaler */ + + uint32_t IC1Filter; /*!< Specifies the input capture filter. + This parameter can be a number between Min_Data = 0x0 and Max_Data = 0xF */ + + uint32_t Commutation_Delay; /*!< Specifies the pulse value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */ +} TIM_HallSensor_InitTypeDef; +/** + * @} + */ +/* End of exported types -----------------------------------------------------*/ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Constants TIM Extended Exported Constants + * @{ + */ + +/** @defgroup TIMEx_Remap TIM Extended Remapping + * @{ + */ +/** + * @} + */ + +/** + * @} + */ +/* End of exported constants -------------------------------------------------*/ + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Macros TIM Extended Exported Macros + * @{ + */ + +/** + * @} + */ +/* End of exported macro -----------------------------------------------------*/ + +/* Private macro -------------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Macros TIM Extended Private Macros + * @{ + */ + +/** + * @} + */ +/* End of private macro ------------------------------------------------------*/ + +/* Exported functions --------------------------------------------------------*/ +/** @addtogroup TIMEx_Exported_Functions TIM Extended Exported Functions + * @{ + */ + +/** @addtogroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * @{ + */ +/* Timer Hall Sensor functions **********************************************/ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim); + +void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim); +void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim); + +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions + * @brief Timer Complementary Output Compare functions + * @{ + */ +/* Timer Complementary Output Compare functions *****************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions + * @brief Timer Complementary PWM functions + * @{ + */ +/* Timer Complementary PWM functions ****************************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel); +/* Non-Blocking mode: DMA */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length); +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions + * @brief Timer Complementary One Pulse functions + * @{ + */ +/* Timer Complementary One Pulse functions **********************************/ +/* Blocking mode: Polling */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel); + +/* Non-Blocking mode: Interrupt */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions + * @brief Peripheral Control functions + * @{ + */ +/* Extended Control functions ************************************************/ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource); +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, + const TIM_MasterConfigTypeDef *sMasterConfig); +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, + const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig); +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions + * @brief Extended Callbacks functions + * @{ + */ +/* Extended Callback **********************************************************/ +void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim); +void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim); +/** + * @} + */ + +/** @addtogroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions + * @brief Extended Peripheral State functions + * @{ + */ +/* Extended Peripheral State functions ***************************************/ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim); +HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim, uint32_t ChannelN); +/** + * @} + */ + +/** + * @} + */ +/* End of exported functions -------------------------------------------------*/ + +/* Private functions----------------------------------------------------------*/ +/** @addtogroup TIMEx_Private_Functions TIM Extended Private Functions + * @{ + */ +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma); +void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma); +/** + * @} + */ +/* End of private functions --------------------------------------------------*/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif /* STM32F1xx_HAL_TIM_EX_H */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_adc.h b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_adc.h new file mode 100644 index 0000000..a3a3592 --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_adc.h @@ -0,0 +1,3929 @@ +/** + ****************************************************************************** + * @file stm32f1xx_ll_adc.h + * @author MCD Application Team + * @brief Header file of ADC LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F1xx_LL_ADC_H +#define __STM32F1xx_LL_ADC_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx.h" + +/** @addtogroup STM32F1xx_LL_Driver + * @{ + */ + +#if defined (ADC1) || defined (ADC2) || defined (ADC3) + +/** @defgroup ADC_LL ADC + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup ADC_LL_Private_Constants ADC Private Constants + * @{ + */ + +/* Internal mask for ADC group regular sequencer: */ +/* To select into literal LL_ADC_REG_RANK_x the relevant bits for: */ +/* - sequencer register offset */ +/* - sequencer rank bits position into the selected register */ + +/* Internal register offset for ADC group regular sequencer configuration */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_SQR1_REGOFFSET 0x00000000U +#define ADC_SQR2_REGOFFSET 0x00000100U +#define ADC_SQR3_REGOFFSET 0x00000200U +#define ADC_SQR4_REGOFFSET 0x00000300U + +#define ADC_REG_SQRX_REGOFFSET_MASK (ADC_SQR1_REGOFFSET | ADC_SQR2_REGOFFSET | ADC_SQR3_REGOFFSET | ADC_SQR4_REGOFFSET) +#define ADC_REG_RANK_ID_SQRX_MASK (ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0) + +/* Definition of ADC group regular sequencer bits information to be inserted */ +/* into ADC group regular sequencer ranks literals definition. */ +#define ADC_REG_RANK_1_SQRX_BITOFFSET_POS ( 0U) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ1) */ +#define ADC_REG_RANK_2_SQRX_BITOFFSET_POS ( 5U) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ2) */ +#define ADC_REG_RANK_3_SQRX_BITOFFSET_POS (10U) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ3) */ +#define ADC_REG_RANK_4_SQRX_BITOFFSET_POS (15U) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ4) */ +#define ADC_REG_RANK_5_SQRX_BITOFFSET_POS (20U) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ5) */ +#define ADC_REG_RANK_6_SQRX_BITOFFSET_POS (25U) /* Value equivalent to POSITION_VAL(ADC_SQR3_SQ6) */ +#define ADC_REG_RANK_7_SQRX_BITOFFSET_POS ( 0U) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ7) */ +#define ADC_REG_RANK_8_SQRX_BITOFFSET_POS ( 5U) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ8) */ +#define ADC_REG_RANK_9_SQRX_BITOFFSET_POS (10U) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ9) */ +#define ADC_REG_RANK_10_SQRX_BITOFFSET_POS (15U) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ10) */ +#define ADC_REG_RANK_11_SQRX_BITOFFSET_POS (20U) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ11) */ +#define ADC_REG_RANK_12_SQRX_BITOFFSET_POS (25U) /* Value equivalent to POSITION_VAL(ADC_SQR2_SQ12) */ +#define ADC_REG_RANK_13_SQRX_BITOFFSET_POS ( 0U) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ13) */ +#define ADC_REG_RANK_14_SQRX_BITOFFSET_POS ( 5U) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ14) */ +#define ADC_REG_RANK_15_SQRX_BITOFFSET_POS (10U) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ15) */ +#define ADC_REG_RANK_16_SQRX_BITOFFSET_POS (15U) /* Value equivalent to POSITION_VAL(ADC_SQR1_SQ16) */ + +/* Internal mask for ADC group injected sequencer: */ +/* To select into literal LL_ADC_INJ_RANK_x the relevant bits for: */ +/* - data register offset */ +/* - offset register offset */ +/* - sequencer rank bits position into the selected register */ + +/* Internal register offset for ADC group injected data register */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_JDR1_REGOFFSET 0x00000000U +#define ADC_JDR2_REGOFFSET 0x00000100U +#define ADC_JDR3_REGOFFSET 0x00000200U +#define ADC_JDR4_REGOFFSET 0x00000300U + +/* Internal register offset for ADC group injected offset configuration */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_JOFR1_REGOFFSET 0x00000000U +#define ADC_JOFR2_REGOFFSET 0x00001000U +#define ADC_JOFR3_REGOFFSET 0x00002000U +#define ADC_JOFR4_REGOFFSET 0x00003000U + +#define ADC_INJ_JDRX_REGOFFSET_MASK (ADC_JDR1_REGOFFSET | ADC_JDR2_REGOFFSET | ADC_JDR3_REGOFFSET | ADC_JDR4_REGOFFSET) +#define ADC_INJ_JOFRX_REGOFFSET_MASK (ADC_JOFR1_REGOFFSET | ADC_JOFR2_REGOFFSET | ADC_JOFR3_REGOFFSET | ADC_JOFR4_REGOFFSET) +#define ADC_INJ_RANK_ID_JSQR_MASK (ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0) + +/* Internal mask for ADC channel: */ +/* To select into literal LL_ADC_CHANNEL_x the relevant bits for: */ +/* - channel identifier defined by number */ +/* - channel differentiation between external channels (connected to */ +/* GPIO pins) and internal channels (connected to internal paths) */ +/* - channel sampling time defined by SMPRx register offset */ +/* and SMPx bits positions into SMPRx register */ +#define ADC_CHANNEL_ID_NUMBER_MASK (ADC_CR1_AWDCH) +#define ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS ( 0U)/* Value equivalent to POSITION_VAL(ADC_CHANNEL_ID_NUMBER_MASK) */ +#define ADC_CHANNEL_ID_MASK (ADC_CHANNEL_ID_NUMBER_MASK | ADC_CHANNEL_ID_INTERNAL_CH_MASK) +/* Equivalent mask of ADC_CHANNEL_NUMBER_MASK aligned on register LSB (bit 0) */ +#define ADC_CHANNEL_ID_NUMBER_MASK_POSBIT0 0x0000001FU /* Equivalent to shift: (ADC_CHANNEL_NUMBER_MASK >> POSITION_VAL(ADC_CHANNEL_NUMBER_MASK)) */ + +/* Channel differentiation between external and internal channels */ +#define ADC_CHANNEL_ID_INTERNAL_CH 0x80000000U /* Marker of internal channel */ +#define ADC_CHANNEL_ID_INTERNAL_CH_2 0x40000000U /* Marker of internal channel for other ADC instances, in case of different ADC internal channels mapped on same channel number on different ADC instances */ +#define ADC_CHANNEL_ID_INTERNAL_CH_MASK (ADC_CHANNEL_ID_INTERNAL_CH | ADC_CHANNEL_ID_INTERNAL_CH_2) + +/* Internal register offset for ADC channel sampling time configuration */ +/* (offset placed into a spare area of literal definition) */ +#define ADC_SMPR1_REGOFFSET 0x00000000U +#define ADC_SMPR2_REGOFFSET 0x02000000U +#define ADC_CHANNEL_SMPRX_REGOFFSET_MASK (ADC_SMPR1_REGOFFSET | ADC_SMPR2_REGOFFSET) + +#define ADC_CHANNEL_SMPx_BITOFFSET_MASK 0x01F00000U +#define ADC_CHANNEL_SMPx_BITOFFSET_POS (20U) /* Value equivalent to POSITION_VAL(ADC_CHANNEL_SMPx_BITOFFSET_MASK) */ + +/* Definition of channels ID number information to be inserted into */ +/* channels literals definition. */ +#define ADC_CHANNEL_0_NUMBER 0x00000000U +#define ADC_CHANNEL_1_NUMBER ( ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_2_NUMBER ( ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_3_NUMBER ( ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_4_NUMBER ( ADC_CR1_AWDCH_2 ) +#define ADC_CHANNEL_5_NUMBER ( ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_6_NUMBER ( ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_7_NUMBER ( ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_8_NUMBER ( ADC_CR1_AWDCH_3 ) +#define ADC_CHANNEL_9_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_10_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_11_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_12_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 ) +#define ADC_CHANNEL_13_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_14_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 ) +#define ADC_CHANNEL_15_NUMBER ( ADC_CR1_AWDCH_3 | ADC_CR1_AWDCH_2 | ADC_CR1_AWDCH_1 | ADC_CR1_AWDCH_0) +#define ADC_CHANNEL_16_NUMBER (ADC_CR1_AWDCH_4 ) +#define ADC_CHANNEL_17_NUMBER (ADC_CR1_AWDCH_4 | ADC_CR1_AWDCH_0) + +/* Definition of channels sampling time information to be inserted into */ +/* channels literals definition. */ +#define ADC_CHANNEL_0_SMP (ADC_SMPR2_REGOFFSET | (( 0U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP0) */ +#define ADC_CHANNEL_1_SMP (ADC_SMPR2_REGOFFSET | (( 3U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP1) */ +#define ADC_CHANNEL_2_SMP (ADC_SMPR2_REGOFFSET | (( 6U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP2) */ +#define ADC_CHANNEL_3_SMP (ADC_SMPR2_REGOFFSET | (( 9U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP3) */ +#define ADC_CHANNEL_4_SMP (ADC_SMPR2_REGOFFSET | ((12U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP4) */ +#define ADC_CHANNEL_5_SMP (ADC_SMPR2_REGOFFSET | ((15U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP5) */ +#define ADC_CHANNEL_6_SMP (ADC_SMPR2_REGOFFSET | ((18U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP6) */ +#define ADC_CHANNEL_7_SMP (ADC_SMPR2_REGOFFSET | ((21U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP7) */ +#define ADC_CHANNEL_8_SMP (ADC_SMPR2_REGOFFSET | ((24U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP8) */ +#define ADC_CHANNEL_9_SMP (ADC_SMPR2_REGOFFSET | ((27U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR2_SMP9) */ +#define ADC_CHANNEL_10_SMP (ADC_SMPR1_REGOFFSET | (( 0U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP10) */ +#define ADC_CHANNEL_11_SMP (ADC_SMPR1_REGOFFSET | (( 3U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP11) */ +#define ADC_CHANNEL_12_SMP (ADC_SMPR1_REGOFFSET | (( 6U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP12) */ +#define ADC_CHANNEL_13_SMP (ADC_SMPR1_REGOFFSET | (( 9U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP13) */ +#define ADC_CHANNEL_14_SMP (ADC_SMPR1_REGOFFSET | ((12U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP14) */ +#define ADC_CHANNEL_15_SMP (ADC_SMPR1_REGOFFSET | ((15U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP15) */ +#define ADC_CHANNEL_16_SMP (ADC_SMPR1_REGOFFSET | ((18U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP16) */ +#define ADC_CHANNEL_17_SMP (ADC_SMPR1_REGOFFSET | ((21U) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) /* Value shifted is equivalent to POSITION_VAL(ADC_SMPR1_SMP17) */ + +/* Internal mask for ADC analog watchdog: */ +/* To select into literals LL_ADC_AWD_CHANNELx_xxx the relevant bits for: */ +/* (concatenation of multiple bits used in different analog watchdogs, */ +/* (feature of several watchdogs not available on all STM32 families)). */ +/* - analog watchdog 1: monitored channel defined by number, */ +/* selection of ADC group (ADC groups regular and-or injected). */ + +/* Internal register offset for ADC analog watchdog channel configuration */ +#define ADC_AWD_CR1_REGOFFSET 0x00000000U + +#define ADC_AWD_CRX_REGOFFSET_MASK (ADC_AWD_CR1_REGOFFSET) + +#define ADC_AWD_CR1_CHANNEL_MASK (ADC_CR1_AWDCH | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) +#define ADC_AWD_CR_ALL_CHANNEL_MASK (ADC_AWD_CR1_CHANNEL_MASK) + +/* Internal register offset for ADC analog watchdog threshold configuration */ +#define ADC_AWD_TR1_HIGH_REGOFFSET 0x00000000U +#define ADC_AWD_TR1_LOW_REGOFFSET 0x00000001U +#define ADC_AWD_TRX_REGOFFSET_MASK (ADC_AWD_TR1_HIGH_REGOFFSET | ADC_AWD_TR1_LOW_REGOFFSET) + +/* ADC registers bits positions */ +#define ADC_CR1_DUALMOD_BITOFFSET_POS (16U) /* Value equivalent to POSITION_VAL(ADC_CR1_DUALMOD) */ + +/** + * @} + */ + + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup ADC_LL_Private_Macros ADC Private Macros + * @{ + */ + +/** + * @brief Driver macro reserved for internal use: isolate bits with the + * selected mask and shift them to the register LSB + * (shift mask on register position bit 0). + * @param __BITS__ Bits in register 32 bits + * @param __MASK__ Mask in register 32 bits + * @retval Bits in register 32 bits + */ +#define __ADC_MASK_SHIFT(__BITS__, __MASK__) \ + (((__BITS__) & (__MASK__)) >> POSITION_VAL((__MASK__))) + +/** + * @brief Driver macro reserved for internal use: set a pointer to + * a register from a register basis from which an offset + * is applied. + * @param __REG__ Register basis from which the offset is applied. + * @param __REG_OFFFSET__ Offset to be applied (unit: number of registers). + * @retval Pointer to register address + */ +#define __ADC_PTR_REG_OFFSET(__REG__, __REG_OFFFSET__) \ + ((__IO uint32_t *)((uint32_t) ((uint32_t)(&(__REG__)) + ((__REG_OFFFSET__) << 2U)))) + +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup ADC_LL_ES_INIT ADC Exported Init structure + * @{ + */ + +/** + * @brief Structure definition of some features of ADC common parameters + * and multimode + * (all ADC instances belonging to the same ADC common instance). + * @note The setting of these parameters by function @ref LL_ADC_CommonInit() + * is conditioned to ADC instances state (all ADC instances + * sharing the same ADC common instance): + * All ADC instances sharing the same ADC common instance must be + * disabled. + */ +typedef struct +{ + uint32_t Multimode; /*!< Set ADC multimode configuration to operate in independent mode or multimode (for devices with several ADC instances). + This parameter can be a value of @ref ADC_LL_EC_MULTI_MODE + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetMultimode(). */ +} LL_ADC_CommonInitTypeDef; +/** + * @brief Structure definition of some features of ADC instance. + * @note These parameters have an impact on ADC scope: ADC instance. + * Affects both group regular and group injected (availability + * of ADC group injected depends on STM32 families). + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Instance . + * @note The setting of these parameters by function @ref LL_ADC_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ +typedef struct +{ + uint32_t DataAlignment; /*!< Set ADC conversion data alignment. + This parameter can be a value of @ref ADC_LL_EC_DATA_ALIGN + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetDataAlignment(). */ + + uint32_t SequencersScanMode; /*!< Set ADC scan selection. + This parameter can be a value of @ref ADC_LL_EC_SCAN_SELECTION + + This feature can be modified afterwards using unitary function @ref LL_ADC_SetSequencersScanMode(). */ + +} LL_ADC_InitTypeDef; + +/** + * @brief Structure definition of some features of ADC group regular. + * @note These parameters have an impact on ADC scope: ADC group regular. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Group_Regular + * (functions with prefix "REG"). + * @note The setting of these parameters by function @ref LL_ADC_REG_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ +typedef struct +{ + uint32_t TriggerSource; /*!< Set ADC group regular conversion trigger source: internal (SW start) or from external IP (timer event, external interrupt line). + This parameter can be a value of @ref ADC_LL_EC_REG_TRIGGER_SOURCE + @note On this STM32 series, external trigger is set with trigger polarity: rising edge + (only trigger polarity available on this STM32 series). + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetTriggerSource(). */ + + uint32_t SequencerLength; /*!< Set ADC group regular sequencer length. + This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_SCAN_LENGTH + @note This parameter is discarded if scan mode is disabled (refer to parameter 'ADC_SequencersScanMode'). + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetSequencerLength(). */ + + uint32_t SequencerDiscont; /*!< Set ADC group regular sequencer discontinuous mode: sequence subdivided and scan conversions interrupted every selected number of ranks. + This parameter can be a value of @ref ADC_LL_EC_REG_SEQ_DISCONT_MODE + @note This parameter has an effect only if group regular sequencer is enabled + (scan length of 2 ranks or more). + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetSequencerDiscont(). */ + + uint32_t ContinuousMode; /*!< Set ADC continuous conversion mode on ADC group regular, whether ADC conversions are performed in single mode (one conversion per trigger) or in continuous mode (after the first trigger, following conversions launched successively automatically). + This parameter can be a value of @ref ADC_LL_EC_REG_CONTINUOUS_MODE + Note: It is not possible to enable both ADC group regular continuous mode and discontinuous mode. + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetContinuousMode(). */ + + uint32_t DMATransfer; /*!< Set ADC group regular conversion data transfer: no transfer or transfer by DMA, and DMA requests mode. + This parameter can be a value of @ref ADC_LL_EC_REG_DMA_TRANSFER + + This feature can be modified afterwards using unitary function @ref LL_ADC_REG_SetDMATransfer(). */ + +} LL_ADC_REG_InitTypeDef; + +/** + * @brief Structure definition of some features of ADC group injected. + * @note These parameters have an impact on ADC scope: ADC group injected. + * Refer to corresponding unitary functions into + * @ref ADC_LL_EF_Configuration_ADC_Group_Regular + * (functions with prefix "INJ"). + * @note The setting of these parameters by function @ref LL_ADC_INJ_Init() + * is conditioned to ADC state: + * ADC instance must be disabled. + * This condition is applied to all ADC features, for efficiency + * and compatibility over all STM32 families. However, the different + * features can be set under different ADC state conditions + * (setting possible with ADC enabled without conversion on going, + * ADC enabled with conversion on going, ...) + * Each feature can be updated afterwards with a unitary function + * and potentially with ADC in a different state than disabled, + * refer to description of each function for setting + * conditioned to ADC state. + */ +typedef struct +{ + uint32_t TriggerSource; /*!< Set ADC group injected conversion trigger source: internal (SW start) or from external IP (timer event, external interrupt line). + This parameter can be a value of @ref ADC_LL_EC_INJ_TRIGGER_SOURCE + @note On this STM32 series, external trigger is set with trigger polarity: rising edge + (only trigger polarity available on this STM32 series). + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetTriggerSource(). */ + + uint32_t SequencerLength; /*!< Set ADC group injected sequencer length. + This parameter can be a value of @ref ADC_LL_EC_INJ_SEQ_SCAN_LENGTH + @note This parameter is discarded if scan mode is disabled (refer to parameter 'ADC_SequencersScanMode'). + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetSequencerLength(). */ + + uint32_t SequencerDiscont; /*!< Set ADC group injected sequencer discontinuous mode: sequence subdivided and scan conversions interrupted every selected number of ranks. + This parameter can be a value of @ref ADC_LL_EC_INJ_SEQ_DISCONT_MODE + @note This parameter has an effect only if group injected sequencer is enabled + (scan length of 2 ranks or more). + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetSequencerDiscont(). */ + + uint32_t TrigAuto; /*!< Set ADC group injected conversion trigger: independent or from ADC group regular. + This parameter can be a value of @ref ADC_LL_EC_INJ_TRIG_AUTO + Note: This parameter must be set to set to independent trigger if injected trigger source is set to an external trigger. + + This feature can be modified afterwards using unitary function @ref LL_ADC_INJ_SetTrigAuto(). */ + +} LL_ADC_INJ_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Constants ADC Exported Constants + * @{ + */ + +/** @defgroup ADC_LL_EC_FLAG ADC flags + * @brief Flags defines which can be used with LL_ADC_ReadReg function + * @{ + */ +#define LL_ADC_FLAG_STRT ADC_SR_STRT /*!< ADC flag ADC group regular conversion start */ +#define LL_ADC_FLAG_EOS ADC_SR_EOC /*!< ADC flag ADC group regular end of sequence conversions (Note: on this STM32 series, there is no flag ADC group regular end of unitary conversion. Flag noted as "EOC" is corresponding to flag "EOS" in other STM32 families) */ +#define LL_ADC_FLAG_JSTRT ADC_SR_JSTRT /*!< ADC flag ADC group injected conversion start */ +#define LL_ADC_FLAG_JEOS ADC_SR_JEOC /*!< ADC flag ADC group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_FLAG_AWD1 ADC_SR_AWD /*!< ADC flag ADC analog watchdog 1 */ +#if defined(ADC_MULTIMODE_SUPPORT) +#define LL_ADC_FLAG_EOS_MST ADC_SR_EOC /*!< ADC flag ADC multimode master group regular end of sequence conversions (Note: on this STM32 series, there is no flag ADC group regular end of unitary conversion. Flag noted as "EOC" is corresponding to flag "EOS" in other STM32 families) */ +#define LL_ADC_FLAG_EOS_SLV ADC_SR_EOC /*!< ADC flag ADC multimode slave group regular end of sequence conversions (Note: on this STM32 series, there is no flag ADC group regular end of unitary conversion. Flag noted as "EOC" is corresponding to flag "EOS" in other STM32 families) (on STM32F1, this flag must be read from ADC instance slave: ADC2) */ +#define LL_ADC_FLAG_JEOS_MST ADC_SR_JEOC /*!< ADC flag ADC multimode master group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_FLAG_JEOS_SLV ADC_SR_JEOC /*!< ADC flag ADC multimode slave group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) (on STM32F1, this flag must be read from ADC instance slave: ADC2) */ +#define LL_ADC_FLAG_AWD1_MST ADC_SR_AWD /*!< ADC flag ADC multimode master analog watchdog 1 of the ADC master */ +#define LL_ADC_FLAG_AWD1_SLV ADC_SR_AWD /*!< ADC flag ADC multimode slave analog watchdog 1 of the ADC slave (on STM32F1, this flag must be read from ADC instance slave: ADC2) */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_IT ADC interruptions for configuration (interruption enable or disable) + * @brief IT defines which can be used with LL_ADC_ReadReg and LL_ADC_WriteReg functions + * @{ + */ +#define LL_ADC_IT_EOS ADC_CR1_EOCIE /*!< ADC interruption ADC group regular end of sequence conversions (Note: on this STM32 series, there is no flag ADC group regular end of unitary conversion. Flag noted as "EOC" is corresponding to flag "EOS" in other STM32 families) */ +#define LL_ADC_IT_JEOS ADC_CR1_JEOCIE /*!< ADC interruption ADC group injected end of sequence conversions (Note: on this STM32 series, there is no flag ADC group injected end of unitary conversion. Flag noted as "JEOC" is corresponding to flag "JEOS" in other STM32 families) */ +#define LL_ADC_IT_AWD1 ADC_CR1_AWDIE /*!< ADC interruption ADC analog watchdog 1 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REGISTERS ADC registers compliant with specific purpose + * @{ + */ +/* List of ADC registers intended to be used (most commonly) with */ +/* DMA transfer. */ +/* Refer to function @ref LL_ADC_DMA_GetRegAddr(). */ +#define LL_ADC_DMA_REG_REGULAR_DATA 0x00000000U /* ADC group regular conversion data register (corresponding to register DR) to be used with ADC configured in independent mode. Without DMA transfer, register accessed by LL function @ref LL_ADC_REG_ReadConversionData32() and other functions @ref LL_ADC_REG_ReadConversionDatax() */ +#if defined(ADC_MULTIMODE_SUPPORT) +#define LL_ADC_DMA_REG_REGULAR_DATA_MULTI 0x00000001U /* ADC group regular conversion data register (corresponding to register CDR) to be used with ADC configured in multimode (available on STM32 devices with several ADC instances). Without DMA transfer, register accessed by LL function @ref LL_ADC_REG_ReadMultiConversionData32() */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_COMMON_PATH_INTERNAL ADC common - Measurement path to internal channels + * @{ + */ +/* Note: Other measurement paths to internal channels may be available */ +/* (connections to other peripherals). */ +/* If they are not listed below, they do not require any specific */ +/* path enable. In this case, Access to measurement path is done */ +/* only by selecting the corresponding ADC internal channel. */ +#define LL_ADC_PATH_INTERNAL_NONE 0x00000000U /*!< ADC measurement paths all disabled */ +#define LL_ADC_PATH_INTERNAL_VREFINT (ADC_CR2_TSVREFE) /*!< ADC measurement path to internal channel VrefInt */ +#define LL_ADC_PATH_INTERNAL_TEMPSENSOR (ADC_CR2_TSVREFE) /*!< ADC measurement path to internal channel temperature sensor */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_RESOLUTION ADC instance - Resolution + * @{ + */ +#define LL_ADC_RESOLUTION_12B 0x00000000U /*!< ADC resolution 12 bits */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_DATA_ALIGN ADC instance - Data alignment + * @{ + */ +#define LL_ADC_DATA_ALIGN_RIGHT 0x00000000U /*!< ADC conversion data alignment: right aligned (alignment on data register LSB bit 0)*/ +#define LL_ADC_DATA_ALIGN_LEFT (ADC_CR2_ALIGN) /*!< ADC conversion data alignment: left aligned (alignment on data register MSB bit 15)*/ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_SCAN_SELECTION ADC instance - Scan selection + * @{ + */ +#define LL_ADC_SEQ_SCAN_DISABLE 0x00000000U /*!< ADC conversion is performed in unitary conversion mode (one channel converted, that defined in rank 1). Configuration of both groups regular and injected sequencers (sequence length, ...) is discarded: equivalent to length of 1 rank.*/ +#define LL_ADC_SEQ_SCAN_ENABLE (ADC_CR1_SCAN) /*!< ADC conversions are performed in sequence conversions mode, according to configuration of both groups regular and injected sequencers (sequence length, ...). */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_GROUPS ADC instance - Groups + * @{ + */ +#define LL_ADC_GROUP_REGULAR 0x00000001U /*!< ADC group regular (available on all STM32 devices) */ +#define LL_ADC_GROUP_INJECTED 0x00000002U /*!< ADC group injected (not available on all STM32 devices)*/ +#define LL_ADC_GROUP_REGULAR_INJECTED 0x00000003U /*!< ADC both groups regular and injected */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL ADC instance - Channel number + * @{ + */ +#define LL_ADC_CHANNEL_0 (ADC_CHANNEL_0_NUMBER | ADC_CHANNEL_0_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN0 */ +#define LL_ADC_CHANNEL_1 (ADC_CHANNEL_1_NUMBER | ADC_CHANNEL_1_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN1 */ +#define LL_ADC_CHANNEL_2 (ADC_CHANNEL_2_NUMBER | ADC_CHANNEL_2_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN2 */ +#define LL_ADC_CHANNEL_3 (ADC_CHANNEL_3_NUMBER | ADC_CHANNEL_3_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN3 */ +#define LL_ADC_CHANNEL_4 (ADC_CHANNEL_4_NUMBER | ADC_CHANNEL_4_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN4 */ +#define LL_ADC_CHANNEL_5 (ADC_CHANNEL_5_NUMBER | ADC_CHANNEL_5_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN5 */ +#define LL_ADC_CHANNEL_6 (ADC_CHANNEL_6_NUMBER | ADC_CHANNEL_6_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN6 */ +#define LL_ADC_CHANNEL_7 (ADC_CHANNEL_7_NUMBER | ADC_CHANNEL_7_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN7 */ +#define LL_ADC_CHANNEL_8 (ADC_CHANNEL_8_NUMBER | ADC_CHANNEL_8_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN8 */ +#define LL_ADC_CHANNEL_9 (ADC_CHANNEL_9_NUMBER | ADC_CHANNEL_9_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN9 */ +#define LL_ADC_CHANNEL_10 (ADC_CHANNEL_10_NUMBER | ADC_CHANNEL_10_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN10 */ +#define LL_ADC_CHANNEL_11 (ADC_CHANNEL_11_NUMBER | ADC_CHANNEL_11_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN11 */ +#define LL_ADC_CHANNEL_12 (ADC_CHANNEL_12_NUMBER | ADC_CHANNEL_12_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN12 */ +#define LL_ADC_CHANNEL_13 (ADC_CHANNEL_13_NUMBER | ADC_CHANNEL_13_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN13 */ +#define LL_ADC_CHANNEL_14 (ADC_CHANNEL_14_NUMBER | ADC_CHANNEL_14_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN14 */ +#define LL_ADC_CHANNEL_15 (ADC_CHANNEL_15_NUMBER | ADC_CHANNEL_15_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN15 */ +#define LL_ADC_CHANNEL_16 (ADC_CHANNEL_16_NUMBER | ADC_CHANNEL_16_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN16 */ +#define LL_ADC_CHANNEL_17 (ADC_CHANNEL_17_NUMBER | ADC_CHANNEL_17_SMP) /*!< ADC external channel (channel connected to GPIO pin) ADCx_IN17 */ +#define LL_ADC_CHANNEL_VREFINT (LL_ADC_CHANNEL_17 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected to VrefInt: Internal voltage reference. On STM32F1, ADC channel available only on ADC instance: ADC1. */ +#define LL_ADC_CHANNEL_TEMPSENSOR (LL_ADC_CHANNEL_16 | ADC_CHANNEL_ID_INTERNAL_CH) /*!< ADC internal channel connected to Temperature sensor. */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_SOURCE ADC group regular - Trigger source + * @{ + */ +/* ADC group regular external triggers for ADC instances: ADC1, ADC2, ADC3 (for ADC instances ADCx available on the selected device) */ +#define LL_ADC_REG_TRIG_SOFTWARE (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0) /*!< ADC group regular conversion trigger internal: SW start. */ +#define LL_ADC_REG_TRIG_EXT_TIM1_CH3 (ADC_CR2_EXTSEL_1) /*!< ADC group regular conversion trigger from external IP: TIM1 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +/* ADC group regular external triggers for ADC instances: ADC1, ADC2 (for ADC instances ADCx available on the selected device) */ +#define LL_ADC_REG_TRIG_EXT_TIM1_CH1 0x00000000U /*!< ADC group regular conversion trigger from external IP: TIM1 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM1_CH2 (ADC_CR2_EXTSEL_0) /*!< ADC group regular conversion trigger from external IP: TIM1 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_CH2 (ADC_CR2_EXTSEL_1 | ADC_CR2_EXTSEL_0) /*!< ADC group regular conversion trigger from external IP: TIM2 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM3_TRGO (ADC_CR2_EXTSEL_2) /*!< ADC group regular conversion trigger from external IP: TIM3 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM4_CH4 (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_0) /*!< ADC group regular conversion trigger from external IP: TIM4 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_EXTI_LINE11 (ADC_CR2_EXTSEL_2 | ADC_CR2_EXTSEL_1) /*!< ADC group regular conversion trigger from external IP: external interrupt line 11. Trigger edge set to rising edge (default setting). */ +#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC) +/* Note: TIM8_TRGO is available on ADC1 and ADC2 only in high-density and */ +/* XL-density devices. */ +/* Note: To use TIM8_TRGO on ADC1 or ADC2, a remap of trigger must be done */ +/* A remap of trigger must be done at top level (refer to */ +/* AFIO peripheral). */ +#define LL_ADC_REG_TRIG_EXT_TIM8_TRGO (LL_ADC_REG_TRIG_EXT_EXTI_LINE11) /*!< ADC group regular conversion trigger from external IP: TIM8 TRGO. Trigger edge set to rising edge (default setting). Available only on high-density and XL-density devices. A remap of trigger must be done at top level (refer to AFIO peripheral).*/ +#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ +#if defined (STM32F103xE) || defined (STM32F103xG) +/* ADC group regular external triggers for ADC instances: ADC3 (for ADC instances ADCx available on the selected device) */ +#define LL_ADC_REG_TRIG_EXT_TIM3_CH1 (LL_ADC_REG_TRIG_EXT_TIM1_CH1) /*!< ADC group regular conversion trigger from external IP: TIM3 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM2_CH3 (LL_ADC_REG_TRIG_EXT_TIM1_CH2) /*!< ADC group regular conversion trigger from external IP: TIM2 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM8_CH1 (LL_ADC_REG_TRIG_EXT_TIM2_CH2) /*!< ADC group regular conversion trigger from external IP: TIM8 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM8_TRGO_ADC3 (LL_ADC_REG_TRIG_EXT_TIM3_TRGO) /*!< ADC group regular conversion trigger from external IP: TIM8 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM5_CH1 (LL_ADC_REG_TRIG_EXT_TIM4_CH4) /*!< ADC group regular conversion trigger from external IP: TIM5 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_REG_TRIG_EXT_TIM5_CH3 (LL_ADC_REG_TRIG_EXT_EXTI_LINE11) /*!< ADC group regular conversion trigger from external IP: TIM5 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_TRIGGER_EDGE ADC group regular - Trigger edge + * @{ + */ +#define LL_ADC_REG_TRIG_EXT_RISING ADC_CR2_EXTTRIG /*!< ADC group regular conversion trigger polarity set to rising edge */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_CONTINUOUS_MODE ADC group regular - Continuous mode +* @{ +*/ +#define LL_ADC_REG_CONV_SINGLE 0x00000000U /*!< ADC conversions are performed in single mode: one conversion per trigger */ +#define LL_ADC_REG_CONV_CONTINUOUS (ADC_CR2_CONT) /*!< ADC conversions are performed in continuous mode: after the first trigger, following conversions launched successively automatically */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_DMA_TRANSFER ADC group regular - DMA transfer of ADC conversion data + * @{ + */ +#define LL_ADC_REG_DMA_TRANSFER_NONE 0x00000000U /*!< ADC conversions are not transferred by DMA */ +#define LL_ADC_REG_DMA_TRANSFER_UNLIMITED (ADC_CR2_DMA) /*!< ADC conversion data are transferred by DMA, in unlimited mode: DMA transfer requests are unlimited, whatever number of DMA data transferred (number of ADC conversions). This ADC mode is intended to be used with DMA mode circular. */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_SCAN_LENGTH ADC group regular - Sequencer scan length + * @{ + */ +#define LL_ADC_REG_SEQ_SCAN_DISABLE 0x00000000U /*!< ADC group regular sequencer disable (equivalent to sequencer of 1 rank: ADC conversion on only 1 channel) */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS ( ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 2 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS ( ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 3 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS ( ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 4 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS ( ADC_SQR1_L_2 ) /*!< ADC group regular sequencer enable with 5 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS ( ADC_SQR1_L_2 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 6 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS ( ADC_SQR1_L_2 | ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 7 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS ( ADC_SQR1_L_2 | ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 8 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS (ADC_SQR1_L_3 ) /*!< ADC group regular sequencer enable with 9 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 10 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 11 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 12 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 ) /*!< ADC group regular sequencer enable with 13 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 14 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 | ADC_SQR1_L_1 ) /*!< ADC group regular sequencer enable with 15 ranks in the sequence */ +#define LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS (ADC_SQR1_L_3 | ADC_SQR1_L_2 | ADC_SQR1_L_1 | ADC_SQR1_L_0) /*!< ADC group regular sequencer enable with 16 ranks in the sequence */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_DISCONT_MODE ADC group regular - Sequencer discontinuous mode + * @{ + */ +#define LL_ADC_REG_SEQ_DISCONT_DISABLE 0x00000000U /*!< ADC group regular sequencer discontinuous mode disable */ +#define LL_ADC_REG_SEQ_DISCONT_1RANK ( ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every rank */ +#define LL_ADC_REG_SEQ_DISCONT_2RANKS ( ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enabled with sequence interruption every 2 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_3RANKS ( ADC_CR1_DISCNUM_1 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 3 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_4RANKS ( ADC_CR1_DISCNUM_1 | ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 4 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_5RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 5 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_6RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 6 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_7RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCNUM_1 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 7 ranks */ +#define LL_ADC_REG_SEQ_DISCONT_8RANKS (ADC_CR1_DISCNUM_2 | ADC_CR1_DISCNUM_1 | ADC_CR1_DISCNUM_0 | ADC_CR1_DISCEN) /*!< ADC group regular sequencer discontinuous mode enable with sequence interruption every 8 ranks */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_REG_SEQ_RANKS ADC group regular - Sequencer ranks + * @{ + */ +#define LL_ADC_REG_RANK_1 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_1_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 1 */ +#define LL_ADC_REG_RANK_2 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_2_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 2 */ +#define LL_ADC_REG_RANK_3 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_3_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 3 */ +#define LL_ADC_REG_RANK_4 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_4_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 4 */ +#define LL_ADC_REG_RANK_5 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_5_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 5 */ +#define LL_ADC_REG_RANK_6 (ADC_SQR3_REGOFFSET | ADC_REG_RANK_6_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 6 */ +#define LL_ADC_REG_RANK_7 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_7_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 7 */ +#define LL_ADC_REG_RANK_8 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_8_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 8 */ +#define LL_ADC_REG_RANK_9 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_9_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 9 */ +#define LL_ADC_REG_RANK_10 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_10_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 10 */ +#define LL_ADC_REG_RANK_11 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_11_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 11 */ +#define LL_ADC_REG_RANK_12 (ADC_SQR2_REGOFFSET | ADC_REG_RANK_12_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 12 */ +#define LL_ADC_REG_RANK_13 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_13_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 13 */ +#define LL_ADC_REG_RANK_14 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_14_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 14 */ +#define LL_ADC_REG_RANK_15 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_15_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 15 */ +#define LL_ADC_REG_RANK_16 (ADC_SQR1_REGOFFSET | ADC_REG_RANK_16_SQRX_BITOFFSET_POS) /*!< ADC group regular sequencer rank 16 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_TRIGGER_SOURCE ADC group injected - Trigger source + * @{ + */ +/* ADC group injected external triggers for ADC instances: ADC1, ADC2, ADC3 (for ADC instances ADCx available on the selected device) */ +#define LL_ADC_INJ_TRIG_SOFTWARE (ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0) /*!< ADC group injected conversion trigger internal: SW start. */ +#define LL_ADC_INJ_TRIG_EXT_TIM1_TRGO 0x00000000U /*!< ADC group injected conversion trigger from external IP: TIM1 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM1_CH4 (ADC_CR2_JEXTSEL_0) /*!< ADC group injected conversion trigger from external IP: TIM1 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +/* ADC group injected external triggers for ADC instances: ADC1, ADC2 (for ADC instances ADCx available on the selected device) */ +#define LL_ADC_INJ_TRIG_EXT_TIM2_TRGO (ADC_CR2_JEXTSEL_1) /*!< ADC group injected conversion trigger from external IP: TIM2 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM2_CH1 (ADC_CR2_JEXTSEL_1 | ADC_CR2_JEXTSEL_0) /*!< ADC group injected conversion trigger from external IP: TIM2 channel 1 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM3_CH4 (ADC_CR2_JEXTSEL_2) /*!< ADC group injected conversion trigger from external IP: TIM3 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_0) /*!< ADC group injected conversion trigger from external IP: TIM4 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 (ADC_CR2_JEXTSEL_2 | ADC_CR2_JEXTSEL_1) /*!< ADC group injected conversion trigger from external IP: external interrupt line 15. Trigger edge set to rising edge (default setting). */ +#if defined (STM32F101xE) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC) +/* Note: TIM8_CH4 is available on ADC1 and ADC2 only in high-density and */ +/* XL-density devices. */ +/* Note: To use TIM8_TRGO on ADC1 or ADC2, a remap of trigger must be done */ +/* A remap of trigger must be done at top level (refer to */ +/* AFIO peripheral). */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) /*!< ADC group injected conversion trigger from external IP: TIM8 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). Available only on high-density and XL-density devices. A remap of trigger must be done at top level (refer to AFIO peripheral). */ +#endif /* STM32F101xE || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */ +#if defined (STM32F103xE) || defined (STM32F103xG) +/* ADC group injected external triggers for ADC instances: ADC3 (for ADC instances ADCx available on the selected device) */ +#define LL_ADC_INJ_TRIG_EXT_TIM4_CH3 (LL_ADC_INJ_TRIG_EXT_TIM2_TRGO) /*!< ADC group injected conversion trigger from external IP: TIM4 channel 3 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_CH2 (LL_ADC_INJ_TRIG_EXT_TIM2_CH1) /*!< ADC group injected conversion trigger from external IP: TIM8 channel 2 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM8_CH4_ADC3 (LL_ADC_INJ_TRIG_EXT_TIM3_CH4) /*!< ADC group injected conversion trigger from external IP: TIM8 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM5_TRGO (LL_ADC_INJ_TRIG_EXT_TIM4_TRGO) /*!< ADC group injected conversion trigger from external IP: TIM5 TRGO. Trigger edge set to rising edge (default setting). */ +#define LL_ADC_INJ_TRIG_EXT_TIM5_CH4 (LL_ADC_INJ_TRIG_EXT_EXTI_LINE15) /*!< ADC group injected conversion trigger from external IP: TIM5 channel 4 event (capture compare: input capture or output capture). Trigger edge set to rising edge (default setting). */ +#endif +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_TRIGGER_EDGE ADC group injected - Trigger edge + * @{ + */ +#define LL_ADC_INJ_TRIG_EXT_RISING ADC_CR2_JEXTTRIG /*!< ADC group injected conversion trigger polarity set to rising edge */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_TRIG_AUTO ADC group injected - Automatic trigger mode +* @{ +*/ +#define LL_ADC_INJ_TRIG_INDEPENDENT 0x00000000U /*!< ADC group injected conversion trigger independent. Setting mandatory if ADC group injected injected trigger source is set to an external trigger. */ +#define LL_ADC_INJ_TRIG_FROM_GRP_REGULAR (ADC_CR1_JAUTO) /*!< ADC group injected conversion trigger from ADC group regular. Setting compliant only with group injected trigger source set to SW start, without any further action on ADC group injected conversion start or stop: in this case, ADC group injected is controlled only from ADC group regular. */ +/** + * @} + */ + + +/** @defgroup ADC_LL_EC_INJ_SEQ_SCAN_LENGTH ADC group injected - Sequencer scan length + * @{ + */ +#define LL_ADC_INJ_SEQ_SCAN_DISABLE 0x00000000U /*!< ADC group injected sequencer disable (equivalent to sequencer of 1 rank: ADC conversion on only 1 channel) */ +#define LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS ( ADC_JSQR_JL_0) /*!< ADC group injected sequencer enable with 2 ranks in the sequence */ +#define LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS (ADC_JSQR_JL_1 ) /*!< ADC group injected sequencer enable with 3 ranks in the sequence */ +#define LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS (ADC_JSQR_JL_1 | ADC_JSQR_JL_0) /*!< ADC group injected sequencer enable with 4 ranks in the sequence */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_SEQ_DISCONT_MODE ADC group injected - Sequencer discontinuous mode + * @{ + */ +#define LL_ADC_INJ_SEQ_DISCONT_DISABLE 0x00000000U /*!< ADC group injected sequencer discontinuous mode disable */ +#define LL_ADC_INJ_SEQ_DISCONT_1RANK (ADC_CR1_JDISCEN) /*!< ADC group injected sequencer discontinuous mode enable with sequence interruption every rank */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_INJ_SEQ_RANKS ADC group injected - Sequencer ranks + * @{ + */ +#define LL_ADC_INJ_RANK_1 (ADC_JDR1_REGOFFSET | ADC_JOFR1_REGOFFSET | 0x00000001U) /*!< ADC group injected sequencer rank 1 */ +#define LL_ADC_INJ_RANK_2 (ADC_JDR2_REGOFFSET | ADC_JOFR2_REGOFFSET | 0x00000002U) /*!< ADC group injected sequencer rank 2 */ +#define LL_ADC_INJ_RANK_3 (ADC_JDR3_REGOFFSET | ADC_JOFR3_REGOFFSET | 0x00000003U) /*!< ADC group injected sequencer rank 3 */ +#define LL_ADC_INJ_RANK_4 (ADC_JDR4_REGOFFSET | ADC_JOFR4_REGOFFSET | 0x00000004U) /*!< ADC group injected sequencer rank 4 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_CHANNEL_SAMPLINGTIME Channel - Sampling time + * @{ + */ +#define LL_ADC_SAMPLINGTIME_1CYCLE_5 0x00000000U /*!< Sampling time 1.5 ADC clock cycle */ +#define LL_ADC_SAMPLINGTIME_7CYCLES_5 (ADC_SMPR2_SMP0_0) /*!< Sampling time 7.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_13CYCLES_5 (ADC_SMPR2_SMP0_1) /*!< Sampling time 13.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_28CYCLES_5 (ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0) /*!< Sampling time 28.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_41CYCLES_5 (ADC_SMPR2_SMP0_2) /*!< Sampling time 41.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_55CYCLES_5 (ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_0) /*!< Sampling time 55.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_71CYCLES_5 (ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1) /*!< Sampling time 71.5 ADC clock cycles */ +#define LL_ADC_SAMPLINGTIME_239CYCLES_5 (ADC_SMPR2_SMP0_2 | ADC_SMPR2_SMP0_1 | ADC_SMPR2_SMP0_0) /*!< Sampling time 239.5 ADC clock cycles */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_NUMBER Analog watchdog - Analog watchdog number + * @{ + */ +#define LL_ADC_AWD1 (ADC_AWD_CR1_CHANNEL_MASK | ADC_AWD_CR1_REGOFFSET) /*!< ADC analog watchdog number 1 */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_CHANNELS Analog watchdog - Monitored channels + * @{ + */ +#define LL_ADC_AWD_DISABLE 0x00000000U /*!< ADC analog watchdog monitoring disabled */ +#define LL_ADC_AWD_ALL_CHANNELS_REG ( ADC_CR1_AWDEN ) /*!< ADC analog watchdog monitoring of all channels, converted by group regular only */ +#define LL_ADC_AWD_ALL_CHANNELS_INJ ( ADC_CR1_JAWDEN ) /*!< ADC analog watchdog monitoring of all channels, converted by group injected only */ +#define LL_ADC_AWD_ALL_CHANNELS_REG_INJ ( ADC_CR1_JAWDEN | ADC_CR1_AWDEN ) /*!< ADC analog watchdog monitoring of all channels, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_0_REG ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN0, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_0_INJ ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN0, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_0_REG_INJ ((LL_ADC_CHANNEL_0 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN0, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_1_REG ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN1, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_1_INJ ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN1, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_1_REG_INJ ((LL_ADC_CHANNEL_1 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN1, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_2_REG ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN2, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_2_INJ ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN2, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_2_REG_INJ ((LL_ADC_CHANNEL_2 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN2, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_3_REG ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN3, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_3_INJ ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN3, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_3_REG_INJ ((LL_ADC_CHANNEL_3 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN3, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_4_REG ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN4, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_4_INJ ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN4, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_4_REG_INJ ((LL_ADC_CHANNEL_4 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN4, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_5_REG ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN5, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_5_INJ ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN5, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_5_REG_INJ ((LL_ADC_CHANNEL_5 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN5, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_6_REG ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN6, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_6_INJ ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN6, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_6_REG_INJ ((LL_ADC_CHANNEL_6 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN6, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_7_REG ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN7, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_7_INJ ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN7, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_7_REG_INJ ((LL_ADC_CHANNEL_7 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN7, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_8_REG ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN8, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_8_INJ ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN8, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_8_REG_INJ ((LL_ADC_CHANNEL_8 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN8, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_9_REG ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN9, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_9_INJ ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN9, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_9_REG_INJ ((LL_ADC_CHANNEL_9 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN9, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_10_REG ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN10, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_10_INJ ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN10, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_10_REG_INJ ((LL_ADC_CHANNEL_10 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN10, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_11_REG ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN11, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_11_INJ ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN11, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_11_REG_INJ ((LL_ADC_CHANNEL_11 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN11, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_12_REG ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN12, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_12_INJ ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN12, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_12_REG_INJ ((LL_ADC_CHANNEL_12 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN12, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_13_REG ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN13, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_13_INJ ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN13, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_13_REG_INJ ((LL_ADC_CHANNEL_13 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN13, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_14_REG ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN14, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_14_INJ ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN14, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_14_REG_INJ ((LL_ADC_CHANNEL_14 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN14, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_15_REG ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN15, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_15_INJ ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN15, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_15_REG_INJ ((LL_ADC_CHANNEL_15 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN15, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_16_REG ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN16, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_16_INJ ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN16, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_16_REG_INJ ((LL_ADC_CHANNEL_16 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN16, converted by either group regular or injected */ +#define LL_ADC_AWD_CHANNEL_17_REG ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN17, converted by group regular only */ +#define LL_ADC_AWD_CHANNEL_17_INJ ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN17, converted by group injected only */ +#define LL_ADC_AWD_CHANNEL_17_REG_INJ ((LL_ADC_CHANNEL_17 & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC external channel (channel connected to GPIO pin) ADCx_IN17, converted by either group regular or injected */ +#define LL_ADC_AWD_CH_VREFINT_REG ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to VrefInt: Internal voltage reference, converted by group regular only */ +#define LL_ADC_AWD_CH_VREFINT_INJ ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to VrefInt: Internal voltage reference, converted by group injected only */ +#define LL_ADC_AWD_CH_VREFINT_REG_INJ ((LL_ADC_CHANNEL_VREFINT & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to VrefInt: Internal voltage reference, converted by either group regular or injected */ +#define LL_ADC_AWD_CH_TEMPSENSOR_REG ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by group regular only */ +#define LL_ADC_AWD_CH_TEMPSENSOR_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by group injected only */ +#define LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ ((LL_ADC_CHANNEL_TEMPSENSOR & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) /*!< ADC analog watchdog monitoring of ADC internal channel connected to Temperature sensor, converted by either group regular or injected */ +/** + * @} + */ + +/** @defgroup ADC_LL_EC_AWD_THRESHOLDS Analog watchdog - Thresholds + * @{ + */ +#define LL_ADC_AWD_THRESHOLD_HIGH (ADC_AWD_TR1_HIGH_REGOFFSET) /*!< ADC analog watchdog threshold high */ +#define LL_ADC_AWD_THRESHOLD_LOW (ADC_AWD_TR1_LOW_REGOFFSET) /*!< ADC analog watchdog threshold low */ +/** + * @} + */ + +#if !defined(ADC_MULTIMODE_SUPPORT) +/** @defgroup ADC_LL_EC_MULTI_MODE Multimode - Mode + * @{ + */ +#define LL_ADC_MULTI_INDEPENDENT 0x00000000U /*!< ADC dual mode disabled (ADC independent mode) */ +/** + * @} + */ +#endif +#if defined(ADC_MULTIMODE_SUPPORT) +/** @defgroup ADC_LL_EC_MULTI_MODE Multimode - Mode + * @{ + */ +#define LL_ADC_MULTI_INDEPENDENT 0x00000000U /*!< ADC dual mode disabled (ADC independent mode) */ +#define LL_ADC_MULTI_DUAL_REG_SIMULT ( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 ) /*!< ADC dual mode enabled: group regular simultaneous */ +#define LL_ADC_MULTI_DUAL_REG_INTERL_FAST ( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0) /*!< ADC dual mode enabled: Combined group regular interleaved fast (delay between ADC sampling phases: 7 ADC clock cycles) (equivalent to multimode sampling delay set to "LL_ADC_MULTI_TWOSMP_DELAY_7CYCLES" on other STM32 devices)) */ +#define LL_ADC_MULTI_DUAL_REG_INTERL_SLOW (ADC_CR1_DUALMOD_3 ) /*!< ADC dual mode enabled: Combined group regular interleaved slow (delay between ADC sampling phases: 14 ADC clock cycles) (equivalent to multimode sampling delay set to "LL_ADC_MULTI_TWOSMP_DELAY_14CYCLES" on other STM32 devices)) */ +#define LL_ADC_MULTI_DUAL_INJ_SIMULT ( ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_0) /*!< ADC dual mode enabled: group injected simultaneous slow (delay between ADC sampling phases: 14 ADC clock cycles) (equivalent to multimode sampling delay set to "LL_ADC_MULTI_TWOSMP_DELAY_14CYCLES" on other STM32 devices)) */ +#define LL_ADC_MULTI_DUAL_INJ_ALTERN (ADC_CR1_DUALMOD_3 | ADC_CR1_DUALMOD_0) /*!< ADC dual mode enabled: group injected alternate trigger. Works only with external triggers (not internal SW start) */ +#define LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM ( ADC_CR1_DUALMOD_0) /*!< ADC dual mode enabled: Combined group regular simultaneous + group injected simultaneous */ +#define LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT ( ADC_CR1_DUALMOD_1 ) /*!< ADC dual mode enabled: Combined group regular simultaneous + group injected alternate trigger */ +#define LL_ADC_MULTI_DUAL_REG_INTFAST_INJ_SIM ( ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0) /*!< ADC dual mode enabled: Combined group regular interleaved fast (delay between ADC sampling phases: 7 ADC clock cycles) + group injected simultaneous */ +#define LL_ADC_MULTI_DUAL_REG_INTSLOW_INJ_SIM ( ADC_CR1_DUALMOD_2 ) /*!< ADC dual mode enabled: Combined group regular interleaved slow (delay between ADC sampling phases: 14 ADC clock cycles) + group injected simultaneous */ + +/** + * @} + */ + +/** @defgroup ADC_LL_EC_MULTI_MASTER_SLAVE Multimode - ADC master or slave + * @{ + */ +#define LL_ADC_MULTI_MASTER ( ADC_DR_DATA) /*!< In multimode, selection among several ADC instances: ADC master */ +#define LL_ADC_MULTI_SLAVE (ADC_DR_ADC2DATA ) /*!< In multimode, selection among several ADC instances: ADC slave */ +#define LL_ADC_MULTI_MASTER_SLAVE (ADC_DR_ADC2DATA | ADC_DR_DATA) /*!< In multimode, selection among several ADC instances: both ADC master and ADC slave */ +/** + * @} + */ + +#endif /* ADC_MULTIMODE_SUPPORT */ + + +/** @defgroup ADC_LL_EC_HW_DELAYS Definitions of ADC hardware constraints delays + * @note Only ADC IP HW delays are defined in ADC LL driver driver, + * not timeout values. + * For details on delays values, refer to descriptions in source code + * above each literal definition. + * @{ + */ + +/* Note: Only ADC IP HW delays are defined in ADC LL driver driver, */ +/* not timeout values. */ +/* Timeout values for ADC operations are dependent to device clock */ +/* configuration (system clock versus ADC clock), */ +/* and therefore must be defined in user application. */ +/* Indications for estimation of ADC timeout delays, for this */ +/* STM32 series: */ +/* - ADC enable time: maximum delay is 1us */ +/* (refer to device datasheet, parameter "tSTAB") */ +/* - ADC conversion time: duration depending on ADC clock and ADC */ +/* configuration. */ +/* (refer to device reference manual, section "Timing") */ + +/* Delay for temperature sensor stabilization time. */ +/* Literal set to maximum value (refer to device datasheet, */ +/* parameter "tSTART"). */ +/* Unit: us */ +#define LL_ADC_DELAY_TEMPSENSOR_STAB_US (10U) /*!< Delay for internal voltage reference stabilization time */ + +/* Delay required between ADC disable and ADC calibration start. */ +/* Note: On this STM32 series, before starting a calibration, */ +/* ADC must be disabled. */ +/* A minimum number of ADC clock cycles are required */ +/* between ADC disable state and calibration start. */ +/* Refer to literal @ref LL_ADC_DELAY_ENABLE_CALIB_ADC_CYCLES. */ +/* Wait time can be computed in user application by waiting for the */ +/* equivalent number of CPU cycles, by taking into account */ +/* ratio of CPU clock versus ADC clock prescalers. */ +/* Unit: ADC clock cycles. */ +#define LL_ADC_DELAY_DISABLE_CALIB_ADC_CYCLES (2U) /*!< Delay required between ADC disable and ADC calibration start */ + +/* Delay required between end of ADC Enable and the start of ADC calibration. */ +/* Note: On this STM32 series, a minimum number of ADC clock cycles */ +/* are required between the end of ADC enable and the start of ADC */ +/* calibration. */ +/* Wait time can be computed in user application by waiting for the */ +/* equivalent number of CPU cycles, by taking into account */ +/* ratio of CPU clock versus ADC clock prescalers. */ +/* Unit: ADC clock cycles. */ +#define LL_ADC_DELAY_ENABLE_CALIB_ADC_CYCLES (2U) /*!< Delay required between end of ADC enable and the start of ADC calibration */ + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported macro ------------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Macros ADC Exported Macros + * @{ + */ + +/** @defgroup ADC_LL_EM_WRITE_READ Common write and read registers Macros + * @{ + */ + +/** + * @brief Write a value in ADC register + * @param __INSTANCE__ ADC Instance + * @param __REG__ Register to be written + * @param __VALUE__ Value to be written in the register + * @retval None + */ +#define LL_ADC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, (__VALUE__)) + +/** + * @brief Read a value in ADC register + * @param __INSTANCE__ ADC Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_ADC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__) +/** + * @} + */ + +/** @defgroup ADC_LL_EM_HELPER_MACRO ADC helper macro + * @{ + */ + +/** + * @brief Helper macro to get ADC channel number in decimal format + * from literals LL_ADC_CHANNEL_x. + * @note Example: + * __LL_ADC_CHANNEL_TO_DECIMAL_NB(LL_ADC_CHANNEL_4) + * will return decimal number "4". + * @note The input can be a value from functions where a channel + * number is returned, either defined with number + * or with bitfield (only one bit must be set). + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval Value between Min_Data=0 and Max_Data=18 + */ +#define __LL_ADC_CHANNEL_TO_DECIMAL_NB(__CHANNEL__) \ + (((__CHANNEL__) & ADC_CHANNEL_ID_NUMBER_MASK) >> ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) + +/** + * @brief Helper macro to get ADC channel in literal format LL_ADC_CHANNEL_x + * from number in decimal format. + * @note Example: + * __LL_ADC_DECIMAL_NB_TO_CHANNEL(4) + * will return a data equivalent to "LL_ADC_CHANNEL_4". + * @param __DECIMAL_NB__: Value between Min_Data=0 and Max_Data=18 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + */ +#define __LL_ADC_DECIMAL_NB_TO_CHANNEL(__DECIMAL_NB__) \ + (((__DECIMAL_NB__) <= 9U) \ + ? ( \ + ((__DECIMAL_NB__) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) | \ + (ADC_SMPR2_REGOFFSET | (((uint32_t) (3U * (__DECIMAL_NB__))) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) \ + ) \ + : \ + ( \ + ((__DECIMAL_NB__) << ADC_CHANNEL_ID_NUMBER_BITOFFSET_POS) | \ + (ADC_SMPR1_REGOFFSET | (((uint32_t) (3U * ((__DECIMAL_NB__) - 10U))) << ADC_CHANNEL_SMPx_BITOFFSET_POS)) \ + ) \ + ) + +/** + * @brief Helper macro to determine whether the selected channel + * corresponds to literal definitions of driver. + * @note The different literal definitions of ADC channels are: + * - ADC internal channel: + * LL_ADC_CHANNEL_VREFINT, LL_ADC_CHANNEL_TEMPSENSOR, ... + * - ADC external channel (channel connected to a GPIO pin): + * LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ... + * @note The channel parameter must be a value defined from literal + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...), + * must not be a value from functions where a channel number is + * returned from ADC registers, + * because internal and external channels share the same channel + * number in ADC registers. The differentiation is made only with + * parameters definitions of driver. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval Value "0" if the channel corresponds to a parameter definition of a ADC external channel (channel connected to a GPIO pin). + * Value "1" if the channel corresponds to a parameter definition of a ADC internal channel. + */ +#define __LL_ADC_IS_CHANNEL_INTERNAL(__CHANNEL__) \ + (((__CHANNEL__) & ADC_CHANNEL_ID_INTERNAL_CH_MASK) != 0U) + +/** + * @brief Helper macro to convert a channel defined from parameter + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * to its equivalent parameter definition of a ADC external channel + * (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...). + * @note The channel parameter can be, additionally to a value + * defined from parameter definition of a ADC internal channel + * (LL_ADC_CHANNEL_VREFINT, LL_ADC_CHANNEL_TEMPSENSOR, ...), + * a value defined from parameter definition of + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...) + * or a value from functions where a channel number is returned + * from ADC registers. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + */ +#define __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(__CHANNEL__) \ + ((__CHANNEL__) & ~ADC_CHANNEL_ID_INTERNAL_CH_MASK) + +/** + * @brief Helper macro to determine whether the internal channel + * selected is available on the ADC instance selected. + * @note The channel parameter must be a value defined from parameter + * definition of a ADC internal channel (LL_ADC_CHANNEL_VREFINT, + * LL_ADC_CHANNEL_TEMPSENSOR, ...), + * must not be a value defined from parameter definition of + * ADC external channel (LL_ADC_CHANNEL_1, LL_ADC_CHANNEL_2, ...) + * or a value from functions where a channel number is + * returned from ADC registers, + * because internal and external channels share the same channel + * number in ADC registers. The differentiation is made only with + * parameters definitions of driver. + * @param __ADC_INSTANCE__ ADC instance + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval Value "0" if the internal channel selected is not available on the ADC instance selected. + * Value "1" if the internal channel selected is available on the ADC instance selected. + */ +#define __LL_ADC_IS_CHANNEL_INTERNAL_AVAILABLE(__ADC_INSTANCE__, __CHANNEL__) \ + (((__ADC_INSTANCE__) == ADC1) \ + ? ( \ + ((__CHANNEL__) == LL_ADC_CHANNEL_VREFINT) || \ + ((__CHANNEL__) == LL_ADC_CHANNEL_TEMPSENSOR) \ + ) \ + : \ + (0U) \ + ) + +/** + * @brief Helper macro to define ADC analog watchdog parameter: + * define a single channel to monitor with analog watchdog + * from sequencer channel and groups definition. + * @note To be used with function @ref LL_ADC_SetAnalogWDMonitChannels(). + * Example: + * LL_ADC_SetAnalogWDMonitChannels( + * ADC1, LL_ADC_AWD1, + * __LL_ADC_ANALOGWD_CHANNEL_GROUP(LL_ADC_CHANNEL4, LL_ADC_GROUP_REGULAR)) + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + * @param __GROUP__ This parameter can be one of the following values: + * @arg @ref LL_ADC_GROUP_REGULAR + * @arg @ref LL_ADC_GROUP_INJECTED + * @arg @ref LL_ADC_GROUP_REGULAR_INJECTED + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + */ +#define __LL_ADC_ANALOGWD_CHANNEL_GROUP(__CHANNEL__, __GROUP__) \ + (((__GROUP__) == LL_ADC_GROUP_REGULAR) \ + ? (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) \ + : \ + ((__GROUP__) == LL_ADC_GROUP_INJECTED) \ + ? (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL) \ + : \ + (((__CHANNEL__) & ADC_CHANNEL_ID_MASK) | ADC_CR1_JAWDEN | ADC_CR1_AWDEN | ADC_CR1_AWDSGL) \ + ) + +/** + * @brief Helper macro to set the value of ADC analog watchdog threshold high + * or low in function of ADC resolution, when ADC resolution is + * different of 12 bits. + * @note To be used with function @ref LL_ADC_SetAnalogWDThresholds(). + * Example, with a ADC resolution of 8 bits, to set the value of + * analog watchdog threshold high (on 8 bits): + * LL_ADC_SetAnalogWDThresholds + * (< ADCx param >, + * __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(LL_ADC_RESOLUTION_8B, ) + * ); + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @param __AWD_THRESHOLD__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +/* Note: On this STM32 series, ADC is fixed to resolution 12 bits. */ +/* This macro has been kept anyway for compatibility with other */ +/* STM32 families featuring different ADC resolutions. */ +#define __LL_ADC_ANALOGWD_SET_THRESHOLD_RESOLUTION(__ADC_RESOLUTION__, __AWD_THRESHOLD__) \ + ((__AWD_THRESHOLD__) << (0U)) + +/** + * @brief Helper macro to get the value of ADC analog watchdog threshold high + * or low in function of ADC resolution, when ADC resolution is + * different of 12 bits. + * @note To be used with function @ref LL_ADC_GetAnalogWDThresholds(). + * Example, with a ADC resolution of 8 bits, to get the value of + * analog watchdog threshold high (on 8 bits): + * < threshold_value_6_bits > = __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION + * (LL_ADC_RESOLUTION_8B, + * LL_ADC_GetAnalogWDThresholds(, LL_ADC_AWD_THRESHOLD_HIGH) + * ); + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @param __AWD_THRESHOLD_12_BITS__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +/* Note: On this STM32 series, ADC is fixed to resolution 12 bits. */ +/* This macro has been kept anyway for compatibility with other */ +/* STM32 families featuring different ADC resolutions. */ +#define __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION(__ADC_RESOLUTION__, __AWD_THRESHOLD_12_BITS__) \ + (__AWD_THRESHOLD_12_BITS__) + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Helper macro to get the ADC multimode conversion data of ADC master + * or ADC slave from raw value with both ADC conversion data concatenated. + * @note This macro is intended to be used when multimode transfer by DMA + * is enabled. + * In this case the transferred data need to processed with this macro + * to separate the conversion data of ADC master and ADC slave. + * @param __ADC_MULTI_MASTER_SLAVE__ This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_MASTER + * @arg @ref LL_ADC_MULTI_SLAVE + * @param __ADC_MULTI_CONV_DATA__ Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +#define __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(__ADC_MULTI_MASTER_SLAVE__, __ADC_MULTI_CONV_DATA__) \ + (((__ADC_MULTI_CONV_DATA__) >> POSITION_VAL((__ADC_MULTI_MASTER_SLAVE__))) & ADC_DR_DATA) +#endif + +/** + * @brief Helper macro to select the ADC common instance + * to which is belonging the selected ADC instance. + * @note ADC common register instance can be used for: + * - Set parameters common to several ADC instances + * - Multimode (for devices with several ADC instances) + * Refer to functions having argument "ADCxy_COMMON" as parameter. + * @note On STM32F1, there is no common ADC instance. + * However, ADC instance ADC1 has a role of common ADC instance + * for ADC1 and ADC2: + * this instance is used to manage internal channels + * and multimode (these features are managed in ADC common + * instances on some other STM32 devices). + * ADC instance ADC3 (if available on the selected device) + * has no ADC common instance. + * @param __ADCx__ ADC instance + * @retval ADC common register instance + */ +#if defined(ADC1) && defined(ADC2) && defined(ADC3) +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) \ + ((((__ADCx__) == ADC1) || ((__ADCx__) == ADC2)) \ + ? ( \ + (ADC12_COMMON) \ + ) \ + : \ + ( \ + (0U) \ + ) \ + ) +#elif defined(ADC1) && defined(ADC2) +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) \ + (ADC12_COMMON) +#else +#define __LL_ADC_COMMON_INSTANCE(__ADCx__) \ + (ADC1_COMMON) +#endif + +/** + * @brief Helper macro to check if all ADC instances sharing the same + * ADC common instance are disabled. + * @note This check is required by functions with setting conditioned to + * ADC state: + * All ADC instances of the ADC common group must be disabled. + * Refer to functions having argument "ADCxy_COMMON" as parameter. + * @note On devices with only 1 ADC common instance, parameter of this macro + * is useless and can be ignored (parameter kept for compatibility + * with devices featuring several ADC common instances). + * @note On STM32F1, there is no common ADC instance. + * However, ADC instance ADC1 has a role of common ADC instance + * for ADC1 and ADC2: + * this instance is used to manage internal channels + * and multimode (these features are managed in ADC common + * instances on some other STM32 devices). + * ADC instance ADC3 (if available on the selected device) + * has no ADC common instance. + * @param __ADCXY_COMMON__ ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Value "0" if all ADC instances sharing the same ADC common instance + * are disabled. + * Value "1" if at least one ADC instance sharing the same ADC common instance + * is enabled. + */ +#if defined(ADC1) && defined(ADC2) && defined(ADC3) +#define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ + (((__ADCXY_COMMON__) == ADC12_COMMON) \ + ? ( \ + (LL_ADC_IsEnabled(ADC1) | \ + LL_ADC_IsEnabled(ADC2) ) \ + ) \ + : \ + ( \ + LL_ADC_IsEnabled(ADC3) \ + ) \ + ) +#elif defined(ADC1) && defined(ADC2) +#define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ + (LL_ADC_IsEnabled(ADC1) | \ + LL_ADC_IsEnabled(ADC2) ) +#else +#define __LL_ADC_IS_ENABLED_ALL_COMMON_INSTANCE(__ADCXY_COMMON__) \ + LL_ADC_IsEnabled(ADC1) +#endif + +/** + * @brief Helper macro to define the ADC conversion data full-scale digital + * value corresponding to the selected ADC resolution. + * @note ADC conversion data full-scale corresponds to voltage range + * determined by analog voltage references Vref+ and Vref- + * (refer to reference manual). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \ + (0xFFFU) + + +/** + * @brief Helper macro to calculate the voltage (unit: mVolt) + * corresponding to a ADC conversion data (unit: digital value). + * @note Analog reference voltage (Vref+) must be known from + * user board environment or can be calculated using ADC measurement. + * @param __VREFANALOG_VOLTAGE__ Analog reference voltage (unit: mV) + * @param __ADC_DATA__ ADC conversion data (resolution 12 bits) + * (unit: digital value). + * @param __ADC_RESOLUTION__ This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @retval ADC conversion data equivalent voltage value (unit: mVolt) + */ +#define __LL_ADC_CALC_DATA_TO_VOLTAGE(__VREFANALOG_VOLTAGE__,\ + __ADC_DATA__,\ + __ADC_RESOLUTION__) \ + ((__ADC_DATA__) * (__VREFANALOG_VOLTAGE__) \ + / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__) \ + ) + + +/** + * @brief Helper macro to calculate the temperature (unit: degree Celsius) + * from ADC conversion data of internal temperature sensor. + * @note Computation is using temperature sensor typical values + * (refer to device datasheet). + * @note Calculation formula: + * Temperature = (TS_TYP_CALx_VOLT(uV) - TS_ADC_DATA * Conversion_uV) + * / Avg_Slope + CALx_TEMP + * with TS_ADC_DATA = temperature sensor raw data measured by ADC + * (unit: digital value) + * Avg_Slope = temperature sensor slope + * (unit: uV/Degree Celsius) + * TS_TYP_CALx_VOLT = temperature sensor digital value at + * temperature CALx_TEMP (unit: mV) + * Caution: Calculation relevancy under reserve the temperature sensor + * of the current device has characteristics in line with + * datasheet typical values. + * If temperature sensor calibration values are available on + * on this device (presence of macro __LL_ADC_CALC_TEMPERATURE()), + * temperature calculation will be more accurate using + * helper macro @ref __LL_ADC_CALC_TEMPERATURE(). + * @note As calculation input, the analog reference voltage (Vref+) must be + * defined as it impacts the ADC LSB equivalent voltage. + * @note Analog reference voltage (Vref+) must be known from + * user board environment or can be calculated using ADC measurement. + * @note ADC measurement data must correspond to a resolution of 12bits + * (full scale digital value 4095). If not the case, the data must be + * preliminarily rescaled to an equivalent resolution of 12 bits. + * @param __TEMPSENSOR_TYP_AVGSLOPE__ Device datasheet data: Temperature sensor slope typical value (unit: uV/DegCelsius). + * On STM32F1, refer to device datasheet parameter "Avg_Slope". + * @param __TEMPSENSOR_TYP_CALX_V__ Device datasheet data: Temperature sensor voltage typical value (at temperature and Vref+ defined in parameters below) (unit: mV). + * On STM32F1, refer to device datasheet parameter "V25". + * @param __TEMPSENSOR_CALX_TEMP__ Device datasheet data: Temperature at which temperature sensor voltage (see parameter above) is corresponding (unit: mV) + * @param __VREFANALOG_VOLTAGE__ Analog voltage reference (Vref+) voltage (unit: mV) + * @param __TEMPSENSOR_ADC_DATA__ ADC conversion data of internal temperature sensor (unit: digital value). + * @param __ADC_RESOLUTION__ ADC resolution at which internal temperature sensor voltage has been measured. + * This parameter can be one of the following values: + * @arg @ref LL_ADC_RESOLUTION_12B + * @retval Temperature (unit: degree Celsius) + */ +#define __LL_ADC_CALC_TEMPERATURE_TYP_PARAMS(__TEMPSENSOR_TYP_AVGSLOPE__,\ + __TEMPSENSOR_TYP_CALX_V__,\ + __TEMPSENSOR_CALX_TEMP__,\ + __VREFANALOG_VOLTAGE__,\ + __TEMPSENSOR_ADC_DATA__,\ + __ADC_RESOLUTION__) \ + ((( ( \ + (int32_t)(((__TEMPSENSOR_TYP_CALX_V__)) \ + * 1000) \ + - \ + (int32_t)((((__TEMPSENSOR_ADC_DATA__) * (__VREFANALOG_VOLTAGE__)) \ + / __LL_ADC_DIGITAL_SCALE(__ADC_RESOLUTION__)) \ + * 1000) \ + ) \ + ) / (__TEMPSENSOR_TYP_AVGSLOPE__) \ + ) + (__TEMPSENSOR_CALX_TEMP__) \ + ) + +/** + * @} + */ + +/** + * @} + */ + + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup ADC_LL_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADC_LL_EF_DMA_Management ADC DMA management + * @{ + */ +/* Note: LL ADC functions to set DMA transfer are located into sections of */ +/* configuration of ADC instance, groups and multimode (if available): */ +/* @ref LL_ADC_REG_SetDMATransfer(), ... */ + +/** + * @brief Function to help to configure DMA transfer from ADC: retrieve the + * ADC register address from ADC instance and a list of ADC registers + * intended to be used (most commonly) with DMA transfer. + * @note These ADC registers are data registers: + * when ADC conversion data is available in ADC data registers, + * ADC generates a DMA transfer request. + * @note This macro is intended to be used with LL DMA driver, refer to + * function "LL_DMA_ConfigAddresses()". + * Example: + * LL_DMA_ConfigAddresses(DMA1, + * LL_DMA_CHANNEL_1, + * LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA), + * (uint32_t)&< array or variable >, + * LL_DMA_DIRECTION_PERIPH_TO_MEMORY); + * @note For devices with several ADC: in multimode, some devices + * use a different data register outside of ADC instance scope + * (common data register). This macro manages this register difference, + * only ADC instance has to be set as parameter. + * @note On STM32F1, only ADC instances ADC1 and ADC3 have DMA transfer + * capability, not ADC2 (ADC2 and ADC3 instances not available on + * all devices). + * @note On STM32F1, multimode can be used only with ADC1 and ADC2, not ADC3. + * Therefore, the corresponding parameter of data transfer + * for multimode can be used only with ADC1 and ADC2. + * (ADC2 and ADC3 instances not available on all devices). + * @rmtoll DR DATA LL_ADC_DMA_GetRegAddr + * @param ADCx ADC instance + * @param Register This parameter can be one of the following values: + * @arg @ref LL_ADC_DMA_REG_REGULAR_DATA + * @arg @ref LL_ADC_DMA_REG_REGULAR_DATA_MULTI (1) + * + * (1) Available on devices with several ADC instances. + * @retval ADC register address + */ +#if defined(ADC_MULTIMODE_SUPPORT) +__STATIC_INLINE uint32_t LL_ADC_DMA_GetRegAddr(ADC_TypeDef *ADCx, uint32_t Register) +{ + uint32_t data_reg_addr = 0U; + + if (Register == LL_ADC_DMA_REG_REGULAR_DATA) + { + /* Retrieve address of register DR */ + data_reg_addr = (uint32_t)&(ADCx->DR); + } + else /* (Register == LL_ADC_DMA_REG_REGULAR_DATA_MULTI) */ + { + /* Retrieve address of register of multimode data */ + data_reg_addr = (uint32_t)&(ADC12_COMMON->DR); + } + + return data_reg_addr; +} +#else +__STATIC_INLINE uint32_t LL_ADC_DMA_GetRegAddr(ADC_TypeDef *ADCx, uint32_t Register) +{ + /* Retrieve address of register DR */ + return (uint32_t)&(ADCx->DR); +} +#endif + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Common Configuration of ADC hierarchical scope: common to several ADC instances + * @{ + */ + +/** + * @brief Set parameter common to several ADC: measurement path to internal + * channels (VrefInt, temperature sensor, ...). + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * @note Stabilization time of measurement path to internal channel: + * After enabling internal paths, before starting ADC conversion, + * a delay is required for internal voltage reference and + * temperature sensor stabilization time. + * Refer to device datasheet. + * Refer to literal @ref LL_ADC_DELAY_TEMPSENSOR_STAB_US. + * @note ADC internal channel sampling time constraint: + * For ADC conversion of internal channels, + * a sampling time minimum value is required. + * Refer to device datasheet. + * @rmtoll CR2 TSVREFE LL_ADC_SetCommonPathInternalCh + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param PathInternal This parameter can be a combination of the following values: + * @arg @ref LL_ADC_PATH_INTERNAL_NONE + * @arg @ref LL_ADC_PATH_INTERNAL_VREFINT + * @arg @ref LL_ADC_PATH_INTERNAL_TEMPSENSOR + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetCommonPathInternalCh(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t PathInternal) +{ + MODIFY_REG(ADCxy_COMMON->CR2, (ADC_CR2_TSVREFE), PathInternal); +} + +/** + * @brief Get parameter common to several ADC: measurement path to internal + * channels (VrefInt, temperature sensor, ...). + * @note One or several values can be selected. + * Example: (LL_ADC_PATH_INTERNAL_VREFINT | + * LL_ADC_PATH_INTERNAL_TEMPSENSOR) + * @rmtoll CR2 TSVREFE LL_ADC_GetCommonPathInternalCh + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be a combination of the following values: + * @arg @ref LL_ADC_PATH_INTERNAL_NONE + * @arg @ref LL_ADC_PATH_INTERNAL_VREFINT + * @arg @ref LL_ADC_PATH_INTERNAL_TEMPSENSOR + */ +__STATIC_INLINE uint32_t LL_ADC_GetCommonPathInternalCh(ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CR2, ADC_CR2_TSVREFE)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Instance Configuration of ADC hierarchical scope: ADC instance + * @{ + */ + +/** + * @brief Set ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CR2 ALIGN LL_ADC_SetDataAlignment + * @param ADCx ADC instance + * @param DataAlignment This parameter can be one of the following values: + * @arg @ref LL_ADC_DATA_ALIGN_RIGHT + * @arg @ref LL_ADC_DATA_ALIGN_LEFT + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetDataAlignment(ADC_TypeDef *ADCx, uint32_t DataAlignment) +{ + MODIFY_REG(ADCx->CR2, ADC_CR2_ALIGN, DataAlignment); +} + +/** + * @brief Get ADC conversion data alignment. + * @note Refer to reference manual for alignments formats + * dependencies to ADC resolutions. + * @rmtoll CR2 ALIGN LL_ADC_SetDataAlignment + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_DATA_ALIGN_RIGHT + * @arg @ref LL_ADC_DATA_ALIGN_LEFT + */ +__STATIC_INLINE uint32_t LL_ADC_GetDataAlignment(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_ALIGN)); +} + +/** + * @brief Set ADC sequencers scan mode, for all ADC groups + * (group regular, group injected). + * @note According to sequencers scan mode : + * - If disabled: ADC conversion is performed in unitary conversion + * mode (one channel converted, that defined in rank 1). + * Configuration of sequencers of all ADC groups + * (sequencer scan length, ...) is discarded: equivalent to + * scan length of 1 rank. + * - If enabled: ADC conversions are performed in sequence conversions + * mode, according to configuration of sequencers of + * each ADC group (sequencer scan length, ...). + * Refer to function @ref LL_ADC_REG_SetSequencerLength() + * and to function @ref LL_ADC_INJ_SetSequencerLength(). + * @rmtoll CR1 SCAN LL_ADC_SetSequencersScanMode + * @param ADCx ADC instance + * @param ScanMode This parameter can be one of the following values: + * @arg @ref LL_ADC_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_SEQ_SCAN_ENABLE + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetSequencersScanMode(ADC_TypeDef *ADCx, uint32_t ScanMode) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_SCAN, ScanMode); +} + +/** + * @brief Get ADC sequencers scan mode, for all ADC groups + * (group regular, group injected). + * @note According to sequencers scan mode : + * - If disabled: ADC conversion is performed in unitary conversion + * mode (one channel converted, that defined in rank 1). + * Configuration of sequencers of all ADC groups + * (sequencer scan length, ...) is discarded: equivalent to + * scan length of 1 rank. + * - If enabled: ADC conversions are performed in sequence conversions + * mode, according to configuration of sequencers of + * each ADC group (sequencer scan length, ...). + * Refer to function @ref LL_ADC_REG_SetSequencerLength() + * and to function @ref LL_ADC_INJ_SetSequencerLength(). + * @rmtoll CR1 SCAN LL_ADC_GetSequencersScanMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_SEQ_SCAN_ENABLE + */ +__STATIC_INLINE uint32_t LL_ADC_GetSequencersScanMode(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_SCAN)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Group_Regular Configuration of ADC hierarchical scope: group regular + * @{ + */ + +/** + * @brief Set ADC group regular conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note On this STM32 series, external trigger is set with trigger polarity: + * rising edge (only trigger polarity available on this STM32 series). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 EXTSEL LL_ADC_REG_SetTriggerSource + * @param ADCx ADC instance + * @param TriggerSource This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_SOFTWARE + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH3 (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH1 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH2 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH2 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_CH4 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE11 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO (2)(4) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO_ADC3 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_CH1 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH3 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_CH1 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH1 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH3 (3) + * + * (1) On STM32F1, parameter available on all ADC instances: ADC1, ADC2, ADC3 (for ADC instances ADCx available on the selected device).\n + * (2) On STM32F1, parameter available only on ADC instances: ADC1, ADC2 (for ADC instances ADCx available on the selected device).\n + * (3) On STM32F1, parameter available only on ADC instances: ADC3 (for ADC instances ADCx available on the selected device).\n + * (4) On STM32F1, parameter available only on high-density and XL-density devices. A remap of trigger must be done at top level (refer to AFIO peripheral). + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetTriggerSource(ADC_TypeDef *ADCx, uint32_t TriggerSource) +{ +/* Note: On this STM32 series, ADC group regular external trigger edge */ +/* is used to perform a ADC conversion start. */ +/* This function does not set external trigger edge. */ +/* This feature is set using function */ +/* @ref LL_ADC_REG_StartConversionExtTrig(). */ + MODIFY_REG(ADCx->CR2, ADC_CR2_EXTSEL, (TriggerSource & ADC_CR2_EXTSEL)); +} + +/** + * @brief Get ADC group regular conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note To determine whether group regular trigger source is + * internal (SW start) or external, without detail + * of which peripheral is selected as external trigger, + * (equivalent to + * "if(LL_ADC_REG_GetTriggerSource(ADC1) == LL_ADC_REG_TRIG_SOFTWARE)") + * use function @ref LL_ADC_REG_IsTriggerSourceSWStart. + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 EXTSEL LL_ADC_REG_GetTriggerSource + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_SOFTWARE + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH3 (1) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH1 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM1_CH2 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH2 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_TRGO (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM4_CH4 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_EXTI_LINE11 (2) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO (2)(4) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO_ADC3 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM3_CH1 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM2_CH3 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_CH1 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM8_TRGO (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH1 (3) + * @arg @ref LL_ADC_REG_TRIG_EXT_TIM5_CH3 (3) + * + * (1) On STM32F1, parameter available on all ADC instances: ADC1, ADC2, ADC3 (for ADC instances ADCx available on the selected device).\n + * (2) On STM32F1, parameter available only on ADC instances: ADC1, ADC2 (for ADC instances ADCx available on the selected device).\n + * (3) On STM32F1, parameter available only on ADC instances: ADC3 (for ADC instances ADCx available on the selected device).\n + * (4) On STM32F1, parameter available only on high-density and XL-density devices. A remap of trigger must be done at top level (refer to AFIO peripheral). + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetTriggerSource(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_EXTSEL)); +} + +/** + * @brief Get ADC group regular conversion trigger source internal (SW start) + or external. + * @note In case of group regular trigger source set to external trigger, + * to determine which peripheral is selected as external trigger, + * use function @ref LL_ADC_REG_GetTriggerSource(). + * @rmtoll CR2 EXTSEL LL_ADC_REG_IsTriggerSourceSWStart + * @param ADCx ADC instance + * @retval Value "0" if trigger source external trigger + * Value "1" if trigger source SW start. + */ +__STATIC_INLINE uint32_t LL_ADC_REG_IsTriggerSourceSWStart(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR2, ADC_CR2_EXTSEL) == (LL_ADC_REG_TRIG_SOFTWARE)); +} + + +/** + * @brief Set ADC group regular sequencer length and scan direction. + * @note Description of ADC group regular sequencer features: + * - For devices with sequencer fully configurable + * (function "LL_ADC_REG_SetSequencerRanks()" available): + * sequencer length and each rank affectation to a channel + * are configurable. + * This function performs configuration of: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerRanks()". + * - For devices with sequencer not fully configurable + * (function "LL_ADC_REG_SetSequencerChannels()" available): + * sequencer length and each rank affectation to a channel + * are defined by channel number. + * This function performs configuration of: + * - Sequence length: Number of ranks in the scan sequence is + * defined by number of channels set in the sequence, + * rank of each channel is fixed by channel HW number. + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from lowest channel number to + * highest channel number). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerChannels()". + * @note On this STM32 series, group regular sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll SQR1 L LL_ADC_REG_SetSequencerLength + * @param ADCx ADC instance + * @param SequencerNbRanks This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetSequencerLength(ADC_TypeDef *ADCx, uint32_t SequencerNbRanks) +{ + MODIFY_REG(ADCx->SQR1, ADC_SQR1_L, SequencerNbRanks); +} + +/** + * @brief Get ADC group regular sequencer length and scan direction. + * @note Description of ADC group regular sequencer features: + * - For devices with sequencer fully configurable + * (function "LL_ADC_REG_SetSequencerRanks()" available): + * sequencer length and each rank affectation to a channel + * are configurable. + * This function retrieves: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerRanks()". + * - For devices with sequencer not fully configurable + * (function "LL_ADC_REG_SetSequencerChannels()" available): + * sequencer length and each rank affectation to a channel + * are defined by channel number. + * This function retrieves: + * - Sequence length: Number of ranks in the scan sequence is + * defined by number of channels set in the sequence, + * rank of each channel is fixed by channel HW number. + * (channel 0 fixed on rank 0, channel 1 fixed on rank1, ...). + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from lowest channel number to + * highest channel number). + * Sequencer ranks are selected using + * function "LL_ADC_REG_SetSequencerChannels()". + * @note On this STM32 series, group regular sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll SQR1 L LL_ADC_REG_SetSequencerLength + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_5RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_6RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_7RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_8RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_9RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_10RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_11RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_12RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_13RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_14RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_15RANKS + * @arg @ref LL_ADC_REG_SEQ_SCAN_ENABLE_16RANKS + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerLength(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->SQR1, ADC_SQR1_L)); +} + +/** + * @brief Set ADC group regular sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @note It is not possible to enable both ADC group regular + * continuous mode and sequencer discontinuous mode. + * @note It is not possible to enable both ADC auto-injected mode + * and ADC group regular sequencer discontinuous mode. + * @rmtoll CR1 DISCEN LL_ADC_REG_SetSequencerDiscont\n + * CR1 DISCNUM LL_ADC_REG_SetSequencerDiscont + * @param ADCx ADC instance + * @param SeqDiscont This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_REG_SEQ_DISCONT_1RANK + * @arg @ref LL_ADC_REG_SEQ_DISCONT_2RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_3RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_4RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_5RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_6RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_7RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_8RANKS + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetSequencerDiscont(ADC_TypeDef *ADCx, uint32_t SeqDiscont) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_DISCEN | ADC_CR1_DISCNUM, SeqDiscont); +} + +/** + * @brief Get ADC group regular sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @rmtoll CR1 DISCEN LL_ADC_REG_GetSequencerDiscont\n + * CR1 DISCNUM LL_ADC_REG_GetSequencerDiscont + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_REG_SEQ_DISCONT_1RANK + * @arg @ref LL_ADC_REG_SEQ_DISCONT_2RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_3RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_4RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_5RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_6RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_7RANKS + * @arg @ref LL_ADC_REG_SEQ_DISCONT_8RANKS + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerDiscont(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_DISCEN | ADC_CR1_DISCNUM)); +} + +/** + * @brief Set ADC group regular sequence: channel on the selected + * scan sequence rank. + * @note This function performs configuration of: + * - Channels ordering into each rank of scan sequence: + * whatever channel can be placed into whatever rank. + * @note On this STM32 series, ADC group regular sequencer is + * fully configurable: sequencer length and each rank + * affectation to a channel are configurable. + * Refer to description of function @ref LL_ADC_REG_SetSequencerLength(). + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @rmtoll SQR3 SQ1 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ2 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ3 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ4 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ5 LL_ADC_REG_SetSequencerRanks\n + * SQR3 SQ6 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ7 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ8 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ9 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ10 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ11 LL_ADC_REG_SetSequencerRanks\n + * SQR2 SQ12 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ13 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ14 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ15 LL_ADC_REG_SetSequencerRanks\n + * SQR1 SQ16 LL_ADC_REG_SetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_RANK_1 + * @arg @ref LL_ADC_REG_RANK_2 + * @arg @ref LL_ADC_REG_RANK_3 + * @arg @ref LL_ADC_REG_RANK_4 + * @arg @ref LL_ADC_REG_RANK_5 + * @arg @ref LL_ADC_REG_RANK_6 + * @arg @ref LL_ADC_REG_RANK_7 + * @arg @ref LL_ADC_REG_RANK_8 + * @arg @ref LL_ADC_REG_RANK_9 + * @arg @ref LL_ADC_REG_RANK_10 + * @arg @ref LL_ADC_REG_RANK_11 + * @arg @ref LL_ADC_REG_RANK_12 + * @arg @ref LL_ADC_REG_RANK_13 + * @arg @ref LL_ADC_REG_RANK_14 + * @arg @ref LL_ADC_REG_RANK_15 + * @arg @ref LL_ADC_REG_RANK_16 + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetSequencerRanks(ADC_TypeDef *ADCx, uint32_t Rank, uint32_t Channel) +{ + /* Set bits with content of parameter "Channel" with bits position */ + /* in register and register position depending on parameter "Rank". */ + /* Parameters "Rank" and "Channel" are used with masks because containing */ + /* other bits reserved for other purpose. */ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SQR1, __ADC_MASK_SHIFT(Rank, ADC_REG_SQRX_REGOFFSET_MASK)); + + MODIFY_REG(*preg, + ADC_CHANNEL_ID_NUMBER_MASK << (Rank & ADC_REG_RANK_ID_SQRX_MASK), + (Channel & ADC_CHANNEL_ID_NUMBER_MASK) << (Rank & ADC_REG_RANK_ID_SQRX_MASK)); +} + +/** + * @brief Get ADC group regular sequence: channel on the selected + * scan sequence rank. + * @note On this STM32 series, ADC group regular sequencer is + * fully configurable: sequencer length and each rank + * affectation to a channel are configurable. + * Refer to description of function @ref LL_ADC_REG_SetSequencerLength(). + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note Usage of the returned channel number: + * - To reinject this channel into another function LL_ADC_xxx: + * the returned channel number is only partly formatted on definition + * of literals LL_ADC_CHANNEL_x. Therefore, it has to be compared + * with parts of literals LL_ADC_CHANNEL_x or using + * helper macro @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Then the selected literal LL_ADC_CHANNEL_x can be used + * as parameter for another function. + * - To get the channel number in decimal format: + * process the returned value with the helper macro + * @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * @rmtoll SQR3 SQ1 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ2 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ3 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ4 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ5 LL_ADC_REG_GetSequencerRanks\n + * SQR3 SQ6 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ7 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ8 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ9 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ10 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ11 LL_ADC_REG_GetSequencerRanks\n + * SQR2 SQ12 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ13 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ14 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ15 LL_ADC_REG_GetSequencerRanks\n + * SQR1 SQ16 LL_ADC_REG_GetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_RANK_1 + * @arg @ref LL_ADC_REG_RANK_2 + * @arg @ref LL_ADC_REG_RANK_3 + * @arg @ref LL_ADC_REG_RANK_4 + * @arg @ref LL_ADC_REG_RANK_5 + * @arg @ref LL_ADC_REG_RANK_6 + * @arg @ref LL_ADC_REG_RANK_7 + * @arg @ref LL_ADC_REG_RANK_8 + * @arg @ref LL_ADC_REG_RANK_9 + * @arg @ref LL_ADC_REG_RANK_10 + * @arg @ref LL_ADC_REG_RANK_11 + * @arg @ref LL_ADC_REG_RANK_12 + * @arg @ref LL_ADC_REG_RANK_13 + * @arg @ref LL_ADC_REG_RANK_14 + * @arg @ref LL_ADC_REG_RANK_15 + * @arg @ref LL_ADC_REG_RANK_16 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetSequencerRanks(ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SQR1, __ADC_MASK_SHIFT(Rank, ADC_REG_SQRX_REGOFFSET_MASK)); + + return (uint32_t) (READ_BIT(*preg, + ADC_CHANNEL_ID_NUMBER_MASK << (Rank & ADC_REG_RANK_ID_SQRX_MASK)) + >> (Rank & ADC_REG_RANK_ID_SQRX_MASK) + ); +} + +/** + * @brief Set ADC continuous conversion mode on ADC group regular. + * @note Description of ADC continuous conversion mode: + * - single mode: one conversion per trigger + * - continuous mode: after the first trigger, following + * conversions launched successively automatically. + * @note It is not possible to enable both ADC group regular + * continuous mode and sequencer discontinuous mode. + * @rmtoll CR2 CONT LL_ADC_REG_SetContinuousMode + * @param ADCx ADC instance + * @param Continuous This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_CONV_SINGLE + * @arg @ref LL_ADC_REG_CONV_CONTINUOUS + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetContinuousMode(ADC_TypeDef *ADCx, uint32_t Continuous) +{ + MODIFY_REG(ADCx->CR2, ADC_CR2_CONT, Continuous); +} + +/** + * @brief Get ADC continuous conversion mode on ADC group regular. + * @note Description of ADC continuous conversion mode: + * - single mode: one conversion per trigger + * - continuous mode: after the first trigger, following + * conversions launched successively automatically. + * @rmtoll CR2 CONT LL_ADC_REG_GetContinuousMode + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_CONV_SINGLE + * @arg @ref LL_ADC_REG_CONV_CONTINUOUS + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetContinuousMode(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_CONT)); +} + +/** + * @brief Set ADC group regular conversion data transfer: no transfer or + * transfer by DMA, and DMA requests mode. + * @note If transfer by DMA selected, specifies the DMA requests + * mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note To configure DMA source address (peripheral address), + * use function @ref LL_ADC_DMA_GetRegAddr(). + * @rmtoll CR2 DMA LL_ADC_REG_SetDMATransfer + * @param ADCx ADC instance + * @param DMATransfer This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_DMA_TRANSFER_NONE + * @arg @ref LL_ADC_REG_DMA_TRANSFER_UNLIMITED + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_SetDMATransfer(ADC_TypeDef *ADCx, uint32_t DMATransfer) +{ + MODIFY_REG(ADCx->CR2, ADC_CR2_DMA, DMATransfer); +} + +/** + * @brief Get ADC group regular conversion data transfer: no transfer or + * transfer by DMA, and DMA requests mode. + * @note If transfer by DMA selected, specifies the DMA requests + * mode: + * - Limited mode (One shot mode): DMA transfer requests are stopped + * when number of DMA data transfers (number of + * ADC conversions) is reached. + * This ADC mode is intended to be used with DMA mode non-circular. + * - Unlimited mode: DMA transfer requests are unlimited, + * whatever number of DMA data transfers (number of + * ADC conversions). + * This ADC mode is intended to be used with DMA mode circular. + * @note If ADC DMA requests mode is set to unlimited and DMA is set to + * mode non-circular: + * when DMA transfers size will be reached, DMA will stop transfers of + * ADC conversions data ADC will raise an overrun error + * (overrun flag and interruption if enabled). + * @note To configure DMA source address (peripheral address), + * use function @ref LL_ADC_DMA_GetRegAddr(). + * @rmtoll CR2 DMA LL_ADC_REG_GetDMATransfer + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_REG_DMA_TRANSFER_NONE + * @arg @ref LL_ADC_REG_DMA_TRANSFER_UNLIMITED + */ +__STATIC_INLINE uint32_t LL_ADC_REG_GetDMATransfer(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_DMA)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Group_Injected Configuration of ADC hierarchical scope: group injected + * @{ + */ + +/** + * @brief Set ADC group injected conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note On this STM32 series, external trigger is set with trigger polarity: + * rising edge (only trigger polarity available on this STM32 series). + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 JEXTSEL LL_ADC_INJ_SetTriggerSource + * @param ADCx ADC instance + * @param TriggerSource This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_SOFTWARE + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_CH4 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_TRGO (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_CH1 (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH4 (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (2)(4) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4_ADC3 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH3 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH2 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_TRGO (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_CH4 (3) + * + * (1) On STM32F1, parameter available on all ADC instances: ADC1, ADC2, ADC3 (for ADC instances ADCx available on the selected device).\n + * (2) On STM32F1, parameter available only on ADC instances: ADC1, ADC2 (for ADC instances ADCx available on the selected device).\n + * (3) On STM32F1, parameter available only on ADC instances: ADC3 (for ADC instances ADCx available on the selected device).\n + * (4) On STM32F1, parameter available only on high-density and XL-density devices. A remap of trigger must be done at top level (refer to AFIO peripheral). + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetTriggerSource(ADC_TypeDef *ADCx, uint32_t TriggerSource) +{ +/* Note: On this STM32 series, ADC group injected external trigger edge */ +/* is used to perform a ADC conversion start. */ +/* This function does not set external trigger edge. */ +/* This feature is set using function */ +/* @ref LL_ADC_INJ_StartConversionExtTrig(). */ + MODIFY_REG(ADCx->CR2, ADC_CR2_JEXTSEL, (TriggerSource & ADC_CR2_JEXTSEL)); +} + +/** + * @brief Get ADC group injected conversion trigger source: + * internal (SW start) or from external IP (timer event, + * external interrupt line). + * @note To determine whether group injected trigger source is + * internal (SW start) or external, without detail + * of which peripheral is selected as external trigger, + * (equivalent to + * "if(LL_ADC_INJ_GetTriggerSource(ADC1) == LL_ADC_INJ_TRIG_SOFTWARE)") + * use function @ref LL_ADC_INJ_IsTriggerSourceSWStart. + * @note Availability of parameters of trigger sources from timer + * depends on timers availability on the selected device. + * @rmtoll CR2 JEXTSEL LL_ADC_INJ_GetTriggerSource + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_SOFTWARE + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_TRGO (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM1_CH4 (1) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_TRGO (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM2_CH1 (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM3_CH4 (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_TRGO (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_EXTI_LINE15 (2) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (2)(4) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4_ADC3 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM4_CH3 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH2 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM8_CH4 (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_TRGO (3) + * @arg @ref LL_ADC_INJ_TRIG_EXT_TIM5_CH4 (3) + * + * (1) On STM32F1, parameter available on all ADC instances: ADC1, ADC2, ADC3 (for ADC instances ADCx available on the selected device).\n + * (2) On STM32F1, parameter available only on ADC instances: ADC1, ADC2 (for ADC instances ADCx available on the selected device).\n + * (3) On STM32F1, parameter available only on ADC instances: ADC3 (for ADC instances ADCx available on the selected device).\n + * (4) On STM32F1, parameter available only on high-density and XL-density devices. A remap of trigger must be done at top level (refer to AFIO peripheral). + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetTriggerSource(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR2, ADC_CR2_JEXTSEL)); +} + +/** + * @brief Get ADC group injected conversion trigger source internal (SW start) + or external + * @note In case of group injected trigger source set to external trigger, + * to determine which peripheral is selected as external trigger, + * use function @ref LL_ADC_INJ_GetTriggerSource. + * @rmtoll CR2 JEXTSEL LL_ADC_INJ_IsTriggerSourceSWStart + * @param ADCx ADC instance + * @retval Value "0" if trigger source external trigger + * Value "1" if trigger source SW start. + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_IsTriggerSourceSWStart(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR2, ADC_CR2_JEXTSEL) == LL_ADC_INJ_TRIG_SOFTWARE); +} + +/** + * @brief Set ADC group injected sequencer length and scan direction. + * @note This function performs configuration of: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * @note On this STM32 series, group injected sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll JSQR JL LL_ADC_INJ_SetSequencerLength + * @param ADCx ADC instance + * @param SequencerNbRanks This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetSequencerLength(ADC_TypeDef *ADCx, uint32_t SequencerNbRanks) +{ + MODIFY_REG(ADCx->JSQR, ADC_JSQR_JL, SequencerNbRanks); +} + +/** + * @brief Get ADC group injected sequencer length and scan direction. + * @note This function retrieves: + * - Sequence length: Number of ranks in the scan sequence. + * - Sequence direction: Unless specified in parameters, sequencer + * scan direction is forward (from rank 1 to rank n). + * @note On this STM32 series, group injected sequencer configuration + * is conditioned to ADC instance sequencer mode. + * If ADC instance sequencer mode is disabled, sequencers of + * all groups (group regular, group injected) can be configured + * but their execution is disabled (limited to rank 1). + * Refer to function @ref LL_ADC_SetSequencersScanMode(). + * @note Sequencer disabled is equivalent to sequencer of 1 rank: + * ADC conversion on only 1 channel. + * @rmtoll JSQR JL LL_ADC_INJ_GetSequencerLength + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_SCAN_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_2RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_3RANKS + * @arg @ref LL_ADC_INJ_SEQ_SCAN_ENABLE_4RANKS + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetSequencerLength(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->JSQR, ADC_JSQR_JL)); +} + +/** + * @brief Set ADC group injected sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @note It is not possible to enable both ADC group injected + * auto-injected mode and sequencer discontinuous mode. + * @rmtoll CR1 DISCEN LL_ADC_INJ_SetSequencerDiscont + * @param ADCx ADC instance + * @param SeqDiscont This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_1RANK + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetSequencerDiscont(ADC_TypeDef *ADCx, uint32_t SeqDiscont) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_JDISCEN, SeqDiscont); +} + +/** + * @brief Get ADC group injected sequencer discontinuous mode: + * sequence subdivided and scan conversions interrupted every selected + * number of ranks. + * @rmtoll CR1 DISCEN LL_ADC_REG_GetSequencerDiscont + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_DISABLE + * @arg @ref LL_ADC_INJ_SEQ_DISCONT_1RANK + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetSequencerDiscont(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_JDISCEN)); +} + +/** + * @brief Set ADC group injected sequence: channel on the selected + * sequence rank. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note On this STM32 series, to measure internal channels (VrefInt, + * TempSensor, ...), measurement paths to internal channels must be + * enabled separately. + * This can be done using function @ref LL_ADC_SetCommonPathInternalCh(). + * @rmtoll JSQR JSQ1 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ2 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ3 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ4 LL_ADC_INJ_SetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetSequencerRanks(ADC_TypeDef *ADCx, uint32_t Rank, uint32_t Channel) +{ + /* Set bits with content of parameter "Channel" with bits position */ + /* in register depending on parameter "Rank". */ + /* Parameters "Rank" and "Channel" are used with masks because containing */ + /* other bits reserved for other purpose. */ + uint32_t tmpreg1 = (READ_BIT(ADCx->JSQR, ADC_JSQR_JL) >> ADC_JSQR_JL_Pos) + 1U; + + MODIFY_REG(ADCx->JSQR, + ADC_CHANNEL_ID_NUMBER_MASK << (5U * (uint8_t)(((Rank) + 3U) - (tmpreg1))), + (Channel & ADC_CHANNEL_ID_NUMBER_MASK) << (5U * (uint8_t)(((Rank) + 3U) - (tmpreg1)))); +} + +/** + * @brief Get ADC group injected sequence: channel on the selected + * sequence rank. + * @note Depending on devices and packages, some channels may not be available. + * Refer to device datasheet for channels availability. + * @note Usage of the returned channel number: + * - To reinject this channel into another function LL_ADC_xxx: + * the returned channel number is only partly formatted on definition + * of literals LL_ADC_CHANNEL_x. Therefore, it has to be compared + * with parts of literals LL_ADC_CHANNEL_x or using + * helper macro @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Then the selected literal LL_ADC_CHANNEL_x can be used + * as parameter for another function. + * - To get the channel number in decimal format: + * process the returned value with the helper macro + * @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * @rmtoll JSQR JSQ1 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ2 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ3 LL_ADC_INJ_SetSequencerRanks\n + * JSQR JSQ4 LL_ADC_INJ_SetSequencerRanks + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1.\n + * (1) For ADC channel read back from ADC register, + * comparison with internal channel parameter to be done + * using helper macro @ref __LL_ADC_CHANNEL_INTERNAL_TO_EXTERNAL(). + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetSequencerRanks(ADC_TypeDef *ADCx, uint32_t Rank) +{ + uint32_t tmpreg1 = (READ_BIT(ADCx->JSQR, ADC_JSQR_JL) >> ADC_JSQR_JL_Pos) + 1U; + + return (uint32_t)(READ_BIT(ADCx->JSQR, + ADC_CHANNEL_ID_NUMBER_MASK << (5U * (uint8_t)(((Rank) + 3U) - (tmpreg1)))) + >> (5U * (uint8_t)(((Rank) + 3U) - (tmpreg1))) + ); +} + +/** + * @brief Set ADC group injected conversion trigger: + * independent or from ADC group regular. + * @note This mode can be used to extend number of data registers + * updated after one ADC conversion trigger and with data + * permanently kept (not erased by successive conversions of scan of + * ADC sequencer ranks), up to 5 data registers: + * 1 data register on ADC group regular, 4 data registers + * on ADC group injected. + * @note If ADC group injected injected trigger source is set to an + * external trigger, this feature must be must be set to + * independent trigger. + * ADC group injected automatic trigger is compliant only with + * group injected trigger source set to SW start, without any + * further action on ADC group injected conversion start or stop: + * in this case, ADC group injected is controlled only + * from ADC group regular. + * @note It is not possible to enable both ADC group injected + * auto-injected mode and sequencer discontinuous mode. + * @rmtoll CR1 JAUTO LL_ADC_INJ_SetTrigAuto + * @param ADCx ADC instance + * @param TrigAuto This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_INDEPENDENT + * @arg @ref LL_ADC_INJ_TRIG_FROM_GRP_REGULAR + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetTrigAuto(ADC_TypeDef *ADCx, uint32_t TrigAuto) +{ + MODIFY_REG(ADCx->CR1, ADC_CR1_JAUTO, TrigAuto); +} + +/** + * @brief Get ADC group injected conversion trigger: + * independent or from ADC group regular. + * @rmtoll CR1 JAUTO LL_ADC_INJ_GetTrigAuto + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_INDEPENDENT + * @arg @ref LL_ADC_INJ_TRIG_FROM_GRP_REGULAR + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetTrigAuto(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, ADC_CR1_JAUTO)); +} + +/** + * @brief Set ADC group injected offset. + * @note It sets: + * - ADC group injected rank to which the offset programmed + * will be applied + * - Offset level (offset to be subtracted from the raw + * converted data). + * Caution: Offset format is dependent to ADC resolution: + * offset has to be left-aligned on bit 11, the LSB (right bits) + * are set to 0. + * @note Offset cannot be enabled or disabled. + * To emulate offset disabled, set an offset value equal to 0. + * @rmtoll JOFR1 JOFFSET1 LL_ADC_INJ_SetOffset\n + * JOFR2 JOFFSET2 LL_ADC_INJ_SetOffset\n + * JOFR3 JOFFSET3 LL_ADC_INJ_SetOffset\n + * JOFR4 JOFFSET4 LL_ADC_INJ_SetOffset + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @param OffsetLevel Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_SetOffset(ADC_TypeDef *ADCx, uint32_t Rank, uint32_t OffsetLevel) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JOFR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JOFRX_REGOFFSET_MASK)); + + MODIFY_REG(*preg, + ADC_JOFR1_JOFFSET1, + OffsetLevel); +} + +/** + * @brief Get ADC group injected offset. + * @note It gives offset level (offset to be subtracted from the raw converted data). + * Caution: Offset format is dependent to ADC resolution: + * offset has to be left-aligned on bit 11, the LSB (right bits) + * are set to 0. + * @rmtoll JOFR1 JOFFSET1 LL_ADC_INJ_GetOffset\n + * JOFR2 JOFFSET2 LL_ADC_INJ_GetOffset\n + * JOFR3 JOFFSET3 LL_ADC_INJ_GetOffset\n + * JOFR4 JOFFSET4 LL_ADC_INJ_GetOffset + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_GetOffset(ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JOFR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JOFRX_REGOFFSET_MASK)); + + return (uint32_t)(READ_BIT(*preg, + ADC_JOFR1_JOFFSET1) + ); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_Channels Configuration of ADC hierarchical scope: channels + * @{ + */ + +/** + * @brief Set sampling time of the selected ADC channel + * Unit: ADC clock cycles. + * @note On this device, sampling time is on channel scope: independently + * of channel mapped on ADC group regular or injected. + * @note In case of internal channel (VrefInt, TempSensor, ...) to be + * converted: + * sampling time constraints must be respected (sampling time can be + * adjusted in function of ADC clock frequency and sampling time + * setting). + * Refer to device datasheet for timings values (parameters TS_vrefint, + * TS_temp, ...). + * @note Conversion time is the addition of sampling time and processing time. + * Refer to reference manual for ADC processing time of + * this STM32 series. + * @note In case of ADC conversion of internal channel (VrefInt, + * temperature sensor, ...), a sampling time minimum value + * is required. + * Refer to device datasheet. + * @rmtoll SMPR1 SMP17 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP16 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP15 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP14 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP13 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP12 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP11 LL_ADC_SetChannelSamplingTime\n + * SMPR1 SMP10 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP9 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP8 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP7 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP6 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP5 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP4 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP3 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP2 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP1 LL_ADC_SetChannelSamplingTime\n + * SMPR2 SMP0 LL_ADC_SetChannelSamplingTime + * @param ADCx ADC instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @param SamplingTime This parameter can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_1CYCLE_5 + * @arg @ref LL_ADC_SAMPLINGTIME_7CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_13CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_41CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_55CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_71CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_239CYCLES_5 + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetChannelSamplingTime(ADC_TypeDef *ADCx, uint32_t Channel, uint32_t SamplingTime) +{ + /* Set bits with content of parameter "SamplingTime" with bits position */ + /* in register and register position depending on parameter "Channel". */ + /* Parameter "Channel" is used with masks because containing */ + /* other bits reserved for other purpose. */ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SMPR1, __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPRX_REGOFFSET_MASK)); + + MODIFY_REG(*preg, + ADC_SMPR2_SMP0 << __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK), + SamplingTime << __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK)); +} + +/** + * @brief Get sampling time of the selected ADC channel + * Unit: ADC clock cycles. + * @note On this device, sampling time is on channel scope: independently + * of channel mapped on ADC group regular or injected. + * @note Conversion time is the addition of sampling time and processing time. + * Refer to reference manual for ADC processing time of + * this STM32 series. + * @rmtoll SMPR1 SMP17 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP16 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP15 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP14 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP13 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP12 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP11 LL_ADC_GetChannelSamplingTime\n + * SMPR1 SMP10 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP9 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP8 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP7 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP6 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP5 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP4 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP3 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP2 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP1 LL_ADC_GetChannelSamplingTime\n + * SMPR2 SMP0 LL_ADC_GetChannelSamplingTime + * @param ADCx ADC instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_ADC_CHANNEL_0 + * @arg @ref LL_ADC_CHANNEL_1 + * @arg @ref LL_ADC_CHANNEL_2 + * @arg @ref LL_ADC_CHANNEL_3 + * @arg @ref LL_ADC_CHANNEL_4 + * @arg @ref LL_ADC_CHANNEL_5 + * @arg @ref LL_ADC_CHANNEL_6 + * @arg @ref LL_ADC_CHANNEL_7 + * @arg @ref LL_ADC_CHANNEL_8 + * @arg @ref LL_ADC_CHANNEL_9 + * @arg @ref LL_ADC_CHANNEL_10 + * @arg @ref LL_ADC_CHANNEL_11 + * @arg @ref LL_ADC_CHANNEL_12 + * @arg @ref LL_ADC_CHANNEL_13 + * @arg @ref LL_ADC_CHANNEL_14 + * @arg @ref LL_ADC_CHANNEL_15 + * @arg @ref LL_ADC_CHANNEL_16 + * @arg @ref LL_ADC_CHANNEL_17 + * @arg @ref LL_ADC_CHANNEL_VREFINT (1) + * @arg @ref LL_ADC_CHANNEL_TEMPSENSOR (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_SAMPLINGTIME_1CYCLE_5 + * @arg @ref LL_ADC_SAMPLINGTIME_7CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_13CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_28CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_41CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_55CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_71CYCLES_5 + * @arg @ref LL_ADC_SAMPLINGTIME_239CYCLES_5 + */ +__STATIC_INLINE uint32_t LL_ADC_GetChannelSamplingTime(ADC_TypeDef *ADCx, uint32_t Channel) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->SMPR1, __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPRX_REGOFFSET_MASK)); + + return (uint32_t)(READ_BIT(*preg, + ADC_SMPR2_SMP0 << __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK)) + >> __ADC_MASK_SHIFT(Channel, ADC_CHANNEL_SMPx_BITOFFSET_MASK) + ); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_AnalogWatchdog Configuration of ADC transversal scope: analog watchdog + * @{ + */ + +/** + * @brief Set ADC analog watchdog monitored channels: + * a single channel or all channels, + * on ADC groups regular and-or injected. + * @note Once monitored channels are selected, analog watchdog + * is enabled. + * @note In case of need to define a single channel to monitor + * with analog watchdog from sequencer channel definition, + * use helper macro @ref __LL_ADC_ANALOGWD_CHANNEL_GROUP(). + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC groups regular and-or injected. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @rmtoll CR1 AWD1CH LL_ADC_SetAnalogWDMonitChannels\n + * CR1 AWD1SGL LL_ADC_SetAnalogWDMonitChannels\n + * CR1 AWD1EN LL_ADC_SetAnalogWDMonitChannels + * @param ADCx ADC instance + * @param AWDChannelGroup This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_INJ (1) + * @arg @ref LL_ADC_AWD_CH_VREFINT_REG_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_INJ (1) + * @arg @ref LL_ADC_AWD_CH_TEMPSENSOR_REG_INJ (1) + * + * (1) On STM32F1, parameter available only on ADC instance: ADC1. + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetAnalogWDMonitChannels(ADC_TypeDef *ADCx, uint32_t AWDChannelGroup) +{ + MODIFY_REG(ADCx->CR1, + (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL | ADC_CR1_AWDCH), + AWDChannelGroup); +} + +/** + * @brief Get ADC analog watchdog monitored channel. + * @note Usage of the returned channel number: + * - To reinject this channel into another function LL_ADC_xxx: + * the returned channel number is only partly formatted on definition + * of literals LL_ADC_CHANNEL_x. Therefore, it has to be compared + * with parts of literals LL_ADC_CHANNEL_x or using + * helper macro @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Then the selected literal LL_ADC_CHANNEL_x can be used + * as parameter for another function. + * - To get the channel number in decimal format: + * process the returned value with the helper macro + * @ref __LL_ADC_CHANNEL_TO_DECIMAL_NB(). + * Applicable only when the analog watchdog is set to monitor + * one channel. + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC groups regular and-or injected. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @rmtoll CR1 AWD1CH LL_ADC_GetAnalogWDMonitChannels\n + * CR1 AWD1SGL LL_ADC_GetAnalogWDMonitChannels\n + * CR1 AWD1EN LL_ADC_GetAnalogWDMonitChannels + * @param ADCx ADC instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_AWD_DISABLE + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_INJ + * @arg @ref LL_ADC_AWD_ALL_CHANNELS_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG + * @arg @ref LL_ADC_AWD_CHANNEL_0_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_0_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG + * @arg @ref LL_ADC_AWD_CHANNEL_1_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_1_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG + * @arg @ref LL_ADC_AWD_CHANNEL_2_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_2_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG + * @arg @ref LL_ADC_AWD_CHANNEL_3_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_3_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG + * @arg @ref LL_ADC_AWD_CHANNEL_4_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_4_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG + * @arg @ref LL_ADC_AWD_CHANNEL_5_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_5_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG + * @arg @ref LL_ADC_AWD_CHANNEL_6_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_6_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG + * @arg @ref LL_ADC_AWD_CHANNEL_7_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_7_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG + * @arg @ref LL_ADC_AWD_CHANNEL_8_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_8_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG + * @arg @ref LL_ADC_AWD_CHANNEL_9_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_9_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG + * @arg @ref LL_ADC_AWD_CHANNEL_10_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_10_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG + * @arg @ref LL_ADC_AWD_CHANNEL_11_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_11_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG + * @arg @ref LL_ADC_AWD_CHANNEL_12_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_12_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG + * @arg @ref LL_ADC_AWD_CHANNEL_13_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_13_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG + * @arg @ref LL_ADC_AWD_CHANNEL_14_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_14_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG + * @arg @ref LL_ADC_AWD_CHANNEL_15_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_15_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG + * @arg @ref LL_ADC_AWD_CHANNEL_16_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_16_REG_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG + * @arg @ref LL_ADC_AWD_CHANNEL_17_INJ + * @arg @ref LL_ADC_AWD_CHANNEL_17_REG_INJ + */ +__STATIC_INLINE uint32_t LL_ADC_GetAnalogWDMonitChannels(ADC_TypeDef *ADCx) +{ + return (uint32_t)(READ_BIT(ADCx->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_AWDSGL | ADC_CR1_AWDCH))); +} + +/** + * @brief Set ADC analog watchdog threshold value of threshold + * high or low. + * @note On this STM32 series, there is only 1 kind of analog watchdog + * instance: + * - AWD standard (instance AWD1): + * - channels monitored: can monitor 1 channel or all channels. + * - groups monitored: ADC groups regular and-or injected. + * - resolution: resolution is not limited (corresponds to + * ADC resolution configured). + * @rmtoll HTR HT LL_ADC_SetAnalogWDThresholds\n + * LTR LT LL_ADC_SetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDThresholdsHighLow This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @param AWDThresholdValue: Value between Min_Data=0x000 and Max_Data=0xFFF + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetAnalogWDThresholds(ADC_TypeDef *ADCx, uint32_t AWDThresholdsHighLow, uint32_t AWDThresholdValue) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->HTR, AWDThresholdsHighLow); + + MODIFY_REG(*preg, + ADC_HTR_HT, + AWDThresholdValue); +} + +/** + * @brief Get ADC analog watchdog threshold value of threshold high or + * threshold low. + * @note In case of ADC resolution different of 12 bits, + * analog watchdog thresholds data require a specific shift. + * Use helper macro @ref __LL_ADC_ANALOGWD_GET_THRESHOLD_RESOLUTION(). + * @rmtoll HTR HT LL_ADC_GetAnalogWDThresholds\n + * LTR LT LL_ADC_GetAnalogWDThresholds + * @param ADCx ADC instance + * @param AWDThresholdsHighLow This parameter can be one of the following values: + * @arg @ref LL_ADC_AWD_THRESHOLD_HIGH + * @arg @ref LL_ADC_AWD_THRESHOLD_LOW + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF +*/ +__STATIC_INLINE uint32_t LL_ADC_GetAnalogWDThresholds(ADC_TypeDef *ADCx, uint32_t AWDThresholdsHighLow) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->HTR, AWDThresholdsHighLow); + + return (uint32_t)(READ_BIT(*preg, ADC_HTR_HT)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Configuration_ADC_Multimode Configuration of ADC hierarchical scope: multimode + * @{ + */ + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Set ADC multimode configuration to operate in independent mode + * or multimode (for devices with several ADC instances). + * @note If multimode configuration: the selected ADC instance is + * either master or slave depending on hardware. + * Refer to reference manual. + * @rmtoll CR1 DUALMOD LL_ADC_SetMultimode + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param Multimode This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_INDEPENDENT + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTERL_FAST + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTERL_SLOW + * @arg @ref LL_ADC_MULTI_DUAL_INJ_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_INJ_ALTERN + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTFAST_INJ_SIM + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTSLOW_INJ_SIM + * @retval None + */ +__STATIC_INLINE void LL_ADC_SetMultimode(ADC_Common_TypeDef *ADCxy_COMMON, uint32_t Multimode) +{ + MODIFY_REG(ADCxy_COMMON->CR1, ADC_CR1_DUALMOD, Multimode); +} + +/** + * @brief Get ADC multimode configuration to operate in independent mode + * or multimode (for devices with several ADC instances). + * @note If multimode configuration: the selected ADC instance is + * either master or slave depending on hardware. + * Refer to reference manual. + * @rmtoll CR1 DUALMOD LL_ADC_GetMultimode + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval Returned value can be one of the following values: + * @arg @ref LL_ADC_MULTI_INDEPENDENT + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTERL_FAST + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTERL_SLOW + * @arg @ref LL_ADC_MULTI_DUAL_INJ_SIMULT + * @arg @ref LL_ADC_MULTI_DUAL_INJ_ALTERN + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_SIM + * @arg @ref LL_ADC_MULTI_DUAL_REG_SIM_INJ_ALT + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTFAST_INJ_SIM + * @arg @ref LL_ADC_MULTI_DUAL_REG_INTSLOW_INJ_SIM + */ +__STATIC_INLINE uint32_t LL_ADC_GetMultimode(ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (uint32_t)(READ_BIT(ADCxy_COMMON->CR1, ADC_CR1_DUALMOD)); +} + +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ +/** @defgroup ADC_LL_EF_Operation_ADC_Instance Operation on ADC hierarchical scope: ADC instance + * @{ + */ + +/** + * @brief Enable the selected ADC instance. + * @note On this STM32 series, after ADC enable, a delay for + * ADC internal analog stabilization is required before performing a + * ADC conversion start. + * Refer to device datasheet, parameter tSTAB. + * @rmtoll CR2 ADON LL_ADC_Enable + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_Enable(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR2, ADC_CR2_ADON); +} + +/** + * @brief Disable the selected ADC instance. + * @rmtoll CR2 ADON LL_ADC_Disable + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_Disable(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR2, ADC_CR2_ADON); +} + +/** + * @brief Get the selected ADC instance enable state. + * @rmtoll CR2 ADON LL_ADC_IsEnabled + * @param ADCx ADC instance + * @retval 0: ADC is disabled, 1: ADC is enabled. + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabled(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR2, ADC_CR2_ADON) == (ADC_CR2_ADON)); +} + +/** + * @brief Start ADC calibration in the mode single-ended + * or differential (for devices with differential mode available). + * @note On this STM32 series, before starting a calibration, + * ADC must be disabled. + * A minimum number of ADC clock cycles are required + * between ADC disable state and calibration start. + * Refer to literal @ref LL_ADC_DELAY_DISABLE_CALIB_ADC_CYCLES. + * @note On this STM32 series, hardware prerequisite before starting a calibration: + the ADC must have been in power-on state for at least + two ADC clock cycles. + * @rmtoll CR2 CAL LL_ADC_StartCalibration + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_StartCalibration(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR2, ADC_CR2_CAL); +} + +/** + * @brief Get ADC calibration state. + * @rmtoll CR2 CAL LL_ADC_IsCalibrationOnGoing + * @param ADCx ADC instance + * @retval 0: calibration complete, 1: calibration in progress. + */ +__STATIC_INLINE uint32_t LL_ADC_IsCalibrationOnGoing(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR2, ADC_CR2_CAL) == (ADC_CR2_CAL)); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Operation_ADC_Group_Regular Operation on ADC hierarchical scope: group regular + * @{ + */ + +/** + * @brief Start ADC group regular conversion. + * @note On this STM32 series, this function is relevant only for + * internal trigger (SW start), not for external trigger: + * - If ADC trigger has been set to software start, ADC conversion + * starts immediately. + * - If ADC trigger has been set to external trigger, ADC conversion + * start must be performed using function + * @ref LL_ADC_REG_StartConversionExtTrig(). + * (if external trigger edge would have been set during ADC other + * settings, ADC conversion would start at trigger event + * as soon as ADC is enabled). + * @rmtoll CR2 SWSTART LL_ADC_REG_StartConversionSWStart + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StartConversionSWStart(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG)); +} + +/** + * @brief Start ADC group regular conversion from external trigger. + * @note ADC conversion will start at next trigger event (on the selected + * trigger edge) following the ADC start conversion command. + * @note On this STM32 series, this function is relevant for + * ADC conversion start from external trigger. + * If internal trigger (SW start) is needed, perform ADC conversion + * start using function @ref LL_ADC_REG_StartConversionSWStart(). + * @rmtoll CR2 EXTEN LL_ADC_REG_StartConversionExtTrig + * @param ExternalTriggerEdge This parameter can be one of the following values: + * @arg @ref LL_ADC_REG_TRIG_EXT_RISING + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StartConversionExtTrig(ADC_TypeDef *ADCx, uint32_t ExternalTriggerEdge) +{ + SET_BIT(ADCx->CR2, ExternalTriggerEdge); +} + +/** + * @brief Stop ADC group regular conversion from external trigger. + * @note No more ADC conversion will start at next trigger event + * following the ADC stop conversion command. + * If a conversion is on-going, it will be completed. + * @note On this STM32 series, there is no specific command + * to stop a conversion on-going or to stop ADC converting + * in continuous mode. These actions can be performed + * using function @ref LL_ADC_Disable(). + * @rmtoll CR2 EXTSEL LL_ADC_REG_StopConversionExtTrig + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_REG_StopConversionExtTrig(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR2, ADC_CR2_EXTTRIG); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * all ADC configurations: all ADC resolutions and + * all oversampling increased data width (for devices + * with feature oversampling). + * @rmtoll DR RDATA LL_ADC_REG_ReadConversionData32 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_ADC_REG_ReadConversionData32(ADC_TypeDef *ADCx) +{ + return (uint16_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * ADC resolution 12 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_REG_ReadConversionData32. + * @rmtoll DR RDATA LL_ADC_REG_ReadConversionData12 + * @param ADCx ADC instance + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint16_t LL_ADC_REG_ReadConversionData12(ADC_TypeDef *ADCx) +{ + return (uint16_t)(READ_BIT(ADCx->DR, ADC_DR_DATA)); +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Get ADC multimode conversion data of ADC master, ADC slave + * or raw data with ADC master and slave concatenated. + * @note If raw data with ADC master and slave concatenated is retrieved, + * a macro is available to get the conversion data of + * ADC master or ADC slave: see helper macro + * @ref __LL_ADC_MULTI_CONV_DATA_MASTER_SLAVE(). + * (however this macro is mainly intended for multimode + * transfer by DMA, because this function can do the same + * by getting multimode conversion data of ADC master or ADC slave + * separately). + * @rmtoll DR DATA LL_ADC_REG_ReadMultiConversionData32\n + * DR ADC2DATA LL_ADC_REG_ReadMultiConversionData32 + * @param ADCx ADC instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @param ConversionData This parameter can be one of the following values: + * @arg @ref LL_ADC_MULTI_MASTER + * @arg @ref LL_ADC_MULTI_SLAVE + * @arg @ref LL_ADC_MULTI_MASTER_SLAVE + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_ADC_REG_ReadMultiConversionData32(ADC_TypeDef *ADCx, uint32_t ConversionData) +{ + return (uint32_t)(READ_BIT(ADCx->DR, + ADC_DR_ADC2DATA) + >> POSITION_VAL(ConversionData) + ); +} +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_Operation_ADC_Group_Injected Operation on ADC hierarchical scope: group injected + * @{ + */ + +/** + * @brief Start ADC group injected conversion. + * @note On this STM32 series, this function is relevant only for + * internal trigger (SW start), not for external trigger: + * - If ADC trigger has been set to software start, ADC conversion + * starts immediately. + * - If ADC trigger has been set to external trigger, ADC conversion + * start must be performed using function + * @ref LL_ADC_INJ_StartConversionExtTrig(). + * (if external trigger edge would have been set during ADC other + * settings, ADC conversion would start at trigger event + * as soon as ADC is enabled). + * @rmtoll CR2 JSWSTART LL_ADC_INJ_StartConversionSWStart + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StartConversionSWStart(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG)); +} + +/** + * @brief Start ADC group injected conversion from external trigger. + * @note ADC conversion will start at next trigger event (on the selected + * trigger edge) following the ADC start conversion command. + * @note On this STM32 series, this function is relevant for + * ADC conversion start from external trigger. + * If internal trigger (SW start) is needed, perform ADC conversion + * start using function @ref LL_ADC_INJ_StartConversionSWStart(). + * @rmtoll CR2 JEXTEN LL_ADC_INJ_StartConversionExtTrig + * @param ExternalTriggerEdge This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_TRIG_EXT_RISING + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StartConversionExtTrig(ADC_TypeDef *ADCx, uint32_t ExternalTriggerEdge) +{ + SET_BIT(ADCx->CR2, ExternalTriggerEdge); +} + +/** + * @brief Stop ADC group injected conversion from external trigger. + * @note No more ADC conversion will start at next trigger event + * following the ADC stop conversion command. + * If a conversion is on-going, it will be completed. + * @note On this STM32 series, there is no specific command + * to stop a conversion on-going or to stop ADC converting + * in continuous mode. These actions can be performed + * using function @ref LL_ADC_Disable(). + * @rmtoll CR2 JEXTSEL LL_ADC_INJ_StopConversionExtTrig + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_INJ_StopConversionExtTrig(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR2, ADC_CR2_JEXTTRIG); +} + +/** + * @brief Get ADC group regular conversion data, range fit for + * all ADC configurations: all ADC resolutions and + * all oversampling increased data width (for devices + * with feature oversampling). + * @rmtoll JDR1 JDATA LL_ADC_INJ_ReadConversionData32\n + * JDR2 JDATA LL_ADC_INJ_ReadConversionData32\n + * JDR3 JDATA LL_ADC_INJ_ReadConversionData32\n + * JDR4 JDATA LL_ADC_INJ_ReadConversionData32 + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x00000000 and Max_Data=0xFFFFFFFF + */ +__STATIC_INLINE uint32_t LL_ADC_INJ_ReadConversionData32(ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JDRX_REGOFFSET_MASK)); + + return (uint32_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @brief Get ADC group injected conversion data, range fit for + * ADC resolution 12 bits. + * @note For devices with feature oversampling: Oversampling + * can increase data width, function for extended range + * may be needed: @ref LL_ADC_INJ_ReadConversionData32. + * @rmtoll JDR1 JDATA LL_ADC_INJ_ReadConversionData12\n + * JDR2 JDATA LL_ADC_INJ_ReadConversionData12\n + * JDR3 JDATA LL_ADC_INJ_ReadConversionData12\n + * JDR4 JDATA LL_ADC_INJ_ReadConversionData12 + * @param ADCx ADC instance + * @param Rank This parameter can be one of the following values: + * @arg @ref LL_ADC_INJ_RANK_1 + * @arg @ref LL_ADC_INJ_RANK_2 + * @arg @ref LL_ADC_INJ_RANK_3 + * @arg @ref LL_ADC_INJ_RANK_4 + * @retval Value between Min_Data=0x000 and Max_Data=0xFFF + */ +__STATIC_INLINE uint16_t LL_ADC_INJ_ReadConversionData12(ADC_TypeDef *ADCx, uint32_t Rank) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCx->JDR1, __ADC_MASK_SHIFT(Rank, ADC_INJ_JDRX_REGOFFSET_MASK)); + + return (uint16_t)(READ_BIT(*preg, + ADC_JDR1_JDATA) + ); +} + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_FLAG_Management ADC flag management + * @{ + */ + +/** + * @brief Get flag ADC group regular end of sequence conversions. + * @rmtoll SR EOC LL_ADC_IsActiveFlag_EOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_EOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group regular */ + /* end of unitary conversion. */ + /* Flag noted as "EOC" is corresponding to flag "EOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCx->SR, LL_ADC_FLAG_EOS) == (LL_ADC_FLAG_EOS)); +} + + +/** + * @brief Get flag ADC group injected end of sequence conversions. + * @rmtoll SR JEOC LL_ADC_IsActiveFlag_JEOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCx->SR, LL_ADC_FLAG_JEOS) == (LL_ADC_FLAG_JEOS)); +} + +/** + * @brief Get flag ADC analog watchdog 1 flag + * @rmtoll SR AWD LL_ADC_IsActiveFlag_AWD1 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_AWD1(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->SR, LL_ADC_FLAG_AWD1) == (LL_ADC_FLAG_AWD1)); +} + +/** + * @brief Clear flag ADC group regular end of sequence conversions. + * @rmtoll SR EOC LL_ADC_ClearFlag_EOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_EOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group regular */ + /* end of unitary conversion. */ + /* Flag noted as "EOC" is corresponding to flag "EOS" */ + /* in other STM32 families). */ + WRITE_REG(ADCx->SR, ~LL_ADC_FLAG_EOS); +} + + +/** + * @brief Clear flag ADC group injected end of sequence conversions. + * @rmtoll SR JEOC LL_ADC_ClearFlag_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + WRITE_REG(ADCx->SR, ~LL_ADC_FLAG_JEOS); +} + +/** + * @brief Clear flag ADC analog watchdog 1. + * @rmtoll SR AWD LL_ADC_ClearFlag_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_ClearFlag_AWD1(ADC_TypeDef *ADCx) +{ + WRITE_REG(ADCx->SR, ~LL_ADC_FLAG_AWD1); +} + +#if defined(ADC_MULTIMODE_SUPPORT) +/** + * @brief Get flag multimode ADC group regular end of sequence conversions of the ADC master. + * @rmtoll SR EOC LL_ADC_IsActiveFlag_MST_EOS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_MST_EOS(ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Note: on this STM32 series, there is no flag ADC group regular */ + /* end of unitary conversion. */ + /* Flag noted as "EOC" is corresponding to flag "EOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCxy_COMMON->SR, ADC_SR_EOC) == (ADC_SR_EOC)); +} + +/** + * @brief Get flag multimode ADC group regular end of sequence conversions of the ADC slave. + * @rmtoll SR EOC LL_ADC_IsActiveFlag_SLV_EOS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV_EOS(ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Note: on this STM32 series, there is no flag ADC group regular */ + /* end of unitary conversion. */ + /* Flag noted as "EOC" is corresponding to flag "EOS" */ + /* in other STM32 families). */ + + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCxy_COMMON->SR, 1U); + + return (READ_BIT(*preg, LL_ADC_FLAG_EOS_SLV) == (LL_ADC_FLAG_EOS_SLV)); +} + + +/** + * @brief Get flag multimode ADC group injected end of sequence conversions of the ADC master. + * @rmtoll SR JEOC LL_ADC_IsActiveFlag_MST_JEOS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_MST_JEOS(ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCxy_COMMON->SR, ADC_SR_JEOC) == (ADC_SR_JEOC)); +} + +/** + * @brief Get flag multimode ADC group injected end of sequence conversions of the ADC slave. + * @rmtoll SR JEOC LL_ADC_IsActiveFlag_SLV_JEOS + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV_JEOS(ADC_Common_TypeDef *ADCxy_COMMON) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCxy_COMMON->SR, 1U); + + return (READ_BIT(*preg, LL_ADC_FLAG_JEOS_SLV) == (LL_ADC_FLAG_JEOS_SLV)); +} + +/** + * @brief Get flag multimode ADC analog watchdog 1 of the ADC master. + * @rmtoll SR AWD LL_ADC_IsActiveFlag_MST_AWD1 + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_MST_AWD1(ADC_Common_TypeDef *ADCxy_COMMON) +{ + return (READ_BIT(ADCxy_COMMON->SR, LL_ADC_FLAG_AWD1) == (LL_ADC_FLAG_AWD1)); +} + +/** + * @brief Get flag multimode analog watchdog 1 of the ADC slave. + * @rmtoll SR AWD LL_ADC_IsActiveFlag_SLV_AWD1 + * @param ADCxy_COMMON ADC common instance + * (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() ) + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsActiveFlag_SLV_AWD1(ADC_Common_TypeDef *ADCxy_COMMON) +{ + __IO uint32_t *preg = __ADC_PTR_REG_OFFSET(ADCxy_COMMON->SR, 1U); + + return (READ_BIT(*preg, LL_ADC_FLAG_AWD1) == (LL_ADC_FLAG_AWD1)); +} + +#endif /* ADC_MULTIMODE_SUPPORT */ + +/** + * @} + */ + +/** @defgroup ADC_LL_EF_IT_Management ADC IT management + * @{ + */ + +/** + * @brief Enable interruption ADC group regular end of sequence conversions. + * @rmtoll CR1 EOCIE LL_ADC_EnableIT_EOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_EOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group regular */ + /* end of unitary conversion. */ + /* Flag noted as "EOC" is corresponding to flag "EOS" */ + /* in other STM32 families). */ + SET_BIT(ADCx->CR1, ADC_CR1_EOCIE); +} + + +/** + * @brief Enable interruption ADC group injected end of sequence conversions. + * @rmtoll CR1 JEOCIE LL_ADC_EnableIT_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + SET_BIT(ADCx->CR1, LL_ADC_IT_JEOS); +} + +/** + * @brief Enable interruption ADC analog watchdog 1. + * @rmtoll CR1 AWDIE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_EnableIT_AWD1(ADC_TypeDef *ADCx) +{ + SET_BIT(ADCx->CR1, LL_ADC_IT_AWD1); +} + +/** + * @brief Disable interruption ADC group regular end of sequence conversions. + * @rmtoll CR1 EOCIE LL_ADC_DisableIT_EOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_EOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group regular */ + /* end of unitary conversion. */ + /* Flag noted as "EOC" is corresponding to flag "EOS" */ + /* in other STM32 families). */ + CLEAR_BIT(ADCx->CR1, ADC_CR1_EOCIE); +} + + +/** + * @brief Disable interruption ADC group injected end of sequence conversions. + * @rmtoll CR1 JEOCIE LL_ADC_EnableIT_JEOS + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + CLEAR_BIT(ADCx->CR1, LL_ADC_IT_JEOS); +} + +/** + * @brief Disable interruption ADC analog watchdog 1. + * @rmtoll CR1 AWDIE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval None + */ +__STATIC_INLINE void LL_ADC_DisableIT_AWD1(ADC_TypeDef *ADCx) +{ + CLEAR_BIT(ADCx->CR1, LL_ADC_IT_AWD1); +} + +/** + * @brief Get state of interruption ADC group regular end of sequence conversions + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll CR1 EOCIE LL_ADC_IsEnabledIT_EOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_EOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group regular */ + /* end of unitary conversion. */ + /* Flag noted as "EOC" is corresponding to flag "EOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCx->CR1, LL_ADC_IT_EOS) == (LL_ADC_IT_EOS)); +} + + +/** + * @brief Get state of interruption ADC group injected end of sequence conversions + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll CR1 JEOCIE LL_ADC_EnableIT_JEOS + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_JEOS(ADC_TypeDef *ADCx) +{ + /* Note: on this STM32 series, there is no flag ADC group injected */ + /* end of unitary conversion. */ + /* Flag noted as "JEOC" is corresponding to flag "JEOS" */ + /* in other STM32 families). */ + return (READ_BIT(ADCx->CR1, LL_ADC_IT_JEOS) == (LL_ADC_IT_JEOS)); +} + +/** + * @brief Get state of interruption ADC analog watchdog 1 + * (0: interrupt disabled, 1: interrupt enabled). + * @rmtoll CR1 AWDIE LL_ADC_EnableIT_AWD1 + * @param ADCx ADC instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_ADC_IsEnabledIT_AWD1(ADC_TypeDef *ADCx) +{ + return (READ_BIT(ADCx->CR1, LL_ADC_IT_AWD1) == (LL_ADC_IT_AWD1)); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup ADC_LL_EF_Init Initialization and de-initialization functions + * @{ + */ + +/* Initialization of some features of ADC common parameters and multimode */ +ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON); +ErrorStatus LL_ADC_CommonInit(ADC_Common_TypeDef *ADCxy_COMMON, LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct); +void LL_ADC_CommonStructInit(LL_ADC_CommonInitTypeDef *ADC_CommonInitStruct); + +/* De-initialization of ADC instance, ADC group regular and ADC group injected */ +/* (availability of ADC group injected depends on STM32 families) */ +ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx); + +/* Initialization of some features of ADC instance */ +ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct); +void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct); + +/* Initialization of some features of ADC instance and ADC group regular */ +ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct); +void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct); + +/* Initialization of some features of ADC instance and ADC group injected */ +ErrorStatus LL_ADC_INJ_Init(ADC_TypeDef *ADCx, LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct); +void LL_ADC_INJ_StructInit(LL_ADC_INJ_InitTypeDef *ADC_INJ_InitStruct); + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* ADC1 || ADC2 || ADC3 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F1xx_LL_ADC_H */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_tim.h b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_tim.h new file mode 100644 index 0000000..d54a00e --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_ll_tim.h @@ -0,0 +1,3901 @@ +/** + ****************************************************************************** + * @file stm32f1xx_ll_tim.h + * @author MCD Application Team + * @brief Header file of TIM LL module. + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F1xx_LL_TIM_H +#define __STM32F1xx_LL_TIM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx.h" + +/** @addtogroup STM32F1xx_LL_Driver + * @{ + */ + +#if defined (TIM1) || defined (TIM2) || defined (TIM3) || defined (TIM4) || defined (TIM5) || defined (TIM6) || defined (TIM7) || defined (TIM8) || defined (TIM9) || defined (TIM10) || defined (TIM11) || defined (TIM12) || defined (TIM13) || defined (TIM14) || defined (TIM15) || defined (TIM16) || defined (TIM17) + +/** @defgroup TIM_LL TIM + * @{ + */ + +/* Private types -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Variables TIM Private Variables + * @{ + */ +static const uint8_t OFFSET_TAB_CCMRx[] = +{ + 0x00U, /* 0: TIMx_CH1 */ + 0x00U, /* 1: TIMx_CH1N */ + 0x00U, /* 2: TIMx_CH2 */ + 0x00U, /* 3: TIMx_CH2N */ + 0x04U, /* 4: TIMx_CH3 */ + 0x04U, /* 5: TIMx_CH3N */ + 0x04U /* 6: TIMx_CH4 */ +}; + +static const uint8_t SHIFT_TAB_OCxx[] = +{ + 0U, /* 0: OC1M, OC1FE, OC1PE */ + 0U, /* 1: - NA */ + 8U, /* 2: OC2M, OC2FE, OC2PE */ + 0U, /* 3: - NA */ + 0U, /* 4: OC3M, OC3FE, OC3PE */ + 0U, /* 5: - NA */ + 8U /* 6: OC4M, OC4FE, OC4PE */ +}; + +static const uint8_t SHIFT_TAB_ICxx[] = +{ + 0U, /* 0: CC1S, IC1PSC, IC1F */ + 0U, /* 1: - NA */ + 8U, /* 2: CC2S, IC2PSC, IC2F */ + 0U, /* 3: - NA */ + 0U, /* 4: CC3S, IC3PSC, IC3F */ + 0U, /* 5: - NA */ + 8U /* 6: CC4S, IC4PSC, IC4F */ +}; + +static const uint8_t SHIFT_TAB_CCxP[] = +{ + 0U, /* 0: CC1P */ + 2U, /* 1: CC1NP */ + 4U, /* 2: CC2P */ + 6U, /* 3: CC2NP */ + 8U, /* 4: CC3P */ + 10U, /* 5: CC3NP */ + 12U /* 6: CC4P */ +}; + +static const uint8_t SHIFT_TAB_OISx[] = +{ + 0U, /* 0: OIS1 */ + 1U, /* 1: OIS1N */ + 2U, /* 2: OIS2 */ + 3U, /* 3: OIS2N */ + 4U, /* 4: OIS3 */ + 5U, /* 5: OIS3N */ + 6U /* 6: OIS4 */ +}; +/** + * @} + */ + +/* Private constants ---------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Constants TIM Private Constants + * @{ + */ + + + +/* Mask used to set the TDG[x:0] of the DTG bits of the TIMx_BDTR register */ +#define DT_DELAY_1 ((uint8_t)0x7F) +#define DT_DELAY_2 ((uint8_t)0x3F) +#define DT_DELAY_3 ((uint8_t)0x1F) +#define DT_DELAY_4 ((uint8_t)0x1F) + +/* Mask used to set the DTG[7:5] bits of the DTG bits of the TIMx_BDTR register */ +#define DT_RANGE_1 ((uint8_t)0x00) +#define DT_RANGE_2 ((uint8_t)0x80) +#define DT_RANGE_3 ((uint8_t)0xC0) +#define DT_RANGE_4 ((uint8_t)0xE0) + + +/** + * @} + */ + +/* Private macros ------------------------------------------------------------*/ +/** @defgroup TIM_LL_Private_Macros TIM Private Macros + * @{ + */ +/** @brief Convert channel id into channel index. + * @param __CHANNEL__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval none + */ +#define TIM_GET_CHANNEL_INDEX( __CHANNEL__) \ + (((__CHANNEL__) == LL_TIM_CHANNEL_CH1) ? 0U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH1N) ? 1U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH2) ? 2U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH2N) ? 3U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH3) ? 4U :\ + ((__CHANNEL__) == LL_TIM_CHANNEL_CH3N) ? 5U : 6U) + +/** @brief Calculate the deadtime sampling period(in ps). + * @param __TIMCLK__ timer input clock frequency (in Hz). + * @param __CKD__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @retval none + */ +#define TIM_CALC_DTS(__TIMCLK__, __CKD__) \ + (((__CKD__) == LL_TIM_CLOCKDIVISION_DIV1) ? ((uint64_t)1000000000000U/(__TIMCLK__)) : \ + ((__CKD__) == LL_TIM_CLOCKDIVISION_DIV2) ? ((uint64_t)1000000000000U/((__TIMCLK__) >> 1U)) : \ + ((uint64_t)1000000000000U/((__TIMCLK__) >> 2U))) +/** + * @} + */ + + +/* Exported types ------------------------------------------------------------*/ +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_ES_INIT TIM Exported Init structure + * @{ + */ + +/** + * @brief TIM Time Base configuration structure definition. + */ +typedef struct +{ + uint16_t Prescaler; /*!< Specifies the prescaler value used to divide the TIM clock. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetPrescaler().*/ + + uint32_t CounterMode; /*!< Specifies the counter mode. + This parameter can be a value of @ref TIM_LL_EC_COUNTERMODE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetCounterMode().*/ + + uint32_t Autoreload; /*!< Specifies the auto reload value to be loaded into the active + Auto-Reload Register at the next update event. + This parameter must be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + Some timer instances may support 32 bits counters. In that case this parameter must + be a number between 0x0000 and 0xFFFFFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetAutoReload().*/ + + uint32_t ClockDivision; /*!< Specifies the clock division. + This parameter can be a value of @ref TIM_LL_EC_CLOCKDIVISION. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetClockDivision().*/ + + uint32_t RepetitionCounter; /*!< Specifies the repetition counter value. Each time the RCR downcounter + reaches zero, an update event is generated and counting restarts + from the RCR value (N). + This means in PWM mode that (N+1) corresponds to: + - the number of PWM periods in edge-aligned mode + - the number of half PWM period in center-aligned mode + GP timers: this parameter must be a number between Min_Data = 0x00 and + Max_Data = 0xFF. + Advanced timers: this parameter must be a number between Min_Data = 0x0000 and + Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetRepetitionCounter().*/ +} LL_TIM_InitTypeDef; + +/** + * @brief TIM Output Compare configuration structure definition. + */ +typedef struct +{ + uint32_t OCMode; /*!< Specifies the output mode. + This parameter can be a value of @ref TIM_LL_EC_OCMODE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetMode().*/ + + uint32_t OCState; /*!< Specifies the TIM Output Compare state. + This parameter can be a value of @ref TIM_LL_EC_OCSTATE. + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_CC_EnableChannel() or @ref LL_TIM_CC_DisableChannel().*/ + + uint32_t OCNState; /*!< Specifies the TIM complementary Output Compare state. + This parameter can be a value of @ref TIM_LL_EC_OCSTATE. + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_CC_EnableChannel() or @ref LL_TIM_CC_DisableChannel().*/ + + uint32_t CompareValue; /*!< Specifies the Compare value to be loaded into the Capture Compare Register. + This parameter can be a number between Min_Data=0x0000 and Max_Data=0xFFFF. + + This feature can be modified afterwards using unitary function + LL_TIM_OC_SetCompareCHx (x=1..6).*/ + + uint32_t OCPolarity; /*!< Specifies the output polarity. + This parameter can be a value of @ref TIM_LL_EC_OCPOLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetPolarity().*/ + + uint32_t OCNPolarity; /*!< Specifies the complementary output polarity. + This parameter can be a value of @ref TIM_LL_EC_OCPOLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetPolarity().*/ + + + uint32_t OCIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetIdleState().*/ + + uint32_t OCNIdleState; /*!< Specifies the TIM Output Compare pin state during Idle state. + This parameter can be a value of @ref TIM_LL_EC_OCIDLESTATE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetIdleState().*/ +} LL_TIM_OC_InitTypeDef; + +/** + * @brief TIM Input Capture configuration structure definition. + */ + +typedef struct +{ + + uint32_t ICPolarity; /*!< Specifies the active edge of the input signal. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t ICActiveInput; /*!< Specifies the input. + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t ICPrescaler; /*!< Specifies the Input Capture Prescaler. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t ICFilter; /*!< Specifies the input capture filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ +} LL_TIM_IC_InitTypeDef; + + +/** + * @brief TIM Encoder interface configuration structure definition. + */ +typedef struct +{ + uint32_t EncoderMode; /*!< Specifies the encoder resolution (x2 or x4). + This parameter can be a value of @ref TIM_LL_EC_ENCODERMODE. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetEncoderMode().*/ + + uint32_t IC1Polarity; /*!< Specifies the active edge of TI1 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC1ActiveInput; /*!< Specifies the TI1 input source + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC1Filter; /*!< Specifies the TI1 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + + uint32_t IC2Polarity; /*!< Specifies the active edge of TI2 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC2ActiveInput; /*!< Specifies the TI2 input source + This parameter can be a value of @ref TIM_LL_EC_ACTIVEINPUT. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetActiveInput().*/ + + uint32_t IC2Prescaler; /*!< Specifies the TI2 input prescaler value. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC2Filter; /*!< Specifies the TI2 input filter. + This parameter can be a value of @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + +} LL_TIM_ENCODER_InitTypeDef; + +/** + * @brief TIM Hall sensor interface configuration structure definition. + */ +typedef struct +{ + + uint32_t IC1Polarity; /*!< Specifies the active edge of TI1 input. + This parameter can be a value of @ref TIM_LL_EC_IC_POLARITY. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPolarity().*/ + + uint32_t IC1Prescaler; /*!< Specifies the TI1 input prescaler value. + Prescaler must be set to get a maximum counter period longer than the + time interval between 2 consecutive changes on the Hall inputs. + This parameter can be a value of @ref TIM_LL_EC_ICPSC. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetPrescaler().*/ + + uint32_t IC1Filter; /*!< Specifies the TI1 input filter. + This parameter can be a value of + @ref TIM_LL_EC_IC_FILTER. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_IC_SetFilter().*/ + + uint32_t CommutationDelay; /*!< Specifies the compare value to be loaded into the Capture Compare Register. + A positive pulse (TRGO event) is generated with a programmable delay every time + a change occurs on the Hall inputs. + This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetCompareCH2().*/ +} LL_TIM_HALLSENSOR_InitTypeDef; + +/** + * @brief BDTR (Break and Dead Time) structure definition + */ +typedef struct +{ + uint32_t OSSRState; /*!< Specifies the Off-State selection used in Run mode. + This parameter can be a value of @ref TIM_LL_EC_OSSR + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level 2 has been + programmed. */ + + uint32_t OSSIState; /*!< Specifies the Off-State used in Idle state. + This parameter can be a value of @ref TIM_LL_EC_OSSI + + This feature can be modified afterwards using unitary function + @ref LL_TIM_SetOffStates() + + @note This bit-field cannot be modified as long as LOCK level 2 has been + programmed. */ + + uint32_t LockLevel; /*!< Specifies the LOCK level parameters. + This parameter can be a value of @ref TIM_LL_EC_LOCKLEVEL + + @note The LOCK bits can be written only once after the reset. Once the TIMx_BDTR + register has been written, their content is frozen until the next reset.*/ + + uint8_t DeadTime; /*!< Specifies the delay time between the switching-off and the + switching-on of the outputs. + This parameter can be a number between Min_Data = 0x00 and Max_Data = 0xFF. + + This feature can be modified afterwards using unitary function + @ref LL_TIM_OC_SetDeadTime() + + @note This bit-field can not be modified as long as LOCK level 1, 2 or 3 has been + programmed. */ + + uint16_t BreakState; /*!< Specifies whether the TIM Break input is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_BREAK_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableBRK() or @ref LL_TIM_DisableBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t BreakPolarity; /*!< Specifies the TIM Break Input pin polarity. + This parameter can be a value of @ref TIM_LL_EC_BREAK_POLARITY + + This feature can be modified afterwards using unitary function + @ref LL_TIM_ConfigBRK() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ + + uint32_t AutomaticOutput; /*!< Specifies whether the TIM Automatic Output feature is enabled or not. + This parameter can be a value of @ref TIM_LL_EC_AUTOMATICOUTPUT_ENABLE + + This feature can be modified afterwards using unitary functions + @ref LL_TIM_EnableAutomaticOutput() or @ref LL_TIM_DisableAutomaticOutput() + + @note This bit-field can not be modified as long as LOCK level 1 has been + programmed. */ +} LL_TIM_BDTR_InitTypeDef; + +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/* Exported constants --------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Constants TIM Exported Constants + * @{ + */ + +/** @defgroup TIM_LL_EC_GET_FLAG Get Flags Defines + * @brief Flags defines which can be used with LL_TIM_ReadReg function. + * @{ + */ +#define LL_TIM_SR_UIF TIM_SR_UIF /*!< Update interrupt flag */ +#define LL_TIM_SR_CC1IF TIM_SR_CC1IF /*!< Capture/compare 1 interrupt flag */ +#define LL_TIM_SR_CC2IF TIM_SR_CC2IF /*!< Capture/compare 2 interrupt flag */ +#define LL_TIM_SR_CC3IF TIM_SR_CC3IF /*!< Capture/compare 3 interrupt flag */ +#define LL_TIM_SR_CC4IF TIM_SR_CC4IF /*!< Capture/compare 4 interrupt flag */ +#define LL_TIM_SR_COMIF TIM_SR_COMIF /*!< COM interrupt flag */ +#define LL_TIM_SR_TIF TIM_SR_TIF /*!< Trigger interrupt flag */ +#define LL_TIM_SR_BIF TIM_SR_BIF /*!< Break interrupt flag */ +#define LL_TIM_SR_CC1OF TIM_SR_CC1OF /*!< Capture/Compare 1 overcapture flag */ +#define LL_TIM_SR_CC2OF TIM_SR_CC2OF /*!< Capture/Compare 2 overcapture flag */ +#define LL_TIM_SR_CC3OF TIM_SR_CC3OF /*!< Capture/Compare 3 overcapture flag */ +#define LL_TIM_SR_CC4OF TIM_SR_CC4OF /*!< Capture/Compare 4 overcapture flag */ +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EC_BREAK_ENABLE Break Enable + * @{ + */ +#define LL_TIM_BREAK_DISABLE 0x00000000U /*!< Break function disabled */ +#define LL_TIM_BREAK_ENABLE TIM_BDTR_BKE /*!< Break function enabled */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_AUTOMATICOUTPUT_ENABLE Automatic output enable + * @{ + */ +#define LL_TIM_AUTOMATICOUTPUT_DISABLE 0x00000000U /*!< MOE can be set only by software */ +#define LL_TIM_AUTOMATICOUTPUT_ENABLE TIM_BDTR_AOE /*!< MOE can be set by software or automatically at the next update event */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup TIM_LL_EC_IT IT Defines + * @brief IT defines which can be used with LL_TIM_ReadReg and LL_TIM_WriteReg functions. + * @{ + */ +#define LL_TIM_DIER_UIE TIM_DIER_UIE /*!< Update interrupt enable */ +#define LL_TIM_DIER_CC1IE TIM_DIER_CC1IE /*!< Capture/compare 1 interrupt enable */ +#define LL_TIM_DIER_CC2IE TIM_DIER_CC2IE /*!< Capture/compare 2 interrupt enable */ +#define LL_TIM_DIER_CC3IE TIM_DIER_CC3IE /*!< Capture/compare 3 interrupt enable */ +#define LL_TIM_DIER_CC4IE TIM_DIER_CC4IE /*!< Capture/compare 4 interrupt enable */ +#define LL_TIM_DIER_COMIE TIM_DIER_COMIE /*!< COM interrupt enable */ +#define LL_TIM_DIER_TIE TIM_DIER_TIE /*!< Trigger interrupt enable */ +#define LL_TIM_DIER_BIE TIM_DIER_BIE /*!< Break interrupt enable */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_UPDATESOURCE Update Source + * @{ + */ +#define LL_TIM_UPDATESOURCE_REGULAR 0x00000000U /*!< Counter overflow/underflow, Setting the UG bit or Update generation through the slave mode controller generates an update request */ +#define LL_TIM_UPDATESOURCE_COUNTER TIM_CR1_URS /*!< Only counter overflow/underflow generates an update request */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_ONEPULSEMODE One Pulse Mode + * @{ + */ +#define LL_TIM_ONEPULSEMODE_SINGLE TIM_CR1_OPM /*!< Counter stops counting at the next update event */ +#define LL_TIM_ONEPULSEMODE_REPETITIVE 0x00000000U /*!< Counter is not stopped at update event */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_COUNTERMODE Counter Mode + * @{ + */ +#define LL_TIM_COUNTERMODE_UP 0x00000000U /*!< Counter used as upcounter */ +#define LL_TIM_COUNTERMODE_DOWN TIM_CR1_DIR /*!< Counter used as downcounter */ +#define LL_TIM_COUNTERMODE_CENTER_DOWN TIM_CR1_CMS_0 /*!< The counter counts up and down alternatively. Output compare interrupt flags of output channels are set only when the counter is counting down. */ +#define LL_TIM_COUNTERMODE_CENTER_UP TIM_CR1_CMS_1 /*!< The counter counts up and down alternatively. Output compare interrupt flags of output channels are set only when the counter is counting up */ +#define LL_TIM_COUNTERMODE_CENTER_UP_DOWN TIM_CR1_CMS /*!< The counter counts up and down alternatively. Output compare interrupt flags of output channels are set only when the counter is counting up or down. */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_CLOCKDIVISION Clock Division + * @{ + */ +#define LL_TIM_CLOCKDIVISION_DIV1 0x00000000U /*!< tDTS=tCK_INT */ +#define LL_TIM_CLOCKDIVISION_DIV2 TIM_CR1_CKD_0 /*!< tDTS=2*tCK_INT */ +#define LL_TIM_CLOCKDIVISION_DIV4 TIM_CR1_CKD_1 /*!< tDTS=4*tCK_INT */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_COUNTERDIRECTION Counter Direction + * @{ + */ +#define LL_TIM_COUNTERDIRECTION_UP 0x00000000U /*!< Timer counter counts up */ +#define LL_TIM_COUNTERDIRECTION_DOWN TIM_CR1_DIR /*!< Timer counter counts down */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_CCUPDATESOURCE Capture Compare Update Source + * @{ + */ +#define LL_TIM_CCUPDATESOURCE_COMG_ONLY 0x00000000U /*!< Capture/compare control bits are updated by setting the COMG bit only */ +#define LL_TIM_CCUPDATESOURCE_COMG_AND_TRGI TIM_CR2_CCUS /*!< Capture/compare control bits are updated by setting the COMG bit or when a rising edge occurs on trigger input (TRGI) */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_CCDMAREQUEST Capture Compare DMA Request + * @{ + */ +#define LL_TIM_CCDMAREQUEST_CC 0x00000000U /*!< CCx DMA request sent when CCx event occurs */ +#define LL_TIM_CCDMAREQUEST_UPDATE TIM_CR2_CCDS /*!< CCx DMA requests sent when update event occurs */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_LOCKLEVEL Lock Level + * @{ + */ +#define LL_TIM_LOCKLEVEL_OFF 0x00000000U /*!< LOCK OFF - No bit is write protected */ +#define LL_TIM_LOCKLEVEL_1 TIM_BDTR_LOCK_0 /*!< LOCK Level 1 */ +#define LL_TIM_LOCKLEVEL_2 TIM_BDTR_LOCK_1 /*!< LOCK Level 2 */ +#define LL_TIM_LOCKLEVEL_3 TIM_BDTR_LOCK /*!< LOCK Level 3 */ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_CHANNEL Channel + * @{ + */ +#define LL_TIM_CHANNEL_CH1 TIM_CCER_CC1E /*!< Timer input/output channel 1 */ +#define LL_TIM_CHANNEL_CH1N TIM_CCER_CC1NE /*!< Timer complementary output channel 1 */ +#define LL_TIM_CHANNEL_CH2 TIM_CCER_CC2E /*!< Timer input/output channel 2 */ +#define LL_TIM_CHANNEL_CH2N TIM_CCER_CC2NE /*!< Timer complementary output channel 2 */ +#define LL_TIM_CHANNEL_CH3 TIM_CCER_CC3E /*!< Timer input/output channel 3 */ +#define LL_TIM_CHANNEL_CH3N TIM_CCER_CC3NE /*!< Timer complementary output channel 3 */ +#define LL_TIM_CHANNEL_CH4 TIM_CCER_CC4E /*!< Timer input/output channel 4 */ +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EC_OCSTATE Output Configuration State + * @{ + */ +#define LL_TIM_OCSTATE_DISABLE 0x00000000U /*!< OCx is not active */ +#define LL_TIM_OCSTATE_ENABLE TIM_CCER_CC1E /*!< OCx signal is output on the corresponding output pin */ +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** @defgroup TIM_LL_EC_OCMODE Output Configuration Mode + * @{ + */ +#define LL_TIM_OCMODE_FROZEN 0x00000000U /*!TIMx_CCRy else active.*/ +#define LL_TIM_OCMODE_PWM2 (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_0) /*!TIMx_CCRy else inactive*/ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_OCPOLARITY Output Configuration Polarity + * @{ + */ +#define LL_TIM_OCPOLARITY_HIGH 0x00000000U /*!< OCxactive high*/ +#define LL_TIM_OCPOLARITY_LOW TIM_CCER_CC1P /*!< OCxactive low*/ +/** + * @} + */ + +/** @defgroup TIM_LL_EC_OCIDLESTATE Output Configuration Idle State + * @{ + */ +#define LL_TIM_OCIDLESTATE_LOW 0x00000000U /*!__REG__, (__VALUE__)) + +/** + * @brief Read a value in TIM register. + * @param __INSTANCE__ TIM Instance + * @param __REG__ Register to be read + * @retval Register value + */ +#define LL_TIM_ReadReg(__INSTANCE__, __REG__) READ_REG((__INSTANCE__)->__REG__) +/** + * @} + */ + +/** + * @brief HELPER macro calculating DTG[0:7] in the TIMx_BDTR register to achieve the requested dead time duration. + * @note ex: @ref __LL_TIM_CALC_DEADTIME (80000000, @ref LL_TIM_GetClockDivision (), 120); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CKD__ This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @param __DT__ deadtime duration (in ns) + * @retval DTG[0:7] + */ +#define __LL_TIM_CALC_DEADTIME(__TIMCLK__, __CKD__, __DT__) \ + ( (((uint64_t)((__DT__)*1000U)) < ((DT_DELAY_1+1U) * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(((uint64_t)((__DT__)*1000U) / TIM_CALC_DTS((__TIMCLK__), (__CKD__))) & DT_DELAY_1) : \ + (((uint64_t)((__DT__)*1000U)) < ((64U + (DT_DELAY_2+1U)) * 2U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_2 | ((uint8_t)((uint8_t)((((uint64_t)((__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 1U) - (uint8_t) 64) & DT_DELAY_2)) :\ + (((uint64_t)((__DT__)*1000U)) < ((32U + (DT_DELAY_3+1U)) * 8U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_3 | ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 3U) - (uint8_t) 32) & DT_DELAY_3)) :\ + (((uint64_t)((__DT__)*1000U)) < ((32U + (DT_DELAY_4+1U)) * 16U * TIM_CALC_DTS((__TIMCLK__), (__CKD__)))) ? \ + (uint8_t)(DT_RANGE_4 | ((uint8_t)((uint8_t)(((((uint64_t)(__DT__)*1000U))/ TIM_CALC_DTS((__TIMCLK__), \ + (__CKD__))) >> 4U) - (uint8_t) 32) & DT_DELAY_4)) :\ + 0U) + +/** + * @brief HELPER macro calculating the prescaler value to achieve the required counter clock frequency. + * @note ex: @ref __LL_TIM_CALC_PSC (80000000, 1000000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __CNTCLK__ counter clock frequency (in Hz) + * @retval Prescaler value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PSC(__TIMCLK__, __CNTCLK__) \ + (((__TIMCLK__) >= (__CNTCLK__)) ? (uint32_t)((((__TIMCLK__) + (__CNTCLK__)/2U)/(__CNTCLK__)) - 1U) : 0U) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required output signal frequency. + * @note ex: @ref __LL_TIM_CALC_ARR (1000000, @ref LL_TIM_GetPrescaler (), 10000); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __FREQ__ output signal frequency (in Hz) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_ARR(__TIMCLK__, __PSC__, __FREQ__) \ + ((((__TIMCLK__)/((__PSC__) + 1U)) >= (__FREQ__)) ? (((__TIMCLK__)/((__FREQ__) * ((__PSC__) + 1U))) - 1U) : 0U) + +/** + * @brief HELPER macro calculating the compare value required to achieve the required timer output compare + * active/inactive delay. + * @note ex: @ref __LL_TIM_CALC_DELAY (1000000, @ref LL_TIM_GetPrescaler (), 10); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @retval Compare value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_DELAY(__TIMCLK__, __PSC__, __DELAY__) \ + ((uint32_t)(((uint64_t)(__TIMCLK__) * (uint64_t)(__DELAY__)) \ + / ((uint64_t)1000000U * (uint64_t)((__PSC__) + 1U)))) + +/** + * @brief HELPER macro calculating the auto-reload value to achieve the required pulse duration + * (when the timer operates in one pulse mode). + * @note ex: @ref __LL_TIM_CALC_PULSE (1000000, @ref LL_TIM_GetPrescaler (), 10, 20); + * @param __TIMCLK__ timer input clock frequency (in Hz) + * @param __PSC__ prescaler + * @param __DELAY__ timer output compare active/inactive delay (in us) + * @param __PULSE__ pulse duration (in us) + * @retval Auto-reload value (between Min_Data=0 and Max_Data=65535) + */ +#define __LL_TIM_CALC_PULSE(__TIMCLK__, __PSC__, __DELAY__, __PULSE__) \ + ((uint32_t)(__LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__PULSE__)) \ + + __LL_TIM_CALC_DELAY((__TIMCLK__), (__PSC__), (__DELAY__)))) + +/** + * @brief HELPER macro retrieving the ratio of the input capture prescaler + * @note ex: @ref __LL_TIM_GET_ICPSC_RATIO (@ref LL_TIM_IC_GetPrescaler ()); + * @param __ICPSC__ This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval Input capture prescaler ratio (1, 2, 4 or 8) + */ +#define __LL_TIM_GET_ICPSC_RATIO(__ICPSC__) \ + ((uint32_t)(0x01U << (((__ICPSC__) >> 16U) >> TIM_CCMR1_IC1PSC_Pos))) + + +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIM_LL_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIM_LL_EF_Time_Base Time Base configuration + * @{ + */ +/** + * @brief Enable timer counter. + * @rmtoll CR1 CEN LL_TIM_EnableCounter + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableCounter(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_CEN); +} + +/** + * @brief Disable timer counter. + * @rmtoll CR1 CEN LL_TIM_DisableCounter + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableCounter(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_CEN); +} + +/** + * @brief Indicates whether the timer counter is enabled. + * @rmtoll CR1 CEN LL_TIM_IsEnabledCounter + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledCounter(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_CEN) == (TIM_CR1_CEN)) ? 1UL : 0UL); +} + +/** + * @brief Enable update event generation. + * @rmtoll CR1 UDIS LL_TIM_EnableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableUpdateEvent(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_UDIS); +} + +/** + * @brief Disable update event generation. + * @rmtoll CR1 UDIS LL_TIM_DisableUpdateEvent + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableUpdateEvent(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_UDIS); +} + +/** + * @brief Indicates whether update event generation is enabled. + * @rmtoll CR1 UDIS LL_TIM_IsEnabledUpdateEvent + * @param TIMx Timer instance + * @retval Inverted state of bit (0 or 1). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledUpdateEvent(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_UDIS) == (uint32_t)RESET) ? 1UL : 0UL); +} + +/** + * @brief Set update event source + * @note Update event source set to LL_TIM_UPDATESOURCE_REGULAR: any of the following events + * generate an update interrupt or DMA request if enabled: + * - Counter overflow/underflow + * - Setting the UG bit + * - Update generation through the slave mode controller + * @note Update event source set to LL_TIM_UPDATESOURCE_COUNTER: only counter + * overflow/underflow generates an update interrupt or DMA request if enabled. + * @rmtoll CR1 URS LL_TIM_SetUpdateSource + * @param TIMx Timer instance + * @param UpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetUpdateSource(TIM_TypeDef *TIMx, uint32_t UpdateSource) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_URS, UpdateSource); +} + +/** + * @brief Get actual event update source + * @rmtoll CR1 URS LL_TIM_GetUpdateSource + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_UPDATESOURCE_REGULAR + * @arg @ref LL_TIM_UPDATESOURCE_COUNTER + */ +__STATIC_INLINE uint32_t LL_TIM_GetUpdateSource(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_URS)); +} + +/** + * @brief Set one pulse mode (one shot v.s. repetitive). + * @rmtoll CR1 OPM LL_TIM_SetOnePulseMode + * @param TIMx Timer instance + * @param OnePulseMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOnePulseMode(TIM_TypeDef *TIMx, uint32_t OnePulseMode) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_OPM, OnePulseMode); +} + +/** + * @brief Get actual one pulse mode. + * @rmtoll CR1 OPM LL_TIM_GetOnePulseMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ONEPULSEMODE_SINGLE + * @arg @ref LL_TIM_ONEPULSEMODE_REPETITIVE + */ +__STATIC_INLINE uint32_t LL_TIM_GetOnePulseMode(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_OPM)); +} + +/** + * @brief Set the timer counter counting mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * @rmtoll CR1 DIR LL_TIM_SetCounterMode\n + * CR1 CMS LL_TIM_SetCounterMode + * @param TIMx Timer instance + * @param CounterMode This parameter can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCounterMode(TIM_TypeDef *TIMx, uint32_t CounterMode) +{ + MODIFY_REG(TIMx->CR1, (TIM_CR1_DIR | TIM_CR1_CMS), CounterMode); +} + +/** + * @brief Get actual counter mode. + * @note Macro IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx) can be used to + * check whether or not the counter mode selection feature is supported + * by a timer instance. + * @rmtoll CR1 DIR LL_TIM_GetCounterMode\n + * CR1 CMS LL_TIM_GetCounterMode + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERMODE_UP + * @arg @ref LL_TIM_COUNTERMODE_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP + * @arg @ref LL_TIM_COUNTERMODE_CENTER_DOWN + * @arg @ref LL_TIM_COUNTERMODE_CENTER_UP_DOWN + */ +__STATIC_INLINE uint32_t LL_TIM_GetCounterMode(const TIM_TypeDef *TIMx) +{ + uint32_t counter_mode; + + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CMS)); + + if (counter_mode == 0U) + { + counter_mode = (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); + } + + return counter_mode; +} + +/** + * @brief Enable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_EnableARRPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableARRPreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR1, TIM_CR1_ARPE); +} + +/** + * @brief Disable auto-reload (ARR) preload. + * @rmtoll CR1 ARPE LL_TIM_DisableARRPreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableARRPreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR1, TIM_CR1_ARPE); +} + +/** + * @brief Indicates whether auto-reload (ARR) preload is enabled. + * @rmtoll CR1 ARPE LL_TIM_IsEnabledARRPreload + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledARRPreload(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR1, TIM_CR1_ARPE) == (TIM_CR1_ARPE)) ? 1UL : 0UL); +} + +/** + * @brief Set the division ratio between the timer clock and the sampling clock used by the dead-time generators + * (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_SetClockDivision + * @param TIMx Timer instance + * @param ClockDivision This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetClockDivision(TIM_TypeDef *TIMx, uint32_t ClockDivision) +{ + MODIFY_REG(TIMx->CR1, TIM_CR1_CKD, ClockDivision); +} + +/** + * @brief Get the actual division ratio between the timer clock and the sampling clock used by the dead-time + * generators (when supported) and the digital filters. + * @note Macro IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx) can be used to check + * whether or not the clock division feature is supported by the timer + * instance. + * @rmtoll CR1 CKD LL_TIM_GetClockDivision + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CLOCKDIVISION_DIV1 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV2 + * @arg @ref LL_TIM_CLOCKDIVISION_DIV4 + */ +__STATIC_INLINE uint32_t LL_TIM_GetClockDivision(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_CKD)); +} + +/** + * @brief Set the counter value. + * @rmtoll CNT CNT LL_TIM_SetCounter + * @param TIMx Timer instance + * @param Counter Counter value (between Min_Data=0 and Max_Data=0xFFFF) + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetCounter(TIM_TypeDef *TIMx, uint32_t Counter) +{ + WRITE_REG(TIMx->CNT, Counter); +} + +/** + * @brief Get the counter value. + * @rmtoll CNT CNT LL_TIM_GetCounter + * @param TIMx Timer instance + * @retval Counter value (between Min_Data=0 and Max_Data=0xFFFF) + */ +__STATIC_INLINE uint32_t LL_TIM_GetCounter(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CNT)); +} + +/** + * @brief Get the current direction of the counter + * @rmtoll CR1 DIR LL_TIM_GetDirection + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_COUNTERDIRECTION_UP + * @arg @ref LL_TIM_COUNTERDIRECTION_DOWN + */ +__STATIC_INLINE uint32_t LL_TIM_GetDirection(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR1, TIM_CR1_DIR)); +} + +/** + * @brief Set the prescaler value. + * @note The counter clock frequency CK_CNT is equal to fCK_PSC / (PSC[15:0] + 1). + * @note The prescaler can be changed on the fly as this control register is buffered. The new + * prescaler ratio is taken into account at the next update event. + * @note Helper macro @ref __LL_TIM_CALC_PSC can be used to calculate the Prescaler parameter + * @rmtoll PSC PSC LL_TIM_SetPrescaler + * @param TIMx Timer instance + * @param Prescaler between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Prescaler) +{ + WRITE_REG(TIMx->PSC, Prescaler); +} + +/** + * @brief Get the prescaler value. + * @rmtoll PSC PSC LL_TIM_GetPrescaler + * @param TIMx Timer instance + * @retval Prescaler value between Min_Data=0 and Max_Data=65535 + */ +__STATIC_INLINE uint32_t LL_TIM_GetPrescaler(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->PSC)); +} + +/** + * @brief Set the auto-reload value. + * @note The counter is blocked while the auto-reload value is null. + * @note Helper macro @ref __LL_TIM_CALC_ARR can be used to calculate the AutoReload parameter + * @rmtoll ARR ARR LL_TIM_SetAutoReload + * @param TIMx Timer instance + * @param AutoReload between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetAutoReload(TIM_TypeDef *TIMx, uint32_t AutoReload) +{ + WRITE_REG(TIMx->ARR, AutoReload); +} + +/** + * @brief Get the auto-reload value. + * @rmtoll ARR ARR LL_TIM_GetAutoReload + * @param TIMx Timer instance + * @retval Auto-reload value + */ +__STATIC_INLINE uint32_t LL_TIM_GetAutoReload(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->ARR)); +} + +/** + * @brief Set the repetition counter value. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_SetRepetitionCounter + * @param TIMx Timer instance + * @param RepetitionCounter between Min_Data=0 and Max_Data=255 or 65535 for advanced timer. + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetRepetitionCounter(TIM_TypeDef *TIMx, uint32_t RepetitionCounter) +{ + WRITE_REG(TIMx->RCR, RepetitionCounter); +} + +/** + * @brief Get the repetition counter value. + * @note Macro IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports a repetition counter. + * @rmtoll RCR REP LL_TIM_GetRepetitionCounter + * @param TIMx Timer instance + * @retval Repetition counter value + */ +__STATIC_INLINE uint32_t LL_TIM_GetRepetitionCounter(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->RCR)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Capture_Compare Capture Compare configuration + * @{ + */ +/** + * @brief Enable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note CCxE, CCxNE and OCxM bits are preloaded, after having been written, + * they are updated only when a commutation event (COM) occurs. + * @note Only on channels that have a complementary output. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_EnablePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_EnablePreload(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR2, TIM_CR2_CCPC); +} + +/** + * @brief Disable the capture/compare control bits (CCxE, CCxNE and OCxM) preload. + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCPC LL_TIM_CC_DisablePreload + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_DisablePreload(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR2, TIM_CR2_CCPC); +} + +/** + * @brief Indicates whether the capture/compare control bits (CCxE, CCxNE and OCxM) preload is enabled. + * @rmtoll CR2 CCPC LL_TIM_CC_IsEnabledPreload + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledPreload(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR2, TIM_CR2_CCPC) == (TIM_CR2_CCPC)) ? 1UL : 0UL); +} + +/** + * @brief Set the updated source of the capture/compare control bits (CCxE, CCxNE and OCxM). + * @note Macro IS_TIM_COMMUTATION_EVENT_INSTANCE(TIMx) can be used to check + * whether or not a timer instance is able to generate a commutation event. + * @rmtoll CR2 CCUS LL_TIM_CC_SetUpdate + * @param TIMx Timer instance + * @param CCUpdateSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_ONLY + * @arg @ref LL_TIM_CCUPDATESOURCE_COMG_AND_TRGI + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetUpdate(TIM_TypeDef *TIMx, uint32_t CCUpdateSource) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_CCUS, CCUpdateSource); +} + +/** + * @brief Set the trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_SetDMAReqTrigger + * @param TIMx Timer instance + * @param DMAReqTrigger This parameter can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetDMAReqTrigger(TIM_TypeDef *TIMx, uint32_t DMAReqTrigger) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_CCDS, DMAReqTrigger); +} + +/** + * @brief Get actual trigger of the capture/compare DMA request. + * @rmtoll CR2 CCDS LL_TIM_CC_GetDMAReqTrigger + * @param TIMx Timer instance + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_CCDMAREQUEST_CC + * @arg @ref LL_TIM_CCDMAREQUEST_UPDATE + */ +__STATIC_INLINE uint32_t LL_TIM_CC_GetDMAReqTrigger(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_BIT(TIMx->CR2, TIM_CR2_CCDS)); +} + +/** + * @brief Set the lock level to freeze the + * configuration of several capture/compare parameters. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * the lock mechanism is supported by a timer instance. + * @rmtoll BDTR LOCK LL_TIM_CC_SetLockLevel + * @param TIMx Timer instance + * @param LockLevel This parameter can be one of the following values: + * @arg @ref LL_TIM_LOCKLEVEL_OFF + * @arg @ref LL_TIM_LOCKLEVEL_1 + * @arg @ref LL_TIM_LOCKLEVEL_2 + * @arg @ref LL_TIM_LOCKLEVEL_3 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_SetLockLevel(TIM_TypeDef *TIMx, uint32_t LockLevel) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_LOCK, LockLevel); +} + +/** + * @brief Enable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_EnableChannel\n + * CCER CC1NE LL_TIM_CC_EnableChannel\n + * CCER CC2E LL_TIM_CC_EnableChannel\n + * CCER CC2NE LL_TIM_CC_EnableChannel\n + * CCER CC3E LL_TIM_CC_EnableChannel\n + * CCER CC3NE LL_TIM_CC_EnableChannel\n + * CCER CC4E LL_TIM_CC_EnableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_EnableChannel(TIM_TypeDef *TIMx, uint32_t Channels) +{ + SET_BIT(TIMx->CCER, Channels); +} + +/** + * @brief Disable capture/compare channels. + * @rmtoll CCER CC1E LL_TIM_CC_DisableChannel\n + * CCER CC1NE LL_TIM_CC_DisableChannel\n + * CCER CC2E LL_TIM_CC_DisableChannel\n + * CCER CC2NE LL_TIM_CC_DisableChannel\n + * CCER CC3E LL_TIM_CC_DisableChannel\n + * CCER CC3NE LL_TIM_CC_DisableChannel\n + * CCER CC4E LL_TIM_CC_DisableChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_CC_DisableChannel(TIM_TypeDef *TIMx, uint32_t Channels) +{ + CLEAR_BIT(TIMx->CCER, Channels); +} + +/** + * @brief Indicate whether channel(s) is(are) enabled. + * @rmtoll CCER CC1E LL_TIM_CC_IsEnabledChannel\n + * CCER CC1NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC2E LL_TIM_CC_IsEnabledChannel\n + * CCER CC2NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC3E LL_TIM_CC_IsEnabledChannel\n + * CCER CC3NE LL_TIM_CC_IsEnabledChannel\n + * CCER CC4E LL_TIM_CC_IsEnabledChannel + * @param TIMx Timer instance + * @param Channels This parameter can be a combination of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_CC_IsEnabledChannel(const TIM_TypeDef *TIMx, uint32_t Channels) +{ + return ((READ_BIT(TIMx->CCER, Channels) == (Channels)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Output_Channel Output channel configuration + * @{ + */ +/** + * @brief Configure an output channel. + * @rmtoll CCMR1 CC1S LL_TIM_OC_ConfigOutput\n + * CCMR1 CC2S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC3S LL_TIM_OC_ConfigOutput\n + * CCMR2 CC4S LL_TIM_OC_ConfigOutput\n + * CCER CC1P LL_TIM_OC_ConfigOutput\n + * CCER CC2P LL_TIM_OC_ConfigOutput\n + * CCER CC3P LL_TIM_OC_ConfigOutput\n + * CCER CC4P LL_TIM_OC_ConfigOutput\n + * CR2 OIS1 LL_TIM_OC_ConfigOutput\n + * CR2 OIS2 LL_TIM_OC_ConfigOutput\n + * CR2 OIS3 LL_TIM_OC_ConfigOutput\n + * CR2 OIS4 LL_TIM_OC_ConfigOutput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH or @ref LL_TIM_OCPOLARITY_LOW + * @arg @ref LL_TIM_OCIDLESTATE_LOW or @ref LL_TIM_OCIDLESTATE_HIGH + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_ConfigOutput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_CC1S << SHIFT_TAB_OCxx[iChannel])); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), + (Configuration & TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), + (Configuration & TIM_CR2_OIS1) << SHIFT_TAB_OISx[iChannel]); +} + +/** + * @brief Define the behavior of the output reference signal OCxREF from which + * OCx and OCxN (when relevant) are derived. + * @rmtoll CCMR1 OC1M LL_TIM_OC_SetMode\n + * CCMR1 OC2M LL_TIM_OC_SetMode\n + * CCMR2 OC3M LL_TIM_OC_SetMode\n + * CCMR2 OC4M LL_TIM_OC_SetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Mode This parameter can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetMode(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Mode) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel]), Mode << SHIFT_TAB_OCxx[iChannel]); +} + +/** + * @brief Get the output compare mode of an output channel. + * @rmtoll CCMR1 OC1M LL_TIM_OC_GetMode\n + * CCMR1 OC2M LL_TIM_OC_GetMode\n + * CCMR2 OC3M LL_TIM_OC_GetMode\n + * CCMR2 OC4M LL_TIM_OC_GetMode + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCMODE_FROZEN + * @arg @ref LL_TIM_OCMODE_ACTIVE + * @arg @ref LL_TIM_OCMODE_INACTIVE + * @arg @ref LL_TIM_OCMODE_TOGGLE + * @arg @ref LL_TIM_OCMODE_FORCED_INACTIVE + * @arg @ref LL_TIM_OCMODE_FORCED_ACTIVE + * @arg @ref LL_TIM_OCMODE_PWM1 + * @arg @ref LL_TIM_OCMODE_PWM2 + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetMode(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return (READ_BIT(*pReg, ((TIM_CCMR1_OC1M | TIM_CCMR1_CC1S) << SHIFT_TAB_OCxx[iChannel])) >> SHIFT_TAB_OCxx[iChannel]); +} + +/** + * @brief Set the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_SetPolarity\n + * CCER CC1NP LL_TIM_OC_SetPolarity\n + * CCER CC2P LL_TIM_OC_SetPolarity\n + * CCER CC2NP LL_TIM_OC_SetPolarity\n + * CCER CC3P LL_TIM_OC_SetPolarity\n + * CCER CC3NP LL_TIM_OC_SetPolarity\n + * CCER CC4P LL_TIM_OC_SetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Polarity This parameter can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Polarity) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel]), Polarity << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Get the polarity of an output channel. + * @rmtoll CCER CC1P LL_TIM_OC_GetPolarity\n + * CCER CC1NP LL_TIM_OC_GetPolarity\n + * CCER CC2P LL_TIM_OC_GetPolarity\n + * CCER CC2NP LL_TIM_OC_GetPolarity\n + * CCER CC3P LL_TIM_OC_GetPolarity\n + * CCER CC3NP LL_TIM_OC_GetPolarity\n + * CCER CC4P LL_TIM_OC_GetPolarity + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCPOLARITY_HIGH + * @arg @ref LL_TIM_OCPOLARITY_LOW + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetPolarity(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, (TIM_CCER_CC1P << SHIFT_TAB_CCxP[iChannel])) >> SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Set the IDLE state of an output channel + * @note This function is significant only for the timer instances + * supporting the break feature. Macro IS_TIM_BREAK_INSTANCE(TIMx) + * can be used to check whether or not a timer instance provides + * a break input. + * @rmtoll CR2 OIS1 LL_TIM_OC_SetIdleState\n + * CR2 OIS1N LL_TIM_OC_SetIdleState\n + * CR2 OIS2 LL_TIM_OC_SetIdleState\n + * CR2 OIS2N LL_TIM_OC_SetIdleState\n + * CR2 OIS3 LL_TIM_OC_SetIdleState\n + * CR2 OIS3N LL_TIM_OC_SetIdleState\n + * CR2 OIS4 LL_TIM_OC_SetIdleState + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param IdleState This parameter can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetIdleState(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t IdleState) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel]), IdleState << SHIFT_TAB_OISx[iChannel]); +} + +/** + * @brief Get the IDLE state of an output channel + * @rmtoll CR2 OIS1 LL_TIM_OC_GetIdleState\n + * CR2 OIS1N LL_TIM_OC_GetIdleState\n + * CR2 OIS2 LL_TIM_OC_GetIdleState\n + * CR2 OIS2N LL_TIM_OC_GetIdleState\n + * CR2 OIS3 LL_TIM_OC_GetIdleState\n + * CR2 OIS3N LL_TIM_OC_GetIdleState\n + * CR2 OIS4 LL_TIM_OC_GetIdleState + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH1N + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH2N + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH3N + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_OCIDLESTATE_LOW + * @arg @ref LL_TIM_OCIDLESTATE_HIGH + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetIdleState(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CR2, (TIM_CR2_OIS1 << SHIFT_TAB_OISx[iChannel])) >> SHIFT_TAB_OISx[iChannel]); +} + +/** + * @brief Enable fast mode for the output channel. + * @note Acts only if the channel is configured in PWM1 or PWM2 mode. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_EnableFast\n + * CCMR1 OC2FE LL_TIM_OC_EnableFast\n + * CCMR2 OC3FE LL_TIM_OC_EnableFast\n + * CCMR2 OC4FE LL_TIM_OC_EnableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnableFast(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + +} + +/** + * @brief Disable fast mode for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_DisableFast\n + * CCMR1 OC2FE LL_TIM_OC_DisableFast\n + * CCMR2 OC3FE LL_TIM_OC_DisableFast\n + * CCMR2 OC4FE LL_TIM_OC_DisableFast + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisableFast(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel])); + +} + +/** + * @brief Indicates whether fast mode is enabled for the output channel. + * @rmtoll CCMR1 OC1FE LL_TIM_OC_IsEnabledFast\n + * CCMR1 OC2FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC3FE LL_TIM_OC_IsEnabledFast\n + * CCMR2 OC4FE LL_TIM_OC_IsEnabledFast\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledFast(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1FE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Enable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_EnablePreload\n + * CCMR1 OC2PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC3PE LL_TIM_OC_EnablePreload\n + * CCMR2 OC4PE LL_TIM_OC_EnablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnablePreload(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Disable compare register (TIMx_CCRx) preload for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_DisablePreload\n + * CCMR1 OC2PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC3PE LL_TIM_OC_DisablePreload\n + * CCMR2 OC4PE LL_TIM_OC_DisablePreload + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisablePreload(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Indicates whether compare register (TIMx_CCRx) preload is enabled for the output channel. + * @rmtoll CCMR1 OC1PE LL_TIM_OC_IsEnabledPreload\n + * CCMR1 OC2PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC3PE LL_TIM_OC_IsEnabledPreload\n + * CCMR2 OC4PE LL_TIM_OC_IsEnabledPreload\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledPreload(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1PE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Enable clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_EnableClear\n + * CCMR1 OC2CE LL_TIM_OC_EnableClear\n + * CCMR2 OC3CE LL_TIM_OC_EnableClear\n + * CCMR2 OC4CE LL_TIM_OC_EnableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_EnableClear(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + SET_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Disable clearing the output channel on an external event. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_DisableClear\n + * CCMR1 OC2CE LL_TIM_OC_DisableClear\n + * CCMR2 OC3CE LL_TIM_OC_DisableClear\n + * CCMR2 OC4CE LL_TIM_OC_DisableClear + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_DisableClear(TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + CLEAR_BIT(*pReg, (TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel])); +} + +/** + * @brief Indicates clearing the output channel on an external event is enabled for the output channel. + * @note This function enables clearing the output channel on an external event. + * @note This function can only be used in Output compare and PWM modes. It does not work in Forced mode. + * @note Macro IS_TIM_OCXREF_CLEAR_INSTANCE(TIMx) can be used to check whether + * or not a timer instance can clear the OCxREF signal on an external event. + * @rmtoll CCMR1 OC1CE LL_TIM_OC_IsEnabledClear\n + * CCMR1 OC2CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC3CE LL_TIM_OC_IsEnabledClear\n + * CCMR2 OC4CE LL_TIM_OC_IsEnabledClear\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_OC_IsEnabledClear(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + uint32_t bitfield = TIM_CCMR1_OC1CE << SHIFT_TAB_OCxx[iChannel]; + return ((READ_BIT(*pReg, bitfield) == bitfield) ? 1UL : 0UL); +} + +/** + * @brief Set the dead-time delay (delay inserted between the rising edge of the OCxREF signal and the rising edge of + * the Ocx and OCxN signals). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * dead-time insertion feature is supported by a timer instance. + * @note Helper macro @ref __LL_TIM_CALC_DEADTIME can be used to calculate the DeadTime parameter + * @rmtoll BDTR DTG LL_TIM_OC_SetDeadTime + * @param TIMx Timer instance + * @param DeadTime between Min_Data=0 and Max_Data=255 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetDeadTime(TIM_TypeDef *TIMx, uint32_t DeadTime) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_DTG, DeadTime); +} + +/** + * @brief Set compare value for output channel 1 (TIMx_CCR1). + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_OC_SetCompareCH1 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH1(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR1, CompareValue); +} + +/** + * @brief Set compare value for output channel 2 (TIMx_CCR2). + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_OC_SetCompareCH2 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH2(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR2, CompareValue); +} + +/** + * @brief Set compare value for output channel 3 (TIMx_CCR3). + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_OC_SetCompareCH3 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH3(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR3, CompareValue); +} + +/** + * @brief Set compare value for output channel 4 (TIMx_CCR4). + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_OC_SetCompareCH4 + * @param TIMx Timer instance + * @param CompareValue between Min_Data=0 and Max_Data=65535 + * @retval None + */ +__STATIC_INLINE void LL_TIM_OC_SetCompareCH4(TIM_TypeDef *TIMx, uint32_t CompareValue) +{ + WRITE_REG(TIMx->CCR4, CompareValue); +} + +/** + * @brief Get compare value (TIMx_CCR1) set for output channel 1. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * output channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_OC_GetCompareCH1 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH1(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get compare value (TIMx_CCR2) set for output channel 2. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * output channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_OC_GetCompareCH2 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH2(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get compare value (TIMx_CCR3) set for output channel 3. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * output channel 3 is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_OC_GetCompareCH3 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH3(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get compare value (TIMx_CCR4) set for output channel 4. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * output channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_OC_GetCompareCH4 + * @param TIMx Timer instance + * @retval CompareValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_OC_GetCompareCH4(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR4)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Input_Channel Input channel configuration + * @{ + */ +/** + * @brief Configure input channel. + * @rmtoll CCMR1 CC1S LL_TIM_IC_Config\n + * CCMR1 IC1PSC LL_TIM_IC_Config\n + * CCMR1 IC1F LL_TIM_IC_Config\n + * CCMR1 CC2S LL_TIM_IC_Config\n + * CCMR1 IC2PSC LL_TIM_IC_Config\n + * CCMR1 IC2F LL_TIM_IC_Config\n + * CCMR2 CC3S LL_TIM_IC_Config\n + * CCMR2 IC3PSC LL_TIM_IC_Config\n + * CCMR2 IC3F LL_TIM_IC_Config\n + * CCMR2 CC4S LL_TIM_IC_Config\n + * CCMR2 IC4PSC LL_TIM_IC_Config\n + * CCMR2 IC4F LL_TIM_IC_Config\n + * CCER CC1P LL_TIM_IC_Config\n + * CCER CC1NP LL_TIM_IC_Config\n + * CCER CC2P LL_TIM_IC_Config\n + * CCER CC2NP LL_TIM_IC_Config\n + * CCER CC3P LL_TIM_IC_Config\n + * CCER CC3NP LL_TIM_IC_Config\n + * CCER CC4P LL_TIM_IC_Config\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param Configuration This parameter must be a combination of all the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI or @ref LL_TIM_ACTIVEINPUT_INDIRECTTI or @ref LL_TIM_ACTIVEINPUT_TRC + * @arg @ref LL_TIM_ICPSC_DIV1 or ... or @ref LL_TIM_ICPSC_DIV8 + * @arg @ref LL_TIM_IC_FILTER_FDIV1 or ... or @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @arg @ref LL_TIM_IC_POLARITY_RISING or @ref LL_TIM_IC_POLARITY_FALLING + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_Config(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t Configuration) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), + ((Configuration >> 16U) & (TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC | TIM_CCMR1_CC1S)) \ + << SHIFT_TAB_ICxx[iChannel]); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + (Configuration & (TIM_CCER_CC1NP | TIM_CCER_CC1P)) << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Set the active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_SetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_SetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_SetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICActiveInput This parameter can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetActiveInput(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICActiveInput) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel]), (ICActiveInput >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the current active input. + * @rmtoll CCMR1 CC1S LL_TIM_IC_GetActiveInput\n + * CCMR1 CC2S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC3S LL_TIM_IC_GetActiveInput\n + * CCMR2 CC4S LL_TIM_IC_GetActiveInput + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ACTIVEINPUT_DIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_INDIRECTTI + * @arg @ref LL_TIM_ACTIVEINPUT_TRC + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetActiveInput(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_CC1S) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the prescaler of input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_SetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_SetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_SetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetPrescaler(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPrescaler) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel]), (ICPrescaler >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the current prescaler value acting on an input channel. + * @rmtoll CCMR1 IC1PSC LL_TIM_IC_GetPrescaler\n + * CCMR1 IC2PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC3PSC LL_TIM_IC_GetPrescaler\n + * CCMR2 IC4PSC LL_TIM_IC_GetPrescaler + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_ICPSC_DIV1 + * @arg @ref LL_TIM_ICPSC_DIV2 + * @arg @ref LL_TIM_ICPSC_DIV4 + * @arg @ref LL_TIM_ICPSC_DIV8 + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetPrescaler(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1PSC) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_SetFilter\n + * CCMR1 IC2F LL_TIM_IC_SetFilter\n + * CCMR2 IC3F LL_TIM_IC_SetFilter\n + * CCMR2 IC4F LL_TIM_IC_SetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetFilter(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICFilter) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + MODIFY_REG(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel]), (ICFilter >> 16U) << SHIFT_TAB_ICxx[iChannel]); +} + +/** + * @brief Get the input filter duration. + * @rmtoll CCMR1 IC1F LL_TIM_IC_GetFilter\n + * CCMR1 IC2F LL_TIM_IC_GetFilter\n + * CCMR2 IC3F LL_TIM_IC_GetFilter\n + * CCMR2 IC4F LL_TIM_IC_GetFilter + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_FILTER_FDIV1 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_IC_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_IC_FILTER_FDIV32_N8 + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetFilter(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + const __IO uint32_t *pReg = (__IO uint32_t *)((uint32_t)((uint32_t)(&TIMx->CCMR1) + OFFSET_TAB_CCMRx[iChannel])); + return ((READ_BIT(*pReg, ((TIM_CCMR1_IC1F) << SHIFT_TAB_ICxx[iChannel])) >> SHIFT_TAB_ICxx[iChannel]) << 16U); +} + +/** + * @brief Set the input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_SetPolarity\n + * CCER CC1NP LL_TIM_IC_SetPolarity\n + * CCER CC2P LL_TIM_IC_SetPolarity\n + * CCER CC2NP LL_TIM_IC_SetPolarity\n + * CCER CC3P LL_TIM_IC_SetPolarity\n + * CCER CC3NP LL_TIM_IC_SetPolarity\n + * CCER CC4P LL_TIM_IC_SetPolarity\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @param ICPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_SetPolarity(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ICPolarity) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + MODIFY_REG(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel]), + ICPolarity << SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Get the current input channel polarity. + * @rmtoll CCER CC1P LL_TIM_IC_GetPolarity\n + * CCER CC1NP LL_TIM_IC_GetPolarity\n + * CCER CC2P LL_TIM_IC_GetPolarity\n + * CCER CC2NP LL_TIM_IC_GetPolarity\n + * CCER CC3P LL_TIM_IC_GetPolarity\n + * CCER CC3NP LL_TIM_IC_GetPolarity\n + * CCER CC4P LL_TIM_IC_GetPolarity\n + * @param TIMx Timer instance + * @param Channel This parameter can be one of the following values: + * @arg @ref LL_TIM_CHANNEL_CH1 + * @arg @ref LL_TIM_CHANNEL_CH2 + * @arg @ref LL_TIM_CHANNEL_CH3 + * @arg @ref LL_TIM_CHANNEL_CH4 + * @retval Returned value can be one of the following values: + * @arg @ref LL_TIM_IC_POLARITY_RISING + * @arg @ref LL_TIM_IC_POLARITY_FALLING + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetPolarity(const TIM_TypeDef *TIMx, uint32_t Channel) +{ + uint8_t iChannel = TIM_GET_CHANNEL_INDEX(Channel); + return (READ_BIT(TIMx->CCER, ((TIM_CCER_CC1NP | TIM_CCER_CC1P) << SHIFT_TAB_CCxP[iChannel])) >> + SHIFT_TAB_CCxP[iChannel]); +} + +/** + * @brief Connect the TIMx_CH1, CH2 and CH3 pins to the TI1 input (XOR combination). + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_EnableXORCombination + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_EnableXORCombination(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->CR2, TIM_CR2_TI1S); +} + +/** + * @brief Disconnect the TIMx_CH1, CH2 and CH3 pins from the TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_DisableXORCombination + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_IC_DisableXORCombination(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->CR2, TIM_CR2_TI1S); +} + +/** + * @brief Indicates whether the TIMx_CH1, CH2 and CH3 pins are connectected to the TI1 input. + * @note Macro IS_TIM_XOR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an XOR input. + * @rmtoll CR2 TI1S LL_TIM_IC_IsEnabledXORCombination + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IC_IsEnabledXORCombination(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->CR2, TIM_CR2_TI1S) == (TIM_CR2_TI1S)) ? 1UL : 0UL); +} + +/** + * @brief Get captured value for input channel 1. + * @note Macro IS_TIM_CC1_INSTANCE(TIMx) can be used to check whether or not + * input channel 1 is supported by a timer instance. + * @rmtoll CCR1 CCR1 LL_TIM_IC_GetCaptureCH1 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH1(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR1)); +} + +/** + * @brief Get captured value for input channel 2. + * @note Macro IS_TIM_CC2_INSTANCE(TIMx) can be used to check whether or not + * input channel 2 is supported by a timer instance. + * @rmtoll CCR2 CCR2 LL_TIM_IC_GetCaptureCH2 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH2(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR2)); +} + +/** + * @brief Get captured value for input channel 3. + * @note Macro IS_TIM_CC3_INSTANCE(TIMx) can be used to check whether or not + * input channel 3 is supported by a timer instance. + * @rmtoll CCR3 CCR3 LL_TIM_IC_GetCaptureCH3 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH3(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR3)); +} + +/** + * @brief Get captured value for input channel 4. + * @note Macro IS_TIM_CC4_INSTANCE(TIMx) can be used to check whether or not + * input channel 4 is supported by a timer instance. + * @rmtoll CCR4 CCR4 LL_TIM_IC_GetCaptureCH4 + * @param TIMx Timer instance + * @retval CapturedValue (between Min_Data=0 and Max_Data=65535) + */ +__STATIC_INLINE uint32_t LL_TIM_IC_GetCaptureCH4(const TIM_TypeDef *TIMx) +{ + return (uint32_t)(READ_REG(TIMx->CCR4)); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Clock_Selection Counter clock selection + * @{ + */ +/** + * @brief Enable external clock mode 2. + * @note When external clock mode 2 is enabled the counter is clocked by any active edge on the ETRF signal. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_EnableExternalClock + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableExternalClock(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->SMCR, TIM_SMCR_ECE); +} + +/** + * @brief Disable external clock mode 2. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_DisableExternalClock + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableExternalClock(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_ECE); +} + +/** + * @brief Indicate whether external clock mode 2 is enabled. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR ECE LL_TIM_IsEnabledExternalClock + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledExternalClock(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_ECE) == (TIM_SMCR_ECE)) ? 1UL : 0UL); +} + +/** + * @brief Set the clock source of the counter clock. + * @note when selected clock source is external clock mode 1, the timer input + * the external clock is applied is selected by calling the @ref LL_TIM_SetTriggerInput() + * function. This timer input must be configured by calling + * the @ref LL_TIM_IC_Config() function. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode1. + * @note Macro IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports external clock mode2. + * @rmtoll SMCR SMS LL_TIM_SetClockSource\n + * SMCR ECE LL_TIM_SetClockSource + * @param TIMx Timer instance + * @param ClockSource This parameter can be one of the following values: + * @arg @ref LL_TIM_CLOCKSOURCE_INTERNAL + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE1 + * @arg @ref LL_TIM_CLOCKSOURCE_EXT_MODE2 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetClockSource(TIM_TypeDef *TIMx, uint32_t ClockSource) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS | TIM_SMCR_ECE, ClockSource); +} + +/** + * @brief Set the encoder interface mode. + * @note Macro IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx) can be used to check + * whether or not a timer instance supports the encoder mode. + * @rmtoll SMCR SMS LL_TIM_SetEncoderMode + * @param TIMx Timer instance + * @param EncoderMode This parameter can be one of the following values: + * @arg @ref LL_TIM_ENCODERMODE_X2_TI1 + * @arg @ref LL_TIM_ENCODERMODE_X2_TI2 + * @arg @ref LL_TIM_ENCODERMODE_X4_TI12 + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetEncoderMode(TIM_TypeDef *TIMx, uint32_t EncoderMode) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, EncoderMode); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Timer_Synchronization Timer synchronisation configuration + * @{ + */ +/** + * @brief Set the trigger output (TRGO) used for timer synchronization . + * @note Macro IS_TIM_MASTER_INSTANCE(TIMx) can be used to check + * whether or not a timer instance can operate as a master timer. + * @rmtoll CR2 MMS LL_TIM_SetTriggerOutput + * @param TIMx Timer instance + * @param TimerSynchronization This parameter can be one of the following values: + * @arg @ref LL_TIM_TRGO_RESET + * @arg @ref LL_TIM_TRGO_ENABLE + * @arg @ref LL_TIM_TRGO_UPDATE + * @arg @ref LL_TIM_TRGO_CC1IF + * @arg @ref LL_TIM_TRGO_OC1REF + * @arg @ref LL_TIM_TRGO_OC2REF + * @arg @ref LL_TIM_TRGO_OC3REF + * @arg @ref LL_TIM_TRGO_OC4REF + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerOutput(TIM_TypeDef *TIMx, uint32_t TimerSynchronization) +{ + MODIFY_REG(TIMx->CR2, TIM_CR2_MMS, TimerSynchronization); +} + +/** + * @brief Set the synchronization mode of a slave timer. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR SMS LL_TIM_SetSlaveMode + * @param TIMx Timer instance + * @param SlaveMode This parameter can be one of the following values: + * @arg @ref LL_TIM_SLAVEMODE_DISABLED + * @arg @ref LL_TIM_SLAVEMODE_RESET + * @arg @ref LL_TIM_SLAVEMODE_GATED + * @arg @ref LL_TIM_SLAVEMODE_TRIGGER + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetSlaveMode(TIM_TypeDef *TIMx, uint32_t SlaveMode) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_SMS, SlaveMode); +} + +/** + * @brief Set the selects the trigger input to be used to synchronize the counter. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR TS LL_TIM_SetTriggerInput + * @param TIMx Timer instance + * @param TriggerInput This parameter can be one of the following values: + * @arg @ref LL_TIM_TS_ITR0 + * @arg @ref LL_TIM_TS_ITR1 + * @arg @ref LL_TIM_TS_ITR2 + * @arg @ref LL_TIM_TS_ITR3 + * @arg @ref LL_TIM_TS_TI1F_ED + * @arg @ref LL_TIM_TS_TI1FP1 + * @arg @ref LL_TIM_TS_TI2FP2 + * @arg @ref LL_TIM_TS_ETRF + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetTriggerInput(TIM_TypeDef *TIMx, uint32_t TriggerInput) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_TS, TriggerInput); +} + +/** + * @brief Enable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_EnableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableMasterSlaveMode(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->SMCR, TIM_SMCR_MSM); +} + +/** + * @brief Disable the Master/Slave mode. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_DisableMasterSlaveMode + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableMasterSlaveMode(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->SMCR, TIM_SMCR_MSM); +} + +/** + * @brief Indicates whether the Master/Slave mode is enabled. + * @note Macro IS_TIM_SLAVE_INSTANCE(TIMx) can be used to check whether or not + * a timer instance can operate as a slave timer. + * @rmtoll SMCR MSM LL_TIM_IsEnabledMasterSlaveMode + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledMasterSlaveMode(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SMCR, TIM_SMCR_MSM) == (TIM_SMCR_MSM)) ? 1UL : 0UL); +} + +/** + * @brief Configure the external trigger (ETR) input. + * @note Macro IS_TIM_ETR_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides an external trigger input. + * @rmtoll SMCR ETP LL_TIM_ConfigETR\n + * SMCR ETPS LL_TIM_ConfigETR\n + * SMCR ETF LL_TIM_ConfigETR + * @param TIMx Timer instance + * @param ETRPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_POLARITY_NONINVERTED + * @arg @ref LL_TIM_ETR_POLARITY_INVERTED + * @param ETRPrescaler This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_PRESCALER_DIV1 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV2 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV4 + * @arg @ref LL_TIM_ETR_PRESCALER_DIV8 + * @param ETRFilter This parameter can be one of the following values: + * @arg @ref LL_TIM_ETR_FILTER_FDIV1 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N2 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N4 + * @arg @ref LL_TIM_ETR_FILTER_FDIV1_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV2_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV4_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV8_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV16_N8 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N5 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N6 + * @arg @ref LL_TIM_ETR_FILTER_FDIV32_N8 + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigETR(TIM_TypeDef *TIMx, uint32_t ETRPolarity, uint32_t ETRPrescaler, + uint32_t ETRFilter) +{ + MODIFY_REG(TIMx->SMCR, TIM_SMCR_ETP | TIM_SMCR_ETPS | TIM_SMCR_ETF, ETRPolarity | ETRPrescaler | ETRFilter); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_Break_Function Break function configuration + * @{ + */ +/** + * @brief Enable the break function. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR BKE LL_TIM_EnableBRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableBRK(TIM_TypeDef *TIMx) +{ + __IO uint32_t tmpreg; + SET_BIT(TIMx->BDTR, TIM_BDTR_BKE); + /* Note: Any write operation to this bit takes a delay of 1 APB clock cycle to become effective. */ + tmpreg = READ_REG(TIMx->BDTR); + (void)(tmpreg); +} + +/** + * @brief Disable the break function. + * @rmtoll BDTR BKE LL_TIM_DisableBRK + * @param TIMx Timer instance + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableBRK(TIM_TypeDef *TIMx) +{ + __IO uint32_t tmpreg; + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_BKE); + /* Note: Any write operation to this bit takes a delay of 1 APB clock cycle to become effective. */ + tmpreg = READ_REG(TIMx->BDTR); + (void)(tmpreg); +} + +/** + * @brief Configure the break input. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR BKP LL_TIM_ConfigBRK + * @param TIMx Timer instance + * @param BreakPolarity This parameter can be one of the following values: + * @arg @ref LL_TIM_BREAK_POLARITY_LOW + * @arg @ref LL_TIM_BREAK_POLARITY_HIGH + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigBRK(TIM_TypeDef *TIMx, uint32_t BreakPolarity) +{ + __IO uint32_t tmpreg; + MODIFY_REG(TIMx->BDTR, TIM_BDTR_BKP, BreakPolarity); + /* Note: Any write operation to BKP bit takes a delay of 1 APB clock cycle to become effective. */ + tmpreg = READ_REG(TIMx->BDTR); + (void)(tmpreg); +} + +/** + * @brief Select the outputs off state (enabled v.s. disabled) in Idle and Run modes. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR OSSI LL_TIM_SetOffStates\n + * BDTR OSSR LL_TIM_SetOffStates + * @param TIMx Timer instance + * @param OffStateIdle This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSI_DISABLE + * @arg @ref LL_TIM_OSSI_ENABLE + * @param OffStateRun This parameter can be one of the following values: + * @arg @ref LL_TIM_OSSR_DISABLE + * @arg @ref LL_TIM_OSSR_ENABLE + * @retval None + */ +__STATIC_INLINE void LL_TIM_SetOffStates(TIM_TypeDef *TIMx, uint32_t OffStateIdle, uint32_t OffStateRun) +{ + MODIFY_REG(TIMx->BDTR, TIM_BDTR_OSSI | TIM_BDTR_OSSR, OffStateIdle | OffStateRun); +} + +/** + * @brief Enable automatic output (MOE can be set by software or automatically when a break input is active). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_EnableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableAutomaticOutput(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_AOE); +} + +/** + * @brief Disable automatic output (MOE can be set only by software). + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_DisableAutomaticOutput + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableAutomaticOutput(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_AOE); +} + +/** + * @brief Indicate whether automatic output is enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR AOE LL_TIM_IsEnabledAutomaticOutput + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledAutomaticOutput(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_AOE) == (TIM_BDTR_AOE)) ? 1UL : 0UL); +} + +/** + * @brief Enable the outputs (set the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_EnableAllOutputs + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableAllOutputs(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->BDTR, TIM_BDTR_MOE); +} + +/** + * @brief Disable the outputs (reset the MOE bit in TIMx_BDTR register). + * @note The MOE bit in TIMx_BDTR register allows to enable /disable the outputs by + * software and is reset in case of break or break2 event. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_DisableAllOutputs + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableAllOutputs(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->BDTR, TIM_BDTR_MOE); +} + +/** + * @brief Indicates whether outputs are enabled. + * @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not + * a timer instance provides a break input. + * @rmtoll BDTR MOE LL_TIM_IsEnabledAllOutputs + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledAllOutputs(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->BDTR, TIM_BDTR_MOE) == (TIM_BDTR_MOE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_DMA_Burst_Mode DMA burst mode configuration + * @{ + */ +/** + * @brief Configures the timer DMA burst feature. + * @note Macro IS_TIM_DMABURST_INSTANCE(TIMx) can be used to check whether or + * not a timer instance supports the DMA burst mode. + * @rmtoll DCR DBL LL_TIM_ConfigDMABurst\n + * DCR DBA LL_TIM_ConfigDMABurst + * @param TIMx Timer instance + * @param DMABurstBaseAddress This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_SMCR + * @arg @ref LL_TIM_DMABURST_BASEADDR_DIER + * @arg @ref LL_TIM_DMABURST_BASEADDR_SR + * @arg @ref LL_TIM_DMABURST_BASEADDR_EGR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCMR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCER + * @arg @ref LL_TIM_DMABURST_BASEADDR_CNT + * @arg @ref LL_TIM_DMABURST_BASEADDR_PSC + * @arg @ref LL_TIM_DMABURST_BASEADDR_ARR + * @arg @ref LL_TIM_DMABURST_BASEADDR_RCR + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR1 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR2 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR3 + * @arg @ref LL_TIM_DMABURST_BASEADDR_CCR4 + * @arg @ref LL_TIM_DMABURST_BASEADDR_BDTR + * @param DMABurstLength This parameter can be one of the following values: + * @arg @ref LL_TIM_DMABURST_LENGTH_1TRANSFER + * @arg @ref LL_TIM_DMABURST_LENGTH_2TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_3TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_4TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_5TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_6TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_7TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_8TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_9TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_10TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_11TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_12TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_13TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_14TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_15TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_16TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_17TRANSFERS + * @arg @ref LL_TIM_DMABURST_LENGTH_18TRANSFERS + * @retval None + */ +__STATIC_INLINE void LL_TIM_ConfigDMABurst(TIM_TypeDef *TIMx, uint32_t DMABurstBaseAddress, uint32_t DMABurstLength) +{ + MODIFY_REG(TIMx->DCR, (TIM_DCR_DBL | TIM_DCR_DBA), (DMABurstBaseAddress | DMABurstLength)); +} + +/** + * @} + */ + + +/** @defgroup TIM_LL_EF_FLAG_Management FLAG-Management + * @{ + */ +/** + * @brief Clear the update interrupt flag (UIF). + * @rmtoll SR UIF LL_TIM_ClearFlag_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_UPDATE(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_UIF)); +} + +/** + * @brief Indicate whether update interrupt flag (UIF) is set (update interrupt is pending). + * @rmtoll SR UIF LL_TIM_IsActiveFlag_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_UPDATE(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_UIF) == (TIM_SR_UIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 1 interrupt flag (CC1F). + * @rmtoll SR CC1IF LL_TIM_ClearFlag_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC1(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1IF)); +} + +/** + * @brief Indicate whether Capture/Compare 1 interrupt flag (CC1F) is set (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1IF LL_TIM_IsActiveFlag_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC1IF) == (TIM_SR_CC1IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 2 interrupt flag (CC2F). + * @rmtoll SR CC2IF LL_TIM_ClearFlag_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC2(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2IF)); +} + +/** + * @brief Indicate whether Capture/Compare 2 interrupt flag (CC2F) is set (Capture/Compare 2 interrupt is pending). + * @rmtoll SR CC2IF LL_TIM_IsActiveFlag_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC2IF) == (TIM_SR_CC2IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 3 interrupt flag (CC3F). + * @rmtoll SR CC3IF LL_TIM_ClearFlag_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC3(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3IF)); +} + +/** + * @brief Indicate whether Capture/Compare 3 interrupt flag (CC3F) is set (Capture/Compare 3 interrupt is pending). + * @rmtoll SR CC3IF LL_TIM_IsActiveFlag_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC3IF) == (TIM_SR_CC3IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 4 interrupt flag (CC4F). + * @rmtoll SR CC4IF LL_TIM_ClearFlag_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC4(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4IF)); +} + +/** + * @brief Indicate whether Capture/Compare 4 interrupt flag (CC4F) is set (Capture/Compare 4 interrupt is pending). + * @rmtoll SR CC4IF LL_TIM_IsActiveFlag_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4IF) == (TIM_SR_CC4IF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the commutation interrupt flag (COMIF). + * @rmtoll SR COMIF LL_TIM_ClearFlag_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_COM(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_COMIF)); +} + +/** + * @brief Indicate whether commutation interrupt flag (COMIF) is set (commutation interrupt is pending). + * @rmtoll SR COMIF LL_TIM_IsActiveFlag_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_COMIF) == (TIM_SR_COMIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the trigger interrupt flag (TIF). + * @rmtoll SR TIF LL_TIM_ClearFlag_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_TRIG(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_TIF)); +} + +/** + * @brief Indicate whether trigger interrupt flag (TIF) is set (trigger interrupt is pending). + * @rmtoll SR TIF LL_TIM_IsActiveFlag_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_TRIG(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_TIF) == (TIM_SR_TIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the break interrupt flag (BIF). + * @rmtoll SR BIF LL_TIM_ClearFlag_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_BRK(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_BIF)); +} + +/** + * @brief Indicate whether break interrupt flag (BIF) is set (break interrupt is pending). + * @rmtoll SR BIF LL_TIM_IsActiveFlag_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_BRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_BIF) == (TIM_SR_BIF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 1 over-capture interrupt flag (CC1OF). + * @rmtoll SR CC1OF LL_TIM_ClearFlag_CC1OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC1OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC1OF)); +} + +/** + * @brief Indicate whether Capture/Compare 1 over-capture interrupt flag (CC1OF) is set + * (Capture/Compare 1 interrupt is pending). + * @rmtoll SR CC1OF LL_TIM_IsActiveFlag_CC1OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC1OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC1OF) == (TIM_SR_CC1OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 2 over-capture interrupt flag (CC2OF). + * @rmtoll SR CC2OF LL_TIM_ClearFlag_CC2OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC2OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC2OF)); +} + +/** + * @brief Indicate whether Capture/Compare 2 over-capture interrupt flag (CC2OF) is set + * (Capture/Compare 2 over-capture interrupt is pending). + * @rmtoll SR CC2OF LL_TIM_IsActiveFlag_CC2OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC2OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC2OF) == (TIM_SR_CC2OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 3 over-capture interrupt flag (CC3OF). + * @rmtoll SR CC3OF LL_TIM_ClearFlag_CC3OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC3OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC3OF)); +} + +/** + * @brief Indicate whether Capture/Compare 3 over-capture interrupt flag (CC3OF) is set + * (Capture/Compare 3 over-capture interrupt is pending). + * @rmtoll SR CC3OF LL_TIM_IsActiveFlag_CC3OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC3OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC3OF) == (TIM_SR_CC3OF)) ? 1UL : 0UL); +} + +/** + * @brief Clear the Capture/Compare 4 over-capture interrupt flag (CC4OF). + * @rmtoll SR CC4OF LL_TIM_ClearFlag_CC4OVR + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_ClearFlag_CC4OVR(TIM_TypeDef *TIMx) +{ + WRITE_REG(TIMx->SR, ~(TIM_SR_CC4OF)); +} + +/** + * @brief Indicate whether Capture/Compare 4 over-capture interrupt flag (CC4OF) is set + * (Capture/Compare 4 over-capture interrupt is pending). + * @rmtoll SR CC4OF LL_TIM_IsActiveFlag_CC4OVR + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsActiveFlag_CC4OVR(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->SR, TIM_SR_CC4OF) == (TIM_SR_CC4OF)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_IT_Management IT-Management + * @{ + */ +/** + * @brief Enable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_EnableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_UIE); +} + +/** + * @brief Disable update interrupt (UIE). + * @rmtoll DIER UIE LL_TIM_DisableIT_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_UPDATE(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_UIE); +} + +/** + * @brief Indicates whether the update interrupt (UIE) is enabled. + * @rmtoll DIER UIE LL_TIM_IsEnabledIT_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_UPDATE(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_UIE) == (TIM_DIER_UIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_EnableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC1IE); +} + +/** + * @brief Disable capture/compare 1 interrupt (CC1IE). + * @rmtoll DIER CC1IE LL_TIM_DisableIT_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC1(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1IE); +} + +/** + * @brief Indicates whether the capture/compare 1 interrupt (CC1IE) is enabled. + * @rmtoll DIER CC1IE LL_TIM_IsEnabledIT_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC1(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1IE) == (TIM_DIER_CC1IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_EnableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC2IE); +} + +/** + * @brief Disable capture/compare 2 interrupt (CC2IE). + * @rmtoll DIER CC2IE LL_TIM_DisableIT_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2IE); +} + +/** + * @brief Indicates whether the capture/compare 2 interrupt (CC2IE) is enabled. + * @rmtoll DIER CC2IE LL_TIM_IsEnabledIT_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2IE) == (TIM_DIER_CC2IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_EnableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC3IE); +} + +/** + * @brief Disable capture/compare 3 interrupt (CC3IE). + * @rmtoll DIER CC3IE LL_TIM_DisableIT_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC3(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3IE); +} + +/** + * @brief Indicates whether the capture/compare 3 interrupt (CC3IE) is enabled. + * @rmtoll DIER CC3IE LL_TIM_IsEnabledIT_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC3(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3IE) == (TIM_DIER_CC3IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_EnableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC4IE); +} + +/** + * @brief Disable capture/compare 4 interrupt (CC4IE). + * @rmtoll DIER CC4IE LL_TIM_DisableIT_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_CC4(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4IE); +} + +/** + * @brief Indicates whether the capture/compare 4 interrupt (CC4IE) is enabled. + * @rmtoll DIER CC4IE LL_TIM_IsEnabledIT_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_CC4(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4IE) == (TIM_DIER_CC4IE)) ? 1UL : 0UL); +} + +/** + * @brief Enable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_EnableIT_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_COMIE); +} + +/** + * @brief Disable commutation interrupt (COMIE). + * @rmtoll DIER COMIE LL_TIM_DisableIT_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_COM(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMIE); +} + +/** + * @brief Indicates whether the commutation interrupt (COMIE) is enabled. + * @rmtoll DIER COMIE LL_TIM_IsEnabledIT_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMIE) == (TIM_DIER_COMIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_EnableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_TIE); +} + +/** + * @brief Disable trigger interrupt (TIE). + * @rmtoll DIER TIE LL_TIM_DisableIT_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_TRIG(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_TIE); +} + +/** + * @brief Indicates whether the trigger interrupt (TIE) is enabled. + * @rmtoll DIER TIE LL_TIM_IsEnabledIT_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_TRIG(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TIE) == (TIM_DIER_TIE)) ? 1UL : 0UL); +} + +/** + * @brief Enable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_EnableIT_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableIT_BRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_BIE); +} + +/** + * @brief Disable break interrupt (BIE). + * @rmtoll DIER BIE LL_TIM_DisableIT_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableIT_BRK(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_BIE); +} + +/** + * @brief Indicates whether the break interrupt (BIE) is enabled. + * @rmtoll DIER BIE LL_TIM_IsEnabledIT_BRK + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledIT_BRK(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_BIE) == (TIM_DIER_BIE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_DMA_Management DMA Management + * @{ + */ +/** + * @brief Enable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_EnableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_UDE); +} + +/** + * @brief Disable update DMA request (UDE). + * @rmtoll DIER UDE LL_TIM_DisableDMAReq_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_UPDATE(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_UDE); +} + +/** + * @brief Indicates whether the update DMA request (UDE) is enabled. + * @rmtoll DIER UDE LL_TIM_IsEnabledDMAReq_UPDATE + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_UPDATE(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_UDE) == (TIM_DIER_UDE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_EnableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC1DE); +} + +/** + * @brief Disable capture/compare 1 DMA request (CC1DE). + * @rmtoll DIER CC1DE LL_TIM_DisableDMAReq_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC1(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC1DE); +} + +/** + * @brief Indicates whether the capture/compare 1 DMA request (CC1DE) is enabled. + * @rmtoll DIER CC1DE LL_TIM_IsEnabledDMAReq_CC1 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC1(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC1DE) == (TIM_DIER_CC1DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_EnableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC2DE); +} + +/** + * @brief Disable capture/compare 2 DMA request (CC2DE). + * @rmtoll DIER CC2DE LL_TIM_DisableDMAReq_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC2(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC2DE); +} + +/** + * @brief Indicates whether the capture/compare 2 DMA request (CC2DE) is enabled. + * @rmtoll DIER CC2DE LL_TIM_IsEnabledDMAReq_CC2 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC2(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC2DE) == (TIM_DIER_CC2DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_EnableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC3DE); +} + +/** + * @brief Disable capture/compare 3 DMA request (CC3DE). + * @rmtoll DIER CC3DE LL_TIM_DisableDMAReq_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC3(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC3DE); +} + +/** + * @brief Indicates whether the capture/compare 3 DMA request (CC3DE) is enabled. + * @rmtoll DIER CC3DE LL_TIM_IsEnabledDMAReq_CC3 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC3(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC3DE) == (TIM_DIER_CC3DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_EnableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_CC4DE); +} + +/** + * @brief Disable capture/compare 4 DMA request (CC4DE). + * @rmtoll DIER CC4DE LL_TIM_DisableDMAReq_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_CC4(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_CC4DE); +} + +/** + * @brief Indicates whether the capture/compare 4 DMA request (CC4DE) is enabled. + * @rmtoll DIER CC4DE LL_TIM_IsEnabledDMAReq_CC4 + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_CC4(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_CC4DE) == (TIM_DIER_CC4DE)) ? 1UL : 0UL); +} + +/** + * @brief Enable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_EnableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_COMDE); +} + +/** + * @brief Disable commutation DMA request (COMDE). + * @rmtoll DIER COMDE LL_TIM_DisableDMAReq_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_COM(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_COMDE); +} + +/** + * @brief Indicates whether the commutation DMA request (COMDE) is enabled. + * @rmtoll DIER COMDE LL_TIM_IsEnabledDMAReq_COM + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_COM(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_COMDE) == (TIM_DIER_COMDE)) ? 1UL : 0UL); +} + +/** + * @brief Enable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_EnableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_EnableDMAReq_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->DIER, TIM_DIER_TDE); +} + +/** + * @brief Disable trigger interrupt (TDE). + * @rmtoll DIER TDE LL_TIM_DisableDMAReq_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_DisableDMAReq_TRIG(TIM_TypeDef *TIMx) +{ + CLEAR_BIT(TIMx->DIER, TIM_DIER_TDE); +} + +/** + * @brief Indicates whether the trigger interrupt (TDE) is enabled. + * @rmtoll DIER TDE LL_TIM_IsEnabledDMAReq_TRIG + * @param TIMx Timer instance + * @retval State of bit (1 or 0). + */ +__STATIC_INLINE uint32_t LL_TIM_IsEnabledDMAReq_TRIG(const TIM_TypeDef *TIMx) +{ + return ((READ_BIT(TIMx->DIER, TIM_DIER_TDE) == (TIM_DIER_TDE)) ? 1UL : 0UL); +} + +/** + * @} + */ + +/** @defgroup TIM_LL_EF_EVENT_Management EVENT-Management + * @{ + */ +/** + * @brief Generate an update event. + * @rmtoll EGR UG LL_TIM_GenerateEvent_UPDATE + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_UPDATE(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_UG); +} + +/** + * @brief Generate Capture/Compare 1 event. + * @rmtoll EGR CC1G LL_TIM_GenerateEvent_CC1 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC1(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC1G); +} + +/** + * @brief Generate Capture/Compare 2 event. + * @rmtoll EGR CC2G LL_TIM_GenerateEvent_CC2 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC2(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC2G); +} + +/** + * @brief Generate Capture/Compare 3 event. + * @rmtoll EGR CC3G LL_TIM_GenerateEvent_CC3 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC3(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC3G); +} + +/** + * @brief Generate Capture/Compare 4 event. + * @rmtoll EGR CC4G LL_TIM_GenerateEvent_CC4 + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_CC4(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_CC4G); +} + +/** + * @brief Generate commutation event. + * @rmtoll EGR COMG LL_TIM_GenerateEvent_COM + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_COM(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_COMG); +} + +/** + * @brief Generate trigger event. + * @rmtoll EGR TG LL_TIM_GenerateEvent_TRIG + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_TRIG(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_TG); +} + +/** + * @brief Generate break event. + * @rmtoll EGR BG LL_TIM_GenerateEvent_BRK + * @param TIMx Timer instance + * @retval None + */ +__STATIC_INLINE void LL_TIM_GenerateEvent_BRK(TIM_TypeDef *TIMx) +{ + SET_BIT(TIMx->EGR, TIM_EGR_BG); +} + +/** + * @} + */ + +#if defined(USE_FULL_LL_DRIVER) +/** @defgroup TIM_LL_EF_Init Initialisation and deinitialisation functions + * @{ + */ + +ErrorStatus LL_TIM_DeInit(const TIM_TypeDef *TIMx); +void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct); +ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, const LL_TIM_InitTypeDef *TIM_InitStruct); +void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, const LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct); +void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct); +ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, const LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct); +void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, const LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct); +void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); +ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, const LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct); +void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); +ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, const LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct); +/** + * @} + */ +#endif /* USE_FULL_LL_DRIVER */ + +/** + * @} + */ + +/** + * @} + */ + +#endif /* TIM1 || TIM2 || TIM3 || TIM4 || TIM5 || TIM6 || TIM7 || TIM8 || TIM9 || TIM10 || TIM11 || TIM12 || TIM13 || TIM14 || TIM15 || TIM16 || TIM17 */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F1xx_LL_TIM_H */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c new file mode 100644 index 0000000..29d7466 --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c @@ -0,0 +1,2428 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_adc.c + * @author MCD Application Team + * @brief This file provides firmware functions to manage the following + * functionalities of the Analog to Digital Convertor (ADC) + * peripheral: + * + Initialization and de-initialization functions + * + Peripheral Control functions + * + Peripheral State functions + * Other functions (extended functions) are available in file + * "stm32f1xx_hal_adc_ex.c". + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### ADC peripheral features ##### + ============================================================================== + [..] + (+) 12-bit resolution + + (+) Interrupt generation at the end of regular conversion, end of injected + conversion, and in case of analog watchdog or overrun events. + + (+) Single and continuous conversion modes. + + (+) Scan mode for conversion of several channels sequentially. + + (+) Data alignment with in-built data coherency. + + (+) Programmable sampling time (channel wise) + + (+) ADC conversion of regular group and injected group. + + (+) External trigger (timer or EXTI) + for both regular and injected groups. + + (+) DMA request generation for transfer of conversions data of regular group. + + (+) Multimode Dual mode (available on devices with 2 ADCs or more). + + (+) Configurable DMA data storage in Multimode Dual mode (available on devices + with 2 DCs or more). + + (+) Configurable delay between conversions in Dual interleaved mode (available + on devices with 2 DCs or more). + + (+) ADC calibration + + (+) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at + slower speed. + + (+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to + Vdda or to an external voltage reference). + + + ##### How to use this driver ##### + ============================================================================== + [..] + + *** Configuration of top level parameters related to ADC *** + ============================================================ + [..] + + (#) Enable the ADC interface + (++) As prerequisite, ADC clock must be configured at RCC top level. + Caution: On STM32F1, ADC clock frequency max is 14MHz (refer + to device datasheet). + Therefore, ADC clock prescaler must be configured in + function of ADC clock source frequency to remain below + this maximum frequency. + (++) One clock setting is mandatory: + ADC clock (core clock, also possibly conversion clock). + (+++) Example: + Into HAL_ADC_MspInit() (recommended code location) or with + other device clock parameters configuration: + (+++) RCC_PeriphCLKInitTypeDef PeriphClkInit; + (+++) __ADC1_CLK_ENABLE(); + (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; + (+++) PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV2; + (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + (#) ADC pins configuration + (++) Enable the clock for the ADC GPIOs + using macro __HAL_RCC_GPIOx_CLK_ENABLE() + (++) Configure these ADC pins in analog mode + using function HAL_GPIO_Init() + + (#) Optionally, in case of usage of ADC with interruptions: + (++) Configure the NVIC for ADC + using function HAL_NVIC_EnableIRQ(ADCx_IRQn) + (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler() + into the function of corresponding ADC interruption vector + ADCx_IRQHandler(). + + (#) Optionally, in case of usage of DMA: + (++) Configure the DMA (DMA channel, mode normal or circular, ...) + using function HAL_DMA_Init(). + (++) Configure the NVIC for DMA + using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn) + (++) Insert the ADC interruption handler function HAL_ADC_IRQHandler() + into the function of corresponding DMA interruption vector + DMAx_Channelx_IRQHandler(). + + *** Configuration of ADC, groups regular/injected, channels parameters *** + ========================================================================== + [..] + + (#) Configure the ADC parameters (resolution, data alignment, ...) + and regular group parameters (conversion trigger, sequencer, ...) + using function HAL_ADC_Init(). + + (#) Configure the channels for regular group parameters (channel number, + channel rank into sequencer, ..., into regular group) + using function HAL_ADC_ConfigChannel(). + + (#) Optionally, configure the injected group parameters (conversion trigger, + sequencer, ..., of injected group) + and the channels for injected group parameters (channel number, + channel rank into sequencer, ..., into injected group) + using function HAL_ADCEx_InjectedConfigChannel(). + + (#) Optionally, configure the analog watchdog parameters (channels + monitored, thresholds, ...) + using function HAL_ADC_AnalogWDGConfig(). + + (#) Optionally, for devices with several ADC instances: configure the + multimode parameters + using function HAL_ADCEx_MultiModeConfigChannel(). + + *** Execution of ADC conversions *** + ==================================== + [..] + + (#) Optionally, perform an automatic ADC calibration to improve the + conversion accuracy + using function HAL_ADCEx_Calibration_Start(). + + (#) ADC driver can be used among three modes: polling, interruption, + transfer by DMA. + + (++) ADC conversion by polling: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start() + (+++) Wait for ADC conversion completion + using function HAL_ADC_PollForConversion() + (or for injected group: HAL_ADCEx_InjectedPollForConversion() ) + (+++) Retrieve conversion results + using function HAL_ADC_GetValue() + (or for injected group: HAL_ADCEx_InjectedGetValue() ) + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop() + + (++) ADC conversion by interruption: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start_IT() + (+++) Wait for ADC conversion completion by call of function + HAL_ADC_ConvCpltCallback() + (this function must be implemented in user program) + (or for injected group: HAL_ADCEx_InjectedConvCpltCallback() ) + (+++) Retrieve conversion results + using function HAL_ADC_GetValue() + (or for injected group: HAL_ADCEx_InjectedGetValue() ) + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop_IT() + + (++) ADC conversion with transfer by DMA: + (+++) Activate the ADC peripheral and start conversions + using function HAL_ADC_Start_DMA() + (+++) Wait for ADC conversion completion by call of function + HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback() + (these functions must be implemented in user program) + (+++) Conversion results are automatically transferred by DMA into + destination variable address. + (+++) Stop conversion and disable the ADC peripheral + using function HAL_ADC_Stop_DMA() + + (++) For devices with several ADCs: ADC multimode conversion + with transfer by DMA: + (+++) Activate the ADC peripheral (slave) and start conversions + using function HAL_ADC_Start() + (+++) Activate the ADC peripheral (master) and start conversions + using function HAL_ADCEx_MultiModeStart_DMA() + (+++) Wait for ADC conversion completion by call of function + HAL_ADC_ConvCpltCallback() or HAL_ADC_ConvHalfCpltCallback() + (these functions must be implemented in user program) + (+++) Conversion results are automatically transferred by DMA into + destination variable address. + (+++) Stop conversion and disable the ADC peripheral (master) + using function HAL_ADCEx_MultiModeStop_DMA() + (+++) Stop conversion and disable the ADC peripheral (slave) + using function HAL_ADC_Stop_IT() + + [..] + + (@) Callback functions must be implemented in user program: + (+@) HAL_ADC_ErrorCallback() + (+@) HAL_ADC_LevelOutOfWindowCallback() (callback of analog watchdog) + (+@) HAL_ADC_ConvCpltCallback() + (+@) HAL_ADC_ConvHalfCpltCallback + (+@) HAL_ADCEx_InjectedConvCpltCallback() + + *** Deinitialization of ADC *** + ============================================================ + [..] + + (#) Disable the ADC interface + (++) ADC clock can be hard reset and disabled at RCC top level. + (++) Hard reset of ADC peripherals + using macro __ADCx_FORCE_RESET(), __ADCx_RELEASE_RESET(). + (++) ADC clock disable + using the equivalent macro/functions as configuration step. + (+++) Example: + Into HAL_ADC_MspDeInit() (recommended code location) or with + other device clock parameters configuration: + (+++) PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC + (+++) PeriphClkInit.AdcClockSelection = RCC_ADCPLLCLK2_OFF + (+++) HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) + + (#) ADC pins configuration + (++) Disable the clock for the ADC GPIOs + using macro __HAL_RCC_GPIOx_CLK_DISABLE() + + (#) Optionally, in case of usage of ADC with interruptions: + (++) Disable the NVIC for ADC + using function HAL_NVIC_EnableIRQ(ADCx_IRQn) + + (#) Optionally, in case of usage of DMA: + (++) Deinitialize the DMA + using function HAL_DMA_Init(). + (++) Disable the NVIC for DMA + using function HAL_NVIC_EnableIRQ(DMAx_Channelx_IRQn) + + [..] + + *** Callback registration *** + ============================================= + [..] + + The compilation flag USE_HAL_ADC_REGISTER_CALLBACKS, when set to 1, + allows the user to configure dynamically the driver callbacks. + Use Functions HAL_ADC_RegisterCallback() + to register an interrupt callback. + [..] + + Function HAL_ADC_RegisterCallback() allows to register following callbacks: + (+) ConvCpltCallback : ADC conversion complete callback + (+) ConvHalfCpltCallback : ADC conversion DMA half-transfer callback + (+) LevelOutOfWindowCallback : ADC analog watchdog 1 callback + (+) ErrorCallback : ADC error callback + (+) InjectedConvCpltCallback : ADC group injected conversion complete callback + (+) MspInitCallback : ADC Msp Init callback + (+) MspDeInitCallback : ADC Msp DeInit callback + This function takes as parameters the HAL peripheral handle, the Callback ID + and a pointer to the user callback function. + [..] + + Use function HAL_ADC_UnRegisterCallback to reset a callback to the default + weak function. + [..] + + HAL_ADC_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + This function allows to reset following callbacks: + (+) ConvCpltCallback : ADC conversion complete callback + (+) ConvHalfCpltCallback : ADC conversion DMA half-transfer callback + (+) LevelOutOfWindowCallback : ADC analog watchdog 1 callback + (+) ErrorCallback : ADC error callback + (+) InjectedConvCpltCallback : ADC group injected conversion complete callback + (+) MspInitCallback : ADC Msp Init callback + (+) MspDeInitCallback : ADC Msp DeInit callback + [..] + + By default, after the HAL_ADC_Init() and when the state is HAL_ADC_STATE_RESET + all callbacks are set to the corresponding weak functions: + examples HAL_ADC_ConvCpltCallback(), HAL_ADC_ErrorCallback(). + Exception done for MspInit and MspDeInit functions that are + reset to the legacy weak functions in the HAL_ADC_Init()/ HAL_ADC_DeInit() only when + these callbacks are null (not registered beforehand). + [..] + + If MspInit or MspDeInit are not null, the HAL_ADC_Init()/ HAL_ADC_DeInit() + keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. + [..] + + Callbacks can be registered/unregistered in HAL_ADC_STATE_READY state only. + Exception done MspInit/MspDeInit functions that can be registered/unregistered + in HAL_ADC_STATE_READY or HAL_ADC_STATE_RESET state, + thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. + [..] + + Then, the user first registers the MspInit/MspDeInit user callbacks + using HAL_ADC_RegisterCallback() before calling HAL_ADC_DeInit() + or HAL_ADC_Init() function. + [..] + + When the compilation flag USE_HAL_ADC_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available and all callbacks + are set to the corresponding weak functions. + + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal.h" + +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @defgroup ADC ADC + * @brief ADC HAL module driver + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup ADC_Private_Constants ADC Private Constants + * @{ + */ + + /* Timeout values for ADC enable and disable settling time. */ + /* Values defined to be higher than worst cases: low clocks freq, */ + /* maximum prescaler. */ + /* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */ + /* prescaler 4, sampling time 12.5 ADC clock cycles, resolution 12 bits. */ + /* Unit: ms */ + #define ADC_ENABLE_TIMEOUT 2U + #define ADC_DISABLE_TIMEOUT 2U + + /* Delay for ADC stabilization time. */ + /* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */ + /* Unit: us */ + #define ADC_STAB_DELAY_US 1U + + /* Delay for temperature sensor stabilization time. */ + /* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */ + /* Unit: us */ + #define ADC_TEMPSENSOR_DELAY_US 10U + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @defgroup ADC_Private_Functions ADC Private Functions + * @{ + */ +/** + * @} + */ + +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup ADC_Exported_Functions ADC Exported Functions + * @{ + */ + +/** @defgroup ADC_Exported_Functions_Group1 Initialization/de-initialization functions + * @brief Initialization and Configuration functions + * +@verbatim + =============================================================================== + ##### Initialization and de-initialization functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Initialize and configure the ADC. + (+) De-initialize the ADC. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the ADC peripheral and regular group according to + * parameters specified in structure "ADC_InitTypeDef". + * @note As prerequisite, ADC clock must be configured at RCC top level + * (clock source APB2). + * See commented example code below that can be copied and uncommented + * into HAL_ADC_MspInit(). + * @note Possibility to update parameters on the fly: + * This function initializes the ADC MSP (HAL_ADC_MspInit()) only when + * coming from ADC state reset. Following calls to this function can + * be used to reconfigure some parameters of ADC_InitTypeDef + * structure on the fly, without modifying MSP configuration. If ADC + * MSP has to be modified again, HAL_ADC_DeInit() must be called + * before HAL_ADC_Init(). + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_InitTypeDef". + * @note This function configures the ADC within 2 scopes: scope of entire + * ADC and scope of regular group. For parameters details, see comments + * of structure "ADC_InitTypeDef". + * @param hadc: ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + uint32_t tmp_cr1 = 0U; + uint32_t tmp_cr2 = 0U; + uint32_t tmp_sqr1 = 0U; + + /* Check ADC handle */ + if(hadc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign)); + assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv)); + + if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE) + { + assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode)); + if(hadc->Init.DiscontinuousConvMode != DISABLE) + { + assert_param(IS_ADC_REGULAR_DISCONT_NUMBER(hadc->Init.NbrOfDiscConversion)); + } + } + + /* As prerequisite, into HAL_ADC_MspInit(), ADC clock must be configured */ + /* at RCC top level. */ + /* Refer to header of this file for more details on clock enabling */ + /* procedure. */ + + /* Actions performed only if ADC is coming from state reset: */ + /* - Initialization of ADC MSP */ + if (hadc->State == HAL_ADC_STATE_RESET) + { + /* Initialize ADC error code */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Allocate lock resource and initialize it */ + hadc->Lock = HAL_UNLOCKED; + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + /* Init the ADC Callback settings */ + hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback; /* Legacy weak callback */ + hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback; /* Legacy weak callback */ + hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback; /* Legacy weak callback */ + hadc->ErrorCallback = HAL_ADC_ErrorCallback; /* Legacy weak callback */ + hadc->InjectedConvCpltCallback = HAL_ADCEx_InjectedConvCpltCallback; /* Legacy weak callback */ + + if (hadc->MspInitCallback == NULL) + { + hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */ + } + + /* Init the low level hardware */ + hadc->MspInitCallback(hadc); +#else + /* Init the low level hardware */ + HAL_ADC_MspInit(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + /* Note: In case of ADC already enabled, precaution to not launch an */ + /* unwanted conversion while modifying register CR2 by writing 1 to */ + /* bit ADON. */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + + /* Configuration of ADC parameters if previous preliminary actions are */ + /* correctly completed. */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL) && + (tmp_hal_status == HAL_OK) ) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_BUSY_INTERNAL); + + /* Set ADC parameters */ + + /* Configuration of ADC: */ + /* - data alignment */ + /* - external trigger to start conversion */ + /* - external trigger polarity (always set to 1, because needed for all */ + /* triggers: external trigger of SW start) */ + /* - continuous conversion mode */ + /* Note: External trigger polarity (ADC_CR2_EXTTRIG) is set into */ + /* HAL_ADC_Start_xxx functions because if set in this function, */ + /* a conversion on injected group would start a conversion also on */ + /* regular group after ADC enabling. */ + tmp_cr2 |= (hadc->Init.DataAlign | + ADC_CFGR_EXTSEL(hadc, hadc->Init.ExternalTrigConv) | + ADC_CR2_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) ); + + /* Configuration of ADC: */ + /* - scan mode */ + /* - discontinuous mode disable/enable */ + /* - discontinuous mode number of conversions */ + tmp_cr1 |= (ADC_CR1_SCAN_SET(hadc->Init.ScanConvMode)); + + /* Enable discontinuous mode only if continuous mode is disabled */ + /* Note: If parameter "Init.ScanConvMode" is set to disable, parameter */ + /* discontinuous is set anyway, but will have no effect on ADC HW. */ + if (hadc->Init.DiscontinuousConvMode == ENABLE) + { + if (hadc->Init.ContinuousConvMode == DISABLE) + { + /* Enable the selected ADC regular discontinuous mode */ + /* Set the number of channels to be converted in discontinuous mode */ + SET_BIT(tmp_cr1, ADC_CR1_DISCEN | + ADC_CR1_DISCONTINUOUS_NUM(hadc->Init.NbrOfDiscConversion) ); + } + else + { + /* ADC regular group settings continuous and sequencer discontinuous*/ + /* cannot be enabled simultaneously. */ + + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + } + } + + /* Update ADC configuration register CR1 with previous settings */ + MODIFY_REG(hadc->Instance->CR1, + ADC_CR1_SCAN | + ADC_CR1_DISCEN | + ADC_CR1_DISCNUM , + tmp_cr1 ); + + /* Update ADC configuration register CR2 with previous settings */ + MODIFY_REG(hadc->Instance->CR2, + ADC_CR2_ALIGN | + ADC_CR2_EXTSEL | + ADC_CR2_EXTTRIG | + ADC_CR2_CONT , + tmp_cr2 ); + + /* Configuration of regular group sequencer: */ + /* - if scan mode is disabled, regular channels sequence length is set to */ + /* 0x00: 1 channel converted (channel on regular rank 1) */ + /* Parameter "NbrOfConversion" is discarded. */ + /* Note: Scan mode is present by hardware on this device and, if */ + /* disabled, discards automatically nb of conversions. Anyway, nb of */ + /* conversions is forced to 0x00 for alignment over all STM32 devices. */ + /* - if scan mode is enabled, regular channels sequence length is set to */ + /* parameter "NbrOfConversion" */ + if (ADC_CR1_SCAN_SET(hadc->Init.ScanConvMode) == ADC_SCAN_ENABLE) + { + tmp_sqr1 = ADC_SQR1_L_SHIFT(hadc->Init.NbrOfConversion); + } + + MODIFY_REG(hadc->Instance->SQR1, + ADC_SQR1_L , + tmp_sqr1 ); + + /* Check back that ADC registers have effectively been configured to */ + /* ensure of no potential problem of ADC core IP clocking. */ + /* Check through register CR2 (excluding bits set in other functions: */ + /* execution control bits (ADON, JSWSTART, SWSTART), regular group bits */ + /* (DMA), injected group bits (JEXTTRIG and JEXTSEL), channel internal */ + /* measurement path bit (TSVREFE). */ + if (READ_BIT(hadc->Instance->CR2, ~(ADC_CR2_ADON | ADC_CR2_DMA | + ADC_CR2_SWSTART | ADC_CR2_JSWSTART | + ADC_CR2_JEXTTRIG | ADC_CR2_JEXTSEL | + ADC_CR2_TSVREFE )) + == tmp_cr2) + { + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Set the ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_READY); + } + else + { + /* Update ADC state machine to error */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + tmp_hal_status = HAL_ERROR; + } + + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + tmp_hal_status = HAL_ERROR; + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Deinitialize the ADC peripheral registers to their default reset + * values, with deinitialization of the ADC MSP. + * If needed, the example code can be copied and uncommented into + * function HAL_ADC_MspDeInit(). + * @param hadc: ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check ADC handle */ + if(hadc == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + + /* Configuration of ADC parameters if previous preliminary actions are */ + /* correctly completed. */ + if (tmp_hal_status == HAL_OK) + { + /* ========== Reset ADC registers ========== */ + + + + + /* Reset register SR */ + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD | ADC_FLAG_JEOC | ADC_FLAG_EOC | + ADC_FLAG_JSTRT | ADC_FLAG_STRT)); + + /* Reset register CR1 */ + CLEAR_BIT(hadc->Instance->CR1, (ADC_CR1_AWDEN | ADC_CR1_JAWDEN | ADC_CR1_DISCNUM | + ADC_CR1_JDISCEN | ADC_CR1_DISCEN | ADC_CR1_JAUTO | + ADC_CR1_AWDSGL | ADC_CR1_SCAN | ADC_CR1_JEOCIE | + ADC_CR1_AWDIE | ADC_CR1_EOCIE | ADC_CR1_AWDCH )); + + /* Reset register CR2 */ + CLEAR_BIT(hadc->Instance->CR2, (ADC_CR2_TSVREFE | ADC_CR2_SWSTART | ADC_CR2_JSWSTART | + ADC_CR2_EXTTRIG | ADC_CR2_EXTSEL | ADC_CR2_JEXTTRIG | + ADC_CR2_JEXTSEL | ADC_CR2_ALIGN | ADC_CR2_DMA | + ADC_CR2_RSTCAL | ADC_CR2_CAL | ADC_CR2_CONT | + ADC_CR2_ADON )); + + /* Reset register SMPR1 */ + CLEAR_BIT(hadc->Instance->SMPR1, (ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16 | ADC_SMPR1_SMP15 | + ADC_SMPR1_SMP14 | ADC_SMPR1_SMP13 | ADC_SMPR1_SMP12 | + ADC_SMPR1_SMP11 | ADC_SMPR1_SMP10 )); + + /* Reset register SMPR2 */ + CLEAR_BIT(hadc->Instance->SMPR2, (ADC_SMPR2_SMP9 | ADC_SMPR2_SMP8 | ADC_SMPR2_SMP7 | + ADC_SMPR2_SMP6 | ADC_SMPR2_SMP5 | ADC_SMPR2_SMP4 | + ADC_SMPR2_SMP3 | ADC_SMPR2_SMP2 | ADC_SMPR2_SMP1 | + ADC_SMPR2_SMP0 )); + + /* Reset register JOFR1 */ + CLEAR_BIT(hadc->Instance->JOFR1, ADC_JOFR1_JOFFSET1); + /* Reset register JOFR2 */ + CLEAR_BIT(hadc->Instance->JOFR2, ADC_JOFR2_JOFFSET2); + /* Reset register JOFR3 */ + CLEAR_BIT(hadc->Instance->JOFR3, ADC_JOFR3_JOFFSET3); + /* Reset register JOFR4 */ + CLEAR_BIT(hadc->Instance->JOFR4, ADC_JOFR4_JOFFSET4); + + /* Reset register HTR */ + CLEAR_BIT(hadc->Instance->HTR, ADC_HTR_HT); + /* Reset register LTR */ + CLEAR_BIT(hadc->Instance->LTR, ADC_LTR_LT); + + /* Reset register SQR1 */ + CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L | + ADC_SQR1_SQ16 | ADC_SQR1_SQ15 | + ADC_SQR1_SQ14 | ADC_SQR1_SQ13 ); + + /* Reset register SQR1 */ + CLEAR_BIT(hadc->Instance->SQR1, ADC_SQR1_L | + ADC_SQR1_SQ16 | ADC_SQR1_SQ15 | + ADC_SQR1_SQ14 | ADC_SQR1_SQ13 ); + + /* Reset register SQR2 */ + CLEAR_BIT(hadc->Instance->SQR2, ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 | + ADC_SQR2_SQ9 | ADC_SQR2_SQ8 | ADC_SQR2_SQ7 ); + + /* Reset register SQR3 */ + CLEAR_BIT(hadc->Instance->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 | + ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1 ); + + /* Reset register JSQR */ + CLEAR_BIT(hadc->Instance->JSQR, ADC_JSQR_JL | + ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 | + ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 ); + + /* Reset register JSQR */ + CLEAR_BIT(hadc->Instance->JSQR, ADC_JSQR_JL | + ADC_JSQR_JSQ4 | ADC_JSQR_JSQ3 | + ADC_JSQR_JSQ2 | ADC_JSQR_JSQ1 ); + + /* Reset register DR */ + /* bits in access mode read only, no direct reset applicable*/ + + /* Reset registers JDR1, JDR2, JDR3, JDR4 */ + /* bits in access mode read only, no direct reset applicable*/ + + /* ========== Hard reset ADC peripheral ========== */ + /* Performs a global reset of the entire ADC peripheral: ADC state is */ + /* forced to a similar state after device power-on. */ + /* If needed, copy-paste and uncomment the following reset code into */ + /* function "void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)": */ + /* */ + /* __HAL_RCC_ADC1_FORCE_RESET() */ + /* __HAL_RCC_ADC1_RELEASE_RESET() */ + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + if (hadc->MspDeInitCallback == NULL) + { + hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */ + } + + /* DeInit the low level hardware */ + hadc->MspDeInitCallback(hadc); +#else + /* DeInit the low level hardware */ + HAL_ADC_MspDeInit(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + + /* Set ADC state */ + hadc->State = HAL_ADC_STATE_RESET; + + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Initializes the ADC MSP. + * @param hadc: ADC handle + * @retval None + */ +__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADC_MspInit must be implemented in the user file. + */ +} + +/** + * @brief DeInitializes the ADC MSP. + * @param hadc: ADC handle + * @retval None + */ +__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADC_MspDeInit must be implemented in the user file. + */ +} + +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User ADC Callback + * To be used instead of the weak predefined callback + * @param hadc Pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID + * @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion complete callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID + * @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID + * @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID + * @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID + * @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit callback ID + * @param pCallback pointer to the Callback function + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID, pADC_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + return HAL_ERROR; + } + + if ((hadc->State & HAL_ADC_STATE_READY) != 0) + { + switch (CallbackID) + { + case HAL_ADC_CONVERSION_COMPLETE_CB_ID : + hadc->ConvCpltCallback = pCallback; + break; + + case HAL_ADC_CONVERSION_HALF_CB_ID : + hadc->ConvHalfCpltCallback = pCallback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID : + hadc->LevelOutOfWindowCallback = pCallback; + break; + + case HAL_ADC_ERROR_CB_ID : + hadc->ErrorCallback = pCallback; + break; + + case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID : + hadc->InjectedConvCpltCallback = pCallback; + break; + + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = pCallback; + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_ADC_STATE_RESET == hadc->State) + { + switch (CallbackID) + { + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = pCallback; + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = pCallback; + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a ADC Callback + * ADC callback is redirected to the weak predefined callback + * @param hadc Pointer to a ADC_HandleTypeDef structure that contains + * the configuration information for the specified ADC. + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID + * @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion complete callback ID + * @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID + * @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID + * @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID + * @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID + * @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID + * @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit callback ID + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if ((hadc->State & HAL_ADC_STATE_READY) != 0) + { + switch (CallbackID) + { + case HAL_ADC_CONVERSION_COMPLETE_CB_ID : + hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback; + break; + + case HAL_ADC_CONVERSION_HALF_CB_ID : + hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback; + break; + + case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID : + hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback; + break; + + case HAL_ADC_ERROR_CB_ID : + hadc->ErrorCallback = HAL_ADC_ErrorCallback; + break; + + case HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID : + hadc->InjectedConvCpltCallback = HAL_ADCEx_InjectedConvCpltCallback; + break; + + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (HAL_ADC_STATE_RESET == hadc->State) + { + switch (CallbackID) + { + case HAL_ADC_MSPINIT_CB_ID : + hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */ + break; + + case HAL_ADC_MSPDEINIT_CB_ID : + hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */ + break; + + default : + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Update the error code */ + hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK; + + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group2 IO operation functions + * @brief Input and Output operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion of regular group. + (+) Stop conversion of regular group. + (+) Poll for conversion complete on regular group. + (+) Poll for conversion event. + (+) Get result of regular channel conversion. + (+) Start conversion of regular group and enable interruptions. + (+) Stop conversion of regular group and disable interruptions. + (+) Handle ADC interrupt request + (+) Start conversion of regular group and enable DMA transfer. + (+) Stop conversion of regular group and disable ADC DMA transfer. +@endverbatim + * @{ + */ + +/** + * @brief Enables ADC, starts conversion of regular group. + * Interruptions enabled in this function: None. + * @param hadc: ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC, + HAL_ADC_STATE_REG_BUSY); + + /* Set group injected state (from auto-injection) and multimode state */ + /* for all cases of multimode: independent mode, multimode ADC master */ + /* or multimode ADC slave (for devices with several ADCs): */ + if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc)) + { + /* Set ADC state (ADC independent or master) */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + } + else + { + /* Set ADC state (ADC slave) */ + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (ADC_MULTIMODE_AUTO_INJECTED(hadc)) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* State machine update: Check if an injected conversion is ongoing */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to conversions on group regular */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Clear regular group conversion flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC); + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Case of multimode enabled: */ + /* - if ADC is slave, ADC is enabled only (conversion is not started). */ + /* - if ADC is master, ADC is enabled and conversion is started. */ + /* If ADC is master, ADC is enabled and conversion is started. */ + /* Note: Alternate trigger for single conversion could be to force an */ + /* additional set of bit ADON "hadc->Instance->CR2 |= ADC_CR2_ADON;"*/ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) ) + { + /* Start ADC conversion on regular group with SW start */ + SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG)); + } + else + { + /* Start ADC conversion on regular group with external trigger */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG); + } + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected channels in + * case of auto_injection mode), disable ADC peripheral. + * @note: ADC peripheral disable is forcing stop of potential + * conversion on injected group. If injected group is under use, it + * should be preliminarily stopped using HAL_ADCEx_InjectedStop function. + * @param hadc: ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Wait for regular group conversion to be completed. + * @note This function cannot be used in a particular setup: ADC configured + * in DMA mode. + * In this case, DMA resets the flag EOC and polling cannot be + * performed on each conversion. + * @note On STM32F1 devices, limitation in case of sequencer enabled + * (several ranks selected): polling cannot be done on each + * conversion inside the sequence. In this case, polling is replaced by + * wait for maximum conversion time. + * @param hadc: ADC handle + * @param Timeout: Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) +{ + uint32_t tickstart = 0U; + + /* Variables for polling in case of scan mode enabled and polling for each */ + /* conversion. */ + __IO uint32_t Conversion_Timeout_CPU_cycles = 0U; + uint32_t Conversion_Timeout_CPU_cycles_max = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Get tick count */ + tickstart = HAL_GetTick(); + + /* Verification that ADC configuration is compliant with polling for */ + /* each conversion: */ + /* Particular case is ADC configured in DMA mode */ + if (HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_DMA)) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Polling for end of conversion: differentiation if single/sequence */ + /* conversion. */ + /* - If single conversion for regular group (Scan mode disabled or enabled */ + /* with NbrOfConversion =1), flag EOC is used to determine the */ + /* conversion completion. */ + /* - If sequence conversion for regular group (scan mode enabled and */ + /* NbrOfConversion >=2), flag EOC is set only at the end of the */ + /* sequence. */ + /* To poll for each conversion, the maximum conversion time is computed */ + /* from ADC conversion time (selected sampling time + conversion time of */ + /* 12.5 ADC clock cycles) and APB2/ADC clock prescalers (depending on */ + /* settings, conversion time range can be from 28 to 32256 CPU cycles). */ + /* As flag EOC is not set after each conversion, no timeout status can */ + /* be set. */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_SCAN) && + HAL_IS_BIT_CLR(hadc->Instance->SQR1, ADC_SQR1_L) ) + { + /* Wait until End of Conversion flag is raised */ + while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_EOC)) + { + /* Check if timeout is disabled (set to infinite wait) */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_EOC)) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + } + else + { + /* Replace polling by wait for maximum conversion time */ + /* - Computation of CPU clock cycles corresponding to ADC clock cycles */ + /* and ADC maximum conversion cycles on all channels. */ + /* - Wait for the expected ADC clock cycles delay */ + Conversion_Timeout_CPU_cycles_max = ((SystemCoreClock + / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC)) + * ADC_CONVCYCLES_MAX_RANGE(hadc) ); + + while(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max) + { + /* Check if timeout is disabled (set to infinite wait) */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + Conversion_Timeout_CPU_cycles ++; + } + } + + /* Clear regular group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC); + + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F1 devices, in case of sequencer enabled */ + /* (several ranks selected), end of conversion flag is raised */ + /* at the end of the sequence. */ + if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Return ADC state */ + return HAL_OK; +} + +/** + * @brief Poll for conversion event. + * @param hadc: ADC handle + * @param EventType: the ADC event type. + * This parameter can be one of the following values: + * @arg ADC_AWD_EVENT: ADC Analog watchdog event. + * @param Timeout: Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout) +{ + uint32_t tickstart = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_EVENT_TYPE(EventType)); + + /* Get tick count */ + tickstart = HAL_GetTick(); + + /* Check selected event flag */ + while(__HAL_ADC_GET_FLAG(hadc, EventType) == RESET) + { + /* Check if timeout is disabled (set to infinite wait) */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if(__HAL_ADC_GET_FLAG(hadc, EventType) == RESET) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + + /* Analog watchdog (level out of window) event */ + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); + + /* Clear ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); + + /* Return ADC state */ + return HAL_OK; +} + +/** + * @brief Enables ADC, starts conversion of regular group with interruption. + * Interruptions enabled in this function: + * - EOC (end of conversion of regular group) + * Each of these interruptions has its dedicated callback function. + * @param hadc: ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP, + HAL_ADC_STATE_REG_BUSY); + + /* Set group injected state (from auto-injection) and multimode state */ + /* for all cases of multimode: independent mode, multimode ADC master */ + /* or multimode ADC slave (for devices with several ADCs): */ + if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc)) + { + /* Set ADC state (ADC independent or master) */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + } + else + { + /* Set ADC state (ADC slave) */ + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (ADC_MULTIMODE_AUTO_INJECTED(hadc)) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* State machine update: Check if an injected conversion is ongoing */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to conversions on group regular */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Clear regular group conversion flag and overrun flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC); + + /* Enable end of conversion interrupt for regular group */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_EOC); + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Case of multimode enabled: */ + /* - if ADC is slave, ADC is enabled only (conversion is not started). */ + /* - if ADC is master, ADC is enabled and conversion is started. */ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) ) + { + /* Start ADC conversion on regular group with SW start */ + SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG)); + } + else + { + /* Start ADC conversion on regular group with external trigger */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG); + } + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected group in + * case of auto_injection mode), disable interrution of + * end-of-conversion, disable ADC peripheral. + * @param hadc: ADC handle + * @retval None + */ +HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Disable ADC end of conversion interrupt for regular group */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Enables ADC, starts conversion of regular group and transfers result + * through DMA. + * Interruptions enabled in this function: + * - DMA transfer complete + * - DMA half transfer + * Each of these interruptions has its dedicated callback function. + * @note For devices with several ADCs: This function is for single-ADC mode + * only. For multimode, use the dedicated MultimodeStart function. + * @note On STM32F1 devices, only ADC1 and ADC3 (ADC availability depending + * on devices) have DMA capability. + * ADC2 converted data can be transferred in dual ADC mode using DMA + * of ADC1 (ADC master in multimode). + * In case of using ADC1 with DMA on a device featuring 2 ADC + * instances: ADC1 conversion register DR contains ADC1 conversion + * result (ADC1 register DR bits 0 to 11) and, additionally, ADC2 last + * conversion result (ADC1 register DR bits 16 to 27). Therefore, to + * have DMA transferring the conversion results of ADC1 only, DMA must + * be configured to transfer size: half word. + * @param hadc: ADC handle + * @param pData: The destination Buffer address. + * @param Length: The length of data to be transferred from ADC peripheral to memory. + * @retval None + */ +HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_DMA_CAPABILITY_INSTANCE(hadc->Instance)); + + /* Verification if multimode is disabled (for devices with several ADC) */ + /* If multimode is enabled, dedicated function multimode conversion */ + /* start DMA must be used. */ + if(ADC_MULTIMODE_IS_ENABLE(hadc) == RESET) + { + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP, + HAL_ADC_STATE_REG_BUSY); + + /* Set group injected state (from auto-injection) and multimode state */ + /* for all cases of multimode: independent mode, multimode ADC master */ + /* or multimode ADC slave (for devices with several ADCs): */ + if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc)) + { + /* Set ADC state (ADC independent or master) */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + } + else + { + /* Set ADC state (ADC slave) */ + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (ADC_MULTIMODE_AUTO_INJECTED(hadc)) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + } + + /* State machine update: Check if an injected conversion is ongoing */ + if (HAL_IS_BIT_SET(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + /* Reset ADC error code fields related to conversions on group regular */ + CLEAR_BIT(hadc->ErrorCode, (HAL_ADC_ERROR_OVR | HAL_ADC_ERROR_DMA)); + } + else + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Set the DMA transfer complete callback */ + hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; + + /* Set the DMA half transfer complete callback */ + hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; + + /* Set the DMA error callback */ + hadc->DMA_Handle->XferErrorCallback = ADC_DMAError; + + + /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */ + /* start (in case of SW start): */ + + /* Clear regular group conversion flag and overrun flag */ + /* (To ensure of no unknown state from potential previous ADC */ + /* operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC); + + /* Enable ADC DMA mode */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_DMA); + + /* Start the DMA channel */ + HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); + + /* Enable conversion of regular group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc)) + { + /* Start ADC conversion on regular group with SW start */ + SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG)); + } + else + { + /* Start ADC conversion on regular group with external trigger */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG); + } + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + } + else + { + tmp_hal_status = HAL_ERROR; + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected group in + * case of auto_injection mode), disable ADC DMA transfer, disable + * ADC peripheral. + * @note: ADC peripheral disable is forcing stop of potential + * conversion on injected group. If injected group is under use, it + * should be preliminarily stopped using HAL_ADCEx_InjectedStop function. + * @note For devices with several ADCs: This function is for single-ADC mode + * only. For multimode, use the dedicated MultimodeStop function. + * @note On STM32F1 devices, only ADC1 and ADC3 (ADC availability depending + * on devices) have DMA capability. + * @param hadc: ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_DMA_CAPABILITY_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Disable ADC DMA mode */ + CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA); + + /* Disable the DMA channel (in case of DMA in circular mode or stop while */ + /* DMA transfer is on going) */ + if (hadc->DMA_Handle->State == HAL_DMA_STATE_BUSY) + { + tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); + + /* Check if DMA channel effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA); + } + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Get ADC regular group conversion result. + * @note Reading register DR automatically clears ADC flag EOC + * (ADC group regular end of unitary conversion). + * @note This function does not clear ADC flag EOS + * (ADC group regular end of sequence conversion). + * Occurrence of flag EOS rising: + * - If sequencer is composed of 1 rank, flag EOS is equivalent + * to flag EOC. + * - If sequencer is composed of several ranks, during the scan + * sequence flag EOC only is raised, at the end of the scan sequence + * both flags EOC and EOS are raised. + * To clear this flag, either use function: + * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming + * model polling: @ref HAL_ADC_PollForConversion() + * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS). + * @param hadc: ADC handle + * @retval ADC group regular conversion data + */ +uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Note: EOC flag is not cleared here by software because automatically */ + /* cleared by hardware when reading register DR. */ + + /* Return ADC converted value */ + return hadc->Instance->DR; +} + +/** + * @brief Handles ADC interrupt request + * @param hadc: ADC handle + * @retval None + */ +void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc) +{ + uint32_t tmp_sr = hadc->Instance->SR; + uint32_t tmp_cr1 = hadc->Instance->CR1; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + assert_param(IS_ADC_REGULAR_NB_CONV(hadc->Init.NbrOfConversion)); + + + /* ========== Check End of Conversion flag for regular group ========== */ + if((tmp_cr1 & ADC_IT_EOC) == ADC_IT_EOC) + { + if((tmp_sr & ADC_FLAG_EOC) == ADC_FLAG_EOC) + { + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + } + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F1 devices, in case of sequencer enabled */ + /* (several ranks selected), end of conversion flag is raised */ + /* at the end of the sequence. */ + if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) + { + /* Disable ADC end of conversion interrupt on group regular */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Conversion complete callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ConvCpltCallback(hadc); +#else + HAL_ADC_ConvCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear regular group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_STRT | ADC_FLAG_EOC); + } + } + + /* ========== Check End of Conversion flag for injected group ========== */ + if((tmp_cr1 & ADC_IT_JEOC) == ADC_IT_JEOC) + { + if((tmp_sr & ADC_FLAG_JEOC) == ADC_FLAG_JEOC) + { + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL)) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC); + } + + /* Determine whether any further conversion upcoming on group injected */ + /* by external trigger, scan sequence on going or by automatic injected */ + /* conversion from group regular (same conditions as group regular */ + /* interruption disabling above). */ + /* Note: On STM32F1 devices, in case of sequencer enabled */ + /* (several ranks selected), end of conversion flag is raised */ + /* at the end of the sequence. */ + if(ADC_IS_SOFTWARE_START_INJECTED(hadc) || + (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) && + (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) ) ) + { + /* Disable ADC end of conversion interrupt on group injected */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Conversion complete callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->InjectedConvCpltCallback(hadc); +#else + HAL_ADCEx_InjectedConvCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear injected group conversion flag */ + __HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_JSTRT | ADC_FLAG_JEOC)); + } + } + + /* ========== Check Analog watchdog flags ========== */ + if((tmp_cr1 & ADC_IT_AWD) == ADC_IT_AWD) + { + if((tmp_sr & ADC_FLAG_AWD) == ADC_FLAG_AWD) + { + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_AWD1); + + /* Level out of window callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->LevelOutOfWindowCallback(hadc); +#else + HAL_ADC_LevelOutOfWindowCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + + /* Clear the ADC analog watchdog flag */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD); + } + } + +} + +/** + * @brief Conversion complete callback in non blocking mode + * @param hadc: ADC handle + * @retval None + */ +__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADC_ConvCpltCallback must be implemented in the user file. + */ +} + +/** + * @brief Conversion DMA half-transfer callback in non blocking mode + * @param hadc: ADC handle + * @retval None + */ +__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file. + */ +} + +/** + * @brief Analog watchdog callback in non blocking mode. + * @param hadc: ADC handle + * @retval None + */ +__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADC_LevelOutOfWindowCallback must be implemented in the user file. + */ +} + +/** + * @brief ADC error callback in non blocking mode + * (ADC conversion with interruption or transfer by DMA) + * @param hadc: ADC handle + * @retval None + */ +__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function should not be modified. When the callback is needed, + function HAL_ADC_ErrorCallback must be implemented in the user file. + */ +} + + +/** + * @} + */ + +/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure channels on regular group + (+) Configure the analog watchdog + +@endverbatim + * @{ + */ + +/** + * @brief Configures the the selected channel to be linked to the regular + * group. + * @note In case of usage of internal measurement channels: + * Vbat/VrefInt/TempSensor. + * These internal paths can be be disabled using function + * HAL_ADC_DeInit(). + * @note Possibility to update parameters on the fly: + * This function initializes channel into regular group, following + * calls to this function can be used to reconfigure some parameters + * of structure "ADC_ChannelConfTypeDef" on the fly, without resetting + * the ADC. + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_ChannelConfTypeDef". + * @param hadc: ADC handle + * @param sConfig: Structure of ADC channel for regular group. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + __IO uint32_t wait_loop_index = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_CHANNEL(sConfig->Channel)); + assert_param(IS_ADC_REGULAR_RANK(sConfig->Rank)); + assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime)); + + /* Process locked */ + __HAL_LOCK(hadc); + + + /* Regular sequence configuration */ + /* For Rank 1 to 6 */ + if (sConfig->Rank < 7U) + { + MODIFY_REG(hadc->Instance->SQR3 , + ADC_SQR3_RK(ADC_SQR3_SQ1, sConfig->Rank) , + ADC_SQR3_RK(sConfig->Channel, sConfig->Rank) ); + } + /* For Rank 7 to 12 */ + else if (sConfig->Rank < 13U) + { + MODIFY_REG(hadc->Instance->SQR2 , + ADC_SQR2_RK(ADC_SQR2_SQ7, sConfig->Rank) , + ADC_SQR2_RK(sConfig->Channel, sConfig->Rank) ); + } + /* For Rank 13 to 16 */ + else + { + MODIFY_REG(hadc->Instance->SQR1 , + ADC_SQR1_RK(ADC_SQR1_SQ13, sConfig->Rank) , + ADC_SQR1_RK(sConfig->Channel, sConfig->Rank) ); + } + + + /* Channel sampling time configuration */ + /* For channels 10 to 17 */ + if (sConfig->Channel >= ADC_CHANNEL_10) + { + MODIFY_REG(hadc->Instance->SMPR1 , + ADC_SMPR1(ADC_SMPR1_SMP10, sConfig->Channel) , + ADC_SMPR1(sConfig->SamplingTime, sConfig->Channel) ); + } + else /* For channels 0 to 9 */ + { + MODIFY_REG(hadc->Instance->SMPR2 , + ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel) , + ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel) ); + } + + /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */ + /* and VREFINT measurement path. */ + if ((sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) || + (sConfig->Channel == ADC_CHANNEL_VREFINT) ) + { + /* For STM32F1 devices with several ADC: Only ADC1 can access internal */ + /* measurement channels (VrefInt/TempSensor). If these channels are */ + /* intended to be set on other ADC instances, an error is reported. */ + if (hadc->Instance == ADC1) + { + if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET) + { + SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE); + + if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR) + { + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U)); + while(wait_loop_index != 0U) + { + wait_loop_index--; + } + } + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Configures the analog watchdog. + * @note Analog watchdog thresholds can be modified while ADC conversion + * is on going. + * In this case, some constraints must be taken into account: + * the programmed threshold values are effective from the next + * ADC EOC (end of unitary conversion). + * Considering that registers write delay may happen due to + * bus activity, this might cause an uncertainty on the + * effective timing of the new programmed threshold values. + * @param hadc: ADC handle + * @param AnalogWDGConfig: Structure of ADC analog watchdog configuration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig) +{ + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode)); + assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode)); + assert_param(IS_ADC_RANGE(AnalogWDGConfig->HighThreshold)); + assert_param(IS_ADC_RANGE(AnalogWDGConfig->LowThreshold)); + + if((AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG) || + (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_INJEC) || + (AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REGINJEC) ) + { + assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Analog watchdog configuration */ + + /* Configure ADC Analog watchdog interrupt */ + if(AnalogWDGConfig->ITMode == ENABLE) + { + /* Enable the ADC Analog watchdog interrupt */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD); + } + else + { + /* Disable the ADC Analog watchdog interrupt */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD); + } + + /* Configuration of analog watchdog: */ + /* - Set the analog watchdog enable mode: regular and/or injected groups, */ + /* one or all channels. */ + /* - Set the Analog watchdog channel (is not used if watchdog */ + /* mode "all channels": ADC_CFGR_AWD1SGL=0). */ + MODIFY_REG(hadc->Instance->CR1 , + ADC_CR1_AWDSGL | + ADC_CR1_JAWDEN | + ADC_CR1_AWDEN | + ADC_CR1_AWDCH , + AnalogWDGConfig->WatchdogMode | + AnalogWDGConfig->Channel ); + + /* Set the high threshold */ + WRITE_REG(hadc->Instance->HTR, AnalogWDGConfig->HighThreshold); + + /* Set the low threshold */ + WRITE_REG(hadc->Instance->LTR, AnalogWDGConfig->LowThreshold); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return HAL_OK; +} + + +/** + * @} + */ + + +/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions + * @brief Peripheral State functions + * +@verbatim + =============================================================================== + ##### Peripheral State and Errors functions ##### + =============================================================================== + [..] + This subsection provides functions to get in run-time the status of the + peripheral. + (+) Check the ADC state + (+) Check the ADC error code + +@endverbatim + * @{ + */ + +/** + * @brief return the ADC state + * @param hadc: ADC handle + * @retval HAL state + */ +uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc) +{ + /* Return ADC state */ + return hadc->State; +} + +/** + * @brief Return the ADC error code + * @param hadc: ADC handle + * @retval ADC Error Code + */ +uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc) +{ + return hadc->ErrorCode; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup ADC_Private_Functions ADC Private Functions + * @{ + */ + +/** + * @brief Enable the selected ADC. + * @note Prerequisite condition to use this function: ADC must be disabled + * and voltage regulator must be enabled (done into HAL_ADC_Init()). + * @param hadc: ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc) +{ + uint32_t tickstart = 0U; + __IO uint32_t wait_loop_index = 0U; + + /* ADC enable and wait for ADC ready (in case of ADC is disabled or */ + /* enabling phase not yet completed: flag ADC ready not yet set). */ + /* Timeout implemented to not be stuck if ADC cannot be enabled (possible */ + /* causes: ADC clock not running, ...). */ + if (ADC_IS_ENABLE(hadc) == RESET) + { + /* Enable the Peripheral */ + __HAL_ADC_ENABLE(hadc); + + /* Delay for ADC stabilization time */ + /* Compute number of CPU cycles to wait for */ + wait_loop_index = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U)); + while(wait_loop_index != 0U) + { + wait_loop_index--; + } + + /* Get tick count */ + tickstart = HAL_GetTick(); + + /* Wait for ADC effectively enabled */ + while(ADC_IS_ENABLE(hadc) == RESET) + { + if((HAL_GetTick() - tickstart) > ADC_ENABLE_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if(ADC_IS_ENABLE(hadc) == RESET) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + } + } + } + + /* Return HAL status */ + return HAL_OK; +} + +/** + * @brief Stop ADC conversion and disable the selected ADC + * @note Prerequisite condition to use this function: ADC conversions must be + * stopped to disable the ADC. + * @param hadc: ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef ADC_ConversionStop_Disable(ADC_HandleTypeDef* hadc) +{ + uint32_t tickstart = 0U; + + /* Verification if ADC is not already disabled */ + if (ADC_IS_ENABLE(hadc) != RESET) + { + /* Disable the ADC peripheral */ + __HAL_ADC_DISABLE(hadc); + + /* Get tick count */ + tickstart = HAL_GetTick(); + + /* Wait for ADC effectively disabled */ + while(ADC_IS_ENABLE(hadc) != RESET) + { + if((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if(ADC_IS_ENABLE(hadc) != RESET) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Set ADC error code to ADC IP internal error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL); + + return HAL_ERROR; + } + } + } + } + + /* Return HAL status */ + return HAL_OK; +} + +/** + * @brief DMA transfer complete callback. + * @param hdma: pointer to DMA handle. + * @retval None + */ +void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Update state machine on conversion status if not in error state */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA)) + { + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC); + + /* Determine whether any further conversion upcoming on group regular */ + /* by external trigger, continuous mode or scan sequence on going. */ + /* Note: On STM32F1 devices, in case of sequencer enabled */ + /* (several ranks selected), end of conversion flag is raised */ + /* at the end of the sequence. */ + if(ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_REG_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_INJ_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Conversion complete callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ConvCpltCallback(hadc); +#else + HAL_ADC_ConvCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ + } + else + { + /* Call DMA error callback */ + hadc->DMA_Handle->XferErrorCallback(hdma); + } +} + +/** + * @brief DMA half transfer complete callback. + * @param hdma: pointer to DMA handle. + * @retval None + */ +void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Half conversion callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ConvHalfCpltCallback(hadc); +#else + HAL_ADC_ConvHalfCpltCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +} + +/** + * @brief DMA error callback + * @param hdma: pointer to DMA handle. + * @retval None + */ +void ADC_DMAError(DMA_HandleTypeDef *hdma) +{ + /* Retrieve ADC handle corresponding to current DMA handle */ + ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; + + /* Set ADC state */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA); + + /* Set ADC error code to DMA error */ + SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA); + + /* Error callback */ +#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1) + hadc->ErrorCallback(hadc); +#else + HAL_ADC_ErrorCallback(hadc); +#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */ +} + +/** + * @} + */ + +#endif /* HAL_ADC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c new file mode 100644 index 0000000..af85089 --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c @@ -0,0 +1,1325 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_adc_ex.c + * @author MCD Application Team + * @brief This file provides firmware functions to manage the following + * functionalities of the Analog to Digital Convertor (ADC) + * peripheral: + * + Peripheral Control functions + * Other functions (generic functions) are available in file + * "stm32f1xx_hal_adc.c". + * + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + [..] + (@) Sections "ADC peripheral features" and "How to use this driver" are + available in file of generic functions "stm32f1xx_hal_adc.c". + [..] + @endverbatim + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal.h" + +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @defgroup ADCEx ADCEx + * @brief ADC Extension HAL module driver + * @{ + */ + +#ifdef HAL_ADC_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/** @defgroup ADCEx_Private_Constants ADCEx Private Constants + * @{ + */ + + /* Delay for ADC calibration: */ + /* Hardware prerequisite before starting a calibration: the ADC must have */ + /* been in power-on state for at least two ADC clock cycles. */ + /* Unit: ADC clock cycles */ + #define ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES 2U + + /* Timeout value for ADC calibration */ + /* Value defined to be higher than worst cases: low clocks freq, */ + /* maximum prescaler. */ + /* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */ + /* prescaler 4, sampling time 12.5 ADC clock cycles, resolution 12 bits. */ + /* Unit: ms */ + #define ADC_CALIBRATION_TIMEOUT 10U + + /* Delay for temperature sensor stabilization time. */ + /* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */ + /* Unit: us */ + #define ADC_TEMPSENSOR_DELAY_US 10U + +/** + * @} + */ + +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +/** @defgroup ADCEx_Exported_Functions ADCEx Exported Functions + * @{ + */ + +/** @defgroup ADCEx_Exported_Functions_Group1 Extended Extended IO operation functions + * @brief Extended Extended Input and Output operation functions + * +@verbatim + =============================================================================== + ##### IO operation functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Start conversion of injected group. + (+) Stop conversion of injected group. + (+) Poll for conversion complete on injected group. + (+) Get result of injected channel conversion. + (+) Start conversion of injected group and enable interruptions. + (+) Stop conversion of injected group and disable interruptions. + + (+) Start multimode and enable DMA transfer. + (+) Stop multimode and disable ADC DMA transfer. + (+) Get result of multimode conversion. + + (+) Perform the ADC self-calibration for single or differential ending. + (+) Get calibration factors for single or differential ending. + (+) Set calibration factors for single or differential ending. + +@endverbatim + * @{ + */ + +/** + * @brief Perform an ADC automatic self-calibration + * Calibration prerequisite: ADC must be disabled (execute this + * function before HAL_ADC_Start() or after HAL_ADC_Stop() ). + * During calibration process, ADC is enabled. ADC is let enabled at + * the completion of this function. + * @param hadc: ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_Calibration_Start(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + uint32_t tickstart; + __IO uint32_t wait_loop_index = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* 1. Disable ADC peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + /* 2. Calibration prerequisite delay before starting the calibration. */ + /* - ADC must be enabled for at least two ADC clock cycles */ + tmp_hal_status = ADC_Enable(hadc); + + /* Check if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_BUSY_INTERNAL); + + /* Hardware prerequisite: delay before starting the calibration. */ + /* - Computation of CPU clock cycles corresponding to ADC clock cycles. */ + /* - Wait for the expected ADC clock cycles delay */ + wait_loop_index = ((SystemCoreClock + / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC)) + * ADC_PRECALIBRATION_DELAY_ADCCLOCKCYCLES ); + + while(wait_loop_index != 0U) + { + wait_loop_index--; + } + + /* 3. Resets ADC calibration registers */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_RSTCAL); + + tickstart = HAL_GetTick(); + + /* Wait for calibration reset completion */ + while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL)) + { + if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_RSTCAL)) + { + /* Update ADC state machine to error */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_ERROR_INTERNAL); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + } + } + + /* 4. Start ADC calibration */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_CAL); + + tickstart = HAL_GetTick(); + + /* Wait for calibration completion */ + while(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL)) + { + if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT) + { + /* New check to avoid false timeout detection in case of preemption */ + if(HAL_IS_BIT_SET(hadc->Instance->CR2, ADC_CR2_CAL)) + { + /* Update ADC state machine to error */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_ERROR_INTERNAL); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + } + } + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_BUSY_INTERNAL, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Enables ADC, starts conversion of injected group. + * Interruptions enabled in this function: None. + * @param hadc: ADC handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to injected group conversion results */ + /* - Set state bitfield related to injected operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC, + HAL_ADC_STATE_INJ_BUSY); + + /* Case of independent mode or multimode (for devices with several ADCs): */ + /* Set multimode state. */ + if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc)) + { + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } + else + { + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } + + /* Check if a regular conversion is ongoing */ + /* Note: On this device, there is no ADC error code fields related to */ + /* conversions on group injected only. In case of conversion on */ + /* going on group regular, no error code is reset. */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Clear injected group conversion flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); + + /* Enable conversion of injected group. */ + /* If software start has been selected, conversion starts immediately. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* If automatic injected conversion is enabled, conversion will start */ + /* after next regular group conversion. */ + /* Case of multimode enabled (for devices with several ADCs): if ADC is */ + /* slave, ADC is enabled only (conversion is not started). If ADC is */ + /* master, ADC is enabled and conversion is started. */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO)) + { + if (ADC_IS_SOFTWARE_START_INJECTED(hadc) && + ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) ) + { + /* Start ADC conversion on injected group with SW start */ + SET_BIT(hadc->Instance->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG)); + } + else + { + /* Start ADC conversion on injected group with external trigger */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_JEXTTRIG); + } + } + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop conversion of injected channels. Disable ADC peripheral if + * no regular conversion is on going. + * @note If ADC must be disabled and if conversion is on going on + * regular group, function HAL_ADC_Stop must be used to stop both + * injected and regular groups, and disable the ADC. + * @note If injected group mode auto-injection is enabled, + * function HAL_ADC_Stop must be used. + * @note In case of auto-injection mode, HAL_ADC_Stop must be used. + * @param hadc: ADC handle + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion and disable ADC peripheral */ + /* Conditioned to: */ + /* - No conversion on the other group (regular group) is intended to */ + /* continue (injected and regular groups stop conversion and ADC disable */ + /* are common) */ + /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */ + if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) && + HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) ) + { + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Wait for injected group conversion to be completed. + * @param hadc: ADC handle + * @param Timeout: Timeout value in millisecond. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedPollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout) +{ + uint32_t tickstart; + + /* Variables for polling in case of scan mode enabled and polling for each */ + /* conversion. */ + __IO uint32_t Conversion_Timeout_CPU_cycles = 0U; + uint32_t Conversion_Timeout_CPU_cycles_max = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Get timeout */ + tickstart = HAL_GetTick(); + + /* Polling for end of conversion: differentiation if single/sequence */ + /* conversion. */ + /* For injected group, flag JEOC is set only at the end of the sequence, */ + /* not for each conversion within the sequence. */ + /* - If single conversion for injected group (scan mode disabled or */ + /* InjectedNbrOfConversion ==1), flag JEOC is used to determine the */ + /* conversion completion. */ + /* - If sequence conversion for injected group (scan mode enabled and */ + /* InjectedNbrOfConversion >=2), flag JEOC is set only at the end of the */ + /* sequence. */ + /* To poll for each conversion, the maximum conversion time is computed */ + /* from ADC conversion time (selected sampling time + conversion time of */ + /* 12.5 ADC clock cycles) and APB2/ADC clock prescalers (depending on */ + /* settings, conversion time range can be from 28 to 32256 CPU cycles). */ + /* As flag JEOC is not set after each conversion, no timeout status can */ + /* be set. */ + if ((hadc->Instance->JSQR & ADC_JSQR_JL) == RESET) + { + /* Wait until End of Conversion flag is raised */ + while(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_JEOC)) + { + /* Check if timeout is disabled (set to infinite wait) */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0U) || ((HAL_GetTick() - tickstart ) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if(HAL_IS_BIT_CLR(hadc->Instance->SR, ADC_FLAG_JEOC)) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + } + } + else + { + /* Replace polling by wait for maximum conversion time */ + /* - Computation of CPU clock cycles corresponding to ADC clock cycles */ + /* and ADC maximum conversion cycles on all channels. */ + /* - Wait for the expected ADC clock cycles delay */ + Conversion_Timeout_CPU_cycles_max = ((SystemCoreClock + / HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_ADC)) + * ADC_CONVCYCLES_MAX_RANGE(hadc) ); + + while(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max) + { + /* Check if timeout is disabled (set to infinite wait) */ + if(Timeout != HAL_MAX_DELAY) + { + if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) + { + /* New check to avoid false timeout detection in case of preemption */ + if(Conversion_Timeout_CPU_cycles < Conversion_Timeout_CPU_cycles_max) + { + /* Update ADC state machine to timeout */ + SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_TIMEOUT; + } + } + } + Conversion_Timeout_CPU_cycles ++; + } + } + + /* Clear injected group conversion flag */ + /* Note: On STM32F1 ADC, clear regular conversion flag raised */ + /* simultaneously. */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JSTRT | ADC_FLAG_JEOC | ADC_FLAG_EOC); + + /* Update ADC state machine */ + SET_BIT(hadc->State, HAL_ADC_STATE_INJ_EOC); + + /* Determine whether any further conversion upcoming on group injected */ + /* by external trigger or by automatic injected conversion */ + /* from group regular. */ + if(ADC_IS_SOFTWARE_START_INJECTED(hadc) || + (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) && + (ADC_IS_SOFTWARE_START_REGULAR(hadc) && + (hadc->Init.ContinuousConvMode == DISABLE) ) ) ) + { + /* Set ADC state */ + CLEAR_BIT(hadc->State, HAL_ADC_STATE_INJ_BUSY); + + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + SET_BIT(hadc->State, HAL_ADC_STATE_READY); + } + } + + /* Return ADC state */ + return HAL_OK; +} + +/** + * @brief Enables ADC, starts conversion of injected group with interruption. + * - JEOC (end of conversion of injected group) + * Each of these interruptions has its dedicated callback function. + * @param hadc: ADC handle + * @retval HAL status. + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStart_IT(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Enable the ADC peripheral */ + tmp_hal_status = ADC_Enable(hadc); + + /* Start conversion if ADC is effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state */ + /* - Clear state bitfield related to injected group conversion results */ + /* - Set state bitfield related to injected operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_INJ_EOC, + HAL_ADC_STATE_INJ_BUSY); + + /* Case of independent mode or multimode (for devices with several ADCs): */ + /* Set multimode state. */ + if (ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc)) + { + CLEAR_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } + else + { + SET_BIT(hadc->State, HAL_ADC_STATE_MULTIMODE_SLAVE); + } + + /* Check if a regular conversion is ongoing */ + /* Note: On this device, there is no ADC error code fields related to */ + /* conversions on group injected only. In case of conversion on */ + /* going on group regular, no error code is reset. */ + if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_REG_BUSY)) + { + /* Reset ADC all error code fields */ + ADC_CLEAR_ERRORCODE(hadc); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Clear injected group conversion flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_JEOC); + + /* Enable end of conversion interrupt for injected channels */ + __HAL_ADC_ENABLE_IT(hadc, ADC_IT_JEOC); + + /* Start conversion of injected group if software start has been selected */ + /* and if automatic injected conversion is disabled. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* If automatic injected conversion is enabled, conversion will start */ + /* after next regular group conversion. */ + if (HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO)) + { + if (ADC_IS_SOFTWARE_START_INJECTED(hadc) && + ADC_NONMULTIMODE_OR_MULTIMODEMASTER(hadc) ) + { + /* Start ADC conversion on injected group with SW start */ + SET_BIT(hadc->Instance->CR2, (ADC_CR2_JSWSTART | ADC_CR2_JEXTTRIG)); + } + else + { + /* Start ADC conversion on injected group with external trigger */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_JEXTTRIG); + } + } + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop conversion of injected channels, disable interruption of + * end-of-conversion. Disable ADC peripheral if no regular conversion + * is on going. + * @note If ADC must be disabled and if conversion is on going on + * regular group, function HAL_ADC_Stop must be used to stop both + * injected and regular groups, and disable the ADC. + * @note If injected group mode auto-injection is enabled, + * function HAL_ADC_Stop must be used. + * @param hadc: ADC handle + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedStop_IT(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion and disable ADC peripheral */ + /* Conditioned to: */ + /* - No conversion on the other group (regular group) is intended to */ + /* continue (injected and regular groups stop conversion and ADC disable */ + /* are common) */ + /* - In case of auto-injection mode, HAL_ADC_Stop must be used. */ + if(((hadc->State & HAL_ADC_STATE_REG_BUSY) == RESET) && + HAL_IS_BIT_CLR(hadc->Instance->CR1, ADC_CR1_JAUTO) ) + { + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if (tmp_hal_status == HAL_OK) + { + /* Disable ADC end of conversion interrupt for injected channels */ + __HAL_ADC_DISABLE_IT(hadc, ADC_IT_JEOC); + + /* Set ADC state */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +/** + * @brief Enables ADC, starts conversion of regular group and transfers result + * through DMA. + * Multimode must have been previously configured using + * HAL_ADCEx_MultiModeConfigChannel() function. + * Interruptions enabled in this function: + * - DMA transfer complete + * - DMA half transfer + * Each of these interruptions has its dedicated callback function. + * @note: On STM32F1 devices, ADC slave regular group must be configured + * with conversion trigger ADC_SOFTWARE_START. + * @note: ADC slave can be enabled preliminarily using single-mode + * HAL_ADC_Start() function. + * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used) + * @param pData: The destination Buffer address. + * @param Length: The length of data to be transferred from ADC peripheral to memory. + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStart_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + ADC_HandleTypeDef tmphadcSlave={0}; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Set a temporary handle of the ADC slave associated to the ADC master */ + ADC_MULTI_SLAVE(hadc, &tmphadcSlave); + + /* On STM32F1 devices, ADC slave regular group must be configured with */ + /* conversion trigger ADC_SOFTWARE_START. */ + /* Note: External trigger of ADC slave must be enabled, it is already done */ + /* into function "HAL_ADC_Init()". */ + if(!ADC_IS_SOFTWARE_START_REGULAR(&tmphadcSlave)) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Enable the ADC peripherals: master and slave (in case if not already */ + /* enabled previously) */ + tmp_hal_status = ADC_Enable(hadc); + if (tmp_hal_status == HAL_OK) + { + tmp_hal_status = ADC_Enable(&tmphadcSlave); + } + + /* Start conversion if all ADCs of multimode are effectively enabled */ + if (tmp_hal_status == HAL_OK) + { + /* Set ADC state (ADC master) */ + /* - Clear state bitfield related to regular group conversion results */ + /* - Set state bitfield related to regular operation */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_MULTIMODE_SLAVE, + HAL_ADC_STATE_REG_BUSY); + + /* If conversions on group regular are also triggering group injected, */ + /* update ADC state. */ + if (READ_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO) != RESET) + { + ADC_STATE_CLR_SET(hadc->State, HAL_ADC_STATE_INJ_EOC, HAL_ADC_STATE_INJ_BUSY); + } + + /* Process unlocked */ + /* Unlock before starting ADC conversions: in case of potential */ + /* interruption, to let the process to ADC IRQ Handler. */ + __HAL_UNLOCK(hadc); + + /* Set ADC error code to none */ + ADC_CLEAR_ERRORCODE(hadc); + + + /* Set the DMA transfer complete callback */ + hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt; + + /* Set the DMA half transfer complete callback */ + hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt; + + /* Set the DMA error callback */ + hadc->DMA_Handle->XferErrorCallback = ADC_DMAError; + + + /* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */ + /* start (in case of SW start): */ + + /* Clear regular group conversion flag and overrun flag */ + /* (To ensure of no unknown state from potential previous ADC operations) */ + __HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_EOC); + + /* Enable ADC DMA mode of ADC master */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_DMA); + + /* Start the DMA channel */ + HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length); + + /* Start conversion of regular group if software start has been selected. */ + /* If external trigger has been selected, conversion will start at next */ + /* trigger event. */ + /* Note: Alternate trigger for single conversion could be to force an */ + /* additional set of bit ADON "hadc->Instance->CR2 |= ADC_CR2_ADON;"*/ + if (ADC_IS_SOFTWARE_START_REGULAR(hadc)) + { + /* Start ADC conversion on regular group with SW start */ + SET_BIT(hadc->Instance->CR2, (ADC_CR2_SWSTART | ADC_CR2_EXTTRIG)); + } + else + { + /* Start ADC conversion on regular group with external trigger */ + SET_BIT(hadc->Instance->CR2, ADC_CR2_EXTTRIG); + } + } + else + { + /* Process unlocked */ + __HAL_UNLOCK(hadc); + } + + /* Return function status */ + return tmp_hal_status; +} + +/** + * @brief Stop ADC conversion of regular group (and injected channels in + * case of auto_injection mode), disable ADC DMA transfer, disable + * ADC peripheral. + * @note Multimode is kept enabled after this function. To disable multimode + * (set with HAL_ADCEx_MultiModeConfigChannel(), ADC must be + * reinitialized using HAL_ADC_Init() or HAL_ADC_ReInit(). + * @note In case of DMA configured in circular mode, function + * HAL_ADC_Stop_DMA must be called after this function with handle of + * ADC slave, to properly disable the DMA channel. + * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used) + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeStop_DMA(ADC_HandleTypeDef* hadc) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + ADC_HandleTypeDef tmphadcSlave={0}; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Stop potential conversion on going, on regular and injected groups */ + /* Disable ADC master peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(hadc); + + /* Check if ADC is effectively disabled */ + if(tmp_hal_status == HAL_OK) + { + /* Set a temporary handle of the ADC slave associated to the ADC master */ + ADC_MULTI_SLAVE(hadc, &tmphadcSlave); + + /* Disable ADC slave peripheral */ + tmp_hal_status = ADC_ConversionStop_Disable(&tmphadcSlave); + + /* Check if ADC is effectively disabled */ + if(tmp_hal_status != HAL_OK) + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL); + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + return HAL_ERROR; + } + + /* Disable ADC DMA mode */ + CLEAR_BIT(hadc->Instance->CR2, ADC_CR2_DMA); + + /* Reset configuration of ADC DMA continuous request for dual mode */ + CLEAR_BIT(hadc->Instance->CR1, ADC_CR1_DUALMOD); + + /* Disable the DMA channel (in case of DMA in circular mode or stop while */ + /* while DMA transfer is on going) */ + tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle); + + /* Change ADC state (ADC master) */ + ADC_STATE_CLR_SET(hadc->State, + HAL_ADC_STATE_REG_BUSY | HAL_ADC_STATE_INJ_BUSY, + HAL_ADC_STATE_READY); + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/** + * @brief Get ADC injected group conversion result. + * @note Reading register JDRx automatically clears ADC flag JEOC + * (ADC group injected end of unitary conversion). + * @note This function does not clear ADC flag JEOS + * (ADC group injected end of sequence conversion) + * Occurrence of flag JEOS rising: + * - If sequencer is composed of 1 rank, flag JEOS is equivalent + * to flag JEOC. + * - If sequencer is composed of several ranks, during the scan + * sequence flag JEOC only is raised, at the end of the scan sequence + * both flags JEOC and EOS are raised. + * Flag JEOS must not be cleared by this function because + * it would not be compliant with low power features + * (feature low power auto-wait, not available on all STM32 families). + * To clear this flag, either use function: + * in programming model IT: @ref HAL_ADC_IRQHandler(), in programming + * model polling: @ref HAL_ADCEx_InjectedPollForConversion() + * or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_JEOS). + * @param hadc: ADC handle + * @param InjectedRank: the converted ADC injected rank. + * This parameter can be one of the following values: + * @arg ADC_INJECTED_RANK_1: Injected Channel1 selected + * @arg ADC_INJECTED_RANK_2: Injected Channel2 selected + * @arg ADC_INJECTED_RANK_3: Injected Channel3 selected + * @arg ADC_INJECTED_RANK_4: Injected Channel4 selected + * @retval ADC group injected conversion data + */ +uint32_t HAL_ADCEx_InjectedGetValue(ADC_HandleTypeDef* hadc, uint32_t InjectedRank) +{ + uint32_t tmp_jdr = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_INJECTED_RANK(InjectedRank)); + + /* Get ADC converted value */ + switch(InjectedRank) + { + case ADC_INJECTED_RANK_4: + tmp_jdr = hadc->Instance->JDR4; + break; + case ADC_INJECTED_RANK_3: + tmp_jdr = hadc->Instance->JDR3; + break; + case ADC_INJECTED_RANK_2: + tmp_jdr = hadc->Instance->JDR2; + break; + case ADC_INJECTED_RANK_1: + default: + tmp_jdr = hadc->Instance->JDR1; + break; + } + + /* Return ADC converted value */ + return tmp_jdr; +} + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +/** + * @brief Returns the last ADC Master&Slave regular conversions results data + * in the selected multi mode. + * @param hadc: ADC handle of ADC master (handle of ADC slave must not be used) + * @retval The converted data value. + */ +uint32_t HAL_ADCEx_MultiModeGetValue(ADC_HandleTypeDef* hadc) +{ + uint32_t tmpDR = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + + /* Note: EOC flag is not cleared here by software because automatically */ + /* cleared by hardware when reading register DR. */ + + /* On STM32F1 devices, ADC1 data register DR contains ADC2 conversions */ + /* only if ADC1 DMA mode is enabled. */ + tmpDR = hadc->Instance->DR; + + if (HAL_IS_BIT_CLR(ADC1->CR2, ADC_CR2_DMA)) + { + tmpDR |= (ADC2->DR << 16U); + } + + /* Return ADC converted value */ + return tmpDR; +} +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ + +/** + * @brief Injected conversion complete callback in non blocking mode + * @param hadc: ADC handle + * @retval None + */ +__weak void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(hadc); + /* NOTE : This function Should not be modified, when the callback is needed, + the HAL_ADCEx_InjectedConvCpltCallback could be implemented in the user file + */ +} + +/** + * @} + */ + +/** @defgroup ADCEx_Exported_Functions_Group2 Extended Peripheral Control functions + * @brief Extended Peripheral Control functions + * +@verbatim + =============================================================================== + ##### Peripheral Control functions ##### + =============================================================================== + [..] This section provides functions allowing to: + (+) Configure channels on injected group + (+) Configure multimode + +@endverbatim + * @{ + */ + +/** + * @brief Configures the ADC injected group and the selected channel to be + * linked to the injected group. + * @note Possibility to update parameters on the fly: + * This function initializes injected group, following calls to this + * function can be used to reconfigure some parameters of structure + * "ADC_InjectionConfTypeDef" on the fly, without resetting the ADC. + * The setting of these parameters is conditioned to ADC state: + * this function must be called when ADC is not under conversion. + * @param hadc: ADC handle + * @param sConfigInjected: Structure of ADC injected group and ADC channel for + * injected group. + * @retval None + */ +HAL_StatusTypeDef HAL_ADCEx_InjectedConfigChannel(ADC_HandleTypeDef* hadc, ADC_InjectionConfTypeDef* sConfigInjected) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + __IO uint32_t wait_loop_index = 0U; + + /* Check the parameters */ + assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_CHANNEL(sConfigInjected->InjectedChannel)); + assert_param(IS_ADC_SAMPLE_TIME(sConfigInjected->InjectedSamplingTime)); + assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->AutoInjectedConv)); + assert_param(IS_ADC_EXTTRIGINJEC(sConfigInjected->ExternalTrigInjecConv)); + assert_param(IS_ADC_RANGE(sConfigInjected->InjectedOffset)); + + if(hadc->Init.ScanConvMode != ADC_SCAN_DISABLE) + { + assert_param(IS_ADC_INJECTED_RANK(sConfigInjected->InjectedRank)); + assert_param(IS_ADC_INJECTED_NB_CONV(sConfigInjected->InjectedNbrOfConversion)); + assert_param(IS_FUNCTIONAL_STATE(sConfigInjected->InjectedDiscontinuousConvMode)); + } + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Configuration of injected group sequencer: */ + /* - if scan mode is disabled, injected channels sequence length is set to */ + /* 0x00: 1 channel converted (channel on regular rank 1) */ + /* Parameter "InjectedNbrOfConversion" is discarded. */ + /* Note: Scan mode is present by hardware on this device and, if */ + /* disabled, discards automatically nb of conversions. Anyway, nb of */ + /* conversions is forced to 0x00 for alignment over all STM32 devices. */ + /* - if scan mode is enabled, injected channels sequence length is set to */ + /* parameter "InjectedNbrOfConversion". */ + if (hadc->Init.ScanConvMode == ADC_SCAN_DISABLE) + { + if (sConfigInjected->InjectedRank == ADC_INJECTED_RANK_1) + { + /* Clear the old SQx bits for all injected ranks */ + MODIFY_REG(hadc->Instance->JSQR , + ADC_JSQR_JL | + ADC_JSQR_JSQ4 | + ADC_JSQR_JSQ3 | + ADC_JSQR_JSQ2 | + ADC_JSQR_JSQ1 , + ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, + ADC_INJECTED_RANK_1, + 0x01U)); + } + /* If another injected rank than rank1 was intended to be set, and could */ + /* not due to ScanConvMode disabled, error is reported. */ + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + } + else + { + /* Since injected channels rank conv. order depends on total number of */ + /* injected conversions, selected rank must be below or equal to total */ + /* number of injected conversions to be updated. */ + if (sConfigInjected->InjectedRank <= sConfigInjected->InjectedNbrOfConversion) + { + /* Clear the old SQx bits for the selected rank */ + /* Set the SQx bits for the selected rank */ + MODIFY_REG(hadc->Instance->JSQR , + + ADC_JSQR_JL | + ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, + sConfigInjected->InjectedRank, + sConfigInjected->InjectedNbrOfConversion) , + + ADC_JSQR_JL_SHIFT(sConfigInjected->InjectedNbrOfConversion) | + ADC_JSQR_RK_JL(sConfigInjected->InjectedChannel, + sConfigInjected->InjectedRank, + sConfigInjected->InjectedNbrOfConversion) ); + } + else + { + /* Clear the old SQx bits for the selected rank */ + MODIFY_REG(hadc->Instance->JSQR , + + ADC_JSQR_JL | + ADC_JSQR_RK_JL(ADC_JSQR_JSQ1, + sConfigInjected->InjectedRank, + sConfigInjected->InjectedNbrOfConversion) , + + 0x00000000U); + } + } + + /* Configuration of injected group */ + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated only when ADC is disabled: */ + /* - external trigger to start conversion */ + /* Parameters update not conditioned to ADC state: */ + /* - Automatic injected conversion */ + /* - Injected discontinuous mode */ + /* Note: In case of ADC already enabled, caution to not launch an unwanted */ + /* conversion while modifying register CR2 by writing 1 to bit ADON. */ + if (ADC_IS_ENABLE(hadc) == RESET) + { + MODIFY_REG(hadc->Instance->CR2 , + ADC_CR2_JEXTSEL | + ADC_CR2_ADON , + ADC_CFGR_JEXTSEL(hadc, sConfigInjected->ExternalTrigInjecConv) ); + } + + + /* Configuration of injected group */ + /* - Automatic injected conversion */ + /* - Injected discontinuous mode */ + + /* Automatic injected conversion can be enabled if injected group */ + /* external triggers are disabled. */ + if (sConfigInjected->AutoInjectedConv == ENABLE) + { + if (sConfigInjected->ExternalTrigInjecConv == ADC_INJECTED_SOFTWARE_START) + { + SET_BIT(hadc->Instance->CR1, ADC_CR1_JAUTO); + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + } + + /* Injected discontinuous can be enabled only if auto-injected mode is */ + /* disabled. */ + if (sConfigInjected->InjectedDiscontinuousConvMode == ENABLE) + { + if (sConfigInjected->AutoInjectedConv == DISABLE) + { + SET_BIT(hadc->Instance->CR1, ADC_CR1_JDISCEN); + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + } + + + /* InjectedChannel sampling time configuration */ + /* For channels 10 to 17 */ + if (sConfigInjected->InjectedChannel >= ADC_CHANNEL_10) + { + MODIFY_REG(hadc->Instance->SMPR1 , + ADC_SMPR1(ADC_SMPR1_SMP10, sConfigInjected->InjectedChannel) , + ADC_SMPR1(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); + } + else /* For channels 0 to 9 */ + { + MODIFY_REG(hadc->Instance->SMPR2 , + ADC_SMPR2(ADC_SMPR2_SMP0, sConfigInjected->InjectedChannel) , + ADC_SMPR2(sConfigInjected->InjectedSamplingTime, sConfigInjected->InjectedChannel) ); + } + + /* If ADC1 InjectedChannel_16 or InjectedChannel_17 is selected, enable Temperature sensor */ + /* and VREFINT measurement path. */ + if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || + (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) ) + { + SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE); + } + + + /* Configure the offset: offset enable/disable, InjectedChannel, offset value */ + switch(sConfigInjected->InjectedRank) + { + case 1: + /* Set injected channel 1 offset */ + MODIFY_REG(hadc->Instance->JOFR1, + ADC_JOFR1_JOFFSET1, + sConfigInjected->InjectedOffset); + break; + case 2: + /* Set injected channel 2 offset */ + MODIFY_REG(hadc->Instance->JOFR2, + ADC_JOFR2_JOFFSET2, + sConfigInjected->InjectedOffset); + break; + case 3: + /* Set injected channel 3 offset */ + MODIFY_REG(hadc->Instance->JOFR3, + ADC_JOFR3_JOFFSET3, + sConfigInjected->InjectedOffset); + break; + case 4: + default: + MODIFY_REG(hadc->Instance->JOFR4, + ADC_JOFR4_JOFFSET4, + sConfigInjected->InjectedOffset); + break; + } + + /* If ADC1 Channel_16 or Channel_17 is selected, enable Temperature sensor */ + /* and VREFINT measurement path. */ + if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR) || + (sConfigInjected->InjectedChannel == ADC_CHANNEL_VREFINT) ) + { + /* For STM32F1 devices with several ADC: Only ADC1 can access internal */ + /* measurement channels (VrefInt/TempSensor). If these channels are */ + /* intended to be set on other ADC instances, an error is reported. */ + if (hadc->Instance == ADC1) + { + if (READ_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE) == RESET) + { + SET_BIT(hadc->Instance->CR2, ADC_CR2_TSVREFE); + + if ((sConfigInjected->InjectedChannel == ADC_CHANNEL_TEMPSENSOR)) + { + /* Delay for temperature sensor stabilization time */ + /* Compute number of CPU cycles to wait for */ + wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U)); + while(wait_loop_index != 0U) + { + wait_loop_index--; + } + } + } + } + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + } + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} + +#if defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F105xC) || defined (STM32F107xC) || defined (STM32F103xE) || defined (STM32F103xG) +/** + * @brief Enable ADC multimode and configure multimode parameters + * @note Possibility to update parameters on the fly: + * This function initializes multimode parameters, following + * calls to this function can be used to reconfigure some parameters + * of structure "ADC_MultiModeTypeDef" on the fly, without resetting + * the ADCs (both ADCs of the common group). + * The setting of these parameters is conditioned to ADC state. + * For parameters constraints, see comments of structure + * "ADC_MultiModeTypeDef". + * @note To change back configuration from multimode to single mode, ADC must + * be reset (using function HAL_ADC_Init() ). + * @param hadc: ADC handle + * @param multimode: Structure of ADC multimode configuration + * @retval HAL status + */ +HAL_StatusTypeDef HAL_ADCEx_MultiModeConfigChannel(ADC_HandleTypeDef* hadc, ADC_MultiModeTypeDef* multimode) +{ + HAL_StatusTypeDef tmp_hal_status = HAL_OK; + ADC_HandleTypeDef tmphadcSlave={0}; + + /* Check the parameters */ + assert_param(IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)); + assert_param(IS_ADC_MODE(multimode->Mode)); + + /* Process locked */ + __HAL_LOCK(hadc); + + /* Set a temporary handle of the ADC slave associated to the ADC master */ + ADC_MULTI_SLAVE(hadc, &tmphadcSlave); + + /* Parameters update conditioned to ADC state: */ + /* Parameters that can be updated when ADC is disabled or enabled without */ + /* conversion on going on regular group: */ + /* - ADC master and ADC slave DMA configuration */ + /* Parameters that can be updated only when ADC is disabled: */ + /* - Multimode mode selection */ + /* To optimize code, all multimode settings can be set when both ADCs of */ + /* the common group are in state: disabled. */ + if ((ADC_IS_ENABLE(hadc) == RESET) && + (ADC_IS_ENABLE(&tmphadcSlave) == RESET) && + (IS_ADC_MULTIMODE_MASTER_INSTANCE(hadc->Instance)) ) + { + MODIFY_REG(hadc->Instance->CR1, + ADC_CR1_DUALMOD , + multimode->Mode ); + } + /* If one of the ADC sharing the same common group is enabled, no update */ + /* could be done on neither of the multimode structure parameters. */ + else + { + /* Update ADC state machine to error */ + SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG); + + tmp_hal_status = HAL_ERROR; + } + + + /* Process unlocked */ + __HAL_UNLOCK(hadc); + + /* Return function status */ + return tmp_hal_status; +} +#endif /* defined STM32F103x6 || defined STM32F103xB || defined STM32F105xC || defined STM32F107xC || defined STM32F103xE || defined STM32F103xG */ +/** + * @} + */ + +/** + * @} + */ + +#endif /* HAL_ADC_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c new file mode 100644 index 0000000..c00a9de --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c @@ -0,0 +1,7629 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_tim.c + * @author MCD Application Team + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer (TIM) peripheral: + * + TIM Time Base Initialization + * + TIM Time Base Start + * + TIM Time Base Start Interruption + * + TIM Time Base Start DMA + * + TIM Output Compare/PWM Initialization + * + TIM Output Compare/PWM Channel Configuration + * + TIM Output Compare/PWM Start + * + TIM Output Compare/PWM Start Interruption + * + TIM Output Compare/PWM Start DMA + * + TIM Input Capture Initialization + * + TIM Input Capture Channel Configuration + * + TIM Input Capture Start + * + TIM Input Capture Start Interruption + * + TIM Input Capture Start DMA + * + TIM One Pulse Initialization + * + TIM One Pulse Channel Configuration + * + TIM One Pulse Start + * + TIM Encoder Interface Initialization + * + TIM Encoder Interface Start + * + TIM Encoder Interface Start Interruption + * + TIM Encoder Interface Start DMA + * + Commutation Event configuration with Interruption and DMA + * + TIM OCRef clear configuration + * + TIM External Clock configuration + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### TIMER Generic features ##### + ============================================================================== + [..] The Timer features include: + (#) 16-bit up, down, up/down auto-reload counter. + (#) 16-bit programmable prescaler allowing dividing (also on the fly) the + counter clock frequency either by any factor between 1 and 65536. + (#) Up to 4 independent channels for: + (++) Input Capture + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + (#) Synchronization circuit to control the timer with external signals and to interconnect + several timers together. + (#) Supports incremental encoder for positioning purposes + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending on the selected feature: + (++) Time Base : HAL_TIM_Base_MspInit() + (++) Input Capture : HAL_TIM_IC_MspInit() + (++) Output Compare : HAL_TIM_OC_MspInit() + (++) PWM generation : HAL_TIM_PWM_MspInit() + (++) One-pulse mode output : HAL_TIM_OnePulse_MspInit() + (++) Encoder mode output : HAL_TIM_Encoder_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + Initialization function of this driver: + (++) HAL_TIM_Base_Init: to use the Timer to generate a simple time base + (++) HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to generate an + Output Compare signal. + (++) HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a + PWM signal. + (++) HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an + external signal. + (++) HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer + in One Pulse Mode. + (++) HAL_TIM_Encoder_Init: to use the Timer Encoder Interface. + + (#) Activate the TIM peripheral using one of the start functions depending from the feature used: + (++) Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT() + (++) Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT() + (++) Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT() + (++) PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT() + (++) One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT() + (++) Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT(). + + (#) The DMA Burst is managed with the two following functions: + HAL_TIM_DMABurst_WriteStart() + HAL_TIM_DMABurst_ReadStart() + + *** Callback registration *** + ============================================= + + [..] + The compilation define USE_HAL_TIM_REGISTER_CALLBACKS when set to 1 + allows the user to configure dynamically the driver callbacks. + + [..] + Use Function HAL_TIM_RegisterCallback() to register a callback. + HAL_TIM_RegisterCallback() takes as parameters the HAL peripheral handle, + the Callback ID and a pointer to the user callback function. + + [..] + Use function HAL_TIM_UnRegisterCallback() to reset a callback to the default + weak function. + HAL_TIM_UnRegisterCallback takes as parameters the HAL peripheral handle, + and the Callback ID. + + [..] + These functions allow to register/unregister following callbacks: + (+) Base_MspInitCallback : TIM Base Msp Init Callback. + (+) Base_MspDeInitCallback : TIM Base Msp DeInit Callback. + (+) IC_MspInitCallback : TIM IC Msp Init Callback. + (+) IC_MspDeInitCallback : TIM IC Msp DeInit Callback. + (+) OC_MspInitCallback : TIM OC Msp Init Callback. + (+) OC_MspDeInitCallback : TIM OC Msp DeInit Callback. + (+) PWM_MspInitCallback : TIM PWM Msp Init Callback. + (+) PWM_MspDeInitCallback : TIM PWM Msp DeInit Callback. + (+) OnePulse_MspInitCallback : TIM One Pulse Msp Init Callback. + (+) OnePulse_MspDeInitCallback : TIM One Pulse Msp DeInit Callback. + (+) Encoder_MspInitCallback : TIM Encoder Msp Init Callback. + (+) Encoder_MspDeInitCallback : TIM Encoder Msp DeInit Callback. + (+) HallSensor_MspInitCallback : TIM Hall Sensor Msp Init Callback. + (+) HallSensor_MspDeInitCallback : TIM Hall Sensor Msp DeInit Callback. + (+) PeriodElapsedCallback : TIM Period Elapsed Callback. + (+) PeriodElapsedHalfCpltCallback : TIM Period Elapsed half complete Callback. + (+) TriggerCallback : TIM Trigger Callback. + (+) TriggerHalfCpltCallback : TIM Trigger half complete Callback. + (+) IC_CaptureCallback : TIM Input Capture Callback. + (+) IC_CaptureHalfCpltCallback : TIM Input Capture half complete Callback. + (+) OC_DelayElapsedCallback : TIM Output Compare Delay Elapsed Callback. + (+) PWM_PulseFinishedCallback : TIM PWM Pulse Finished Callback. + (+) PWM_PulseFinishedHalfCpltCallback : TIM PWM Pulse Finished half complete Callback. + (+) ErrorCallback : TIM Error Callback. + (+) CommutationCallback : TIM Commutation Callback. + (+) CommutationHalfCpltCallback : TIM Commutation half complete Callback. + (+) BreakCallback : TIM Break Callback. + + [..] +By default, after the Init and when the state is HAL_TIM_STATE_RESET +all interrupt callbacks are set to the corresponding weak functions: + examples HAL_TIM_TriggerCallback(), HAL_TIM_ErrorCallback(). + + [..] + Exception done for MspInit and MspDeInit functions that are reset to the legacy weak + functionalities in the Init / DeInit only when these callbacks are null + (not registered beforehand). If not, MspInit or MspDeInit are not null, the Init / DeInit + keep and use the user MspInit / MspDeInit callbacks(registered beforehand) + + [..] + Callbacks can be registered / unregistered in HAL_TIM_STATE_READY state only. + Exception done MspInit / MspDeInit that can be registered / unregistered + in HAL_TIM_STATE_READY or HAL_TIM_STATE_RESET state, + thus registered(user) MspInit / DeInit callbacks can be used during the Init / DeInit. + In that case first register the MspInit/MspDeInit user callbacks + using HAL_TIM_RegisterCallback() before calling DeInit or Init function. + + [..] + When The compilation define USE_HAL_TIM_REGISTER_CALLBACKS is set to 0 or + not defined, the callback registration feature is not available and all callbacks + are set to the corresponding weak functions. + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal.h" + +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @defgroup TIM TIM + * @brief TIM HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/** @addtogroup TIM_Private_Functions + * @{ + */ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config); +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter); +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter); +static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource); +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma); +static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + const TIM_SlaveConfigTypeDef *sSlaveConfig); +/** + * @} + */ +/* Exported functions --------------------------------------------------------*/ + +/** @defgroup TIM_Exported_Functions TIM Exported Functions + * @{ + */ + +/** @defgroup TIM_Exported_Functions_Group1 TIM Time Base functions + * @brief Time Base functions + * +@verbatim + ============================================================================== + ##### Time Base functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM base. + (+) De-initialize the TIM base. + (+) Start the Time Base. + (+) Stop the Time Base. + (+) Start the Time Base and enable interrupt. + (+) Stop the Time Base and disable interrupt. + (+) Start the Time Base and enable DMA transfer. + (+) Stop the Time Base and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Time base Unit according to the specified + * parameters in the TIM_HandleTypeDef and initialize the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_Base_DeInit() before HAL_TIM_Base_Init() + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->Base_MspInitCallback == NULL) + { + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->Base_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the Time Base configuration */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Base peripheral + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->Base_MspDeInitCallback == NULL) + { + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; + } + /* DeInit the low level hardware */ + htim->Base_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Base_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Base MSP. + * @param htim TIM Base handle + * @retval None + */ +__weak void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Base_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Base MSP. + * @param htim TIM Base handle + * @retval None + */ +__weak void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Base_MspDeInit could be implemented in the user file + */ +} + + +/** + * @brief Starts the TIM Base generation. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Check the TIM state */ + if (htim->State != HAL_TIM_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in interrupt mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Check the TIM state */ + if (htim->State != HAL_TIM_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Enable the TIM Update interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in interrupt mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + /* Disable the TIM Update interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Base generation in DMA mode. + * @param htim TIM Base handle + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Start_DMA(TIM_HandleTypeDef *htim, const uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + /* Set the TIM state */ + if (htim->State == HAL_TIM_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->State == HAL_TIM_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + htim->State = HAL_TIM_STATE_BUSY; + } + } + else + { + return HAL_ERROR; + } + + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)pData, (uint32_t)&htim->Instance->ARR, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Update DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_UPDATE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Base generation in DMA mode. + * @param htim TIM Base handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Base_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMA_INSTANCE(htim->Instance)); + + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_UPDATE); + + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group2 TIM Output Compare functions + * @brief TIM Output Compare functions + * +@verbatim + ============================================================================== + ##### TIM Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Output Compare. + (+) De-initialize the TIM Output Compare. + (+) Start the TIM Output Compare. + (+) Stop the TIM Output Compare. + (+) Start the TIM Output Compare and enable interrupt. + (+) Stop the TIM Output Compare and disable interrupt. + (+) Start the TIM Output Compare and enable DMA transfer. + (+) Stop the TIM Output Compare and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Output Compare according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_OC_DeInit() before HAL_TIM_OC_Init() + * @param htim TIM Output Compare handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->OC_MspInitCallback == NULL) + { + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->OC_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the Output Compare */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM Output Compare handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->OC_MspDeInitCallback == NULL) + { + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; + } + /* DeInit the low level hardware */ + htim->OC_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OC_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Output Compare MSP. + * @param htim TIM Output Compare handle + * @retval None + */ +__weak void HAL_TIM_OC_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Output Compare MSP. + * @param htim TIM Output Compare handle + * @retval None + */ +__weak void HAL_TIM_OC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Output Compare signal generation. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Set the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Output compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group3 TIM PWM functions + * @brief TIM PWM functions + * +@verbatim + ============================================================================== + ##### TIM PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM PWM. + (+) De-initialize the TIM PWM. + (+) Start the TIM PWM. + (+) Stop the TIM PWM. + (+) Start the TIM PWM and enable interrupt. + (+) Stop the TIM PWM and disable interrupt. + (+) Start the TIM PWM and enable DMA transfer. + (+) Stop the TIM PWM and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM PWM Time Base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_PWM_DeInit() before HAL_TIM_PWM_Init() + * @param htim TIM PWM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->PWM_MspInitCallback == NULL) + { + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->PWM_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the PWM */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM PWM handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->PWM_MspDeInitCallback == NULL) + { + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; + } + /* DeInit the low level hardware */ + htim->PWM_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_PWM_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM PWM MSP. + * @param htim TIM PWM handle + * @retval None + */ +__weak void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM PWM MSP. + * @param htim TIM PWM handle + * @retval None + */ +__weak void HAL_TIM_PWM_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the PWM signal generation. + * @param htim TIM handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode. + * @param htim TIM PWM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Set the TIM channel state */ + if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Capture/Compare 3 request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)pData, (uint32_t)&htim->Instance->CCR4, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode. + * @param htim TIM PWM handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group4 TIM Input Capture functions + * @brief TIM Input Capture functions + * +@verbatim + ============================================================================== + ##### TIM Input Capture functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Input Capture. + (+) De-initialize the TIM Input Capture. + (+) Start the TIM Input Capture. + (+) Stop the TIM Input Capture. + (+) Start the TIM Input Capture and enable interrupt. + (+) Stop the TIM Input Capture and disable interrupt. + (+) Start the TIM Input Capture and enable DMA transfer. + (+) Stop the TIM Input Capture and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Input Capture Time base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_IC_DeInit() before HAL_TIM_IC_Init() + * @param htim TIM Input Capture handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_PERIOD(htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->IC_MspInitCallback == NULL) + { + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->IC_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Init the base time for the input capture */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM peripheral + * @param htim TIM Input Capture handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->IC_MspDeInitCallback == NULL) + { + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; + } + /* DeInit the low level hardware */ + htim->IC_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_IC_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET_ALL(htim, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Input Capture MSP. + * @param htim TIM Input Capture handle + * @retval None + */ +__weak void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Input Capture MSP. + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_IC_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Input Capture measurement. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel); + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if ((channel_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Input Capture measurement. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Input Capture measurement in interrupt mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel); + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM channel state */ + if ((channel_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Enable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Input Capture measurement in interrupt mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM Input Capture measurement in DMA mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @param pData The destination Buffer address. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + HAL_TIM_ChannelStateTypeDef channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + HAL_TIM_ChannelStateTypeDef complementary_channel_state = TIM_CHANNEL_N_STATE_GET(htim, Channel); + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + /* Set the TIM channel state */ + if ((channel_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + /* Enable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->CCR3, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + case TIM_CHANNEL_4: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->CCR4, (uint32_t)pData, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC4); + break; + } + + default: + status = HAL_ERROR; + break; + } + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Input Capture measurement in DMA mode. + * @param htim TIM Input Capture handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + assert_param(IS_TIM_DMA_CC_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel */ + TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + case TIM_CHANNEL_4: + { + /* Disable the TIM Capture/Compare 4 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC4); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group5 TIM One Pulse functions + * @brief TIM One Pulse functions + * +@verbatim + ============================================================================== + ##### TIM One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM One Pulse. + (+) De-initialize the TIM One Pulse. + (+) Start the TIM One Pulse. + (+) Stop the TIM One Pulse. + (+) Start the TIM One Pulse and enable interrupt. + (+) Stop the TIM One Pulse and disable interrupt. + (+) Start the TIM One Pulse and enable DMA transfer. + (+) Stop the TIM One Pulse and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM One Pulse Time Base according to the specified + * parameters in the TIM_HandleTypeDef and initializes the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_OnePulse_DeInit() before HAL_TIM_OnePulse_Init() + * @note When the timer instance is initialized in One Pulse mode, timer + * channels 1 and channel 2 are reserved and cannot be used for other + * purpose. + * @param htim TIM One Pulse handle + * @param OnePulseMode Select the One pulse mode. + * This parameter can be one of the following values: + * @arg TIM_OPMODE_SINGLE: Only one pulse will be generated. + * @arg TIM_OPMODE_REPETITIVE: Repetitive pulses will be generated. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode) +{ + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_OPM_MODE(OnePulseMode)); + assert_param(IS_TIM_PERIOD(htim->Init.Period)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->OnePulse_MspInitCallback == NULL) + { + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->OnePulse_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_OnePulse_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Configure the Time base in the One Pulse Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Reset the OPM Bit */ + htim->Instance->CR1 &= ~TIM_CR1_OPM; + + /* Configure the OPM Mode */ + htim->Instance->CR1 |= OnePulseMode; + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM One Pulse + * @param htim TIM One Pulse handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->OnePulse_MspDeInitCallback == NULL) + { + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; + } + /* DeInit the low level hardware */ + htim->OnePulse_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_OnePulse_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM One Pulse MSP. + * @param htim TIM One Pulse handle + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM One Pulse MSP. + * @param htim TIM One Pulse handle + * @retval None + */ +__weak void HAL_TIM_OnePulse_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OnePulse_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM One Pulse signal generation. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together + + No need to enable the counter, it's enabled automatically by hardware + (the counter starts in response to a stimulus and generate a pulse */ + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Enable the main output */ + __HAL_TIM_MOE_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode. + * @note Though OutputChannel parameter is deprecated and ignored by the function + * it has been kept to avoid HAL_TIM API compatibility break. + * @note The pulse output channel is determined when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel See note above + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(OutputChannel); + + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the Capture compare and the Input Capture channels + (in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) + if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and + if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output + whatever the combination, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET) + { + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group6 TIM Encoder functions + * @brief TIM Encoder functions + * +@verbatim + ============================================================================== + ##### TIM Encoder functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure the TIM Encoder. + (+) De-initialize the TIM Encoder. + (+) Start the TIM Encoder. + (+) Stop the TIM Encoder. + (+) Start the TIM Encoder and enable interrupt. + (+) Stop the TIM Encoder and disable interrupt. + (+) Start the TIM Encoder and enable DMA transfer. + (+) Stop the TIM Encoder and disable DMA transfer. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Encoder Interface and initialize the associated handle. + * @note Switching from Center Aligned counter mode to Edge counter mode (or reverse) + * requires a timer reset to avoid unexpected direction + * due to DIR bit readonly in center aligned mode. + * Ex: call @ref HAL_TIM_Encoder_DeInit() before HAL_TIM_Encoder_Init() + * @note Encoder mode and External clock mode 2 are not compatible and must not be selected together + * Ex: A call for @ref HAL_TIM_Encoder_Init will erase the settings of @ref HAL_TIM_ConfigClockSource + * using TIM_CLOCKSOURCE_ETRMODE2 and vice versa + * @note When the timer instance is initialized in Encoder mode, timer + * channels 1 and channel 2 are reserved and cannot be used for other + * purpose. + * @param htim TIM Encoder Interface handle + * @param sConfig TIM Encoder Interface configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, const TIM_Encoder_InitTypeDef *sConfig) +{ + uint32_t tmpsmcr; + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection)); + assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection)); + assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC2Polarity)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter)); + assert_param(IS_TIM_PERIOD(htim->Init.Period)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy weak callbacks */ + TIM_ResetCallback(htim); + + if (htim->Encoder_MspInitCallback == NULL) + { + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->Encoder_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIM_Encoder_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Reset the SMS and ECE bits */ + htim->Instance->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_ECE); + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Get the TIMx CCMR1 register value */ + tmpccmr1 = htim->Instance->CCMR1; + + /* Get the TIMx CCER register value */ + tmpccer = htim->Instance->CCER; + + /* Set the encoder Mode */ + tmpsmcr |= sConfig->EncoderMode; + + /* Select the Capture Compare 1 and the Capture Compare 2 as input */ + tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S); + tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U)); + + /* Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */ + tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC); + tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F); + tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8U); + tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U); + + /* Set the TI1 and the TI2 Polarities */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P); + tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U); + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Write to TIMx CCMR1 */ + htim->Instance->CCMR1 = tmpccmr1; + + /* Write to TIMx CCER */ + htim->Instance->CCER = tmpccer; + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + + +/** + * @brief DeInitializes the TIM Encoder interface + * @param htim TIM Encoder Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->Encoder_MspDeInitCallback == NULL) + { + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; + } + /* DeInit the low level hardware */ + htim->Encoder_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIM_Encoder_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Encoder Interface MSP. + * @param htim TIM Encoder Interface handle + * @retval None + */ +__weak void HAL_TIM_Encoder_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Encoder Interface MSP. + * @param htim TIM Encoder Interface handle + * @retval None + */ +__weak void HAL_TIM_Encoder_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_Encoder_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Encoder Interface. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel(s) state */ + if (Channel == TIM_CHANNEL_1) + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else if (Channel == TIM_CHANNEL_2) + { + if ((channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + + /* Enable the encoder interface channels */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + break; + } + } + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + break; + } + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel(s) state */ + if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2)) + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in interrupt mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel(s) state */ + if (Channel == TIM_CHANNEL_1) + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else if (Channel == TIM_CHANNEL_2) + { + if ((channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + + /* Enable the encoder interface channels */ + /* Enable the capture compare Interrupts 1 and/or 2 */ + switch (Channel) + { + case TIM_CHANNEL_1: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + default : + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + } + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in interrupt mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if (Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + } + else if (Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts 1 and 2 */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel(s) state */ + if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2)) + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Encoder Interface in DMA mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @param pData1 The destination Buffer address for IC1. + * @param pData2 The destination Buffer address for IC2. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData1, + uint32_t *pData2, uint16_t Length) +{ + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel(s) state */ + if (Channel == TIM_CHANNEL_1) + { + if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData1 == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + } + else if (Channel == TIM_CHANNEL_2) + { + if ((channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_2_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData2 == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + } + else + { + if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (channel_2_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_2_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((((pData1 == NULL) || (pData2 == NULL))) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError; + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + break; + } + + default: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->CCR2, (uint32_t)pData2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + /* Enable the TIM Input Capture DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + + /* Enable the Capture compare channel */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE); + + /* Enable the Peripheral */ + __HAL_TIM_ENABLE(htim); + + break; + } + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Encoder Interface in DMA mode. + * @param htim TIM Encoder Interface handle + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_ALL: TIM Channel 1 and TIM Channel 2 are selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_Encoder_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1 and 2 + (in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */ + if (Channel == TIM_CHANNEL_1) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + } + else if (Channel == TIM_CHANNEL_2) + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + } + else + { + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE); + + /* Disable the capture compare DMA Request 1 and 2 */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + } + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel(s) state */ + if ((Channel == TIM_CHANNEL_1) || (Channel == TIM_CHANNEL_2)) + { + TIM_CHANNEL_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ +/** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management + * @brief TIM IRQ handler management + * +@verbatim + ============================================================================== + ##### IRQ handler management ##### + ============================================================================== + [..] + This section provides Timer IRQ handler function. + +@endverbatim + * @{ + */ +/** + * @brief This function handles TIM interrupts requests. + * @param htim TIM handle + * @retval None + */ +void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim) +{ + uint32_t itsource = htim->Instance->DIER; + uint32_t itflag = htim->Instance->SR; + + /* Capture compare 1 event */ + if ((itflag & (TIM_FLAG_CC1)) == (TIM_FLAG_CC1)) + { + if ((itsource & (TIM_IT_CC1)) == (TIM_IT_CC1)) + { + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC1); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + /* Input capture event */ + if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + } + /* Capture compare 2 event */ + if ((itflag & (TIM_FLAG_CC2)) == (TIM_FLAG_CC2)) + { + if ((itsource & (TIM_IT_CC2)) == (TIM_IT_CC2)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC2); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + /* Input capture event */ + if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 3 event */ + if ((itflag & (TIM_FLAG_CC3)) == (TIM_FLAG_CC3)) + { + if ((itsource & (TIM_IT_CC3)) == (TIM_IT_CC3)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC3); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + /* Input capture event */ + if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* Capture compare 4 event */ + if ((itflag & (TIM_FLAG_CC4)) == (TIM_FLAG_CC4)) + { + if ((itsource & (TIM_IT_CC4)) == (TIM_IT_CC4)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_CC4); + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + /* Input capture event */ + if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U) + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + /* Output compare event */ + else + { +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->OC_DelayElapsedCallback(htim); + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_OC_DelayElapsedCallback(htim); + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; + } + } + /* TIM Update event */ + if ((itflag & (TIM_FLAG_UPDATE)) == (TIM_FLAG_UPDATE)) + { + if ((itsource & (TIM_IT_UPDATE)) == (TIM_IT_UPDATE)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_UPDATE); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedCallback(htim); +#else + HAL_TIM_PeriodElapsedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Break input event */ + if ((itflag & (TIM_FLAG_BREAK)) == (TIM_FLAG_BREAK)) + { + if ((itsource & (TIM_IT_BREAK)) == (TIM_IT_BREAK)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_BREAK); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->BreakCallback(htim); +#else + HAL_TIMEx_BreakCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM Trigger detection event */ + if ((itflag & (TIM_FLAG_TRIGGER)) == (TIM_FLAG_TRIGGER)) + { + if ((itsource & (TIM_IT_TRIGGER)) == (TIM_IT_TRIGGER)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_TRIGGER); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerCallback(htim); +#else + HAL_TIM_TriggerCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } + /* TIM commutation event */ + if ((itflag & (TIM_FLAG_COM)) == (TIM_FLAG_COM)) + { + if ((itsource & (TIM_IT_COM)) == (TIM_IT_COM)) + { + __HAL_TIM_CLEAR_FLAG(htim, TIM_FLAG_COM); +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationCallback(htim); +#else + HAL_TIMEx_CommutCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + } +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions + * @brief TIM Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode. + (+) Configure External Clock source. + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master and the Slave synchronization. + (+) Configure the DMA Burst Mode. + +@endverbatim + * @{ + */ + +/** + * @brief Initializes the TIM Output Compare Channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim TIM Output Compare handle + * @param sConfig TIM Output Compare configuration structure + * @param Channel TIM Channels to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim, + const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_OC_MODE(sConfig->OCMode)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + + /* Process Locked */ + __HAL_LOCK(htim); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 1 in Output Compare */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 2 in Output Compare */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 3 in Output Compare */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Configure the TIM Channel 4 in Output Compare */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + break; + } + + default: + status = HAL_ERROR; + break; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Initializes the TIM Input Capture Channels according to the specified + * parameters in the TIM_IC_InitTypeDef. + * @param htim TIM IC handle + * @param sConfig TIM Input Capture configuration structure + * @param Channel TIM Channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, const TIM_IC_InitTypeDef *sConfig, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_IC_POLARITY(sConfig->ICPolarity)); + assert_param(IS_TIM_IC_SELECTION(sConfig->ICSelection)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->ICPrescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->ICFilter)); + + /* Process Locked */ + __HAL_LOCK(htim); + + if (Channel == TIM_CHANNEL_1) + { + /* TI1 Configuration */ + TIM_TI1_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->ICPrescaler; + } + else if (Channel == TIM_CHANNEL_2) + { + /* TI2 Configuration */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Set the IC2PSC value */ + htim->Instance->CCMR1 |= (sConfig->ICPrescaler << 8U); + } + else if (Channel == TIM_CHANNEL_3) + { + /* TI3 Configuration */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + TIM_TI3_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC3PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC; + + /* Set the IC3PSC value */ + htim->Instance->CCMR2 |= sConfig->ICPrescaler; + } + else if (Channel == TIM_CHANNEL_4) + { + /* TI4 Configuration */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + TIM_TI4_SetConfig(htim->Instance, + sConfig->ICPolarity, + sConfig->ICSelection, + sConfig->ICFilter); + + /* Reset the IC4PSC Bits */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC; + + /* Set the IC4PSC value */ + htim->Instance->CCMR2 |= (sConfig->ICPrescaler << 8U); + } + else + { + status = HAL_ERROR; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Initializes the TIM PWM channels according to the specified + * parameters in the TIM_OC_InitTypeDef. + * @param htim TIM PWM handle + * @param sConfig TIM PWM configuration structure + * @param Channel TIM Channels to be configured + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim, + const TIM_OC_InitTypeDef *sConfig, + uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CHANNELS(Channel)); + assert_param(IS_TIM_PWM_MODE(sConfig->OCMode)); + assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity)); + assert_param(IS_TIM_FAST_STATE(sConfig->OCFastMode)); + + /* Process Locked */ + __HAL_LOCK(htim); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Configure the Channel 1 in PWM mode */ + TIM_OC1_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel1 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode; + break; + } + + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Configure the Channel 2 in PWM mode */ + TIM_OC2_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel2 */ + htim->Instance->CCMR1 |= TIM_CCMR1_OC2PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE; + htim->Instance->CCMR1 |= sConfig->OCFastMode << 8U; + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Configure the Channel 3 in PWM mode */ + TIM_OC3_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel3 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC3PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode; + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Configure the Channel 4 in PWM mode */ + TIM_OC4_SetConfig(htim->Instance, sConfig); + + /* Set the Preload enable bit for channel4 */ + htim->Instance->CCMR2 |= TIM_CCMR2_OC4PE; + + /* Configure the Output Fast mode */ + htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE; + htim->Instance->CCMR2 |= sConfig->OCFastMode << 8U; + break; + } + + default: + status = HAL_ERROR; + break; + } + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Initializes the TIM One Pulse Channels according to the specified + * parameters in the TIM_OnePulse_InitTypeDef. + * @param htim TIM One Pulse handle + * @param sConfig TIM One Pulse configuration structure + * @param OutputChannel TIM output channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @param InputChannel TIM input Channel to configure + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @note To output a waveform with a minimum delay user can enable the fast + * mode by calling the @ref __HAL_TIM_ENABLE_OCxFAST macro. Then CCx + * output is forced in response to the edge detection on TIx input, + * without taking in account the comparison. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig, + uint32_t OutputChannel, uint32_t InputChannel) +{ + HAL_StatusTypeDef status = HAL_OK; + TIM_OC_InitTypeDef temp1; + + /* Check the parameters */ + assert_param(IS_TIM_OPM_CHANNELS(OutputChannel)); + assert_param(IS_TIM_OPM_CHANNELS(InputChannel)); + + if (OutputChannel != InputChannel) + { + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Extract the Output compare configuration from sConfig structure */ + temp1.OCMode = sConfig->OCMode; + temp1.Pulse = sConfig->Pulse; + temp1.OCPolarity = sConfig->OCPolarity; + temp1.OCNPolarity = sConfig->OCNPolarity; + temp1.OCIdleState = sConfig->OCIdleState; + temp1.OCNIdleState = sConfig->OCNIdleState; + + switch (OutputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_OC1_SetConfig(htim->Instance, &temp1); + break; + } + + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_OC2_SetConfig(htim->Instance, &temp1); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + switch (InputChannel) + { + case TIM_CHANNEL_1: + { + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + TIM_TI1_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1FP1; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + break; + } + + case TIM_CHANNEL_2: + { + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + TIM_TI2_SetConfig(htim->Instance, sConfig->ICPolarity, + sConfig->ICSelection, sConfig->ICFilter); + + /* Reset the IC2PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC; + + /* Select the Trigger source */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI2FP2; + + /* Select the Slave Mode */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER; + break; + } + + default: + status = HAL_ERROR; + break; + } + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return status; + } + else + { + return HAL_ERROR; + } +} + +/** + * @brief Configure the DMA Burst to transfer Data from the memory to the TIM peripheral + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data write + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @note This function should be used only when BurstLength is equal to DMA data transfer length. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, + uint32_t BurstLength) +{ + HAL_StatusTypeDef status; + + status = HAL_TIM_DMABurst_MultiWriteStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength, + ((BurstLength) >> 8U) + 1U); + + + + return status; +} + +/** + * @brief Configure the DMA Burst to transfer multiple Data from the memory to the TIM peripheral + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data write + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @param DataLength Data length. This parameter can be one value + * between 1 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiWriteStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, const uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength)); + + if (htim->DMABurstState == HAL_DMA_BURST_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->DMABurstState == HAL_DMA_BURST_STATE_READY) + { + if ((BurstBuffer == NULL) && (BurstLength > 0U)) + { + return HAL_ERROR; + } + else + { + htim->DMABurstState = HAL_DMA_BURST_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC4: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMADelayPulseCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_COM: + { + /* Set the DMA commutation callbacks */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_TRIGGER: + { + /* Set the DMA trigger callbacks */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)BurstBuffer, + (uint32_t)&htim->Instance->DMAR, DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Configure the DMA Burst Mode */ + htim->Instance->DCR = (BurstBaseAddress | BurstLength); + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM DMA Burst mode + * @param htim TIM handle + * @param BurstRequestSrc TIM DMA Request sources to disable + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_WriteStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + break; + } + case TIM_DMA_CC1: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + case TIM_DMA_CC2: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + case TIM_DMA_CC3: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + case TIM_DMA_CC4: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + case TIM_DMA_COM: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]); + break; + } + case TIM_DMA_TRIGGER: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]); + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data read + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @note This function should be used only when BurstLength is equal to DMA data transfer length. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, uint32_t BurstLength) +{ + HAL_StatusTypeDef status; + + status = HAL_TIM_DMABurst_MultiReadStart(htim, BurstBaseAddress, BurstRequestSrc, BurstBuffer, BurstLength, + ((BurstLength) >> 8U) + 1U); + + + return status; +} + +/** + * @brief Configure the DMA Burst to transfer Data from the TIM peripheral to the memory + * @param htim TIM handle + * @param BurstBaseAddress TIM Base address from where the DMA will start the Data read + * This parameter can be one of the following values: + * @arg TIM_DMABASE_CR1 + * @arg TIM_DMABASE_CR2 + * @arg TIM_DMABASE_SMCR + * @arg TIM_DMABASE_DIER + * @arg TIM_DMABASE_SR + * @arg TIM_DMABASE_EGR + * @arg TIM_DMABASE_CCMR1 + * @arg TIM_DMABASE_CCMR2 + * @arg TIM_DMABASE_CCER + * @arg TIM_DMABASE_CNT + * @arg TIM_DMABASE_PSC + * @arg TIM_DMABASE_ARR + * @arg TIM_DMABASE_RCR + * @arg TIM_DMABASE_CCR1 + * @arg TIM_DMABASE_CCR2 + * @arg TIM_DMABASE_CCR3 + * @arg TIM_DMABASE_CCR4 + * @arg TIM_DMABASE_BDTR + * @param BurstRequestSrc TIM DMA Request sources + * This parameter can be one of the following values: + * @arg TIM_DMA_UPDATE: TIM update Interrupt source + * @arg TIM_DMA_CC1: TIM Capture Compare 1 DMA source + * @arg TIM_DMA_CC2: TIM Capture Compare 2 DMA source + * @arg TIM_DMA_CC3: TIM Capture Compare 3 DMA source + * @arg TIM_DMA_CC4: TIM Capture Compare 4 DMA source + * @arg TIM_DMA_COM: TIM Commutation DMA source + * @arg TIM_DMA_TRIGGER: TIM Trigger DMA source + * @param BurstBuffer The Buffer address. + * @param BurstLength DMA Burst length. This parameter can be one value + * between: TIM_DMABURSTLENGTH_1TRANSFER and TIM_DMABURSTLENGTH_18TRANSFERS. + * @param DataLength Data length. This parameter can be one value + * between 1 and 0xFFFF. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_MultiReadStart(TIM_HandleTypeDef *htim, uint32_t BurstBaseAddress, + uint32_t BurstRequestSrc, uint32_t *BurstBuffer, + uint32_t BurstLength, uint32_t DataLength) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + assert_param(IS_TIM_DMA_BASE(BurstBaseAddress)); + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + assert_param(IS_TIM_DMA_LENGTH(BurstLength)); + assert_param(IS_TIM_DMA_DATA_LENGTH(DataLength)); + + if (htim->DMABurstState == HAL_DMA_BURST_STATE_BUSY) + { + return HAL_BUSY; + } + else if (htim->DMABurstState == HAL_DMA_BURST_STATE_READY) + { + if ((BurstBuffer == NULL) && (BurstLength > 0U)) + { + return HAL_ERROR; + } + else + { + htim->DMABurstState = HAL_DMA_BURST_STATE_BUSY; + } + } + else + { + /* nothing to do */ + } + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + /* Set the DMA Period elapsed callbacks */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferCpltCallback = TIM_DMAPeriodElapsedCplt; + htim->hdma[TIM_DMA_ID_UPDATE]->XferHalfCpltCallback = TIM_DMAPeriodElapsedHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_UPDATE]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_UPDATE], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC1: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC2: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC3: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_CC4: + { + /* Set the DMA capture callbacks */ + htim->hdma[TIM_DMA_ID_CC4]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC4]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC4]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC4], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_COM: + { + /* Set the DMA commutation callbacks */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_COMMUTATION], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + case TIM_DMA_TRIGGER: + { + /* Set the DMA trigger callbacks */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferCpltCallback = TIM_DMATriggerCplt; + htim->hdma[TIM_DMA_ID_TRIGGER]->XferHalfCpltCallback = TIM_DMATriggerHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_TRIGGER]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_TRIGGER], (uint32_t)&htim->Instance->DMAR, (uint32_t)BurstBuffer, + DataLength) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Configure the DMA Burst Mode */ + htim->Instance->DCR = (BurstBaseAddress | BurstLength); + + /* Enable the TIM DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, BurstRequestSrc); + } + + /* Return function status */ + return status; +} + +/** + * @brief Stop the DMA burst reading + * @param htim TIM handle + * @param BurstRequestSrc TIM DMA Request sources to disable. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_DMABurst_ReadStop(TIM_HandleTypeDef *htim, uint32_t BurstRequestSrc) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_DMA_SOURCE(BurstRequestSrc)); + + /* Abort the DMA transfer (at least disable the DMA channel) */ + switch (BurstRequestSrc) + { + case TIM_DMA_UPDATE: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_UPDATE]); + break; + } + case TIM_DMA_CC1: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + case TIM_DMA_CC2: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + case TIM_DMA_CC3: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + case TIM_DMA_CC4: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC4]); + break; + } + case TIM_DMA_COM: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_COMMUTATION]); + break; + } + case TIM_DMA_TRIGGER: + { + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_TRIGGER]); + break; + } + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the TIM Update DMA request */ + __HAL_TIM_DISABLE_DMA(htim, BurstRequestSrc); + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + } + + /* Return function status */ + return status; +} + +/** + * @brief Generate a software event + * @param htim TIM handle + * @param EventSource specifies the event source. + * This parameter can be one of the following values: + * @arg TIM_EVENTSOURCE_UPDATE: Timer update Event source + * @arg TIM_EVENTSOURCE_CC1: Timer Capture Compare 1 Event source + * @arg TIM_EVENTSOURCE_CC2: Timer Capture Compare 2 Event source + * @arg TIM_EVENTSOURCE_CC3: Timer Capture Compare 3 Event source + * @arg TIM_EVENTSOURCE_CC4: Timer Capture Compare 4 Event source + * @arg TIM_EVENTSOURCE_COM: Timer COM event source + * @arg TIM_EVENTSOURCE_TRIGGER: Timer Trigger Event source + * @arg TIM_EVENTSOURCE_BREAK: Timer Break event source + * @note Basic timers can only generate an update event. + * @note TIM_EVENTSOURCE_COM is relevant only with advanced timer instances. + * @note TIM_EVENTSOURCE_BREAK are relevant only for timer instances + * supporting a break input. + * @retval HAL status + */ + +HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + assert_param(IS_TIM_EVENT_SOURCE(EventSource)); + + /* Process Locked */ + __HAL_LOCK(htim); + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Set the event sources */ + htim->Instance->EGR = EventSource; + + /* Change the TIM state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Configures the OCRef clear feature + * @param htim TIM handle + * @param sClearInputConfig pointer to a TIM_ClearInputConfigTypeDef structure that + * contains the OCREF clear feature and parameters for the TIM peripheral. + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim, + const TIM_ClearInputConfigTypeDef *sClearInputConfig, + uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_OCXREF_CLEAR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_CLEARINPUT_SOURCE(sClearInputConfig->ClearInputSource)); + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + switch (sClearInputConfig->ClearInputSource) + { + case TIM_CLEARINPUTSOURCE_NONE: + { + /* Clear the OCREF clear selection bit and the the ETR Bits */ + CLEAR_BIT(htim->Instance->SMCR, (TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP)); + break; + } + + case TIM_CLEARINPUTSOURCE_ETR: + { + /* Check the parameters */ + assert_param(IS_TIM_CLEARINPUT_POLARITY(sClearInputConfig->ClearInputPolarity)); + assert_param(IS_TIM_CLEARINPUT_PRESCALER(sClearInputConfig->ClearInputPrescaler)); + assert_param(IS_TIM_CLEARINPUT_FILTER(sClearInputConfig->ClearInputFilter)); + + /* When OCRef clear feature is used with ETR source, ETR prescaler must be off */ + if (sClearInputConfig->ClearInputPrescaler != TIM_CLEARINPUTPRESCALER_DIV1) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + TIM_ETR_SetConfig(htim->Instance, + sClearInputConfig->ClearInputPrescaler, + sClearInputConfig->ClearInputPolarity, + sClearInputConfig->ClearInputFilter); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + switch (Channel) + { + case TIM_CHANNEL_1: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 1 */ + SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE); + } + else + { + /* Disable the OCREF clear feature for Channel 1 */ + CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE); + } + break; + } + case TIM_CHANNEL_2: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 2 */ + SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE); + } + else + { + /* Disable the OCREF clear feature for Channel 2 */ + CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE); + } + break; + } + case TIM_CHANNEL_3: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 3 */ + SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE); + } + else + { + /* Disable the OCREF clear feature for Channel 3 */ + CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE); + } + break; + } + case TIM_CHANNEL_4: + { + if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE) + { + /* Enable the OCREF clear feature for Channel 4 */ + SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE); + } + else + { + /* Disable the OCREF clear feature for Channel 4 */ + CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE); + } + break; + } + default: + break; + } + } + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Configures the clock source to be used + * @param htim TIM handle + * @param sClockSourceConfig pointer to a TIM_ClockConfigTypeDef structure that + * contains the clock source information for the TIM peripheral. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, const TIM_ClockConfigTypeDef *sClockSourceConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Process Locked */ + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Check the parameters */ + assert_param(IS_TIM_CLOCKSOURCE(sClockSourceConfig->ClockSource)); + + /* Reset the SMS, TS, ECE, ETPS and ETRF bits */ + tmpsmcr = htim->Instance->SMCR; + tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS); + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + htim->Instance->SMCR = tmpsmcr; + + switch (sClockSourceConfig->ClockSource) + { + case TIM_CLOCKSOURCE_INTERNAL: + { + assert_param(IS_TIM_INSTANCE(htim->Instance)); + break; + } + + case TIM_CLOCKSOURCE_ETRMODE1: + { + /* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance)); + + /* Check ETR input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler)); + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + + /* Select the External clock mode1 and the ETRF trigger */ + tmpsmcr = htim->Instance->SMCR; + tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1); + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + break; + } + + case TIM_CLOCKSOURCE_ETRMODE2: + { + /* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance)); + + /* Check ETR input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler)); + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + /* Configure the ETR Clock source */ + TIM_ETR_SetConfig(htim->Instance, + sClockSourceConfig->ClockPrescaler, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + /* Enable the External clock mode2 */ + htim->Instance->SMCR |= TIM_SMCR_ECE; + break; + } + + case TIM_CLOCKSOURCE_TI1: + { + /* Check whether or not the timer instance supports external clock mode 1 */ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI1 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1); + break; + } + + case TIM_CLOCKSOURCE_TI2: + { + /* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI2 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI2_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2); + break; + } + + case TIM_CLOCKSOURCE_TI1ED: + { + /* Check whether or not the timer instance supports external clock mode 1 */ + assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance)); + + /* Check TI1 input conditioning related parameters */ + assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity)); + assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter)); + + TIM_TI1_ConfigInputStage(htim->Instance, + sClockSourceConfig->ClockPolarity, + sClockSourceConfig->ClockFilter); + TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED); + break; + } + + case TIM_CLOCKSOURCE_ITR0: + case TIM_CLOCKSOURCE_ITR1: + case TIM_CLOCKSOURCE_ITR2: + case TIM_CLOCKSOURCE_ITR3: + { + /* Check whether or not the timer instance supports internal trigger input */ + assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance)); + + TIM_ITRx_SetConfig(htim->Instance, sClockSourceConfig->ClockSource); + break; + } + + default: + status = HAL_ERROR; + break; + } + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return status; +} + +/** + * @brief Selects the signal connected to the TI1 input: direct from CH1_input + * or a XOR combination between CH1_input, CH2_input & CH3_input + * @param htim TIM handle. + * @param TI1_Selection Indicate whether or not channel 1 is connected to the + * output of a XOR gate. + * This parameter can be one of the following values: + * @arg TIM_TI1SELECTION_CH1: The TIMx_CH1 pin is connected to TI1 input + * @arg TIM_TI1SELECTION_XORCOMBINATION: The TIMx_CH1, CH2 and CH3 + * pins are connected to the TI1 input (XOR combination) + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection) +{ + uint32_t tmpcr2; + + /* Check the parameters */ + assert_param(IS_TIM_XOR_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TI1SELECTION(TI1_Selection)); + + /* Get the TIMx CR2 register value */ + tmpcr2 = htim->Instance->CR2; + + /* Reset the TI1 selection */ + tmpcr2 &= ~TIM_CR2_TI1S; + + /* Set the TI1 selection */ + tmpcr2 |= TI1_Selection; + + /* Write to TIMxCR2 */ + htim->Instance->CR2 = tmpcr2; + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode + * @param htim TIM handle. + * @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the Slave mode + * (Disable, Reset, Gated, Trigger, External clock mode 1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, const TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + /* Disable Trigger Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in Slave mode in interrupt mode + * @param htim TIM handle. + * @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that + * contains the selected trigger (internal trigger input, filtered + * timer input or external trigger input) and the Slave mode + * (Disable, Reset, Gated, Trigger, External clock mode 1). + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim, + const TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + /* Check the parameters */ + assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode)); + assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger)); + + __HAL_LOCK(htim); + + htim->State = HAL_TIM_STATE_BUSY; + + if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK) + { + htim->State = HAL_TIM_STATE_READY; + __HAL_UNLOCK(htim); + return HAL_ERROR; + } + + /* Enable Trigger Interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_TRIGGER); + + /* Disable Trigger DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER); + + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Read the captured value from Capture Compare unit + * @param htim TIM handle. + * @param Channel TIM Channels to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @arg TIM_CHANNEL_4: TIM Channel 4 selected + * @retval Captured value + */ +uint32_t HAL_TIM_ReadCapturedValue(const TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpreg = 0U; + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + + /* Return the capture 1 value */ + tmpreg = htim->Instance->CCR1; + + break; + } + case TIM_CHANNEL_2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + + /* Return the capture 2 value */ + tmpreg = htim->Instance->CCR2; + + break; + } + + case TIM_CHANNEL_3: + { + /* Check the parameters */ + assert_param(IS_TIM_CC3_INSTANCE(htim->Instance)); + + /* Return the capture 3 value */ + tmpreg = htim->Instance->CCR3; + + break; + } + + case TIM_CHANNEL_4: + { + /* Check the parameters */ + assert_param(IS_TIM_CC4_INSTANCE(htim->Instance)); + + /* Return the capture 4 value */ + tmpreg = htim->Instance->CCR4; + + break; + } + + default: + break; + } + + return tmpreg; +} + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions + * @brief TIM Callbacks functions + * +@verbatim + ============================================================================== + ##### TIM Callbacks functions ##### + ============================================================================== + [..] + This section provides TIM callback functions: + (+) TIM Period elapsed callback + (+) TIM Output Compare callback + (+) TIM Input capture callback + (+) TIM Trigger callback + (+) TIM Error callback + +@endverbatim + * @{ + */ + +/** + * @brief Period elapsed callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PeriodElapsedCallback could be implemented in the user file + */ +} + +/** + * @brief Period elapsed half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PeriodElapsedHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PeriodElapsedHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Output Compare callback in non-blocking mode + * @param htim TIM OC handle + * @retval None + */ +__weak void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_OC_DelayElapsedCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture callback in non-blocking mode + * @param htim TIM IC handle + * @retval None + */ +__weak void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_CaptureCallback could be implemented in the user file + */ +} + +/** + * @brief Input Capture half complete callback in non-blocking mode + * @param htim TIM IC handle + * @retval None + */ +__weak void HAL_TIM_IC_CaptureHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_IC_CaptureHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief PWM Pulse finished callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_PulseFinishedCallback could be implemented in the user file + */ +} + +/** + * @brief PWM Pulse finished half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_PWM_PulseFinishedHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Trigger detection callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_TriggerCallback could be implemented in the user file + */ +} + +/** + * @brief Hall Trigger detection half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_TriggerHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_TriggerHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Timer error callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIM_ErrorCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIM_ErrorCallback could be implemented in the user file + */ +} + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief Register a User TIM callback to be used instead of the weak predefined callback + * @param htim tim handle + * @param CallbackID ID of the callback to be registered + * This parameter can be one of the following values: + * @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID + * @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID + * @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID + * @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID + * @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID + * @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID + * @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID + * @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID + * @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID + * @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID + * @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID + * @param pCallback pointer to the callback function + * @retval status + */ +HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID, + pTIM_CallbackTypeDef pCallback) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (pCallback == NULL) + { + return HAL_ERROR; + } + + if (htim->State == HAL_TIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = pCallback; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_CB_ID : + htim->PeriodElapsedCallback = pCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID : + htim->PeriodElapsedHalfCpltCallback = pCallback; + break; + + case HAL_TIM_TRIGGER_CB_ID : + htim->TriggerCallback = pCallback; + break; + + case HAL_TIM_TRIGGER_HALF_CB_ID : + htim->TriggerHalfCpltCallback = pCallback; + break; + + case HAL_TIM_IC_CAPTURE_CB_ID : + htim->IC_CaptureCallback = pCallback; + break; + + case HAL_TIM_IC_CAPTURE_HALF_CB_ID : + htim->IC_CaptureHalfCpltCallback = pCallback; + break; + + case HAL_TIM_OC_DELAY_ELAPSED_CB_ID : + htim->OC_DelayElapsedCallback = pCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_CB_ID : + htim->PWM_PulseFinishedCallback = pCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID : + htim->PWM_PulseFinishedHalfCpltCallback = pCallback; + break; + + case HAL_TIM_ERROR_CB_ID : + htim->ErrorCallback = pCallback; + break; + + case HAL_TIM_COMMUTATION_CB_ID : + htim->CommutationCallback = pCallback; + break; + + case HAL_TIM_COMMUTATION_HALF_CB_ID : + htim->CommutationHalfCpltCallback = pCallback; + break; + + case HAL_TIM_BREAK_CB_ID : + htim->BreakCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (htim->State == HAL_TIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + htim->Base_MspInitCallback = pCallback; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + htim->Base_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + htim->IC_MspInitCallback = pCallback; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + htim->IC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + htim->OC_MspInitCallback = pCallback; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + htim->OC_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + htim->PWM_MspInitCallback = pCallback; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + htim->PWM_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + htim->OnePulse_MspInitCallback = pCallback; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + htim->OnePulse_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + htim->Encoder_MspInitCallback = pCallback; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + htim->Encoder_MspDeInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + htim->HallSensor_MspInitCallback = pCallback; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + htim->HallSensor_MspDeInitCallback = pCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} + +/** + * @brief Unregister a TIM callback + * TIM callback is redirected to the weak predefined callback + * @param htim tim handle + * @param CallbackID ID of the callback to be unregistered + * This parameter can be one of the following values: + * @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID + * @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID + * @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID + * @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID + * @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID + * @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID + * @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID + * @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID + * @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID + * @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID + * @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID + * @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID + * @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID + * @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID + * @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID + * @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID + * @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID + * @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID + * @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID + * @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID + * @retval status + */ +HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID) +{ + HAL_StatusTypeDef status = HAL_OK; + + if (htim->State == HAL_TIM_STATE_READY) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + /* Legacy weak Base MspInit Callback */ + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + /* Legacy weak Base Msp DeInit Callback */ + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + /* Legacy weak IC Msp Init Callback */ + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + /* Legacy weak IC Msp DeInit Callback */ + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + /* Legacy weak OC Msp Init Callback */ + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + /* Legacy weak OC Msp DeInit Callback */ + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + /* Legacy weak PWM Msp Init Callback */ + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + /* Legacy weak PWM Msp DeInit Callback */ + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + /* Legacy weak One Pulse Msp Init Callback */ + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + /* Legacy weak One Pulse Msp DeInit Callback */ + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + /* Legacy weak Encoder Msp Init Callback */ + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + /* Legacy weak Encoder Msp DeInit Callback */ + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + /* Legacy weak Hall Sensor Msp Init Callback */ + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + /* Legacy weak Hall Sensor Msp DeInit Callback */ + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; + break; + + case HAL_TIM_PERIOD_ELAPSED_CB_ID : + /* Legacy weak Period Elapsed Callback */ + htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; + break; + + case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID : + /* Legacy weak Period Elapsed half complete Callback */ + htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; + break; + + case HAL_TIM_TRIGGER_CB_ID : + /* Legacy weak Trigger Callback */ + htim->TriggerCallback = HAL_TIM_TriggerCallback; + break; + + case HAL_TIM_TRIGGER_HALF_CB_ID : + /* Legacy weak Trigger half complete Callback */ + htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; + break; + + case HAL_TIM_IC_CAPTURE_CB_ID : + /* Legacy weak IC Capture Callback */ + htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; + break; + + case HAL_TIM_IC_CAPTURE_HALF_CB_ID : + /* Legacy weak IC Capture half complete Callback */ + htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; + break; + + case HAL_TIM_OC_DELAY_ELAPSED_CB_ID : + /* Legacy weak OC Delay Elapsed Callback */ + htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_CB_ID : + /* Legacy weak PWM Pulse Finished Callback */ + htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; + break; + + case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID : + /* Legacy weak PWM Pulse Finished half complete Callback */ + htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; + break; + + case HAL_TIM_ERROR_CB_ID : + /* Legacy weak Error Callback */ + htim->ErrorCallback = HAL_TIM_ErrorCallback; + break; + + case HAL_TIM_COMMUTATION_CB_ID : + /* Legacy weak Commutation Callback */ + htim->CommutationCallback = HAL_TIMEx_CommutCallback; + break; + + case HAL_TIM_COMMUTATION_HALF_CB_ID : + /* Legacy weak Commutation half complete Callback */ + htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; + break; + + case HAL_TIM_BREAK_CB_ID : + /* Legacy weak Break Callback */ + htim->BreakCallback = HAL_TIMEx_BreakCallback; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else if (htim->State == HAL_TIM_STATE_RESET) + { + switch (CallbackID) + { + case HAL_TIM_BASE_MSPINIT_CB_ID : + /* Legacy weak Base MspInit Callback */ + htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; + break; + + case HAL_TIM_BASE_MSPDEINIT_CB_ID : + /* Legacy weak Base Msp DeInit Callback */ + htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; + break; + + case HAL_TIM_IC_MSPINIT_CB_ID : + /* Legacy weak IC Msp Init Callback */ + htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; + break; + + case HAL_TIM_IC_MSPDEINIT_CB_ID : + /* Legacy weak IC Msp DeInit Callback */ + htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; + break; + + case HAL_TIM_OC_MSPINIT_CB_ID : + /* Legacy weak OC Msp Init Callback */ + htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; + break; + + case HAL_TIM_OC_MSPDEINIT_CB_ID : + /* Legacy weak OC Msp DeInit Callback */ + htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; + break; + + case HAL_TIM_PWM_MSPINIT_CB_ID : + /* Legacy weak PWM Msp Init Callback */ + htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; + break; + + case HAL_TIM_PWM_MSPDEINIT_CB_ID : + /* Legacy weak PWM Msp DeInit Callback */ + htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; + break; + + case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID : + /* Legacy weak One Pulse Msp Init Callback */ + htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; + break; + + case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID : + /* Legacy weak One Pulse Msp DeInit Callback */ + htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; + break; + + case HAL_TIM_ENCODER_MSPINIT_CB_ID : + /* Legacy weak Encoder Msp Init Callback */ + htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; + break; + + case HAL_TIM_ENCODER_MSPDEINIT_CB_ID : + /* Legacy weak Encoder Msp DeInit Callback */ + htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID : + /* Legacy weak Hall Sensor Msp Init Callback */ + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; + break; + + case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID : + /* Legacy weak Hall Sensor Msp DeInit Callback */ + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; + break; + + default : + /* Return error status */ + status = HAL_ERROR; + break; + } + } + else + { + /* Return error status */ + status = HAL_ERROR; + } + + return status; +} +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions + * @brief TIM Peripheral State functions + * +@verbatim + ============================================================================== + ##### Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Base handle state. + * @param htim TIM Base handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM OC handle state. + * @param htim TIM Output Compare handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM PWM handle state. + * @param htim TIM handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Input Capture handle state. + * @param htim TIM IC handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM One Pulse Mode handle state. + * @param htim TIM OPM handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Encoder Mode handle state. + * @param htim TIM Encoder Interface handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return the TIM Encoder Mode handle state. + * @param htim TIM handle + * @retval Active channel + */ +HAL_TIM_ActiveChannel HAL_TIM_GetActiveChannel(const TIM_HandleTypeDef *htim) +{ + return htim->Channel; +} + +/** + * @brief Return actual state of the TIM channel. + * @param htim TIM handle + * @param Channel TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @arg TIM_CHANNEL_5: TIM Channel 5 + * @arg TIM_CHANNEL_6: TIM Channel 6 + * @retval TIM Channel state + */ +HAL_TIM_ChannelStateTypeDef HAL_TIM_GetChannelState(const TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_TIM_ChannelStateTypeDef channel_state; + + /* Check the parameters */ + assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel)); + + channel_state = TIM_CHANNEL_STATE_GET(htim, Channel); + + return channel_state; +} + +/** + * @brief Return actual state of a DMA burst operation. + * @param htim TIM handle + * @retval DMA burst state + */ +HAL_TIM_DMABurstStateTypeDef HAL_TIM_DMABurstState(const TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_DMABURST_INSTANCE(htim->Instance)); + + return htim->DMABurstState; +} + +/** + * @} + */ + +/** + * @} + */ + +/** @defgroup TIM_Private_Functions TIM Private Functions + * @{ + */ + +/** + * @brief TIM DMA error callback + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMAError(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + htim->State = HAL_TIM_STATE_READY; + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->ErrorCallback(htim); +#else + HAL_TIM_ErrorCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Delay Pulse complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMADelayPulseCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + } + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Delay Pulse half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMADelayPulseHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedHalfCpltCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Capture complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMACaptureCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_4, HAL_TIM_CHANNEL_STATE_READY); + } + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureCallback(htim); +#else + HAL_TIM_IC_CaptureCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Capture half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIM_DMACaptureHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC4]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4; + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->IC_CaptureHalfCpltCallback(htim); +#else + HAL_TIM_IC_CaptureHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA Period Elapse complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (htim->hdma[TIM_DMA_ID_UPDATE]->Init.Mode == DMA_NORMAL) + { + htim->State = HAL_TIM_STATE_READY; + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedCallback(htim); +#else + HAL_TIM_PeriodElapsedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Period Elapse half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PeriodElapsedHalfCpltCallback(htim); +#else + HAL_TIM_PeriodElapsedHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Trigger callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (htim->hdma[TIM_DMA_ID_TRIGGER]->Init.Mode == DMA_NORMAL) + { + htim->State = HAL_TIM_STATE_READY; + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerCallback(htim); +#else + HAL_TIM_TriggerCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Trigger half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->TriggerHalfCpltCallback(htim); +#else + HAL_TIM_TriggerHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief Time Base configuration + * @param TIMx TIM peripheral + * @param Structure TIM Base configuration structure + * @retval None + */ +void TIM_Base_SetConfig(TIM_TypeDef *TIMx, const TIM_Base_InitTypeDef *Structure) +{ + uint32_t tmpcr1; + tmpcr1 = TIMx->CR1; + + /* Set TIM Time Base Unit parameters ---------------------------------------*/ + if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx)) + { + /* Select the Counter Mode */ + tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS); + tmpcr1 |= Structure->CounterMode; + } + + if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx)) + { + /* Set the clock division */ + tmpcr1 &= ~TIM_CR1_CKD; + tmpcr1 |= (uint32_t)Structure->ClockDivision; + } + + /* Set the auto-reload preload */ + MODIFY_REG(tmpcr1, TIM_CR1_ARPE, Structure->AutoReloadPreload); + + TIMx->CR1 = tmpcr1; + + /* Set the Autoreload value */ + TIMx->ARR = (uint32_t)Structure->Period ; + + /* Set the Prescaler value */ + TIMx->PSC = Structure->Prescaler; + + if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx)) + { + /* Set the Repetition Counter value */ + TIMx->RCR = Structure->RepetitionCounter; + } + + /* Generate an update event to reload the Prescaler + and the repetition counter (only for advanced timer) value immediately */ + TIMx->EGR = TIM_EGR_UG; + + /* Check if the update flag is set after the Update Generation, if so clear the UIF flag */ + if (HAL_IS_BIT_SET(TIMx->SR, TIM_FLAG_UPDATE)) + { + /* Clear the update flag */ + CLEAR_BIT(TIMx->SR, TIM_FLAG_UPDATE); + } +} + +/** + * @brief Timer Output Compare 1 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 1: Reset the CC1E Bit */ + TIMx->CCER &= ~TIM_CCER_CC1E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare Mode Bits */ + tmpccmrx &= ~TIM_CCMR1_OC1M; + tmpccmrx &= ~TIM_CCMR1_CC1S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC1P; + /* Set the Output Compare Polarity */ + tmpccer |= OC_Config->OCPolarity; + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1)) + { + /* Check parameters */ + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC1NP; + /* Set the Output N Polarity */ + tmpccer |= OC_Config->OCNPolarity; + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC1NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS1; + tmpcr2 &= ~TIM_CR2_OIS1N; + /* Set the Output Idle state */ + tmpcr2 |= OC_Config->OCIdleState; + /* Set the Output N Idle state */ + tmpcr2 |= OC_Config->OCNIdleState; + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR1 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 2 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 2: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC2E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR1 register value */ + tmpccmrx = TIMx->CCMR1; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR1_OC2M; + tmpccmrx &= ~TIM_CCMR1_CC2S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8U); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC2P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 4U); + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2)) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC2NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 4U); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC2NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS2; + tmpcr2 &= ~TIM_CR2_OIS2N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 2U); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 2U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR1 */ + TIMx->CCMR1 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR2 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 3 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 3: Reset the CC2E Bit */ + TIMx->CCER &= ~TIM_CCER_CC3E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC3M; + tmpccmrx &= ~TIM_CCMR2_CC3S; + /* Select the Output Compare Mode */ + tmpccmrx |= OC_Config->OCMode; + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC3P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 8U); + + if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_3)) + { + assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity)); + + /* Reset the Output N Polarity level */ + tmpccer &= ~TIM_CCER_CC3NP; + /* Set the Output N Polarity */ + tmpccer |= (OC_Config->OCNPolarity << 8U); + /* Reset the Output N State */ + tmpccer &= ~TIM_CCER_CC3NE; + } + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState)); + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare and Output Compare N IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS3; + tmpcr2 &= ~TIM_CR2_OIS3N; + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 4U); + /* Set the Output N Idle state */ + tmpcr2 |= (OC_Config->OCNIdleState << 4U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR3 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Timer Output Compare 4 configuration + * @param TIMx to select the TIM peripheral + * @param OC_Config The output configuration structure + * @retval None + */ +static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, const TIM_OC_InitTypeDef *OC_Config) +{ + uint32_t tmpccmrx; + uint32_t tmpccer; + uint32_t tmpcr2; + + /* Get the TIMx CCER register value */ + tmpccer = TIMx->CCER; + + /* Disable the Channel 4: Reset the CC4E Bit */ + TIMx->CCER &= ~TIM_CCER_CC4E; + + /* Get the TIMx CR2 register value */ + tmpcr2 = TIMx->CR2; + + /* Get the TIMx CCMR2 register value */ + tmpccmrx = TIMx->CCMR2; + + /* Reset the Output Compare mode and Capture/Compare selection Bits */ + tmpccmrx &= ~TIM_CCMR2_OC4M; + tmpccmrx &= ~TIM_CCMR2_CC4S; + + /* Select the Output Compare Mode */ + tmpccmrx |= (OC_Config->OCMode << 8U); + + /* Reset the Output Polarity level */ + tmpccer &= ~TIM_CCER_CC4P; + /* Set the Output Compare Polarity */ + tmpccer |= (OC_Config->OCPolarity << 12U); + + if (IS_TIM_BREAK_INSTANCE(TIMx)) + { + /* Check parameters */ + assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState)); + + /* Reset the Output Compare IDLE State */ + tmpcr2 &= ~TIM_CR2_OIS4; + + /* Set the Output Idle state */ + tmpcr2 |= (OC_Config->OCIdleState << 6U); + } + + /* Write to TIMx CR2 */ + TIMx->CR2 = tmpcr2; + + /* Write to TIMx CCMR2 */ + TIMx->CCMR2 = tmpccmrx; + + /* Set the Capture Compare Register value */ + TIMx->CCR4 = OC_Config->Pulse; + + /* Write to TIMx CCER */ + TIMx->CCER = tmpccer; +} + +/** + * @brief Slave Timer configuration function + * @param htim TIM handle + * @param sSlaveConfig Slave timer configuration + * @retval None + */ +static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim, + const TIM_SlaveConfigTypeDef *sSlaveConfig) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Reset the Trigger Selection Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source */ + tmpsmcr |= sSlaveConfig->InputTrigger; + + /* Reset the slave mode Bits */ + tmpsmcr &= ~TIM_SMCR_SMS; + /* Set the slave mode */ + tmpsmcr |= sSlaveConfig->SlaveMode; + + /* Write to TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + + /* Configure the trigger prescaler, filter, and polarity */ + switch (sSlaveConfig->InputTrigger) + { + case TIM_TS_ETRF: + { + /* Check the parameters */ + assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPRESCALER(sSlaveConfig->TriggerPrescaler)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + /* Configure the ETR Trigger source */ + TIM_ETR_SetConfig(htim->Instance, + sSlaveConfig->TriggerPrescaler, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_TI1F_ED: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + if (sSlaveConfig->SlaveMode == TIM_SLAVEMODE_GATED) + { + return HAL_ERROR; + } + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = htim->Instance->CCER; + htim->Instance->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = htim->Instance->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((sSlaveConfig->TriggerFilter) << 4U); + + /* Write to TIMx CCMR1 and CCER registers */ + htim->Instance->CCMR1 = tmpccmr1; + htim->Instance->CCER = tmpccer; + break; + } + + case TIM_TS_TI1FP1: + { + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI1 Filter and Polarity */ + TIM_TI1_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_TI2FP2: + { + /* Check the parameters */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity)); + assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter)); + + /* Configure TI2 Filter and Polarity */ + TIM_TI2_ConfigInputStage(htim->Instance, + sSlaveConfig->TriggerPolarity, + sSlaveConfig->TriggerFilter); + break; + } + + case TIM_TS_ITR0: + case TIM_TS_ITR1: + case TIM_TS_ITR2: + case TIM_TS_ITR3: + { + /* Check the parameter */ + assert_param(IS_TIM_CC2_INSTANCE(htim->Instance)); + break; + } + + default: + status = HAL_ERROR; + break; + } + + return status; +} + +/** + * @brief Configure the TI1 as Input. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 1 is selected to be connected to IC1. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 1 is selected to be connected to IC2. + * @arg TIM_ICSELECTION_TRC: TIM Input 1 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI2FP1 + * (on channel2 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + */ +void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + + /* Select the Input */ + if (IS_TIM_CC2_INSTANCE(TIMx) != RESET) + { + tmpccmr1 &= ~TIM_CCMR1_CC1S; + tmpccmr1 |= TIM_ICSelection; + } + else + { + tmpccmr1 |= TIM_CCMR1_CC1S_0; + } + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= ((TIM_ICFilter << 4U) & TIM_CCMR1_IC1F); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the Polarity and Filter for TI1. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 1: Reset the CC1E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC1E; + tmpccmr1 = TIMx->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC1F; + tmpccmr1 |= (TIM_ICFilter << 4U); + + /* Select the Polarity and set the CC1E Bit */ + tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP); + tmpccer |= TIM_ICPolarity; + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI2 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 2 is selected to be connected to IC2. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 2 is selected to be connected to IC1. + * @arg TIM_ICSELECTION_TRC: TIM Input 2 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI1FP2 + * (on channel1 path) is used as the input signal. Therefore CCMR1 must be + * protected against un-initialized filter and polarity values. + */ +static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 2: Reset the CC2E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + + /* Select the Input */ + tmpccmr1 &= ~TIM_CCMR1_CC2S; + tmpccmr1 |= (TIM_ICSelection << 8U); + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= ((TIM_ICFilter << 12U) & TIM_CCMR1_IC2F); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= ((TIM_ICPolarity << 4U) & (TIM_CCER_CC2P | TIM_CCER_CC2NP)); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the Polarity and Filter for TI2. + * @param TIMx to select the TIM peripheral. + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @arg TIM_ICPOLARITY_BOTHEDGE + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + */ +static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr1; + uint32_t tmpccer; + + /* Disable the Channel 2: Reset the CC2E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC2E; + tmpccmr1 = TIMx->CCMR1; + + /* Set the filter */ + tmpccmr1 &= ~TIM_CCMR1_IC2F; + tmpccmr1 |= (TIM_ICFilter << 12U); + + /* Select the Polarity and set the CC2E Bit */ + tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP); + tmpccer |= (TIM_ICPolarity << 4U); + + /* Write to TIMx CCMR1 and CCER registers */ + TIMx->CCMR1 = tmpccmr1 ; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI3 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 3 is selected to be connected to IC3. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 3 is selected to be connected to IC4. + * @arg TIM_ICSELECTION_TRC: TIM Input 3 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @retval None + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI3FP4 + * (on channel1 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + */ +static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + + /* Disable the Channel 3: Reset the CC3E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC3E; + tmpccmr2 = TIMx->CCMR2; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC3S; + tmpccmr2 |= TIM_ICSelection; + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC3F; + tmpccmr2 |= ((TIM_ICFilter << 4U) & TIM_CCMR2_IC3F); + + /* Select the Polarity and set the CC3E Bit */ + tmpccer &= ~(TIM_CCER_CC3P); + tmpccer |= ((TIM_ICPolarity << 8U) & TIM_CCER_CC3P); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer; +} + +/** + * @brief Configure the TI4 as Input. + * @param TIMx to select the TIM peripheral + * @param TIM_ICPolarity The Input Polarity. + * This parameter can be one of the following values: + * @arg TIM_ICPOLARITY_RISING + * @arg TIM_ICPOLARITY_FALLING + * @param TIM_ICSelection specifies the input to be used. + * This parameter can be one of the following values: + * @arg TIM_ICSELECTION_DIRECTTI: TIM Input 4 is selected to be connected to IC4. + * @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 4 is selected to be connected to IC3. + * @arg TIM_ICSELECTION_TRC: TIM Input 4 is selected to be connected to TRC. + * @param TIM_ICFilter Specifies the Input Capture Filter. + * This parameter must be a value between 0x00 and 0x0F. + * @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI4FP3 + * (on channel1 path) is used as the input signal. Therefore CCMR2 must be + * protected against un-initialized filter and polarity values. + * @retval None + */ +static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection, + uint32_t TIM_ICFilter) +{ + uint32_t tmpccmr2; + uint32_t tmpccer; + + /* Disable the Channel 4: Reset the CC4E Bit */ + tmpccer = TIMx->CCER; + TIMx->CCER &= ~TIM_CCER_CC4E; + tmpccmr2 = TIMx->CCMR2; + + /* Select the Input */ + tmpccmr2 &= ~TIM_CCMR2_CC4S; + tmpccmr2 |= (TIM_ICSelection << 8U); + + /* Set the filter */ + tmpccmr2 &= ~TIM_CCMR2_IC4F; + tmpccmr2 |= ((TIM_ICFilter << 12U) & TIM_CCMR2_IC4F); + + /* Select the Polarity and set the CC4E Bit */ + tmpccer &= ~(TIM_CCER_CC4P); + tmpccer |= ((TIM_ICPolarity << 12U) & TIM_CCER_CC4P); + + /* Write to TIMx CCMR2 and CCER registers */ + TIMx->CCMR2 = tmpccmr2; + TIMx->CCER = tmpccer ; +} + +/** + * @brief Selects the Input Trigger source + * @param TIMx to select the TIM peripheral + * @param InputTriggerSource The Input Trigger source. + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal Trigger 0 + * @arg TIM_TS_ITR1: Internal Trigger 1 + * @arg TIM_TS_ITR2: Internal Trigger 2 + * @arg TIM_TS_ITR3: Internal Trigger 3 + * @arg TIM_TS_TI1F_ED: TI1 Edge Detector + * @arg TIM_TS_TI1FP1: Filtered Timer Input 1 + * @arg TIM_TS_TI2FP2: Filtered Timer Input 2 + * @arg TIM_TS_ETRF: External Trigger input + * @retval None + */ +static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource) +{ + uint32_t tmpsmcr; + + /* Get the TIMx SMCR register value */ + tmpsmcr = TIMx->SMCR; + /* Reset the TS Bits */ + tmpsmcr &= ~TIM_SMCR_TS; + /* Set the Input Trigger source and the slave mode*/ + tmpsmcr |= (InputTriggerSource | TIM_SLAVEMODE_EXTERNAL1); + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} +/** + * @brief Configures the TIMx External Trigger (ETR). + * @param TIMx to select the TIM peripheral + * @param TIM_ExtTRGPrescaler The external Trigger Prescaler. + * This parameter can be one of the following values: + * @arg TIM_ETRPRESCALER_DIV1: ETRP Prescaler OFF. + * @arg TIM_ETRPRESCALER_DIV2: ETRP frequency divided by 2. + * @arg TIM_ETRPRESCALER_DIV4: ETRP frequency divided by 4. + * @arg TIM_ETRPRESCALER_DIV8: ETRP frequency divided by 8. + * @param TIM_ExtTRGPolarity The external Trigger Polarity. + * This parameter can be one of the following values: + * @arg TIM_ETRPOLARITY_INVERTED: active low or falling edge active. + * @arg TIM_ETRPOLARITY_NONINVERTED: active high or rising edge active. + * @param ExtTRGFilter External Trigger Filter. + * This parameter must be a value between 0x00 and 0x0F + * @retval None + */ +void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler, + uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter) +{ + uint32_t tmpsmcr; + + tmpsmcr = TIMx->SMCR; + + /* Reset the ETR Bits */ + tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP); + + /* Set the Prescaler, the Filter value and the Polarity */ + tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (TIM_ExtTRGPolarity | (ExtTRGFilter << 8U))); + + /* Write to TIMx SMCR */ + TIMx->SMCR = tmpsmcr; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel x. + * @param TIMx to select the TIM peripheral + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @arg TIM_CHANNEL_4: TIM Channel 4 + * @param ChannelState specifies the TIM Channel CCxE bit new state. + * This parameter can be: TIM_CCx_ENABLE or TIM_CCx_DISABLE. + * @retval None + */ +void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState) +{ + uint32_t tmp; + + /* Check the parameters */ + assert_param(IS_TIM_CC1_INSTANCE(TIMx)); + assert_param(IS_TIM_CHANNELS(Channel)); + + tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */ + + /* Reset the CCxE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxE Bit */ + TIMx->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */ +} + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) +/** + * @brief Reset interrupt callbacks to the legacy weak callbacks. + * @param htim pointer to a TIM_HandleTypeDef structure that contains + * the configuration information for TIM module. + * @retval None + */ +void TIM_ResetCallback(TIM_HandleTypeDef *htim) +{ + /* Reset the TIM callback to the legacy weak callbacks */ + htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; + htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; + htim->TriggerCallback = HAL_TIM_TriggerCallback; + htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; + htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; + htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; + htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; + htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; + htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; + htim->ErrorCallback = HAL_TIM_ErrorCallback; + htim->CommutationCallback = HAL_TIMEx_CommutCallback; + htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; + htim->BreakCallback = HAL_TIMEx_BreakCallback; +} +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c new file mode 100644 index 0000000..8a565a6 --- /dev/null +++ b/STM32F103C8T6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c @@ -0,0 +1,2359 @@ +/** + ****************************************************************************** + * @file stm32f1xx_hal_tim_ex.c + * @author MCD Application Team + * @brief TIM HAL module driver. + * This file provides firmware functions to manage the following + * functionalities of the Timer Extended peripheral: + * + Time Hall Sensor Interface Initialization + * + Time Hall Sensor Interface Start + * + Time Complementary signal break and dead time configuration + * + Time Master and Slave synchronization configuration + * + Timer remapping capabilities configuration + ****************************************************************************** + * @attention + * + * Copyright (c) 2016 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + @verbatim + ============================================================================== + ##### TIMER Extended features ##### + ============================================================================== + [..] + The Timer Extended features include: + (#) Complementary outputs with programmable dead-time for : + (++) Output Compare + (++) PWM generation (Edge and Center-aligned Mode) + (++) One-pulse mode output + (#) Synchronization circuit to control the timer with external signals and to + interconnect several timers together. + (#) Break input to put the timer output signals in reset state or in a known state. + (#) Supports incremental (quadrature) encoder and hall-sensor circuitry for + positioning purposes + + ##### How to use this driver ##### + ============================================================================== + [..] + (#) Initialize the TIM low level resources by implementing the following functions + depending on the selected feature: + (++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit() + + (#) Initialize the TIM low level resources : + (##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE(); + (##) TIM pins configuration + (+++) Enable the clock for the TIM GPIOs using the following function: + __HAL_RCC_GPIOx_CLK_ENABLE(); + (+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init(); + + (#) The external Clock can be configured, if needed (the default clock is the + internal clock from the APBx), using the following function: + HAL_TIM_ConfigClockSource, the clock configuration should be done before + any start function. + + (#) Configure the TIM in the desired functioning mode using one of the + initialization function of this driver: + (++) HAL_TIMEx_HallSensor_Init() and HAL_TIMEx_ConfigCommutEvent(): to use the + Timer Hall Sensor Interface and the commutation event with the corresponding + Interrupt and DMA request if needed (Note that One Timer is used to interface + with the Hall sensor Interface and another Timer should be used to use + the commutation event). + + (#) Activate the TIM peripheral using one of the start functions: + (++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), + HAL_TIMEx_OCN_Start_IT() + (++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), + HAL_TIMEx_PWMN_Start_IT() + (++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT() + (++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), + HAL_TIMEx_HallSensor_Start_IT(). + + @endverbatim + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f1xx_hal.h" + +/** @addtogroup STM32F1xx_HAL_Driver + * @{ + */ + +/** @defgroup TIMEx TIMEx + * @brief TIM Extended HAL module driver + * @{ + */ + +#ifdef HAL_TIM_MODULE_ENABLED + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macros ------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma); +static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma); +static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState); + +/* Exported functions --------------------------------------------------------*/ +/** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions + * @{ + */ + +/** @defgroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions + * @brief Timer Hall Sensor functions + * +@verbatim + ============================================================================== + ##### Timer Hall Sensor functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Initialize and configure TIM HAL Sensor. + (+) De-initialize TIM HAL Sensor. + (+) Start the Hall Sensor Interface. + (+) Stop the Hall Sensor Interface. + (+) Start the Hall Sensor Interface and enable interrupts. + (+) Stop the Hall Sensor Interface and disable interrupts. + (+) Start the Hall Sensor Interface and enable DMA transfers. + (+) Stop the Hall Sensor Interface and disable DMA transfers. + +@endverbatim + * @{ + */ +/** + * @brief Initializes the TIM Hall Sensor Interface and initialize the associated handle. + * @note When the timer instance is initialized in Hall Sensor Interface mode, + * timer channels 1 and channel 2 are reserved and cannot be used for + * other purpose. + * @param htim TIM Hall Sensor Interface handle + * @param sConfig TIM Hall Sensor configuration structure + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, const TIM_HallSensor_InitTypeDef *sConfig) +{ + TIM_OC_InitTypeDef OC_Config; + + /* Check the TIM handle allocation */ + if (htim == NULL) + { + return HAL_ERROR; + } + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode)); + assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision)); + assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload)); + assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity)); + assert_param(IS_TIM_PERIOD(htim->Init.Period)); + assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler)); + assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter)); + + if (htim->State == HAL_TIM_STATE_RESET) + { + /* Allocate lock resource and initialize it */ + htim->Lock = HAL_UNLOCKED; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + /* Reset interrupt callbacks to legacy week callbacks */ + TIM_ResetCallback(htim); + + if (htim->HallSensor_MspInitCallback == NULL) + { + htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; + } + /* Init the low level hardware : GPIO, CLOCK, NVIC */ + htim->HallSensor_MspInitCallback(htim); +#else + /* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */ + HAL_TIMEx_HallSensor_MspInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + } + + /* Set the TIM state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Configure the Time base in the Encoder Mode */ + TIM_Base_SetConfig(htim->Instance, &htim->Init); + + /* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */ + TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter); + + /* Reset the IC1PSC Bits */ + htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC; + /* Set the IC1PSC value */ + htim->Instance->CCMR1 |= sConfig->IC1Prescaler; + + /* Enable the Hall sensor interface (XOR function of the three inputs) */ + htim->Instance->CR2 |= TIM_CR2_TI1S; + + /* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= TIM_TS_TI1F_ED; + + /* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */ + htim->Instance->SMCR &= ~TIM_SMCR_SMS; + htim->Instance->SMCR |= TIM_SLAVEMODE_RESET; + + /* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/ + OC_Config.OCFastMode = TIM_OCFAST_DISABLE; + OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET; + OC_Config.OCMode = TIM_OCMODE_PWM2; + OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET; + OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH; + OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH; + OC_Config.Pulse = sConfig->Commutation_Delay; + + TIM_OC2_SetConfig(htim->Instance, &OC_Config); + + /* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2 + register to 101 */ + htim->Instance->CR2 &= ~TIM_CR2_MMS; + htim->Instance->CR2 |= TIM_TRGO_OC2REF; + + /* Initialize the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_READY; + + /* Initialize the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Initialize the TIM state*/ + htim->State = HAL_TIM_STATE_READY; + + return HAL_OK; +} + +/** + * @brief DeInitializes the TIM Hall Sensor interface + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_INSTANCE(htim->Instance)); + + htim->State = HAL_TIM_STATE_BUSY; + + /* Disable the TIM Peripheral Clock */ + __HAL_TIM_DISABLE(htim); + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + if (htim->HallSensor_MspDeInitCallback == NULL) + { + htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; + } + /* DeInit the low level hardware */ + htim->HallSensor_MspDeInitCallback(htim); +#else + /* DeInit the low level hardware: GPIO, CLOCK, NVIC */ + HAL_TIMEx_HallSensor_MspDeInit(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + /* Change the DMA burst operation state */ + htim->DMABurstState = HAL_DMA_BURST_STATE_RESET; + + /* Change the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_RESET); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_RESET); + + /* Change TIM state */ + htim->State = HAL_TIM_STATE_RESET; + + /* Release Lock */ + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Initializes the TIM Hall Sensor MSP. + * @param htim TIM Hall Sensor Interface handle + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file + */ +} + +/** + * @brief DeInitializes TIM Hall Sensor MSP. + * @param htim TIM Hall Sensor Interface handle + * @retval None + */ +__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file + */ +} + +/** + * @brief Starts the TIM Hall Sensor Interface. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall sensor Interface. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channels 1, 2 and 3 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in interrupt mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the capture compare Interrupts 1 event */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in interrupt mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + /* Disable the capture compare Interrupts event */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Hall Sensor Interface in DMA mode. + * @param htim TIM Hall Sensor Interface handle + * @param pData The destination Buffer address. + * @param Length The length of data to be transferred from TIM peripheral to memory. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length) +{ + uint32_t tmpsmcr; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Set the TIM channel state */ + if ((channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY) + || (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_BUSY)) + { + return HAL_BUSY; + } + else if ((channel_1_state == HAL_TIM_CHANNEL_STATE_READY) + && (complementary_channel_1_state == HAL_TIM_CHANNEL_STATE_READY)) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + /* Enable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE); + + /* Set the DMA Input Capture 1 Callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ; + + /* Enable the DMA channel for Capture 1*/ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the capture compare 1 Interrupt */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Hall Sensor Interface in DMA mode. + * @param htim TIM Hall Sensor Interface handle + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim) +{ + /* Check the parameters */ + assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance)); + + /* Disable the Input Capture channel 1 + (in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, + TIM_CHANNEL_2 and TIM_CHANNEL_3) */ + TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE); + + + /* Disable the capture compare Interrupts 1 event */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channel state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions + * @brief Timer Complementary Output Compare functions + * +@verbatim + ============================================================================== + ##### Timer Complementary Output Compare functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary Output Compare/PWM. + (+) Stop the Complementary Output Compare/PWM. + (+) Start the Complementary Output Compare/PWM and enable interrupts. + (+) Stop the Complementary Output Compare/PWM and disable interrupts. + (+) Start the Complementary Output Compare/PWM and enable DMA transfers. + (+) Stop the Complementary Output Compare/PWM and disable DMA transfers. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM Output Compare signal generation on the complementary + * output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM Output Compare signal generation on the complementary + * output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim TIM OC handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Output Compare interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in interrupt mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + tmpccer = htim->Instance->CCER; + if ((tmpccer & TIM_CCER_CCxNE_MASK) == (uint32_t)RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Set the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Output Compare DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM Output Compare signal generation in DMA mode + * on the complementary output. + * @param htim TIM Output Compare handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Output Compare DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the Capture compare channel N */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions + * @brief Timer Complementary PWM functions + * +@verbatim + ============================================================================== + ##### Timer Complementary PWM functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary PWM. + (+) Stop the Complementary PWM. + (+) Start the Complementary PWM and enable interrupts. + (+) Stop the Complementary PWM and disable interrupts. + (+) Start the Complementary PWM and enable DMA transfers. + (+) Stop the Complementary PWM and disable DMA transfers. +@endverbatim + * @{ + */ + +/** + * @brief Starts the PWM signal generation on the complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the PWM signal generation on the complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Check the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) != HAL_TIM_CHANNEL_STATE_READY) + { + return HAL_ERROR; + } + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Enable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the TIM Break interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK); + + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the PWM signal generation in interrupt mode on the + * complementary output. + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpccer; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the TIM Break interrupt (only if no more channel is active) */ + tmpccer = htim->Instance->CCER; + if ((tmpccer & TIM_CCER_CCxNE_MASK) == (uint32_t)RESET) + { + __HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK); + } + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @brief Starts the TIM PWM signal generation in DMA mode on the + * complementary output + * @param htim TIM handle + * @param Channel TIM Channel to be enabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @param pData The source Buffer address. + * @param Length The length of data to be transferred from memory to TIM peripheral + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, const uint32_t *pData, + uint16_t Length) +{ + HAL_StatusTypeDef status = HAL_OK; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + /* Set the TIM complementary channel state */ + if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_BUSY) + { + return HAL_BUSY; + } + else if (TIM_CHANNEL_N_STATE_GET(htim, Channel) == HAL_TIM_CHANNEL_STATE_READY) + { + if ((pData == NULL) || (Length == 0U)) + { + return HAL_ERROR; + } + else + { + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_BUSY); + } + } + else + { + return HAL_ERROR; + } + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1); + break; + } + + case TIM_CHANNEL_2: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2); + break; + } + + case TIM_CHANNEL_3: + { + /* Set the DMA compare callbacks */ + htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseNCplt; + htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt; + + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAErrorCCxN ; + + /* Enable the DMA channel */ + if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, + Length) != HAL_OK) + { + /* Return error status */ + return HAL_ERROR; + } + /* Enable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Enable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */ + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS; + if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr)) + { + __HAL_TIM_ENABLE(htim); + } + } + else + { + __HAL_TIM_ENABLE(htim); + } + } + + /* Return function status */ + return status; +} + +/** + * @brief Stops the TIM PWM signal generation in DMA mode on the complementary + * output + * @param htim TIM handle + * @param Channel TIM Channel to be disabled + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @arg TIM_CHANNEL_3: TIM Channel 3 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel) +{ + HAL_StatusTypeDef status = HAL_OK; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel)); + + switch (Channel) + { + case TIM_CHANNEL_1: + { + /* Disable the TIM Capture/Compare 1 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]); + break; + } + + case TIM_CHANNEL_2: + { + /* Disable the TIM Capture/Compare 2 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]); + break; + } + + case TIM_CHANNEL_3: + { + /* Disable the TIM Capture/Compare 3 DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3); + (void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]); + break; + } + + default: + status = HAL_ERROR; + break; + } + + if (status == HAL_OK) + { + /* Disable the complementary PWM output */ + TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM complementary channel state */ + TIM_CHANNEL_N_STATE_SET(htim, Channel, HAL_TIM_CHANNEL_STATE_READY); + } + + /* Return function status */ + return status; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions + * @brief Timer Complementary One Pulse functions + * +@verbatim + ============================================================================== + ##### Timer Complementary One Pulse functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Start the Complementary One Pulse generation. + (+) Stop the Complementary One Pulse. + (+) Start the Complementary One Pulse and enable interrupts. + (+) Stop the Complementary One Pulse and disable interrupts. + +@endverbatim + * @{ + */ + +/** + * @brief Starts the TIM One Pulse signal generation on the complementary + * output. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to enable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation on the complementary + * output. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to disable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Starts the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to enable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + HAL_TIM_ChannelStateTypeDef channel_1_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef channel_2_state = TIM_CHANNEL_STATE_GET(htim, TIM_CHANNEL_2); + HAL_TIM_ChannelStateTypeDef complementary_channel_1_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_1); + HAL_TIM_ChannelStateTypeDef complementary_channel_2_state = TIM_CHANNEL_N_STATE_GET(htim, TIM_CHANNEL_2); + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Check the TIM channels state */ + if ((channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (channel_2_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_1_state != HAL_TIM_CHANNEL_STATE_READY) + || (complementary_channel_2_state != HAL_TIM_CHANNEL_STATE_READY)) + { + return HAL_ERROR; + } + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_BUSY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_BUSY); + + /* Enable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1); + + /* Enable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2); + + /* Enable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_ENABLE); + + /* Enable the Main Output */ + __HAL_TIM_MOE_ENABLE(htim); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Stops the TIM One Pulse signal generation in interrupt mode on the + * complementary channel. + * @note OutputChannel must match the pulse output channel chosen when calling + * @ref HAL_TIM_OnePulse_ConfigChannel(). + * @param htim TIM One Pulse handle + * @param OutputChannel pulse output channel to disable + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 selected + * @arg TIM_CHANNEL_2: TIM Channel 2 selected + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel) +{ + uint32_t input_channel = (OutputChannel == TIM_CHANNEL_1) ? TIM_CHANNEL_2 : TIM_CHANNEL_1; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel)); + + /* Disable the TIM Capture/Compare 1 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1); + + /* Disable the TIM Capture/Compare 2 interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2); + + /* Disable the complementary One Pulse output channel and the Input Capture channel */ + TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE); + TIM_CCxChannelCmd(htim->Instance, input_channel, TIM_CCx_DISABLE); + + /* Disable the Main Output */ + __HAL_TIM_MOE_DISABLE(htim); + + /* Disable the Peripheral */ + __HAL_TIM_DISABLE(htim); + + /* Set the TIM channels state */ + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + + /* Return function status */ + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions + * @brief Peripheral Control functions + * +@verbatim + ============================================================================== + ##### Peripheral Control functions ##### + ============================================================================== + [..] + This section provides functions allowing to: + (+) Configure the commutation event in case of use of the Hall sensor interface. + (+) Configure Output channels for OC and PWM mode. + + (+) Configure Complementary channels, break features and dead time. + (+) Configure Master synchronization. + (+) Configure timer remapping capabilities. + +@endverbatim + * @{ + */ + +/** + * @brief Configure the TIM commutation event sequence. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Disable Commutation Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM); + + /* Disable Commutation DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with interrupt. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Disable Commutation DMA request */ + __HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM); + + /* Enable the Commutation Interrupt */ + __HAL_TIM_ENABLE_IT(htim, TIM_IT_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configure the TIM commutation event sequence with DMA. + * @note This function is mandatory to use the commutation event in order to + * update the configuration at each commutation detection on the TRGI input of the Timer, + * the typical use of this feature is with the use of another Timer(interface Timer) + * configured in Hall sensor interface, this interface Timer will generate the + * commutation at its TRGO output (connected to Timer used in this function) each time + * the TI1 of the Interface Timer detect a commutation at its input TI1. + * @note The user should configure the DMA in his own software, in This function only the COMDE bit is set + * @param htim TIM handle + * @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor + * This parameter can be one of the following values: + * @arg TIM_TS_ITR0: Internal trigger 0 selected + * @arg TIM_TS_ITR1: Internal trigger 1 selected + * @arg TIM_TS_ITR2: Internal trigger 2 selected + * @arg TIM_TS_ITR3: Internal trigger 3 selected + * @arg TIM_TS_NONE: No trigger is needed + * @param CommutationSource the Commutation Event source + * This parameter can be one of the following values: + * @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer + * @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger, + uint32_t CommutationSource) +{ + /* Check the parameters */ + assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance)); + assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger)); + + __HAL_LOCK(htim); + + if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) || + (InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3)) + { + /* Select the Input trigger */ + htim->Instance->SMCR &= ~TIM_SMCR_TS; + htim->Instance->SMCR |= InputTrigger; + } + + /* Select the Capture Compare preload feature */ + htim->Instance->CR2 |= TIM_CR2_CCPC; + /* Select the Commutation event source */ + htim->Instance->CR2 &= ~TIM_CR2_CCUS; + htim->Instance->CR2 |= CommutationSource; + + /* Enable the Commutation DMA Request */ + /* Set the DMA Commutation Callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt; + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt; + /* Set the DMA error callback */ + htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError; + + /* Disable Commutation Interrupt */ + __HAL_TIM_DISABLE_IT(htim, TIM_IT_COM); + + /* Enable the Commutation DMA Request */ + __HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM); + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIM in master mode. + * @param htim TIM handle. + * @param sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that + * contains the selected trigger output (TRGO) and the Master/Slave + * mode. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim, + const TIM_MasterConfigTypeDef *sMasterConfig) +{ + uint32_t tmpcr2; + uint32_t tmpsmcr; + + /* Check the parameters */ + assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance)); + assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger)); + assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode)); + + /* Check input state */ + __HAL_LOCK(htim); + + /* Change the handler state */ + htim->State = HAL_TIM_STATE_BUSY; + + /* Get the TIMx CR2 register value */ + tmpcr2 = htim->Instance->CR2; + + /* Get the TIMx SMCR register value */ + tmpsmcr = htim->Instance->SMCR; + + /* Reset the MMS Bits */ + tmpcr2 &= ~TIM_CR2_MMS; + /* Select the TRGO source */ + tmpcr2 |= sMasterConfig->MasterOutputTrigger; + + /* Update TIMx CR2 */ + htim->Instance->CR2 = tmpcr2; + + if (IS_TIM_SLAVE_INSTANCE(htim->Instance)) + { + /* Reset the MSM Bit */ + tmpsmcr &= ~TIM_SMCR_MSM; + /* Set master mode */ + tmpsmcr |= sMasterConfig->MasterSlaveMode; + + /* Update TIMx SMCR */ + htim->Instance->SMCR = tmpsmcr; + } + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State + * and the AOE(automatic output enable). + * @param htim TIM handle + * @param sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that + * contains the BDTR Register configuration information for the TIM peripheral. + * @note Interrupts can be generated when an active level is detected on the + * break input, the break 2 input or the system break input. Break + * interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim, + const TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig) +{ + /* Keep this variable initialized to 0 as it is used to configure BDTR register */ + uint32_t tmpbdtr = 0U; + + /* Check the parameters */ + assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance)); + assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode)); + assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode)); + assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel)); + assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime)); + assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState)); + assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity)); + assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput)); + + /* Check input state */ + __HAL_LOCK(htim); + + /* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State, + the OSSI State, the dead time value and the Automatic Output Enable Bit */ + + /* Set the BDTR bits */ + MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime); + MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode); + MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState); + MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity); + MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput); + + + /* Set TIMx_BDTR */ + htim->Instance->BDTR = tmpbdtr; + + __HAL_UNLOCK(htim); + + return HAL_OK; +} + +/** + * @brief Configures the TIMx Remapping input capabilities. + * @param htim TIM handle. + * @param Remap specifies the TIM remapping source. + * + * @retval HAL status + */ +HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + UNUSED(Remap); + + return HAL_OK; +} + +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions + * @brief Extended Callbacks functions + * +@verbatim + ============================================================================== + ##### Extended Callbacks functions ##### + ============================================================================== + [..] + This section provides Extended TIM callback functions: + (+) Timer Commutation callback + (+) Timer Break callback + +@endverbatim + * @{ + */ + +/** + * @brief Commutation callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_CommutCallback could be implemented in the user file + */ +} +/** + * @brief Commutation half complete callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file + */ +} + +/** + * @brief Break detection callback in non-blocking mode + * @param htim TIM handle + * @retval None + */ +__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim) +{ + /* Prevent unused argument(s) compilation warning */ + UNUSED(htim); + + /* NOTE : This function should not be modified, when the callback is needed, + the HAL_TIMEx_BreakCallback could be implemented in the user file + */ +} +/** + * @} + */ + +/** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions + * @brief Extended Peripheral State functions + * +@verbatim + ============================================================================== + ##### Extended Peripheral State functions ##### + ============================================================================== + [..] + This subsection permits to get in run-time the status of the peripheral + and the data flow. + +@endverbatim + * @{ + */ + +/** + * @brief Return the TIM Hall Sensor interface handle state. + * @param htim TIM Hall Sensor handle + * @retval HAL state + */ +HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(const TIM_HandleTypeDef *htim) +{ + return htim->State; +} + +/** + * @brief Return actual state of the TIM complementary channel. + * @param htim TIM handle + * @param ChannelN TIM Complementary channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @retval TIM Complementary channel state + */ +HAL_TIM_ChannelStateTypeDef HAL_TIMEx_GetChannelNState(const TIM_HandleTypeDef *htim, uint32_t ChannelN) +{ + HAL_TIM_ChannelStateTypeDef channel_state; + + /* Check the parameters */ + assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, ChannelN)); + + channel_state = TIM_CHANNEL_N_STATE_GET(htim, ChannelN); + + return channel_state; +} +/** + * @} + */ + +/** + * @} + */ + +/* Private functions ---------------------------------------------------------*/ +/** @defgroup TIMEx_Private_Functions TIM Extended Private Functions + * @{ + */ + +/** + * @brief TIM DMA Commutation callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationCallback(htim); +#else + HAL_TIMEx_CommutCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + +/** + * @brief TIM DMA Commutation half complete callback. + * @param hdma pointer to DMA handle. + * @retval None + */ +void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + /* Change the htim state */ + htim->State = HAL_TIM_STATE_READY; + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->CommutationHalfCpltCallback(htim); +#else + HAL_TIMEx_CommutHalfCpltCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ +} + + +/** + * @brief TIM DMA Delay Pulse complete callback (complementary channel). + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMADelayPulseNCplt(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + + if (hdma->Init.Mode == DMA_NORMAL) + { + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->PWM_PulseFinishedCallback(htim); +#else + HAL_TIM_PWM_PulseFinishedCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief TIM DMA error callback (complementary channel) + * @param hdma pointer to DMA handle. + * @retval None + */ +static void TIM_DMAErrorCCxN(DMA_HandleTypeDef *hdma) +{ + TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; + + if (hdma == htim->hdma[TIM_DMA_ID_CC1]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1; + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_1, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC2]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2; + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_2, HAL_TIM_CHANNEL_STATE_READY); + } + else if (hdma == htim->hdma[TIM_DMA_ID_CC3]) + { + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3; + TIM_CHANNEL_N_STATE_SET(htim, TIM_CHANNEL_3, HAL_TIM_CHANNEL_STATE_READY); + } + else + { + /* nothing to do */ + } + +#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1) + htim->ErrorCallback(htim); +#else + HAL_TIM_ErrorCallback(htim); +#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */ + + htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED; +} + +/** + * @brief Enables or disables the TIM Capture Compare Channel xN. + * @param TIMx to select the TIM peripheral + * @param Channel specifies the TIM Channel + * This parameter can be one of the following values: + * @arg TIM_CHANNEL_1: TIM Channel 1 + * @arg TIM_CHANNEL_2: TIM Channel 2 + * @arg TIM_CHANNEL_3: TIM Channel 3 + * @param ChannelNState specifies the TIM Channel CCxNE bit new state. + * This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable. + * @retval None + */ +static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState) +{ + uint32_t tmp; + + tmp = TIM_CCER_CC1NE << (Channel & 0xFU); /* 0xFU = 15 bits max shift */ + + /* Reset the CCxNE Bit */ + TIMx->CCER &= ~tmp; + + /* Set or reset the CCxNE Bit */ + TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0xFU)); /* 0xFU = 15 bits max shift */ +} +/** + * @} + */ + +#endif /* HAL_TIM_MODULE_ENABLED */ +/** + * @} + */ + +/** + * @} + */ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6.uvprojx b/STM32F103C8T6/MDK-ARM/STM32F103C8T6.uvprojx index ccc8d00..aae044e 100644 --- a/STM32F103C8T6/MDK-ARM/STM32F103C8T6.uvprojx +++ b/STM32F103C8T6/MDK-ARM/STM32F103C8T6.uvprojx @@ -190,7 +190,7 @@ 0 0 8 - 1 + 0 0 0 0 @@ -340,7 +340,7 @@ USE_HAL_DRIVER,STM32F103xB - ../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP/MultiButton;..\Drivers\BSP\LCD + ../Core/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc;../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F1xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP/MultiButton;../Drivers/BSP/LCD @@ -404,6 +404,62 @@ 1 ../Core/Src/gpio.c + + adc.c + 1 + ../Core/Src/adc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + dma.c 1 @@ -516,6 +572,62 @@ + + tim.c + 1 + ../Core/Src/tim.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + usart.c 1 @@ -542,9 +654,65 @@ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_gpio_ex.c - stm32f1xx_hal_spi.c + stm32f1xx_hal_adc.c 1 - ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + stm32f1xx_hal_adc_ex.c + 1 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_adc_ex.c 2 @@ -647,6 +815,174 @@ 1 ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_exti.c + + stm32f1xx_hal_spi.c + 1 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + stm32f1xx_hal_tim.c + 1 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + stm32f1xx_hal_tim_ex.c + 1 + ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_tim_ex.c + + + 2 + 0 + 0 + 0 + 0 + 1 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + stm32f1xx_hal_uart.c 1 @@ -672,6 +1008,16 @@ 1 ..\Drivers\BSP\LCD\lcd_data.c + + hz16_data.c + 1 + ..\Drivers\BSP\LCD\hz16_data.c + + + lcd.c + 1 + ..\Drivers\BSP\LCD\lcd.c + st7735s.c 1 diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/STM32F103C8T6.lnp b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/STM32F103C8T6.lnp index c1e6e3e..3e1b0be 100644 --- a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/STM32F103C8T6.lnp +++ b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/STM32F103C8T6.lnp @@ -2,13 +2,16 @@ "stm32f103c8t6\startup_stm32f103xb.o" "stm32f103c8t6\main.o" "stm32f103c8t6\gpio.o" +"stm32f103c8t6\adc.o" "stm32f103c8t6\dma.o" "stm32f103c8t6\spi.o" +"stm32f103c8t6\tim.o" "stm32f103c8t6\usart.o" "stm32f103c8t6\stm32f1xx_it.o" "stm32f103c8t6\stm32f1xx_hal_msp.o" "stm32f103c8t6\stm32f1xx_hal_gpio_ex.o" -"stm32f103c8t6\stm32f1xx_hal_spi.o" +"stm32f103c8t6\stm32f1xx_hal_adc.o" +"stm32f103c8t6\stm32f1xx_hal_adc_ex.o" "stm32f103c8t6\stm32f1xx_hal.o" "stm32f103c8t6\stm32f1xx_hal_rcc.o" "stm32f103c8t6\stm32f1xx_hal_rcc_ex.o" @@ -19,13 +22,18 @@ "stm32f103c8t6\stm32f1xx_hal_flash.o" "stm32f103c8t6\stm32f1xx_hal_flash_ex.o" "stm32f103c8t6\stm32f1xx_hal_exti.o" +"stm32f103c8t6\stm32f1xx_hal_spi.o" +"stm32f103c8t6\stm32f1xx_hal_tim.o" +"stm32f103c8t6\stm32f1xx_hal_tim_ex.o" "stm32f103c8t6\stm32f1xx_hal_uart.o" "stm32f103c8t6\system_stm32f1xx.o" "stm32f103c8t6\lcd_data.o" +"stm32f103c8t6\hz16_data.o" +"stm32f103c8t6\lcd.o" "stm32f103c8t6\st7735s_1.o" "stm32f103c8t6\button_driver_1.o" "stm32f103c8t6\multi_button_1.o" ---library_type=microlib --strict --scatter "STM32F103C8T6\STM32F103C8T6.sct" +--strict --scatter "STM32F103C8T6\STM32F103C8T6.sct" --summary_stderr --info summarysizes --map --load_addr_map_info --xref --callgraph --symbols --info sizes --info totals --info unused --info veneers --list "STM32F103C8T6.map" -o STM32F103C8T6\STM32F103C8T6.axf \ No newline at end of file diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/adc.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/adc.crf new file mode 100644 index 0000000..ee1ac94 Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/adc.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/button_driver_1.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/button_driver_1.crf index 5d4dd55..26f5229 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/button_driver_1.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/button_driver_1.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/dma.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/dma.crf index 323500e..67f79a5 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/dma.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/dma.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/gpio.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/gpio.crf index d774b22..377f16e 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/gpio.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/gpio.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/hz16_data.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/hz16_data.crf new file mode 100644 index 0000000..61d213b Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/hz16_data.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/lcd.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/lcd.crf new file mode 100644 index 0000000..53a686b Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/lcd.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/lcd_data.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/lcd_data.crf index 180fde2..24b2158 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/lcd_data.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/lcd_data.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/main.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/main.crf index a1f85b6..c8d6809 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/main.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/main.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/multi_button_1.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/multi_button_1.crf index bba2cb2..93eca20 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/multi_button_1.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/multi_button_1.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/spi.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/spi.crf index 16193bb..e482f92 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/spi.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/spi.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/st7735s_1.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/st7735s_1.crf index af2a3ba..bd317a6 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/st7735s_1.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/st7735s_1.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal.crf index c6955bb..0ac30f3 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_adc.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_adc.crf new file mode 100644 index 0000000..f94d9c7 Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_adc.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_adc_ex.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_adc_ex.crf new file mode 100644 index 0000000..d9205f4 Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_adc_ex.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_cortex.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_cortex.crf index f5b003e..6bf2b87 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_cortex.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_cortex.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_dma.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_dma.crf index c8c3d09..b0316c5 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_dma.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_dma.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_exti.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_exti.crf index bac9ade..90f7beb 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_exti.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_exti.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash.crf index 6c0e2af..51a1a9d 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash_ex.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash_ex.crf index 7622ae8..929109e 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash_ex.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_flash_ex.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio.crf index 62a3834..e4020b6 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio_ex.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio_ex.crf index 5099039..719fdc4 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio_ex.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_gpio_ex.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_msp.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_msp.crf index 247432d..0749244 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_msp.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_msp.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_pwr.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_pwr.crf index 0ac4f66..c7fc05e 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_pwr.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_pwr.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc.crf index 1b745ca..3f23431 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc_ex.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc_ex.crf index 1c4c153..1cd24de 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc_ex.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_rcc_ex.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_spi.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_spi.crf index 6b62bd1..b8267b7 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_spi.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_spi.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_tim.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_tim.crf new file mode 100644 index 0000000..6a3c35b Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_tim.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_tim_ex.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_tim_ex.crf new file mode 100644 index 0000000..bafa8be Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_tim_ex.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_uart.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_uart.crf index 02c0a3f..4daf479 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_uart.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_hal_uart.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_it.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_it.crf index e2be534..9f9e379 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_it.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/stm32f1xx_it.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/system_stm32f1xx.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/system_stm32f1xx.crf index 492136a..dc9e29d 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/system_stm32f1xx.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/system_stm32f1xx.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/tim.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/tim.crf new file mode 100644 index 0000000..3f92301 Binary files /dev/null and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/tim.crf differ diff --git a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/usart.crf b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/usart.crf index 205c92c..c44f525 100644 Binary files a/STM32F103C8T6/MDK-ARM/STM32F103C8T6/usart.crf and b/STM32F103C8T6/MDK-ARM/STM32F103C8T6/usart.crf differ diff --git a/STM32F103C8T6/STM32F103C8T6.ioc b/STM32F103C8T6/STM32F103C8T6.ioc index 82ec7cf..1c93894 100644 --- a/STM32F103C8T6/STM32F103C8T6.ioc +++ b/STM32F103C8T6/STM32F103C8T6.ioc @@ -1,4 +1,29 @@ #MicroXplorer Configuration settings - do not modify +ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_0 +ADC1.Channel-1\#ChannelInjectedConversion=ADC_CHANNEL_0 +ADC1.Channel-2\#ChannelInjectedConversion=ADC_CHANNEL_1 +ADC1.Channel-3\#ChannelInjectedConversion=ADC_CHANNEL_2 +ADC1.Channel-4\#ChannelInjectedConversion=ADC_CHANNEL_3 +ADC1.EnableInjectedConversion=ENABLE +ADC1.ExternalTrigInjecConv=ADC_EXTERNALTRIGINJECCONV_T3_CC4 +ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master,EnableInjectedConversion,InjectedRank-1\#ChannelInjectedConversion,Channel-1\#ChannelInjectedConversion,SamplingTime-1\#ChannelInjectedConversion,InjectedOffset-1\#ChannelInjectedConversion,InjectedRank-2\#ChannelInjectedConversion,Channel-2\#ChannelInjectedConversion,SamplingTime-2\#ChannelInjectedConversion,InjectedOffset-2\#ChannelInjectedConversion,InjectedRank-3\#ChannelInjectedConversion,Channel-3\#ChannelInjectedConversion,SamplingTime-3\#ChannelInjectedConversion,InjectedOffset-3\#ChannelInjectedConversion,InjectedRank-4\#ChannelInjectedConversion,Channel-4\#ChannelInjectedConversion,SamplingTime-4\#ChannelInjectedConversion,InjectedOffset-4\#ChannelInjectedConversion,InjNumberOfConversion,ExternalTrigInjecConv +ADC1.InjNumberOfConversion=4 +ADC1.InjectedOffset-1\#ChannelInjectedConversion=0 +ADC1.InjectedOffset-2\#ChannelInjectedConversion=0 +ADC1.InjectedOffset-3\#ChannelInjectedConversion=0 +ADC1.InjectedOffset-4\#ChannelInjectedConversion=0 +ADC1.InjectedRank-1\#ChannelInjectedConversion=1 +ADC1.InjectedRank-2\#ChannelInjectedConversion=2 +ADC1.InjectedRank-3\#ChannelInjectedConversion=3 +ADC1.InjectedRank-4\#ChannelInjectedConversion=4 +ADC1.NbrOfConversionFlag=1 +ADC1.Rank-0\#ChannelRegularConversion=1 +ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_1CYCLE_5 +ADC1.SamplingTime-1\#ChannelInjectedConversion=ADC_SAMPLETIME_41CYCLES_5 +ADC1.SamplingTime-2\#ChannelInjectedConversion=ADC_SAMPLETIME_41CYCLES_5 +ADC1.SamplingTime-3\#ChannelInjectedConversion=ADC_SAMPLETIME_41CYCLES_5 +ADC1.SamplingTime-4\#ChannelInjectedConversion=ADC_SAMPLETIME_41CYCLES_5 +ADC1.master=1 CAD.formats= CAD.pinconfig= CAD.provider= @@ -18,34 +43,48 @@ GPIO.groupedBy=Group By Peripherals KeepUserPlacement=false Mcu.CPN=STM32F103C8T6 Mcu.Family=STM32F1 -Mcu.IP0=DMA -Mcu.IP1=NVIC -Mcu.IP2=RCC -Mcu.IP3=SPI2 -Mcu.IP4=SYS -Mcu.IP5=USART1 -Mcu.IPNb=6 +Mcu.IP0=ADC1 +Mcu.IP1=DMA +Mcu.IP2=NVIC +Mcu.IP3=RCC +Mcu.IP4=SPI2 +Mcu.IP5=SYS +Mcu.IP6=TIM3 +Mcu.IP7=TIM4 +Mcu.IP8=USART1 +Mcu.IPNb=9 Mcu.Name=STM32F103C(8-B)Tx Mcu.Package=LQFP48 Mcu.Pin0=PC13-TAMPER-RTC Mcu.Pin1=PC14-OSC32_IN -Mcu.Pin10=PA9 -Mcu.Pin11=PA10 -Mcu.Pin12=PA13 -Mcu.Pin13=PA14 -Mcu.Pin14=PB3 -Mcu.Pin15=PB4 -Mcu.Pin16=PB5 -Mcu.Pin17=VP_SYS_VS_Systick +Mcu.Pin10=PB11 +Mcu.Pin11=PB12 +Mcu.Pin12=PB13 +Mcu.Pin13=PB15 +Mcu.Pin14=PA9 +Mcu.Pin15=PA10 +Mcu.Pin16=PA13 +Mcu.Pin17=PA14 +Mcu.Pin18=PB3 +Mcu.Pin19=PB4 Mcu.Pin2=PC15-OSC32_OUT +Mcu.Pin20=PB5 +Mcu.Pin21=PB6 +Mcu.Pin22=PB7 +Mcu.Pin23=PB8 +Mcu.Pin24=PB9 +Mcu.Pin25=VP_SYS_VS_Systick +Mcu.Pin26=VP_TIM3_VS_ClockSourceINT +Mcu.Pin27=VP_TIM3_VS_no_output4 +Mcu.Pin28=VP_TIM4_VS_ClockSourceINT Mcu.Pin3=PD0-OSC_IN Mcu.Pin4=PD1-OSC_OUT -Mcu.Pin5=PB10 -Mcu.Pin6=PB11 -Mcu.Pin7=PB12 -Mcu.Pin8=PB13 -Mcu.Pin9=PB15 -Mcu.PinsNb=18 +Mcu.Pin5=PA0-WKUP +Mcu.Pin6=PA1 +Mcu.Pin7=PA2 +Mcu.Pin8=PA3 +Mcu.Pin9=PB10 +Mcu.PinsNb=29 Mcu.ThirdPartyNb=0 Mcu.UserConstants= Mcu.UserName=STM32F103C8Tx @@ -63,12 +102,20 @@ NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false +PA0-WKUP.Locked=true +PA0-WKUP.Signal=ADCx_IN0 +PA1.Locked=true +PA1.Signal=ADCx_IN1 PA10.Mode=Asynchronous PA10.Signal=USART1_RX PA13.Mode=Serial_Wire PA13.Signal=SYS_JTMS-SWDIO PA14.Mode=Serial_Wire PA14.Signal=SYS_JTCK-SWCLK +PA2.Locked=true +PA2.Signal=ADCx_IN2 +PA3.Locked=true +PA3.Signal=ADCx_IN3 PA9.Mode=Asynchronous PA9.Signal=USART1_TX PB10.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label @@ -111,6 +158,14 @@ PB5.GPIO_Label=KEY2 PB5.GPIO_PuPd=GPIO_PULLDOWN PB5.Locked=true PB5.Signal=GPIO_Input +PB6.Locked=true +PB6.Signal=S_TIM4_CH1 +PB7.Locked=true +PB7.Signal=S_TIM4_CH2 +PB8.Locked=true +PB8.Signal=S_TIM4_CH3 +PB9.Locked=true +PB9.Signal=S_TIM4_CH4 PC13-TAMPER-RTC.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label PC13-TAMPER-RTC.GPIO_Label=LED PC13-TAMPER-RTC.GPIO_PuPd=GPIO_PULLUP @@ -173,7 +228,7 @@ ProjectManager.ToolChainLocation= ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptBeforePath= ProjectManager.UnderRoot=false -ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true +ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_SPI2_Init-SPI2-false-HAL-true,6-MX_TIM4_Init-TIM4-false-HAL-true,7-MX_ADC1_Init-ADC1-false-HAL-true,8-MX_TIM3_Init-TIM3-false-HAL-true RCC.ADCFreqValue=36000000 RCC.AHBFreq_Value=72000000 RCC.APB1CLKDivider=RCC_HCLK_DIV2 @@ -195,14 +250,55 @@ RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK RCC.TimSysFreq_Value=72000000 RCC.USBFreq_Value=72000000 RCC.VCOOutput2Freq_Value=8000000 +SH.ADCx_IN0.0=ADC1_IN0,IN0 +SH.ADCx_IN0.ConfNb=1 +SH.ADCx_IN1.0=ADC1_IN1,IN1 +SH.ADCx_IN1.ConfNb=1 +SH.ADCx_IN2.0=ADC1_IN2,IN2 +SH.ADCx_IN2.ConfNb=1 +SH.ADCx_IN3.0=ADC1_IN3,IN3 +SH.ADCx_IN3.ConfNb=1 +SH.S_TIM4_CH1.0=TIM4_CH1,PWM Generation1 CH1 +SH.S_TIM4_CH1.ConfNb=1 +SH.S_TIM4_CH2.0=TIM4_CH2,PWM Generation2 CH2 +SH.S_TIM4_CH2.ConfNb=1 +SH.S_TIM4_CH3.0=TIM4_CH3,PWM Generation3 CH3 +SH.S_TIM4_CH3.ConfNb=1 +SH.S_TIM4_CH4.0=TIM4_CH4,PWM Generation4 CH4 +SH.S_TIM4_CH4.ConfNb=1 SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2 +SPI2.CLKPhase=SPI_PHASE_2EDGE +SPI2.CLKPolarity=SPI_POLARITY_HIGH SPI2.CalculateBaudRate=18.0 MBits/s SPI2.Direction=SPI_DIRECTION_2LINES -SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler +SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,CLKPolarity,CLKPhase SPI2.Mode=SPI_MODE_MASTER SPI2.VirtualType=VM_MASTER +TIM3.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM3.Channel-PWM\ Generation4\ No\ Output=TIM_CHANNEL_4 +TIM3.IPParameters=Prescaler,Period,AutoReloadPreload,Channel-PWM Generation4 No Output,Pulse-PWM Generation4 No Output +TIM3.Period=999 +TIM3.Prescaler=71 +TIM3.Pulse-PWM\ Generation4\ No\ Output=500 +TIM4.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE +TIM4.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1 +TIM4.Channel-PWM\ Generation2\ CH2=TIM_CHANNEL_2 +TIM4.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3 +TIM4.Channel-PWM\ Generation4\ CH4=TIM_CHANNEL_4 +TIM4.IPParameters=Prescaler,Period,AutoReloadPreload,Channel-PWM Generation1 CH1,Channel-PWM Generation2 CH2,Channel-PWM Generation3 CH3,Channel-PWM Generation4 CH4,Pulse-PWM Generation4 CH4,Pulse-PWM Generation1 CH1,Pulse-PWM Generation2 CH2 +TIM4.Period=999 +TIM4.Prescaler=71 +TIM4.Pulse-PWM\ Generation1\ CH1=500 +TIM4.Pulse-PWM\ Generation2\ CH2=500 +TIM4.Pulse-PWM\ Generation4\ CH4=500 USART1.IPParameters=VirtualMode USART1.VirtualMode=VM_ASYNC VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Signal=SYS_VS_Systick +VP_TIM3_VS_ClockSourceINT.Mode=Internal +VP_TIM3_VS_ClockSourceINT.Signal=TIM3_VS_ClockSourceINT +VP_TIM3_VS_no_output4.Mode=PWM Generation4 No Output +VP_TIM3_VS_no_output4.Signal=TIM3_VS_no_output4 +VP_TIM4_VS_ClockSourceINT.Mode=Internal +VP_TIM4_VS_ClockSourceINT.Signal=TIM4_VS_ClockSourceINT board=custom diff --git a/tools/font_gen.py b/tools/font_gen.py new file mode 100644 index 0000000..ede0ffb --- /dev/null +++ b/tools/font_gen.py @@ -0,0 +1,394 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +STM32 ST7735S LCD 字模生成工具(Pillow 版) +- ASCII 8×16:生成 lcd_data.c +- CJK 16×16:生成 hz16_data.c + hz16_data.h(含二分查找函数) + +用法: + # ASCII + python font_gen.py --font simsun --size 56 --threshold 64 + + # CJK 常用汉字(GB2312 一级,约 3755 字) + python font_gen.py --cjk --font simsun --size 32 --threshold 64 + + # CJK + 标点 + python font_gen.py --cjk --punct +""" + +import os +import sys +import argparse +import struct + +try: + from PIL import Image, ImageFont, ImageDraw +except ImportError: + print("请安装 Pillow: pip install Pillow", file=sys.stderr) + sys.exit(1) + +# ── 通用渲染 ── + +def render_char(font, char: str, w: int, h: int, scale: int = 1, + threshold: int = 64) -> list: + """ + 在 w*scale × h*scale 画布上渲染字符,缩放到 w×h + 返回逐行字节列表(MSB 优先) + """ + bw, bh = w * scale, h * scale + img = Image.new("L", (bw, bh), 0) + draw = ImageDraw.Draw(img) + + bbox = draw.textbbox((0, 0), char, font=font) + tw = bbox[2] - bbox[0] + th = bbox[3] - bbox[1] + cx = (bw - tw) // 2 - bbox[0] + cy = (bh - th) // 2 - bbox[1] + draw.text((cx, cy), char, font=font, fill=255) + + small = img.resize((w, h), Image.LANCZOS) + pixels = list(small.getdata()) + + bytes_per_row = (w + 7) // 8 + result = [] + for r in range(h): + for br in range(bytes_per_row): + byte_val = 0 + for c in range(8): + col = br * 8 + c + if col < w and pixels[r * w + col] >= threshold: + byte_val |= (1 << (7 - c)) + result.append(byte_val) + return result + + +# ── ASCII 8×16 ── + +def generate_ascii(output_path: str, font_path: str, size: int, + threshold: int, scale: int = 4): + font = ImageFont.truetype(font_path, size) + chars = list(range(32, 127)) + N = len(chars) + + lines = [ + '#include "lcd_data.h"', + '/*ASCII字模数据*********************/', + '', + '/*宽8像素,高16像素*/', + f'/* 字体: {os.path.basename(font_path)}, 字号: {size}, 阈值: {threshold} */', + 'const uint8_t LCD_F8x16[][16] =', + '{', + ] + + for idx, ch in enumerate(chars): + if ch == ord('_'): + bitmap = [0x00] * 15 + [0x7F] + else: + bitmap = render_char(font, chr(ch), 8, 16, scale, threshold) + + show = chr(ch) if 32 <= ch <= 126 else '?' + comma = ',' if idx < N - 1 else '' + line1 = ', '.join(f'0x{b:02X}' for b in bitmap[:8]) + line2 = ', '.join(f'0x{b:02X}' for b in bitmap[8:]) + lines.append(f' {line1},') + lines.append(f' {line2}{comma} // {show} {idx}') + if (idx + 1) % 10 == 0: + print(f" ASCII 进度: {idx+1}/{N}") + + lines.append('};') + lines.append('') + lines.append('/*宽6像素,高8像素(未使用)*/') + lines.append('const uint8_t LCD_F6x8[][6] =') + lines.append('{') + for idx, ch in enumerate(chars): + show = chr(ch) if 32 <= ch <= 126 else '?' + comma = ',' if idx < N - 1 else '' + lines.append(f' 0x00,0x00,0x00,0x00,0x00,0x00{comma} // {show} {idx}') + lines.append('};') + lines.append('') + + content = '\n'.join(lines) + with open(output_path, 'w', encoding='utf-8', newline='\n') as f: + f.write(content) + print(f"已生成 ASCII 字模: {output_path}") + + +# ── CJK 16×16 ── + +CJK_W, CJK_H = 16, 16 +CJK_BYTES = CJK_H * ((CJK_W + 7) // 8) # 32 + + +def get_gb2312_level1_unicodes(): + """GB2312 一级汉字(常用 ~3755 字)的 Unicode 码点""" + out = [] + for u in range(0x4E00, 0x9FA6): + try: + b = chr(u).encode("gb2312") + if len(b) == 2: + qu = b[0] - 0xA1 + if 16 <= qu <= 55: + out.append(u) + except (UnicodeEncodeError, LookupError): + pass + return out + + +def get_gb2312_all_unicodes(): + """GB2312 全部汉字(一级+二级 ~6763 字)""" + out = [] + for u in range(0x4E00, 0x9FA6): + try: + b = chr(u).encode("gb2312") + if len(b) == 2: + out.append(u) + except (UnicodeEncodeError, LookupError): + pass + return out + + +CJK_PUNCTUATION = [ + 0x00B7, 0x2014, 0x2018, 0x2019, 0x201C, 0x201D, 0x2026, + 0x3000, 0x3001, 0x3002, 0x300A, 0x300B, 0x300C, 0x300D, + 0x300E, 0x300F, 0x3010, 0x3011, 0x3014, 0x3015, + 0xFF01, 0xFF02, 0xFF07, 0xFF08, 0xFF09, 0xFF0C, 0xFF0E, + 0xFF1A, 0xFF1B, 0xFF1F, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D, +] + +CJK_FULLWIDTH_ASCII = list(range(0xFF01, 0xFF5F)) # 全角 ASCII + + +def generate_cjk(base_path: str, font_path: str, size: int, + threshold: int, scale: int = 2, + mode: str = 'common', punct: bool = False): + """生成 CJK 16×16 字库 .c + .h""" + + font = ImageFont.truetype(font_path, size) + + if mode == 'common': + unicodes = get_gb2312_level1_unicodes() + print(f"CJK 范围: GB2312 一级汉字 ({len(unicodes)} 字)") + elif mode == 'gb2312': + unicodes = get_gb2312_all_unicodes() + print(f"CJK 范围: GB2312 全部汉字 ({len(unicodes)} 字)") + else: + unicodes = [] + print("CJK 范围: 无") + + if punct: + extra = set(CJK_PUNCTUATION) | set(CJK_FULLWIDTH_ASCII) + unicodes = sorted(set(unicodes) | extra) + print(f"已加入 {len(extra)} 个中文标点/全角字符") + + if not unicodes: + print("未指定 CJK 范围,使用默认字符") + unicodes = [ord(c) for c in "你好世界一二三"] + + unicodes = sorted(set(unicodes)) + N = len(unicodes) + + # 渲染 + bitmaps = [] + for i, u in enumerate(unicodes): + ch = chr(u) + bm = render_char(font, ch, CJK_W, CJK_H, scale, threshold) + bitmaps.append(bm) + if (i + 1) % 500 == 0: + print(f" CJK 进度: {i+1}/{N}") + + # ── 写 .c ── + c_path = base_path + ".c" + h_path = base_path + ".h" + name_base = os.path.basename(base_path) + guard = name_base.upper().replace(".", "_").replace("-", "_") + "_H" + + with open(c_path, 'w', encoding='utf-8', newline='\n') as f: + f.write(f'/* 16×16 CJK 字库,由 font_gen.py 生成 */\n\n') + f.write(f'#include "{name_base}.h"\n\n') + f.write(f'static const uint8_t cjk_bitmaps[][{CJK_BYTES}] = {{\n') + for u, bm in zip(unicodes, bitmaps): + hex_str = ', '.join(f'0x{x:02X}' for x in bm) + try: + comment = f' /* U+{u:04X} {chr(u)} */' + except: + comment = f' /* U+{u:04X} */' + f.write(f' {{ {hex_str} }},{comment}\n') + f.write('};\n\n') + + f.write(f'static const uint16_t cjk_unicodes[{N}] = {{\n') + for i in range(0, N, 16): + chunk = unicodes[i:i+16] + f.write(' ' + ', '.join(f'0x{u:04X}' for u in chunk) + ',\n') + f.write('};\n\n') + + f.write(f'const uint8_t* cjk_get_bitmap(uint16_t unicode)\n') + f.write('{\n') + f.write(f' int lo = 0, hi = {N};\n') + f.write(' while (lo < hi) {\n') + f.write(' int mid = (lo + hi) >> 1;\n') + f.write(' if (cjk_unicodes[mid] < unicode) lo = mid + 1;\n') + f.write(' else if (cjk_unicodes[mid] > unicode) hi = mid;\n') + f.write(' else return cjk_bitmaps[mid];\n') + f.write(' }\n') + f.write(' return (const uint8_t*)0;\n') + f.write('}\n') + + print(f'已生成: {c_path}') + + # ── 写 .h ── + with open(h_path, 'w', encoding='utf-8', newline='\n') as f: + f.write(f'/* 16×16 CJK 字库,由 font_gen.py 生成 */\n\n') + f.write(f'#ifndef {guard}\n#define {guard}\n\n') + f.write(f'#include \n\n') + f.write(f'#define CJK_BYTES_PER_CHAR {CJK_BYTES}\n') + f.write(f'#define CJK_WIDTH {CJK_W}\n') + f.write(f'#define CJK_HEIGHT {CJK_H}\n') + f.write(f'#define CJK_NUM_CHARS {N}\n\n') + f.write(f'/* 按 Unicode 码点查找 16×16 点阵,返回 {CJK_BYTES} 字节,未找到返回 NULL */\n') + f.write(f'const uint8_t* cjk_get_bitmap(uint16_t unicode);\n\n') + f.write(f'#endif /* {guard} */\n') + + print(f'已生成: {h_path}') + + +def generate_cjk_direct(base_path: str, font_path: str, size: int, + threshold: int, scale: int, + unicodes: list): + """用指定的 Unicode 列表生成 CJK 字库""" + font = ImageFont.truetype(font_path, size) + N = len(unicodes) + + print(f"CJK 自定义字符: {N} 字: {''.join(chr(u) for u in unicodes[:50])}{'...' if N > 50 else ''}") + + bitmaps = [] + for i, u in enumerate(unicodes): + bm = render_char(font, chr(u), CJK_W, CJK_H, scale, threshold) + bitmaps.append(bm) + + # ── 写 .c ── + c_path = base_path + ".c" + h_path = base_path + ".h" + name_base = os.path.basename(base_path) + guard = name_base.upper().replace(".", "_").replace("-", "_") + "_H" + + with open(c_path, 'w', encoding='utf-8', newline='\n') as f: + f.write(f'/* 16×16 CJK 字库,由 font_gen.py 生成(自定义) */\n\n') + f.write(f'#include "{name_base}.h"\n\n') + f.write(f'static const uint8_t cjk_bitmaps[][{CJK_BYTES}] = {{\n') + for u, bm in zip(unicodes, bitmaps): + hex_str = ', '.join(f'0x{x:02X}' for x in bm) + f.write(f' {{ {hex_str} }}, /* U+{u:04X} {chr(u)} */\n') + f.write('};\n\n') + + f.write(f'static const uint16_t cjk_unicodes[{N}] = {{\n') + for i in range(0, N, 16): + chunk = unicodes[i:i+16] + f.write(' ' + ', '.join(f'0x{u:04X}' for u in chunk) + ',\n') + f.write('};\n\n') + + f.write(f'const uint8_t* cjk_get_bitmap(uint16_t unicode)\n') + f.write('{\n') + f.write(f' int lo = 0, hi = {N};\n') + f.write(' while (lo < hi) {\n') + f.write(' int mid = (lo + hi) >> 1;\n') + f.write(' if (cjk_unicodes[mid] < unicode) lo = mid + 1;\n') + f.write(' else if (cjk_unicodes[mid] > unicode) hi = mid;\n') + f.write(' else return cjk_bitmaps[mid];\n') + f.write(' }\n') + f.write(' return (const uint8_t*)0;\n') + f.write('}\n') + + print(f'已生成: {c_path}') + + # ── 写 .h ── + with open(h_path, 'w', encoding='utf-8', newline='\n') as f: + f.write(f'/* 16×16 CJK 字库,由 font_gen.py 生成(自定义) */\n\n') + f.write(f'#ifndef {guard}\n#define {guard}\n\n') + f.write(f'#include \n\n') + f.write(f'#define CJK_BYTES_PER_CHAR {CJK_BYTES}\n') + f.write(f'#define CJK_WIDTH {CJK_W}\n') + f.write(f'#define CJK_HEIGHT {CJK_H}\n') + f.write(f'#define CJK_NUM_CHARS {N}\n\n') + f.write(f'const uint8_t* cjk_get_bitmap(uint16_t unicode);\n\n') + f.write(f'#endif /* {guard} */\n') + + print(f'已生成: {h_path}') + + +# ── 主入口 ── + +def _resolve_font(name_or_path: str) -> str: + if os.path.isfile(name_or_path): + return name_or_path + font_dir = r'C:\Windows\Fonts' + key = name_or_path.lower() + known = { + 'consolas': 'consola.ttf', 'arial': 'arial.ttf', + 'tahoma': 'tahoma.ttf', 'simsun': 'simsun.ttc', + 'songti': 'simsun.ttc', '宋体': 'simsun.ttc', + 'simhei': 'simhei.ttf', '黑体': 'simhei.ttf', + 'yahei': 'msyh.ttc', '微软雅黑': 'msyh.ttc', + } + if key in known: + full = os.path.join(font_dir, known[key]) + if os.path.isfile(full): + return full + for f in os.listdir(font_dir): + if f.lower().startswith(key) and f.lower().endswith(('.ttf', '.ttc')): + return os.path.join(font_dir, f) + # fallback + fallback = os.path.join(font_dir, 'simsun.ttc') + if os.path.isfile(fallback): + return fallback + return name_or_path + + +def main(): + p = argparse.ArgumentParser(description='字模生成工具') + p.add_argument('--font', default='simsun', help='字体名称或路径') + p.add_argument('--size', type=int, default=64, help='渲染字号') + p.add_argument('--threshold', type=int, default=50, help='二值化阈值(默认50)') + p.add_argument('--scale', type=int, default=4, help='缩放倍率') + + g = p.add_argument_group('ASCII 8×16') + g.add_argument('--ascii', action='store_true', help='生成 ASCII 字模(默认)') + + g = p.add_argument_group('CJK 16×16') + g.add_argument('--cjk', action='store_true', help='生成 CJK 汉字字模') + g.add_argument('--common', action='store_true', help='CJK:仅常用汉字(GB2312 一级)') + g.add_argument('--gb2312', action='store_true', help='CJK:GB2312 全部汉字') + g.add_argument('--punct', action='store_true', help='CJK:加入中文标点/全角字符') + g.add_argument('--string', type=str, default=None, help='CJK:仅生成指定字符串中的字符(节省空间)') + g.add_argument('--output', '-o', default=None, help='CJK 输出基名(不含扩展名)') + + args = p.parse_args() + + font_path = _resolve_font(args.font) + print(f"字体: {font_path}") + + proj_dir = os.path.abspath(os.path.join( + os.path.dirname(__file__), + '..', 'STM32F103C8T6', 'Drivers', 'BSP', 'LCD')) + + if args.cjk: + size = args.size or 48 + scale = args.scale or 3 + out_base = args.output or os.path.join(proj_dir, 'hz16_data') + + if args.string is not None: + unicodes = sorted(set(ord(c) for c in args.string)) + generate_cjk_direct(out_base, font_path, size, args.threshold, scale, unicodes) + else: + generate_cjk(out_base, font_path, size, args.threshold, scale, + mode='common' if args.common else ('gb2312' if args.gb2312 else 'common'), + punct=args.punct) + else: + # 默认 ASCII + size = args.size or 56 + scale = args.scale or 4 + out = os.path.join(proj_dir, 'lcd_data.c') + generate_ascii(out, font_path, size, args.threshold, scale) + + +if __name__ == '__main__': + main() diff --git a/tools/to_escape.py b/tools/to_escape.py new file mode 100644 index 0000000..24569c9 --- /dev/null +++ b/tools/to_escape.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 +import sys + +def main(): + text = sys.argv[1] if len(sys.argv) > 1 else input("Enter Chinese: ") + escaped = ''.join(f'\\x{b:02X}' for b in text.encode('utf-8')) + print(escaped) + +if __name__ == '__main__': + main()