generated from hulk/gd32e23x_template
	Compare commits
	
		
			50 Commits
		
	
	
		
			c88a383c29
			...
			研发稳定版本
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b94a430ba2 | |||
| 8cd24132a6 | |||
| e2e17d870c | |||
| d359ab5320 | |||
| 0ebe9c5d16 | |||
| 444804efe4 | |||
| e89169582d | |||
| 19e73080e6 | |||
| 0ac221ce6f | |||
| 9b9f14f97a | |||
| 7d6be9f390 | |||
| 97587ba990 | |||
| 6792caa04f | |||
| ce6289a82a | |||
| 67ea11a45e | |||
| 4d98e4dc30 | |||
| 9a07dba591 | |||
| a64b1427de | |||
| f130674630 | |||
| d356658079 | |||
| 7a7ed3e369 | |||
| 6c9543648f | |||
| bb61f0be6b | |||
| 378dafdc2d | |||
| eca38a53b8 | |||
| fca25e1981 | |||
| 15730d7234 | |||
| 6702703031 | |||
| ed8b6b3f6d | |||
| 23a8e1d978 | |||
| f081fdac63 | |||
| 569d99cbf3 | |||
| fa7f364bdb | |||
| 2d273efef5 | |||
| 8fa7ed32d8 | |||
| 05fb90c727 | |||
| 4dc9054544 | |||
| 5838f18742 | |||
| dc8bff918d | |||
| f550619217 | |||
| b307160ba0 | |||
| 8e2cdd1ac5 | |||
| 21a5a2e783 | |||
| 2ff2916ed6 | |||
| c635adf812 | |||
| 49f57c6980 | |||
| 930410f91e | |||
| f279251ff7 | |||
| de211abf4e | |||
| 0910a26072 | 
| @@ -4,10 +4,12 @@ include(cmake/toolchain.cmake) | |||||||
| project(xlsw_3dp_LDC1612) | project(xlsw_3dp_LDC1612) | ||||||
|  |  | ||||||
| set(VERSION_MAJOR 0) | set(VERSION_MAJOR 0) | ||||||
| set(VERSION_MINOR 0) | set(VERSION_MINOR 2) | ||||||
| set(VERSION_PATCH 1) | set(VERSION_PATCH 0) | ||||||
| set(VERSION "V${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") | set(VERSION "V${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") | ||||||
| string(TIMESTAMP CURRENT_DATE "%Y-%m-%d") | string(TIMESTAMP CURRENT_DATE "%Y-%m-%d") | ||||||
|  | set(IIC_TYPE "SW-IIC") | ||||||
|  | #set(IIC_TYPE "HW-IIC") | ||||||
|  |  | ||||||
| enable_language(C) | enable_language(C) | ||||||
| enable_language(CXX) | enable_language(CXX) | ||||||
| @@ -24,9 +26,13 @@ set(TARGET_C_SRC | |||||||
|         ${CMAKE_SOURCE_DIR}/src/main.c |         ${CMAKE_SOURCE_DIR}/src/main.c | ||||||
|         ${CMAKE_SOURCE_DIR}/src/gd32e23x_it.c |         ${CMAKE_SOURCE_DIR}/src/gd32e23x_it.c | ||||||
|         ${CMAKE_SOURCE_DIR}/src/systick.c |         ${CMAKE_SOURCE_DIR}/src/systick.c | ||||||
|         ${CMAKE_SOURCE_DIR}/src/peripheral.c |         ${CMAKE_SOURCE_DIR}/src/ldc1612.c | ||||||
|         ${CMAKE_SOURCE_DIR}/src/LDC1612.c |         ${CMAKE_SOURCE_DIR}/src/tmp112.c | ||||||
|         ${CMAKE_SOURCE_DIR}/src/RS485.c |         ${CMAKE_SOURCE_DIR}/src/rs485.c | ||||||
|  |         ${CMAKE_SOURCE_DIR}/src/led.c | ||||||
|  |         ${CMAKE_SOURCE_DIR}/src/i2c.c | ||||||
|  |         ${CMAKE_SOURCE_DIR}/src/soft_i2c.c | ||||||
|  |         ${CMAKE_SOURCE_DIR}/src/fwdgt.c | ||||||
| ) | ) | ||||||
|  |  | ||||||
| add_executable(xlsw_3dp_LDC1612 ${TARGET_C_SRC}) | add_executable(xlsw_3dp_LDC1612 ${TARGET_C_SRC}) | ||||||
|   | |||||||
							
								
								
									
										79
									
								
								CommunicationProtocol.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								CommunicationProtocol.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | |||||||
|  | # 电涡流传感器模块通信协议 | ||||||
|  |  | ||||||
|  | ## 电涡流传感器模块通信协议 | ||||||
|  |  | ||||||
|  | | **序号** | **修改内容** | **版本** | **日期**     | **修改人** | | ||||||
|  | |:------:|:--------:|:------:|:----------:|:-------:| | ||||||
|  | | 1      | 初版       | V1.0   | 2024-12-25 | Hulk    | | ||||||
|  | |        |          |        |            |         | | ||||||
|  | |        |          |        |            |         | | ||||||
|  | |        |          |        |            |         | | ||||||
|  |  | ||||||
|  | ### 发包格式 | ||||||
|  |  | ||||||
|  | | **包头** | **类型** | **数据长度**    | **数据** | **校验** | | ||||||
|  | |:------:|:------:|:-----------:|:------:|:------:| | ||||||
|  | | D5     | 0x03   | Data Length |  Data  | CRC    | | ||||||
|  |  | ||||||
|  | - 数据长度只包含数据部分,不包含包头、类型、数据长度、校验 | ||||||
|  | - CRC求和校验,包含类型、数据长度、数据 | ||||||
|  | - 数据部分为ascii码 | ||||||
|  |  | ||||||
|  | ### 回包格式 | ||||||
|  |  | ||||||
|  | | **包头** |  **状态码**   | **数据长度**    | **数据** | **校验** | | ||||||
|  | |:------:|:----------:|:-----------:|:------:|:------:| | ||||||
|  | |   B5   |  0xF0 正常包  | Data Length |  Data  | CRC    | | ||||||
|  | |   B5   | 0xF1 CRC错误 | Data Length |  Data  | CRC    | | ||||||
|  | |   B5   | 0xF2 包头错误  | Data Length |  Data  | CRC    | | ||||||
|  | |   B5   | 0xF3 类型错误  | Data Length |  Data  | CRC    | | ||||||
|  | |   B5   | 0xF4 包长度错误 | Data Length |  Data  | CRC    | | ||||||
|  |  | ||||||
|  | - 数据长度只包含数据部分,不包含包头、类型、数据长度、校验 | ||||||
|  | - CRC求和校验,包含状态码、数据长度、数据 | ||||||
|  | - 有效数据部分为uint32_t,高字节在前 | ||||||
|  | - 包错误和指令错误时,数据部分为ascii码 `err` | ||||||
|  |  | ||||||
|  | ------------------- | ||||||
|  |  | ||||||
|  | ## 电涡流传感器模块功能 | ||||||
|  |  | ||||||
|  | ### 1. 读取电涡流传感器模块数据 | ||||||
|  |  | ||||||
|  | - 发送M1指令,读取电涡流传感器模块数据。 | ||||||
|  |     - `D5 03 02 4D 31 83` | ||||||
|  | - 电涡流传感器模块涡流回复数据 | ||||||
|  |     - `B5 F0 04 01 AE 1B E4 A2`, 有效数据为 `0x01AE1BE4`,转换为`28187620` | ||||||
|  |     - `B5 F0 04 04 19 C1 FA CC`, 有效数据为 `0x0419C1FAD2`,转换为`17612012242` | ||||||
|  | - 错误命令(M3指令)回包 | ||||||
|  |     - `B5 F0 03 65 72 72 3C`,有效数据为 `err` | ||||||
|  | - CRC错误回包 | ||||||
|  |     - `B5 F1 03 65 72 72 3D`, 有效数据为 `err` | ||||||
|  | - 包头错误回包 | ||||||
|  |     - `B5 F2 03 65 72 72 3E`, 有效数据为 `err` | ||||||
|  | - 类型错误回包 | ||||||
|  |     - `B5 F3 03 65 72 72 3F`, 有效数据为 `err` | ||||||
|  | - 数据长度错误回包 | ||||||
|  |     - `B5 F4 03 65 72 72 40`, 有效数据为 `err` | ||||||
|  |  | ||||||
|  | ### 2. 读取电涡流传感器模块温度补偿数据 | ||||||
|  |  | ||||||
|  | - 发送M2指令,读取电涡流传感器模块数据。 | ||||||
|  |     - `D5 03 02 4D 32 84` | ||||||
|  | - 电涡流传感器模块温度补偿回复数据 | ||||||
|  |     - `B5 F0 04 00 03 40 85 BC`, 有效数据为 `0x00034085`,转换为`213125`(单位为摄氏度*10)温度为21.3125℃ | ||||||
|  |     - `B5 F0 04 00 03 89 C3 43`, 有效数据为 `0x000389C3`,转换为`231875`(单位为摄氏度*10)温度为23.1875℃ | ||||||
|  | - 错误命令(M3指令)回包 | ||||||
|  |     - `B5 F0 03 65 72 72 3C`,有效数据为 `err` | ||||||
|  | - CRC错误回包 | ||||||
|  |     - `B5 F1 03 65 72 72 3D`, 有效数据为 `err` | ||||||
|  | - 包头错误回包 | ||||||
|  |     - `B5 F2 03 65 72 72 3E`, 有效数据为 `err` | ||||||
|  | - 类型错误回包 | ||||||
|  |     - `B5 F3 03 65 72 72 3F`, 有效数据为 `err` | ||||||
|  | - 数据长度错误回包 | ||||||
|  |     - `B5 F4 03 65 72 72 40`, 有效数据为 `err` | ||||||
|  |  | ||||||
|  | ### 3. 读取数据时间间隔 | ||||||
|  |  | ||||||
|  | - 推荐数据时间间隔至少为500ms | ||||||
							
								
								
									
										66
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,63 +1,9 @@ | |||||||
| # gd32e23x_template | # XLSW-3DP-Sensor-LDC1612 | ||||||
| 本项目为GD32E230Fx系列的基于Clion的CMake开发的工程模板。本人暂未入门,强行上强度,放弃keil,拥抱开源。遂尝试使用arm-none-eabi-gcc进行开发。 |  | ||||||
| 有幸寻得[@mo10 ](https://github.com/mo10)大佬的帮助,本项目的基础目录架构与CMakeLists.txt与toolchain.cmake均为大佬提供。 |  | ||||||
|  |  | ||||||
| ## 关于C标准库的printf的重写 | | **版本号** |      **修改内容**       |   **日期**   | **修改人** | | ||||||
| 在Keil开发中,ARMClang有自己的microLIB,所以直接调用,然后重写fputc函数即可,但在gcc中需要重写`_write`函数,本项目模板中已经在`main.c`中完成重写。 | |:-------:|:-------------------:|:----------:|:-------:| | ||||||
| 同时需要添加`--spaces=nano.spaces`编译参数。 | | v0.2.0  | 实现软件与硬件IIC可自选,添加看门狗 | 2024-12-29 | Hulk    | | ||||||
| 但是printf本身占用flash比较大,建议谨慎使用,尤其是本项目搭建时候采用的型号为`GD32E230F4V6`内存非常有限,重写后加上spaces设置,目前能用。 |  | ||||||
|  |  | ||||||
| ## 添加源文件与头文件 | ## 电涡流传感器模块通信协议 | ||||||
| 在`ProjectDir/CMakeLists.txt`中21行左右,添加对应源文件即可。 |  | ||||||
|  |  | ||||||
| ```cmake | 通信协议:[LDC1612通信协议](CommunicationProtocol.md) | ||||||
| set(TARGET_C_SRC |  | ||||||
|         ${CMAKE_SOURCE_DIR}/src/main.c |  | ||||||
|         ${CMAKE_SOURCE_DIR}/src/gd32e23x_it.c |  | ||||||
|         ${CMAKE_SOURCE_DIR}/src/systick.c |  | ||||||
|         ${CMAKE_SOURCE_DIR}/src/peripheral.c |  | ||||||
| ) |  | ||||||
| ``` |  | ||||||
| ## 关于链接脚本 |  | ||||||
| 注意芯片选型, 不同型号的芯片 FLASH 和 RAM 大小不同。需要修改链接脚本`ld/gd32e23x_gcc.ld` |  | ||||||
|  |  | ||||||
| | 芯片型号       | FLASH | RAM | |  | ||||||
| |------------|-------|-----| |  | ||||||
| | GD32E230F4 | 16K   | 4K  | |  | ||||||
| | GD32E230F8 | 64K   | 8K  | |  | ||||||
|  |  | ||||||
| ```linkerscript |  | ||||||
| /* memory map */ |  | ||||||
| MEMORY |  | ||||||
| { |  | ||||||
| FLASH (rx)      : ORIGIN = 0x08000000, LENGTH = 16K |  | ||||||
| RAM (xrw)       : ORIGIN = 0x20000000, LENGTH = 4K |  | ||||||
| } |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## 关于Startup文件 |  | ||||||
|  |  | ||||||
| [@mo10 ](https://github.com/mo10)大佬提供的一些想法,具体如下。但是我目前还没测试到实际的影响和作用范围,所以暂未同步进来,仅作为备忘内容 |  | ||||||
| ```asm |  | ||||||
| Reset_Handler: |  | ||||||
|     ldr   r0, =_sp |  | ||||||
|     mov   sp, r0 |  | ||||||
|     ldr   r0, =_end |  | ||||||
|     msr   msplim, r0 |  | ||||||
| /* copy the data segment into ram */ |  | ||||||
|     movs  r1, #0 |  | ||||||
|     b  LoopCopyDataInit |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
|  |  | ||||||
| ## Ref |  | ||||||
|  |  | ||||||
| 1. 参考LD/Startup |  | ||||||
|  |  | ||||||
| [https://github.com/Noveren/gd32e23x-template/blob/main/gd32e23x/template/linker.ld](https://github.com/Noveren/gd32e23x-template/blob/main/gd32e23x/template/linker.ld) |  | ||||||
|  |  | ||||||
| [https://github.com/Noveren/gd32e23x-template/blob/main/gd32e23x/template/startup.s](https://github.com/Noveren/gd32e23x-template/blob/main/gd32e23x/template/startup.s) |  | ||||||
|  |  | ||||||
| 2. 官方LD/Startup |  | ||||||
|  |  | ||||||
| 使用Embedded Builder工具生成的C标准库生成的模板 |  | ||||||
| @@ -41,12 +41,12 @@ function(print_size_of_target TARGET) | |||||||
|             ) |             ) | ||||||
| endfunction() | endfunction() | ||||||
|  |  | ||||||
| function(_generate_file TARGET PREFIX VERSION DATE OUTPUT_EXTENSION OBJCOPY_BFD_OUTPUT) | function(_generate_file TARGET PREFIX VERSION DATE IIC_TYPE OUTPUT_EXTENSION OBJCOPY_BFD_OUTPUT) | ||||||
|     get_target_property(TARGET_OUTPUT_NAME ${TARGET} OUTPUT_NAME) |     get_target_property(TARGET_OUTPUT_NAME ${TARGET} OUTPUT_NAME) | ||||||
|     if (TARGET_OUTPUT_NAME) |     if (TARGET_OUTPUT_NAME) | ||||||
|         set(OUTPUT_FILE_NAME "${PREFIX}_${VERSION}_${DATE}.${OUTPUT_EXTENSION}") |         set(OUTPUT_FILE_NAME "${PREFIX}_${VERSION}_${DATE}_${IIC_TYPE}.${OUTPUT_EXTENSION}") | ||||||
|     else() |     else() | ||||||
|         set(OUTPUT_FILE_NAME "${TARGET}_${VERSION}_${DATE}.${OUTPUT_EXTENSION}") |         set(OUTPUT_FILE_NAME "${TARGET}_${VERSION}_${DATE}_${IIC_TYPE}.${OUTPUT_EXTENSION}") | ||||||
|     endif() |     endif() | ||||||
|  |  | ||||||
|     get_target_property(RUNTIME_OUTPUT_DIRECTORY ${TARGET} RUNTIME_OUTPUT_DIRECTORY) |     get_target_property(RUNTIME_OUTPUT_DIRECTORY ${TARGET} RUNTIME_OUTPUT_DIRECTORY) | ||||||
| @@ -66,11 +66,11 @@ function(_generate_file TARGET PREFIX VERSION DATE OUTPUT_EXTENSION OBJCOPY_BFD_ | |||||||
| endfunction() | endfunction() | ||||||
|  |  | ||||||
| function(generate_binary_file TARGET PREFIX) | function(generate_binary_file TARGET PREFIX) | ||||||
|     _generate_file(${TARGET} "${PREFIX}" "${VERSION}" "${CURRENT_DATE}" "bin" "binary") |     _generate_file(${TARGET} "${PREFIX}" "${VERSION}" "${CURRENT_DATE}" "${IIC_TYPE}" "bin" "binary") | ||||||
| endfunction() | endfunction() | ||||||
|  |  | ||||||
| function(generate_hex_file TARGET PREFIX) | function(generate_hex_file TARGET PREFIX) | ||||||
|     _generate_file(${TARGET} "${PREFIX}" "${VERSION}" "${CURRENT_DATE}" "hex" "ihex") |     _generate_file(${TARGET} "${PREFIX}" "${VERSION}" "${CURRENT_DATE}" "${IIC_TYPE}" "hex" "ihex") | ||||||
| endfunction() | endfunction() | ||||||
|  |  | ||||||
| set(CMAKE_EXECUTABLE_SUFFIX_C   .elf) | set(CMAKE_EXECUTABLE_SUFFIX_C   .elf) | ||||||
|   | |||||||
							
								
								
									
										31
									
								
								inc/RS485.h
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								inc/RS485.h
									
									
									
									
									
								
							| @@ -1,31 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by dell on 24-12-3. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #ifndef RS485_H |  | ||||||
| #define RS485_H |  | ||||||
|  |  | ||||||
| #include "gd32e23x_it.h" |  | ||||||
| #include "gd32e23x.h" |  | ||||||
| #include "systick.h" |  | ||||||
| #include <stdbool.h> |  | ||||||
| #include <string.h> |  | ||||||
| #include <stdio.h> |  | ||||||
| #include <stdlib.h> |  | ||||||
|  |  | ||||||
| #define RS485_RCU            RCU_USART0 |  | ||||||
| #define RS485_GPIO_RCU       RCU_GPIOA |  | ||||||
| #define RS485_GPIO_PORT      GPIOA |  | ||||||
| #define RS485_TX_PIN         GPIO_PIN_2 |  | ||||||
| #define RS485_RX_PIN         GPIO_PIN_3 |  | ||||||
| #define RS485_PHY            USART0 |  | ||||||
| #define RS485_BAUDRATE       115200U |  | ||||||
|  |  | ||||||
| #define RS485_EN_PIN         GPIO_PIN_1 |  | ||||||
|  |  | ||||||
| #define RX_BUFFER_SIZE 64 |  | ||||||
|  |  | ||||||
| void RS485_config(void); |  | ||||||
| void process_command(char *cmd); |  | ||||||
|  |  | ||||||
| #endif //RS485_H |  | ||||||
							
								
								
									
										44
									
								
								inc/board_config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								inc/board_config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-28. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef BOARD_CONFIG_H | ||||||
|  | #define BOARD_CONFIG_H | ||||||
|  |  | ||||||
|  | #define SOFTWARE_IIC | ||||||
|  |  | ||||||
|  | // #define DEBUG_VERBOES | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define RCU_GPIO_I2C         RCU_GPIOF | ||||||
|  | #define RCU_I2C              RCU_I2C0 | ||||||
|  | #define I2C_SCL_PORT         GPIOF | ||||||
|  | #define I2C_SCL_PIN          GPIO_PIN_1 | ||||||
|  | #define I2C_SDA_PORT         GPIOF | ||||||
|  | #define I2C_SDA_PIN          GPIO_PIN_0 | ||||||
|  | #define I2C_GPIO_AF          GPIO_AF_1 | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define RS485_RCU            RCU_USART0 | ||||||
|  | #define RS485_GPIO_RCU       RCU_GPIOA | ||||||
|  | #define RS485_GPIO_PORT      GPIOA | ||||||
|  | #define RS485_TX_PIN         GPIO_PIN_2 | ||||||
|  | #define RS485_RX_PIN         GPIO_PIN_3 | ||||||
|  | #define RS485_PHY            USART0 | ||||||
|  | #define RS485_BAUDRATE       115200U | ||||||
|  | #define RS485_EN_PIN         GPIO_PIN_1 | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define LED_PORT             GPIOA | ||||||
|  | #define LED_PIN              GPIO_PIN_7 | ||||||
|  | #define LED_RCU              RCU_GPIOA | ||||||
|  | #define LED_BLINK_TIMER_RCU  RCU_TIMER16 | ||||||
|  | #define LED_BLINK_TIMER      TIMER16 | ||||||
|  | #define LED_BLINK_IRQ        TIMER16_IRQn | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #endif //BOARD_CONFIG_H | ||||||
							
								
								
									
										15
									
								
								inc/fwdgt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								inc/fwdgt.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | // | ||||||
|  | // Created by yelv1 on 24-12-29. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef FWDGT_H | ||||||
|  | #define FWDGT_H | ||||||
|  |  | ||||||
|  | #include "gd32e23x.h" | ||||||
|  | #include "board_config.h" | ||||||
|  |  | ||||||
|  | void watchdog_init(void); | ||||||
|  |  | ||||||
|  | void fwdgt_reset_mcu(void); | ||||||
|  |  | ||||||
|  | #endif //FWDGT_H | ||||||
							
								
								
									
										53
									
								
								inc/i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								inc/i2c.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-20. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef I2C_H | ||||||
|  | #define I2C_H | ||||||
|  |  | ||||||
|  | #include "gd32e23x_it.h" | ||||||
|  | #include "gd32e23x.h" | ||||||
|  | #include "systick.h" | ||||||
|  | #include "main.h" | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <string.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <math.h> | ||||||
|  |  | ||||||
|  | #include "board_config.h" | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define I2C_SPEED       20000 | ||||||
|  |  | ||||||
|  | #define I2C_TIME_OUT    (uint16_t)(5000) | ||||||
|  | #define I2C_OK          1 | ||||||
|  | #define I2C_FAIL        0 | ||||||
|  | #define I2C_END         1 | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | typedef enum { | ||||||
|  |     I2C_START = 0, | ||||||
|  |     I2C_SEND_ADDRESS, | ||||||
|  |     I2C_CLEAR_ADDRESS_FLAG, | ||||||
|  |     I2C_TRANSMIT_DATA, | ||||||
|  |     I2C_STOP | ||||||
|  | } i2c_process_enum; | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | void i2c_gpio_config(void); | ||||||
|  |  | ||||||
|  | void i2c_config(void); | ||||||
|  |  | ||||||
|  | void i2c_bus_reset(void); | ||||||
|  |  | ||||||
|  | void i2c_scan(void); | ||||||
|  |  | ||||||
|  | uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]); | ||||||
|  |  | ||||||
|  | uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); | ||||||
|  |  | ||||||
|  | #endif //I2C_H | ||||||
| @@ -13,11 +13,17 @@ | |||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <math.h> | #include <math.h> | ||||||
|  | #include "board_config.h" | ||||||
|  | #include "soft_i2c.h" | ||||||
|  | #include "i2c.h" | ||||||
|  | 
 | ||||||
|  | /***************************************************************************/ | ||||||
| 
 | 
 | ||||||
| #define LDC1612_ADDR         (0x2B << 1) | #define LDC1612_ADDR         (0x2B << 1) | ||||||
| 
 | 
 | ||||||
| /*Register Rddr*/ | /*Register Rddr*/ | ||||||
| /***************************************************************************/ | /***************************************************************************/ | ||||||
|  | 
 | ||||||
| #define CONVERTION_RESULT_REG_START             0X00 | #define CONVERTION_RESULT_REG_START             0X00 | ||||||
| #define SET_CONVERSION_TIME_REG_START           0X08 | #define SET_CONVERSION_TIME_REG_START           0X08 | ||||||
| #define SET_CONVERSION_OFFSET_REG_START         0X0C | #define SET_CONVERSION_OFFSET_REG_START         0X0C | ||||||
| @@ -41,12 +47,13 @@ | |||||||
| 
 | 
 | ||||||
| /******************************************************************************/ | /******************************************************************************/ | ||||||
| 
 | 
 | ||||||
| #define LDC1612_CONVERSION_TIME_CH0        0X0546  //0536
 | #define LDC1612_CONVERSION_TIME_CH0        0x0546  //0536
 | ||||||
| #define LDC1612_DRIVE_CURRENT              0X9000  //A000
 | #define LDC1612_DRIVE_CURRENT              0x9000  //A000
 | ||||||
| #define LDC1612_MUX_CONFIG                 0X020C  // no auto scan and filter bandwidth 3.3MHz
 | #define LDC1612_MUX_CONFIG                 0x020C  // no auto scan and filter bandwidth 3.3MHz
 | ||||||
| #define LDC1612_SENSOR_CONFIG              0X1601 | #define LDC1612_SENSOR_CONFIG              0x1601 | ||||||
| #define LDC1612_ERROR_CONFIG               0x0000 | #define LDC1612_ERROR_CONFIG               0x0000 | ||||||
| #define LC_STABILIZE_TIME_CH0              0X001E //30
 | #define LC_STABILIZE_TIME_CH0              0x001E //30
 | ||||||
|  | #define LDC1612_RESET_DEV                  0x8000 //[15:0] 0b1000 0000 0000 0000
 | ||||||
| 
 | 
 | ||||||
| /******************************************************************************/ | /******************************************************************************/ | ||||||
| 
 | 
 | ||||||
| @@ -55,35 +62,7 @@ | |||||||
| #define COIL_C_PF                150 | #define COIL_C_PF                150 | ||||||
| #define COIL_Q_FACTOR            35.97 | #define COIL_Q_FACTOR            35.97 | ||||||
| 
 | 
 | ||||||
| typedef enum { | /******************************************************************************/ | ||||||
|     I2C_START = 0, |  | ||||||
|     I2C_SEND_ADDRESS, |  | ||||||
|     I2C_CLEAR_ADDRESS_FLAG, |  | ||||||
|     I2C_TRANSMIT_DATA, |  | ||||||
|     I2C_STOP |  | ||||||
| } i2c_process_enum; |  | ||||||
| 
 |  | ||||||
| #define I2C_TIME_OUT    (uint16_t)(10000) |  | ||||||
| #define I2C_OK          1 |  | ||||||
| #define I2C_FAIL        0 |  | ||||||
| #define I2C_END         1 |  | ||||||
| 
 |  | ||||||
| #define I2C_SPEED 20000 |  | ||||||
| #define RCU_GPIO_I2C RCU_GPIOF |  | ||||||
| #define RCU_I2C RCU_I2C0 |  | ||||||
| #define I2C_SCL_PORT GPIOF |  | ||||||
| #define I2C_SCL_PIN GPIO_PIN_1 |  | ||||||
| #define I2C_SDA_PORT GPIOF |  | ||||||
| #define I2C_SDA_PIN GPIO_PIN_0 |  | ||||||
| #define I2C_GPIO_AF GPIO_AF_1 |  | ||||||
| 
 |  | ||||||
| void i2c_gpio_config(void); |  | ||||||
| 
 |  | ||||||
| void i2c_config(void); |  | ||||||
| 
 |  | ||||||
| void i2c_bus_reset(void); |  | ||||||
| 
 |  | ||||||
| void i2c_scan(void); |  | ||||||
| 
 | 
 | ||||||
| void ldc1612_set_conversion_time(uint8_t channel, uint16_t result); | void ldc1612_set_conversion_time(uint8_t channel, uint16_t result); | ||||||
| 
 | 
 | ||||||
| @@ -115,8 +94,4 @@ uint32_t ldc1612_get_raw_channel_result(uint8_t channel); | |||||||
| 
 | 
 | ||||||
| uint32_t ldc1612_parse_raw_result(uint32_t raw_result); | uint32_t ldc1612_parse_raw_result(uint32_t raw_result); | ||||||
| 
 | 
 | ||||||
| uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data); |  | ||||||
| 
 |  | ||||||
| uint8_t ldc1612_iic_write_16bits(uint8_t reg_addr, uint8_t data[2]); |  | ||||||
| 
 |  | ||||||
| #endif //LDC1612_H
 | #endif //LDC1612_H
 | ||||||
							
								
								
									
										13
									
								
								inc/led.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								inc/led.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-20. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef LED_H | ||||||
|  | #define LED_H | ||||||
|  |  | ||||||
|  | #include "gd32e23x_it.h" | ||||||
|  | #include "board_config.h" | ||||||
|  |  | ||||||
|  | void led_config(void); | ||||||
|  |  | ||||||
|  | #endif //LED_H | ||||||
							
								
								
									
										21
									
								
								inc/main.h
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								inc/main.h
									
									
									
									
									
								
							| @@ -35,13 +35,20 @@ OF SUCH DAMAGE. | |||||||
| #ifndef MAIN_H | #ifndef MAIN_H | ||||||
| #define MAIN_H | #define MAIN_H | ||||||
|  |  | ||||||
| #define LED_PORT            GPIOA | #include <stdio.h> | ||||||
| #define LED_PIN             GPIO_PIN_7 | #include "gd32e23x.h" | ||||||
| #define LED_RCU             RCU_GPIOA | #include "systick.h" | ||||||
| #define LED_TIMER_RCU       RCU_TIMER16 | #include "gd32e23x_libopt.h" | ||||||
| #define LED_TIMER           TIMER16 | #include "rs485.h" | ||||||
| #define LED_IRQ             TIMER16_IRQn | #include "led.h" | ||||||
|  | #include "ldc1612.h" | ||||||
|  | #include "fwdgt.h" | ||||||
|  | #include "board_config.h" | ||||||
|  |  | ||||||
| void led_config(void); | #ifdef SOFTWARE_IIC | ||||||
|  | #include "soft_i2c.h" | ||||||
|  | #else | ||||||
|  | #include "i2c.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #endif /* MAIN_H */ | #endif /* MAIN_H */ | ||||||
|   | |||||||
| @@ -1,11 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by yelv1 on 24-9-22. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #ifndef PERIPHERAL_H |  | ||||||
| #define PERIPHERAL_H |  | ||||||
|  |  | ||||||
| void usart_config(void); |  | ||||||
| void led_blink_config(void); |  | ||||||
|  |  | ||||||
| #endif //PERIPHERAL_H |  | ||||||
							
								
								
									
										56
									
								
								inc/rs485.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								inc/rs485.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-3. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef RS485_H | ||||||
|  | #define RS485_H | ||||||
|  |  | ||||||
|  | #include "gd32e23x_it.h" | ||||||
|  | #include "gd32e23x.h" | ||||||
|  | #include "systick.h" | ||||||
|  | #include <stdio.h> | ||||||
|  | #include "ldc1612.h" | ||||||
|  | #include "tmp112.h" | ||||||
|  | #include "fwdgt.h" | ||||||
|  | #include "board_config.h" | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define RX_BUFFER_SIZE            32 | ||||||
|  |  | ||||||
|  | #define PROTOCOL_PACKAGE_HEADER   0xD5 | ||||||
|  | #define PROTOCOL_BOARD_TYPE       0x03 | ||||||
|  | #define PROTOCOL_PACKAGE_LENGTH   0x02 | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | typedef enum | ||||||
|  | { | ||||||
|  |     VALIDATION_SUCCESS = 0, | ||||||
|  |     VALIDATION_CRC_ERROR = 1, | ||||||
|  |     VALIDATION_HEADER_ERROR = 2, | ||||||
|  |     VALIDATION_TYPE_ERROR = 4, | ||||||
|  |     VALIDATION_LENGTH_ERROR = 8 | ||||||
|  | } validation_result_t; | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | void rs485_config(void); | ||||||
|  |  | ||||||
|  | void process_command(uint8_t* cmd, size_t length); | ||||||
|  |  | ||||||
|  | uint8_t calculate_crc(uint8_t data[], uint8_t data_length); | ||||||
|  |  | ||||||
|  | validation_result_t validate_package_crc(uint8_t* data, uint8_t data_length); | ||||||
|  |  | ||||||
|  | validation_result_t validate_package_header(uint8_t* data); | ||||||
|  |  | ||||||
|  | validation_result_t validate_package_type(uint8_t* data); | ||||||
|  |  | ||||||
|  | validation_result_t validate_data_length(uint8_t* data); | ||||||
|  |  | ||||||
|  | void eddy_current_value_report(void); | ||||||
|  |  | ||||||
|  | void tempture_value_report(void); | ||||||
|  |  | ||||||
|  | #endif //RS485_H | ||||||
							
								
								
									
										53
									
								
								inc/soft_i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								inc/soft_i2c.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-28. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef SOFT_I2C_H | ||||||
|  | #define SOFT_I2C_H | ||||||
|  |  | ||||||
|  | #include "gd32e23x_it.h" | ||||||
|  | #include "gd32e23x.h" | ||||||
|  | #include "systick.h" | ||||||
|  | #include "main.h" | ||||||
|  |  | ||||||
|  | #include "board_config.h" | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define I2C_SCL_HIGH()      gpio_bit_set(I2C_SCL_PORT, I2C_SCL_PIN) | ||||||
|  | #define I2C_SCL_LOW()       gpio_bit_reset(I2C_SCL_PORT, I2C_SCL_PIN) | ||||||
|  | #define I2C_SDA_HIGH()      gpio_bit_set(I2C_SDA_PORT, I2C_SDA_PIN) | ||||||
|  | #define I2C_SDA_LOW()       gpio_bit_reset(I2C_SDA_PORT, I2C_SDA_PIN) | ||||||
|  | #define I2C_SDA_READ()      gpio_input_bit_get(I2C_SDA_PORT, I2C_SDA_PIN) | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define SOFT_I2C_OK          1 | ||||||
|  | #define SOFT_I2C_FAIL        0 | ||||||
|  | #define SOFT_I2C_END         1 | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | void soft_i2c_delay(void); | ||||||
|  |  | ||||||
|  | void soft_i2c_config(void); | ||||||
|  |  | ||||||
|  | void soft_i2c_start(void); | ||||||
|  |  | ||||||
|  | void soft_i2c_stop(void); | ||||||
|  |  | ||||||
|  | void soft_i2c_send_ack(void); | ||||||
|  |  | ||||||
|  | void soft_i2c_send_nack(void); | ||||||
|  |  | ||||||
|  | uint8_t soft_i2c_wait_ack(void); | ||||||
|  |  | ||||||
|  | void soft_i2c_send_byte(uint8_t data); | ||||||
|  |  | ||||||
|  | uint8_t soft_i2c_receive_byte(uint8_t ack); | ||||||
|  |  | ||||||
|  | uint8_t soft_i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]); | ||||||
|  |  | ||||||
|  | uint8_t soft_i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data); | ||||||
|  |  | ||||||
|  | #endif //SOFT_I2C_H | ||||||
							
								
								
									
										29
									
								
								inc/tmp112.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								inc/tmp112.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-20. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef TMP112_H | ||||||
|  | #define TMP112_H | ||||||
|  |  | ||||||
|  | #include "gd32e23x_it.h" | ||||||
|  | #include "gd32e23x.h" | ||||||
|  |  | ||||||
|  | #include "board_config.h" | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  | #include "soft_i2c.h" | ||||||
|  | #else | ||||||
|  | #include "i2c.h" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define TMP112A_ADDR         (0x49 << 1) | ||||||
|  |  | ||||||
|  | /******************************************************************************/ | ||||||
|  |  | ||||||
|  | #define TMP112A_TEMP_REG     0x00 | ||||||
|  |  | ||||||
|  | uint32_t tmp112a_get_raw_channel_result(void); | ||||||
|  |  | ||||||
|  | #endif //TMP112_H | ||||||
| @@ -45,9 +45,9 @@ | |||||||
|  |  | ||||||
| /* select a system clock by uncommenting the following line */ | /* select a system clock by uncommenting the following line */ | ||||||
| //#define __SYSTEM_CLOCK_8M_HXTAL              (__HXTAL) | //#define __SYSTEM_CLOCK_8M_HXTAL              (__HXTAL) | ||||||
| #define __SYSTEM_CLOCK_8M_IRC8M              (__IRC8M) | // #define __SYSTEM_CLOCK_8M_IRC8M              (__IRC8M) | ||||||
| // #define __SYSTEM_CLOCK_72M_PLL_HXTAL         (uint32_t)(72000000) | // #define __SYSTEM_CLOCK_72M_PLL_HXTAL         (uint32_t)(72000000) | ||||||
| // #define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2    (uint32_t)(72000000) | #define __SYSTEM_CLOCK_72M_PLL_IRC8M_DIV2    (uint32_t)(72000000) | ||||||
|  |  | ||||||
| #define RCU_MODIFY(__delay)     do{                                     \ | #define RCU_MODIFY(__delay)     do{                                     \ | ||||||
|                                     volatile uint32_t i;                \ |                                     volatile uint32_t i;                \ | ||||||
|   | |||||||
							
								
								
									
										50
									
								
								src/RS485.c
									
									
									
									
									
								
							
							
						
						
									
										50
									
								
								src/RS485.c
									
									
									
									
									
								
							| @@ -1,50 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by dell on 24-12-3. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #include "RS485.h" |  | ||||||
|  |  | ||||||
| void RS485_config(void) { |  | ||||||
|     rcu_periph_clock_enable(RS485_GPIO_RCU); |  | ||||||
|     rcu_periph_clock_enable(RS485_RCU); |  | ||||||
|  |  | ||||||
|     gpio_af_set(RS485_GPIO_PORT, GPIO_AF_1, GPIO_PIN_2 | GPIO_PIN_3); |  | ||||||
|  |  | ||||||
|     /* configure USART Tx&Rx as alternate function push-pull */ |  | ||||||
|     gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, RS485_TX_PIN | RS485_RX_PIN); |  | ||||||
|     gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, RS485_TX_PIN | RS485_RX_PIN); |  | ||||||
|  |  | ||||||
|     /* configure RS485 EN Pin */ |  | ||||||
|     gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS485_EN_PIN); |  | ||||||
|     gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_EN_PIN); |  | ||||||
|     gpio_bit_write(RS485_GPIO_PORT, RS485_EN_PIN, SET); |  | ||||||
|  |  | ||||||
|     /* USART configure */ |  | ||||||
|     usart_deinit(RS485_PHY); |  | ||||||
|     usart_baudrate_set(RS485_PHY, RS485_BAUDRATE); |  | ||||||
|     usart_receive_config(RS485_PHY, USART_RECEIVE_ENABLE); |  | ||||||
|     usart_transmit_config(RS485_PHY, USART_TRANSMIT_ENABLE); |  | ||||||
|  |  | ||||||
|     usart_enable(RS485_PHY); |  | ||||||
|  |  | ||||||
|     nvic_irq_enable(USART0_IRQn, 0); |  | ||||||
|     usart_interrupt_enable(RS485_PHY, USART_INT_RBNE); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void process_command(char *cmd) { |  | ||||||
|     if (strncmp(cmd, "M1", 2) == 0) { |  | ||||||
|         printf("M1 -=-=- OK!\r\n"); |  | ||||||
|     } else if (strncmp(cmd, "M2", 2) == 0) { |  | ||||||
|         printf("M2 -=-=- OK!\r\n"); |  | ||||||
|         // } else if (strncmp(cmd, "M3", 2) == 0) { |  | ||||||
|         //     char *param_str = cmd + 2; // Skip "M3" |  | ||||||
|         //     int param = atoi(param_str + 1); // Skip "S" and convert to integer |  | ||||||
|         //     if (param >= 0 && param <= 100) { |  | ||||||
|         //         printf("M3 with parameter %d -=-=- OK!\r\n", param); |  | ||||||
|         //     } else { |  | ||||||
|         //         printf("Invalid parameter for M3 command!\r\n"); |  | ||||||
|         //     } |  | ||||||
|     } else { |  | ||||||
|         printf("Invalid Command!\r\n"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										28
									
								
								src/fwdgt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/fwdgt.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | // | ||||||
|  | // Created by yelv1 on 24-12-29. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "fwdgt.h" | ||||||
|  |  | ||||||
|  | void watchdog_init(void) { | ||||||
|  |     /* Enable the LSI clock */ | ||||||
|  |     rcu_osci_on(RCU_IRC40K); | ||||||
|  |     rcu_osci_stab_wait(RCU_IRC40K); | ||||||
|  |  | ||||||
|  |     /* Configure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */ | ||||||
|  |     fwdgt_config(625, FWDGT_PSC_DIV64); // Set timeout to 1 seconds (625 / 0.625 KHz) | ||||||
|  |  | ||||||
|  |     /* Enable FWDGT */ | ||||||
|  |     fwdgt_enable(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void fwdgt_reset_mcu(void) { | ||||||
|  |     /* Enable the write access to the FWDGT_CTL register */ | ||||||
|  |     FWDGT_CTL = FWDGT_WRITEACCESS_ENABLE; | ||||||
|  |  | ||||||
|  |     /* Configure FWDGT to trigger a system reset */ | ||||||
|  |     fwdgt_config(50, FWDGT_PSC_DIV4); | ||||||
|  |  | ||||||
|  |     /* Reload the counter to trigger the reset */ | ||||||
|  |     fwdgt_counter_reload(); | ||||||
|  | } | ||||||
| @@ -35,7 +35,9 @@ OF SUCH DAMAGE. | |||||||
| #include "gd32e23x_it.h" | #include "gd32e23x_it.h" | ||||||
| #include "main.h" | #include "main.h" | ||||||
| #include "systick.h" | #include "systick.h" | ||||||
| #include "LDC1612.h" | #include "ldc1612.h" | ||||||
|  | #include "rs485.h" | ||||||
|  | #include "led.h" | ||||||
|  |  | ||||||
| /*! | /*! | ||||||
|     \brief      this function handles NMI exception |     \brief      this function handles NMI exception | ||||||
| @@ -43,10 +45,9 @@ OF SUCH DAMAGE. | |||||||
|     \param[out] none |     \param[out] none | ||||||
|     \retval     none |     \retval     none | ||||||
| */ | */ | ||||||
| void NMI_Handler(void) | void NMI_Handler(void) { | ||||||
| { |  | ||||||
|     /* if NMI exception occurs, go to infinite loop */ |     /* if NMI exception occurs, go to infinite loop */ | ||||||
|     while(1) { |     while (1) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -56,10 +57,9 @@ void NMI_Handler(void) | |||||||
|     \param[out] none |     \param[out] none | ||||||
|     \retval     none |     \retval     none | ||||||
| */ | */ | ||||||
| void HardFault_Handler(void) | void HardFault_Handler(void) { | ||||||
| { |  | ||||||
|     /* if Hard Fault exception occurs, go to infinite loop */ |     /* if Hard Fault exception occurs, go to infinite loop */ | ||||||
|     while(1) { |     while (1) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -69,10 +69,9 @@ void HardFault_Handler(void) | |||||||
|     \param[out] none |     \param[out] none | ||||||
|     \retval     none |     \retval     none | ||||||
| */ | */ | ||||||
| void SVC_Handler(void) | void SVC_Handler(void) { | ||||||
| { |  | ||||||
|     /* if SVC exception occurs, go to infinite loop */ |     /* if SVC exception occurs, go to infinite loop */ | ||||||
|     while(1) { |     while (1) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -82,10 +81,9 @@ void SVC_Handler(void) | |||||||
|     \param[out] none |     \param[out] none | ||||||
|     \retval     none |     \retval     none | ||||||
| */ | */ | ||||||
| void PendSV_Handler(void) | void PendSV_Handler(void) { | ||||||
| { |  | ||||||
|     /* if PendSV exception occurs, go to infinite loop */ |     /* if PendSV exception occurs, go to infinite loop */ | ||||||
|     while(1) { |     while (1) { | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -95,8 +93,7 @@ void PendSV_Handler(void) | |||||||
|     \param[out] none |     \param[out] none | ||||||
|     \retval     none |     \retval     none | ||||||
| */ | */ | ||||||
| void SysTick_Handler(void) | void SysTick_Handler(void) { | ||||||
| { |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -106,18 +103,40 @@ void SysTick_Handler(void) | |||||||
|   * @retval None |   * @retval None | ||||||
|   */ |   */ | ||||||
| void TIMER16_IRQHandler(void) { | void TIMER16_IRQHandler(void) { | ||||||
|     if (timer_interrupt_flag_get(LED_TIMER, TIMER_INT_FLAG_UP) == SET) |     if (timer_interrupt_flag_get(LED_BLINK_TIMER, TIMER_INT_FLAG_UP) == SET) { | ||||||
|     { |         timer_interrupt_flag_clear(LED_BLINK_TIMER, TIMER_INT_FLAG_UP); | ||||||
|         timer_interrupt_flag_clear(LED_TIMER, TIMER_INT_FLAG_UP); |  | ||||||
|         static uint8_t led_status = 0; |         static uint8_t led_status = 0; | ||||||
|         if (led_status) |         if (led_status) { | ||||||
|         { |  | ||||||
|             gpio_bit_write(LED_PORT, LED_PIN, RESET); |             gpio_bit_write(LED_PORT, LED_PIN, RESET); | ||||||
|             timer_autoreload_value_config(LED_TIMER, 19200); |             timer_autoreload_value_config(LED_BLINK_TIMER, 19200); | ||||||
|         } else { |         } else { | ||||||
|             gpio_bit_write(LED_PORT, LED_PIN, SET); |             gpio_bit_write(LED_PORT, LED_PIN, SET); | ||||||
|             timer_autoreload_value_config(LED_TIMER, 800); |             timer_autoreload_value_config(LED_BLINK_TIMER, 800); | ||||||
|         } |         } | ||||||
|         led_status = !led_status; |         led_status = !led_status; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void USART0_IRQHandler(void) { | ||||||
|  |     static uint8_t rx_index = 0; | ||||||
|  |     static uint8_t rx_buffer[RX_BUFFER_SIZE]; | ||||||
|  |  | ||||||
|  |     if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)) { | ||||||
|  |         usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE); | ||||||
|  |         uint8_t received_data = (uint8_t) usart_data_receive(USART0); | ||||||
|  |  | ||||||
|  |         // 将接收到的数据存储到缓冲区 | ||||||
|  |         if (rx_index < RX_BUFFER_SIZE - 1) { | ||||||
|  |             rx_buffer[rx_index++] = received_data; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_IDLE)) { | ||||||
|  |         usart_interrupt_flag_clear(USART0, USART_INT_FLAG_IDLE); | ||||||
|  |  | ||||||
|  |         process_command(rx_buffer, rx_index); // 处理指令 | ||||||
|  |  | ||||||
|  |         rx_index = 0; // 重置缓冲区索引 | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| //
 | //
 | ||||||
| // Created by dell on 24-12-3.
 | // Created by dell on 24-12-20.
 | ||||||
| //
 | //
 | ||||||
| 
 | 
 | ||||||
| #include "LDC1612.h" | #include "i2c.h" | ||||||
| 
 | 
 | ||||||
| /*!
 | /*!
 | ||||||
|     \brief      configure the GPIO ports |     \brief      configure the GPIO ports | ||||||
| @@ -32,12 +32,14 @@ void i2c_gpio_config(void) { | |||||||
|     \retval     none |     \retval     none | ||||||
| */ | */ | ||||||
| void i2c_config(void) { | void i2c_config(void) { | ||||||
|  |     /* configure I2C GPIO */ | ||||||
|  |     i2c_gpio_config(); | ||||||
|     /* enable I2C clock */ |     /* enable I2C clock */ | ||||||
|     rcu_periph_clock_enable(RCU_I2C); |     rcu_periph_clock_enable(RCU_I2C); | ||||||
|     /* configure I2C clock */ |     /* configure I2C clock */ | ||||||
|     i2c_clock_config(I2C0, I2C_SPEED, I2C_DTCY_2); |     i2c_clock_config(I2C0, I2C_SPEED, I2C_DTCY_2); | ||||||
|     /* configure I2C address */ |     /* configure I2C address */ | ||||||
|     i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, LDC1612_ADDR); |     i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0xA0); | ||||||
|     /* enable I2CX */ |     /* enable I2CX */ | ||||||
|     i2c_enable(I2C0); |     i2c_enable(I2C0); | ||||||
|     /* enable acknowledge */ |     /* enable acknowledge */ | ||||||
| @@ -137,214 +139,164 @@ void i2c_scan(void) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /** @brief set conversion interval time.
 | uint8_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) { | ||||||
|     @param channel LDC1612 has total two channels. |     uint8_t state = I2C_START; | ||||||
|     @param result The value to be set. |     uint16_t timeout = 0; | ||||||
|  * */ |     uint8_t i2c_timeout_flag = 0; | ||||||
| void ldc1612_set_conversion_time(uint8_t channel, uint16_t result) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     data[0] = (result >> 8) & 0xFF; |  | ||||||
|     data[1] = result & 0xFF; |  | ||||||
|     ldc1612_iic_write_16bits(SET_CONVERSION_TIME_REG_START + channel, data); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| /** @brief set conversion offset.
 |     /* enable acknowledge */ | ||||||
|     @param channel LDC1612 has total two channels. |     i2c_ack_config(I2C0, I2C_ACK_ENABLE); | ||||||
|     @param result The value to be set. |     while (!(i2c_timeout_flag)) { | ||||||
|  * */ |         switch (state) { | ||||||
| void ldc1612_set_conversion_offset(uint8_t channel, uint16_t result) { |             case I2C_START: | ||||||
|     uint8_t data[2] = {0}; |                 /* i2c master sends start signal only when the bus is idle */ | ||||||
|     data[0] = (result >> 8) & 0xFF; |                 while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { | ||||||
|     data[1] = result & 0xFF; |                     timeout++; | ||||||
|     ldc1612_iic_write_16bits(SET_CONVERSION_OFFSET_REG_START + channel, data); |                 } | ||||||
| } |                 if (timeout < I2C_TIME_OUT) { | ||||||
| 
 |                     i2c_start_on_bus(I2C0); | ||||||
| /** @brief Before conversion,wait LC sensor stabilize for a short time.
 |                     timeout = 0; | ||||||
|     @param channel LDC1612 has total two channels. |                     state = I2C_SEND_ADDRESS; | ||||||
|     @param result The value to be set. |  | ||||||
|  * */ |  | ||||||
| void ldc1612_set_LC_stabilize_time(uint8_t channel, uint16_t result) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     data[0] = (result >> 8) & 0xFF; |  | ||||||
|     data[1] = result & 0xFF; |  | ||||||
|     ldc1612_iic_write_16bits(SET_LC_STABILIZE_REG_START + channel, data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @brief set input frequency divide and fref divide.
 |  | ||||||
|     @param channel LDC1612 has total two channels. |  | ||||||
|     @param FIN_DIV FIN input divide |  | ||||||
|     @param FREF_DIV fref,reference frequency of sensor. |  | ||||||
|  * */ |  | ||||||
| void ldc1612_set_freq_divide(uint8_t channel) { |  | ||||||
|     uint16_t value; |  | ||||||
|     uint16_t fin_div, freq_div; |  | ||||||
|     float sensor_freq; |  | ||||||
| 
 |  | ||||||
|     sensor_freq = 1 / (2 * 3.14 * sqrt(COIL_L_UH * COIL_C_PF * pow(10, -18))) * pow(10, -6); |  | ||||||
| 
 |  | ||||||
|     fin_div = (uint16_t) (sensor_freq / 8.75 + 1); |  | ||||||
| 
 |  | ||||||
|     if (fin_div * 4 < 40) { |  | ||||||
|         freq_div = 2; |  | ||||||
|                 } else { |                 } else { | ||||||
|         freq_div = 4; |                     timeout = 0; | ||||||
|  |                     state = I2C_START; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|  |                     printf("i2c bus is busy in WRITE BYTE!\n"); | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case I2C_SEND_ADDRESS: | ||||||
|  |                 /* i2c master sends START signal successfully */ | ||||||
|  |                 while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { | ||||||
|  |                     timeout++; | ||||||
|  |                 } | ||||||
|  |                 if (timeout < I2C_TIME_OUT) { | ||||||
|  |                     i2c_master_addressing(I2C0, slave_addr, I2C_TRANSMITTER); | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_CLEAR_ADDRESS_FLAG; | ||||||
|  |                 } else { | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_START; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|  |                     printf("i2c master sends start signal timeout in WRITE BYTE!\n"); | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case I2C_CLEAR_ADDRESS_FLAG: | ||||||
|  |                 /* address flag set means i2c slave sends ACK */ | ||||||
|  |                 while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { | ||||||
|  |                     timeout++; | ||||||
|  |                 } | ||||||
|  |                 if (timeout < I2C_TIME_OUT) { | ||||||
|  |                     i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_TRANSMIT_DATA; | ||||||
|  |                 } else { | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_START; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|  |                     printf("i2c master clears address flag timeout in WRITE BYTE!\n"); | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case I2C_TRANSMIT_DATA: | ||||||
|  |                 /* wait until the transmit data buffer is empty */ | ||||||
|  |                 while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) { | ||||||
|  |                     timeout++; | ||||||
|  |                 } | ||||||
|  |                 if (timeout < I2C_TIME_OUT) { | ||||||
|  |                     /* send IIC register address */ | ||||||
|  |                     i2c_data_transmit(I2C0, reg_addr); | ||||||
|  |                     timeout = 0; | ||||||
|  |                 } else { | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_START; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|  |                     printf("i2c master sends data timeout in WRITE BYTE!\n"); | ||||||
|  | #endif | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|     value = fin_div << 12; |             /* wait until BTC bit is set */ | ||||||
|     value |= freq_div; |                 while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { | ||||||
|     // printf("\tvalue: 0x%x\r\n", value);
 |                     timeout++; | ||||||
| 
 |                 } | ||||||
|     uint8_t data[2] = {0}; |                 if (timeout < I2C_TIME_OUT) { | ||||||
|     data[0] = (value >> 8) & 0xFF; |                     /* send register MSB value */ | ||||||
|     data[1] = value & 0xFF; |                     i2c_data_transmit(I2C0, data[0]); | ||||||
|     // printf("\tFIN_DIV: %d, FREF_DIV: %d\r\n", fin_div, freq_div);
 |                     timeout = 0; | ||||||
| 
 |                 } else { | ||||||
|     ldc1612_iic_write_16bits(SET_FREQ_REG_START + channel, data); |                     timeout = 0; | ||||||
| } |                     state = I2C_START; | ||||||
| 
 | #ifdef DEBUG_VERBOES | ||||||
| /** @brief Error output config.
 |                     printf("i2c master sends MSB data timeout in WRITE BYTE!\n"); | ||||||
|     @param result The value to be set. | #endif | ||||||
|  * */ |  | ||||||
| void ldc1612_set_error_config(uint16_t value) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     data[0] = (value >> 8) & 0xFF; |  | ||||||
|     data[1] = value & 0xFF; |  | ||||||
| 
 |  | ||||||
|     ldc1612_iic_write_16bits(ERROR_CONFIG_REG, data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @brief mux  config.
 |  | ||||||
|     @param result The value to be set. |  | ||||||
|  * */ |  | ||||||
| void ldc1612_set_mux_config(uint16_t value) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     data[0] = (value >> 8) & 0xFF; |  | ||||||
|     data[1] = value & 0xFF; |  | ||||||
| 
 |  | ||||||
|     ldc1612_iic_write_16bits(MUL_CONFIG_REG, data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @brief reset sensor.
 |  | ||||||
| 
 |  | ||||||
|  * */ |  | ||||||
| void ldc1612_reset_sensor(void) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     data[0] = 0x80; |  | ||||||
|     data[1] = 0x00; |  | ||||||
|     ldc1612_iic_write_16bits(SENSOR_RESET_REG, data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @brief set drive current of sensor.
 |  | ||||||
|     @param result The value to be set. |  | ||||||
|  * */ |  | ||||||
| void ldc1612_set_drive_current(uint8_t channel, uint16_t value) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     data[0] = (value >> 8) & 0xFF; |  | ||||||
|     data[1] = value & 0xFF; |  | ||||||
| 
 |  | ||||||
|     ldc1612_iic_write_16bits(SET_DRIVER_CURRENT_REG + channel, data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @brief Main config part of sensor.Contains select channel、start conversion、sleep mode、sensor activation mode、INT pin disable ..
 |  | ||||||
|     @param result The value to be set. |  | ||||||
|  * */ |  | ||||||
| void ldc1612_set_sensor_config(uint16_t value) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     data[0] = (value >> 8) & 0xFF; |  | ||||||
|     data[1] = value & 0xFF; |  | ||||||
| 
 |  | ||||||
|     ldc1612_iic_write_16bits(SENSOR_CONFIG_REG, data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ldc1612_single_ch0_config(void) { |  | ||||||
|     ldc1612_set_freq_divide(CHANNEL_0); //0x14 --0x1002
 |  | ||||||
| 
 |  | ||||||
|     ldc1612_set_LC_stabilize_time(CHANNEL_0, LC_STABILIZE_TIME_CH0); //0x10 --0x001E
 |  | ||||||
| 
 |  | ||||||
|     ldc1612_set_conversion_time(CHANNEL_0, LDC1612_CONVERSION_TIME_CH0); //0x08 --0x0546
 |  | ||||||
| 
 |  | ||||||
|     ldc1612_set_error_config(LDC1612_ERROR_CONFIG); //0x19 --0x0000)
 |  | ||||||
| 
 |  | ||||||
|     ldc1612_set_drive_current(CHANNEL_0, LDC1612_DRIVE_CURRENT); //0x1E --0x9000
 |  | ||||||
| 
 |  | ||||||
|     ldc1612_set_mux_config(LDC1612_MUX_CONFIG); //0x1B --0x020C
 |  | ||||||
| 
 |  | ||||||
|     ldc1612_set_sensor_config(LDC1612_SENSOR_CONFIG); //0x1A --0x1601
 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void ldc1612_iic_get_sensor_infomation(void) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     ldc1612_iic_read_16bits(READ_MANUFACTURER_ID, data); |  | ||||||
|     printf("\tManufacturer: 0x%x\r\n", (data[0] << 8) | data[1]); |  | ||||||
|     ldc1612_iic_read_16bits(READ_DEVICE_ID, data); |  | ||||||
|     printf("\tDevice: 0x%x\r\n", (data[0] << 8) | data[1]); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint16_t ldc1612_get_manufacturer_id(void) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     ldc1612_iic_read_16bits(READ_MANUFACTURER_ID, data); |  | ||||||
|     return (data[0] << 8) | data[1]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint16_t ldc1612_get_deveice_id(void) { |  | ||||||
|     uint8_t data[2] = {0}; |  | ||||||
|     ldc1612_iic_read_16bits(READ_DEVICE_ID, data); |  | ||||||
|     return (data[0] << 8) | data[1]; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @brief read the raw channel result from register.
 |  | ||||||
|     @param channel LDC1612 has total two channels. |  | ||||||
|     @param result raw data |  | ||||||
|  * */ |  | ||||||
| uint32_t ldc1612_get_raw_channel_result(uint8_t channel) { |  | ||||||
|     uint32_t raw_value = 0; |  | ||||||
|     uint8_t value[2] = {0}; |  | ||||||
| 
 |  | ||||||
|     ldc1612_iic_read_16bits(CONVERTION_RESULT_REG_START + channel, value); |  | ||||||
|     raw_value |= (uint32_t) ((value[0] << 8) | value[1]) << 16; |  | ||||||
|     ldc1612_iic_read_16bits(CONVERTION_RESULT_REG_START + channel + 1, value); |  | ||||||
|     raw_value |= (uint32_t) ((value[0] << 8) | value[1]); |  | ||||||
|     return ldc1612_parse_raw_result(raw_value); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /** @brief parse the data which read from data register.
 |  | ||||||
|     @param channel LDC1612 has total two channels. |  | ||||||
|     @param raw_result the raw data which read from data register,it contains error codes and sensor value; |  | ||||||
|  * */ |  | ||||||
| uint32_t ldc1612_parse_raw_result(uint32_t raw_result) { |  | ||||||
|     uint32_t calibration_value = 0; |  | ||||||
|     uint8_t error_code = 0; |  | ||||||
| 
 |  | ||||||
|     calibration_value = raw_result & 0x0FFFFFFF; |  | ||||||
|     if (0xFFFFFFF == calibration_value) { |  | ||||||
|         return 0xF0000000; |  | ||||||
|         // ERR_NC-No coil detected!!!
 |  | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|     error_code = raw_result >> 24; |             /* wait until BTC bit is set */ | ||||||
| 
 |                 while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { | ||||||
|     if (error_code & 0x80) { |                     timeout++; | ||||||
|         return 0x80000000; |  | ||||||
|         // ERR_UR-Under range error!!!
 |  | ||||||
|                 } |                 } | ||||||
|     if (error_code & 0x40) { |                 if (timeout < I2C_TIME_OUT) { | ||||||
|         return 0x40000000; |                     /* send register LSB value */ | ||||||
|         // ERR_OR-Over range error!!!
 |                     i2c_data_transmit(I2C0, data[1]); | ||||||
|     } |                     timeout = 0; | ||||||
|     if (error_code & 0x20) { |                     state = I2C_STOP; | ||||||
|         return 0x20000000; |                 } else { | ||||||
|         // ERR_WD-Watch dog timeout error!!!
 |                     timeout = 0; | ||||||
|     } |                     state = I2C_START; | ||||||
|     if (error_code & 0x10) { | #ifdef DEBUG_VERBOES | ||||||
|         return 0x10000000; |                     printf("i2c master sends LSB data timeout in WRITE BYTE!\n"); | ||||||
|         // ERR_AE-error!!!
 | #endif | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|     return raw_result; |             /* wait until BTC bit is set */ | ||||||
|  |                 while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { | ||||||
|  |                     timeout++; | ||||||
|  |                 } | ||||||
|  |                 if (timeout < I2C_TIME_OUT) { | ||||||
|  |                     state = I2C_STOP; | ||||||
|  |                     timeout = 0; | ||||||
|  |                 } else { | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_START; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|  |                     printf("i2c master sends data timeout in WRITE BYTE!\n"); | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             case I2C_STOP: | ||||||
|  |                 /* send a stop condition to I2C bus */ | ||||||
|  |                 i2c_stop_on_bus(I2C0); | ||||||
|  |             /* i2c master sends STOP signal successfully */ | ||||||
|  |                 while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { | ||||||
|  |                     timeout++; | ||||||
|  |                 } | ||||||
|  |                 if (timeout < I2C_TIME_OUT) { | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_END; | ||||||
|  |                     i2c_timeout_flag = I2C_OK; | ||||||
|  |                 } else { | ||||||
|  |                     timeout = 0; | ||||||
|  |                     state = I2C_START; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|  |                     printf("i2c master sends stop signal timeout in WRITE BYTE!\n"); | ||||||
|  | #endif | ||||||
|  |                 } | ||||||
|  |                 break; | ||||||
|  |             default: | ||||||
|  |                 state = I2C_START; | ||||||
|  |                 i2c_timeout_flag = I2C_OK; | ||||||
|  |                 timeout = 0; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|  |                 printf("i2c master sends start signal in WRITE BYTE.\n"); | ||||||
|  | #endif | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     return I2C_END; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | uint8_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) { | ||||||
| uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { |  | ||||||
|     uint8_t state = I2C_START; |     uint8_t state = I2C_START; | ||||||
|     uint8_t read_cycle = 0; |     uint8_t read_cycle = 0; | ||||||
|     uint16_t timeout = 0; |     uint16_t timeout = 0; | ||||||
| @@ -369,11 +321,12 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                         // i2c_bus_reset();
 |                         // i2c_bus_reset();
 | ||||||
|                         timeout = 0; |                         timeout = 0; | ||||||
|                         state = I2C_START; |                         state = I2C_START; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                         printf("i2c bus is busy in READ!\n"); |                         printf("i2c bus is busy in READ!\n"); | ||||||
|  | #endif | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             /* send the start signal */ |             /* send the start signal */ | ||||||
|                 delay_us(5); |  | ||||||
|                 i2c_start_on_bus(I2C0); |                 i2c_start_on_bus(I2C0); | ||||||
|                 timeout = 0; |                 timeout = 0; | ||||||
|                 state = I2C_SEND_ADDRESS; |                 state = I2C_SEND_ADDRESS; | ||||||
| @@ -385,10 +338,10 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                 } |                 } | ||||||
|                 if (timeout < I2C_TIME_OUT) { |                 if (timeout < I2C_TIME_OUT) { | ||||||
|                     if (RESET == read_cycle) { |                     if (RESET == read_cycle) { | ||||||
|                         i2c_master_addressing(I2C0, LDC1612_ADDR, I2C_TRANSMITTER); |                         i2c_master_addressing(I2C0, slave_addr, I2C_TRANSMITTER); | ||||||
|                         state = I2C_CLEAR_ADDRESS_FLAG; |                         state = I2C_CLEAR_ADDRESS_FLAG; | ||||||
|                     } else { |                     } else { | ||||||
|                         i2c_master_addressing(I2C0, LDC1612_ADDR, I2C_RECEIVER); |                         i2c_master_addressing(I2C0, slave_addr, I2C_RECEIVER); | ||||||
|                         i2c_ack_config(I2C0, I2C_ACK_DISABLE); |                         i2c_ack_config(I2C0, I2C_ACK_DISABLE); | ||||||
|                         state = I2C_CLEAR_ADDRESS_FLAG; |                         state = I2C_CLEAR_ADDRESS_FLAG; | ||||||
|                     } |                     } | ||||||
| @@ -397,7 +350,9 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                     timeout = 0; |                     timeout = 0; | ||||||
|                     state = I2C_START; |                     state = I2C_START; | ||||||
|                     read_cycle = RESET; |                     read_cycle = RESET; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                     printf("i2c master sends start signal timeout in READ!\n"); |                     printf("i2c master sends start signal timeout in READ!\n"); | ||||||
|  | #endif | ||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|             case I2C_CLEAR_ADDRESS_FLAG: |             case I2C_CLEAR_ADDRESS_FLAG: | ||||||
| @@ -417,7 +372,9 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                     timeout = 0; |                     timeout = 0; | ||||||
|                     state = I2C_START; |                     state = I2C_START; | ||||||
|                     read_cycle = RESET; |                     read_cycle = RESET; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                     printf("i2c master clears address flag timeout in READ!\n"); |                     printf("i2c master clears address flag timeout in READ!\n"); | ||||||
|  | #endif | ||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|             case I2C_TRANSMIT_DATA: |             case I2C_TRANSMIT_DATA: | ||||||
| @@ -434,7 +391,9 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                         timeout = 0; |                         timeout = 0; | ||||||
|                         state = I2C_START; |                         state = I2C_START; | ||||||
|                         read_cycle = RESET; |                         read_cycle = RESET; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                         printf("i2c master wait data buffer is empty timeout in READ!\n"); |                         printf("i2c master wait data buffer is empty timeout in READ!\n"); | ||||||
|  | #endif | ||||||
|                     } |                     } | ||||||
|                     /* wait until BTC bit is set */ |                     /* wait until BTC bit is set */ | ||||||
|                     while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { |                     while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { | ||||||
| @@ -448,7 +407,9 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                         timeout = 0; |                         timeout = 0; | ||||||
|                         state = I2C_START; |                         state = I2C_START; | ||||||
|                         read_cycle = RESET; |                         read_cycle = RESET; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                         printf("i2c master sends register address timeout in READ!\n"); |                         printf("i2c master sends register address timeout in READ!\n"); | ||||||
|  | #endif | ||||||
|                     } |                     } | ||||||
|                 } else { |                 } else { | ||||||
|                     while (number_of_byte) { |                     while (number_of_byte) { | ||||||
| @@ -473,7 +434,9 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                             timeout = 0; |                             timeout = 0; | ||||||
|                             state = I2C_START; |                             state = I2C_START; | ||||||
|                             read_cycle = 0; |                             read_cycle = 0; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                             printf("i2c master sends data timeout in READ!\n"); |                             printf("i2c master sends data timeout in READ!\n"); | ||||||
|  | #endif | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     timeout = 0; |                     timeout = 0; | ||||||
| @@ -493,7 +456,9 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                     timeout = 0; |                     timeout = 0; | ||||||
|                     state = I2C_START; |                     state = I2C_START; | ||||||
|                     read_cycle = 0; |                     read_cycle = 0; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                     printf("i2c master sends stop signal timeout in READ!\n"); |                     printf("i2c master sends stop signal timeout in READ!\n"); | ||||||
|  | #endif | ||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
| @@ -501,146 +466,9 @@ uint8_t ldc1612_iic_read_16bits(uint8_t reg_addr, uint8_t *data) { | |||||||
|                 read_cycle = 0; |                 read_cycle = 0; | ||||||
|                 i2c_timeout_flag = I2C_OK; |                 i2c_timeout_flag = I2C_OK; | ||||||
|                 timeout = 0; |                 timeout = 0; | ||||||
|  | #ifdef DEBUG_VERBOES | ||||||
|                 printf("i2c master sends start signal in READ.\n"); |                 printf("i2c master sends start signal in READ.\n"); | ||||||
|                 break; | #endif | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     return I2C_END; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uint8_t ldc1612_iic_write_16bits(uint8_t reg_addr, uint8_t data[2]) { |  | ||||||
|     uint8_t state = I2C_START; |  | ||||||
|     uint16_t timeout = 0; |  | ||||||
|     uint8_t i2c_timeout_flag = 0; |  | ||||||
| 
 |  | ||||||
|     /* enable acknowledge */ |  | ||||||
|     i2c_ack_config(I2C0, I2C_ACK_ENABLE); |  | ||||||
|     while (!(i2c_timeout_flag)) { |  | ||||||
|         switch (state) { |  | ||||||
|             case I2C_START: |  | ||||||
|                 /* i2c master sends start signal only when the bus is idle */ |  | ||||||
|                 while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     i2c_start_on_bus(I2C0); |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_SEND_ADDRESS; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c bus is busy in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             case I2C_SEND_ADDRESS: |  | ||||||
|                 /* i2c master sends START signal successfully */ |  | ||||||
|                 while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     i2c_master_addressing(I2C0, LDC1612_ADDR, I2C_TRANSMITTER); |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_CLEAR_ADDRESS_FLAG; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c master sends start signal timeout in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             case I2C_CLEAR_ADDRESS_FLAG: |  | ||||||
|                 /* address flag set means i2c slave sends ACK */ |  | ||||||
|                 while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_TRANSMIT_DATA; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c master clears address flag timeout in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             case I2C_TRANSMIT_DATA: |  | ||||||
|                 /* wait until the transmit data buffer is empty */ |  | ||||||
|                 while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     /* send IIC register address */ |  | ||||||
|                     i2c_data_transmit(I2C0, reg_addr); |  | ||||||
|                     timeout = 0; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c master sends data timeout in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             /* wait until BTC bit is set */ |  | ||||||
|                 while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     /* send register MSB value */ |  | ||||||
|                     i2c_data_transmit(I2C0, data[0]); |  | ||||||
|                     timeout = 0; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c master sends MSB data timeout in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             /* wait until BTC bit is set */ |  | ||||||
|                 while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     /* send register LSB value */ |  | ||||||
|                     i2c_data_transmit(I2C0, data[1]); |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_STOP; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c master sends LSB data timeout in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             /* wait until BTC bit is set */ |  | ||||||
|                 while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     state = I2C_STOP; |  | ||||||
|                     timeout = 0; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c master sends data timeout in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             case I2C_STOP: |  | ||||||
|                 /* send a stop condition to I2C bus */ |  | ||||||
|                 i2c_stop_on_bus(I2C0); |  | ||||||
|             /* i2c master sends STOP signal successfully */ |  | ||||||
|                 while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { |  | ||||||
|                     timeout++; |  | ||||||
|                 } |  | ||||||
|                 if (timeout < I2C_TIME_OUT) { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_END; |  | ||||||
|                     i2c_timeout_flag = I2C_OK; |  | ||||||
|                 } else { |  | ||||||
|                     timeout = 0; |  | ||||||
|                     state = I2C_START; |  | ||||||
|                     printf("i2c master sends stop signal timeout in WRITE BYTE!\n"); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             default: |  | ||||||
|                 state = I2C_START; |  | ||||||
|                 i2c_timeout_flag = I2C_OK; |  | ||||||
|                 timeout = 0; |  | ||||||
|                 printf("i2c master sends start signal in WRITE BYTE.\n"); |  | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
							
								
								
									
										278
									
								
								src/ldc1612.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								src/ldc1612.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-3. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "ldc1612.h" | ||||||
|  |  | ||||||
|  | /** @brief set conversion interval time. | ||||||
|  |     @param channel LDC1612 has total two channels. | ||||||
|  |     @param result The value to be set. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_conversion_time(uint8_t channel, uint16_t result) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (result >> 8) & 0xFF; | ||||||
|  |     data[1] = result & 0xFF; | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, SET_CONVERSION_TIME_REG_START + channel, data); | ||||||
|  | #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, SET_CONVERSION_TIME_REG_START + channel, data); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief set conversion offset. | ||||||
|  |     @param channel LDC1612 has total two channels. | ||||||
|  |     @param result The value to be set. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_conversion_offset(uint8_t channel, uint16_t result) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (result >> 8) & 0xFF; | ||||||
|  |     data[1] = result & 0xFF; | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, SET_CONVERSION_OFFSET_REG_START + channel, data); | ||||||
|  | #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, SET_CONVERSION_OFFSET_REG_START + channel, data); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief Before conversion,wait LC sensor stabilize for a short time. | ||||||
|  |     @param channel LDC1612 has total two channels. | ||||||
|  |     @param result The value to be set. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_LC_stabilize_time(uint8_t channel, uint16_t result) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (result >> 8) & 0xFF; | ||||||
|  |     data[1] = result & 0xFF; | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, SET_LC_STABILIZE_REG_START + channel, data); | ||||||
|  | #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, SET_LC_STABILIZE_REG_START + channel, data); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief set input frequency divide and fref divide. | ||||||
|  |     @param channel LDC1612 has total two channels. | ||||||
|  |     @param FIN_DIV FIN input divide | ||||||
|  |     @param FREF_DIV fref,reference frequency of sensor. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_freq_divide(uint8_t channel) { | ||||||
|  |     uint16_t value; | ||||||
|  |     uint16_t fin_div, freq_div; | ||||||
|  |     float sensor_freq; | ||||||
|  |  | ||||||
|  |     sensor_freq = 1 / (2 * 3.14 * sqrt(COIL_L_UH * COIL_C_PF * pow(10, -18))) * pow(10, -6); | ||||||
|  |  | ||||||
|  |     fin_div = (uint16_t) (sensor_freq / 8.75 + 1); | ||||||
|  |  | ||||||
|  |     if (fin_div * 4 < 40) { | ||||||
|  |         freq_div = 2; | ||||||
|  |     } else { | ||||||
|  |         freq_div = 4; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     value = fin_div << 12; | ||||||
|  |     value |= freq_div; | ||||||
|  |     // printf("\tvalue: 0x%x\r\n", value); | ||||||
|  |  | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (value >> 8) & 0xFF; | ||||||
|  |     data[1] = value & 0xFF; | ||||||
|  |     // printf("\tFIN_DIV: %d, FREF_DIV: %d\r\n", fin_div, freq_div); | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, SET_FREQ_REG_START + channel, data); | ||||||
|  | #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, SET_FREQ_REG_START + channel, data); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief Error output config. | ||||||
|  |     @param result The value to be set. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_error_config(uint16_t value) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (value >> 8) & 0xFF; | ||||||
|  |     data[1] = value & 0xFF; | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, ERROR_CONFIG_REG, data); | ||||||
|  | #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, ERROR_CONFIG_REG, data); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief mux  config. | ||||||
|  |     @param result The value to be set. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_mux_config(uint16_t value) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (value >> 8) & 0xFF; | ||||||
|  |     data[1] = value & 0xFF; | ||||||
|  |  | ||||||
|  |     #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, MUL_CONFIG_REG, data); | ||||||
|  |     #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, MUL_CONFIG_REG, data); | ||||||
|  |     #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief reset sensor. | ||||||
|  |  | ||||||
|  |  * */ | ||||||
|  | void ldc1612_reset_sensor(void) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = 0x80; | ||||||
|  |     data[1] = 0x00; | ||||||
|  |  | ||||||
|  |     #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, SENSOR_RESET_REG, data); | ||||||
|  |     #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, SENSOR_RESET_REG, data); | ||||||
|  |     #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief set drive current of sensor. | ||||||
|  |     @param result The value to be set. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_drive_current(uint8_t channel, uint16_t value) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (value >> 8) & 0xFF; | ||||||
|  |     data[1] = value & 0xFF; | ||||||
|  |  | ||||||
|  |     #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, SET_DRIVER_CURRENT_REG + channel, data); | ||||||
|  |     #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, SET_DRIVER_CURRENT_REG + channel, data); | ||||||
|  |     #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief Main config part of sensor.Contains select channel、start conversion、sleep mode、sensor activation mode、INT pin disable .. | ||||||
|  |     @param result The value to be set. | ||||||
|  |  * */ | ||||||
|  | void ldc1612_set_sensor_config(uint16_t value) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |     data[0] = (value >> 8) & 0xFF; | ||||||
|  |     data[1] = value & 0xFF; | ||||||
|  |  | ||||||
|  |     #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_write_16bits(LDC1612_ADDR, SENSOR_CONFIG_REG, data); | ||||||
|  |     #else | ||||||
|  |     i2c_write_16bits(LDC1612_ADDR, SENSOR_CONFIG_REG, data); | ||||||
|  |     #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ldc1612_single_ch0_config(void) { | ||||||
|  |     ldc1612_set_freq_divide(CHANNEL_0); //0x14 --0x1002 | ||||||
|  |  | ||||||
|  |     ldc1612_set_LC_stabilize_time(CHANNEL_0, LC_STABILIZE_TIME_CH0); //0x10 --0x001E | ||||||
|  |  | ||||||
|  |     ldc1612_set_conversion_time(CHANNEL_0, LDC1612_CONVERSION_TIME_CH0); //0x08 --0x0546 | ||||||
|  |  | ||||||
|  |     ldc1612_set_error_config(LDC1612_ERROR_CONFIG); //0x19 --0x0000) | ||||||
|  |  | ||||||
|  |     ldc1612_set_drive_current(CHANNEL_0, LDC1612_DRIVE_CURRENT); //0x1E --0x9000 | ||||||
|  |  | ||||||
|  |     ldc1612_set_mux_config(LDC1612_MUX_CONFIG); //0x1B --0x020C | ||||||
|  |  | ||||||
|  |     ldc1612_set_sensor_config(LDC1612_SENSOR_CONFIG); //0x1A --0x1601 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ldc1612_iic_get_sensor_infomation(void) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_read_16bits(LDC1612_ADDR, READ_MANUFACTURER_ID, data); | ||||||
|  | #else | ||||||
|  |     i2c_read_16bits(LDC1612_ADDR, READ_MANUFACTURER_ID, data); | ||||||
|  | #endif | ||||||
|  |     printf("\tManufacturer: 0x%x", (data[0] << 8) | data[1]); | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_read_16bits(LDC1612_ADDR, READ_DEVICE_ID, data); | ||||||
|  | #else | ||||||
|  |     i2c_read_16bits(LDC1612_ADDR, READ_DEVICE_ID, data); | ||||||
|  | #endif | ||||||
|  |     printf("\tDevice: 0x%x", (data[0] << 8) | data[1]); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint16_t ldc1612_get_manufacturer_id(void) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_read_16bits(LDC1612_ADDR, READ_MANUFACTURER_ID, data); | ||||||
|  | #else | ||||||
|  |     i2c_read_16bits(LDC1612_ADDR, READ_MANUFACTURER_ID, data); | ||||||
|  | #endif | ||||||
|  |     return (data[0] << 8) | data[1]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint16_t ldc1612_get_deveice_id(void) { | ||||||
|  |     uint8_t data[2] = {0}; | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_read_16bits(LDC1612_ADDR, READ_DEVICE_ID, data); | ||||||
|  | #else | ||||||
|  |     i2c_read_16bits(LDC1612_ADDR, READ_DEVICE_ID, data); | ||||||
|  | #endif | ||||||
|  |     return (data[0] << 8) | data[1]; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief read the raw channel result from register. | ||||||
|  |     @param channel LDC1612 has total two channels. | ||||||
|  |     @param result raw data | ||||||
|  |  * */ | ||||||
|  | uint32_t ldc1612_get_raw_channel_result(uint8_t channel) { | ||||||
|  |     uint32_t raw_value = 0; | ||||||
|  |     uint8_t value[2] = {0}; | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_read_16bits(LDC1612_ADDR, CONVERTION_RESULT_REG_START + channel, value); | ||||||
|  | #else | ||||||
|  |     i2c_read_16bits(LDC1612_ADDR, CONVERTION_RESULT_REG_START + channel, value); | ||||||
|  | #endif | ||||||
|  |     raw_value |= (uint32_t) ((value[0] << 8) | value[1]) << 16; | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_read_16bits(LDC1612_ADDR, CONVERTION_RESULT_REG_START + channel + 1, value); | ||||||
|  | #else | ||||||
|  |     i2c_read_16bits(LDC1612_ADDR, CONVERTION_RESULT_REG_START + channel + 1, value); | ||||||
|  | #endif | ||||||
|  |     raw_value |= (uint32_t) ((value[0] << 8) | value[1]); | ||||||
|  |     return ldc1612_parse_raw_result(raw_value); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /** @brief parse the data which read from data register. | ||||||
|  |     @param channel LDC1612 has total two channels. | ||||||
|  |     @param raw_result the raw data which read from data register,it contains error codes and sensor value; | ||||||
|  |  * */ | ||||||
|  | uint32_t ldc1612_parse_raw_result(uint32_t raw_result) { | ||||||
|  |     uint32_t calibration_value = 0; | ||||||
|  |     uint8_t error_code = 0; | ||||||
|  |  | ||||||
|  |     calibration_value = raw_result & 0x0FFFFFFF; | ||||||
|  |     if (0xFFFFFFF == calibration_value) { | ||||||
|  |         return 0xF0000000; | ||||||
|  |         // ERR_NC-No coil detected!!! | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     error_code = raw_result >> 24; | ||||||
|  |  | ||||||
|  |     if (error_code & 0x80) { | ||||||
|  |         return 0x80000000; | ||||||
|  |         // ERR_UR-Under range error!!! | ||||||
|  |     } | ||||||
|  |     if (error_code & 0x40) { | ||||||
|  |         return 0x40000000; | ||||||
|  |         // ERR_OR-Over range error!!! | ||||||
|  |     } | ||||||
|  |     if (error_code & 0x20) { | ||||||
|  |         return 0x20000000; | ||||||
|  |         // ERR_WD-Watch dog timeout error!!! | ||||||
|  |     } | ||||||
|  |     if (error_code & 0x10) { | ||||||
|  |         return 0x10000000; | ||||||
|  |         // ERR_AE-error!!! | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return raw_result; | ||||||
|  | } | ||||||
							
								
								
									
										32
									
								
								src/led.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								src/led.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-20. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "led.h" | ||||||
|  |  | ||||||
|  | void led_config(void) { | ||||||
|  |     rcu_periph_clock_enable(LED_RCU); | ||||||
|  |  | ||||||
|  |     gpio_mode_set(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PIN); | ||||||
|  |     gpio_output_options_set(LED_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED_PIN); | ||||||
|  |     gpio_bit_write(LED_PORT, LED_PIN, SET); | ||||||
|  |  | ||||||
|  |     rcu_periph_clock_enable(LED_BLINK_TIMER_RCU); | ||||||
|  |     timer_deinit(LED_BLINK_TIMER); | ||||||
|  |  | ||||||
|  |     timer_parameter_struct timer_initpara; | ||||||
|  |     timer_struct_para_init(&timer_initpara); | ||||||
|  |     timer_initpara.prescaler = 7199; | ||||||
|  |     timer_initpara.alignedmode = TIMER_COUNTER_EDGE; | ||||||
|  |     timer_initpara.counterdirection = TIMER_COUNTER_UP; | ||||||
|  |     timer_initpara.period = 9999; | ||||||
|  |     timer_initpara.clockdivision = TIMER_CKDIV_DIV1; | ||||||
|  |     timer_init(LED_BLINK_TIMER, &timer_initpara); | ||||||
|  |  | ||||||
|  |     timer_auto_reload_shadow_enable(LED_BLINK_TIMER); | ||||||
|  |     timer_interrupt_enable(LED_BLINK_TIMER, TIMER_INT_UP); | ||||||
|  |  | ||||||
|  |     timer_enable(LED_BLINK_TIMER); | ||||||
|  |  | ||||||
|  |     nvic_irq_enable(LED_BLINK_IRQ, 2); | ||||||
|  | } | ||||||
							
								
								
									
										59
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										59
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -5,39 +5,6 @@ | |||||||
|     \version 2024-02-22, V2.1.0, firmware for GD32E23x |     \version 2024-02-22, V2.1.0, firmware for GD32E23x | ||||||
| */ | */ | ||||||
| #include "main.h" | #include "main.h" | ||||||
| #include <stdio.h> |  | ||||||
| #include "gd32e23x.h" |  | ||||||
| #include "systick.h" |  | ||||||
| #include "gd32e23x_libopt.h" |  | ||||||
| #include "RS485.h" |  | ||||||
| #include "LDC1612.h" |  | ||||||
|  |  | ||||||
| void led_config(void) { |  | ||||||
|     rcu_periph_clock_enable(LED_RCU); |  | ||||||
|  |  | ||||||
|     gpio_mode_set(LED_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED_PIN); |  | ||||||
|     gpio_output_options_set(LED_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED_PIN); |  | ||||||
|     gpio_bit_write(LED_PORT, LED_PIN, SET); |  | ||||||
|  |  | ||||||
|     rcu_periph_clock_enable(LED_TIMER_RCU); |  | ||||||
|     timer_deinit(LED_TIMER); |  | ||||||
|  |  | ||||||
|     timer_parameter_struct timer_initpara; |  | ||||||
|     timer_struct_para_init(&timer_initpara); |  | ||||||
|     timer_initpara.prescaler = 799; |  | ||||||
|     timer_initpara.alignedmode = TIMER_COUNTER_EDGE; |  | ||||||
|     timer_initpara.counterdirection = TIMER_COUNTER_UP; |  | ||||||
|     timer_initpara.period = 999; |  | ||||||
|     timer_initpara.clockdivision = TIMER_CKDIV_DIV1; |  | ||||||
|     timer_init(LED_TIMER, &timer_initpara); |  | ||||||
|  |  | ||||||
|     timer_auto_reload_shadow_enable(LED_TIMER); |  | ||||||
|     timer_interrupt_enable(LED_TIMER, TIMER_INT_UP); |  | ||||||
|  |  | ||||||
|     timer_enable(LED_TIMER); |  | ||||||
|  |  | ||||||
|     nvic_irq_enable(LED_IRQ, 2); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /*! | /*! | ||||||
|     \brief      main function |     \brief      main function | ||||||
| @@ -46,24 +13,34 @@ void led_config(void) { | |||||||
|     \retval     none |     \retval     none | ||||||
| */ | */ | ||||||
| int main(void) { | int main(void) { | ||||||
|  |     setbuf(stdout, NULL); | ||||||
|     /* configure systick */ |     /* configure systick */ | ||||||
|     systick_config(); |     systick_config(); | ||||||
|     RS485_config(); |     /* configure USART */ | ||||||
|  |     rs485_config(); | ||||||
|  |     /* configure LED */ | ||||||
|     led_config(); |     led_config(); | ||||||
|     i2c_gpio_config(); |  | ||||||
|  |     /* configure I2C */ | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_config(); | ||||||
|  | #else | ||||||
|     i2c_config(); |     i2c_config(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|     uint32_t raw_value = 0; | #ifdef DEBUG_VERBOES | ||||||
|  |  | ||||||
|     delay_ms(500); |  | ||||||
|     ldc1612_iic_get_sensor_infomation(); |     ldc1612_iic_get_sensor_infomation(); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     /* configure LDC1612 */ | ||||||
|     ldc1612_single_ch0_config(); |     ldc1612_single_ch0_config(); | ||||||
|  |  | ||||||
|  |     /* Initialize watchdog */ | ||||||
|  |     watchdog_init(); | ||||||
|  |  | ||||||
|     while (1) { |     while (1) { | ||||||
|         delay_ms(500); |         delay_ms(99); | ||||||
|         raw_value = ldc1612_get_raw_channel_result(CHANNEL_0); |         fwdgt_counter_reload(); | ||||||
|         printf("data:%ld\r\n",raw_value); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,63 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by yelv1 on 24-9-22. |  | ||||||
| // |  | ||||||
| #include "peripheral.h" |  | ||||||
| #include "gd32e23x.h" |  | ||||||
|  |  | ||||||
| void usart_config(void) |  | ||||||
| { |  | ||||||
|     rcu_periph_clock_enable(RCU_GPIOA); |  | ||||||
|     rcu_periph_clock_enable(RCU_USART0); |  | ||||||
|  |  | ||||||
|     gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_3); |  | ||||||
|     gpio_af_set(GPIOA, GPIO_AF_1, GPIO_PIN_2); |  | ||||||
|  |  | ||||||
|     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_3); |  | ||||||
|     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_3); |  | ||||||
|     gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_2); |  | ||||||
|     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_2); |  | ||||||
|  |  | ||||||
|     usart_deinit(USART0); |  | ||||||
|     usart_baudrate_set(USART0, 115200U); |  | ||||||
|     usart_receive_config(USART0, USART_RECEIVE_ENABLE); |  | ||||||
|     usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); |  | ||||||
|  |  | ||||||
|     usart_enable(USART0); |  | ||||||
|  |  | ||||||
|     gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_4); |  | ||||||
|     gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4); |  | ||||||
|  |  | ||||||
|     gpio_bit_write(GPIOA, GPIO_PIN_4, SET); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| /*! |  | ||||||
|     \brief      led blink configuration |  | ||||||
|     \param[in]  none |  | ||||||
|     \param[out] none |  | ||||||
|     \retval     none |  | ||||||
| */ |  | ||||||
| void led_blink_config(void) |  | ||||||
| { |  | ||||||
|     rcu_periph_clock_enable(RCU_GPIOB); |  | ||||||
|  |  | ||||||
|     gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1); |  | ||||||
|     gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_1); |  | ||||||
|     gpio_bit_write(GPIOB, GPIO_PIN_1, SET); |  | ||||||
|  |  | ||||||
|     rcu_periph_clock_enable(RCU_TIMER13); |  | ||||||
|     timer_deinit(RCU_TIMER13); |  | ||||||
|  |  | ||||||
|     timer_parameter_struct timer_initpara; |  | ||||||
|     timer_struct_para_init(&timer_initpara); |  | ||||||
|     timer_initpara.prescaler        =7199; |  | ||||||
|     timer_initpara.alignedmode      =TIMER_COUNTER_EDGE; |  | ||||||
|     timer_initpara.counterdirection =TIMER_COUNTER_UP; |  | ||||||
|     timer_initpara.period           =999; |  | ||||||
|     timer_initpara.clockdivision    =TIMER_CKDIV_DIV1; |  | ||||||
|     timer_init(TIMER13, &timer_initpara); |  | ||||||
|  |  | ||||||
|     timer_auto_reload_shadow_enable(TIMER13); |  | ||||||
|     timer_interrupt_enable(TIMER13, TIMER_INT_UP); |  | ||||||
|     nvic_irq_enable(TIMER13_IRQn, 0); |  | ||||||
|     timer_enable(TIMER13); |  | ||||||
| } |  | ||||||
							
								
								
									
										160
									
								
								src/rs485.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								src/rs485.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,160 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-3. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "rs485.h" | ||||||
|  |  | ||||||
|  | uint8_t package_header[3] = {0xB5, 0xF0, 0x04}; | ||||||
|  | uint8_t package_data[4] = {0}; | ||||||
|  |  | ||||||
|  | void rs485_config(void) { | ||||||
|  |     rcu_periph_clock_enable(RS485_GPIO_RCU); | ||||||
|  |     rcu_periph_clock_enable(RS485_RCU); | ||||||
|  |  | ||||||
|  |     gpio_af_set(RS485_GPIO_PORT, GPIO_AF_1, GPIO_PIN_2 | GPIO_PIN_3); | ||||||
|  |  | ||||||
|  |     /* configure USART Tx&Rx as alternate function push-pull */ | ||||||
|  |     gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, RS485_TX_PIN | RS485_RX_PIN); | ||||||
|  |     gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, RS485_TX_PIN | RS485_RX_PIN); | ||||||
|  |  | ||||||
|  |     /* configure RS485 EN Pin */ | ||||||
|  |     gpio_mode_set(RS485_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, RS485_EN_PIN); | ||||||
|  |     gpio_output_options_set(RS485_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, RS485_EN_PIN); | ||||||
|  |     gpio_bit_write(RS485_GPIO_PORT, RS485_EN_PIN, SET); | ||||||
|  |  | ||||||
|  |     /* USART configure */ | ||||||
|  |     usart_deinit(RS485_PHY); | ||||||
|  |     usart_baudrate_set(RS485_PHY, RS485_BAUDRATE); | ||||||
|  |     usart_receive_config(RS485_PHY, USART_RECEIVE_ENABLE); | ||||||
|  |     usart_transmit_config(RS485_PHY, USART_TRANSMIT_ENABLE); | ||||||
|  |  | ||||||
|  |     usart_enable(RS485_PHY); | ||||||
|  |  | ||||||
|  |     nvic_irq_enable(USART0_IRQn, 0); | ||||||
|  |     usart_interrupt_enable(RS485_PHY, USART_INT_RBNE); | ||||||
|  |     usart_interrupt_enable(RS485_PHY, USART_INT_IDLE); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void process_command(uint8_t *cmd, size_t length) { | ||||||
|  |     char combined_str[3]; | ||||||
|  |     validation_result_t validate = VALIDATION_SUCCESS; | ||||||
|  |  | ||||||
|  |     validate = (validate_package_header(cmd) | | ||||||
|  |                 validate_package_type(cmd) | | ||||||
|  |                 validate_data_length(cmd) | | ||||||
|  |                 validate_package_crc(cmd, length)); | ||||||
|  |  | ||||||
|  |     switch (validate) { | ||||||
|  |         case VALIDATION_SUCCESS: | ||||||
|  |             // printf("%d", length); | ||||||
|  |             sprintf(combined_str, "%c%c", cmd[3], cmd[4]); | ||||||
|  |             if (strcmp(combined_str, "M1") == 0) { | ||||||
|  |                 eddy_current_value_report(); | ||||||
|  |             } else if (strcmp(combined_str, "M2") == 0) | ||||||
|  |             { | ||||||
|  |                 tempture_value_report(); | ||||||
|  |             } else if (strcmp(combined_str, "M3") == 0) | ||||||
|  |             { | ||||||
|  |                 printf("%c%c%c%c%c%c", 0xB5, 0xF1, 0x02, 0x6F, 0x6B, 0xCC); | ||||||
|  |                 fwdgt_reset_mcu(); | ||||||
|  |             } else { | ||||||
|  |                 printf("%c%c%c%c%c%c%c", 0xB5, 0xF0, 0x03, 0x65, 0x72, 0x72, 0x3C); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             break; | ||||||
|  |         case VALIDATION_CRC_ERROR: | ||||||
|  |             printf("%c%c%c%c%c%c%c", 0xB5, 0xF1, 0x03, 0x65, 0x72, 0x72, 0x3D); | ||||||
|  |             break; | ||||||
|  |         case VALIDATION_HEADER_ERROR: | ||||||
|  |             printf("%c%c%c%c%c%c%c", 0xB5, 0xF2, 0x03, 0x65, 0x72, 0x72, 0x3E); | ||||||
|  |             break; | ||||||
|  |         case VALIDATION_TYPE_ERROR: | ||||||
|  |             printf("%c%c%c%c%c%c%c", 0xB5, 0xF3, 0x03, 0x65, 0x72, 0x72, 0x3F); | ||||||
|  |             break; | ||||||
|  |         case VALIDATION_LENGTH_ERROR: | ||||||
|  |             printf("%c%c%c%c%c%c%c", 0xB5, 0xF4, 0x03, 0x65, 0x72, 0x72, 0x40); | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint8_t calculate_crc(uint8_t data[], uint8_t data_length) { | ||||||
|  |     uint8_t crc = 0; | ||||||
|  |  | ||||||
|  |     for (uint8_t i = 1; i < data_length - 1; i++) { | ||||||
|  |         crc += data[i]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return (uint8_t) (crc & 0xFF); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | validation_result_t validate_package_crc(uint8_t *data, uint8_t data_length) { | ||||||
|  |     if (data[data_length - 1] == calculate_crc(data, data_length) && data_length == 3 + data[2] + 1) { | ||||||
|  |         return VALIDATION_SUCCESS; | ||||||
|  |     } else { | ||||||
|  |         return VALIDATION_CRC_ERROR; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | validation_result_t validate_package_header(uint8_t *data) { | ||||||
|  |     if (data[0] == PROTOCOL_PACKAGE_HEADER) { | ||||||
|  |         return VALIDATION_SUCCESS; | ||||||
|  |     } else { | ||||||
|  |         return VALIDATION_HEADER_ERROR; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | validation_result_t validate_package_type(uint8_t *data) { | ||||||
|  |     if (data[1] == PROTOCOL_BOARD_TYPE) { | ||||||
|  |         return VALIDATION_SUCCESS; | ||||||
|  |     } else { | ||||||
|  |         return VALIDATION_TYPE_ERROR; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | validation_result_t validate_data_length(uint8_t *data) { | ||||||
|  |     if (data[2] == PROTOCOL_PACKAGE_LENGTH) { | ||||||
|  |         return VALIDATION_SUCCESS; | ||||||
|  |     } else { | ||||||
|  |         return VALIDATION_LENGTH_ERROR; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void eddy_current_value_report(void) { | ||||||
|  |     static uint32_t eddy_current_value_uint32 = 0; | ||||||
|  |  | ||||||
|  |     eddy_current_value_uint32 = ldc1612_get_raw_channel_result(CHANNEL_0); | ||||||
|  |  | ||||||
|  |     package_data[0] = (eddy_current_value_uint32 >> 24) & 0xFF; | ||||||
|  |     package_data[1] = (eddy_current_value_uint32 >> 16) & 0xFF; | ||||||
|  |     package_data[2] = (eddy_current_value_uint32 >> 8) & 0xFF; | ||||||
|  |     package_data[3] = eddy_current_value_uint32 & 0xFF; | ||||||
|  |  | ||||||
|  |     uint8_t combined_data[7]; | ||||||
|  |     memcpy(combined_data, package_header, 3); | ||||||
|  |     memcpy(combined_data + 3, package_data, 4); | ||||||
|  |  | ||||||
|  |     printf("%c%c%c", package_header[0], package_header[1], package_header[2]); | ||||||
|  |     printf("%c%c%c%c", package_data[0], package_data[1], package_data[2], package_data[3]); | ||||||
|  |     printf("%c", calculate_crc(combined_data, 8)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void tempture_value_report(void) { | ||||||
|  |     static uint32_t temperature_uint32 = 0; | ||||||
|  |  | ||||||
|  |     temperature_uint32 = tmp112a_get_raw_channel_result(); | ||||||
|  |  | ||||||
|  |     package_data[0] = (temperature_uint32 >> 24) & 0xFF; | ||||||
|  |     package_data[1] = (temperature_uint32 >> 16) & 0xFF; | ||||||
|  |     package_data[2] = (temperature_uint32 >> 8) & 0xFF; | ||||||
|  |     package_data[3] = temperature_uint32 & 0xFF; | ||||||
|  |  | ||||||
|  |     uint8_t combined_data[7]; | ||||||
|  |     memcpy(combined_data, package_header, 3); | ||||||
|  |     memcpy(combined_data + 3, package_data, 4); | ||||||
|  |  | ||||||
|  |     printf("%c%c%c", package_header[0], package_header[1], package_header[2]); | ||||||
|  |     printf("%c%c%c%c", package_data[0], package_data[1], package_data[2], package_data[3]); | ||||||
|  |     printf("%c", calculate_crc(combined_data, 8)); | ||||||
|  | } | ||||||
							
								
								
									
										217
									
								
								src/soft_i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								src/soft_i2c.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-28. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "soft_i2c.h" | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      delay | ||||||
|  |     \param[in]  none | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     none | ||||||
|  | */ | ||||||
|  | void soft_i2c_delay(void) { | ||||||
|  |     delay_us(20); // Adjust delay as needed | ||||||
|  |     /* delay to freq | ||||||
|  |      *  15KHz: delay_us(20); | ||||||
|  |      *  65KHz: delay_us(1); | ||||||
|  |      */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      configure the software IIC GPIO | ||||||
|  |     \param[in]  none | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     none | ||||||
|  | */ | ||||||
|  | void soft_i2c_config(void) { | ||||||
|  |     rcu_periph_clock_enable(RCU_GPIO_I2C); | ||||||
|  |  | ||||||
|  |     gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SCL_PIN); | ||||||
|  |     gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN); | ||||||
|  |  | ||||||
|  |     gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SDA_PIN); | ||||||
|  |     gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); | ||||||
|  |  | ||||||
|  |     I2C_SCL_HIGH(); | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      generate I2C start signal | ||||||
|  |     \param[in]  none | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     none | ||||||
|  | */ | ||||||
|  | void soft_i2c_start(void) { | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  |     I2C_SCL_HIGH(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SDA_LOW(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SCL_LOW(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      generate I2C stop signal | ||||||
|  |     \param[in]  none | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     none | ||||||
|  | */ | ||||||
|  | void soft_i2c_stop(void) { | ||||||
|  |     // sda_out(); | ||||||
|  |     I2C_SCL_LOW(); | ||||||
|  |     I2C_SDA_LOW(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SCL_HIGH(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      send I2C ACK signal | ||||||
|  |     \param[in]  none | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     none | ||||||
|  | */ | ||||||
|  | void soft_i2c_send_ack(void) { | ||||||
|  |     // sda_out(); | ||||||
|  |     I2C_SDA_LOW(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SCL_HIGH(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SCL_LOW(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      send I2C NACK signal | ||||||
|  |     \param[in]  none | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     none | ||||||
|  | */ | ||||||
|  | void soft_i2c_send_nack(void) { | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SCL_HIGH(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SCL_LOW(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      wait I2C ACK signal | ||||||
|  |     \param[in]  none | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     0: ACK received, 1: ACK not received | ||||||
|  | */ | ||||||
|  | uint8_t soft_i2c_wait_ack(void) { | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     I2C_SCL_HIGH(); | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     uint8_t ack = !I2C_SDA_READ(); | ||||||
|  |     I2C_SCL_LOW(); | ||||||
|  |     return ack; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      send a byte via I2C | ||||||
|  |     \param[in]  byte: byte to be sent | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     none | ||||||
|  | */ | ||||||
|  | void soft_i2c_send_byte(uint8_t byte) { | ||||||
|  |     // sda_out(); | ||||||
|  |     for (int i = 0; i < 8; i++) { | ||||||
|  |         if (byte & 0x80) { | ||||||
|  |             I2C_SDA_HIGH(); | ||||||
|  |         } else { | ||||||
|  |             I2C_SDA_LOW(); | ||||||
|  |         } | ||||||
|  |         byte <<= 1; | ||||||
|  |         soft_i2c_delay(); | ||||||
|  |         I2C_SCL_HIGH(); | ||||||
|  |         soft_i2c_delay(); | ||||||
|  |         I2C_SCL_LOW(); | ||||||
|  |         soft_i2c_delay(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /*! | ||||||
|  |     \brief      receive a byte via I2C | ||||||
|  |     \param[in]  ack: 1: send ACK, 0: send NACK | ||||||
|  |     \param[out] none | ||||||
|  |     \retval     received byte | ||||||
|  | */ | ||||||
|  | uint8_t soft_i2c_receive_byte(uint8_t ack) { | ||||||
|  |     uint8_t byte = 0; | ||||||
|  |     I2C_SDA_HIGH(); | ||||||
|  |     for (int i = 0; i < 8; i++) { | ||||||
|  |         byte <<= 1; | ||||||
|  |         I2C_SCL_HIGH(); | ||||||
|  |         soft_i2c_delay(); | ||||||
|  |         if (I2C_SDA_READ()) { | ||||||
|  |             byte |= 0x01; | ||||||
|  |         } | ||||||
|  |         I2C_SCL_LOW(); | ||||||
|  |         soft_i2c_delay(); | ||||||
|  |     } | ||||||
|  |     if (ack) { | ||||||
|  |         soft_i2c_send_ack(); | ||||||
|  |     } else { | ||||||
|  |         soft_i2c_send_nack(); | ||||||
|  |     } | ||||||
|  |     return byte; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint8_t soft_i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[2]) { | ||||||
|  |     soft_i2c_start(); | ||||||
|  |     soft_i2c_send_byte(slave_addr); | ||||||
|  |     if (!soft_i2c_wait_ack()) { | ||||||
|  |         soft_i2c_stop(); | ||||||
|  |         return SOFT_I2C_FAIL; | ||||||
|  |     } | ||||||
|  |     soft_i2c_send_byte(reg_addr); | ||||||
|  |     if (!soft_i2c_wait_ack()) { | ||||||
|  |         soft_i2c_stop(); | ||||||
|  |         return SOFT_I2C_FAIL; | ||||||
|  |     } | ||||||
|  |     soft_i2c_send_byte(data[0]); | ||||||
|  |     if (!soft_i2c_wait_ack()) { | ||||||
|  |         soft_i2c_stop(); | ||||||
|  |         return SOFT_I2C_FAIL; | ||||||
|  |     } | ||||||
|  |     soft_i2c_send_byte(data[1]); | ||||||
|  |     if (soft_i2c_wait_ack()){} | ||||||
|  |     soft_i2c_stop(); | ||||||
|  |     return SOFT_I2C_OK; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint8_t soft_i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) | ||||||
|  | { | ||||||
|  |     soft_i2c_start(); | ||||||
|  |     soft_i2c_send_byte(slave_addr); | ||||||
|  |     if (!soft_i2c_wait_ack()) { | ||||||
|  |         soft_i2c_stop(); | ||||||
|  |         return SOFT_I2C_FAIL; | ||||||
|  |     } | ||||||
|  |     soft_i2c_send_byte(reg_addr); | ||||||
|  |     if (!soft_i2c_wait_ack()) { | ||||||
|  |         soft_i2c_stop(); | ||||||
|  |         return SOFT_I2C_FAIL; | ||||||
|  |     } | ||||||
|  |     soft_i2c_start(); | ||||||
|  |     soft_i2c_send_byte(slave_addr | 0x01); | ||||||
|  |     if (!soft_i2c_wait_ack()) { | ||||||
|  |         soft_i2c_stop(); | ||||||
|  |         return SOFT_I2C_FAIL; | ||||||
|  |     } | ||||||
|  |     soft_i2c_delay(); | ||||||
|  |     data[0] = soft_i2c_receive_byte(1); | ||||||
|  |     data[1] = soft_i2c_receive_byte(0); | ||||||
|  |     soft_i2c_stop(); | ||||||
|  |     return SOFT_I2C_OK; | ||||||
|  | } | ||||||
							
								
								
									
										21
									
								
								src/tmp112.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/tmp112.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | // | ||||||
|  | // Created by dell on 24-12-20. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "tmp112.h" | ||||||
|  |  | ||||||
|  | uint32_t tmp112a_get_raw_channel_result(void) { | ||||||
|  |     uint16_t raw_value = 0; | ||||||
|  |     uint8_t value[2] = {0}; | ||||||
|  |  | ||||||
|  |     // ldc1612_iic_read_16bits(CONVERTION_RESULT_REG_START + channel, value); | ||||||
|  |  | ||||||
|  | #ifdef SOFTWARE_IIC | ||||||
|  |     soft_i2c_read_16bits(TMP112A_ADDR, TMP112A_TEMP_REG, value); | ||||||
|  | #else | ||||||
|  |     i2c_read_16bits(TMP112A_ADDR, TMP112A_TEMP_REG, value); | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |     raw_value = ((uint16_t) (value[0] << 4) | (value[1]>>4)); | ||||||
|  |     return (raw_value * 625); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user