YA SPI Question, follow-up

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

YA SPI Question, follow-up

8,070 Views
farwestav
Contributor I
First, thanks to Mac and Peg for their eariler comments and suggestions which seem to be leading me in the right direction. Well, until this roadblock.
 
void main(void) {
EnableInterrupts;
SPIC1_MSTR = 1;    // MCU set as SPI master
SPIC1_CPHA = 0;    // clock phase default
SPIC1_SSOE = 1;    // slave select output enable
SPIC2_MODFEN = 1;  // ss pin acts as slave select
SPIC2_SPC0 = 0;    // uses seperate pins for I/O
SPIC1_SPE = 1;     // Enable SPI
SPIBR = 0;         // Set baud rate to max (no divisors)   
 
for(;:smileywink: {
 __RESET_WATCHDOG(); // feeds the dog
// yes, it's a very short for loop
}
}                    // end of main()
 
interrupt 18 void KBI_ISR(void)
{ KBISC_KBACK = 1;
if (SW1 == 0){
while (!SPIS_SPTEF);     
SPID = 0x05;             
while (!SPIS_SPRF);      
my_status = (SPID);      
}
 
else if (SW2 == 0){
while (!SPIS_SPTEF);     
SPID = 0x03;
while (!SPIS_SPTEF);
SPID = 0x00;             
while (!SPIS_SPRF);      
my_serial = (my_serial | SPID) << 4;
while (!SPIS_SPRF);
my_serial = (my_serial | SPID);
 }
}
 
So, everything seems to be good and I can check the various flags in the debugger, but writing to SPID (SPID = 0x05;) doesn't do anything and the value of SPID doesn't change. I haven't put a scope on the lines yet, so I don't know if SS is rising and falling as it should, but I'd at least figure that I'd see SPID change. Am I missing something here? That's a silly question.. of course I'm missing something, but what?
 
TIA
Rob
Labels (1)
0 Kudos
Reply
5 Replies

1,816 Views
bigmac
Specialist III
Hello Rob,
 
What EEPROM device are you using?  I have previously done some progamming for the 25C640 device - it looks like you may be using something similar.
 
So the first command you send is probably RDSR (read status register) = 0x05.  The first returned byte must be discarded because the command has not yet been processed by the EEPROM.  The next byte sent would be a null, so that the return should then be the correct status byte.
 
The next command you send appears to be a READ = 0x03.  What you are then trying to do is a little unclear to me.  For the 25C640, the next bytes to be sent would be the high byte of the first address, followed by the low byte of the address.  A series of null bytes would then be sent to read one or more of the stored values.
 
I personally think that the code is much easier to understand when the SPI transaction is handled as a function, as previously suggested (Freegeeks post).  I would also define a label for each of the command bytes so the meaning of each command byte is clearer.  For example, reading the status register might look like the following:
 
SPI_proc(RDSR);
my_status = SPI_proc(0);
 
You do not say how you are programming the EEPROM in the first instance.
 
Another potential issue could exist if SW1 and SW2 are mechanical switches - you would need to provide debounce so the keyboard ISR does not run multiple times for a single keypress.
 
Regards,
Mac
0 Kudos
Reply

1,816 Views
farwestav
Contributor I

Mac-

Yes, I'm using the AT25640 EEPROM.

I agree that doing this in a function will be easier, and once I prove out the protocol, I'll roll my code into a function or two.

Your idea of sending a byte, ignoring the returned byte, then sending a nulll byte to get the real data byte isn't one I've seen discussed before. I'll add that to my code and see what happens. As to the Read command, I'm going to do this:

  1. Send 03h
  2. read a byte and discard
  3. send upper byte of address
  4. read a byte and discard
  5. send lower byte of address
  6. read the first data byte
  7. send a null byte
  8. read the second data byte (the address auto-increments)

When it comes to writing, I'm going to write a similar routine; the code here is just v1.0 and will get additions when I think I know what I'm doing.

Yes, I'm using the mechanical switches on the dev board to trigger the KBI. I think, though, that I'm trapping the KBI well enough that it will only trigger once with each press, regardless of bounce.

Thanks for any other comments,

Rob

0 Kudos
Reply

1,816 Views
rocco
Senior Contributor II
Rob, you are short one SPI transfer. You need to discard one more byte. Since the byte that you fetch as the first data byte was received during the transmission of the last address byte, it is not valid. Try this:
  1. Send 03h
  2. read a byte and discard
  3. send upper byte of address
  4. read a byte and discard
  5. send lower byte of address
  6. read a byte and discard
  7. send a null byte
  8. read the first data byte
  9. send a null byte
  10. read the second data byte (the address auto-increments)

Let us know how it goes . . .
0 Kudos
Reply

1,816 Views
peg
Senior Contributor IV

Hi Rob,

Register SPID is actually two registers at the same address.

A read gives you the recieved data register

And a write writes to the transmit buffer and then sends it out.

When something is sent something is sent, something is received at exactly the same time. In fact if you just want to recieve you *MUST* send something!!!

In your code for SW1

you do this:

1. wait for txbuf MT

2. send 05

3. wait till its gone and the recieve register is full (same thing)

4. read the SPID **RECEIVE** buffer and load to my_status :smileyhappy:

my_status will hold some undefined value as you have not told us what is connected to MISO.:smileysad:

 

For SW2

1. send 03 and ignore what came in

2. send 00 and get recieved byte and do something with it :smileyhappy:

3. now you hang and trip the COP because the reciever will never get full again unless you send something!!! :smileymad:

P.S. Not sure what your trying to do with your processing of my_status??? :smileyindifferent:

BR

Peg

 

0 Kudos
Reply

1,816 Views
farwestav
Contributor I
Peg-
 
Thanks for the quick response.
 
You said I have to send to receive and that makes sense, but implementing it is confusing. Reading the spec sheet for the EEPROM I'm talking to, it says that the read sequence can be continued as the address is automatically incremented and the data continues to be shifted out.
 
As to what's happening in these two routines. For SW1, I want to send the op code 05h and then receive back the chip status register byte. MISO from the chip is connected to SO on the EEPROM
 
For SW2, I'm trying to read from two address locations and contantinate the two bytes. I need to send the Read op code, 03h, then send the address 00h. I should expect to receive one byte. Now, if I really should expect to send a byte to get a byte, what do I send to get the second byte, 03h (the op code) followed by 01h (the second address location) ? That kinda makes sense, but then I'm stuck on what happens when I send the 03h byte. Does something come back which I just ignore, or will nothing come back?
 
TIA,
Rob

Message Edited by farwestav on 02-16-200608:57 AM

0 Kudos
Reply