µTasker Forum
µTasker Forum => NXPTM M522XX, KINETIS and i.MX RT => Topic started by: ewan on November 03, 2008, 10:00:25 PM
-
I have the SPI where I can read and write to a periperal without error when I do a couple of reads and writes then have a breakpoint to check the results. When I let the program run, it gets stuck in the while loop (see below).
// Write one byte to the reader IC address space
/*!
* -o address (IN) reader ic register address
* -o value (IN) 8 bit value
* return: none
*
* Function for writting one char to the reader module
*
*/
void WriteRawRC(unsigned char addr, unsigned char value)
{
addr <<= 1;
addr &= ~0x81; // fix up addr
_CLEARBITS(AS, PORT_AS_BIT3); // lower cs
QIR = 0xd00f; // reset errors
QAR = QSPI_COMMAND_RAM_0; // set address to first command location
QDR = 0x0f00; // command to use no cs
QDR = 0x0f00; // command to use no cs
QAR = QSPI_TRANSMIT_RAM_0; // set address to first transmit location
QDR = addr; // save it
QDR = value; // save it
QWR = QSPI_CSIV | 0x100; // two sends
QDLYR = QSPI_SPE; // QSPI enable (start)
while (!(QIR & QSPI_SPIF)) {} // wait for transfer to complete [stuck here]
QIR |= QSPI_SPIF; // reset SPIF et al.
_SETBITS(AS, PORT_AS_BIT3); // raise cs
}
The funny thing is that when I add a variable to it {test = QIR;} to test the loop, QIR equals 1 but the while loop continues anyway. Also the CS line has already been released. I cannot fathom how this is possible from several points of view. Does anyone have any ideas about this? When I disable the part of the program which deals with this stuff the ethernet/HTTP etc. works fine.
-
Well, perhaps just writing it down gets the brain thinking. Anyway -- problem solved. The routine above was being called by both the main program and an interrupt routine. (And reentrant is not sufficient with an I/O device.) I saved the state of the interrupt enable and dissabled that interrupt at the start of the routine. At the end I restored it.
void WriteRawRC(unsigned char addr, unsigned char value)
{
unsigned char eport;
eport = EPIER0; // save EPORT
RC531_IRQ_Disable(); // disable interrupt from RC531
addr <<= 1;
addr &= ~0x81; // fix up addr
_CLEARBITS(AS, PORT_AS_BIT3); // lower cs
QIR = 0xd00f; // reset errors
QAR = QSPI_COMMAND_RAM_0; // set address to first command location
QDR = 0x0f00; // command to use no cs
QDR = 0x0f00; // command to use no cs
QAR = QSPI_TRANSMIT_RAM_0; // set address to first transmit location
QDR = addr; // save it
QDR = value; // save it
QWR = QSPI_CSIV | 0x100; // two sends
QDLYR = QSPI_SPE; // QSPI enable (start)
while (!(QIR & QSPI_SPIF)) {} // wait for transfer to complete
QIR |= QSPI_SPIF; // reset SPIF
_SETBITS(AS, PORT_AS_BIT3); // raise cs
EPIER0 = eport; // restore EPORT & reenable ints from RC531
}
I don't understand how all the weirdness happened in the first place, but it has gone away.
Ewan.