New software for Spejbl motor control now on lpcanvca.
[HelloWorldCan.git] / app / spejbl_motor / pwm.c
blobd6879d4cb4e3a4c88ab63eb5102ba80e309c9ee4
1 #include <cpu_def.h>
2 #include "pwm.h"
4 int PWM_PINSEL[] = {
5 /*nothing*/ 1, /*PWM1*/ 1, 15, 3, 17, /*PWM5*/ 11, /*PWM6*/ 19
6 };
8 uint32_t *PWM_MR[] = {
9 (uint32_t*)&(PWMMR0),
10 (uint32_t*)&(PWMMR1),
11 (uint32_t*)&(PWMMR2),
12 (uint32_t*)&(PWMMR3),
13 (uint32_t*)&(PWMMR4),
14 (uint32_t*)&(PWMMR5),
15 (uint32_t*)&(PWMMR6)
18 void pwm_channel(int n, int double_edge) {
19 uint32_t bit;
21 PWMPCR |= (0x100 | (double_edge && n)) << n;
22 if (n == 5) {
23 PINSEL1 |= 0x00000400;
24 PINSEL1 &= 0xfffff7ff;
26 else {
27 bit = 1 << PWM_PINSEL[n];
28 PINSEL0 |= bit;
29 bit = ~(bit >> 1);
30 PINSEL0 &= bit;
34 void pwm_set(int n, uint32_t when) {
35 *PWM_MR[n] = when;
36 PWMLER |= 1 << n;
39 void pwm_set_double(int n, uint32_t from, uint32_t to) {
40 *PWM_MR[n-1] = from;
41 *PWM_MR[n] = to;
42 PWMLER |= 0x3 << (n-1);
45 void pwm_init(uint32_t prescale, uint32_t period) {
46 PWMPR = prescale - 1;
47 PWMMR0 = period;
48 PWMLER |= 0x1;
49 PWMMCR |= 0x00000002;
50 PWMTCR &= ~0x2;
51 PWMTCR |= 0x9;
54 void sync_pwm_timer(uint32_t *tc_addr) {
55 cli();
56 asm volatile
58 "mov r2, %0 \n\t"
59 "mov r3, %1 \n\t"
60 "ldr r1, [r2] \n\t"
61 "add r1, r1, #12 \n\t"
62 "str r1, [r3] \n\t"
63 : /* no output */ : "r" (tc_addr), "r" (&PWMTC)
65 sti();