phase_current.c 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "hal/adc.h"
  2. #include "foc_type.h"
  3. #define NB_OFFSET_SAMPLES 32
  4. static float __inline adc_to_current(u32 adc){
  5. int i_adc = (int)adc;
  6. if (i_adc > INT16_MAX){
  7. i_adc = INT16_MAX;
  8. }else if (i_adc < -INT16_MAX) {
  9. i_adc = - INT16_MAX;
  10. }
  11. return (i_adc/65535.0f * 3.3f / 1.53f / 0.33f);
  12. }
  13. void phase_current_init(current_samp_t *cs) {
  14. cs->adc_inject_flags = LL_ADC_INJ_TRIG_EXT_RISING;
  15. cs->offset_sample_count = NB_OFFSET_SAMPLES;
  16. }
  17. void phase_current_offset(current_samp_t *cs) {
  18. u32 phase_current1, phase_current2;
  19. HAL_ADC1_Inject_Read(cs->sector, &phase_current1, &phase_current2);
  20. cs->offset_sample_count--;
  21. if (cs->sector == SECTOR_5 && cs->offset_sample_count >= 0) {
  22. cs->adc_offset_a += phase_current1;
  23. cs->adc_offset_b += phase_current2;
  24. if (cs->offset_sample_count == 0) {
  25. cs->adc_offset_a = cs->adc_offset_a / NB_OFFSET_SAMPLES;
  26. cs->adc_offset_b = cs->adc_offset_b / NB_OFFSET_SAMPLES;
  27. }
  28. }
  29. if (cs->sector == SECTOR_1 && cs->offset_sample_count >= 0) {
  30. cs->adc_offset_c += phase_current2;
  31. if (cs->offset_sample_count == 0) {
  32. cs->adc_offset_c = cs->adc_offset_c / NB_OFFSET_SAMPLES;
  33. }
  34. }
  35. }
  36. void phase_current_sample(current_samp_t *cs){
  37. u32 phase_current1, phase_current2;
  38. HAL_ADC1_Inject_Read(cs->sector, &phase_current1, &phase_current2);
  39. if (cs->sector == SECTOR_4 || cs->sector == SECTOR_5) {
  40. /* Current on Phase C is not accessible */
  41. /* Ia = PhaseAOffset - ADC converted value) */
  42. cs->ia = adc_to_current(phase_current1 - cs->adc_offset_a);
  43. cs->ib = adc_to_current(phase_current2 - cs->adc_offset_b);
  44. cs->ic = -(cs->ia + cs->ib);
  45. }else if (cs->sector == SECTOR_1 || cs->sector == SECTOR_6) {
  46. /* Current on Phase A is not accessible */
  47. /* Ib = PhaseBOffset - ADC converted value) */
  48. cs->ib = adc_to_current(phase_current1 - cs->adc_offset_b);
  49. cs->ic = adc_to_current(phase_current2 - cs->adc_offset_c);
  50. cs->ia = -(cs->ib + cs->ic);
  51. }else if (cs->sector == SECTOR_2 || cs->sector == SECTOR_3) {
  52. /* Current on Phase B is not accessible */
  53. /* Ia = PhaseAOffset - ADC converted value) */
  54. cs->ia = adc_to_current(phase_current1 - cs->adc_offset_a);
  55. cs->ic = adc_to_current(phase_current2 - cs->adc_offset_c);
  56. cs->ib = -(cs->ia + cs->ic);
  57. }
  58. static int tet_p = 0;
  59. if (tet_p++ % 20 == 0) {
  60. printf("$%d %d %d;", (int)(cs->ia * 1000), (int)(cs->ib*1000), -(int)(cs->ic*1000));
  61. }
  62. }
  63. u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector){
  64. u32 low_side_low_duty = FOC_PWM_Half_Period - time->low;
  65. cs->sector = sector;
  66. //duty > deadtime + max(Rise time, Noise time)
  67. if (low_side_low_duty > (TDead + MAX(TRise, TNoise))) {
  68. cs->sector = SECTOR_5;
  69. return FOC_PWM_Half_Period - 1;
  70. }else {
  71. u32 low_side_mid_duty = FOC_PWM_period/2 - time->midle;
  72. u32 delta_duty = low_side_mid_duty - low_side_low_duty;
  73. if (delta_duty > low_side_low_duty * 2) {
  74. return time->low - TADC;
  75. }else {
  76. u32 sample_point = time->low + (TDead + MAX(TRise, TNoise));
  77. if (sample_point >= FOC_PWM_Half_Period) {
  78. /* ADC trigger edge must be changed from positive to negative */
  79. cs->adc_inject_flags= (uint16_t) LL_ADC_INJ_TRIG_EXT_FALLING;
  80. sample_point = ( 2u * FOC_PWM_Half_Period ) - sample_point - (uint16_t) 1;
  81. }
  82. return sample_point;
  83. }
  84. }
  85. }
  86. void phase_current_adc_triger(current_samp_t *cs){
  87. HAL_ADC1_Inject_Config(cs->sector, cs->adc_inject_flags);
  88. cs->adc_inject_flags = LL_ADC_INJ_TRIG_EXT_RISING;
  89. }