I am using a USB Protoboard (RevD) to host a project that uses a microSD card. I have CS on P3, and I can see it toggle as the card is inserted with
3 pin@ . \ gives 0 if card is in, -1 if not
This board has a 100 K pull up on CS, and I see Peter's comments that this resistor is redundant and unnecessary, and sure enough I can't seem to get Tachyon to see the card. Rather than cutting traces, ...
Has anyone used the ucard reassignment to introduce and alternative detection scheme ? Any tips ? Is this the approach to take ?
Cheers!
I am using a USB Protoboard (RevD) to host a project that uses a microSD card. I have CS on P3, and I can see it toggle as the card is inserted with
3 pin@ . \ gives 0 if card is in, -1 if not
This board has a 100 K pull up on CS, and I see Peter's comments that this resistor is redundant and unnecessary, and sure enough I can't seem to get Tachyon to see the card. Rather than cutting traces, ...
Has anyone used the ucard reassignment to introduce and alternative detection scheme ? Any tips ? Is this the approach to take ?
Cheers!
here is a quote from SDCARD.fth
--- Used to set C3 SD method etc
TRUE == C3CARD
pub C3 $C3 ' PCB 1+ ! &32.10.9.11 SDPINS ' C3CARD ucard W! ;
so in your case
pub mycard 3 ?LOW ;
pub MyBoard $45 ' PCB 1+ ! &32.10.9.11 SDPINS ' mycard ucard W! ;
Thanks MJB, you have helped more than you could have imagined. I searched my SDCARD.fth for that code, didn't find it! Turns out I am somehow working with 2013 code in this module. Time to reload everything and see what is going on with current versions. I'm not sure what the PCB variable is all about, but will see.
To be honest, I'm not sure my brain is up to this...progress is v. slow.
Thanks again!
Thanks MJB, you have helped more than you could have imagined. I searched my SDCARD.fth for that code, didn't find it! Turns out I am somehow working with 2013 code in this module. Time to reload everything and see what is going on with current versions. I'm not sure what the PCB variable is all about, but will see.
To be honest, I'm not sure my brain is up to this...progress is v. slow.
Thanks again!
Hardware specific files such as SDCARD.fth need to know which pins are being used and also about any special methods to use the hardware. By default it uses a configuration that suits some of my hardware. To make these drivers hardware specific it can be done in one of two ways. The default method is simply to change these parameters at runtime by defining new pins using SDPINS and possibly revectoring the card detect method. The other method is to use a header file with all the pin definitions etc for that pcb plus a way to identify the pcb. This is where PCB$ and the PCB constant come in as they can provide that information to the drivers and also useful for reporting hardware information. So PCB is a unique constant that identifies the hardware, in the case of the C3 I elect to use the value $C3, sound simple enough. If I have one of my P1432 boards then I set the PCB constant to 1432 and also set PCB$ to a human friendly string like this:
" P1432 +P8" 0 STRING PCB$
#1432 == PCB
Using a header file is the way I prefer to compile but if you use a precompiled binary then you can still setup the board at runtime.
Many Parallax boards use pullups on CS and dedicate an I/O for card detect or use a clunky resistor method. Either way it is simply a matter of defining a specific card detect routine and patching the vector "ucard" like this:
I'm not sure which board is the "USB protoboard" but the SDPIN parameter is defined as &cs.miso.mosi.sck where mosi is the Master Out Slave in or in other words the data from the Prop to the SD card. You would never have 32 as a value really, valid values are from 0..31. MJB selected $45 ' PCB 1+ ! to change the PCB constant but normally this value would give some indication of model etc. I noticed that if PCB is not already defined that the SDCARD code will not compile so I have just made a little fix to that now and will update the dropbox. I may just make a new sdcard binary and you can always setup the board at runtime.
Thanks Peter, that clears much up ... I didn't know if PCB and PCB$ had deeper meanings. The boards is product #32810 from Parallax, and I have created defs much like you suggest.
Since SDPINS will run using my defs of &SDDO etc when SDCARD loads, then I will define the replacement routine for ucard in my hardware profile file, then make it active in the main code.
Has MULTIFAT been completely replaced by EasyFile ? As a heads up, the Readme.txt file in the root of the DropBox refers to MULTIFAT
The new (?) kernel (version long 27_150908,1000 ; was uploadedto Dropbox 21 days ago) has a long named pblksz, line 1046&1062, that is set to 512, and this is keeping it from compiling to the board My previous version (version long 27_150902,0100) had a constant of 511 on line 1046, seemed to work fine.
Thanks again!
That product doesn't show up on the Parallax site so I guess it's an old one. Multifat was a long time ago too, it's been Easyfile for a while now.
I will check and update the readme and I see the problem with pblksiz, it compiles fine in BST but not in Prop tool, but it is an error that I will fix shortly. Look for v2.8 kernel though as I have some updates to replace 2.7.
Hi Peter ... here is the link. It's a simple board that is can get a microSD and QuickStart header added. It still has the hateful 1-hole soldering pad pattern.
Thanks for looking at that ... I can only imagine how much time you pour into this to support others ... you probably cringe when another newbie shows interest in Tachyon. Trust me though, even if I understand only a fraction of what you say and have done, I very much appreciate all of it.
Cheers!
MOUNT is designed to mount the FAT32 volume which also involves initializing the SD card itself. Some routines such as DIR will check to see if it needs mounting however once you start opening files it is assumed all this has been done already in your boot routine. There is ?SDCARD which if added as a background poll will automount cards.
So either MOUNT at startup or add ?SDCARD as a poll with: ' ?SDCARD +POLL which off course still involves a user startup. However just for interacting you would just type MOUNT or else DIR after startup.
Remember too that you can have 4 files 0..3 open at a time although file 1 is also used for the directory.
Thanks MJB, you have helped more than you could have imagined. I searched my SDCARD.fth for that code, didn't find it! Turns out I am somehow working with 2013 code in this module. Time to reload everything and see what is going on with current versions. I'm not sure what the PCB variable is all about, but will see.
To be honest, I'm not sure my brain is up to this...progress is v. slow.
Thanks again!
Also, as Peter points out #P32 is not a possibility, so is &32.10.9.11 just a way to have SDCS = #P0 ?
The magic and mystery of forth continue to block me ...
If you already have created a hardware definition file and loaded that before SDCARD.fth then you don't need to worry about SDPINS. However you can use SDPINS to reassign the default SD pins at runtime before you try to initialize or mount the card. So SDPINS is a quick and easy way to set those pins using a single long or the handy & notation.
In the screenshot from the schematic you can see all the pins of the SD card however besides power and ground only four lines are required and they are the same for any bidirectional SPI device: Serial Clock (CLK or SCK), Data out to device (MOSI), Data in from device (MISO), and an active low chip select (CS). The constant that has been used to set SDPINS is only an example as the actual pin numbers you need to set are according to how you have connected them back to the Prop. Also I see that your board does not have any card detect scheme but the easiest way to make it detect the card is simply to get a hot iron with a bit of solder and flick R26 off the board (or cut the track) so that pin 2 of the SD card which is CS is left floating the way it should be. When a card is inserted it already has a pullup resistor which is how by default Tachyon detects the card.
So just substitute the pin numbers you are using in place of these symbols &CS.MISO.MOSI.SCK SDPINS. If you removed R26 then you don't need to patch the user card vector to do something different and it is not necessary to setup the PCB constant either. Forget about those two lines of example code, either have the hardware lines predefined during compile or just use SDPINS at runtime.
There is no need to set the PCB constant which is handy for reporting and software to check the hardware details if it needs to know. However if you do define it during compile then you may as well set it to the Parallax number #32810 == PCB or modify it at runtime by directly modifying the compiled constant with #32810 TO PCB which is the same as saying #32810 ' PCB 1+ !. If you then type PCB PRINT it should print out the value of that constant which is now 32810.
BTW, The & notation is a a way to force a number to a particular base such as $BEEF for hex, #9876 for decimal, %10110001 for binary, and & for IP notation where each dot separated number 0..255 represents a byte in a long. However SDPINS expects pin numbers in the range of 0..31 as it converts this to a 32-bit mask internally so there is no such pin as P32 so it wraps around to 0 in this faulty case.
Also, as Peter points out #P32 is not a possibility, so is &32.10.9.11 just a way to have SDCS = #P0 ?
The magic and mystery of forth continue to block me ...
usually ucard is 0
in this line it is tested and if not 0 it is inpterpreted as a call vector and jumped to ececute the word/bytecode at the address.
ucard W@ ?DUP IF JUMP THEN --- use alternative card detect method if selected
in the C3 example above C3CARD just executes TRUE, so just make sure a SD in in already ;-)
the SDPIN parameter is defined as &cs.miso.mosi.sck with pin values in decimal.
so you are right, 32 is definitely strange, I just copied the line from SDCARD.fth
I don't know the C3 and what this would mean, either bug or Peter trick ;-)
If your SDCS = #P0 then just put a 0 there and try.
this just got me curious ... and I gabe it a quick try.
&32.10.9.11 .S Data Stack (1)
$200A.090B - 537528587 ok
#32 MASK .S Data Stack (6)
$0000.0001 - 1
there is a bit of a strange behaviour in the &x.x.x.x reader.
&0.1.2.3 .S Data Stack (9)
$0000.007B - 123
&3.2.1.0 .S Data Stack (10)
$0302.0100 - 50462976
&1.1.1.1 .S Data Stack (11)
$0101.0101 - 16843009
&0.1.1.1 .S Data Stack (12)
$0000.006F - 111
but &32.x.x.x sets SDCS to #P0
better just use IP notation, there leading 0 works
MJB, yes, I did those checks and the &a.b.c.d gets messed up if a=0, so a=32 sets the sixth bit of the high byte, but the code (I guess) only uses the bottom 5 bits, so it reads as 0. A sweet trick!
The line you show is the one that is making me spin my wheels ..
ucard W@ ?DUP IF JUMP THEN
If ucard has been assigned true (-1), then wouldn't this line cause a crazy jump when run ?
MJB, yes, I did those checks and the &a.b.c.d gets messed up if a=0, so a=32 sets the sixth bit of the high byte, but the code (I guess) only uses the bottom 5 bits, so it reads as 0. A sweet trick!
The line you show is the one that is making me spin my wheels ..
ucard W@ ?DUP IF JUMP THEN
If ucard has been assigned true (-1), then wouldn't this line cause a crazy jump when run ?
The default is ucard = 0 so therefore no JUMP will be taken. This vector was added for odd hardware but you don't need to worry about it. If though you put a "crazy" address in there then it may indeed do crazy things.
NOTE: I see there is a bug with the &0.x.x.x processing that I will have to check although the infix : notation seems to work correctly
Peter, and MJB, thank you for your help.
Peter, that is exactly what I have done, with my hardware file
TACHYON
[~
FORGET AUTOHELM.fth
pub AUTOHELM.fth ." AutoHelm Board Definitions 20160416 v1 " ;
{
DESCRIPTION
These are the header files that define the functions of the pins plus any other special functions
needed for the AutoHelm board. Although these definitions are not strictly required they do
simplify integration of the various Tachyon Forth modules which will be automatically configured to run on the board
Autohelm is built on a Parallax Propeller USB Protoboard, part number 32810, equipped with SD card
}
( P8X32A PINOUTS )
( PIN MASK NAME HDR2X20 DESCRIPTION )
( * SD CARD SPI * )
#P0 |< == &SDDO '' Pin 1 Data from SDCARD S/D input
#P1 |< == &SDCK '' Pin 2 SDCARD clock S/D resistor
#P2 |< == &SDDI '' Pin 3 Data to SDCARD
#P3 |< == &SDCS '' Pin 4 SDCARD chip select (cut pullup for card detect)
{ once SDCARD is loaded, the value of sdpins should be
3x2^24 + 0x2^16 + 2x2^8 + 1 = 50332161
}
" AutoHelm" 0 STRING PCB$
#32811 == PCB
{ this is a replacement for the std SDCARD card detect routine. It is required for this board
because the 32810 has pull up resistors on CS, incompatible with Tachyon's approach
the replacement ucard routine should return -1 (ie true) if a card is inserted, false otherwise
Somewhere in the user code need to have a line like
' SDdetect ucard W!
}
pub SDdetect &SDCS >| PIN@ NOT ;
pub SDpinCheck ( &a.b.c.d -- )
DUP DUP DUP ." ce-miso-mosi-clk = "
24 shr . ." - "
8 shl 24 shr . ." - "
16 shl 24 shr . ." - "
24 shl 24 shr .
;
]~
END
The odd thing is that everything works before trying to mount the sd. SDdetect returns true/false if there is/isn't a card installed. Once I try a mount, then it always reads true, and even if I pull the card the DSCS pin is being held low by the propeller. I thought the pin@ code would mask it as an input but it seems a forever output (low) after the mount. And of course, the mount fails
SDdetect . -1 ok \ card in
SDdetect . 0 ok \ card out
SDdetect . -1 ok \ card in
' SDdetect ucard W! ok
SDdetect . -1 ok \ card in
SDdetect . 0 ok \ card out
SDdetect . -1 ok \ crd in
mount *Card Error* ok
SDdetect . -1 ok \card in
SDdetect . -1 ok \ card out
SDdetect . -1 ok \card in
So to show even more ignorance, I thought that the cs line to the microSD was an input detection line, but Peter's note makes it seem like it is an enable output to the SPI-SD device. Does Tachyon do both a detect and a enable with this pin ?
There is a card detect switch on the holder, with a solder pad, but no explicit contact point. I could add one. Or find and pluck that resistor R26.
I don't understand how you are doing card detect with the CS. If you remove the resistor you only have to call the default CARD? routine that is part of SDCARD.fth as it checks for a floating line by testing rise time, you can't just read it directly as the line would float when it's an input and when no card is inserted. This is the code that is used:
&SDCS OUTCLR --- pulse low, float, check, return high
&SDCS INPUTS --- Float CS
&SDCS IN --- Is it still low or has it been pulled up (by the card's pullup)
&SDCS OUTSET --- force back to an inactive CE output
BTW, although SDpinCheck is unnecessary it could have been written like this:
Peter, now I think I am seeing this. I thought that pad 2 of the microSD was for detecting the card (the SD mode pin is called CD), but you use it for both
detection (floating or not) AND as the SPI chip select ... is this correct ?
Does the R26 interfere with the SPI-CS function ? I shouldn't think so, it goes low as expected following a mount.
If I do a dummy always-true ucard replacement (like the C3 example), the Mount command still fails with *Card Error*, so I am still messed on something.
*** this is a 16 GB FAT32 microSD card ... will Tachyon read this correctly ?
My SDpinCheck was just to see if sdpins was getting set correctly through reboots etc. I like the >B trick! ANd now I see there are a great many such words in Extend!
Peter, now I think I am seeing this. I thought that pad 2 of the microSD was for detecting the card (the SD mode pin is called CD), but you use it for both
detection (floating or not) AND as the SPI chip select ... is this correct ?
Does the R26 interfere with the SPI-CS function ? I shouldn't think so, it goes low as expected following a mount.
If I do a dummy always-true ucard replacement (like the C3 example), the Mount command still fails with *Card Error*, so I am still messed on something.
*** this is a 16 GB FAT32 microSD card ... will Tachyon read this correctly ?
My SDpinCheck was just to see if sdpins was getting set correctly through reboots etc. I like the >B trick! ANd now I see there are a great many such words in Extend!
The only lines that are relevant for SPI modes are those 4 lines. While R26 does not interfere with CS it does interfere with CD which is the SD Card Association's recommended method that uses the card's internal pull-up resistor but you can't detect that if you already have one, so remove it. Adding a pullup on this line is a common mistake as CS is normally an output and doesn't need pulling up. I have had no problems reading all kinds of cards up to 32GB but normally I recommend using Sandisk as some other ones seem less predictable, at least in SPI mode. To dummy the card detect just leave the resistor in and don't add any of your own detect routines via ucard, just leave it plain and simple, it will work.
OK, just plain and simple gives the error on mount, had another 16GB uSD (SanDisk too!) that fails in the same way. So either my build is broken somehow, or I can't read 4 pinouts, or I don't have what this needs. Thanks for all of your help Peter!
EDIT ... fourth option ... bad solder on the Vdd to the uSD socket ... Dang.
OK, just plain and simple gives the error on mount, had another 16GB uSD (SanDisk too!) that fails in the same way. So either my build is broken somehow, or I can't read 4 pinouts, or I don't have what this needs. Thanks for all of your help Peter!
EDIT ... fourth option ... bad solder on the Vdd to the uSD socket ... Dang.
Cheers!
Dang! the "fifth" wire! Does it work now?
P2 must go to "MOSI", the Master(Prop) out to SD Data In and also P0 to "MISO"
So sdpincheck should report 03 00 02 01
I see the bad contact with the meter, but my solder iron isn't fine enough ... tomorrow at the shop.
I'm not sure why my SDdetect could see the card without Vdd ... maybe a trickle of current .. ? I tried a few cards too, and one RaspPi card gave another error ('format') even though it is fat32. So it is a partially blown fuse. Or the signal lines were powering up the uSD ?
I had checked all of the signal connections, thought I did the supplies, but intermitants are hard to figure. Better to do it right.
I see the bad contact with the meter, but my solder iron isn't fine enough ... tomorrow at the shop.
I'm not sure why my SDdetect could see the card without Vdd ... maybe a trickle of current .. ? I tried a few cards too, and one RaspPi card gave another error ('format') even though it is fat32. So it is a partially blown fuse. Or the signal lines were powering up the uSD ?
I had checked all of the signal connections, thought I did the supplies, but intermitants are hard to figure. Better to do it right.
With SCK and MOSI high there will be enough current flowing through that CD may appear high. I don't think it's an intermittent though since there is no power getting to the card. Expect that as long as you have your pins configured correctly that everything should work. In case there is a format error a simple !SD should return with a non-zero value if all is well with the card itself.
In EasyFile.fth, this is the definition of the FC@ routine
pub FC@ ( faddr --- byte )
FILE@ ?DUP IF + 0 MAX FSIZE@ MIN XC@ ELSE FALSE THEN
;
If I get this (Ha!) the faddr is an offset into the file, and can range from 0 to the filelength. TF constrains (faddr+File@) to be >=0, then finds the minimum of (faddr+FILE@) and FSIZE@.
Won't the this MIN always return a small number that probably isn't even in the file ?
On the other hand, simply adding the offset to FILE@ and executing XC@ directly seems to work.
FILE@ 200 + XC@ .BYTE 6F ok *** seems to get a byte from the file
200 FC@ .BYTE 00 ok *** always returns false
In EasyFile.fth, this is the definition of the FC@ routine
pub FC@ ( faddr --- byte )
FILE@ ?DUP IF + 0 MAX FSIZE@ MIN XC@ ELSE FALSE THEN
;
If I get this (Ha!) the faddr is an offset into the file, and can range from 0 to the filelength. TF constrains (faddr+File@) to be >=0, then finds the minimum of (faddr+FILE@) and FSIZE@.
Won't the this MIN always return a small number that probably isn't even in the file ?
On the other hand, simply adding the offset to FILE@ and executing XC@ directly seems to work.
FILE@ 200 + XC@ .BYTE 6F ok *** seems to get a byte from the file
200 FC@ .BYTE 00 ok *** always returns false
The 0 MAX and FSIZE@ MIN (return the minimum value) simply constrain the address to no more or no less than the file which is especially important when writing to the file and only to the file. But there are probably some changes due as virtual file access is still limited to the first 4GB but all I have to do is use sector addresses as an offset instead. It is probably unlikely that more than 4GB will be used for embedded work but somebody will probably still dig out their 32GB card packed full of files and expect it to work as they play.
Hi Peter, thanks for the quick reply.
So MIN is finding the minimum of (FSIZE@, offset+FILE@), which so far is always FSIZE@ (by a longshot!). And this is not directing XC@ to a byte in the file.
What if MIN checked (FSIZE@, offset) instead ?
This is reading from a file that contains some TACHYON documentation ... the pointer math I think I get, but I don't see how the checks inside FC@
are intended to run.
dir
NO NAME
SYSTEM~1. .hs.d. 0000.4040 Apr 16 2016 13:48 0,000
TEST .TXT .....a 0000.40C0 Apr 16 2016 13:49 3,187
LOG0003 .TXT .....a 0000.4100 Nov 3 2013 15:25 1,072
LOG0004 .TXT .....a 0000.4200 Nov 3 2013 15:25 1,072
LOG0005 .TXT .....a 0000.4300 Nov 3 2013 15:25 1,072
LOG0006 .TXT .....a 0000.4400 Nov 3 2013 15:25 1,072
LOG0007 .TXT .....a 0000.4500 Nov 3 2013 15:25 1,072
LOG0008 .TXT .....a 0000.4600 Nov 3 2013 15:25 1,072
LOG0001 .TXT .....a 0000.4700 Nov 3 2013 15:25 1,072
LOG0002 .TXT .....a 0000.4800 Nov 3 2013 15:25 1,072 ok
[b]fopen TEST.TXT...opened at 0000.40C0 ok
fsize@ . 3187 ok
file@ . 8486912 ok
300 1 do i file@ + XC@ emit loop[/b] [color="red"]hange baud rate if desired (default=230400) **** Version 2.7 has default of 115200 (line 184)
Compile and load into Prop EEPROM (F11)
Connect terminal emulator to Prop serial (same as programming port), set for 230400,8N1
Hit CR (Enter) key and the board should respond with " ok" (^C will cause [/color] ok
ok
ok
[b]300 1 do i FC@ emit loop ok
300 1 do i file@ + XC@ emit loop[/b] [color="red"]hange baud rate if desired (default=230400) **** Version 2.7 has default of 115200 (line 184)
Compile and load into Prop EEPROM (F11)
Connect terminal emulator to Prop serial (same as programming port), set for 230400,8N1
Hit CR (Enter) key and the board should respond with " ok" (^C will cause[/color] ok
In EasyFile.fth, this is the definition of the FC@ routine
pub FC@ ( faddr --- byte )
FILE@ ?DUP IF + 0 MAX FSIZE@ MIN XC@ ELSE FALSE THEN
;
If I get this (Ha!) the faddr is an offset into the file, and can range from 0 to the filelength. TF constrains (faddr+File@) to be >=0, then finds the minimum of (faddr+FILE@) and FSIZE@.
Won't the this MIN always return a small number that probably isn't even in the file ?
On the other hand, simply adding the offset to FILE@ and executing XC@ directly seems to work.
FILE@ 200 + XC@ .BYTE 6F ok *** seems to get a byte from the file
200 FC@ .BYTE 00 ok *** always returns false
got curious and had a look
to me it looks like Peter started to implement the handling of SD > 4GB, but did not fully complete it.
writing 4GB will take a very long time anyhow ;-)
I never used >4GB SDs.
And I think the MIN/MAX check for faddr between 0 and filesize should go before the add.
got curious and had a look
to me it looks like Peter started to implement the handling of SD > 4GB, but did not fully complete it.
writing 4GB will take a very long time anyhow ;-)
I never used >4GB SDs.
And I think the MIN/MAX check for faddr between 0 and filesize should go before the add.
Yes, I had started and tested it but got sidetracked and forgot about it! Even though I am using 8GB microSD cards now as even Sandisk ones are very cheap, I doubt that most embedded projects will need that capacity although they would for a large number of wave files or for the learner who likes to insert any card and expects that everything just works. So it just works for 4GB but I had started to implement using the file sector instead which would allow access for up to 2TB using 512 byte blocks.
Comments
3 pin@ . \ gives 0 if card is in, -1 if not
This board has a 100 K pull up on CS, and I see Peter's comments that this resistor is redundant and unnecessary, and sure enough I can't seem to get Tachyon to see the card. Rather than cutting traces, ...
Has anyone used the ucard reassignment to introduce and alternative detection scheme ? Any tips ? Is this the approach to take ?
Cheers!
here is a quote from SDCARD.fth
--- Used to set C3 SD method etc
TRUE == C3CARD
pub C3 $C3 ' PCB 1+ ! &32.10.9.11 SDPINS ' C3CARD ucard W! ;
so in your case
pub mycard 3 ?LOW ;
pub MyBoard $45 ' PCB 1+ ! &32.10.9.11 SDPINS ' mycard ucard W! ;
with your pins setting could do
To be honest, I'm not sure my brain is up to this...progress is v. slow.
Thanks again!
Hardware specific files such as SDCARD.fth need to know which pins are being used and also about any special methods to use the hardware. By default it uses a configuration that suits some of my hardware. To make these drivers hardware specific it can be done in one of two ways. The default method is simply to change these parameters at runtime by defining new pins using SDPINS and possibly revectoring the card detect method. The other method is to use a header file with all the pin definitions etc for that pcb plus a way to identify the pcb. This is where PCB$ and the PCB constant come in as they can provide that information to the drivers and also useful for reporting hardware information. So PCB is a unique constant that identifies the hardware, in the case of the C3 I elect to use the value $C3, sound simple enough. If I have one of my P1432 boards then I set the PCB constant to 1432 and also set PCB$ to a human friendly string like this:
Using a header file is the way I prefer to compile but if you use a precompiled binary then you can still setup the board at runtime.
Many Parallax boards use pullups on CS and dedicate an I/O for card detect or use a clunky resistor method. Either way it is simply a matter of defining a specific card detect routine and patching the vector "ucard" like this:
I'm not sure which board is the "USB protoboard" but the SDPIN parameter is defined as &cs.miso.mosi.sck where mosi is the Master Out Slave in or in other words the data from the Prop to the SD card. You would never have 32 as a value really, valid values are from 0..31. MJB selected $45 ' PCB 1+ ! to change the PCB constant but normally this value would give some indication of model etc. I noticed that if PCB is not already defined that the SDCARD code will not compile so I have just made a little fix to that now and will update the dropbox. I may just make a new sdcard binary and you can always setup the board at runtime.
Since SDPINS will run using my defs of &SDDO etc when SDCARD loads, then I will define the replacement routine for ucard in my hardware profile file, then make it active in the main code.
Has MULTIFAT been completely replaced by EasyFile ? As a heads up, the Readme.txt file in the root of the DropBox refers to MULTIFAT
The new (?) kernel (version long 27_150908,1000 ; was uploadedto Dropbox 21 days ago) has a long named pblksz, line 1046&1062, that is set to 512, and this is keeping it from compiling to the board My previous version (version long 27_150902,0100) had a constant of 511 on line 1046, seemed to work fine.
Thanks again!
I will check and update the readme and I see the problem with pblksiz, it compiles fine in BST but not in Prop tool, but it is an error that I will fix shortly. Look for v2.8 kernel though as I have some updates to replace 2.7.
https://www.parallax.com/product/32810
Thanks for looking at that ... I can only imagine how much time you pour into this to support others ... you probably cringe when another newbie shows interest in Tachyon. Trust me though, even if I understand only a fraction of what you say and have done, I very much appreciate all of it.
Cheers!
So either MOUNT at startup or add ?SDCARD as a poll with: ' ?SDCARD +POLL which off course still involves a user startup. However just for interacting you would just type MOUNT or else DIR after startup.
Remember too that you can have 4 files 0..3 open at a time although file 1 is also used for the directory.
also have a look here Tachyon code and documentation snippets from Tachyon thread
TRUE == C3CARD
pub C3 $C3 ' PCB 1+ ! &32.10.9.11 SDPINS ' C3CARD ucard W! ;
or it can contain a reference to a executable word
pub mycard 3 PIN@ NOT ;
pub MyBoard $45 ' PCB 1+ ! &32.10.9.11 SDPINS ' mycard ucard W! ;
Also, as Peter points out #P32 is not a possibility, so is &32.10.9.11 just a way to have SDCS = #P0 ?
The magic and mystery of forth continue to block me ...
If you already have created a hardware definition file and loaded that before SDCARD.fth then you don't need to worry about SDPINS. However you can use SDPINS to reassign the default SD pins at runtime before you try to initialize or mount the card. So SDPINS is a quick and easy way to set those pins using a single long or the handy & notation.
In the screenshot from the schematic you can see all the pins of the SD card however besides power and ground only four lines are required and they are the same for any bidirectional SPI device: Serial Clock (CLK or SCK), Data out to device (MOSI), Data in from device (MISO), and an active low chip select (CS). The constant that has been used to set SDPINS is only an example as the actual pin numbers you need to set are according to how you have connected them back to the Prop. Also I see that your board does not have any card detect scheme but the easiest way to make it detect the card is simply to get a hot iron with a bit of solder and flick R26 off the board (or cut the track) so that pin 2 of the SD card which is CS is left floating the way it should be. When a card is inserted it already has a pullup resistor which is how by default Tachyon detects the card.
So just substitute the pin numbers you are using in place of these symbols &CS.MISO.MOSI.SCK SDPINS. If you removed R26 then you don't need to patch the user card vector to do something different and it is not necessary to setup the PCB constant either. Forget about those two lines of example code, either have the hardware lines predefined during compile or just use SDPINS at runtime.
There is no need to set the PCB constant which is handy for reporting and software to check the hardware details if it needs to know. However if you do define it during compile then you may as well set it to the Parallax number #32810 == PCB or modify it at runtime by directly modifying the compiled constant with #32810 TO PCB which is the same as saying #32810 ' PCB 1+ !. If you then type PCB PRINT it should print out the value of that constant which is now 32810.
BTW, The & notation is a a way to force a number to a particular base such as $BEEF for hex, #9876 for decimal, %10110001 for binary, and & for IP notation where each dot separated number 0..255 represents a byte in a long. However SDPINS expects pin numbers in the range of 0..31 as it converts this to a 32-bit mask internally so there is no such pin as P32 so it wraps around to 0 in this faulty case.
usually ucard is 0
in this line it is tested and if not 0 it is inpterpreted as a call vector and jumped to ececute the word/bytecode at the address.
in the C3 example above C3CARD just executes TRUE, so just make sure a SD in in already ;-)
the SDPIN parameter is defined as &cs.miso.mosi.sck with pin values in decimal.
so you are right, 32 is definitely strange, I just copied the line from SDCARD.fth
I don't know the C3 and what this would mean, either bug or Peter trick ;-)
If your SDCS = #P0 then just put a 0 there and try.
this just got me curious ... and I gabe it a quick try. better just use IP notation, there leading 0 works
The line you show is the one that is making me spin my wheels ..
If ucard has been assigned true (-1), then wouldn't this line cause a crazy jump when run ?
The default is ucard = 0 so therefore no JUMP will be taken. This vector was added for odd hardware but you don't need to worry about it. If though you put a "crazy" address in there then it may indeed do crazy things.
NOTE: I see there is a bug with the &0.x.x.x processing that I will have to check although the infix : notation seems to work correctly
Peter, that is exactly what I have done, with my hardware file
The odd thing is that everything works before trying to mount the sd. SDdetect returns true/false if there is/isn't a card installed. Once I try a mount, then it always reads true, and even if I pull the card the DSCS pin is being held low by the propeller. I thought the pin@ code would mask it as an input but it seems a forever output (low) after the mount. And of course, the mount fails
So to show even more ignorance, I thought that the cs line to the microSD was an input detection line, but Peter's note makes it seem like it is an enable output to the SPI-SD device. Does Tachyon do both a detect and a enable with this pin ?
There is a card detect switch on the holder, with a solder pad, but no explicit contact point. I could add one. Or find and pluck that resistor R26.
BTW, although SDpinCheck is unnecessary it could have been written like this: >B simply does a $FF AND to extract the byte.
detection (floating or not) AND as the SPI chip select ... is this correct ?
Does the R26 interfere with the SPI-CS function ? I shouldn't think so, it goes low as expected following a mount.
If I do a dummy always-true ucard replacement (like the C3 example), the Mount command still fails with *Card Error*, so I am still messed on something.
*** this is a 16 GB FAT32 microSD card ... will Tachyon read this correctly ?
My SDpinCheck was just to see if sdpins was getting set correctly through reboots etc. I like the >B trick! ANd now I see there are a great many such words in Extend!
The only lines that are relevant for SPI modes are those 4 lines. While R26 does not interfere with CS it does interfere with CD which is the SD Card Association's recommended method that uses the card's internal pull-up resistor but you can't detect that if you already have one, so remove it. Adding a pullup on this line is a common mistake as CS is normally an output and doesn't need pulling up. I have had no problems reading all kinds of cards up to 32GB but normally I recommend using Sandisk as some other ones seem less predictable, at least in SPI mode. To dummy the card detect just leave the resistor in and don't add any of your own detect routines via ucard, just leave it plain and simple, it will work.
EDIT ... fourth option ... bad solder on the Vdd to the uSD socket ... Dang.
Cheers!
P2 must go to "MOSI", the Master(Prop) out to SD Data In and also P0 to "MISO"
So sdpincheck should report 03 00 02 01
I'm not sure why my SDdetect could see the card without Vdd ... maybe a trickle of current .. ? I tried a few cards too, and one RaspPi card gave another error ('format') even though it is fat32. So it is a partially blown fuse. Or the signal lines were powering up the uSD ?
I had checked all of the signal connections, thought I did the supplies, but intermitants are hard to figure. Better to do it right.
With SCK and MOSI high there will be enough current flowing through that CD may appear high. I don't think it's an intermittent though since there is no power getting to the card. Expect that as long as you have your pins configured correctly that everything should work. In case there is a format error a simple !SD should return with a non-zero value if all is well with the card itself.
Of course ! why wouldn't it
Thanks for your patience Peter, MJB. Now to learn the language and to make it tick over.
Cheers!
In EasyFile.fth, this is the definition of the FC@ routine
If I get this (Ha!) the faddr is an offset into the file, and can range from 0 to the filelength. TF constrains (faddr+File@) to be >=0, then finds the minimum of (faddr+FILE@) and FSIZE@.
Won't the this MIN always return a small number that probably isn't even in the file ?
On the other hand, simply adding the offset to FILE@ and executing XC@ directly seems to work.
The 0 MAX and FSIZE@ MIN (return the minimum value) simply constrain the address to no more or no less than the file which is especially important when writing to the file and only to the file. But there are probably some changes due as virtual file access is still limited to the first 4GB but all I have to do is use sector addresses as an offset instead. It is probably unlikely that more than 4GB will be used for embedded work but somebody will probably still dig out their 32GB card packed full of files and expect it to work as they play.
So MIN is finding the minimum of (FSIZE@, offset+FILE@), which so far is always FSIZE@ (by a longshot!). And this is not directing XC@ to a byte in the file.
What if MIN checked (FSIZE@, offset) instead ?
This is reading from a file that contains some TACHYON documentation ... the pointer math I think I get, but I don't see how the checks inside FC@
are intended to run.
got curious and had a look
to me it looks like Peter started to implement the handling of SD > 4GB, but did not fully complete it.
writing 4GB will take a very long time anyhow ;-)
I never used >4GB SDs.
And I think the MIN/MAX check for faddr between 0 and filesize should go before the add.