save
This commit is contained in:
+249
-243
@@ -24,7 +24,7 @@ TODO
|
||||
==== product information ====
|
||||
===========================*/
|
||||
|
||||
#define DEVICE_NAME "NeuliveSTI-M0.1"
|
||||
#define DEVICE_NAME "NeuliveSTI"
|
||||
#define MAJOR_PRODUCT_NUMBER 1
|
||||
#define MINOR_PRODUCT_NUMBER 2
|
||||
#define MAJOR_VERSION_NUMBER 1
|
||||
@@ -46,6 +46,9 @@ TODO
|
||||
#define RIS_LOCAL 0x40
|
||||
#define RIS_CHANNEL 0x80
|
||||
|
||||
// ask sti remain times
|
||||
#define DEBUG_INS_TIMES 0x10
|
||||
// ask device sleeping
|
||||
#define DEBUG_INS_SLEEP 0x50
|
||||
|
||||
#define STI_WAVEFORM_POS 0x00
|
||||
@@ -59,13 +62,37 @@ TODO
|
||||
==== include ====
|
||||
================*/
|
||||
|
||||
#define HEADSTAGE_PIN_USE_CC26XX
|
||||
|
||||
#include "headstage_debug.h"
|
||||
#include "headstage_power.h"
|
||||
#include "headstage_pin.h"
|
||||
#include "sti/headstage_adc.h"
|
||||
#include "sti/headstage_gptimer.h"
|
||||
#include "sti/headstage_pwm.h"
|
||||
|
||||
static uint32_t cpu_frequency;
|
||||
|
||||
#ifdef headstage_gptimer_set_frequency
|
||||
#undef headstage_gptimer_set_frequency
|
||||
#define headstage_gptimer_set_frequency(gptimer_handle, frequency) \
|
||||
do { \
|
||||
uint32_t _frequency = (uint32_t)(frequency); \
|
||||
GPTimerCC26XX_Value _load = cpu_frequency / _frequency - 1; \
|
||||
_load = (_load < 0xFFFF) ? _load : ((0xFA0000 | (_load / 250)) - 1); \
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle, _load); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef headstage_gptimer_set_timeout
|
||||
#undef headstage_gptimer_set_timeout
|
||||
#define headstage_gptimer_set_timeout(gptimer_handle, timeout_us) \
|
||||
do { \
|
||||
GPTimerCC26XX_Value _load = (timeout_us)*cpu_frequency / 1000000 - 1; \
|
||||
_load = (_load < 0xFFFF) ? _load : ((0xFA0000 | (_load / 250)) - 1); \
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle, _load); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/*=================================
|
||||
==== constant parameter table ====
|
||||
================================*/
|
||||
@@ -75,44 +102,72 @@ TODO
|
||||
========================*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t enable;
|
||||
uint8_t mode;
|
||||
uint8_t precision;
|
||||
uint16_t frequency;
|
||||
uint16_t pulse_width;
|
||||
uint16_t pw_ipi;
|
||||
uint16_t times;
|
||||
/**
|
||||
* enable channel
|
||||
*/
|
||||
uint8_t enable;
|
||||
|
||||
/**
|
||||
* low frequency counter.
|
||||
* waveform
|
||||
*/
|
||||
int low_freq_counter;
|
||||
uint8_t mode;
|
||||
|
||||
/**
|
||||
* frequency factor
|
||||
*/
|
||||
uint8_t precision;
|
||||
|
||||
/**
|
||||
* pulse frequency
|
||||
*/
|
||||
uint16_t frequency;
|
||||
|
||||
/**
|
||||
* pulse width
|
||||
*/
|
||||
uint16_t pulse_width;
|
||||
|
||||
/**
|
||||
* pulse internal pulse interval
|
||||
*/
|
||||
uint16_t pw_ipi;
|
||||
|
||||
/**
|
||||
* stimulation times
|
||||
*/
|
||||
uint8_t times;
|
||||
} NeuLiveStiChanelParameter;
|
||||
|
||||
typedef struct {
|
||||
uint8_t pon;
|
||||
uint8_t pol;
|
||||
uint8_t stage;
|
||||
} NeuLiveStiChanelState;
|
||||
|
||||
struct HEADSTAGE_PARAMETER_TABLE {
|
||||
uint32_t duty_cycle;
|
||||
NeuLiveStiChanelParameter channel[TOTAL_CHANNEL_NUMBER];
|
||||
NeuLiveStiChanelState state[TOTAL_CHANNEL_NUMBER];
|
||||
} INSTRUCTION = {0};
|
||||
|
||||
#define reset_parameter_table() memset(&INSTRUCTION, 0, sizeof(struct HEADSTAGE_PARAMETER_TABLE));
|
||||
#define reset_parameter_table() \
|
||||
do { \
|
||||
memset(&INSTRUCTION, 0, sizeof(struct HEADSTAGE_PARAMETER_TABLE)); \
|
||||
INSTRUCTION.state[CHANNEL_STI_0].pon = PIN_PON0; \
|
||||
INSTRUCTION.state[CHANNEL_STI_0].pol = PIN_POL0; \
|
||||
INSTRUCTION.state[CHANNEL_STI_1].pon = PIN_PON1; \
|
||||
INSTRUCTION.state[CHANNEL_STI_1].pol = PIN_POL1; \
|
||||
} while (0)
|
||||
|
||||
#define actual_channel_frequency(p) (p->frequency / (p->precision ? 10 : 1))
|
||||
|
||||
#define is_low_frequency(p) ((p->frequency < 4 && p->precision == 0) || (p->frequency < 2000 && p->precision == 1))
|
||||
#define infinite_times(p) (p->times >= 1000)
|
||||
|
||||
static GPTimerCC26XX_Handle headstage_gptimer_handle[] = {
|
||||
//
|
||||
gptimer_handle_2,
|
||||
gptimer_handle_0,
|
||||
gptimer_handle_1,
|
||||
//
|
||||
};
|
||||
|
||||
static ADC_Handle headstage_adc_handle[] = {
|
||||
//
|
||||
headstage_adc_handle_2,
|
||||
headstage_adc_handle_0,
|
||||
headstage_adc_handle_1,
|
||||
gptimer_handle_2,
|
||||
//
|
||||
};
|
||||
|
||||
@@ -129,25 +184,6 @@ static void headstage_sti_collect_stimulation_information();
|
||||
=======================*/
|
||||
|
||||
static void headstage_sti_event() {
|
||||
if (flag_mask(EVT_PERIODIC_GPTIMER_0)) {
|
||||
flag_disable(EVT_PERIODIC_GPTIMER_0);
|
||||
|
||||
headstage_sti_pulse_event(CHANNEL_STI_0);
|
||||
}
|
||||
|
||||
if (flag_mask(EVT_PERIODIC_GPTIMER_1)) {
|
||||
flag_disable(EVT_PERIODIC_GPTIMER_1);
|
||||
|
||||
headstage_sti_pulse_event(CHANNEL_STI_1);
|
||||
}
|
||||
|
||||
if (flag_mask(EVT_PERIODIC_GPTIMER_2)) {
|
||||
flag_disable(EVT_PERIODIC_GPTIMER_2);
|
||||
|
||||
headstage_sti_collect_recording_data(CHANNEL_BATTERY);
|
||||
headstage_sti_collect_stimulation_information();
|
||||
}
|
||||
|
||||
if (EVENT_MASK == 0) {
|
||||
// fast return
|
||||
return;
|
||||
@@ -164,158 +200,132 @@ static void headstage_sti_event() {
|
||||
|
||||
static void headstage_init() {
|
||||
headstage_pin_open();
|
||||
|
||||
Types_FreqHz cpu_freq;
|
||||
BIOS_getCpuFreq(&cpu_freq);
|
||||
cpu_frequency = cpu_freq.lo;
|
||||
|
||||
headstage_gptimer_open();
|
||||
|
||||
headstage_pwm_open();
|
||||
headstage_adc_open();
|
||||
|
||||
headstage_gptimer_set_frequency(headstage_gptimer[CHANNEL_BATTERY], 200);
|
||||
|
||||
headstage_pwm_start();
|
||||
|
||||
headstage_pin_output(PIN_STI_0, 0);
|
||||
headstage_pin_output(PIN_SET_1, 0);
|
||||
headstage_pin_output(PIN_SET_3, 1);
|
||||
headstage_pin_output(PIN_SET_5, 0);
|
||||
headstage_pin_output(PIN_SET_6, 0);
|
||||
headstage_pin_output(PIN_SET_10, 0);
|
||||
headstage_pin_output(PIN_SET_11, 0);
|
||||
headstage_pin_output(PIN_POL0, 0);
|
||||
headstage_pin_output(PIN_POL1, 0);
|
||||
headstage_pin_output(PIN_PON0, 0);
|
||||
headstage_pin_output(PIN_PON1, 0);
|
||||
headstage_pin_output(PIN_TPS, 1);
|
||||
}
|
||||
|
||||
static void headstage_update_ris_instruction(uint8_t ins_len, uint8_t *instruction) {
|
||||
uint8_t ins_oper = instruction[0] & 0xE0;
|
||||
|
||||
switch (ins_oper) {
|
||||
case RIS_GLOBAL: {
|
||||
// 5b11111#header;2b0#GV;12bCURRENT
|
||||
// --------------------
|
||||
// 3b001#header#;1bx;12bCURRENT
|
||||
case RIS_GLOBAL: {
|
||||
// 3b001#header#;1bx;12bCURRENT
|
||||
|
||||
uint16_t a = (uint16_t)(instruction[0]) && 0x0F;
|
||||
uint16_t b = (uint16_t)(instruction[1]) && 0xFF;
|
||||
uint16_t current = (a << 8) | b; // actual current output(mA) in 1mA mode (2019/03)
|
||||
uint16_t a = (uint16_t)(instruction[0]) && 0x0F;
|
||||
uint16_t b = (uint16_t)(instruction[1]) && 0xFF;
|
||||
uint16_t current = (a << 8) | b; // actual current output(mA) in 1mA mode (2019/03)
|
||||
|
||||
INSTRUCTION.duty_cycle = current;
|
||||
headstage_pwm_set(MAX_DUTY, current);
|
||||
break;
|
||||
}
|
||||
|
||||
case RIS_LOCAL: {
|
||||
// 5b11111#header;2b01#LV
|
||||
// 3b>channel
|
||||
// 1b>PRECISION[channel]
|
||||
// 3b>STI_MODE[channel]
|
||||
// 12b>STI_FREQ[channel]
|
||||
// 10b>STI_PW[channel]
|
||||
// 10b>STI_PW_IPI[channel]
|
||||
// 10b>STI_NUM[channel]
|
||||
// --------------------
|
||||
// 3b010#header;1bx
|
||||
// 4b>channel
|
||||
// 3b>STI_MODE[channel]
|
||||
// 1b>PRECISION[channel]
|
||||
// 12b>STI_FREQ[channel]
|
||||
// 10b>STI_PW[channel]
|
||||
// 10b>STI_PW_IPI[channel]
|
||||
// 10b>STI_NUM[channel]
|
||||
uint8_t channel = (instruction[0] & 0x0F);
|
||||
uint8_t mode = (instruction[1] & 0xE0) >> 5;
|
||||
uint8_t prec = (instruction[1] & 0x10) >> 4;
|
||||
uint16_t freq_a = (uint16_t)(instruction[1]) & 0x0F;
|
||||
uint16_t freq_b = (uint16_t)(instruction[2]) & 0xFF;
|
||||
uint16_t freq = (freq_a << 8) | freq_b;
|
||||
uint16_t width_a = (uint16_t)(instruction[3]) & 0xFF;
|
||||
uint16_t width_b = (uint16_t)(instruction[4]) & 0xC0;
|
||||
uint16_t width = (width_a << 2) | (width_b >> 6);
|
||||
uint16_t ipi_a = (uint16_t)(instruction[4]) & 0x3F;
|
||||
uint16_t ipi_b = (uint16_t)(instruction[5]) & 0xF0;
|
||||
uint16_t ipi = (ipi_a << 4) | (ipi_b >> 4);
|
||||
uint16_t times_a = (uint16_t)(instruction[5]) & 0x0F;
|
||||
uint16_t times_b = (uint16_t)(instruction[6]) & 0xFC;
|
||||
uint16_t times = (times_a << 6) | (times_b >> 2);
|
||||
|
||||
if (channel < TOTAL_CHANNEL_NUMBER - 1) {
|
||||
NeuLiveStiChanelParameter *p = &INSTRUCTION.channel + 1 + channel;
|
||||
|
||||
uint16_t adjust_value = (channel == 0) ? 3 : 5;
|
||||
|
||||
if (width > 0) {
|
||||
// error when output 100us
|
||||
width += (width * adjust_value / 100) - 1;
|
||||
}
|
||||
|
||||
if (ipi > 0) {
|
||||
// error when output 100us
|
||||
ipi += (ipi * adjust_value / 100) - 1;
|
||||
}
|
||||
|
||||
p->mode = mode;
|
||||
p->precision = prec;
|
||||
p->frequency = freq;
|
||||
p->pulse_width = width;
|
||||
p->pulse_width = width;
|
||||
p->pw_ipi = ipi;
|
||||
p->times = times;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case RIS_CHANNEL: {
|
||||
// 5b11111#header;2b10#CE
|
||||
// a0;a1;a2;a3;a4;a5;a6;a7;a8;a9;aa;ab;ac;ad;ae;af
|
||||
// --------------------
|
||||
// 3b100#header;5bx;
|
||||
// a0;a1;a2;a3;a4;a5;a6;a7;a8;a9;aa;ab;ac;ad;ae;af
|
||||
|
||||
if (INSTRUCTION.duty_cycle == 0) {
|
||||
INSTRUCTION.duty_cycle = current;
|
||||
headstage_pwm_set(MAX_DUTY, current);
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint8_t channel = 1; channel < TOTAL_CHANNEL_NUMBER; i++) {
|
||||
NeuLiveStiChanelParameter *p = &INSTRUCTION.channel + channel;
|
||||
case RIS_LOCAL: {
|
||||
// 3b010#header;1bx
|
||||
// 4b>channel
|
||||
// 3b>STI_MODE[channel]
|
||||
// 1b>PRECISION[channel]
|
||||
// 12b>STI_FREQ[channel]
|
||||
// 10b>STI_PW[channel]
|
||||
// 10b>STI_PW_IPI[channel]
|
||||
// 10b>STI_NUM[channel]
|
||||
uint8_t channel = (instruction[0] & 0x0F);
|
||||
uint8_t mode = (instruction[1] & 0xE0) >> 5;
|
||||
uint8_t prec = (instruction[1] & 0x10) >> 4;
|
||||
uint16_t freq_a = (uint16_t)(instruction[1]) & 0x0F;
|
||||
uint16_t freq_b = (uint16_t)(instruction[2]) & 0xFF;
|
||||
uint16_t freq = (freq_a << 8) | freq_b;
|
||||
uint16_t width_a = (uint16_t)(instruction[3]) & 0xFF;
|
||||
uint16_t width_b = (uint16_t)(instruction[4]) & 0xC0;
|
||||
uint16_t width = (width_a << 2) | (width_b >> 6);
|
||||
uint16_t ipi_a = (uint16_t)(instruction[4]) & 0x3F;
|
||||
uint16_t ipi_b = (uint16_t)(instruction[5]) & 0xF0;
|
||||
uint16_t ipi = (ipi_a << 4) | (ipi_b >> 4);
|
||||
uint16_t times_a = (uint16_t)(instruction[5]) & 0x0F;
|
||||
uint16_t times_b = (uint16_t)(instruction[6]) & 0xFC;
|
||||
uint16_t times = (times_a << 6) | (times_b >> 2);
|
||||
|
||||
uint8_t index = 1 + (channel - 1) % 8;
|
||||
uint8_t mask = 1 << (7 - (channel - 1) / 8);
|
||||
if (channel < TOTAL_CHANNEL_NUMBER - 1) {
|
||||
NeuLiveStiChanelParameter *p = &INSTRUCTION.channel + 1 + channel;
|
||||
|
||||
p->enable = 0;
|
||||
|
||||
if ((instruction[index] & mask) != 0) {
|
||||
uint16_t frequency = actual_channel_frequency(p);
|
||||
|
||||
if (is_low_frequency(p)) {
|
||||
frequency *= 100;
|
||||
}
|
||||
|
||||
if (frequency != 0 && p->pulse_width != 0) {
|
||||
p->enable = 1;
|
||||
headstage_gptimer_set_frequency(headstage_gptimer_handle[channel], frequency);
|
||||
}
|
||||
p->mode = mode;
|
||||
p->precision = prec;
|
||||
p->frequency = freq;
|
||||
p->pulse_width = width;
|
||||
p->pulse_width = width;
|
||||
p->pw_ipi = ipi;
|
||||
p->times = times;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RIS_CHANNEL: {
|
||||
// 3b100#header;5bx;
|
||||
// a0;a1;a2;a3;a4;a5;a6;a7;a8;a9;aa;ab;ac;ad;ae;af
|
||||
|
||||
if (INSTRUCTION.duty_cycle == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint8_t channel = 1; channel < TOTAL_CHANNEL_NUMBER; i++) {
|
||||
NeuLiveStiChanelParameter *p = &INSTRUCTION.channel + channel;
|
||||
|
||||
uint8_t index = 1 + (channel - 1) % 8;
|
||||
uint8_t mask = 1 << (7 - (channel - 1) / 8);
|
||||
|
||||
p->enable = 0;
|
||||
|
||||
if ((instruction[index] & mask) != 0) {
|
||||
if (p->frequency != 0 && p->pulse_width != 0) {
|
||||
p->enable = 1;
|
||||
headstage_gptimer_set_frequency(headstage_gptimer_handle[channel], frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void headstage_update_vis_instruction(uint8_t vis_oper) {
|
||||
switch (vis_oper) {
|
||||
case VIS_STI:
|
||||
headstage_gptimer_start(gptimer_handle_0);
|
||||
headstage_gptimer_start(gptimer_handle_1);
|
||||
headstage_gptimer_start(gptimer_handle_2);
|
||||
break;
|
||||
case VIS_RST:
|
||||
headstage_gptimer_stop(gptimer_handle_0);
|
||||
headstage_gptimer_stop(gptimer_handle_1);
|
||||
headstage_gptimer_stop(gptimer_handle_2);
|
||||
reset_parameter_table();
|
||||
break;
|
||||
case VIS_INT:
|
||||
headstage_gptimer_stop(gptimer_handle_0);
|
||||
headstage_gptimer_stop(gptimer_handle_1);
|
||||
headstage_gptimer_stop(gptimer_handle_2);
|
||||
break;
|
||||
case VIS_STI: {
|
||||
for (uint8_t channel = 1; channel < TOTAL_CHANNEL_NUMBER; i++) {
|
||||
NeuLiveStiChanelParameter *p = &INSTRUCTION.channel + channel;
|
||||
|
||||
if (p->enable) {
|
||||
headstage_gptimer_start(headstage_gptimer_handle[channel]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIS_RST: {
|
||||
for (uint8_t channel = 0; channel < TOTAL_CHANNEL_NUMBER; i++) {
|
||||
headstage_gptimer_stop(headstage_gptimer_handle[channel]);
|
||||
}
|
||||
reset_parameter_table();
|
||||
break;
|
||||
}
|
||||
case VIS_INT: {
|
||||
for (uint8_t channel = 0; channel < TOTAL_CHANNEL_NUMBER; i++) {
|
||||
headstage_gptimer_stop(headstage_gptimer_handle[channel]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,11 +333,20 @@ static uint8_t headstage_debug_instruction(uint8_t ins_buf) {
|
||||
uint8_t ins_oper = ins_buf[0] & 0xF0;
|
||||
|
||||
switch (ins_oper) {
|
||||
case DEBUG_INS_SLEEP:
|
||||
headstage_pin_output(IOID_3, 0);
|
||||
headstage_power_shutdown();
|
||||
break;
|
||||
case DEBUG_INS_TIMES:
|
||||
for (uint8_t channel = 1; channel < TOTAL_CHANNEL_NUMBER; i++) {
|
||||
ins_buf[channel] = INSTRUCTION.channel[channel].times;
|
||||
}
|
||||
return TOTAL_CHANNEL_NUMBER;
|
||||
|
||||
case DEBUG_INS_SLEEP:
|
||||
headstage_update_vis_instruction(VIS_INT);
|
||||
headstage_pin_output(PIN_TPS, 0);
|
||||
headstage_power_shutdown();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*========================
|
||||
@@ -336,95 +355,82 @@ static uint8_t headstage_debug_instruction(uint8_t ins_buf) {
|
||||
|
||||
static void headstage_sti_pulse_event(uint8_t channel) {
|
||||
NeuLiveStiChanelParameter *p;
|
||||
NeuLiveStiChanelState * s;
|
||||
|
||||
switch (channel) {
|
||||
case CHANNEL_STI_0:
|
||||
case CHANNEL_STI_1:
|
||||
p = &INSTRUCTION.channel + channel;
|
||||
break;
|
||||
case CHANNEL_BATTERY:
|
||||
default:
|
||||
return;
|
||||
case CHANNEL_STI_0:
|
||||
case CHANNEL_STI_1:
|
||||
p = &INSTRUCTION.channel + channel;
|
||||
s = &INSTRUCTION.state + channel;
|
||||
break;
|
||||
case CHANNEL_BATTERY:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(p->enable && p->times > 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t p0, p1, p2;
|
||||
|
||||
switch (channel) {
|
||||
case CHANNEL_STI_0:
|
||||
p0 = PIN_STI_0;
|
||||
p1 = PIN_SET_10;
|
||||
p2 = PIN_SET_11;
|
||||
break;
|
||||
case CHANNEL_STI_1:
|
||||
p0 = PIN_STI_1;
|
||||
p1 = PIN_SET_6;
|
||||
p2 = PIN_SET_5;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (p->mode) {
|
||||
case STI_WAVEFORM_POS:
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
break;
|
||||
case STI_WAVEFORM_NEG:
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
break;
|
||||
case STI_WAVEFORM_P2N:
|
||||
if (p->pw_ipi == 0) {
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
} else {
|
||||
case STI_WAVEFORM_POS:
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
headstage_cpu_delay_us(p->pw_ipi);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
}
|
||||
break;
|
||||
case STI_WAVEFORM_N2P:
|
||||
if (p->pw_ipi == 0) {
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
} else {
|
||||
break;
|
||||
case STI_WAVEFORM_NEG:
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
headstage_cpu_delay_us(p->pw_ipi);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case STI_WAVEFORM_P2N:
|
||||
if (p->pw_ipi == 0) {
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
} else {
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
headstage_cpu_delay_us(p->pw_ipi);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
}
|
||||
break;
|
||||
case STI_WAVEFORM_N2P:
|
||||
if (p->pw_ipi == 0) {
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
} else {
|
||||
headstage_pin_output(p1, 1);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p0, 1);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
headstage_cpu_delay_us(p->pw_ipi);
|
||||
headstage_pin_output(p2, 1);
|
||||
headstage_pin_output(p1, 0);
|
||||
headstage_cpu_delay_us(p->pulse_width);
|
||||
headstage_pin_output(p2, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
headstage_sti_collect_recording_data(channel);
|
||||
|
||||
+34
-17
@@ -6,6 +6,8 @@
|
||||
#include <Board.h>
|
||||
#include <ti/drivers/timer/GPTimerCC26XX.h>
|
||||
#include <ti/sysbios/BIOS.h>
|
||||
#include <ti/sysbios/family/arm/cc26xx/Power.h>
|
||||
#include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
|
||||
#include <xdc/runtime/Types.h>
|
||||
|
||||
#define EVT_PERIODIC_GPTIMER_0 EVT_PERIODIC_0
|
||||
@@ -22,23 +24,29 @@ static void headstage_gptimer_callback(GPTimerCC26XX_Handle handle, GPTimerCC26X
|
||||
#define headstage_gptimer_stop(gptimer_handle) GPTimerCC26XX_stop(gptimer_handle)
|
||||
#define headstage_gptimer_close(gptimer_handle) GPTimerCC26XX_close(gptimer_handle)
|
||||
|
||||
#define headstage_gptimer_open() \
|
||||
do { \
|
||||
GPTimerCC26XX_Params params; \
|
||||
GPTimerCC26XX_Params_init(¶ms); \
|
||||
params.width = GPT_CONFIG_16BIT; \
|
||||
params.mode = GPT_MODE_PERIODIC_DOWN; \
|
||||
params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF; \
|
||||
gptimer_handle_0 = GPTimerCC26XX_open(Board_GPTIMER0A, ¶ms); \
|
||||
gptimer_handle_1 = GPTimerCC26XX_open(Board_GPTIMER1A, ¶ms); \
|
||||
gptimer_handle_2 = GPTimerCC26XX_open(Board_GPTIMER2A, ¶ms); \
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle_0, 0xFFFFFF); \
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle_1, 0xFFFFFF); \
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle_2, 0xFFFFFF); \
|
||||
GPTimerCC26XX_registerInterrupt(gptimer_handle_0, headstage_gptimer_callback, GPT_INT_TIMEOUT); \
|
||||
GPTimerCC26XX_registerInterrupt(gptimer_handle_1, headstage_gptimer_callback, GPT_INT_TIMEOUT); \
|
||||
GPTimerCC26XX_registerInterrupt(gptimer_handle_2, headstage_gptimer_callback, GPT_INT_TIMEOUT); \
|
||||
} while (0)
|
||||
static void headstage_gptimer_open() {
|
||||
// improve timer accuracy
|
||||
// Power_setDependency(XOSC_HF);
|
||||
|
||||
GPTimerCC26XX_Params params;
|
||||
GPTimerCC26XX_Params_init(¶ms);
|
||||
|
||||
params.width = GPT_CONFIG_16BIT;
|
||||
params.mode = GPT_MODE_PERIODIC_DOWN;
|
||||
params.debugStallMode = GPTimerCC26XX_DEBUG_STALL_OFF;
|
||||
|
||||
gptimer_handle_0 = GPTimerCC26XX_open(Board_GPTIMER0A, ¶ms);
|
||||
gptimer_handle_1 = GPTimerCC26XX_open(Board_GPTIMER1A, ¶ms);
|
||||
gptimer_handle_2 = GPTimerCC26XX_open(Board_GPTIMER2A, ¶ms);
|
||||
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle_0, 0xFFFFFF);
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle_1, 0xFFFFFF);
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle_2, 0xFFFFFF);
|
||||
|
||||
GPTimerCC26XX_registerInterrupt(gptimer_handle_0, headstage_gptimer_callback, GPT_INT_TIMEOUT);
|
||||
GPTimerCC26XX_registerInterrupt(gptimer_handle_1, headstage_gptimer_callback, GPT_INT_TIMEOUT);
|
||||
GPTimerCC26XX_registerInterrupt(gptimer_handle_2, headstage_gptimer_callback, GPT_INT_TIMEOUT);
|
||||
}
|
||||
|
||||
#define headstage_gptimer_set_frequency(gptimer_handle, frequency) \
|
||||
do { \
|
||||
@@ -50,4 +58,13 @@ static void headstage_gptimer_callback(GPTimerCC26XX_Handle handle, GPTimerCC26X
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle, _load); \
|
||||
} while (0)
|
||||
|
||||
#define headstage_gptimer_set_timeout(gptimer_handle, timeout_us) \
|
||||
do { \
|
||||
Types_FreqHz _cpu_freq; \
|
||||
BIOS_getCpuFreq(&_cpu_freq); \
|
||||
GPTimerCC26XX_Value _load = (timeout_us)*_cpu_freq.lo / 1000000 - 1; \
|
||||
_load = (_load < 0xFFFF) ? _load : ((0xFA0000 | (_load / 250)) - 1); \
|
||||
GPTimerCC26XX_setLoadValue(gptimer_handle, _load); \
|
||||
} while (0)
|
||||
|
||||
#endif // HEADSTAGE_GPTIMER_H
|
||||
+1
@@ -22,6 +22,7 @@ static PIN_Config headstage_pin_configuration[] = { //
|
||||
PIN_POL1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
|
||||
PIN_POL0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
|
||||
PIN_PON0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
|
||||
PIN_TPS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL,
|
||||
|
||||
//
|
||||
PIN_TERMINATE};
|
||||
|
||||
+39
-62
@@ -146,6 +146,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
#include <xdc/std.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@@ -158,14 +159,13 @@ extern "C" {
|
||||
#include <driverlib/ioc.h>
|
||||
#include <driverlib/timer.h>
|
||||
#include <inc/hw_gpt.h>
|
||||
|
||||
// clang-format on
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
* Definitions for specifying the GPTimer configuration (width)
|
||||
*/
|
||||
typedef enum GPTimerCC26XX_Width
|
||||
{
|
||||
typedef enum GPTimerCC26XX_Width {
|
||||
GPT_CONFIG_32BIT = GPT_CFG_CFG_32BIT_TIMER,
|
||||
GPT_CONFIG_16BIT = GPT_CFG_CFG_16BIT_TIMER,
|
||||
} GPTimerCC26XX_Width;
|
||||
@@ -178,29 +178,22 @@ typedef enum GPTimerCC26XX_Width
|
||||
* also updating driver.
|
||||
*
|
||||
*/
|
||||
typedef enum GPTimerCC26XX_Mode
|
||||
{
|
||||
typedef enum GPTimerCC26XX_Mode {
|
||||
/* One shot mode counting upwards */
|
||||
GPT_MODE_ONESHOT_UP = GPT_TAMR_TAMR_ONE_SHOT | GPT_TAMR_TACDIR_UP | \
|
||||
GPT_TAMR_TAMIE,
|
||||
/* Periodic mode counting downwards */
|
||||
GPT_MODE_PERIODIC_DOWN = GPT_TAMR_TAMR_PERIODIC | GPT_TAMR_TACDIR_DOWN | \
|
||||
GPT_TAMR_TAMIE,
|
||||
GPT_MODE_ONESHOT_UP = GPT_TAMR_TAMR_ONE_SHOT | GPT_TAMR_TACDIR_UP | GPT_TAMR_TAMIE,
|
||||
/* One shot mode counting downwards */
|
||||
GPT_MODE_ONESHOT_DOWN = GPT_TAMR_TAMR_ONE_SHOT | GPT_TAMR_TACDIR_DOWN | GPT_TAMR_TAMIE,
|
||||
/* Periodic mode counting upwards */
|
||||
GPT_MODE_PERIODIC_UP = GPT_TAMR_TAMR_PERIODIC | GPT_TAMR_TACDIR_UP | \
|
||||
GPT_TAMR_TAMIE,
|
||||
GPT_MODE_PERIODIC_UP = GPT_TAMR_TAMR_PERIODIC | GPT_TAMR_TACDIR_UP | GPT_TAMR_TAMIE,
|
||||
/* Periodic mode counting downwards */
|
||||
GPT_MODE_PERIODIC_DOWN = GPT_TAMR_TAMR_PERIODIC | GPT_TAMR_TACDIR_DOWN | GPT_TAMR_TAMIE,
|
||||
/* Edge count mode counting upwards */
|
||||
GPT_MODE_EDGE_COUNT_UP = GPT_TAMR_TAMR_CAPTURE | GPT_TAMR_TACDIR_UP | \
|
||||
GPT_TAMR_TACM_EDGCNT,
|
||||
GPT_MODE_EDGE_COUNT_UP = GPT_TAMR_TAMR_CAPTURE | GPT_TAMR_TACDIR_UP | GPT_TAMR_TACM_EDGCNT,
|
||||
/* Edge count mode counting upwards */
|
||||
GPT_MODE_EDGE_TIME_UP = GPT_TAMR_TAMR_CAPTURE | GPT_TAMR_TACDIR_UP | \
|
||||
GPT_TAMR_TACM_EDGTIME,
|
||||
GPT_MODE_EDGE_TIME_UP = GPT_TAMR_TAMR_CAPTURE | GPT_TAMR_TACDIR_UP | GPT_TAMR_TACM_EDGTIME,
|
||||
/* PWM mode counting downwards. This specific configuration is used by the
|
||||
PWM2TimerCC26XX driver */
|
||||
GPT_MODE_PWM = GPT_TAMR_TAMR_PERIODIC | GPT_TAMR_TACDIR_UP | \
|
||||
GPT_TAMR_TAAMS_PWM | GPT_TAMR_TACM_EDGCNT | \
|
||||
GPT_TAMR_TAPLO_CCP_ON_TO | GPT_TAMR_TAPWMIE_EN | \
|
||||
GPT_TAMR_TAMRSU_CYCLEUPDATE,
|
||||
GPT_MODE_PWM = GPT_TAMR_TAMR_PERIODIC | GPT_TAMR_TACDIR_UP | GPT_TAMR_TAAMS_PWM | GPT_TAMR_TACM_EDGCNT | GPT_TAMR_TAPLO_CCP_ON_TO | GPT_TAMR_TAPWMIE_EN | GPT_TAMR_TAMRSU_CYCLEUPDATE,
|
||||
} GPTimerCC26XX_Mode;
|
||||
|
||||
/*!
|
||||
@@ -209,16 +202,15 @@ typedef enum GPTimerCC26XX_Mode
|
||||
* arguments should be a bit vector containing these definitions.
|
||||
* See description in Technical Reference
|
||||
*/
|
||||
typedef enum GPTimerCC26XX_Interrupt
|
||||
{
|
||||
GPT_INT_TIMEOUT = 1 << 0,
|
||||
GPT_INT_CAPTURE_MATCH = 1 << 1,
|
||||
GPT_INT_CAPTURE = 1 << 2,
|
||||
GPT_INT_MATCH = 1 << 3,
|
||||
typedef enum GPTimerCC26XX_Interrupt {
|
||||
GPT_INT_TIMEOUT = 1 << 0,
|
||||
GPT_INT_CAPTURE_MATCH = 1 << 1,
|
||||
GPT_INT_CAPTURE = 1 << 2,
|
||||
GPT_INT_MATCH = 1 << 3,
|
||||
} GPTimerCC26XX_Interrupt;
|
||||
|
||||
/* Number of entries in GPTimerCC26XX_Interrupt */
|
||||
#define GPT_NUM_INTS 4
|
||||
#define GPT_NUM_INTS 4
|
||||
|
||||
/*!
|
||||
* @brief
|
||||
@@ -226,8 +218,7 @@ typedef enum GPTimerCC26XX_Interrupt
|
||||
* Used in GPTimer configuration structure GPTimerCC26XX_config to
|
||||
* configure the corresponding timer unit.
|
||||
*/
|
||||
typedef enum GPTimerCC26XX_Part
|
||||
{
|
||||
typedef enum GPTimerCC26XX_Part {
|
||||
GPT_A = 0,
|
||||
GPT_B,
|
||||
GPT_PARTS_COUNT,
|
||||
@@ -241,8 +232,7 @@ typedef enum GPTimerCC26XX_Part
|
||||
* @sa PINCC26XX_setMux
|
||||
* @sa GPTimerCC26XX_getPinMux
|
||||
*/
|
||||
typedef enum GPTimerCC26XX_PinMux
|
||||
{
|
||||
typedef enum GPTimerCC26XX_PinMux {
|
||||
GPT_PIN_0A = IOC_PORT_MCU_PORT_EVENT0,
|
||||
GPT_PIN_0B = IOC_PORT_MCU_PORT_EVENT1,
|
||||
GPT_PIN_1A = IOC_PORT_MCU_PORT_EVENT2,
|
||||
@@ -257,8 +247,7 @@ typedef enum GPTimerCC26XX_PinMux
|
||||
* @brief
|
||||
* Definitions for controlling timer debug stall mode
|
||||
*/
|
||||
typedef enum GPTimerCC26XX_DebugMode
|
||||
{
|
||||
typedef enum GPTimerCC26XX_DebugMode {
|
||||
GPTimerCC26XX_DEBUG_STALL_OFF = 0,
|
||||
GPTimerCC26XX_DEBUG_STALL_ON,
|
||||
} GPTimerCC26XX_DebugMode;
|
||||
@@ -268,28 +257,26 @@ typedef enum GPTimerCC26XX_DebugMode
|
||||
* Definitions for controlling edges used for timer capture.
|
||||
* Used in GPTimer edge-time and edge-count modes.
|
||||
*/
|
||||
typedef enum GPTimerCC26XX_Edge
|
||||
{
|
||||
typedef enum GPTimerCC26XX_Edge {
|
||||
GPTimerCC26XX_POS_EDGE = GPT_CTL_TAEVENT_POS,
|
||||
GPTimerCC26XX_NEG_EDGE = GPT_CTL_TAEVENT_NEG,
|
||||
GPTimerCC26XX_BOTH_EDGES = GPT_CTL_TAEVENT_BOTH,
|
||||
} GPTimerCC26XX_Edge;
|
||||
|
||||
|
||||
/* Forward declaration of GPTimer configuration */
|
||||
typedef const struct GPTimerCC26XX_Config GPTimerCC26XX_Config;
|
||||
typedef const struct GPTimerCC26XX_Config GPTimerCC26XX_Config;
|
||||
|
||||
/* GPTimer handle is pointer to configuration structure */
|
||||
typedef GPTimerCC26XX_Config * GPTimerCC26XX_Handle;
|
||||
typedef GPTimerCC26XX_Config *GPTimerCC26XX_Handle;
|
||||
|
||||
/* Interrupt bit vector. See GPTimerCC26XX_Interrupt for available interrupts */
|
||||
typedef uint16_t GPTimerCC26XX_IntMask;
|
||||
typedef uint16_t GPTimerCC26XX_IntMask;
|
||||
|
||||
/* Timer value */
|
||||
typedef uint32_t GPTimerCC26XX_Value;
|
||||
typedef uint32_t GPTimerCC26XX_Value;
|
||||
|
||||
/* Function prototype for interrupt callbacks */
|
||||
typedef void (*GPTimerCC26XX_HwiFxn) (GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask);
|
||||
typedef void (*GPTimerCC26XX_HwiFxn)(GPTimerCC26XX_Handle handle, GPTimerCC26XX_IntMask interruptMask);
|
||||
|
||||
/*!
|
||||
* @brief GPTimer26XX Hardware attributes
|
||||
@@ -311,12 +298,11 @@ typedef void (*GPTimerCC26XX_HwiFxn) (GPTimerCC26XX_Handle handle, GPTimerCC26XX
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct GPTimerCC26XX_HWAttrs
|
||||
{
|
||||
typedef struct GPTimerCC26XX_HWAttrs {
|
||||
/*!< GPTimer peripheral base address */
|
||||
uint32_t baseAddr;
|
||||
/*! GPTimer peripheral interrupt vector */
|
||||
uint8_t intNum;
|
||||
uint8_t intNum;
|
||||
/*! GPTimer peripheral's interrupt priority.
|
||||
The CC26xx uses three of the priority bits,
|
||||
meaning ~0 has the same effect as (7 << 5).
|
||||
@@ -326,11 +312,11 @@ typedef struct GPTimerCC26XX_HWAttrs
|
||||
HWI's with priority 0 ignore the HWI dispatcher to support zero-latency
|
||||
interrupts, thus invalidating the critical sections in this driver.
|
||||
*/
|
||||
uint8_t intPriority;
|
||||
uint8_t intPriority;
|
||||
/*!< GPTimer peripheral's power manager ID */
|
||||
uint8_t powerMngrId;
|
||||
uint8_t powerMngrId;
|
||||
/*! GPTimer half timer unit */
|
||||
GPTimerCC26XX_Part timer;
|
||||
GPTimerCC26XX_Part timer;
|
||||
/*! PIN driver MUX */
|
||||
GPTimerCC26XX_PinMux pinMux;
|
||||
} GPTimerCC26XX_HWAttrs;
|
||||
@@ -349,8 +335,7 @@ typedef struct GPTimerCC26XX_HWAttrs
|
||||
* GPTimerCC26XX_Object gptimerCC26XXObjects[CC2650_GPTIMERCOUNT];
|
||||
* @endcode
|
||||
*/
|
||||
typedef struct GPTimerCC26XX_Object
|
||||
{
|
||||
typedef struct GPTimerCC26XX_Object {
|
||||
GPTimerCC26XX_Width width; /*!< Timer width configuration (16/32bit)*/
|
||||
bool isOpen[GPT_PARTS_COUNT]; /*!< Object is opened flag */
|
||||
Hwi_Struct hwi[GPT_PARTS_COUNT]; /*!< Hardware interrupt struct */
|
||||
@@ -358,7 +343,6 @@ typedef struct GPTimerCC26XX_Object
|
||||
volatile bool powerConstraint[GPT_PARTS_COUNT]; /*!< Standby power constraint flag */
|
||||
} GPTimerCC26XX_Object;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief GPTimer Global configuration
|
||||
*
|
||||
@@ -379,11 +363,10 @@ typedef struct GPTimerCC26XX_Object
|
||||
* };
|
||||
* @endcode
|
||||
*/
|
||||
struct GPTimerCC26XX_Config
|
||||
{
|
||||
GPTimerCC26XX_Object *object;
|
||||
struct GPTimerCC26XX_Config {
|
||||
GPTimerCC26XX_Object * object;
|
||||
const GPTimerCC26XX_HWAttrs *hwAttrs;
|
||||
GPTimerCC26XX_Part timerPart;
|
||||
GPTimerCC26XX_Part timerPart;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -394,14 +377,12 @@ struct GPTimerCC26XX_Config
|
||||
*
|
||||
* @sa GPTimerCC26XX_Params_init()
|
||||
*/
|
||||
typedef struct GPTimerCC26XX_Params
|
||||
{
|
||||
typedef struct GPTimerCC26XX_Params {
|
||||
GPTimerCC26XX_Width width; /*!< Timer configuration (32/16-bit) */
|
||||
GPTimerCC26XX_Mode mode; /*!< Timer mode */
|
||||
GPTimerCC26XX_DebugMode debugStallMode; /*!< Timer debug stall mode */
|
||||
} GPTimerCC26XX_Params;
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Function to initialize the GPTimerCC26XX_Params struct to
|
||||
* its default values
|
||||
@@ -499,7 +480,6 @@ extern void GPTimerCC26XX_setLoadValue(GPTimerCC26XX_Handle handle, GPTimerCC26X
|
||||
*/
|
||||
extern void GPTimerCC26XX_setMatchValue(GPTimerCC26XX_Handle handle, GPTimerCC26XX_Value matchValue);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Function to set which input edge the GPTimer capture should
|
||||
* use. Applies to edge-count and edge-time modes
|
||||
@@ -546,7 +526,6 @@ extern GPTimerCC26XX_Value GPTimerCC26XX_getFreeRunValue(GPTimerCC26XX_Handle ha
|
||||
*/
|
||||
extern GPTimerCC26XX_Value GPTimerCC26XX_getValue(GPTimerCC26XX_Handle handle);
|
||||
|
||||
|
||||
/*!
|
||||
* @brief Function to register a CPU interrupt for a given timer handle and
|
||||
* enable a set of timer interrupt sources. The interrupt to the CPU
|
||||
@@ -648,12 +627,10 @@ extern void GPTimerCC26XX_configureDebugStall(GPTimerCC26XX_Handle handle, GPTim
|
||||
*
|
||||
* @sa GPTimerCC26XX_open
|
||||
*/
|
||||
static inline GPTimerCC26XX_PinMux GPTimerCC26XX_getPinMux(GPTimerCC26XX_Handle handle)
|
||||
{
|
||||
static inline GPTimerCC26XX_PinMux GPTimerCC26XX_getPinMux(GPTimerCC26XX_Handle handle) {
|
||||
return handle->hwAttrs->pinMux;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user