19 changed files with 353 additions and 36 deletions
-
4.vscode/settings.json
-
4app/app.uvoptx
-
8app/app.uvprojx
-
6app/main.c
-
2app/src/basic/board.c
-
2app/src/basic/board.h
-
2app/src/basic/zble_module.c
-
2app/src/basic/zdatachannel_service.c
-
21app/src/one_conduction/one_conduction_board.c
-
6app/src/one_conduction/one_conduction_main.c
-
0app/src/three_conduction/three_conduction_board.c
-
0app/src/three_conduction/three_conduction_board.h
-
265app/src/three_lead/three_lead_board.c
-
65app/src/three_lead/three_lead_board.h
-
0app/src/three_lead/three_lead_main.c
-
0app/src/three_lead/three_lead_main.h
-
2libznordic
@ -0,0 +1,265 @@ |
|||
#include "three_lead_board.h" |
|||
|
|||
#include "znordic.h" |
|||
// |
|||
#include "app_timer.h" |
|||
#include "diskio_blkdev.h" |
|||
#include "ff.h" |
|||
#include "nrf_block_dev_sdc.h" |
|||
#include "nrf_delay.h" |
|||
#include "nrf_drv_pwm.h" |
|||
#include "nrf_drv_saadc.h" |
|||
#include "nrf_drv_twi.h" |
|||
#include "nrf_drv_wdt.h" |
|||
#include "nrf_gpio.h" |
|||
|
|||
#define SCREEN_SPI_INSTANCE 0 |
|||
#define SCREEN_RESET_PIN 20 |
|||
#define SCREEN_POWER_PIN 30 |
|||
#define SCREEN_A0PIN 31 |
|||
#define SCREEN_CS_PIN 29 |
|||
#define SCREEN_CLK_PIN 4 |
|||
#define SCREEN_MOSI_PIN 11 |
|||
|
|||
#define LED_GREEN_PIN 9 |
|||
#define LED_BLUE_PIN 10 |
|||
|
|||
#define ECG_NLOD_PIN 3 |
|||
#define ECG_PLOD_PIN 28 |
|||
#define ECG_ADC_PIN NRF_SAADC_INPUT_AIN2 |
|||
#define ECG_ADC_CHANNEL 0 // 不重复即可 |
|||
|
|||
#define BATTERY_ADC_PIN NRF_SAADC_INPUT_VDD |
|||
#define BATTERY_ADC_CHANNEL 1 // 不重复即可 |
|||
|
|||
#define EEPROM_I2C_SCL_M 15 // I2C SCL引脚 |
|||
#define EEPROM_I2C_SDA_M 17 // I2C SDA引脚 |
|||
#define EEPROM_I2C_INSTANCE 1 // I2C使用的硬件控制器ID |
|||
|
|||
/******************************************************************************* |
|||
* TOOLS * |
|||
*******************************************************************************/ |
|||
|
|||
/******************************************************************************* |
|||
* ADC * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_adc_module_init() { |
|||
nrf_drv_saadc_config_t adccfg = NRFX_SAADC_DEFAULT_CONFIG; |
|||
adccfg.resolution = NRF_SAADC_RESOLUTION_12BIT; // 4096 等于满采样率 |
|||
ZERROR_CHECK(nrf_drv_saadc_init(&adccfg, NULL)); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 蜂鸣器 * |
|||
*******************************************************************************/ |
|||
static nrf_drv_pwm_t m_beep_pwm0 = NRF_DRV_PWM_INSTANCE(0); |
|||
static nrf_pwm_values_individual_t m_beep_pwm0_seq_values = {0}; |
|||
static nrf_pwm_sequence_t const m_beep_pwm0_seq = { |
|||
.values.p_individual = &m_beep_pwm0_seq_values, |
|||
.length = NRF_PWM_VALUES_LENGTH(m_beep_pwm0_seq_values), |
|||
.repeats = 0, |
|||
.end_delay = 0, |
|||
}; |
|||
static nrf_drv_pwm_config_t const m_beep_pwm0_config0 = { |
|||
.output_pins = {11}, |
|||
.irq_priority = APP_IRQ_PRIORITY_LOWEST, |
|||
.base_clock = NRF_PWM_CLK_125kHz, |
|||
.count_mode = NRF_PWM_MODE_UP, |
|||
.top_value = 46, // 125kHz / 46 = 2.717k |
|||
.load_mode = NRF_PWM_LOAD_INDIVIDUAL, |
|||
.step_mode = NRF_PWM_STEP_AUTO, |
|||
}; |
|||
void ThreeLeadECG_beep_init() { APP_ERROR_CHECK(nrfx_pwm_init(&m_beep_pwm0, &m_beep_pwm0_config0, NULL)); } |
|||
void ThreeLeadECG_beep_set_state(bool state) { |
|||
if (state) { |
|||
m_beep_pwm0_seq_values.channel_0 = 23; // 设置占空比,数值最大不超过 top_value |
|||
nrfx_pwm_simple_playback(&m_beep_pwm0, &m_beep_pwm0_seq, 1, NRF_DRV_PWM_FLAG_LOOP); |
|||
} else { |
|||
nrfx_pwm_stop(&m_beep_pwm0, true); |
|||
} |
|||
} |
|||
/******************************************************************************* |
|||
* SCREEN * |
|||
*******************************************************************************/ |
|||
|
|||
typedef struct { |
|||
// BASIC IF |
|||
uint32_t reset_pin; |
|||
uint32_t power_pin; |
|||
uint32_t a0pin; // cmd/data |
|||
// SPI IF |
|||
uint32_t cs_pin; |
|||
uint32_t clk_pin; |
|||
uint32_t mosi_pin; |
|||
|
|||
} screen_handler_t; |
|||
|
|||
static screen_handler_t m_screen_handler = { |
|||
.reset_pin = SCREEN_RESET_PIN, |
|||
.power_pin = SCREEN_POWER_PIN, |
|||
.a0pin = SCREEN_A0PIN, |
|||
.cs_pin = SCREEN_CS_PIN, |
|||
.clk_pin = SCREEN_CLK_PIN, |
|||
.mosi_pin = SCREEN_MOSI_PIN, |
|||
}; |
|||
static const nrf_drv_spi_t m_screen_spi = NRF_DRV_SPI_INSTANCE(SCREEN_SPI_INSTANCE); /**< SPI instance. */ |
|||
|
|||
void ThreeLeadECG_screen_init() { |
|||
znrf_gpio_cfg_output(SCREEN_RESET_PIN, NRF_GPIO_PIN_NOPULL); |
|||
znrf_gpio_cfg_output(SCREEN_POWER_PIN, NRF_GPIO_PIN_NOPULL); |
|||
znrf_gpio_cfg_output(SCREEN_A0PIN, NRF_GPIO_PIN_NOPULL); |
|||
|
|||
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; |
|||
spi_config.ss_pin = SCREEN_CS_PIN; // NRF_DRV_SPI_PIN_NOT_USED |
|||
spi_config.miso_pin = NRF_DRV_SPI_PIN_NOT_USED; |
|||
spi_config.mosi_pin = SCREEN_MOSI_PIN; |
|||
spi_config.sck_pin = SCREEN_CLK_PIN; |
|||
spi_config.frequency = NRF_DRV_SPI_FREQ_1M; |
|||
ZERROR_CHECK(nrf_drv_spi_init(&m_screen_spi, &spi_config, NULL, NULL)); |
|||
} |
|||
|
|||
void ThreeLeadECG_screen_deinit() { |
|||
// TODO |
|||
} |
|||
uint8_t ThreeLeadECG_spi_init(void) { return 0; } |
|||
uint8_t ThreeLeadECG_spi_deinit(void) { return 0; } |
|||
uint8_t ThreeLeadECG_spi_cmd_data_gpio_init(void) { return 0; } |
|||
uint8_t ThreeLeadECG_spi_cmd_data_gpio_deinit(void) { return 0; } |
|||
void ThreeLeadECG_debug_print(const char *const fmt, ...) {} |
|||
uint8_t ThreeLeadECG_reset_gpio_init(void) { return 0; } |
|||
uint8_t ThreeLeadECG_reset_gpio_deinit(void) { return 0; } |
|||
uint8_t ThreeLeadECG_spi_write_cmd(uint8_t *buf, uint16_t len) { // |
|||
ZERROR_CHECK(nrf_drv_spi_transfer(&m_screen_spi, buf, len, NULL, 0)); |
|||
return 0; |
|||
} |
|||
void ThreeLeadECG_delay_ms(uint32_t ms) { nrf_delay_ms(ms); } |
|||
uint8_t ThreeLeadECG_spi_cmd_data_gpio_write(uint8_t value) { |
|||
if (value) { |
|||
nrf_gpio_pin_set(SCREEN_A0PIN); |
|||
} else { |
|||
nrf_gpio_pin_clear(SCREEN_A0PIN); |
|||
} |
|||
return 0; |
|||
} |
|||
uint8_t ThreeLeadECG_reset_gpio_write(uint8_t value) { |
|||
if (value) { |
|||
nrf_gpio_pin_set(SCREEN_RESET_PIN); |
|||
} else { |
|||
nrf_gpio_pin_clear(SCREEN_RESET_PIN); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* LED * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_led_init() { |
|||
znrf_gpio_cfg_output(LED_GREEN_PIN, NRF_GPIO_PIN_NOPULL); |
|||
znrf_gpio_cfg_output(LED_BLUE_PIN, NRF_GPIO_PIN_NOPULL); |
|||
} |
|||
void ThreeLeadECG_led_green_set_state(bool state) { |
|||
if (state) { |
|||
nrf_gpio_pin_set(LED_GREEN_PIN); |
|||
} else { |
|||
nrf_gpio_pin_clear(LED_GREEN_PIN); |
|||
} |
|||
} |
|||
void ThreeLeadECG_led_blue_set_state(bool state) { |
|||
if (state) { |
|||
nrf_gpio_pin_set(LED_BLUE_PIN); |
|||
} else { |
|||
nrf_gpio_pin_clear(LED_BLUE_PIN); |
|||
} |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* ecg * |
|||
*******************************************************************************/ |
|||
|
|||
void ThreeLeadECG_ecg_init() { |
|||
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ECG_ADC_PIN); |
|||
channel_config.acq_time = NRF_SAADC_ACQTIME_40US; |
|||
ZERROR_CHECK(nrfx_saadc_channel_init(ECG_ADC_CHANNEL, &channel_config)); |
|||
|
|||
nrf_gpio_cfg_sense_input(ECG_NLOD_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); |
|||
} |
|||
|
|||
bool ThreeLeadECG_ecg_nlod_get_connected_state() { return nrf_gpio_pin_read(ECG_NLOD_PIN) == 0; } |
|||
bool ThreeLeadECG_ecg_plod_get_connected_state() { return nrf_gpio_pin_read(ECG_PLOD_PIN) == 0; } |
|||
int16_t ThreeLeadECG_ecg_plod_get_ecg_val() { return znrf_adc_channel_read_val(ECG_ADC_CHANNEL); } |
|||
|
|||
/******************************************************************************* |
|||
* BATTERY * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_battery_init() { |
|||
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(BATTERY_ADC_PIN); |
|||
channel_config.acq_time = NRF_SAADC_ACQTIME_10US; |
|||
ZERROR_CHECK(nrfx_saadc_channel_init(BATTERY_ADC_CHANNEL, &channel_config)); |
|||
} |
|||
int16_t ThreeLeadECG_battery_get_adc_val() { |
|||
int16_t val = znrf_adc_channel_read_val(BATTERY_ADC_CHANNEL); |
|||
return val; |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* eeprom * |
|||
*******************************************************************************/ |
|||
static const nrf_drv_twi_t m_eeprom_twi_master = NRF_DRV_TWI_INSTANCE(EEPROM_I2C_INSTANCE); |
|||
|
|||
void ThreeLeadECG_eeprom_init() { |
|||
const nrf_drv_twi_config_t config = { |
|||
.scl = EEPROM_I2C_SCL_M, |
|||
.sda = EEPROM_I2C_SDA_M, |
|||
.frequency = NRF_DRV_TWI_FREQ_100K, |
|||
.interrupt_priority = APP_IRQ_PRIORITY_HIGH, |
|||
.clear_bus_init = false, |
|||
}; |
|||
|
|||
ZERROR_CHECK(nrf_drv_twi_init(&m_eeprom_twi_master, &config, NULL, NULL)); |
|||
nrf_drv_twi_enable(&m_eeprom_twi_master); |
|||
} |
|||
static uint8_t eeprom_cache[EEPROM_PAGE + 2]; |
|||
|
|||
static void assign_i2c_add(uint32_t add, bool wr, uint8_t *i2cadd, uint8_t *memadd0, uint8_t *memadd1) { |
|||
// DEVICE SELECT |
|||
// bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 |
|||
// 1 0 1 0 E2 A17 A16 RW(W=0) |
|||
// |
|||
// PS: E2 参考原理图中的电平为0,所以bit3为0 |
|||
// |
|||
// MEM0 |
|||
// bit15 bit14 bit13 bit12 bit11 bit10 bit9 bit8 |
|||
// MEM1 |
|||
// bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 |
|||
// |
|||
|
|||
*i2cadd = 0xA0; |
|||
uint8_t a16a17 = (add >> 16) & 0x03; |
|||
*i2cadd |= a16a17 << 1; |
|||
|
|||
*i2cadd = wr ? *i2cadd & 0xFE : *i2cadd | 0x01; |
|||
|
|||
*memadd0 = add >> 8; |
|||
*memadd1 = add & 0xFF; |
|||
} |
|||
|
|||
void ThreeLeadECG_eeprom_write(uint16_t page, uint8_t *data, uint16_t len) { // |
|||
uint32_t addr = page * EEPROM_PAGE; |
|||
len = len > EEPROM_PAGE ? EEPROM_PAGE : len; |
|||
uint8_t deviceSelect = 0; |
|||
|
|||
assign_i2c_add(addr, true, &deviceSelect, &eeprom_cache[0], &eeprom_cache[1]); |
|||
nrf_drv_twi_tx(&m_eeprom_twi_master, deviceSelect, eeprom_cache, len + 2, false); |
|||
} |
|||
|
|||
void ThreeLeadECG_eeprom_read(uint32_t add, uint8_t *data, uint16_t len) { |
|||
uint8_t deviceSelect = 0; |
|||
uint8_t wadd[2] = {0}; |
|||
|
|||
assign_i2c_add(add, false, &deviceSelect, &wadd[0], &wadd[1]); |
|||
nrf_drv_twi_tx(&m_eeprom_twi_master, deviceSelect, wadd, 2, false); |
|||
|
|||
deviceSelect |= 0x01; // read |
|||
nrf_drv_twi_rx(&m_eeprom_twi_master, deviceSelect, data, len); |
|||
} |
@ -0,0 +1,65 @@ |
|||
#pragma once |
|||
#define VERSION 1 |
|||
#define MANUFACTURER_NAME "iflytop" |
|||
#define BLE_NAME "iflytop_test" |
|||
|
|||
/******************************************************************************* |
|||
* INCLUDE * |
|||
*******************************************************************************/ |
|||
#include <stdbool.h> |
|||
|
|||
#include "basic/ssd1306/driver_ssd1306_interface.h" |
|||
|
|||
/******************************************************************************* |
|||
* basic * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_adc_module_init(); |
|||
|
|||
/******************************************************************************* |
|||
* 蜂鸣器 * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_beep_init(); |
|||
void ThreeLeadECG_beep_set_state(bool state); |
|||
|
|||
/******************************************************************************* |
|||
* EEPROM * |
|||
*******************************************************************************/ |
|||
/** |
|||
* |
|||
* PageSize 256byte |
|||
* |
|||
*/ |
|||
#define EEPROM_PAGE 256 |
|||
void ThreeLeadECG_eeprom_init(); |
|||
void ThreeLeadECG_eeprom_write_page(uint16_t page, uint8_t* data, uint16_t len); |
|||
void ThreeLeadECG_eeprom_read(uint32_t add, uint8_t* data, uint16_t len); |
|||
|
|||
/******************************************************************************* |
|||
* SCREEN * |
|||
*******************************************************************************/ |
|||
|
|||
void ThreeLeadECG_screen_init(); |
|||
void ThreeLeadECG_screen_deinit(); |
|||
|
|||
/******************************************************************************* |
|||
* LED * |
|||
*******************************************************************************/ |
|||
void ThreeLeadECG_led_init(); |
|||
void ThreeLeadECG_led_green_set_state(bool state); |
|||
void ThreeLeadECG_led_blue_set_state(bool state); |
|||
|
|||
/******************************************************************************* |
|||
* ECG * |
|||
*******************************************************************************/ |
|||
|
|||
void ThreeLeadECG_ecg_init(); |
|||
bool ThreeLeadECG_ecg_nlod_get_connected_state(); |
|||
bool ThreeLeadECG_ecg_plod_get_connected_state(); |
|||
int16_t ThreeLeadECG_ecg_plod_get_ecg_val(); |
|||
|
|||
/******************************************************************************* |
|||
* BATTERY * |
|||
*******************************************************************************/ |
|||
|
|||
void ThreeLeadECG_battery_init(); |
|||
int16_t ThreeLeadECG_battery_get_adc_val(); |
@ -1 +1 @@ |
|||
Subproject commit e20cb4c21a5a95b8b60d76d29156faba65246b67 |
|||
Subproject commit efdb1b55c3432d3b539fb9fcecb14209874dae0d |
Write
Preview
Loading…
Cancel
Save
Reference in new issue