Here's some direct register access SPI code. Sends a command to an encoder to read position and reads back 8 bytes of data. Long but tested working..
NOTE: Best to remove extra CR's in this paste in - not sure why they occur
static void
prvSetupHardware( void )
{
static unsigned char encoder[1000];
/* Enable the interrupt on SW1. */
taskDISABLE_INTERRUPTS();
#define
WANT_SPI_MUX_SETUP
#ifdef
WANT_SPI_MUX_SETUP
#define
BYTES_TO_READ 8
// Turn on the SPI0 clock
SIM_SCGC6 |= SIM_SCGC6_DSPI0_MASK;
// PTE26 A0 - encode mux selection
// PTE27 A1
// PTE28 A2
// PTE12 A3
PORTE_PCR26 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK |
PORT_PCR_DSE_MASK;
PORTE_PCR27 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK |
PORT_PCR_DSE_MASK;
PORTE_PCR28 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK |
PORT_PCR_DSE_MASK;
PORTE_PCR12 = PORT_PCR_MUX( 1 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK |
PORT_PCR_DSE_MASK;
GPIOE_PDDR |= (1<<26);
GPIOE_PDDR |= (1<<27);
GPIOE_PDDR |= (1<<28);
GPIOE_PDDR |= (1<<12);
// Set mult out A0-A2 to 0 ENDAT mux
GPIOE_PDOR &= ~((1<<26) |
(1<<27) | (1<<27) | (1<<12) );
// Set up needed pins for SPI0
// PTD0 - CS0
// PTD1 - Clock
// PTD2 - DOut
// PTD3 - DIn
// All pins - ALT2 config for SPI0, nor
IRQ/DMA, high drive strength and fast slew (0 for fast slew)
PORTD_PCR0 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK |
PORT_PCR_DSE_MASK;
PORTD_PCR1 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK |
PORT_PCR_DSE_MASK;
PORTD_PCR2 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_SRE_MASK |
PORT_PCR_DSE_MASK;
PORTD_PCR3 = PORT_PCR_MUX( 2 ) |
PORT_PCR_IRQC(0) | PORT_PCR_PE_MASK /* |
PORT_PCR_PS_MASK */ ; //pull down
// PTE26, 27, 28, 12 output for encoder mux selection. pull down.
// Set up the SPI0 MCR register for what we
need
// Looks like we need:
//
Use Master mode - the encoder is the slave
//
Continuous clock?
//
?? Use CS5 as peripheral CS ?? - Need to enable it in PCR
//
PCS lines - set active low or high - use high for now (1 = inactive
high)
//
Clear TX Fifo (1)
//
Clear RX Fif0 (1)
//
Run SCLK Continuous (1)
SPI0_MCR = SPI_MCR_HALT_MASK | // stop the SPI;
SPI_MCR_MSTR_MASK | // master mode
SPI_MCR_CONT_SCKE_MASK | // sclk cont
SPI_MCR_DCONF(0) | // SPI mode
// SPI_MCR_PCSSE_MASK | //cs5 continuous
SPI_MCR_PCSIS(1) | // cs0 inactive hi
SPI_MCR_CLR_RXF_MASK |
SPI_MCR_CLR_TXF_MASK ; // Last
//for (int z=0; z<13; z++)
printf(".");
// CTOR configuration
// We want:
//
Double baud rate?
//
Frame size is 8 (size is fmsz+1)
//
Delay
//
Close phase - output fulling receive falling
SPI0_CTAR0 = (/*
SPI_CTAR_DBR_MASK*/ SPI_CTAR_FMSZ(7)
// BR 5 and PBR 0 is 1Mhz
// BR 4 and PBR 0 is 2Mhz - this doesnt
work
| SPI_CTAR_PDT(7) | SPI_CTAR_BR(5) |
SPI_CTAR_PBR(0) |
SPI_CTAR_CPHA_MASK |
SPI_CTAR_LSBFE_MASK |
SPI_CTAR_PCSSCK(0) |
SPI_CTAR_CSSCK(3) );
// SPI_CTAR_CPOL_MASK );
#ifdef
ENCODER_STARTUP
while ( 1 ) {
// Do a read and wait
SPI0_MCR = ~SPI_MCR_HALT_MASK &
SPI0_MCR; // clear the halt bit
unsigned char command = 0x70; // read
//unsigned char command = 0x5a; // read w/ reset
// Clear tranfer count register
// SPI0_TCR = 0;
int spi_cnt;
for (spi_cnt=0;
spi_cnt<BYTES_TO_READ; spi_cnt++ )
{
SPI0_PUSHR = (command | SPI_PUSHR_CONT_MASK | SPI_PUSHR_PCS(1) |
SPI_PUSHR_CTAS(0));
//while (!(SPI0_SR &
SPI_SR_TFFF_MASK) );
command = spi_cnt+1;
while (!(SPI0_SR &
SPI_SR_RFDF_MASK) );
unsigned char byte;
encoder[spi_cnt] = SPI0_POPR;
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not
self-clearing)
//printf("byte read
%0x\n",SPI0_POPR );
}
// Last byte transfer/receiver
command = 0xff;
SPI0_PUSHR = (command | /* SPI_PUSHR_CONT_MASK | */
SPI_PUSHR_PCS(1) | SPI_PUSHR_CTAS(0));
while (!(SPI0_SR &
SPI_SR_TFFF_MASK) ); // wait for transmit
while (!(SPI0_SR &
SPI_SR_RFDF_MASK) );
unsigned char junk = SPI0_POPR;
SPI0_SR = SPI_SR_RFDF_MASK; // clear the reception flag (not
self-clearing)
}