m0 tc and tcc work
This commit is contained in:
parent
6c3075bec6
commit
8479eef578
|
@ -34,6 +34,9 @@
|
||||||
|
|
||||||
#include "atmel_start_pins.h"
|
#include "atmel_start_pins.h"
|
||||||
#include "hal/utils/include/utils_repeat_macro.h"
|
#include "hal/utils/include/utils_repeat_macro.h"
|
||||||
|
#ifdef SAMD21
|
||||||
|
#include "hpl/gclk/hpl_gclk_base.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "samd21_pins.h"
|
#include "samd21_pins.h"
|
||||||
|
|
||||||
|
@ -53,8 +56,16 @@ const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024};
|
||||||
#ifdef SAMD21
|
#ifdef SAMD21
|
||||||
uint8_t tcc_channels[3] = {0xf0, 0xfc, 0xfc};
|
uint8_t tcc_channels[3] = {0xf0, 0xfc, 0xfc};
|
||||||
const uint8_t tcc_cc_num[3] = {4, 2, 2};
|
const uint8_t tcc_cc_num[3] = {4, 2, 2};
|
||||||
const uint8_t tc_gclk_ids[] = {};
|
const uint8_t tc_gclk_ids[TC_INST_NUM] = {TC3_GCLK_ID,
|
||||||
const uint8_t tc_gclk_ids[5] = {TC3_GCLK_ID, TC4_GCLK_ID, TC5_GCLK_ID, TC6_GCLK_ID, TC7_GCLK_ID};
|
TC4_GCLK_ID,
|
||||||
|
TC5_GCLK_ID,
|
||||||
|
#ifdef TC6_GCLK_ID
|
||||||
|
, TC6_GCLK_ID
|
||||||
|
#endif
|
||||||
|
#ifdef TC7_GCLK_ID
|
||||||
|
, TC7_GCLK_ID
|
||||||
|
#endif
|
||||||
|
};
|
||||||
const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID};
|
const uint8_t tcc_gclk_ids[3] = {TCC0_GCLK_ID, TCC1_GCLK_ID, TCC2_GCLK_ID};
|
||||||
#endif
|
#endif
|
||||||
#ifdef SAMD51
|
#ifdef SAMD51
|
||||||
|
@ -120,9 +131,16 @@ static uint8_t tcc_channel(const pin_timer_t* t) {
|
||||||
|
|
||||||
static void tc_set_enable(Tc* tc, bool enable) {
|
static void tc_set_enable(Tc* tc, bool enable) {
|
||||||
tc->COUNT16.CTRLA.bit.ENABLE = enable;
|
tc->COUNT16.CTRLA.bit.ENABLE = enable;
|
||||||
|
#ifdef SAMD21
|
||||||
|
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {
|
||||||
|
/* Wait for sync */
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef SAMD51
|
||||||
while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) {
|
while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) {
|
||||||
/* Wait for sync */
|
/* Wait for sync */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tcc_set_enable(Tcc* tcc, bool enable) {
|
static void tcc_set_enable(Tcc* tcc, bool enable) {
|
||||||
|
@ -132,6 +150,15 @@ static void tcc_set_enable(Tcc* tcc, bool enable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tc_wait_for_sync(Tc* tc) {
|
||||||
|
#ifdef SAMD21
|
||||||
|
while (tc->COUNT16.STATUS.bit.SYNCBUSY != 0) {}
|
||||||
|
#endif
|
||||||
|
#ifdef SAMD51
|
||||||
|
while (tc->COUNT16.SYNCBUSY.reg != 0) {}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool channel_ok(const pin_timer_t* t) {
|
bool channel_ok(const pin_timer_t* t) {
|
||||||
uint8_t channel_bit = 1 << tcc_channel(t);
|
uint8_t channel_bit = 1 << tcc_channel(t);
|
||||||
return (!t->is_tc && ((tcc_channels[t->index] & channel_bit) == 0)) ||
|
return (!t->is_tc && ((tcc_channels[t->index] & channel_bit) == 0)) ||
|
||||||
|
@ -381,9 +408,7 @@ void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
|
||||||
Tc* tc = tc_insts[t->index];
|
Tc* tc = tc_insts[t->index];
|
||||||
tc_set_enable(tc, false);
|
tc_set_enable(tc, false);
|
||||||
tc->COUNT16.CTRLA.bit.SWRST = true;
|
tc->COUNT16.CTRLA.bit.SWRST = true;
|
||||||
while (tc->COUNT16.SYNCBUSY.bit.SWRST != 0) {
|
tc_wait_for_sync(tc);
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
tcc_refcount[t->index]--;
|
tcc_refcount[t->index]--;
|
||||||
tcc_channels[t->index] &= ~(1 << tcc_channel(t));
|
tcc_channels[t->index] &= ~(1 << tcc_channel(t));
|
||||||
|
@ -422,7 +447,12 @@ extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self,
|
||||||
while ((tcc->SYNCBUSY.vec.CC & (1 << channel)) != 0) {
|
while ((tcc->SYNCBUSY.vec.CC & (1 << channel)) != 0) {
|
||||||
// Wait for a previous value to be written.
|
// Wait for a previous value to be written.
|
||||||
}
|
}
|
||||||
|
#ifdef SAMD21
|
||||||
|
tcc->CCB[channel].reg = adjusted_duty;
|
||||||
|
#endif
|
||||||
|
#ifdef SAMD51
|
||||||
tcc->CCBUF[channel].reg = adjusted_duty;
|
tcc->CCBUF[channel].reg = adjusted_duty;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,9 +460,7 @@ uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
|
||||||
const pin_timer_t* t = self->timer;
|
const pin_timer_t* t = self->timer;
|
||||||
if (t->is_tc) {
|
if (t->is_tc) {
|
||||||
Tc* tc = tc_insts[t->index];
|
Tc* tc = tc_insts[t->index];
|
||||||
while (tc->COUNT16.SYNCBUSY.reg != 0) {
|
tc_wait_for_sync(tc);
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
uint16_t cv = tc->COUNT16.CC[t->wave_output].reg;
|
uint16_t cv = tc->COUNT16.CC[t->wave_output].reg;
|
||||||
return cv * 0xffff / tc_periods[t->index];
|
return cv * 0xffff / tc_periods[t->index];
|
||||||
} else {
|
} else {
|
||||||
|
@ -487,39 +515,38 @@ void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self,
|
||||||
Tc* tc = tc_insts[t->index];
|
Tc* tc = tc_insts[t->index];
|
||||||
uint8_t old_divisor = tc->COUNT16.CTRLA.bit.PRESCALER;
|
uint8_t old_divisor = tc->COUNT16.CTRLA.bit.PRESCALER;
|
||||||
if (new_divisor != old_divisor) {
|
if (new_divisor != old_divisor) {
|
||||||
tc->COUNT16.CTRLA.bit.ENABLE = false;
|
tc_set_enable(tc, false);
|
||||||
while (tc->COUNT16.SYNCBUSY.bit.ENABLE != 0) {
|
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
tc->COUNT16.CTRLA.bit.PRESCALER = new_divisor;
|
tc->COUNT16.CTRLA.bit.PRESCALER = new_divisor;
|
||||||
tc->COUNT16.CTRLA.bit.ENABLE = true;
|
tc_set_enable(tc, true);
|
||||||
}
|
}
|
||||||
tc_periods[t->index] = new_top;
|
tc_periods[t->index] = new_top;
|
||||||
while (tc->COUNT16.SYNCBUSY.reg != 0) {
|
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
#ifdef SAMD21
|
#ifdef SAMD21
|
||||||
tc->COUNT16.CC[0].reg = new_top;
|
tc->COUNT16.CC[0].reg = new_top;
|
||||||
#endif
|
#endif
|
||||||
#ifdef SAMD51
|
#ifdef SAMD51
|
||||||
|
while (tc->COUNT16.SYNCBUSY.reg != 0) {
|
||||||
|
/* Wait for sync */
|
||||||
|
}
|
||||||
tc->COUNT16.CCBUF[0].reg = new_top;
|
tc->COUNT16.CCBUF[0].reg = new_top;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
Tcc* tcc = tcc_insts[t->index];
|
Tcc* tcc = tcc_insts[t->index];
|
||||||
uint8_t old_divisor = tcc->CTRLA.bit.PRESCALER;
|
uint8_t old_divisor = tcc->CTRLA.bit.PRESCALER;
|
||||||
if (new_divisor != old_divisor) {
|
if (new_divisor != old_divisor) {
|
||||||
tcc->CTRLA.bit.ENABLE = false;
|
tcc_set_enable(tcc, false);
|
||||||
while (tcc->SYNCBUSY.bit.ENABLE != 0) {
|
|
||||||
/* Wait for sync */
|
|
||||||
}
|
|
||||||
tcc->CTRLA.bit.PRESCALER = new_divisor;
|
tcc->CTRLA.bit.PRESCALER = new_divisor;
|
||||||
tcc->CTRLA.bit.ENABLE = true;
|
tcc_set_enable(tcc, true);
|
||||||
}
|
}
|
||||||
tcc_periods[t->index] = new_top;
|
tcc_periods[t->index] = new_top;
|
||||||
|
#ifdef SAMD21
|
||||||
|
tcc->PERB.bit.PERB = new_top;
|
||||||
|
#endif
|
||||||
|
#ifdef SAMD51
|
||||||
while (tcc->SYNCBUSY.reg != 0) {
|
while (tcc->SYNCBUSY.reg != 0) {
|
||||||
/* Wait for sync */
|
/* Wait for sync */
|
||||||
}
|
}
|
||||||
tcc->PERBUF.bit.PERBUF = new_top;
|
tcc->PERBUF.bit.PERBUF = new_top;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
common_hal_pulseio_pwmout_set_duty_cycle(self, old_duty);
|
common_hal_pulseio_pwmout_set_duty_cycle(self, old_duty);
|
||||||
|
|
|
@ -39,12 +39,12 @@
|
||||||
|
|
||||||
#include "tick.h"
|
#include "tick.h"
|
||||||
|
|
||||||
static pulseio_pulsein_obj_t *active_pulseins[EIC_NUMBER_OF_INTERRUPTS];
|
static pulseio_pulsein_obj_t *active_pulseins[EIC_EXTINT_NUM];
|
||||||
static uint64_t last_ms[EIC_NUMBER_OF_INTERRUPTS];
|
static uint64_t last_ms[EIC_EXTINT_NUM];
|
||||||
static uint16_t last_us[EIC_NUMBER_OF_INTERRUPTS];
|
static uint16_t last_us[EIC_EXTINT_NUM];
|
||||||
|
|
||||||
void pulsein_reset(void) {
|
void pulsein_reset(void) {
|
||||||
for (int i = 0; i < EIC_NUMBER_OF_INTERRUPTS; i++) {
|
for (int i = 0; i < EIC_EXTINT_NUM; i++) {
|
||||||
if (active_pulseins[i] != NULL) {
|
if (active_pulseins[i] != NULL) {
|
||||||
//extint_chan_disable_callback(i, EXTINT_CALLBACK_TYPE_DETECT);
|
//extint_chan_disable_callback(i, EXTINT_CALLBACK_TYPE_DETECT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,7 +386,11 @@ PIN(PA22, EXTINT_CHANNEL(6), NO_ADC, NO_TOUCH,
|
||||||
SERCOM(3, 0),
|
SERCOM(3, 0),
|
||||||
#ifdef SERCOM5
|
#ifdef SERCOM5
|
||||||
SERCOM(5, 0),
|
SERCOM(5, 0),
|
||||||
#els0, 4));
|
#else
|
||||||
|
NO_SERCOM,
|
||||||
|
#endif
|
||||||
|
TC(4, 0),
|
||||||
|
TCC(0, 4));
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIN_PA23
|
#ifdef PIN_PA23
|
||||||
PIN(PA23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH,
|
PIN(PA23, EXTINT_CHANNEL(7), NO_ADC, NO_TOUCH,
|
||||||
|
|
Loading…
Reference in New Issue