aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKing Kévin <kingkevin@cuvoodoo.info>2014-07-12 18:33:34 -0700
committerKing Kévin <kingkevin@cuvoodoo.info>2014-07-12 18:33:34 -0700
commit816b2190e20814f1a7016370b8e13d5b6a0fa691 (patch)
treec1f77a367c7d525ebeb543448bae7510de94bc5c
parentc1eee8aaf12759714aa190549033bf347f6a46b4 (diff)
created 318LPW1K-L firmware
-rw-r--r--pic/318LPW1K-L/318LPW1K-L.c152
1 files changed, 152 insertions, 0 deletions
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 <pic12f629.h>
+#include <stdint.h>
+#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)
+ }
+ }
+}