Forum - MCS Electronics

 

FAQFAQ SearchSearch RegisterRegister Log inLog in

reading from a sd card in spi mode?

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive
View previous topic :: View next topic  
Author Message
philm

Bascom Member



Joined: 14 Jul 2004
Posts: 138
Location: Australia

australia.gif
PostPosted: Sun Jan 09, 2005 9:24 am    Post subject: reading from a sd card in spi mode? Reply with quote

Does anyone know how to read a block from a sd memory card in spi mode?
following is my code that does not work.
Code:
Config Spi = Hard , Data Order = Msb , Master = Yes , Polarity = High , Phase = 1 , Clockrate = 16 , Noss = 1
Declare Sub Sdsendcommand(byval Command As Byte , Byval Argument As Long)
Declare Function Sdreadresponse() As Byte
Declare Sub Getbock(buffer As Byte)
Sdcs Alias Portb.0                                          'the Slave Select port
Dim Temp As Byte
Dim Idx As Word
Dim Rxblock(512) As Byte
Set Ddrb.0                                                  'make CS = output
Spiinit                                                     'init hardware SPI
Set Sdcs                                                    'make CS = high
Waitms 1000                                                 'wait a second
For Idx = 1 To 10
   Temp = Spimove(&Hff)                                     '80 clocks
Next Idx

Print "start INI"
Call Sdsendcommand(0 , 0)                                   'send command 0 GO_TO_IDLE
Do
   Temp = Sdreadresponse()                                  'get response in temp
Loop Until Temp = 1                                         'confirm that we are in idle state
                             '
Do
   Call Sdsendcommand(1 , 0)                                'send command 1 SEND_OP_COND
   Temp = Sdreadresponse()
Loop Until Temp = 0                                         'wait for 0 to be returned
Print "finished INI"

Print "set block len"
Call Sdsendcommand(16 , 512)                                'send command 16 SET_BLOCKLEN=512
Do
   Temp = Sdreadresponse()
Loop Until Temp = 0                                         'wait for 0 to be returned

Print "read block cmd"
Call Sdsendcommand(17 , 0)                                  'send command 17 READ_SINGLE_BLOCK=0
Do
   Temp = Sdreadresponse()
Loop Until Temp = 0                                         'wait for 0 to be returned

Print "ready for block xfer"
Call Getbock(rxblock(1))                                    'get the block & stick it in rxblock
Print "printing block"
For Idx = 1 To 512
   Print Hex(rxblock(idx)) ; " " ;
Next Idx
Print
End

Sub Sdsendcommand(byval Command As Byte , Byval Argument As Long)
Local extra As Byte
Extra = &HFF
Set Sdcs                                                    'make CS = high
Spiout Extra , 1                                            '8 bit delay
Reset Sdcs                                                  'make CS low
Command = Command Or &H40                                   'set bit 6, host bit, bit 7 should be clear (no commands above &H80)
Extra = &H95                                                'checksum & end bit for command 0, ignored once in spi mode
Print "Command " ; Hex(command)
Print "Argument " ; Hex(argument)
Print "crc " ; Hex(extra)
Spiout Command , 1                                          'send command
Spiout Argument , 4                                         'send argument
Spiout Extra , 1                                            'send checksum & end bit
End Sub

Function Sdreadresponse() As Byte
Do
   Spiin Sdreadresponse , 1
Loop Until Sdreadresponse <> &HFF                           'until response not equal to &HFF
Print "Sdreadresponse " ; Sdreadresponse
End Function

Sub Getbock(buffer() As Byte)
Local Rxcrc16 As Word
Spiin Buffer(1) , 512
Spiin Rxcrc16 , 2
Print "CRC " ; Hex(rxcrc16)
End Sub

This code prints the following. The "Sdreadresponse 4" keeps going forever.
Quote:
Sdreadresponstart INI
Command 40
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 1
Command 41
Argument 00000000
crc 95
Sdreadresponse 0
finished INI
set block len
Command 50
Argument 00000200
crc 95
Sdreadresponse 64
Sdreadresponse 4
Sdreadresponse 4
Sdreadresponse 4

After I try and set the block length, it comes back with bit 2 set = illegal command
Back to top
View user's profile
DToolan

Bascom Member



Joined: 14 Aug 2004
Posts: 1384
Location: Dallas / Fort Worth, Texas (USA)

blank.gif
PostPosted: Mon Jan 10, 2005 12:19 am    Post subject: Reply with quote

Just an idea.... check your SPI SS pin. It should be configured as output. If configured as an input while in master mode, it can cause the SPI transaction to fail.
Back to top
View user's profile Yahoo Messenger
philm

Bascom Member



Joined: 14 Jul 2004
Posts: 138
Location: Australia

australia.gif
PostPosted: Mon Jan 10, 2005 12:59 am    Post subject: Reply with quote

Yep it's an output
Quote:
Set Ddrb.0 'make CS = output

With the SS pin = input, the SPI will be slave, and nothing will happen.

I think I found out why I am receving bit 2 set = illegal command.
The SPI uses MSBit first, it also uses MSByte first.
So when I send "Spiout Argument , 4" I am actually sending the MSBit of the LSByte first. (AVR is little endian)
So I have to rotate argument left 8 to get the MSByte and do it 4 times.
I will have another look at it tomorrow.
Next step is to read a valid block??
Phil
Back to top
View user's profile
oe9vfj

Moderator



Joined: 17 Jun 2004
Posts: 269
Location: Austria, Hard

austria.gif
PostPosted: Mon Jan 10, 2005 7:50 am    Post subject: Reply with quote

Hi,

Check the site http://members.aon.at/voegel There is a driver for MMC/SD card which can be used with the BASCOM Statements DriveRead and DriveWrite to read and write a Sector (512 Bytes) on the card.
You can use it also with AVR-DOS, the DOS-File-System for BASCOM-AVR.

best regards
Josef

_________________
regards Josef

DOS - File System for BASCOM-AVR on http://members.aon.at/voegel
Back to top
View user's profile Visit poster's website
philm

Bascom Member



Joined: 14 Jul 2004
Posts: 138
Location: Australia

australia.gif
PostPosted: Mon Jan 10, 2005 10:21 pm    Post subject: Reply with quote

Thanks Josef
Back to top
View user's profile
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    www.mcselec.com Forum Index -> BASCOM-AVR Archive All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum