foc.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. #include <string.h>
  2. #include "libs/task.h"
  3. #include "bsp/bsp.h"
  4. #include "foc/foc.h"
  5. #include "foc/park_clark.h"
  6. #include "foc/svpwm.h"
  7. #include "foc/foc_task.h"
  8. #include "foc/phase_current.h"
  9. #include "foc/hall_speed.h"
  10. static void charge_cap_timer_handler(timer_t *t);
  11. static u32 foc_main_task_handler(void);
  12. static timer_t charge_cap_timer = {.handler = charge_cap_timer_handler};
  13. static motor_foc_t m_foc;
  14. void foc_init(void) {
  15. /* init pwm hardware timer */
  16. m_foc.state = IDLE;
  17. m_foc.gate_output = false;
  18. hall_sensor_init();
  19. PWM_TimerInit();
  20. task_start(foc_main_task_handler, 0);
  21. foc_hall_detect(6.0f, (u16 *)m_foc.hall_table);
  22. }
  23. int foc_hall_detect(float current, u16 *hall_table){
  24. foc_start_pwm(true);
  25. m_foc.override_p.is_override_theta = true;
  26. m_foc.override_p.theta = 0.0f;
  27. m_foc.override_p.is_override_v_dq = true;
  28. m_foc.override_p.v_dq.d = .0f;
  29. m_foc.override_p.v_dq.q = .0f;
  30. for (int i = 0;i < 1000;i++) {
  31. m_foc.override_p.v_dq.d = (float)i * current / 1000.0f;
  32. task_udelay(1000);
  33. }
  34. float sin_hall[8];
  35. float cos_hall[8];
  36. int hall_iterations[8];
  37. memset(sin_hall, 0, sizeof(sin_hall));
  38. memset(cos_hall, 0, sizeof(cos_hall));
  39. memset(hall_iterations, 0, sizeof(hall_iterations));
  40. // Forwards
  41. for (int i = 0;i < 3;i++) {
  42. for (int j = 0;j < 360;j++) {
  43. m_foc.override_p.theta = j;
  44. task_udelay(10 * 1000);
  45. int hall = get_hall_stat(7);
  46. float s, c;
  47. normal_sincosf(degree_2_pi(j), &s, &c);
  48. sin_hall[hall] += s;
  49. cos_hall[hall] += c;
  50. hall_iterations[hall]++;
  51. }
  52. }
  53. // Reverse
  54. for (int i = 0;i < 3;i++) {
  55. for (int j = 360;j >= 0;j--) {
  56. m_foc.override_p.theta = j;
  57. task_udelay(10 * 1000);
  58. int hall = get_hall_stat(7);
  59. float s, c;
  60. normal_sincosf(degree_2_pi(j), &s, &c);
  61. sin_hall[hall] += s;
  62. cos_hall[hall] += c;
  63. hall_iterations[hall]++;
  64. }
  65. }
  66. foc_start_pwm(false);
  67. m_foc.override_p.is_override_theta = false;
  68. m_foc.override_p.is_override_v_dq = false;
  69. int fails = 0;
  70. for(int i = 0;i < 8;i++) {
  71. if (hall_iterations[i] > 30) {
  72. float ang = pi_2_degree(atan2f(sin_hall[i], cos_hall[i]));
  73. fast_norm_angle(&ang);
  74. hall_table[i] = (u16)ang;
  75. } else {
  76. hall_table[i] = 0xFFFF;
  77. fails++;
  78. }
  79. }
  80. return fails == 2;
  81. }
  82. static void charge_cap_timer_handler(timer_t *t) {
  83. if (m_foc.state == CHARGER_BOOT_CAP) {
  84. m_foc.state = READY_TO_RUN;
  85. }
  86. }
  87. static u32 foc_main_task_handler(void) {
  88. switch (m_foc.state) {
  89. case START:
  90. m_foc.state = CHARGER_BOOT_CAP;
  91. timer_post(&charge_cap_timer, 10);
  92. PWM_TurnOnLowSides();
  93. break;
  94. case CHARGER_BOOT_CAP:
  95. break;
  96. case READY_TO_RUN:
  97. break;
  98. default:
  99. break;
  100. }
  101. return 1;
  102. }
  103. void foc_brake_handler(void) {
  104. if (m_foc.state == CHARGER_BOOT_CAP) {
  105. timer_post(&charge_cap_timer, 10);
  106. PWM_TurnOnLowSides();
  107. }
  108. }
  109. void foc_pwm_up_handler(void){
  110. phase_current_adc_triger(&m_foc.current_samp);
  111. }
  112. void current_sample_handler(void) {
  113. foc_task(&m_foc);
  114. }
  115. void foc_start_pwm(bool start) {
  116. if (start != m_foc.gate_output) {
  117. if (start) {
  118. PWM_Start();
  119. }else {
  120. PWM_Stop();
  121. }
  122. m_foc.gate_output = start;
  123. }
  124. }