Daiki Kato / PwmOutResetSync

Dependents:   Motor_Control_using_lib Motor_Control_API

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pwmout_rst_sync_api.c Source File

pwmout_rst_sync_api.c

00001 #include "mbed_assert.h"
00002 #include "pwmout_rst_sync_api.h"
00003 #include "pinmap.h"
00004 #include "RZ_A1_Init.h"
00005 #include "gpio_addrdefine.h"
00006 
00007 
00008 #define MTU2_PWM_NUM            3
00009 
00010 /*  PORT ID, MTU2_PWMType, Pin function */
00011 static const PinMap PinMap_PWM[] = {
00012     {P7_9     , 0  , 7},
00013     {P8_11    , 0  , 4},
00014     {P3_5     , 0  , 6},
00015     {P7_12    , 1  , 7},
00016     {P3_8     , 1  , 6},
00017     {P4_4     , 1  , 3},
00018     {P11_0    , 1  , 2},
00019     {P7_13    , 2  , 7},
00020     {P3_9     , 2  , 6},
00021     {P4_5     , 2  , 3},
00022     {P11_1    , 2  , 2},
00023     {NC       , NC , 0}
00024 };
00025 
00026 static __IO uint16_t *MTU2_PWM_MATCH[MTU2_PWM_NUM] = {
00027     { &MTU2TGRD_3 },
00028     { &MTU2TGRC_4 },
00029     { &MTU2TGRD_4 } 
00030 };
00031 
00032 static int32_t  mtu2_period    = 1000;    /* default period 1ms */
00033 static uint8_t  mtu2_toer      = 0xc0;
00034 static uint8_t  init_end       = 0;
00035 
00036 void pwmout_rst_sync_init(pwmout_rst_sync_t* obj, PinName pin) {
00037     /* Port setting for S/W I/O Contorol */
00038     int pwm_type   = pinmap_peripheral(pin, PinMap_PWM);
00039     MBED_ASSERT(pwm_type != NC);
00040     MBED_ASSERT((mtu2_toer & (0x01 << pwm_type)) == 0);
00041 
00042     obj->pwm_type   = pwm_type;
00043     mtu2_toer |= (0x01 << obj->pwm_type);
00044 
00045     /* Wire pinout */
00046     pinmap_pinout(pin, PinMap_PWM);
00047     *PMSR(PINGROUP(pin)) = ((1 << (pin  & 0xf)) << 16) | 0;
00048 
00049     /* Mosule stop 33(MTU2) canceling */
00050     CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP33);
00051 
00052     /* default duty 0.0f */
00053     if (init_end == 0) {
00054         MTU2TSTR     &= 0xBF;
00055         MTU2TGRB_3    = MTU2TGRD_3 = 0;
00056         MTU2TGRA_4    = MTU2TGRC_4 = 0;
00057         MTU2TGRB_4    = MTU2TGRD_4 = 0;
00058         init_end = 1;
00059     }
00060 
00061     pwmout_rst_sync_period_us(mtu2_period);
00062 }
00063 
00064 void pwmout_rst_sync_free(pwmout_rst_sync_t* obj) {
00065     pwmout_rst_sync_write(obj, 0);
00066     mtu2_toer &= ~(0x01 << obj->pwm_type);
00067     if (mtu2_toer == 0xc0) {
00068         init_end = 0;
00069     }
00070 }
00071 
00072 void pwmout_rst_sync_write(pwmout_rst_sync_t* obj, float value) {
00073     uint32_t wk_cycle;
00074     uint16_t wk_set_value;
00075 
00076     if (value < 0.0f) {
00077         value = 0.0f;
00078     } else if (value > 1.0f) {
00079         value = 1.0f;
00080     } else {
00081         /* Do Nothing */
00082     }
00083     wk_cycle = MTU2TGRA_3 & 0xffff;
00084     wk_set_value = (uint16_t)((float)wk_cycle * value);
00085     if ((wk_set_value == wk_cycle) && (wk_set_value != 0)) {
00086         wk_set_value -= 1;
00087     }
00088     /* set channel match to percentage */
00089     *MTU2_PWM_MATCH[obj->pwm_type] = wk_set_value;
00090 }
00091 
00092 float pwmout_rst_sync_read(pwmout_rst_sync_t* obj) {
00093     uint32_t wk_cycle;
00094     float value;
00095     uint32_t wk_pulse;
00096 
00097     wk_cycle = MTU2TGRA_3 & 0xffff;
00098     if (wk_cycle != 0) {
00099         wk_pulse = *MTU2_PWM_MATCH[obj->pwm_type];
00100         value = ((float)wk_pulse / (float)wk_cycle);
00101     } else {
00102         value = 0.0f;
00103     }
00104 
00105     return (value > 1.0f) ? (1.0f) : (value);
00106 }
00107 
00108 void pwmout_rst_sync_period(float seconds) {
00109     pwmout_rst_sync_period_us(seconds * 1000000.0f);
00110 }
00111 
00112 void pwmout_rst_sync_period_ms(int ms) {
00113     pwmout_rst_sync_period_us(ms * 1000);
00114 }
00115 
00116 static void set_mtu2_duty_again(__IO uint16_t *p_pwmpbfr, uint16_t last_cycle, uint16_t new_cycle){
00117     uint16_t wk_pwmpbfr;
00118     float    value;
00119 
00120     if (last_cycle != 0) {
00121         wk_pwmpbfr = *p_pwmpbfr;
00122         value      = ((float)(wk_pwmpbfr & 0xffff) / (float)last_cycle);
00123         *p_pwmpbfr = (uint16_t)((float)new_cycle * value);
00124     } else {
00125         *p_pwmpbfr = 0;
00126     }
00127 }
00128 
00129 /* Set the PWM period, keeping the duty cycle the same. */
00130 void pwmout_rst_sync_period_us(int us) {
00131     uint64_t wk_cycle_mtu2;
00132     uint32_t pclk_base;
00133     uint32_t wk_cycle;
00134     uint32_t wk_cks = 0;
00135     uint16_t wk_last_cycle;
00136     int      max_us = 0;
00137 
00138     max_us = 2000000;
00139     if (us > max_us) {
00140         us = max_us;
00141     } else if (us < 1) {
00142         us = 1;
00143     } else {
00144         /* Do Nothing */
00145     }
00146 
00147     if (RZ_A1_IsClockMode0() == false) {
00148         pclk_base = (uint32_t)CM1_RENESAS_RZ_A1_P0_CLK;
00149     } else {
00150         pclk_base = (uint32_t)CM0_RENESAS_RZ_A1_P0_CLK;
00151     }
00152 
00153     wk_cycle_mtu2 = (uint64_t)pclk_base * us;
00154     while (wk_cycle_mtu2 >= 65535000000) {
00155         wk_cycle_mtu2 >>= 2;
00156         wk_cks++;
00157     }
00158     wk_cycle = (uint32_t)(wk_cycle_mtu2 / 1000000);
00159 
00160     /* Counter Stop */
00161     MTU2TSTR     &= 0xBF;
00162     wk_last_cycle = MTU2TGRA_3;
00163     MTU2TCR_3     = 0x20 + wk_cks;        /* TCNT Clear(TGRA), P0φ/1  */
00164     MTU2TOCR1     = 0x04;                 /*                          */
00165     MTU2TOCR2     = 0x40;                 /* N L>H  P H>L             */
00166     MTU2TMDR_3    = 0x38;                 /* Buff:ON Reset-Synchronized PWM mode */
00167     MTU2TMDR_4    = 0x30;                 /* Buff:ON                  */
00168     MTU2TOER      = mtu2_toer;            /* enabled output           */
00169     MTU2TCNT_3    = MTU2TCNT_4 = 0;       /* TCNT3,TCNT4 Set 0        */
00170     MTU2TGRA_3    = MTU2TGRC_3 = (uint16_t)wk_cycle;
00171 
00172     set_mtu2_duty_again(MTU2_PWM_MATCH[0], wk_last_cycle, wk_cycle);
00173     set_mtu2_duty_again(MTU2_PWM_MATCH[1], wk_last_cycle, wk_cycle);
00174     set_mtu2_duty_again(MTU2_PWM_MATCH[2], wk_last_cycle, wk_cycle);
00175 
00176     MTU2TSTR     |= 0x40;                 /* TCNT_4 Start             */
00177 
00178     /* Save for future use */
00179     mtu2_period = us;
00180 }
00181 
00182 void pwmout_rst_sync_pulsewidth(pwmout_rst_sync_t* obj, float seconds) {
00183     pwmout_rst_sync_pulsewidth_us(obj, seconds * 1000000.0f);
00184 }
00185 
00186 void pwmout_rst_sync_pulsewidth_ms(pwmout_rst_sync_t* obj, int ms) {
00187     pwmout_rst_sync_pulsewidth_us(obj, ms * 1000);
00188 }
00189 
00190 void pwmout_rst_sync_pulsewidth_us(pwmout_rst_sync_t* obj, int us) {
00191     float value = 0;
00192 
00193     if (mtu2_period != 0) {
00194         value = (float)us / (float)mtu2_period;
00195     }
00196     pwmout_rst_sync_write(obj, value);
00197 }