variable b0 1fc allot fl { PropForth3.4 2010.9.24 Only SDSC no error trap 2010.10.3 Add SDHC-initialize Change sd_init,csd,collect_info (SDSC & SDHC)) } 15 constant _sd_cs 16 constant _sd_di \ connected SD's di 17 constant _sd_clk 18 constant _sd_do \ connected SD's do 1 _sd_cs lshift constant _sd_csm 1 _sd_di lshift constant _sd_dim 1 _sd_clk lshift constant _sd_clkm 1 _sd_do lshift constant _sd_dom : _sd_cs_out _sd_cs pinout ; : _sd_di_out _sd_di pinout ; : _sd_clk_out _sd_clk pinout ; : _sd_do_in _sd_do pinin ; : _sd_cs_out_l _sd_csm _maskoutlo ; : _sd_cs_out_h _sd_csm _maskouthi ; : _sd_di_out_l _sd_dim _maskoutlo ; : _sd_di_out_h _sd_dim _maskouthi ; : _sd_clk_out_l _sd_clkm _maskoutlo ; : _sd_clk_out_h _sd_clkm _maskouthi ; wvariable tmp wvariable tmp1 wvariable time_value 0 c, a c, c c, d c, f c, 14 c, 19 c, 1e c, 23 c, 28 c, 2d c, 32 c, 37 c, 3c c, 46 c, 50 c, wvariable time_unit 1 c, a c, 64 c, 1 c, a c, 64 c, 1 c, a c, wvariable rate_unit 64 c, 1 c, a c, 64 c, wvariable buff_ptr wvariable sdhc wvariable ccs wvariable first_sector wvariable byte/sector wvariable sector/cluster wvariable reserve_sector wvariable num_fat wvariable root_entry variable sector/fat variable total_sector variable rootCluster variable BTB_addr variable FAT_addr variable RDE_addr variable USER_addr : sd_shift_out 8 0 do dup 1 7 i - lshift and 0> if _sd_di_out_h else _sd_di_out_l then _sd_clk_out_l _sd_clk_out_h loop drop ; : sd_shift_in 0 8 0 do _sd_clk_out_l _sd_clk_out_h ina COG@ _sd_dom and 0> if 1+ then 1 lshift loop 1 rshift ; : dummy ff sd_shift_out ; \ dummy 8clock : sd_init _sd_di_out _sd_di_out_h _sd_clk_out _sd_clk_out_h _sd_do_in _sd_cs_out _sd_cs_out_h 0 sdhc W! 0 ccs W! 0 tmp W! 4a 0 do \ 74 clock _sd_clk_out_l _sd_clk_out_h loop _sd_cs_out_l 40 sd_shift_out \ CMD0 0 4 0 do dup sd_shift_out loop drop 95 sd_shift_out \ CRC begin sd_shift_in 1 = if 1 else tmp dup W@ 1+ swap W! tmp W@ 100 = if ." error" cr cr exit else 0 then then until dummy 48 sd_shift_out \ CMD8 0 2 0 do dup sd_shift_out loop drop 1 sd_shift_out aa sd_shift_out 87 sd_shift_out \ Response for CMD8 begin sd_shift_in dup 1 = if drop 1 else 5 = if begin 77 sd_shift_out \ CMD55 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 3 0 do sd_shift_in drop loop \ skip response dummy 69 sd_shift_out \ ACMD41 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 5 0 do sd_shift_in 0= if 4 seti 1 else i 4 = if 0 then then loop dummy until ." SDSC initialize success" cr cr exit then 0 then until \ begin sd_shift_in dup . 1 = if 1 else 0 then until cr 2 0 do sd_shift_in drop loop sd_shift_in sd_shift_in aa = if 1 = if 1 else 0 then else drop 0 then if begin 77 sd_shift_out \ CMD55 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 3 0 do sd_shift_in drop loop \ skip response dummy 69 sd_shift_out \ ACMD41 40 sd_shift_out 0 3 0 do dup sd_shift_out loop drop 1 sd_shift_out 5 0 do sd_shift_in 0= if 4 seti 1 else i 4 = if 0 then then loop dummy until 7a sd_shift_out \ CMD58 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out begin sd_shift_in 0= until sd_shift_in \ Get CardCapacityStatus of OCR 4 0 do sd_shift_in drop loop dummy 40 and 0= if 0 ccs W! else 1 ccs W! then else begin 77 sd_shift_out \ CMD55 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 3 0 do sd_shift_in drop loop \ skip response dummy 69 sd_shift_out \ ACMD41 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out 5 0 do sd_shift_in 0= if 4 seti 1 else i 4 = if 0 then then loop dummy until then 49 sd_shift_out \ CMD9 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out dummy begin sd_shift_in 0= until dummy begin sd_shift_in fe = until \ start-byte for data token sd_shift_in f 0 do sd_shift_in drop loop \ data block begin sd_shift_in ff = until \ drop crc dummy 40 and 40 = if 1 sdhc W! ." SDHC initialize success" cr cr else ." SDSC initialize success" cr cr then _sd_cs_out_h ; : Block 4 0 do dup ff and swap 8 rshift loop drop ." " 10 0 do i . ." " loop cr _sd_cs_out_l 51 sd_shift_out \ CMD17 Single Block read sd_shift_out sd_shift_out sd_shift_out sd_shift_out 1 sd_shift_out \ CRC begin sd_shift_in 0= until dummy begin sd_shift_in fe = until \ start-byte for data token 20 0 do i 10 u* dup 10 < if ." 00" . else dup 100 < if ." 0" . else . then then b0 W@ 10 0 do dup sd_shift_in swap W! 2 + loop drop b0 W@ 10 0 do dup W@ dup 10 < if ." 0" . else . then 2 + loop drop ." " b0 W@ 10 0 do dup W@ dup 20 < if ." ." drop else dup 7e > if ." ." drop else emit then then 2 + loop drop cr loop begin sd_shift_in ff = until \ drop crc dummy _sd_cs_out_h ; : month f and 30 + dup 39 > if dup 3a = if ." 10" drop else dup 3b = if ." 11" drop else ." 12" drop then then else emit then ; : cid ." Card IDentification Register(CID)" cr _sd_cs_out_l 4a sd_shift_out \ CMD10 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out dummy begin sd_shift_in 0= until dummy begin sd_shift_in fe = until \ start-byte for data token ." ManufactureID " sd_shift_in .byte cr ." OEM/AppricationID " sd_shift_in sd_shift_in swap emit emit cr ." ProductName " 5 0 do sd_shift_in emit loop cr ." ProductRev " sd_shift_in dup 4 rshift .hex ." ." .hex cr ." SerialNumber " 4 0 do sd_shift_in .byte loop cr ." ManufactyreDate " sd_shift_in sd_shift_in swap ." 20" .hex dup 4 rshift .hex ." /" month cr sd_shift_in drop begin sd_shift_in ff = until \ drop crc dummy _sd_cs_out_h ; : to_decimal 0 tmp W! 3e8 swap over 4 0 do u/mod dup 0> if 1 tmp W! .hex else tmp W@ if 0> .hex else drop then then swap a / swap over loop 3drop ; : to_decimal_dot 0 tmp W! 3e8 swap over 4 0 do i 3 = if ." ." then u/mod dup 0> if 1 tmp W! .hex else tmp W@ if 0> .hex else drop then then swap a / swap over loop 3drop ; : csd ." Card Specific Data register(CSD)" cr _sd_cs_out_l 49 sd_shift_out \ CMD9 0 4 0 do dup sd_shift_out loop drop 1 sd_shift_out dummy begin sd_shift_in 0= until dummy begin sd_shift_in fe = until \ start-byte for data token sd_shift_in drop \ skip ." Access Time " sd_shift_in dup dup 78 and 3 rshift time_value 2 + + C@ \ access time swap 7 and time_unit 2 + + C@ * to_decimal_dot 7 and dup 3 < if ." nsec" else 6 < if ." usec" else ." msec" then then cr sd_shift_in drop \ skip ." Transfer Speed " sd_shift_in dup dup 78 and 3 rshift time_value 2 + + C@ \ transfer speed swap 7 and rate_unit 2 + + C@ * to_decimal_dot 7 and 0= if ." kbit/s" else ." Mbit/s" then cr sd_shift_in drop \ skip ." Data Block Length " sd_shift_in f and dup tmp1 W! 1 swap lshift to_decimal ." byte" cr sdhc W@ if sd_shift_in drop \ skip sd_shift_in 3f and 10 lshift sd_shift_in 8 lshift or sd_shift_in or ." Capacity " 1+ 200 * 400 * 100000 u/ to_decimal ." Mbyte" cr else ." Capacity " sd_shift_in 3 and a lshift \ C_SIZE sd_shift_in 2 lshift or sd_shift_in c0 and 6 rshift or 1 + sd_shift_in 3 and 1 lshift \ C_SIZE_MULT sd_shift_in 7 rshift or 2 + 1 swap lshift * 1 tmp1 W@ lshift * 100000 u/ to_decimal ." Mbyte" cr then 5 0 do sd_shift_in drop loop begin sd_shift_in ff = until \ drop crc dummy _sd_cs_out_h ; : clear_buff_ptr b0 buff_ptr W! ; : buff_ptr+1 buff_ptr W@ 1+ buff_ptr W! ; : block_read 4 0 do dup ff and swap 8 rshift loop drop _sd_cs_out_l 51 sd_shift_out \ CMD17 Single Block read sd_shift_out sd_shift_out sd_shift_out sd_shift_out 1 sd_shift_out \ CRC begin sd_shift_in 0= until dummy begin sd_shift_in fe = until \ start-byte for data token clear_buff_ptr 200 0 do sd_shift_in buff_ptr W@ C! buff_ptr+1 loop begin sd_shift_in ff = until \ drop crc dummy begin sd_shift_in ff = until \ drop crc dummy _sd_cs_out_h ; : collect_info 0 block_read clear_buff_ptr buff_ptr W@ 1c6 + W@ buff_ptr W@ 1c8 + W@ 10 lshift or dup first_sector W! \ 200 * block_read ccs W@ if block_read else 200 * block_read then clear_buff_ptr buff_ptr W@ b + C@ buff_ptr W@ c + C@ 8 lshift or byte/sector W! buff_ptr W@ d + C@ sector/cluster W! buff_ptr W@ e + W@ reserve_sector W! buff_ptr W@ 10 + C@ num_fat W! buff_ptr W@ 11 + C@ buff_ptr W@ 12 + C@ 8 lshift or root_entry W! sdhc W@ if buff_ptr W@ 24 + L@ sector/fat L! else buff_ptr W@ 16 + W@ sector/fat L! then buff_ptr W@ 20 + W@ buff_ptr W@ 22 + W@ 10 lshift or total_sector L! buff_ptr W@ 2c + L@ rootCluster L! sdhc W@ if first_sector W@ BTB_addr L! first_sector W@ reserve_sector W@ + FAT_addr L! num_fat W@ sector/fat W@ * FAT_addr L@ + RDE_addr L! root_entry W@ 20 * byte/sector W@ u/ RDE_addr L@ + USER_addr L! ccs W@ 0 = if BTB_addr L@ 200 * BTB_addr L! FAT_addr L@ 200 * FAT_addr L! RDE_addr L@ 200 * RDE_addr L! USER_addr L@ 200 * USER_addr L! then else first_sector W@ 200 * BTB_addr L! first_sector W@ reserve_sector W@ + 200 * FAT_addr L! num_fat W@ sector/fat W@ * 200 * FAT_addr L@ + RDE_addr L! root_entry W@ 20 * RDE_addr L@ + USER_addr L! then ; : conversion 100000 u/mod dup 0> if to_decimal ." M" drop else drop 400 u/mod dup 0> if to_decimal ." k" drop else drop to_decimal then then ." byte" ;