Compare commits

...

24 Commits

Author SHA1 Message Date
weiting2 9f33098b52 update rec cali data 2021-01-21 17:39:55 +08:00
weiting2 dd9f64662e update rec cali data 2021-01-21 17:32:06 +08:00
weiting2 a80ab9a72f E7DA special version, update cali and its formula 2021-01-21 17:14:12 +08:00
weiting2 a348b9553d [bug] "rec+sti" mode will stop read spi sometime 2020-12-22 18:26:10 +08:00
weiting2 2937fa6a11 [bug] "rec+sti" mode will stop read spi sometime 2020-12-22 18:15:36 +08:00
weiting2 4a973421df there are bug if "start all -> stop all -> start rec" 2020-12-22 09:55:22 +08:00
weiting2 521e241978 change led and enable rec after limit sti end 2020-12-18 18:09:40 +08:00
weiting2 d1ba348ea0 fast set do not reset sti now 2020-12-11 11:36:55 +08:00
weiting2 8686220e28 do not check sti in limit mode; resend rec ch when press "start rec" 2020-12-10 19:18:05 +08:00
weiting2 91e62474d1 idle state pull low MISO; send three time ins to close sti 2020-12-10 17:30:28 +08:00
weiting2 734da9a27e correct start rec bug; should be test: sti turn on/off correctly? 2020-12-10 13:58:48 +08:00
weiting2 bd48ac8d49 should be test: sti turn on/off correctly? 2020-12-09 17:07:15 +08:00
weiting2 9f68a07d31 attempt to fix sti start/stop failed issue 2020-12-09 16:41:51 +08:00
weiting2 87cac38444 fix central on_change bug 2020-11-30 11:31:10 +08:00
weiting2 7f163e85c3 special version for E7DA, E6EA 2020-11-27 18:11:56 +08:00
weiting2 7880fce151 special version for E7DA, E6EA 2020-11-25 14:06:16 +08:00
weiting2 abf67f5dd4 [stable] sti_amp with init value 2020-11-24 18:28:15 +08:00
weiting2 cf9766c786 [stable] better current cali; "start sti" no bug 2020-11-24 17:59:36 +08:00
weiting2 7063a2460a update E7DA, E6EA sti cali data 2020-11-23 14:25:16 +08:00
weiting2 11a6389a83 neulive without sti frequency on change 2020-11-16 14:48:21 +08:00
weiting2 9dde948902 Merge branch 'neulive_onchange_central_debug' into neulive20_development_onchange_central
# Conflicts:
#	simplelink/ble_sdk_2_02_02_25/src/examples/simple_peripheral/cc26xx/app/headstage/headstage_dbs_object.h
#	simplelink/ble_sdk_2_02_02_25/src/examples/simple_peripheral/cc26xx/app/headstage/headstage_version.h
2020-11-16 14:47:11 +08:00
weiting2 9209d9dff7 neulive without sti frequency on change 2020-11-16 14:44:17 +08:00
weiting2 acd0080929 sti_clk ratio should be system register 2020-11-13 18:30:41 +08:00
weiting2 8ae43d0628 sti_clk ratio should be system register 2020-11-13 16:06:21 +08:00
11 changed files with 569 additions and 254 deletions
+2 -2
View File
@@ -16,8 +16,8 @@ no device y=ax+b MAC a+ b+ a- b- avg
15 E871 E871 A4:DA:32:D4:E8:71 2175 -4549 2220 31468 4.60684608395208
16 EFC4 EFC4 A4:DA:32:D4:EF:C4 2348 -4371 2374 -26606 4.45106768611704
17 EF85 EF85 A4:DA:32:D4:EF:85 2136 -3339 2189 -30040 4.61909624778354
18 E7DA E7DA A4:DA:32:D4:E7:DA 2081 -3015 2122 -21543 4.79766509652981
19 E6EA E6EA A4:DA:32:D4:E6:EA 2039 -262 2127 -47259 4.79384458739747
18 E7DA E7DA A4:DA:32:D4:E7:DA 2096 -10653 2054 -14255 3.73011080492424
19 E6EA E6EA A4:DA:32:D4:E6:EA 2074 -13075 2031 -13585 3.77641447962488
20 EEDB EEDB A4:DA:32:D4:EE:DB 2214 -1170 2351 -24636 4.44485358085645
21 E73A E73A A4:DA:32:D4:E7:3A 2210 -4855 2339 -16434 4.47776494604746
22 E6CF E6CF A4:DA:32:D4:E6:CF 2135 -5206 2193 -30885 4.73462680884304
@@ -102,8 +102,8 @@ typedef enum {
FLUSH_BUFFER2, // clean SPI buffer twice
READ_REG, // read DBS register value, used after a "read" SPI instruction (MISO)
READ_REG2, // read DBS register value, used after a "read" SPI instruction (MISO)
END_TRANSMIT, // read DBS register value, used after a "read" SPI instruction (MISO)
ONE_SHOT_SPI, // end spi instruction
ONE_SHOT_FLUSH, // read DBS register value, used after a "read" SPI instruction (MISO)
CONTI_SPI_WITH_FLUSH, // end spi instruction
READ_MOSI
} SPI_CB_MODE;
@@ -119,6 +119,8 @@ static bool ConnectState = false;
static bool ErrorRestart = false;
static SPI_CB_MODE SPICallBack;
static uint8 adc_spi_en_switch = 1;
static bool rewrite_rec_en = false;
static bool rewrite_sti_en = false;
/*
* Let C = command, S = status;
@@ -192,18 +192,18 @@ struct _StiCaliStiTable{
#elif defined(BOARD_A4_DA_32_D4_E7_DA)
{
.p_ch.coefficient = 2081,
.p_ch.offset = -3015,
.n_ch.coefficient = 2122,
.n_ch.offset = -21543
.p_ch.coefficient = 4834,
.p_ch.offset = -10653,
.n_ch.coefficient = 4628,
.n_ch.offset = -14255
};
#elif defined(BOARD_A4_DA_32_D4_E6_EA)
{
.p_ch.coefficient = 2039,
.p_ch.offset = -262,
.n_ch.coefficient = 2127,
.n_ch.offset = -47259
.p_ch.coefficient = 4980,
.p_ch.offset = -13075,
.n_ch.coefficient = 4660,
.n_ch.offset = -13585
};
#elif defined(BOARD_A4_DA_32_D4_EE_DB)
@@ -2,7 +2,7 @@
#ifndef NEU_CALI_TABLE
#define NEU_CALI_TABLE
#define BOARD_TEST
#define BOARD_A4_DA_32_D4_E7_DA
typedef struct _SingleChannelCali{
uint16_t Gain[4];
@@ -1673,70 +1673,70 @@ struct _CaliTable{
#elif defined(BOARD_A4_DA_32_D4_E7_DA)
{
.DeviceName = "BOARD_A4_DA_32_D4_E7_DA",
.Ch[0].Gain[0] = 49,
.Ch[0].Offset[0] = -13,
.Ch[1].Gain[0] = 49,
.Ch[0].Gain[0] = 48,
.Ch[0].Offset[0] = -14,
.Ch[1].Gain[0] = 48,
.Ch[1].Offset[0] = 26,
.Ch[2].Gain[0] = 49,
.Ch[2].Offset[0] = -14,
.Ch[3].Gain[0] = 49,
.Ch[2].Gain[0] = 48,
.Ch[2].Offset[0] = -15,
.Ch[3].Gain[0] = 48,
.Ch[3].Offset[0] = 17,
.Ch[4].Gain[0] = 49,
.Ch[4].Offset[0] = 5,
.Ch[5].Gain[0] = 49,
.Ch[5].Offset[0] = -2,
.Ch[6].Gain[0] = 47,
.Ch[6].Offset[0] = -8,
.Ch[7].Gain[0] = 47,
.Ch[7].Offset[0] = -11,
.Ch[0].Gain[1] = 359,
.Ch[0].Offset[1] = -54,
.Ch[1].Gain[1] = 359,
.Ch[4].Gain[0] = 48,
.Ch[4].Offset[0] = 4,
.Ch[5].Gain[0] = 48,
.Ch[5].Offset[0] = -3,
.Ch[6].Gain[0] = 46,
.Ch[6].Offset[0] = -9,
.Ch[7].Gain[0] = 46,
.Ch[7].Offset[0] = -12,
.Ch[0].Gain[1] = 354,
.Ch[0].Offset[1] = -55,
.Ch[1].Gain[1] = 355,
.Ch[1].Offset[1] = 230,
.Ch[2].Gain[1] = 362,
.Ch[2].Offset[1] = -70,
.Ch[3].Gain[1] = 361,
.Ch[3].Offset[1] = 164,
.Ch[4].Gain[1] = 361,
.Ch[4].Offset[1] = 72,
.Ch[5].Gain[1] = 360,
.Ch[2].Gain[1] = 356,
.Ch[2].Offset[1] = -71,
.Ch[3].Gain[1] = 355,
.Ch[3].Offset[1] = 163,
.Ch[4].Gain[1] = 356,
.Ch[4].Offset[1] = 73,
.Ch[5].Gain[1] = 355,
.Ch[5].Offset[1] = 22,
.Ch[6].Gain[1] = 345,
.Ch[6].Offset[1] = -23,
.Ch[7].Gain[1] = 345,
.Ch[7].Offset[1] = -39,
.Ch[0].Gain[2] = 1482,
.Ch[0].Offset[2] = -197,
.Ch[1].Gain[2] = 1372,
.Ch[1].Offset[2] = 946,
.Ch[2].Gain[2] = 1473,
.Ch[2].Offset[2] = -275,
.Ch[3].Gain[2] = 1443,
.Ch[3].Offset[2] = 686,
.Ch[4].Gain[2] = 1477,
.Ch[4].Offset[2] = 313,
.Ch[5].Gain[2] = 1479,
.Ch[5].Offset[2] = 104,
.Ch[6].Gain[2] = 1424,
.Ch[6].Offset[2] = -75,
.Ch[7].Gain[2] = 1436,
.Ch[6].Gain[1] = 336,
.Ch[6].Offset[1] = -21,
.Ch[7].Gain[1] = 335,
.Ch[7].Offset[1] = -37,
.Ch[0].Gain[2] = 1458,
.Ch[0].Offset[2] = -198,
.Ch[1].Gain[2] = 1347,
.Ch[1].Offset[2] = 944,
.Ch[2].Gain[2] = 1455,
.Ch[2].Offset[2] = -271,
.Ch[3].Gain[2] = 1423,
.Ch[3].Offset[2] = 677,
.Ch[4].Gain[2] = 1454,
.Ch[4].Offset[2] = 320,
.Ch[5].Gain[2] = 1454,
.Ch[5].Offset[2] = 106,
.Ch[6].Gain[2] = 1369,
.Ch[6].Offset[2] = -65,
.Ch[7].Gain[2] = 1381,
.Ch[7].Offset[2] = -134,
.Ch[0].Gain[3] = 2821,
.Ch[0].Offset[3] = -357,
.Ch[1].Gain[3] = 1262,
.Ch[1].Offset[3] = 1440,
.Ch[2].Gain[3] = 2746,
.Ch[2].Offset[3] = -506,
.Ch[3].Gain[3] = 1934,
.Ch[3].Offset[3] = 1131,
.Ch[4].Gain[3] = 2659,
.Ch[4].Offset[3] = 576,
.Ch[5].Gain[3] = 2873,
.Ch[5].Offset[3] = 212,
.Ch[6].Gain[3] = 2770,
.Ch[6].Offset[3] = -142,
.Ch[7].Gain[3] = 2764,
.Ch[7].Offset[3] = -239
.Ch[0].Gain[3] = 2775,
.Ch[0].Offset[3] = -362,
.Ch[1].Gain[3] = 1257,
.Ch[1].Offset[3] = 1442,
.Ch[2].Gain[3] = 2713,
.Ch[2].Offset[3] = -503,
.Ch[3].Gain[3] = 1929,
.Ch[3].Offset[3] = 1125,
.Ch[4].Gain[3] = 2621,
.Ch[4].Offset[3] = 580,
.Ch[5].Gain[3] = 2834,
.Ch[5].Offset[3] = 206,
.Ch[6].Gain[3] = 2698,
.Ch[6].Offset[3] = -115,
.Ch[7].Gain[3] = 2690,
.Ch[7].Offset[3] = -250
};
#elif defined(BOARD_A4_DA_32_D4_E6_EA)
@@ -27,7 +27,7 @@ static void check_register(uint8_t register_to_check, uint16_t instruction_to_fi
check_reg_counter = 0;
if(check_ins(instruction_to_fit)){
NEULIVE_STATE.state = next_state;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
// update rec_sti_command
if(!(rec_sti_command & ENABLE_STI)){
@@ -70,7 +70,7 @@ static void check_register(uint8_t register_to_check, uint16_t instruction_to_fi
IsFirstData = true;
}
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
ReopenSPI();
}
headstage_spi_transaction(3);
@@ -167,7 +167,7 @@ static void check_sti_t1_t5(NEU_WORK_STATE next_state){
else{
NEULIVE_STATE.state = next_state;
}
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
headstage_spi_transaction(3);
}
@@ -8,6 +8,7 @@
#define SYS_GENERAL_ENABLE_INDEX 1
#define SYS_LNA_BIOS1_INDEX 2
#define SYS_LNA_BIOS2_INDEX 3
#define SYS_STI_CLK_RATIO_INDEX 4
#define REC_CHANNEL_INDEX 0
#define REC_GAIN_INDEX 1
@@ -37,37 +38,44 @@
typedef struct _DBSRegister{
uint8_t address;
bool WriteRegister, CheckRegister;
void (*write_reg) (struct _DBSRegister *self, uint16_t reg_value);
void (*write_reg) (uint8_t self_address, uint16_t reg_value);
void (*read_reg) (struct _DBSRegister *self);
}DBSRegister;
void write_reg(DBSRegister *self, uint16_t reg_value){
spi_txbuf[0] = 0x80 | self->address;
void write_reg(uint8_t self_address, uint16_t reg_value){
spi_txbuf[0] = 0x80 | self_address;
spi_txbuf[1] = (reg_value >> 8) & 0xFF ;
spi_txbuf[2] = reg_value & 0xFF;
SPICallBack = ONE_SHOT_SPI;
// self->WriteRegister = false;
// self->CheckRegister = true;
SPICallBack = CONTI_SPI_WITH_FLUSH;
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
void read_reg(DBSRegister *self){
spi_txbuf[0] = 0x7F & self->address;
spi_txbuf[1] = 0x7F & self->address; // it's don't care actually
spi_txbuf[2] = 0x7F & self->address; // it's don't care actually
spi_txbuf[1] = 0; // it's don't care actually
spi_txbuf[2] = 0; // it's don't care actually
SPICallBack = READ_REG;
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
static uint16_t sys_register_default_value[4] = {
static uint16_t sys_register_default_value[5] = {
0x0000,
0x40F2,
0x0210,
0x4210
0x4210,
0x0002
};
static uint16_t rec_register_value[3];
static uint16_t sti_register_value[43];
static uint16_t fast_settle_param[43];
static void init_fast_settle();
static DBSRegister sys_register[4];
static DBSRegister sys_register[5];
static DBSRegister rec_register[3];
static DBSRegister sti_register[43];
@@ -76,6 +84,7 @@ static void InitSysRegister(){
sys_register[SYS_GENERAL_ENABLE_INDEX].address = 47; // general enable
sys_register[SYS_LNA_BIOS1_INDEX].address = 57;
sys_register[SYS_LNA_BIOS2_INDEX].address = 58;
sys_register[SYS_STI_CLK_RATIO_INDEX].address = 52;
for(int i=0 ; i<sizeof(sys_register)/sizeof(DBSRegister) ; i++){
sys_register[i].WriteRegister = false;
@@ -96,6 +105,10 @@ static void InitRecRegister(){
rec_register[i].write_reg = &write_reg;
rec_register[i].read_reg = &read_reg;
}
rec_register_value[REC_CHANNEL_INDEX] = 0;
rec_register_value[REC_GAIN_INDEX] = 1;
rec_register_value[REC_ADC_CLOCK_INDEX] = 100;
}
static void InitStiRegister(){
@@ -124,18 +137,24 @@ static void InitStiRegister(){
sti_register[i].write_reg = &write_reg;
sti_register[i].read_reg = &read_reg;
}
sti_register_value[STI_AMP_POS_INDEX] = 1;
sti_register_value[STI_AMP_NEG_INDEX] = 1;
}
static void InitDBSRegister(){
InitSysRegister();
InitRecRegister();
InitStiRegister();
init_fast_settle();
// for(int i=1 ; i<sizeof(sys_register)/sizeof(DBSRegister) ; i++){
for(int i=1 ; i<4 ; i++){
for(int i=1 ; i<sizeof(sys_register)/sizeof(DBSRegister) ; i++){
sys_register[i].WriteRegister = true;
}
flag_notify(EVT_NEU_SPI);
sys_register[0].CheckRegister = true;
sys_register[0].write_reg(sys_register[0].address, sys_register_default_value[0]);
// flag_notify(EVT_NEU_SPI);
}
static void ResetDBSRegister(){
@@ -161,4 +180,35 @@ static void ResetDBSRegister(){
}
}
static uint16_t fast_settle_param[43];
static void init_fast_settle(){
uint8_t ch = 7;
uint8_t t1=25, t2=0, t3=25 , t4=0, t5=0;
// setting t1~t5
fast_settle_param[ch*4 + STI_DURATION0_INDEX] = (t2 & 0x003F) << 10 | (t1 & 0x03FF);
fast_settle_param[ch*4 + STI_DURATION1_INDEX] = (t4 & 0x0003) << 14 | (t3 & 0x03FF) << 4 | (t2 & 0x03C0) >> 6;
fast_settle_param[ch*4 + STI_DURATION2_INDEX] = (t4 & 0x0007FFFC) >> 2;
fast_settle_param[ch*4 + STI_DURATION3_INDEX] = t5;
// cycle number
fast_settle_param[STI_CYCLE_CH67_INDEX] = 10 << 8 | 0;
// set polarity, it's don't care in fast settle
fast_settle_param[STI_POLARITY_INDEX] = 0;
// set stimulate mode
fast_settle_param[STI_MODE_INDEX] = 0;
// INSTRUCTION.sti_mode = 0; // 1 = continuous mode; 0 = limit mode
// INSTRUCTION.sti_h_bridge = 0; // voltage sti must use H-bridge
// INSTRUCTION.sti_ref = 0; // 1 = GND; 0 = Vref
// using minimum amplitude
fast_settle_param[STI_AMP_POS_INDEX] = 0;
fast_settle_param[STI_AMP_NEG_INDEX] = 0;
// using ch8 to fast settle
fast_settle_param[STI_ENABLE_INDEX] = 0b0000000010000000; // 0bxxxx_xxxv_cccc_cccc, c = current; v = volt, x = don't care
}
#endif
@@ -407,25 +407,46 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
}
case NEU_MULTI_STI: {
uint8_t ch = instruction[1];
// uint8_t sti_cycles = instruction[2];
// INSTRUCTION.sti_t1[ch] = (instruction[3] << 8) | instruction[4];
// INSTRUCTION.sti_t2[ch] = (instruction[5] << 8) | instruction[6];
// INSTRUCTION.sti_t3[ch] = (instruction[7] << 8) | instruction[8];
// INSTRUCTION.sti_t4[ch] = (0x00 << 24) | (instruction[9] << 16) | (instruction[10] << 8) | instruction[11];
// INSTRUCTION.sti_t5[ch] = (instruction[12] << 8) | instruction[13];
// INSTRUCTION.current_sti_cycle[ch] = sti_cycles;
// uint8_t ch = instruction[1];
uint8_t sti_cycles = instruction[2];
uint16_t t1 = (instruction[3] << 8) | instruction[4]; // t1 is 10 bits
uint16_t t2 = (instruction[5] << 8) | instruction[6]; // t2 is 10 bits
uint16_t t3 = (instruction[7] << 8) | instruction[8]; // t3 is 10 bits
uint32_t t4 = (0x00 << 24) | (instruction[9] << 16) | (instruction[10] << 8) | instruction[11]; // t4 is 17 bits
uint16_t t5 = (instruction[12] << 8) | instruction[13]; // t5 is 10 bits
for(int i=0 ; i<8 ; i++){
uint8_t sti_cycles = instruction[2];
INSTRUCTION.sti_t1[i] = (instruction[3] << 8) | instruction[4];
INSTRUCTION.sti_t2[i] = (instruction[5] << 8) | instruction[6];
INSTRUCTION.sti_t3[i] = (instruction[7] << 8) | instruction[8];
INSTRUCTION.sti_t4[i] = (0x00 << 24) | (instruction[9] << 16) | (instruction[10] << 8) | instruction[11];
INSTRUCTION.sti_t5[i] = (instruction[12] << 8) | instruction[13];
INSTRUCTION.sti_t1[i] = t1;
INSTRUCTION.sti_t2[i] = t2;
INSTRUCTION.sti_t3[i] = t3;
INSTRUCTION.sti_t4[i] = t4;
INSTRUCTION.sti_t5[i] = t5;
INSTRUCTION.current_sti_cycle[i] = sti_cycles;
}
sti_register[STI_CYCLE_CH01_INDEX].WriteRegister = true;
sti_register_value[STI_CYCLE_CH01_INDEX] = sti_cycles;
sti_register[STI_CYCLE_CH23_INDEX].WriteRegister = true;
sti_register_value[STI_CYCLE_CH23_INDEX] = sti_cycles;
sti_register[STI_CYCLE_CH45_INDEX].WriteRegister = true;
sti_register_value[STI_CYCLE_CH45_INDEX] = sti_cycles;
sti_register[STI_CYCLE_CH67_INDEX].WriteRegister = true;
sti_register_value[STI_CYCLE_CH67_INDEX] = sti_cycles;
for(int ch=0 ; ch<8 ; ch++){
sti_register[ch*4 + STI_DURATION0_INDEX].WriteRegister = true;
sti_register_value[ch*4 + STI_DURATION0_INDEX] = (t2 & 0x003F) << 10 | (t1 & 0x03FF);
sti_register[ch*4 + STI_DURATION1_INDEX].WriteRegister = true;
sti_register_value[ch*4 + STI_DURATION1_INDEX] = (t4 & 0x0003) << 14 | (t3 & 0x03FF) << 4 | (t2 & 0x03C0) >> 6;
sti_register[ch*4 + STI_DURATION2_INDEX].WriteRegister = true;
sti_register_value[ch*4 + STI_DURATION2_INDEX] = (t4 & 0x0007FFFC) >> 2;
sti_register[ch*4 + STI_DURATION3_INDEX].WriteRegister = true;
sti_register_value[ch*4 + STI_DURATION3_INDEX] = t5;
}
break;
}
@@ -451,6 +472,14 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
INSTRUCTION.sys_clk_ratio = sys_clk_ratio;
INSTRUCTION.amplifier_gain = amplifier_gain; /**< control shift*/
INSTRUCTION.chopper_ratio = chopper_ratio;
rec_register_value[REC_CHANNEL_INDEX] = recording_channel;
rec_register_value[REC_GAIN_INDEX] = amplifier_gain;
rec_register_value[REC_ADC_CLOCK_INDEX] = adc_clock_ratio;
rec_register[REC_CHANNEL_INDEX].WriteRegister = true;
rec_register[REC_GAIN_INDEX].WriteRegister = true;
rec_register[REC_ADC_CLOCK_INDEX].WriteRegister = true;
break;
}
@@ -514,7 +543,13 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
rec_register[REC_CHANNEL_INDEX].WriteRegister = true;
rec_register_value[REC_CHANNEL_INDEX] = reg_value;
INSTRUCTION.recording_channel = reg_value;
flag_notify(EVT_NEU_SPI);
// if(rec_sti_command & STATUS_REC){
// // do nothing
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
@@ -528,7 +563,13 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
case REC_ADC_CLOCK_INDEX:{
rec_register[REC_ADC_CLOCK_INDEX].WriteRegister = true;
rec_register_value[REC_ADC_CLOCK_INDEX] = reg_value;
flag_notify(EVT_NEU_SPI);
// if(rec_sti_command & STATUS_REC){
// // do nothing
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
@@ -549,35 +590,61 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
}
case STI_AMP_POS_INDEX:{
uint16_t sti_amp_cali = 0;
sti_register[STI_AMP_POS_INDEX].WriteRegister = true;
sti_register_value[STI_AMP_POS_INDEX] = sti_reg_value;
sti_amp_cali = UserCode2StiCode(sti_reg_value, POSITIVE_CHANNEL);
sti_register_value[STI_AMP_POS_INDEX] = sti_amp_cali;
// pos, neg amplitude should be same at this DBS version
sti_register[STI_AMP_NEG_INDEX].WriteRegister = true;
sti_register_value[STI_AMP_NEG_INDEX] = sti_reg_value;
sti_amp_cali = UserCode2StiCode(sti_reg_value, NEGATIVE_CHANNEL);
sti_register_value[STI_AMP_NEG_INDEX] = sti_amp_cali;
flag_notify(EVT_NEU_SPI);
// if(rec_sti_command & STATUS_STI){
// // do nothing
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
case STI_AMP_NEG_INDEX:{
sti_register[STI_AMP_NEG_INDEX].WriteRegister = true;
sti_register_value[STI_AMP_NEG_INDEX] = sti_reg_value;
flag_notify(EVT_NEU_SPI);
// if(rec_sti_command & STATUS_STI){
// // do nothing
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
case STI_POLARITY_INDEX:{
sti_register[STI_POLARITY_INDEX].WriteRegister = true;
sti_register_value[STI_POLARITY_INDEX] = sti_reg_value;
flag_notify(EVT_NEU_SPI);
// if(rec_sti_command & STATUS_STI){
// // do nothing
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
case STI_MODE_INDEX:{
sti_register[STI_MODE_INDEX].WriteRegister = true;
sti_register_value[STI_MODE_INDEX] = instruction[2];
flag_notify(EVT_NEU_SPI);
// if(rec_sti_command & STATUS_STI){
// // do nothing
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
@@ -590,7 +657,7 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
sti_register_value[STI_CYCLE_CH45_INDEX] = sti_reg_value;
sti_register[STI_CYCLE_CH67_INDEX].WriteRegister = true;
sti_register_value[STI_CYCLE_CH67_INDEX] = sti_reg_value;
flag_notify(EVT_NEU_SPI);
// flag_notify(EVT_NEU_SPI);
break;
}
@@ -614,7 +681,7 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
sti_register[ch*4 + STI_DURATION3_INDEX].WriteRegister = true;
sti_register_value[ch*4 + STI_DURATION3_INDEX] = t5;
}
flag_notify(EVT_NEU_SPI);
// flag_notify(EVT_NEU_SPI);
break;
}
@@ -635,7 +702,7 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
*
* description: decode virtual instruction to start, stop, reset, etc.
*/
static uint8_t fast_set = 0;
static void headstage_update_vis_instruction(uint8_t vis_oper) {
switch (vis_oper) {
case VIS_RST: {
@@ -644,7 +711,7 @@ static void headstage_update_vis_instruction(uint8_t vis_oper) {
FlushNotify();
}
NEULIVE_STATE.state = NEU_RST;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
flag_notify(EVT_NEU_SPI);
/**< stop spi transaction */
break; /**< reset all the parameter */
@@ -652,53 +719,33 @@ static void headstage_update_vis_instruction(uint8_t vis_oper) {
case VIS_FAST_SET:{
uint8_t ch = 7;
uint8_t t1=25, t2=0, t3=25 , t4=0, t5=0;
// using ch8 to fast settle
INSTRUCTION.sti_channel = 0b0000000010000000;
sti_register_value[STI_ENABLE_INDEX] = 0b0000000010000000; // 0bxxxx_xxxv_cccc_cccc, c = current; v = volt, x = don't care
sti_register[STI_ENABLE_INDEX].WriteRegister = true;
// setting t1~t5
sti_register_value[ch*4 + STI_DURATION0_INDEX] = (t2 & 0x003F) << 10 | (t1 & 0x03FF);
sti_register_value[ch*4 + STI_DURATION1_INDEX] = (t4 & 0x0003) << 14 | (t3 & 0x03FF) << 4 | (t2 & 0x03C0) >> 6;
sti_register_value[ch*4 + STI_DURATION2_INDEX] = (t4 & 0x0007FFFC) >> 2;
sti_register_value[ch*4 + STI_DURATION3_INDEX] = t5;
fast_set = 1; // fast set flag will turn off after
sti_register[ch*4 + STI_DURATION0_INDEX].WriteRegister = true;
sti_register[ch*4 + STI_DURATION1_INDEX].WriteRegister = true;
sti_register[ch*4 + STI_DURATION2_INDEX].WriteRegister = true;
sti_register[ch*4 + STI_DURATION3_INDEX].WriteRegister = true;
// cycle number
sti_register_value[STI_CYCLE_CH67_INDEX] = 10 << 8 | 0;
sti_register[STI_CYCLE_CH67_INDEX].WriteRegister = true;
// set polarity, it's don't care in fast settle
sti_register_value[STI_POLARITY_INDEX] = 0;
sti_register[STI_POLARITY_INDEX].WriteRegister = true;
// set stimulate mode
sti_register_value[STI_MODE_INDEX] = 0;
sti_register[STI_MODE_INDEX].WriteRegister = true;
// INSTRUCTION.sti_mode = 0; // 1 = continuous mode; 0 = limit mode
// INSTRUCTION.sti_h_bridge = 0; // voltage sti must use H-bridge
// INSTRUCTION.sti_ref = 0; // 1 = GND; 0 = Vref
// using minimum amplitude
sti_register_value[STI_AMP_POS_INDEX] = 0;
sti_register_value[STI_AMP_NEG_INDEX] = 0;
sti_register[STI_AMP_POS_INDEX].WriteRegister = true;
sti_register[STI_AMP_NEG_INDEX].WriteRegister = true;
rec_sti_command |= ENABLE_STI;
// using ch8 to fast settle
sti_register[STI_ENABLE_INDEX].WriteRegister = true;
// is neu wording now?
if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// nothing to do
}
else{
flag_notify(EVT_NEU_SPI);
}
rec_sti_command |= ENABLE_STI;
break;
}
@@ -713,66 +760,89 @@ static void headstage_update_vis_instruction(uint8_t vis_oper) {
// FlushNotify();
// }
if(INSTRUCTION.sti_channel){
if(sti_register_value[STI_ENABLE_INDEX]){
rec_sti_command |= ENABLE_STI;
NEULIVE_STATE.state = NEU_WRITE_STI_INS;
INSTRUCTION.ins_opcode = T_ZE;
// sti_register[STI_ENABLE_INDEX].WriteRegister = true;
sti_register[STI_MODE_INDEX].WriteRegister = true;
sti_register[STI_POLARITY_INDEX].WriteRegister = true;
sti_register[STI_AMP_POS_INDEX].WriteRegister = true;
sti_register[STI_AMP_NEG_INDEX].WriteRegister = true;
}
if(INSTRUCTION.recording_channel){
rec_sti_command |= ENABLE_REC;
// old instrucion type
NEULIVE_STATE.state = NEU_WRITE_REC_INS;
INSTRUCTION.ins_opcode = BIAS_ONE;
// new instruction type
rec_register[REC_CHANNEL_INDEX].WriteRegister = true;
rec_register[REC_GAIN_INDEX].WriteRegister = true;
rec_register[REC_ADC_CLOCK_INDEX].WriteRegister = true;
}
NEULIVE_STATE.config_type = NEU_WARM_UP;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
// is neu wording now?
if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// nothing to do
}
else{
flag_notify(EVT_NEU_SPI);
}
// if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// // nothing to do
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break; /**< start to operate */
}
case VIS_REC: {
if(INSTRUCTION.recording_channel){
rec_sti_command |= ENABLE_REC;
// old instrucion type
NEULIVE_STATE.state = NEU_WRITE_REC_INS;
INSTRUCTION.ins_opcode = BIAS_ONE;
NEULIVE_STATE.config_type = NEU_WARM_UP;
SPICallBack = ONE_SHOT_SPI;
// new instruction type
rec_register[REC_CHANNEL_INDEX].WriteRegister = true;
rec_register[REC_GAIN_INDEX].WriteRegister = true;
rec_register[REC_ADC_CLOCK_INDEX].WriteRegister = true;
SPICallBack = CONTI_SPI_WITH_FLUSH;
// is neu wording now?
if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// nothing to do
}
else{
flag_notify(EVT_NEU_SPI);
}
// if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// // nothing to do
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
}
break;
}
case VIS_STI:{
if(INSTRUCTION.sti_channel){
if(sti_register_value[STI_ENABLE_INDEX]){
rec_sti_command |= ENABLE_STI;
NEULIVE_STATE.state = NEU_WRITE_STI_INS;
NEULIVE_STATE.config_type = NEU_WARM_UP;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
INSTRUCTION.ins_opcode = T_ZE;
// sti_register[STI_ENABLE_INDEX].WriteRegister = true;
sti_register[STI_MODE_INDEX].WriteRegister = true;
sti_register[STI_POLARITY_INDEX].WriteRegister = true;
sti_register[STI_AMP_POS_INDEX].WriteRegister = true;
sti_register[STI_AMP_NEG_INDEX].WriteRegister = true;
// is neu wording now?
if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// nothing to do
}
else{
flag_notify(EVT_NEU_SPI);
}
// if( rec_sti_command & STATUS_REC ){
// // nothing to do
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
}
break;
}
@@ -780,40 +850,42 @@ static void headstage_update_vis_instruction(uint8_t vis_oper) {
case VIS_STOP_REC:{
rec_sti_command &= ~ENABLE_REC;
ResetDBSRegister();
// ResetDBSRegister();
// is neu wording now?
if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// nothing to do
}
else{
flag_notify(EVT_NEU_SPI);
}
// if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// // nothing to do
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
case VIS_STOP_STI:{
sti_register_value[STI_ENABLE_INDEX] = 0;
rec_sti_command &= ~ENABLE_STI;
// is neu wording now?
if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// nothing to do
}
else{
flag_notify(EVT_NEU_SPI);
}
// if( (rec_sti_command & STATUS_STI) || (rec_sti_command & STATUS_REC) ){
// // nothing to do
// }
// else{
// flag_notify(EVT_NEU_SPI);
// }
break;
}
case VIS_INT: {
// headstage_spi_transaction_cancel(headstage_spi_handle);
sti_register_value[STI_ENABLE_INDEX] = 0;
rec_sti_command &= ~ENABLE_REC;
rec_sti_command &= ~ENABLE_STI;
SPICallBack = ONE_SHOT_SPI;
NEULIVE_STATE.state = NEU_IDLE;
STI = false;
Neu2Reset();
// SPICallBack = CONTI_SPI_WITH_FLUSH;
// NEULIVE_STATE.state = NEU_IDLE;
// STI = false;
// Neu2Reset();
// for(int i=0 ; i<12 ; i++){
// FlushNotify();
@@ -973,7 +1045,7 @@ static void headstage_neu_state_spi() {
/* recording */
case NEU_WRITE_REC_INS: {
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
nxt_ins = build_rec_ins(NEULIVE_STATE.config_type, &value); /**< set instruction one by one in order to set all the parameter.*/
NEULIVE_STATE.config_type = nxt_ins;
@@ -1027,7 +1099,7 @@ static void headstage_neu_state_spi() {
value = (0x01 << 23) | (0x33 << 16) | INSTRUCTION.adc_clock_ratio;
AppendSPITX(0, value);
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
NEULIVE_STATE.state = NEU_CHECK_SAMPLE_RATE;
headstage_spi_transaction(3);
break;
@@ -1041,7 +1113,7 @@ static void headstage_neu_state_spi() {
case NEU_PREPARE_READ:{
if(spi_state_counter < 6){
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
NEULIVE_STATE.state = NEU_PREPARE_READ;
spi_state_counter ++;
AppendSPITX(0, 0);
@@ -1072,7 +1144,7 @@ static void headstage_neu_state_spi() {
// go to send sti instruction
NEULIVE_STATE.state = NEU_WRITE_STI_INS;
NEULIVE_STATE.config_type = NEU_WARM_UP;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
INSTRUCTION.ins_opcode = T_ZE;
AppendSPITX(0, 0);
@@ -1082,7 +1154,7 @@ static void headstage_neu_state_spi() {
// disable stimulation
else if( !(rec_sti_command & ENABLE_STI) && (rec_sti_command & STATUS_STI) ){
NEULIVE_STATE.state = NEU_STI_INT;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
AppendSPITX(0, 0);
headstage_spi_transaction(SPI_BUFFER_SIZE);
@@ -1095,7 +1167,7 @@ static void headstage_neu_state_spi() {
if(rec_sti_command & STATUS_STI){
NEULIVE_STATE.state = NEU_STI;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
AppendSPITX(0, 0);
headstage_spi_transaction(SPI_BUFFER_SIZE);
@@ -1111,7 +1183,7 @@ static void headstage_neu_state_spi() {
spi_txbuf[i] = 0;
spi_rxbuf[i] = 0;
}
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
ReopenSPI();
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
@@ -1129,7 +1201,7 @@ static void headstage_neu_state_spi() {
/* stimulation */
case NEU_WRITE_STI_INS:{
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
nxt_ins = build_sti_ins(NEULIVE_STATE.config_type, &value); /**< set instruction one by one in order to set all the parameter.*/
NEULIVE_STATE.config_type = nxt_ins;
@@ -1181,7 +1253,7 @@ static void headstage_neu_state_spi() {
value = (0x01 << 23) | (0x2E << 16) | INSTRUCTION.sti_channel;
AppendSPITX(0, value);
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
NEULIVE_STATE.state = NEU_STI_LED;
headstage_spi_transaction(3);
break;
@@ -1192,7 +1264,7 @@ static void headstage_neu_state_spi() {
// value = (0x01 << 23) | (0x2E << 16) | INSTRUCTION.sti_channel;
// AppendSPITX(0, value);
//
// SPICallBack = ONE_SHOT_SPI;
// SPICallBack = CONTI_SPI_WITH_FLUSH;
// NEULIVE_STATE.state = NEU_CHECK_STI_CH;
// headstage_spi_transaction(3);
// break;
@@ -1209,7 +1281,7 @@ static void headstage_neu_state_spi() {
headstage_led_control();
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
AppendSPITX(0, 0);
headstage_spi_transaction(SPI_BUFFER_SIZE);
break;
@@ -1220,7 +1292,7 @@ static void headstage_neu_state_spi() {
// recv disable sti command
if(!(rec_sti_command & ENABLE_STI)){
NEULIVE_STATE.state = NEU_STI_INT;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
AppendSPITX(0, 0);
headstage_spi_transaction(SPI_BUFFER_SIZE);
@@ -1230,7 +1302,7 @@ static void headstage_neu_state_spi() {
else if(rec_sti_command & ENABLE_REC){
NEULIVE_STATE.state = NEU_WRITE_REC_INS;
NEULIVE_STATE.config_type = NEU_WARM_UP;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
INSTRUCTION.ins_opcode = BIAS_ONE;
AppendSPITX(0, 0);
@@ -1250,7 +1322,7 @@ static void headstage_neu_state_spi() {
// terminate stimulation
case NEU_STI_INT: {
NEULIVE_STATE.state = NEU_STI_INT_TWICE;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
value = (0x01 << 23) | (0x2E << 16) | 0;
AppendSPITX(0, value);
@@ -1260,7 +1332,7 @@ static void headstage_neu_state_spi() {
case NEU_STI_INT_TWICE: {
NEULIVE_STATE.state = NEU_CHECK_STI_INT;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
value = (0x01 << 23) | (0x2E << 16) | 0;
AppendSPITX(0, value);
@@ -1281,7 +1353,7 @@ static void headstage_neu_state_spi() {
case NEU_LED:{
NEULIVE_STATE.state = NEU_IDLE;
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
AppendSPITX(0, 0);
headstage_led_control();
@@ -1305,11 +1377,17 @@ static void headstage_neu_state_spi() {
}
}
static uint8_t close_sti_third = 0;
static uint8_t limit_mode_sti_counter = 0;
static void check_limit_sti_reg(DBSRegister *dbs_register, uint16_t value_to_fit, uint8_t *limit_sti_open);
static uint8_t check_register_value(DBSRegister *dbs_register, uint8_t reg_size, uint16_t *value_to_fit);
static uint8_t write_register(DBSRegister *dbs_register, uint8_t reg_size, uint16_t *value_to_write);
static void stimulation_handle();
static void idle_state_handle();
static void headstage_neu_spi(){
static uint8_t limit_sti_open = 0;
// check system register if we have written it before
if( check_register_value(sys_register, sizeof(sys_register)/sizeof(DBSRegister), sys_register_default_value) ){
@@ -1327,27 +1405,28 @@ static void headstage_neu_spi(){
return;
}
if(check_register_value(sti_register, sizeof(sti_register)/sizeof(DBSRegister), sti_register_value)){
return;
if(fast_set){
if(check_register_value(sti_register, sizeof(sti_register)/sizeof(DBSRegister), fast_settle_param)){
return;
}
if(write_register(sti_register, sizeof(sti_register)/sizeof(DBSRegister), fast_settle_param)){
return;
}
}
if(write_register(sti_register, sizeof(sti_register)/sizeof(DBSRegister), sti_register_value)){
return;
else{
if(check_register_value(sti_register, sizeof(sti_register)/sizeof(DBSRegister), sti_register_value)){
return;
}
if(write_register(sti_register, sizeof(sti_register)/sizeof(DBSRegister), sti_register_value)){
return;
}
}
// enable recording channel
if(rec_register[REC_CHANNEL_INDEX].WriteRegister){
rec_register[REC_CHANNEL_INDEX].WriteRegister = false;
rec_register[REC_CHANNEL_INDEX].CheckRegister = true;
rec_register[REC_CHANNEL_INDEX].write_reg(rec_register+REC_CHANNEL_INDEX, rec_register_value[REC_CHANNEL_INDEX]);
return;
}
// enable stimulation
// WriteRegister will only be enable at check_register_value()
if(sti_register[STI_ENABLE_INDEX].WriteRegister){
sti_register[STI_ENABLE_INDEX].WriteRegister = false;
sti_register[STI_ENABLE_INDEX].CheckRegister = true;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register+STI_ENABLE_INDEX, sti_register_value[STI_ENABLE_INDEX]);
rec_register[REC_CHANNEL_INDEX].write_reg(rec_register[REC_CHANNEL_INDEX].address, rec_register_value[REC_CHANNEL_INDEX]);
return;
}
@@ -1356,33 +1435,57 @@ static void headstage_neu_spi(){
(!(rec_sti_command & ENABLE_STI) && (rec_sti_command & STATUS_STI))){
if(rec_sti_command & ENABLE_STI){
if(sti_register_value[STI_ENABLE_INDEX]){
rec_sti_command |= STATUS_STI;
if(fast_set){
fast_set = 0;
rec_sti_command |= STATUS_STI;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register[STI_ENABLE_INDEX].address, fast_settle_param[STI_ENABLE_INDEX]);
headstage_led_control();
}
// change LED base on working status
headstage_led_control();
else if(sti_register_value[STI_ENABLE_INDEX]){
// continuous sti mode
if(sti_register_value[STI_MODE_INDEX] & 0x0004){
// we will change led if check register without error
sti_register[STI_ENABLE_INDEX].WriteRegister = false;
sti_register[STI_ENABLE_INDEX].CheckRegister = true;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register[STI_ENABLE_INDEX].address, sti_register_value[STI_ENABLE_INDEX]);
}
sti_register[STI_ENABLE_INDEX].WriteRegister = false;
sti_register[STI_ENABLE_INDEX].CheckRegister = true;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register+STI_ENABLE_INDEX, sti_register_value[STI_ENABLE_INDEX]);
// limit sti mode
else{
// we have to send dummy instruction
// then send real instruction to avoid cc2650 slave spi bug
if(limit_mode_sti_counter < 2){
// sti_register[STI_ENABLE_INDEX].read_reg(sti_register+STI_ENABLE_INDEX);
limit_mode_sti_counter ++;
AppendSPITX(0, 9);
SPICallBack = CONTI_SPI_WITH_FLUSH;
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
else{
rec_sti_command |= STATUS_STI;
limit_sti_open = 1;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register[STI_ENABLE_INDEX].address,
sti_register_value[STI_ENABLE_INDEX]);
limit_mode_sti_counter = 0;
headstage_led_control();
}
}
}
return;
}
else{
rec_sti_command &= ~STATUS_STI;
headstage_led_control();
// enable stimulation and check register
// disable stimulation and check register
sti_register[STI_ENABLE_INDEX].WriteRegister = false;
sti_register[STI_ENABLE_INDEX].CheckRegister = true;
sti_register_value[STI_ENABLE_INDEX] = 0;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register+STI_ENABLE_INDEX, sti_register_value[STI_ENABLE_INDEX]);
limit_sti_open = 0;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register[STI_ENABLE_INDEX].address, sti_register_value[STI_ENABLE_INDEX]);
return;
}
}
// start recording
if(!(rec_sti_command & STATUS_REC) && (rec_sti_command & ENABLE_REC)){
IsFirstData = true;
IsFirstData = true;
if(rec_sti_command & ENABLE_REC){
rec_sti_command |= STATUS_REC; // neu is recording now
@@ -1397,14 +1500,22 @@ static void headstage_neu_spi(){
return;
}
// terminate limit sti and change led
if(limit_sti_open){
check_limit_sti_reg(sti_register, 0, &limit_sti_open);
return;
}
if(rec_sti_command & STATUS_REC){
// terminate record
if(!(rec_sti_command & ENABLE_REC)){
// terminate record
rec_sti_command &= ~STATUS_REC;
headstage_led_control();
AppendSPITX(0, 0);
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
// continuous recording
else{
if(SPICallBack != READ_MOSI){
SPICallBack = READ_MOSI;
@@ -1421,6 +1532,9 @@ static void headstage_neu_spi(){
stimulation_handle();
return;
}
idle_state_handle();
return;
}
#define RESEND_SPI_READ_NUMBER 3
@@ -1440,15 +1554,74 @@ static uint8_t check_register_value(DBSRegister *dbs_register, uint8_t reg_size,
if(ins_recv != ins_to_fit){
SPI_close(headstage_spi_handle);
dbs_register[i].WriteRegister = true;
// dbs_register[i].WriteRegister = true;
if(rec_sti_command & ENABLE_STI){
sti_register[STI_AMP_POS_INDEX].WriteRegister = true;
sti_register[STI_AMP_NEG_INDEX].WriteRegister = true;
sti_register[STI_AMP_NEG_INDEX].WriteRegister = true;
sti_register[STI_POLARITY_INDEX].WriteRegister = true;
sti_register[STI_MODE_INDEX].WriteRegister = true;
sti_register[STI_CYCLE_CH01_INDEX].WriteRegister = true;
sti_register[STI_CYCLE_CH23_INDEX].WriteRegister = true;
sti_register[STI_CYCLE_CH45_INDEX].WriteRegister = true;
sti_register[STI_CYCLE_CH67_INDEX].WriteRegister = true;
for(int ch=0 ; ch<8 ; ch++){
sti_register[ch*4 + STI_DURATION0_INDEX].WriteRegister = true;
sti_register[ch*4 + STI_DURATION1_INDEX].WriteRegister = true;
sti_register[ch*4 + STI_DURATION2_INDEX].WriteRegister = true;
sti_register[ch*4 + STI_DURATION3_INDEX].WriteRegister = true;
}
}
if(rec_sti_command & ENABLE_REC){
rec_register[REC_CHANNEL_INDEX].WriteRegister = true;
rec_register[REC_GAIN_INDEX].WriteRegister = true;
rec_register[REC_ADC_CLOCK_INDEX].WriteRegister = true;
}
if(i == 0){
// STI_ENABLE_INDEX
if(dbs_register[i].address == 46){
rewrite_sti_en = true;
}
// REC_CHANNEL_INDEX
else if(dbs_register[i].address == 48){
rewrite_rec_en = true;
}
}
ReopenSPI();
dbs_register[i].write_reg(dbs_register+i, value_to_fit[i]);
}
else{
AppendSPITX(0, 0);
SPICallBack = ONE_SHOT_SPI;
headstage_spi_transaction(SPI_BUFFER_SIZE);
if(i == 0){
// STI_ENABLE_INDEX
if(dbs_register[i].address == 46){
// sti register config correctly
if(sti_register_value[STI_ENABLE_INDEX]){
rec_sti_command |= STATUS_STI;
}
else{
// the check of "sti turn off" may has bug
// we should check the reg twice if the bug still exist
if(close_sti_third < 3){
sti_register[STI_ENABLE_INDEX].WriteRegister = true;
rewrite_sti_en = true;
close_sti_third ++;
}
else{
close_sti_third = 0;
rec_sti_command &= ~STATUS_STI;
}
}
// change LED base on working status
headstage_led_control();
}
}
}
AppendSPITX(0, 0);
SPICallBack = CONTI_SPI_WITH_FLUSH;
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
return 1;
}
@@ -1456,6 +1629,15 @@ static uint8_t check_register_value(DBSRegister *dbs_register, uint8_t reg_size,
return 0;
}
/*
* write_register - update register value.
*
* dbs_register - register to be update
* reg_size - register size
* value_to_write - register to be update
*
* return 1 if there is register been writed
*/
static uint8_t write_register(DBSRegister *dbs_register, uint8_t reg_size, uint16_t *value_to_write){
// start from index 1, since 0 is rec/sti enable
@@ -1463,21 +1645,80 @@ static uint8_t write_register(DBSRegister *dbs_register, uint8_t reg_size, uint1
if(dbs_register[i].WriteRegister){
dbs_register[i].WriteRegister = false;
dbs_register[i].CheckRegister = true;
dbs_register[i].write_reg(dbs_register+i, value_to_write[i]);
dbs_register[i].write_reg(dbs_register[i].address, value_to_write[i]);
return 1;
}
}
if(rewrite_sti_en || rewrite_rec_en){
if(dbs_register[0].address == 46){
rewrite_sti_en = false;
}
else if(dbs_register[0].address == 48){
rewrite_rec_en = false;
}
if(dbs_register[0].WriteRegister){
dbs_register[0].WriteRegister = false;
dbs_register[0].CheckRegister = true;
dbs_register[0].write_reg(dbs_register[0].address, value_to_write[0]);
return 1;
}
}
return 0;
}
/*
* return 0: limit sti end
* 1: still need to check
*/
static void check_limit_sti_reg(DBSRegister *dbs_register, uint16_t value_to_fit, uint8_t *limit_sti_open){
if(check_reg_counter < RESEND_SPI_READ_NUMBER){
*limit_sti_open = 1;
dbs_register[STI_ENABLE_INDEX].read_reg(dbs_register+STI_ENABLE_INDEX);
}
else{
// check register value
check_reg_counter = 0;
uint16_t ins_to_fit = value_to_fit;
uint16_t ins_recv = spi_rxbuf[1] << 8 | spi_rxbuf[2];
if(ins_recv != ins_to_fit){
SPI_close(headstage_spi_handle);
*limit_sti_open = 1;
ReopenSPI();
SPICallBack = CONTI_SPI_WITH_FLUSH;
}
else{
*limit_sti_open = 0;
sti_register_value[STI_ENABLE_INDEX] = 0;
rec_sti_command &= ~ENABLE_STI;
// rec_sti_command &= ~STATUS_STI;
// rec_sti_command &= ~ENABLE_STI;
// headstage_led_control();
// if(rec_sti_command & STATUS_REC){
// SPICallBack = READ_MOSI;
// }
// else{
// SPICallBack = CONTI_SPI_WITH_FLUSH;
// }
}
AppendSPITX(0, 0);
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
}
static void recording_handle(){
// terminate record
if(!(rec_sti_command & ENABLE_REC)){
// terminate record
rec_sti_command &= ~STATUS_REC;
headstage_led_control();
if(rec_sti_command & STATUS_STI){
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
AppendSPITX(0, 0);
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
@@ -1490,7 +1731,7 @@ static void recording_handle(){
spi_txbuf[i] = 0;
spi_rxbuf[i] = 0;
}
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
ReopenSPI();
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
@@ -1505,19 +1746,26 @@ static void recording_handle(){
static void stimulation_handle(){
if(!(rec_sti_command & ENABLE_STI)){
rec_sti_command &= ~STATUS_STI;
headstage_led_control();
// rec_sti_command &= ~STATUS_STI;
// headstage_led_control();
sti_register[STI_ENABLE_INDEX].WriteRegister = false;
sti_register[STI_ENABLE_INDEX].CheckRegister = true;
sti_register_value[STI_ENABLE_INDEX] = 0;
sti_register[STI_ENABLE_INDEX].write_reg(sti_register+STI_ENABLE_INDEX, sti_register_value[STI_ENABLE_INDEX]);
sti_register[STI_ENABLE_INDEX].write_reg(sti_register[STI_ENABLE_INDEX].address, sti_register_value[STI_ENABLE_INDEX]);
}
// nothing to do
else{
AppendSPITX(0, 0);
SPICallBack = CONTI_SPI_WITH_FLUSH;
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
}
static void idle_state_handle(){
AppendSPITX(0, 0);
SPICallBack = CONTI_SPI_WITH_FLUSH;
headstage_spi_transaction(SPI_BUFFER_SIZE);
}
#endif
@@ -6,7 +6,7 @@
static uint16_t UserCode2StiCode(uint16_t amp, uint8_t positive_ch){
// get real current value (uA)
uint32_t sti_code, real_amp = amp * 5;
int32_t sti_code, real_amp = amp * 5;
if(StiCaliTable.p_ch.coefficient == 10000 && StiCaliTable.p_ch.offset == 0){
return amp;
@@ -15,15 +15,29 @@ static uint16_t UserCode2StiCode(uint16_t amp, uint8_t positive_ch){
return amp;
}
// trans into sti code
if(positive_ch){
sti_code = StiCaliTable.p_ch.coefficient * real_amp + StiCaliTable.p_ch.offset;
if(real_amp < 200){
sti_code = 2023 * real_amp -4170;
}
else if(real_amp <500){
sti_code = 2077 * real_amp - 11729;
}
else{
sti_code = StiCaliTable.n_ch.coefficient * real_amp + StiCaliTable.n_ch.offset;
sti_code = 2096 * real_amp - 45970;
}
sti_code = sti_code / 10000;
// trans into sti code
// if(positive_ch){
// sti_code = StiCaliTable.p_ch.coefficient * real_amp + StiCaliTable.p_ch.offset;
// }
// else{
// sti_code = StiCaliTable.n_ch.coefficient * real_amp + StiCaliTable.n_ch.offset;
// }
if(sti_code <= 10000){
sti_code = 10000;
}
sti_code = (sti_code+5000) / 10000;
return (uint16_t) (sti_code);
}
@@ -2,16 +2,16 @@
#ifndef VERSION_DATE
#define VERSION_DATE
#define VERSION_DATE_YEAR 20
#define VERSION_DATE_MONTH 10
#define VERSION_DATE_DAY 26
#define VERSION_DATE_YEAR 21
#define VERSION_DATE_MONTH 1
#define VERSION_DATE_DAY 21
#define VERSION_DATE_HOUR 17
#define VERSION_DATE_MINUTE 3
#define VERSION_DATE_MINUTE 39
// this is NOT the version hash !!
// it's the last version hash
#define VERSION_HASH 764bd9364d7a99761ada31d35af557a39e1d65a4
#define VERSION_GIT_BRANCH neulive20_development_onchange_central
#define VERSION_HASH dd9f64662e1a9a993a1c28c18256d230f429f8ac
#define VERSION_GIT_BRANCH neulive2_E7DA_special_version
static void get_board_name(char *board_name_ch, uint8 *board_name_int, uint8 name_size){
uint8 name_offset = 18;
@@ -4,6 +4,7 @@
#include "headstage_instruction.h"
#include "neu/headstage_spi.h"
#include "headstage_dbs_object.h"
static void ResetINSTRUCTION();
@@ -25,7 +26,7 @@ static void MCUReset(){
spi_txbuf[i] = 0;
spi_rxbuf[i] = 0;
}
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
ReopenSPI();
for(int i=0 ; i<SPI_LED_BUFF_SIZE ; i++){
@@ -70,6 +71,7 @@ static void DBSReset(){
static void Neu2Reset(){
DBSReset();
MCUReset();
InitDBSRegister();
}
static void ResetINSTRUCTION(){
@@ -143,7 +143,7 @@ static void headstage_spi_callback(SPI_Handle handle, SPI_Transaction* transacti
break;
}
case FLUSH_BUFFER2:{
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
spi_txbuf[i] = 0x00;
}
@@ -151,7 +151,7 @@ static void headstage_spi_callback(SPI_Handle handle, SPI_Transaction* transacti
// headstage_spi_transaction(SPI_BUFFER_SIZE);
break;
}
case ONE_SHOT_SPI:{
case CONTI_SPI_WITH_FLUSH:{
SPICallBack = FLUSH_BUFFER;
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
spi_txbuf[i] = 0x00;
@@ -172,14 +172,13 @@ static void headstage_spi_callback(SPI_Handle handle, SPI_Transaction* transacti
}
case CLOSE_SPI:{
SPICallBack = ONE_SHOT_SPI;
SPICallBack = CONTI_SPI_WITH_FLUSH;
SPI_close(headstage_spi_handle);
break;
}
case END_TRANSMIT:{
case ONE_SHOT_FLUSH:{
tx_put_u24(0, 0);
SPICallBack = CONTINUOUS_TRANS;
break;
}
default:{