calliope_common/
lib.rs

1
2#![no_std]
3#![allow(non_camel_case_types)]
4
5use nrf51_hal::Timer;
6use crate::hal::timer::Instance;
7use nrf51_hal::prelude::_embedded_hal_blocking_delay_DelayUs;
8
9use core::arch::asm;
10
11pub use nrf51_hal as hal;
12
13pub use hal::pac as pac;
14// pub use hal::pac::Peripherals;
15
16
17pub mod board;
18pub mod gpio;
19
20pub use board::Board;
21
22pub use crate::board::*;
23
24// Experimental unsafe beep function that bypasses not yet existing
25// hal functionality.
26// ToDo: Improve a lot
27pub fn beep<T :Instance, U>(timer: &mut Timer<T,U>) {
28
29    let pin_cnf_28 = 0x50000000usize + 0x770usize;
30    let ptr_pin_cnf_28 = pin_cnf_28 as *mut u32;
31
32    let pin_cnf_29 = 0x50000000usize + 0x774usize;
33    let ptr_pin_cnf_29 = pin_cnf_29 as *mut u32;
34
35    let pin_cnf_30 = 0x50000000usize + 0x778usize;
36    let ptr_pin_cnf_30 = pin_cnf_30 as *mut u32;
37
38    let outset = 0x50000000usize + 0x508usize;
39    let ptr_outset = outset as *mut u32;
40
41    let outclr = 0x50000000usize + 0x50Cusize;
42    let ptr_outclr = outclr as *mut u32;
43
44    let dirset = 0x50000000usize + 0x518usize;
45    let ptr_dirset = dirset as *mut u32;
46
47    unsafe { core::ptr::write_volatile(ptr_dirset, 1u32 << 28) }
48    unsafe { core::ptr::write_volatile(ptr_dirset, 1u32 << 29) }
49    unsafe { core::ptr::write_volatile(ptr_dirset, 1u32 << 30) }
50
51    unsafe { core::ptr::write_volatile(ptr_pin_cnf_28, 1u32 << 0) }
52    unsafe { core::ptr::write_volatile(ptr_pin_cnf_29, 1u32 << 0) }
53    unsafe { core::ptr::write_volatile(ptr_pin_cnf_30, 1u32 << 0) }
54
55    // set sleep of DRV8837 to 1
56    unsafe { core::ptr::write_volatile(ptr_outset, 1u32 << 28) }
57
58    let delay : u32 = 300;
59    for _i in 1..100 {
60            unsafe { core::ptr::write_volatile(ptr_outset, 1u32 << 30) }
61            unsafe { core::ptr::write_volatile(ptr_outclr, 1u32 << 29) }
62            timer.delay_us(delay);
63            unsafe { core::ptr::write_volatile(ptr_outclr, 1u32 << 30) }
64            unsafe { core::ptr::write_volatile(ptr_outset, 1u32 << 29) }
65            timer.delay_us(delay);
66    }
67}
68
69// Set a color on the WS2812
70// Needs inline assembler due to critical timing
71// ToDo: Bug: Seems to set the wrong color directly after poweron?
72// ToDo: Improve and check timing
73// ToDo: Try the same with SPI
74// ToDo: Try to improve to run N Leds on a GPIO
75pub fn set_ws2812( r:u8, g: u8, b:u8) {
76
77    let val = ((g as u32) << 24) + ((r as u32) << 16) + ((b as u32) << 8);
78
79    //rprintln!("Value {:08x}", val);
80
81    let pin_cnf_18 = 0x50000000usize + 0x748usize;
82    let ptr_pin_cnf_18 = pin_cnf_18 as *mut u32;
83
84    //let pin_cnf_22 = 0x50000000usize + 0x758usize;
85    //let ptr_pin_cnf_22 = pin_cnf_22 as *mut u32;
86
87    let outset : u32 = 0x50000000 + 0x508;
88
89    let outclr : u32 = 0x50000000 + 0x50C;
90
91    // Enable pin 18 as output
92    unsafe { core::ptr::write_volatile(ptr_pin_cnf_18, 1u32 << 0) }
93    let pin :u32 = 1u32 << 18;
94    //To test: switch to test port 3 -> pin 22
95    //unsafe { core::ptr::write_volatile(ptr_pin_cnf_22, 1u32 << 0) }
96    //let pin :u32 = 1u32 << 22;
97
98    //let mut index: u32 = 0; Avoid compiler warning
99    let index: u32 = 0;
100
101    unsafe {
102
103        //val = val +1;
104
105        asm!(
106            "1:", // preamble
107
108            "ADDS {1}, {1}, #1",
109            "CMP {1}, #24",
110            "BHI 2f",
111
112            "LSLS {0}, {0}, #1",
113            "BCS 4f",
114
115            //send zero
116
117            // set pin
118            "STR  {2}, [{3}]",
119
120            // wait 0.4 us
121            "nop",
122            "nop",
123            "nop",
124            "nop",
125
126            // clear pin
127            "STR  {2}, [{4}]",
128
129            // wait 0.8 us
130            "nop",
131            "nop",
132            "nop",
133            "nop",
134            // Four nop removed from calculated wait time due to the
135            // preamble with some instructions.
136            //"nop",
137            //"nop",
138            //"nop",
139            //"nop",
140
141            "B 1b",
142
143            //send one
144            "4:",
145            // set pin
146            "STR  {2}, [{3}]",
147
148            // wait 0.8 us
149            "nop",
150            "nop",
151            "nop",
152            "nop",
153            "nop",
154            "nop",
155            "nop",
156            "nop",
157
158            // clear pin
159            "STR  {2}, [{4}]",
160
161            // wait 0.4 us
162            // Four nop removed from calculated wait time due to the
163            // preamble with some instructions.
164            //"nop",
165            //"nop",
166            //"nop",
167            //"nop",
168
169            "B 1b",
170
171            "2:", // End label
172
173            in(reg) val,
174            in(reg) index,
175            in(reg) pin,
176            in(reg) outset,
177            in(reg) outclr,
178        );
179    }
180}
181
182//Ways to access ports(examples)
183
184pub fn pin4_set_high_outset() {
185    let outset = 0x50000000usize + 0x508usize;
186    let ptr_outset = outset as *mut u32;
187    unsafe { core::ptr::write_volatile(ptr_outset, 1u32 << 4) }
188}
189
190pub fn pin4_set_high_gpio() {
191    unsafe { (*pac::GPIO::ptr()).outset.write(|w| w.bits(1u32 << 4)); }
192}
193
194pub fn pin4_set_high_asm() {
195    let outset : u32 = 0x50000000 + 0x508;
196    let pin :u32 = 1u32 << 4;
197    unsafe{
198        asm!(
199            "STR  {1}, [{0}]",
200            in(reg) outset,
201            in(reg) pin,
202        );
203    }
204}
205
206
207