From 67d25d837ac55f28a366c0a3b262e439a6e75fc3 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 19 Aug 2017 12:15:28 +0200 Subject: Add AmForth --- amforth-6.5/avr8/lib/hardware/mmc.frt | 371 ++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 amforth-6.5/avr8/lib/hardware/mmc.frt (limited to 'amforth-6.5/avr8/lib/hardware/mmc.frt') diff --git a/amforth-6.5/avr8/lib/hardware/mmc.frt b/amforth-6.5/avr8/lib/hardware/mmc.frt new file mode 100644 index 0000000..f213c9b --- /dev/null +++ b/amforth-6.5/avr8/lib/hardware/mmc.frt @@ -0,0 +1,371 @@ +\ MMC+SD card - Lubos Pekny, www.forth.cz +\ Library for amforth 3.0, mFC modification +\ Max. 4GB no SDHC, access thru buffer 512B or short block or direct + +\ V.1.0, 16.07.2009, tested on atmega32, amforth30mFC12.zip +\ - used SPI (MOSI, MISO, SCK, SS) +\ mmc_init, mmc_CID, mmc_CSD, mmc_read, mmc_mread, mmc_write, +\ mmc_blk@, mmc_blk!, mmc_c@, mmc_c!, mmc_end?, mmc_end! + +\ needs +/-spi for pin configuration +\ needs +/-mmc for slave select action + +hex + +variable mmc_#buf \ position in buf +variable mmc_buf 1FE allot \ 512B RAM + + + \ enable spi for mmc, set I/O +: mmc_+spi ( -- ) + +spi + -spi2x + SPCR_SPE SPCR_MSTR or + spi.f/128 or + spi.mode0 or SPCR c! ; + + \ send dummy byte x-times +: mmc_dummy ( x -- ) + 0 ?do $ff c!spi loop ; + + +\ convert 32b block to byte addr, double 9 lshift +: mmc_blk2addr ( L H -- L H ) + swap dup 9 lshift \ -- H L L<<9 + swap 7 rshift \ -- H L<<9 L>>7 + rot 9 lshift or ; \ -- L<<9 H<<9 + + + \ waiting for cmd response +: mmc_cresp ( -- c|-1 ) + FF 0 do + c@spi dup 80 and 0= \ bit7=0? + if unloop exit then \ -- c, 0=ok + drop \ -- + loop -1 ; \ -- -1, timeout + + + \ waiting for data response +: mmc_dresp ( -- c|-1 ) + FF 0 do + c@spi dup 11 and 1 = \ xxx0ccc1 + if + 0F and unloop exit \ -- c, 5=ok + then + drop \ -- + loop -1 ; \ -- -1, timeout + + + \ waiting for token +: mmc_token ( -- c|-1 ) + FF 0 do + c@spi dup FF - \ <>FF? + if unloop exit then \ -- c, FC,FE=ok + drop \ -- + loop -1 ; \ -- -1, timeout + + + \ waiting while busy, after write +: mmc_busy ( -- 0|-1 ) + FF 0 do + c@spi FF = \ =FF? + if 0 unloop exit then \ -- 0, ok + loop -1 ; \ -- -1, timeout + + + \ send command cmd, data xl, xh +: mmc_cmd ( xl xh cmd -- c|-1 ) + FF c!spi \ flush spi register + 40 or c!spi \ send command cmd + dup >< c!spi c!spi \ send xhh, xhl + dup >< c!spi c!spi \ send xlh, xll + 95 c!spi \ no crc + mmc_cresp ; \ -- c|-1, c=0 no errors + + + \ set block length +: mmc_length ( n -- c|-1 ) + 0 10 mmc_cmd ; \ CMD16 + + + \ stop multiread +: mmc_rstop ( -- c|-1 ) + 0 0 C mmc_cmd \ CMD12 + mmc_busy or -mmc ; \ -- c|-1, c=0 no errors + + + \ stop multiwrite +: mmc_wstop ( -- c|-1 ) + FD c!spi \ Stop tran for CMD25 + FF c!spi \ 1B wait + mmc_busy -mmc ; \ -- c|-1, c=0 no errors + + + \ reset card, idle +: mmc_reset ( -- c|-1 ) + -mmc 10 mmc_dummy \ 74< clk to reset mmc + +mmc + 0 0 0 mmc_cmd ; \ CMD0, -- 1, reset ok + + + \ detect sd card, 0=SD, -1=timeout +: mmc_sd? ( -- c|-1 ) + 0 0 37 mmc_cmd drop \ CMD55 + 0 0 29 mmc_cmd \ ACMD41, -- c + dup 1+ \ -- -1 0, timeout + if 4 and then ; \ SD(R1.2=0) / MMC(R1.2=1) + + + \ wait for init MMC card +: mmc_waitmmc ( -- 0|-1 ) + FF \ -- cnt + begin + 0 0 1 mmc_cmd 0= \ CMD1, -- cnt f + if drop 0 exit then \ -- 0, ok + 1- dup 0= \ -- cnt-1 f + until 1- ; \ -- -1, timeout + + + \ wait for init SD card +: mmc_waitsd ( -- 0|-1 ) + FF \ -- cnt + begin + 0 0 37 mmc_cmd drop \ CMD55 + 0 0 29 mmc_cmd 0= \ ACMD41, -- cnt f + if drop 0 exit then \ -- 0, ok + 1- dup 0= \ -- cnt-1 f + until 1- ; \ -- -1, timeout + + + + + \ check end of sector, for mmc read +: mmc_end? ( -- flag ) + 200 mmc_#buf @ + > 0= dup \ -- c c, -1=end + if \ size<=#buf then + 2 mmc_dummy \ dummy crc + then ; + + +\ check end of sector, wait for no busy, for mmc write +: mmc_end! ( -- 0|-1 ) + mmc_end? \ -- flag, crc dummy for end + if + mmc_dresp 5 <> \ -- 0, 0=ok, response + mmc_busy or \ -- c, 0=ok, writed + else 0 then ; \ -- c, 0=ok, -1=timeout + + +: mmc_buf> ( addr n -- 0|-1 ) + dup mmc_#buf +! \ +n, update buf position + 0 ?do \ addr n -- send n bytes from addr + dup c@ c!spi 1+ \ -- addr+1 + loop drop + \ n!spi + mmc_end! ; \ -- c, 0=ok, -1=timeout + + + \ copy spi to buf +: mmc_>buf ( addr n -- ) + dup mmc_#buf +! \ +n, update buf position + 0 ?do \ write n bytes to addr + c@spi over c! 1+ \ -- addr+1 + loop drop +\ n@spi + mmc_end? drop ; \ crc dummy for end + + + \ wait for token, copy first n bytes to buf +: mmc_(read) ( n 0 -- c|-1 ) + 0 mmc_#buf ! \ reset buf position + dup 0= \ 0 -- , cmd ok + if + drop mmc_token dup \ c -- c c + FE = + if + drop mmc_buf swap \ -- addr n + mmc_>buf 0 \ -- 0, ok + else + swap drop \ n c -- c + then + else + swap drop \ n c -- c + then ; \ 0=ok, -1=timeout + + + \ copy first n bytes to card, response, busy +: mmc_(write) ( n 0 -- c|-1 ) + 0 mmc_#buf ! \ reset buf position + dup 0= \ 0 -- , cmd ok + if + drop FF c!spi \ wait 1B + FE c!spi \ send start byte + mmc_buf swap \ -- addr n + mmc_buf> \ -- c, 0=ok, -1=timeout + else + swap drop \ n c -- c + then ; \ 0=ok, -1=timeout + + + \ copy first n bytes to card, multiwrite, busy +: mmc_(mwrite) ( n 0 -- c|-1 ) + 0 mmc_#buf ! \ reset buf position + dup 0= \ 0 -- , cmd ok + if + drop FF c!spi \ wait 1B + FC c!spi \ send start byte + mmc_buf swap \ -- addr n + mmc_buf> \ -- c, 0=ok, -1=timeout + else + swap drop \ n c -- c + then ; \ 0=ok, -1=timeout + + +\ ----- final words ----- + + \ initialize card MMC or SD v.1.x +: mmc_init ( -- x|-1 ) + 0 mmc_#buf ! + mmc_+spi \ init spi, I/O + mmc_reset \ -- c, 1=ok + dup 1- + if -mmc 100 xor exit then \ <>1 then exit + drop \ -- + + mmc_sd? \ detect SD + dup 0< \ -- 0, SD + if -mmc 200 xor exit then \ -1 --, timeout + if + mmc_waitmmc \ MMC init + else + mmc_waitsd \ SD init + then + 200 mmc_length \ set sector length + or -mmc ; \ -- 0|-1, 0=ok, -1=timeout + + + \ read CID register 16B +: mmc_CID ( -- c|-1 ) + +mmc 10 \ length 16B + 0 0 A mmc_cmd \ CMD10, + mmc_(read) \ 10 c -- c, 0=ok, -1=timeout + 2 mmc_dummy \ dummy CRC + -mmc ; + + + \ read CSD register 16B +: mmc_CSD ( -- c|-1 ) + +mmc 10 \ length 16B + 0 0 9 mmc_cmd \ CMD9 + mmc_(read) \ 10 c -- c, 0=ok, -1=timeout + 2 mmc_dummy \ dummy CRC + -mmc ; + + + \ open sector for read, copy n bytes to buf + \ 200 ABCD 7F mmc_read \ open,copy 512B from sector + \ 0 ABCD 7F mmc_read \ only open sector 7FABCD +: mmc_read ( n xl xh -- c|-1 ) \ length, sector addr + +mmc + mmc_blk2addr \ addr*512, block->byte + 11 mmc_cmd \ addrL addrH 11 --, CMD17 + mmc_(read) \ n c -- c, 0=ok, -1=timeout + -mmc ; + + + \ open sector for multi read, copy n bytes to buf +: mmc_mread ( n xl xh -- c|-1 ) \ length, sector addr + +mmc + mmc_blk2addr \ addr*512, block->byte + 12 mmc_cmd \ addrL addrH 12 --, CMD18 + mmc_(read) \ n c -- c, 0=ok, -1=timeout + -mmc ; + + + \ open sector for write, copy n bytes from buf to card +: mmc_write ( n xl xh -- c|-1 ) \ length, sector addr + +mmc + mmc_blk2addr \ addr*512, block->byte + 18 mmc_cmd \ addrL addrH 18 --, CMD24 + mmc_(write) \ n c -- c, 0=ok, -1=timeout + -mmc ; + + + \ open sector for multi write, copy n bytes from buf to card +: mmc_mwrite ( n xl xh -- c|-1 ) \ length, sector addr + +mmc + mmc_blk2addr \ addr*512, block->byte + 19 mmc_cmd \ addrL addrH 19 --, CMD25 + mmc_(mwrite) \ n c -- c, 0=ok, -1=timeout + -mmc ; + + + \ read short block from opened sector to buf + \ use mmc_read or mmc_(read) first +: mmc_blk@ ( addr n -- ) \ addr, length of blk + +mmc + mmc_>buf \ addr n -- ,copy spi to buf + -mmc ; + + + \ write short block to opened sector from buf + \ use mmc_write or mmc_(write) first +: mmc_blk! ( addr n -- 0|-1 ) \ addr, length of blk + +mmc + mmc_buf> \ addr n -- 0|-1, from buf + -mmc ; \ 0=ok, -1=timeout + + + \ direct read byte from opened sector + \ note: +mmc, if end of sector then dummy crc, -mmc +: mmc_c@ ( -- c ) + c@spi \ read byte from card + 1 mmc_#buf +! ; \ increment position + + + \ direct write byte to opened sector + \ note: +mmc, if end of sector then mmc_end!, -mmc +: mmc_c! ( c -- ) + c!spi \ write byte to card + 1 mmc_#buf +! ; \ increment position + + + \ view n bytes from mmc_buf+offset +: mmc. ( n offset -- ) + mmc_buf + swap + 0 ?do \ addr n -- view n bytes from addr + dup c@ . 1+ \ -- addr+1 + loop drop ; + + +\ sptx Stop transmit + +: mmc_tstmread ( n -- ) \ read n x 1MB + 0 . + 200 0 0 mmc_mread . \ open for multiread + +mmc + 0 ?do + 800 1 do \ 1MB + 200 0 mmc_(read) \ 512B + drop + loop + i . + loop 0 . + mmc_rstop drop ; + + +: mmc_tstread ( n -- ) \ read n x 1MB + 0 . + 200 0 0 mmc_read . + 0 ?do + 800 1 do \ 1MB + 200 0 0 mmc_read \ 512B + drop + loop + i . + loop 0 . ; + + +\ sptx Stop transmit + -- cgit v1.2.3