Anda di halaman 1dari 5

Nathan Barrett 9/30/14

Page 1 of 5

Beaglebone Black SPI Through PRU

You must set SPI up to run by using the previously described BB-SPIDEV9 overlay and
disabling HDMI. Again, P9.31 is SPI Clock, P9.30 is the stream being sent out (this
could also be P9.29 depending on settings). This is McSPI 1 channel 1 in the AM335X
manual.

This program will pass a word, number of words, and frequency to one of the PRU units.
The PRU will then repeatedly send the selected word out of the SPI channel for the
number of words at the specified frequency.

Note: The DTBO frequency is now superseded by the PRUs settings. It doesnt matter
what its set to in the BB-SPIDEV9 overlay.

Program Usage:

./SPI [word] [num words] [frequency (0-15)]

# ./SPI 808464432 1 0

INFO: Initializing.
INFO: Transmitting 808464432 (1 times) at 48000000 Hz
INFO: Sending...PRU program completed (4), in 0 seconds

This sends 0x30303030 down 1 time at 48 Hz. The resulting analyzer shot looks
something like this:

A B Interval: 20 ns

Doing multiples:

A B Cycles: 160 A B Interval: 3.584 S

How does this compare to the expected 48 MHz?

3584 ns / 160 cycles = 22.4 ns / cycle


So 1 / (22.4 * (10^-9)) = 44.64 MHz
Nathan Barrett 9/30/14
Page 2 of 5

How far can we push it? Lets send 128 MB at 48 MHz and watch the CPU usage.

# ./SPI 808464432 33554432 0 &

INFO: Initializing.
INFO: Transmitting 808464432 (33554432 times) at 48000000 Hz
INFO: Sending...PRU program completed (6), in 24 seconds

While sending, the main CPU is sitting around 99% idle

128 MB @ 24 seconds = 5.33 megabytes / sec

How about 24 MHz? This previously took about 60 seconds through the main processor.

./SPI 808464432 33554432 1


INFO: Initializing.
INFO: Transmitting 808464432 (33554432 times) at 24000000 Hz
INFO: Sending...PRU program completed (9), in 47 seconds

Cycles AB: 512 Interval A B: 22.27 S

22.27 S for 512 cycles = 43.49 ns per cycle


1/(43.49 * (10^-9)) = 22.99 MHz over 64 bytes

This is a few MHz faster.


Nathan Barrett 9/30/14
Page 3 of 5

Bulk DMA could also be set up to offload PRU usage as well. Currently, the PRU is
jamming 0x30303030 into the SPI FIFO repeatedly.

Multichannel Serial Port Interface (McSPI)

Clock Signal Max Freq Reference / Source Comments


CLK 100 MHz CORE_CLKOUTM4 / 2 pd_per_l4ls_gclk
Interface clock
From PRCM
CLKSPIREF 48 MHz PER_CLKOUTM2 / 4 pd_per_spi_gclk
Functional clock
From PRCM
Table 24-3. McSPI Clock Signals

Pin Type Description


SPIx_SCLK I/O SPI serial clock (output when master,
input when slave)
SPIx_D0 I/0 Can be configured as either input or
output (MOSI or MISO)
SPIx_D1 I/0 Can be configured as either input or
output (MOSI or MISO)
SPIx_CS0 I/0 SPI chip select 0 output when master,
input when slave (active low)
SPIx_CS1 O SPI chip select 1 output when master,
input when slave (active low)
Table 24-4. McSPI Pin List

Relevant Registers:

CM_PER_SPI1_CLKCTRL @ 0x44E00050
Enable the Clock

MCSPI_SYSCONFIG @ 0x481A0110
Reset the SPI

MCSPI_SYSSTATUS @ 0x481a0114
Check Reset Completed

MCSPI_MODULCTRL @ 0x481A0128
Turn DMA off (for now)

MCSPI_SYSCONFIG @ 0x481A0110
Automatic OCP clock gating strategy is applied, based on the
OCP interface activity.
Nathan Barrett 9/30/14
Page 4 of 5

Smart-idle mode: local target's idle state eventually follows


(acknowledges) the system's idle requests, depending on the IP
module's internal requirements.

Clocks activity during wake-up mode period.


3h = OCP and Functional clocks are maintained.

MCSPI_IRQSTATUS @ 0x481A0118
Disable Interrupts

MCSPI_CH1CTRL @ 0x481A0148
Turn on/off SPI CH1

MCSPI_CH1CTRL @ 0x481A0140
Set polarity, phases, frequencies, word length, tx/rx registers, etc

MCSPI_CH1STAT @ 0x481A0144
Check buffer empty/full

MCSPI_TX1 @ 0x481A014C
Load in data to transfer

MCSPI_XFERLEVEL @ 0x481A017C
Could set this up to take advantage of larger FIFO sizes. Currently not being used
Nathan Barrett 9/30/14
Page 5 of 5

PRU Initialization for SPI


1) Load Device Tree Overlay to Enable PRU
echo "BB-BONE-PRU-01" > /sys/devices/bone_capemgr.*/slots
2) Load Device Tree Overlay to Enable SPI
echo "BB-SPIDEV9" > /sys/devices/bone_capemgr.*/slots

(./init script will do both of these)

// Enable OCP master port


LBCO r0, CONST_PRUCFG, 4, 4 //Config SYSCONFIG
CLR r0, r0, 4 MOV r1, 0x481A0110
SBCO r0, CONST_PRUCFG, 4, 4 MOV r2, 0x00000311
SBBO r2, r1, 0, 4
//C28 will point to 0x00012000
//(PRU shared RAM) //Reset interrupt status bits
MOV r0, 0x00000120 MOV r1, 0x481A0118
MOV r1, CTPPR_0 MOV r2, 0xFFFFFFFF
ST32 r0, r1 SBBO r2, r1, 0, 4

// Enable CLKSPIREF and CLK //Disable interupts


MOV r1, 0x44E00050 MOV r1, 0x481A011C
MOV r2, 0x00000002 MOV r2, 0x00000000
SBBO r2, r1, 0, 4 SBBO r2, r1, 0, 4

// Reset SPI // Disable channel 1


MOV r1, 0x481A0110 MOV r1, 0x481A0148
LBBO r2, r1, 0, 4 MOV r2, 0x00000000
SET r2.t1 SBBO r2, r1, 0, 4
SBBO r2, r1, 0, 4
// Configure channel 1 of MCSPI1
//Wait for RESET MOV r1, 0x481A0140
RESET: MOV r2, 0x000192FC0
MOV r1, 0x481a0114 LBCO r4, CONST_PRUSHAREDRAM,
LBBO r2, r1, 0, 4 8, 4 //frequency
QBBC RESET, r2.t0 OR r2, r2,r4
SBBO r2, r1, 0, 4
//Config MODULCTRL
MOV r1, 0x481A0128
MOV r2, 0x00000000
SBBO r2, r1 , 0, 4