SPI Registers

SPI Registers

Registers #

Old3DSNameAddressWidthUsed by
YesSPI_CNT10x101420002
YesSPI_DATA10x101420021
YesNSPI_CNT10x101428004
YesNSPI_DONE10x101428044
YesNSPI_BLKLEN10x101428084
YesNSPI_FIFO10x1014280C4
YesNSPI_STATUS10x101428104
YesNSPI_AUTOPOLL10x101428144-
YesNSPI_INT_MASK10x101428184-
YesNSPI_INT_STAT10x1014281C4-
YesSPI_CNT20x101430002
YesSPI_DATA20x101430021
YesNSPI_CNT20x101438004
YesNSPI_DONE20x101438044
YesNSPI_BLKLEN20x101438084
YesNSPI_FIFO20x1014380C4
YesNSPI_STATUS20x101438104
YesNSPI_AUTOPOLL20x101438144-
YesNSPI_INT_MASK20x101438184-
YesNSPI_INT_STAT20x1014381C4-
YesSPI_CNT30x101600002
YesSPI_DATA30x101600021
YesNSPI_CNT30x101608004
YesNSPI_DONE30x101608044
YesNSPI_BLKLEN30x101608084
YesNSPI_FIFO30x1016080C4
YesNSPI_STATUS30x101608104
YesNSPI_AUTOPOLL30x101608144-
YesNSPI_INT_MASK30x101608184-
YesNSPI_INT_STAT30x1016081C4-

There are two register interfaces: the old NDS/DSi one and an alternative faster interface introduced with the 3DS.

To toggle between those interfaces, use the CFG11_SPI_CNT register.

SPI_CNT #

This is the old NDS/DSi SPI interface.

BitsName
0-1Baudrate (0=4MHz, 1=2MHz, 2=1MHz, 3=512KHz)
2-6This was added with 3DS.
7Busy Flag (0=Ready, 1=Busy) (presumably Read-only)
8-9Device Select (0=Powerman., 1=Firmware, 2=Touchscreen)
10Transfer Size (0=8bit/Normal, 1=16bit/Bugged)
11Chipselect Hold (0=Deselect after transfer, 1=Keep selected)
12-13Not used (Zero)
14Interrupt Request (0=Disable, 1=Enable)
15SPI Bus Enable (0=Disable, 1=Enable)

NSPI_CNT #

This is an alternative faster interface introduced with the 3DS.

BitsName
0-2Clock
6-7Device select
12Bus mode (0 = 1 bit, 1 = 4 bit)
13Transfer direction (0 = read, 1 = write)
151 = Busy/enable
Device idBusDevice selectClock
0302
1, 231, 2?, ?
3105
4, 511, 2?, ?
620?

NSPI_DONE #

BITDESCRIPTION
0Chip select
1-31Unused

Contains 1 when the SPI slave is selected. A 0 is written here on transfer end to deselect the slave.

NSPI_BLKLEN #

BITDESCRIPTION
0-20Transfer size
21-31Unused

The number of bytes to be sent/read is written to this register.

NSPI_FIFO #

BITDESCRIPTION
0-31Data

32-bit FIFO for reading/writing the SPI payload. This FIFO is one way (half-duplex).

NSPI_STATUS #

BITDESCRIPTION
0FIFO full (0 = not full, 1 = full)
1-31Unused

At transfer start and every 32 bytes the FIFO becomes busy.

NSPI_AUTOPOLL #

BITDESCRIPTION
0-7Command
16-19Timeout (Tries = 31<<Clock (from NSPI_CNT) + Timeout)
24-26Bit offset (0-7)
30Poll for a set or unset bit
311 = Enable/Busy

This automatically sends a command to the device and compares the specified bit in the response with bit 30 until it matches or a timeout occurs.

NSPI_INT_MASK #

BITDESCRIPTION
0Transfer finished (1 = disabled)
1Autopoll success (1 = disabled)
2Autopoll timeout (1 = disabled)

NSPI_INT_STAT #

BITDESCRIPTION
0Transfer finished (also fires on each autopoll try?)
1Autopoll success
2Autopoll timeout

Interrupt ID 0x24, 0x56 or 0x57 (depending on the bus) is fired when any of the bits change to 1 except for interrupts masked in NSPI_INT_MASK. Writing 1 to a bit in this register aknowledges the interrupt.