diff --git a/src/zinc/hal/k20/pin.rs b/src/zinc/hal/k20/pin.rs index 3f2476d9..9c3c6c9f 100644 --- a/src/zinc/hal/k20/pin.rs +++ b/src/zinc/hal/k20/pin.rs @@ -22,11 +22,8 @@ on the package. use core::option::Option; -use util::volatile_cell::VolatileCell; - use super::sim; -#[path="../../util/ioreg.rs"] mod ioreg; /// A pin. #[allow(missing_doc)] @@ -100,23 +97,37 @@ impl Pin { pull: PullConf, drive_strength: DriveStrength, slew_rate: SlewRate, filter: bool, open_drain: bool) { // enable port clock - sim::enable_PORT(self.port as uint); + sim::enable_PORT(self.port); - let value = - (pull as u32 << 0) - | (slew_rate as u32 << 2) - | (filter as u32 << 4) - | (open_drain as u32 << 5) - | (drive_strength as u32 << 6) - | (function as u32 << 8); - self.pcr().set(value); + let (pe, ps) = match pull { + PullNone => (false, reg::PULL_DOWN), + PullDown => (true, reg::PULL_DOWN), + PullUp => (true, reg::PULL_UP), + }; + let sre = match slew_rate { + SlewFast => reg::FAST, + SlewSlow => reg::SLOW, + }; + let dse = match drive_strength { + DriveStrengthHigh => reg::HIGH_DRIVE, + DriveStrengthLow => reg::LOW_DRIVE, + }; + + self.pcr() + .set_pe(pe) + .set_ps(ps) + .set_sre(sre) + .set_pfe(filter) + .set_ode(open_drain) + .set_dse(dse) + .set_mux(function as u32); if function == GPIO { (self as &::hal::pin::GPIO).set_direction(gpiodir.unwrap()); } } - fn gpioreg(&self) -> ®::GPIO { + fn gpioreg(&self) -> &'static reg::GPIO { match self.port { PortA => ®::GPIOA, PortB => ®::GPIOB, @@ -126,11 +137,7 @@ impl Pin { } } - fn gpiobit(&self) -> u32 { - 1 << (self.pin as uint) - } - - fn pcr(&self) -> &VolatileCell { + fn pcr(&self) -> &'static reg::PORT_pcr { let port: ®::PORT = match self.port { PortA => ®::PORTA, PortB => ®::PORTB, @@ -138,59 +145,95 @@ impl Pin { PortD => ®::PORTD, PortE => ®::PORTE, }; - return &port.PCR[self.pin as uint]; + return &port.pcr[self.pin as uint]; } } impl ::hal::pin::GPIO for Pin { /// Sets output GPIO value to high. fn set_high(&self) { - self.gpioreg().set_PSOR(self.gpiobit()); + self.gpioreg().psor.set_ptso(self.pin as uint, true); } /// Sets output GPIO value to low. fn set_low(&self) { - self.gpioreg().set_PCOR(self.gpiobit()); + self.gpioreg().pcor.set_ptco(self.pin as uint, true); } /// Returns input GPIO level. fn level(&self) -> ::hal::pin::GPIOLevel { - let bit: u32 = self.gpiobit(); let reg = self.gpioreg(); - - match reg.PDIR() & bit { - 0 => ::hal::pin::Low, - _ => ::hal::pin::High, + match reg.pdir.pdi(self.pin as uint) { + false => ::hal::pin::Low, + _ => ::hal::pin::High, } } /// Sets output GPIO direction. fn set_direction(&self, new_mode: ::hal::pin::GPIODirection) { - let bit: u32 = self.gpiobit(); let reg = self.gpioreg(); - let val: u32 = reg.PDDR(); - let new_val: u32 = match new_mode { - ::hal::pin::In => val & !bit, - ::hal::pin::Out => val | bit, + let val = match new_mode { + ::hal::pin::In => reg::INPUT, + ::hal::pin::Out => reg::OUTPUT, }; - - reg.set_PDDR(new_val); + reg.pddr.set_pdd(self.pin as uint, val); } } -mod reg { +/// Register definitions +pub mod reg { use util::volatile_cell::VolatileCell; + use core::ops::Drop; - #[allow(non_snake_case)] - pub struct PORT { - pub PCR: [VolatileCell, ..32], - pub GPCLR: VolatileCell, - pub GPCHR: VolatileCell, - pub ISFR: VolatileCell, - pub DFER: VolatileCell, - pub DFCR: VolatileCell, - pub DFWR: VolatileCell, - } + ioregs!(PORT = { + /// Port control register + 0x0 => reg32 pcr[32] + { + 0 => ps { //= Pull direction select + 0 => PULL_DOWN, + 1 => PULL_UP + } + 1 => pe, //= Pull enable + 2 => sre { //= Slew rate + 0 => FAST, + 1 => SLOW + } + 4 => pfe, //= Passive filter enable + 5 => ode, //= Open drain enable + 6 => dse { //= Drive strength + 0 => LOW_DRIVE, + 1 => HIGH_DRIVE + } + 8..10 => mux, //= Multiplexer configuration + 15 => lk, //= Configuration lock + 16..19 => irqc {//= Interrupt configuration + 0 => IRQ_NONE, //= No IRQ enablled + 1 => IRQ_DMA_RISING, //= Trigger DMA on rising edge + 2 => IRQ_DMA_FALLING, //= Trigger DMA on falling edge + 3 => IRQ_DMA_EITHER, //= Trigger DMA on either edge + // reserved + 8 => IRQ_ZERO, + 9 => IRQ_RISING, + 10 => IRQ_FALLING, + 11 => IRQ_EITHER, + 12 => IRQ_ONE, + } + } + + 0x80 => reg32 gpclr { //= Global pin control low + 0..15 => gpwd, + 16..31 => gpwe, + } + + 0x84 => reg32 gpchr { //= Global pin control high + 0..15 => gpwd, + 16..31 => gpwe, + } + + 0x88 => reg32 isfr { //= Interrupt status + 0..31 => isf + } + }) extern { #[link_name="k20_iomem_PORTA"] pub static PORTA: PORT; @@ -200,13 +243,34 @@ mod reg { #[link_name="k20_iomem_PORTE"] pub static PORTE: PORT; } - ioreg_old!(GPIO: u32, PDOR, PSOR, PCOR, PTOR, PDIR, PDDR) - reg_rw!(GPIO, u32, PDOR, set_PDOR, PDOR) - reg_rw!(GPIO, u32, PSOR, set_PSOR, PSOR) - reg_rw!(GPIO, u32, PCOR, set_PCOR, PCOR) - reg_rw!(GPIO, u32, PTOR, set_PTOR, PTOR) - reg_rw!(GPIO, u32, PDIR, set_PDIR, PDIR) - reg_rw!(GPIO, u32, PDDR, set_PDDR, PDDR) + ioregs!(GPIO = { + 0x0 => reg32 pdo { //! port data output register + 0..31 => pdo + } + + 0x4 => reg32 psor { //! port set output register + 0..31 => ptso[32]: wo + } + + 0x8 => reg32 pcor { //! port clear output register + 0..31 => ptco[32]: wo + } + + 0xc => reg32 ptor { //! port toggle output register + 0..31 => ptto[32]: wo + } + + 0x10 => reg32 pdir { //! port data input register + 0..31 => pdi[32] + } + + 0x14 => reg32 pddr { //! port direction register + 0..31 => pdd[32] { + 0 => INPUT, + 1 => OUTPUT, + } + } + }) extern { #[link_name="k20_iomem_GPIOA"] pub static GPIOA: GPIO; diff --git a/src/zinc/hal/k20/sim.rs b/src/zinc/hal/k20/sim.rs index 204ca07e..a28afe30 100644 --- a/src/zinc/hal/k20/sim.rs +++ b/src/zinc/hal/k20/sim.rs @@ -15,44 +15,165 @@ //! HAL for Kinetis SIM module. -#[path="../../util/ioreg.rs"] mod ioreg; +use super::pin; /// Enable clock to a PORTx peripheral -#[allow(non_snake_case)] -pub fn enable_PORT(num: uint) { - reg::SIM.set_SCGC5(reg::SIM.SCGC5() | (1 << (num + 8))); +#[allow(non_snake_case_functions)] +pub fn enable_PORT(port: pin::Port) { + match port { + pin::PortA => {reg::SIM.scgc5.set_porta(true);}, + pin::PortB => {reg::SIM.scgc5.set_portb(true);}, + pin::PortC => {reg::SIM.scgc5.set_portc(true);}, + pin::PortD => {reg::SIM.scgc5.set_portd(true);}, + pin::PortE => {reg::SIM.scgc5.set_porte(true);}, + } } +/// Registers #[allow(dead_code)] -mod reg { +pub mod reg { use util::volatile_cell::VolatileCell; + use core::ops::Drop; - #[allow(non_snake_case)] - struct SIM { - SOPT1: VolatileCell, - SOPT1CFG: VolatileCell, - _pad0: [VolatileCell, ..(0x1004 - 0x8) / 4], - SOPT2: VolatileCell, - _pad1: VolatileCell, - SOPT4: VolatileCell, - SOPT5: VolatileCell, - _pad2: VolatileCell, - SOPT7: VolatileCell, - _pad3: [VolatileCell, ..(0x1024 - 0x101c) / 4], - SDID: VolatileCell, - _pad4: [VolatileCell, ..(0x1034 - 0x1028) / 4], - SCGC4: VolatileCell, - SCGC5: VolatileCell, - SCGC6: VolatileCell, - SCGC7: VolatileCell, - CLKDIV1: VolatileCell, - CLKDIV2: VolatileCell, - FCFG1: VolatileCell, - FCFG2: VolatileCell, - } + ioregs!(SIM = { + 0x0 => reg32 sopt1 { + 12..15 => ramsize: ro, + 19..18 => osc32ksel, + 29 => usbvstby, + 30 => usbstby, + 31 => usbregen, + }, + + 0x4 => reg32 sopt1cfg { + 24 => urwe, + 25 => uvswe, + 26 => usswe, + }, + + 0x1004 => reg32 sopt2 { + 4 => rtcclkoutsel, + 5..7 => clkoutsel, + 11 => ptd7pad, + 12 => traceclksel, + 16 => pllfllsel, + 18 => usbsrc, + }, + + 0x100c => reg32 sopt4 { + 0 => ftm0flt0, + 1 => ftm0flt1, + 4 => ftm1flt0, + 18..19 => ftm1ch0src, + 24 => ftm0clksel, + 25 => ftm1clksel, + 28 => ftm0trg0src, + }, + + 0x1010 => reg32 sopt5 { + 0 => uart0txsrc, + 2..3 => uart0rxsrc, + 4 => uart1txsrc, + 6..7 => uart1rxsrc, + }, + + 0x1018 => reg32 sopt7 { + 0..3 => adc0trgsel { + 0x0 => PDB0_EXTRG, + 0x1 => CMP0_OUT, + 0x2 => CMP1_OUT, + // reserved + 0x4 => PIT_TRG0, + 0x5 => PIT_TRG1, + 0x6 => PIT_TRG2, + 0x7 => PIT_TRG3, + 0x8 => FTM0_TRG, + 0x9 => FTM1_TRG, + // unused + // unused + 0x12 => RTC_ALARM, + 0x13 => RTC_SECONDS, + 0x14 => LPT_TRG, + // unused + }, + 4 => adc0pretrgsel, + 7 => adc0alttrgen, + }, + + 0x1034 => reg32 scgc4 { + 1 => ewm, + 2 => cmt, + 6 => i2c0, + 10 => uart0, + 11 => uart1, + 12 => uart2, + 18 => usbotg, + 19 => cmp, + 20 => vreg, + }, + + 0x1038 => reg32 scgc5 { + 0 => lptimer, + 5 => tsi, + 9 => porta, + 10 => portb, + 11 => portc, + 12 => portd, + 13 => porte, + }, + + 0x103c => reg32 scgc6 { + 0 => ftfl, + 1 => dmamux, + 12 => spi0, + 15 => i2s, + 18 => crc, + 21 => usbdcd, + 22 => pdb, + 23 => pit, + 24 => ftm0, + 25 => ftm1, + 27 => adc0, + 29 => rtc, + }, + + 0x1040 => reg32 scgc7 { + 1 => dma, + }, + + 0x1044 => reg32 clkdiv1 { + 16..19 => outdiv4, + 24..27 => outdiv2, + 28..31 => outdiv1, + }, + + 0x1048 => reg32 clkdiv2 { + 0 => usbfrac, + 1..3 => usbdiv, + }, + + 0x104c => reg32 fcfg1 { + 0 => flashdis, + 1 => flashdoze, + 8..11 => depart, + 16..19 => eesize, + 24..27 => pfsize, + 28..31 => nvmsize, + }, + + 0x1050 => reg32 fcfg2 { + 16..22 => maxaddr1, + 23 => pflsh, + 24..30 => maxaddr0, + }, + + 0x1058 => reg32 uidmh { + 0..31 => uid, + }, - reg_rw!(SIM, u32, SOPT5, set_SOPT5, SOPT5) - reg_rw!(SIM, u32, SCGC5, set_SCGC5, SCGC5) + 0x1060 => reg32 uidl { + 0..31 => uid, + }, + }) extern { #[link_name="k20_iomem_SIM"] pub static SIM: SIM; diff --git a/src/zinc/hal/k20/uart.rs b/src/zinc/hal/k20/uart.rs index 023bb022..26f947c2 100644 --- a/src/zinc/hal/k20/uart.rs +++ b/src/zinc/hal/k20/uart.rs @@ -22,7 +22,6 @@ use core::intrinsics::abort; use drivers::chario::CharIO; use hal::uart; -#[path="../../util/ioreg.rs"] mod ioreg; #[path="../../util/wait_for.rs"] mod wait_for; /// Available UART peripherals. @@ -38,24 +37,6 @@ pub struct UART { reg: &'static reg::UART, } -/// UART word length. -#[allow(missing_doc)] -pub enum WordLen { - WordLen8bits = 0, - WordLen9bits = 0b00010000, -} - -impl WordLen { - /// Convert from number to WordLen. - pub fn from_u8(val: u8) -> WordLen { - match val { - 8 => WordLen8bits, - 9 => WordLen9bits, - _ => unsafe { abort() }, - } - } -} - /// Stop bits configuration. /// K20 UART only supports one stop bit. pub enum StopBit { @@ -73,16 +54,6 @@ impl StopBit { } } -enum ParityEnabled { - PEDisabled = 0b00, - PEEnabled = 0b10, -} - -enum ParitySelect { - PSOdd = 0b1, - PSEven = 0b0, -} - impl UARTPeripheral { fn reg(self) -> &'static reg::UART { match self { @@ -101,8 +72,7 @@ impl UART { reg: peripheral.reg() }; uart.set_baud_rate(baudrate); - uart.set_mode(WordLen::from_u8(word_len), parity, - StopBit::from_u8(stop_bits)); + uart.set_mode(reg::UART_c1_m::from_u8(word_len), parity, StopBit::from_u8(stop_bits)); uart.set_fifo_enabled(true); uart @@ -117,80 +87,229 @@ impl UART { fn set_baud_rate(&self, baud_rate: u32) { let sbr: u32 = self.uart_clock() / 16 / baud_rate; let brfa: u32 = (2 * self.uart_clock() / baud_rate) % 32; - (*self.reg).set_BDH((sbr >> 8) as u8); - (*self.reg).set_BDL((sbr & 0xff) as u8); - (*self.reg).set_C4(((*self.reg).C4() & !0b11111) | brfa as u8); + (*self.reg).bdh.set_sbr((sbr >> 8) as u8); + (*self.reg).bdl.set_sbr((sbr & 0xff) as u8); + (*self.reg).c4.set_brfa(brfa as u8); } #[no_stack_check] - fn set_mode(&self, word_len: WordLen, parity: uart::Parity, _: StopBit) { - let c1: u8 = (*(self.reg)).C1(); - let computed_val: u8 = word_len as u8 | match parity { - uart::Disabled => PEDisabled as u8 | PSOdd as u8, - uart::Odd => PEEnabled as u8 | PSOdd as u8, - uart::Even => PEEnabled as u8 | PSEven as u8, + fn set_mode(&self, word_len: reg::UART_c1_m, parity: uart::Parity, + _stop_bits: StopBit) { + let mut c1 = (*self.reg).c1.set_m(word_len); + match parity { + uart::Disabled => {c1.set_pe(false);} + uart::Odd => {c1.set_pe(true).set_pt(reg::Odd);} + uart::Even => {c1.set_pe(true).set_pt(reg::Even);} uart::Forced1 => unsafe { abort() }, uart::Forced0 => unsafe { abort() }, }; - let new_c1 = (c1 & !0x3) | computed_val; - - (*(self.reg)).set_C1(new_c1); + (*self.reg).c2.set_te(true).set_re(true); } fn set_fifo_enabled(&self, enabled: bool) { - let val: u8 = match enabled { - true => PFIFOTxFifoEnabled | PFIFORxFifoEnabled, - false => 0, - }; - - (*(self.reg)).set_PFIFO(val); + (*(self.reg)).pfifo.set_rxfe(enabled).set_txfe(enabled); } } impl CharIO for UART { fn putc(&self, value: char) { - wait_for!(self.reg.S1() as u8 & S1TDREmpty == S1TDREmpty); - self.reg.set_D(value as u8); + wait_for!(self.reg.s1.tdre()); + self.reg.d.set_re(value as u8); } } -static S1TDREmpty: u8 = 0b1000_0000; +/// Register definitions +pub mod reg { + use util::volatile_cell::VolatileCell; + use core::ops::Drop; + use core::intrinsics::abort; -static PFIFOTxFifoEnabled: u8 = 0b1000_0000; -static PFIFORxFifoEnabled: u8 = 0b0000_1000; + ioregs!(UART = { + 0x0 => reg8 bdh { //! baud rate high + 0..4 => sbr, //= baud rate (high 5 bits) + 6 => rxedgie, //= RxD input active edge interrupt enable + 7 => lbkdie, //= LIN break detect interrupt enable + }, -mod reg { - use util::volatile_cell::VolatileCell; + 0x1 => reg8 bdl { //! baud rate low + 0..7 => sbr, //= baud rate (low 8 bits) + } + + 0x2 => reg8 c1 { //! Control register 1 + 0 => pt { //! parity type + 0x0 => Even, //= even parity + 0x1 => Odd, //= odd parity + } + 1 => pe, //= parity enable + 2 => ilt { //! idle line type select + 0x0 => AfterStart, //= idle character bit count starts after start bit + 0x1 => AfterStop, //= idle character bit count starts after stop bit + } + 3 => wake { //! receiver wakeup method select + 0x0 => IdleLineWakeup, + 0x1 => AddressMarkWakeup, + } + 4 => m { //! bit width mode select + 0x0 => DataBits8, //= start + 8 data bits + stop + 0x1 => DataBits9, //= start + 9 data bits + stop + } + 5 => rsrc { //! receiver source select + 0x0 => RxLoopback, //= select internal loop-back mode + 0x1 => SingleWire, //= single-wire UART mode + } + 6 => uartswai, //= should UART stop in Wait mode + 7 => loops, //= loop mode enable + }, + + 0x3 => reg8 c2 { //! Control register 2 + 0 => sbk, //= send break + 1 => rwu, //= receiver wakeup control + 2 => re, //= receiver enable + 3 => te, //= transmitter enable + 4 => ilie, //= idle line interrupt enable + 5 => rie, //= receiver full interrupt enable + 6 => tcie, //= transmission complete interrupt enable + 7 => tie, //= transmitter interrupt enable + }, + + 0x4 => reg8 s1 { //! Status register 1 + 0 => pf, //= parity error flag + 1 => fe, //= framing error flag + 2 => nf, //= noise flag + 3 => or, //= receiver overrun flag + 4 => idle, //= idle line flag + 5 => rdrf, //= receive data register full flag + 6 => tc, //= transmit complete flag + 7 => tdre, //= transmit data register empty flag + }, - ioreg_old!(UART: u8, BDH, BDL, C1, C2, S1, S2, C3, D, MA1, MA2, C4, C5, ED, MODEM, IR, - PFIFO, CFIFO, SFIFO, TWFIFO, TCFIFO, RWFIFO, RCFIFO) - reg_rw!(UART, u8, BDH, set_BDH, BDH) - reg_rw!(UART, u8, BDL, set_BDL, BDL) - reg_rw!(UART, u8, C1, set_C1, C1) - reg_rw!(UART, u8, C2, set_C2, C2) - reg_r!( UART, u8, S1, S1) - reg_rw!(UART, u8, S2, set_S2, S2) - reg_rw!(UART, u8, C3, set_C3, C3) - reg_rw!(UART, u8, D, set_D, D) - reg_rw!(UART, u8, MA1, set_MA1, MA1) - reg_rw!(UART, u8, MA2, set_MA2, MA2) - reg_rw!(UART, u8, C4, set_C4, C4) - reg_rw!(UART, u8, C5, set_C5, C5) - reg_rw!(UART, u8, ED, set_ED, ED) - reg_rw!(UART, u8, MODEM, set_MODEM, MODEM) - reg_rw!(UART, u8, IR, set_IR, IR) - reg_rw!(UART, u8, PFIFO, set_PFIFO, PFIFO) - reg_rw!(UART, u8, CFIFO, set_CFIFO, CFIFO) - reg_rw!(UART, u8, SFIFO, set_SFIFO, SFIFO) - reg_rw!(UART, u8, TWFIFO, set_TWFIFO, TWFIFO) - reg_r!( UART, u8, TCFIFO, TCFIFO) - reg_rw!(UART, u8, RWFIFO, set_RWFIFO, RWFIFO) - reg_r!( UART, u8, RCFIFO, RCFIFO) - // FIXME(bgamari): Specialized registers omitted + 0x5 => reg8 s2 { //! Status register 2 + 0 => raf: ro, //= reciever active flag + 1 => lbkde, //= LIN break detection enable + 2 => brk13, //= break transmit character length + 3 => rwuid, //= receive wakeup idle detect + 4 => rxinv, //= receive data inversion + 5 => msbf, //= most significant bit first + 6 => rxedgif, //= RxD pin active edge interrupt flag + 7 => lbkdif, //= LIN break detect interrupt flag + }, + + 0x6 => reg8 c3 { //! Control register 3 + 0 => peie, //= parity error interrupt enable + 1 => feie, //= framing error interrupt enable + 2 => neie, //= noise error interrupt enable + 3 => orie, //= overrun error interrupt enable + 4 => txinv, //= transmit data inversion + 5 => txdir, //= transmitter pin data direction in single-wire mode + 6 => t8, //= transmit bit 8 + 7 => r8: ro, //= receieved bit 8 + }, + + 0x7 => reg8 d { //! Data register + 0..7 => re, //= reads return the contents of the receive data register, + //= writes go to the transmit data register. + }, + + 0x8 => reg8 ma1 { //! Match address register 1 + 0..7 => ma, //= match address + }, + + 0x9 => reg8 ma2 { //! Match address register 2 + 0..7 => ma, //= match address + }, + + 0xa => reg8 c4 { //! Control register 4 + 0..4 => brfa, //= baud rate fine adjust + 5 => m10, //= 10-bit mode select + 6 => maen2, //= match address 2 enable + 7 => maen1, //= match address 1 enable + }, + + 0xb => reg8 c5 { //! Control register 5 + 5 => rdmas, //= receiver full DMA select + 7 => tdmas, //= transmitter DMA select + }, + + 0xc => reg8 ed { //! Extended data register + 6 => paritye: ro, //= The current received data word has a parity error + 7 => noisy: ro, //= The current received data word was received with noise + }, + + 0xd => reg8 modem { //! Modem register + 0 => txctse, //= transmitter clear-to-send enable + 1 => txrese, //= transmitter request-to-send enable + 2 => txrtspol, //= transmitter request-to-send polarity + 3 => rxrtse, //= receiver request-to-send polarity + }, + + 0xe => reg8 ir { //! Infrared register + 0..1 => tnp { //! transmitter narrow pulse + 0 => PULSE_3_16, + 1 => PULSE_1_16, + 2 => PULSE_1_32, + 3 => PULSE_1_4, + }, + 2 => iren, //= infrared enable + }, + + 0x10 => reg8 pfifo { //! FIFO parameters + 0..2 => rxfifosize: ro, //= receive FIFO buffer depth + 3 => rxfe, //= receive FIFO enable + 4..6 => txfifosize: ro, //= transmit FIFO buffer depth + 7 => txfe, //= transmit FIFO enable + }, + + 0x11 => reg8 cfifo { //! FIFO control + 0 => rxufe, //= receive FIFO underflow interrupt enable + 1 => txofe, //= transmit FIFO overflow interrupt enable + 2 => rxofe, //= receive FIFO overflow interrupt enable + 6 => rxflush: wo, //= flush receive FIFO + 7 => txflush: wo, //= flush transmit FIFO + }, + + 0x12 => reg8 sfifo { //! FIFO status + 0 => rxuf, //= recieve FIFO underflow flag + 1 => txof, //= transmit FIFO overflow flag + 2 => rxof, //= recieve FIFO overflow flag + 6 => rxempt: ro, //= recieve FIFO empty flag + 7 => txempt: ro, //= transmit FIFO empty flag + }, + + 0x13 => reg8 twfifo { //! Transmit FIFO watermark + 0..7 => txwater, //= number of data words to transmit before generating + //= an interrupt or DMA request + }, + + 0x14 => reg8 tcfifo { //! Transmit FIFO count + 0..7 => txcount, //= number of data words in the transmit FIFO buffer. + } + + 0x15 => reg8 rwfifo { //! Receive FIFO watermark + 0..7 => rxwater, //= number of data words to receive before generating + //= an interrupt or DMA request + }, + + 0x16 => reg8 rcfifo { //! Receive FIFO count + 0..7 => rxcount, //= number of data words in the receive FIFO buffer. + }, + + // FIXME(bgamari): Specialized registers omitted + }) + + impl UART_c1_m { + /// UART data word length flag value from bit count + pub fn from_u8(val: u8) -> UART_c1_m { + match val { + 8 => DataBits8, + 9 => DataBits9, + _ => unsafe { abort() }, + } + } + } extern { - #[link_name="k20_iomem_UART1"] pub static UART0: UART; - #[link_name="k20_iomem_UART2"] pub static UART1: UART; - #[link_name="k20_iomem_UART3"] pub static UART2: UART; + #[link_name="k20_iomem_UART0"] pub static UART0: UART; + #[link_name="k20_iomem_UART1"] pub static UART1: UART; + #[link_name="k20_iomem_UART2"] pub static UART2: UART; } }