Skip to content

Commit

Permalink
initial SPI DMA support
Browse files Browse the repository at this point in the history
  • Loading branch information
Guy Sviry committed Sep 2, 2023
1 parent 31f505f commit 7fdf050
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 3 deletions.
31 changes: 29 additions & 2 deletions src/peripherals/spi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { RP2040 } from '../rp2040';
import { FIFO } from '../utils/fifo';
import { DREQChannel } from './dma';
import { BasePeripheral, Peripheral } from './peripheral';

const SSPCR0 = 0x000; // Control register 0, SSPCR0 on page 3-4
Expand Down Expand Up @@ -58,6 +59,11 @@ const SSPRXINTR = 1 << 2;
const SSPRTINTR = 1 << 1;
const SSPRORINTR = 1 << 0;

export interface ISPIDMAChannels {
rx: DREQChannel;
tx: DREQChannel;
}

export class RPSPI extends BasePeripheral implements Peripheral {
readonly rxFIFO = new FIFO(8);
readonly txFIFO = new FIFO(8);
Expand Down Expand Up @@ -105,8 +111,26 @@ export class RPSPI extends BasePeripheral implements Peripheral {
return this.rp2040.clkPeri / (this.clockDivisor * (1 + scr));
}

constructor(rp2040: RP2040, name: string, readonly irq: number) {
private updateDMATx() {
if (this.txFIFO.full) {
this.rp2040.dma.clearDREQ(this.dreq.tx);
} else {
this.rp2040.dma.setDREQ(this.dreq.tx);
}
}

private updateDMARx() {
if (this.rxFIFO.empty) {
this.rp2040.dma.clearDREQ(this.dreq.rx);
} else {
this.rp2040.dma.setDREQ(this.dreq.rx);
}
}

constructor(rp2040: RP2040, name: string, readonly irq: number, readonly dreq: ISPIDMAChannels) {
super(rp2040, name);
this.updateDMATx()
this.updateDMARx()
}

private doTX() {
Expand Down Expand Up @@ -159,6 +183,7 @@ export class RPSPI extends BasePeripheral implements Peripheral {
case SSPDR:
if (!this.rxFIFO.empty) {
const value = this.rxFIFO.pull();
this.updateDMARx();
this.fifosUpdated();
return value;
}
Expand Down Expand Up @@ -211,8 +236,10 @@ export class RPSPI extends BasePeripheral implements Peripheral {
return;
case SSPDR:
if (!this.txFIFO.full) {
this.txFIFO.push(value);
// decoded with respect to SSPCR0.DSS
this.txFIFO.push(value & ((1<<this.dataBits)-1));
this.doTX();
this.updateDMATx();
this.fifosUpdated();
}
return;
Expand Down
10 changes: 9 additions & 1 deletion src/rp2040.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export class RP2040 {
}),
];
readonly i2c = [new RPI2C(this, 'I2C0', IRQ.I2C0), new RPI2C(this, 'I2C1', IRQ.I2C1)];
readonly spi = [new RPSPI(this, 'SPI0', IRQ.SPI0), new RPSPI(this, 'SPI1', IRQ.SPI1)];
readonly pwm = new RPPWM(this, 'PWM_BASE');
readonly adc = new RPADC(this, 'ADC');

Expand Down Expand Up @@ -121,6 +120,15 @@ export class RP2040 {
new RPPIO(this, 'PIO1', IRQ.PIO1_IRQ0, 1),
];
readonly usbCtrl = new RPUSBController(this, 'USB');
readonly spi = [
new RPSPI(this, 'SPI0', IRQ.SPI0, {
rx: DREQChannel.DREQ_SPI0_RX,
tx: DREQChannel.DREQ_SPI0_TX,
}),
new RPSPI(this, 'SPI1', IRQ.SPI1, {
rx: DREQChannel.DREQ_SPI1_RX,
tx: DREQChannel.DREQ_SPI1_RX,
})];

private stopped = true;

Expand Down

0 comments on commit 7fdf050

Please sign in to comment.