View previous topic :: View next topic |
Author |
Message |
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Tue Dec 01, 2009 10:24 pm Post subject: Is there a difference between Hardware and Software SPI?? |
|
|
Hello,
During an experiment with writing to an EEPROM chip - in this case, the 93LC56 - I found that using Hardware SPI versus Software SPI yield different results. The Software definition works while the Hardware definition does not.
You'll see in the program code below that either one of the two configurations - Config SPI=Hard ... or the Config SPI=Soft ... can be selected.
The output from running both configurations is shown below that. Notice that the Software SPI version shows the correct values from EEPROM but the data from the Hardware SPI seems to be off. (Being hard-headed, I spent a day with the Hardware SPI thinking that I was missing something - and also posting for help.)
Has anyone seen this before? Or is there something that should be defined differently.
(NOTE: all the documents are included as attachments)
Ennio M
----------------------------------------
$regfile = "m8535.dat"
$crystal = 8000000
$baud = 9600
'from Microchip datasheet: 93LC46/56/66 pages 8-10
'Used an ATC 93LC56 (PDIP) in 16-bit mode! Refer to TABLE 2-4 pg 4.
'Common to all instructions:
' CS active HIGH and must go LOW between commands.
' Data bits set on rising edge of CLK
' DI and DO are Data In and Data Out -relative to chip
Dim Dwrite As Byte , Dread As Byte , Derase As Byte
Dim Ewds(2) As Byte , Wral(2) As Byte , Eral(2) As Byte , Ewen(2) As Byte
Dim Dum As Byte
'Address-specific commands on falling edge of CS
Dwrite = &B00000101 'WRITE
'DI xxxxx101 Address |x6..0|D15..D0
'D0 hi-z
Dread = &B00000110 'READ see FIGURE 3-6 pg 7
'DI xxxxx110 Address |x6..0|
'DO |0 D15..D0
Derase = &B00000111 'ERASE ADdress to logical "1"
'DI xxxxx111 Address x6..0
'Memory Access commands
Ewds(1) = &B00000100 'EWDS - Erase/Write Disable
Ewds(2) = &B00010101 '00xxxxxx x-don't care but must be clocked
Ewen(1) = &B00000100 'EWEN - Erase/Write ENable
Ewen(2) = &B11010101 'must preceed all erase/write commands
'11xxxxxx
'Self-timed commands
Wral(1) = &B00000100 'WRAL - WRite ALl - write specified value to
Wral(2) = &B01010101 'all memory locations
'01xxxxxx
Eral(1) = &B00000100 'ERAL - ERase ALl - sets all memory bits to 1
Eral(2) = &B10010101 '10xxxxxx
'Operational notes from datasheet:
'1. After power-up, the device is automatically in the EWDS mode. Therefore, All
' programming/write modes must be preceded by an ERASE/WRITE Enable (EWEN)
' instruction before the initial ERASE or WRITE instruction can be executed.
' Once the EWEN instruction is executed, programming remains enabled until
' an EWDS instruction is executed or Vcc is removed from the device.
'2. The EWEN and EWDS commands give additional protection against accidentally
' programming during normal operation. For added protection, an EWDS command
' should be performed after every write operation.
'3. After issuing a self-timed command, taking CS LOW for 250 nSec then HIGH again,
' will show that the chip is BUSY on DO (LOW) until the operation is complete.
'4. READ instruction is executed regardless of the EWDS status.
'5. A dummy zero bit precedes the 8 or 16-bit DO output!!!
Config Portb.4 = Output 'set up micro as master per ATMEL AVR151 recommendation
Set Portb.4 'set !SS Output|High - although not used
Config Portb.5 = Output
Config Portb.7 = Output
Config Portb.6 = Input
Ddrb.6 = 0 'Necessary??
'Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1 , Spiin = 255
Config Spi = Soft , Din = Pinb.6 , Dout = Portb.5 , Clock = Portb.7 , Ss = Portb.4 , Spiin = 255
'Note: CS for these chips is active HIGH whereas SPI SS is active Low.
' Therefore NOSS is set 1 (disable SPI SS) and CS is manipulated by code.
Cs Alias Portd.7 'location of CS
Config Portd.7 = Output
Reset Cs
Declare Sub Readad
Declare Sub Writead
Declare Sub Eraseall
Declare Sub Memdisplay
Dim Ad As Byte , B(2) As Byte , Strt As Word , Endd As Word
Strt = &H00 'sample memory range
Endd = &H1F
'main
Spiinit 'as required
Set Cs
Spiout Ewen(1) , 2 'Enable write after power up or EWDS
Reset Cs
Waitms 10
Call Eraseall 'self-timed write with $FF
Print "Original memory contents after Erase All"
Call Memdisplay 'original contents
Print
Print "Write a specific byte to a specific address"
B(1) = 0
B(2) = Asc( "a") 'char to write
For Ad = 3 To &H13 'random address range
Call Writead
Incr B(2) 'incr chars
Next Ad
Call Memdisplay 'modified contents
End
Sub Memdisplay
For Ad = Strt To Endd
Call Readad
Print Hex(ad) ; " " ; B(1) ; "(" ; Hex(b(1)) ; ") " ; B(2) ; "(" ; Hex(b(2)) ; ") " ; Chr(b(2))
Next Ad
End Sub
Sub Eraseall
Set Cs
Spiout Eral(1) , 2 'Erase all memory and set to $FF
Reset Cs
Waitms 20
End Sub
Sub Writead
Set Cs
Spiout Dwrite , 1 'write memory
Spiout Ad , 1
Spiout B(1) , 2 'write 16-bit word
Reset Cs
Waitms 5
End Sub
Sub Readad
Set Cs
Spiout Dread , 1 'Read memory
Spiout Ad , 1
Spiin B(1) , 2 'read 16-bit word
'B(1) = Spimove(255) 'same results are produced
'B(2) = Spimove(255)
Reset Cs
Waitms 5
End Sub
------------------------
This is the output using the SPI Hardware definition:
Original memory contents after Erase All
00 127(7F) 255(FF) ÿ
01 127(7F) 255(FF) ÿ
02 127(7F) 255(FF) ÿ
03 127(7F) 255(FF) ÿ
04 127(7F) 255(FF) ÿ
05 127(7F) 255(FF) ÿ
06 127(7F) 255(FF) ÿ
07 127(7F) 255(FF) ÿ
08 127(7F) 255(FF) ÿ
09 127(7F) 255(FF) ÿ
0A 127(7F) 255(FF) ÿ
0B 127(7F) 255(FF) ÿ
0C 127(7F) 255(FF) ÿ
0D 127(7F) 255(FF) ÿ
0E 127(7F) 255(FF) ÿ
0F 127(7F) 255(FF) ÿ
10 127(7F) 255(FF) ÿ
11 127(7F) 255(FF) ÿ
12 127(7F) 255(FF) ÿ
13 127(7F) 255(FF) ÿ
14 127(7F) 255(FF) ÿ
15 127(7F) 255(FF) ÿ
16 127(7F) 255(FF) ÿ
17 127(7F) 255(FF) ÿ
18 127(7F) 255(FF) ÿ
19 127(7F) 255(FF) ÿ
1A 127(7F) 255(FF) ÿ
1B 127(7F) 255(FF) ÿ
1C 127(7F) 255(FF) ÿ
1D 127(7F) 255(FF) ÿ
1E 127(7F) 255(FF) ÿ
1F 127(7F) 255(FF) ÿ
Write a specific byte to a specific address
00 127(7F) 255(FF) ÿ
01 127(7F) 255(FF) ÿ
02 127(7F) 255(FF) ÿ
03 0(00) 48(30) 0
04 0(00) 49(31) 1
05 0(00) 49(31) 1
06 0(00) 50(32) 2
07 0(00) 50(32) 2
08 0(00) 51(33) 3
09 0(00) 51(33) 3
0A 0(00) 52(34) 4
0B 0(00) 52(34) 4
0C 0(00) 53(35) 5
0D 0(00) 53(35) 5
0E 0(00) 54(36) 6
0F 0(00) 54(36) 6
10 0(00) 55(37) 7
11 0(00) 55(37) 7
12 0(00) 56(38) 8
13 0(00) 56(38) 8
14 127(7F) 255(FF) ÿ
15 127(7F) 255(FF) ÿ
16 127(7F) 255(FF) ÿ
17 127(7F) 255(FF) ÿ
18 127(7F) 255(FF) ÿ
19 127(7F) 255(FF) ÿ
1A 127(7F) 255(FF) ÿ
1B 127(7F) 255(FF) ÿ
1C 127(7F) 255(FF) ÿ
1D 127(7F) 255(FF) ÿ
1E 127(7F) 255(FF) ÿ
1F 127(7F) 255(FF) ÿ
------------------------------------------------------------------------------
This is the output using the SPI Software definition:
Original memory contents after Erase All
00 255(FF) 255(FF) ÿ
01 255(FF) 255(FF) ÿ
02 255(FF) 255(FF) ÿ
03 255(FF) 255(FF) ÿ
04 255(FF) 255(FF) ÿ
05 255(FF) 255(FF) ÿ
06 255(FF) 255(FF) ÿ
07 255(FF) 255(FF) ÿ
08 255(FF) 255(FF) ÿ
09 255(FF) 255(FF) ÿ
0A 255(FF) 255(FF) ÿ
0B 255(FF) 255(FF) ÿ
0C 255(FF) 255(FF) ÿ
0D 255(FF) 255(FF) ÿ
0E 255(FF) 255(FF) ÿ
0F 255(FF) 255(FF) ÿ
10 255(FF) 255(FF) ÿ
11 255(FF) 255(FF) ÿ
12 255(FF) 255(FF) ÿ
13 255(FF) 255(FF) ÿ
14 255(FF) 255(FF) ÿ
15 255(FF) 255(FF) ÿ
16 255(FF) 255(FF) ÿ
17 255(FF) 255(FF) ÿ
18 255(FF) 255(FF) ÿ
19 255(FF) 255(FF) ÿ
1A 255(FF) 255(FF) ÿ
1B 255(FF) 255(FF) ÿ
1C 255(FF) 255(FF) ÿ
1D 255(FF) 255(FF) ÿ
1E 255(FF) 255(FF) ÿ
1F 255(FF) 255(FF) ÿ
Write a specific byte to a specific address
00 255(FF) 255(FF) ÿ
01 255(FF) 255(FF) ÿ
02 255(FF) 255(FF) ÿ
03 0(00) 97(61) a
04 0(00) 98(62) b
05 0(00) 99(63) c
06 0(00) 100(64) d
07 0(00) 101(65) e
08 0(00) 102(66) f
09 0(00) 103(67) g
0A 0(00) 104(68) h
0B 0(00) 105(69) i
0C 0(00) 106(6A) j
0D 0(00) 107(6B) k
0E 0(00) 108(6C) l
0F 0(00) 109(6D) m
10 0(00) 110(6E) n
11 0(00) 111(6F) o
12 0(00) 112(70) p
13 0(00) 113(71) q
14 255(FF) 255(FF) ÿ
15 255(FF) 255(FF) ÿ
16 255(FF) 255(FF) ÿ
17 255(FF) 255(FF) ÿ
18 255(FF) 255(FF) ÿ
19 255(FF) 255(FF) ÿ
1A 255(FF) 255(FF) ÿ
1B 255(FF) 255(FF) ÿ
1C 255(FF) 255(FF) ÿ
1D 255(FF) 255(FF) ÿ
1E 255(FF) 255(FF) ÿ
1F 255(FF) 255(FF) ÿ |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Wed Dec 02, 2009 12:29 am Post subject: |
|
|
I never used software SPI, but hardware SPI certainly does work. However you must not use the hardware SS pin for manual chip select when using hardware SPI. When you define the AVR as master, driving SS low will cause an internal error flag to be set, since this normally detects a bus contention problem. Use another pin for the chip select.
I saw your other request for sample code, but where I use SPI is mostly in ASM, within an IRQ to get very fast and timed transfers, much more complex that you needed.
From your results, it looks like you are missing some of the bits of the transmission from the eeprom. That is usually caused by having the clock and polarity settings wrong. But it could be from the SS errors as above. Fix this first. Then if that does not help, play with the config:
Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1 , Spiin = 255
Change the Polarity and the Phase, one at a time, to the other settings. One combination of the 4 should give you the correct result. You might also try a lower clockrate, just to be sure that you are not missing edges. But only change one setting in the config at a time, else you get confusing results.
You do not need ( or want ) interrupts on in there either. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Wed Dec 02, 2009 1:00 am Post subject: |
|
|
Thank-you Adrian for your prompt reply.
I think you'll find that Portb.4 - which is the SS for the Hardware SPI on the ATMEGA8535 - is set to OUTPUT and HIGH in the code (just before the CONFIG statement) and not used during execution. Portd.7 is used for CS.
I had played around with all the Hardware SPI parameters and, with the exception of POLARITY=LOW and PHASE=0, no other combination worked.
This combination of polarity and phase yielded the same results as shown with POLARITY=HIGH and PHASE=1 --- which, I think, makes sense.
I don't get the sense that this issue has much to do with the EEPROM chip.
Thanks |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Wed Dec 02, 2009 1:20 am Post subject: |
|
|
Ok, I missed the fact that you are using a different pin than SS for chip select. And if you have already tried the other phase and polarity combinations, then you do have some other problem. But do turn off the interrupt in the config. Since you have no 'enable interrupts' statement, it might be possible that the config generates interrupt code, but the program has no way of executing it.
One difficulty always with eeproms is to figure out if its the write or the read giving errors. Perhaps since you know that the software SPI works for both write and read, in that you get the expected results, is to use software SPI to do a write of some known values, and then switch to hardware SPI to do a read. If the read then works, it must the be hardware SPI write causing the error. Maybe that helps you trace the problem. Using a 'scope on the data and clock lines might also give you some clues.
Of course you could just give up and use software SPI, although of course it costs more code and is slower to execute.
All I can say is that I have used hardware SPI extensively with Atmel dataflash chips, Texas ADCs, Ramtron ferro-ram, Maxim UARTS, and various other devices, and always found it works without problems, once I got the config correct.
Just one further thought. Make sure the eeprom is well bypassed with the recommended caps right at the supply pins. Some chips draw large pulse currents particularly during the write sequence, and this could be causing the missing edge effects. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
nguyenduonghoang
Joined: 22 Mar 2008 Posts: 91
|
Posted: Wed Dec 02, 2009 6:27 am Post subject: |
|
|
AdrianJ wrote: |
Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 4 , Noss = 1 , Spiin = 255
|
Hi,
May be dont have "Spiin=255".
Anyone had used SPI software, i had tried it but it not operate.
Best Regards.
Hoang. |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Wed Dec 02, 2009 4:00 pm Post subject: |
|
|
Thank-you for all replies.
I've now compared the Hardware and Software SPI on 3 different micros and the results are as follows:
Using SPOUT and SPIIN (SPIMOVE gives similar results as SPIIN).
ATMEGA8535
Hardware SPI: Write OK: Read -NO-
Software SPI: Write OK: Read OK
ATMEGA644P
Hardware SPI: Write OK: Read -NO-
Software SPI: Write OK: Read OK
ATTiny2313
Hardware SPI: -NA-
Software SPI: Write OK: Read OK
It now seems as if the Hardware SPI in both Mega devices writes data correctly but will read it incorrectly; that is, if the data is written to the EEPROM with the Hardware SPI and subsequently read with a Software SPI, it can be confirmed that the data was written OK.
Perhaps others could verify my results.
Adrian, since you've not experienced this problem before, could this be a problem specifc to the routines used for the Mega micros??
(By the way, the parameter SPIIN=255 in the CONFIG statement does not affect the results.)
Ennio M |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Wed Dec 02, 2009 7:41 pm Post subject: |
|
|
Adrian,
further to my earlier posting, I have confirmed using the Microchip MCP3201 (12-bit ADC and Mega8535) that the Software SPI retrieves a different number than the Hardware SPI. The MSB is retrieved earlier in the bit sequence by the Software SPI and resulting in a higher number. Since the ADC pads the end of the transmission with zeros, the number can be SHIFTed RIGHT, 1 and ends up being equal to the number retrieved by the Hardware SPI.
So ...... you are correct.
We need to be aware of the difference in the two SPI configurations and use the one that fits our needs - although, I can envision times when we do not know which one is right.
Ennio M |
|
Back to top |
|
|
AdrianJ
Joined: 16 Jan 2006 Posts: 2483 Location: Queensland
|
Posted: Thu Dec 03, 2009 12:07 am Post subject: |
|
|
Good work ! But there should be no difference between hardware and software SPI. Mind you, I never used software SPI, so I dont know.
However here are some hardware SPI examples pulled out of a couple of working programs. Processors for the bits I pulled out are AtMega16 and AtMega64, but I have also used the old AT90S8535, and that works too.
Note these are not complete working code, just the SPI bits pulled out to show what I did. Some are in ASM, some in Basic. Note also that the AVR-DOS routines of Josef Vogel also use hardware and software SPI interchangeably, and I know that at least the hardware config works perfectly.
Note that there is almost no 'code' with hardware SPI, all the actual transfer is done purely by hardware, and the code simply picks the transferred byte out of the SPI data register. Its hard to see how this can make bit errors like you see.
If I get a chance, I will try setting up for software SPI on a test rig I can use, and do some snooping with a scope, but it may not be soon. I am almost certain that the problem lies somewhere in the phase/polarity settings, judging from the results you posted. _________________ Adrian Jansen
Computer language is a framework for creativity |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Thu Dec 03, 2009 12:59 am Post subject: |
|
|
Thank-you Adrian for your support.
While your suspicion about Polarity and Phase may be right, all the combinations I tried (except for 2) resulted in errors and those 2 had the data shifted. I also find it difficult to understand why the same set of Polarity and Phase settings would Write correctly but Read incorrectly.
In any event, I will wait for your analysis.
Ennio M |
|
Back to top |
|
|
nguyenduonghoang
Joined: 22 Mar 2008 Posts: 91
|
Posted: Thu Dec 03, 2009 3:16 am Post subject: |
|
|
Hi Enniom,
Could you post some code about SPI software, i use mega32.
THanks a lot.
Best Regards.
Hoang. |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Fri Dec 04, 2009 12:15 am Post subject: |
|
|
Hoang,
I'm not sure I understand your question - but I'll do my best.
You'll see code at the begining of this thread that includes both Hardware SPI and Software SPI sample code that communicates with a 93LC56 EEPROM.
The code provides a typical approach you may want to follow to set up communication with any other SPI-compatible device. First set up initialization, if required, then issue appropriate data transfer commands.
If you run into problems, you may wish to start another thread for the Forum participants to assist you.
Ennio M |
|
Back to top |
|
|
nguyenduonghoang
Joined: 22 Mar 2008 Posts: 91
|
Posted: Fri Dec 04, 2009 4:18 am Post subject: |
|
|
Hi Ennio,
Sorry for my bad English
I had used Hardware SPI and it worked well. With Software SPI, i had just simulate it on Proteus and it worked, but actually, it does not work.
On Proteus, i use oscillo and have some picture, and you can see a different between Hard SPI and Soft SPI.
With the Hard SPI , it has a period between each byte of date
Code: | Config Spi = Soft , Din = Pinb.4 , Dout = Portb.2 , Ss = Portb.0 , Clock = Portb.1
Spiinit
Spiout X(1) , 3 |
With Soft SPI
I dont understand why had a different like this. You can give me some ideal.
So you can help me how to config soft spi is, because my code just worked on simulation but actually didnt.
Thanks a lot !
Best Regards.
Hoang. |
|
Back to top |
|
|
enniom
Joined: 20 Oct 2009 Posts: 537
|
Posted: Fri Dec 04, 2009 3:23 pm Post subject: |
|
|
Hoang,
I assume that the images show the Clock as yellow and the Data Out of the micro (SPIOUT) as blue. If this is the case, I can offer the following:
1. It appears as if in the Hardware SPI, the Clock is active Low while in the Software SPI it is active High. Its possible that the Software SPI defaults to this mode. I do not know that it can be changed. It would be interesting however, if you tried the various combinations of Polarity and Phase settings in the Hardware SPI to see if you can match the waveforms.
2. Have you confirmed that the receiving device does not recognize the two data bit-streams? My breadboard work showed that write commands from the micros worked properly for both the Hardware and Software SPI - once I set the correct Polarity and Phase.
As far as your request for assistance for Software SPI configuration settings, I think the BASCOM help files are best. Perhaps, Adrian or others may suggest Assembler code or Register tweaks that can provide more capabilities.
Regards,
Ennio M |
|
Back to top |
|
|
nguyenduonghoang
Joined: 22 Mar 2008 Posts: 91
|
Posted: Fri Dec 04, 2009 5:55 pm Post subject: |
|
|
Thanks very much for your answer.
I will try it now.
Best Regards.
Hoang. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|