mjs513
Senior Member+
@KurtE
I took you sketch and broke it up into a Master and Slave sketch so I could test a few things. Right now its set up to go from SPI to SPI and of course it has our pin changes to it. What I was testing was sending more than 1 sample from the Master to the Slave.
On the Master I have:
and the slave sketch I have:
what I am seeing as being received on the slave is:
It gets the first 3 correct but why its not getting the rest correct?
EDIT: I did notice this in DMAChannel.h
I took you sketch and broke it up into a Master and Slave sketch so I could test a few things. Right now its set up to go from SPI to SPI and of course it has our pin changes to it. What I was testing was sending more than 1 sample from the Master to the Slave.
On the Master I have:
Code:
#include <DMAChannel.h>
#include <SPI.h>
#define PRREG(x) Serial.print(#x" 0x"); Serial.println(x, BIN) //Serial.println(x,BIN)
#define SAMPLES 1
#define SPIM SPI
#define CS_MASTER 10
volatile bool received_data = false;
DMAMEM static uint16_t rx_buffer[SAMPLES];
uint16_t loop_count = 0;
void setup() {
while (!Serial);
Serial.begin(115200);
// I am going to use SPI1 as the master.
SPIM.begin(); // initialize it...
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_01 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 SDI (MISO) */
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_02 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 SDO (MOSI) */
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 SCK (CLK) */
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_00 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 PCS0 (CS) */
pinMode(CS_MASTER, OUTPUT);
digitalWrite(CS_MASTER, HIGH);
}
void loop() {
elapsedMicros emloop = 0;
received_data = false;
digitalWrite(CS_MASTER, LOW);
[COLOR="#FF0000"] SPIM.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
//uint16_t spi_returned_data = SPIM.transfer16(loop_count);
SPIM.transfer16(0x9254);
SPIM.transfer16(0x06);
SPIM.transfer16(0x01);
SPIM.transfer16(0x02);
SPIM.transfer16(0x03);
SPIM.transfer16(0xD0D0);
SPIM.endTransaction();[/COLOR]
//while (!received_data && (emloop < 250000)) ;
//Serial.printf("SPI Transfer: %x Return: %x delay: %d\n", loop_count, spi_returned_data,(uint32_t)emloop);
digitalWrite(CS_MASTER, HIGH);
delay(250);
loop_count++;
}
Code:
#include <DMAChannel.h>
#include <SPI.h>
#define PRREG(x) Serial.print(#x" 0x"); Serial.println(x, BIN) //Serial.println(x,BIN)
#define SAMPLES 6
#define SPIS SPI
#define ChipSelectSlave 10
IMXRT_LPSPI_t *spis_regs = &IMXRT_LPSPI4_S;
#define SPIS_DMAMUX_SOURCE_RX DMAMUX_SOURCE_LPSPI4_RX
volatile bool received_data = false;
DMAMEM static uint16_t rx_buffer[SAMPLES];
uint16_t loop_count = 0;
DMAChannel rx(false);
void rxISR() {
rx.clearInterrupt();
received_data = true;
arm_dcache_delete(rx_buffer, SAMPLES); //delete Cache!
spis_regs->TDR = rx_buffer[0]; //Transmit data back to the Master
asm volatile ("dsb");
}
bool initSPISlaveDMA() {
rx.begin(true);
rx.source((uint16_t &) spis_regs->RDR); //receiving data from the master
rx.triggerAtHardwareEvent(SPIS_DMAMUX_SOURCE_RX);
rx.attachInterrupt(rxISR);
rx.interruptAtCompletion(); //TCD->CSR |= DMA_TCD_CSR_INTMAJOR;
rx.destinationBuffer(rx_buffer, SAMPLES + 1);
rx.enable();
return 1;
}
bool initSPISlave() {
spis_regs->CR &= ~LPSPI_CR_MEN; //Modul ausschalten
spis_regs->CR = LPSPI_CR_RST; //Master Logic reset! (Control Register => Software Reset)
spis_regs->CR &= ~LPSPI_CR_RST; //Master Logic reset! (Control Register => Software Reset)
spis_regs->TCR = LPSPI_TCR_FRAMESZ(15); //16Bit Mode
spis_regs->DER = LPSPI_DER_RDDE; //RX DMA Request Enable
spis_regs->CR |= LPSPI_CR_MEN; //Enable SPI Module!
return 1;
}
void setup() {
while (!Serial);
Serial.begin(115200);
// I am going to use SPI1 as the master.
//SPIM.begin(); // initialize it...
//pinMode(CS_MASTER, OUTPUT);
//digitalWrite(CS_MASTER, HIGH);
SPIS.begin();
pinMode(ChipSelectSlave, INPUT);
uint8_t cs_mask = SPIS.setCS(ChipSelectSlave);
Serial.printf("Slave CS: %d set: %x\n", ChipSelectSlave, cs_mask);
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_01 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 SDI (MISO) */
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_02 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 SDO (MOSI) */
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_03 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 SCK (CLK) */
IOMUXC_SW_PAD_CTL_PAD_GPIO_B0_00 = IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3) | IOMUXC_PAD_PKE; /* LPSPI4 PCS0 (CS) */
Serial.println("Init SPI!");
if (initSPISlave()) {
Serial.println("SPI SLAVE init!");
}
if (initSPISlaveDMA()) {
Serial.println("DMA Channel init!");
}
}
void loop() {
if(received_data) {
for(uint16_t i = 0; i < SAMPLES; i++){
Serial.printf("SPI Transfer: %d %x\n", i, rx_buffer[i]);
}
Serial.println();
//received_data = false;
}
}
Code:
SPI Transfer: 0 9254
SPI Transfer: 1 6
SPI Transfer: 2 1
SPI Transfer: 3 54ba
SPI Transfer: 4 4091
SPI Transfer: 5 3a4c
EDIT: I did notice this in DMAChannel.h
But not sure how to say don't do half?// An interrupt routine can be run when the DMA channel completes
// the entire transfer, and also optionally when half of the
// transfer is completed.
Last edited: