case avr_timer_com_clear: // clear on compare match => set on tov
avr_raise_irq(irq, 1);
break;
- case avr_timer_com_set: //set on compare match => clear on tov
+ case avr_timer_com_set: // set on compare match => clear on tov
avr_raise_irq(irq, 0);
break;
}
float fc = clock / (float)(ocr+1);
p->comp[compi].comp_cycles = 0;
- // printf("%s-%c clock %d top %d OCR%c %d\n", __FUNCTION__, p->name, clock, top, 'A'+compi, ocr);
+ if (p->trace & (avr_timer_trace_compa << compi))
+ printf("%s-%c clock %d top %d OCR%c %d\n", __FUNCTION__, p->name, clock, top, 'A'+compi, ocr);
if (ocr && ocr <= top) {
p->comp[compi].comp_cycles = frequency / fc; // avr_hz_to_cycles(p->io.avr, fa);
- AVR_LOG(p->io.avr, LOG_TRACE, "TIMER: %s-%c %c %.2fHz = %d cycles\n",
+// AVR_LOG(p->io.avr, LOG_TRACE,
+ if (p->trace & (avr_timer_trace_compa << compi)) printf(
+ "TIMER: %s-%c %c %.2fHz = %d cycles\n",
__FUNCTION__, p->name,
'A'+compi, fc, (int)p->comp[compi].comp_cycles);
}
avr_raise_interrupt(avr, &p->icr);
}
+static int
+avr_timer_ioctl(
+ avr_io_t * port,
+ uint32_t ctl,
+ void * io_param)
+{
+ avr_timer_t * p = (avr_timer_t *)port;
+ int res = -1;
+
+ /* Allow setting individual trace flags */
+ if (ctl == AVR_IOCTL_TIMER_SET_TRACE(p->name)) {
+ p->trace = *((uint32_t*)io_param);
+ res = 0;
+ }
+
+ return res;
+}
+
static void
avr_timer_reset(
avr_io_t * port)
static avr_io_t _io = {
.kind = "timer",
- .reset = avr_timer_reset,
.irq_names = irq_names,
+ .reset = avr_timer_reset,
+ .ioctl = avr_timer_ioctl,
};
void
// Get the internal IRQ corresponding to the INT
#define AVR_IOCTL_TIMER_GETIRQ(_name) AVR_IOCTL_DEF('t','m','r',(_name))
+// add timer number/name (character) to set tracing flags
+#define AVR_IOCTL_TIMER_SET_TRACE(_number) AVR_IOCTL_DEF('t','m','t',(_number))
+
// Waveform generation modes
enum {
avr_timer_wgm_none = 0, // invalid mode
avr_timer_wgm_reg_ocra,
avr_timer_wgm_reg_icr,
};
+
typedef struct avr_timer_wgm_t {
uint32_t top: 8, bottom: 8, size : 8, kind : 8;
} avr_timer_wgm_t;
avr_io_addr_t r_ocrh; // comparator register hi byte
avr_regbit_t com; // comparator output mode registers
avr_regbit_t com_pin; // where comparator output is connected
- uint64_t comp_cycles;
+ uint64_t comp_cycles;
} avr_timer_comp_t, *avr_timer_comp_p;
+enum {
+ avr_timer_trace_ocr = (1 << 0),
+ avr_timer_trace_tcnt = (1 << 1),
+
+ avr_timer_trace_compa = (1 << 8),
+ avr_timer_trace_compb = (1 << 9),
+ avr_timer_trace_compc = (1 << 10),
+};
+
typedef struct avr_timer_t {
- avr_io_t io;
- char name;
+ avr_io_t io;
+ char name;
+ uint32_t trace; // debug trace
avr_regbit_t disabled; // bit in the PRR
avr_regbit_t wgm[4];
avr_timer_wgm_t wgm_op[16];
avr_timer_wgm_t mode;
- int wgm_op_mode_kind;
- uint32_t wgm_op_mode_size;
+ int wgm_op_mode_kind;
+ uint32_t wgm_op_mode_size;
avr_regbit_t as2; // asynchronous clock 32khz
avr_regbit_t cs[4];
- uint8_t cs_div[16];
- uint32_t cs_div_clock;
+ uint8_t cs_div[16];
+ uint32_t cs_div_clock;
avr_regbit_t icp; // input capture pin, to link IRQs
avr_regbit_t ices; // input capture edge select