Skip to content

Commit f0f14d7

Browse files
Cruz Monrreal IICruz Monrreal II
authored andcommitted
Merge pull request ARMmbed#9952 from d-kato/rza1xx_pwm
Fix PWM driver of RZ/A1
2 parents ed5ea32 + d67af43 commit f0f14d7

File tree

5 files changed

+105
-130
lines changed

5 files changed

+105
-130
lines changed

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/PeripheralNames.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ typedef enum {
5151
PWM_TIOC0A = 0x20,
5252
PWM_TIOC0C,
5353
PWM_TIOC1A,
54+
PWM_TIOC1B,
5455
PWM_TIOC2A,
56+
PWM_TIOC2B,
5557
PWM_TIOC3A,
5658
PWM_TIOC3C,
5759
PWM_TIOC4A,

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_GR_LYCHEE/PeripheralPins.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,14 @@ const PinMap PinMap_PWM[] = {
246246
{P7_9 , PWM_TIOC1A, 6},
247247
{P9_2 , PWM_TIOC1A, 5}, /* for 208QFP */
248248
{P2_7 , PWM_TIOC1A, 3},
249+
{P9_3 , PWM_TIOC1B, 5}, /* for 208QFP */
250+
{P4_0 , PWM_TIOC1B, 3},
251+
{P2_6 , PWM_TIOC2A, 3},
252+
{P5_14 , PWM_TIOC2A, 4},
253+
{P7_0 , PWM_TIOC2A, 5},
254+
{P9_4 , PWM_TIOC2A, 5}, /* for 208QFP */
255+
{P9_5 , PWM_TIOC2B, 5}, /* for 208QFP */
256+
{P4_1 , PWM_TIOC2B, 3},
249257
{P6_7 , PWM_TIOC3A, 5},
250258
{P2_5 , PWM_TIOC3A, 3},
251259
{P3_11 , PWM_TIOC3A, 3},

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/PeripheralNames.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ typedef enum {
5454
PWM_TIOC0A = 0x20,
5555
PWM_TIOC0C,
5656
PWM_TIOC1A,
57+
PWM_TIOC1B,
5758
PWM_TIOC2A,
59+
PWM_TIOC2B,
5860
PWM_TIOC3A,
5961
PWM_TIOC3C,
6062
PWM_TIOC4A,

targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_VK_RZ_A1H/PeripheralNames.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ typedef enum {
5454
PWM_TIOC0A = 0x20,
5555
PWM_TIOC0C,
5656
PWM_TIOC1A,
57+
PWM_TIOC1B,
5758
PWM_TIOC2A,
59+
PWM_TIOC2B,
5860
PWM_TIOC3A,
5961
PWM_TIOC3C,
6062
PWM_TIOC4A,

targets/TARGET_RENESAS/TARGET_RZ_A1XX/pwmout_api.c

Lines changed: 91 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,6 @@ static int32_t period_ch2 = 1;
9090
#endif
9191

9292
#ifdef FUMC_MTU2_PWM
93-
#define MTU2_PWM_SIGNAL 2
94-
9593
typedef enum {
9694
TIOC0A = 0,
9795
TIOC0B,
@@ -111,89 +109,31 @@ typedef enum {
111109
TIOC4D,
112110
} MTU2_PWMType;
113111

114-
static const MTU2_PWMType MTU2_PORT[] = {
115-
TIOC0A, // PWM_TIOC0A
116-
TIOC0C, // PWM_TIOC0C
117-
TIOC1A, // PWM_TIOC1A
118-
TIOC2A, // PWM_TIOC2A
119-
TIOC3A, // PWM_TIOC3A
120-
TIOC3C, // PWM_TIOC3C
121-
TIOC4A, // PWM_TIOC4A
122-
TIOC4C, // PWM_TIOC4C
123-
};
124-
125-
static __IO uint16_t *MTU2_PWM_MATCH[][MTU2_PWM_SIGNAL] = {
126-
{ &MTU2TGRA_0, &MTU2TGRB_0 }, // PWM_TIOC0A
127-
{ &MTU2TGRC_0, &MTU2TGRD_0 }, // PWM_TIOC0C
128-
{ &MTU2TGRA_1, &MTU2TGRB_1 }, // PWM_TIOC1A
129-
{ &MTU2TGRA_2, &MTU2TGRB_2 }, // PWM_TIOC2A
130-
{ &MTU2TGRA_3, &MTU2TGRB_3 }, // PWM_TIOC3A
131-
{ &MTU2TGRC_3, &MTU2TGRD_3 }, // PWM_TIOC3C
132-
{ &MTU2TGRA_4, &MTU2TGRB_4 }, // PWM_TIOC4A
133-
{ &MTU2TGRC_4, &MTU2TGRD_4 }, // PWM_TIOC4C
134-
};
135-
136-
static __IO uint8_t *TCR_MATCH[] = {
137-
&MTU2TCR_0,
138-
&MTU2TCR_1,
139-
&MTU2TCR_2,
140-
&MTU2TCR_3,
141-
&MTU2TCR_4,
142-
};
143-
144-
static __IO uint8_t *TIORH_MATCH[] = {
145-
&MTU2TIORH_0,
146-
&MTU2TIOR_1,
147-
&MTU2TIOR_2,
148-
&MTU2TIORH_3,
149-
&MTU2TIORH_4,
150-
};
151-
152-
static __IO uint8_t *TIORL_MATCH[] = {
153-
&MTU2TIORL_0,
154-
NULL,
155-
NULL,
156-
&MTU2TIORL_3,
157-
&MTU2TIORL_4,
158-
};
159-
160-
static __IO uint16_t *TGRA_MATCH[] = {
161-
&MTU2TGRA_0,
162-
&MTU2TGRA_1,
163-
&MTU2TGRA_2,
164-
&MTU2TGRA_3,
165-
&MTU2TGRA_4,
112+
typedef struct {
113+
MTU2_PWMType port;
114+
__IO uint16_t * pulse1;
115+
__IO uint16_t * pulse2;
116+
__IO uint16_t * period1;
117+
__IO uint16_t * period2;
118+
__IO uint8_t * tior;
119+
__IO uint8_t * tcr;
120+
__IO uint8_t * tmdr;
121+
int max_period;
122+
} st_mtu2_ctrl_t;
123+
124+
static st_mtu2_ctrl_t mtu2_ctl[] = {
125+
{ TIOC0A, &MTU2TGRA_0, &MTU2TGRC_0, &MTU2TGRB_0, &MTU2TGRD_0, &MTU2TIORH_0, &MTU2TCR_0, &MTU2TMDR_0, 125000 }, // PWM_TIOC0A
126+
{ TIOC0C, &MTU2TGRC_0, &MTU2TGRA_0, &MTU2TGRB_0, &MTU2TGRD_0, &MTU2TIORL_0, &MTU2TCR_0, &MTU2TMDR_0, 125000 }, // PWM_TIOC0C
127+
{ TIOC1A, &MTU2TGRA_1, NULL , &MTU2TGRB_1, NULL , &MTU2TIOR_1 , &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1A
128+
{ TIOC1B, &MTU2TGRB_1, NULL , &MTU2TGRA_1, NULL , &MTU2TIOR_1 , &MTU2TCR_1, &MTU2TMDR_1, 503000 }, // PWM_TIOC1B
129+
{ TIOC2A, &MTU2TGRA_2, NULL , &MTU2TGRB_2, NULL , &MTU2TIOR_2 , &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2A
130+
{ TIOC2B, &MTU2TGRB_2, NULL , &MTU2TGRA_2, NULL , &MTU2TIOR_2 , &MTU2TCR_2, &MTU2TMDR_2, 2000000 }, // PWM_TIOC2B
131+
{ TIOC3A, &MTU2TGRA_3, &MTU2TGRC_3, &MTU2TGRB_3, &MTU2TGRD_3, &MTU2TIORH_3, &MTU2TCR_3, &MTU2TMDR_3, 2000000 }, // PWM_TIOC3A
132+
{ TIOC3C, &MTU2TGRC_3, &MTU2TGRA_3, &MTU2TGRB_3, &MTU2TGRD_3, &MTU2TIORL_3, &MTU2TCR_3, &MTU2TMDR_3, 2000000 }, // PWM_TIOC3C
133+
{ TIOC4A, &MTU2TGRA_4, &MTU2TGRC_4, &MTU2TGRB_4, &MTU2TGRD_4, &MTU2TIORH_4, &MTU2TCR_4, &MTU2TMDR_4, 2000000 }, // PWM_TIOC4A
134+
{ TIOC4C, &MTU2TGRC_4, &MTU2TGRA_4, &MTU2TGRB_4, &MTU2TGRD_4, &MTU2TIORL_4, &MTU2TCR_4, &MTU2TMDR_4, 2000000 }, // PWM_TIOC4C
166135
};
167136

168-
static __IO uint16_t *TGRC_MATCH[] = {
169-
&MTU2TGRC_0,
170-
NULL,
171-
NULL,
172-
&MTU2TGRC_3,
173-
&MTU2TGRC_4,
174-
};
175-
176-
static __IO uint8_t *TMDR_MATCH[] = {
177-
&MTU2TMDR_0,
178-
&MTU2TMDR_1,
179-
&MTU2TMDR_2,
180-
&MTU2TMDR_3,
181-
&MTU2TMDR_4,
182-
};
183-
184-
static int MAX_PERIOD[] = {
185-
125000,
186-
503000,
187-
2000000,
188-
2000000,
189-
2000000,
190-
};
191-
192-
typedef enum {
193-
MTU2_PULSE = 0,
194-
MTU2_PERIOD
195-
} MTU2Signal;
196-
197137
static uint16_t init_mtu2_period_ch[5] = {0};
198138
static int32_t mtu2_period_ch[5] = {1, 1, 1, 1, 1};
199139
#endif
@@ -206,26 +146,21 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
206146
if (pwm >= MTU2_PWM_OFFSET) {
207147
#ifdef FUMC_MTU2_PWM
208148
/* PWM by MTU2 */
209-
int tmp_pwm;
210-
211149
// power on
212150
mtu2_init();
213-
151+
214152
obj->pwm = pwm;
215-
tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
216-
if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000040) == 0x00000040) {
217-
obj->ch = 4;
153+
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
154+
155+
obj->ch = (uint8_t)(((uint32_t)p_mtu2_ctl->port & 0x000000F0) >> 4);
156+
if (obj->ch == 4) {
218157
MTU2TOER |= 0x36;
219-
} else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000030) == 0x00000030) {
220-
obj->ch = 3;
158+
} else if (obj->ch == 3) {
221159
MTU2TOER |= 0x09;
222-
} else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000020) == 0x00000020) {
223-
obj->ch = 2;
224-
} else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000010) == 0x00000010) {
225-
obj->ch = 1;
226160
} else {
227-
obj->ch = 0;
161+
// do nothing
228162
}
163+
229164
// Wire pinout
230165
pinmap_pinout(pin, PinMap_PWM);
231166

@@ -284,7 +219,8 @@ void pwmout_write(pwmout_t* obj, float value) {
284219
if (obj->pwm >= MTU2_PWM_OFFSET) {
285220
#ifdef FUMC_MTU2_PWM
286221
/* PWM by MTU2 */
287-
int tmp_pwm;
222+
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
223+
uint8_t tmp_tstr_st;
288224

289225
if (value < 0.0f) {
290226
value = 0.0f;
@@ -293,13 +229,40 @@ void pwmout_write(pwmout_t* obj, float value) {
293229
} else {
294230
// Do Nothing
295231
}
296-
tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
297-
wk_cycle = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] & 0xffff;
232+
wk_cycle = (uint32_t)*p_mtu2_ctl->period1;
233+
if ((obj->ch == 4) || (obj->ch == 3)) {
234+
tmp_tstr_st = (1 << (obj->ch + 3));
235+
} else {
236+
tmp_tstr_st = (1 << obj->ch);
237+
}
238+
298239
// set channel match to percentage
299240
if (value == 1.0f) {
300-
*MTU2_PWM_MATCH[tmp_pwm][MTU2_PULSE] = (uint16_t)(wk_cycle - 1);
241+
if (*p_mtu2_ctl->tior != 0x66) {
242+
MTU2TSTR &= ~tmp_tstr_st;
243+
*p_mtu2_ctl->tior = 0x66;
244+
}
245+
} else if (value == 0.0f) {
246+
if (*p_mtu2_ctl->tior != 0x11) {
247+
MTU2TSTR &= ~tmp_tstr_st;
248+
*p_mtu2_ctl->tior = 0x11;
249+
}
250+
} else if (((uint8_t)p_mtu2_ctl->port & 0x0F) == 0x01) {
251+
if (*p_mtu2_ctl->tior != 0x56) {
252+
MTU2TSTR &= ~tmp_tstr_st;
253+
*p_mtu2_ctl->tior = 0x56;
254+
}
301255
} else {
302-
*MTU2_PWM_MATCH[tmp_pwm][MTU2_PULSE] = (uint16_t)((float)wk_cycle * value);
256+
if (*p_mtu2_ctl->tior != 0x65) {
257+
MTU2TSTR &= ~tmp_tstr_st;
258+
*p_mtu2_ctl->tior = 0x65;
259+
}
260+
}
261+
*p_mtu2_ctl->pulse1 = (uint16_t)((float)wk_cycle * value);
262+
263+
// Counter Restart
264+
if ((MTU2TSTR & tmp_tstr_st) == 0) {
265+
MTU2TSTR |= tmp_tstr_st;
303266
}
304267
#endif
305268
} else {
@@ -336,11 +299,10 @@ float pwmout_read(pwmout_t* obj) {
336299
#ifdef FUMC_MTU2_PWM
337300
/* PWM by MTU2 */
338301
uint32_t wk_pulse;
339-
int tmp_pwm;
340-
341-
tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
342-
wk_cycle = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] & 0xffff;
343-
wk_pulse = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PULSE] & 0xffff;
302+
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
303+
304+
wk_cycle = (uint32_t)*p_mtu2_ctl->period1;
305+
wk_pulse = (uint32_t)*p_mtu2_ctl->pulse1;
344306
value = ((float)wk_pulse / (float)wk_cycle);
345307
#endif
346308
} else {
@@ -403,12 +365,11 @@ void pwmout_period_us(pwmout_t* obj, int us) {
403365
int max_us = 0;
404366

405367
/* PWM by MTU2 */
406-
int tmp_pwm;
368+
st_mtu2_ctrl_t * p_mtu2_ctl = &mtu2_ctl[(int)(obj->pwm - MTU2_PWM_OFFSET)];
407369
uint8_t tmp_tcr_up;
408-
uint8_t tmp_tstr_sp;
409370
uint8_t tmp_tstr_st;
410-
411-
max_us = MAX_PERIOD[obj->ch];
371+
372+
max_us = p_mtu2_ctl->max_period;
412373
if (us > max_us) {
413374
us = max_us;
414375
} else if (us < 1) {
@@ -436,37 +397,37 @@ void pwmout_period_us(pwmout_t* obj, int us) {
436397
}
437398
wk_cycle = (uint32_t)(wk_cycle_mtu2 / 1000000);
438399

439-
tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
440-
if (((uint8_t)MTU2_PORT[tmp_pwm] & 0x02) == 0x02) {
441-
tmp_tcr_up = 0xC0;
400+
if (((uint8_t)p_mtu2_ctl->port & 0x0F) == 0x01) {
401+
tmp_tcr_up = 0x20;
442402
} else {
443403
tmp_tcr_up = 0x40;
444404
}
445405
if ((obj->ch == 4) || (obj->ch == 3)) {
446-
tmp_tstr_sp = ~(0x38 | (1 << (obj->ch + 3)));
447406
tmp_tstr_st = (1 << (obj->ch + 3));
448407
} else {
449-
tmp_tstr_sp = ~(0x38 | (1 << obj->ch));
450408
tmp_tstr_st = (1 << obj->ch);
451409
}
410+
452411
// Counter Stop
453-
MTU2TSTR &= tmp_tstr_sp;
454-
wk_last_cycle = *MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] & 0xffff;
455-
*TCR_MATCH[obj->ch] = tmp_tcr_up | wk_cks;
456-
*TIORH_MATCH[obj->ch] = 0x21;
457-
if ((obj->ch == 0) || (obj->ch == 3) || (obj->ch == 4)) {
458-
*TIORL_MATCH[obj->ch] = 0x21;
412+
MTU2TSTR &= ~tmp_tstr_st;
413+
wk_last_cycle = *p_mtu2_ctl->period1;
414+
*p_mtu2_ctl->tcr = tmp_tcr_up | wk_cks;
415+
// Set period
416+
*p_mtu2_ctl->period1 = (uint16_t)wk_cycle;
417+
if (p_mtu2_ctl->period2 != NULL) {
418+
*p_mtu2_ctl->period2 = (uint16_t)wk_cycle;
459419
}
460-
*MTU2_PWM_MATCH[tmp_pwm][MTU2_PERIOD] = (uint16_t)wk_cycle; // Set period
461-
462-
// Set duty again(TGRA)
463-
set_mtu2_duty_again(TGRA_MATCH[obj->ch], wk_last_cycle, wk_cycle);
464-
if ((obj->ch == 0) || (obj->ch == 3) || (obj->ch == 4)) {
465-
// Set duty again(TGRC)
466-
set_mtu2_duty_again(TGRC_MATCH[obj->ch], wk_last_cycle, wk_cycle);
420+
// Set duty again
421+
set_mtu2_duty_again(p_mtu2_ctl->pulse1, wk_last_cycle, wk_cycle);
422+
if (p_mtu2_ctl->pulse2 != NULL) {
423+
set_mtu2_duty_again(p_mtu2_ctl->pulse2, wk_last_cycle, wk_cycle);
424+
}
425+
// Set mode
426+
if (((uint8_t)p_mtu2_ctl->port & 0x0F) == 0x01) {
427+
*p_mtu2_ctl->tmdr = 0x03; // PWM mode 2
428+
} else {
429+
*p_mtu2_ctl->tmdr = 0x02; // PWM mode 1
467430
}
468-
*TMDR_MATCH[obj->ch] = 0x02; // PWM mode 1
469-
470431
// Counter Start
471432
MTU2TSTR |= tmp_tstr_st;
472433
// Save for future use

0 commit comments

Comments
 (0)