ARM: allow non-PWM pins as heater output.

Just like with AVR, they're simply set as a GPIO output and
turned on and off as needed.

Bed heater and temp sensor not yet re-enabled, because Gen7-ARM
has a driver MOSFET for the bed, which needs an inverted signal.
It can be enabled for testing; M106 P1 S2 turns it on, M106 P1 S20
turns it off. Not the way it should work.
This commit is contained in:
Markus Hitter 2015-08-09 16:39:10 +02:00
parent 10310e9d19
commit a1ef39f1f0
2 changed files with 98 additions and 18 deletions

View File

@ -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

View File

@ -6,6 +6,7 @@
#if defined TEACUP_C_INCLUDE && defined __ARMEL__
#include "cmsis-lpc11xx.h"
#include <stddef.h>
#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();