Forum Index
HomeZBasic Home   Forum RulesForum Rules   Forum FAQForum FAQ   MemberlistMemberlist   UsergroupsUsergroups   RSS FeedRSS Feed
Site SearchSite Search   LinksLinks   DownloadDownload   Digests and SubscriptionsDigests and Subscriptions
ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in   RegisterRegister
S/W SPI works, H/W SPI doesn't

 
Post new topic   Reply to topic    Forum Index -> ZBasic Language
Author Message
spamiam



Joined: 13 Nov 2005
Posts: 665

Posted: 20 September 2006, 16:05 PM    Post subject: S/W SPI works, H/W SPI doesn't Reply with quote

I got my disposable SD/MMC card back and I have it working properly. At the very least, I get valid results from card initialization commands.

To the best of my ability, the two interfaces are exact duplicates. One big difference is that the H/W bus must be shared, so the card loses /CS between card accesses, but on the S/W bus, the card never loses /CS until all operations are finished.

When I try to initialize the card with the H/W interface, all I ever read is zero.

One issue with interfacing the card is that it runs at 3.3V. Therefore the MISO pin only sees 3.3v at the most, maybe less. This does not seem to be a problem for the S/W driven interface, but it might be when operating at 10x that speed on the H/W bus, this becomes a problem.

Does this seem like it is a possible source of the problem?

If so, is there any simple way to get the 3.x volt MISO card output to have a 5 volt output? I have some NPN transistors, various logic gates, diodes, resistors easily at hand.

I was worried that if I use a simple pull up resistor on the MISO signal from the card to the ZX-24 I will either mess up the ZX's own SPI communication, or I will damage the card.

Any suggestions?

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 20 September 2006, 18:36 PM    Post subject: Re: S/W SPI works, H/W SPI doesn't Reply with quote

spamiam wrote:
When I try to initialize the card with the H/W interface, all I ever read is zero.

I suspect that an operation must read or write an entire 512 byte sector while keeping CS asserted. This is just conjecture, however.

spamiam wrote:
[...] is there any simple way to get the 3.x volt MISO card output to have a 5 volt output? I have some NPN transistors, various logic gates, diodes, resistors easily at hand.

There are some ideas for 3.3V to 5V conversion in [http://www.zbasic.net/appnotes.php#AN213]AN-213 External Device Interfacing[/url] including one circuit that uses an NPN and a couple of resistors and another that uses a diode and a resistor.
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 665

Posted: 20 September 2006, 19:13 PM    Post subject: Re: S/W SPI works, H/W SPI doesn't Reply with quote

dkinzer wrote:
I suspect that an operation must read or write an entire 512 byte sector while keeping CS asserted. This is just conjecture, however.


Well, the operation I am trying to get working is just Command Zero. (Reset). In the S/W version, I send the command bytes and then send dummy bytes, reading the result. When I finally get a value of 1, it is done resetting.

In the S/W version, I have to loop 3 times, and get theresults: 255, 255, 1

Granted that the H.W version is 10x faster (set to 1/128 speed), but I never get a "1", and I always seem to get zeros. Not the expected 255!

I Used SPICommand() The args are (1,0,0,512,Oarray). The first 7 bytes of the output array are filled with the command bytes, just the same as whaty I send for the S/W version. The rest is filled with 255's.

This will read back 500-something bytes, and all of them are zero. Did not work!

Thus I asked my question re: level shifting. BUT, do I NEED to level shift when I use the MISO SPI pin rather than a general purpose I/O pin (used in the S/W version)? If I get good data on the general purpose pin, why wouldn't I get good data on the MISO pin?

dkinzer wrote:
[...]There are some ideas for 3.3V to 5V conversion in [http://www.zbasic.net/appnotes.php#AN213]AN-213 External Device Interfacing[/url] including one circuit that uses an NPN and a couple of resistors and another that uses a diode and a resistor.


I saw that nice and simple technique. I am about to try it. In this technique, doesn't the MMC card output end up draining about 1.1 volts through the diode, rather than sourcing current? Is this "back flow" a problem?

What happens when I put a 10K pull-up on the MISO pin?

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 20 September 2006, 20:41 PM    Post subject: Re: S/W SPI works, H/W SPI doesn't Reply with quote

spamiam wrote:
I saw that nice and simple technique. I am about to try it. In this technique, doesn't the MMC card output end up draining about 1.1 volts through the diode, rather than sourcing current? Is this "back flow" a problem?

It might be a problem, I suppose, depending on the structure of the 3.3V driver output. The resistor/diode junction will rise to about 4 volts when the 3.3V output is in the high state. This is high enough to be guaranteed to be read as a 1 by the ZX.

I have generally used the transistor circuit and it works well.
Back to top
GTBecker



Joined: 18 Jan 2006
Posts: 457
Location: Cape Coral

Posted: 20 September 2006, 21:02 PM    Post subject: S/W SPI works, H/W SPI doesn't Reply with quote

FWIW, I'm using 3.3v SPI from a PNI compass on a BX-24p with only
dropping diodes for power to the compass, resistive voltage dividers on
MOSI, SCK and /CS, and a direct connection for MISO.


Tom
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 665

Posted: 21 September 2006, 0:59 AM    Post subject: Re: S/W SPI works, H/W SPI doesn't Reply with quote

GTBecker wrote:
FWIW, I'm using 3.3v SPI from a PNI compass on a BX-24p with only
dropping diodes for power to the compass, resistive voltage dividers on
MOSI, SCK and /CS, and a direct connection for MISO.


Tom


What a simple technique! I have been using something similar (though I have a 3.3v regulator). So far, though, it is not working. I think it is a problem with the card losing /CS when it would rather not.

-Tony
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 665

Posted: 21 September 2006, 1:11 AM    Post subject: Reply with quote

OK!

I got it working.

I was right about the card not sharing the SPI bus happily.

I decided that I need to implement a separate /CS to the MMC card, so it would never be dropped, except when I wanted it to be dropped.

Therefore I had to prevent the signals on the SPI bus from getting through to the card except when it was being addressed specifically.

I solved this with a quad AND gate, and an inverter gate.

The SPI channel's SSEL goes to the inverter to get inverted. Now SSEL is HIGH when selected.

This signal goes to 3 of the 4 AND gates. The other signals to the AND gates are the SPI SCLK, MOSI, MISO. This is how the MISO signal gets level translated.

Now, the SCLK, MISO and MOSI signals only get to/from the card when the cards SSEL is selected.

It works!!!!!!!

I was just about to give up and let someone else figure it out!

I did the development with the SPI speed set to the slowest (F/128) to make up for the poor bandwidth of the 4000 series logic gate I am using. I don't have any high speed AND gates.

Once it was working, I turned up the speed on the SPI bus, and I found that the AND gate (or the resistor dividers, i guess) crapped out at above F/8, I.E. above about 1 MHz.

In my next order for electronic parts, I will get some higher speed logic parts. (actually my inverter is adequate, it is in the 74HCT family)

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 21 September 2006, 3:30 AM    Post subject: Reply with quote

spamiam wrote:
I solved this with a quad AND gate, and an inverter gate.

There might be a problem with the CS signal applied to the device not having the correct setup and hold time with respect to SCK. You'd have to look at the specifications to see if there is a requirement.

On the AT25256A, the CS signal must be applied at least 25nS before the rising edge of the SCK signal and must remain asserted at least 25nS after the falling edge of the SCK signal. Asserting or deasserting the CS signal at other times may cause misbehavior.
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 665

Posted: 21 September 2006, 12:38 PM    Post subject: Reply with quote

Quote:
CS signal must be applied at least 25nS before the rising edge of the SCK signal and must remain asserted at least 25nS after the falling edge of the SCK signal. Asserting or deasserting the CS signal at other times may cause misbehavior.


Good point, and I definitely DO NOT control the timing of the software-driven /CS signal specifically in my current ZBasic testbed.

BUT, I suspect that on a ZX platform this will not be a problem.

Even if I write code like this

Code:
Call PutPin(MMC_CS,0)
Call PutPin(1,0,0,512,O_Array)
Call PutPin(MMC_CS,1)


I would think that there will always be more than the requisite 25nS (2.7 clocks at 14.7MHz)delay between SPI operations and the MMC_CS signal change.

In C or Assembler, this could be a problem, and a few NOP()'s would need to be inserted.

You said "at least". Presumably a MUCH longer delay is not a problem. I definitively have much longer delays than that and it seems to work OK.

A while back, someone (JC?) speculated that if /CS can remain asserted, then the clock speed to the SD/MMC card can drop to zero. This appears to be true, but I have not tried long delays between individual byte writes to the card. Long gaps between commands definitely is not a problem. I will next be trying writing individual bytes very intermittently to see what happens.

-Tony
Back to top
JC



Joined: 20 Feb 2006
Posts: 56
Location: Hudson,OH

Posted: 22 September 2006, 1:01 AM    Post subject: Reply with quote

Hi Tony,
I do not have my notes before me...
I was data logging GPS data, mixed with some other inputs, and storing it on an MMC card. I used my own bit banged (slooow) interface, which I believe is posted on the forum.
The SD/MMC requires a 512 byte block of data to write to the card, one can not write an arbitrary (smaller) number of bytes with one write command. Setting the Block Length does not change this minimum.
One can, therefore, buffer the data, and write a full buffer; or read in 512 bytes, update what you want, and re-write it back.
I did not wish to do either of these, so I start a write, and send small packets of data at 1 second intervals, within the single MMC write command. After sending all 512 of the data bytes, over a period of ~15 seconds, I complete the write command, and issue a new one, awaiting the next packet of data. It works fine.
With the ZX's multitasking, I can write the data in the background, and speed is no longer an issue.
JC
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 665

Posted: 22 September 2006, 1:18 AM    Post subject: Reply with quote

I have not tested writing less than the full 512 bytes, but what happens if you drop CS befoire completing the full 512?

I would have thought that this would allows only a partial sector to be written.

-Tony
Back to top
dkinzer
Site Admin


Joined: 03 Sep 2005
Posts: 2499
Location: Portland, OR

Posted: 22 September 2006, 1:25 AM    Post subject: Reply with quote

spamiam wrote:
[...] what happens if you drop CS before completing the full 512? I would have thought that this would allows only a partial sector to be written.

My understanding is that the result is undefined - it might work and it might not. The specification calls for full sector operations only.


Last edited by dkinzer on 22 September 2006, 1:55 AM; edited 1 time in total
Back to top
JC



Joined: 20 Feb 2006
Posts: 56
Location: Hudson,OH

Posted: 22 September 2006, 1:35 AM    Post subject: Reply with quote

The first time I worked with MMC cards was several years ago, then it sat on back burner until I nneded it again.
I tried extensively to do single byte and < 512 block writes without success.
The San Disk manual was contradictory in this regard.
A table implied that it was possible, the text, and a later manual addendum made it clear that it was not.
JC
Back to top
spamiam



Joined: 13 Nov 2005
Posts: 665

Posted: 22 September 2006, 12:55 PM    Post subject: Reply with quote

I will try writing on my OLD OLD OLD SD/MMC card. When I tried partial block writes in previous testing, it seemed to work OK, but I was not specifically checking the reliability.

It was relatively up to date when I got it. It is an 8Meg card. THat tells you how old it is. I have no idea what brand it actually is. Something weird. Maybe it will not adhere to the Sandisk standard the way newer cards will. For instance, I can get a "valid" read on the Card ID structure, but it is gibberish. Either I am not getting a good read off the card, or the CID is not quite according to the SanDisk literature I have been reading.


More on interfacing to the hardware SPI bus:

As I read the SanDisk standards, it says that the CS must remain low for the entire Command-Response-Data sequence.

The only successful method I have had to get the response is to poll the card. I tried to use SPICmd() to send the command bytes, then read back a ton of bytes. None of them registered a "good" response. Without getting (and understanding )a valid response byte, you do not know when to start looking for the data, nor when to stop reading the data.

When I poll the card it works.

So, I do not see any feasible way to use "standard" SPI techniques to keep the Comand-Response-Data atomic (as far as the CS signal is concerned) other than having the CS signal separately controlled from the SPI signals.

Don had previously said that an SPI device that does not adhere to SPI standards is pointless. I agree. I suppose the SD/MMC card designer had envisioned a bus dedicated to the memory cards only. In this way, there is no need to interleave other SPI accesses between the Command-Data-Response elements. Or else the Firmware understands that MMC card accesses are diffeent from other devices and will hold the CS signal until it is appropriate to release it. This is not something that a general-purpose SPI interface should be expected to handle.

I suppose that there could be an "extended" SPICMD(), where there is an extra argument. It defaults to ZERO. If set to "1", the interface will not release SSEL. until an SPICmd() is received with a zero as the last arg.

Of course, this is not compatible with the ZX architecture, unless the user program is not run on SPI-based EEPROM. (maybe on a larger CPU the bootloader, VM, and the user program can all be stored in flash).

-Tony
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Forum Index -> ZBasic Language Time synchro. with the server - Timezone/DST with your computer
Page 1 of 1

 


All content Copyright © 2005-2012 Elba Corp. All Rights Reserved.
Opinions expressed in posts are those of the author and not necessarily those of Elba Corp.
Powered by phpBB © 2001, 2005 phpBB Group