# -*- makefile -*-
-SUBDIRS = boot can lpcan lpcanvca uart_zen uart-nozen ldscripts
+SUBDIRS = boot can lpcan lpcanvca pwm uart_zen uart-nozen ldscripts
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or parent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+# -*- makefile -*-
+
+lib_LIBRARIES = pwm
+
+pwm_SOURCES = pwm.c pwm_set.c pwm_sync.c
+
+include_HEADERS = pwm.h
--- /dev/null
+#include "pwm.h"
+
+int PWM_PINSEL[] = {
+ /*nothing*/ 1, /*PWM1*/ 1, 15, 3, 17, /*PWM5*/ 11, /*PWM6*/ 19
+};
+
+uint32_t *PWM_MR[] = {
+ (uint32_t*)&(PWMMR0),
+ (uint32_t*)&(PWMMR1),
+ (uint32_t*)&(PWMMR2),
+ (uint32_t*)&(PWMMR3),
+ (uint32_t*)&(PWMMR4),
+ (uint32_t*)&(PWMMR5),
+ (uint32_t*)&(PWMMR6)
+};
+
+void pwm_channel(int n, int double_edge) {
+ uint32_t bit;
+
+ PWMPCR |= (0x100 | (double_edge && n)) << n;
+ if (n == 5) {
+ PINSEL1 |= 0x00000400;
+ PINSEL1 &= 0xfffff7ff;
+ }
+ else {
+ bit = 1 << PWM_PINSEL[n];
+ PINSEL0 |= bit;
+ bit = ~(bit >> 1);
+ PINSEL0 &= bit;
+ }
+}
+
+void pwm_init(uint32_t prescale, uint32_t period) {
+ PWMPR = prescale - 1;
+ PWMMR0 = period;
+ PWMLER |= 0x1;
+ PWMMCR |= 0x00000002;
+ PWMTCR &= ~0x2;
+ PWMTCR |= 0x9;
+}
--- /dev/null
+#include <lpc21xx.h>
+#include <types.h>
+
+extern int PWM_PINSEL[];
+extern uint32_t *PWM_MR[];
+
+void pwm_channel(int n, int double_edge);
+void pwm_set(int n, uint32_t when);
+void pwm_set_double(int n, uint32_t from, uint32_t to);
+void pwm_init(uint32_t prescale, uint32_t period);
+void sync_pwm_timer(uint32_t *tc_addr);
--- /dev/null
+#include "pwm.h"
+
+void pwm_set(int n, uint32_t when) {
+ *PWM_MR[n] = when;
+ PWMLER |= 1 << n;
+}
+
+void pwm_set_double(int n, uint32_t from, uint32_t to) {
+ *PWM_MR[n-1] = from;
+ *PWM_MR[n] = to;
+ PWMLER |= 0x3 << (n-1);
+}
--- /dev/null
+#include <cpu_def.h>
+#include "pwm.h"
+
+void sync_pwm_timer(uint32_t *tc_addr) {
+ cli();
+ asm volatile
+ (
+ "mov r2, %0 \n\t"
+ "mov r3, %1 \n\t"
+ "ldr r1, [r2] \n\t"
+ "add r1, r1, #12 \n\t"
+ "str r1, [r3] \n\t"
+ : /* no output */ : "r" (tc_addr), "r" (&PWMTC)
+ );
+ sti();
+}