diff --git a/.vscode/settings.json b/.vscode/settings.json index c325d3f..938c9e8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -58,6 +58,7 @@ "driver_ssd1306_basic.h": "c", "driver_ssd1306_interface.h": "c", "three_lead_board.h": "c", - "znordic.h": "c" + "znordic.h": "c", + "ads1293.h": "c" } } \ No newline at end of file diff --git a/app/app.uvoptx b/app/app.uvoptx index d2afdf7..dff98f5 100644 --- a/app/app.uvoptx +++ b/app/app.uvoptx @@ -524,6 +524,42 @@ 0 0 + + 1 + 10 + 1 + 0 + 0 + 0 + .\src\three_lead\three_lead_board.c + three_lead_board.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + .\src\three_lead\three_lead_main.c + three_lead_main.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + .\src\basic\ads1293\ads1293.c + ads1293.c + 0 + 0 + @@ -534,7 +570,7 @@ 0 2 - 10 + 13 1 0 0 @@ -554,7 +590,7 @@ 0 3 - 11 + 14 1 0 0 @@ -566,7 +602,7 @@ 3 - 12 + 15 1 0 0 @@ -586,7 +622,7 @@ 0 4 - 13 + 16 1 0 0 @@ -606,7 +642,7 @@ 0 5 - 14 + 17 1 0 0 @@ -618,7 +654,7 @@ 5 - 15 + 18 1 0 0 @@ -630,7 +666,7 @@ 5 - 16 + 19 1 0 0 @@ -642,7 +678,7 @@ 5 - 17 + 20 1 0 0 @@ -654,7 +690,7 @@ 5 - 18 + 21 1 0 0 @@ -666,7 +702,7 @@ 5 - 19 + 22 1 0 0 @@ -678,7 +714,7 @@ 5 - 20 + 23 1 0 0 @@ -690,7 +726,7 @@ 5 - 21 + 24 1 0 0 @@ -710,7 +746,7 @@ 0 6 - 22 + 25 1 0 0 @@ -730,7 +766,7 @@ 0 7 - 23 + 26 1 0 0 @@ -742,7 +778,7 @@ 7 - 24 + 27 1 0 0 @@ -754,7 +790,7 @@ 7 - 25 + 28 1 0 0 @@ -766,7 +802,7 @@ 7 - 26 + 29 1 0 0 @@ -778,7 +814,7 @@ 7 - 27 + 30 1 0 0 @@ -790,7 +826,7 @@ 7 - 28 + 31 1 0 0 @@ -802,7 +838,7 @@ 7 - 29 + 32 1 0 0 @@ -814,7 +850,7 @@ 7 - 30 + 33 1 0 0 @@ -826,7 +862,7 @@ 7 - 31 + 34 1 0 0 @@ -838,7 +874,7 @@ 7 - 32 + 35 1 0 0 @@ -850,7 +886,7 @@ 7 - 33 + 36 1 0 0 @@ -862,7 +898,7 @@ 7 - 34 + 37 1 0 0 @@ -874,7 +910,7 @@ 7 - 35 + 38 1 0 0 @@ -886,7 +922,7 @@ 7 - 36 + 39 1 0 0 @@ -898,7 +934,7 @@ 7 - 37 + 40 1 0 0 @@ -910,7 +946,7 @@ 7 - 38 + 41 1 0 0 @@ -922,7 +958,7 @@ 7 - 39 + 42 1 0 0 @@ -934,7 +970,7 @@ 7 - 40 + 43 1 0 0 @@ -954,7 +990,7 @@ 0 8 - 41 + 44 1 0 0 @@ -966,7 +1002,7 @@ 8 - 42 + 45 1 0 0 @@ -978,7 +1014,7 @@ 8 - 43 + 46 1 0 0 @@ -990,7 +1026,7 @@ 8 - 44 + 47 1 0 0 @@ -1002,7 +1038,7 @@ 8 - 45 + 48 1 0 0 @@ -1014,7 +1050,7 @@ 8 - 46 + 49 1 0 0 @@ -1026,7 +1062,7 @@ 8 - 47 + 50 1 0 0 @@ -1038,7 +1074,7 @@ 8 - 48 + 51 1 0 0 @@ -1050,7 +1086,7 @@ 8 - 49 + 52 1 0 0 @@ -1062,7 +1098,7 @@ 8 - 50 + 53 1 0 0 @@ -1074,7 +1110,7 @@ 8 - 51 + 54 1 0 0 @@ -1086,7 +1122,7 @@ 8 - 52 + 55 1 0 0 @@ -1098,7 +1134,7 @@ 8 - 53 + 56 1 0 0 @@ -1110,7 +1146,7 @@ 8 - 54 + 57 1 0 0 @@ -1122,7 +1158,7 @@ 8 - 55 + 58 1 0 0 @@ -1134,7 +1170,7 @@ 8 - 56 + 59 1 0 0 @@ -1146,7 +1182,7 @@ 8 - 57 + 60 1 0 0 @@ -1158,7 +1194,7 @@ 8 - 58 + 61 1 0 0 @@ -1170,7 +1206,7 @@ 8 - 59 + 62 1 0 0 @@ -1182,7 +1218,7 @@ 8 - 60 + 63 1 0 0 @@ -1194,7 +1230,7 @@ 8 - 61 + 64 1 0 0 @@ -1206,7 +1242,7 @@ 8 - 62 + 65 1 0 0 @@ -1218,7 +1254,7 @@ 8 - 63 + 66 1 0 0 @@ -1230,7 +1266,7 @@ 8 - 64 + 67 1 0 0 @@ -1242,7 +1278,7 @@ 8 - 65 + 68 1 0 0 @@ -1254,7 +1290,7 @@ 8 - 66 + 69 1 0 0 @@ -1266,7 +1302,7 @@ 8 - 67 + 70 1 0 0 @@ -1286,7 +1322,7 @@ 0 9 - 68 + 71 1 0 0 @@ -1298,7 +1334,7 @@ 9 - 69 + 72 1 0 0 @@ -1310,7 +1346,7 @@ 9 - 70 + 73 1 0 0 @@ -1322,7 +1358,7 @@ 9 - 71 + 74 1 0 0 @@ -1334,7 +1370,7 @@ 9 - 72 + 75 1 0 0 @@ -1346,7 +1382,7 @@ 9 - 73 + 76 1 0 0 @@ -1366,7 +1402,7 @@ 0 10 - 74 + 77 1 0 0 @@ -1378,7 +1414,7 @@ 10 - 75 + 78 1 0 0 @@ -1390,7 +1426,7 @@ 10 - 76 + 79 1 0 0 @@ -1410,7 +1446,7 @@ 0 11 - 77 + 80 1 0 0 @@ -1422,7 +1458,7 @@ 11 - 78 + 81 1 0 0 @@ -1434,7 +1470,7 @@ 11 - 79 + 82 1 0 0 @@ -1454,7 +1490,7 @@ 0 12 - 80 + 83 1 0 0 @@ -1474,7 +1510,7 @@ 0 13 - 81 + 84 1 0 0 @@ -1486,7 +1522,7 @@ 13 - 82 + 85 1 0 0 diff --git a/app/app.uvprojx b/app/app.uvprojx index 828754f..43757b9 100644 --- a/app/app.uvprojx +++ b/app/app.uvprojx @@ -428,6 +428,21 @@ 1 .\src\basic\ssd1306\driver_ssd1306_interface.c + + three_lead_board.c + 1 + .\src\three_lead\three_lead_board.c + + + three_lead_main.c + 1 + .\src\three_lead\three_lead_main.c + + + ads1293.c + 1 + .\src\basic\ads1293\ads1293.c + @@ -4192,6 +4207,21 @@ 1 .\src\basic\ssd1306\driver_ssd1306_interface.c + + three_lead_board.c + 1 + .\src\three_lead\three_lead_board.c + + + three_lead_main.c + 1 + .\src\three_lead\three_lead_main.c + + + ads1293.c + 1 + .\src\basic\ads1293\ads1293.c + diff --git a/app/src/basic/ads1293/ads1293.c b/app/src/basic/ads1293/ads1293.c new file mode 100644 index 0000000..b0ff411 --- /dev/null +++ b/app/src/basic/ads1293/ads1293.c @@ -0,0 +1,63 @@ +/* + * ADS1293.h + * + * Created on: Jun 6, 2022 + * Author: Hans Hüttmann + */ +#include "ads1293.h" + +#include +#include +#include + +static uint8_t txcache[256]; +static uint8_t rxcache[256]; + +void ads1293_spi_init(ads1293_t* ch, ads1293_spi_tx_rx_t spi_tx_rx) { ch->spi_tx_rx = spi_tx_rx; } + +void ads1293_spi_writereg(ads1293_t* ch, uint8_t addr, uint8_t data) { + uint8_t txcache[2]; + txcache[0] = ADS1293_WRITE_BIT & addr; + txcache[1] = data; + ch->spi_tx_rx(txcache, NULL, 2); +} +uint8_t ads1293_spi_readreg(ads1293_t* ch, uint8_t addr) { + uint8_t txcache[2]; + txcache[0] = ADS1293_READ_BIT | addr; + txcache[1] = 0; + uint8_t rxcache[2]; + ch->spi_tx_rx(txcache, rxcache, 2); + return txcache[1]; +} + +void ads1293_spi_autoinc_writereg(ads1293_t* ch, uint8_t addr, uint8_t* data, uint8_t len) { // + len = len > 255 ? 255 : len; + uint8_t addbyte = ADS1293_WRITE_BIT & addr; + + txcache[0] = addbyte; + memcpy(txcache + 1, data, len); + + ch->spi_tx_rx(txcache, NULL, len + 1); +} +void ads1293_spi_autoinc_readreg(ads1293_t* ch, uint8_t addr, uint8_t* data, uint8_t len) { + len = len > 255 ? 255 : len; + uint8_t addbyte = ADS1293_READ_BIT | addr; + + txcache[0] = addbyte; + memset(txcache + 1, 0, len); + + ch->spi_tx_rx(txcache, rxcache, len + 1); + + memcpy(data, rxcache + 1, len); +} +void ads1293_spi_stream_readreg(ads1293_t* ch, uint8_t* data, uint8_t len) { + len = len > 255 ? 255 : len; + + memset(txcache, 0, len); + memset(rxcache, 0, len); + + uint8_t addbyte = ADS1293_READ_BIT | TI_ADS1293_DATA_LOOP_REG; + + ch->spi_tx_rx(&addbyte, rxcache, len); + memcpy(data, rxcache, len); +} diff --git a/app/src/basic/ads1293/ads1293.h b/app/src/basic/ads1293/ads1293.h new file mode 100644 index 0000000..3b67820 --- /dev/null +++ b/app/src/basic/ads1293/ads1293.h @@ -0,0 +1,119 @@ +//---------------------------------------------------------------------------- +// Description: This file contains definitions specific to the ADS1293. +// All the ADS1293 registers are defined as well as some common masks +// for these registers. +// +// MSP430/ADS1293 Interface Code Library v1.0 +// +// Vishy Natarajan +// Texas Instruments Inc. +// April 2013 +// Built with IAR Embedded Workbench Version: 5.5x +//------------------------------------------------------------------------------ +// Change Log: +//------------------------------------------------------------------------------ +// Version: 1.00 +// Comments: Initial Release Version +//------------------------------------------------------------------------------ +#ifndef HEADER_FILE_TI_ADS1293_H + +#define HEADER_FILE_TI_ADS1293_H + +#include + +/************************************************************ + * TI ADS1293 REGISTER SET ADDRESSES + ************************************************************/ + +#define TI_ADS1293_CONFIG_REG (0x00) /* Main Configuration */ + +#define TI_ADS1293_FLEX_CH1_CN_REG (0x01) /* Flex Routing Swich Control for Channel 1 */ +#define TI_ADS1293_FLEX_CH2_CN_REG (0x02) /* Flex Routing Swich Control for Channel 2 */ +#define TI_ADS1293_FLEX_CH3_CN_REG (0x03) /* Flex Routing Swich Control for Channel 3 */ +#define TI_ADS1293_FLEX_PACE_CN_REG (0x04) /* Flex Routing Swich Control for Pace Channel */ +#define TI_ADS1293_FLEX_VBAT_CN_REG (0x05) /* Flex Routing Swich Control for Battery Monitoriing */ + +#define TI_ADS1293_LOD_CN_REG (0x06) /* Lead Off Detect Control */ +#define TI_ADS1293_LOD_EN_REG (0x07) /* Lead Off Detect Enable */ +#define TI_ADS1293_LOD_CURRENT_REG (0x08) /* Lead Off Detect Current */ +#define TI_ADS1293_LOD_AC_CN_REG (0x09) /* AC Lead Off Detect Current */ + +#define TI_ADS1293_CMDET_EN_REG (0x0A) /* Common Mode Detect Enable */ +#define TI_ADS1293_CMDET_CN_REG (0x0B) /* Commond Mode Detect Control */ +#define TI_ADS1293_RLD_CN_REG (0x0C) /* Right Leg Drive Control */ + +#define TI_ADS1293_WILSON_EN1_REG (0x0D) /* Wilson Reference Input one Selection */ +#define TI_ADS1293_WILSON_EN2_REG (0x0E) /* Wilson Reference Input two Selection */ +#define TI_ADS1293_WILSON_EN3_REG (0x0F) /* Wilson Reference Input three Selection */ +#define TI_ADS1293_WILSON_CN_REG (0x10) /* Wilson Reference Input Control */ + +#define TI_ADS1293_REF_CN_REG (0x11) /* Internal Reference Voltage Control */ + +#define TI_ADS1293_OSC_CN_REG (0x12) /* Clock Source and Output Clock Control */ + +#define TI_ADS1293_AFE_RES_REG (0x13) /* Analog Front-End Frequency and Resolution */ +#define TI_ADS1293_AFE_SHDN_CN_REG (0x14) /* Analog Front-End Shutdown Control */ +#define TI_ADS1293_AFE_FAULT_CN_REG (0x15) /* Analog Front-End Fault Detection Control */ +#define TI_ADS1293_AFE_DITHER_EN_REG (0x16) /* Enable Dithering in Signma-Delta */ +#define TI_ADS1293_AFE_PACE_CN_REG (0x17) /* Analog Pace Channel Output Routing Control */ + +#define TI_ADS1293_ERROR_LOD_REG (0x18) /* Lead Off Detect Error Status */ +#define TI_ADS1293_ERROR_STATUS_REG (0x19) /* Other Error Status */ +#define TI_ADS1293_ERROR_RANGE1_REG (0x1A) /* Channel 1 Amplifier Out of Range Status */ +#define TI_ADS1293_ERROR_RANGE2_REG (0x1B) /* Channel 1 Amplifier Out of Range Status */ +#define TI_ADS1293_ERROR_RANGE3_REG (0x1C) /* Channel 1 Amplifier Out of Range Status */ +#define TI_ADS1293_ERROR_SYNC_REG (0x1D) /* Synchronization Error */ + +#define TI_ADS1293_R2_RATE_REG (0x21) /* R2 Decimation Rate */ +#define TI_ADS1293_R3_RATE1_REG (0x22) /* R3 Decimation Rate for Channel 1 */ +#define TI_ADS1293_R3_RATE2_REG (0x23) /* R3 Decimation Rate for Channel 2 */ +#define TI_ADS1293_R3_RATE3_REG (0x24) /* R3 Decimation Rate for Channel 3 */ +#define TI_ADS1293_P_DRATE_REG (0x25) /* 2x Pace Data Rate */ +#define TI_ADS1293_DIS_EFILTER_REG (0x26) /* ECG Filter Disable */ +#define TI_ADS1293_DRDYB_SRC_REG (0x27) /* Data Ready Pin Source */ +#define TI_ADS1293_SYNCOUTB_SRC_REG (0x28) /* Sync Out Pin Source */ +#define TI_ADS1293_MASK_DRDYB_REG (0x29) /* Optional Mask Control for DRDYB Output */ +#define TI_ADS1293_MASK_ERR_REG (0x2A) /* Mask Error on ALARMB Pin */ + +#define TI_ADS1293_ALARM_FILTER_REG (0x2E) /* Digital Filter for Analog Alarm Signals */ +#define TI_ADS1293_CH_CNFG_REG (0x2F) /* Configure Channel for Loop Read Back Mode */ + +#define TI_ADS1293_DATA_STATUS_REG (0x30) /* ECG and Pace Data Ready Status */ +#define TI_ADS1293_DATA_CH1_PACE_H_REG (0x31) /* Channel1 Pace Data High [15:8] */ +#define TI_ADS1293_DATA_CH1_PACE_L_REG (0x32) /* Channel1 Pace Data Low [7:0] */ +#define TI_ADS1293_DATA_CH2_PACE_H_REG (0x33) /* Channel2 Pace Data High [15:8] */ +#define TI_ADS1293_DATA_CH2_PACE_L_REG (0x34) /* Channel2 Pace Data Low [7:0] */ +#define TI_ADS1293_DATA_CH3_PACE_H_REG (0x35) /* Channel3 Pace Data High [15:8] */ +#define TI_ADS1293_DATA_CH3_PACE_L_REG (0x36) /* Channel3 Pace Data Low [7:0] */ +#define TI_ADS1293_DATA_CH1_ECG_H_REG (0x37) /* Channel1 ECG Data High [23:16] */ +#define TI_ADS1293_DATA_CH1_ECG_M_REG (0x38) /* Channel1 ECG Data Medium [15:8] */ +#define TI_ADS1293_DATA_CH1_ECG_L_REG (0x39) /* Channel1 ECG Data Low [7:0] */ +#define TI_ADS1293_DATA_CH2_ECG_H_REG (0x3A) /* Channel2 ECG Data High [23:16] */ +#define TI_ADS1293_DATA_CH2_ECG_M_REG (0x3B) /* Channel2 ECG Data Medium [15:8] */ +#define TI_ADS1293_DATA_CH2_ECG_L_REG (0x3C) /* Channel2 ECG Data Low [7:0] */ +#define TI_ADS1293_DATA_CH3_ECG_H_REG (0x3D) /* Channel3 ECG Data High [23:16] */ +#define TI_ADS1293_DATA_CH3_ECG_M_REG (0x3E) /* Channel3 ECG Data Medium [15:8] */ +#define TI_ADS1293_DATA_CH3_ECG_L_REG (0x3F) /* Channel3 ECG Data Low [7:0] */ + +#define TI_ADS1293_REVID_REG (0x40) /* Revision ID */ +#define TI_ADS1293_DATA_LOOP_REG (0x50) /* Loop Read Back Address */ + +// Useful definitions +#define ADS1293_READ_BIT (0x80) +#define ADS1293_WRITE_BIT (0x7F) + +typedef void (*ads1293_spi_tx_rx_t)(uint8_t* tx, uint8_t* rx, uint8_t len); +typedef struct { + ads1293_spi_tx_rx_t spi_tx_rx; +} ads1293_t; + +void ads1293_spi_init(ads1293_t* ch, ads1293_spi_tx_rx_t spi_tx_rx); + +void ads1293_spi_writereg(ads1293_t* ch, uint8_t addr, uint8_t data); +uint8_t ads1293_spi_readreg(ads1293_t* ch, uint8_t addr); + +void ads1293_spi_autoinc_writereg(ads1293_t* ch, uint8_t addr, uint8_t* data, uint8_t len); +void ads1293_spi_autoinc_readreg(ads1293_t* ch, uint8_t addr, uint8_t* data, uint8_t len); +void ads1293_spi_stream_readreg(ads1293_t* ch, uint8_t* data, uint8_t len); + +#endif // HEADER_FILE_TI_ADS1293_H diff --git a/app/src/one_conduction/one_conduction_board.c b/app/src/one_conduction/one_conduction_board.c index 526c9a8..db1b608 100644 --- a/app/src/one_conduction/one_conduction_board.c +++ b/app/src/one_conduction/one_conduction_board.c @@ -36,6 +36,9 @@ #define EEPROM_I2C_SDA_M 17 // I2C SDA引脚 #define EEPROM_I2C_INSTANCE 1 // I2C使用的硬件控制器ID +#define BEEP_PWM_INSTANCE 0 +#define BEEP_PIN 18 + /******************************************************************************* * TOOLS * *******************************************************************************/ @@ -52,7 +55,7 @@ void SingleLeadECG_adc_module_init() { /******************************************************************************* * 蜂鸣器 * *******************************************************************************/ -static nrf_drv_pwm_t m_beep_pwm0 = NRF_DRV_PWM_INSTANCE(0); +static nrf_drv_pwm_t m_beep_pwm0 = NRF_DRV_PWM_INSTANCE(BEEP_PWM_INSTANCE); 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, @@ -61,7 +64,7 @@ static nrf_pwm_sequence_t const m_beep_pwm0_seq = { .end_delay = 0, }; static nrf_drv_pwm_config_t const m_beep_pwm0_config0 = { - .output_pins = {11}, + .output_pins = {BEEP_PIN}, .irq_priority = APP_IRQ_PRIORITY_LOWEST, .base_clock = NRF_PWM_CLK_125kHz, .count_mode = NRF_PWM_MODE_UP, diff --git a/app/src/three_lead/three_lead_board.c b/app/src/three_lead/three_lead_board.c index 489e07d..4aaa7a0 100644 --- a/app/src/three_lead/three_lead_board.c +++ b/app/src/three_lead/three_lead_board.c @@ -3,6 +3,7 @@ #include "znordic.h" // #include "app_timer.h" +#include "basic\ads1293\ads1293.h" #include "diskio_blkdev.h" #include "ff.h" #include "nrf_block_dev_sdc.h" @@ -13,28 +14,15 @@ #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_PIN NRF_SAADC_INPUT_AIN2 #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 +#define BUTTON_PIN 0 + +#define BEEP_PWM_INSTANCE 0 +#define BEEP_PIN 18 /******************************************************************************* * TOOLS * @@ -50,9 +38,20 @@ void ThreeLeadECG_adc_module_init() { } /******************************************************************************* + * BUTTON * + *******************************************************************************/ +void ThreeLeadECG_button_init() { // + nrf_gpio_cfg_sense_input(BUTTON_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); +} +bool ThreeLeadECG_button_get_state() { + // 低电平有效 + return nrf_gpio_pin_read(BUTTON_PIN) == 0; +} + +/******************************************************************************* * 蜂鸣器 * *******************************************************************************/ -static nrf_drv_pwm_t m_beep_pwm0 = NRF_DRV_PWM_INSTANCE(0); +static nrf_drv_pwm_t m_beep_pwm0 = NRF_DRV_PWM_INSTANCE(BEEP_PWM_INSTANCE); 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, @@ -61,7 +60,7 @@ static nrf_pwm_sequence_t const m_beep_pwm0_seq = { .end_delay = 0, }; static nrf_drv_pwm_config_t const m_beep_pwm0_config0 = { - .output_pins = {11}, + .output_pins = {BEEP_PIN}, .irq_priority = APP_IRQ_PRIORITY_LOWEST, .base_clock = NRF_PWM_CLK_125kHz, .count_mode = NRF_PWM_MODE_UP, @@ -78,85 +77,11 @@ void ThreeLeadECG_beep_set_state(bool state) { 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_init() { znrf_gpio_cfg_output(LED_GREEN_PIN, NRF_GPIO_PIN_NOPULL); } void ThreeLeadECG_led_green_set_state(bool state) { if (state) { nrf_gpio_pin_set(LED_GREEN_PIN); @@ -164,30 +89,6 @@ void ThreeLeadECG_led_green_set_state(bool state) { 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 * @@ -203,63 +104,225 @@ int16_t ThreeLeadECG_battery_get_adc_val() { } /******************************************************************************* - * eeprom * + * SDCARD * *******************************************************************************/ -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); + +/** + * @brief + * + * SPI + * nand flash + * sd card + * switch + */ +#define SDC_SCK_PIN 29 ///< SDC serial clock (SCK) pin. +#define SDC_MOSI_PIN 30 ///< SDC serial data in (DI) pin. +#define SDC_MISO_PIN 31 ///< SDC serial data out (DO) pin. +#define SDC_CS_PIN 20 ///< SDC chip select (CS) pin. + +#define SDCARD_SPI_CS_PIN 8 +#define SDCARD_SPI_MISO_PIN 7 +#define SDCARD_SPI_MOSI_PIN 6 +#define SDCARD_SPI_SCK_PIN 5 +#define SDCARD_USBDRIVER_IC_JUNCTION_CTRL_PIN 5 +#define SDCARD_USBDRIVER_IC_RESET_PIN 5 +#define SDCARD_POWER_CTRL_PIN 5 + +void ThreeLeadECG_sdcard_base_init() { // + /** + * @brief spi引脚切换成输入 + */ + nrf_gpio_cfg_sense_input(SDCARD_SPI_CS_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); + nrf_gpio_cfg_sense_input(SDCARD_SPI_MISO_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); + nrf_gpio_cfg_sense_input(SDCARD_SPI_MOSI_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); + nrf_gpio_cfg_sense_input(SDCARD_SPI_SCK_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); + /** + * @brief USBDRIVER_IC_RESET_PIN ctrl pin + */ + znrf_gpio_cfg_output(SDCARD_USBDRIVER_IC_RESET_PIN, NRF_GPIO_PIN_NOPULL); + nrf_gpio_pin_set(SDCARD_USBDRIVER_IC_RESET_PIN); + /** + * @brief 初始化 SDCARD_USBDRIVER_IC_JUNCTION_CTRL_PIN + */ + znrf_gpio_cfg_output(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_PIN, NRF_GPIO_PIN_NOPULL); + nrf_gpio_pin_set(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_PIN); + /** + * @brief SDCARD电源控制引脚 + */ + znrf_gpio_cfg_output(SDCARD_POWER_CTRL_PIN, NRF_GPIO_PIN_NOPULL); + nrf_gpio_pin_set(SDCARD_POWER_CTRL_PIN); +} +void ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic(bool connect) { + if (connect) { + nrf_gpio_pin_clear(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_PIN); + } else { + nrf_gpio_pin_set(SDCARD_USBDRIVER_IC_JUNCTION_CTRL_PIN); + } } -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_sdcard_flash_power_ctrl(bool power) { + if (!power) { + nrf_gpio_pin_set(SDCARD_POWER_CTRL_PIN); + } else { + nrf_gpio_pin_clear(SDCARD_POWER_CTRL_PIN); + } } -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; +void ThreeLeadECG_sdcard_spi_umount() { + nrf_gpio_cfg_sense_input(SDCARD_SPI_CS_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); + nrf_gpio_cfg_sense_input(SDCARD_SPI_MISO_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); + nrf_gpio_cfg_sense_input(SDCARD_SPI_MOSI_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); + nrf_gpio_cfg_sense_input(SDCARD_SPI_SCK_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_NOSENSE); +} - 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_sdcard_init() { + /** + * @brief + * 0. 必要引脚初始化 + * 1. spi引脚切换成输入 + * 2. 连接flash和usbflash驱动器连接 + * <----option----> + * 4. 打开flash电源 + * + */ + ThreeLeadECG_sdcard_base_init(); // 必要引脚初始化 + ThreeLeadECG_sdcard_spi_umount(); // + ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic(true); + ThreeLeadECG_sdcard_flash_power_ctrl(true); } -void ThreeLeadECG_eeprom_read(uint32_t add, uint8_t *data, uint16_t len) { - uint8_t deviceSelect = 0; - uint8_t wadd[2] = {0}; +NRF_BLOCK_DEV_SDC_DEFINE(m_block_dev_sdc, // + NRF_BLOCK_DEV_SDC_CONFIG(SDC_SECTOR_SIZE, // + APP_SDCARD_CONFIG(SDCARD_SPI_MOSI_PIN, // + SDCARD_SPI_MISO_PIN, // + SDCARD_SPI_SCK_PIN, // + SDCARD_SPI_CS_PIN)), + NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00")); +static FATFS fs; + +void sdcard_test_write_text() { +#define FILE_NAME "IFLYTOP_W_TEST.TXT" + static FIL file; + uint32_t bytes_written; + + NRF_LOG_INFO("Writing to file " FILE_NAME "..."); + FRESULT ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND); + if (ff_result != FR_OK) { + NRF_LOG_INFO("Unable to open or create file: " FILE_NAME "."); + return; + } + + ff_result = f_write(&file, "iflytop", sizeof("iflytop") - 1, (UINT*)&bytes_written); + if (ff_result != FR_OK) { + NRF_LOG_INFO("Write failed\r\n."); + } else { + NRF_LOG_INFO("%d bytes written.", bytes_written); + } + + (void)f_close(&file); +} + +void ThreeLeadECG_sdcard_mount() { + /** + * @brief + * 1. 关闭flash电源 + * 2. 断开flash和usbflash驱动器连接 + * 3. 打开flash电源 + * 4. 初始化SPI引脚,驱动flash + */ + + ThreeLeadECG_sdcard_flash_power_ctrl(false); + ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic(false); + ThreeLeadECG_sdcard_flash_power_ctrl(true); + + /** + * @brief + * 1. 初始化SPI引脚,驱动flash + */ + DSTATUS disk_state = STA_NOINIT; + for (uint32_t retries = 3; retries && disk_state; --retries) { + disk_state = disk_initialize(0); + } + if (disk_state) { + NRF_LOG_INFO("Disk initialization failed. %d", disk_state); + return; + } + NRF_LOG_INFO("Disk initialization succeeded."); + FRESULT ff_result; + ff_result = f_mount(&fs, "", 1); + if (ff_result) { + NRF_LOG_INFO("Mount failed."); + return; + } + sdcard_test_write_text(); +} +void ThreeLeadECG_sdcard_umount() { + /** + * @brief + * 1. 卸载磁盘 + * 2. 失能SPI引脚 + * 3. SPI引脚切换成输入高阻 + * 4. 关闭flash电源 + * 5. 连接flash和usbflash驱动器连接 + * <----option----> + * 6. 打开flash电源(硬件改版后,flash的电可以从USB上取,就不需要再打开flash电源了) + */ + // umount + f_mount(NULL, "", 1); + disk_uninitialize(0); + ThreeLeadECG_sdcard_spi_umount(); + ThreeLeadECG_sdcard_flash_power_ctrl(false); + ThreeLeadECG_sdcard_connect2_ext_usb_sdcard_driver_ic(true); + ThreeLeadECG_sdcard_flash_power_ctrl(true); +} + +/******************************************************************************* + * ecg * + *******************************************************************************/ +#define ADS1293_SPI_MISO_PIN 31 +#define ADS1293_SPI_CS0_PIN 20 +#define ADS1293_SPI_CS1_PIN 20 +#define ADS1293_SPI_SCK_PIN 29 +#define ADS1293_SPI_MOSI_PIN 30 + +static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(0); /**< SPI instance. */ + +static ads1293_t m_ads1293_0; +static ads1293_t m_ads1293_1; + +void ads1293_spi_tx_rx_0(uint8_t* tx, uint8_t* rx, uint8_t len) { + nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN); + nrf_drv_spi_transfer(&spi, tx, len, rx, len); + nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); +} +void ads1293_spi_tx_rx_1(uint8_t* tx, uint8_t* rx, uint8_t len) { + nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN); + nrf_drv_spi_transfer(&spi, tx, len, rx, len); + nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); +} + +void ThreeLeadECG_ecg_init() { + nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; + spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; // NRF_DRV_SPI_PIN_NOT_USED + spi_config.miso_pin = ADS1293_SPI_MISO_PIN; + spi_config.mosi_pin = ADS1293_SPI_MOSI_PIN; + spi_config.sck_pin = ADS1293_SPI_SCK_PIN; + spi_config.frequency = NRF_DRV_SPI_FREQ_1M; + ZERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, NULL, NULL)); + + nrf_gpio_cfg_input(ADS1293_SPI_CS0_PIN, NRF_GPIO_PIN_NOPULL); + nrf_gpio_cfg_input(ADS1293_SPI_CS1_PIN, NRF_GPIO_PIN_NOPULL); + + nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); + nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); + + m_ads1293_0.spi_tx_rx = ads1293_spi_tx_rx_0; + m_ads1293_1.spi_tx_rx = ads1293_spi_tx_rx_1; - assign_i2c_add(add, false, &deviceSelect, &wadd[0], &wadd[1]); - nrf_drv_twi_tx(&m_eeprom_twi_master, deviceSelect, wadd, 2, false); + ads1293_spi_init(&m_ads1293_0, ads1293_spi_tx_rx_0); + ads1293_spi_init(&m_ads1293_1, ads1293_spi_tx_rx_1); - deviceSelect |= 0x01; // read - nrf_drv_twi_rx(&m_eeprom_twi_master, deviceSelect, data, len); + uint8_t revid = ads1293_spi_readreg(&m_ads1293_0, TI_ADS1293_REVID_REG); + NRF_LOG_INFO("ads1293_0 revid: %d", revid); + revid = ads1293_spi_readreg(&m_ads1293_1, TI_ADS1293_REVID_REG); + NRF_LOG_INFO("ads1293_1 revid: %d", revid); } diff --git a/app/src/three_lead/three_lead_board.h b/app/src/three_lead/three_lead_board.h index 6fcb22f..6807166 100644 --- a/app/src/three_lead/three_lead_board.h +++ b/app/src/three_lead/three_lead_board.h @@ -14,7 +14,11 @@ * basic * *******************************************************************************/ void ThreeLeadECG_adc_module_init(); - +/******************************************************************************* + * BUTTON * + *******************************************************************************/ +void ThreeLeadECG_button_init(); +bool ThreeLeadECG_button_get_state(); /******************************************************************************* * 蜂鸣器 * *******************************************************************************/ @@ -22,44 +26,22 @@ 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(); \ No newline at end of file +int16_t ThreeLeadECG_battery_get_adc_val(); +/******************************************************************************* + * SDCARD * + *******************************************************************************/ +void ThreeLeadECG_sdcard_init(); +void ThreeLeadECG_sdcard_mount(); +void ThreeLeadECG_sdcard_umount(); +/******************************************************************************* + * ECG * + *******************************************************************************/ +void ThreeLeadECG_ecg_init();