Compare commits

...

6 Commits

Author SHA1 Message Date
borshin_chang@gapp.nthu.edu.tw 8cc4ebea74 C6:52 Channel_3
threshold setting 115,000 always 1

so change it to 11,500,000 can do it
2021-03-29 13:44:11 +08:00
borshin_chang@gapp.nthu.edu.tw 81b99ce4b1 first_version of 16-point FFT on offline
with refer to MATLAB code cc6250_emulation_closed_loop.m
2021-03-29 11:05:49 +08:00
Borshin Chang 78720a9a7e RawData can transfer to RealData with difference CaliTable an userDefineGain
remove bugs in FFT_step (not infulence)

golden data specified !! Good result but 45,000 threshold is little bit high
2020-12-01 16:25:14 +08:00
Borshin Chang baeeafd002 RawData can transfer to RealData with difference CaliTable an userDefineGain
remove bugs in FFT_step (not infulence)
2020-12-01 15:05:19 +08:00
Borshin Chang be9084d8f1 LED can light central cDBS for "* flower" 2020-12-01 12:06:01 +08:00
Borshin Chang da1e1a54ac cDBS as central verision for "* flower" 2020-12-01 10:40:01 +08:00
6 changed files with 224 additions and 10 deletions
@@ -2,17 +2,17 @@
<launchConfiguration type="com.ti.ccstudio.debug.launchType.device.debugging">
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS100v3 USB Debug Probe_0/Cortex_M3_0" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot; ?&gt;&#10;&lt;PropertyValues&gt;&#10;&#10; &lt;property id=&quot;ConnectOnStartup&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;EnableInstalledBreakpoint&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;IgnoreSoftLaunchFailures&quot;&gt;&#10; &lt;curValue&gt;0&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10;&lt;/PropertyValues&gt;&#10;"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot; ?&gt;&#10;&lt;PropertyValues&gt;&#10;&#10; &lt;property id=&quot;ConnectOnStartup&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;EnableInstalledBreakpoint&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;IgnoreSoftLaunchFailures&quot;&gt;&#10; &lt;curValue&gt;0&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10;&lt;/PropertyValues&gt;&#10;"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot; ?&gt;&#10;&lt;PropertyValues&gt;&#10;&#10; &lt;property id=&quot;ConnectOnStartup&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;EnableInstalledBreakpoint&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;IgnoreSoftLaunchFailures&quot;&gt;&#10; &lt;curValue&gt;0&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10;&lt;/PropertyValues&gt;&#10;"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_DEBUGGER_PROPERTIES.CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot; ?&gt;&#10;&lt;PropertyValues&gt;&#10;&#10; &lt;property id=&quot;ConnectOnStartup&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;EnableInstalledBreakpoint&quot;&gt;&#10; &lt;curValue&gt;1&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10; &lt;property id=&quot;IgnoreSoftLaunchFailures&quot;&gt;&#10; &lt;curValue&gt;0&lt;/curValue&gt;&#10; &lt;/property&gt;&#10;&#10;&lt;/PropertyValues&gt;&#10;"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROGRAM.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS100v3 USB Debug Probe_0/Cortex_M3_0" value="${build_artifact:simple_peripheral_cc2650em_app}"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROGRAM.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="${build_artifact:simple_peripheral_cc2650em_app}"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROGRAM.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="${build_artifact:simple_peripheral_cc2650em_app}"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROGRAM.CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="${build_artifact:simple_peripheral_cc2650em_app}"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROJECT.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS100v3 USB Debug Probe_0/Cortex_M3_0" value="simple_peripheral_cc2650em_app"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROJECT.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="simple_peripheral_cc2650em_app"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROJECT.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="simple_peripheral_cc2650em_app"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_PROJECT.CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="simple_peripheral_cc2650em_app"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.ATTR_TARGET_CONFIG" value="${target_config_active_default:simple_peripheral_cc2650em_app}"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.MRU_PROGRAM.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS100v3 USB Debug Probe_0/Cortex_M3_0" value="C:/ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\FlashROM\simple_peripheral_cc2650em_app.out"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.MRU_PROGRAM.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe/Cortex_M3_0" value="C:/ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\FlashROM\simple_peripheral_cc2650em_app.out"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.MRU_PROGRAM.C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\targetConfigs\CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="C:/ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\FlashROM\simple_peripheral_cc2650em_app.out"/>
<stringAttribute key="com.ti.ccstudio.debug.debugModel.MRU_PROGRAM.CC2650F128.ccxml.Texas Instruments XDS110 USB Debug Probe_0/Cortex_M3_0" value="C:\ti\simplelink\ble_sdk_2_02_02_25\examples\cc2650em\simple_peripheral\ccs\app\FlashROM\simple_peripheral_cc2650em_app.out"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/simple_peripheral_cc2650em_app"/>
</listAttribute>
@@ -19,7 +19,7 @@
</property>
<property Type="choicelist" Value="1" id="Debug Probe Selection">
<choice Name="Select by serial number" value="0">
<property Type="stringfield" Value="L1000537" id="-- Enter the serial number"/>
<property Type="stringfield" Value="L1000628" id="-- Enter the serial number"/>
</choice>
</property>
<platform XML_version="1.2" id="platform_0">
@@ -146,6 +146,7 @@ extern const PIN_Config BoardGpioInitTable[];
#define Board_GLED PIN_UNASSIGNED /* Green LED */
#define Board_RLED PIN_UNASSIGNED /* Red LED */
/* UART Board */
#define Board_UART_TX Board_BP_UART_Rx /* RXD */
#define Board_UART_RX Board_BP_UART_Tx /* TXD */
@@ -2,7 +2,9 @@
#ifndef NEU_CALI_TABLE
#define NEU_CALI_TABLE
#define BOARD_TEST
// define Device_Name if "BOARD_TEST" as default
// else find headstage ID
#define BOARD_18_04_ED_37_C6_52
typedef struct _SingleChannelCali{
uint16_t Gain[4];
@@ -9,9 +9,24 @@
#endif
#include "headstage_dbs_object.h"
#define NOT_BUF_OFFSET_INIT 8
#include "headstage_cali_table.h"
static uint8_t numFFT = 16; // user define
static uint8_t step = 8; // which is numFFT/2
static uint8_t stageFFT = 4; // which is log2(numFFT)
static int twiddle_real[16] = {10000, 9238, 7071, 3826, 0, -3827, -7072, -9239, -10000, -9239, \
-7072, -3827, -1, 3826, 7071, 9238};
static int twiddle_imag[16] = { 0, -3827, -7072, -9239, -10000, -9239, -7072, -3827, -1, 3826, \
7071, 9238, 10000, 9238, 7071, 3826};
static void FFT(int* pred_LFP, int* imag_LFP, int numFFT);
static void BitReverse(int* BR_Array, int numFFT);
static void CLP(uint16_t raw_data);
static int ADC_U2S( uint16_t unsigned_buff);
static uint8_t not_buf_offset = NOT_BUF_OFFSET_INIT;
static uint32_t not_time_stamp = 0;
@@ -48,11 +63,29 @@ static void headstage_neu_append_notify_data() {
// illegal channel
return;
}
uint8_t not_buf[2];
not_buf[0] = (channel & 0x0F) << 4 | (spi_rxbuf[1] & 0x0F);
not_buf[1] = spi_rxbuf[2];
// Borshin closed-loop start here <<<<<<<<<<<<<<<<<<<<---->>>>>>>>>>>>>>>>>>>>----------------------
uint16_t borshin_raw;
uint8_t borshin_a;
uint8_t borshin_b;
uint8_t borshin_sample_rate;
uint16_t borshin_real;
borshin_raw = (spi_rxbuf[1]&0x0F)<<8 | spi_rxbuf[2];
borshin_a = CaliTable.Ch[channel].Gain[ rec_register_value[REC_CHANNEL_INDEX] ];
borshin_b = CaliTable.Ch[channel].Offset[ rec_register_value[REC_CHANNEL_INDEX] ];
borshin_real = borshin_raw * borshin_a + borshin_b; // range from [ FFF , 000 ]
borshin_sample_rate = 2000000/10/rec_register_value[REC_ADC_CLOCK_INDEX];
CLP( borshin_raw ); // This function input is 12-bit value
// the function will buffer 16-point then
// perform 16-point FFT.
// Afterwards, calculate sum of PSD then
// decided if HVS happened. (GPIO_4)
// Borshin closed-loop END here <<<<<<<<<<<<<<<<<<<<----------------------------->>>>>>>>>>>>>>>>>>>>
uint8_t data_size = headstage_notify_append_data(not_buf);
if (data_size >= BLE_NOT_BUFF_SIZE) {
@@ -108,3 +141,179 @@ static uint8_t headstage_notify_append_data(uint8_t *data_value) {
}
#endif // HEADSTAGE_NOTIFY_TDC4VAF2_H
/*********************************************************************
* @fn FFT
*
* @brief TI Cortex M3 doesn't have floating-point ALU, we have to do
* fixed-point FFT. And in-place FFT because lack of RAM.
*
* @param None.
*
* @return None.
*/
static void FFT(int* pred_LFP, int* imag_LFP, int numFFT){
// testing_sig = !testing_sig;
// uint8_t stageFFT = 6; // static global log2(numFFT)
int l;
int product_real, product_imag;
int upfly_real, upfly_imag;
int downfly_real, downfly_imag;
for (int i=0; i<stageFFT; i++){
l = 1<<i;
for (int j=0; j<numFFT; j+=2*l){
for (int k=0; k<l; k++){
//printf("stage = %d , butterfly_top = %d , butterfly_down = %d , twiddle[%d] \n", i, j+k, j+k+l, NFFT*(k)/2/l);
product_real = pred_LFP[j+k+l] * twiddle_real[numFFT*(k)/2/l] \
- imag_LFP[j+k+l] * twiddle_imag[numFFT*(k)/2/l];
product_imag = pred_LFP[j+k+l] * twiddle_imag[numFFT*(k)/2/l] \
+ imag_LFP[j+k+l] * twiddle_real[numFFT*(k)/2/l];
product_real = product_real/10000; // left shift number =10 which is up to Int_twiddle-factor
product_imag = product_imag/10000;
upfly_real = pred_LFP[j+k] + product_real;
upfly_imag = imag_LFP[j+k] + product_imag;
downfly_real = pred_LFP[j+k] - product_real;
downfly_imag = imag_LFP[j+k] - product_imag;
pred_LFP[j+k] = upfly_real;
imag_LFP[j+k] = upfly_imag;
pred_LFP[j+k+l] = downfly_real;
imag_LFP[j+k+l] = downfly_imag;
}
}
}
return;
}
/*********************************************************************
* @fn ADC_U2S
*
* @brief ADC sample data in 12-bit which is FFF~000, but for FFT
* it needs to be pulled back to +7FF to -7FF. These is based
* on simulation result, which is like the function ADC_ISR()
* in Ramesh or Remy's code. [ ADC_unsigned_2_signed ]
*
* @param unsigned 16-bit input
*
* @return signed 16-bit output ----_0000_0000_0000 ~ ----_1000_0000_0000
*/
static int ADC_U2S( uint16_t unsigned_buff){
// 0x0FFF ~ 0x0000 (16-bit unsigned)
int output; // 0x07FF-0x0000 ~ 0x0FFF-0x0800
// int is 32-bit 0x0000_0000
if ( unsigned_buff >= 0x00000800)
output = unsigned_buff - 0x00000800;
else
output = unsigned_buff | 0xFFFFF800;
return output;
}
/*********************************************************************
* @fn BitReverse
*
* @brief Do array Bit-Reverse before perform FFT
*
* @param None.
*
* @return None.
*/
static void BitReverse(int* BR_Array, int numFFT){
// This BIR specify for 7-bit (0000_0000 ~ 0111_1111)
uint8_t n=0;
int tmp;
for (uint8_t i=0; i<numFFT; i++){
n = i; // printf ("%d %d\n",i,n);
n = (n&0x0f)<<4 | (n&0xf0)>>4; // 0123_4567 -> 4567_0123
n = (n&0x33)<<2 | (n&0xcc)>>2; // 4567_0123 -> 6745_2301
n = (n&0xaa)<<2 | (n&0x55)>>1; // 7856_3412 -> 7654_3210
n = n >> 1; // 7654_3210 -> 0765_4321
if (n>i){
tmp = BR_Array[n];
BR_Array[n] = BR_Array[i];
BR_Array[i] = tmp;
}
}
return;
} // END Bit Reverse Order Sort
/*********************************************************************
* @fn CLP ( Closed LooP )
*
* @brief
*
* @param None.
*
* @return None.
*/
static void CLP(uint16_t unsigned_real_data){
int signed_buff;
static int accumu_sum;
static int x_in[16];
static int real[16];
static int imag[16];
static int count_sample;
static int count_data;
int abs_tmp;
static int present, past1, past2, hvs;
// static int w[6] = {1597,-1909,1856,-1190,630,23};
static int w[6] = { 1, -2, 2, -1, 1, 0};
count_sample++; // count+1 every 1-ms
if (count_sample>=24){ // ensure sample LFP data every 24-ms(41.6667Hz)
signed_buff = ADC_U2S(unsigned_real_data); // FFF ~ 000 to +7FF ~ -7FF
x_in[count_data] = signed_buff;
real[count_data] = signed_buff;
imag[count_data] = 0;
count_sample = 0; // re-calculate count
count_data++;
if (count_data>=6){
accumu_sum = 0;
for (int i=6;i<numFFT;i++){
real[i] = ( w[0] * real[i-1] \
+ w[1] * real[i-2] \
+ w[2] * real[i-3] \
+ w[3] * real[i-4] \
+ w[4] * real[i-5] \
+ w[5] * real[i-6] );
imag[i] = 0;
}
BitReverse( real, numFFT);
FFT( real, imag, numFFT);
for (int i=1;i<6;i++){
if (i>=2&&i<=4){
accumu_sum += real[i]*real[i]+imag[i]*imag[i];
}
real[i-1] = x_in[i];
imag[i-1] = 0;
x_in[i-1] = x_in[i];
}
present = ( (accumu_sum) > 11500000 )?1:0;
if (present+past1+past2==3)
hvs = 1;
else
hvs = 0;
past2 = past1;
past1 = present;
if (hvs==1)
headstage_pin_output(PIN_CLP, 1);
else
headstage_pin_output(PIN_CLP, 0);
count_data--;
}
}
return;
}
@@ -29,7 +29,8 @@
#define PIN_LED_CLK IOID_1 // SPI1 clock
#define PIN_DC_DC IOID_2 // STI select need
#define PIN_EN_ADC_SPI_CLK IOID_3 //
#define PIN_BATT_HALF IOID_4 //
//#define PIN_BATT_HALF IOID_4 //
#define PIN_CLP IOID_4 // cDBS detect HVS LED::also added in config table
#define PIN_SPI_MISO IOID_7 //
#define PIN_SPI_MOSI IOID_8 //
#define PIN_SPI_CS IOID_9 //
@@ -77,7 +78,8 @@ static PIN_Config headstage_pin_configuration[] = { //
PIN_RESET | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
PIN_EN_ADC_SPI_CLK | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
PIN_DC_DC | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
PIN_BATT_HALF | PIN_INPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
PIN_CLP | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL, // cDBS detect HVS LED::added in config table
// PIN_BATT_HALF | PIN_INPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
PIN_STI_CLK | PIN_INPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
// TODO : add PIN_IRQ for STI clock to detect STI status (update LED & resend STI command if failed before)
PIN_TERMINATE};