diff options
author | Aidan MacDonald <amachronic@protonmail.com> | 2021-06-02 23:44:47 +0100 |
---|---|---|
committer | Aidan MacDonald <amachronic@protonmail.com> | 2021-06-02 23:52:53 +0100 |
commit | a6b5de6a89c82ec8c6d0d7bafb9a377f9035d46b (patch) | |
tree | 962e8d78ab79641cb5c3d0a9a958373da4e10b50 /firmware/target/mips | |
parent | 0187fca64024c872c8c7708583d5f1ced5224544 (diff) | |
download | rockbox-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
Diffstat (limited to 'firmware/target/mips')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/pwm-x1000.c | 39 |
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 | ||
35 | struct pwm_state { | 35 | struct 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 | ||
43 | static 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 | |||
44 | static struct pwm_state pwm_state[] = { | 51 | static 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 | ||
52 | void pwm_init(int chn) | 59 | void 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 | ||
161 | void pwm_disable(int chn) | 168 | void 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); |