Skip to content

Latest commit

 

History

History
226 lines (164 loc) · 10.5 KB

PERIPHERALS.md

File metadata and controls

226 lines (164 loc) · 10.5 KB

RISC-V Peripherals

Several peripherals are built into this microcontroller.

Bit Description Notation

Bit Type Codes

  • in means that the bit represents an input.
  • out means that the bit represents an output. (Reads might represent the external value, see the access code).
  • i/o od means that the bit represents an I/O pin that is open drain.

Bit Access Codes

  • rw means a normal read/write bit.
  • rwc means that the bit can be read and written, but that writes have a special control function -- consult the description.
  • ro means that the bit is read-only; write values are ignored.
  • r0wi means that the bit reads as zero, and write values are ignored. (This is a special case of ro.)
  • r1wi means that the bit reads as one, and write values are ignored.
  • rw1c means that the bit has a value that is set by hardware. Writes with this bit zero have no effect; writes with this bit set clear the bit.
  • rpwd means that the bit reads the value from the pin, and writes a data value to a register. Normally this means that the output is controlled by the written value, but the read-back depends on what is happening externally to the FPGA. For example, an open-drain wire-ORed output might read back zero even after the register has been written to 1, because some other device on the wire is still driving the wire to zero.

Address Map

Address Bytes Name Description
0x80000000 16 UART0 Simple UART instance 0
0x80000010 16 UART1 Simple UART instance 1
0x80000020 16 I2C Simple I2C interface
0x80000030 16 GPIO GPIO Interface
0x80000040 16 SPI Simple SPI interface
0x80000050 16 CYCLES Cycle counter

UART

Each UART interface operates at a fixed baud rate set in the Verilog code -- check the top-level for your design. Typically this is 230,400 baud.

As is traditional, data bytes are read and written from a UART_DATA register; control-plane information is accessed via a UART_CSR register.

The transmit path has a write FIFO (16 bytes deep in the default implementation, but again, check your design to be sure). Software typically writes until the FIFO is full, then waits for the FIFO to drain, polling bits in the UART CSR.

The receive path has no FIFO at all in the current design, but the character buffer is separate from the shift register. It's up to software to keep up, but software has roughly 9 bit times to consume the character before it can be overwritten.

The current microcontroller's implementation is not great about disambiguating reads -- it simply copies whatever appears at the ALU output to the read register, without generating a strobe for the LD instruction. Rather than fix the core, we currently require software to explicitly acknowledge each byte read.

UART Registers

Base address:

  • UART0: 0x80000000.
  • UART1: 0x80000010.
Offset Width Name Description
0x0 32 DATA Data to/from the UART
0x4 32 CSR Control/status register
0x8 32 reserved Not implemented
0xC 32 reserved Not implemented

UART Data

Bit 31 .. 8 7 .. 0
Name reserved FIFO
Reset 0 0
Access r0wi rwc

UART Control/Status

Bit 31 .. 8 7 6 .. 2 1 0
Name reserved RXD reserved RXRDY TXFULL
Reset 0 0 0 0 0
Access r0wi ro r0wi rw1c ro

The RXRDY bit has two functions.

  • When read, it is 1 if there is valid receive data in the DATA.FIFO register.
  • When written, if this bit is set, it acknowledges the previous character, clearing the RXRDY bit until a new character arrives.

The TXFULL bit is set by hardware whenever the transmit FIFO is full. It is cleared whenever the FIFO drops below full. (Yes, it would be nice to have empty and 50% status bits.)

RXD represents the current state of the UART's receive pin. On UART0, for the LoRaWAN face-detect demo, it's connected to FACE, the "face present" signal (1 == face present), a non-inverting input.

I2C Interface

The I2C implementation is completely software driven; but it has a dedicated GPIO register to make programming easier and faster.

Two pins, I2C_SCL and I2C_SDA, are controlled by this interface. Both are open-drain signals -- in other words, they alternate between high-impedance (no drive at all), and driving actively to ground. Each pin is in the high-impedance (or "Z") state when the corresponding register bit is set to 1. A pin is in the low-impedance to ground (or "L") state when the corresponding register bit is set to 0.

I2C Registers

Base address: 0x80000020.

Offset Width Name Description
0x0 32 DATA Data to/from the pins registers
0x4 32 reserved not implemented
0x8 32 reserved Not implemented
0xC 32 reserved Not implemented

I2C Data

| Bit | 31 .. 2 | 1 | 0 | |:----------:|:--------:|:-:|:-:|:-:| | Name | reserved | SDA | SCL | | Reset | 0 | 1 | 1 | | Type | n/a | i/o od | i/o od | | Access | r0wi | rpwd | rpwd |

Software is responsible for bit-banging the interface and for implementing the I2C protocol.

Note that the value read back is the current value at the pin of the device, not the last value written to the register.

GPIO Interface

The GPIOs are architected as classic software-configured GPIOs. They are programmable for input/output direction and (if output) for totem-pole vs open-drain drive. However, in this implementation we remove the programmability; so they're fixed function.

GPIO Registers

Base address: 0x80000030.

Offset Width Name Description
0x0 32 DATA Data to/from the GPIO registers
0x4 32 reserved not implemented
0x8 32 reserved Not implemented
0xC 32 reserved Not implemented

GPIO Data

Bit 31 .. 6 6 5 4 3 2 1 0
Name reserved GPIO6 GPIO5 GPIO4 GPIO3 GPIO2 GPIO1 GPIO0
Reset 0 0 0 0 0 0 1 0
Type n/a in in in in in i/o od out
Access r0wi ro ro ro ro ro rpwd rpwd

The GPIO bits are intended to be used as follows:

Bit name LoRaWAN radio signal Comments
GPIO0 CS chip select output to radio.
GPIO1 NRST reset output to radio. open drain output, active low, set to 1 by reset.
GPIO2 DIO1 DIO1 output of radio, non-inverting input.
GPIO3 IRQ Interrupt request from radio, non-inverting input.
GPIO4 DIO2 DIO2 output of radio, non-invering input.
GPIO5 SPARE4 Spare non-inverting input, connected to screw terminal JP3-1 on the LoRaWAN radio board.
GPIO6 SPARE5 Spare non-inverting input, connected to screw terminal JP3-2 on the LoRaWAN radio board.

Due to pin and board-design limitations, GPIO5 and GPIO6 are not available on the MDP implementation of this design, and will always read as zero. Instead, UART0 TX and RX are connected to SPARE_C4 and SPARE_C5, repectively.

SPI Interface

The SPI implementation is completely software driven; but it has a dedicated GPIO register to make programming easier and faster.

SPI Registers

Base address: 0x80000040.

Offset Width Name Description
0x0 32 DATA Data to/from the pins registers
0x4 32 reserved not implemented
0x8 32 reserved Not implemented
0xC 32 reserved Not implemented

SPI Data

Bit 31 .. 3 2 1 0
Name reserved SCK MOSI MISO
Reset 0 0 0 0
Type n/a out out in
Access r0wi rpwd rpwd ro

SCK and MOSI are the classic SPI outputs (to the LoRaWAN radio, in this case). MISO is the classic SPI input. Software is responsible for bit-banging the interface. Software is also responsible for asserting CS (via the GPIO interface) before a SPI access to the radio, and clearing it afterwards.

Cycle Counter

A free-running 32-bit counter is provided. It is incremented on every CPU clock cycle. Software can change the value by writing to the data register.

Cycle Counter Registers

Offset Width Name Description
0x0 32 DATA Counter Data
0x4 32 reserved Not implemented
0x8 32 reserved Not implemented
0xC 32 reserved Not implemented

Cycle-Counter Data Register

Bit 31 .. 0
Name COUNT
Reset 0
Access rw

This register is incremented by hardware on every CPU clock cycle. Software may change the value by writing to this register; but note that it will never read back exactly what it wrote, because the value is constantly incrementing.