You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

преди 11 години
преди 7 години
преди 11 години
преди 7 години
преди 11 години
преди 7 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 8 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 9 години
преди 9 години
преди 9 години
преди 11 години
преди 10 години
преди 11 години
преди 9 години
преди 9 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 11 години
преди 8 години
преди 11 години
преди 11 години
преди 10 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 6 години
преди 10 години
преди 9 години
преди 10 години
преди 8 години
преди 9 години
преди 11 години
преди 9 години
преди 10 години
преди 9 години
преди 10 години
преди 9 години
преди 11 години
преди 9 години
преди 10 години
преди 9 години
преди 10 години
преди 9 години
преди 10 години
преди 9 години
преди 10 години
преди 11 години
преди 11 години
преди 8 години
преди 9 години
преди 11 години
преди 8 години
преди 11 години
преди 9 години
преди 8 години
преди 9 години
преди 9 години
преди 11 години
преди 8 години
преди 11 години
преди 9 години
преди 8 години
преди 9 години
преди 11 години
преди 11 години
преди 6 години
преди 11 години
преди 6 години
преди 11 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 9 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 9 години
преди 8 години
преди 9 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 9 години
преди 9 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 9 години
преди 8 години
преди 11 години
преди 8 години
преди 11 години
преди 11 години
преди 9 години
преди 11 години
преди 10 години
преди 6 години
преди 8 години
преди 8 години
преди 10 години
преди 11 години
преди 10 години
преди 11 години
преди 10 години
преди 10 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
преди 11 години
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351
  1. /* Teensyduino Core Library
  2. * http://www.pjrc.com/teensy/
  3. * Copyright (c) 2017 PJRC.COM, LLC.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * 1. The above copyright notice and this permission notice shall be
  14. * included in all copies or substantial portions of the Software.
  15. *
  16. * 2. If the Software is incorporated into a build system that allows
  17. * selection among a list of target devices, then similar target
  18. * devices manufactured by PJRC.COM must be included in the list of
  19. * target devices and selectable in the same manner.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  22. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  23. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  24. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  25. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  26. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  27. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  28. * SOFTWARE.
  29. */
  30. #include "core_pins.h"
  31. #include "pins_arduino.h"
  32. #include "HardwareSerial.h"
  33. #if defined(KINETISK)
  34. #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
  35. #define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
  36. //#define GPIO_SET_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 1)
  37. //#define GPIO_CLR_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 0)
  38. const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
  39. {GPIO_BITBAND_PTR(CORE_PIN0_PORTREG, CORE_PIN0_BIT), &CORE_PIN0_CONFIG},
  40. {GPIO_BITBAND_PTR(CORE_PIN1_PORTREG, CORE_PIN1_BIT), &CORE_PIN1_CONFIG},
  41. {GPIO_BITBAND_PTR(CORE_PIN2_PORTREG, CORE_PIN2_BIT), &CORE_PIN2_CONFIG},
  42. {GPIO_BITBAND_PTR(CORE_PIN3_PORTREG, CORE_PIN3_BIT), &CORE_PIN3_CONFIG},
  43. {GPIO_BITBAND_PTR(CORE_PIN4_PORTREG, CORE_PIN4_BIT), &CORE_PIN4_CONFIG},
  44. {GPIO_BITBAND_PTR(CORE_PIN5_PORTREG, CORE_PIN5_BIT), &CORE_PIN5_CONFIG},
  45. {GPIO_BITBAND_PTR(CORE_PIN6_PORTREG, CORE_PIN6_BIT), &CORE_PIN6_CONFIG},
  46. {GPIO_BITBAND_PTR(CORE_PIN7_PORTREG, CORE_PIN7_BIT), &CORE_PIN7_CONFIG},
  47. {GPIO_BITBAND_PTR(CORE_PIN8_PORTREG, CORE_PIN8_BIT), &CORE_PIN8_CONFIG},
  48. {GPIO_BITBAND_PTR(CORE_PIN9_PORTREG, CORE_PIN9_BIT), &CORE_PIN9_CONFIG},
  49. {GPIO_BITBAND_PTR(CORE_PIN10_PORTREG, CORE_PIN10_BIT), &CORE_PIN10_CONFIG},
  50. {GPIO_BITBAND_PTR(CORE_PIN11_PORTREG, CORE_PIN11_BIT), &CORE_PIN11_CONFIG},
  51. {GPIO_BITBAND_PTR(CORE_PIN12_PORTREG, CORE_PIN12_BIT), &CORE_PIN12_CONFIG},
  52. {GPIO_BITBAND_PTR(CORE_PIN13_PORTREG, CORE_PIN13_BIT), &CORE_PIN13_CONFIG},
  53. {GPIO_BITBAND_PTR(CORE_PIN14_PORTREG, CORE_PIN14_BIT), &CORE_PIN14_CONFIG},
  54. {GPIO_BITBAND_PTR(CORE_PIN15_PORTREG, CORE_PIN15_BIT), &CORE_PIN15_CONFIG},
  55. {GPIO_BITBAND_PTR(CORE_PIN16_PORTREG, CORE_PIN16_BIT), &CORE_PIN16_CONFIG},
  56. {GPIO_BITBAND_PTR(CORE_PIN17_PORTREG, CORE_PIN17_BIT), &CORE_PIN17_CONFIG},
  57. {GPIO_BITBAND_PTR(CORE_PIN18_PORTREG, CORE_PIN18_BIT), &CORE_PIN18_CONFIG},
  58. {GPIO_BITBAND_PTR(CORE_PIN19_PORTREG, CORE_PIN19_BIT), &CORE_PIN19_CONFIG},
  59. {GPIO_BITBAND_PTR(CORE_PIN20_PORTREG, CORE_PIN20_BIT), &CORE_PIN20_CONFIG},
  60. {GPIO_BITBAND_PTR(CORE_PIN21_PORTREG, CORE_PIN21_BIT), &CORE_PIN21_CONFIG},
  61. {GPIO_BITBAND_PTR(CORE_PIN22_PORTREG, CORE_PIN22_BIT), &CORE_PIN22_CONFIG},
  62. {GPIO_BITBAND_PTR(CORE_PIN23_PORTREG, CORE_PIN23_BIT), &CORE_PIN23_CONFIG},
  63. {GPIO_BITBAND_PTR(CORE_PIN24_PORTREG, CORE_PIN24_BIT), &CORE_PIN24_CONFIG},
  64. {GPIO_BITBAND_PTR(CORE_PIN25_PORTREG, CORE_PIN25_BIT), &CORE_PIN25_CONFIG},
  65. {GPIO_BITBAND_PTR(CORE_PIN26_PORTREG, CORE_PIN26_BIT), &CORE_PIN26_CONFIG},
  66. {GPIO_BITBAND_PTR(CORE_PIN27_PORTREG, CORE_PIN27_BIT), &CORE_PIN27_CONFIG},
  67. {GPIO_BITBAND_PTR(CORE_PIN28_PORTREG, CORE_PIN28_BIT), &CORE_PIN28_CONFIG},
  68. {GPIO_BITBAND_PTR(CORE_PIN29_PORTREG, CORE_PIN29_BIT), &CORE_PIN29_CONFIG},
  69. {GPIO_BITBAND_PTR(CORE_PIN30_PORTREG, CORE_PIN30_BIT), &CORE_PIN30_CONFIG},
  70. {GPIO_BITBAND_PTR(CORE_PIN31_PORTREG, CORE_PIN31_BIT), &CORE_PIN31_CONFIG},
  71. {GPIO_BITBAND_PTR(CORE_PIN32_PORTREG, CORE_PIN32_BIT), &CORE_PIN32_CONFIG},
  72. {GPIO_BITBAND_PTR(CORE_PIN33_PORTREG, CORE_PIN33_BIT), &CORE_PIN33_CONFIG},
  73. #ifdef CORE_PIN34_PORTREG
  74. {GPIO_BITBAND_PTR(CORE_PIN34_PORTREG, CORE_PIN34_BIT), &CORE_PIN34_CONFIG},
  75. {GPIO_BITBAND_PTR(CORE_PIN35_PORTREG, CORE_PIN35_BIT), &CORE_PIN35_CONFIG},
  76. {GPIO_BITBAND_PTR(CORE_PIN36_PORTREG, CORE_PIN36_BIT), &CORE_PIN36_CONFIG},
  77. {GPIO_BITBAND_PTR(CORE_PIN37_PORTREG, CORE_PIN37_BIT), &CORE_PIN37_CONFIG},
  78. {GPIO_BITBAND_PTR(CORE_PIN38_PORTREG, CORE_PIN38_BIT), &CORE_PIN38_CONFIG},
  79. {GPIO_BITBAND_PTR(CORE_PIN39_PORTREG, CORE_PIN39_BIT), &CORE_PIN39_CONFIG},
  80. {GPIO_BITBAND_PTR(CORE_PIN40_PORTREG, CORE_PIN40_BIT), &CORE_PIN40_CONFIG},
  81. {GPIO_BITBAND_PTR(CORE_PIN41_PORTREG, CORE_PIN41_BIT), &CORE_PIN41_CONFIG},
  82. {GPIO_BITBAND_PTR(CORE_PIN42_PORTREG, CORE_PIN42_BIT), &CORE_PIN42_CONFIG},
  83. {GPIO_BITBAND_PTR(CORE_PIN43_PORTREG, CORE_PIN43_BIT), &CORE_PIN43_CONFIG},
  84. {GPIO_BITBAND_PTR(CORE_PIN44_PORTREG, CORE_PIN44_BIT), &CORE_PIN44_CONFIG},
  85. {GPIO_BITBAND_PTR(CORE_PIN45_PORTREG, CORE_PIN45_BIT), &CORE_PIN45_CONFIG},
  86. {GPIO_BITBAND_PTR(CORE_PIN46_PORTREG, CORE_PIN46_BIT), &CORE_PIN46_CONFIG},
  87. {GPIO_BITBAND_PTR(CORE_PIN47_PORTREG, CORE_PIN47_BIT), &CORE_PIN47_CONFIG},
  88. {GPIO_BITBAND_PTR(CORE_PIN48_PORTREG, CORE_PIN48_BIT), &CORE_PIN48_CONFIG},
  89. {GPIO_BITBAND_PTR(CORE_PIN49_PORTREG, CORE_PIN49_BIT), &CORE_PIN49_CONFIG},
  90. {GPIO_BITBAND_PTR(CORE_PIN50_PORTREG, CORE_PIN50_BIT), &CORE_PIN50_CONFIG},
  91. {GPIO_BITBAND_PTR(CORE_PIN51_PORTREG, CORE_PIN51_BIT), &CORE_PIN51_CONFIG},
  92. {GPIO_BITBAND_PTR(CORE_PIN52_PORTREG, CORE_PIN52_BIT), &CORE_PIN52_CONFIG},
  93. {GPIO_BITBAND_PTR(CORE_PIN53_PORTREG, CORE_PIN53_BIT), &CORE_PIN53_CONFIG},
  94. {GPIO_BITBAND_PTR(CORE_PIN54_PORTREG, CORE_PIN54_BIT), &CORE_PIN54_CONFIG},
  95. {GPIO_BITBAND_PTR(CORE_PIN55_PORTREG, CORE_PIN55_BIT), &CORE_PIN55_CONFIG},
  96. {GPIO_BITBAND_PTR(CORE_PIN56_PORTREG, CORE_PIN56_BIT), &CORE_PIN56_CONFIG},
  97. {GPIO_BITBAND_PTR(CORE_PIN57_PORTREG, CORE_PIN57_BIT), &CORE_PIN57_CONFIG},
  98. {GPIO_BITBAND_PTR(CORE_PIN58_PORTREG, CORE_PIN58_BIT), &CORE_PIN58_CONFIG},
  99. {GPIO_BITBAND_PTR(CORE_PIN59_PORTREG, CORE_PIN59_BIT), &CORE_PIN59_CONFIG},
  100. {GPIO_BITBAND_PTR(CORE_PIN60_PORTREG, CORE_PIN60_BIT), &CORE_PIN60_CONFIG},
  101. {GPIO_BITBAND_PTR(CORE_PIN61_PORTREG, CORE_PIN61_BIT), &CORE_PIN61_CONFIG},
  102. {GPIO_BITBAND_PTR(CORE_PIN62_PORTREG, CORE_PIN62_BIT), &CORE_PIN62_CONFIG},
  103. {GPIO_BITBAND_PTR(CORE_PIN63_PORTREG, CORE_PIN63_BIT), &CORE_PIN63_CONFIG},
  104. #endif
  105. };
  106. #elif defined(KINETISL)
  107. const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
  108. {((volatile uint8_t *)&CORE_PIN0_PORTREG + (CORE_PIN0_BIT >> 3)), &CORE_PIN0_CONFIG, (1<<(CORE_PIN0_BIT & 7))},
  109. {((volatile uint8_t *)&CORE_PIN1_PORTREG + (CORE_PIN1_BIT >> 3)), &CORE_PIN1_CONFIG, (1<<(CORE_PIN1_BIT & 7))},
  110. {((volatile uint8_t *)&CORE_PIN2_PORTREG + (CORE_PIN2_BIT >> 3)), &CORE_PIN2_CONFIG, (1<<(CORE_PIN2_BIT & 7))},
  111. {((volatile uint8_t *)&CORE_PIN3_PORTREG + (CORE_PIN3_BIT >> 3)), &CORE_PIN3_CONFIG, (1<<(CORE_PIN3_BIT & 7))},
  112. {((volatile uint8_t *)&CORE_PIN4_PORTREG + (CORE_PIN4_BIT >> 3)), &CORE_PIN4_CONFIG, (1<<(CORE_PIN4_BIT & 7))},
  113. {((volatile uint8_t *)&CORE_PIN5_PORTREG + (CORE_PIN5_BIT >> 3)), &CORE_PIN5_CONFIG, (1<<(CORE_PIN5_BIT & 7))},
  114. {((volatile uint8_t *)&CORE_PIN6_PORTREG + (CORE_PIN6_BIT >> 3)), &CORE_PIN6_CONFIG, (1<<(CORE_PIN6_BIT & 7))},
  115. {((volatile uint8_t *)&CORE_PIN7_PORTREG + (CORE_PIN7_BIT >> 3)), &CORE_PIN7_CONFIG, (1<<(CORE_PIN7_BIT & 7))},
  116. {((volatile uint8_t *)&CORE_PIN8_PORTREG + (CORE_PIN8_BIT >> 3)), &CORE_PIN8_CONFIG, (1<<(CORE_PIN8_BIT & 7))},
  117. {((volatile uint8_t *)&CORE_PIN9_PORTREG + (CORE_PIN9_BIT >> 3)), &CORE_PIN9_CONFIG, (1<<(CORE_PIN9_BIT & 7))},
  118. {((volatile uint8_t *)&CORE_PIN10_PORTREG + (CORE_PIN10_BIT >> 3)), &CORE_PIN10_CONFIG, (1<<(CORE_PIN10_BIT & 7))},
  119. {((volatile uint8_t *)&CORE_PIN11_PORTREG + (CORE_PIN11_BIT >> 3)), &CORE_PIN11_CONFIG, (1<<(CORE_PIN11_BIT & 7))},
  120. {((volatile uint8_t *)&CORE_PIN12_PORTREG + (CORE_PIN12_BIT >> 3)), &CORE_PIN12_CONFIG, (1<<(CORE_PIN12_BIT & 7))},
  121. {((volatile uint8_t *)&CORE_PIN13_PORTREG + (CORE_PIN13_BIT >> 3)), &CORE_PIN13_CONFIG, (1<<(CORE_PIN13_BIT & 7))},
  122. {((volatile uint8_t *)&CORE_PIN14_PORTREG + (CORE_PIN14_BIT >> 3)), &CORE_PIN14_CONFIG, (1<<(CORE_PIN14_BIT & 7))},
  123. {((volatile uint8_t *)&CORE_PIN15_PORTREG + (CORE_PIN15_BIT >> 3)), &CORE_PIN15_CONFIG, (1<<(CORE_PIN15_BIT & 7))},
  124. {((volatile uint8_t *)&CORE_PIN16_PORTREG + (CORE_PIN16_BIT >> 3)), &CORE_PIN16_CONFIG, (1<<(CORE_PIN16_BIT & 7))},
  125. {((volatile uint8_t *)&CORE_PIN17_PORTREG + (CORE_PIN17_BIT >> 3)), &CORE_PIN17_CONFIG, (1<<(CORE_PIN17_BIT & 7))},
  126. {((volatile uint8_t *)&CORE_PIN18_PORTREG + (CORE_PIN18_BIT >> 3)), &CORE_PIN18_CONFIG, (1<<(CORE_PIN18_BIT & 7))},
  127. {((volatile uint8_t *)&CORE_PIN19_PORTREG + (CORE_PIN19_BIT >> 3)), &CORE_PIN19_CONFIG, (1<<(CORE_PIN19_BIT & 7))},
  128. {((volatile uint8_t *)&CORE_PIN20_PORTREG + (CORE_PIN20_BIT >> 3)), &CORE_PIN20_CONFIG, (1<<(CORE_PIN20_BIT & 7))},
  129. {((volatile uint8_t *)&CORE_PIN21_PORTREG + (CORE_PIN21_BIT >> 3)), &CORE_PIN21_CONFIG, (1<<(CORE_PIN21_BIT & 7))},
  130. {((volatile uint8_t *)&CORE_PIN22_PORTREG + (CORE_PIN22_BIT >> 3)), &CORE_PIN22_CONFIG, (1<<(CORE_PIN22_BIT & 7))},
  131. {((volatile uint8_t *)&CORE_PIN23_PORTREG + (CORE_PIN23_BIT >> 3)), &CORE_PIN23_CONFIG, (1<<(CORE_PIN23_BIT & 7))},
  132. {((volatile uint8_t *)&CORE_PIN24_PORTREG + (CORE_PIN24_BIT >> 3)), &CORE_PIN24_CONFIG, (1<<(CORE_PIN24_BIT & 7))},
  133. {((volatile uint8_t *)&CORE_PIN25_PORTREG + (CORE_PIN25_BIT >> 3)), &CORE_PIN25_CONFIG, (1<<(CORE_PIN25_BIT & 7))},
  134. {((volatile uint8_t *)&CORE_PIN26_PORTREG + (CORE_PIN26_BIT >> 3)), &CORE_PIN26_CONFIG, (1<<(CORE_PIN26_BIT & 7))}
  135. };
  136. #endif
  137. static void dummy_isr() {};
  138. typedef void (*voidFuncPtr)(void);
  139. #if defined(KINETISK)
  140. #ifdef NO_PORT_ISR_FASTRUN
  141. static void port_A_isr(void);
  142. static void port_B_isr(void);
  143. static void port_C_isr(void);
  144. static void port_D_isr(void);
  145. static void port_E_isr(void);
  146. #else
  147. static void port_A_isr(void) __attribute__ ((section(".fastrun"), noinline, noclone ));
  148. static void port_B_isr(void) __attribute__ ((section(".fastrun"), noinline, noclone ));
  149. static void port_C_isr(void) __attribute__ ((section(".fastrun"), noinline, noclone ));
  150. static void port_D_isr(void) __attribute__ ((section(".fastrun"), noinline, noclone ));
  151. static void port_E_isr(void) __attribute__ ((section(".fastrun"), noinline, noclone ));
  152. #endif
  153. voidFuncPtr isr_table_portA[CORE_MAX_PIN_PORTA+1] = { [0 ... CORE_MAX_PIN_PORTA] = dummy_isr };
  154. voidFuncPtr isr_table_portB[CORE_MAX_PIN_PORTB+1] = { [0 ... CORE_MAX_PIN_PORTB] = dummy_isr };
  155. voidFuncPtr isr_table_portC[CORE_MAX_PIN_PORTC+1] = { [0 ... CORE_MAX_PIN_PORTC] = dummy_isr };
  156. voidFuncPtr isr_table_portD[CORE_MAX_PIN_PORTD+1] = { [0 ... CORE_MAX_PIN_PORTD] = dummy_isr };
  157. voidFuncPtr isr_table_portE[CORE_MAX_PIN_PORTE+1] = { [0 ... CORE_MAX_PIN_PORTE] = dummy_isr };
  158. // The Pin Config Register is used to look up the correct interrupt table
  159. // for the corresponding port.
  160. static inline voidFuncPtr* getIsrTable(volatile uint32_t *config) {
  161. voidFuncPtr* isr_table = NULL;
  162. if(&PORTA_PCR0 <= config && config <= &PORTA_PCR31) isr_table = isr_table_portA;
  163. else if(&PORTB_PCR0 <= config && config <= &PORTB_PCR31) isr_table = isr_table_portB;
  164. else if(&PORTC_PCR0 <= config && config <= &PORTC_PCR31) isr_table = isr_table_portC;
  165. else if(&PORTD_PCR0 <= config && config <= &PORTD_PCR31) isr_table = isr_table_portD;
  166. else if(&PORTE_PCR0 <= config && config <= &PORTE_PCR31) isr_table = isr_table_portE;
  167. return isr_table;
  168. }
  169. inline uint32_t getPinIndex(volatile uint32_t *config) {
  170. uintptr_t v = (uintptr_t) config;
  171. // There are 32 pin config registers for each port, each port starting at a round address.
  172. // They are spaced 4 bytes apart.
  173. return (v % 128) / 4;
  174. }
  175. #elif defined(KINETISL)
  176. volatile static voidFuncPtr intFunc[CORE_NUM_DIGITAL] = { [0 ... CORE_NUM_DIGITAL-1] = dummy_isr };
  177. static void porta_interrupt(void);
  178. static void portcd_interrupt(void);
  179. #endif
  180. void attachInterruptVector(enum IRQ_NUMBER_t irq, void (*function)(void))
  181. {
  182. _VectorsRam[irq + 16] = function;
  183. }
  184. void attachInterrupt(uint8_t pin, void (*function)(void), int mode)
  185. {
  186. volatile uint32_t *config;
  187. uint32_t cfg, mask;
  188. if (pin >= CORE_NUM_DIGITAL) return;
  189. switch (mode) {
  190. case CHANGE: mask = 0x0B; break;
  191. case RISING: mask = 0x09; break;
  192. case FALLING: mask = 0x0A; break;
  193. case LOW: mask = 0x08; break;
  194. case HIGH: mask = 0x0C; break;
  195. default: return;
  196. }
  197. mask = (mask << 16) | 0x01000000;
  198. config = portConfigRegister(pin);
  199. if ((*config & 0x00000700) == 0) {
  200. // for compatibility with programs which depend
  201. // on AVR hardware default to input mode.
  202. pinMode(pin, INPUT);
  203. }
  204. #if defined(KINETISK)
  205. attachInterruptVector(IRQ_PORTA, port_A_isr);
  206. attachInterruptVector(IRQ_PORTB, port_B_isr);
  207. attachInterruptVector(IRQ_PORTC, port_C_isr);
  208. attachInterruptVector(IRQ_PORTD, port_D_isr);
  209. attachInterruptVector(IRQ_PORTE, port_E_isr);
  210. voidFuncPtr* isr_table = getIsrTable(config);
  211. if(!isr_table) return;
  212. uint32_t pin_index = getPinIndex(config);
  213. __disable_irq();
  214. cfg = *config;
  215. cfg &= ~0x000F0000; // disable any previous interrupt
  216. *config = cfg;
  217. isr_table[pin_index] = function; // set the function pointer
  218. cfg |= mask;
  219. *config = cfg; // enable the new interrupt
  220. __enable_irq();
  221. #elif defined(KINETISL)
  222. attachInterruptVector(IRQ_PORTA, porta_interrupt);
  223. attachInterruptVector(IRQ_PORTCD, portcd_interrupt);
  224. __disable_irq();
  225. cfg = *config;
  226. cfg &= ~0x000F0000; // disable any previous interrupt
  227. *config = cfg;
  228. intFunc[pin] = function; // set the function pointer
  229. cfg |= mask;
  230. *config = cfg; // enable the new interrupt
  231. __enable_irq();
  232. #endif
  233. }
  234. void detachInterrupt(uint8_t pin)
  235. {
  236. volatile uint32_t *config;
  237. config = portConfigRegister(pin);
  238. #if defined(KINETISK)
  239. voidFuncPtr* isr_table = getIsrTable(config);
  240. if(!isr_table) return;
  241. uint32_t pin_index = getPinIndex(config);
  242. __disable_irq();
  243. *config = ((*config & ~0x000F0000) | 0x01000000);
  244. isr_table[pin_index] = dummy_isr;
  245. __enable_irq();
  246. #elif defined(KINETISL)
  247. __disable_irq();
  248. *config = ((*config & ~0x000F0000) | 0x01000000);
  249. intFunc[pin] = dummy_isr;
  250. __enable_irq();
  251. #endif
  252. }
  253. typedef void (*voidFuncPtr)(void);
  254. // Using CTZ instead of CLZ is faster, since it allows more efficient bit
  255. // clearing and fast indexing into the pin ISR table.
  256. #define PORT_ISR_FUNCTION_CLZ(port_name) \
  257. static void port_ ## port_name ## _isr(void) { \
  258. uint32_t isfr = PORT ## port_name ##_ISFR; \
  259. PORT ## port_name ##_ISFR = isfr; \
  260. voidFuncPtr* isr_table = isr_table_port ## port_name; \
  261. uint32_t bit_nr; \
  262. while(isfr) { \
  263. bit_nr = __builtin_ctz(isfr); \
  264. isr_table[bit_nr](); \
  265. isfr = isfr & (isfr-1); \
  266. if(!isfr) return; \
  267. } \
  268. }
  269. // END PORT_ISR_FUNCTION_CLZ
  270. #if defined(KINETISK)
  271. PORT_ISR_FUNCTION_CLZ(A)
  272. PORT_ISR_FUNCTION_CLZ(B)
  273. PORT_ISR_FUNCTION_CLZ(C)
  274. PORT_ISR_FUNCTION_CLZ(D)
  275. PORT_ISR_FUNCTION_CLZ(E)
  276. #elif defined(KINETISL)
  277. // Kinetis L (Teensy LC) is based on Cortex M0 and doesn't have hardware
  278. // support for CLZ.
  279. #define DISPATCH_PIN_ISR(pin_nr) { voidFuncPtr pin_isr = intFunc[pin_nr]; \
  280. if(isfr & CORE_PIN ## pin_nr ## _BITMASK) pin_isr(); }
  281. static void porta_interrupt(void)
  282. {
  283. uint32_t isfr = PORTA_ISFR;
  284. PORTA_ISFR = isfr;
  285. DISPATCH_PIN_ISR(3);
  286. DISPATCH_PIN_ISR(4);
  287. }
  288. static void portcd_interrupt(void)
  289. {
  290. uint32_t isfr = PORTC_ISFR;
  291. PORTC_ISFR = isfr;
  292. DISPATCH_PIN_ISR(9);
  293. DISPATCH_PIN_ISR(10);
  294. DISPATCH_PIN_ISR(11);
  295. DISPATCH_PIN_ISR(12);
  296. DISPATCH_PIN_ISR(13);
  297. DISPATCH_PIN_ISR(15);
  298. DISPATCH_PIN_ISR(22);
  299. DISPATCH_PIN_ISR(23);
  300. isfr = PORTD_ISFR;
  301. PORTD_ISFR = isfr;
  302. DISPATCH_PIN_ISR(2);
  303. DISPATCH_PIN_ISR(5);
  304. DISPATCH_PIN_ISR(6);
  305. DISPATCH_PIN_ISR(7);
  306. DISPATCH_PIN_ISR(8);
  307. DISPATCH_PIN_ISR(14);
  308. DISPATCH_PIN_ISR(20);
  309. DISPATCH_PIN_ISR(21);
  310. }
  311. #undef DISPATCH_PIN_ISR
  312. #endif
  313. #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  314. unsigned long rtc_get(void)
  315. {
  316. return RTC_TSR;
  317. }
  318. void rtc_set(unsigned long t)
  319. {
  320. RTC_SR = 0;
  321. RTC_TPR = 0;
  322. RTC_TSR = t;
  323. RTC_SR = RTC_SR_TCE;
  324. }
  325. // adjust is the amount of crystal error to compensate, 1 = 0.1192 ppm
  326. // For example, adjust = -100 is slows the clock by 11.92 ppm
  327. //
  328. void rtc_compensate(int adjust)
  329. {
  330. uint32_t comp, interval, tcr;
  331. // This simple approach tries to maximize the interval.
  332. // Perhaps minimizing TCR would be better, so the
  333. // compensation is distributed more evenly across
  334. // many seconds, rather than saving it all up and then
  335. // altering one second up to +/- 0.38%
  336. if (adjust >= 0) {
  337. comp = adjust;
  338. interval = 256;
  339. while (1) {
  340. tcr = comp * interval;
  341. if (tcr < 128*256) break;
  342. if (--interval == 1) break;
  343. }
  344. tcr = tcr >> 8;
  345. } else {
  346. comp = -adjust;
  347. interval = 256;
  348. while (1) {
  349. tcr = comp * interval;
  350. if (tcr < 129*256) break;
  351. if (--interval == 1) break;
  352. }
  353. tcr = tcr >> 8;
  354. tcr = 256 - tcr;
  355. }
  356. RTC_TCR = ((interval - 1) << 8) | tcr;
  357. }
  358. #else
  359. unsigned long rtc_get(void) { return 0; }
  360. void rtc_set(unsigned long t) { }
  361. void rtc_compensate(int adjust) { }
  362. #endif
  363. #if 0
  364. // TODO: build system should define this
  365. // so RTC is automatically initialized to approx correct time
  366. // at least when the program begins running right after upload
  367. #ifndef TIME_T
  368. #define TIME_T 1350160272
  369. #endif
  370. void init_rtc(void)
  371. {
  372. serial_print("init_rtc\n");
  373. //SIM_SCGC6 |= SIM_SCGC6_RTC;
  374. // enable the RTC crystal oscillator, for approx 12pf crystal
  375. if (!(RTC_CR & RTC_CR_OSCE)) {
  376. serial_print("start RTC oscillator\n");
  377. RTC_SR = 0;
  378. RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
  379. }
  380. // should wait for crystal to stabilize.....
  381. serial_print("SR=");
  382. serial_phex32(RTC_SR);
  383. serial_print("\n");
  384. serial_print("CR=");
  385. serial_phex32(RTC_CR);
  386. serial_print("\n");
  387. serial_print("TSR=");
  388. serial_phex32(RTC_TSR);
  389. serial_print("\n");
  390. serial_print("TCR=");
  391. serial_phex32(RTC_TCR);
  392. serial_print("\n");
  393. if (RTC_SR & RTC_SR_TIF) {
  394. // enable the RTC
  395. RTC_SR = 0;
  396. RTC_TPR = 0;
  397. RTC_TSR = TIME_T;
  398. RTC_SR = RTC_SR_TCE;
  399. }
  400. }
  401. #endif
  402. extern void usb_init(void);
  403. // create a default PWM at the same 488.28 Hz as Arduino Uno
  404. #if defined(KINETISK)
  405. #define F_TIMER F_BUS
  406. #elif defined(KINETISL)
  407. #if F_CPU > 16000000
  408. #define F_TIMER (F_PLL/2)
  409. #else
  410. #define F_TIMER (F_PLL)
  411. #endif//Low Power
  412. #endif
  413. #if F_TIMER == 128000000
  414. #define DEFAULT_FTM_MOD (65536 - 1)
  415. #define DEFAULT_FTM_PRESCALE 2
  416. #elif F_TIMER == 120000000
  417. #define DEFAULT_FTM_MOD (61440 - 1)
  418. #define DEFAULT_FTM_PRESCALE 2
  419. #elif F_TIMER == 108000000
  420. #define DEFAULT_FTM_MOD (55296 - 1)
  421. #define DEFAULT_FTM_PRESCALE 2
  422. #elif F_TIMER == 96000000
  423. #define DEFAULT_FTM_MOD (49152 - 1)
  424. #define DEFAULT_FTM_PRESCALE 2
  425. #elif F_TIMER == 90000000
  426. #define DEFAULT_FTM_MOD (46080 - 1)
  427. #define DEFAULT_FTM_PRESCALE 2
  428. #elif F_TIMER == 80000000
  429. #define DEFAULT_FTM_MOD (40960 - 1)
  430. #define DEFAULT_FTM_PRESCALE 2
  431. #elif F_TIMER == 72000000
  432. #define DEFAULT_FTM_MOD (36864 - 1)
  433. #define DEFAULT_FTM_PRESCALE 2
  434. #elif F_TIMER == 64000000
  435. #define DEFAULT_FTM_MOD (65536 - 1)
  436. #define DEFAULT_FTM_PRESCALE 1
  437. #elif F_TIMER == 60000000
  438. #define DEFAULT_FTM_MOD (61440 - 1)
  439. #define DEFAULT_FTM_PRESCALE 1
  440. #elif F_TIMER == 56000000
  441. #define DEFAULT_FTM_MOD (57344 - 1)
  442. #define DEFAULT_FTM_PRESCALE 1
  443. #elif F_TIMER == 54000000
  444. #define DEFAULT_FTM_MOD (55296 - 1)
  445. #define DEFAULT_FTM_PRESCALE 1
  446. #elif F_TIMER == 48000000
  447. #define DEFAULT_FTM_MOD (49152 - 1)
  448. #define DEFAULT_FTM_PRESCALE 1
  449. #elif F_TIMER == 40000000
  450. #define DEFAULT_FTM_MOD (40960 - 1)
  451. #define DEFAULT_FTM_PRESCALE 1
  452. #elif F_TIMER == 36000000
  453. #define DEFAULT_FTM_MOD (36864 - 1)
  454. #define DEFAULT_FTM_PRESCALE 1
  455. #elif F_TIMER == 24000000
  456. #define DEFAULT_FTM_MOD (49152 - 1)
  457. #define DEFAULT_FTM_PRESCALE 0
  458. #elif F_TIMER == 16000000
  459. #define DEFAULT_FTM_MOD (32768 - 1)
  460. #define DEFAULT_FTM_PRESCALE 0
  461. #elif F_TIMER == 8000000
  462. #define DEFAULT_FTM_MOD (16384 - 1)
  463. #define DEFAULT_FTM_PRESCALE 0
  464. #elif F_TIMER == 4000000
  465. #define DEFAULT_FTM_MOD (8192 - 1)
  466. #define DEFAULT_FTM_PRESCALE 0
  467. #elif F_TIMER == 2000000
  468. #define DEFAULT_FTM_MOD (4096 - 1)
  469. #define DEFAULT_FTM_PRESCALE 0
  470. #endif
  471. //void init_pins(void)
  472. __attribute__((noinline))
  473. void _init_Teensyduino_internal_(void)
  474. {
  475. #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  476. NVIC_ENABLE_IRQ(IRQ_PORTA);
  477. NVIC_ENABLE_IRQ(IRQ_PORTB);
  478. NVIC_ENABLE_IRQ(IRQ_PORTC);
  479. NVIC_ENABLE_IRQ(IRQ_PORTD);
  480. NVIC_ENABLE_IRQ(IRQ_PORTE);
  481. #elif defined(__MKL26Z64__)
  482. NVIC_ENABLE_IRQ(IRQ_PORTA);
  483. NVIC_ENABLE_IRQ(IRQ_PORTCD);
  484. #endif
  485. //SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
  486. //SIM_SCGC6 |= SIM_SCGC6_FTM1;
  487. FTM0_CNT = 0;
  488. FTM0_MOD = DEFAULT_FTM_MOD;
  489. FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
  490. FTM0_C1SC = 0x28;
  491. FTM0_C2SC = 0x28;
  492. FTM0_C3SC = 0x28;
  493. FTM0_C4SC = 0x28;
  494. FTM0_C5SC = 0x28;
  495. #if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
  496. FTM0_C6SC = 0x28;
  497. FTM0_C7SC = 0x28;
  498. #endif
  499. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  500. FTM3_C0SC = 0x28;
  501. FTM3_C1SC = 0x28;
  502. FTM3_C2SC = 0x28;
  503. FTM3_C3SC = 0x28;
  504. FTM3_C4SC = 0x28;
  505. FTM3_C5SC = 0x28;
  506. FTM3_C6SC = 0x28;
  507. FTM3_C7SC = 0x28;
  508. #endif
  509. FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  510. FTM1_CNT = 0;
  511. FTM1_MOD = DEFAULT_FTM_MOD;
  512. FTM1_C0SC = 0x28;
  513. FTM1_C1SC = 0x28;
  514. FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  515. #if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__MKL26Z64__)
  516. FTM2_CNT = 0;
  517. FTM2_MOD = DEFAULT_FTM_MOD;
  518. FTM2_C0SC = 0x28;
  519. FTM2_C1SC = 0x28;
  520. FTM2_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  521. #endif
  522. #if defined(__MK64FX512__) || defined(__MK66FX1M0__)
  523. FTM3_CNT = 0;
  524. FTM3_MOD = DEFAULT_FTM_MOD;
  525. FTM3_C0SC = 0x28;
  526. FTM3_C1SC = 0x28;
  527. FTM3_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
  528. #endif
  529. #if defined(__MK66FX1M0__)
  530. SIM_SCGC2 |= SIM_SCGC2_TPM1;
  531. SIM_SOPT2 |= SIM_SOPT2_TPMSRC(2);
  532. TPM1_CNT = 0;
  533. TPM1_MOD = 32767;
  534. TPM1_C0SC = 0x28;
  535. TPM1_C1SC = 0x28;
  536. TPM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0);
  537. #endif
  538. analog_init();
  539. // for background about this startup delay, please see these conversations
  540. // https://forum.pjrc.com/threads/36606-startup-time-(400ms)?p=113980&viewfull=1#post113980
  541. // https://forum.pjrc.com/threads/31290-Teensey-3-2-Teensey-Loader-1-24-Issues?p=87273&viewfull=1#post87273
  542. #if TEENSYDUINO >= 142
  543. delay(25);
  544. usb_init();
  545. delay(275);
  546. #else
  547. delay(50);
  548. usb_init();
  549. delay(350);
  550. #endif
  551. }
  552. #if defined(__MK20DX128__)
  553. #define FTM0_CH0_PIN 22
  554. #define FTM0_CH1_PIN 23
  555. #define FTM0_CH2_PIN 9
  556. #define FTM0_CH3_PIN 10
  557. #define FTM0_CH4_PIN 6
  558. #define FTM0_CH5_PIN 20
  559. #define FTM0_CH6_PIN 21
  560. #define FTM0_CH7_PIN 5
  561. #define FTM1_CH0_PIN 3
  562. #define FTM1_CH1_PIN 4
  563. #elif defined(__MK20DX256__)
  564. #define FTM0_CH0_PIN 22
  565. #define FTM0_CH1_PIN 23
  566. #define FTM0_CH2_PIN 9
  567. #define FTM0_CH3_PIN 10
  568. #define FTM0_CH4_PIN 6
  569. #define FTM0_CH5_PIN 20
  570. #define FTM0_CH6_PIN 21
  571. #define FTM0_CH7_PIN 5
  572. #define FTM1_CH0_PIN 3
  573. #define FTM1_CH1_PIN 4
  574. #define FTM2_CH0_PIN 32
  575. #define FTM2_CH1_PIN 25
  576. #elif defined(__MKL26Z64__)
  577. #define FTM0_CH0_PIN 22
  578. #define FTM0_CH1_PIN 23
  579. #define FTM0_CH2_PIN 9
  580. #define FTM0_CH3_PIN 10
  581. #define FTM0_CH4_PIN 6
  582. #define FTM0_CH5_PIN 20
  583. #define FTM1_CH0_PIN 16
  584. #define FTM1_CH1_PIN 17
  585. #define FTM2_CH0_PIN 3
  586. #define FTM2_CH1_PIN 4
  587. #elif defined(__MK64FX512__)
  588. #define FTM0_CH0_PIN 22
  589. #define FTM0_CH1_PIN 23
  590. #define FTM0_CH2_PIN 9
  591. #define FTM0_CH3_PIN 10
  592. #define FTM0_CH4_PIN 6
  593. #define FTM0_CH5_PIN 20
  594. #define FTM0_CH6_PIN 21
  595. #define FTM0_CH7_PIN 5
  596. #define FTM1_CH0_PIN 3
  597. #define FTM1_CH1_PIN 4
  598. #define FTM2_CH0_PIN 29
  599. #define FTM2_CH1_PIN 30
  600. #define FTM3_CH0_PIN 2
  601. #define FTM3_CH1_PIN 14
  602. #define FTM3_CH2_PIN 7
  603. #define FTM3_CH3_PIN 8
  604. #define FTM3_CH4_PIN 35
  605. #define FTM3_CH5_PIN 36
  606. #define FTM3_CH6_PIN 37
  607. #define FTM3_CH7_PIN 38
  608. #elif defined(__MK66FX1M0__)
  609. #define FTM0_CH0_PIN 22
  610. #define FTM0_CH1_PIN 23
  611. #define FTM0_CH2_PIN 9
  612. #define FTM0_CH3_PIN 10
  613. #define FTM0_CH4_PIN 6
  614. #define FTM0_CH5_PIN 20
  615. #define FTM0_CH6_PIN 21
  616. #define FTM0_CH7_PIN 5
  617. #define FTM1_CH0_PIN 3
  618. #define FTM1_CH1_PIN 4
  619. #define FTM2_CH0_PIN 29
  620. #define FTM2_CH1_PIN 30
  621. #define FTM3_CH0_PIN 2
  622. #define FTM3_CH1_PIN 14
  623. #define FTM3_CH2_PIN 7
  624. #define FTM3_CH3_PIN 8
  625. #define FTM3_CH4_PIN 35
  626. #define FTM3_CH5_PIN 36
  627. #define FTM3_CH6_PIN 37
  628. #define FTM3_CH7_PIN 38
  629. #define TPM1_CH0_PIN 16
  630. #define TPM1_CH1_PIN 17
  631. #endif
  632. #define FTM_PINCFG(pin) FTM_PINCFG2(pin)
  633. #define FTM_PINCFG2(pin) CORE_PIN ## pin ## _CONFIG
  634. static uint8_t analog_write_res = 8;
  635. // SOPT4 is SIM select clocks?
  636. // FTM is clocked by the bus clock, either 24 or 48 MHz
  637. // input capture can be FTM1_CH0, CMP0 or CMP1 or USB start of frame
  638. // 24 MHz with reload 49152 to match Arduino's speed = 488.28125 Hz
  639. void analogWrite(uint8_t pin, int val)
  640. {
  641. uint32_t cval, max;
  642. #if defined(__MK20DX256__)
  643. if (pin == A14) {
  644. uint8_t res = analog_write_res;
  645. if (res < 12) {
  646. val <<= 12 - res;
  647. } else if (res > 12) {
  648. val >>= res - 12;
  649. }
  650. analogWriteDAC0(val);
  651. return;
  652. }
  653. #elif defined(__MKL26Z64__)
  654. if (pin == A12) {
  655. uint8_t res = analog_write_res;
  656. if (res < 12) {
  657. val <<= 12 - res;
  658. } else if (res > 12) {
  659. val >>= res - 12;
  660. }
  661. analogWriteDAC0(val);
  662. return;
  663. }
  664. #elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
  665. if (pin == A21 || pin == A22) {
  666. uint8_t res = analog_write_res;
  667. if (res < 12) {
  668. val <<= 12 - res;
  669. } else if (res > 12) {
  670. val >>= res - 12;
  671. }
  672. if (pin == A21) analogWriteDAC0(val);
  673. else analogWriteDAC1(val);
  674. return;
  675. }
  676. #endif
  677. max = 1 << analog_write_res;
  678. if (val <= 0) {
  679. digitalWrite(pin, LOW);
  680. pinMode(pin, OUTPUT); // TODO: implement OUTPUT_LOW
  681. return;
  682. } else if (val >= max) {
  683. digitalWrite(pin, HIGH);
  684. pinMode(pin, OUTPUT); // TODO: implement OUTPUT_HIGH
  685. return;
  686. }
  687. //serial_print("analogWrite\n");
  688. //serial_print("val = ");
  689. //serial_phex32(val);
  690. //serial_print("\n");
  691. //serial_print("analog_write_res = ");
  692. //serial_phex(analog_write_res);
  693. //serial_print("\n");
  694. if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
  695. cval = ((uint32_t)val * (uint32_t)(FTM1_MOD + 1)) >> analog_write_res;
  696. #if defined(FTM2_CH0_PIN)
  697. } else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
  698. cval = ((uint32_t)val * (uint32_t)(FTM2_MOD + 1)) >> analog_write_res;
  699. #endif
  700. #if defined(FTM3_CH0_PIN)
  701. } else if (pin == FTM3_CH0_PIN || pin == FTM3_CH1_PIN || pin == FTM3_CH2_PIN
  702. || pin == FTM3_CH3_PIN || pin == FTM3_CH4_PIN || pin == FTM3_CH5_PIN
  703. || pin == FTM3_CH6_PIN || pin == FTM3_CH7_PIN) {
  704. cval = ((uint32_t)val * (uint32_t)(FTM3_MOD + 1)) >> analog_write_res;
  705. #endif
  706. #if defined(TPM1_CH0_PIN)
  707. } else if (pin == TPM1_CH0_PIN || pin == TPM1_CH1_PIN) {
  708. cval = ((uint32_t)val * (uint32_t)(TPM1_MOD + 1)) >> analog_write_res;
  709. #endif
  710. } else {
  711. cval = ((uint32_t)val * (uint32_t)(FTM0_MOD + 1)) >> analog_write_res;
  712. }
  713. //serial_print("cval = ");
  714. //serial_phex32(cval);
  715. //serial_print("\n");
  716. switch (pin) {
  717. #ifdef FTM0_CH0_PIN
  718. case FTM0_CH0_PIN: // PTC1, FTM0_CH0
  719. FTM0_C0V = cval;
  720. FTM_PINCFG(FTM0_CH0_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  721. break;
  722. #endif
  723. #ifdef FTM0_CH1_PIN
  724. case FTM0_CH1_PIN: // PTC2, FTM0_CH1
  725. FTM0_C1V = cval;
  726. FTM_PINCFG(FTM0_CH1_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  727. break;
  728. #endif
  729. #ifdef FTM0_CH2_PIN
  730. case FTM0_CH2_PIN: // PTC3, FTM0_CH2
  731. FTM0_C2V = cval;
  732. FTM_PINCFG(FTM0_CH2_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  733. break;
  734. #endif
  735. #ifdef FTM0_CH3_PIN
  736. case FTM0_CH3_PIN: // PTC4, FTM0_CH3
  737. FTM0_C3V = cval;
  738. FTM_PINCFG(FTM0_CH3_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  739. break;
  740. #endif
  741. #ifdef FTM0_CH4_PIN
  742. case FTM0_CH4_PIN: // PTD4, FTM0_CH4
  743. FTM0_C4V = cval;
  744. FTM_PINCFG(FTM0_CH4_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  745. break;
  746. #endif
  747. #ifdef FTM0_CH5_PIN
  748. case FTM0_CH5_PIN: // PTD5, FTM0_CH5
  749. FTM0_C5V = cval;
  750. FTM_PINCFG(FTM0_CH5_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  751. break;
  752. #endif
  753. #ifdef FTM0_CH6_PIN
  754. case FTM0_CH6_PIN: // PTD6, FTM0_CH6
  755. FTM0_C6V = cval;
  756. FTM_PINCFG(FTM0_CH6_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  757. break;
  758. #endif
  759. #ifdef FTM0_CH7_PIN
  760. case FTM0_CH7_PIN: // PTD7, FTM0_CH7
  761. FTM0_C7V = cval;
  762. FTM_PINCFG(FTM0_CH7_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  763. break;
  764. #endif
  765. #ifdef FTM1_CH0_PIN
  766. case FTM1_CH0_PIN: // PTA12, FTM1_CH0
  767. FTM1_C0V = cval;
  768. FTM_PINCFG(FTM1_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  769. break;
  770. #endif
  771. #ifdef FTM1_CH1_PIN
  772. case FTM1_CH1_PIN: // PTA13, FTM1_CH1
  773. FTM1_C1V = cval;
  774. FTM_PINCFG(FTM1_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  775. break;
  776. #endif
  777. #ifdef FTM2_CH0_PIN
  778. case FTM2_CH0_PIN: // PTB18, FTM2_CH0
  779. FTM2_C0V = cval;
  780. FTM_PINCFG(FTM2_CH0_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  781. break;
  782. #endif
  783. #ifdef FTM2_CH1_PIN
  784. case FTM2_CH1_PIN: // PTB19, FTM1_CH1
  785. FTM2_C1V = cval;
  786. FTM_PINCFG(FTM2_CH1_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  787. break;
  788. #endif
  789. #ifdef FTM3_CH0_PIN
  790. case FTM3_CH0_PIN:
  791. FTM3_C0V = cval;
  792. FTM_PINCFG(FTM3_CH0_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  793. break;
  794. #endif
  795. #ifdef FTM3_CH1_PIN
  796. case FTM3_CH1_PIN:
  797. FTM3_C1V = cval;
  798. FTM_PINCFG(FTM3_CH1_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  799. break;
  800. #endif
  801. #ifdef FTM3_CH2_PIN
  802. case FTM3_CH2_PIN:
  803. FTM3_C2V = cval;
  804. FTM_PINCFG(FTM3_CH2_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  805. break;
  806. #endif
  807. #ifdef FTM3_CH3_PIN
  808. case FTM3_CH3_PIN:
  809. FTM3_C3V = cval;
  810. FTM_PINCFG(FTM3_CH3_PIN) = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
  811. break;
  812. #endif
  813. #ifdef FTM3_CH4_PIN
  814. case FTM3_CH4_PIN:
  815. FTM3_C4V = cval;
  816. FTM_PINCFG(FTM3_CH4_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  817. break;
  818. #endif
  819. #ifdef FTM3_CH5_PIN
  820. case FTM3_CH5_PIN:
  821. FTM3_C5V = cval;
  822. FTM_PINCFG(FTM3_CH5_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  823. break;
  824. #endif
  825. #ifdef FTM3_CH6_PIN
  826. case FTM3_CH6_PIN:
  827. FTM3_C6V = cval;
  828. FTM_PINCFG(FTM3_CH6_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  829. break;
  830. #endif
  831. #ifdef FTM3_CH7_PIN
  832. case FTM3_CH7_PIN:
  833. FTM3_C7V = cval;
  834. FTM_PINCFG(FTM3_CH7_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
  835. break;
  836. #endif
  837. #ifdef TPM1_CH0_PIN
  838. case TPM1_CH0_PIN:
  839. TPM1_C0V = cval;
  840. FTM_PINCFG(TPM1_CH0_PIN) = PORT_PCR_MUX(6) | PORT_PCR_DSE | PORT_PCR_SRE;
  841. break;
  842. #endif
  843. #ifdef TPM1_CH1_PIN
  844. case TPM1_CH1_PIN:
  845. TPM1_C1V = cval;
  846. FTM_PINCFG(TPM1_CH1_PIN) = PORT_PCR_MUX(6) | PORT_PCR_DSE | PORT_PCR_SRE;
  847. break;
  848. #endif
  849. default:
  850. digitalWrite(pin, (val > 127) ? HIGH : LOW);
  851. pinMode(pin, OUTPUT);
  852. }
  853. }
  854. uint32_t analogWriteRes(uint32_t bits)
  855. {
  856. uint32_t prior_res;
  857. if (bits < 1) {
  858. bits = 1;
  859. } else if (bits > 16) {
  860. bits = 16;
  861. }
  862. prior_res = analog_write_res;
  863. analog_write_res = bits;
  864. return prior_res;
  865. }
  866. void analogWriteFrequency(uint8_t pin, float frequency)
  867. {
  868. uint32_t prescale, mod, ftmClock, ftmClockSource;
  869. float minfreq;
  870. //serial_print("analogWriteFrequency: pin = ");
  871. //serial_phex(pin);
  872. //serial_print(", freq = ");
  873. //serial_phex32((uint32_t)frequency);
  874. //serial_print("\n");
  875. #ifdef TPM1_CH0_PIN
  876. if (pin == TPM1_CH0_PIN || pin == TPM1_CH1_PIN) {
  877. ftmClockSource = 1;
  878. ftmClock = 16000000;
  879. } else
  880. #endif
  881. #if defined(__MKL26Z64__)
  882. // Teensy LC does not support slow clock source (ftmClockSource = 2)
  883. ftmClockSource = 1; // Use default F_TIMER clock source
  884. ftmClock = F_TIMER; // Set variable for the actual timer clock frequency
  885. #else
  886. if (frequency < (float)(F_TIMER >> 7) / 65536.0f) {
  887. // frequency is too low for working with F_TIMER:
  888. ftmClockSource = 2; // Use alternative 31250Hz clock source
  889. ftmClock = 31250; // Set variable for the actual timer clock frequency
  890. } else {
  891. ftmClockSource = 1; // Use default F_TIMER clock source
  892. ftmClock = F_TIMER; // Set variable for the actual timer clock frequency
  893. }
  894. #endif
  895. for (prescale = 0; prescale < 7; prescale++) {
  896. minfreq = (float)(ftmClock >> prescale) / 65536.0f; //Use ftmClock instead of F_TIMER
  897. if (frequency >= minfreq) break;
  898. }
  899. //serial_print("F_TIMER/ftm_Clock = ");
  900. //serial_phex32(ftmClock >> prescale);
  901. //serial_print("\n");
  902. //serial_print("prescale = ");
  903. //serial_phex(prescale);
  904. //serial_print("\n");
  905. mod = (float)(ftmClock >> prescale) / frequency - 0.5f; //Use ftmClock instead of F_TIMER
  906. if (mod > 65535) mod = 65535;
  907. //serial_print("mod = ");
  908. //serial_phex32(mod);
  909. //serial_print("\n");
  910. if (pin == FTM1_CH0_PIN || pin == FTM1_CH1_PIN) {
  911. FTM1_SC = 0;
  912. FTM1_CNT = 0;
  913. FTM1_MOD = mod;
  914. FTM1_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use ftmClockSource instead of 1
  915. } else if (pin == FTM0_CH0_PIN || pin == FTM0_CH1_PIN
  916. || pin == FTM0_CH2_PIN || pin == FTM0_CH3_PIN
  917. || pin == FTM0_CH4_PIN || pin == FTM0_CH5_PIN
  918. #ifdef FTM0_CH6_PIN
  919. || pin == FTM0_CH6_PIN || pin == FTM0_CH7_PIN
  920. #endif
  921. ) {
  922. FTM0_SC = 0;
  923. FTM0_CNT = 0;
  924. FTM0_MOD = mod;
  925. FTM0_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use ftmClockSource instead of 1
  926. }
  927. #ifdef FTM2_CH0_PIN
  928. else if (pin == FTM2_CH0_PIN || pin == FTM2_CH1_PIN) {
  929. FTM2_SC = 0;
  930. FTM2_CNT = 0;
  931. FTM2_MOD = mod;
  932. FTM2_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use ftmClockSource instead of 1
  933. }
  934. #endif
  935. #ifdef FTM3_CH0_PIN
  936. else if (pin == FTM3_CH0_PIN || pin == FTM3_CH1_PIN
  937. || pin == FTM3_CH2_PIN || pin == FTM3_CH3_PIN
  938. || pin == FTM3_CH4_PIN || pin == FTM3_CH5_PIN
  939. || pin == FTM3_CH6_PIN || pin == FTM3_CH7_PIN) {
  940. FTM3_SC = 0;
  941. FTM3_CNT = 0;
  942. FTM3_MOD = mod;
  943. FTM3_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale); //Use the new ftmClockSource instead of 1
  944. }
  945. #endif
  946. #ifdef TPM1_CH0_PIN
  947. else if (pin == TPM1_CH0_PIN || pin == TPM1_CH1_PIN) {
  948. TPM1_SC = 0;
  949. TPM1_CNT = 0;
  950. TPM1_MOD = mod;
  951. TPM1_SC = FTM_SC_CLKS(ftmClockSource) | FTM_SC_PS(prescale);
  952. }
  953. #endif
  954. }
  955. // TODO: startup code needs to initialize all pins to GPIO mode, input by default
  956. void digitalWrite(uint8_t pin, uint8_t val)
  957. {
  958. if (pin >= CORE_NUM_DIGITAL) return;
  959. #ifdef KINETISK
  960. if (*portModeRegister(pin)) {
  961. if (val) {
  962. *portSetRegister(pin) = 1;
  963. } else {
  964. *portClearRegister(pin) = 1;
  965. }
  966. #else
  967. if (*portModeRegister(pin) & digitalPinToBitMask(pin)) {
  968. if (val) {
  969. *portSetRegister(pin) = digitalPinToBitMask(pin);
  970. } else {
  971. *portClearRegister(pin) = digitalPinToBitMask(pin);
  972. }
  973. #endif
  974. } else {
  975. volatile uint32_t *config = portConfigRegister(pin);
  976. if (val) {
  977. // TODO use bitband for atomic read-mod-write
  978. *config |= (PORT_PCR_PE | PORT_PCR_PS);
  979. //*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
  980. } else {
  981. // TODO use bitband for atomic read-mod-write
  982. *config &= ~(PORT_PCR_PE);
  983. //*config = PORT_PCR_MUX(1);
  984. }
  985. }
  986. }
  987. uint8_t digitalRead(uint8_t pin)
  988. {
  989. if (pin >= CORE_NUM_DIGITAL) return 0;
  990. #ifdef KINETISK
  991. return *portInputRegister(pin);
  992. #else
  993. return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0;
  994. #endif
  995. }
  996. void pinMode(uint8_t pin, uint8_t mode)
  997. {
  998. volatile uint32_t *config;
  999. if (pin >= CORE_NUM_DIGITAL) return;
  1000. config = portConfigRegister(pin);
  1001. if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) {
  1002. #ifdef KINETISK
  1003. *portModeRegister(pin) = 1;
  1004. #else
  1005. *portModeRegister(pin) |= digitalPinToBitMask(pin); // TODO: atomic
  1006. #endif
  1007. *config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
  1008. if (mode == OUTPUT_OPENDRAIN) {
  1009. *config |= PORT_PCR_ODE;
  1010. } else {
  1011. *config &= ~PORT_PCR_ODE;
  1012. }
  1013. } else {
  1014. #ifdef KINETISK
  1015. *portModeRegister(pin) = 0;
  1016. #else
  1017. *portModeRegister(pin) &= ~digitalPinToBitMask(pin);
  1018. #endif
  1019. if (mode == INPUT) {
  1020. *config = PORT_PCR_MUX(1);
  1021. } else if (mode == INPUT_PULLUP) {
  1022. *config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
  1023. } else if (mode == INPUT_PULLDOWN) {
  1024. *config = PORT_PCR_MUX(1) | PORT_PCR_PE;
  1025. } else { // INPUT_DISABLE
  1026. *config = 0;
  1027. }
  1028. }
  1029. }
  1030. void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
  1031. {
  1032. if (bitOrder == LSBFIRST) {
  1033. shiftOut_lsbFirst(dataPin, clockPin, value);
  1034. } else {
  1035. shiftOut_msbFirst(dataPin, clockPin, value);
  1036. }
  1037. }
  1038. void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  1039. {
  1040. uint8_t mask;
  1041. for (mask=0x01; mask; mask <<= 1) {
  1042. digitalWrite(dataPin, value & mask);
  1043. digitalWrite(clockPin, HIGH);
  1044. digitalWrite(clockPin, LOW);
  1045. }
  1046. }
  1047. void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
  1048. {
  1049. uint8_t mask;
  1050. for (mask=0x80; mask; mask >>= 1) {
  1051. digitalWrite(dataPin, value & mask);
  1052. digitalWrite(clockPin, HIGH);
  1053. digitalWrite(clockPin, LOW);
  1054. }
  1055. }
  1056. uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
  1057. {
  1058. if (bitOrder == LSBFIRST) {
  1059. return shiftIn_lsbFirst(dataPin, clockPin);
  1060. } else {
  1061. return shiftIn_msbFirst(dataPin, clockPin);
  1062. }
  1063. }
  1064. uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin)
  1065. {
  1066. uint8_t mask, value=0;
  1067. for (mask=0x01; mask; mask <<= 1) {
  1068. digitalWrite(clockPin, HIGH);
  1069. if (digitalRead(dataPin)) value |= mask;
  1070. digitalWrite(clockPin, LOW);
  1071. }
  1072. return value;
  1073. }
  1074. uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin)
  1075. {
  1076. uint8_t mask, value=0;
  1077. for (mask=0x80; mask; mask >>= 1) {
  1078. digitalWrite(clockPin, HIGH);
  1079. if (digitalRead(dataPin)) value |= mask;
  1080. digitalWrite(clockPin, LOW);
  1081. }
  1082. return value;
  1083. }
  1084. // the systick interrupt is supposed to increment this at 1 kHz rate
  1085. volatile uint32_t systick_millis_count = 0;
  1086. //uint32_t systick_current, systick_count, systick_istatus; // testing only
  1087. uint32_t micros(void)
  1088. {
  1089. uint32_t count, current, istatus;
  1090. __disable_irq();
  1091. current = SYST_CVR;
  1092. count = systick_millis_count;
  1093. istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
  1094. __enable_irq();
  1095. //systick_current = current;
  1096. //systick_count = count;
  1097. //systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
  1098. if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
  1099. current = ((F_CPU / 1000) - 1) - current;
  1100. #if defined(KINETISL) && F_CPU == 48000000
  1101. return count * 1000 + ((current * (uint32_t)87381) >> 22);
  1102. #elif defined(KINETISL) && F_CPU == 24000000
  1103. return count * 1000 + ((current * (uint32_t)174763) >> 22);
  1104. #endif
  1105. return count * 1000 + current / (F_CPU / 1000000);
  1106. }
  1107. void delay(uint32_t ms)
  1108. {
  1109. uint32_t start = micros();
  1110. if (ms > 0) {
  1111. while (1) {
  1112. while ((micros() - start) >= 1000) {
  1113. ms--;
  1114. if (ms == 0) return;
  1115. start += 1000;
  1116. }
  1117. yield();
  1118. }
  1119. }
  1120. }
  1121. // TODO: verify these result in correct timeouts...
  1122. #if F_CPU == 256000000
  1123. #define PULSEIN_LOOPS_PER_USEC 34
  1124. #elif F_CPU == 240000000
  1125. #define PULSEIN_LOOPS_PER_USEC 33
  1126. #elif F_CPU == 216000000
  1127. #define PULSEIN_LOOPS_PER_USEC 31
  1128. #elif F_CPU == 192000000
  1129. #define PULSEIN_LOOPS_PER_USEC 29
  1130. #elif F_CPU == 180000000
  1131. #define PULSEIN_LOOPS_PER_USEC 27
  1132. #elif F_CPU == 168000000
  1133. #define PULSEIN_LOOPS_PER_USEC 25
  1134. #elif F_CPU == 144000000
  1135. #define PULSEIN_LOOPS_PER_USEC 21
  1136. #elif F_CPU == 120000000
  1137. #define PULSEIN_LOOPS_PER_USEC 18
  1138. #elif F_CPU == 96000000
  1139. #define PULSEIN_LOOPS_PER_USEC 14
  1140. #elif F_CPU == 72000000
  1141. #define PULSEIN_LOOPS_PER_USEC 10
  1142. #elif F_CPU == 48000000
  1143. #define PULSEIN_LOOPS_PER_USEC 7
  1144. #elif F_CPU == 24000000
  1145. #define PULSEIN_LOOPS_PER_USEC 4
  1146. #elif F_CPU == 16000000
  1147. #define PULSEIN_LOOPS_PER_USEC 1
  1148. #elif F_CPU == 8000000
  1149. #define PULSEIN_LOOPS_PER_USEC 1
  1150. #elif F_CPU == 4000000
  1151. #define PULSEIN_LOOPS_PER_USEC 1
  1152. #elif F_CPU == 2000000
  1153. #define PULSEIN_LOOPS_PER_USEC 1
  1154. #endif
  1155. #if defined(KINETISK)
  1156. uint32_t pulseIn_high(volatile uint8_t *reg, uint32_t timeout)
  1157. {
  1158. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  1159. uint32_t usec_start, usec_stop;
  1160. // wait for any previous pulse to end
  1161. while (*reg) {
  1162. if (--timeout_count == 0) return 0;
  1163. }
  1164. // wait for the pulse to start
  1165. while (!*reg) {
  1166. if (--timeout_count == 0) return 0;
  1167. }
  1168. usec_start = micros();
  1169. // wait for the pulse to stop
  1170. while (*reg) {
  1171. if (--timeout_count == 0) return 0;
  1172. }
  1173. usec_stop = micros();
  1174. return usec_stop - usec_start;
  1175. }
  1176. uint32_t pulseIn_low(volatile uint8_t *reg, uint32_t timeout)
  1177. {
  1178. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  1179. uint32_t usec_start, usec_stop;
  1180. // wait for any previous pulse to end
  1181. while (!*reg) {
  1182. if (--timeout_count == 0) return 0;
  1183. }
  1184. // wait for the pulse to start
  1185. while (*reg) {
  1186. if (--timeout_count == 0) return 0;
  1187. }
  1188. usec_start = micros();
  1189. // wait for the pulse to stop
  1190. while (!*reg) {
  1191. if (--timeout_count == 0) return 0;
  1192. }
  1193. usec_stop = micros();
  1194. return usec_stop - usec_start;
  1195. }
  1196. // TODO: an inline version should handle the common case where state is const
  1197. uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout)
  1198. {
  1199. if (pin >= CORE_NUM_DIGITAL) return 0;
  1200. if (state) return pulseIn_high(portInputRegister(pin), timeout);
  1201. return pulseIn_low(portInputRegister(pin), timeout);;
  1202. }
  1203. #elif defined(KINETISL)
  1204. // For TeencyLC need to use mask on the input register as the register is shared by several IO pins
  1205. uint32_t pulseIn_high(volatile uint8_t *reg, uint8_t mask, uint32_t timeout)
  1206. {
  1207. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  1208. uint32_t usec_start, usec_stop;
  1209. // wait for any previous pulse to end
  1210. while (*reg & mask) {
  1211. if (--timeout_count == 0) return -1;
  1212. }
  1213. // wait for the pulse to start
  1214. while (!(*reg & mask)) {
  1215. if (--timeout_count == 0) return 0;
  1216. }
  1217. usec_start = micros();
  1218. // wait for the pulse to stop
  1219. while (*reg & mask) {
  1220. if (--timeout_count == 0) return 0;
  1221. }
  1222. usec_stop = micros();
  1223. return usec_stop - usec_start;
  1224. }
  1225. uint32_t pulseIn_low(volatile uint8_t *reg, uint8_t mask, uint32_t timeout)
  1226. {
  1227. uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
  1228. uint32_t usec_start, usec_stop;
  1229. // wait for any previous pulse to end
  1230. while (!(*reg & mask)) {
  1231. if (--timeout_count == 0) return 0;
  1232. }
  1233. // wait for the pulse to start
  1234. while (*reg & mask) {
  1235. if (--timeout_count == 0) return 0;
  1236. }
  1237. usec_start = micros();
  1238. // wait for the pulse to stop
  1239. while (!(*reg & mask)) {
  1240. if (--timeout_count == 0) return 0;
  1241. }
  1242. usec_stop = micros();
  1243. return usec_stop - usec_start;
  1244. }
  1245. // TODO: an inline version should handle the common case where state is const
  1246. uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout)
  1247. {
  1248. if (pin >= CORE_NUM_DIGITAL) return 0;
  1249. if (state) return pulseIn_high(portInputRegister(pin), digitalPinToBitMask(pin), timeout);
  1250. return pulseIn_low(portInputRegister(pin), digitalPinToBitMask(pin), timeout);;
  1251. }
  1252. #endif