diff --git a/stm32f4/CMakeLists.txt b/stm32f4/CMakeLists.txt index 19cccc2..7f7734a 100755 --- a/stm32f4/CMakeLists.txt +++ b/stm32f4/CMakeLists.txt @@ -24,7 +24,9 @@ add_definitions(-DUSE_STDPERIPH_DRIVER) enable_language(ASM) add_executable(${PROJ_NAME}.elf main.c) -target_sources(${PROJ_NAME}.elf PUBLIC start.S) +target_sources(${PROJ_NAME}.elf PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/start.S) +target_sources(${PROJ_NAME}.elf PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../lark1s/lark1s.c) +target_include_directories(${PROJ_NAME}.elf PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../lark1s) add_subdirectory(./driver driver) target_link_libraries(${PROJ_NAME}.elf driver) diff --git a/stm32f4/src/CMakeLists.txt b/stm32f4/src/CMakeLists.txt index d04ad20..a39e1dd 100755 --- a/stm32f4/src/CMakeLists.txt +++ b/stm32f4/src/CMakeLists.txt @@ -6,8 +6,9 @@ dwin.c ) add_library(src STATIC ${FILELIST}) -target_include_directories(src PUBLIC ../driver/cmsis) -target_include_directories(src PUBLIC ../driver/inc) -target_include_directories(src PUBLIC .) +target_include_directories(src PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../driver/cmsis) +target_include_directories(src PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../driver/inc) +target_include_directories(src PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(src PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../lark1s) target_link_libraries(src driver) diff --git a/stm32f4/src/dwin.c b/stm32f4/src/dwin.c index ba51256..c8d69e0 100644 --- a/stm32f4/src/dwin.c +++ b/stm32f4/src/dwin.c @@ -2,6 +2,7 @@ #include "stm32f4xx_gpio.h" #include "stm32f4xx_usart.h" #include "stm32f4xx_dma.h" +#include "lark1s.h" #include "dwin.h" #define DWIN_TX_STREAM DMA1_Stream6 @@ -90,14 +91,138 @@ void dwin_send(uint16_t len) DMA_Cmd(DWIN_TX_STREAM, ENABLE); } +static void dwin_endian_reverse_4byte(uint8_t *buffer, uint32_t val) +{ + buffer[0] = (uint8_t)((val >> 24) & 0xFF); + buffer[1] = (uint8_t)((val >> 16) & 0xFF); + buffer[2] = (uint8_t)((val >> 8) & 0xFF); + buffer[3] = (uint8_t)(val & 0xFF); +} + +static void dwin_endian_reverse_2byte(uint8_t *buffer, uint16_t val) +{ + buffer[0] = (uint8_t)((val >> 8) & 0xFF); + buffer[1] = (uint8_t)(val & 0xFF); +} + void dwin_loop(void) { static uint32_t ms = 0; + static int flag = 0; + uint16_t len; + uint16_t i; - if (system_tick_cnt < (ms + 500)) { + if (system_tick_cnt < (ms + 200)) { return; } ms = system_tick_cnt; + len = 0; + if (flag == 0) { + /* read control data */ + dwin_buff_tx[len++] = 0x5A; + dwin_buff_tx[len++] = 0xA5; /* frame head */ + dwin_buff_tx[len++] = 0x04; /* length */ + dwin_buff_tx[len++] = 0x83; /* read operation */ + dwin_buff_tx[len++] = (DWIN_DATA_CTRL_ADDR >> 8) & 0xFF; /* address high byte */ + dwin_buff_tx[len++] = DWIN_DATA_CTRL_ADDR & 0xFF; /* address low byte */ + dwin_buff_tx[len++] = DWIN_DATA_CTRL_LENG; /* data length to be read */ + } else { + /* write display data */ + dwin_buff_tx[len++] = 0x5A; + dwin_buff_tx[len++] = 0xA5; /* frame head */ + dwin_buff_tx[len++] = DWIN_DATA_DISP_LENG * 2 + 3; /* length */ + dwin_buff_tx[len++] = 0x82; /* write operation */ + dwin_buff_tx[len++] = (DWIN_DATA_DISP_ADDR >> 8) & 0xFF; /* address high byte */ + dwin_buff_tx[len++] = DWIN_DATA_DISP_ADDR & 0xFF; /* address low byte */ + /* gas name */ + for (i = 0; i < 12; i++) { /* lark-1s gas name max 12 byte */ + if (lark1s_gas_info.gas_name[i] > ' ') { + break; + } + } + for (uint16_t j = 0; j < 12 - i; j++) { /* lark-1s gas name max 12 byte */ + dwin_buff_tx[len++] = lark1s_gas_info.gas_name[i + j]; + } + for (uint16_t j = 0; j < 16 - (12 - i); j++) { /* dwin support max 16 byte */ + dwin_buff_tx[len++] = ' '; + } + /* sn */ + for (uint16_t j = 0; j < 16; j++) { + dwin_buff_tx[len++] = sn[j]; + } + /* concentration */ + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_data.gas3_reading); + len += 4; + /* unit name */ + for (i = 0; i < 8; i++) { /* lark-1s unit name max 8 byte */ + if (lark1s_gas_info.unit_name[i] > ' ') { + break; + } + } + for (uint16_t j = 0; j < 8 - i; j++) { /* lark-1s unit name max 8 byte */ + dwin_buff_tx[len++] = lark1s_gas_info.unit_name[i + j]; + } + for (uint16_t j = 0; j < 16 - (8 - i); j++) { /* dwin support max 16 byte */ + dwin_buff_tx[len++] = ' '; + } + /* detector temperature */ + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_data.det_temp); + len += 4; + /* sig CTS */ + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_data.cts_gas3); + len += 4; + /* ref CTS */ + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_data.cts_ref); + len += 4; + /* air pressure */ + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_data.air_pressure); + len += 4; + /* range */ + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_info.range); + len += 4; + /* min calibration */ + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_info.min_cali); + len += 4; + /* status */ + dwin_endian_reverse_2byte(dwin_buff_tx + len, lark1s_status.zero_record[2]); + len += 2; + dwin_endian_reverse_2byte(dwin_buff_tx + len, lark1s_status.span_record[2]); + len += 2; + dwin_endian_reverse_2byte(dwin_buff_tx + len, lark1s_status.active); + len += 2; + dwin_endian_reverse_2byte(dwin_buff_tx + len, lark1s_status.restore); + len += 2; + /* zero calibration */ + if (lark1s_gas_cali_data.available & 1) { + dwin_buff_tx[len++] = 'N'; + } else { + dwin_buff_tx[len++] = 'Y'; + } + dwin_buff_tx[len++] = ' '; + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_cali_data.zero_det_temp); + len += 4; + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_cali_data.zero_sig_cts); + len += 4; + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_cali_data.zero_ref_cts); + len += 4; + /* span calibration */ + if (lark1s_gas_cali_data.available & 2) { + dwin_buff_tx[len++] = 'N'; + } else { + dwin_buff_tx[len++] = 'Y'; + } + dwin_buff_tx[len++] = ' '; + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_cali_data.span_concentration); + len += 4; + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_cali_data.span_det_temp); + len += 4; + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_cali_data.span_sig_cts); + len += 4; + dwin_endian_reverse_4byte(dwin_buff_tx + len, lark1s_gas_cali_data.span_ref_cts); + len += 4; + } + dwin_send(len); + flag++; } void USART2_IRQHandler(void) diff --git a/stm32f4/src/dwin.h b/stm32f4/src/dwin.h index 86c5353..2c7f74f 100644 --- a/stm32f4/src/dwin.h +++ b/stm32f4/src/dwin.h @@ -1,5 +1,5 @@ -#ifndef __RS485_H__ -#define __RS485_H__ +#ifndef __DWIN_H__ +#define __DWIN_H__ #ifdef __cplusplus extern "C" { @@ -12,41 +12,19 @@ #define DWIN_PIN_RX (GPIO_Pin_3) #define DWIN_BAUDRATE (115200) -struct dwin_ctrl_s { - uint32_t baudrate; - uint32_t cali_conc; - uint8_t cali_active; - uint8_t cali_restore; - uint8_t mb_addr; -}; -struct dwin_info_s { - uint8_t gas_name[16]; - uint8_t sn[16]; - uint32_t concentration; - uint8_t conc_unit[16]; - uint32_t det_temp; - uint32_t sig_cts; - uint32_t ref_cts; - uint32_t air_pressure; - uint32_t range; - uint32_t mini_cali; - uint16_t sts_zero; - uint16_t sts_span; - uint16_t sts_active; - uint16_t sts_restore; - uint16_t cali_zero_enable; - uint16_t cali_zero_temp; - uint32_t cali_zero_sig; - uint32_t cali_zero_ref; - uint16_t cali_span_enable; - uint16_t cali_span_temp; - uint32_t cali_span_conc; - uint32_t cali_span_sig; - uint32_t cali_span_ref; -}; +#define DWIN_DATA_DISP_ADDR (0x5000) +#define DWIN_DATA_DISP_LENG (0x38) +#define DWIN_DATA_CTRL_ADDR (0x5100) +#define DWIN_DATA_CTRL_LENG (0x07) -void dwin485_init(void); +extern char sn[16]; +extern struct lark1s_gas_info_s lark1s_gas_info; +extern struct lark1s_gas_cali_data_s lark1s_gas_cali_data; +extern struct lark1s_data_s lark1s_data; +extern struct lark1s_status_s lark1s_status; + +void dwin_init(void); void dwin_send(uint16_t len); void dwin_loop(void); @@ -54,4 +32,4 @@ void dwin_loop(void); } #endif -#endif /* __RS485_H__ */ +#endif /* __DWIN_H__ */ diff --git a/stm32f4/src/rs485.c b/stm32f4/src/rs485.c index 84e9148..ebdef3b 100644 --- a/stm32f4/src/rs485.c +++ b/stm32f4/src/rs485.c @@ -3,6 +3,8 @@ #include "stm32f4xx_usart.h" #include "stm32f4xx_dma.h" #include "rs485.h" +#include "lark1s.h" +#include "dwin.h" #define RS485_TX_STREAM DMA1_Stream3 #define RS485_RX_STREAM DMA1_Stream1 @@ -10,6 +12,13 @@ #define RS485_BUFF_RX_LEN (4096) uint8_t rs485_buff_tx[RS485_BUFF_TX_LEN] __attribute__((aligned(16))); uint8_t rs485_buff_rx[RS485_BUFF_RX_LEN] __attribute__((aligned(16))); +static int __attribute__((section(".bss_ccm"))) sm = 0; + +char sn[16] __attribute__((section(".bss_ccm"))); +struct lark1s_gas_info_s lark1s_gas_info __attribute__((section(".bss_ccm"))); +struct lark1s_gas_cali_data_s lark1s_gas_cali_data __attribute__((section(".bss_ccm"))); +struct lark1s_data_s lark1s_data __attribute__((section(".bss_ccm"))); +struct lark1s_status_s lark1s_status __attribute__((section(".bss_ccm"))); extern uint32_t system_tick_cnt; @@ -109,25 +118,51 @@ void rs485_send(uint16_t len) DMA_Cmd(RS485_TX_STREAM, ENABLE); } -void modbus_get_sn(void) +void rs485_state_machine_tx(void) { + int len; + switch (sm) { + case 0: len = lark1s_req_sn(rs485_buff_tx); break; + case 1: len = lark1s_req_gas3_info(rs485_buff_tx); break; + case 2: len = lark1s_req_gas3_cali_data(rs485_buff_tx); break; + case 3: len = lark1s_req_data(rs485_buff_tx); break; + case 4: len = lark1s_req_status(rs485_buff_tx); break; + default: len = 0; break; + } + rs485_send((uint16_t)len); } -void modbus_get_info(void) +void rs485_state_machine_rx(int len) { + int ret = LARK1S_PARSE_OK; + switch (sm) { + case 0: ret = lark1s_parse_sn(rs485_buff_rx, len, sn); break; + case 1: ret = lark1s_parse_gas3_info(rs485_buff_rx, len, &lark1s_gas_info); break; + case 2: ret = lark1s_parse_gas3_cali_data(rs485_buff_rx, len, &lark1s_gas_cali_data); break; + case 3: ret = lark1s_parse_data(rs485_buff_rx, len, &lark1s_data); break; + case 4: ret = lark1s_parse_status(rs485_buff_rx, len, &lark1s_status); break; + default: break; + } + if (ret) { + return; + } + sm++; + if (sm > 4) { + sm = 0; + } } void rs485_loop(void) { static uint32_t ms = 0; - if (system_tick_cnt < (ms + 500)) { + if (system_tick_cnt < (ms + 200)) { return; } ms = system_tick_cnt; - // rs485_send(15); + rs485_state_machine_tx(); } void USART3_IRQHandler(void) @@ -155,9 +190,6 @@ void USART3_IRQHandler(void) DMA_ClearFlag(RS485_RX_STREAM, DMA_FLAG_TCIF1 | DMA_FLAG_HTIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_FEIF1); len = DMA_GetCurrDataCounter(RS485_RX_STREAM); len = RS485_BUFF_RX_LEN - len; - for (uint16_t i = 0; i < len; i++) { - rs485_buff_tx[i] = rs485_buff_rx[i] + 2; - } - rs485_send(len); + rs485_state_machine_rx((uint16_t)len); } } diff --git a/stm32f4/src/rs485.h b/stm32f4/src/rs485.h index 41c2a1c..f1a91f9 100644 --- a/stm32f4/src/rs485.h +++ b/stm32f4/src/rs485.h @@ -17,6 +17,8 @@ void rs485_init(void); void rs485_send(uint16_t len); +void rs485_state_machine_tx(void); +void rs485_state_machine_rx(int len); void rs485_loop(void); #ifdef __cplusplus