Reference design for SST ATA-Disk Chip into 8051 microcontroller
Application note
Abstract: this application note introduces the hardware and firmware of reference design for SST ATA-Disk Chip SST58SD/LDxxx into SST FlashFlex51 SST89C54/58 (8051 compatible microcontroller).
1.Hardware connections:
Please reference to attached schematic diagram for hardware connections.
SST ATA-Disk Chip (ADC) SST58SD/LDxxx only supports one working mode, ie. ATA/IDE mode, all control signals are connected based on Table 2-8, Page 14 on datasheet. After executed Set Feature Command to enable 8-bit data transfers, all higher 8 bit data bus ( D8-D15) are don’t care and can be No Connect. RESET# (pin1) is optional, it can be tied up to Vcc if not used. After power-up, ADC will automatically be reset internally, it doesn’t need external reset input. But it’s a good practice to connect RESET# to one of I/O pins such as P1.4, in case ADC is out of control for any unknown reasons, host MCU has capability to reset ADC. DASP# is connected to an emitting diode through a resistor to Vcc, LED provides user a visibility of ADC’s internal operation. When ADC is active busy on operation, LED will be on. Please be noted that master/slave selection at CSEL pin won’t take effect until Next reset, in other words, if you change the jumper setting of master/slave selection, you MUST reset ADC once.
Ifyour application system expands any other I/O or data memory, please modify the reference design: (1)change CS3FX# to Vcc, (2)connect the output of address decoder to CS1FX#.When both CS1FX#and CS3FX# are high,ADC is de-selected and be standby state, all data bus are in high-z. When CS1FX# is low, ADC is selected and be operational. So CS1FX# acts as Chip Select (/CS) in most common peripherals.
2.Firmware design guide:
It’s important to know that ATA/IDE standard doesn’t permit access only one byte at a time to its media such as HDD or ADC, firmware must read or write data sector by sector, 1 sector has 512 bytes of data,system design engineer must design data buffer to support random access to ADC. Reference design uses the secondary block (4Kbytes x 8bit) of on-chip flash in SST89C54/58 as data buffer.
After power-up or external reset, ADC is default to be 16-bit operation. As SST89C54/58 is 8-bit MCU, firmware must enable 8-bit operation by Set Features Command, please reference to page 32 on datasheet.
If ADC is set as Slave, other than Master, you need to change the bit4 in Drive/Head Register to be 1 when writing Command to ADC, see page 17 on datasheet.
After power-on or reset,ADC will be ready to read / write operation after 200ms (typical), 500ms (maximum), see page 1 under Start Up Time in Features on datasheet.
3.Conclusion:
It’s easy to modify this reference design to any other embedded controllers as long as you follow above design guidelines.
4.Schematic diagram:
5.8051 Source code:
; all commands supported by ADC.
ChkPwrEqu0E5h; 98h
DiagnosticEqu90h
FormatEqu50h
IdentifyEqu0ECh
IdleEqu0E3h; 97h
IdleImmEqu0E1h; 95h
InitializeEqu91h
ReadBufEqu0E4h
ReadLongEqu22h; 23h
ReadMultiEqu0C4h
ReadSctrEqu20h; 21h
ReadVerifyEqu40h; 41h
RecalibrateEqu10h; 1xh
SeekEqu70h; 7xh
SetFeatureEqu0EFh
SetMultiEqu0C6h
SleepEqu0E6h; 99h
StandbyEqu0E2h; 96h
StandbyImmEqu0E0h; 94h
WriteBufEqu0E8h
WriteLongEqu32h; 33h
WriteMultiEqu0C5h
WriteSctrEqu30h; 31h
WriteVerifyEqu3Ch
;=============================================================
; ADC Drive Register Set definitions
Data_RegEqu8000h; Data Register for read / write
Error_RegEqu8001h; Error Register, read only
FeaturesEqu8001h; features Register, write only
Sectr_CntEqu8002h; Sector Count Register ( R / W )
Sectr_NoEqu8003h; Sector Number Register, or LBA0:7 ( R / W )
Cylinder_LowEqu8004h; Cylinder Low Register or LBA8:15 ( R / W )
Cylinder_HiEqu8005h; Cylinder High Register or LBA16:23 ( R / W )
Drv_HeadEqu8006h; Drive Head Register ( R / W )
StatusEqu8007h; Status Register, read only
CommandEqu8007h; Command Register, write only
Alt_StatusEqu4006h; Alternate Status Register, read only,
; reading Alt_Status doesn't clear interrupt pending flag. Not used in this demo.
Device_CtrlEqu4006h; Device Control Register, write only. Not used in this demo.
Drive_AddrsEqu4007h; Drive Address Register, read only. Not used in this demo.
;=================================================================
; SST FlashFlex51 microcontroller related SFR's definition
SFCFDATA0B1H; SuperFlash Configuration
SFCMDATA0B2H; SuperFlash Command
SFALDATA0B3H; SuperFlash Address Low
SFAHDATA0B4H; SuperFlash Address High
SFDTDATA0B5H; SuperFlash Data
SFSTDATA0B6H; SuperFlash Status
WDTCDATA0C0H; Watchdog Timer Control
WDTDDATA86H; Watchdog Timer Data/Reload
;=================================================================
; constantdefinition
FlashAddrsEqu0F800h; start address to store data from ADC
;===========================================
org0000h
ljmpstart
org0100h
start:clrP1.4; reset ADC
nop
nop
nop
nop
setbP1.4
movr4, #5; delay 0.5 second
loadr5:movr5, #200; delay 0.1 second
loadr6:movr6, #250; delay 0.5ms for 12MHz crystal
djnzr6, $
djnzr5, loadr6
djnzr4, loadr5
acallEnable8bit; First of all, enable 8 bits operation!
;========================================
orlSFCF,#40h; IAPEN=1
movSFAH,#high(FlashAddrs)
movSFAL,#low(FlashAddrs)
movB,#8; erase 8 sectors (512 bytes)
;========================================
erase:movSFCM,#0Bh; sector erase!
acallDone?
mova,SFAL
adda,#64;64 bytes / sector in Block 1 of SST89C54/58
movSFAL, a
mova,SFAH
addca,#0
movSFAH, a
djnzB,erase
anlSFCF,#0BFh; disable IAP
;========================================
main:acall Write_Sctr
acall Read_Sctr
acall Compare
jbF0, fail
clrP1.4; indicates successful operations.
setbP1.5
sjmp$
fail:clrP1.5; flags failed comaprison.
setbP1.4
sjmp$
;========================================
Function:acallBusy
movdptr, #Sectr_Cnt
mova, R2; R2 is Sector Count
movx @dptr, a
movdptr, #Sectr_No
mova, R3; R3 contains LBA0:7
movx @dptr, a
movdptr, #Cylinder_Low
mova, R4; R4 contains LBA8:15
movx @dptr, a
movdptr, #Cylinder_Hi
mova, R5; R5 contains LBA16:23
movx @dptr, a
movdptr, #Drv_Head
mova, R6; R6 contains LBA24:27
anla,#00001111b
orla,#11100000b; bit4=0 as MASTER-p.htm" target="_blank" title="MASTER貨源和PDF資料">MASTER, 1 as Slave; bit6=1, enable LBA.
movx @dptr, a
movdptr, #command
mova, R7; R7 is command code.
movx @dptr, a
ret
;========================================
Busy:movdptr, #status
movx a, @dptr
jbacc.7, Busy
jbacc.0, errors
;jnbacc.6, Busy
clra; acc=0 when successful
clrC; C=0, ADC is not busy (BUSY=0) and no error (ERR=0)
ret; and is ready to accept commands (RDY=1)
errors:movdptr, #Error_Reg
movx a, @dptr
setb C; C=1 flags error codes contained in ACC register
ret
;========================================
WaitDRQ:movdptr, #status
movx a, @dptr
jbacc.7,WaitDRQ; if BUSY=1, then WaitDRQ
jnbacc.3, WaitDRQ; if DRQ=0, then WaitDRQ
jbacc.0,errors; if ERR=1, then read errors code and set flag C
;jnbacc.6, WaitDRQ
clra
clrC; C=0, ADC is BUSY=0, DRQ=1, ERR=0.
ret
;========================================
Done?:mova, SFST
jbacc.2,Done?
ret
;========================================
Enable8bit:acall Busy
movdptr, #Features
mova,#01h; enable 8 bit data transfer
movx@dptr, a
movdptr, #Drv_Head
mova,#11100000b; bit4=0 as MASTER-p.htm" target="_blank" title="MASTER貨源和PDF資料">MASTER, 1 as Slave ; bit6=1, enable LBA
movx@dptr, a
movdptr, #COMMAND
mova,#SetFeature; #0EFh
movx@dptr, a
ret
;========================================
Write_Sctr:movR2,#1; write 1 sector at a time.
movR3,#0Ah; suppose LBA to be 000000Ah
movR4,#0
movR5,#0
movR6,#0
movR7,#WriteSctr
acallFunction
acallWaitDRQ
acallWrite512
ret
;========================================
Write512:movR0,#high(message) ; get the higher address of message
movR1,#low(message); get the lower address of message
movR7,#2; 512 bytes = 2 * 256
movB,#0
write:movdph,R0; get the address
movdpl,R1
clra
movca,@a dptr; get the data in message
incdptr; point to next byte in message
movR0,dph; save the address
movR1,dpl
movDPTR, #Data_Reg; point to ADC
movx@dptr, a; write 1 byte data into ADC
djnzB,write
djnzR7, write; write all 512 bytes to ADC
ret
;========================================
Read_Sctr:movR2,#1; read 1 sector at a time.
movR3,#0Ah; suppose LBA to be 000000Ah
movR4,#0
movR5,#0
movR6,#0
movR7,#ReadSctr
acallFunction
acallWaitDRQ
acallRead512
ret
;========================================
; read 1 sector of 512 bytes data and write into flash on chip of SST FlashFlex51 MCU
Read512:movR7,#2; 512 bytes = 2 * 256
movB,#0
movdptr,#Data_Reg
movSFAH, #high(FlashAddrs)
movSFAL, #low(FlashAddrs)
orlSFCF, #40h; set IAPEN=1 to enable IAP
read:movxa,@dptr; read 1 byte data from ADC
movSFDT, a; program into on-chip flash
movSFCM, #0Eh; issue Byte-Program command
acallDone?; wait until done
mova,SFAL; adjust the address of flash
adda,#1
movSFAL, a
mova,SFAH
addca,#0
movSFAH, a
djnzB,read
djnzR7, read
anlSFCF, #0BFh; disable IAP
ret
;========================================
Compare:movdptr,#message;point to message
movSFAH,#high(FlashAddrs)
movSFAL,#low(FlashAddrs)
orlSFCF, #40h; IAPEN=1
clrF0
movR7,#2
movB,#0
verify:clra
movca,@a dptr; getoriginal data in message
incdptr
movSFCM, #0Ch; issue BYTE-VERIFY command
nop
xrla, SFDT; SFDT contains datain flash, these data come from ADC
jzskip
setbF0; set flag F0 (PSW.5) if any discrepancy.
skip:mova,SFAL; increase the address of flash
adda,#1
movSFAL, a
mova,SFAH
addca,#0
movSFAH, a
djnzB,verify
djnzR7, verify
anlSFCF, #0BFh; disable IAP
ret
;========================================================================
message:DB"This demo program demonstrates how easy to design "
DB"SST ATA-Disk Chip into SST FlashFlex51 embedded microcontroller. "
DB"After you understand how to use the basic WriteSector and ReadSector "
DB"functions, it's easy to try any others."
DB"The hardware connection between ADC and MCU is also very simple,"
DB"just like you expand any I/O or data memory in your application system. "
DB"After power-on, ADC is default to be 16 bit operation as all EIDE "
DB"standards, firmware needs enable 8 bit operation before "
DB"further write / read operation."
end