summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2021-06-02 23:44:47 +0100
committerAidan MacDonald <amachronic@protonmail.com>2021-06-02 23:52:53 +0100
commita6b5de6a89c82ec8c6d0d7bafb9a377f9035d46b (patch)
tree962e8d78ab79641cb5c3d0a9a958373da4e10b50
parent0187fca64024c872c8c7708583d5f1ced5224544 (diff)
downloadrockbox-a6b5de6a89c82ec8c6d0d7bafb9a377f9035d46b.tar.gz
rockbox-a6b5de6a89c82ec8c6d0d7bafb9a377f9035d46b.zip
x1000: minor adjustments to PWM code
- Change busy loop to wait on the timer flag instead of hoping to catch the timer at exactly the right moment... unsurprisingly, that did not work well with higher frequency PWM outputs. - Put GPIO data into a dedicated const array. Change-Id: I2a920ed265c192da197a18c7242f3205d11636d3
-rw-r--r--firmware/target/mips/ingenic_x1000/pwm-x1000.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/firmware/target/mips/ingenic_x1000/pwm-x1000.c b/firmware/target/mips/ingenic_x1000/pwm-x1000.c
index 37d2856c1a..8530a38af5 100644
--- a/firmware/target/mips/ingenic_x1000/pwm-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/pwm-x1000.c
@@ -33,7 +33,6 @@ struct pwm_gpio_data {
33}; 33};
34 34
35struct pwm_state { 35struct pwm_state {
36 struct pwm_gpio_data gpio;
37 int period_ns; 36 int period_ns;
38 int duty_ns; 37 int duty_ns;
39 int full_ticks; 38 int full_ticks;
@@ -41,12 +40,20 @@ struct pwm_state {
41 int prescaler; 40 int prescaler;
42}; 41};
43 42
43static const struct pwm_gpio_data pwm_gpios[] = {
44 {GPIO_C, 1 << 25, GPIO_DEVICE(0)},
45 {GPIO_C, 1 << 26, GPIO_DEVICE(1)},
46 {GPIO_C, 1 << 27, GPIO_DEVICE(1)},
47 {GPIO_B, 1 << 6, GPIO_DEVICE(2)},
48 {GPIO_C, 1 << 24, GPIO_DEVICE(0)},
49};
50
44static struct pwm_state pwm_state[] = { 51static struct pwm_state pwm_state[] = {
45 {{GPIO_C, 1 << 25, GPIO_DEVICE(0)}, -1, -1, -1, -1, -1}, 52 {-1, -1, -1, -1, -1},
46 {{GPIO_C, 1 << 26, GPIO_DEVICE(1)}, -1, -1, -1, -1, -1}, 53 {-1, -1, -1, -1, -1},
47 {{GPIO_C, 1 << 27, GPIO_DEVICE(1)}, -1, -1, -1, -1, -1}, 54 {-1, -1, -1, -1, -1},
48 {{GPIO_B, 1 << 6, GPIO_DEVICE(2)}, -1, -1, -1, -1, -1}, 55 {-1, -1, -1, -1, -1},
49 {{GPIO_C, 1 << 24, GPIO_DEVICE(0)}, -1, -1, -1, -1, -1}, 56 {-1, -1, -1, -1, -1},
50}; 57};
51 58
52void pwm_init(int chn) 59void pwm_init(int chn)
@@ -60,7 +67,8 @@ void pwm_init(int chn)
60 st->prescaler = -1; 67 st->prescaler = -1;
61 68
62 /* clear GPIO and disable timer */ 69 /* clear GPIO and disable timer */
63 gpio_config(st->gpio.port, st->gpio.pin, GPIO_OUTPUT(0)); 70 const struct pwm_gpio_data* pg = &pwm_gpios[chn];
71 gpio_config(pg->port, pg->pin, GPIO_OUTPUT(0));
64 jz_clr(TCU_STOP, 1 << chn); 72 jz_clr(TCU_STOP, 1 << chn);
65 jz_clr(TCU_ENABLE, 1 << chn); 73 jz_clr(TCU_ENABLE, 1 << chn);
66 jz_set(TCU_STOP, 1 << chn); 74 jz_set(TCU_STOP, 1 << chn);
@@ -126,11 +134,10 @@ void pwm_set_period(int chn, int period_ns, int duty_ns)
126 134
127 if(full_ticks != st->full_ticks || half_ticks != st->half_ticks) { 135 if(full_ticks != st->full_ticks || half_ticks != st->half_ticks) {
128 if(enabled) { 136 if(enabled) {
129 /* avoid changing PWM settings in the middle of a cycle */ 137 /* avoid changing PWM settings in the middle of a cycle,
130 unsigned cmp = REG_TCU_CMP_FULL(chn) - 1; 138 * because for some reason, that is supposed to be "bad" */
131 long deadline = current_tick + 3; 139 jz_clr(TCU_FLAG, 1 << chn);
132 while(REG_TCU_COUNT(chn) < cmp 140 while((REG_TCU_FLAG & (1 << chn)) == 0);
133 && TIME_BEFORE(current_tick, deadline));
134 } 141 }
135 142
136 /* these can be changed while the timer is running */ 143 /* these can be changed while the timer is running */
@@ -154,15 +161,15 @@ void pwm_enable(int chn)
154 jz_set(TCU_ENABLE, 1 << chn); 161 jz_set(TCU_ENABLE, 1 << chn);
155 162
156 /* Configure GPIO function */ 163 /* Configure GPIO function */
157 struct pwm_state* st = &pwm_state[chn]; 164 const struct pwm_gpio_data* pg = &pwm_gpios[chn];
158 gpio_config(st->gpio.port, st->gpio.pin, st->gpio.func); 165 gpio_config(pg->port, pg->pin, pg->func);
159} 166}
160 167
161void pwm_disable(int chn) 168void pwm_disable(int chn)
162{ 169{
163 /* Set GPIO to output 0 */ 170 /* Set GPIO to output 0 */
164 struct pwm_state* st = &pwm_state[chn]; 171 const struct pwm_gpio_data* pg = &pwm_gpios[chn];
165 gpio_config(st->gpio.port, st->gpio.pin, GPIO_OUTPUT(0)); 172 gpio_config(pg->port, pg->pin, GPIO_OUTPUT(0));
166 173
167 /* Stop timer */ 174 /* Stop timer */
168 jz_clr(TCU_ENABLE, 1 << chn); 175 jz_clr(TCU_ENABLE, 1 << chn);