input_capture.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. #include "main.h"
  2. #include "input_capture.h"
  3. extern TIM_HandleTypeDef htim3;
  4. extern DMA_HandleTypeDef hdma_tim3_ch1;
  5. extern DMA_HandleTypeDef hdma_tim3_ch2;
  6. DShotStruct DShot;
  7. PWMInputStruct PWMInput;
  8. void DMA1_Channel1_IRQ (DMA_HandleTypeDef *hdma) {
  9. uint32_t flag_it = DMA1->ISR;
  10. uint32_t source_it = hdma->Instance->CCR;
  11. uint16_t value;
  12. uint16_t crc_d;
  13. uint16_t crc_p;
  14. uint8_t i;
  15. uint16_t dif_min = 0xFFFF;
  16. uint8_t D;
  17. if ((0U != (flag_it & (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU)))) && (0U != (source_it & DMA_IT_TC)))
  18. {
  19. if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
  20. {
  21. // Disable the transfer complete and error interrupt
  22. __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
  23. // Change the DMA state
  24. hdma->State = HAL_DMA_STATE_READY;
  25. }
  26. // Clear the transfer complete flag
  27. __HAL_DMA_CLEAR_FLAG(hdma, (DMA_FLAG_TC1 << (hdma->ChannelIndex & 0x1CU)));
  28. // Process Unlocked
  29. __HAL_UNLOCK(hdma);
  30. TIM3->CNT = 0;
  31. // Check Packet
  32. for (i=0; i<16; i++) {
  33. DShot.Dif[i] = DShot.T1[i]-DShot.T2[i];
  34. if ((DShot.Type == DShot_Auto)) {
  35. if (DShot.Dif[i] < dif_min) {
  36. dif_min = DShot.Dif[i];
  37. }
  38. }
  39. if (DShot.Dif[i] > 64000) {
  40. DShot.Restart_Counter++;
  41. if (DShot.Restart_Counter < 100) {
  42. Dshot_DeInit();
  43. Dshot_Init(DShot.Type);
  44. } else {
  45. Dshot_DeInit();
  46. }
  47. return;
  48. }
  49. }
  50. // If DShot_Auto then autodetect 'TDif'
  51. if (DShot.Type == DShot_Auto) {
  52. DShot.TDif = dif_min + (dif_min / 2);
  53. }
  54. value = 0;
  55. crc_p = 0;
  56. for (i=0; i<16; i++) {
  57. D = (DShot.Dif[i] > DShot.TDif);
  58. // Calculate value
  59. if (i <= 11) {
  60. value = (value << 1) | D;
  61. } else {
  62. if (i > 11) { // Get CRC from packet
  63. crc_p = (crc_p << 1) | D;
  64. }
  65. }
  66. }
  67. // Calculate CRC
  68. crc_d = (value ^ (value >> 4) ^ (value >> 8)) & 0xF;
  69. // Check CRC
  70. if (crc_d == crc_p ) {
  71. DShot.Value = (value >> 1) & 0x7FF;
  72. }
  73. }
  74. }
  75. void Dshot_Init(uint8_t type) {
  76. switch ( type )
  77. {
  78. case DShot_150:
  79. DShot.TDif = DSHOT150_TIM_TRIG;
  80. DShot.Type = DShot_150;
  81. break;
  82. case DShot_300:
  83. DShot.TDif = DSHOT300_TIM_TRIG;
  84. DShot.Type = DShot_300;
  85. break;
  86. case DShot_600:
  87. DShot.TDif = DSHOT600_TIM_TRIG;
  88. DShot.Type = DShot_600;
  89. break;
  90. case DShot_Auto:
  91. DShot.TDif = 0;
  92. DShot.Type = DShot_Auto;
  93. break;
  94. default:
  95. DShot.TDif = 0;
  96. DShot.Type = DShot_Auto;
  97. break;
  98. }
  99. htim3.Init.Prescaler = 0;
  100. htim3.Init.Period = 20000;
  101. if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {
  102. Error_Handler();
  103. }
  104. HAL_TIM_IC_Start_DMA(&htim3, TIM_CHANNEL_1, DShot.T1, 16);
  105. HAL_TIM_IC_Start_DMA(&htim3, TIM_CHANNEL_2, DShot.T2, 16);
  106. }
  107. void Dshot_DeInit(void) {
  108. HAL_TIM_IC_Stop_DMA(&htim3, TIM_CHANNEL_1);
  109. HAL_TIM_IC_Stop_DMA(&htim3, TIM_CHANNEL_2);
  110. }
  111. uint32_t DShot_Get(void) {
  112. return DShot.Value;
  113. }
  114. void PWMInput_Init(void) {
  115. PWMInput.Value = 0;
  116. htim3.Init.Prescaler = 64;
  117. htim3.Init.Period = 64000;
  118. if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {
  119. Error_Handler();
  120. }
  121. HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_2);
  122. HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_1);
  123. __HAL_TIM_ENABLE_IT(&htim3, TIM_IT_UPDATE);
  124. }
  125. void PWMInput_DeInit(void) {
  126. HAL_TIM_IC_Stop(&htim3, TIM_CHANNEL_2);
  127. HAL_TIM_IC_Stop(&htim3, TIM_CHANNEL_1);
  128. }
  129. uint32_t PWMInput_Get(void) {
  130. return PWMInput.Value;
  131. }
  132. void TIM3_IRQ(void) {
  133. if (__HAL_TIM_GET_IT_SOURCE(&htim3, TIM_IT_CC1) != RESET)
  134. {
  135. if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_CC1) != RESET)
  136. {
  137. __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_CC1);
  138. }
  139. __HAL_TIM_CLEAR_IT(&htim3, TIM_IT_CC1);
  140. }
  141. if (__HAL_TIM_GET_IT_SOURCE(&htim3, TIM_IT_CC2) != RESET)
  142. {
  143. if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_CC2) != RESET)
  144. {
  145. __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_CC2);
  146. PWMInput.Value = HAL_TIM_ReadCapturedValue(&htim3, TIM_CHANNEL_1);
  147. TIM3->CNT = 0;
  148. PWMInput.OverCaptureCounter = 0;
  149. }
  150. __HAL_TIM_CLEAR_IT(&htim3, TIM_IT_CC2);
  151. }
  152. if (__HAL_TIM_GET_IT_SOURCE(&htim3, TIM_IT_UPDATE) != RESET)
  153. {
  154. __HAL_TIM_CLEAR_IT(&htim3, TIM_IT_UPDATE);
  155. if (PWMInput.OverCaptureCounter > 3) {
  156. PWMInput.Value = 0;
  157. } else {
  158. PWMInput.OverCaptureCounter++;
  159. }
  160. }
  161. }