Slightly off topic, I realize.  If noone can help me, I'll post to the
yahoo group, but I generally like this group better.

I'm having some trouble w/ timing using the SPI master mode of USART0.
I have written both manual "bit-banging" routines and use the built-in
hw port.  The manual "bit-bang" routines work perfectly every time.
However, when I use the built-in HW USART I'm having trouble w/ the
timing and the raising of the CS.

Here's a simplified procedure I'm using:
#define E2READ      0x03        // Read data from memory beginning at
address
#define E2WRITE     0x02        // Write data to memory beginning at
address
#define E2WREN      0x06        // Set the Write Enable Latch (Enable
Write)#define SPITXWAIT   while ( !( IFG1 & UTXIFG0 ) );
#define SPIRXWAIT   TXBUF0 = 0xFF; SPITXWAIT; while ( !( IFG1 & URXIFG0
) );  
#define E2ENABLE    port3.out.pin0 = 0; // Set the CS High
#define E2DISABLE   _NOP( ); _NOP( ); port3.out.pin0 = 1; // Set the CS
Low

    E2ENABLE;         // Select the Memory chip
    TXBUF0 = E2WREN;  // Enable writing to the memory
    SPITXWAIT;        // USART0 TX buffer ready? (done writing?)
    E2DISABLE;
    E2ENABLE;
    TXBUF0 = E2WRITE; // Setup for a write
    SPITXWAIT;        // USART0 TX buffer ready? (done writing?)
    TXBUF0 = 0x01;    // Address MSB
    SPITXWAIT;        // USART0 TX buffer ready? (done writing?)
    TXBUF0 = 0x00;    // Address LSB
    SPITXWAIT;        // USART0 TX buffer ready? (done writing?)
    // ** Ok to write data **
    TXBUF0 = 0x5A;
    SPITXWAIT;
    E2DISABLE;        // End Write operation
    // Read one byte
    E2ENABLE;         // Select the Memory chip
    TXBUF0 = E2READ;  // Setup for a Read
    SPITXWAIT;        // USART0 TX buffer ready? (done writing?)
    TXBUF0 = 0x01;    // Address MSB
    SPITXWAIT;        // USART0 TX buffer ready? (done writing?)
    TXBUF0 = 0x00;    // Address LSB
    SPITXWAIT;        // USART0 TX buffer ready? (done writing?)
    // ** Ok to read data **
    SPIRXWAIT;        // USART0 RX buffer ready? (done reading?)
    templong = RXBUF0;
    E2DISABLE;        // End Read operation

The problem is that the E2DISABLE is coming before the end of the read
or write operation's clocks are complete.  I can see this on my logic
analyzer.  When this happens, the memory chip will not accept the data
byte (the last byte in the stream).  This is really annoying.  The
SPITXWAIT; macro should loop until the transmit is complete.  And, the
SPIRXWAIT, should do the same (well, ok, it does a couple of more
things, but essentially it should wait until the receive bit (URXIFG0)
is low (you have to write a dummy byte to initiate the read clock).
This isn't happening.

Anyone have any ideas why?  I can solve the problem by adding a bunch of
nop's just before the CS line goes high, but this is not a good
solution.  According to the users guide, all I should have to do is wait
for that bit in the IFG1 register.
The CPU is: F449 variety
Thanks!
-Mark





Reply via email to