Compare commits

..

No commits in common. "aec67e8df08ba06cba8e13e8b7021c9803bce523" and "74f37f854d6e1ff377474fb7635ab24fb008eba5" have entirely different histories.

19 changed files with 616 additions and 95 deletions

2
.gitignore vendored
View File

@ -1,4 +1,4 @@
bootloader/build/*
lark1fq/build/*
test/build/*
.vscode/*

View File

@ -8,6 +8,8 @@
#include "ms5611.h"
#include "adc.h"
#include "cali.h"
#include "debug.h"
#include "cli.h"
#include "stm32f4xx_rcc.h"
uint32_t system_tick_cnt;
@ -50,6 +52,8 @@ void system_init(void)
filter_init();
adc_init();
cali_init();
debug_init();
cli_init();
system_tick_init();
device_init();
ltc2640_init();
@ -68,6 +72,7 @@ int main(void)
filter_loop();
concentration_loop();
adc_loop();
cli_loop();
ltc2640_loop();
ms5611_loop();
}

View File

@ -15,6 +15,8 @@ modbus.c
adc.c
cali.c
cali_flash.c
debug.c
cli.c
)
add_library(src STATIC ${FILELIST})

View File

@ -1,5 +1,6 @@
#include "adc.h"
#include "device.h"
#include "debug.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_adc.h"
@ -141,20 +142,24 @@ void adc_loop(void)
}
ms = system_tick_cnt;
val = adc_read();
debug_write_data(20 + ch, (float)val);
adc_input_data(ch, val); /* input data from ADC to sort buffer */
if (ch == 0) {
val = adc_get_filter_data(ch);
value = adc_rtot(val);
debug_write_data(24 + ch, (float)value);
device_data.detector_temperature = value;
ch = 1;
} else if (ch == 1) {
val = adc_get_filter_data(ch);
value = adc_rtot(val);
debug_write_data(24 + ch, (float)value);
device_data.lamp_temperature = value;
ch = 3;
} else if (ch == 3) {
val = adc_get_filter_data(ch);
value = (uint32_t)val * 6600 / 4096;
debug_write_data(24 + ch, (float)value);
device_data.lamp_voltage = value;
ch = 0;
} else {

353
lark1fq/src/cli.c Executable file
View File

@ -0,0 +1,353 @@
#include "cli.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_dma.h"
#define CLI_PRINTABLE_CHAR_SPACE (0x20)
#define CLI_PRINTABLE_CHAR_MIN (0x21)
#define CLI_PRINTABLE_CHAR_MAX (0x7E)
struct cli_data_s cli_data;
struct cli_data_comb_s cli_data_comb;
char cli_buff_tx[CLI_BUFF_TX_LEN] __attribute__((aligned(16)));
char cli_buff_rx[CLI_BUFF_RX_LEN] __attribute__((aligned(16)));
char *cli_cmd_list[] = {
"help",
"force",
"print",
"invalid",
};
uint16_t (*cli_cmd_process_arr[])(char *, uint16_t) = {
cli_cmd_process_help,
cli_cmd_process_force,
cli_cmd_process_print,
cli_cmd_process_invalid,
};
void cli_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* init struct data */
cli_data.rx_len = 0;
cli_data.tx_len = 0;
cli_data.buff_rx = cli_buff_rx;
cli_data.buff_tx = cli_buff_tx;
cli_data.frame_cnt = 0;
cli_data_comb.force_available = 0;
/* config cli uart pin */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_PinAFConfig(CLI_PORT, GPIO_PinSource10, GPIO_AF_USART3);
GPIO_PinAFConfig(CLI_PORT, GPIO_PinSource11, GPIO_AF_USART3);
GPIO_InitStructure.GPIO_Pin = CLI_PIN_TX | CLI_PIN_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(CLI_PORT, &GPIO_InitStructure);
/* config cli uart function */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
USART_DeInit(USART3);
USART_OverSampling8Cmd(USART3, ENABLE);
USART_InitStructure.USART_BaudRate = CLI_BAUDRATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_Init(USART3, &USART_InitStructure);
USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE);
USART_DMACmd(USART3, USART_DMAReq_Rx, ENABLE);
USART_Cmd(USART3, ENABLE);
/* Configure DMA controller to manage USART TX request */
DMA_InitStructure.DMA_BufferSize = CLI_BUFF_TX_LEN;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&(USART3->DR));
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)cli_buff_tx;
DMA_Init(CLI_TX_STREAM, &DMA_InitStructure);
/* Configure DMA controller to manage USART RX request */
DMA_InitStructure.DMA_BufferSize = CLI_BUFF_RX_LEN;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)cli_buff_rx;
DMA_Init(CLI_RX_STREAM, &DMA_InitStructure);
/* Configure interrupt for USART3 RX */
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 12;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
USART_ITConfig(USART3, USART_IT_TC, ENABLE);
/* clear IT flag */
USART_GetITStatus(USART3, USART_IT_IDLE);
USART_ReceiveData(USART3);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
USART_ClearITPendingBit(USART3, USART_IT_TC);
}
void cli_send_data(uint16_t len)
{
USART_GetITStatus(USART3, USART_IT_IDLE);
USART_ReceiveData(USART3);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
if (len == 0) {
DMA_SetCurrDataCounter(CLI_RX_STREAM, CLI_BUFF_RX_LEN);
DMA_Cmd(CLI_RX_STREAM, ENABLE);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
} else {
DMA_SetCurrDataCounter(CLI_TX_STREAM, len);
DMA_Cmd(CLI_TX_STREAM, ENABLE);
}
}
void USART3_IRQHandler(void)
{
uint16_t len;
if (USART_GetITStatus(USART3, USART_IT_TC) != RESET)
{
USART_ClearITPendingBit(USART3, USART_IT_TC);
DMA_ClearFlag(CLI_TX_STREAM, DMA_FLAG_TCIF3 | DMA_FLAG_HTIF3 | DMA_FLAG_TEIF3 | DMA_FLAG_DMEIF3 | DMA_FLAG_FEIF3);
DMA_Cmd(CLI_TX_STREAM, DISABLE);
/* after cli tx complete, config cli rx */
USART_ReceiveData(USART3);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
DMA_SetCurrDataCounter(CLI_RX_STREAM, CLI_BUFF_RX_LEN);
DMA_Cmd(CLI_RX_STREAM, ENABLE);
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
}
if (USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) {
USART_ITConfig(USART3, USART_IT_IDLE, DISABLE);
USART_ReceiveData(USART3);
USART_ClearITPendingBit(USART3, USART_IT_IDLE);
DMA_Cmd(CLI_RX_STREAM, DISABLE);
DMA_ClearFlag(CLI_RX_STREAM, DMA_FLAG_TCIF1 | DMA_FLAG_HTIF1 | DMA_FLAG_TEIF1 | DMA_FLAG_DMEIF1 | DMA_FLAG_FEIF1);
len = DMA_GetCurrDataCounter(CLI_RX_STREAM);
cli_data.rx_len = CLI_BUFF_RX_LEN - len;
cli_data.frame_cnt++;
}
}
uint16_t cli_print_num10(char *buff, uint32_t num)
{
uint16_t i = 0;
uint32_t div, result;
uint8_t non_zero = 0;
div = 1000000000;
while (1) {
result = num / div;
num = num % div;
if (result) {
non_zero = 1;
buff[i] = (char)result + '0';
i++;
} else {
if (non_zero) {
buff[i] = '0';
i++;
} else {
}
}
div /= 10;
if (div == 0) {
return i;
}
}
}
uint16_t cli_scan_num10(char *buff, uint32_t *num)
{
uint32_t sum = 0;
uint16_t i = 0;
char c;
while (1) {
c = buff[i];
if ((c >= '0') && (c <= '9')) {
sum *= 10;
sum += (uint32_t)(c - '0');
i++;
} else {
*num = sum;
return i;
}
}
}
uint16_t cli_string_copy(char *dst, char *src)
{
uint16_t len = 0;
char c;
while(1) {
c = src[len];
if ((c >= CLI_PRINTABLE_CHAR_SPACE) && (c <= CLI_PRINTABLE_CHAR_MAX)) {
dst[len] = c;
len++;
} else {
return len;
}
}
}
uint16_t cli_string_copy_newline(char *dst, char *src)
{
uint16_t len = cli_string_copy(dst, src);
dst[len++] = '\r';
dst[len++] = '\n';
return len;
}
uint8_t cli_string_is_same(char *str1, char *str2, uint16_t *len)
{
uint16_t i = 0;
while (1) {
if (str1[i] == str2[i]) {
if ((str1[i] >= CLI_PRINTABLE_CHAR_MIN) && (str1[i] <= CLI_PRINTABLE_CHAR_MAX)) {
i++;
} else {
*len = i;
return 1;
}
} else {
if (((str1[i] >= CLI_PRINTABLE_CHAR_MIN) && (str1[i] <= CLI_PRINTABLE_CHAR_MAX)) || \
((str2[i] >= CLI_PRINTABLE_CHAR_MIN) && (str2[i] <= CLI_PRINTABLE_CHAR_MAX))) {
return 0;
} else {
*len = i;
return 1;
}
}
}
}
/* buff: is ready for check */
/* if is an cmd, then cmd */
uint8_t cli_is_cmd(char *buff, uint8_t *cmd_idx, uint16_t *len)
{
uint16_t length;
uint16_t cmd_cnt;
cmd_cnt = sizeof(cli_cmd_list) / sizeof(cli_cmd_list[0]);
for (uint8_t i = 0; i < cmd_cnt; i++) {
if (cli_string_is_same(buff, cli_cmd_list[i], &length)) {
*cmd_idx = i;
*len = length;
return 1;
}
}
return 0;
}
uint16_t cli_cmd_process_help(char *buff, uint16_t len)
{
uint16_t len_tx = cli_string_copy_newline(cli_data.buff_tx, "cmd data!");
return len_tx;
}
/* cmd example
force sig1=force
force sig2=free
force sig4=6540926
*/
uint16_t cli_cmd_process_force_error(char *buff)
{
uint16_t len;
len = cli_string_copy_newline(buff, "example:");
len += cli_string_copy_newline(buff + len, "force sig1=force");
len += cli_string_copy_newline(buff + len, "force sig2=free");
len += cli_string_copy_newline(buff + len, "force sig4=6540926");
return len;
}
uint16_t cli_cmd_process_force(char *buff, uint16_t len)
{
uint8_t ch = 0;
if ((buff[0] != ' ') || \
(buff[1] != 's') || \
(buff[2] != 'i') || \
(buff[3] != 'g') || \
((buff[4] < '1') || (buff[4] > '4')) || \
(buff[5] != '=')) {
return cli_cmd_process_force_error(cli_data.buff_tx);
}
ch = buff[4] - '1';
buff += 6;
if ((buff[0] == 'f') && (buff[1] == 'o') && (buff[2] == 'r') && (buff[3] == 'c') && (buff[4] == 'e')) {
cli_data_comb.force_available |= (1 << (ch + CLI_FORCE_FILTER_INPUT1));
return cli_string_copy_newline(cli_data.buff_tx, "force succeed!");
} else if ((buff[0] == 'f') && (buff[1] == 'r') && (buff[2] == 'e') && (buff[3] == 'e')) {
cli_data_comb.force_available &= ~(1 << (ch + CLI_FORCE_FILTER_INPUT1));
return cli_string_copy_newline(cli_data.buff_tx, "free succeed!");
} else {
uint32_t num;
if (0 == cli_scan_num10(buff, &num)) {
return cli_cmd_process_force_error(cli_data.buff_tx);
} else {
cli_data_comb.force_data[ch + CLI_FORCE_FILTER_INPUT1] = num;
return cli_string_copy_newline(cli_data.buff_tx, "force number succeed!");
}
}
}
uint16_t cli_cmd_process_print(char *buff, uint16_t len)
{
return 0;
}
uint16_t cli_cmd_process_invalid(char *buff, uint16_t len)
{
return 0;
}
uint16_t cli_cmd_process(char *buff)
{
uint8_t is_cmd;
uint8_t cmd_idx;
uint16_t cmd_len;
is_cmd = cli_is_cmd(buff, &cmd_idx, &cmd_len);
if (is_cmd == 0) {
uint16_t len = cli_string_copy_newline(cli_data.buff_tx, "not support this cmd!");
return len;
} else {
return cli_cmd_process_arr[cmd_idx](buff + cmd_len, cli_data.rx_len - cmd_len);
}
}
void cli_loop(void)
{
static uint32_t frame_cnt = 0;
if (cli_data.frame_cnt == frame_cnt) {
return;
}
frame_cnt = cli_data.frame_cnt;
cli_data.buff_rx[cli_data.rx_len] = 0;
cli_data.tx_len = cli_cmd_process(cli_data.buff_rx);
cli_send_data(cli_data.tx_len);
}

65
lark1fq/src/cli.h Executable file
View File

@ -0,0 +1,65 @@
#ifndef __CLI_H__
#define __CLI_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx.h"
#define CLI_PORT (GPIOB)
#define CLI_PIN_TX (GPIO_Pin_10)
#define CLI_PIN_RX (GPIO_Pin_11)
#define CLI_BAUDRATE (9600)
#define CLI_BUFF_TX_LEN (4096)
#define CLI_BUFF_RX_LEN (1024)
#define CLI_TX_STREAM DMA1_Stream3
#define CLI_RX_STREAM DMA1_Stream1
#define CLI_FORCE_FILTER_INPUT1 (0)
#define CLI_FORCE_FILTER_INPUT2 (1)
#define CLI_FORCE_FILTER_INPUT3 (2)
#define CLI_FORCE_FILTER_INPUT4 (3)
#define CLI_FORCE_FILTER_INPUT1_MASK (1 << CLI_FORCE_FILTER_INPUT1)
#define CLI_FORCE_FILTER_INPUT2_MASK (1 << CLI_FORCE_FILTER_INPUT2)
#define CLI_FORCE_FILTER_INPUT3_MASK (1 << CLI_FORCE_FILTER_INPUT3)
#define CLI_FORCE_FILTER_INPUT4_MASK (1 << CLI_FORCE_FILTER_INPUT4)
struct cli_data_s {
uint16_t rx_len;
uint16_t tx_len;
char *buff_rx;
char *buff_tx;
uint32_t frame_cnt;
};
struct cli_data_comb_s {
uint32_t force_available;
uint32_t force_data[32];
};
extern struct cli_data_s cli_data;
extern struct cli_data_comb_s cli_data_comb;
void cli_init(void);
void cli_send_data(uint16_t len);
uint16_t cli_string_copy(char *dst, char *src);
uint16_t cli_string_copy_newline(char *dst, char *src);
uint8_t cli_string_is_same(char *str1, char *str2, uint16_t *len);
uint8_t cli_is_cmd(char *buff, uint8_t *cmd_idx, uint16_t *len);
uint16_t cli_cmd_process_help(char *buff, uint16_t len);
uint16_t cli_cmd_process_force(char *buff, uint16_t len);
uint16_t cli_cmd_process_print(char *buff, uint16_t len);
uint16_t cli_cmd_process_invalid(char *buff, uint16_t len);
uint16_t cli_cmd_process(char *buff);
void cli_loop(void);
#ifdef __cplusplus
}
#endif
#endif /* __CLI_H__ */

View File

@ -38,49 +38,6 @@ void concentration_init(void)
}
}
int32_t concentration_neg_drift_compensation(uint8_t ch, int32_t reading)
{
static uint8_t drift_update_enable[4] = {1, 1, 1, 1};
static uint8_t neg_reading_num[4] = {0, 0, 0, 0};
static int32_t neg_reading_sum[4] = {0, 0, 0, 0};
static int32_t zero_neg_drift[4] = {0, 0, 0, 0};
static int32_t reading_fixed[4] = {0, 0, 0, 0};
static uint8_t neg_fixed_num[4] = {0, 0, 0, 0};
reading_fixed[ch] = reading;
if(drift_update_enable[ch]) {
if (reading < 0) {
neg_reading_sum[ch] += reading;
neg_reading_num[ch] ++;
reading_fixed[ch] = 0;
if(neg_reading_num[ch] >= 10) {
zero_neg_drift[ch] = neg_reading_sum[ch] / neg_reading_num[ch];
drift_update_enable[ch] = 0;
neg_reading_num[ch] = 0;
neg_reading_sum[ch] = 0;
}
} else {
neg_reading_num[ch] = 0;
neg_reading_sum[ch] = 0;
}
}
if (zero_neg_drift[ch]) {
reading_fixed[ch] = reading - zero_neg_drift[ch];
if (reading_fixed[ch] < 0) {
neg_fixed_num[ch]++;
if (neg_fixed_num[ch] >= 10) {
drift_update_enable[ch] = 1;
neg_fixed_num[ch] = 0;
}
} else {
neg_fixed_num[ch] = 0;
}
}
return ((reading_fixed[ch] > 0) ? reading_fixed[ch] : 0);
}
int32_t concentration_calc(uint8_t ch)
{
struct data_lookup_table_s *p; /* just for reduce text char in code */
@ -161,20 +118,16 @@ void concentration_loop(void)
for (uint8_t i = 0; i < 4; i++) {
if ((data_gas_info.id[i] != GAS_ID_INVALID) && (data_gas_info.id[i] != GAS_ID_REF)) {
device_data.gas_concentration[i] = concentration_calc(i);
device_data.gas_neg_concentration[i] = concentration_neg_drift_compensation(i, device_data.gas_concentration[i]);
} else {
device_data.gas_concentration[i] = 0;
device_data.gas_neg_concentration[i] = 0;
}
}
} else if (data_gas_info.comb == GAS_COMB_2_2) {
for (uint8_t i = 0; i < 4; i++) {
if ((data_gas_info.id[i] != GAS_ID_INVALID) && (data_gas_info.id[i] != GAS_ID_REF)) {
device_data.gas_concentration[i] = concentration_calc(i);
device_data.gas_neg_concentration[i] = concentration_neg_drift_compensation(i, device_data.gas_concentration[i]);
} else {
device_data.gas_concentration[i] = 0;
device_data.gas_neg_concentration[i] = 0;
}
}
} else if (data_gas_info.comb == GAS_COMB_3_1) {
@ -185,18 +138,15 @@ void concentration_loop(void)
if ((data_gas_info.id[i] != GAS_ID_INVALID) && (data_gas_info.id[i] != GAS_ID_REF)) {
conc = concentration_calc(i);
device_data.gas_concentration[i] = conc;
device_data.gas_neg_concentration[i] = concentration_neg_drift_compensation(i, device_data.gas_concentration[i]);
sum += conc;
} else {
ref = i;
}
}
device_data.gas_concentration[ref] = sum / 3;
device_data.gas_neg_concentration[ref] = concentration_neg_drift_compensation(ref, device_data.gas_concentration[ref]);
} else {
for (uint8_t i = 0; i < 4; i++) {
device_data.gas_concentration[i] = 0;
device_data.gas_neg_concentration[i] = 0;
}
}
}

View File

@ -25,7 +25,6 @@ extern struct data_lookup_table_s data_lookup_table[4];
void concentration_lookup_table_copy(uint8_t ch);
void concentration_init(void);
int32_t concentration_neg_drift_compensation(uint8_t ch, int32_t reading);
int32_t concentration_calc(uint8_t ch);
void concentration_loop(void);

100
lark1fq/src/debug.c Executable file
View File

@ -0,0 +1,100 @@
#include "debug.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_usart.h"
#include "stm32f4xx_dma.h"
struct debug_data_s debug_data;
float debug_buff[DEBUG_CHAN_MAX + 1] __attribute__((aligned(16)));
void debug_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* config debug uart pin */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_PinAFConfig(DEBUG_UART_PORT, GPIO_PinSource10, GPIO_AF_UART4);
GPIO_InitStructure.GPIO_Pin = DEBUG_UART_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(DEBUG_UART_PORT, &GPIO_InitStructure);
/* config debug uart function */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
USART_DeInit(UART4);
USART_OverSampling8Cmd(UART4, DISABLE);
USART_InitStructure.USART_BaudRate = DEBUG_UART_BAUDRATE;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(UART4, &USART_InitStructure);
USART_DMACmd(UART4, USART_DMAReq_Tx, ENABLE);
USART_Cmd(UART4, ENABLE);
/* Configure DMA controller to manage UART TX request */
DMA_InitStructure.DMA_BufferSize = DEBUG_CHAN_MAX * 4 + 4;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)(&(UART4->DR));
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_InitStructure.DMA_Channel = DMA_Channel_4;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)debug_buff;
DMA_Init(DMA1_Stream4, &DMA_InitStructure);
/* Configure interrupt for UART4 TX */
NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 10;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(UART4, USART_IT_TC, ENABLE);
/* debug data init */
debug_data.enable = DEBUG_ENABLE;
debug_data.busy = 0;
}
void debug_send_frame(void)
{
if (debug_data.enable == 0 || debug_data.busy == 1) {
return;
}
debug_data.busy = 1;
*(uint32_t *)(debug_buff + DEBUG_CHAN_MAX) = 0x7F800000;
DMA_SetCurrDataCounter(DMA1_Stream4, sizeof(debug_buff));
USART_ClearITPendingBit(UART4, USART_IT_TC);
DMA_Cmd(DMA1_Stream4, ENABLE);
}
void debug_write_data(uint16_t ch, float data)
{
if (debug_data.enable == 0) {
return;
}
if (ch >= DEBUG_CHAN_MAX) {
while (1) {}
}
debug_buff[ch] = data;
}
void UART4_IRQHandler(void)
{
if (USART_GetITStatus(UART4, USART_IT_TC) != RESET) {
USART_ClearITPendingBit(UART4, USART_IT_TC);
DMA_ClearFlag(DMA1_Stream4, DMA_FLAG_TCIF4);
debug_data.busy = 0;
}
}

33
lark1fq/src/debug.h Executable file
View File

@ -0,0 +1,33 @@
#ifndef __DEBUG_H__
#define __DEBUG_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f4xx.h"
#define DEBUG_ENABLE (1)
#define DEBUG_UART_PORT (GPIOC)
#define DEBUG_UART_PIN (GPIO_Pin_6)
#define DEBUG_UART_BAUDRATE (2 * 1000 * 1000)
#define DEBUG_CHAN_MAX (28)
struct debug_data_s {
uint8_t enable;
uint8_t busy;
};
extern struct debug_data_s debug_data;
void debug_init(void);
void debug_send_frame(void);
void debug_write_data(uint16_t ch, float data);
#ifdef __cplusplus
}
#endif
#endif /* __DEBUG_H__ */

View File

@ -356,7 +356,7 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_GAS1 + 249] = (uint8_t *)&((*bitmap_gas)[0].user_cali.span_data[4][6]) + 2,
[OFFSET_GAS1 + 250] = (uint8_t *)&((*bitmap_gas)[0].user_cali.span_data[4][6]) + 1,
[OFFSET_GAS1 + 251] = (uint8_t *)&((*bitmap_gas)[0].user_cali.span_data[4][6]) + 0,
[(OFFSET_GAS1 + 252) ... (OFFSET_GAS1 + 511)] = num_tab_ro + 0,
[(OFFSET_GAS1 + 252) ... (OFFSET_GAS1 + 511)] = (uint8_t *)0,
[OFFSET_GAS2 + 0] = (uint8_t *)(&bitmap_main->gas2_sub_id) + 3,
[OFFSET_GAS2 + 1] = (uint8_t *)(&bitmap_main->gas2_sub_id) + 2,
@ -642,7 +642,7 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_GAS2 + 249] = (uint8_t *)&((*bitmap_gas)[1].user_cali.span_data[4][6]) + 2,
[OFFSET_GAS2 + 250] = (uint8_t *)&((*bitmap_gas)[1].user_cali.span_data[4][6]) + 1,
[OFFSET_GAS2 + 251] = (uint8_t *)&((*bitmap_gas)[1].user_cali.span_data[4][6]) + 0,
[(OFFSET_GAS2 + 252) ... (OFFSET_GAS2 + 511)] = num_tab_ro + 0,
[(OFFSET_GAS2 + 252) ... (OFFSET_GAS2 + 511)] = (uint8_t *)0,
[OFFSET_GAS3 + 0] = (uint8_t *)(&bitmap_main->gas3_sub_id) + 3,
[OFFSET_GAS3 + 1] = (uint8_t *)(&bitmap_main->gas3_sub_id) + 2,
@ -928,7 +928,7 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_GAS3 + 249] = (uint8_t *)&((*bitmap_gas)[2].user_cali.span_data[4][6]) + 2,
[OFFSET_GAS3 + 250] = (uint8_t *)&((*bitmap_gas)[2].user_cali.span_data[4][6]) + 1,
[OFFSET_GAS3 + 251] = (uint8_t *)&((*bitmap_gas)[2].user_cali.span_data[4][6]) + 0,
[(OFFSET_GAS3 + 252) ... (OFFSET_GAS3 + 511)] = num_tab_ro + 0,
[(OFFSET_GAS3 + 252) ... (OFFSET_GAS3 + 511)] = (uint8_t *)0,
[OFFSET_GAS4 + 0] = (uint8_t *)(&bitmap_main->gas4_sub_id) + 3,
[OFFSET_GAS4 + 1] = (uint8_t *)(&bitmap_main->gas4_sub_id) + 2,
@ -1214,7 +1214,7 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_GAS4 + 249] = (uint8_t *)&((*bitmap_gas)[3].user_cali.span_data[4][6]) + 2,
[OFFSET_GAS4 + 250] = (uint8_t *)&((*bitmap_gas)[3].user_cali.span_data[4][6]) + 1,
[OFFSET_GAS4 + 251] = (uint8_t *)&((*bitmap_gas)[3].user_cali.span_data[4][6]) + 0,
[(OFFSET_GAS4 + 252) ... (OFFSET_GAS4 + 511)] = num_tab_ro + 0,
[(OFFSET_GAS4 + 252) ... (OFFSET_GAS4 + 511)] = (uint8_t *)0,
[OFFSET_DATA + 0] = (uint8_t *)&(device_data.detector_temperature) + 3,
[OFFSET_DATA + 1] = (uint8_t *)&(device_data.detector_temperature) + 2,
@ -1256,7 +1256,7 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_DATA + 37] = (uint8_t *)&(device_data.gas_sig[0]) + 2,
[OFFSET_DATA + 38] = (uint8_t *)&(device_data.gas_sig[0]) + 1,
[OFFSET_DATA + 39] = (uint8_t *)&(device_data.gas_sig[0]) + 0,
[(OFFSET_DATA + 40) ... (OFFSET_DATA + 47)] = num_tab_ro + 0,
[(OFFSET_DATA + 40) ... (OFFSET_DATA + 47)] = (uint8_t *)0,
[OFFSET_DATA + 48] = (uint8_t *)&(device_data.gas_concentration[1]) + 3,
[OFFSET_DATA + 49] = (uint8_t *)&(device_data.gas_concentration[1]) + 2,
[OFFSET_DATA + 50] = (uint8_t *)&(device_data.gas_concentration[1]) + 1,
@ -1265,7 +1265,7 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_DATA + 53] = (uint8_t *)&(device_data.gas_sig[1]) + 2,
[OFFSET_DATA + 54] = (uint8_t *)&(device_data.gas_sig[1]) + 1,
[OFFSET_DATA + 55] = (uint8_t *)&(device_data.gas_sig[1]) + 0,
[(OFFSET_DATA + 56) ... (OFFSET_DATA + 63)] = num_tab_ro + 0,
[(OFFSET_DATA + 56) ... (OFFSET_DATA + 63)] = (uint8_t *)0,
[OFFSET_DATA + 64] = (uint8_t *)&(device_data.gas_concentration[2]) + 3,
[OFFSET_DATA + 65] = (uint8_t *)&(device_data.gas_concentration[2]) + 2,
[OFFSET_DATA + 66] = (uint8_t *)&(device_data.gas_concentration[2]) + 1,
@ -1274,7 +1274,7 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_DATA + 69] = (uint8_t *)&(device_data.gas_sig[2]) + 2,
[OFFSET_DATA + 70] = (uint8_t *)&(device_data.gas_sig[2]) + 1,
[OFFSET_DATA + 71] = (uint8_t *)&(device_data.gas_sig[2]) + 0,
[(OFFSET_DATA + 72) ... (OFFSET_DATA + 79)] = num_tab_ro + 0,
[(OFFSET_DATA + 72) ... (OFFSET_DATA + 79)] = (uint8_t *)0,
[OFFSET_DATA + 80] = (uint8_t *)&(device_data.gas_concentration[3]) + 3,
[OFFSET_DATA + 81] = (uint8_t *)&(device_data.gas_concentration[3]) + 2,
[OFFSET_DATA + 82] = (uint8_t *)&(device_data.gas_concentration[3]) + 1,
@ -1283,24 +1283,8 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_DATA + 85] = (uint8_t *)&(device_data.gas_sig[3]) + 2,
[OFFSET_DATA + 86] = (uint8_t *)&(device_data.gas_sig[3]) + 1,
[OFFSET_DATA + 87] = (uint8_t *)&(device_data.gas_sig[3]) + 0,
[(OFFSET_DATA + 88) ... (OFFSET_DATA + 95)] = num_tab_ro + 0,
[OFFSET_DATA + 96] = (uint8_t *)&(device_data.gas_neg_concentration[0]) + 3,
[OFFSET_DATA + 97] = (uint8_t *)&(device_data.gas_neg_concentration[0]) + 2,
[OFFSET_DATA + 98] = (uint8_t *)&(device_data.gas_neg_concentration[0]) + 1,
[OFFSET_DATA + 99] = (uint8_t *)&(device_data.gas_neg_concentration[0]) + 0,
[OFFSET_DATA + 100] = (uint8_t *)&(device_data.gas_neg_concentration[1]) + 3,
[OFFSET_DATA + 101] = (uint8_t *)&(device_data.gas_neg_concentration[1]) + 2,
[OFFSET_DATA + 102] = (uint8_t *)&(device_data.gas_neg_concentration[1]) + 1,
[OFFSET_DATA + 103] = (uint8_t *)&(device_data.gas_neg_concentration[1]) + 0,
[OFFSET_DATA + 104] = (uint8_t *)&(device_data.gas_neg_concentration[2]) + 3,
[OFFSET_DATA + 105] = (uint8_t *)&(device_data.gas_neg_concentration[2]) + 2,
[OFFSET_DATA + 106] = (uint8_t *)&(device_data.gas_neg_concentration[2]) + 1,
[OFFSET_DATA + 107] = (uint8_t *)&(device_data.gas_neg_concentration[2]) + 0,
[OFFSET_DATA + 108] = (uint8_t *)&(device_data.gas_neg_concentration[3]) + 3,
[OFFSET_DATA + 109] = (uint8_t *)&(device_data.gas_neg_concentration[3]) + 2,
[OFFSET_DATA + 110] = (uint8_t *)&(device_data.gas_neg_concentration[3]) + 1,
[OFFSET_DATA + 111] = (uint8_t *)&(device_data.gas_neg_concentration[3]) + 0,
[(OFFSET_DATA + 112) ... (OFFSET_DATA + 511)] = num_tab_ro + 0,
[(OFFSET_DATA + 88) ... (OFFSET_DATA + 95)] = (uint8_t *)0,
[(OFFSET_DATA + 96) ... (OFFSET_DATA + 511)] = (uint8_t *)0,
[OFFSET_STAT + 0] = (uint8_t *)&(device_status.cali_zero_record_status[0]) + 1,
[OFFSET_STAT + 1] = (uint8_t *)&(device_status.cali_zero_record_status[0]) + 0,
@ -1324,5 +1308,5 @@ const uint8_t * const modbus_map_ro[] = {
[OFFSET_STAT + 19] = (uint8_t *)&(device_status.cali_restore_status) + 0,
[OFFSET_STAT + 20] = (uint8_t *)&(device_status.heat_on_off_status) + 1,
[OFFSET_STAT + 21] = (uint8_t *)&(device_status.heat_on_off_status) + 0,
[(OFFSET_STAT + 22) ... (OFFSET_STAT + 511)] = num_tab_ro + 0,
[(OFFSET_STAT + 22) ... (OFFSET_STAT + 511)] = (uint8_t *)0,
};

View File

@ -161,7 +161,7 @@ struct device_data_s {
uint32_t gas_sig[4];
// uint32_t gas_sig_fliter[4];
int32_t gas_concentration[4];
int32_t gas_neg_concentration[4];
// int32_t gas_neg_concentration[4];
};
struct device_status_s {

View File

@ -1,6 +1,7 @@
#include "filter.h"
#include "ltc1867.h"
#include "device.h"
#include "debug.h"
#include "user_misc.h"
static uint32_t sum_gas1[FILTER_SUM_LEN_GAS1] __attribute__((section(".bss_ccm")));
@ -104,10 +105,12 @@ void filter_sum_process(void)
idx = data_filter[i].sum_idx;
sum = data_filter[i].sum_sum;
val = data_filter[i].input;
debug_write_data(4 + i, (float)val);
sum = sum - data_filter[i].sum_buff[idx];
data_filter[i].sum_buff[idx] = val;
sum = sum + val;
data_filter[i].sum_sum = sum;
debug_write_data(8 + i, (float)(data_filter[i].sum_sum));
data_filter[i].sum_idx++;
if (data_filter[i].sum_idx >= data_filter[i].sum_len) {
data_filter[i].sum_idx = 0;
@ -152,6 +155,7 @@ void filter_median_process(void)
}
/* calc median data */
data_filter[i].median_output = (iter->data + iter->next->data) / 2;
debug_write_data(12 + i, (float)(data_filter[i].median_output));
/* iterate median_idx */
data_filter[i].median_idx++;
if (data_filter[i].median_idx >= data_filter[i].median_len) {
@ -174,6 +178,7 @@ void filter_window_process(void)
sum = sum + val;
data_filter[i].window_sum = sum;
data_filter[i].window_output = sum / data_filter[i].window_len;
debug_write_data(16 + i, (float)(data_filter[i].window_output));
data_filter[i].window_idx++;
if (data_filter[i].window_idx >= data_filter[i].window_len) {
data_filter[i].window_idx = 0;

View File

@ -12,10 +12,10 @@
#define FILTER_SUM_LEN_GAS3 (8 * 2)
#define FILTER_SUM_LEN_GAS4 (8 * 2)
#define FILTER_MEDIAN_LEN_GAS1 (1024)
#define FILTER_MEDIAN_LEN_GAS2 (128)
#define FILTER_MEDIAN_LEN_GAS3 (128)
#define FILTER_MEDIAN_LEN_GAS4 (128)
#define FILTER_MEDIAN_LEN_GAS1 (128)
#define FILTER_MEDIAN_LEN_GAS2 (64)
#define FILTER_MEDIAN_LEN_GAS3 (64)
#define FILTER_MEDIAN_LEN_GAS4 (64)
#define FILTER_WINDOW_LEN_GAS1 (256)
#define FILTER_WINDOW_LEN_GAS2 (32)

View File

@ -3,6 +3,8 @@
#include "device.h"
#include "cali.h"
#include "cali_flash.h"
#include "debug.h"
#include "cli.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_tim.h"
@ -196,14 +198,31 @@ void TIM2_IRQHandler(void)
/* split 2 for loop, because sample timing is strict, only place important code in sample duration */
for (uint8_t i = 0; i < 4; i++) {
data_ltc1867.sum[i] += diff32768(val[i]); /* add every channel original data for next process */
debug_write_data(i, (float)val[i]); /* channel 1~4 for ltc1867 original sample data */
}
data_ltc1867.val_idx++;
if ((data_ltc1867.val_idx >= CALC_CNT) && (data_ltc1867.locked != 0)) {
data_ltc1867.val_idx = 0;
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT1_MASK) {
filter_input_data(0, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT1] / FILTER_SUM_LEN_GAS1);
} else {
filter_input_data(0, data_ltc1867.sum[0]);
}
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT2_MASK) {
filter_input_data(1, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT2] / FILTER_SUM_LEN_GAS2);
} else {
filter_input_data(1, data_ltc1867.sum[1]);
}
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT3_MASK) {
filter_input_data(2, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT3] / FILTER_SUM_LEN_GAS3);
} else {
filter_input_data(2, data_ltc1867.sum[2]);
}
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT4_MASK) {
filter_input_data(3, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT4] / FILTER_SUM_LEN_GAS4);
} else {
filter_input_data(3, data_ltc1867.sum[3]);
}
data_ltc1867.sum[0] = 0;
data_ltc1867.sum[1] = 0;
data_ltc1867.sum[2] = 0;
@ -236,4 +255,5 @@ void TIM2_IRQHandler(void)
}
}
cali_flash_write();
debug_send_frame();
}

View File

@ -121,7 +121,7 @@ void ltc2640_init(void)
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = LTC2640_PIN_SCK | LTC2640_PIN_SDI;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_Init(GPIOB, &GPIO_InitStructure);
@ -187,9 +187,9 @@ void ltc2640_loop(void)
if (system_tick_cnt < (ms + 50)) {
return;
}
GPIO_SetBits(GPIOB, LTC2640_PIN_CS);
GPIO_SetBits(GPIOA, LTC2640_PIN_CS);
ms = system_tick_cnt;
ret = ltc2640_data_process();
GPIO_ResetBits(GPIOB, LTC2640_PIN_CS);
GPIO_ResetBits(GPIOA, LTC2640_PIN_CS);
ltc2640_send_data((uint16_t)ret);
}

View File

@ -8,7 +8,7 @@
#include "stm32f4xx.h"
#define LTC2640_PIN_CLR (GPIO_Pin_7)
#define LTC2640_PIN_CS (GPIO_Pin_6)
#define LTC2640_PIN_CS (GPIO_Pin_15)
#define LTC2640_PIN_SCK (GPIO_Pin_3)
#define LTC2640_PIN_SDI (GPIO_Pin_5)

View File

@ -15,7 +15,7 @@ void led_init(uint16_t led)
.GPIO_PuPd = GPIO_PuPd_NOPULL,
};
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
GPIO_Init(PORT_LED, &GPIO_InitStructure);
led_off(led);
}

View File

@ -7,9 +7,9 @@
#include "stm32f4xx.h"
#define PORT_LED (GPIOB)
#define LED1 (GPIO_Pin_12)
#define LED2 (GPIO_Pin_13)
#define PORT_LED (GPIOC)
#define LED1 (GPIO_Pin_4)
#define LED2 (GPIO_Pin_5)
#define PORT_HEAT (GPIOB)
#define PIN_HEAT (GPIO_Pin_1)