Anyone with any tips on good practices when debugging spi communication. Could be a problem with my initialization or with my external eeprom device. i have an oscilloscope but don't know how to use it as a protocol analyzer. [hyperterminal?, cheap external equipment???] want to know what others use.
First is my intialization which includes sci0 and spi.
Then i include my 2 functions which set commands and transfers data out the queue. Do i have the right concept? [more curious on how to use received buffer ram(read function).]
void setup_qsmcm()
{
//Has 2 sci interfaces and has 1 qspi
QSMCM.QSMCR.B.STOP = 0;
QSMCM.QSMCR.B.FRZ1 = 0;
QSMCM.QSMCR.B.SUPV = 0;
//keep registers access as global not restricted
//Setup Interrupt Pins
QSMCM.QDSCI_IL.B.ILDSCI = 5; // define SCIIRQ at level 5
QSMCM.SCC1R1.B.TIE = 0; // disable transmit interrupt;
QSMCM.SCC1R1.B.TCIE = 0; // disable transmit complete interrupt;
QSMCM.SCC1R1.B.RIE = 1; // enable receiver interrupt;
QSMCM.SCC1R1.B.ILIE = 0; // disable idle-line interrupt;
//Before changing register values, allow the SCI to complete the current transfer,
//then disable the receiver and transmitter.
QSMCM.SCC1R0.B.SC1BR = 40000000/32/9600; // Set 9600 Baud 40000000/32/9600; = 0b0000010000010;
//SCI Control Register
QSMCM.SCC1R1.B.LOOPS = 0;
QSMCM.SCC1R1.B.WOMS = 0; // normal CMOS output [only when configured as output txd]
QSMCM.SCC1R1.B.ILT = 0; // idle-line; 0=short; 1=long
QSMCM.SCC1R1.B.PT = 0; // 0 = even; 1 = odd
QSMCM.SCC1R1.B.PE = 0; // parity disabled
QSMCM.SCC1R1.B.M = 0; // mode select: 0 = 10 bit mode; 1 = 11 bit mode
QSMCM.SCC1R1.B.WAKE = 0; // wakup by address mark; 0 = idle line detection; 1 = address mark (last bit set)
QSMCM.SCC1R1.B.RWU = 0; // normal receiver operation (received data recognized); 1 = wakeup mode enabled (ignore data until awakened)
QSMCM.SCC1R1.B.SBK = 0; // send break 0=normal; 1 = break frame(s)
QSMCM.SC1DR.R = 0x00; // intialize first char to transmit, aka, null
QSMCM.SCC2R0.B.SC2BR = 0; // disable baud rate generator for sci2
QSMCM.SCC2R1.B.LOOPS = 0;
QSMCM.SCC2R1.B.WOMS = 0;
QSMCM.SCC2R1.B.ILT = 0;
QSMCM.SCC2R1.B.PT = 0;
QSMCM.SCC2R1.B.PE = 0;
QSMCM.SCC2R1.B.M = 0;
QSMCM.SCC2R1.B.WAKE = 0;
QSMCM.SCC2R1.B.TIE = 0;
QSMCM.SCC2R1.B.TCIE = 0;
QSMCM.SCC2R1.B.RIE = 0;
QSMCM.SCC2R1.B.ILIE = 0;
QSMCM.SCC2R1.B.RWU = 0;
QSMCM.SCC2R1.B.SBK = 0;
QSMCM.SCC2R1.B.TE = 0;
QSMCM.SCC2R1.B.RE = 0;
//desktop to controller communication
QSMCM.SCC1R1.B.TE = 1; // Enable Transmitter
QSMCM.SCC1R1.B.RE = 1; // Enable Reciever
/*
// when sci as a queue
QSMCM.SCRQ[0].B
// 16 bits; 16 blocks
QSMCM.SCTQ[0].B
// 16 bits; 16 blocks
*/
// above 2 sci initialized
//-----------------------------------------------------------------------
// below 1 qspi initialized
QSMCM.SPCR1.B.SPE = 0; //disable qspi
// PORTQS Pin Assignment Register (Basically prepare to be setup as a QSPI)
QSMCM.PQSPAR.B.QPAPCS3 = 1; // 1 = Pin is assigned PCS3 function else GPIO pin
QSMCM.PQSPAR.B.QPAPCS2 = 1; // 1 = Pin is assigned PCS2 function else GPIO pin
QSMCM.PQSPAR.B.QPAPCS1 = 1; // 1 = Pin is assigned PCS1 function else GPIO pin
QSMCM.PQSPAR.B.QPAPCS0 = 1; // 1 = Pin is assigned PCS[0] function else GPIO pin
QSMCM.PQSPAR.B.QPAMOSI = 1; // 1 = Pin is assigned MOSI function
QSMCM.PQSPAR.B.QPAMISO = 1; // 1 = Pin is assigned MISO function
//PORTQS Data Direction Register (DDRQS)
QSMCM.DDRQS.B.QDDPCS3 = 1;
QSMCM.DDRQS.B.QDDPCS2 = 1;
QSMCM.DDRQS.B.QDDPCS1 = 1;
QSMCM.DDRQS.B.QDDPCS0 = 1;
// pins serve as chip selecter; therefore enable all PCS pins as outputs.
// currently only using QDDPCS0
QSMCM.DDRQS.B.QDDSCK = 1; // 1 = Pin direction is output
QSMCM.DDRQS.B.QDDMOSI = 1; // 1 = Pin direction is output; master output slave input
QSMCM.DDRQS.B.QDDMISO = 0; // 0 = Pin direction is input; master input slave ouput
QSMCM.SPCR0.B.MSTR = 1; // 1 = QSPI is the system master and can initiate transmission to external SPI devices.
QSMCM.SPCR0.B.WOMQ = 0; // 0 = Pins designated for output by DDRQS operate in normal mode.
QSMCM.SPCR0.B.BITS = 0b1000; // 8 bits per transfer
QSMCM.SPCR0.B.CPOL = 0; // Clock polarity.
QSMCM.SPCR0.B.CPHA = 1; // Clock phase.
QSMCM.SPCR0.B.SPBR = 0x03; // 6.66mhz value between 2-255 fsys/(2*0x03) = 6.66E6
QSMCM.SPCR1.B.DSCKL = 0x2; // 50 nano second delay (PCS to SCK Delay) 1 to 127
QSMCM.SPCR1.B.DTL = 0xFF; // Length of delay after transfer. 1 to 255
QSMCM.SPCR2.B.WREN = 0; // disable wrap around mode
QSMCM.SPCR2.B.WRTO = 0; // Wrap to pointer address 0x0
// these settings disable spi after completion
QSMCM.SPCR2.B.ENDQP = 0x0; // Ending queue pointer. [application should only move endqp]
QSMCM.SPCR2.B.NEWQP = 0x0; // New queue pointer value.
QSMCM.SPCR3.B.LOOPQ = 0;
QSMCM.SPCR3.B.HALT = 0;
// interrupt pins
QSMCM.SPCR2.B.SPIFIE = 0; // SPI finished interrupt enable.
QSMCM.SPCR3.B.HMIE = 0;
}
void eeprom_read(unsigned char address, unsigned char *data, unsigned char length)
{
int i = 0;
QSMCM.SPCR2.B.ENDQP = 0x1;
for(i=0; i<=3; i++)
{
QSMCM.COMDRAM[i].B.CONT = 0;
QSMCM.COMDRAM[i].B.BITSE = 1;
QSMCM.COMDRAM[i].B.DT = 1;
QSMCM.COMDRAM[i].B.DSCK = 1;
QSMCM.COMDRAM[i].B.PCS3 = 0;
QSMCM.COMDRAM[i].B.PCS2 = 0;
QSMCM.COMDRAM[i].B.PCS1 = 0;
QSMCM.COMDRAM[i].B.PCS0 = 1;
}
QSMCM.TRANRAM[0].B = 0x03; // Send Read OpCode
QSMCM.TRANRAM[1].B = 0x00; // high address
QSMCM.TRANRAM[2].B = 0x10; // low address
QSMCM.TRANRAM[3].B = 0x0; // dummy data
QSMCM.SPCR1.B.SPE = 1;
while(QSMCM.SPSR.B.SPIF != 1);
*data = (unsigned char)QSMCM.RECRAM[3].B;
}
void eeprom_writechar(unsigned int address, char data )
{
int i = 0;
QSMCM.SPCR2.B.ENDQP = 0x3; // Ending queue pointer; 0x0 - 0x1F = 0-31;
// Execution of 0 and 1 commands
for(i=0; i<=4; i++)
{
QSMCM.COMDRAM[i].B.CONT = 0; // 0 = Control of chip selects returned to PORTQS after transfer is complete.
QSMCM.COMDRAM[i].B.BITSE = 1; // 1 = Number of bits set in BITS field of SPCR0.
QSMCM.COMDRAM[i].B.DT = 1; // 1 = SPCR1 DTL[7:0] specifies delay after transfer PCS valid to SCK.
QSMCM.COMDRAM[i].B.DSCK = 1; // 1 = SPCR1 DSCKL[6:0] specifies delay from PCS valid to SCK.
QSMCM.COMDRAM[i].B.PCS3 = 0;
QSMCM.COMDRAM[i].B.PCS2 = 0;
QSMCM.COMDRAM[i].B.PCS1 = 0;
QSMCM.COMDRAM[i].B.PCS0 = 1; // select this spi device for serial receive & transfer
// up to 32 commands;
}
QSMCM.TRANRAM[0].B = 0x06; // Write Enable prior to Write
QSMCM.TRANRAM[1].B = 0x02; // Send Write OpCode
QSMCM.TRANRAM[2].B = 0x00; // high address
QSMCM.TRANRAM[3].B = 0x11; // low address
QSMCM.TRANRAM[4].B = data;
// 16 bits; 32 transmit data blocks
QSMCM.SPCR1.B.SPE = 1; // 1 = QSPI is enabled. Pins allocated by PQSPAR are controlled by the QSPI.
// since wrap around is disabled... qspi is disabled after execution of commands
while(QSMCM.SPSR.B.SPIF != 1);
// all commands in spi have been completed.
}