phase_current.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. #include "bsp/adc.h"
  2. #include "foc_type.h"
  3. #define NB_OFFSET_SAMPLES 32
  4. static float __inline adc_to_current(int 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->offset_sample_count = NB_OFFSET_SAMPLES;
  15. }
  16. void phase_current_offset(current_samp_t *cs) {
  17. u32 phase_current1, phase_current2;
  18. adc_phase_current_read(cs->sector, &phase_current1, &phase_current2);
  19. if (cs->offset_sample_count > 0) {
  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_c += 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_c = cs->adc_offset_c / NB_OFFSET_SAMPLES;
  27. }
  28. }
  29. if (cs->sector == SECTOR_1 && cs->offset_sample_count >= 0) {
  30. cs->adc_offset_b += phase_current1;
  31. adc_vbus_current_read(cs->sector, &phase_current1, &phase_current2);
  32. cs->adc_offset_ivbus += phase_current1;
  33. if (cs->offset_sample_count == 0) {
  34. cs->adc_offset_b = cs->adc_offset_b / NB_OFFSET_SAMPLES;
  35. cs->adc_offset_ivbus = cs->adc_offset_ivbus / NB_OFFSET_SAMPLES;
  36. }
  37. }
  38. }
  39. }
  40. void phase_current_sample(current_samp_t *cs){
  41. u32 phase_current1, phase_current2;
  42. adc_phase_current_read(cs->sector, &phase_current1, &phase_current2);
  43. if (cs->sector == SECTOR_1 || cs->sector == SECTOR_2) {
  44. /* Current on Phase C is not accessible */
  45. /* Ia = PhaseAOffset - ADC converted value) */
  46. cs->Ib = adc_to_current((int)phase_current1 - (int)cs->adc_offset_b);
  47. cs->Ia = adc_to_current((int)phase_current2 - (int)cs->adc_offset_a);
  48. cs->Ic = -(cs->Ia + cs->Ib);
  49. adc_vbus_current_read(cs->sector, &cs->adc_vbus_ib, &cs->adc_vbus_ia);
  50. }else if (cs->sector == SECTOR_3 || cs->sector == SECTOR_4) {
  51. /* Current on Phase A is not accessible */
  52. /* Ib = PhaseBOffset - ADC converted value) */
  53. cs->Ic = adc_to_current((int)phase_current1 - (int)cs->adc_offset_c);
  54. cs->Ib = adc_to_current((int)phase_current2 - (int)cs->adc_offset_b);
  55. cs->Ia = -(cs->Ib + cs->Ic);
  56. adc_vbus_current_read(cs->sector, &cs->adc_vbus_ic, &cs->adc_vbus_ib);
  57. }else if (cs->sector == SECTOR_5 || cs->sector == SECTOR_6) {
  58. /* Current on Phase B is not accessible */
  59. /* Ia = PhaseAOffset - ADC converted value) */
  60. cs->Ia = adc_to_current((int)phase_current1 - (int)cs->adc_offset_a);
  61. cs->Ic = adc_to_current((int)phase_current2 - (int)cs->adc_offset_c);
  62. cs->Ib = -(cs->Ia + cs->Ic);
  63. adc_vbus_current_read(cs->sector, &cs->adc_vbus_ia, &cs->adc_vbus_ic);
  64. }
  65. #if 0
  66. static int tet_p = 0;
  67. if (tet_p++ % 5 == 0) {
  68. printf("$%d %d %d;", (int)(cs->Ia * 1000), (int)(cs->Ib*1000), (int)(cs->Ic*1000));
  69. }
  70. #endif
  71. }
  72. u32 get_phase_sample_point(current_samp_t *cs, phase_time_t *time, u8 sector){
  73. u32 low_side_low_duty = FOC_PWM_Half_Period - time->low;
  74. cs->sector = sector;
  75. //duty > deadtime + max(Rise time, Noise time)
  76. if (low_side_low_duty > (TDead + MAX(TRise, TNoise))) {
  77. cs->sector = SECTOR_1;
  78. return FOC_PWM_Half_Period - 1;
  79. }else {
  80. u32 low_side_mid_duty = FOC_PWM_Half_Period - time->midle;
  81. u32 delta_duty = low_side_mid_duty - low_side_low_duty;
  82. if (delta_duty > low_side_low_duty * 2) {
  83. return time->low - TADC;
  84. }else {
  85. u32 sample_point = time->low + (TDead + MAX(TRise, TNoise));
  86. if (sample_point >= FOC_PWM_Half_Period) {
  87. sample_point = ( 2u * FOC_PWM_Half_Period ) - sample_point - (uint16_t) 1;
  88. }
  89. return sample_point;
  90. }
  91. }
  92. }
  93. void phase_current_adc_triger(current_samp_t *cs){
  94. adc_phase_inserted_config(cs->sector);
  95. }