diff --git a/pic/ACT-34B/ACT-34B.c b/pic/ACT-34B/ACT-34B.c index c37818e..e3ca7cb 100644 --- a/pic/ACT-34B/ACT-34B.c +++ b/pic/ACT-34B/ACT-34B.c @@ -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)