diff options
Diffstat (limited to 'ble/src')
-rw-r--r-- | ble/src/ble.rs | 28 | ||||
-rw-r--r-- | ble/src/i2c.rs | 2 | ||||
-rw-r--r-- | ble/src/logger.rs | 34 | ||||
-rw-r--r-- | ble/src/main.rs | 47 | ||||
-rw-r--r-- | ble/src/uarte1.rs | 52 |
5 files changed, 102 insertions, 61 deletions
diff --git a/ble/src/ble.rs b/ble/src/ble.rs new file mode 100644 index 0000000..e5f16cb --- /dev/null +++ b/ble/src/ble.rs @@ -0,0 +1,28 @@ +use nrf52840_hal::target::{FICR, RADIO, TIMER0}; +use rubble::link::{AddressKind, DeviceAddress, HardwareInterface, LinkLayer, MIN_PDU_BUF}; +use rubble_nrf52::{radio::BleRadio, timer::BleTimer}; + +struct NRF52840 {} +impl HardwareInterface for NRF52840 { + type Timer = BleTimer<TIMER0>; + type Tx = BleRadio; +} + +pub fn setup(radio: RADIO, timer: TIMER0, ficr: FICR) { + // make sure hfclock is started for timer0 to work at the right + // resolution. + let ble_timer = BleTimer::init(timer); + let mut devaddr = [0u8; 6]; + let devaddr_lo = ficr.deviceaddr[0].read().bits(); + let devaddr_hi = ficr.deviceaddr[1].read().bits(); + devaddr[..4].clone_from_slice(&devaddr_lo.to_le_bytes()); + devaddr[4..].clone_from_slice(&devaddr_hi.to_le_bytes()); + + let addrkind = if ficr.deviceaddrtype.read().deviceaddrtype().is_public() { + AddressKind::Public + } else { + AddressKind::Random + }; + let addr = DeviceAddress::new(devaddr, addrkind); + let mut _ll = LinkLayer::<NRF52840>::new(addr, ble_timer); +} diff --git a/ble/src/i2c.rs b/ble/src/i2c.rs index b5a5114..e95987c 100644 --- a/ble/src/i2c.rs +++ b/ble/src/i2c.rs @@ -2,7 +2,7 @@ use log::{error, trace}; use nrf52840_hal::twis::{self, Twis, TwisInterrupt}; use starb::{Reader, RingBuffer, Writer}; -static mut RB: RingBuffer<u8> = RingBuffer::new(0); +static mut RB: RingBuffer<u8> = RingBuffer::new(); pub fn setup<T>(mut twis: Twis<T>) -> (Reader<'static, u8>, impl FnMut()) where diff --git a/ble/src/logger.rs b/ble/src/logger.rs index b4167b2..07790cc 100644 --- a/ble/src/logger.rs +++ b/ble/src/logger.rs @@ -30,7 +30,7 @@ impl fmt::Write for JoinedRingBuffer<'_> { } } -static mut LB: RingBuffer<u8> = RingBuffer::<u8>::new(0); +static mut LB: RingBuffer<u8> = RingBuffer::<u8>::new(); static mut JRB: JoinedRingBuffer = unsafe { JoinedRingBuffer::new(&LB) }; // The UART isn't necessarily Sync, so wrap it in something that @@ -80,24 +80,36 @@ where } let jrb = unsafe { &mut JRB }; - write!( - jrb, - "[{}] {} {} -- {}\r\n", - rtc::millis(), - record.level(), - record.target(), - record.args() - ) - .ok(); + if record.target() == "usb" { + write!(jrb, "{}", record.args()).ok(); + } else { + write!( + jrb, + "[{}] {} {} -- {}\r\n", + rtc::millis(), + record.level(), + record.target(), + record.args() + ) + .ok(); + } } fn flush(&self) { + //let start = rtc::millis(); let jrb = unsafe { &mut JRB }; let writer = unsafe { &mut (*self.writer.get()) }; let mut buf: [u8; 256] = unsafe { MaybeUninit::<[u8; 256]>::uninit().assume_init() }; let len = jrb.lbr.shift_into(&mut buf); if len > 0 { - writer.w.write(&buf[0..len]).expect("writing log") + writer.w.write(&buf[0..len]).expect("writing log"); + /* + let end = rtc::millis(); + writer + .w + .write(&[b' ', b'-', b' ', b'0' + (end as u8 - start as u8)]) + .ok(); + */ } } } diff --git a/ble/src/main.rs b/ble/src/main.rs index 71e3b82..36c3228 100644 --- a/ble/src/main.rs +++ b/ble/src/main.rs @@ -3,6 +3,7 @@ #![no_std] #![no_main] +mod ble; mod i2c; mod logger; mod macros; @@ -13,7 +14,7 @@ use clint::HandlerArray; use core::mem; use cortex_m::asm::wfi; use cortex_m_rt::{entry, exception, ExceptionFrame}; -use log::{info, LevelFilter}; +use log::{info, log, Level as LogLevel, LevelFilter}; #[allow(unused_imports)] extern crate panic_semihosting; @@ -32,8 +33,7 @@ use nrf52840_mdk_bsp::{ const I2C_ADDR: u8 = 4; // TODO: -// * set up serial reader for trinket -// * and, finally, bluetooth +// * bluetooth // Interrupt handler table. static HANDLERS: HandlerArray = HandlerArray::new(); @@ -48,6 +48,19 @@ fn main() -> ! { log::set_logger(logger_ref).expect("setting logger"); log::set_max_level(LevelFilter::Trace); + // TODO: use hal interface for this. + nrf52 + .CLOCK + .tasks_hfclkstart + .write(|w| w.tasks_hfclkstart().set_bit()); + while nrf52 + .CLOCK + .events_hfclkstarted + .read() + .events_hfclkstarted() + .bit_is_clear() + {} + nrf52.RTC0.intenset.write(|w| w.tick().set()); let mut nvic = nrf52.NVIC; @@ -70,6 +83,8 @@ fn main() -> ! { let uarte1 = uarte1(nrf52.UARTE1, txp, rxp); let (mut uarte1_reader, mut uarte1_handler) = uarte1::setup(uarte1); + //ble::setup(nrf52.RADIO, nrf52.TIMER0, nrf52.FICR); + HANDLERS.with_overrides(|hs| { hs.register(0, &mut rtc_handler); nvic.enable(Interrupt::RTC0); @@ -80,16 +95,19 @@ fn main() -> ! { info!("Bootstrap complete."); - let mut last_tick = rtc::millis(); - last_tick -= last_tick % 1024; - let mut buf: [u8; 256] = [0; 256]; + // Buffer is just scratch space that always gets written to + // before it's read. + let mut buf: [u8; 256] = + unsafe { core::mem::MaybeUninit::<[u8; 256]>::uninit().assume_init() }; + + // TODO: there's some kind of weird multi-millisecond latency + // somewhere. It may be in one of the interrupt handlers, so + // maybe stick a counter on them for every time they're fired + // and then spit out stats once/second from here. + // + // May need to keep total-time-spent inside the handlers as + // well. This lag is infuriatingly hidden. loop { - let tick = rtc::millis(); - if tick >= last_tick + 1024 { - last_tick = tick; - last_tick -= last_tick % 1024; - } - let mut len = twis_reader.shift_into(&mut buf); while len > 0 { info!("i²c data: {:?}", &buf[0..len]); @@ -98,9 +116,8 @@ fn main() -> ! { let mut len = uarte1_reader.shift_into(&mut buf); while len > 0 { - info!( - "serial {}: {}", - len, + log!(target: "usb", LogLevel::Info, + "{}", core::str::from_utf8(&buf[0..len]).expect("utf8conv") ); len = uarte1_reader.shift_into(&mut buf); diff --git a/ble/src/uarte1.rs b/ble/src/uarte1.rs index 1afce29..0beb8cd 100644 --- a/ble/src/uarte1.rs +++ b/ble/src/uarte1.rs @@ -2,9 +2,9 @@ use log::info; use nrf52840_hal::uarte::{self, Uarte}; use starb::{Reader, RingBuffer, Writer}; -static mut RB: RingBuffer<u8> = RingBuffer::new(0); +static mut RB: RingBuffer<u8> = RingBuffer::new(); -const BUFLEN: usize = 128; +const BUFLEN: usize = 255; struct DoubleBuffer { bank0: [u8; BUFLEN], @@ -51,6 +51,9 @@ where w.rxstarted().set_bit() }); + // Keep the transmission going constantly. + uarte.0.shorts.write(|w| w.endrx_startrx().set_bit()); + let ptr = unsafe { DBL_BUFF.next_ptr() }; info!("setting up dma: p: {:x}, maxcnt: {}", ptr as u32, BUFLEN); uarte.0.rxd.ptr.write(|w| unsafe { w.ptr().bits(ptr as _) }); @@ -75,48 +78,29 @@ where if uarte.0.events_endrx.read().events_endrx().bit_is_set() { uarte.0.events_endrx.write(|w| w.events_endrx().clear_bit()); - // The buffer should be swapped from the RXSTARTED event, so - // we can restart the read immediately. - let optr = uarte.0.rxd.ptr.read().ptr().bits(); - let ptr = unsafe { DBL_BUFF.cur_ptr() as u32 }; - /* - if optr == ptr { - uarte - .0 - .rxd - .ptr - .write(|w| unsafe { w.ptr().bits(DBL_BUFF.next_ptr() as _) }); - } - */ - uarte.0.tasks_startrx.write(|w| w.tasks_startrx().set_bit()); - // Copy DMA buffer to ring buffer. let len = uarte.0.rxd.amount.read().amount().bits(); + let ptr = unsafe { DBL_BUFF.cur_ptr() }; + /* + let optr = uarte.0.rxd.ptr.read().ptr().bits(); let mc = uarte.0.rxd.maxcnt.read().maxcnt().bits(); info!( - "endrx - l: {}, p: {:x}, mc: {}, b: {:x}", - len, optr, mc, ptr + "ENDRX optr: {:x}, mc: {}, ptr: {:x}, len: {}", + optr, mc, ptr as u32, len, ); - flush_buf(writer, unsafe { DBL_BUFF.cur_ptr() }, len.into()); - - /* - uarte - .0 - .rxd - .maxcnt - .write(|w| unsafe { w.maxcnt().bits(BUFLEN as _) }); - */ + */ + flush_buf(writer, ptr, len as usize); } else if uarte.0.events_error.read().events_error().bit_is_set() { uarte.0.events_error.write(|w| w.events_error().clear_bit()); let len = uarte.0.rxd.amount.read().amount().bits(); - info!("error: {:b} {}b", uarte.0.errorsrc.read().bits(), len,); + info!("ERROR {:b} {}b", uarte.0.errorsrc.read().bits(), len); } else if uarte.0.events_rxto.read().events_rxto().bit_is_set() { uarte.0.events_rxto.write(|w| w.events_rxto().clear_bit()); let len = uarte.0.rxd.amount.read().amount().bits(); - info!("rxto - {}", len); - flush_buf(writer, unsafe { DBL_BUFF.cur_ptr() }, len.into()); + info!("RXTO - {}", len); + flush_buf(writer, unsafe { DBL_BUFF.cur_ptr() }, len as usize); uarte.0.tasks_flushrx.write(|w| w.tasks_flushrx().set_bit()); } else if uarte .0 @@ -129,7 +113,7 @@ where .0 .events_rxstarted .write(|w| w.events_rxstarted().clear_bit()); - info!("rxstarted"); + //info!("RXSTARTED"); // Swap to the next buffer as soon as the transfer starts to // try and lose as little data as possible. @@ -140,7 +124,7 @@ where fn flush_buf(writer: &mut Writer<u8>, ptr: *mut u8, len: usize) { let buf = unsafe { core::slice::from_raw_parts(ptr, len) }; - info!("flush start"); + //info!("flush start"); writer.unshift_from(buf); - info!("flush end"); + //info!("flush end"); } |