581 Register bank accessible through SPI and I2C

581 : Register bank accessible through SPI and I2C

Design render

How it works

Register bank accessible throught two different serial interfaces: SPI and I2C. Use digital input to select prefered interface.

Digital input ui_in[7] = 0 selects SPI and ui_in[7] = 1 selects I2C.

Block diagram

                +----------------------------------------+
                |                                        |
                |   +-----------+        +-----------+   |
SPI Pins <----> |   | SPI Slave |        | I2C Slave |   | <----> I2C Pins
                |   | Interface |        | Interface |   |
                |   +-----+-----+        +-----+-----+   |
                |         ^                    ^         |
                |         |                    |         |
                |         |                    |         |
                |         v                    v         |
                |      +--+--------------------+--+      |
                |      |        Bus Arbiter       |      |
                |      +-------------+------------+      |
                |                    ^                   |
                |                    |  Internal         |
                |                    |  Register         |
                |                    |  Access Bus       |
                |                    v                   |
                |      +-------------+------------+      |
                |      |       Register Bank      |      |
                |      |                          |      |
                |      |   +------------------+   |      |
                |      |   |       REG0       |---|------|------> 7 segments display
                |      |   +------------------+   |      |
                |      |                          |      |
                |      |   +------------------+   |      |
                |      |   |       REG1       |   |      |
                |      |   +------------------+   |      |
                |      |            ...           |      |
                |      |   +------------------+   |      |
                |      |   |       REG14      |   |      |
                |      |   +------------------+   |      |
                |      |                          |      |
                |      |   +------------------+   |      |
                |      |   |       REG15      |   |      |
                |      |   +------------------+   |      |
                |      +--------------------------+      |
                |                                        |
                +----------------------------------------+

There are 8 read/write 8 bit registers and 8 read only 8 bit registers.

Address 0 (first byte in read/write register space) drives the 7 segment display.

SPI peripheral design based on https://github.com/calonso88/tt07_alu_74181

See that design's docs for information about the SPI peripheral.

Small improvement done on the spi_peripheral module. There used to be two buffer counters (one for RX and one for TX). Since the counters are not used together, it was possible to remove one of them and use a single buffer counter. This has reduced 4 flip flops in total and some combinatorial logic as well.

Added logic to control driver for MISO. On previous submissions of this design, the MISO was always driven. Logic has been added to put MISO into high impedance when CS_N is driven high. Due to a 2-stage synchronizer, the MISO goes to high impedance after 2 clock cycles.

I2C peripheral design based on https://github.com/sanojn/tt06_ttrpg_dice

See that design's docs for information about the I2C peripheral.

Protocol specification

SPI Write (CPOL = 0, CPHA = 0)

SPI Write

SPI Read (CPOL = 0, CPHA = 0)

SPI Write

I2C Frame

I2C frame

Register Map

Offset Name Access Reset Description
0x00 REG0 R/W 0x00 Controls 7 segmets display on demoboard
0x01 REG1 R/W 0x00 General prupose register
0x02 REG2 R/W 0x00 General prupose register
0x03 REG3 R/W 0x00 General prupose register
0x04 REG4 R/W 0x00 General prupose register
0x05 REG5 R/W 0x00 General prupose register
0x06 REG6 R/W 0x00 General prupose register
0x07 REG7 R/W 0x00 General prupose register
0x08 REG8 RO 0xC4 Constant ID Code 1
0x09 REG9 RO 0x10 Constant ID Code 2
0x0A REG10 RO 0xAA Constant ID Code 3
0x0B REG11 RO 0x55 Constant ID Code 4
0x0C REG12 RO 0xFF Constant ID Code 5
0x0D REG13 RO 0x00 Constant ID Code 6
0x0E REG14 RO 0xA5 Constant ID Code 7
0x0F REG15 RO 0x5A Constant ID Code 8

How to test

SPI

Use SPI1 Master peripheral in RP2040 to start communication on SPI interface towards this design. Remember to configure the SPI mode using digital inputs [0] and [1] to high (if you'd like to have CPOL=1 and CPHA=1).

Example code to initialize SPI in REPL:

spi_miso = tt.pins.pin_uio3
spi_cs = tt.pins.pin_uio4
spi_clk = tt.pins.pin_uio5
spi_mosi = tt.pins.pin_uio6
spi_miso.init(spi_miso.IN, spi_miso.PULL_DOWN)
spi_cs.init(spi_cs.OUT)
spi_clk.init(spi_clk.OUT)
spi_mosi.init(spi_mosi.OUT)
spi = machine.SoftSPI(baudrate=10000, polarity=0, phase=0, bits=8, firstbit=machine.SPI.MSB, sck=spi_clk, mosi=spi_mosi, miso=spi_miso)
spi_cs(1)

Example code to write 0xF8 to address[0]:

spi_cs(0); spi.write(b'\x80\xF8'); spi_cs(1)

This should set the 7 segment LED to 0xF8 which will display "t."

Seg A - OFF, Seg B - OFF, Seg C - OFF, Seg D - ON, Seg E - ON, Seg F - ON, Seg G - ON, Seg DP - ON

Example code to read from address[0]:

spi_cs(0); spi.write(b'\x00'); spi.read(1); spi_cs(1)

The result should be 0xF8 or whatever you wrote to address[0].

I2C

Use I2C Master peripheral in RP2040 to start communication on I2C interface towards this design. Remember to configure the I2C address bits using the digital inputs [2], [3] and [4].

Example code to initialize I2C in REPL:

TO DO

Example code to write 0xF8 to address[0]:

TO DO

Example code to read from address[0]:

TO DO

External hardware

You may need to use a pull up resistors on the i2c data and i2c scl lines if not possible to configured internally on the RP2040. To be checked at a later point in time. Write to the first register to set the LEDs on the demoboard.

IO

#InputOutputBidirectional
0cpolspare[0]
1cphaspare[1]i2c_sda
2i2c_addr[0]spare[2]i2c_scl
3i2c_addr[1]spare[3]spi_miso
4i2c_addr[2]spare[4]spi_cs_n
5spare[5]spi_clk
6spare[6]spi_mosi
7peripheral selector (SPI=0/I2C=1)spare[7]

Chip location

Controller Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux Mux tt_um_chip_rom (Chip ROM) tt_um_factory_test (Tiny Tapeout Factory Test) tt_um_htfab_asicle2 (Asicle v2) tt_um_urish_simon (Simon Says memory game) tt_um_dlmiles_ringosc_5inv (Ring Oscillator (5 inverter)) tt_um_rejunity_vga_logo (VGA Tiny Logo) tt_um_rejunity_sn76489 (Classic 8-bit era Programmable Sound Generator SN76489) tt_um_wokwi_392873974467527681 (PILIPINAS_IC) tt_um_wokwi_442081253563458561 (PRISM 8 with TinySnake) tt_um_waferspace_vga_screensaver (Wafer.space Logo VGA Screensaver) tt_um_rejunity_z80 (Zilog Z80) tt_um_MichaelBell_tinyQV (TinyQV Risc-V SoC) tt_um_calonso88_spi_i2c_reg_bank (Register bank accessible through SPI and I2C) tt_um_htfab_caterpillar (Simon's Caterpillar) tt_um_gf0p2_faust_top (Silly-Faust) tt_um_htfab_cells (Cell mux) tt_um_zedtc1_top (Zedulo TestChip1) tt_um_essen (2x2 MAC Systolic array with DFT) tt_um_BLE_RX (SCµM-BLE-RX) tt_um_kianV_rv32ima_uLinux_SoC (KianV uLinux SoC) tt_um_schoeberl_wildcat (Wildcat RISC-V) tt_um_vga_clock (VGA clock) tt_um_digital_clock_example (7-Segment Digital Desk Clock) tt_um_rejunity_vga_test01 (VGA Drop (audio/visual demo)) tt_um_a1k0n_nyancat (VGA Nyan Cat) tt_um_proppy_megabytebeat (megabytebeat) tt_um_javibajocero_top (MarcoPolo) tt_um_kercrafter_leds_racer (LEDs Racer) tt_um_noritsuna_CAN_CTRL (CAN Controller for Rocket) tt_um_algofoogle_raybox_zero (raybox-zero TTGF0p2 edition) tt_um_flummer_ltc (Linear Timecode (LTC) generator) tt_um_dlmiles_bad_synchronizer (Example of Bad Synchronizer) tt_um_multi_bit_puf_wrapper (One Bit PUF) tt_um_algofoogle_vgaringosc (Ring osc on VGA) tt_um_lisa (LISA 8-Bit Microcontroller) tt_um_mmorri22_lockpick_game (Notre Dame - Lockpick Game TT Example) tt_um_simple_riscv (Simple RISC-V) tt_um_mmorri22_cse_30342 (Notre Dame - CSE 30342 - DIC - Advanced FSM Final Project Example) tt_um_zacky1972_PVTMonitorSuite (PVTMonitorSuite) tt_um_SophusAndreassen_dogbattle (Dog Battle Game) tt_um_frequency_counter (Frequency Counter SSD1306 OLED) tt_um_wokwi_445338187869298689 (WokwiPWM) tt_um_kbeckmann_flame (Flame demo) tt_um_2048_vga_game (2048 sliding tile puzzle game (VGA)) tt_um_spi_cpu_top (Super-Simple-SPI-CPU) tt_um_urish_usb_cdc (USB CDC (Serial) Device) tt_um_htfab_vga_tester (Video mode tester) tt_um_dlmiles_ddr_throughput_test (DDR throughput and flop aperature test) tt_um_dlmiles_loopback (GF180MCU loopback tile with input skew measurement) tt_um_thezoq2_quickscope (Quickscope) tt_um_MATTHIAS_M_PAL_TOP_WRAPPER (easy PAL) tt_um_htfab_rotfpga2 (ROTFPGA v2)