PS1ïŒå¥åPSXãå¥åPS OneïŒã¯ããœããŒã®PlayStationã²ãŒã ã³ã³ãœãŒã«ã®ç¬¬1äžä»£ã§ãããäžè¬ã«ç¬¬5äžä»£ã®ã²ãŒã ã³ã³ãœãŒã«ã«å±ããŠããŸãã CDã®èªã¿åãã«ã¯2åéãã©ã€ãã䜿çšããŸãããã®ãããªå€§éã®ããŒã¿ã«ãããçŸåšã®ã³ã³ãœãŒã«ã®åºæºã§ã¯ãã²ãŒã éçºè ã¯ã²ãŒã ã®ã³ã³ãã³ããäœæããéã®å¶éãç¹ã«æ¯ãè¿ãããšãã§ãããåäžä»£ã®ã²ãŒã ãããé«å質ã§ãããã³ã³ãœãŒã«ã®ããŸããã²ãŒã ã¯é·ããªãå¯èœæ§ããããŸãããããŠããŸããªäŸå€ãé€ããŠãåäžä»£ã®ã³ã³ãœãŒã«ã§ã®ã²ãŒã ã1ã€ã®ã²ãŒã ã»ãã·ã§ã³ã§ååã«å®äºããããšãã§ããã°ãPS1ã²ãŒã ã§ã¯ããã¹ãŠãç°ãªã£ãŠããŸãããé²è¡ç¶æ³ãä¿åããããã«ãPlayStationã«ã¯ã¡ã¢ãªã«ãŒãããããŸããããã¯ãåãå€ãå¯èœãªå°åã®äžæ®çºæ§ã¡ã¢ãªã¢ãžã¥ãŒã«ã§ãã
PlayStation 1ã¡ã¢ãªã«ãŒããã©ã®ããã«æ©èœããã®ããã©ã®ããã«æ©èœããã®ãããããŠã©ã®ããã«ç¬èªã®ãã®ãäœæã§ããã®ããæ£ç¢ºã«ç¥ãããå Žåã¯ãcatãžããããã
ãããã£ãŠãPS1ã¡ã¢ãªã«ãŒãã¯ããžã§ã€ãããããžã§ã€ã¹ãã£ãã¯ããã®ä»ã®ã¢ã¯ã»ãµãªã®åç©åå šäœã®ããã«ãæšæºã®åšèŸºæ©åšã§ãããããã©ã®ããã«æ©èœããããæ£ç¢ºã«ç解ããã«ã¯ããŸãå éšã«äœããããã調ã¹ãå¿ èŠããããŸãã
æšæºã®15ãããã¯ã¡ã¢ãªã«ãŒãã®ããªã³ãåè·¯åºæ¿ã®åç
åçãããããããã«ãã«ãŒãã®ããã€ã¹ã¯éåžžã«ã·ã³ãã«ã§ããã·ã¹ãã èŠæ±ãåŠçããã³ã³ãããŒã©ãŒãšãå®éã«ã¯ãæšæºã®NORFLASHã§è¡šãããäžæ®çºæ§ã¡ã¢ãªã§ããè«ççã«ã¯ãã¡ã¢ãªã«ãŒãã¯ã²ãŒã ã§äœ¿çšã§ãã15åã®ãããã¯ã«åå²ãããŠããŸãã 15ã¯ãã€ããªã·ã¹ãã ã§ã¯è«ççã§ã¯ãªãããã«æããããããããŸããããããã§ã¯ççŸã¯ãããŸãããNTFSã¹ããªãŒã ãšåæ§ã«ããã¡ã€ã«ã·ã¹ãã ã«1ã€ã®ãããã¯ãäžãããããã¡ã€ã«åãã¢ãã¡ãŒã·ã§ã³ã¢ã€ã³ã³ãããã«æ ŒçŽãããŸããåãããã¯ã®ãµã€ãºã¯8KiBã§ãåèš16ãããã¯ã¯128 KiBã§ããããã¯ãäžã®åçã®ãã©ãã·ã¥ã¡ã¢ãªã®ããŒãã³ã°ããããããŸãã
æåã¯ããã§ååã§ãããããã®åŸãäžåºŠã«è€æ°ã®ãããã¯ã䜿çšããã²ãŒã ãç»å Žãå§ããŸãããããšãã°ãSega GTãªã©ã®äžéšã®ã·ãã¥ã¬ãŒã¿ãŒã¯4ã5ãããã¯ã䜿çšããŸããã ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãããã£ãŠãäžè¬çã«ã¡ã¢ãªã«ãŒãå šäœã¯15ãããã¯ã§ããããã¯ããå€ãã®ã«ãŒããè³Œå ¥ããããšãäœåãªããããç¶æ³ã¯ãããããŒãã£ã¹ã¯ãŸãã¯ã«ãŒããªããžã®ããã«ãªãæãããããŸããããããããã®åŸãæµ·è³ã¯åŒãäžããŠã2ã4ããŸãã¯8ããŒãžã®ã«ãŒããäžåºŠã«çºè¡ãå§ããŸããããããŠãããŒãžã¯ããžã§ã€ãããã®å·§åŠãªçµã¿åããããŸãã¯ã¡ã¢ãªã«ãŒãèªäœã®æ瀺çãªãã¿ã³ã®ããããã«ãã£ãŠåãæ¿ããããŸããããã ãã2ããŒãžãè¶ ããã«ãŒãã§ã¯å§çž®ã䜿çšãããå®éã®ããŒãžæ°ã¯ã¯ããã«å°ãªããäžéšã®ã«ãŒãã¯ã°ãããŠãããã¯ãããå¯èœæ§ããããŸããããããŠã圌ãããã®ç¶æ ããæãåºãããšã¯éåžžã«å°é£ã§ãããããã¬ã€ã€ãŒã圌ãã®æãã®ããã«è¡ããªãã£ãããšããã«ãããŒãžã¡ã¢ãªã«ãŒãã®ä»£è¡šçãªäŸã次ã«ç€ºããŸãã
å·ŠåŽã¯2ããŒãžã®ã¡ã¢ãªã«ãŒããå³åŽã¯8ããŒãžã®ã¡ã¢ãªã«ãŒãã§ããå³åŽã«ã¯ããŒããŠã§ã¢ããŒãžããããã¿ã³ãš1ãã8ãŸã§ã®æ°åã瀺ãã€ã³ãžã±ãŒã¿ããããŸããæãã¬ã©ã¹ã®åŸãã«é ãããŠãã
å°ããªåæ çãªäœè«
ããã¯ãã¹ãŠ2001幎ã«ç§ããAllEmulatorsããšåŒã°ããPCçšã®å¥è·¡ã®ãã£ã¹ã¯ãè³Œå ¥ãããšãã«å§ãŸããŸããããã®äžã«PS1ãšãã¥ã¬ãŒã¿ãŒããããŸããïŒããã¯Bleemã§ããïŒãããŠåæã®ePSXeããããŠãåœæã®ã³ã³ãã¥ãŒã¿ãŒã¯PS1ãã£ã¹ã¯ãåçå¯èœã«åçããããšããã§ããŸããïŒãããŠå°ãåŸã«ã¢ãã ãæã«å ¥ããDirectPadProã«ã€ããŠåŠã³ãŸãã ããã€ãã£ããžã§ã€ã¹ãã£ãã¯ãã³ã³ãã¥ãŒã¿ãŒã«æ¥ç¶ããïŒLPTçµç±ã§ã¯ãããŸããïŒã«ã¯å€ãã®è²»çšãããããŸãããããŠããã®ã·ã¹ãã ã¯9xãšXPã®äž¡æ¹ã§åäœããŸããïŒãããŠå°ãåŸããã§ã«2002幎ã«ãç§ã¯ã¡ã¢ãªãŒã«ãŒããã£ããã£ãµã¯ã©ã«ã€ããŠåŠã³ãŸãã ïŒãã®ããã°ã©ã ã§ã¯ãåãDirectPadProæ¥ç¶ã¹ããŒã ã䜿çšããŠå®éã®ã¡ã¢ãªã«ãŒããæäœã§ããŸããããã®æãè¿œå ã®ããã€ã¹ãå¿ èŠãšããã«ã³ã³ãã¥ãŒã¿ãšæ å ±ã亀æã§ããããšã³ãã¬ã¹ãã¡ã¢ãªã«ãŒããäœããšããã¢ã€ãã¢ãæãã€ããŸããããããããã®æç§ã¯ååãªæ å ±ãšå©çšå¯èœãªèŠçŽ ããŒã¹ãæã£ãŠããŸããã§ããããããŠãã®èãã¯ãã ã®èãã®ãŸãŸã§ãç§ã®æèã®è£åºã®ã©ããã§ã¡ãã¡ããšå ã£ãŠããŸããã
ãã§ã«ååãªç¥èãããããšã³ãã¬ã¹ã¡ã¢ãªãŒã«ãŒãã®å°ãªããšãããã€ãã®ããŒãžã§ã³ãå®è£ ããæ©äŒãããããšã«æ°ä»ããŠãããã»ãŒ9幎ãçµéããŸããããã ããããã§ã¯å¥ã®èŠå ãé¢ä¿ããŠããŸãã幎霢ãšããã«é¢é£ãããã¹ãŠã®ãã®ã§ãã趣å³ã®æéã¯å°ãªããªããå¿é ã¯ãŸããŸãå¢ããŠããŸãããããŠä»ã ããç§ã¯äžè¬ã®äººã ã«å°ãªããšãããã€ãã®çµæãæ¬æ ŒçãªæŠå¿µå®èšŒãæäŸããããšãã§ããŸãã
ç©çã€ã³ã¿ãŒãã§ãŒã¹
ãã®ãããã¡ã¢ãªã«ãŒããšãžã§ã€ãããã¯å ±éã®ã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠæ©èœããŸãããã®äžã®ä¿¡å·ã®æ°ã¯6ã§ãååãšç®çã¯æ¬¡ã®ãšããã§ãã
- SEL0-æåã®ããŒãéžæä¿¡å·ãã¢ã¯ãã£ãã¬ãã«ãäœã
- SEL1-2çªç®ã®ããŒãéžæä¿¡å·ãã¢ã¯ãã£ãã¬ãã«ãããŒã
- CLK-ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¯ããã¯ä¿¡å·ãããã·ãç¶æ ã®ãã€ã¬ãã«ãç«ã¡äžãããšããžããšããžã§ã®ã©ããã
- CMD-ã³ã³ãœãŒã«ããåšèŸºæ©åšãžã®ããŒã¿ä¿¡å·ã
- DAT-åšèŸºæ©åšããã³ã³ãœãŒã«ãžã®ããŒã¿ä¿¡å·ã
- ACK-ããŒããŠã§ã¢ãã³ãã·ã§ã€ã¯ãã¢ã¯ãã£ãããŒã
ã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯ã3.3vãš7.6vã®2ã€ã®ç°ãªãé»æºé»å§ããããŸããSEL0ãš SEL1ãé€ããã¹ãŠã®ä¿¡å· ã¯ãæ¥ç¶ãããŠãããã¹ãŠã®ããã€ã¹ã«å ±éã§ãããã®ããã2çªç®ã®ã¹ãããã®åäœããŠããªãã¡ã¢ãªã«ãŒããŸãã¯ãžã§ã€ããããæåã®ã¹ãããã®äœæ¥è ã«åœ±é¿ãäžããŸãããã16ãããã³ã³ãœãŒã«ã®åŸã¯å¥åŠã«èŠããŸãããå€ãã®äººããã§ã«ã€ã³ã¿ãŒãã§ãŒã¹ã®æšæºSPIãèªèããŠãããšæããŸã -ãã¹ãŠãæ£ããã§ããããã§ããI / Oåäœã確èªããããã«ACKä¿¡å·ã®ã¿ãè¿œå ããŸã ããã¡ã¢ãªã«ãŒãã®æ¥ç¹ã®ä¿¡å·ã®å²ãåœãŠã¯ 次ã®ãšããã§ã
ã5ãã«ãã®ãã©ãã·ã¥ã§ä¿®åŸ©ãããã¡ã¢ãªã«ãŒã
ã€ã³ã¿ãŒãã§ã€ã¹ã®æè¡çç¹æ§ã¯æ¬¡ã®ãšããã§ãã
___ ___________________________ ____ \ / \ / X X ___/ \___________________________/ \____ ___ ____________ \ / \ \ / \ \____________/ \____ | | | tck | |<--------------------------->| +-------+-------+------+-------+ | | . | . | . | +-------+-------+------+-------+ | tck | 1 | 4 | - | +-------+-------+------+-------+ ACK: ____ SEL- |______________________________________________ ______ __________ ___________ CLK |||||||| |||||||| |||||||| | | ACK- -----------------------|_|-------------|_|--------- | ta1 | | | ta2 | |<------->| | |<----->| | | ap >|-|<----- +-----+------+-------+--------+ | | . | . | . | +-----+------+-------+--------+ | ta1 | 0 | - | 100 | - +-----+------+-------+--------+ | ta2 | | 10 | 1 | +-----+------+-------+--------+ | ap | 2 | | | ACK +-----+------+-------+--------+
CLKä¿¡å·ã®æž¬å®åšæ³¢æ°ã¯ 250kHzã§ãããã¯1ãµã€ã¯ã«ããã4 µsã§ããã€ã³ã¿ãŒãã§ã€ã¹ã®ç©çãã©ã¡ãŒã¿ãæŽçãããã®ã§ããã©ã³ã¹ããŒãå±€ã«ãªããŸãããçµéšè±å¯ãªãšã³ãžãã¢ã¯ããžã§ã€ããããšã¡ã¢ãªã«ãŒããå®å šã«äžŠåã«æ¥ç¶ãããŠãããäºãã«ç«¶åããå¯èœæ§ãããããšã«ãã§ã«æ°ã¥ããŠããŸããå®éãããã«ã¯ãœãããŠã§ã¢ã®èª¿åããããŸããSELnä¿¡å·ã ã¢ã¯ãã£ãåãããåŸãåšèŸºæ©åšã¯ãµã€ã¬ã³ãã®ãŸãŸã§ãããéä¿¡ãããæåã®ãã€ãããªãã¹ã³ããŸãããã®ãã€ãã0x01ã«çããå Žåããžã§ã€ããããã¢ã¯ãã£ãã«ãªããéžæä¿¡å·ãéã¢ã¯ãã£ãã«ãªããŸã§ã¡ã¢ãªã«ãŒãã¯ãµã€ã¬ã³ãã®ãŸãŸã«ãªããŸãããŸãããã€ãã0x81ã®å Žåããã®éãåœãŠã¯ãŸããŸããã¡ã¢ãªã«ãŒããã¢ã¯ãã£ãã«ãªãããžã§ã€ãããã¯ç¡é³ã«ãªããŸããåœç¶ããã¹ãã¯ACKä¿¡å·ãåŸ ã£ãŠããŸã ã¢ãŒããã¬ãŒã·ã§ã³ã®ãã®ãã€ãã§ãé·ãåŸ æ©ããŸãããããã¯ããã®åšèŸºã®äžéšãååšããªãå Žåã«ãåšèŸºã®æ®ãã®éšåã調ã¹ãæéã確ä¿ããããã«å¿ èŠã§ããå®éã®ãšããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯ãããŒã ã®éæ¹åãã¹ã®ä¿¡å·ããŸãã¯VBlankãšããŠããç¥ãããŠããä¿¡å·ã«åŸã£ãŠãã³ã³ãããŒã©ãŒãšã¡ã¢ãªã«ãŒããå³å¯ã«ããŒãªã³ã°ã ãŸãã第5äžä»£ãŸã§ã®ã³ã³ãœãŒã«ã®ã²ãŒã ã¯ããã¬ãŒã ã¬ãŒãã«çãããã®ã¿ã€ãã³ã°ã«é¢é£ä»ããããŠããããšãéåžžã«åãå ¥ããããŠããŸãããŸãããã¬ãŒã ã¬ãŒãã¯å³å¯ã«å®å®ããŠãããæ£èŠåãããŠããŸããPALã®å Žåã¯50HzãNTSCã®å Žåã¯60Hzã§ããã€ãŸãããžã§ã€ã¹ãã£ãã¯ãšã¡ã¢ãªã«ãŒãã®ããŒãªã³ã°æéã¯ãPALã®å Žåã¯20ããªç§ãNTSCã®å Žåã¯16ããªç§ã§ãã
ããã§ãç§ãã¡ã¯ä»²è£ãä»ã§ã¯å®éã®ãããã¬ãã«ãç解ããŸãããæšæºã®PS1ã¡ã¢ãªã«ãŒãã¯ã©ã®ã³ãã³ããç解ããŸããïŒã¯ããå®éããããã¯3ã€ãããããŸããã
- R -0x52ãŸãã¯èªã¿åããã¡ã¢ãªã«ãŒãã®ã»ã¯ã¿ãŒãèªã¿åãã
- W -0x57ãŸãã¯æžã蟌ã¿ãã¡ã¢ãªã«ãŒãã»ã¯ã¿ãŒã®èšé²;
- S -0x53ãŸãã¯ã¹ããŒã¿ã¹ãã¡ã¢ãªãŒã«ãŒãã®ç¶æ ãèªã¿åãã
ã¡ã¢ãªã«ãŒãå šäœãã»ã¯ã¿ãŒã«åå²ãããŠããŸãã128ãã€ãã®1ã»ã¯ã¿ãŒããããã£ãŠã128KiBã¯0x400ãŸãã¯1024ã»ã¯ã¿ãŒã«é©åããŸãããã®å Žåãèšé²ããåã«ã»ã¯ã¿ãŒãæ¶å»ããå¿ èŠã¯ãããŸããããã ããã·ã¹ãã ã¯ãèšé²æã«æ¬¡ã®ãã¬ãŒã å šäœã®æéãäžããããšãä¿èšŒãããŠããŸããã€ãŸãããã¬ãŒã ããšã«ã¡ã¢ãªã«ãŒããèªã¿åãããšãã§ããŸããã1ãã¬ãŒã ããšã«æžã蟌ã¿ãŸããã¡ãªã¿ã«ãããããçš®é¡ã®ãã³ãŒããã¬ãŒã«ãŒãã¯ãã¹ããŒãã¢ããã®ããã«ãããã®ã¿ã€ãã³ã°ã«åºå·ããŠããŸãããåã³ãã³ããããã«è©³ããåæããŠã¿ãŸãããã
ã¡ã¢ãªã«ãŒããããã³ã«
åã³ãã³ãã§éä¿¡ãããããŒã¿ã®é åºã¯æ¬¡ã®ããã«ãªããŸãã
èªæžïŒ
CMD 0x81 0x52 0x00 0x00 MSB LSB 0x00 0x00 0x00 0x00 0x00 ... 0x00 0x00 0x00 DAT ---- FLAG 0x5A 0x5D PRV PRV 0x5C 0x4D MSB LSB DATA ... DATA CHK ACK
:
CMD 0x81 0x57 0x00 0x00 MSB LSB DATA ... DATA CHK 0x00 0x00 0x00 DAT ---- FLAG 0x5A 0x5D PRV PRV PRV ... PRV PRV 0x5C 0x5D ACK
:
CMD 0x81 0x53 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 DAT ---- FLAG 0x5A 0x5D 0x5C 0x5D 0x04 0x00 0x00 0x80
å¡äŸïŒ
CMD-ãã¹ããã«ãŒãã«éä¿¡ããããŒã¿ã
DAT-ã«ãŒãããã¹ãã«éä¿¡ããããŒã¿ã
FLAG-ãããç¶æ ã®çŸåšã®ãã©ã°ãšåã®ã³ãã³ãã®çµæã
PRV-以åã«åä¿¡ããããŒã¿ããããå ã®åè·¯ãåçŽåããçµæã
MSB-ã»ã¯ã¿ãŒçªå·ã®äžäœãã€ãã
LSB-ã»ã¯ã¿ãŒçªå·ã®æäžäœãã€ãã
ããŒã¿-ãã€ããŒãã
CHK-ãããã¯ã®ãã§ãã¯ãµã ã
ACK-確èªãã©ã°ã FLAG
ãã€ã ã¯æ¬¡ã®ãããã䜿çšããŸãã
- D5 â Sony. .
- D3 â . .
- D2 â , .
é»æºæå ¥åŸã FLAGã¯0x08ã§ãããããŠãæåã®ã¬ã³ãŒãã®åŸãããã¯ãŒãã«ãªã»ãããããŸãã PS1ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯åžžã«ãã®ããã«ã»ã¯ã¿ãŒ0x003Fã«æžã蟌ã¿ãããã«ãã£ãŠãã®ã»ã¯ã¿ãŒã«æ©èãåŒãèµ·ãããŸããããããã·ã¹ãã ã«ãã£ãŠã¡ã¢ãªã«ãŒããããŒã¯ãããšããæ çµã¿ã®äžã§ããã®åéã§æçšãªæ å ±ã¯ãããŸãããMSBã»ã¯ã¿ãŒçªå· ïŒ LSB 10ãããã§ãç¯å²ã¯0x0000ã0x03FFã§ããCHKãã§ãã¯ãµã ã¯ã128ãã€ããã¹ãŠã®ããŒã¿+ MSBããã³ LSBã®éåžžã® XORã§ããACKç¢ºèª ã¯3ã€ã®å€ã®ã¿ãåãããšãã§ããŸãïŒ G 0x47ã E 0x43ãã®ãã0xFFã G = è¯å¥œãŸãã¯OKã E = ãšã©ãŒãå®éãã«ãŒãããèªã¿åãå Žåã ACKã¯åžžã«Gã«çãã ãG = OKãæžã蟌ãå Žå ã E =ãã§ãã¯ãµã ãšã©ãŒã§ããã0xFFã¯èª€ã£ãã»ã¯ã¿ãŒçªå·ãæå³ããŸãã確ãã«ãã»ãšãã©ã®ã«ãŒãã¯ã»ã¯ã¿ãŒçªå·ã®äžäœãã€ãã®æªäœ¿çšããããç Žæ£ããã ããªã®ã§ã0xFFã§å¿çããããšã¯ãããŸãããstatusã³ãã³ãã®0x0400ãš0x0080ã®æ°åã¯ããããã»ã¯ã¿ãŒã®æ°ãšãã€ãåäœã®ã»ã¯ã¿ãŒã®ãµã€ãºã§ãããšããç¹å®ã®èãã瀺åããŠããŸãããããã¯ç¢ºå®ã«ã¯ããããŸãããããŠãããã«ãããç§ãã¡ã¯äž»ãªããšã«ãªããŸãïŒ
ããªãã®ã¡ã¢ãªãŒã«ãŒããå®çŸãã
ã€ãŸãããããPS1ã¡ã¢ãªã«ãŒããäœæããããã«å¿ èŠãªãã¹ãŠã®æ å ±ã§ããæœåšçãªããã«ããã¯ã¯æ¬¡ã®ãšããã§ãã
- èªã¿åãæã¯ããŒã¿ã®æŽæ°ã«æéãããããŸããã»ã¯ã¿ãŒçªå·ãšå®éã®ããŒã¿è»¢éã®éã«ã¯ãACKãå°ã䌞ã°ãããšãã§ãã4ãã€ãããããŸããã¡ãªã¿ã«ãNOR FLASHã®å ã®ã¡ã¢ãªã«ãŒãã®å Žåããã¹ãŠã®ACKãåçã«ãªããŸããSPIFLASHã®ããã¡ã¢ãªã«ãŒãã®å ŽåãLSBéä¿¡åŸãã³ã³ãããŒã©ãã³ãã³ããSPI FLASHã«èšå®ããæåã®ãã€ããèªã¿åãACKé 延ããããŸãã ã亀æäžã«æ®ããèªã¿åããŸãã
- èšé²ããå Žåããã±ããå šäœã転éããŠé åã«èšé²ãéå§ããŠããæéãããããŸãããããã§ã¯ã·ã¹ãã èªäœãå¿ èŠãªé 延ãäžããŸãã
é»æºã«é¢ããŠã¯ã3.3Vã®ãžã§ã€ããããããžãã¯ã«äœ¿çšããã7.6Vãã¢ãŒã¿ãŒã«é»åãäŸçµŠããŸããã¡ã¢ãªã«ãŒãã¯éåžžã1ã€ã®é»æºã®ã¿ã䜿çšããŸããå éšã«5vFLASHãããå Žåã¯ã7.6vãšã¹ã¿ãã©ã€ã¶ãŒã䜿çšãããŸãã 3.3v FLASHãããå Žåã3.3vãããã«äœ¿çšãããŸãã
3.3VãæèŒããSTM32F407VGã§æ§ç¯ããæåã®ããŒãžã§ã³ã¯ãPSIOçšã®SPIãé«éSDIOãããã³ç»åå šäœãå éšã«ä¿åããã®ã«ååãªã¡ã¢ãªãåããŠãããåè¿°ã®åé¡ã解決ããŸããå®æããããã€ã¹ã®åçïŒ
STM32F407ã®ç§ã®ã¡ã¢ãªã«ãŒãã®æåã®ããŒãžã§ã³
ããã¯è¿ éã«ã確å®ã«ããããé«äŸ¡ã§ããããšãå€æããŸããããã£ãšå®ãã§ããŸããïŒãŸãããŸããææŠã¯åãå ¥ããããŸããã¿ã¹ã¯ã®è©³çŽ°ãèæ ®ããŠãSTM32F042F6ãéžæããŸãããèµ·ãã£ãããšã¯
次ã®ãšããã§ããSTM32F042ã®ã¡ã¢ãªã«ãŒãã®2çªç®ã®ããŒãžã§ã³
ç§ãã¡ã®ã«ãŒãã¯é§åãããã®ã§ãå€éšã®æ°Žæ¶æ¯ååã«ããåšæ³¢æ°å®å®åã¯å¿ èŠãªããå éšã®çºæ¯åšã§ååã§ãããã®ã³ã³ãããŒã©ãŒã«ã¯ããŒããŠã§ã¢SPIã1ã€ããã®ã§ããã©ã³ã¹ããŒãã®é 延ãæžããããã«SDã«ãŒãã«æž¡ããŸãããPSIOã¯ããã§ãœãããŠã§ã¢ã«ãªããŸãã
ãœãããŠã§ã¢ã®å®è£
æåã«è¡ãããšã¯ãSPIã¢ãŒãã§SDã«ãŒããæäœããããšã§ããç§ã¯ããã«ããŸããã ããã€ããã¯ãããŸãããããã¯é·ãéåã¿ç ãããã€ã³ã¿ãŒãããäžã«æ£ãã°ã£ãŠããŸããã»ã¯ã¿ãŒã®åæåãèªã¿åããæžã蟌ã¿ã³ãŒãã以äžã«ç€ºããŸãã
Card_InitïŒïŒ
// TCardType Card_Init( void ) { // TCardType Res; uint32_t Cnt,OCR; uint8_t Dat, Resp; // CARD_OFF; Res = ctNone; // SPI PCLK/128: 48/128 = 0,375 SPI1->CR1 &= ~SPI_CR1_SPE; SPI1->CR1 = SPI_CR1_MSTR | SPI_LOW_SPEED; SPI1->CR1 |= SPI_CR1_SPE; // HAL_Delay( 1 ); // 256 for (Cnt = 0;Cnt < 256;Cnt++ ) { // Card_SPI( 0xFF ); } // CARD_ON; // do { // 0xFF Dat = Card_SPI( 0xFF ); } while ( Dat != 0xFF ); // CMD0: GO_IDLE_STATE Card_SendCMD( &CARD_CMD0[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, DISABLE, 128 ); // ? if ( Resp == 0x01 ) { // IDLE_STATE, CMD8: SEND_IF_COND Card_SendCMD( &CARD_CMD8[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); // if ( Resp != 0x01 ) { // SDv1/MMC do { // ACMD41: APP_SEND_OP_COND Card_SendCMD( &CARD_ACMD41[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); } while ( Resp == 0x01 ); // ? if ( Resp == 0x00 ) { // SD v1 Res = ctSD1; } else { // MMC, Res = ctUnknown; } } else { // SDv2 if ( (OCR & 0x0001FF) == 0x0001AA ) { // SDv2 do { // ACMD55: APP_CMD Card_SendCMD( &CARD_CMD55[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, DISABLE, 128 ); // if ( Resp == 0x01 ) { // ACMD41: APP_SEND_OP_COND Card_SendCMD( &CARD_ACMD41[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); } } while ( Resp == 0x01 ); // ? if ( Resp == 0x00 ) { // CMD58: READ_OCR Card_SendCMD( &CARD_CMD58[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, ENABLE, 128 ); // ? if ( Resp == 0x00 ) { // OCR if ( (OCR & 0x40000000) == 0x00000000 ) { // Res = ctSD2; } else { // Res = ctSD3; } } else { // Res = ctUnknown; } } else { // Res = ctUnknown; } } else { // Res = ctUnknown; } } } else { // if ( Res != 0xFF ) { Res = ctUnknown; } } // if ( (Res == ctSD1) || (Res == ctSD2) ) { // 512 // CMD16: SET_BLOCKLEN Card_SendCMD( &CARD_CMD16[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( &OCR, DISABLE, 128 ); // ? if ( Resp != 0x00 ) { // Res = ctUnknown; } } // while ( (SPI1->SR & SPI_SR_BSY) != 0x0000 ) { } CARD_OFF; // if ( (Res != ctNone) && (Res != ctUnknown) ) { // SPI PCLK/2: 48/2 = 24 SPI1->CR1 &= ~SPI_CR1_SPE; SPI1->CR1 = SPI_CR1_MSTR; SPI1->CR1 |= SPI_CR1_SPE; } // return Res; }
Card_ReadïŒïŒ
// DMA FunctionalState Card_Read( TCardType CardType, uint8_t *Buf, uint32_t *Loaded, uint32_t Addr ) { // FunctionalState Res; uint8_t Cmd[ 6 ]; uint8_t Dat,Resp; uint32_t Cnt; // Res = DISABLE; // , ? if ( *(Loaded) != Addr ) { // *(Loaded) = Addr; // if ( (CardType == ctSD1) || (CardType == ctSD2) ) { // LBA Addr *= 0x00000200; } // while ( 1 ) { // - if ( CardType == ctNone ) { break; } if ( CardType == ctUnknown ) { break; } // Cmd[ 0 ] = CARD_CMD17; Cmd[ 1 ] = Addr >> 24; Cmd[ 2 ] = Addr >> 16; Cmd[ 3 ] = Addr >> 8; Cmd[ 4 ] = Addr; Cmd[ 5 ] = 0xFF; // CARD_ON; // do { // 0xFF Dat = Card_SPI( 0xFF ); } while ( Dat != 0xFF ); // Card_SendCMD( &Cmd[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( (uint32_t *)&Cmd[ 0 ], DISABLE, 128 ); // if ( Resp != 0x00 ) { break; } // Cnt = 2048; do { // Dat = Card_SPI( 0xFF ); // Cnt--; } while ( (Dat == 0xFF) && (Cnt > 0) ); // ? if ( Cnt == 0 ) { break; } // ? if ( Dat != CARD_DATA_TOKEN ) { break; } // , for (Cnt = 0;Cnt < 512;Cnt++) { // *(Buf) = Card_SPI( 0xFF ); Buf++; } // CRC Cmd[ 0 ] = Card_SPI( 0xFF ); Cmd[ 1 ] = Card_SPI( 0xFF ); // Res = ENABLE; // break; } } else { // Res = ENABLE; } // while ( (SPI1->SR & SPI_SR_BSY) != 0x0000 ) { } CARD_OFF; // , if ( Res == DISABLE ) { *(Loaded) = 0xFFFFFFFF; } // return Res; }
Card_WriteïŒïŒ
// DMA FunctionalState Card_Write( TCardType CardType, uint8_t *Buf, uint32_t *Loaded, uint32_t Addr ) { // FunctionalState Res; uint8_t Cmd[ 6 ]; uint8_t Dat,Resp; uint32_t Cnt; // Res = DISABLE; // if ( (CardType == ctSD1) || (CardType == ctSD2) ) { // LBA Addr *= 0x00000200; } // while ( 1 ) { // - if ( CardType == ctNone ) { break; } if ( CardType == ctUnknown ) { break; } // Cmd[ 0 ] = CARD_CMD24; Cmd[ 1 ] = Addr >> 24; Cmd[ 2 ] = Addr >> 16; Cmd[ 3 ] = Addr >> 8; Cmd[ 4 ] = Addr; Cmd[ 5 ] = 0xFF; // CARD_ON; // do { // 0xFF Dat = Card_SPI( 0xFF ); } while ( Dat != 0xFF ); // Card_SendCMD( &Cmd[ 0 ], CMD_LENGTH ); Resp = Card_WaitResp( (uint32_t *)&Cmd[ 0 ], DISABLE, 128 ); // if ( Resp != 0x00 ) { break; } // Card_SPI( CARD_DATA_TOKEN ); // // , for (Cnt = 0;Cnt < 512;Cnt++) { // Card_SPI( *(Buf) ); Buf++; } // CRC Card_SPI( 0xFF ); Card_SPI( 0xFF ); // Res = ENABLE; // break; } // while ( (SPI1->SR & SPI_SR_BSY) != 0x0000 ) { } CARD_OFF; // ? if ( Res == ENABLE ) { // *(Loaded) = Addr; } else { // *(Loaded) = 0xFFFFFFFF; } // return Res; }
ã«ãŒãã¯375kHzïŒPCLK / 128ïŒã§åæåããã24MHzïŒPCLK / 2ïŒã§åäœããŸãããã®ãããªé床ã§ã®æž¬å®ã§ã¯ãSDv1ãšSDHCããã©ã³ã¶ã¯ã·ã§ã³å šäœã§2.8ããªç§ä»¥å ã«ã»ã¯ã¿ãŒãæäŸããããšã瀺ãããŸãããããã¯èŠããŠããå¿ èŠããããŸã PSIOã®èªã¿åãæäœã«ãšã£ãŠéèŠã§ãã
ããã§ã¯ãPSIOãèŠãŠã¿ãŸããããäžã§è¿°ã¹ãããã«ããšã«ãããœãããŠã§ã¢ã§ãããæã£ãŠããŸãã远跡ããä¿¡å·ã¯ãSELãš CLKã®2ã€ã ã ã§ããäž¡æ¹ã®é¢ã§æåã®ãã®ã远跡ããããŒã¿äº€æã®æºåãããŸãã
EXTI2_3_IRQHandlerïŒïŒ
// SEL void EXTI2_3_IRQHandler( void ) { // EXTI->PR = 0x00000004; // SEL if ( MEM_SEL ) { // SEL = 1 EXTI->IMR &= 0xFFFFFFFE; State.PSIO.Mode = mdSync; // LED_GREEN_OFF; } else { // SEL = 0 EXTI->IMR |= 0x00000001; State.PSIO.Bits = 7; // LED_GREEN_OFF; LED_RED_OFF; } // MEM_DAT1; MEM_nACK; }
åé¢ã«æ²¿ã£ãŠCLKä¿¡å· ã®ã¿ããã£ããããŸããäºå®ãSTM32F042ã¯48MHzã§ããåäœããããã®ããã©ãŒãã³ã¹ã¯ç§ãã¡ã®ã¿ã¹ã¯ã«ã¯å°ããããŸãããŸããäž¡æ¹ã®é¢ã§å²ã蟌ã¿ãå®è¡ãããšããã€ãã®è»¢éäžã«ãå®éã«ã¯å²ã蟌ã¿ãã³ãã©ãŒããæãåºããããã¹ãŠãå¯èœæ§ã®å±æ©ã«çããŠæ£ããæ©èœãã倱æããããšããããŸãããããŠãããã³ãã«ã®ã¿åå¿ããäžéæã«å®è¡ããå¿ èŠã®ããäœæ¥ãå²ã蟌ã¿ã®æåŸã«å®è¡ãããå Žåãããã€ãã®ãã§ãã¯ãã¹ããŒãããå¯èœæ§ããããããCLKæéã®55ïŒ æªæºã§ãã¹ãŠãæ£åžžã§ãã ããã®ãã³ãã©ãŒãã¢ã»ã³ãã©ãŒã§å¯èœãªéãæé©ã«èšè¿°ãããŠããã°ãäž¡æ¹ã®ãžã£ã³ãã§ãæ©èœããã¯ãã§ãããã³ãã©ãŒã³ãŒãã¯æ¬¡ã®ãšããã§ãã
EXTI0_1_IRQHandlerïŒïŒ
// CLK void EXTI0_1_IRQHandler( void ) { // EXTI->PR = 0x00000001; // uint16_t AckTime; // AckTime = 0; // State.PSIO.DataIn >>= 1; if ( MEM_CMD ) { // 1 State.PSIO.DataIn |= 0x80; } else { // 0 State.PSIO.DataIn &= 0x7F; } // if ( State.PSIO.Bits > 0 ) { // State.PSIO.Bits--; } else { // ? if ( State.PSIO.Bits == 0 ) { // State.PSIO.Bits = 7; // State.PSIO.DataOut = State.PSIO.DataIn; // switch ( State.PSIO.Mode ) { // case mdSync : { // if ( State.PSIO.DataIn == 0x81 ) { // State.PSIO.Mode = mdCmd; // State.PSIO.DataOut = State.MemCard.Status; // ACK AckTime = AckNormal; } else if ( State.PSIO.DataIn == 0x01 ) { // , . State.PSIO.Mode = mdDone; } // break; } // case mdCmd : { // State.PSIO.Mode = mdParam; // State.MemCard.Cmd = State.PSIO.DataIn; State.MemCard.Bytes = 0; // State.PSIO.DataOut = 0x5A; // ACK AckTime = AckNormal; // break; } // case mdParam : { // ACK AckTime = AckNormal; // switch ( State.MemCard.Cmd ) { // : R case 0x52 : { // switch ( State.MemCard.Bytes ) { // case 0 : { State.PSIO.DataOut = 0x5D; break; } case 1 : { break; } case 2 : { State.MemCard.Sector = State.PSIO.DataIn * 0x0100; State.MemCard.Check = State.PSIO.DataIn; break; } case 3 : { State.MemCard.Sector += State.PSIO.DataIn; State.MemCard.Check ^= State.PSIO.DataIn; State.PSIO.DataOut = 0x5C; State.SDCard.CardOp = coRead; AckTime = AckDelayed; break; } case 4 : { State.PSIO.DataOut = 0x5D; AckTime = AckDelayed; break; } case 5 : { State.PSIO.DataOut = State.MemCard.Sector >> 8; AckTime = AckDelayed; break; } case 6 : { State.PSIO.DataOut = State.MemCard.Sector; AckTime = AckDelayed; State.PSIO.Mode = mdRdData; State.MemCard.Bytes = 0; break; } default : { State.PSIO.Mode = mdDone; AckTime = 0; break; } } // LED_GREEN_ON; // break; } // : W case 0x57 : { // switch ( State.MemCard.Bytes ) { // case 0 : { State.PSIO.DataOut = 0x5D; break; } case 1 : { break; } case 2 : { State.MemCard.Sector = State.PSIO.DataIn * 0x0100; State.MemCard.Check = State.PSIO.DataIn; break; } case 3 : { State.MemCard.Sector += State.PSIO.DataIn; State.MemCard.Check ^= State.PSIO.DataIn; // break; } State.PSIO.Mode = mdWrData; State.MemCard.Bytes = 0; break; } default : { State.PSIO.Mode = mdDone; AckTime = 0; break; } } // LED_RED_ON; // break; } // : S case 0x53 : { // switch ( State.MemCard.Bytes ) { // case 0 : { State.PSIO.DataOut = 0x5D; break; } case 1 : { State.PSIO.DataOut = 0x5C; break; } case 2 : { State.PSIO.DataOut = 0x5D; break; } case 3 : { State.PSIO.DataOut = 0x04; break; } case 4 : { State.PSIO.DataOut = 0x00; break; } case 5 : { State.PSIO.DataOut = 0x00; break; } case 6 : { State.PSIO.DataOut = 0x80; break; } default : { State.PSIO.Mode = mdDone; AckTime = 0; break; } } // break; } // default : { State.PSIO.Mode = mdDone; break; } } // if ( State.PSIO.Mode == mdParam ) { State.MemCard.Bytes++; } // break; } // case mdRdData : { // ACK AckTime = AckNormal; // if ( State.MemCard.Bytes < 128 ) { // State.PSIO.DataOut = State.MemCard.Data[ State.MemCard.Bytes ]; State.MemCard.Check ^= State.PSIO.DataOut; } else { // switch ( State.MemCard.Bytes ) { // case 128 : { State.PSIO.DataOut = State.MemCard.Check; break; } // case 129 : { State.PSIO.DataOut = 0x47; break; } // default : { State.PSIO.Mode = mdDone; AckTime = 0; LED_GREEN_OFF; break; } } } // State.MemCard.Bytes++; // break; } // case mdWrData : { // ACK AckTime = AckNormal; // if ( State.MemCard.Bytes < 128 ) { // State.MemCard.Data[ State.MemCard.Bytes ] = State.PSIO.DataIn; State.MemCard.Check ^= State.PSIO.DataIn; } else { // switch ( State.MemCard.Bytes ) { // case 128 : { // if ( State.MemCard.Check == State.PSIO.DataIn ) { State.MemCard.Check = 0x47; } else { State.MemCard.Check = 0x4E; } // State.PSIO.DataOut = 0x5C; // break; } // case 129 : { State.PSIO.DataOut = 0x5D; break; } // case 130 : { // , if ( State.MemCard.Sector < 0x4000 ) { // , State.PSIO.DataOut = State.MemCard.Check; // ? if ( State.MemCard.Check == 0x47 ) { // State.SDCard.CardOp = coWrite; // State.MemCard.Status &= ~StateNew; } } else { // , State.PSIO.DataOut = 0xFF; } // break; } // default : { State.PSIO.Mode = mdDone; AckTime = 0; break; } } } // State.MemCard.Bytes++; // break; } // , case mdDone : { break; } // - default : { State.PSIO.Mode = mdSync; break; } } } } // if ( State.PSIO.Mode != mdSync ) { // if ( State.PSIO.DataOut & 0x01 ) { // 1 MEM_DAT1; } else { // 0 MEM_DAT0; } // State.PSIO.DataOut >>= 1; } // ACK? if ( AckTime > 0 ) { // CNT TIM3->CNT = AckTime; // State.PSIO.Ack = DISABLE; // TIM3->SR = 0x0000; // TIM3->CR1 |= TIM_CR1_CEN; } }
TIM3ã¿ã€ããŒã¯ãACKã®çæãæ åœã ãŸããããã¯ããã®é 延äžã«ã«ãŒãã«ãSDã«ãŒããèªç±ã«äœ¿çšã§ããããã«ããããã«å¿ èŠã§ããã¿ã€ããŒå²ã蟌ã¿ãã³ãã©ãŒã¯æ¬¡ã®ããã«ãªããŸãã
TIM3_IRQHandlerïŒïŒ
// TIM3 void TIM3_IRQHandler( void ) { // TIM3->SR = 0x0000; // if ( State.PSIO.Ack == ENABLE ) { // ACK MEM_nACK; } else { // ACK MEM_ACK; // State.PSIO.Ack = ENABLE; // TIM3->CNT = 0; // TIM3->CR1 |= TIM_CR1_CEN; } }
ã³ãŒãã¯ååã«ã³ã¡ã³ããããŠãããå€ãã®åæã¯å¿ èŠãªããšæããŸããèªã¿åãã³ãã³ãã§ã»ã¯ã¿ãŒçªå·ã®2çªç®ã®ãã€ããåä¿¡ããåŸãmainïŒïŒé¢æ°ã®æ°žé ã®ã«ãŒãã§ã¹ãã³ããã³ãŒãã®SDã«ãŒãããã®èªã¿åãæäœã®ãã©ã°ãèšå®ããããšã«æ³šæããŠãã ããããããŠãã®çŽåŸã«ã次ã®4ã€ã® ACKãé·æéçºè¡ãããŸããã€ã³ã¿ãŒãã§ã€ã¹ã§ã¯ã次ã®ããã«ãªããŸãã
ããžãã¯ã¢ãã©ã€ã¶ããã°ã©ã ã®ã¹ã¯ãªãŒã³ã·ã§ããããã©ã³ã¶ã¯ã·ã§ã³ã®4ã€ã®å€§ããªé 延ã匷調衚瀺ãããŠããŸã
åèšã§çŽ3.5msãå ¥åãããŸãããããã¯ã¡ã€ã³ã³ãŒãã®ã¢ã«ãŽãªãºã ãã»ã¯ã¿ãŒãèªã¿åãã®ã«ååã§ããããã«ããã®ã³ãŒãã¯ãäžæããªãå Žåã«ã®ã¿æ©èœããŸããã¡ããã©ãããã®å€§ããªäžæåæ¢ã§ãèšé²äžããã©ã°ã¯æåŸã«èšå®ãããã·ã¹ãã ãã¡ã¢ãªã«ãŒãã«èšé²ã®å®äºãèš±å¯ãããããã¡ã€ã³ã³ãŒãã¯å²ã蟌ã¿ã«ããå¹²æžãªãã«æ©èœããŸããããã§ã¯ãã¡ã€ã³ã«ãŒãã®ã³ãŒããèŠãŠã¿ãŸãããã
ã¡ã€ã³ïŒïŒ
// while ( 1 ) { // if ( CARD_nCD == 0 ) { // if ( State.SDCard.CardType == ctNone ) { // LED_GREEN_ON; LED_RED_OFF; // , State.SDCard.CardType = Card_Init(); // ? if ( State.SDCard.CardType != ctUnknown ) { // if ( Card_FSInit( &State.SDCard, &CARD_IMAGE[ 0 ] ) == ENABLE ) { // , EXTI->IMR |= 0x00000004; // LED_GREEN_OFF; LED_RED_OFF; } else { // State.SDCard.CardType = ctUnknown; // LED_GREEN_ON; LED_RED_ON; } } else { // LED_GREEN_ON; LED_RED_ON; } } } else { // if ( State.SDCard.CardType != ctNone ) { // , PSIO EXTI->IMR &= 0xFFFFFFFA; // State.PSIO.Mode = mdSync; State.PSIO.Bits = 0; State.PSIO.DataIn = 0x00; State.PSIO.DataOut = 0; State.PSIO.Ack = DISABLE; State.MemCard.Status = StateNew; State.SDCard.CardType = ctNone; State.SDCard.CardOp = coIdle; State.SDCard.LoadedLBA = 0xFFFFFFFF; } // LED_GREEN_OFF; LED_RED_OFF; } // if ( (State.SDCard.CardType != ctNone) && (State.SDCard.CardType != ctUnknown) ) { // ? if ( State.SDCard.CardOp == coWrite ) { // Ofs = State.MemCard.Sector & 0x03FF; LBA = (Ofs >> 2) & 0x000000FF; Ofs = (Ofs << 7) & 0x00000180; // Card_Read( State.SDCard.CardType, &State.SDCard.CardBuf[ 0 ], &State.SDCard.LoadedLBA, State.SDCard.CardList[ LBA ] ); // for (Cnt = 0;Cnt < 128;Cnt++) { // State.SDCard.CardBuf[ Ofs + Cnt ] = State.MemCard.Data[ Cnt ]; } // Card_Write( State.SDCard.CardType, &State.SDCard.CardBuf[ 0 ], &State.SDCard.LoadedLBA, State.SDCard.CardList[ LBA ] ); // LED_RED_OFF; // State.SDCard.CardOp = coIdle; } // ? if ( State.SDCard.CardOp == coRead ) { // Ofs = State.MemCard.Sector & 0x03FF; LBA = (Ofs >> 2) & 0x000000FF; Ofs = (Ofs << 7) & 0x00000180; // Card_Read( State.SDCard.CardType, &State.SDCard.CardBuf[ 0 ], &State.SDCard.LoadedLBA, State.SDCard.CardList[ LBA ] ); // for (Cnt = 0;Cnt < 128;Cnt++) { // State.MemCard.Data[ Cnt ] = State.SDCard.CardBuf[ Ofs + Cnt ]; } // State.SDCard.CardOp = coIdle; } } }
ãšã¿ãŒãã«ã«ãŒãã§ã¯ãSDã«ãŒãæ¿å ¥ä¿¡å·ãåžžã«åæãããŸããå€åºå ã§ãããåŒãåºããšãã³ãŒãã¯PSIOãç¡å¹ã«ããPS1ã¯ã«ãŒããã倱ããŸãããã«ãŒããå ã«æ»ãããå ŽåïŒãŸãã¯ã«ãŒããæ¿å ¥ãããç¶æ ã§é»æºããªã³ã«ãªã£ãå ŽåïŒãæåã«Card_InitïŒïŒé¢æ°ã䜿çšããŠã«ãŒããåæåããããšããŸããããã«ãããæ€åºãããã«ãŒãã®ã¿ã€ããè¿ãããŸãã SDv1ãšä»ã®SDHC / SDXCã¢ãã¬ãã·ã³ã°æ¹åŒã¯ç°ãªããããããã¯éèŠã§ããåæåã³ãŒãèªäœã«ã¯ç§å¯ããªããFatFSãåæ§ã®ãããžã§ã¯ãã«ã€ããŠã€ã³ã¿ãŒãããäžã§å ¥æå¯èœãªå€æ°ã®äŸã§ã¹ãã€ãããŸããã
ã«ãŒãã®åæåã«ç¶ããŠãããªãããŒãªé¢æ°Card_FSInitïŒïŒãåŒã³åºãããŸããããããã®ãããžã§ã¯ãã®æãéèŠãªæ©èœã§ããäºå®ãSTM32F042ã¯æ©èœãæ§ããã§ãããå¿ èŠãªé床ã§å®å šãªFatFSãµããŒããåŒãåºãããšã¯ã§ããŸããããããã£ãŠãç§ã¯ãã®æ¹æ³ãæãã€ããŸãããç»åãã¡ã€ã«ã¯åžžã«128KiBã§ããããã512ãã€ãã®256ã»ã¯ã¿ãŒã®ã¿ãç¥ãå¿ èŠããããåã»ã¯ã¿ãŒã«ã¯PS1ã¡ã¢ãªã«ãŒãã®æ£ç¢ºã«4ã»ã¯ã¿ãŒãå«ãŸããŸãããããã£ãŠã次ã®ããšãè¡ããŸãã
- MBRã®ã»ã¯ã¿ãŒLBA =ïŒ0ãåæããŸãããããå®éã«MBRã§ããå ŽåãMBSãé 眮ãããŠããæ°ããã»ã¯ã¿ãŒãååŸããŸãã
- æ³å®ãããMBSã®ã¢ãã¬ã¹ïŒMBRããªãå Žåã¯ïŒ0ãMBRãããå Žåã¯ããã€ãã®çªå·ïŒãåãåã£ãããFAT12ãFAT16ãFAT32ããŸãã¯vFATã®ããããã«å±ãããã©ããã®åæãéå§ããŸãã ã
- ã»ã¯ã¿ãŒããã§ãã¯ã«åæ Œããå Žåããã®ã»ã¯ã¿ãŒããæ§é ã«é¢ããæ å ±ãååŸããã«ãŒããã£ã¬ã¯ããªã§ãã¡ã€ã«åãæã€èŠçŽ ãæ¢ããŸãããã®å Žåã¯ãMEMCRD00.BINãã§ãã
- ãã®ãããªãã¡ã€ã«ãèŠã€ãã£ãå Žåã¯ããã®ãµã€ãºã確èªããŸãã0x20000ãã€ãã«å³å¯ã«åºå®ããå¿ èŠããããŸãããã¹ãŠãããã§ããã°ãæåã®ã¯ã©ã¹ã¿ãŒã®çªå·ãååŸããŸãã
- ãã®ãã€ã³ãã«å°éããå Žåãã€ã¡ãŒãžãé 眮ãããŠããç©çLBAã»ã¯ã¿ãŒã®ãªã¹ããäœæããããã«å¿ èŠãªãã¹ãŠã®æ å ±ããã§ã«ãããŸããFATãã§ãŒã³ãééããMBSããã®æ§é æ å ±ã䜿çšããŠã256ã®LBAã»ã¯ã¿ãŒçªå·ã®ããŒãã«ã«å ¥åããŸãã
æåãããšãPSIOãèµ·åããPS1ã¯ãã®ã«ãŒããéåžžã®15ãããã¯ã«ãŒããšèŠãªããŸããããããã®æ®µéã§ãšã©ãŒãçºçãããšãåäœãäžæãããäž¡æ¹ã®LEDãç¹ç¯ããé»æºãåæããããSDã«ãŒãã亀æããããŸã§ãã¹ãŠããã®ç¶æ ã®ãŸãŸã«ãªããŸãããã®æé ã®ã³ãŒãã¯æ¬¡ã®ãšããã§ãã
Card_FSInitïŒïŒ
// , FAT16 FunctionalState Card_FSInit( TSDCard *SDCard, const uint8_t *FName ) { // FunctionalState Res; uint8_t *Buf; uint8_t Pos; uint16_t ClustSize,Reserv,RootSize,FATSize,Cluster; uint32_t Cnt,LBA,SysOrg,FATOrg,RootOrg,DataOrg; int Compare; // Res = DISABLE; SysOrg = 0; Cluster = 0xFFFF; // while ( 1 ) { // 0 if ( Card_Read( SDCard->CardType, &SDCard->CardBuf[ 0 ], &SDCard->LoadedLBA, SysOrg ) == DISABLE ) { break; } // #0 MBR if ( *((uint16_t *)&SDCard->CardBuf[ 0x01FE ]) != 0xAA55 ) { break; } // MBR if ( ((SDCard->CardBuf[ 0x01BE ] == 0x00) || (SDCard->CardBuf[ 0x01BE ] == 0x80)) && ((SDCard->CardBuf[ 0x01CE ] == 0x00) || (SDCard->CardBuf[ 0x01CE ] == 0x80)) && ((SDCard->CardBuf[ 0x01DE ] == 0x00) || (SDCard->CardBuf[ 0x01DE ] == 0x80)) && ((SDCard->CardBuf[ 0x01EE ] == 0x00) || (SDCard->CardBuf[ 0x01EE ] == 0x80)) ) { // MBR, for (Cnt = 0;Cnt < 4;Cnt++) { // if ( (SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C2 ] == 0x01) || // 0x01: FAT12 (SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C2 ] == 0x04) || // 0x04: FAT16 (SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C2 ] == 0x06) || // 0x06: Big FAT16 (SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C2 ] == 0x0E) ) // 0x0E: vFAT { // , MBS SysOrg = SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C6 ]; SysOrg += (SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C7 ] * 0x00000100); SysOrg += (SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C8 ] * 0x00010000); SysOrg += (SDCard->CardBuf[ (Cnt * 0x0010) + 0x01C9 ] * 0x01000000); // break; } } } // MBS if ( Card_Read( SDCard->CardType, &SDCard->CardBuf[ 0 ], &SDCard->LoadedLBA, SysOrg ) == DISABLE ) { break; } // MBS if ( *((uint16_t *)&SDCard->CardBuf[ 0x01FE ]) != 0xAA55 ) { break; } if ( SDCard->CardBuf[ 0x000D ] == 0x00 ) { break; } if ( (SDCard->CardBuf[ 0x0010 ] == 0x00) || (SDCard->CardBuf[ 0x0010 ] > 0x02) ) { break; } if ( SDCard->CardBuf[ 0x0015 ] != 0xF8 ) { break; } if ( *((uint32_t *)&SDCard->CardBuf[ 0x001C ]) != SysOrg ) { break; } if ( SDCard->CardBuf[ 0x0026 ] != 0x29 ) { break; } if ( *((uint16_t *)&SDCard->CardBuf[ 0x0036 ]) != 0x4146 ) { break; } if ( *((uint16_t *)&SDCard->CardBuf[ 0x0038 ]) != 0x3154 ) { break; } if ( SDCard->CardBuf[ 0x003A ] != 0x36 ) { break; } // , ClustSize = SDCard->CardBuf[ 0x000D ]; Reserv = *((uint16_t *)&SDCard->CardBuf[ 0x000E ]); RootSize = (SDCard->CardBuf[ 0x0012 ] * 0x0100) + SDCard->CardBuf[ 0x0011 ]; FATSize = *((uint16_t *)&SDCard->CardBuf[ 0x0016 ]); // FAT ROOT FATOrg = SysOrg + Reserv; RootOrg = FATOrg + (FATSize * 2); DataOrg = RootOrg + (RootSize / 16 ); // , for (LBA = 0;LBA < (RootSize / 16);LBA++) { // if ( Card_Read( SDCard->CardType, &SDCard->CardBuf[ 0 ], &SDCard->LoadedLBA, RootOrg + LBA ) == ENABLE ) { // 16 , for (Cnt = 0;Cnt < 16;Cnt++) { // Compare = memcmp( &SDCard->CardBuf[ Cnt * 32 ], &CARD_IMAGE[ 0 ], 11 ); if ( Compare == 0 ) { // , if ( *((uint32_t *)&SDCard->CardBuf[ (Cnt * 32) + 0x001C ]) == 0x00020000 ) { // , Cluster = *((uint16_t *)&SDCard->CardBuf[ (Cnt * 32) + 0x001A ]); // Res = ENABLE; // break; } } } // - if ( Res == ENABLE ) { break; } } else { // - break; } } // , , if ( Res == ENABLE ) { // , Pos = 0; do { // if ( Cluster < 0x0002 ) { // , Res = DISABLE; break; } // LBA LBA = DataOrg + ((Cluster - 2) * ClustSize); // for (Cnt = 0;Cnt < ClustSize;Cnt++) { // LBA SDCard->CardList[ Pos ] = LBA + Cnt; // Pos++; if ( Pos == 0 ) { break; } } // , // , if ( Pos != 0 ) { // LBA = FATOrg; Reserv = Cluster; while ( Reserv > 256 ) { LBA++; Reserv -= 256; } // if ( Card_Read( SDCard->CardType, &SDCard->CardBuf[ 0 ], &SDCard->LoadedLBA, LBA ) == ENABLE ) { // Cluster = *((uint16_t *)&SDCard->CardBuf[ Reserv * 2 ]); } else { // Res = DISABLE; break; } } } while ( (Cluster != 0xFFFF) && (Pos != 0) ); } // break; } // return Res; }
æ£çŽãªãšãããããã¯åãªãPoCã§ãããããããã§ã¯FAT16æ€çŽ¢ã®ã¿ãå®è£ ãããŠããŸããFAT12ã¯ããããããµããŒãããå¿ èŠã¯ãããŸãã-ãã®ãããªå°ããªããªã¥ãŒã ã®microSDã¯ååšããŸããããã ããå°æ¥èª°ããå¿ èŠã«ãªã£ãå Žåã¯ãFAT32ãŸãã¯vFATãè¿œå ã§ããŸãã
ç»åã®ååãMEMCRD00.BINãã¯å¶ç¶ã«éžã°ããŸããã§ãããäºå®ãå°æ¥çã«ã¯ããã«ãããŒãžã¡ã¢ãªã«ãŒãã®ãžã§ã€ãããã®ãã¿ã³ã®æšæºçãªçµã¿åãããä»ããŠç»åéžæãè¿œå ããäºå®ã§ããSELECTãæŒãããŸãŸã«ãããšãL1 / R1ã1åæŒããŸãããŸããæåŸã®2æåãå€æŽããããšã§ãã«ãŒããã£ã¬ã¯ããªã§ãMEMCRD00.BINããããMEMCRD99.BINããŸã§ã®100åã®ç»åããµããŒãã§ããŸããSCKå²ã蟌ã¿ãã³ãã©ã«ã¯ããã®ããã®åºç€ããããŸãã PSIOã€ã³ã¿ãŒãã§ã€ã¹ã§ããžã§ã€ããããžã®åŒã³åºããåæããããã©ã³ããã¹ããã¡ãäœæããã®ã«åé¡ã¯ãããŸããããPS1ã³ã³ãããŒã©ã®åšèŸºæ©åšã¯è±å¯ã§ããããããã®ã»ãšãã©ãã¹ãŠããµããŒãããå¿ èŠããããŸãã
ãã®çµæãããã€ã¹ã¯å¹ççã§ããããšãå€æããå¿ èŠã«å¿ããŠèª°ã§ããããç¹°ãè¿ãããšãã§ããŸãã ãããžã§ã¯ãå šäœãžã®ãªã³ã¯ã¯ãã¡ãã§ããèšäºãžã®ã³ã¡ã³ãã«èå³ã®ããæ¹ã®ãæäŒãããããŠããã ããŸãã
PSãã®ãããžã§ã¯ãã®äœæã«äœ¿çšãããã¹ãŠã®æ å ±æºã®ãªã¹ããããã«ç€ºããããšæããŸãããæ®å¿µãªãããããã¯éåžžã«å°é£ã§ããå¶ç¶ã«å€ãã®ããšãè³ã«ãããŸãããç¬èªã®ãšãã¥ã¬ãŒã¿ãŒãäœæããã人ã®ããã«ã15幎以äžåã®PS1ã«é¢ããäžè¬çãªæ å ±ãå«ãTXTãã¡ã€ã«ã®åœ¢åŒã§äœããæäŸãããŸããããããŠä»ãããã¯ãã¹ãŠç§ã®ããŒããã©ã€ãäžã®ããã€ãã®ããã¹ããã¡ã€ã«ãšããŠååšããŸããéå»15幎éãã€ã³ã¿ãŒãããå šäœãæ å ±æºã§ãã£ããšèšããŸãã