correct transmission timing and add inter-transmission pause
This commit is contained in:
parent
bcf548583f
commit
f8d376888a
|
@ -40,8 +40,10 @@
|
|||
/* variables */
|
||||
// a megacode is 3 bytes long (MSB of byte 1 is 1)
|
||||
# define CODE 0xc917c2
|
||||
// transmitting (0: do not transmit, 1: transmit, -1: finish transmiting)
|
||||
// transmitting (0: do not transmit, 1: transmit, -1: finish transmiting, -2: pause before next transmission)
|
||||
volatile int8_t transmit = 0;
|
||||
// the number or timer 2 overflow (0x06554s) to wait before next transmission
|
||||
volatile int8_t pause = 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)
|
||||
volatile uint8_t phase = 0;
|
||||
// save the GPIO state to be able to figure out which changed
|
||||
|
@ -57,20 +59,17 @@ uint16_t __at(_CONFIG) __CONFIG = _WRT_OFF & // entire memory write protected
|
|||
_WDTE_OFF & // disable watchdog
|
||||
_INTRC_OSC_NOCLKOUT; // use internal oscillator and both I/O pins
|
||||
|
||||
/* set timer in ms */
|
||||
#define TICKS_PER_MS 125UL // the number of timer 1 ticks to wait for 1ms, using the internal 4MHz clock and a prescaler of 8, and hand tuning
|
||||
|
||||
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
|
||||
TMR1L = 0x88; // set time (tuned per hand)
|
||||
TMR1H = 0xff; // 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
|
||||
TMR1L = 0x23; // set time (tuned per hand)
|
||||
TMR1H = 0xff; // set time
|
||||
TMR1ON = 1; // start timer 1
|
||||
}
|
||||
|
||||
|
@ -94,11 +93,15 @@ void megacode (void) {
|
|||
timer_2ms();
|
||||
} else { // restart after 25th bit
|
||||
phase = 0xff; // phase will be 0 after incrementing
|
||||
clock_off(); // stop clock
|
||||
if (transmit == -1) { // stop transmiting if requested
|
||||
transmit = 0; // stop transmiting
|
||||
clock_off(); // stop clock
|
||||
} else { // pause before next transmission
|
||||
transmit = -2; // pause state
|
||||
TMR2 = 0; // clear timer 2 (used to measure timer)
|
||||
pause = 0; // reset number of timer 2 overflows (65.54ms)
|
||||
TMR2ON = 1; // start timer 2
|
||||
}
|
||||
timer_1ms();
|
||||
}
|
||||
phase++; // go to next phase
|
||||
}
|
||||
|
@ -118,6 +121,7 @@ void init (void) {
|
|||
GPIE = 1; // enable interrupt on GPIO
|
||||
last_gpio = GPIO; // save current state
|
||||
|
||||
/* use precise timer 1 for the megacode transmission timing */
|
||||
T1CON = _T1CKPS1 | _T1CKPS0; // set prescaler to 8
|
||||
// 0 is set per default, but just be sure
|
||||
TMR1ON = 0; // stop timer 1
|
||||
|
@ -127,6 +131,19 @@ void init (void) {
|
|||
PIE1 = 1; // enable timer 1 interrupt
|
||||
PEIE = 1; // enable timer interrupt
|
||||
|
||||
/* use timer 2 to separate two transmissions in time */
|
||||
TMR2ON = 0; // switch off timer 2
|
||||
T2CKPS0 = 1; // set prescaler to 16
|
||||
T2CKPS1 = 1; // set prescaler to 16
|
||||
TOUTPS0 = 1; // set postscaler to 16
|
||||
TOUTPS1 = 1; // set postscaler to 16
|
||||
TOUTPS2 = 1; // set postscaler to 16
|
||||
TOUTPS3 = 1; // set postscaler to 16
|
||||
PR2 = 0xff; // set interrupt on overflow
|
||||
TMR2 = 0; // clear timer counter
|
||||
TMR2IE = 1; // enable timer 2 interrupt
|
||||
TMR2IF = 0; // clear timer 2 interrupt
|
||||
|
||||
GIE = 1; // enable interrups
|
||||
|
||||
}
|
||||
|
@ -137,9 +154,9 @@ static void interrupt(void) __interrupt 0
|
|||
{
|
||||
if (GPIF) { // pin state changed
|
||||
last_gpio ^= GPIO; // figure out which GPIO changed
|
||||
if (last_gpio&SWITCH2) { // switch 1 (bigger button on top right) changed
|
||||
if (GPIO&SWITCH2) { // button released, stop transmission
|
||||
if (transmit == 1) { // currently transmitting
|
||||
if (last_gpio&SWITCH4) { // switch 1 (bigger button on top right) changed
|
||||
if (GPIO&SWITCH4) { // button released, stop transmission
|
||||
if (transmit != 0) { // currently transmitting
|
||||
transmit = -1; // stop transmitting after last transmition
|
||||
}
|
||||
} else { // switch is pressed, start transmission
|
||||
|
@ -154,11 +171,24 @@ static void interrupt(void) __interrupt 0
|
|||
last_gpio = GPIO; // save current state
|
||||
GPIF = 0; // clear interrupt
|
||||
}
|
||||
if (TMR1IF) { // timer 1 overflow
|
||||
if (TMR1IF) { // timer 1 overflow, used to time megacode pulses
|
||||
megacode(); // continue sending megacode
|
||||
TMR1IF = 0; // clean interrupt
|
||||
}
|
||||
|
||||
if (TMR2IF) { // timer 2 overflow, used to pause between two transmissions
|
||||
pause++; // number of timer 2 overflows (65.54ms)
|
||||
if (transmit == -1) { // stop transmission
|
||||
TMR2ON = 0; // stop counting pauses
|
||||
transmit = 0; // stop transmission
|
||||
} else if (pause==4) { // time between transmissions passed
|
||||
transmit = 1;
|
||||
phase = 0; // start from beginning
|
||||
clock_on(); // start clock and leave it on during the whole transmission
|
||||
megacode(); // start sending megacode
|
||||
TMR2ON = 0; // stop counting pauses
|
||||
}
|
||||
TMR2IF = 0; // clean interrupt
|
||||
}
|
||||
}
|
||||
|
||||
void main (void)
|
||||
|
|
Loading…
Reference in New Issue