From 816b2190e20814f1a7016370b8e13d5b6a0fa691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Sat, 12 Jul 2014 18:33:34 -0700 Subject: [PATCH] created 318LPW1K-L firmware --- pic/318LPW1K-L/318LPW1K-L.c | 152 ++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 pic/318LPW1K-L/318LPW1K-L.c diff --git a/pic/318LPW1K-L/318LPW1K-L.c b/pic/318LPW1K-L/318LPW1K-L.c new file mode 100644 index 0000000..14f1b46 --- /dev/null +++ b/pic/318LPW1K-L/318LPW1K-L.c @@ -0,0 +1,152 @@ +/* micro-controller firmware fot the Monarch 318LIPW1K(-L) remote + */ + +#define __12f629 +#include +#include +#define sleep() __asm sleep __endasm + +/* the peripherals connected to the pins */ +#define LED_ANODE _GP0 +#define TX _GP1 +#define SWITCH _GP4 +#define LED_CATHODE _GP5 + +#define CODE 0xc917c2 // the code to transmit. least significant bit will be sent first, and must be 1 (sync bit) +volatile int8_t transmit = 0; // transmitting (0: do not transmit, 1: transmit, -1: finish transmiting) +volatile uint8_t phase = 0; // the 4 phases of the bit (2ms pause, 1ms pulse, 2ms pause, 1ms pulse. only transmit during one of the two pulse periode depending on the bit value) + +/* simple functions */ +// NOTE LED and TX can not be enabled at the same time +#define led_on() GPIO |= LED_ANODE; +#define led_off() GPIO &= ~LED_ANODE; +#define tx_on() GPIO |= TX; +#define tx_off() GPIO &= ~TX; + +/* configuration bits + * all set (to 1) per default + * clear (to 0) relevant bits + */ +uint16_t __at(_CONFIG) __CONFIG = _CPD_OFF & // no data code protect + _CP_OFF & // no code proect + _BODEN_OFF & // no brown out detect + _MCLRE_OFF & // disable master clear reset + _PWRTE_ON & // enable power-up timeout + _WDTE_OFF & // no watchdog + _INTRC_OSC_NOCLKOUT; // use internal oscilator and both I/O pins + +/* set timer in ms */ +#define TICKS_PER_MS 145UL // the number of timer 1 ticks to wait for 1ms, using the internal 4MHz clock and a prescaler of 8, and hand tuning +// 145 is a good value +/* +void timer (uint8_t ms) { + TMR1ON = 0; // disable timer 1 (to write value safely) + TMR1L = (0xffff-ms*TICKS_PER_MS); // set time + TMR1H = (0xffff-ms*TICKS_PER_MS)>>8; // set time + TMR1ON = 1; // start timer 1 +} +*/ + +void timer_1ms() { + TMR1ON = 0; // disable timer 1 (to write value safely) + TMR1L = (0xffff-1*TICKS_PER_MS); // set time + TMR1H = (0xffff-1*TICKS_PER_MS)>>8; // set time + TMR1ON = 1; // start timer 1 +} + +void timer_2ms() { + TMR1ON = 0; // disable timer 1 (to write value safely) + TMR1L = (0xffff-2*TICKS_PER_MS); // set time + TMR1H = (0xffff-2*TICKS_PER_MS)>>8; // set time + TMR1ON = 1; // start timer 1 +} + +/* transmit the megacode */ +void megacode (void) { + uint8_t bit = phase/4; + if (transmit != 0) { + if (bit<24) { // transmit bit + if (phase%2) { + uint8_t pulse = (CODE>>(23-bit))&0x01; + if ((phase%4==1 && !pulse) || (phase%4==3 && pulse)) { + led_off(); + tx_on(); + } + timer_1ms(); + } else { + tx_off(); + led_on(); + timer_2ms(); + } + } else if (bit==24) { // 25th bit is a blank + led_on(); + tx_off(); + timer_2ms(); + } else { // restart after 25th bit + phase = 0xff; // phase will be 0 after incrementing + if (transmit == -1) { // stop transmiting if requested + led_off(); + transmit = 0; // stop transmiting + } + timer_1ms(); + } + phase++; // go to next phase + } +} + +/* initialize micro-conroller */ +void init (void) { + TRISIO |= SWITCH; // switch is input + WPU |= SWITCH; // enable pull-up on switch + NOT_GPPU = 0; // enable global weak pull-up for inputs + TRISIO &= ~(LED_ANODE|LED_CATHODE|TX); // all other are outputs + GPIO &= ~(LED_ANODE|LED_CATHODE|TX); // clear output +} + +// funcion called on interrupts +// interrupt 0 is only one on PIC12 +static void interrupt(void) __interrupt 0 +{ + if (GPIF) { // pin state changed + if (GPIO&SWITCH) { // switch is released stop transmission + if (transmit == 1) { + transmit = -1; // stop transmitting after last transmition + } + } else if (transmit == 0) { // switch is pressed, start transmission + transmit = 1; + phase = 0; + megacode(); // start sending megacode + } + GPIF = 0; // clear interrupt + } + if (TMR1IF) { // timer 1 overflow + megacode(); // continue sending megacode + TMR1IF = 0; // clean interrupt + } + +} + +void main (void) +{ + init(); // configure micro-controller + + IOC |= SWITCH; // enable interrupt for the switch + GPIE = 1; // enable interrupt on GPIO + + T1CON = _T1CKPS1 | _T1CKPS0; // set prescaler to 8 + // 0 is per default + //TMR1ON = 0; // stop timer 1 + //TMR1GE = 0; // enable timer 1 + //TMR1CS = 0; // use internal clock / 4 (=1MHz) + //TMR1IF = 0; // clear interrupt + PIE1 = 1; // enable timer 1 interrupt + PEIE = 1; // enable timer interrupt + + GIE = 1; // globally enable interrupts + + while (1) { + if (transmit == 0) { + sleep(); // sleep to save power (this will shut down timer 1) + } + } +}