diff --git a/arduino_lpc1114.h b/arduino_lpc1114.h index 3c2d66c..ef4ad77 100644 --- a/arduino_lpc1114.h +++ b/arduino_lpc1114.h @@ -84,48 +84,86 @@ To achieve appropriate pulling behaviour for inputs, 'or' this value with one of the IO_MODEMASKs. + + xxx_TIMER The timer a pin can be connected to, or NO_TIMER, if this + pin can't be connected to a timer for some reason. If a pin + can be connected to a timer, it can output PWM. + + xxx_MATCH Number of the match register of PWM-able pins. Must be defined + for non-PWM-able pins, too, to allow macros to expand. Value + doesn't matter in the latter case. + + xxx_PWM Bits to set/clear to set this pin as PWM output pin in the + IOCON register. See chapter 7.4 of the User Manual. Must be + defined, but value doesn't matter for non-PWM-able pins. */ +#define NO_TIMER ((LPC_TMR_TypeDef *)0) + // Reset pin. Don't use. //#define PIO0_0_CMSIS RESET_PIO0_0 //#define PIO0_0_PIN 0 //#define PIO0_0_PORT LPC_GPIO0 //#define PIO0_0_OUTPUT (0x01 << 0) +//#define PIO0_0_TIMER NO_TIMER +//#define PIO0_0_MATCH 0 +//#define PIO0_0_PWM 0 #define PIO0_1_CMSIS PIO0_1 #define PIO0_1_PIN 1 #define PIO0_1_PORT LPC_GPIO0 #define PIO0_1_OUTPUT 0x00 // Timer pin CT32B0_MAT2, but timer used for Step interrupt. +#define PIO0_1_TIMER NO_TIMER +#define PIO0_1_MATCH 0 +#define PIO0_1_PWM 0 #define PIO0_2_CMSIS PIO0_2 #define PIO0_2_PIN 2 #define PIO0_2_PORT LPC_GPIO0 #define PIO0_2_OUTPUT 0x00 +#define PIO0_2_TIMER NO_TIMER +#define PIO0_2_MATCH 0 +#define PIO0_2_PWM 0 #define PIO0_3_CMSIS PIO0_3 #define PIO0_3_PIN 3 #define PIO0_3_PORT LPC_GPIO0 #define PIO0_3_OUTPUT 0x00 +#define PIO0_3_TIMER NO_TIMER +#define PIO0_3_MATCH 0 +#define PIO0_3_PWM 0 #define PIO0_4_CMSIS PIO0_4 #define PIO0_4_PIN 4 #define PIO0_4_PORT LPC_GPIO0 #define PIO0_4_OUTPUT (0x01 << 8) +#define PIO0_4_TIMER NO_TIMER +#define PIO0_4_MATCH 0 +#define PIO0_4_PWM 0 #define PIO0_5_CMSIS PIO0_5 #define PIO0_5_PIN 5 #define PIO0_5_PORT LPC_GPIO0 #define PIO0_5_OUTPUT (0x01 << 8) +#define PIO0_5_TIMER NO_TIMER +#define PIO0_5_MATCH 0 +#define PIO0_5_PWM 0 #define PIO0_6_CMSIS PIO0_6 #define PIO0_6_PIN 6 #define PIO0_6_PORT LPC_GPIO0 #define PIO0_6_OUTPUT 0x00 +#define PIO0_6_TIMER NO_TIMER +#define PIO0_6_MATCH 0 +#define PIO0_6_PWM 0 #define PIO0_7_CMSIS PIO0_7 #define PIO0_7_PIN 7 #define PIO0_7_PORT LPC_GPIO0 #define PIO0_7_OUTPUT 0x00 +#define PIO0_7_TIMER NO_TIMER +#define PIO0_7_MATCH 0 +#define PIO0_7_PWM 0 #define PIO0_8_CMSIS PIO0_8 #define PIO0_8_PIN 8 @@ -157,12 +195,18 @@ #define PIO0_11_OUTPUT ((0x01 << 0) | (0x01 << 7)) #define PIO0_11_ADC 0 // Timer pin CT32B0_MAT3, but timer used for Step interrupt. +#define PIO0_11_TIMER NO_TIMER +#define PIO0_11_MATCH 0 +#define PIO0_11_PWM 0 #define PIO1_0_CMSIS R_PIO1_0 #define PIO1_0_PIN 0 #define PIO1_0_PORT LPC_GPIO1 #define PIO1_0_OUTPUT ((0x01 << 0) | (0x01 << 7)) #define PIO1_0_ADC 1 +#define PIO1_0_TIMER NO_TIMER +#define PIO1_0_MATCH 0 +#define PIO1_0_PWM 0 #define PIO1_1_CMSIS R_PIO1_1 #define PIO1_1_PIN 1 @@ -197,28 +241,43 @@ #define PIO1_4_OUTPUT (0x01 << 7) #define PIO1_4_ADC 5 // Timer pin CT32B1_MAT3, but match used for PWM reset. +#define PIO1_4_TIMER NO_TIMER +#define PIO1_4_MATCH 0 +#define PIO1_4_PWM 0 #define PIO1_5_CMSIS PIO1_5 #define PIO1_5_PIN 5 #define PIO1_5_PORT LPC_GPIO1 #define PIO1_5_OUTPUT 0x00 +#define PIO1_5_TIMER NO_TIMER +#define PIO1_5_MATCH 0 +#define PIO1_5_PWM 0 #define PIO1_6_CMSIS PIO1_6 #define PIO1_6_PIN 6 #define PIO1_6_PORT LPC_GPIO1 #define PIO1_6_OUTPUT 0x00 // Timer pin CT32B0_MAT0, but timer used for Step interrupt. +#define PIO1_6_TIMER NO_TIMER +#define PIO1_6_MATCH 0 +#define PIO1_6_PWM 0 #define PIO1_7_CMSIS PIO1_7 #define PIO1_7_PIN 7 #define PIO1_7_PORT LPC_GPIO1 #define PIO1_7_OUTPUT 0x00 // Timer pin CT32B0_MAT1, but timer used for Step interrupt. +#define PIO1_7_TIMER NO_TIMER +#define PIO1_7_MATCH 0 +#define PIO1_7_PWM 0 #define PIO1_8_CMSIS PIO1_8 #define PIO1_8_PIN 8 #define PIO1_8_PORT LPC_GPIO1 #define PIO1_8_OUTPUT 0x00 +#define PIO1_8_TIMER NO_TIMER +#define PIO1_8_MATCH 0 +#define PIO1_8_PWM 0 #define PIO1_9_CMSIS PIO1_9 #define PIO1_9_PIN 9 diff --git a/heater-arm.c b/heater-arm.c index 5dcdd47..690245c 100644 --- a/heater-arm.c +++ b/heater-arm.c @@ -6,6 +6,7 @@ #if defined TEACUP_C_INCLUDE && defined __ARMEL__ #include "cmsis-lpc11xx.h" +#include #include "pinio.h" #include "sersendf.h" #include "debug.h" @@ -57,14 +58,24 @@ #include "config_wrapper.h" trick. */ typedef struct { - /// Pointer to the match register which changes PWM duty. - __IO uint32_t* match; + union { + /// Pointer to the match register which changes PWM duty. + __IO uint32_t* match; + /// Pointer to the port for non-PWM pins. + __IO uint32_t* masked_port; + }; + uint8_t uses_pwm; } heater_definition_t; #undef DEFINE_HEATER #define DEFINE_HEATER(name, pin, pwm) \ - { &(pin ## _TIMER->MR[pin ## _MATCH]) }, + { \ + { pwm && pin ## _TIMER ? \ + &(pin ## _TIMER->MR[pin ## _MATCH]) : \ + &(pin ## _PORT->MASKED_ACCESS[MASK(pin ## _PIN)]) }, \ + pwm && pin ## _TIMER \ + }, static const heater_definition_t heaters[NUM_HEATERS] = { #include "config_wrapper.h" }; @@ -114,12 +125,12 @@ void heater_init() { PIO1_7 CT32B0_MAT1 0x2 TXD, Step timer PIO1_9 CT16B1_MAT0 0x1 --- */ - if (NUM_HEATERS) { // At least one channel in use. - uint32_t freq; - - // Auto-generate pin setup. - #undef DEFINE_HEATER - #define DEFINE_HEATER(name, pin, pwm) \ + // Auto-generate pin setup. + #undef DEFINE_HEATER + #define DEFINE_HEATER(name, pin, pwm) \ + if (pwm && pin ## _TIMER) { \ + uint32_t freq; \ + \ if (pin ## _TIMER == LPC_TMR16B0) { \ LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7); /* Turn on CT16B0. */ \ } \ @@ -133,7 +144,7 @@ void heater_init() { LPC_IOCON->pin ## _CMSIS = pin ## _PWM; /* Connect to timer. */ \ /*pin ## _TIMER->IR = 0; ( = reset value) No interrupts. */ \ pin ## _TIMER->TCR = (1 << 0); /* Enable counter. */ \ - freq = F_CPU / PWM_SCALE / pwm; /* Figure PWM freq. */ \ + freq = F_CPU / PWM_SCALE / (pwm ? pwm : 1); /* Figure PWM freq. */ \ if (freq > 65535) \ freq = 65535; \ if (freq < 1) \ @@ -149,10 +160,14 @@ void heater_init() { | (0x03 << ((pin ## _MATCH * 2) + 4))); /* Toggle pin on match.*/ \ /*pin ## _TIMER->CTCR = 0; ( = reset value) Timer mode. */ \ pin ## _TIMER->PWMC |= ((1 << 3) /* 3 to PWM mode. */ \ - | (1 << pin ## _MATCH)); /* Pin to PWM mode. */ - #include "config_wrapper.h" - #undef DEFINE_HEATER - } /* NUM_HEATERS */ + | (1 << pin ## _MATCH)); /* Pin to PWM mode. */ \ + } \ + else { \ + SET_OUTPUT(pin); \ + WRITE(pin, 0); \ + } + #include "config_wrapper.h" + #undef DEFINE_HEATER #if 0 pid_init(i); @@ -175,11 +190,17 @@ void heater_set(heater_t index, uint8_t value) { heaters_runtime[index].heater_output = value; - // Remember, we scale, and duty cycle is inverted. - *heaters[index].match = PWM_SCALE - ((uint32_t)value * (PWM_SCALE / 255)); + if (heaters[index].uses_pwm) { + // Remember, we scale, and duty cycle is inverted. + *heaters[index].match = PWM_SCALE - ((uint32_t)value * (PWM_SCALE / 255)); - if (DEBUG_PID && (debug_flags & DEBUG_PID)) - sersendf_P(PSTR("PWM %su = %lu\n"), index, *heaters[index].match); + if (DEBUG_PID && (debug_flags & DEBUG_PID)) + sersendf_P(PSTR("PWM %su = %lu\n"), index, *heaters[index].match); + } + else { + *(heaters[index].masked_port) = + (value >= HEATER_THRESHOLD) ? 0xFFFF : 0x0000; + } if (value) power_on();