[simio] support Timer_B
Timer_B is identical to Timer_A with the following exceptions. 1. The SCCI bit function is not implemented in Timer_B. 2. The interrupt vector word of TBIFG is different than TAIFG one. 3. The length of Timer_B is programable to be 8, 10, 12, or 16 bits. 4. Timer_B TBCCRx registers can be double-buffered. 5. Timer_B TBCCRx registers can be grouped. This change implements 1, 2, and 3. Double-buffering and grouping TBCCRx will be following.
This commit is contained in:
parent
8db02ae3d4
commit
f9f897e95e
|
@ -36,13 +36,18 @@
|
|||
#define TACLR 0x0004 /* Timer A counter clear */
|
||||
#define TAIE 0x0002 /* Timer A counter interrupt enable */
|
||||
#define TAIFG 0x0001 /* Timer A counter interrupt flag */
|
||||
/* TBCTL bits */
|
||||
#define TBCLGRP1 0x4000 /* Timer B Compare latch load group 1 */
|
||||
#define TBCLGRP0 0x2000 /* Timer B Compare latch load group 0 */
|
||||
#define CNTL1 0x1000 /* Timer B Counter length 1 */
|
||||
#define CNTL0 0x0800 /* Timer B Counter length 0 */
|
||||
|
||||
/* TACCTLx flags (taken from mspgcc) */
|
||||
#define CM1 0x8000 /* Capture mode 1 */
|
||||
#define CM0 0x4000 /* Capture mode 0 */
|
||||
#define CCIS1 0x2000 /* Capture input select 1 */
|
||||
#define CCIS0 0x1000 /* Capture input select 0 */
|
||||
#define SCS 0x0800 /* Capture sychronize */
|
||||
#define SCS 0x0800 /* Capture synchronize */
|
||||
#define SCCI 0x0400 /* Latched capture signal (read) */
|
||||
#define CAP 0x0100 /* Capture mode: 1 /Compare mode : 0 */
|
||||
#define OUTMOD2 0x0080 /* Output mode 2 */
|
||||
|
@ -53,9 +58,20 @@
|
|||
/* #define OUT 0x0004 PWM Output signal if output mode 0 */
|
||||
#define COV 0x0002 /* Capture/compare overflow flag */
|
||||
#define CCIFG 0x0001 /* Capture/compare interrupt flag */
|
||||
/* TBCCTLx flags */
|
||||
#define CLLD1 0x0400 /* Compare latch load source 1 */
|
||||
#define CLLD0 0x0200 /* Compare latch load source 0 */
|
||||
/* Timer IV words */
|
||||
#define TAIV_TAIFG 0x000A /* Interrupt vector word for TAIFG */
|
||||
#define TBIV_TBIFG 0x000E /* Interrupt vector word for TBIFG */
|
||||
|
||||
#define MAX_CCRS 7
|
||||
|
||||
typedef enum {
|
||||
TIMER_TYPE_A,
|
||||
TIMER_TYPE_B,
|
||||
} timer_type_t;
|
||||
|
||||
struct timer {
|
||||
struct simio_device base;
|
||||
|
||||
|
@ -67,6 +83,7 @@ struct timer {
|
|||
address_t iv_addr;
|
||||
int irq0;
|
||||
int irq1;
|
||||
timer_type_t timer_type;
|
||||
|
||||
/* IO registers */
|
||||
uint16_t tactl;
|
||||
|
@ -110,6 +127,7 @@ static struct simio_device *timer_create(char **arg_text)
|
|||
tr->iv_addr = 0x12e;
|
||||
tr->irq0 = 9;
|
||||
tr->irq1 = 8;
|
||||
tr->timer_type = TIMER_TYPE_A;
|
||||
|
||||
return (struct simio_device *)tr;
|
||||
}
|
||||
|
@ -149,6 +167,28 @@ static int config_addr(address_t *addr, char **arg_text)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int config_type(timer_type_t *timer_type, char **arg_text)
|
||||
{
|
||||
char *text = get_arg(arg_text);
|
||||
|
||||
if (!text) {
|
||||
printc_err("timer: config: expected type\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!strcasecmp(text, "A")) {
|
||||
*timer_type = TIMER_TYPE_A;
|
||||
return 0;
|
||||
}
|
||||
if (!strcasecmp(text, "B")) {
|
||||
*timer_type = TIMER_TYPE_B;
|
||||
return 0;
|
||||
}
|
||||
|
||||
printc_err("timer: can't parse type: %s\n", text);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int config_irq(int *irq, char **arg_text)
|
||||
{
|
||||
char *text = get_arg(arg_text);
|
||||
|
@ -237,6 +277,8 @@ static int timer_config(struct simio_device *dev,
|
|||
|
||||
if (!strcasecmp(param, "base"))
|
||||
return config_addr(&tr->base_addr, arg_text);
|
||||
if (!strcasecmp(param, "type"))
|
||||
return config_type(&tr->timer_type, arg_text);
|
||||
if (!strcasecmp(param, "iv"))
|
||||
return config_addr(&tr->iv_addr, arg_text);
|
||||
if (!strcasecmp(param, "irq0"))
|
||||
|
@ -266,7 +308,8 @@ static uint16_t calc_iv(struct timer *tr, int update)
|
|||
if ((tr->tactl & (TAIFG | TAIE)) == (TAIFG | TAIE)) {
|
||||
if (update)
|
||||
tr->tactl &= ~TAIFG;
|
||||
return 0xa;
|
||||
return (tr->timer_type == TIMER_TYPE_A) ?
|
||||
TAIV_TAIFG : TBIV_TBIFG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -276,24 +319,44 @@ static int timer_info(struct simio_device *dev)
|
|||
{
|
||||
struct timer *tr = (struct timer *)dev;
|
||||
int i;
|
||||
char timer_type = (tr->timer_type == TIMER_TYPE_A) ? 'A' : 'B';
|
||||
|
||||
printc("Base address: 0x%04x\n", tr->base_addr);
|
||||
printc("IV address: 0x%04x\n", tr->iv_addr);
|
||||
printc("IRQ0: %d\n", tr->irq0);
|
||||
printc("IRQ1: %d\n", tr->irq1);
|
||||
printc("\n");
|
||||
printc("TACTL: 0x%04x\n", tr->tactl);
|
||||
printc("TAR: 0x%04x\n", tr->tar);
|
||||
printc("TAIV: 0x%02x\n", calc_iv(tr, 0));
|
||||
printc("T%cCTL: 0x%04x\n", timer_type, tr->tactl);
|
||||
printc("T%cR: 0x%04x\n", timer_type, tr->tar);
|
||||
printc("T%cIV: 0x%02x\n", timer_type, calc_iv(tr, 0));
|
||||
printc("\n");
|
||||
|
||||
for (i = 0; i < tr->size; i++)
|
||||
printc("Channel %2d, TACCTL = 0x%04x, TACCR = 0x%04x\n",
|
||||
i, tr->ctls[i], tr->ccrs[i]);
|
||||
for (i = 0; i < tr->size; i++) {
|
||||
printc("T%cCCTL%d = 0x%04x, T%cCCR%d = 0x%04x",
|
||||
timer_type, i, tr->ctls[i], timer_type, i, tr->ccrs[i]);
|
||||
printc("\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint16_t tar_mask(struct timer *tr)
|
||||
{
|
||||
if (tr->timer_type == TIMER_TYPE_B) {
|
||||
switch (tr->tactl & (CNTL1 | CNTL0)) {
|
||||
case 0: /* 16 bits */
|
||||
break;
|
||||
case CNTL0: /* 12 bits */
|
||||
return 0x0fff;
|
||||
case CNTL1: /* 10 bits */
|
||||
return 0x03ff;
|
||||
case CNTL1 | CNTL0: /* 8 bits */
|
||||
return 0x00ff;
|
||||
}
|
||||
}
|
||||
return 0xffff;
|
||||
}
|
||||
|
||||
static int timer_write(struct simio_device *dev,
|
||||
address_t addr, uint16_t data)
|
||||
{
|
||||
|
@ -308,7 +371,7 @@ static int timer_write(struct simio_device *dev,
|
|||
}
|
||||
|
||||
if (addr == tr->base_addr + 0x10) {
|
||||
tr->tar = data;
|
||||
tr->tar = data & tar_mask(tr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -316,8 +379,13 @@ static int timer_write(struct simio_device *dev,
|
|||
addr < tr->base_addr + (tr->size << 1) + 2) {
|
||||
int index = ((addr & 0xf) - 2) >> 1;
|
||||
uint16_t oldval = tr->ctls[index];
|
||||
uint16_t mask;
|
||||
|
||||
tr->ctls[index] = (data & 0xf9f7) | (oldval & 0x0608);
|
||||
if (tr->timer_type == TIMER_TYPE_A)
|
||||
mask = 0x0608;
|
||||
if (tr->timer_type == TIMER_TYPE_B)
|
||||
mask = 0x0008;
|
||||
tr->ctls[index] = (data & ~mask) | (oldval & mask);
|
||||
/* Check capture initiated by Software */
|
||||
if ((data & (CAP | CCIS1)) == (CAP | CCIS1))
|
||||
trigger_capture(tr, index, oldval & CCI, data & CCIS0);
|
||||
|
@ -409,23 +477,37 @@ static void timer_ack_interrupt(struct simio_device *dev, int irq)
|
|||
/* By design irq1 does not clear CCIFG or TAIFG automatically */
|
||||
}
|
||||
|
||||
static uint16_t tar_increment(struct timer *tr)
|
||||
{
|
||||
tr->tar++;
|
||||
tr->tar &= tar_mask(tr);
|
||||
return tr->tar;
|
||||
}
|
||||
|
||||
static uint16_t tar_decrement(struct timer *tr)
|
||||
{
|
||||
tr->tar--;
|
||||
tr->tar &= tar_mask(tr);
|
||||
return tr->tar;
|
||||
}
|
||||
|
||||
static void tar_step(struct timer *tr)
|
||||
{
|
||||
switch ((tr->tactl >> 4) & 3) {
|
||||
case 0: break;
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
if (tr->tar == tr->ccrs[0] || tr->go_down) {
|
||||
tr->tar = 0;
|
||||
tr->tactl |= TAIFG;
|
||||
tr->go_down = false;
|
||||
} else {
|
||||
tr->tar++;
|
||||
tar_increment(tr);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
tr->tar++;
|
||||
if (!tr->tar)
|
||||
if (tar_increment(tr) == 0)
|
||||
tr->tactl |= TAIFG;
|
||||
break;
|
||||
|
||||
|
@ -436,16 +518,34 @@ static void tar_step(struct timer *tr)
|
|||
tr->go_down = false;
|
||||
|
||||
if (tr->go_down) {
|
||||
tr->tar--;
|
||||
if (!tr->tar)
|
||||
if (tar_decrement(tr) == 0)
|
||||
tr->tactl |= TAIFG;
|
||||
} else {
|
||||
tr->tar++;
|
||||
tar_increment(tr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void comparator_step(struct timer *tr, int index)
|
||||
{
|
||||
if (tr->timer_type == TIMER_TYPE_A) {
|
||||
if (tr->tar == tr->ccrs[index]) {
|
||||
tr->ctls[index] |= CCIFG;
|
||||
if (tr->ctls[index] & CCI)
|
||||
tr->ctls[index] |= SCCI;
|
||||
else
|
||||
tr->ctls[index] &= ~SCCI;
|
||||
}
|
||||
}
|
||||
|
||||
if (tr->timer_type == TIMER_TYPE_B) {
|
||||
if (tr->tar == tr->ccrs[index]) {
|
||||
tr->ctls[index] |= CCIFG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_step(struct simio_device *dev,
|
||||
uint16_t status, const int *clocks)
|
||||
{
|
||||
|
@ -471,16 +571,10 @@ static void timer_step(struct simio_device *dev,
|
|||
for (i = 0; i < pulse_count; i++) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < tr->size; j++)
|
||||
if (!(tr->ctls[j] & CAP) && (tr->tar == tr->ccrs[j])) {
|
||||
if (tr->ctls[j] & CCI)
|
||||
tr->ctls[j] |= SCCI;
|
||||
else
|
||||
tr->ctls[j] &= ~SCCI;
|
||||
|
||||
tr->ctls[j] |= CCIFG;
|
||||
for (j = 0; j < tr->size; j++) {
|
||||
if (!(tr->ctls[j] & CAP))
|
||||
comparator_step(tr, j);
|
||||
}
|
||||
|
||||
tar_step(tr);
|
||||
}
|
||||
}
|
||||
|
@ -488,22 +582,24 @@ static void timer_step(struct simio_device *dev,
|
|||
const struct simio_class simio_timer = {
|
||||
.name = "timer",
|
||||
.help =
|
||||
"This peripheral implements the Timer_A module.\n"
|
||||
"\n"
|
||||
"Constructor arguments: [size]\n"
|
||||
" Specify the number of capture/compare registers.\n"
|
||||
"\n"
|
||||
"Config arguments are:\n"
|
||||
" base <address>\n"
|
||||
" Set the peripheral base address.\n"
|
||||
" irq0 <interrupt>\n"
|
||||
" Set the interrupt vector for CCR0.\n"
|
||||
" irq1 <interrupt>\n"
|
||||
" Set the interrupt vector for CCR1.\n"
|
||||
" iv <address>\n"
|
||||
" Set the interrupt vector register address.\n"
|
||||
" set <channel> <0|1>\n"
|
||||
" Set the capture input value on the given channel.\n",
|
||||
"This peripheral implements the Timer_A and Timer_B module.\n"
|
||||
"\n"
|
||||
"Constructor arguments: [size]\n"
|
||||
" Specify the number of capture/compare registers.\n"
|
||||
"\n"
|
||||
"Config arguments are:\n"
|
||||
" base <address>\n"
|
||||
" Set the peripheral base address.\n"
|
||||
" type <A|B>\n"
|
||||
" Set timer type.\n"
|
||||
" irq0 <interrupt>\n"
|
||||
" Set the interrupt vector for CCR0.\n"
|
||||
" irq1 <interrupt>\n"
|
||||
" Set the interrupt vector for CCR1.\n"
|
||||
" iv <address>\n"
|
||||
" Set the interrupt vector register address.\n"
|
||||
" set <channel> <0|1>\n"
|
||||
" Set the capture input value on the given channel.\n",
|
||||
|
||||
.create = timer_create,
|
||||
.destroy = timer_destroy,
|
||||
|
|
|
@ -71,7 +71,6 @@ static int config_timer(struct simio_device *dev, const char *param,
|
|||
#define TxCCTL(index) (0x02 + (index) * 2)
|
||||
#define TxCCR(index) (0x12 + (index) * 2)
|
||||
#define TxIV_TxIFG(index) ((index) * 2)
|
||||
#define TAIV_TAIFG 0x0a
|
||||
|
||||
static uint16_t read_timer(struct simio_device *dev, int offset)
|
||||
{
|
||||
|
@ -185,6 +184,7 @@ static void test_create_no_option()
|
|||
// Check default values.
|
||||
struct timer *tmr = (struct timer *)dev;
|
||||
assert(tmr->size == 3);
|
||||
assert(tmr->timer_type == TIMER_TYPE_A);
|
||||
assert(tmr->base_addr == 0x0160);
|
||||
assert(tmr->iv_addr == 0x012e);
|
||||
assert(tmr->irq0 == 9);
|
||||
|
@ -226,6 +226,53 @@ static void test_create_with_size_1()
|
|||
assert(dev == NULL);
|
||||
}
|
||||
|
||||
static void test_config_type_default()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
// Default timer type is A.
|
||||
struct timer *tmr = (struct timer *)dev;
|
||||
assert(tmr->timer_type == TIMER_TYPE_A);
|
||||
}
|
||||
|
||||
static void test_config_type_A()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
// Timer can configured as type A.
|
||||
assert(config_timer(dev, "type", "A") == 0);
|
||||
struct timer *tmr = (struct timer *)dev;
|
||||
assert(tmr->timer_type == TIMER_TYPE_A);
|
||||
}
|
||||
|
||||
static void test_config_type_B()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
// Timer can configured as type B.
|
||||
struct timer *tmr = (struct timer *)dev;
|
||||
assert(config_timer(dev, "type", "B") == 0);
|
||||
assert(tmr->timer_type == TIMER_TYPE_B);
|
||||
}
|
||||
|
||||
static void test_config_type_bad()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
struct timer *tmr = (struct timer *)dev;
|
||||
// Timer can't configured other than A/B.
|
||||
assert(config_timer(dev, "type", "bad") != 0);
|
||||
}
|
||||
|
||||
static void test_config_type_empty()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
struct timer *tmr = (struct timer *)dev;
|
||||
// Timer type can't be empty.
|
||||
assert(config_timer(dev, "type", "") != 0);
|
||||
}
|
||||
|
||||
static void test_address_space()
|
||||
{
|
||||
dev = create_timer("7");
|
||||
|
@ -319,7 +366,7 @@ static void test_timer_updown_stop()
|
|||
assert(read_timer(dev, TxR) == 0);
|
||||
}
|
||||
|
||||
static void test_timer_up()
|
||||
static void test_timer_a_up()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
|
@ -348,7 +395,7 @@ static void test_timer_up()
|
|||
assert(check_noirq(dev));
|
||||
}
|
||||
|
||||
static void test_timer_up_change_period()
|
||||
static void test_timer_a_up_change_period()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
|
@ -396,7 +443,7 @@ static void test_timer_up_change_period()
|
|||
assert_not(read_timer(dev, TxCTL) & TAIFG);
|
||||
}
|
||||
|
||||
static void test_timer_updown_change_period()
|
||||
static void test_timer_a_updown_change_period()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
|
@ -657,7 +704,7 @@ static void test_timer_capture_by_signal()
|
|||
assert(read_timer(dev, TxCCR(2)) == 50);
|
||||
}
|
||||
|
||||
static void test_timer_compare()
|
||||
static void test_timer_a_compare()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
|
@ -722,6 +769,142 @@ static void test_timer_compare()
|
|||
assert_not(read_timer(dev, TxCCTL(1)) & SCCI);
|
||||
}
|
||||
|
||||
static void test_timer_b_compare()
|
||||
{
|
||||
dev = create_timer("");
|
||||
config_timer(dev, "type", "B");
|
||||
|
||||
/* Continuous mode, ACLK, interrupt enable, clear */
|
||||
write_timer(dev, TxCTL, MC1 | TASSEL0 | TACLR | TAIE);
|
||||
write_timer(dev, TxR, 0xffff);
|
||||
/* Compare mode, enable interrupts */
|
||||
write_timer(dev, TxCCTL(0), CCIE);
|
||||
write_timer(dev, TxCCR(0), 200);
|
||||
write_timer(dev, TxCCTL(1), CCIE);
|
||||
write_timer(dev, TxCCR(1), 100);
|
||||
write_timer(dev, TxCCTL(2), CCIE);
|
||||
write_timer(dev, TxCCR(2), 200);
|
||||
|
||||
// Timer_B overflow interrupt should happen.
|
||||
step_aclk(dev, 1);
|
||||
assert(check_irq1(dev));
|
||||
// Timer_B overflow vector is 0x0e.
|
||||
assert(TBIV_TBIFG == 0x0e);
|
||||
assert(read_iv(dev) == TBIV_TBIFG);
|
||||
assert(check_noirq(dev));
|
||||
assert(read_timer(dev, TxR) == 0);
|
||||
|
||||
step_aclk(dev, 100);
|
||||
assert(check_noirq(dev));
|
||||
// Set CCI of CCTL[1] to 1.
|
||||
config_timer(dev, "set", "1 1");
|
||||
// Timer_B comparator interrupt should happen.
|
||||
step_aclk(dev, 1);
|
||||
assert(check_irq1(dev));
|
||||
assert(read_timer(dev, TxCCTL(1)) & CCIFG);
|
||||
assert(read_iv(dev) == TxIV_TxIFG(1));
|
||||
assert(check_noirq(dev));
|
||||
assert_not(read_timer(dev, TxCCTL(1)) & CCIFG);
|
||||
|
||||
// Timer_B comparator interrupts should happen.
|
||||
step_aclk(dev, 100);
|
||||
assert(check_irq0(dev));
|
||||
assert(read_timer(dev, TxCCTL(0)) & CCIFG);
|
||||
ack_irq0(dev);
|
||||
assert_not(check_noirq(dev));
|
||||
assert_not(read_timer(dev, TxCCTL(0)) & CCIFG);
|
||||
// Lower priority interrupt.
|
||||
assert(check_irq1(dev));
|
||||
assert(read_timer(dev, TxCCTL(2)) & CCIFG);
|
||||
assert(read_iv(dev) == TxIV_TxIFG(2));
|
||||
assert(check_noirq(dev));
|
||||
assert_not(read_timer(dev, TxCCTL(2)) & CCIFG);
|
||||
|
||||
// Set CCI of CCTL[1] to 0.
|
||||
config_timer(dev, "set", "1 0");
|
||||
write_timer(dev, TxCCR(1), 300);
|
||||
step_aclk(dev, 100);
|
||||
// Timer_B comparator interrupt should happen.
|
||||
assert(check_irq1(dev));
|
||||
assert(read_timer(dev, TxCCTL(1)) & CCIFG);
|
||||
assert(read_iv(dev) == TxIV_TxIFG(1));
|
||||
assert(check_noirq(dev));
|
||||
assert_not(read_timer(dev, TxCCTL(1)) & CCIFG);
|
||||
}
|
||||
|
||||
static void test_timer_capture()
|
||||
{
|
||||
dev = create_timer("");
|
||||
|
||||
/* Continuous mode, ACLK, clear */
|
||||
write_timer(dev, TxCTL, MC1 | TASSEL0 | TACLR);
|
||||
/* Capture mode, enable interrupts */
|
||||
}
|
||||
|
||||
static void test_timer_b_length_8()
|
||||
{
|
||||
dev = create_timer("");
|
||||
config_timer(dev, "type", "B");
|
||||
|
||||
/* Continuous 8 bit, SMCLK, interrupt enable, clear */
|
||||
write_timer(dev, TxCTL, MC1 | CNTL1 | CNTL0 | TACLR | TAIE | TASSEL1);
|
||||
write_timer(dev, TxR, 0x00ff);
|
||||
step_smclk(dev, 2);
|
||||
|
||||
// Timer B can configured as 8 bit length.
|
||||
assert(check_irq1(dev));
|
||||
assert(read_iv(dev) == TBIV_TBIFG);
|
||||
assert(read_timer(dev, TxR) == 1);
|
||||
}
|
||||
|
||||
static void test_timer_b_length_10()
|
||||
{
|
||||
dev = create_timer("");
|
||||
config_timer(dev, "type", "B");
|
||||
|
||||
/* Continuous 10 bit, ACLK, interrupt enable, clear */
|
||||
write_timer(dev, TxCTL, MC1 | CNTL1 | TACLR | TAIE | TASSEL0);
|
||||
write_timer(dev, TxR, 0x03ff);
|
||||
step_aclk(dev, 3);
|
||||
|
||||
// Timer B can configured as 10 bit length.
|
||||
assert(check_irq1(dev));
|
||||
assert(read_iv(dev) == TBIV_TBIFG);
|
||||
assert(read_timer(dev, TxR) == 2);
|
||||
}
|
||||
|
||||
static void test_timer_b_length_12()
|
||||
{
|
||||
dev = create_timer("");
|
||||
config_timer(dev, "type", "B");
|
||||
|
||||
/* Continuous 12 bit, SMCLK, interrupt enable, clear */
|
||||
write_timer(dev, TxCTL, MC1 | CNTL0 | TACLR | TAIE | TASSEL1);
|
||||
write_timer(dev, TxR, 0x0fff);
|
||||
step_smclk(dev, 4);
|
||||
|
||||
// Timer B can configured as 12 bit length.
|
||||
assert(check_irq1(dev));
|
||||
assert(read_iv(dev) == TBIV_TBIFG);
|
||||
assert(read_timer(dev, TxR) == 3);
|
||||
}
|
||||
|
||||
static void test_timer_b_length_16()
|
||||
{
|
||||
dev = create_timer("");
|
||||
config_timer(dev, "type", "B");
|
||||
|
||||
/* Continuous 16 bit, SMCLK, interrupt enable, clear */
|
||||
write_timer(dev, TxCTL, MC1 | TACLR | TAIE | TASSEL1);
|
||||
write_timer(dev, TxR, 0xffff);
|
||||
step_smclk(dev, 5);
|
||||
|
||||
// Timer B can configured as 16 bit length.
|
||||
assert(check_irq1(dev));
|
||||
assert(read_iv(dev) == TBIV_TBIFG);
|
||||
assert(read_timer(dev, TxR) == 4);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Test runner.
|
||||
|
@ -748,16 +931,26 @@ int main(int argc, char **argv)
|
|||
RUN_TEST(test_create_with_size_2);
|
||||
RUN_TEST(test_create_with_size_8);
|
||||
RUN_TEST(test_create_with_size_1);
|
||||
RUN_TEST(test_config_type_default);
|
||||
RUN_TEST(test_config_type_A);
|
||||
RUN_TEST(test_config_type_B);
|
||||
RUN_TEST(test_config_type_bad);
|
||||
RUN_TEST(test_config_type_empty);
|
||||
RUN_TEST(test_address_space);
|
||||
RUN_TEST(test_timer_continuous);
|
||||
RUN_TEST(test_timer_stop);
|
||||
RUN_TEST(test_timer_up_stop);
|
||||
RUN_TEST(test_timer_updown_stop);
|
||||
RUN_TEST(test_timer_up);
|
||||
RUN_TEST(test_timer_up_change_period);
|
||||
RUN_TEST(test_timer_updown_change_period);
|
||||
RUN_TEST(test_timer_a_up);
|
||||
RUN_TEST(test_timer_a_up_change_period);
|
||||
RUN_TEST(test_timer_a_updown_change_period);
|
||||
RUN_TEST(test_timer_divider);
|
||||
RUN_TEST(test_timer_capture_by_software);
|
||||
RUN_TEST(test_timer_capture_by_signal);
|
||||
RUN_TEST(test_timer_compare);
|
||||
RUN_TEST(test_timer_a_compare);
|
||||
RUN_TEST(test_timer_b_compare);
|
||||
RUN_TEST(test_timer_b_length_8);
|
||||
RUN_TEST(test_timer_b_length_10);
|
||||
RUN_TEST(test_timer_b_length_12);
|
||||
RUN_TEST(test_timer_b_length_16);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue