
ååŒãåºãã®å¯¿åœã«ã¯ãæ§æãã¡ã€ã«ã®ç¬èªã®ããŒããŒãFPGAã«æžã蟌ã¿ãããšãããããŸãã ç§ã¯ãå·¥ç§å€§åŠã®åŠéšã®ãã¬ãŒãã³ã°ã¹ã¿ã³ãã®éçºã«åå ããå¿ èŠããããŸããã ã¹ã¿ã³ãã¯ããžã¿ã«ä¿¡å·åŠçãç 究ããããã«èšèšãããŠããŸããããã®èšäºã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ç¹ã«éèŠã§ã¯ãããŸããã ãŸããéèŠãªããšã¯ãFPGAïŒAltera Cyclone IVïŒãã¹ã¿ã³ãã®ããŒã¹ã«ãããã¹ã¿ã³ãã®äœæè ãèããããã«ãåŠçãããããçš®é¡ã®DSPã¹ããŒã ãåéããããšã§ãã ã¹ã¿ã³ãã¯USBçµç±ã§ã³ã³ãã¥ãŒã¿ãŒã«æ¥ç¶ãããŸãã USBçµç±ã§ã³ã³ãã¥ãŒã¿ãŒããFPGAãããŠã³ããŒãããå¿ èŠããããŸãã
2ãã£ã³ãã«åãããFT2232Hã§FTDIã䜿çšããŠPCã«æ¥ç¶ããããšã決å®ãããŸããã 1ã€ã®ãã£ãã«ã¯FPGAã³ã³ãã£ã®ã¥ã¬ãŒã·ã§ã³ã«äœ¿çšããããã1ã€ã®ãã£ãã«ã¯é«éFIFO亀æã«äœ¿çšã§ããŸãã
FTDIã«ã¯MORPH-IC-IIãããã°ããŒãããããCyclone II FPGAã¯USBçµç±ã§ãã©ãã·ã¥ãããŸãã ãããªãã¯ãã¡ã€ã³ã®æŠå¿µã ããŒãããŒããŒã®ãœãŒã¹ã³ãŒãã¯éšåçã«éããŠããŸããããŒãããŒããŒèªäœã¯äœ¿çšå¯èœã§ãããFTDIãæäœããããžãã¯ã¯ãã¹ãŠãã©ã€ããŒãã©ã€ãã©ãªã«ç§»åãããå€æŽã§ããŸããã å®éãç§ã¯åœåããã®ããŒãããŒããŒããããžã§ã¯ãã§äœ¿çšãããã極端ãªå Žåã«ã¯DLLã«åºã¥ããŠã·ã§ã«ãäœæããããšãèšç»ããŠããŸããã ãã¡ãŒã ãŠã§ã¢ã¯ãããã·ãã·ãªã¢ã«ã¢ãŒãïŒããã·ãã·ãªã¢ã«-PSïŒã§FPGAã«ããŒããããFTDIã¯MPSSEã¢ãŒãã§åäœããŸãã ãã¬ããããŒãäžã§ãMORPH-IC-IIãœãªã¥ãŒã·ã§ã³ã®ããã©ãŒãã³ã¹ã¯å®å šã«ç¢ºèªãããŸããããåé¡ã¯ããããããšã§ãããããããã¯çºçããŸããã§ããã dll MORPH-IC-IIã®åäœäžãæ¥ç¶ãããŠãããã¹ãŠã®FTDIããã€ã¹ããããã¯ããããã¬ãŒãã³ã°ã³ã³ãã¬ãã¯ã¹ã®äžéšãšããŠãåæ§ã®ã³ã³ããŒã¿ãŒãåãã2ã€ã®ããã€ã¹ããžã§ãã¬ãŒã¿ãŒãšã·ã°ãã«ã¢ãã©ã€ã¶ãŒããããŸãã ããããšã®åæäœæ¥ã¯äžå¯èœã§ãã ããããããããŠè¿·æã§ãã
åæ§ã®ã±ãŒã¹ããç«ææ¢æ»æ©ã®ã¡ã³ããŒã«ãã£ãŠå®è£ ãããŸããïŒ USB JTAGããã°ã©ããŒMBFTDI ã FTDIã¯MPSSEã¢ãŒãã§ã䜿çšãããŸãããMORPH-IC-IIãšã¯ç°ãªããFPGAã®åäœã¯JTAGã¢ãŒãã§çºçããŸãã ãœãŒã¹ã¯ç¡æã§å ¥æã§ããŸããããã®ã¹ããŒã¿ã¹ïŒã©ã€ã»ã³ã¹ïŒãæ確ã«ç€ºããã®ã¯èŠã€ãããŸããã§ããã ãããã£ãŠãåæ¥ãããžã§ã¯ãã§ãããã䜿çšããããã«ãç§ã®æã¯äžãããŸããã§ããã
ãã®ãããªééããä¿®æ£ããŸãããã®èšäºã®ãã¬ãŒã ã¯ãŒã¯ã§æ瀺ããããã¹ãŠã®ãã®ã¯ãBSDã©ã€ã»ã³ã¹ã®äžã§ãªãŒãã³ãªãªããžããªã«æçš¿ãããŸãã
ã³ã³ãã£ã®ã¥ã¬ãŒã·ã§ã³ãã¡ã€ã«ãFPGAãããã«ããŠã³ããŒããã
ãŸããFPGAããŒãã¢ãŒãã«å¯ŸåŠããå¿ èŠããããŸãã ãããã¯ã«ç²Ÿéãå§ããŠãã人ã®ããã«ãç§ã¯å°ããªé 足ãäžããŸãã Cyclone IV Eãã¡ããªã®ã¢ã«ãã©ïŒIntelïŒFPGAãããŒãã«ã€ã³ã¹ããŒã«ãããŠããŸãããããŒãæ¹æ³ã¯Cyclone FPGAã°ã«ãŒãå šäœã§é¡äŒŒããŠãããäœããã®åœ¢ã§ä»ã®å€ãã®ãã¡ããªã«é©ããŠãããšæãããŸãã
ãã®ã¿ã€ãã®FPGAã¯ãæ®çºæ§SRAMã䜿çšããŠæ§æããŒã¿ãä¿åããŸãã ãããã®æ§æããŒã¿ã¯ãçµæã®ããã€ã¹ã®æ©èœã決å®ããŸãã å°éçšèªã§ã¯ããã®ããŒã¿ã¯ãã°ãã°ããã¡ãŒã ãŠã§ã¢ããšåŒã°ããŸãã ãããã£ãŠããã¡ãŒã ãŠã§ã¢ã¯ç¹å¥ãªRAMã«ä¿åãããããã€ã¹ã®é»æºãå ¥ãããã³ã«FPGAãããã«ããŒãããå¿ èŠããããŸãã ãã¡ãŒã ãŠã§ã¢ãSRAMã«ããŒãããã«ã¯ãããã€ãã®æ¹æ³ïŒæ§æã¹ããŒã ïŒããããŸãïŒãªã¹ãã¯Cyclone IV Eã«é¢é£ããŠããŸãïŒã
- ã¢ã¯ãã£ãã·ãªã¢ã«ïŒASïŒã
- ã¢ã¯ãã£ããã©ã¬ã«ïŒAPïŒ
- ããã·ãã·ãªã¢ã«ïŒPSïŒ
- é«éåå䞊åïŒFPPïŒã
- JTAGã
ç¹å®ã®ããŒãã¢ãŒãã®éžæã¯ãFPGAïŒMSELã°ã«ãŒãïŒã®å€éšç«¯åã䜿çšããŠå®è¡ãããŸãã JTAGã¢ãŒãã¯åžžã«äœ¿çšå¯èœã§ãã ã¢ã¯ãã£ãã¢ãŒãã¯ãé»åãäŸçµŠããããšãFPGAãå€éšã¡ã¢ãªïŒã·ãªã¢ã«ãŸãã¯ãã©ã¬ã«ïŒããç¬ç«ããŠããŒã¿ãèªã¿åãããšãæå³ããŸãã ããã·ãã¢ãŒãã§ã¯ãFPGAã¯å€éšã¡ãã£ã¢ãæ§æããŒã¿ãããã¢ã¯ãã£ãã«è»¢éããã®ãåŸ ã¡ãŸãã ãããã®ã¹ããŒã ã¯ããã¹ã¿ãŒïŒãã¹ã¿ãŒïŒ-ã¹ã¬ãŒãïŒã¹ã¬ãŒãïŒã®æŠå¿µã«ããŸãé©åããŸãã ã¢ã¯ãã£ãã¢ãŒãã§ã¯ãFPGAã¯ãã¹ã¿ãŒãšããŠæ©èœããããã·ãã¢ãŒãã§ã¯ã¹ã¬ãŒããšããŠæ©èœããŸãã
ãã®åé¡ã§ã¯ãFPGAã§ã¯ãããŸãããããŠãŒã¶ãŒã¯ãã¡ãŒã ãŠã§ã¢ã®æŽæ°ææã決å®ããå¿
èŠããããããããŒãã¢ãŒãã¯ããã·ãã«ããå¿
èŠããããŸãã ãŸãããããã®èãç¯çŽããããã«ãã·ãªã¢ã«ã€ã³ã¿ãŒãã§ã€ã¹ãéžæããŸãã ããã§ã¯ãããã·ãã·ãªã¢ã«ïŒPSïŒã¢ãŒããšJTAGãé©ããŠããŸãã JTAGã®ããžãã¯ã¯ããè€éãªã®ã§ãæåã®ãªãã·ã§ã³ã«æ³šç®ããŸãããã
以äžã®å³ã¯ãPSã¢ãŒãã§ããŠã³ããŒãããããã®å€éšã³ã³ãããŒã©ãŒãžã®FPGAã®æ¥ç¶ã¹ããŒã ã瀺ããŠããŸãã

æ§æãéå§ããã«ã¯ãå€éšãã¹ã¿ãŒãnCONFIGã©ã€ã³ã§LowããHighãžã®é·ç§»ãçæããå¿ èŠããããŸãã FPGAãããŒã¿ãåä¿¡ããæºåãã§ãããšããã«ã nSTATUSã©ã€ã³ã§é«ã¬ãã«ã圢æããŸãã ãã®åŸããã¹ã¿ã¯DATAã©ã€ã³[0]ã§ããŒã¿ã®éä¿¡ãéå§ãã DCLKã©ã€ã³ã§å¯Ÿå¿ããã¯ããã¯ãã«ã¹ãéä¿¡ã§ããŸã ã CONF_DONEã©ã€ã³ã§é«ã¬ãã«ã確ç«ããïŒãŸãã¯ããŒã¿ãçµäºããªãïŒãFPGAãåæåç¶æ ã«åãæ¿ãããŸã§ãããŒã¿ãã¿ãŒã²ããããã€ã¹ã«éä¿¡ããå¿ èŠããããŸãã CONF_DONEã 1ã«èšå®ãããåŸãFPGAãåæåãéå§ããããã«ãããã«2ã€ã®ã¯ããã¯ãã«ã¹ãé©çšããå¿ èŠãããããšã«æ³šæããŠãã ããã
ããŒã¿ã¯æäžäœãããïŒ LSB ïŒé ã§éä¿¡ãããŸããã€ãŸããæ§æãã¡ã€ã«ã«ã·ãŒã±ã³ã¹02 1B EE 01 FAãå«ãŸããŠããå ŽåïŒãã³ãããã¯ã®äŸããã®ãŸãŸäœ¿çšïŒãããŒã¿è¡ã§ã·ãŒã±ã³ã¹ã圢æããå¿ èŠããããŸãã
0100-0000 1101-1000 0111-0111 1000-0000 0101-1111
ãããã£ãŠã5è¡ã®ã¿ã䜿çšãããŸã ãã·ãªã¢ã«éä¿¡ã®å Žåã¯DATAè¡[0]ããã³DCLK ãå¶åŸ¡ã®å Žåã¯nCONFIG ã nSTATUS ã CONF_DONEè¡ã§ãã
åºæ¬çã«ãPSã¢ãŒãã¯è¿œå ã®ãã©ã°æäœãåããSPIã«ä»ãªããŸããã
ããŒã¿è»¢éã¬ãŒãã¯ãããã¥ã¡ã³ãã«ç€ºãããŠããæ倧åšæ³¢æ°ãããäœãããå¿
èŠããããŸã;ãããžã§ã¯ãã§äœ¿çšãããCyclone IV Eã·ãªãŒãºã®å Žåã66 MHzã§ãã
æå°éä¿¡åšæ³¢æ°ã¯ååšããŸãããçè«çã«ã¯ãæ§æãç¡æéã«äžæããããšãå¯èœã§ãã ããã«ããããªã·ãã¹ã³ãŒãã䜿çšãã段éçãªãããã°ã®åªããæ©äŒãåŸãããŸããããã¯å¿ ã䜿çšããŸãã
次ã®å³ã¯ãæãéèŠãªã¿ã€ãã³ã°ãæã€ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ã€ãã³ã°å³ã瀺ããŠããŸãã

ã¹ã©ã€ããŒã¹ãMPSSE
MPSSEã¢ãŒãã§ã®FTDIã®æäœãæ€èšããŠãã ããã ç§ã®æèŠã§ã¯ãMPSSEïŒãã«ããããã³ã«åæã·ãªã¢ã«ãšã³ãžã³ïŒã¢ãŒãã¯ãSPIãI2CãJTAGã1ç·ãªã©ã®åºç¯ãªããŒã¿è»¢éãããã³ã«ãå®è£ ããæ©äŒãéçºè ã«æäŸããããã«ãäœããã®çš®é¡ã®ã·ãªã¢ã«ã€ã³ã¿ãŒãã§ã€ã¹ãã¶ã€ããŒãäœæããããã®å€ããå°ãªããæåããè©Šã¿ã§ããããã«åºã¥ããã®ä»ã
çŸåšããã®ã¢ãŒãã¯FT232HãFT2232DãFT2232HãFT4232Hã®è¶ å°ååè·¯ã§äœ¿çšã§ããŸãã ç§ã®ãããžã§ã¯ãã§ã¯FT2232Hã䜿çšããŠãããããããåºãç¯å²ã§ããã«ã€ããŠè©±ããŸãã MPSSEã¢ãŒãã®å Žåã16åã®ã¬ãã°ãå²ãåœãŠãããäžäœLãšæé«Hã®2ãã€ãã«åå²ãããŸããåãã€ãã¯èªã¿åããŸãã¯èšå®ã§ããŸãã ãã€ãLã®4ã€ã®äžåŽã®èã«ã¯ç¹å¥ãªæ©èœããããŸã-ã·ãªã¢ã«ããŒã¿äŒéã¯ããããéããŠè¡ãããŸãã åã¬ãã°ã¯å ¥åãŸãã¯åºåãšããŠèšå®ã§ããããã©ã«ãå€ãåºåã«èšå®ã§ããŸãã é 次éä¿¡ã®å Žåããããã®é åºïŒ MSB / LSB ïŒãéä¿¡ã¯ãŒãé·ãã¯ããã¯åšæ³¢æ°ãåæããã³ã-ããã³ãïŒç«ã¡äžããïŒãŸãã¯ãªã¢ïŒç«ã¡äžããïŒãããŒã¿ãªãã§ã¯ããã¯ãã«ã¹ã®ã¿ãéä¿¡ãããã3çžã¯ããã¯ãéžæã§ããŸãïŒI2Cã«é¢é£ïŒãªã©ã
ã·ãŒã ã¬ã¹ã«ããã°ã©ãã³ã°ã«ç§»è¡ããŸãã ãœãããŠã§ã¢ãšFTDIããããšã®å¯Ÿè©±ã«ã¯ã2ã€ã®ä»£æ¿æ¹æ³ããããŸãïŒæåã«ãã¯ã©ã·ãã¯ãšåŒã³ãŸãããããã®å ŽåãUSBããŒãã«æ¥ç¶ãããšãã·ã¹ãã å ã®ãããã¯ä»®æ³ã·ãªã¢ã«ããŒãïŒCOMïŒãšããŠå®çŸ©ããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã¯VCPïŒä»®æ³COMããŒãïŒãã©ã€ããŒã䜿çšããŸãã ãã以éã®ããã°ã©ãã³ã°ã¯ãã¹ãŠãåŸæ¥ã®COMããŒãã®ããã°ã©ãã³ã°ãšéãã¯ãããŸããããªãŒãã³-éä¿¡/ã«ãŠã³ã-ã¯ããŒãºã ããã¯ãLinuxãMac OSãå«ãããŸããŸãªãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã«åœãŠã¯ãŸããŸãã ãã ãããã®ã¢ãããŒãã§ã¯ãFTDIã³ã³ãããŒã©ãŒã®ãã¹ãŠã®æ©èœãå®çŸããããšã¯ã§ããŸããããããã¯USB-UARTã¢ããã¿ãŒãšããŠæ©èœããŸãã 2çªç®ã®æ¹æ³ã¯ãFTD2XXç¬èªã®ã©ã€ãã©ãªã«ãã£ãŠæäŸãããŸãããã®ã€ã³ã¿ãŒãã§ã€ã¹ã¯ãæšæºã®COMããŒãAPIã§ã¯å©çšã§ããªãç¹å¥ãªæ©èœãæäŸããŸããç¹ã«ãMPSSEã245 FIFOãBit-bangãªã©ã®ç¹å¥ãªåäœã¢ãŒããèšå®ããã³äœ¿çšã§ããŸãã FTD2XX APIã©ã€ãã©ãªãŒã¯ã ãœãããŠã§ã¢ã¢ããªã±ãŒã·ã§ã³éçºD2XXããã°ã©ããŒãºã¬ã€ãã«è©³ããææžåãããŠããŸãã ã¯ããFTD2XXã¯ããŸããŸãªãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã§ã䜿çšã§ããŸãã
FTDIéçºè ã¯ãæ¯èŒçæ°ããMPSSEãæ¢åã®D2XXãœãããŠã§ã¢çžäºäœçšã¢ãã«ã«çµ±åãããšãã課é¡ã«çŽé¢ããŠããŸããã ãããŠåœŒãã¯æåããŸãããMPSSEã¢ãŒãã§ã®äœæ¥ã«ã¯ãä»ã®ãã¯ã©ã·ãã¯ãã¢ãŒããšåãé¢æ°ã»ããã䜿çšãããåãã©ã€ãã©ãªFTD2XX APIã䜿çšãããŸãã
ã€ãŸããMPSSEã¢ãŒãã§åäœããããã®ã¢ã«ãŽãªãºã ã¯æ¬¡ã®ããã«èª¬æã§ããŸãã
- ã·ã¹ãã ã§ããã€ã¹ãèŠã€ããŠéããŸãã
- ããããåæåããMPSSEã¢ãŒãã«ããŸãã
- MPSEEã®åäœã¢ãŒããèšå®ããŸãã
- ããŒã¿ã®çŽæ¥äœæ¥ïŒGPIOã®éä¿¡ãåä¿¡ã管ç-ã¿ãŒã²ãã亀æãããã³ã«ãå®è£ ããŸãã
- ããã€ã¹ãéããŸãã
ããŒãããŒããŒãæžã
å®çšçãªéšåã«åãããããŸãããã ç§ã®å®éšã§ã¯ãOxygen.3aãªãªãŒã¹ã®EclipseããŒãžã§ã³ïŒ4.7.3aïŒãIDEãšããŠãmingw32-gccïŒ6.3.0ïŒãã³ã³ãã€ã©ãšããŠäœ¿çšããŸãã Win7ãªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã
FTDI Webãµã€ãããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã çšã®ææ°ããŒãžã§ã³ã®ãã©ã€ããŒãããŠã³ããŒãããŸãã ã¢ãŒã«ã€ãã«ã¯ããã¹ãŠã®APIé¢æ°ã®èª¬æãå«ãããããŒãã¡ã€ã«ftd2xx.hããããŸãã APIèªäœã¯ftd2xx.dllãšããŠå®è£ ãããŠããŸãããåçã€ã³ããŒãã¯åŸã§æ®ããéçãªã³ã¯ã䜿çšããŸããã©ã€ãã©ãªãã¡ã€ã«ftd2xx.libãå¿ èŠã§ãã ç§ã®å Žåãftd2xx.libã¯i386ãã£ã¬ã¯ããªã«ãããŸãã
Eclipseã§ãæ°ããCãããžã§ã¯ããäœæããŸãã ã¡ã€ã¯ãã¡ã€ã«ã®äœæã¯ãIDEã§ä¿¡é Œã§ããŸãã ãªã³ã«èšå®ã§ãftd2xxã©ã€ãã©ãªã®ãã¹ãšååãæå®ããŸãïŒå¿ èŠãªãã¡ã€ã«ãftdiãã©ã«ãã®ãããžã§ã¯ããã£ã¬ã¯ããªã«è»¢éããŸããïŒã Eclipseã®ãããžã§ã¯ããã»ããã¢ããããæ©èœã«ã¯çŠç¹ãåœãŠãŸãããã»ãšãã©ã®å ŽåãWinã§ã®ããã°ã©ãã³ã°ã«ä»ã®ç°å¢ãšã³ã³ãã€ã©ãŒã䜿çšããŠãããšæãããããã§ãã
ãã€ã³ã1ã ããã€ã¹ãèŠã€ããŠéã
FTD2XX APIã䜿çšãããšããããã«é¢ããæ¢ç¥ã®æ
å ±ã䜿çšããŠããããéãããšãã§ããŸãã ããã¯ãã·ã¹ãã å
ã®ã·ãªã¢ã«çªå·ã§ããå¯èœæ§ããããŸããæåã«æ¥ç¶ãããFTDIãããã¯ãçªå·0ã次ã®1ãªã©ãååŸããŸãã ã·ã¹ãã å
ã®çªå·ã¯ããã€ã¯ããµãŒããããæ¥ç¶ããé åºã«ãã£ãŠæ±ºå®ãããŸãããããæ§ããã«èšããšãããã¯å¿
ããã䟿å©ã§ã¯ãããŸããã ããããçªå·ã§éãã«ã¯ã FT_Open
é¢æ°ãFT_Open
ãŸãã ã·ãªã¢ã«çªå·ïŒ FT_OPEN_BY_SERIAL_NUMBER
ïŒã説æïŒ FT_OPEN_BY_DESCRIPTION
ïŒããŸãã¯å ŽæïŒ FT_OPEN_BY_LOCATION
ïŒã§ããããéãããšãã§ããŸããããã«ã¯ã FT_OpenEx
é¢æ°ãFT_OpenEx
ãŸãã ã·ãªã¢ã«çªå·ãšèª¬æã¯ãããã®å
éšã¡ã¢ãªã«ä¿åãããFTDIãã€ã³ã¹ããŒã«ãããããã€ã¹ã®è£œé äžã«ããã«èšé²ã§ããŸãã 説æã¯ãååãšããŠãããã€ã¹ãŸãã¯ãã¡ããªã®ã¿ã€ããç¹åŸŽä»ãããã®ã§ãããã·ãªã¢ã«çªå·ã¯è£œåããšã«äžæã§ãªããã°ãªããŸããã ãããã£ãŠãéçºäžã®ããã°ã©ã ã§ãµããŒããããŠããããã€ã¹ãèå¥ããæã䟿å©ãªæ¹æ³ã¯ããã®èª¬æã§ãã 説æïŒèšè¿°åïŒã«åŸã£ãŠFTDIããããéããŸãã å®éãæåã«ãããèšè¿°åæååãç¥ã£ãŠããã°ãã·ã¹ãã å
ã®ããã€ã¹ãæ¢ãå¿
èŠã¯ãããŸããããå®éšãšããŠãFTDIã䜿çšããŠã³ã³ãã¥ãŒã¿ãŒã«æ¥ç¶ãããŠãããã¹ãŠã®ããã€ã¹ã衚瀺ããŸãã FT_CreateDeviceInfoList
é¢æ°ã䜿çšããŠãæ¥ç¶ããããããã®è©³çŽ°ãªãªã¹ããäœæãã FT_GetDeviceInfoList
é¢æ°ã䜿çšããŠã FT_GetDeviceInfoList
æ€èšããŸãã
ftStatus = FT_CreateDeviceInfoList(&numDevs); if (ftStatus == FT_OK) { printf("Number of devices is %d\n",numDevs); } if (numDevs == 0) return -1; // allocate storage for list based on numDevs devInfo = (FT_DEVICE_LIST_INFO_NODE*)malloc(sizeof(FT_DEVICE_LIST_INFO_NODE)*numDevs); ftStatus = FT_GetDeviceInfoList(devInfo,&numDevs); if (ftStatus == FT_OK) for (int i = 0; i < numDevs; i++) { printf("Dev %d:\n",i); printf(" Flags=0x%x\n",devInfo[i].Flags); printf(" Type=0x%x\n",devInfo[i].Type); printf(" ID=0x%x\n",devInfo[i].ID); printf(" LocId=0x%x\n",devInfo[i].LocId); printf(" SerialNumber=%s\n",devInfo[i].SerialNumber); printf(" Description=%s\n",devInfo[i].Description); }
D:\workspace\ftdi-mpsse-ps\Debug>ftdi-mpsse-ps.exe Number of devices is 4 Dev 0: Flags = 0x0 Type = 0x5 ID = 0x4036001 LocId = 0x214 SerialNumber = AI043NNV Description = FT232R USB UART Dev 1: Flags = 0x2 Type = 0x6 ID = 0x4036010 LocId = 0x2121 SerialNumber = L731T70OA Description = LESO7 A Dev 2: Flags = 0x2 Type = 0x6 ID = 0x4036010 LocId = 0x2122 SerialNumber = L731T70OB Description = LESO7 B Dev 3: Flags = 0x2 Type = 0x8 ID = 0x4036014 LocId = 0x213 SerialNumber = FTYZ92L6 Description = LESO4.1_ER
FTDIããããæèŒãã3ã€ã®ããã€ã¹ãPCã«æ¥ç¶ãããŠããŸãïŒFT232RLïŒã¿ã€ã0x5ïŒãFT2232HïŒã¿ã€ã0x6ïŒãããã³FT232HïŒtepe 0x8ïŒã ã·ã¹ãã ã®FT2232Hãããã¯ã2ã€ã®ç¬ç«ããããã€ã¹ïŒDev 1ããã³Dev 2ïŒãšããŠè¡šç€ºãããŸããã FPGA PSã€ã³ã¿ãŒãã§ã€ã¹ã¯Dev 2ã«æ¥ç¶ããããã®èšè¿°åã¯ãLESO7 Bãã§ãã ãããéããŸãïŒ
//Open a device with device description "LESO7 B" ftStatus = FT_OpenEx("LESO7 B", FT_OPEN_BY_DESCRIPTION, &ftHandle); if (ftStatus != FT_OK) { printf ("pen failure\r\n"); return -1; }
ã»ãšãã©ã®APIé¢æ°ã¯ãã¿ã€ãFT_STATUS
åŒã³åºãã®ã¹ããŒã¿ã¹ãè¿ããŸãããã¹ãŠã®å¯èœãªå€ã¯ãããããŒãã¡ã€ã«ã«åæãšããŠèšè¿°ãããŠããŸãã ãããã®å€ãããããŸããã FT_OK
å€ã«ãšã©ãŒããªãããšãä»ã®ãã¹ãŠã®å€ã¯ãšã©ãŒã³ãŒãã§ããããšãç¥ãã ãã§ååã§ãã é©åãªããã°ã©ãã³ã°ã¹ã¿ã€ã«ã¯ãAPIé¢æ°ãåŒã³åºããã³ã«ã¹ããŒã¿ã¹å€ã確èªããããšã§ãã
ããã€ã¹ãæ£åžžã«éãããå Žåã ftHandle
å€æ°ã«ã¯ããŒã以å€ã®å€ããã¡ã€ã«ãæäœãããšãã«äœ¿çšãããåçã®ãã¡ã€ã«èšè¿°åã衚瀺ãããŸãã çµæã®ãã³ãã«ã¯ãããŒããŠã§ã¢ã€ã³ã¿ãŒãã§ã€ã¹ãšã®æ¥ç¶ã確ç«ããããããžã®ã¢ã¯ã»ã¹ãå¿
èŠãšãããã¹ãŠã®ã©ã€ãã©ãªé¢æ°ãåŒã³åºããšãã«äœ¿çšããå¿
èŠããããŸãã
çŸåšã®æ®µéã§ã·ã¹ãã ã®æäœæ§ãå®éã«ç¢ºèªããã«ã¯ãã¢ã«ãŽãªãºã ã®ã¹ããã5ã«ããã«é²ãå¿
èŠããããŸãã
ãããã§ã®äœæ¥ãçµäºãããããããéããå¿
èŠããããŸãã ãããè¡ãã«ã¯ã FT_Close
é¢æ°ã䜿çšããŸãã
FT_Close(ftHandle);
ãã€ã³ã2.ããããåæåããMPSSEããªã³ã«ããŸã
ãã®èšå®ã¯ã»ãšãã©ã®ã¢ãŒãã§äžè¬çã§ããã AN_135 FTDI MPSSE Basicsã®ããã¥ã¡ã³ãã§è©³ãã説æãããŠããŸãã
- ãããã®ãªã»ããïŒrezetïŒãå®è¡ããŸãã
FT_ResetDevice
é¢æ°ã - åä¿¡ãããã¡ã«ãŽããããå Žåã¯ãã¯ãªã¢ããŸãã
FT_Purge
é¢æ°ã - èªã¿åãããã³æžã蟌ã¿çšã®ãããã¡ãŒã®ãµã€ãºã調æŽããŸãã é¢æ°
FT_SetUSBParameters
ã - ããªãã£ããªãã«ããŸãã
FT_SetChars
ã - èªã¿åããšæžã蟌ã¿ã®ã¿ã€ã ã¢ãŠããèšå®ããŸãã ããã©ã«ãã§ã¯ãã¿ã€ã ã¢ãŠãã¯ç¡å¹ã«ãªã£ãŠãããéä¿¡ã¿ã€ã ã¢ãŠããæå¹ã«ãªã£ãŠããŸãã
FT_SetTimeouts
ã - ããããããã¹ãã«ãã±ãããéä¿¡ããããã®åŸ
ã¡æéãèšå®ããŸãã ããã©ã«ãã§ã¯ã16 msã1 msã«å éããŸãã
FT_SetLatencyTimer
ã - ãããŒå¶åŸ¡ããªã³ã«ããŠãçä¿¡èŠæ±ãåæããŸãã
FT_SetFlowControl
ã - ãã¹ãŠãMPSSEã¢ãŒããã¢ã¯ãã£ãã«ããæºåãã§ããŠããŸãã MPSSEã³ã³ãããŒã©ãŒããªã»ããããŸãã
FT_SetBitMode
é¢æ°ã䜿çšããŠãã¢ãŒãã0ã«èšå®ããŸãïŒã¢ãŒã= 0ããã¹ã¯= 0ïŒã - MPSSEã¢ãŒãããªã³ã«ããŸãã é¢æ°
FT_SetBitMode
ã¢ãŒã= 2ããã¹ã¯= 0ã
MPSSE_open
é¢æ°ã§ããããçµåããŠæ§æããŸãããã©ã¡ãŒã¿ãŒãšããŠãéãããã€ã¹ã®ãã³ãã«ãå«ãè¡ãæž¡ããŸãã
static FT_STATUS MPSSE_open (char *description) { FT_STATUS ftStatus; ftStatus = FT_OpenEx(description, FT_OPEN_BY_DESCRIPTION, &ftHandle); if (ftStatus != FT_OK) { printf ("open failure\r\n"); return FT_DEVICE_NOT_OPENED; } printf ("open OK, %d\r\n", ftHandle); printf("\nConfiguring port for MPSSE use...\n"); ftStatus |= FT_ResetDevice(ftHandle); //Purge USB receive buffer first by reading out all old data from FT2232H receive buff: ftStatus |= FT_Purge(ftHandle, FT_PURGE_RX); //Set USB request transfer sizes to 64K: ftStatus |= FT_SetUSBParameters(ftHandle, 65536, 65536); //Disable event and error characters: ftStatus |= FT_SetChars(ftHandle, 0, 0, 0, 0); //Sets the read and write timeouts in milliseconds: ftStatus |= FT_SetTimeouts(ftHandle, 0, 5000); //Set the latency timer to 1mS (default is 16mS): ftStatus |= FT_SetLatencyTimer(ftHandle, 1); //Turn on flow control to synchronize IN requests: ftStatus |= FT_SetFlowControl(ftHandle, FT_FLOW_RTS_CTS, 0x00, 0x00); //Reset controller: ftStatus |= FT_SetBitMode(ftHandle, 0x0, FT_BITMODE_RESET); //Enable MPSSE mode: ftStatus |= FT_SetBitMode(ftHandle, 0x0, FT_BITMODE_MPSSE); if (ftStatus != FT_OK) { printf("Error in initializing the MPSSE %d\n", ftStatus); return FT_OTHER_ERROR; } Sleep(50); // Wait for all the USB stuff to complete and work return FT_OK; }
é ç®3. MPSEEæäœã¢ãŒããæ§æãã
å®éããã®æ®µéã§ãMPSSEããã»ããµãã¢ã¯ãã£ãã«ãªããã³ãã³ããåä¿¡ããæºåãæŽããŸãã ã³ãã³ãã¯ãã€ãã·ãŒã±ã³ã¹ã§ããããã®æåã®ãã€ãã¯ãop-codeãã§ããã®åŸã«ã³ãã³ããã©ã¡ãŒã¿ãŒãç¶ããŸãã ã³ãã³ãã«ã¯ãã©ã¡ãŒã¿ãŒããªãã1ã€ã®ãop-codeãã§æ§æãããŠããå ŽåããããŸãã ã³ãã³ãã¯FT_Write
é¢æ°ã䜿çšããŠéä¿¡ãããMPSSEããã»ããµããã®å¿çã¯FT_Read
é¢æ°ã䜿çšããŠååŸã§ããŸãã
ã³ãã³ããéä¿¡ãããã³ã«ãããã»ããµã®å¿çãèªã¿åããšäŸ¿å©ã§ããäžæ£ãªã³ãã³ãã®å Žåãå¿çã«ã¯ãšã©ãŒã¡ãã»ãŒãžïŒæå0xFAïŒãå«ãŸããå¯èœæ§ãããããã§ãã ãäžè¯ã³ãã³ã-0xFAå¿çãã¡ã«ããºã ã䜿çšããŠãã¢ããªã±ãŒã·ã§ã³ããã°ã©ã ãMPSSEããã»ããµãšåæã§ããŸãã ãã¹ãŠãæ£åžžã§ããã°ããããã¯æå³çã«èª€ã£ãã³ãã³ãã§0xFAæåãè¿ããŸãã ãªãã³ãŒãã«ã€ããŠã¯ãMPSSEããã³MCUãã¹ããã¹ãšãã¥ã¬ãŒã·ã§ã³ã¢ãŒãã®ã³ãã³ãããã»ããµã§èª¬æããŠããŸã ã
MPSSEã®æ§æã¯ãI / Oã©ã€ã³ã®ããŒã¿ã¬ãŒããæ¹åãããã³åæç¶æ
ã®èšå®ã«åž°çããŸãã
MPSSEããã»ããµã®ããŒã¿ã¬ãŒãã®èšå®ãæ€èšããŠãã ããã ãã«ã¹ããŒãã¢ãŒãïŒFT2232 D ïŒã®ã¿ããµããŒãããããããšãã€ã¹ããŒãïŒFT2232 H ãFT232HãFT4232HïŒããµããŒããããããã®èšå®ã¯å€å°ç°ãªããŸãã å»æ¢ãããFT2232Dã¯12 MHzã¯ããã¯ã䜿çšããŸãããææ°ã®ãã®ã¯60 MHzã䜿çšããŸãã ãããã£ãŠãããŒã¿è»¢éé床ãèšç®ããããã®åŒïŒ
ããã§ã f coreã¯FTDI ã³ã¢ã®åšæ³¢æ°ã Divisorã¯2ãã€ãã®ååšåšã§ãããå®éã«ã¯ããŒã¿ã¯ããã¯åšæ³¢æ°ãèšå®ããŸãã
ãã®çµæãååšåšããŒãã«çããå Žåãæ倧ããŒã¿è»¢éé床ã¯30 Mbpsã«ãªããæå°ããŒã¿è»¢éé床ã¯ååšåš65535-458ããã/ç§ã«ãªããŸãã
é€ç®åšã®èšç®ã¯ããªããã»ããµã«ä»»ããŸãã ãã¯ãã¯é€æ°ãè¿ããŸãã
#define FCORE 60000000ul #define MPSSE_DATA_SPEED_DIV(data_speed) ((FCORE/(2*data_speed)) -1)
ãããŠããããã®2ã€ã®ãã¯ãã¯ããããããã£ãã€ããŒã®äžäœãã€ããšäžäœãã€ããè¿ããŸãã
#define MPSSE_DATA_SPEED_DIV_H(data_speed) ((MPSSE_DATA_SPEED_DIV(data_speed)) >> 8) #define MPSSE_DATA_SPEED_DIV_L(data_speed) \ (MPSSE_DATA_SPEED_DIV(data_speed) - (MPSSE_DATA_SPEED_DIV_H(data_speed)<< 8))
ããã«ãå€ãFT2232Dãšã®äºææ§ã®ããã®ææ°ã®ãããã«ã¯ã60 MHzã12 MHzã«å€æãã5ååšåšãè¿œå ãããŠããããšã«æ³šæããŠãã ããã ãã®ãã£ãã€ããŒã¯ããã©ã«ãã§ã¢ã¯ãã£ãã«ãªã£ãŠããŸãããã®å Žåããªãã«ããå¿
èŠããããŸãã
察å¿ããop-codeïŒ0x8AïŒãšããã»ããµãžã®ãã«ã¡ããã³ãã³ããèŠã€ããŸãã
BYTE byOutputBuffer[8], byInputBuffer[8]; DWORD dwNumBytesToRead, dwNumBytesSent = 0, dwNumBytesRead = 0; byOutputBuffer[0] = 0x8A; ftStatus = FT_Write(ftHandle, byOutputBuffer, 1, &dwNumBytesSent); Sleep(2); // Wait for data to be transmitted and status ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead); ftStatus |= FT_Read(ftHandle, byInputBuffer, dwNumBytesToRead, &dwNumBytesRead); if (ftStatus != FT_OK) { printf("Error\r\n"); return FT_OTHER_ERROR; } else if (dwNumBytesToRead > 0) { printf("dwNumBytesToRead = %d:", dwNumBytesToRead); for ( int i = 0; i < dwNumBytesToRead; i++) printf (" %02Xh", byInputBuffer[i]); printf("\r\n"); return FT_INVALID_PARAMETER; } return FT_OK;
å®éšãšããŠãæå¹ãª0x8Aã³ãã³ãã®ä»£ããã«ãå€0xFEãéä¿¡ããŸããããã¯ãã©ã®opã³ãŒãã«ã察å¿ãããã³ã³ãœãŒã«åºåã§ãã
dwNumBytesToRead = 2: FAh FEh
ããã»ããµã¯2ãã€ããè¿ããŸãããäžè¯ã³ãã³ããã€ãã¯0xFAã§ããããã®äžè¯ã³ãã³ãã®å€ã§ãã ãããã£ãŠãè€æ°ã®ã³ãã³ããäžåºŠã«éä¿¡ããããšã§ããšã©ãŒèªäœã远跡ã§ããã ãã§ãªãããã®ãšã©ãŒãçºçããããŒã ãææ¡ããããšãã§ããŸãã
å°æ¥ãããžãã¯ãã³ããŒããåŠçããªãããã«ããã¹ãŠã®ãªãã³ãŒããå®æ°ã®åœ¢åŒã§ãã©ãŒãããããå¥ã®ããããŒãã¡ã€ã«ã«é
眮ããŸãã
ã¢ãŒããå®å
šã«æ§æããã«ã¯ãI / Oã©ã€ã³ã®æ¹åãšãã®ããã©ã«ãå€ãæå®ããå¿
èŠããããŸãã æ¥ç¶å³ã«ç§»ããŸãããã ãã§ã«è¥å€§åããèšäºãç
©éã«ããªãããã«ãã¹ããŒã ã®èå³æ·±ãæçãæããŠããŸãã

DCLK ã DATA [0] ã nCONFIGã©ã€ã³ã¯åºåãšããŠã nSTATUS ã CONF_DONEã©ã€ã³ã¯å ¥åãšããŠèšå®ããå¿ èŠããããŸãã ãã€ã¢ã°ã©ã ã䜿çšããŠãã©ã€ã³ã®åæç¶æ ã決å®ããŸãã ããããããããããã«ãåè·¯ã®ãã³é åãè¡šã«ãŸãšããŠããŸãã
FPGAãã³ | ãã³å | ãã³ | MPSSE | æ¹å | ããã©ã«ã |
---|---|---|---|---|---|
DCLK | BDBUS0 | 38 | TCK / SK | ã¢ãŠã | 0 |
ããŒã¿[0] | BDBUS1 | 39 | TDI / DO | ã¢ãŠã | 1 |
nCONFIG | BDBUS2 | 40 | TDO / DI | ã¢ãŠã | 1 |
nSTATUS | BDBUS3 | 41 | TMS / CS | 㧠| 1 |
CONF_DONE | BDBUS4 | 43 | GPIOL0 | 㧠| 1 |
䜿çšããããã¹ãŠã®è¡ã¯ãMPSSEããŒãã®äžäœãã€ãã«ãããŸãã å€ãèšå®ããã«ã¯ãop-code 0x80ã䜿çšããŸãã ãã®ã³ãã³ãã¯2ã€ã®åŒæ°ãæ³å®ããŠããŸãããªãã³ãŒãã«ç¶ãæåã®ãã€ãã¯ãããåäœã®å€ã§ããã2çªç®ã¯æ¹åã§ãïŒ1ã€ã¯åºåããŒãã0ã¯å
¥åããŒãïŒã
ãããžãã¯ãã³ããŒããšã®æŠãã®äžç°ãšããŠããã¹ãŠã®ã©ã€ã³ã·ãªã¢ã«çªå·ãšãã®ããã©ã«ãå€ãå®æ°ãšããŠæŽçããŸãã
#define PORT_DIRECTION (0x07) #define DCLK (0) #define DATA0 (1) #define N_CONFIG (2) #define N_STATUS (3) #define CONF_DONE (4) // initial states of the MPSSE interface #define DCLK_DEF (1) #define DATA0_DEF (0) #define N_CONFIG_DEF (1) #define N_STATUS_DEF (1) #define CONF_DONE_DEF (1)
TDI-TDOã«ãŒããç¡å¹ã«ãªã£ãŠããïŒãã¹ãçšã«ã¢ã¯ãã£ãåã§ããïŒããšã確èªããå¥ã®é¢æ°ã«é 眮ããããã ãã«æ®ããŸãã
static FT_STATUS MPSSE_setup () { DWORD dwNumBytesToSend, dwNumBytesSent, dwNumBytesToRead, dwNumBytesRead; BYTE byOutputBuffer[8], byInputBuffer[8]; FT_STATUS ftStatus; // Multple commands can be sent to the MPSSE with one FT_Write dwNumBytesToSend = 0; // Start with a fresh index byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_DISABLE_DIVIDER_5; byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_DISABLE_ADAPTIVE_CLK; byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_DISABLE_3PHASE_CLOCKING; ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); dwNumBytesToSend = 0; // Reset output buffer pointer // Set TCK frequency // Command to set clock divisor: byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_SET_TCK_DIVISION; // Set ValueL of clock divisor: byOutputBuffer[dwNumBytesToSend++] = MPSSE_DATA_SPEED_DIV_L(DATA_SPEED); // Set 0xValueH of clock divisor: byOutputBuffer[dwNumBytesToSend++] = MPSSE_DATA_SPEED_DIV_H(DATA_SPEED); ftStatus |= FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); dwNumBytesToSend = 0; // Reset output buffer pointer // Set initial states of the MPSSE interface // - low byte, both pin directions and output values /* | FPGA pin | Pin Name | Pin | MPSSE | Dir | def | | --------- | -------- | --- | ------ | --- | --- | | DCLK | BDBUS0 | 38 | TCK/SK | Out | 0 | | DATA[0] | BDBUS1 | 39 | TDI/DO | Out | 1 | | nCONFIG | BDBUS2 | 40 | TDO/DI | Out | 1 | | nSTATUS | BDBUS3 | 41 | TMS/CS | In | 1 | | CONF_DONE | BDBUS4 | 43 | GPIOL0 | In | 1 | */ // Configure data bits low-byte of MPSSE port: byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_SET_DATA_BITS_LOWBYTE; // Initial state config above: byOutputBuffer[dwNumBytesToSend++] = (DCLK_DEF << DCLK) | (DATA0_DEF << DATA0) | (N_CONFIG_DEF << N_CONFIG) | (N_STATUS_DEF << N_STATUS) | (CONF_DONE_DEF << CONF_DONE); // Direction config above: byOutputBuffer[dwNumBytesToSend++] = PORT_DIRECTION; ftStatus |= FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); // Send off the low GPIO config commands dwNumBytesToSend = 0; // Reset output buffer pointer // Set initial states of the MPSSE interface // - high byte, all input, Initial State -- 0. // Send off the high GPIO config commands: byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_SET_DATA_BITS_HIGHBYTE; byOutputBuffer[dwNumBytesToSend++] = 0x00; byOutputBuffer[dwNumBytesToSend++] = 0x00; ftStatus |= FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); // Disable loopback: byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_DISABLE_LOOP_TDI_TDO; ftStatus |= FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); Sleep(2); // Wait for data to be transmitted and status ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead); ftStatus |= FT_Read(ftHandle, byInputBuffer, dwNumBytesToRead, &dwNumBytesRead); if (ftStatus != FT_OK) { printf("Unknown error in initializing the MPSSE\r\n"); return FT_OTHER_ERROR; } else if (dwNumBytesToRead > 0) { printf("Error in initializing the MPSSE, bad code:\r\n"); for ( int i = 0; i < dwNumBytesToRead; i++) printf (" %02Xh", byInputBuffer[i]); printf("\r\n"); return FT_INVALID_PARAMETER; } return FT_OK; }
ãã€ã³ã4.ããŒããããã³ã«ãå®è£ ãã
ãã¹ãŠãå®éã®å®éšã®æºåãã§ããŠããããã§ãã æåã«ãåæåãæ£ããå®è¡ãããŠããããšã確èªããããã°ã©ã ã®æ¬äœã§MPSSE_open()
ããã³MPSSE_setup()
åŒã³åºããããã€ã¹ãéããåã«ïŒ FT_Close
ïŒã空ã®getchar()
ãŸãã ããã°ã©ã ãå®è¡ãããªã·ãã¹ã³ãŒãã䜿çšããŠãPSã®ãã¹ãŠã®ã¬ãã«ãããã©ã«ãã¬ãã«ã«èšå®ãããŠããããšã確èªããŸãã åæåã§ãããã®ã¬ãã«ã®å€ãå€æŽãããšïŒFPGAã§åé¡ãçºçããããšã¯ãããŸããïŒãMPSSEããã»ããµãŒãç®çã®çµæãæå¹ãªãã®ãšããŠæäŸããŸãããã¹ãŠãé©åã«æ©èœããããŒã¿ã®è»¢éã«é²ãããšãã§ããŸãã
ããŒã¿ã®é 次éåä¿¡ã¯ãåããªãã³ãŒãã䜿çšããŠã³ãã³ãã¢ãŒãã§å®è¡ãããŸãã ã³ãã³ãã®æåã®ãã€ãã¯ãªãã³ãŒãã§ãããæäœã®ã¿ã€ãã決å®ãããã®åŸã«éä¿¡ãŸãã¯åä¿¡ãããã·ãŒã±ã³ã¹ã®é·ããããã³éä¿¡ã®å Žåã¯å®éã®ããŒã¿ãç¶ããŸãã MPSSEããã»ããµã¯ãããŒã¿ãéåä¿¡ã§ããåæã«ããŒã¿ãéåä¿¡ã§ããŸãã éä¿¡ã¯ãæäžäœããã転éïŒLSBïŒãŸãã¯æäžäœãããïŒMSBïŒã®ããããã§ãã ããŒã¿éä¿¡ã¯ãã¯ããã¯ãã«ã¹ã®ç«ã¡äžãããšããžãŸãã¯ç«ã¡äžãããšããžã§çºçããŸãã ãªãã·ã§ã³ã®åçµã¿åããã«ã¯ç¬èªã®op-codeããããåop-codeãããã¯æäœã¢ãŒããèšè¿°ããŸãã
ããã | æ©èœ |
---|---|
0 | ããã³ãã©ã€ãåæïŒ0-æ£ã1-è² |
1 | 1-ãã€ãã§åäœã0-ãããã§åäœ |
2 | èªã¿åãã®ããã³ããšããžïŒ0-æ£ã1-è² |
3 | äŒéã¢ãŒãïŒ1-LSBã0-MSBãã¡ãŒã¹ã |
4 | TDIããŒã¿éä¿¡ |
5 | TDOã©ã€ã³ããã®ããŒã¿ã®èªã¿åã |
6 | TMSããŒã¿éä¿¡ |
7 | 0ã§ãªããã°ãªããŸãããããã§ãªããã°ãããã¯ã³ãã³ãã®ç°ãªãã°ã«ãŒãã§ã |
PSã¹ããŒã ã«åŸã£ãŠFPGAãæ§æãããšãããŒã¿ã¯LSBã¢ãŒãã®ãªãŒãã£ã³ã°ãšããžã§éä¿¡ãããŸãã , , op-code 0001_1000b 0x18 . ( , ), . : . , , 0, 65536, 65535. , . MPSSE_send
.
static BYTE byBuffer[65536 + 3]; static FT_STATUS MPSSE_send(BYTE * buff, DWORD dwBytesToWrite) { DWORD dwNumBytesToSend = 0, dwNumBytesSent, bytes; FT_STATUS ftStatus; // Output on rising clock, no input // MSB first, clock a number of bytes out byBuffer[dwNumBytesToSend++] = MPSSE_CMD_LSB_DATA_OUT_BYTES_POS_EDGE; // 0x18 bytes = dwBytesToWrite -1; byBuffer[dwNumBytesToSend++] = (bytes) & 0xFF; // Length L byBuffer[dwNumBytesToSend++] = (bytes >> 8) & 0xFF; // Length H memcpy(&byBuffer[dwNumBytesToSend], buff, dwBytesToWrite); dwNumBytesToSend += dwBytesToWrite; ftStatus = FT_Write(ftHandle, byBuffer, dwNumBytesToSend, &dwNumBytesSent); if (ftStatus != FT_OK ) { printf ("ERROR send data\r\n"); return ftStatus; } else if (dwNumBytesSent != dwNumBytesToSend) { printf ("ERROR send data, %d %d\r\n", dwNumBytesSent, dwNumBytesToSend); } return FT_OK; }
â 65 , - , op-code . byBuffer
, buff
, , op-code . , , .
, "" , 25 , , , 1 ( , #define DATA_SPEED 1000000ul
). :
BYTE byOutputBuffer[] = {0x02, 0x1B, 0xEE, 0x01, 0xFA}; MPSSE_send(byOutputBuffer, sizeof(byOutputBuffer));
â DATA[0] , â DCLK . . , , .
, SPI ( ). , PS, . nCONFIG , nSTATUS , CONF_DONE . â , , â , .
MPSSE_get_lbyte
, , .
static FT_STATUS MPSSE_get_lbyte(BYTE *lbyte) { DWORD dwNumBytesToSend, dwNumBytesSent, dwNumBytesToRead, dwNumBytesRead; BYTE byOutputBuffer[8]; FT_STATUS ftStatus; dwNumBytesToSend = 0; byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_GET_DATA_BITS_LOWBYTE; ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); Sleep(2); // Wait for data to be transmitted and status ftStatus = FT_GetQueueStatus(ftHandle, &dwNumBytesToRead); ftStatus |= FT_Read(ftHandle, lbyte, dwNumBytesToRead, &dwNumBytesRead); if ((ftStatus != FT_OK) & (dwNumBytesToRead != 1)) { printf("Error read Lbyte\r\n"); return FT_OTHER_ERROR; // Exit with error } return FT_OK; }
, op-code , . , - , , . , . MPSSE_set_lbyte
:
static FT_STATUS MPSSE_set_lbyte(BYTE lb, BYTE mask) { DWORD dwNumBytesToSend, dwNumBytesSent; BYTE byOutputBuffer[8], lbyte; FT_STATUS ftStatus; ftStatus = MPSSE_get_lbyte(&lbyte); if ( ftStatus != FT_OK) return ftStatus; // Set to zero the bits selected by the mask: lbyte &= ~mask; // Setting zero is not selected by the mask bits: lb &= mask; lbyte |= lb; dwNumBytesToSend = 0; // Set data bits low-byte of MPSSE port: byOutputBuffer[dwNumBytesToSend++] = MPSSE_CMD_SET_DATA_BITS_LOWBYTE; byOutputBuffer[dwNumBytesToSend++] = lbyte; byOutputBuffer[dwNumBytesToSend++] = PORT_DIRECTION; ftStatus = FT_Write(ftHandle, byOutputBuffer, dwNumBytesToSend, &dwNumBytesSent); if ((ftStatus != FT_OK) & (dwNumBytesSent != 1)) { printf("Error set Lbyte\r\n"); return FT_OTHER_ERROR; } return FT_OK; }
, . : FTDI; MPSSE; rbf- , nCONFIG , N_STATUS ; rbf- ; , , CONF_DONE . , MPSSE FTDI . , nCONFIG "" , , , .
int main(int argc, char *argv[]) { FT_STATUS ftStatus; BYTE lowByte; DWORD numDevs; // create the device information list if ( argv[1] == NULL) { printf ("NO file\r\n"); return -1; } frbf = fopen(argv[1],"rb"); if (frbf == NULL) { printf ("Error open rbf\r\n"); return -1; } ftStatus = FT_CreateDeviceInfoList(&numDevs); if ((numDevs == 0) || (ftStatus != FT_OK)) { printf("Error. FTDI devices not found in the system\r\n"); return -1; } ftStatus = MPSSE_open ("LESO7 B"); if (ftStatus != FT_OK) { printf("Error in MPSSE_open %d\n", ftStatus); EXIT(-1); } MPSSE_setup(); if (ftStatus != FT_OK) { printf("Error in MPSSE_setup %d\n", ftStatus); EXIT(-1); } printf ("nConfig -> 0\r\n"); MPSSE_set_lbyte(0, 1 << N_CONFIG); printf ("nConfig -> 1\r\n"); MPSSE_set_lbyte(1 << N_CONFIG, 1 << N_CONFIG); if (MPSSE_get_lbyte(&lowByte) != FT_OK) { EXIT(-1); } if (((lowByte >> N_STATUS) & 1) == 0) { printf("Error. FPGA is not responding\r\n"); EXIT(-1); } int i = 0; size_t readBytes = 0; // Send the configuration file: do { readBytes = fread(buff, 1, MPSSE_PCK_SEND_SIZE, frbf); if (MPSSE_send(buff, readBytes) != FT_OK) EXIT(-1); putchar('*'); if (!((++i)%16)) printf("\r\n"); } while (readBytes == MPSSE_PCK_SEND_SIZE); printf("\r\n"); memset(buff, 0x00, sizeof(buff)); MPSSE_send(buff, 1); // ? printf("Load complete\r\n"); // wait CONF_DONE set // A low-to-high transition on the CONF_DONE pin indicates that the configuration is // complete and initialization of the device can begin. i = 0; do { if (MPSSE_get_lbyte(&lowByte) != FT_OK) { printf ("Error read CONF_DONE\r\n"); EXIT(-1); } if (i++ > TIMEOUT_CONF_DONE) { printf ("Error CONF_DONE\r\n"); EXIT(-1); } Sleep(2); } while (((lowByte >> CONF_DONE) & 1) == 0); printf("Configuration complete\r\n"); FT_Close(ftHandle); fclose(frbf); }
ããã°ã©ã ãéå§ããäŸïŒ
pen "LESO7 B" OK nConfig -> 0 nConfig -> 1 ** Load complete Configuration complete
rbf- . . 30 / .
, - JTAG.
é¢é£è³æ
- FTDI-MPSSE-Altera PS . .
- . . .
- Software Application Development D2XX Programmer's Guide . FTDI. API D2XX.
- FTDI MPSSE Basics. Application Note AN_135 . . FTDI MPSSE. .
- MPSSEããã³MCUãã¹ããã¹ãšãã¥ã¬ãŒã·ã§ã³ã¢ãŒãçšã®ã³ãã³ãããã»ããµã泚AN_108ã¢ããªã±ãŒã·ã§ã³ããªãã³ãŒãã®ãªãã¡ã¬ã³ã¹ããããªãã§ã¯ä»æ¹ãããŸããã
- D2XXãã©ã€ããŒãFTDIãã©ã€ããŒã