{"id":145,"date":"2012-07-28T23:59:50","date_gmt":"2012-07-28T23:59:50","guid":{"rendered":"http:\/\/retroramblings.net\/?p=145"},"modified":"2012-07-29T12:13:25","modified_gmt":"2012-07-29T12:13:25","slug":"experimenting-with-tg68-9","status":"publish","type":"post","link":"http:\/\/retroramblings.net\/?p=145","title":{"rendered":"Experimenting with TG68"},"content":{"rendered":"<p><strong>Part 9 &#8211; Accessing the SD card<\/strong><\/p>\n<p>A computer&#8217;s not much use without a way to load data onto it, so the latest aspect of this project has been getting the SD card slot doing something useful.<\/p>\n<p>SD cards have more than one way of accessing them &#8211; they have a &#8220;native&#8221; protocol, and then an SPI mode.\u00a0 While the native mode can provide better performance, an SPI host is a built-in feature of many microcontrollers, and documentation is easier to come by.\u00a0 The Minimig project uses the SD card in SPI mode, and since I&#8217;m using that project for reference wherever I&#8217;m finding gaps in my own understanding, I&#8217;ve used SPI as well!<\/p>\n<p>At one time it was nearly impossible for a hobbyist to obtain official SD card specifications &#8211; thankfully the situation is much improved now, and a simplified specification is now available for free download at <a href=\"https:\/\/www.sdcard.org\/downloads\/pls\/\">https:\/\/www.sdcard.org\/downloads\/pls\/<\/a><\/p>\n<p>Another useful page for reference is this: <a href=\"http:\/\/elm-chan.org\/docs\/mmc\/mmc_e.html\">http:\/\/elm-chan.org\/docs\/mmc\/mmc_e.html<\/a><\/p>\n<p>One thing that confused me to start with is that to invoke &#8220;CMD0&#8221; we have to send 0x40 to the SD card, while &#8220;CMD1&#8221; ends up being 0x41, and so on.\u00a0 This is because the SD native protocol employs a &#8216;0&#8217; start bit, then a &#8216;1&#8217; transmission bit &#8211; and these are retained even in SPI mode.<\/p>\n<p>Another peculiarity of SPI is that communication is always bidirectional; the host provides 8 clocks, and eight bits of data are sent in each direction.\u00a0 This means that in order to read responses from the card, the host must write a dummy byte for each byte it wishes to receive.<\/p>\n<p>For the MiniSOC project, I&#8217;ve added some extra hardware registers in the peripheral controller at base 0x810000<\/p>\n<pre><strong>0x20: SD<\/strong>\r\n   On read, returns the data received during the previous\r\n   write operation.\r\n   On write, causes the byte written to the low 8 bits to be\r\n  \u00a0clocked out, and data from the card to be clocked in.\r\n   Note: this is asynchronous, so it's important to check that any\r\n   previous write has finished!<strong>\r\n\r\n0x22 SD_CS\r\n \u00a0<\/strong>Read: bit 15 indicates whether the SPI host is busy performing\r\n  \u00a0a transfer\r\n   Write: bit 0 sets the chip select line of the SD card.<strong>\r\n\r\n0x24 - SD_Blocking.<\/strong>\r\n   This is equivalent to 0x20 except that both reads and writes will\r\n  \u00a0incur wait states until any previous transfer has completed,\r\n  \u00a0eliminating the need to poll 0x22.<strong>\r\n\r\n0x100 onwards:<\/strong>\r\n   This area is deliberately incompletely decoded, so reads from\r\n   anywhere within the region will have the same effect.\u00a0 Unlike both\r\n   0x20 and 0x24, reading from these registers will trigger a new\r\n  \u00a0transfer, sending sixteen bits of 0xffff and receiving 16 bits back\r\n  \u00a0from the SD card.\u00a0 The point of this is to allow driver code to use\r\n  \u00a0constructs like this:\r\n\r\n; set up a block read command, then...\r\n\u00a0 lea 0x810100,a0\r\n\u00a0 lea sector_buffer,a1\r\n\u00a0 move.l #15,d7\r\n  move.w (a0),d0 ; pump the first 16 bits.\r\n.loop\r\n\u00a0 movem.l (a0),d0-6\/a2 ; pump 64 bits in one command!\r\n\u00a0 movem.l d0-6\/a2,(a1)\r\n\u00a0 add.l #32,a1\r\n\u00a0 dbf d7,.loop\r\n\r\nThis is much faster than receiving data a single byte at a time.<\/pre>\n<p>Full source and binaries can be found <a href=\"http:\/\/retroramblings.net\/downloads\/\">here<\/a>, for anyone that might be interested.<\/p>\n<p>To try this out, you&#8217;ll need (a) an Altera DE1 board, (b) HyperTerminal or (preferably) something similar but faster, and (c) an SD card containing the file &#8220;Test.img&#8221; from the Misc directory in the archive.<\/p>\n<p>Use Quartus to program the DE1 with the .sof file.<\/p>\n<p>Use HyperTerminal or similar at 115200 baud, 8N1, to send the file &#8220;out.srec&#8221; from the CFirmware directory in the archive.\u00a0 If everything goes to plan, the MiniSOC should load the image, display it on screen, then scroll up and down as before.<\/p>\n<p><a href=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2012\/07\/FPGABee.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-146\" title=\"FPGABee\" src=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2012\/07\/FPGABee.jpg\" alt=\"\" width=\"667\" height=\"500\" srcset=\"http:\/\/retroramblings.net\/wp-content\/uploads\/2012\/07\/FPGABee.jpg 667w, http:\/\/retroramblings.net\/wp-content\/uploads\/2012\/07\/FPGABee-300x224.jpg 300w, http:\/\/retroramblings.net\/wp-content\/uploads\/2012\/07\/FPGABee-400x300.jpg 400w\" sizes=\"auto, (max-width: 667px) 100vw, 667px\" \/><\/a><\/p>\n<p>One of the next tasks will be to bootstrap directly from the SD card, eliminating the need for serial bootstrapping.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Part 9 &#8211; Accessing the SD card A computer&#8217;s not much use without a way to load data onto it, so the latest aspect of this project has been getting the SD card slot doing something useful. SD cards have &hellip; <a href=\"http:\/\/retroramblings.net\/?p=145\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-145","post","type-post","status-publish","format-standard","hentry","category-fpga"],"_links":{"self":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/145","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=145"}],"version-history":[{"count":5,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/145\/revisions"}],"predecessor-version":[{"id":150,"href":"http:\/\/retroramblings.net\/index.php?rest_route=\/wp\/v2\/posts\/145\/revisions\/150"}],"wp:attachment":[{"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=145"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=145"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/retroramblings.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=145"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}