 The story so far. I am porting Fusix to the ESP8266 and Currently I am fighting the SD card driver I have everything working with the internal flash, but it's just too slow So I want to use a external SD card for storage and this is turning out to be harder than everything else put together So after several sessions of not getting anywhere with it. I decided to Instead do some work on the TTY, but plans changed when I had a bit of a breakthrough or rather a Realization of the really obvious thing I should have tried very early on Which is to write some Arduino code to talk to the SD card and see what it did the answer is works fine So this is the signal Analyzer trace of the Arduino code Writing to well accessing the card So that you can see here is the init sequence Here is the command going out here is it receiving the reply and here is the reply back from the card so Everything is fine except that pulse few doesn't seem to want to decode that very well I'm a little suspicious of pulse fuse decoder to be honest at this point so we know that the card is working the SD card reader is working the the SPI interface on the microcontroller is working and This means that whatever's wrong is just my code which makes life so much simpler Plus we have a trace here to compare against for my code versus The Arduino code so let's Refresh it with my code and see what happens. I think I can actually already guess what might be the problem But let's just set up a new Session I wish I could duplicate this one But I'm not sure I can Might be able to save it and then load it in again Yeah, that seems to work Unless it's going to try and you do something clever because they both have the same file name let's save this again and Session to just to make sure they are different. Okay, so let's Refresh. Oh, yeah, and I forgot to wipe the file system on the NAND flash, but that's okay. I don't care about that for now So it's flashing Hit the hang on with the run Button what we can only run the first session fantastic Okay, well Let's hit the run button Hit the reset button. I think I was it's Great. It's hung Fantastic. Okay. Let's try that again. Good job. I saved the session so 12 megahertz 200 million and Here it is So this is produced by my code. So if I create a new session and open the old one Okay, so this is the Arduino code this is the Fusix code and Wait a minute. That's a response Let me try that again. Well, of course, this will be happening because the Arduino code powered on the SD card And initialized it. So now now it's this is This is garbage This is the command going out This is the clock chopping madly Okay That's weird. That was the weird behavior I was seeing before Interesting. Well, anyway, let's compare with What we are getting out of The Arduino code So firstly the clock timing is 250 kilohertz which is Similar to the 320 that we're using here This is sending one two three four five six seven eight nine ten bytes of Sync pulses versus our 20 that's fine Comparing the the actual command byte we see the Well apart from the nasty clock noise. We are seeing the signal going ha The mozzie signal is changing on a clock Trailing edge and being sampled on the clock leading edge, which is just what we're seeing here Let's find that So I believe that apart from the nasty clock noise. This is all fine. However, the big difference is There's a long period with CS high and mozzie low before it does the initialization Which may be important Now I thought that the init code would do that so this is raising CS and then sending out the 20 bytes of data hmm However, I am a little worried about the clock noise and I'm wondering if I'm failing to configure the clock properly and The issue we're seeing here is because the Arduino codes have set up the clock in a particular fashion but The clock here is okay, and we're using the same code to write These pulses as we are to write the command You know except for the clock select lie or the chip select line. This is kind of weird Do we need a pull-up resistor? Well I can go find the Arduino code. I have looked at this before and their SBI code is annoyingly complex This is This is their code Which does a complete transaction? I think there is nothing particularly interesting here so I actually want the SPI interface Let's Where is this called from this? I remember is being called from here, so Wait SPI zero command Sends it to SPI zero Okay, this is the one we want. So let's find out where this is called from. Oh, no, I was wrong. No, it's wrong Confusingly wrong. Yes, I'm a little bit puzzled I'm sure I remember seeing SPI stuff in here slave In here, I don't think so okay, um Honestly, I remember seeing the code before I just can't remember where it is Was one of these wasn't it? I've got the actual Arduino code In here, I believe yes, so let's use some more sensible Traces That's too much noise about this this routine looks like it's Talking to the NAND flash, which is not what we want. We've got SPI utils. We've already looked at By This is this is all NAND flash stuff. Yeah, I'm sure I found this before So here is the SD card file system So what's this calling? underscore f s ESP SD fat Is empty SD is nothing in there SD FS This is the thing we saw before. This is looking at underscore FS which is SD fat in here Okay, I am deeply confused. I did remember seeing this before Let's search for one of these SPI 1c that should all right, right. I thought this was a Generic SPI, but it's not it's platform specific. I would still like to find the the actual SD card stuff SPI usse Well, anyway, let's get back to this The clock initialization I am Uncertain about But this we can do something about fairly straightforward Lee in the in it code Before we send out the bytes we want a short delay And we can do that with set timer sick Believe well figure out exactly how much the delay is and this end is here That's 200 microseconds, so we probably don't want to use a timer for this but instead a busy loop set timer duration I Think is in milliseconds. We'll have one millisecond delay work 16 bits mini ticks The actual SD card stuff here has a slightly upset timer milliseconds Yeah, let's Set timer to the seconds one millisecond Wait for the timer to expire simple Because we have the timer interrupts this should work rather than just hang if it does just hang then that means our timer interrupt Doesn't work. Okay. I'm going to guess a timer interrupt doesn't work Okay, I wonder if interrupts are on at this point Well, let's just do a busy loop So the volatile int is to prevent the compiler from optimizing that away great, and there goes the signal analyzer again Wasn't crashing so much last time. I Think I forgot to save here Okay, so let's set this to 12 megahertz 200 meg samples Hit run and Work let's try that again. Okay. What have we got? Okay? Here is our Delay here is our init sequence Here is our mangled clock So I think I'm going to have to Do something about that all right, so Let's take a look at this SBI code and see what it does It's possible. We're setting the clock up incorrectly So here we are configuring our pins the S clock pin gets set to the HSBI function my so HSBI Mozi HSBI I don't know what that you sse is This appears to be configuring everything to well the control register becomes zero and This is In our code. This is configured down here SPI slave edge That I think this would be the wrong setting Maybe this is configured elsewhere U1 is configuring the size of the bytes of the words Which we are doing here it's setting duplex mode because we want this kind of Sending okay, this is setting the chip select stuff. It wants to know whether to use the The HSBI is chip select handling or to use a GPIO. I'm not sure why this configuring it as an input But never mind. So Set the SPI mode. We want mode zero CPOL zero CPHA is zero We don't want this set You don't want this set. Yeah, all zeros is fine for SPI mode zero Set the bit order. We want most significant bit first to unset both of these. Yes clock configuration Which is the complex computation and then eventually it calls set clock divider, which is this Which is what we are doing here? GP mux is unset Whatever this does Okay, set the data bit. We want eight bits. So yes, so this is seven shifted left and seven shifted left I think for this we want this But I don't think that makes a difference Right when we do a transfer we set eight bits of data Configure SPI you yeah set the data into SPI w zero Set busy wait until not busy and return the value So this is both a send and a receive we could Combine this easily enough transmit bite is send receive be and ignore the result Receive a bite is send receive Other than ff Make our code a bit smaller So my guess is something's wrong with the clock configuration Because this clock is us hopelessly garbled So let's try power cycling the board and try that again. Okay board power cycled run reset and our clock is back the way it was Interesting, however, we are still not getting any response from the board Okay So let's open our saved session What is different about these two traces? Well here we have our Initialization and the command packet here. We have our initialization and the command packet So this is actually responding. This is decoding The command and the response bite. This is doing the commands, but not the response bite So what could be different do we need to toggle CS here? Possibly as we're not doing that here. Okay at the beginning of our command packet in the working code we drop CS Pause immediately start sending data These look the same These look the same So there are only really two possible differences here One is the clock speed Because we are using a faster clock than the Arduino is The Arduino is using 250 kilohertz for this and the other is this toggling of chip select Well, this is the easier one to fix. So let's do that Sdi sbc lower CS Sbi raise CS Okay possibly that wants to be a bit longer, but We have actually toggled CS and Nothing's happening. Is there a I don't think there's a busy loop routine we can use for short delays Now I don't think there is okay, so Well, it's not going to be equal zero So this has the Arduino has fewer reset pulses than we do They are the same shape as ours So maybe it's the clock speed. I Am somewhat suspicious about this the clock speed initialization Now this uses this Extremely complex clock initialization code which Itterates onto iterates computing values Until you come up with the closest possible Clock speed to the one you asked for Which would be somewhat of a pain to actually Copy what's this last set register thing? Don't configure the clock I Circumstances Well, we can use This computes the actual clock frequency from the value being set in the clock register However, there are actually multiple fields and that routine only seems to use two of them and we stole this code from the the SDK So thought it would be right So set clock divider is actually doing the work has been set to reg value Which is being initialized nowhere? Oh Oh, it's It this is a union of an int32 and a bit field So what it's doing is dividing up the bits in the bit field Sorry the bits in the register by fields here That might be worth stealing Yeah, I think the sensible thing to do here is to Steal the steal this union and then the clock generation code So that will be This we'll have to convert this into C and chop it down somewhat Okay, so This wants to go here Clock T becomes a clock T This is a normal function So this is going to be peripheral clock just to find in globals clock times so if The requested speed is faster than the peripheral clock set the peripheral clock speed. I Don't care about the last set stuff set the This calculates the new clock speed change that into a She would to do that throughout and but we also need to change the These as well put the debug tracing in turn this off and we want to Set frequency Go fast wants to be eight megahertz otherwise 250 kilohertz Undefined reference to abs Okay, what's this going to do? It worked Look it found partition table so apparently the clock frequency is much more Sensitive than I thought here we go command byte response and it has found This is actually the SD card I use for the MSP 430. So I think I will not overwrite this But that has successfully probed the partition table done all Yeah, it works Awesome. Okay. I'm Do I want to keep this code or attempt to Clean it up it is It is a blatant ripoff of the Arduino code, which I kind of like to avoid nothing wrong with the Arduino code but I Would like to be able to Understand it more What does the tracing say? these are and In fact The tracing is mostly garbage real frequency zero 250 kilohertz so the Only thing I can think of is that we failed to set the clock correctly Here are the fields in the clock which are all ones so the pre-div What's name is? two Assuming these are left to right, which I don't necessarily know so what seems to be happening here is It started with a guess Which is presumably here. Now it starts with the Minimum and then it's it resets to value of zero it fills the various fields with something And then it iterates it does a binary search Looking for an appropriate value Okay, so if you switch back to my original code With no other changes What happens? It doesn't work What is the value we are writing to? clock register this Let's go back to the Arduino code and the value being written is this SPI clock before the register documentation such as it is You get SPI clock be nice to have Documentation as what these actually mean, but this is the only reference in the whole thing so SPI frequency is Oh, well, that's actually pretty straightforward in terms of computation So why is the Arduino going through all this complexity well There seem to be only two values we care about Which is the pre computation value at n H and L are derived from the others so if we simply do Uh, let's copy this so we actually want to calculate Pre and then so that would be three plus one I assume that the parentheses are like this That is there are two divisions So that would end up being n plus one times three equals 80 Megahertz divided by pre plus one and plus one times pre plus one Times freak equals 80 megahertz We know that this is 250 kilohertz So the top so the pre computation value We want 16 17 18 so it's this shifted right by two four and is shifted right by 12 But n is only six bits. So that's a one so therefore our Actually, I need to do so therefore going by the first formula so that's 80 megahertz divided by five divided by two Which is eight million That is not 250 kilohertz. Oh This has actually broken out the values for us here, which is nice But that still gives us pre equals four n equals one so This routine Yes clock divided by No, I've been doing that I've been doing this incorrectly The parentheses It's like that No, it's not. No, it's not. I Think I was right the first time so 80 divided by the pre computation value gives this divide that by the n value Gives this but that is nothing like the 250 kilohertz that We should be getting our peripheral clock is set to 80 megahertz. We know this to be true Otherwise, this computation would not work. Also. Why is the real frequency? Calculated by this Wait a minute. Where is ESP 8266 clock set? Here well, this should be Peripheral clock times One million. Let me just check to make sure that still works Maths is not my strong point. I have a lot of trouble keeping numbers straight in my head. I Suspect it may be Okay, that's not working It may be a very small touch of dyslexia. I'm okay with words. I'm good with words. I write but Maths not so good. Oh Actual maths. I'm fine with I'm all thinking of arithmetic Okay, so this is the value being written So pre computation of four n is one Real frequency is zero. I Really don't understand what's going on here Yeah, I think I am just going to keep this code given that it works, but let's Simplify slightly and Reformat it according to the way I like I'll also simplify these I Because we're always checking for busy before and after each operation. We don't need Those weight routines, is there any real abs we can use? studlib.h I can't remember studlib is part of the The compiler library this should be all right This normally means yep Missing brace there Rather an extra base there There may be an abs in the Rom so wait for that to That is on abs. What's that what this is doing is a two is the input It negates it If the result is greater than zero If a two is greater than zero copy if a two is greater than zero copy a two into a four Copy a four into a two. It's not how I would have written it, but it's there. In fact, there's an abs instruction Interesting, but we can use this which will save a hand for the bytes of SDSP I now do we know libraries SPI SPI okay, so We now have a working SD card library, so let's quickly Check that in and then let's put the file system on it Though it suddenly occurs to me that It doesn't seem to be scanning the flash. So did I disable that? Yes, I did We want the flash to be HD a for reasons Here we go Scanning flash 189k HDA we can prove the just improve the tracing a little so It hasn't found any flash partitions It has found three SD card partitions on HPU one HP two and HP three It's failed to mount the flash. So it panics Okay now let's undo some of our Debug code This we will need This we will not need This should just be raised. Let's just get rid of all of that Does it still work? Okay, let's power cycle the board and reset it Still works good. So here is the SD card stuff here is the Our boot code which we fiddled with without really knowing what we're doing Device in it with the SD card stuff in it Dev SPI badly needs a cleanup. Oh, yes, and we don't want to try and run SH instead of in it But that's the lot so Reverts starts to see Just to rebuild make sure it works Good. All right. So now we want to put together a file system, which is easily done As I said, I don't want to write onto the The same card that I'm using for the MSP 430 because I might as well keep that for the time being So I'm going to go find another card and get this set up be back in a moment Okay, so I dug up a card. It's an old one gigabyte one that I seem to have been using for a Android firmware upgrade. So let's partition it. Here's the old partition table delete I'm going to create a primary partition for the swap Which can be one leg I mean we have loads of space now create another partition. I Don't actually know how big physics partitions can be Let's just make the rest and see what happens so there we have our two partitions Right, we're going to use our The same Command we were using the same script we were using before to set up the root file system, but we're going to Adjust it so we don't want to do the Loopback stuff. We want this is the The partition that we're going to put the actual file system on We don't want to do this anymore because we don't care about Trimming on the SD card. It will take care of itself We don't want to do that and we don't want to do that Okay, so SDG is correct Okay, so it did the thing so now the only thing to do is To put the card in the board Which is done fire up the serial terminal Press the reset button reset button Interesting. In fact, that's not the only thing we need to do because we need to change the the boot partition This is we need want HDB in both cases. So we're going to have to Refresh Dressing Let me power cycle that board again, okay Flash it's not flashing. I haven't done anything to it other than to Replace the card what I pull the card out Okay, reflash it flashes and of course the cards not in it. Let's put the card back in Hit the reset button. It doesn't like the card interesting it's a Sandisk micro SD card in an adapter. There's nothing particularly exotic there. Let's try the other card The one I was using before and reset Okay, that's bizarre let's swap the Micro SD cards I Mean they're both Sandisk devices So now I'm putting the new micro SD card into the old adapter Like it's in Reset it doesn't like the card, but it works fine in the PC and this is the Old card in the new adapter Yep Interesting. Oh, well, I suppose I better go and get another one Here's a 512 mega card. I have a lot of cards and it's on SDG as before That looks like I think I may have already flashed this Okay, so let's it's partitioned This card may not work, but let's actually just try it. Okay, and unplug from the PC Plug into the board serial terminal This is very strange Okay, card number three or four even Okay, here is a one gigabyte Sandisk card a different one. I haven't flashed it I'm just going to stick it in the board and hit the reset button No, why isn't this working? Let's just try the one we know works first I think I may have got them swapped around Why is this one Consistently working and all the others consistently not Well, here's a slightly dodgy MMC card No, back the original card Odd very very odd thing is this can't be anything to do with my code because it's booting perfectly, well The kernel is being loaded out of flash so none of my code is ever running Unless there is something else going on Let's try Let's try a random card and hit the button. Okay, that's not working. So let's put some message in here Um like so I cannot yes, put the Yeah, I keep typing etc instead of this Okay, so this should print the word boot and start up Okay, I just unplugged the card and it suddenly starts up. This is nothing to do with me Absolutely nothing. Well, you can't see the word boot appear because it hasn't The serial does of you art hasn't settled it seems to be that some cards work and some don't so Well, I want to get on so I think For the only thing to do here is the working card The only thing to do is to reuse this card So There it is an SDG So we've got a two megabyte swap partition a 32 megabyte file system partition and everything else So let's just do let's just copy the File system like that like that and just reuse the old card The only one that I know works all right, it's plugged in it's flashed hit the reset button and It's mounted the file system Good grief. This is slow Is it actually working? I don't need this anymore. It didn't work anyway Well, it's loaded in it and in it is running So one thing we can do is to optimize our transmit and receive functions But let's just put in So we should be able to see it read and write sectors So get to here and it just stops dead. That's not so brilliant But reading and writing is much faster than it was this was it loading in it From the file system doing some file system stuff presumably forking This is it swapping out in it Okay Something's not right Luckily we have the tools to debug this Okay, we can see it's done the fork. That's got further Started in it Does it stuff it forks here it swaps something out Swap out done We swap we load in yeah, here's exec loading in the new stuff Set something up swap out fail. It's printed swapping out But it hasn't printed swap out done So it seems to have stopped about here This sounds like Something in our transmit receive code has wedged and it's waiting for the card to respond But it's not Okay, so let's Take a look at this Here's our transfer sector function so Here is it writing out a sector So you transmit the the We send the command to do the right Including the lba address Then we transmit the data And wait for the result Now Is it successfully transmitting a complete sector? Yes, it is. It's the next thing's not working. I'm just going to change this to send receive after a plus One And this to send receive OXFF because that then will allow me to do this So that we can trace each individual byte going out but not the sector data Okay, so We have We have I believe sent the command Plus the four byte argument Plus the dummy crc at the end Then we transmit the We've got an okay from the card. So we transmit the The 254 to indicate the data's arriving Then our sector data Then our dummy crc in a padding byte And then we wait for a response sdi spi wait Is supposed to time out, but it won't time out because our timer doesn't work So I think that something's gone wrong with the card. It's not receiving a response, but Uh, we aren't timing out and attempting to retry All right, then so in devices Here is where we set up the timer Here is our timer interrupt I'm pretty sure this was working No queues. Oh, we are getting queues periodically So why are we suddenly stopped? And why is the timer not advancing? So timer stuff is dead simple The timer itself is just the value where the timer expires Which happens here Let's just see. Are we actually Incrementing the timer The system clock I do not see any eyes So let's put that here and see if that makes a difference Yes, we're getting eyes throughout So this is not working right Where is ticks per d second set up? Uh, that's supposed to be Uh, so ticks this d second is a counter of the number of ticks per tenth of a second So This will period this will count up until we fill a fill up a d second And then it will update the system timer start.c ticks per d second so is Ticks per sec should be 20 that doesn't look very bad Okay This may crash horribly calling key print f from interrupt handles is a terribly bad idea So six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen zero one And then swap out happens Is swap out happening from inside a interrupt handler? Uh from with it with interrupts turned off it might be So that happens in here Calling do fork interrupts have been turned off We call do fork So this is timing out because Well, it's hanging because something's gone wrong with the sd card. It's timing out inside a place where the Timeout timer isn't operating Okay, so let's try Well, let's put that back the way it was and let's go to Here and let's try Slowing down the sd card See if that makes a difference Nope, it still fails. So this is spi weight that's Failing so we can let's just see what the card returns Well, that seemed to be fine It did lots of stuff And eventually it crashed Here it's tried to Store to instruction ram With a byte that's not going to work This makes me very suspicious as to why it ever worked before Okay Let's Because remember the instruction ram can't do byte accesses So we're going to have to rewrite these To use Block transfers So let's receive an entire sector Now the There's our buffer. Here we go. There are 64 bytes worth of buffer Which only does 32 bit accesses We want to fill the buffer Um So this is eight chunks we want to do So we've got this mem copy routine. It does Unaligned copies And it does copies where the source and the destination are aligned I think That For this we're going to need to have copy routines For the cases where the source is aligned and the destination is unaligned and vice versa Which is annoying? Well, what i'm planning on doing Is We're going to We are going to send 64 by Eight We're going to send 512 bytes at a time We only want Hang on. This is receiving so this wants to be My so So we're going to want to copy the destination is the buffer The source is our data pointer. The size is 64 bytes Wait. No. No. I'm thinking of This is a input. So all we want is this We then copy Into our destination from the buffer 64 bytes Advance the buffer So this will do a much faster transfer 512 bits at a time From the card. So let's just see what this does I believe it's Failed to read from the card Look up lba D pointer and I might need the signal analyzer again to see what's going on here Interestingly, I don't see it call SPI receive sector Okay, let's try it in the signal analyzer Stupid thing This is the screen recorder i'm using Okay, and it seems to have Failed to identify my signal analyzer as it glitched out somehow Apparently it has interesting Okay, let's just try power cycling it and trying it again Okay, well apparently it's died completely for some reason Well, I don't know why this hasn't Worked at all So this is the initialization code here. You can see it writing out our 20 well reading our 20 bytes Here's the init sequence With various commands Is it I think it's actually retrying multiple times it keeps sending that 65 command Maybe it doesn't like this Okay, well, thanks to the magic of undo. Let's try taking out our receive code to here and See if that works any better No power cycle the board intriguing Okay, well, let's put all our stuff back again and give that a try Okay So we should be able to see yep here. It is reading Sectors from the disk And it looks like they're all Word aligned which is nice. I don't think we can guarantee that But it does Fail here So let's just copy our code So this is transmitting So we want to write to our output buffer from s pointer 64 bytes Turn on the transmitter Wait till it's completed Advanced But doesn't that like doesn't like that being a point of the volatile Okay, well, it's doing the same thing it did before It's getting a decent amount of the way through and is then just stalling So let's try Putting this back Right, we just continually read ff's the card never wakes up. I am beginning to suspect There's some kind of issue with Running an sd card off this Device That may be causing the card to glitch out somehow The card is connected to the 3.3 volt line rather than the 5 volt line Which I believe to be correct. Oh, you're behaving now No, you're not You can just we can still try changing the Uh the frequency No very slow Seems to be consistently dying at about the same place each time So the last thing we did was we tried to write a sector to the card and then the card stalls So what is it returning? Well, that seemed to work At least work better. It successfully swapped stuff out this Looks So these are the responses we're getting from swap out and it's always this cycle Oh now the card's gone completely power cycle Does it need to be connected to the 5 volt line? Well, I can find out Okay No It seems to work the first time after a power cycle So I can see the messages go past After a reflash, it still doesn't work I wish the signal analyzer was working again Yeah, something extremely strange is going on as I suspect is hardware related Uh, what can I do to proceed? I wonder Well, until I can load a binary off disk I can't actually Start work on the last remaining major piece of work, which is the tty driver So I plug the card into the PC and yes, it is there. It is a card and here is our file system So, I mean it seems to be working One possible thing is if the signal analyzer has crapped out Because it is hooked up to the sd card lines. Maybe that's affecting the communication So I can at least unplug that So I've just pulled the plug on the Signal analyzer. The wires are still plugged into the hardware. The hardware is unpowered Interesting That's working. Well, it's still failing, but it's working Now it's not working What happens if I unplug the signal analyzer completely? Which is done That seems to be more consistent It still doesn't Always fail in the same place. You sometimes it gets a bit further But that seems to be more reliable. So let's try and Let's put those two lines of tracing back in And see what comes out See now it gets With those two lines of tracing now it gets much further Right. So each call to wait returns A different value This seems exceptionally dodgy to me I wonder whether It's So the swapping out is writing to the card Where's the swapping in? There aren't any I bet that it's writing garbage to the card And the first time we do a swap in It reads garbage from the card and then immediately dies when we try to actually call it Uh, what's this address? 216911 Yeah We're following the pointer to the p-tab which is from the u-data Which we've loaded off disk So if that's garbage that pointers garbage, which means we follow a hyperspace pointer and It just stops working. So Let's try turning down the speed It's failing consistently No matter what the speed is which means it's unlikely to be timing related Maybe we actually want to be writing correctly Rather than reading That might make a bit of a difference And that also explains the garbage we seem to be getting back from the disk Interesting indeed Let's try the usual power cycle because if we were Reading instead of writing Yeah See, I thought we might be writing garbage Our commands to the card I mean we've got a login prompt it works Okay, that seemed to be what was going on but let's Get rid of this tracing we've already done that tracing And that's tracing And that tracing And I think it's frozen So it likes having tracing So we put the syscall tracing back again Okay, so seems to be doing the same thing as before So if we Do that Okay, it's died on a swap out Right, we do need to Do this if You in 32t d pointer and three Unaligned read Now I would expect to see a processor exception if we tried to do an unaligned read, but this is a memory peripheral Okay So we might not be getting the error we expect 64 by 8 is 512 So we do have the numbers right We know receive sector works because otherwise we wouldn't be getting as far as in it We don't know about transmit sector It's writing eight chunks 64 bytes each This is a unate style which means adding a number on changes a byte Mozi we're writing Yeah, it looks okay to me That works See we've got all the way to the login prompt Why Does it not work Without the delay a smaller delay Okay, that works That doesn't work Do we need a particular delay between receiving a byte and Uh Sending the next one Do we need to wait for the card to finish? I mean when you send the command We do call spi wait, which waits for the card to actually uh Respond correctly S d spi wait true means that we're waiting for an ff response So if we do Like this All right that hangs and notice that it's hung Uh outside the two braces So it's not happening here Okay, so let's do this That seems to be fine So where are we calling? spi wait before the command between the command and receiving the sector See this is waiting for a an fe response And this is waiting for an ff response To indicate that uh, we're either ready to read or ready to write So let's get rid of those Want that Okay, that's I was expecting it to hang before the close bracket That is in here, but it's not I Think it's hanging here Waiting for the data to be accepted No Waiting here for the the right to finish Right It's stuck here. It's waiting for a response from the card somewhere between So the data has been Accepted and now we're waiting for the right to to complete Okay Uh, was it a success? Well, it must be a success. Otherwise it wouldn't be calling sd spi wait Right. It's a success So we are continually spamming the card waiting for a response So let's do That that puts in quite a big delay between attempts And now it's fine So what the card doesn't like being poked so frequently I wish the logic analyzer were working So I'll be trying the well you see this you can see how long it's taking for the right to happen Here's a particularly long delay This seems to be more normal Do we need A delay here That's not helping Do we need a delay here? That works What about here? That's fine So it seems to want a delay between getting the response getting the acceptance response And poking the card to see if the right occurred But that doesn't help See it it moves on a Random ish amount before failing But never quite gets to the login prompt But putting the delay here works So the difference is that putting the delay here means that every iteration Where the card returns zero there's a pause before we ask again Oh, I hate dealing with sd cards So that's worked Now these long runs of zeros I believe are Waiting for the card to return a successful right response Which would be the three here We wait for a A status with five in the bottom two bits. Is that two two nine? And x one f is five. Okay. So this is the acceptance byte Then there's zeros Then there's Our response byte So this is the useful documentation So this is a single block right So in the command 24 We wait for the response We pause We send the data packet the data packet is defined here Now we get a response, which is our five Then there's a busy delay but then This doesn't say anything about Having to send another command to get the response So the five we are seeing is 0101 data accepted Okay. Well, let's take a look at our old friend the Arduino code And we want sd No sdfs This is just calling another library sd fat Is empty as we found before Looking for useful looking keywords. Okay. I don't see anything Okay, so let's take a look at the node ncu Source So I think this would be app fatfs Should talk to the sd card stuff Platform sd card read block Let's form sd card write block right block So we do the command 24 If that fails give up then we do sd card write data Which is here We Send the start token which is fe We send 512 bytes of data We send 16 bits of crc, which is a dummy We would get a single status And then we exit we are never querying for The second response so My suspicion Is that this code Doesn't work So where's our weight? Let's get rid of that. Let's try this and see what it does It works Okay, that is odd That's very odd. Um So of course the next command that happens after a write is going to call sd send command Which in the first thing this does is going to Wait for an ff ready byte My gut feeling says that this is Spinning so fast on the sd card that the sd card is never getting a chance to actually do anything But that seems Implausible to me But anyway We are now successfully uh booting of a file system on the sd card To the login prompt See we've got the flash partition. Although there's nothing on it We've got the sd card with its three partitions This all does seem to be working. I'll hit the reset button a few more times. Yep Where did I set the clock here? Let's put that back to eight megahertz Just make it a bit faster Yeah, it seems to be okay So that is a Good progress I'm still confused as to what's going on and I'm confused as to why my Signal analyzer just stopped working And I'm confused about many things, but it does actually seem to be Working and it's nice and fast So much faster than the mand So, uh Use fast transfers for sd card access disable some possibly In the dev sd right path But it's now running up to the login prompt. So we should be good to start work on the tty next time Which is nice. This is actually looking like it might be finished soon And even though it's single tasking I mean that's running a shell script and several binaries And it's forking a lot And startup is still well under a second on this Single tasking system. So I'm pleased with that That is a perfectly usable speed So all I need to do now is the tty so that we can actually log into it and add some more programs and I can probably call it done Plus, of course the inevitable cleanup Yay Okay, well, I'm glad that is finally possibly sorted. Maybe we'll see if it stays sorted So that has been for maybe five Videos entirely devoted to trying to make the blasted sd card work I still don't understand why it's working I hate sd cards But yeah I hope you enjoyed this video and please let me know what you think in the comments