Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 226f38bbba | |||
| f4861bb6cb | |||
| c29273f7e6 | |||
| f3391fe63b | |||
| 332e8a127f | |||
| ab83ab2ce0 | |||
| 498a3aceb6 | |||
| 41c6cb2964 | |||
| 33c3db2601 | |||
| 60c885a625 |
+1
-1
@@ -4,7 +4,7 @@
|
||||
#folder=$($path | awk -F"/" '{$NF}')
|
||||
folder=$(basename "$(pwd)")
|
||||
|
||||
if [ "$folder" == "ti" ] ; then
|
||||
if [ "$folder" == "ti" ]; then
|
||||
year=$(date +%-y)
|
||||
month=$(date +%-m)
|
||||
day=$(date +%-d)
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
-138
@@ -1,138 +0,0 @@
|
||||
|
||||
#ifndef DBS_OBJECT_H
|
||||
#define DBS_OBJECT_H
|
||||
|
||||
#include "neu/headstage_spi.h"
|
||||
|
||||
#define SYS_RESERVED_INDEX 0
|
||||
#define SYS_GENERAL_ENABLE_INDEX 1
|
||||
#define SYS_LNA_BIOS1_INDEX 2
|
||||
#define SYS_LNA_BIOS2_INDEX 3
|
||||
|
||||
#define REC_CHANNEL_INDEX 0
|
||||
#define REC_GAIN_INDEX 1
|
||||
#define REC_ADC_CLOCK_INDEX 2
|
||||
|
||||
#define STI_ENABLE_INDEX 0
|
||||
#define STI_DURATION0_INDEX 1
|
||||
#define STI_DURATION1_INDEX 2
|
||||
#define STI_DURATION2_INDEX 3
|
||||
#define STI_DURATION3_INDEX 4
|
||||
#define STI_AMP_POS_INDEX 5
|
||||
#define STI_AMP_NEG_INDEX 6
|
||||
#define STI_POLARITY_INDEX 7
|
||||
#define STI_CYCLE_CH01_INDEX 8
|
||||
#define STI_CYCLE_CH23_INDEX 9
|
||||
#define STI_CYCLE_CH45_INDEX 10
|
||||
#define STI_CYCLE_CH67_INDEX 11
|
||||
#define STI_CLK_RATIO_INDEX 12
|
||||
#define STI_ARBITRARY_EN_INDEX 13
|
||||
#define STI_MODE_INDEX 14
|
||||
|
||||
//#define DBS_REGISTER \
|
||||
// uint8_t address; \
|
||||
// void (*write_reg) (DBSRegister *self, uint32_t reg_value); \
|
||||
// uint32_t (*read_reg) (DBSRegister *self)
|
||||
|
||||
typedef struct _DBSRegister{
|
||||
uint8_t address;
|
||||
bool WriteRegister, CheckRegister;
|
||||
void (*write_reg) (struct _DBSRegister *self, 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;
|
||||
spi_txbuf[1] = (reg_value >> 8) & 0xFF ;
|
||||
spi_txbuf[2] = reg_value & 0xFF;
|
||||
SPICallBack = ONE_SHOT_SPI;
|
||||
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
|
||||
SPICallBack = READ_REG;
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
|
||||
static uint16_t sys_register_default_value[4] = {
|
||||
0x0000,
|
||||
0x40F2,
|
||||
0x0210,
|
||||
0x4210
|
||||
};
|
||||
static uint16_t rec_register_value[3];
|
||||
static uint16_t sti_register_value[15];
|
||||
|
||||
static DBSRegister sys_register[4];
|
||||
static DBSRegister rec_register[3];
|
||||
static DBSRegister sti_register[15];
|
||||
|
||||
static void InitSysRegister(){
|
||||
sys_register[SYS_RESERVED_INDEX].address = 0x00;
|
||||
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;
|
||||
|
||||
for(int i=0 ; i<sizeof(sys_register)/sizeof(DBSRegister) ; i++){
|
||||
sys_register[i].WriteRegister = false;
|
||||
sys_register[i].CheckRegister = false;
|
||||
sys_register[i].write_reg = &write_reg;
|
||||
sys_register[i].read_reg = &read_reg;
|
||||
}
|
||||
}
|
||||
|
||||
static void InitRecRegister(){
|
||||
rec_register[REC_CHANNEL_INDEX].address = 48;
|
||||
rec_register[REC_GAIN_INDEX].address = 49;
|
||||
rec_register[REC_ADC_CLOCK_INDEX].address = 51; // sampling rate
|
||||
|
||||
for(int i=0 ; i<sizeof(rec_register)/sizeof(DBSRegister) ; i++){
|
||||
rec_register[i].WriteRegister = false;
|
||||
rec_register[i].CheckRegister = false;
|
||||
rec_register[i].write_reg = &write_reg;
|
||||
rec_register[i].read_reg = &read_reg;
|
||||
}
|
||||
}
|
||||
|
||||
static void InitStiRegister(){
|
||||
sti_register[STI_ENABLE_INDEX].address = 46;
|
||||
sti_register[STI_DURATION0_INDEX].address = 1;
|
||||
sti_register[STI_DURATION1_INDEX].address = 2;
|
||||
sti_register[STI_DURATION2_INDEX].address = 3;
|
||||
sti_register[STI_DURATION3_INDEX].address = 4;
|
||||
sti_register[STI_AMP_POS_INDEX].address = 37;
|
||||
sti_register[STI_AMP_NEG_INDEX].address = 38;
|
||||
sti_register[STI_POLARITY_INDEX].address = 40;
|
||||
sti_register[STI_CYCLE_CH01_INDEX].address = 42;
|
||||
sti_register[STI_CYCLE_CH23_INDEX].address = 43;
|
||||
sti_register[STI_CYCLE_CH45_INDEX].address = 44;
|
||||
sti_register[STI_CYCLE_CH67_INDEX].address = 45;
|
||||
sti_register[STI_CLK_RATIO_INDEX].address = 52;
|
||||
sti_register[STI_ARBITRARY_EN_INDEX].address = 54;
|
||||
sti_register[STI_MODE_INDEX].address = 56;
|
||||
|
||||
for(int i=0 ; i<sizeof(sti_register)/sizeof(DBSRegister) ; i++){
|
||||
sti_register[i].WriteRegister = false;
|
||||
sti_register[i].CheckRegister = false;
|
||||
sti_register[i].write_reg = &write_reg;
|
||||
sti_register[i].read_reg = &read_reg;
|
||||
}
|
||||
}
|
||||
|
||||
static void InitDBSRegister(){
|
||||
InitSysRegister();
|
||||
InitRecRegister();
|
||||
InitStiRegister();
|
||||
|
||||
// for(int i=1 ; i<sizeof(sys_register)/sizeof(DBSRegister) ; i++){
|
||||
for(int i=1 ; i<4 ; i++){
|
||||
sys_register[i].WriteRegister = true;
|
||||
}
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
}
|
||||
|
||||
#endif
|
||||
+215
-183
@@ -160,20 +160,16 @@ static void FlushNotify();
|
||||
#define NEU_REC_PARAM 0x20
|
||||
#define NEU_MULTI_STI 0x40
|
||||
#define NEU_TEST_INS 0x60
|
||||
#define RIS_REC_ON_CHANGE 0x80
|
||||
#define RIS_STI_ON_CHANGE 0xA0
|
||||
#define RIS_STOP_STI 0x80
|
||||
|
||||
/** event */
|
||||
#define EVT_NEU_SPI 0x0001 /**< spi transaction event */
|
||||
#define EVT_NEU_LED 0x0002 /**< set led event */
|
||||
#define EVT_NEU_CHECK 0x0004 /**< check neulive single instruction */
|
||||
#define EVT_NEU_REG_SPI 0x0008 /** register spi event */
|
||||
#define EVT_NEU_PREPARE 0x0010 /** prepare to record or stimulate **/
|
||||
#define EVT_NEU_REC 0x0020
|
||||
#define EVT_NEU_STI 0x0040
|
||||
|
||||
/** clock setting */
|
||||
#define NEU_SYS_CLK 2000000 /**< 10Mhz */
|
||||
#define NEU_SYS_CLK 4000000 /**< 10Mhz */
|
||||
#define NEU_POLY_R_CLK 1000 /**< 1khz */
|
||||
#define NEU_SPI_FREQ NEU_SYS_CLK/10 /**< 1Mhz */ // should be NEU_SYS_CLK/10
|
||||
//#define NEU_LED_FREQ 1000000 /**< 1Mhz */
|
||||
@@ -302,7 +298,13 @@ typedef enum{
|
||||
#include "string.h"
|
||||
#include "headstage_rec_ins.h"
|
||||
#include "headstage_sti_ins.h"
|
||||
#include "headstage_dbs_object.h"
|
||||
|
||||
/* Debug function and parameter
|
||||
*
|
||||
*/
|
||||
static uint8_t data_rate_counter = 0;
|
||||
static uint32_t msg_counter = 0;
|
||||
static void SimpleBLEPeripheral_blastData();
|
||||
|
||||
/*
|
||||
* todo: need to define some procedure to detect this device status
|
||||
@@ -342,8 +344,53 @@ static void headstage_init() {
|
||||
#undef THREE_POINT_THREE_VOLT
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn headstage_neu_append_notify_data
|
||||
*/
|
||||
#define CHANNEL_VALID (INSTRUCTION.recording_channel & (0x0001 << channel))
|
||||
static void headstage_neu_append_notify_data() {
|
||||
|
||||
uint8_t channel = spi_rxbuf[0];
|
||||
|
||||
// close-reopen SPI, if the first channel received is invalid
|
||||
if(IsFirstData){
|
||||
// start record
|
||||
if((INSTRUCTION.recording_channel & (0x0001 << channel)) && (channel < 16)){
|
||||
IsFirstData = false;
|
||||
}
|
||||
// restart SPI
|
||||
else{
|
||||
SPI_close(headstage_spi_handle);
|
||||
ReopenSPI();
|
||||
IsFirstData = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// discard illegal channel
|
||||
// uint16_t valid_channel = INSTRUCTION.recording_channel & (0x0001 << channel);
|
||||
if(!(INSTRUCTION.recording_channel & (0x0001 << channel)) || (channel > 15)){
|
||||
// illegal channel
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t not_buf[3];
|
||||
not_buf[0] = channel; // ch
|
||||
not_buf[1] = spi_rxbuf[1];
|
||||
not_buf[2] = spi_rxbuf[2];
|
||||
|
||||
// not_buf[1] = (INSTRUCTION.recording_channel | 0xFF00) >> 8;
|
||||
// not_buf[2] = (INSTRUCTION.recording_channel | 0x00FF);
|
||||
|
||||
uint8_t data_size = headstage_notify_append_data(not_buf);
|
||||
|
||||
if (data_size >= BLE_NOT_BUFF_SIZE) {
|
||||
headstage_notify_flip_buffer();
|
||||
headstage_notify_send();
|
||||
}
|
||||
}
|
||||
|
||||
static void headstage_neu_state_spi();
|
||||
static void headstage_neu_spi();
|
||||
|
||||
/**
|
||||
* @fn headstage_neu_event
|
||||
@@ -352,27 +399,93 @@ static void headstage_neu_spi();
|
||||
*/
|
||||
|
||||
static void headstage_neu_event() {
|
||||
if (EVENT_MASK == 0) {
|
||||
// fast return
|
||||
return;
|
||||
}
|
||||
|
||||
if (flag_mask(EVT_NEU_SPI)) {
|
||||
flag_disable(EVT_NEU_SPI);
|
||||
// headstage_neu_state_spi();
|
||||
headstage_neu_spi();
|
||||
headstage_neu_state_spi();
|
||||
}
|
||||
|
||||
if (flag_mask(EVT_NEU_LED)) {
|
||||
flag_disable(EVT_NEU_LED); /** reserved to set led power and set color manually */
|
||||
}
|
||||
|
||||
if (EVENT_MASK == 0) {
|
||||
// fast return
|
||||
}
|
||||
|
||||
if (flag_mask(EVT_DISCONNECTED)) {
|
||||
ConnectState = false;
|
||||
headstage_update_vis_instruction(VIS_INT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn headstage_spi_callback
|
||||
*
|
||||
* description: callback function to deal with data transmission between DBS and CC2650
|
||||
*/
|
||||
|
||||
static void headstage_spi_callback(SPI_Handle handle, SPI_Transaction* transaction) {
|
||||
switch(SPICallBack){
|
||||
case CONTINUOUS_TRANS:{
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
break;
|
||||
}
|
||||
case FLUSH_BUFFER:{
|
||||
SPICallBack = FLUSH_BUFFER2;
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
break;
|
||||
}
|
||||
case FLUSH_BUFFER2:{
|
||||
SPICallBack = ONE_SHOT_SPI;
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
// headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
break;
|
||||
}
|
||||
case ONE_SHOT_SPI:{
|
||||
SPICallBack = FLUSH_BUFFER;
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
case READ_MOSI:{
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
break;
|
||||
}
|
||||
|
||||
case READ_REG:{
|
||||
check_reg_counter ++;
|
||||
break;
|
||||
}
|
||||
|
||||
case CLOSE_SPI:{
|
||||
SPICallBack = ONE_SHOT_SPI;
|
||||
SPI_close(headstage_spi_handle);
|
||||
break;
|
||||
}
|
||||
|
||||
case END_TRANSMIT:{
|
||||
tx_put_u24(0, 0);
|
||||
SPICallBack = CONTINUOUS_TRANS;
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn headstage_update_ris_instruction
|
||||
*
|
||||
@@ -430,6 +543,7 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
|
||||
}
|
||||
|
||||
case NEU_REC_PARAM: {
|
||||
headstage_led_color(COLOR_MAGENTA);
|
||||
uint8_t vgrp = instruction[0] & 0x1F;
|
||||
uint8_t vgrn = (instruction[1] & 0xF8) >> 3;
|
||||
uint8_t vgr_int_old = ((instruction[1] & 0x07) << 2) | ((instruction[2] & 0xC0) >> 6);
|
||||
@@ -460,8 +574,8 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
|
||||
INSTRUCTION.vgr_intp = 16;
|
||||
INSTRUCTION.vgr_intn = 16;
|
||||
INSTRUCTION.vgr_int_old = 16;
|
||||
INSTRUCTION.recording_channel = 0b0000000001000010;
|
||||
INSTRUCTION.adc_clock_ratio = 50;
|
||||
INSTRUCTION.recording_channel = 0b0000000000000010;
|
||||
INSTRUCTION.adc_clock_ratio = 100; // sample rate = [NEU_SYS_CLK / (sys_clk_ratio = 10)] / adc_clock_ratio
|
||||
INSTRUCTION.sys_clk_ratio = 10;
|
||||
INSTRUCTION.sti_clock_ratio = 10;
|
||||
INSTRUCTION.amplifier_gain = 0;
|
||||
@@ -483,7 +597,7 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
|
||||
INSTRUCTION.current_sti_cycle[0] = 100;
|
||||
INSTRUCTION.current_sti_cycle[1] = 100;
|
||||
INSTRUCTION.current_sti_cycle[8] = 10; // ch8 is volt ch
|
||||
INSTRUCTION.sti_channel = 0b0000000000000011; // 0bxxxx_xxxv_cccc_cccc, c = current; v = volt, x = don't care
|
||||
INSTRUCTION.sti_channel = 0b0000000000000000; // 0bxxxx_xxxv_cccc_cccc, c = current; v = volt, x = don't care
|
||||
INSTRUCTION.arbitrary_en = 0;
|
||||
INSTRUCTION.arbitrary_index = 0;
|
||||
INSTRUCTION.sti_mode = 0; // 1 = continuous mode; 0 = limit mode
|
||||
@@ -507,37 +621,6 @@ static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t* instructi
|
||||
break;
|
||||
}
|
||||
|
||||
case RIS_REC_ON_CHANGE:{
|
||||
uint16_t reg_value = instruction[2] << 8 | instruction[3];
|
||||
switch(instruction[1]){
|
||||
case REC_CHANNEL_INDEX:{
|
||||
rec_register[REC_CHANNEL_INDEX].WriteRegister = true;
|
||||
rec_register_value[REC_CHANNEL_INDEX] = reg_value;
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
break;
|
||||
}
|
||||
|
||||
case REC_GAIN_INDEX:{
|
||||
rec_register[REC_GAIN_INDEX].WriteRegister = true;
|
||||
rec_register_value[REC_GAIN_INDEX] = reg_value;
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
break;
|
||||
}
|
||||
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@@ -805,7 +888,6 @@ static void headstage_update_cis_instruction(uint8_t cis_oper) {
|
||||
cdr_buf[6] = 0xCD;
|
||||
}
|
||||
|
||||
|
||||
SimpleProfile_SetParameter(BLE_CDR_BUFF_CHAR, BLE_CDR_SAMLL_SIZE, cdr_buf);
|
||||
break;
|
||||
}
|
||||
@@ -959,7 +1041,7 @@ static void headstage_neu_state_spi() {
|
||||
}
|
||||
case NEU_READ_DATA: {
|
||||
|
||||
// sti enable command
|
||||
// recv sti enable command
|
||||
if( (rec_sti_command & ENABLE_STI) && !(rec_sti_command & STATUS_STI) ){
|
||||
// go to send sti instruction
|
||||
NEULIVE_STATE.state = NEU_WRITE_STI_INS;
|
||||
@@ -971,7 +1053,7 @@ static void headstage_neu_state_spi() {
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
// disable stimulation
|
||||
// recv disable stimulation
|
||||
else if( !(rec_sti_command & ENABLE_STI) && (rec_sti_command & STATUS_STI) ){
|
||||
NEULIVE_STATE.state = NEU_STI_INT;
|
||||
SPICallBack = ONE_SHOT_SPI;
|
||||
@@ -983,6 +1065,7 @@ static void headstage_neu_state_spi() {
|
||||
// recv disable recording
|
||||
else if( !(rec_sti_command & ENABLE_REC) ){
|
||||
rec_sti_command &= ~STATUS_REC;
|
||||
headstage_led_color(COLOR_WHITE);
|
||||
headstage_led_control();
|
||||
|
||||
if(rec_sti_command & STATUS_STI){
|
||||
@@ -1011,6 +1094,16 @@ static void headstage_neu_state_spi() {
|
||||
|
||||
// recording
|
||||
else{
|
||||
// for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
// spi_txbuf[i] = 0;
|
||||
// }
|
||||
//
|
||||
// if(data_rate_counter >= 63){
|
||||
// data_rate_counter = 0;
|
||||
// SimpleBLEPeripheral_blastData();
|
||||
// }
|
||||
// data_rate_counter ++;
|
||||
// headstage_spi_transaction(3);
|
||||
headstage_neu_append_notify_data();
|
||||
AppendSPITX(0, 0);
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
@@ -1197,142 +1290,81 @@ static void headstage_neu_state_spi() {
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
typedef enum{
|
||||
dbs_idle = 0x00,
|
||||
dbs_prepare = 0x01,
|
||||
dbs_recording = 0x02,
|
||||
dbs_stimulate = 0x04
|
||||
}dbs_status;
|
||||
/*********************************************************************
|
||||
* @fn SimpleBLEPeripheral_blastData
|
||||
*
|
||||
* @brief Sends ATT notifications in a tight while loop to demo
|
||||
* throughput
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
static void SimpleBLEPeripheral_blastData() {
|
||||
|
||||
static void headstage_neu_spi(){
|
||||
static dbs_status status;
|
||||
|
||||
// check system register if we have written it before
|
||||
if( check_register_value(sys_register, sizeof(sys_register)/sizeof(DBSRegister), sys_register_default_value) ){
|
||||
return;
|
||||
}
|
||||
// write system register
|
||||
if (write_register(sys_register, sizeof(sys_register)/sizeof(DBSRegister), sys_register_default_value)){
|
||||
return;
|
||||
}
|
||||
|
||||
if(check_register_value(rec_register, sizeof(rec_register)/sizeof(DBSRegister), rec_register_value)){
|
||||
return;
|
||||
}
|
||||
if(write_register(rec_register, sizeof(rec_register)/sizeof(DBSRegister), rec_register_value)){
|
||||
return;
|
||||
}
|
||||
|
||||
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){
|
||||
status |= dbs_prepare;
|
||||
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;
|
||||
}
|
||||
|
||||
if(status & dbs_prepare){
|
||||
status &= ~dbs_prepare;
|
||||
|
||||
if(rec_sti_command & ENABLE_REC){
|
||||
status |= dbs_recording;
|
||||
rec_sti_command |= STATUS_REC; // neu is recording now
|
||||
}
|
||||
|
||||
// change LED base on working status
|
||||
headstage_led_control();
|
||||
|
||||
AppendSPITX(0, 0);
|
||||
SPICallBack = ONE_SHOT_SPI;
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
if(rec_sti_command & STATUS_REC){
|
||||
if(!(rec_sti_command & ENABLE_REC)){
|
||||
// terminate record
|
||||
}
|
||||
else{
|
||||
headstage_neu_append_notify_data();
|
||||
AppendSPITX(0, 0);
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
uint32_t not_time_stamp = headstage_time_stamp_us();
|
||||
headstage_notify_buffer[0] = (msg_counter >> 24) & 0xFF;
|
||||
headstage_notify_buffer[1] = (msg_counter >> 16) & 0xFF;
|
||||
headstage_notify_buffer[2] = (msg_counter >> 8) & 0xFF;
|
||||
headstage_notify_buffer[3] = msg_counter & 0xFF;
|
||||
headstage_notify_buffer[4] = 0xFB;
|
||||
headstage_notify_buffer[5] = not_time_stamp & 0xFF;
|
||||
headstage_notify_buffer[6] = (not_time_stamp >> 8) & 0xFF;
|
||||
headstage_notify_buffer[7] = (not_time_stamp >> 16) & 0xFF;
|
||||
headstage_notify_buffer[8] = (not_time_stamp >> 24) & 0xFF;
|
||||
msg_counter++;
|
||||
SimpleProfile_SetParameter(BLE_NOT_BUFF_CHAR, BLE_NOT_BUFF_SIZE, headstage_notify_buffer);
|
||||
|
||||
// Subtract the total packet overhead of ATT and L2CAP layer from notification payload
|
||||
// uint16_t len = MAX_PDU_SIZE - TOTAL_PACKET_OVERHEAD;
|
||||
// attHandleValueNoti_t noti;
|
||||
// bStatus_t status;
|
||||
// noti.handle = 0x27;
|
||||
// noti.len = len;
|
||||
//
|
||||
// // it's recording
|
||||
// if(rec_sti_command & STATUS_REC){
|
||||
// if(!(rec_sti_command & ENABLE_REC)){
|
||||
// // stop recording
|
||||
// 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, value_to_write[REC_CHANNEL_INDEX]);
|
||||
// }
|
||||
// else{
|
||||
// // keep recording
|
||||
// headstage_neu_append_notify_data();
|
||||
// AppendSPITX(0, 0);
|
||||
// headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
// uint32_t not_time_stamp;
|
||||
//
|
||||
// // Store hte connection handle for future reference
|
||||
// uint16_t connectionHandle;
|
||||
// GAPRole_GetParameter(GAPROLE_CONNHANDLE, &connectionHandle);
|
||||
//
|
||||
// not_time_stamp = Timestamp_get32() / 2;
|
||||
// noti.pValue = (uint8 *)GATT_bm_alloc(connectionHandle, ATT_HANDLE_VALUE_NOTI, GATT_MAX_MTU, &len);
|
||||
//
|
||||
// if (noti.pValue != NULL) // if allocated
|
||||
// {
|
||||
// // Place index
|
||||
// noti.pValue[2] = not_time_stamp & 0xFF;
|
||||
// noti.pValue[3] = (not_time_stamp >> 8) & 0xFF;
|
||||
// noti.pValue[4] = (not_time_stamp >> 16) & 0xFF;
|
||||
// noti.pValue[5] = (not_time_stamp >> 24) & 0xFF;
|
||||
// noti.pValue[6] = 100;
|
||||
// noti.pValue[7] = 0;
|
||||
//
|
||||
// // Attempt to send the notification
|
||||
// status = GATT_Notification(connectionHandle, ¬i, GATT_NO_AUTHENTICATION);
|
||||
// if (status != SUCCESS) // if noti not sent
|
||||
// {
|
||||
//// PIN_setOutputValue(hSbpPins, Board_LED1, Board_LED_ON);
|
||||
// headstage_led_color(COLOR_RED);
|
||||
// headstage_led_color(COLOR_BLACK);
|
||||
// GATT_bm_free((gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI);
|
||||
// } else {
|
||||
// // Notification is successfully sent, increment counters
|
||||
//// Display_print0(dispHandle, 4, 0, "success");
|
||||
//// PIN_setOutputValue(hSbpPins, Board_LED2, Board_LED_ON);
|
||||
// headstage_led_color(COLOR_BLUE);
|
||||
// headstage_led_color(COLOR_BLACK);
|
||||
// msg_counter++;
|
||||
// }
|
||||
// } else {
|
||||
// // bleNoResources was returned
|
||||
// asm(" NOP ");
|
||||
// }
|
||||
|
||||
// Reset debug pins
|
||||
// PIN_setOutputValue(hSbpPins, Board_LED1, Board_LED_OFF);
|
||||
// PIN_setOutputValue(hSbpPins, Board_LED2, Board_LED_OFF);
|
||||
}
|
||||
|
||||
#define RESEND_SPI_READ_NUMBER 3
|
||||
static uint8_t check_register_value(DBSRegister *dbs_register, uint8_t reg_size, uint16_t *value_to_fit){
|
||||
for(int i=0 ; i<reg_size ; i++){
|
||||
if(dbs_register[i].CheckRegister){
|
||||
if(check_reg_counter < RESEND_SPI_READ_NUMBER){
|
||||
dbs_register[i].read_reg(dbs_register+i);
|
||||
}
|
||||
else{
|
||||
// check register value
|
||||
check_reg_counter = 0;
|
||||
dbs_register[i].CheckRegister = false;
|
||||
|
||||
uint16_t ins_to_fit = value_to_fit[i];
|
||||
uint16_t ins_recv = spi_rxbuf[1] << 8 | spi_rxbuf[2];
|
||||
|
||||
if(ins_recv != ins_to_fit){
|
||||
SPI_close(headstage_spi_handle);
|
||||
dbs_register[i].WriteRegister = 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);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
for(int i=1 ; i<reg_size ; i++){
|
||||
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]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+6
-6
@@ -3,15 +3,15 @@
|
||||
#define VERSION_DATE
|
||||
|
||||
#define VERSION_DATE_YEAR 20
|
||||
#define VERSION_DATE_MONTH 9
|
||||
#define VERSION_DATE_DAY 9
|
||||
#define VERSION_DATE_HOUR 10
|
||||
#define VERSION_DATE_MINUTE 26
|
||||
#define VERSION_DATE_MONTH 8
|
||||
#define VERSION_DATE_DAY 3
|
||||
#define VERSION_DATE_HOUR 17
|
||||
#define VERSION_DATE_MINUTE 42
|
||||
|
||||
// this is NOT the version hash !!
|
||||
// it's the last version hash
|
||||
#define VERSION_HASH b9c9cc0bbcdb1ad375f9f5966577ca34ef3fd6d1
|
||||
#define VERSION_GIT_BRANCH neulive20_development_without_central
|
||||
#define VERSION_HASH f4861bb6cb427dcb36cb0cb6e8f1c962dbd89fa8
|
||||
#define VERSION_GIT_BRANCH neulive20_linux_debug
|
||||
|
||||
static void get_board_name(char *board_name_ch, uint8 *board_name_int, uint8 name_size){
|
||||
uint8 name_offset = 18;
|
||||
|
||||
+8
-52
@@ -13,57 +13,7 @@
|
||||
static uint8_t not_buf_offset = NOT_BUF_OFFSET_INIT;
|
||||
static uint32_t not_time_stamp = 0;
|
||||
|
||||
static void headstage_notify_set_timestamp();
|
||||
static void headstage_notify_flip_buffer();
|
||||
static uint8_t headstage_notify_append_data(uint8_t *data_value);
|
||||
|
||||
/**
|
||||
* @fn headstage_neu_append_notify_data
|
||||
*/
|
||||
#define CHANNEL_VALID (INSTRUCTION.recording_channel & (0x0001 << channel))
|
||||
static void headstage_neu_append_notify_data() {
|
||||
|
||||
uint8_t channel = spi_rxbuf[0];
|
||||
|
||||
// close-reopen SPI, if the first channel received is invalid
|
||||
if(IsFirstData){
|
||||
// start record
|
||||
if((INSTRUCTION.recording_channel & (0x0001 << channel)) && (channel < 16)){
|
||||
IsFirstData = false;
|
||||
}
|
||||
// restart SPI
|
||||
else{
|
||||
SPI_close(headstage_spi_handle);
|
||||
ReopenSPI();
|
||||
IsFirstData = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// discard illegal channel
|
||||
// uint16_t valid_channel = INSTRUCTION.recording_channel & (0x0001 << channel);
|
||||
if(!(INSTRUCTION.recording_channel & (0x0001 << channel)) || (channel > 15)){
|
||||
// illegal channel
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t not_buf[3];
|
||||
not_buf[0] = channel; // ch
|
||||
not_buf[1] = spi_rxbuf[1];
|
||||
not_buf[2] = spi_rxbuf[2];
|
||||
|
||||
// not_buf[1] = (INSTRUCTION.recording_channel | 0xFF00) >> 8;
|
||||
// not_buf[2] = (INSTRUCTION.recording_channel | 0x00FF);
|
||||
|
||||
uint8_t data_size = headstage_notify_append_data(not_buf);
|
||||
|
||||
if (data_size >= BLE_NOT_BUFF_SIZE) {
|
||||
headstage_notify_flip_buffer();
|
||||
headstage_notify_send();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint32_t debug_counter = 0;
|
||||
static void headstage_notify_set_timestamp() {
|
||||
not_time_stamp = headstage_time_stamp_us();
|
||||
|
||||
@@ -71,12 +21,18 @@ static void headstage_notify_set_timestamp() {
|
||||
headstage_notify_buffer[3] = (not_time_stamp >> 8) & 0xFF;
|
||||
headstage_notify_buffer[4] = (not_time_stamp >> 16) & 0xFF;
|
||||
headstage_notify_buffer[5] = (not_time_stamp >> 24) & 0xFF;
|
||||
|
||||
// headstage_notify_buffer[2] = (debug_counter >> 24) & 0xFF;
|
||||
// headstage_notify_buffer[3] = (debug_counter >> 16) & 0xFF;
|
||||
// headstage_notify_buffer[4] = (debug_counter >> 8) & 0xFF;
|
||||
// headstage_notify_buffer[5] = debug_counter & 0xFF;
|
||||
// debug_counter ++;
|
||||
}
|
||||
|
||||
static void headstage_notify_flip_buffer() {
|
||||
uint8_t data_count = (not_buf_offset - NOT_BUF_OFFSET_INIT) / 3;
|
||||
|
||||
headstage_notify_buffer[0] = CHIP_ID;
|
||||
headstage_notify_buffer[0] = 4;
|
||||
headstage_notify_buffer[1] = data_count;
|
||||
|
||||
not_buf_offset = NOT_BUF_OFFSET_INIT;
|
||||
|
||||
-68
@@ -120,72 +120,4 @@ static void AppendSPITX(uint8_t index, uint32_t value){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @fn headstage_spi_callback
|
||||
*
|
||||
* description: callback function to deal with data transmission between DBS and CC2650
|
||||
*/
|
||||
static void headstage_spi_callback(SPI_Handle handle, SPI_Transaction* transaction) {
|
||||
switch(SPICallBack){
|
||||
case CONTINUOUS_TRANS:{
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
break;
|
||||
}
|
||||
case FLUSH_BUFFER:{
|
||||
SPICallBack = FLUSH_BUFFER2;
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
break;
|
||||
}
|
||||
case FLUSH_BUFFER2:{
|
||||
SPICallBack = ONE_SHOT_SPI;
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
// headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
break;
|
||||
}
|
||||
case ONE_SHOT_SPI:{
|
||||
SPICallBack = FLUSH_BUFFER;
|
||||
for(int i=0 ; i<SPI_BUFFER_SIZE ; i++){
|
||||
spi_txbuf[i] = 0x00;
|
||||
}
|
||||
headstage_spi_transaction(SPI_BUFFER_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
case READ_MOSI:{
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
break;
|
||||
}
|
||||
|
||||
case READ_REG:{
|
||||
check_reg_counter ++;
|
||||
flag_notify(EVT_NEU_SPI);
|
||||
break;
|
||||
}
|
||||
|
||||
case CLOSE_SPI:{
|
||||
SPICallBack = ONE_SHOT_SPI;
|
||||
SPI_close(headstage_spi_handle);
|
||||
break;
|
||||
}
|
||||
|
||||
case END_TRANSMIT:{
|
||||
tx_put_u24(0, 0);
|
||||
SPICallBack = CONTINUOUS_TRANS;
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+3
-4
@@ -120,17 +120,17 @@
|
||||
// Maximum connection interval (units of 1.25ms, 800=1000ms) if automatic
|
||||
// parameter update request is enabled
|
||||
//#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 6
|
||||
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 30
|
||||
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 40
|
||||
|
||||
#else //! FEATURE_OAD
|
||||
// Minimum connection interval (units of 1.25ms, 8=10ms) if automatic
|
||||
// parameter update request is enabled
|
||||
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 80
|
||||
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 8
|
||||
//#define DEFAULT_DESIRED_MIN_CONN_INTERVAL 14
|
||||
|
||||
// Maximum connection interval (units of 1.25ms, 8=10ms) if automatic
|
||||
// parameter update request is enabled
|
||||
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 80
|
||||
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 40
|
||||
//#define DEFAULT_DESIRED_MAX_CONN_INTERVAL 25
|
||||
|
||||
#endif // FEATURE_OAD
|
||||
@@ -561,7 +561,6 @@ static void SimpleBLEPeripheral_taskFxn(UArg a0, UArg a1) {
|
||||
headstage_init_device_info();
|
||||
|
||||
headstage_init();
|
||||
InitDBSRegister();
|
||||
|
||||
for (;;) {
|
||||
// Waits for a signal to the semaphore associated with the calling thread.
|
||||
|
||||
Reference in New Issue
Block a user