äžè¬çã«ãScord Cortex-M3ã¯ãŸã£ããããã§ã¯ãããŸããããä»æ¥ãCortex-M4F-ææã®ããã»ããµã³ã¢ã®æ¡åŒµããŒãžã§ã³ã詳现ã«æ€èšããããšãææ¡ããŸãã Cortex-M3ã«åºã¥ãããã€ã¯ãã³ã³ãããŒã©ãŒããCortex-M4Fã«åºã¥ããã¯ãªã¹ã¿ã«ã«ãããžã§ã¯ãã転éããã®ã¯éåžžã«ç°¡åã§ãããå€ãã®ã¿ã¹ã¯ã«ãšã£ãŠãã®ç§»è¡ã¯åªåãã䟡å€ããããŸãã
ã«ãã¿ãŒã®äžã«ã¯ãææ°ã®Cortexã®ç°¡åãªæŠèŠãCortex-M4FãšCortex-M3ãåºå¥ãããããã¯ãšã³ãã³ãã®è©³çŽ°ãªèª¬æãããã³å®éã®ã¿ã¹ã¯ã§ã®ããã»ããµã³ã¢ã®æ¯èŒããããŸããç°ãªãã³ã¢ãæã€ãã€ã¯ãã³ã³ãããŒã©ã®ã©ã³ãããªãã«ãŒåšæ³¢æ°ã枬å®ããŸãã
ã¬ãã¥ãŒéš
é£ç¶ããäžä»£ã®ARMããã»ããµã³ã¢ãäºãã«ã©ã®ããã«æåãããã«ã€ããŠãèšå€§ãªæ°ã®èšäºãšã¬ãã¥ãŒãæžãããŠããŸãã ãŠã£ãããã£ã¢ã«ãããã¹ãŠããã€ã³ãããçç±ã¯ãããŸããããåºæ¬çãªäºå®ãæãåºãããŸãã
äŒç€ŸARM Ltd. RISCã¢ãŒããã¯ãã£ãåãããã€ã¯ãããã»ããµããã³ãã€ã¯ãã³ã³ãããŒã©ã³ã¢ãéçºããé©åãªæè¡ã䜿çšããŠæ°Žæ¶ã®è£œé ã©ã€ã»ã³ã¹ãé»åéšåã¡ãŒã«ãŒã«è²©å£²ããŠããŸãã ãã®ãããªè£œé æ¥è ã¯äžçäžã«äœåãäœçŸãšããããã®äžã«ã¯åœå äŒæ¥ããããŸãã
ææ°ã®ARMã³ã¢ã¯ãCortexãšããååã§çµ±äžãããŠããŸãã
ã¡ãªã¿ã«ããç®è³ªããšããèšèã¯ã倧è³ç®è³ªããšç¿»èš³ãããŠããŸããããã¯ãèåšã®å調äœæ¥ãæèãããã³é«æ¬¡ã®ç¥çµæŽ»åã«é¢äžããæ§é ã§ãã ç§ã®æèŠã§ã¯ãçŽ æŽãããååã§ãã
ãã®ãããARM Cortexããã»ããµã³ã¢ã¯3ã€ã®äž»èŠãªã°ã«ãŒãã«åãããŠããŸãã
- Cortex-A-ã¢ããªã±ãŒã·ã§ã³ããã»ããµ-é«æ§èœãå¿ èŠãšããã¢ããªã±ãŒã·ã§ã³åãã ã»ãšãã©ã®å ŽåãLinuxãAndroidãããã³é¡äŒŒã®OSãå®è¡ããŸã
- Cortex-R-çµã¿èŸŒã¿ãªã¢ã«ã¿ã€ã ããã»ããµ-ãªã¢ã«ã¿ã€ã ã¢ããªã±ãŒã·ã§ã³çš
- Cortex-M-çµã¿èŸŒã¿ããã»ããµ-çµã¿èŸŒã¿ã·ã¹ãã çš
æåŸã®ã°ã«ãŒããèããŠãCortex-M3 / Cortex-M4Fã®ãã¢ã«åŸã ã«è¿ã¥ããŸãã åèšã§ã2015幎æ«ã«ãCortex-M0ã-M0 +ã-M1ã-M3ã-M4ã-M7ã®6ã€ã®ããã»ããµã³ã¢ãçºè¡šãããŸããã
-M1ã¯FPGAé¢é£ã®ã¢ããªã±ãŒã·ã§ã³ã§ã®ã¿èšèšããã³äœ¿çšããããããCortex-M1ã¯ãã®ãªã¹ããããã°ãã°ãé€å€ããããŸãã æ®ãã®ã³ã¢ã«ã¯ããã®ãããªç¹æ®ãªã¢ããªã±ãŒã·ã§ã³åéããªããããã©ãŒãã³ã¹ãç°ãªããŸã-æãåçŽãª-M0ããé«æ§èœã®-M7ã§ãã
Cortex-M0ãšæ¯èŒããŠãCortex-M0 +ã«ã¯ãMPUã¡ã¢ãªä¿è·ãŠãããããããã°ããã°ã©ã çšã®ãã€ã¯ããã¬ãŒã¹ãããã¡ãŒãè¿œå ã§è£ åãããŠããŸãããŸããåšèŸºãããã¯ãšå ¥åºåã©ã€ã³ãžã®3ã¹ããŒãžã®åçŽåãããã¢ã¯ã»ã¹ã®ä»£ããã«ã2ã¹ããŒãžãã€ãã©ã€ã³ããããŸãã
Cortex-M0ããã³Cortex-M0 +ã«ã¯ã·ã³ã°ã«ãã¹ãã©ã³ãã€ãã³ã¢ãŒããã¯ãã£ããããCortex-M3ã³ã¢ã¯ãã§ã«ããŒããŒãã§ãã Cortex-M3ã¯ãã©ã€ã³ã®ãè¥ãã代衚ãšã¯ãŸã£ããç°ãªããããã«å€ãã®æ©èœãåããŠããŸãã
Cortex-M4ã¯ãŸã£ããåãã¢ãŒããã¯ãã£ã§æ§ç¯ãããŠããããæ§é çã«ãCortex-M3ãšéãã¯ãããŸããã éãã¯ãµããŒããããŠããã³ãã³ãã·ã¹ãã ã«ãããŸãããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã Cortex-M4Fã¯ãFPUæµ®åå°æ°ç¹ãŠããããååšããç¹ã§-M4ãšç°ãªããŸãã
Cortex-M7ã¢ãŒããã¯ãã£ã¯æ¯èŒçæè¿ã®ãã®ã§ãããCortex-M3 / M4ãšCortex-M0ãç°ãªãã®ãšåæ§ã«ãCortex-M3 / M4ãšã¯ç°ãªããŸãã 6ã¹ããŒãžã®ã¹ãŒããŒã¹ã«ã©ãŒãã€ãã©ã€ã³ãããŒã¿ãšåœä»€çšã®åå¥ã®ãã£ãã·ã¥ãæ§æå¯èœãªTCMã¡ã¢ãªãããã³ãã®ã³ã¢ã®ä»ã®ç¹åŸŽçãªæ©èœã¯ãæé«ã®ããã©ãŒãã³ã¹ãå®çŸããããã«ãã·ã£ãŒããã«ãªã£ãŠããŸãã å®éãCortex-M7ã«åºã¥ããã³ã³ãããŒã©ã®æ©èœã¯ãçµã¿èŸŒã¿ããã»ããµã°ã«ãŒãã®ä»ã®ã³ã³ãããŒã©ãããCortex-A5ããã³-R5ãšæ¯èŒãããå¯èœæ§ãé«ããªããŸãã ãã¯ãããžãŒã¢ããªã±ãŒã·ã§ã³ã®å¢çã¯ãããŸãã«ãªãç¶ããŠããŸãã
Cortex-Mã³ã¢ã®æ©èœã¯ãŸã£ããç°ãªããŸãããåã³ã¢ã®ã³ãã³ãã»ããã«ã¯ãäžäœã®ã³ã¢ã§ãµããŒããããŠãããã¹ãŠã®ã³ãã³ããå«ãŸããŠããŸãã ããã«ãããç°ãªãã³ã¢ã«åºã¥ãããœãããŠã§ã¢äºæãã€ã¯ãã³ã³ãããŒã©ãŒãéçºããæ©äŒãæäŸãããŸããããã¯ãã»ãšãã©ã®ãã€ã¯ãã³ã³ãããŒã©ãŒã¡ãŒã«ãŒãè¡ã£ãŠããããšã§ãã
ã³ã¢Cortex-M0ããã³Cortex-M0 +ã¯ãåãã³ãã³ãã·ã¹ãã ã§ãã Cortex-M3åœä»€ã»ããã«ã¯ããã¹ãŠã®Cortex-M0ã³ãã³ããšçŽ100ã®è¿œå åœä»€ãå«ãŸããŠããŸãã Cortex-M4ããã³Cortex-M7ããã»ããµã³ã¢ã«ã¯ãåãåœä»€ã»ããããããŸããCortex-M3åœä»€ã»ãããšãããããDSPåœä»€ã§ãã Cortex-M4Fã³ã¢ã¯ãCortex-M4 / -M7ã»ããã«å ããŠãæµ®åå°æ°ç¹èšç®åœä»€ããµããŒãããCortex-M7Fåœä»€ã»ããã«ã¯ãå粟床浮åå°æ°ç¹æŒç®çšã®14åã®åœä»€ãå«ãŸããŠããŸãã
çè«éš
ãã®ããã人æ°ã®ããCortex-M3ããã»ããµã³ã¢ã®æãè¿ããé£æ¥ãã¯ãDSPåœä»€ã®ãµããŒããè¿œå ãããCortex-M4ãšãFPUãè¿œå ããŠå¯Ÿå¿ããã³ãã³ãããµããŒãããCortex-M4Fã§ãã DSPããã³FPUã³ãã³ããæ€èšããŠãã ããã
DSPåœä»€
ç¥èªDSPã¯ãã»ãšãã©ã®å Žåãããžã¿ã«ã·ã°ãã«ããã»ããµãšããŠè§£èªãããŸãã ããžã¿ã«ä¿¡å·åŠçã®ã¿ã¹ã¯çšã«èšèšãããå®å šã«ç¬ç«ããç¬ç«ããã³ã³ãããŒã©ãŒãŸãã¯ã³ããã»ããµãŒã ç¹æ®ãªDSPããããšDSPåœä»€ã®ã»ãããæ··åããªãã§ãã ããã DSPã³ãã³ãïŒProcess ãŸãã¯ã®ä»£ããã«ããžã¿ã«ä¿¡å·åŠçãè¡šãïŒã¯ãå€æ°ã®ARMããã»ããµã³ã¢ã§ãµããŒããããŠããäžé£ã®ã³ãã³ãã§ãããããžã¿ã«ä¿¡å·åŠçã®äžè¬çãªæäœã«å¯Ÿå¿ããŠããŸãã
ãã®ãããªæäœã®æåã®ã°ã«ãŒãã¯ã 环ç©ä¹ç® ïŒSingle-cycle Multiply AccumulateãŸãã¯åã«MACïŒã§ãã
æå°ã®å ŽåïŒçŽ¯ç®ã䌎ãä¹ç®ã¯ãåŒS = S + A x Bã§èšè¿°ãããŸãã察å¿ããã³ãã³ãã¯ã2ã€ã®ã¬ãžã¹ã¿ãšçŽ¯ç®åšã§ã®çµæã®åèšããã³é¢é£ããæŒç®ãšã®ä¹ç®ãèšè¿°ããŸãã
16ãããããã³32ãããå€æ°ã®æäœãæäŸãããå€ãã®äžè¬çãªããžã¿ã«ä¿¡å·åŠçã¢ã«ãŽãªãºã ã§éèŠãªåœ¹å²ãæãããŸãã ããšãã°ã FIRãã£ã«ã¿ãŒ ïŒããã¯å€å žçãªãããšãã°ã»ãŒå¹³å¡ãªïŒã¯ã环ç®ã䌎ãä¹ç®ã®ã·ãŒã±ã³ã¹ã§ããã€ãŸãããã®é床ã¯ã环ç®ã䌎ãä¹ç®ã®é床ã«çŽæ¥äŸåããŸãã
Cortex-M4ïŒFïŒã³ã¢ãåãããã€ã¯ãã³ã³ãããŒã©ãŒã®ãã¹ãŠã®MACåœä»€ã¯ãåäžãã·ã³ãµã€ã¯ã«ã§å®è¡ãããŸãã
DSPåœä»€ã®2çªç®ã®ã°ã«ãŒãã¯ãSIMDïŒSingle Instruction Multiple DataïŒæäœã§ããããã«ããã䞊åèšç®ã«ããããŒã¿åŠçã®æé©åãå¯èœã«ãªããŸãã ç¬ç«å€æ°ã®ãã¢ã¯ããã倧ããªæ¬¡å ã®åäžã®ã¬ãžã¹ã¿ã«ãã¢ããšã«é 眮ãããç®è¡æŒç®ã¯ã倧ããªãã¬ãžã¹ã¿ã§ãã§ã«å®è¡ãããŠããŸãã
ããšãã°ã SADD16ã³ãã³ãã§ã¯ã16ãããã®ç¬Šå·ä»ãæ°å€ã®2ã€ã®ãã¢ãåæã«å ç®ããçµæã第1ãªãã©ã³ããæ ŒçŽããã¬ãžã¹ã¿ã«æžã蟌ã¿ãŸãã
SADD16 R1, R0
æ±çšã¬ãžã¹ã¿ã®å®¹éã¯32ãããã§ãããããåã¬ãžã¹ã¿ã«ã¯2ã€ã®16ãããå€æ°ïŒããŒãã¯ãŒãïŒã ãã§ãªããæ倧4ã€ã®8ãããå€æ°ïŒãã€ãïŒãå«ããããšãã§ããŸãã ããã§ãSADD8ã³ãã³ããå¿ èŠãªçç±ãç°¡åã«ç解ã§ããŸãã
次ã«ãããè€éãªæäœã瀺ããŸããäžäœã®ããŒãã¯ãŒããä¹ç®ããäžäœã®ããŒãã¯ãŒããä¹ç®ãã64ãããã®çŽ¯ç©ã§ããŒã¹ãåèšããŸãã SMLALDã³ãã³ãã¯ããããã¹ãŠã®ã¢ã¯ã·ã§ã³ãèšè¿°ããåäžãã·ã³ãµã€ã¯ã«ã§Cortex-M4ã«ãã£ãŠå®è¡ãããŸãã SMLALDã¯ãä»ã®å€ãã®ããŒã ãšåæ§ã«ãSIMDã«åºã¥ããŠä¹ç®ãšçŽ¯ç©ããã³ããŒã¿åŠçãçµã¿åãããŸãã
SMLALD R6, R8, R5, R1
åçŽãªSIMDã³ãã³ãïŒç¬Šå·ä»ãããã³ç¬Šå·ãªãã®8ãããããã³16ãããã®å ç®ããã³æžç®ãªã©ïŒãšSMLALDãªã©ã®è€éãªã³ãã³ãã®äž¡æ¹ã1ãã·ã³ãµã€ã¯ã«ã§å®è¡ãããŸãã
DSPåœä»€ã®æ¬¡ã®ã°ã«ãŒãã¯ã飜ååœä»€ã§ãã ãããã¯ã«ãããªãæäœãšãåŒã°ãããªãŒããŒãããŒä¿è·ãè¡šããŸãã æšæºã³ãã³ãã䜿çšããå Žåãçµæãæ ŒçŽããã¬ãžã¹ã¿ã¯ããªãŒããŒãããŒæã«æåããããªããŒããããã飜åãæäŸããã³ãã³ãã¯ãªãŒããŒãããŒæã«ã蚱容æ倧容éã§çµæãä¿®æ£ããŸãã ããã«ãããããã°ã©ãããªãŒããŒãããŒãã©ã°ãåŠçããå¿ èŠããªããªããŸãã
Cortex-M4ããã»ããµã³ã¢ã®åœä»€ã«ã¯ããéåžžã®ãç®è¡æŒç®ãšé£œåã䌎ãåãæŒç®ã®äž¡æ¹ããããŸãã åŸè ã®äœ¿çšã¯ãé床ã®ããã«èšç®ã®ç²ŸåºŠãç ç²ã«ããå¯èœæ§ã®ããåé¡ã§ç¹ã«éèŠããããŸãã DSPã«ã¯ãã®ãããªã¿ã¹ã¯ãå€æ°ãããŸãã
FPUåœä»€
æµ®åå°æ°ç¹èšç®ïŒãŸãã¯ä»»æã®ãã€ã³ãïŒã®ããŒããŠã§ã¢ãµããŒãã¯ãCortex-M4Fã³ã¢ãšCortex-Mã©ã€ã³ã®å€ã代衚ã®æ©èœã§ãã
æµ®åå°æ°ç¹èšç®ã³ãã³ãã䜿çšãããšãå®æ°ã«å¯ŸããŠæ倧ã®ããã©ãŒãã³ã¹ã§æäœãå®è¡ã§ããŸãã äžè¬ã«ãçŸåšãå®æ°ã®è¡šçŸã«ã¯åºå®å°æ°ç¹ãšæµ®åå°æ°ç¹ã®2ã€ã®åœ¢åŒã䜿çšãããŠããŸãã åè ã®å ŽåãæŽæ°éšãšå°æ°éšãèšé²ããããã®ãããæ°ã¯åºå®ãããŠãããèšç®ã¯æŽæ°ã®æŒç®ã«åæžãããŸããåŸè ã®å Žåãæ°ã¯ç¬Šå·ãããã次æ°ãšä»®æ°éšã®çµã¿åãããšããŠè¡šãããŸãã
ïŒ-1ïŒ s * mÃb e ã
ããã§ãsã¯ç¬Šå·ãb-baseãeã¯æ¬¡æ°ãmã¯ä»®æ°ã§ãã
æµ®åå°æ°ç¹åœ¢åŒã®å€æ°ã®å€ã®ç¯å²ãã¯ããã«åºããããä¿¡å·ãåŠçããå Žåã¯ãæµ®åå°æ°ç¹åœ¢åŒã䜿çšããããšããå§ãããŸãã FPUæäœã䜿çšãããšãéçºè ãããã深床ãç£èŠããå¿ èŠããªããªããŸãã å粟床浮åå°æ°ç¹æ°åœ¢åŒã¯IEEE 754æšæºã§èšè¿°ãããŠããããã®è¡šçŸã¯Cortex-M4Fã³ã¢ãåãããã€ã¯ãã³ã³ãããŒã©ãŒã§äœ¿çšãããŸãã 蚱容å€ã®ç¯å²ã¯ïŒ10 â38 ... 10 38 ïŒã§ããã10é²æ°ãžã®è¿äŒŒå€æãè¡ãããŸãã
ãšããã§ãCortex-M7Fã¯ãå粟床浮åå°æ°ç¹æ°åœ¢åŒã«å¯ŸããŠåãåçã䜿çšããŸããã32ãããè¡šçŸã®ä»£ããã«64ãããè¡šçŸã䜿çšããŸãã æ¡ã¯11ããããä»®æ°52ã«ãªããŸãã
æµ®åå°æ°ç¹åœ¢åŒãHabréã§æžãããè€æ°å䜿çšãããçç±ãšçç±ã«ã€ããŠïŒ ããã§ã¯ãåªããèšäºãªã©ïŒã ããããç§ã¯ãã以äžæžãããšãã§ããªãã®ã§ãå ã«é²ã¿ãŸãããã
çµã¿ç«ãŠãããDSPããã³FPUã³ãã³ãã®ãªã¹ã
Cortex-M4ã䜿çšããããŒã¿åŠçã®éãç解ããããã«ãèŠæš¡ã®æèŠãã€ããããã«ãDSPããã³FPUåœä»€ã®å®å šãªãªã¹ããåŠã¶ããšãã§ããŸãã ãããã®ããŒãã«ã®å®çšçãªäŸ¡å€ã«ã€ããŠã¯å€§ããªçåããããŸãããèå³æ·±ããã®ã§ãã
ãã¹ãŠã®DSPããã³ã»ãšãã©ã®FPUåœä»€ã¯ãåäžãã·ã³ãµã€ã¯ã«ã§å®è¡ãããŸãã
Cortex-M4ã«ãŒãã«DSPåœä»€
ããŒã | éå¶ |
PKHTBãPKHBT | å¿ èŠã«å¿ããŠããåä¿¡ãã¬ãžã¹ã¿ã®å 容ãã·ããããŠãããã¬ãžã¹ã¿ããå¥ã®ã¬ãžã¹ã¿ã«ããŒãã¯ãŒããæžãæããŸã |
QADD | 飜åãã笊å·ä»ãå ç® |
QADD16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ç¬Šå·å ç®ïŒé£œåããïŒ |
QADD8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ä»ãå ç®ïŒé£œåããïŒ |
QASX | 第2ãªãã©ã³ãã®äžäœããŒãã¯ãŒããšç¬¬1ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç¬Šå·ä»ãå ç®ã第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒãããã®ç¬¬2ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãã®ç¬Šå·ä»ãæžç®ïŒé£œåããïŒ
|
QDADD | 第2ãªãã©ã³ãã2åã«ããçµæã第1ãªãã©ã³ããšå ç®ããïŒç¬Šå·ä»ãã飜åïŒ |
QDSUB | 第2ãªãã©ã³ãã2åã«ãã第1ãªãã©ã³ãããçµæãæžç®ïŒç¬Šå·ä»ãã飜åããïŒ |
QSAX | 第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãããã®ç¬¬2ãªãã©ã³ãã®å¯ããŒãã¯ãŒãã®ææãªæžç®+第1ãªãã©ã³ãã®å¯ããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ææãªå ç®ïŒé£œåããïŒ |
QSUB | 笊å·ä»ãæžç®ïŒé£œåããïŒ |
QSUB16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ææãªæžç®ïŒé£œåããïŒ |
QSUB8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ææãªæžç®ïŒé£œåããïŒ |
SADD16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®å€§å¹ ãªè¿œå |
SADD8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ä»ãå ç® |
ãµãã¯ã¹ | 第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç¬Šå·ä»ãå ç®ãçµæã®äžäœããŒãã¯ãŒãã®ã¬ã³ãŒããçµæã®äžäœããŒãã¯ãŒãã®ãšã³ããªãæã€ç¬¬1ãªãã©ã³ãã®äžäœããŒãã¯ãŒãããã®ç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç¬Šå·ä»ãæžç®
|
SEL | GE [3ïŒ0]ã®ãããã«å¿ãããªãã©ã³ãããã®ãã€ãã®éžæïŒç®è¡æŒç®ã®å®è¡æã«ã以äžããªã©ã®ããŸããŸãªæ¡ä»¶ãèšå®ããããšãã«èšå®ãããããã©ã°ãïŒ |
SHADD16 | ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ç¬Šå·å ç®ã2ã€ã®çµæã®å³ãžã®1ãããã®ã·ãã |
SHADD8 | ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ä»ãå ç®ã4ã€ã®çµæãå³ã«1ãããã·ãã |
SHASX | 第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç¬Šå·ä»ãå ç®ãæå®ãããã¬ãžã¹ã¿ã®æäžäœããŒãã¯ãŒãã«çµæã1ãããå³ã·ããã§æžã蟌ã¿ã第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããã第2ãªãã©ã³ãã®æäžäœããŒãã¯ãŒããå€§å¹ ã«æžç®ããå³ã·ãã1ã§æå®ã¬ãžã¹ã¿ã®äžäœããŒãã¯ãŒãã«çµæãèšé²ããå°ã |
SHSAX | 第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒããã第2ãªãã©ã³ãã®äžäœããŒãã¯ãŒããææã«æžç®ããæå®ããã¬ãžã¹ã¿ã®äžäœããŒãã¯ãŒãã«çµæã1ãããå³ã·ããããŠæžã蟌ã¿ã第2ãªãã©ã³ãã®äžäœããŒãã¯ãŒããšç¬¬1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããææã«å ç®ããæå®ããã¬ãžã¹ã¿ã®äžäœããŒãã¯ãŒãã«å³ã·ãã1ã§çµæãæžã蟌ãå°ã |
SHSUB16 | 第1ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒããã第2ãªãã©ã³ãã®äžäœããã³äžäœããŒãã¯ãŒããå€§å¹ ã«æžç®ããçµæã1ãããå³ã«ã·ããããŸãã |
SHSUB8 | 第1ãªãã©ã³ãã®å¯Ÿå¿ãããã€ããã第2ãªãã©ã³ãã®äžäœããã³äžäœãã€ããå€§å¹ ã«æžç®ããçµæã1ãããå³ã«ã·ããããŸã |
SMLABBãSMLABTãSMLATBãSMLATT | 2ã€ã®ãªãã©ã³ãã®äžäœãŸãã¯äžäœããŒãã¯ãŒããš32ããã环ç©ã®ä¹ç® |
SMLADãSMLADX | 2ã€ã®ãªãã©ã³ãã®ããŒãã¯ãŒãã®ãã¢ã¯ã€ãºä¹ç®ã32ããã环ç©ã§2ã€ã®ç©ãåèš |
SMLALBBãSMLALBTãSMLALTBãSMLALTT | 2ã€ã®ãªãã©ã³ãïŒé«ãŸãã¯äœïŒã®ã·ã³ããªãã¯ããŒãã¯ãŒããš64ãããã®çŽ¯ç©ããã³64ãããã®çµæã®ä¹ç® |
SMLALDãSMLALDX | 第1ãªãã©ã³ãããååŸãã2ãã€ããšç¬¬2ãªãã©ã³ãããååŸãã2ãã€ãã®ãã¢ã¯ã€ãºä¹ç®ãåä¿¡ãã2ã€ã®ç©ã®åèšãš64ãããã®çŽ¯ç©ããã³64ãããã®çµæ |
SMLAWBãSMLAWT | 第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããŸãã¯äžäœããŒãã¯ãŒããš32ããã环ç©ã®ç¬¬2ãªãã©ã³ããä¹ç®ãããšã48ãããã®çµæã®æåã®32ããããçµæã¬ãžã¹ã¿ã«æžã蟌ãŸããŸã |
SMLSD | 2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒããš32ããã环ç©ã®2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç©ã®æžç® |
SMLSLD | 2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒããš64ããã环ç®ã®2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç©ã®æžç® |
SMMLA | 2ã€ã®ãªãã©ã³ããš32ããã环ç®ã®ä¹ç®ïŒç©ã®äžäœ32ãããã®ã¿ãååŸãããŸãïŒ |
SMMLSãSMMLR | 2ã€ã®ãªãã©ã³ãã®ä¹ç®ãæå®ãããã¬ãžã¹ã¿ãŒããã®çµæã®æžç®ïŒç©ã®äžäœ32ãããã®ã¿ãååŸãããŸãïŒ |
SMMULãSMMULR | ãªãã©ã³ãã®ä¹ç®ïŒçµæ-äžäœ32ããã補åïŒ |
SMUAD | 2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ä¹ç®ã2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ä¹ç®ãç©ã®å ç® |
SMULBBãSMULBT SMULTBãSMULTT | 2ã€ã®ãªãã©ã³ãã®äžäœãŸãã¯äžäœããŒãã¯ãŒãã®ä¹ç® |
SMULWBãSMULWT | 第1ãªãã©ã³ãã«ç¬¬2ãªãã©ã³ãã®äžäœãŸãã¯äžäœããŒãã¯ãŒããä¹ç®ãããšã48ãããã®çµæã®æåã®32ããããçµæã¬ãžã¹ã¿ã«æžã蟌ãŸããŸã |
SMUSDãSMUSDX | 2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ä¹ç®ã2ã€ã®ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ä¹ç®ã2çªç®ã®ãªãã©ã³ãããæåã®ç©ã®æžç® |
SSAT16 | æå®ãããå€ãžã®ããŒãã¯ãŒãã®ç¬Šå·ä»ã飜å |
SSAX | çµæã®äžäœããŒãã¯ãŒãã«æžã蟌ã¿ãè¡ã第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒããã第2ãªãã©ã³ãã®äžäœããŒãã¯ãŒããææã«æžç®ããçµæã®äžäœããŒãã¯ãŒãã«æžã蟌ã¿ãè¡ã第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒããå ç®ãã |
SSUB16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ææãªæžç® |
SSUB8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ææãªæžç® |
SXTAB | ã¬ãžã¹ã¿ããããã[7ïŒ0]ãæœåºãããããã笊å·ãèæ ®ããŠ32ãããã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ããŸã |
SXTAB16 | ã¬ãžã¹ã¿ããããã[7ïŒ0]ããã³[23:16]ãæœåºãã笊å·ãèæ ®ããŠããããããŒãã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ãã |
SXTAH | ã¬ãžã¹ã¿ããããã[15ïŒ0]ãæœåºãããããã笊å·ãèæ ®ããŠ32ãããã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ããŸã |
SXTB16 | 笊å·ãèæ ®ããŠ2ãã€ãã2ã€ã®ããŒãã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ãã |
UADD16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ç¬Šå·ãªãå ç® |
UADD8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ãªãå ç® |
USAX | çµæã®äžäœããŒãã¯ãŒãã«çµæãæžã蟌ãããšã«ããã第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®å ç®ãçµæã®äžäœããŒãã¯ãŒãã®ãšã³ããªãæã€ç¬¬1ãªãã©ã³ãã®äžäœããŒãã¯ãŒãããã®ç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç¬Šå·ãªãæžç® |
UHADD16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ç¬Šå·ãªãå ç®ãšçµæã®1ãããå³ãžã®ã·ãã |
UHADD8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ãªãå ç®ãšçµæã®å³ãžã®1ãããã®ã·ãã |
ãŠãã¯ã¹ | å ç®çµæã1ãããå³ã«ã·ããããŠã第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã笊å·ãªãå ç®ããçµæãæäžäœããŒãã¯ãŒãã«æžã蟌ãã第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããã第2ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãã笊å·ãªãæžç®ã§å³ã«1ãããæžç®ããäžäœããŒãã¯ãŒãã«æžã蟌ãçµæ |
UHSax | 第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒããã第2ãªãã©ã³ãã®æåŸã®ããŒãã¯ãŒãã笊å·ãªãæžç®ããæžç®çµæã1ãããå³ã«ã·ããããçµæãæäžäœããŒãã¯ãŒãã«æžã蟌ã¿ã第1ãªãã©ã³ãã®äžäœããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®ç¬Šå·ãªãå ç®ã1ãããå³ã«å ç®ããäžäœããŒãã¯ãŒãã«æžã蟌ãçµæ |
UHSUB16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ç¬Šå·ãªãæžç®ãçµæãå³ã«1ãããã·ãã |
UHSUB8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ãªãæžç®ãçµæã1ãããå³ã«ã·ããããŸã |
ãŠããŒã« | ããã«32ããã环ç©ãš64ãããçµæã®ç¬Šå·ãªãä¹ç® |
UQADD16 | 16ãããå€æ°ã®ç¬Šå·ãªãå ç®ïŒé£œåããïŒ |
UQADD8 | 8ãããå€æ°ã®ç¬Šå·ãªãå ç®ïŒé£œåããïŒ |
UQASX | 第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãããã®ç¬¬2ãªãã©ã³ãã®æå°ããŒãã¯ãŒãã®ç¬Šå·ãªãæžç®ã第1ãªãã©ã³ãã®æå°ããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãã®ç¬Šå·ãªãå ç®ïŒé£œåããïŒ |
UQSAX | 第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãããã®ç¬¬2ãªãã©ã³ãã®æå°ããŒãã¯ãŒãã®ç¬Šå·ãªãæžç®ã第1ãªãã©ã³ãã®æå°ããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãã®ç¬Šå·ãªãå ç®ïŒé£œåããïŒ |
UQSUB16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ç¬Šå·ãªãæžç®ïŒé£œåããïŒ |
UQSUB8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ãªãæžç®ïŒé£œåããïŒ |
USAD8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ãªãæžç®ã絶察差ã®å ç® |
USADA8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ãªãæžç®ã絶察差ã®å ç®ãæŒç®çµæãšããããªãŒã®å 容ã®å ç® |
USAT16 | æå®ãããå€ãžã®ããŒãã¯ãŒãã®ç¬Šå·ãªã飜å |
Uasx | çµæã®äžäœããŒãã¯ãŒããžã®æžã蟌ã¿ã䌎ã第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãããã®ç¬¬2ãªãã©ã³ãã®æäžäœããŒãã¯ãŒãã®ç¬Šå·ãªãæžç®ãçµæã®äžäœããŒãã¯ãŒããžã®çµæã®æžã蟌ã¿ã䌎ã第1ãªãã©ã³ãã®æäžäœããŒãã¯ãŒããšç¬¬2ãªãã©ã³ãã®äžäœããŒãã¯ãŒãã®å ç® |
USUB16 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ããããŒãã¯ãŒãã®ç¬Šå·ãªãæžç® |
USUB8 | 2ã€ã®ãªãã©ã³ãã®å¯Ÿå¿ãããã€ãã®ç¬Šå·ãªãæžç® |
UXTAB | ã¬ãžã¹ã¿ããããã[7ïŒ0]ãæœåºãã笊å·ã«é¢ä¿ãªã32ãããã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ããŸã |
UXTAB16 | ã¬ãžã¹ã¿ããããã[7ïŒ0]ããã³[23:16]ãæœåºãããããã笊å·ã«é¢ä¿ãªãããŒãã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ãã |
UXTAH | ã¬ãžã¹ã¿ããããã[15ïŒ0]ãæœåºãããããã笊å·ã«é¢ä¿ãªã32ãããã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ããŸã |
UXTB16 | 笊å·ãèæ ®ããã«2ãã€ãã2ã€ã®ããŒãã¯ãŒãã«å€æããçµæãã¯ãŒããŸãã¯ããŒãã¯ãŒãã«è¿œå ãã |
Cortex-M4Fã«ãŒãã«FPUåœä»€
ããŒã | éå¶ |
VABS.F32 | ãªãã©ã³ãã®çµ¶å¯Ÿå€ãååŸãã |
VADD.F32 | ãªãã©ã³ãã®è¿œå |
VCMP.F32 | 2ã€ã®ãªãã©ã³ããŸãã¯ãªãã©ã³ããšãŒãã®æ¯èŒ |
VCMPE.F32 | 誀ã£ããªãã©ã³ãïŒNaNïŒããã§ãã¯ããŠã2ã€ã®ãªãã©ã³ããŸãã¯ãªãã©ã³ããšãŒããæ¯èŒãã |
VCVT.S32.F32 | ããŒã¿åéã®å€æïŒæµ®åå°æ°ç¹/æŽæ°ïŒ |
VCVT.S16.F32 | ããŒã¿åéã®å€æïŒæµ®åå°æ°ç¹/åºå®å°æ°ç¹ïŒ |
VCVTR.S32.F32 | äžžãã䜿çšããããŒã¿åïŒæµ®åå°æ°ç¹/æŽæ°ïŒéã®å€æ |
VCVT <B | H> .F32.F16 | ããŒã¿åéã®å€æïŒæµ®åå°æ°ç¹ä»ãã®ããŒãã¯ãŒã-ãå粟床æ°ã/æµ®åå°æ°ç¹ã§ããããŸãïŒ |
VCVTT <B | T> .F32.F16 | ããŒã¿åéã®å€æïŒæµ®åå°æ°ç¹/ããŒãã¯ãŒãæµ®åå°æ°ç¹ïŒ |
VDIV.F32 | ãªãã©ã³ãã®åå² |
VFMA.F32 | 2ã€ã®å€æ°ã®ä¹ç®ãä¹ç®ã®çµæãæå®ãããã¬ãžã¹ã¿ã®å 容ã«è¿œå |
VFNMA.F32 | 第1ãªãã©ã³ããå転ããçµæã«ç¬¬2ãªãã©ã³ããä¹ç®ããç©ãšæå®ãããã¬ãžã¹ã¿ã®å転å€ãå ç®ããŸã |
VFMS.F32 | 第1ãªãã©ã³ããå転ããçµæã«ç¬¬2ãªãã©ã³ããä¹ç®ããæå®ãããã¬ãžã¹ã¿ã®ç©ãšå€ãå ç®ããŸã |
VFNMS.F32 | 2ã€ã®ãªãã©ã³ãã®ä¹ç®ãç©ã®å ç®ãæå®ãããã¬ãžã¹ã¿ããã®åè»¢å€ |
VLDM.F <32 | 64> | ããã°ã©ã ã¡ã¢ãªããããã€ãã®æå®ãããã¬ãžã¹ã¿ã®å 容ãæœåºãã |
VLDR.F <32 | 64> | æå®ãããã¬ãžã¹ã¿ã®å 容ãããã°ã©ã ã¡ã¢ãªããæœåºãã |
VLMA.F32 | 环ç©ä¹ç® |
VLMS.F32 | æå®ãããã¬ãžã¹ã¿ãã2ã€ã®ãªãã©ã³ãã®ç©ãæžç®ããŸã |
Vmov | ãæšæºãARMã¬ãžã¹ã¿ãšFPSCRïŒæµ®åå°æ°ç¹ã¹ããŒã¿ã¹ããã³å¶åŸ¡ã¬ãžã¹ã¿ïŒã¬ãžã¹ã¿éã®ããŒã¿è»¢éãæµ®åå°æ°ç¹åœ¢åŒã¬ãžã¹ã¿ïŒFPUã¬ãžã¹ã¿ïŒéã®ããŒã¿è»¢éãFPUã¬ãžã¹ã¿ãžã®å®æ°ã®æžã蟌ã¿ãªã©ã |
VMOVãVMRSãVMSR | ãæšæºãARMã¬ãžã¹ã¿ãšFPSCRïŒæµ®åå°æ°ç¹ã¹ããŒã¿ã¹ããã³å¶åŸ¡ã¬ãžã¹ã¿ïŒéã®ããŒã¿è»¢é |
VMUL.F32 | ãªãã©ã³ãã®ä¹ç® |
VNEG.F32 | å転 |
VNMLA.F32 | 2ã€ã®ãªãã©ã³ãã®ä¹ç®ãçµæã®ã€ã³ãã³ããªãæå®ãããã¬ãžã¹ã¿ããã®å転ç©ãšå転å€ã®è¿œå |
VNMLS.F32 | æå®ãããã¬ãžã¹ã¿ã®2ã€ã®ãªãã©ã³ããç©ãããã³å転å€ã®ä¹ç® |
ãŽã³ã ã« | 2ã€ã®ãªãã©ã³ãã®ä¹ç®ãçµæã®ã€ã³ãã³ã㪠|
VPOP | ãŸã ããã |
VPUSH | æŒã |
VSQRT.F32 | å¹³æ¹æ ¹æœåº |
Vstm | æå®ãããè€æ°ã®ã¬ãžã¹ã¿ã®å 容ãããã°ã©ã ã¡ã¢ãªã«ä¿åãã |
VSTR.F <32 | 64> | æå®ãããã¬ãžã¹ã¿ã®å 容ãããã°ã©ã ã¡ã¢ãªã«ä¿åãã |
VSUB.F <32 | 64> | ãªãã©ã³ãã®æžç® |
ãã ããå®éã«ã¯ãã«ãŒãã«åœä»€èªäœã¯ããŸã䜿çšãããŸããã éåžžãéçºæã«ã¯ãã³ã¢ããã³ã¯ãªã¹ã¿ã«ã¡ãŒã«ãŒã®ã³ã³ãããŒã©ãŒããã³ã©ã€ãã©ãªã©ã€ãã©ãªã®ããã¥ã¡ã³ããåŠçããã ãã§ååã§ãã ç¹ã«ãCortexã³ã¢ã«ã¯ãç°ãªãã¡ãŒã«ãŒã®Cortex-Mããã»ããµã«äœ¿çšãããCMSISã©ã€ãã©ãªã®ARMã»ããããããŸãã CMSISã«ã¯CMSIS-DSPã©ã€ãã©ãªãå«ãŸããŠããŸãã
- åºæ¬çãªæ°åŠé¢æ°ããã¯ãã«ã®æäœ
- é«éã®äžè§é¢æ°ããã³è¶ è¶é¢æ°ïŒsinãcosãsqrtãªã©ïŒ
- ç·åœ¢ããã³åç·åœ¢è£é
- è€çŽ æ°ç®è¡
- çµ±èšé¢æ°
- ãã£ã«ã¿ãªã³ã°ã¢ã«ãŽãªãºã -IIRãFIRãã£ã«ã¿ãŒãæå°äºä¹å¹³å誀差ã¢ã«ãŽãªãºã
- ä¿¡å·å€æã¢ã«ãŽãªãºã ïŒFFTãªã©ïŒ
- è¡åæŒç®
- PIDã³ã³ãããŒã©ãŒ
- é åãæäœããããã®é¢æ°
å®çšçãªéšå
ååãšããŠãCortex-M3ãšCortex-M4ïŒFïŒã³ã¢ã®æ¯èŒã¯çŸããã°ã©ãã§çµãããŸã-DSPã¿ã€ãã®äžè¬çãªæäœïŒFIRãã£ã«ã¿ãŒãFFTããããªãã¯ã¹èšç®ãPID -ã¬ã®ã¥ã¬ãŒã¿ãªã©ïŒã 䜿çšããã³ã³ãããŒã©ãŒããã®æ瀺ãªãã§ãèšç®ããã³æž¬å®æé ã
ãããã朮ãšéåžžã®æŽå€ãæ¯èŒããã®ã§ã¯ãªããå®éã®ããŒããŠã§ã¢ãšãœãããŠã§ã¢ã®ãã©ãããã©ãŒã ã䜿çšããŸãã
ãã®æç¹ã§ãCortex-M4Fæ°åŠè£ 眮ãé¢é£ããã¿ã¹ã¯ã«ã€ããŠå°ã泚æãããããçèããããšã¯çã«ããªã£ãŠããŸãã Cortex-M4ã³ã¢ã®ããã©ãŒãã³ã¹ã ãã§ã¯ã¹ããªãŒãã³ã°ããŒã¿ããã«ãã¡ãã£ã¢ãæ±ãã®ã«ååã§ã¯ãªãããšã¯æããã§ããããŒã¿ç®¡çããã³åŠçã·ã¹ãã ã«ã€ããŠè©³ãã説æããŠããŸãã
ããšãã°ãäžéšã®ãã¬ã¡ããªããŒã¿ãåéãããŠããŸãã , , «» . â , .
. - -. bluetooth ? ãã¡ããéããŸãã .
. , « »? ! , .
EFM32 Wonder Gecko SiLabs. . -.
EFM32WG â Cortex-M4F. EFM32, . Cortex-M3 Cortex-M4F.
:
EFM32WG-STK3800 â Cortex-M4F
EFM32GG-STK3700 â Cortex-M3
.
Simplicity Studio. SiLabs- , , , , Silabs. â IDE, energy profiler, user guide .
. , , , 0,5 : 512 . ProcessFFT().
, . .
Simplicity Studio, Simplicity IDE, .
ããã°ã©ã ãªã¹ã
, â , Simplicity IDE, IAR, Keil .
/***************************************************************************//** * @file lightsensefft.c * @brief FFT transform example * @details * Use ADC in order to capture and analyse input from the * light sensor on the STK. Runs floating point FFT algorithm from the CMSIS * DSP Library, and estimate the frequency of the most luminous light source * using sinc interpolation. The main point with this example is to show the * use of the CMSIS DSP library and the floating point capability of the CPU. * * @par Usage * Connect the light sensor output to the ADC input by shorting pins * 15 and 14 on the EXP_HEADER of the STK. * Direct various light sources to the light sensor. Expect no specific * frequency from daylight or from a flashlight. Mains powered incandescent * bulbs should give twice the mains frequency. Using another STK running the * "blink" example modified to various blink rates is an excellent signal * source. The frequency bandwidth is approximately 10-500 Hz. * The frequency shows in the 4 digit numerical display upper right on * the LCD. The LCD also displays the number of CPU cycles used to do * the FFT transform. * * @author Silicon Labs * @version 1.04 ******************************************************************************* * @section License * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b> ******************************************************************************* * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no * obligation to support this Software. Silicon Labs is providing the * Software "AS IS", with no express or implied warranties of any kind, * including, but not limited to, any implied warranties of merchantability * or fitness for any particular purpose or warranties against infringement * of any proprietary rights of a third party. * * Silicon Labs will not be liable for any consequential, incidental, or * special damages, or any other relief, or for any claim by any third party, * arising from your use of this Software. * ******************************************************************************/ #include "em_common.h" #include "em_emu.h" #include "em_cmu.h" #include "em_chip.h" #include "em_adc.h" #include "em_gpio.h" #include "em_rtc.h" #include "em_acmp.h" #include "em_lesense.h" #include "segmentlcd.h" #include "arm_math.h" #include "math.h" /** * Number of samples processed at a time. This number has to be equal to one * of the accepted input sizes of the rfft transform of the CMSIS DSP library. * Increasing it gives better resolution in the frequency, but also a longer * sampling time. */ #define BUFFER_SAMPLES 512 /** (Approximate) sample rate used for sampling data. */ #define SAMPLE_RATE (1024) /** The GPIO pin used to power the light sensor. */ #define EXCITE_PIN gpioPortD,6 /* Default configuration for alternate excitation channel. */ #define LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF \ { \ false, /* Alternate excitation enabled.*/ \ lesenseAltExPinIdleDis, /* Alternate excitation pin is disabled in idle. */ \ false /* Excite only for corresponding channel. */ \ } /* ACMP */ #define ACMP_NEG_REF acmpChannelVDD #define ACMP_THRESHOLD 0x38 /* Reference value for the lightsensor. * Value works well in office light * conditions. Might need adjustment * for other conditions. */ /* LESENSE Pin config */ #define LIGHTSENSE_CH 6 #define LIGHTSENSE_EXCITE_PORT gpioPortD #define LIGHTSENSE_EXCITE_PIN 6 #define LIGHTSENSE_SENSOR_PORT gpioPortC #define LIGHTSENSE_SENSOR_PIN 6 #define LCSENSE_SCAN_FREQ 5 #define LIGHTSENSE_INTERRUPT LESENSE_IF_CH6 /** Buffer of uint16_t sample values ready to be FFT-ed. */ static uint16_t lightToFFTBuffer[BUFFER_SAMPLES]; /** Buffer of float samples ready for FFT. */ static float32_t floatBuf[BUFFER_SAMPLES]; /** Complex (interleaved) output from FFT. */ static float32_t fftOutputComplex[BUFFER_SAMPLES * 2]; /** Magnitude of complex numbers in FFT output. */ static float32_t fftOutputMag[BUFFER_SAMPLES]; /** Flag used to indicate whether data is ready for processing */ static volatile bool dataReadyForFFT; /** Indicate whether we are currently processing data through FFT */ static volatile bool processingFFT; /** Instance structures for float32_t RFFT */ static arm_rfft_instance_f32 rfft_instance; /** Instance structure for float32_t CFFT used by the RFFT */ static arm_cfft_radix4_instance_f32 cfft_instance; /**************************************************************************//** * Interrupt handlers prototypes *****************************************************************************/ void LESENSE_IRQHandler(void); /**************************************************************************//** * Functions prototypes *****************************************************************************/ void setupCMU(void); void setupACMP(void); void setupLESENSE(void); /**************************************************************************//** * @brief LESENSE_IRQHandler * Interrupt Service Routine for LESENSE Interrupt Line *****************************************************************************/ void LESENSE_IRQHandler(void) { /* Clear interrupt flag */ LESENSE_IntClear(LIGHTSENSE_INTERRUPT); } /***************************************************************************//** * @brief Enables LFACLK and selects osc as clock source for RTC ******************************************************************************/ void RTC_Setup(CMU_Select_TypeDef osc) { RTC_Init_TypeDef init; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, osc); /* Division prescaler to decrease consumption. */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; init.debugRun = false; init.comp0Top = true; /* Count only to top before wrapping */ RTC_Init(&init); /* RTC clock divider is 32 which gives 1024 ticks per second. */ RTC_CompareSet(0, ((1024 * SAMPLE_RATE) / 1000000)-1); /* Enable interrupt generation from RTC0, needed for WFE (wait for event). */ /* Notice that enabling the interrupt in the NVIC is not needed. */ RTC_IntEnable(RTC_IF_COMP0); } /**************************************************************************//** * @brief Enable clocks for all the peripherals to be used *****************************************************************************/ void setupCMU(void) { /* Ensure core frequency has been updated */ SystemCoreClockUpdate(); /* Set the clock frequency to 11MHz so the ADC can run on the undivided HFCLK */ CMU_HFRCOBandSet(cmuHFRCOBand_11MHz); /* ACMP */ CMU_ClockEnable(cmuClock_ACMP0, true); /* GPIO */ CMU_ClockEnable(cmuClock_GPIO, true); /* ADC */ CMU_ClockEnable(cmuClock_ADC0, true); /* Low energy peripherals * LESENSE * LFRCO clock must be enables prior to enabling * clock for the low energy peripherals */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO); CMU_ClockEnable(cmuClock_CORELE, true); CMU_ClockEnable(cmuClock_LESENSE, true); /* RTC */ CMU_ClockEnable(cmuClock_RTC, true); /* Disable clock source for LFB clock. */ CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_Disabled); } /**************************************************************************//** * @brief Sets up the ACMP *****************************************************************************/ void setupACMP(void) { /* Configuration structure for ACMP */ static const ACMP_Init_TypeDef acmpInit = { .fullBias = false, /* The lightsensor is slow acting, */ .halfBias = true, /* comparator bias current can be set to lowest setting.*/ .biasProg = 0x0, /* Analog comparator will still be fast enough */ .interruptOnFallingEdge = false, /* No comparator interrupt, lesense will issue interrupts. */ .interruptOnRisingEdge = false, .warmTime = acmpWarmTime512, /* Not applicable, lesense controls this. */ .hysteresisLevel = acmpHysteresisLevel5, /* Some hysteresis will prevent excessive toggling. */ .inactiveValue = false, /* Not applicable, lesense controls this. */ .lowPowerReferenceEnabled = false, /* Can be enabled for even lower power. */ .vddLevel = 0x00, /* Not applicable, lesense controls this through .acmpThres value. */ .enable = false /* Not applicable, lesense controls this. */ }; /* Initialize ACMP */ ACMP_Init(ACMP0, &acmpInit); /* Disable ACMP0 out to a pin. */ ACMP_GPIOSetup(ACMP0, 0, false, false); /* Set up ACMP negSel to VDD, posSel is controlled by LESENSE. */ ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel0); /* LESENSE controls ACMP thus ACMP_Enable(ACMP0) should NOT be called in order * to ensure lower current consumption. */ } /**************************************************************************//** * @brief Sets up the LESENSE *****************************************************************************/ void setupLESENSE(void) { /* LESENSE configuration structure */ static const LESENSE_Init_TypeDef initLesense = { .coreCtrl = { /* LESENSE configured for periodic scan. */ .scanStart = lesenseScanStartPeriodic, .prsSel = lesensePRSCh0, .scanConfSel = lesenseScanConfDirMap, .invACMP0 = false, .invACMP1 = false, .dualSample = false, .storeScanRes = false, .bufOverWr = true, .bufTrigLevel = lesenseBufTrigHalf, .wakeupOnDMA = lesenseDMAWakeUpDisable, .biasMode = lesenseBiasModeDutyCycle, /* Lesense should duty cycle comparator and related references etc. */ .debugRun = false }, .timeCtrl = { .startDelay = 0 /* No start delay needed for this application. */ }, .perCtrl = { /* DAC is not needed for this application. */ .dacCh0Data = lesenseDACIfData, .dacCh0ConvMode = lesenseDACConvModeDisable, .dacCh0OutMode = lesenseDACOutModeDisable, .dacCh1Data = lesenseDACIfData, .dacCh1ConvMode = lesenseDACConvModeDisable, .dacCh1OutMode = lesenseDACOutModeDisable, .dacPresc = 0, .dacRef = lesenseDACRefBandGap, .acmp0Mode = lesenseACMPModeMuxThres, /* Allow LESENSE to control ACMP mux and reference threshold. */ .acmp1Mode = lesenseACMPModeMuxThres, .warmupMode = lesenseWarmupModeNormal /* Normal mode means LESENSE is allowed to dutycycle comparator and reference. */ }, .decCtrl = { /* Decoder or statemachine not used in this code example. */ .decInput = lesenseDecInputSensorSt, .initState = 0, .chkState = false, .intMap = true, .hystPRS0 = false, .hystPRS1 = false, .hystPRS2 = false, .hystIRQ = false, .prsCount = true, .prsChSel0 = lesensePRSCh0, .prsChSel1 = lesensePRSCh1, .prsChSel2 = lesensePRSCh2, .prsChSel3 = lesensePRSCh3 } }; /* Channel configuration */ /* Only one channel is configured for the lightsense application. */ static const LESENSE_ChDesc_TypeDef initLesenseCh = { .enaScanCh = true, .enaPin = false, /* Pin is input, no enabling needed. Separate pin is exciting the sensor. */ .enaInt = true, /* Enable interrupt for this channel. */ .chPinExMode = lesenseChPinExHigh, /* Excite by pullin pin high. */ .chPinIdleMode = lesenseChPinIdleDis, /* During Idle, excite pin should be disabled (tri-stated). */ .useAltEx = true, /* Use alternate excite pin. */ .shiftRes = false, /* Not applicable, only for decoder operation. */ .invRes = false, /* No need to invert result. */ .storeCntRes = true, /* Not applicable, don't care really. */ .exClk = lesenseClkLF, /* Using low frequency clock for timing the excitation. */ .sampleClk = lesenseClkLF, /* Using low frequency clock for timing the sample instant. */ .exTime = 0x01, /* 1 LFclk cycle is enough excitation time, this depends on response time of light sensor. */ .sampleDelay = 0x01, /* Sampling should happen when excitation ends, it it happens earlier, excitation time might as well be reduced. */ .measDelay = 0x00, /* Not used here, basically only used for applications which uses the counting feature. */ .acmpThres = ACMP_THRESHOLD, /* This is the analog comparator threshold setting, determines when the acmp triggers. */ .sampleMode = lesenseSampleModeACMP, /* Sampling acmp, not counting. */ .intMode = lesenseSetIntLevel, /* Interrupt when voltage goes above threshold. */ .cntThres = 0x0000, /* Not applicable. */ .compMode = lesenseCompModeLess /* Not applicable. */ }; /* Alternate excitation channels configuration. */ /* The lightsensor is excited by alternate excite channel 0. */ static const LESENSE_ConfAltEx_TypeDef initAltEx = { .altExMap = lesenseAltExMapALTEX, .AltEx[0] = { .enablePin = true, .idleConf = lesenseAltExPinIdleDis, .alwaysEx = true }, .AltEx[1] = LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF, .AltEx[2] = LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF, .AltEx[3] = LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF, .AltEx[4] = LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF, .AltEx[5] = LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF, .AltEx[6] = LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF, .AltEx[7] = LESENSE_LIGHTSENSE_ALTEX_DIS_CH_CONF }; /* Initialize LESENSE interface _with_ RESET. */ LESENSE_Init(&initLesense, true); /* Configure LESENSE channel */ LESENSE_ChannelConfig(&initLesenseCh, LIGHTSENSE_CH); /* Configure alternate excitation channels */ LESENSE_AltExConfig(&initAltEx); /* Set scan frequency */ LESENSE_ScanFreqSet(0, LCSENSE_SCAN_FREQ); /* Set clock divisor for LF clock. */ LESENSE_ClkDivSet(lesenseClkLF, lesenseClkDiv_2); } /**************************************************************************//** * @brief Sets up the GPIO *****************************************************************************/ void setupGPIO(void) { /* Configure the drive strength of the ports for the light sensor. */ GPIO_DriveModeSet(LIGHTSENSE_EXCITE_PORT, gpioDriveModeStandard); GPIO_DriveModeSet(LIGHTSENSE_SENSOR_PORT, gpioDriveModeStandard); /* Initialize the 2 GPIO pins of the light sensor setup. */ GPIO_PinModeSet(LIGHTSENSE_EXCITE_PORT, LIGHTSENSE_EXCITE_PIN, gpioModePushPull, 0); GPIO_PinModeSet(LIGHTSENSE_SENSOR_PORT, LIGHTSENSE_SENSOR_PIN, gpioModeDisabled, 0); } /**************************************************************************//** * @brief Configure ADC for 12 bit mode, sample channel 0 with Vdd as reference * and use shortest acquisition time. *****************************************************************************/ static void ADC_Config(void) { CMU_ClockEnable(cmuClock_ADC0, true); ADC_Init_TypeDef init = ADC_INIT_DEFAULT; ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT; /* Init common settings for both single conversion and scan mode- */ /* Set timebase to 10, this gives 11 cycles which equals 1us at 11 MHz. */ init.timebase = 10; /* Set ADC clock prescaler to 0, we are using 11MHz HFRCO, which results in HFPERCLK < 13MHz- */ init.prescale = 0; ADC_Init(ADC0, &init); /* Init for single conversion use, measure channel 0 with Vdd as reference. */ /* Using Vdd as reference removes the 5us warmup time for the bandgap reference. */ singleInit.reference = adcRefVDD; singleInit.input = adcSingleInpCh5; /* Resolution can be set lower for even more energy efficient operation. */ singleInit.resolution = adcRes8Bit; /* Assuming we are mesuring a low impedance source we can safely use the shortest */ /* acquisition time. */ singleInit.acqTime = adcAcqTime1; ADC_InitSingle(ADC0, &singleInit); /* Enable ADC Interrupt when Single Conversion Complete. */ /* This is necessary for WFE (wait for event) to work. */ /* Notice that enabling the interrupt in the NVIC is not needed. */ ADC0->IEN = ADC_IEN_SINGLE; } /**************************************************************************//** * @brief A separate function for taking all the samples is preferred since * the whole idea is to stay in EM2 between samples. If other code is added, * it might be more energy efficient to configure the ADC to use DMA while * the cpu can do other work. *****************************************************************************/ void doAdcSampling(uint16_t* buffer) { uint16_t sample_count = 0; /* Enable RTC, this can be enabled all the time as well if needed. */ RTC_Enable(true); while(sample_count < BUFFER_SAMPLES) { /* Enable deep sleep to enter EM2 between samples. */ SCB->SCR = SCB_SCR_SEVONPEND_Msk | SCB_SCR_SLEEPDEEP_Msk; /* Go to sleep while waiting for RTC event (set by RTC_IRQ pending bit) */ /* Since IRQ is not enabled in the NVIC, no ISR will be entered */ __WFE(); /* Start ADC conversion as soon as we wake up. */ ADC_Start(ADC0, adcStartSingle); /* Clear the interrupt flag */ RTC_IntClear(RTC_IF_COMP0); /* Clear pending RTC IRQ */ NVIC_ClearPendingIRQ(RTC_IRQn); /* Wait while conversion is active in EM1, should be almost finished since it */ /* takes 13 cycles + warmup (1us), and it was started a while ago. */ /* Disable deep sleep so we wait in EM1 for conversion to finish. */ SCB->SCR = SCB_SCR_SEVONPEND_Msk; __WFE(); /* Clear the interrupt flag */ ADC_IntClear(ADC0, ADC_IF_SINGLE); /* Clear pending IRQ */ NVIC_ClearPendingIRQ(ADC0_IRQn); /* Get ADC result */ buffer[sample_count++] = ADC_DataSingleGet(ADC0); } RTC_Enable(false); } /***************************************************************************//** * @brief * Process the sampled data through FFT. *******************************************************************************/ void ProcessFFT(void) { uint16_t *inBuf; int32_t value; int i; inBuf = lightToFFTBuffer; /* * Convert to float values. */ for (i = 0; i < BUFFER_SAMPLES; ++i) { value = (int32_t)*inBuf++; floatBuf[i] = (float32_t)value; } /* Process the data through the RFFT module, resulting complex output is * stored in fftOutputComplex */ arm_rfft_f32(&rfft_instance, floatBuf, fftOutputComplex); /* Compute the magnitude of all the resulting complex numbers */ arm_cmplx_mag_f32(fftOutputComplex, fftOutputMag, BUFFER_SAMPLES); } /***************************************************************************//** * @brief * Find the maximal bin and estimate the frequency using sinc interpolation. * @return * Frequency of maximal peak *******************************************************************************/ float32_t GetFreq(void) { float32_t maxVal; uint32_t maxIndex; /* Real and imag components of maximal bin and bins on each side */ float32_t rz_p, iz_p, rz_n, iz_n, rz_0, iz_0; /* Small correction to the "index" of the maximal bin */ float32_t deltaIndex; /* Real and imag components of the intermediate result */ float32_t a, b, c, d; #define START_INDEX 4 /* Find the biggest bin, disregarding the first bins because of DC offset and * low frequency noise. */ arm_max_f32(&fftOutputMag[START_INDEX], BUFFER_SAMPLES / 2 - START_INDEX, &maxVal, &maxIndex); maxIndex += START_INDEX; /* Perform sinc() interpolation using the two bins on each side of the * maximal bin. For more information see page 113 of * http://tmo.jpl.nasa.gov/progress_report/42-118/118I.pdf */ /* z_{peak} */ rz_0 = fftOutputComplex[maxIndex * 2]; iz_0 = fftOutputComplex[maxIndex * 2 + 1]; /* z_{peak+1} */ rz_p = fftOutputComplex[maxIndex * 2 + 2]; iz_p = fftOutputComplex[maxIndex * 2 + 2 + 1]; /* z_{peak-1} */ rz_n = fftOutputComplex[maxIndex * 2 - 2]; iz_n = fftOutputComplex[maxIndex * 2 - 2 + 1]; /* z_{peak+1} - z_{peak-1} */ a = rz_p - rz_n; b = iz_p - iz_n; /* z_{peak+1} + z_{peak-1} - 2*z_{peak} */ c = rz_p + rz_n - (float32_t)2.0 * rz_0; d = iz_p + iz_n - (float32_t)2.0 * iz_0; /* Re (z_{peak+1} - z_{peak-1}) / (z_{peak+1} + z_{peak-1} - 2*z_{peak}) */ deltaIndex = (a*c + b*d) / (c*c + d*d); return ((float32_t)maxIndex + deltaIndex) * (float32_t)SAMPLE_RATE / (float32_t)BUFFER_SAMPLES; } /***************************************************************************//** * @brief * Main function. Setup ADC, FFT, clocks, PRS, DMA, Timer, * and process FFT forever. *******************************************************************************/ int main(void) { uint32_t time; arm_status status; /* Chip errata */ CHIP_Init(); /* Enable clocks for used peripherals */ setupCMU(); /* Setup the ACMP */ setupACMP(); /* Setup the GPIO */ setupGPIO(); /* setup lesense */ setupLESENSE(); /* Enable LCD without voltage boost */ SegmentLCD_Init(false); SegmentLCD_Symbol(LCD_SYMBOL_GECKO, 1); SegmentLCD_Symbol(LCD_SYMBOL_EFM32, 1); /* Initialize the CFFT/CIFFT module */ status = arm_rfft_init_f32(&rfft_instance, &cfft_instance, BUFFER_SAMPLES, 0, /* forward transform */ 1); /* normal, not bitreversed, order */ if (status != ARM_MATH_SUCCESS) { /* Error initializing RFFT module. */ SegmentLCD_Write(" Error "); while (1) ; } /* Configure RTC to use LFXO as clock source */ RTC_Setup(cmuSelect_LFXO); /* Configure ADC */ ADC_Config(); /* Enable DWT */ CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; /* Make sure CYCCNT is running */ DWT->CTRL |= 1; while (1) { /* Power the light sensor with GPIO. */ GPIO_PinModeSet( EXCITE_PIN, gpioModePushPull, 1); /* Do sampling. */ doAdcSampling(lightToFFTBuffer); /* Power off the light sensor. */ GPIO_PinModeSet( EXCITE_PIN, gpioModeDisabled, 0); /* Do FFT, measure number of cpu cycles used. */ time = DWT->CYCCNT; ProcessFFT(); time = DWT->CYCCNT - time; /* Display dominant frequency. */ SegmentLCD_Number( (int)GetFreq() ); /* Display cpu cycle count used to do FFT. */ SegmentLCD_LowerNumber( (int)time ); /* Check last ADC value to determine if lightlevel is too low. */ /* Go to sleep with lesense enabled if ADC reading is below 10. */ if(lightToFFTBuffer[BUFFER_SAMPLES-1] < 10) { /* Write to LCD that lightlevel is too low. */ SegmentLCD_NumberOff(); SegmentLCD_Write("DARK"); /* Set gpio in pushpull for lesense operation. */ GPIO_PinModeSet(LIGHTSENSE_EXCITE_PORT, LIGHTSENSE_EXCITE_PIN, gpioModePushPull, 0); LESENSE->ROUTE = LESENSE_ROUTE_ALTEX0PEN; /* Start scan. */ LESENSE_ScanStart(); /* Enable deep sleep to enter EM2. */ SCB->SCR = SCB_SCR_SEVONPEND_Msk | SCB_SCR_SLEEPDEEP_Msk; /* Go to sleep while waiting for LESENSE event */ /* Since IRQ is not enabled in the NVIC, no ISR will be entered */ __WFE(); /* Clear interrupt flag */ LESENSE_IntClear(LIGHTSENSE_INTERRUPT); /* Clear pending RTC IRQ */ NVIC_ClearPendingIRQ(LESENSE_IRQn); LESENSE_ScanStop(); LESENSE->ROUTE &= ~LESENSE_ROUTE_ALTEX0PEN; } } }
DBG, , ( light sensor), .
: . , â 100 ( 50 , « » , , .. ). «DARK», â «» .
energy profiler , , .
EFM32WG-STK3800.
EFM32WG990F256 49 , â 411 . Cortex-M3, DSP- FPU- .
EFM32WG990F256 EFM32GG990F1024,
, cortex-m3 cortex-m4,
fpu.
, IDE , , .
, .
: 48 , , .
, . «» . Cortex-M3 2.2 , .
, , Cortex-M3, , .
, .