pudding_pac/cdns/
ttc.rs

1#![allow(dead_code)]
2
3use core::ptr;
4
5// TTCレジスタ
6#[repr(C)]
7pub struct Regs {
8    pub clock_control: [u32; 3],
9    pub counter_control: [u32; 3],
10    pub counter_value: [u32; 3],
11    pub interval_counter: [u32; 3],
12    pub match_1_counter: [u32; 3],
13    pub match_2_counter: [u32; 3],
14    pub match_3_counter: [u32; 3],
15    pub interrupt_register: [u32; 3],
16    pub interrupt_enable: [u32; 3],
17    pub event_control_timer: [u32; 3],
18    pub event_register: [u32; 3],
19}
20
21pub enum Timer {
22    Timer1 = 0,
23    Timer2 = 1,
24    Timer3 = 2,
25}
26
27use bitflags::bitflags;
28
29bitflags! {
30    pub struct ClockControl: u32 {
31        const NONE = 0x00;
32        const PRESCALER_ENABLE = 0x01;
33        const CLOCK_SOURCE_EXTERNAL = 0x20;
34        const EXTERNAL_CLOCK_EDGE_NEGATIVE  = 0x40;
35    }
36}
37
38impl ClockControl {
39    pub fn clear(&mut self) {
40        *self.0.bits_mut() = 0;
41    }
42}
43
44bitflags! {
45    pub struct CounterControl: u32 {
46        const NONE = 0;
47        const DISABLE = 0x01;
48        const INTERVAL = 0x02;
49        const DECREMENT = 0x04;
50        const MATCH = 0x08;
51        const RESET = 0x10;
52        const OUTPUT_WAVEFORM_DISABLE = 0x20;
53        const OUTPUT_WAVEFORM_POLARITY = 0x40;
54    }
55}
56
57impl CounterControl {
58    pub fn clear(&mut self) {
59        *self.0.bits_mut() = 0;
60    }
61}
62
63bitflags! {
64    pub struct Interrupt: u32 {
65        const NONE = 0;
66        const INTERVAL = 0x01;
67        const MATCH1 = 0x02;
68        const MATCH2 = 0x04;
69        const MATCH3 = 0x08;
70        const COUNTER_OVERFLOW = 0x10;
71        const EVENT_TIMER_OVERFLOW = 0x20;
72    }
73}
74
75impl Interrupt {
76    pub fn clear(&mut self) {
77        *self.0.bits_mut() = 0;
78    }
79}
80
81bitflags! {
82    pub struct EventTimerControl: u32 {
83        const NONE = 0x00;
84        const ENABLE = 0x01;
85        const LOW_LEVEL = 0x02;
86        const CONTINUES_COUNTING_ON_OVERFLOW = 0x04;
87        const TEST_MODE = 0x08;
88    }
89}
90
91impl EventTimerControl {
92    pub fn clear(&mut self) {
93        *self.0.bits_mut() = 0;
94    }
95}
96
97pub struct Ttc {
98    pub address: usize,
99}
100
101impl Ttc {
102    pub const fn new(address: usize) -> Self {
103        Ttc { address: address }
104    }
105
106    pub fn set_base_address(&mut self, address: usize) {
107        self.address = address;
108    }
109
110    fn take(&self) -> &mut Regs {
111        unsafe { &mut *(self.address as *mut Regs) }
112    }
113
114    pub fn reset(&self, timer: Timer) {
115        let regs = self.take();
116        let timer = timer as usize;
117        unsafe {
118            ptr::write_volatile(&mut regs.counter_control[timer], 0x31); // stop and reset
119                                                                         //          ptr::write_volatile(&mut regs.counter_control[timer], 0x21);  // stop
120            ptr::read_volatile(&mut regs.interrupt_register[timer]);
121        }
122    }
123
124    pub fn set_clock_control(&self, timer: Timer, flags: ClockControl, prescale: u32) {
125        assert_eq!(prescale & !0xf, 0);
126        let regs = self.take();
127        unsafe {
128            ptr::write_volatile(
129                &mut regs.clock_control[timer as usize],
130                flags.bits() | (prescale << 1),
131            );
132        }
133    }
134
135    pub fn set_counter_control(&self, timer: Timer, flags: CounterControl) {
136        let regs = self.take();
137        unsafe {
138            ptr::write_volatile(&mut regs.counter_control[timer as usize], flags.bits());
139        }
140    }
141
142    pub fn get_counter_value(&self, timer: Timer) -> u32 {
143        let regs = self.take();
144        unsafe { ptr::read_volatile(&mut regs.counter_value[timer as usize]) }
145    }
146
147    pub fn set_interval_counter(&self, timer: Timer, value: u32) {
148        let regs = self.take();
149        unsafe {
150            ptr::write_volatile(&mut regs.interval_counter[timer as usize], value);
151        }
152    }
153
154    pub fn set_match1_counter(&self, timer: Timer, value: u32) {
155        let regs = self.take();
156        unsafe {
157            ptr::write_volatile(&mut regs.match_1_counter[timer as usize], value);
158        }
159    }
160    pub fn set_match2_counter(&self, timer: Timer, value: u32) {
161        let regs = self.take();
162        unsafe {
163            ptr::write_volatile(&mut regs.match_2_counter[timer as usize], value);
164        }
165    }
166    pub fn set_match3_counter(&self, timer: Timer, value: u32) {
167        let regs = self.take();
168        unsafe {
169            ptr::write_volatile(&mut regs.match_3_counter[timer as usize], value);
170        }
171    }
172
173    pub fn clear_interrupt(&self, timer: Timer) -> Option<Interrupt> {
174        let regs = self.take();
175        unsafe {
176            let flags = ptr::read_volatile(&mut regs.interrupt_register[timer as usize]); // 読み出すとクリア
177            Interrupt::from_bits(flags)
178        }
179    }
180
181    pub fn enable_interrupt(&self, timer: Timer, flag: Interrupt) {
182        let regs = self.take();
183        unsafe {
184            ptr::write_volatile(&mut regs.interrupt_enable[timer as usize], flag.bits());
185            // Interrupt enable
186        }
187    }
188
189    pub fn set_event_timer_control(&self, timer: Timer, flag: EventTimerControl) {
190        let regs = self.take();
191        unsafe {
192            ptr::write_volatile(&mut regs.interrupt_enable[timer as usize], flag.bits());
193            // Interrupt enable
194        }
195    }
196}