common: Make Gps::update() access UART0's receive buffer via a closure.
authorTilman Sauerbeck <tilman@code-monkey.de>
Wed, 8 Jan 2020 17:30:19 +0000 (18:30 +0100)
committerTilman Sauerbeck <tilman@code-monkey.de>
Thu, 9 Jan 2020 14:19:36 +0000 (15:19 +0100)
This will allow us to write tests for Gps without providing a fake
implementation of the UART reader function in the test.

src/application/main.rs
src/common/gps.rs

index 3523b885fe9a907b081c9b85da75f9d8b3380643..444ffd464da0219263f11038f4abd6df6561704d 100644 (file)
@@ -30,6 +30,7 @@ extern crate common;
 mod uart0;
 
 use common::buffer::Buffer;
+use common::ringbuf::Ringbuf;
 use common::clock;
 use common::systick;
 use common::port;
@@ -122,6 +123,20 @@ fn configure_push_buttons() {
     port::set_pull(port::PORTE, 31, port::Pull::Up);
 }
 
+fn uart0_try_read() -> Option<u8> {
+    extern {
+        static mut uart0_rx_buf: Ringbuf;
+    }
+
+    unsafe {
+        if uart0_rx_buf.is_empty() {
+            None
+        } else {
+            Some(uart0_rx_buf.read())
+        }
+    }
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn _start() -> ! {
     clock::configure();
@@ -207,7 +222,7 @@ pub unsafe extern "C" fn _start() -> ! {
         let mut show_time = false;
         let old_gps_has_fix = gps_has_fix;
 
-        while gps.update(&mut tap) {
+        while gps.update(&mut tap, uart0_try_read) {
             prev_tap = tap;
 
             show_time = true;
index 64772c775189526e06bec8cb8b604e8e7055c427..178e55198879edffbd1fb2dec11947579320daa6 100644 (file)
@@ -21,7 +21,6 @@
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
-use ringbuf::Ringbuf;
 use systick;
 
 enum ParseState {
@@ -63,20 +62,6 @@ fn to_lower(c: u8) -> u8 {
     c | 0x20
 }
 
-fn try_read() -> Option<u8> {
-    extern {
-        static mut uart0_rx_buf: Ringbuf;
-    }
-
-    unsafe {
-        if uart0_rx_buf.is_empty() {
-            None
-        } else {
-            Some(uart0_rx_buf.read())
-        }
-    }
-}
-
 fn parse_coordinate(s: &[u8]) -> i32 {
     // Find the position of the decimal separator for the minutes.
     let dot_position = s.iter().enumerate().find(|(_, &c)| {
@@ -205,10 +190,12 @@ impl Gps {
         }
     }
 
-    pub fn update(&mut self, tap: &mut TimeAndPos) -> bool {
+    pub fn update<F>(&mut self, tap: &mut TimeAndPos, mut read_func: F) -> bool
+                     where F: FnMut() -> Option<u8>
+    {
         let hexdigits = b"0123456789abcdef";
 
-        while let Some(received) = try_read() {
+        while let Some(received) = read_func() {
             if received == b'$' {
                 self.state = ParseState::InPacket;
                 self.offset = 0;