I configured the SPI as follows, but I am constantly reading 0s from SPI_RDR, the RDRF flag was never raised either.
void setup() {
Serial.begin(9600);
//SPI serial recieve
REG_PMC_PCER0 |= PMC_PCER0_PID24;// Power up SPI clock
REG_SPI0_WPMR = 0<<SPI_WPMR_WPEN;//Unlock user interface for SPI
//Instance SPI0, MISO: PA25, (MISO), MOSI: PA26, (MOSI), SCLK: PA27, (SCLK), NSS: PA28, (NPCS0)
REG_PIOA_ABSR |= PIO_ABSR_P25; // Transfer Pin control from PIO to SPI
REG_PIOA_PDR |= PIO_PDR_P25; // Set MISO pin to an output
REG_PIOA_ABSR |= PIO_ABSR_P26; // Transfer Pin control from PIO to SPI
//REG_PIOA_PDR |= 0<<PIO_PDR_P26; // Set MOSI pin to an input
REG_PIOA_ABSR |= PIO_ABSR_P27; // Transfer Pin control from PIO to SPI
//REG_PIOA_PDR |= 0<<PIO_PDR_P27; // Set SCLK pin to an input
REG_PIOA_ABSR |= PIO_ABSR_P28; // Transfer Pin control from PIO to SPI
//REG_PIOA_PDR |= 0<<PIO_PDR_P28; // Set NSS pin to an input
REG_SPI0_CR |= SPI_CR_SPIEN; // Enable SPI
REG_SPI0_MR = 0<<SPI_MR_MSTR; // Slave mode
}
void loop() {
// put your main code here, to run repeatedly:
//if(REG_SPI0_SR&0x0001 == 1)
//{
int result = REG_SPI0_RDR;
Serial.println(result);
delayMicroseconds(1);
//}
}
Due_Fast_PWM.ino.ino (2.96 KB)
Never mind I figure that out.
Here’s my code:
//SPI serial recieve
REG_PMC_PCER0 |= PMC_PCER0_PID24;// Power up SPI clock
REG_SPI0_WPMR = 0<<SPI_WPMR_WPEN;//Unlock user interface for SPI
//Instance SPI0, MISO: PA25, (MISO), MOSI: PA26, (MOSI), SCLK: PA27, (SCLK), NSS: PA28, (NPCS0)
REG_PIOA_ABSR |= PIO_ABSR_P25; // Transfer Pin control from PIO to SPI
REG_PIOA_PDR |= PIO_PDR_P25; // Set MISO pin to an output
REG_PIOA_ABSR |= PIO_ABSR_P26; // Transfer Pin control from PIO to SPI
REG_PIOA_PDR |= 0<<PIO_PDR_P26; // Set MOSI pin to an input
REG_PIOA_ABSR |= PIO_ABSR_P27; // Transfer Pin control from PIO to SPI
REG_PIOA_PDR |= 0<<PIO_PDR_P27; // Set SCLK pin to an input
REG_PIOA_ABSR |= PIO_ABSR_P28; // Transfer Pin control from PIO to SPI
REG_PIOA_PDR |= 0<<PIO_PDR_P28; // Set NSS pin to an input
//REG_ISER0 = 1<<24; //Enable interrupt controller
REG_SPI0_CR = 1; // Enable SPI
REG_SPI0_MR = 0; // Slave mode
REG_SPI0_IER = 1<<SPI_IER_RDRF|1<<SPI_IER_OVRES|1<<SPI_IER_NSSR; //Enable interrupts
SPI0->SPI_CSR[0] = SPI_CSR_NCPHA|SPI_CSR_BITS_12_BIT; // Shift on falling edge and transfer 12 bits.
1 Like
Here is an example sketch to test SPI0 in loopback:
/********************************************************************************/
/** SPI in local or remote loopback with interruptions **/
/** Connect MISO to MOSI pins on a single board **/
/********************************************************************************/
volatile uint32_t DataReceived;
volatile boolean Flag_SPI;
void setup() {
Serial.begin(250000);
PMC->PMC_PCER0 |= PMC_PCER0_PID24; // SPI0 power ON
// Program the PIO controllers to assign
// the SPI output pins to their peripheral functions (page 679)
PIOA->PIO_PDR = PIO_PDR_P25
| PIO_PDR_P26
| PIO_PDR_P27
| PIO_PDR_P28;
PIOA->PIO_ABSR &= ~(PIO_PA25A_SPI0_MISO
| PIO_PA26A_SPI0_MOSI
| PIO_PA27A_SPI0_SPCK
| PIO_PA28A_SPI0_NPCS0);
// SPI Disable
SPI0->SPI_CR = SPI_CR_SPIDIS;// SPI is in slave mode after software reset !!
// Perform a SPI software reset twice, like SAM does.
SPI0->SPI_CR = SPI_CR_SWRST;
SPI0->SPI_CR = SPI_CR_SWRST;
delay(10);
// SPI0 operates in Master mode, local loopback
SPI0->SPI_MR = SPI_MR_MSTR
| SPI_MR_MODFDIS // Disable Mode Fault detection
| SPI_MR_WDRBT // Wait data read before Transfer
| SPI_MR_LLB // Local loopback (MISO -->MOSI)
| SPI_MR_PCS(0b1110)
| SPI_MR_DLYBCS(0b01111111); // Maximum delay between Chip Selects
// Data transfer parameters
SPI0->SPI_CSR[0] |= SPI_CSR_CPOL // Inactive state value of SPCK is logic level one
| SPI_CSR_NCPHA // Data is captured on the leading edge of SPCK and changed on the following edge
| SPI_CSR_CSNAAT // Chip select active after transfer
| SPI_CSR_BITS_16_BIT // Bits per transfer
| SPI_CSR_SCBR(100) // slowest bit rate
| SPI_CSR_DLYBS(100); // Maximum delay from NPCS falling edge (activation)
// to the first valid SPCK transition
// Receive Data Register Full Interrupt and
// Transmit Data Register Empty Interrupt Enable
SPI0->SPI_IER = SPI_IER_RDRF | SPI_IER_TDRE;
NVIC_EnableIRQ(SPI0_IRQn);
SPI0->SPI_CR = SPI_CR_SPIEN; // Enable SPI0
}
void loop() {
if (Flag_SPI) {
Serial.print(" Data Received = 0b"); Serial.println( DataReceived & 0xFFFF, BIN);
Flag_SPI = false;
delay(1000);
}
}
void SPI0_Handler() {
uint16_t DataSend = 0b1100110011001100;
uint32_t status = SPI0->SPI_SR;
if ((status & SPI_SR_TDRE) == SPI_SR_TDRE) SPI0->SPI_TDR |= SPI_TDR_TD(DataSend);
if ((status & SPI_SR_RDRF) == SPI_SR_RDRF) {
DataReceived = SPI0->SPI_RDR & SPI_RDR_RD_Msk;
Flag_SPI = true;
}
}