created 318LPW1K-L firmware

This commit is contained in:
King Kévin 2014-07-12 18:33:34 -07:00
parent c1eee8aaf1
commit 816b2190e2
1 changed files with 152 additions and 0 deletions

152
pic/318LPW1K-L/318LPW1K-L.c Normal file
View File

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