config.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma once
  2. #include <kinetis.h>
  3. #include <core_pins.h>
  4. namespace TeensyStepFTM
  5. {
  6. //==========================================================================
  7. // Available timer modules for the Teensy XX boards. Please note that those
  8. // timers are also used by the core libraries for PWM and AnalogWrite.
  9. // Therefore, choose a timer which isn't attached to the pins you need for
  10. // PWM or AnalogWrite. (TEENSY LC not yet supported)
  11. //
  12. // D: Default, X: available
  13. //
  14. // TIMER | Channels| Timer is available for |
  15. // | | T-LC | T3.0 | T3.1 | T3.2 | T3.5 | T3.6|
  16. //----------------------|---------|------|------|-------|------|------|-----|
  17. #define TIMER_FTM0 1 //| 8 | | D | D | D | D | D |
  18. #define TIMER_FTM1 2 //| 2 | | X | X | X | X | X |
  19. #define TIMER_FTM2 3 //| 2 | | | X | X | X | X |
  20. #define TIMER_FTM3 4 //| 8 | | | | | X | X |
  21. #define TIMER_TPM0 5 //| 6 | | | | | | |
  22. #define TIMER_TPM1 6 //| 2 | | | | | | X |
  23. #define TIMER_TPM2 7 //| 2 | | | | | | X |
  24. #define TIMER_DEFAULT -1
  25. // If you need a special timer, please replace "TIMER_DEFAULT" by a timer from the list above
  26. #define USE_TIMER TIMER_DEFAULT
  27. //==========================================================================
  28. // Nothing to be changed below here
  29. //==========================================================================
  30. #if USE_TIMER == TIMER_DEFAULT
  31. #undef USE_TIMER
  32. #if defined __MKL26Z64__
  33. #define USE_TIMER TIMER_TPM0
  34. #else
  35. #define USE_TIMER TIMER_FTM0
  36. #endif
  37. #endif
  38. constexpr unsigned selTimer = USE_TIMER - 1;
  39. constexpr bool isFTM = selTimer <= 3;
  40. //================================================
  41. // Which board do we use
  42. enum class _boards
  43. {
  44. T_LC, T_30, T31_2, T_35, T_36
  45. };
  46. #if defined __MKL26Z64__
  47. constexpr _boards board = _boards::T_LC;
  48. #elif defined __MK20DX128__
  49. constexpr _boards board = _boards::T_30;
  50. #elif defined __MK20DX256__
  51. constexpr _boards board = _boards::T31_2;
  52. #elif defined __MK64FX512__
  53. constexpr _boards board = _boards::T_35;
  54. #elif defined __MK66FX1M0__
  55. constexpr _boards board = _boards::T_36;
  56. #endif
  57. //====================================================================
  58. // Memory layout of register banks for FTM and TPM timers
  59. typedef struct // FTM & TPM Channels
  60. {
  61. uint32_t SC;
  62. uint32_t CV;
  63. } FTM_CH_t;
  64. typedef struct // FTM register block (this layout is compatible to a TPM register block)
  65. {
  66. uint32_t SC;
  67. uint32_t CNT;
  68. uint32_t MOD;
  69. FTM_CH_t CH[8];
  70. uint32_t CNTIN;
  71. uint32_t STATUS;
  72. uint32_t MODE;
  73. uint32_t SYNC;
  74. uint32_t OUTINIT;
  75. uint32_t OUTMASK;
  76. uint32_t COMBINE;
  77. uint32_t DEADTIME;
  78. uint32_t EXTTRIG;
  79. uint32_t POL;
  80. uint32_t FMS;
  81. uint32_t FILTER;
  82. uint32_t FLTCTRL;
  83. uint32_t QDCTRL;
  84. uint32_t CONF;
  85. uint32_t FLTPOL;
  86. uint32_t SYNCONF;
  87. uint32_t INVCTRL;
  88. uint32_t SWOCTRL;
  89. uint32_t PWMLOAD;
  90. }FTM_t;
  91. //-----------------------------------------------------------------------------------
  92. // Definition of base address for register block, number of channels and IRQ number
  93. //
  94. constexpr uintptr_t TimerBaseAddr[][7] =
  95. { // FTM0 FTM1 FTM2 FTM3 TPM0 TMP1 TMP2
  96. { 0, 0, 0, 0, 0, 0, 0 }, // Teensy LC not yet supported
  97. { 0x40038000, 0x40039000, 0, 0, 0, 0, 0, }, // Teensy 3.0
  98. { 0x40038000, 0x40039000, 0x400B8000, 0, 0, 0, 0, }, // Teensy 3.1/3.2
  99. { 0x40038000, 0x40039000, 0x400B8000, 0x400B9000, 0, 0, 0, }, // Teensy 3.5
  100. { 0x40038000, 0x40039000, 0x400B8000, 0x400B9000, 0, 0x400C9000, 0x400CA000 }, // Teensy 3.6
  101. };
  102. constexpr int IRQ_Number[][7]
  103. {
  104. // FTM0 FTM1 FTM2 FTM3 TPM0 TPM1 TPM2
  105. { 0, 0, 0, 0, 0, 0, 0 }, // Teensy LC
  106. { 25, 26, 0, 0, 0, 0, 0 }, // Teensy 3.0
  107. { 62, 63, 64, 0, 0, 0, 0 }, // Teensy 3.1/3.2
  108. { 42, 43, 44, 71, 0, 0, 0 }, // Teensy 3.5
  109. { 42, 43, 44, 71, 0, 88, 89 }, // Teensy 3.6
  110. };
  111. constexpr int _nrOfChannels[]
  112. {
  113. 8, // FTM0
  114. 2, // FTM1
  115. 2, // FTM2
  116. 8, // FTM3
  117. 6, // TPM0
  118. 2, // TPM1
  119. 2, // TPM2
  120. };
  121. constexpr uintptr_t timerAddr = TimerBaseAddr[(int)board][selTimer];
  122. constexpr volatile FTM_t* timer = __builtin_constant_p((FTM_t*)timerAddr) ? (FTM_t*)timerAddr : (FTM_t*)timerAddr; // base address for register block of selected timer
  123. constexpr unsigned irq = IRQ_Number[(int)board][selTimer]; // IRQ number of selected timer
  124. constexpr unsigned maxChannel = _nrOfChannels[selTimer]; // Number of channels for selected timer
  125. static_assert(timer != nullptr && irq != 0, "Board does not support choosen timer"); //Generate compiler error in case the board does not support the selected timer
  126. //-----------------------------------------------------------------------------------
  127. //Frequency dependent settings
  128. constexpr unsigned _timer_frequency = isFTM ? F_BUS : 16000000; // FTM timers are clocked with F_BUS, the TPM timers are clocked with OSCERCLK (16MHz for all teensies)
  129. // Choose prescaler such that one timer cycle corresponds to about 1µs
  130. constexpr unsigned prescale =
  131. _timer_frequency > 120000000 ? 0b111 :
  132. _timer_frequency > 60000000 ? 0b110 :
  133. _timer_frequency > 30000000 ? 0b101 :
  134. _timer_frequency > 15000000 ? 0b100 :
  135. _timer_frequency > 8000000 ? 0b011 :
  136. _timer_frequency > 4000000 ? 0b010 :
  137. _timer_frequency > 2000000 ? 0b001 : 0b000;
  138. // Calculates required reload value to get a delay of mu microseconds.
  139. // this will be completely evaluated by the compiler as long as mu is known at compile time
  140. constexpr int microsToReload(const float mu)
  141. {
  142. return mu * 1E-6 * _timer_frequency / (1 << prescale) + 0.5;
  143. }
  144. }