[chronojump] Updated encoder firmware, scannable
- From: Xavier de Blas <xaviblas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [chronojump] Updated encoder firmware, scannable
- Date: Fri, 20 Apr 2012 13:59:35 +0000 (UTC)
commit 9c28520a51c10304a242f0199d9a39b8de741bba
Author: Xavier de Blas <xaviblas gmail com>
Date: Fri Apr 20 15:58:34 2012 +0200
Updated encoder firmware, scannable
.../chronopic-firmware-c/chronopic-firmware.c | 505 +++++++++++++-------
1 files changed, 335 insertions(+), 170 deletions(-)
---
diff --git a/chronopic-firmware/chronopic-firmware-c/chronopic-firmware.c b/chronopic-firmware/chronopic-firmware-c/chronopic-firmware.c
index 62ca757..89b61ab 100644
--- a/chronopic-firmware/chronopic-firmware-c/chronopic-firmware.c
+++ b/chronopic-firmware/chronopic-firmware-c/chronopic-firmware.c
@@ -1,27 +1,38 @@
/*
Software for the microcontroller PIC16F876A used by the Chronopic chronometer on Chronojump project
-
+
Translation of firmware from assembler to C (SDCC):
source: http://git.gnome.org/browse/chronojump/plain/chronopic-firmware/chronopic-firmware-assembler/chronopic-firmware.asm
LICENSE: GPL
+encoder:
+ * brown: VCC
+ * blue : GND
+ * black: CLK pin 21
+ * white: VATA pin 23
+
+PIC16F87
+ * RB5 : option pin 26
+
History:
- 2005 Original Firmware from Juan GonzÃlez <juan iearobotics com>
- 2010 Translated comments to english by Xavi de Blas <xaviblas gmail com>
- 2011-01-01 Rewritten Firmware on C. complete TMR0 interrupt by Teng Wei Hua <wadedang gmail com>
- 2011-05-13 Fixed ERROR: TIME = 04 ED by Teng Wei Hua <wadedang gmail com>
+ 2011-01-01 complete TMR0 interrupt
+ 2011-05-13 ERROR: TIME = 04 ED
modify configuration Bits: close WDT
modify ISR and MAIN LOOP's if --> else if
limit COUNTDEBOUNCE overflow in INTERRUPT(isr)
assembler is more efficient than C
- 2011-05-25 change crystal from 4 to 20 MHz by Teng Wei Hua <wadedang gmail com>
+ 2011-05-25 change crystal from 4 to 20 MHz
let SPBRG = 0X81
+ 2011-07-23 add new function of encoder.
+ 2011-07-30 complete every 1 ms send 1 byte to PC, detect if encoder turn clockwise or counterclockwise
+ 2011-08-09 version 5 set baud rate = 625000.
+ 2012-04-02 change the baud rate = 115200, set default function = encoder.
+ 2012-04-19 if PC send command 'J' for porti scanning, Chronopic will return 'J'
*/
//-- this PIC is going to be used:
-#include <pic16f876A.h> //Wade (Windows)
-//#include <pic16f876a.h> //xavi (Linux Mint 10)
+#include <pic16f876A.h>
//*****************************************
@@ -41,12 +52,15 @@ unsigned char RSTATUS = 'E'; // Response of the status frame
//-- Initialization value of the TIMER0 to have TICKS with a duration of 10ms
//-- It's used for the debouncing time
-unsigned char TICK = 0xD9;
+//4M:D9 20M:3D
+unsigned char TICK = 0x3D;
//-- Value of the debouncing time (in units of 10 milliseconds)
//-- This value can be changed, in order to select the most suitable
//-- Signals with a duration lower than this value are considered spurious
-unsigned char DEBOUNCE_TIME = 0x05;
+//unsigned char DEBOUNCE_TIME = 0x05;
+//0x14
+unsigned char DEBOUNCE_TIME = 0x14;
//-- Status of main automaton
unsigned char STAT_WAITING_EVENT = 0x00;
@@ -92,86 +106,143 @@ unsigned char pause_l;
//-- Store a character of the received frame
unsigned char my_char;
-unsigned char i = 0;
+
+//-- wade's addition variables
+unsigned char i = 0, j = 0;
+unsigned char option = 1; // option: 0 button enable, 1 encoder enable
+unsigned char command_port_scanning = 'J';
+
+//-- encoder's valus
+char encoder_count = 0;
+
// Interruptions routine
// Find the interruption cause
void isr(void) __interrupt 0
{
- //******************************************************
- //* Routine of interruption of timer0
- //* timer0 is used to control debouncing time
- //* A change on input signal is stable if time it's at minimum equal to debouncing time
- //* This timer is working all the time.
- //* Main automaton know when there's valid information
- //******************************************************
- // Cause by timer0
- if (T0IF == 1)
- {
- T0IF = 0; // Remove overflow flag
- TMR0 = TICK; //-- Execute timer again inside a click
- if (COUNTDEBOUNCE > 0) // wade : limit COUNTDEBOUNCE overflow
- COUNTDEBOUNCE--; //-- Decrese debouncing counter
- }
- //****************************************************
- // Routine of port B interruption
- // Called everytime that's a change on bit RB4
- // This is the main part.
- // Everytime that's a change on input signal,
- // it's timestamp is recorded on variable (TIMESTAMP, 3 bytes)
- // and we start debouncing time phase
- //****************************************************
- // Caused by a change on B port
- else if (RBIF == 1)
+ //while (!TXIF);
+ //TXREG = 0xaa;
+ if (option == 0)
{
- if (reset == 1)
- {
- //-- It's the first event after reset
- //-- Put counter on zero and go to status reset=0
+ //******************************************************
+ //* Routine of interruption of timer0
+ //* timer0 is used to control debouncing time
+ //* A change on input signal is stable if time it's at minimum equal to debouncing time
+ //* This timer is working all the time.
+ //* Main automaton know when there's valid information
+ //******************************************************
+ // Cause by timer0
+ if (T0IF == 1)
+ {
+ T0IF = 0; // Remove overflow flag
+ TMR0 = TICK; //-- Execute timer again inside a click
+ if (COUNTDEBOUNCE > 0) // wade : limit COUNTDEBOUNCE overflow
+ COUNTDEBOUNCE--; //-- Decrese debouncing counter
+ while (!TXIF);
+ TXREG = COUNTDEBOUNCE;
+ }
+ //****************************************************
+ // Routine of port B interruption
+ // Called everytime that's a change on bit RB4
+ // This is the main part.
+ // Everytime that's a change on input signal,
+ // it's timestamp is recorded on variable (TIMESTAMP, 3 bytes)
+ // and we start debouncing time phase
+ //****************************************************
+ // Caused by a change on B port
+ else if (RBIF == 1)
+ {
+ if (reset == 1)
+ {
+ //-- It's the first event after reset
+ //-- Put counter on zero and go to status reset=0
+ TMR1HH = 0;
+ TMR1H = 0;
+ TMR1L = 0;
+ reset = 0;
+ }
+ //-- Store the value of chronometer on TIMESTAMP
+ //-- This is the timestamp of this event
+ TIMESTAMP_HH = TMR1HH;
+ TIMESTAMP_H = TMR1H;
+ TIMESTAMP_L = TMR1L;
+ //-- Initialize timer 1
TMR1HH = 0;
TMR1H = 0;
TMR1L = 0;
- reset = 0;
+ //-- Initialize debouncing counter
+ COUNTDEBOUNCE = DEBOUNCE_TIME;
+
+ //-- start debouncing status
+ status = STAT_DEBOUNCE;
+ //-- start debouncing timer on a tick
+ TMR0 = TICK;
+ //-- Remove interruption flag
+ RBIF = 0;
+ //-- Inhabilite B port interruption
+ // wade : take care
+ RBIE = 0;
}
- //-- Store the value of chronometer on TIMESTAMP
- //-- This is the timestamp of this event
- TIMESTAMP_HH = TMR1HH;
- TIMESTAMP_H = TMR1H;
- TIMESTAMP_L = TMR1L;
- //-- Initialize timer 1
- TMR1HH = 0;
- TMR1H = 0;
- TMR1L = 0;
- //-- Initialize debouncing counter
- COUNTDEBOUNCE = DEBOUNCE_TIME;
-
- //-- start debouncing status
- status = STAT_DEBOUNCE;
- //-- start debouncing timer on a tick
- TMR0 = TICK;
- //-- Remove interruption flag
- RBIF = 0;
- //-- Inhabilite B port interruption
- RBIE = 0;
- }
- //********************************************************
- //* Routine of interruption of timer1
- //* timer 1 controls the cronometring
- //* This routine is invoked when there's an overflow
- //* Timer 1 gets extended with 1 more byte: TMR1HH
- //********************************************************
- // Caused by timer1
- else if (TMR1IF == 1)
+ //********************************************************
+ //* Routine of interruption of timer1
+ //* timer 1 controls the cronometring
+ //* This routine is invoked when there's an overflow
+ //* Timer 1 gets extended with 1 more byte: TMR1HH
+ //********************************************************
+ // Caused by timer1
+ else if (TMR1IF == 1)
+ {
+ TMR1IF = 0; // Remove overflow flag
+ if (TMR1HH != 0xFF)
+ {
+ //-- Overflow control
+ //-- Check if counter has arrived to it's maximum value
+ //-- If it's maximum, then not increment
+ TMR1HH++;
+ }
+ }
+ } // end of (option == 0)
+
+ if (option == 1)
{
- TMR1IF = 0; // Remove overflow flag
- if (TMR1HH != 0xFF)
- {
- //-- Overflow control
- //-- Check if counter has arrived to it's maximum value
- //-- If it's maximum, then not increment
- TMR1HH++;
- }
- }
+ //******************************************************
+ //* Routine of interruption of timer0
+ //* This timer is working all the time.
+ //******************************************************
+ // Cause by timer0
+ if (T0IF == 1)
+ {
+ T0IF = 0; // Remove overflow flag
+ TMR0 = 255 - 18; //-- Execute timer again inside a click
+ //wade : start
+ while (!TXIF);
+ TXREG = encoder_count;
+ encoder_count = 0;
+ // wade : end
+ }
+ if (INTF == 1)
+ {
+ INTF = 0;
+ if (RB2 == 1)
+ {
+ //if (encoder_count < 255)
+ encoder_count++;
+ }
+ else if (RB2 == 0)
+ {
+ //if (encoder_count > 0)
+ encoder_count--;
+ }
+ else
+ {
+ }
+ }
+ else
+ {
+ //while (!TXIF);
+ //TXREG = 0xcc;
+ }
+ } // end of if (option == 1)
}
//---------------------------------------
@@ -181,9 +252,16 @@ void isr(void) __interrupt 0
void sci_configuration()
{
// wade : start
+ // formula: Baud = Frequency / ( 16(x+1) )
// SPBRG = 0X19; // crystal: 4MHz Speed: 9600 baud
// SPBRG = 0X81; // crystal: 20MHz Speed: 9600 baud
- SPBRG = 0X81; // Speed: 9600 baud
+ // SPBRG = 0X0A; // crystal: 20MHz Speed: 115200 baud
+ // SPBRG = 0X01; // crystal: 20MHz Speed: 625000
+ if (option == 0)
+ SPBRG = 0X81; // Speed: 9600 baud
+ else
+ SPBRG = 0X0A; // Speed: 115200 baud
+
// wade : end
TXSTA = 0X24; // Configure transmitter
RCSTA = 0X90; // Configure receiver
@@ -197,7 +275,7 @@ void sci_configuration()
//**************************************************
unsigned char sci_readchar()
{
- while (!RCIF);
+ while (!RCIF); // P1R1:RCIF Receive Interrupt Flag
return RCREG;
}
@@ -265,6 +343,11 @@ void update_led()
//-- Led is on bit RB1. Input variable contains
//-- only an information bit (1,0) on less signficant bit
RB1 = !input;
+ // 2012-04-02
+ if (option == 1)
+ {
+ RB1 = 1;
+ }
}
//*****************************************************
@@ -296,31 +379,54 @@ void status_serv()
RBIE = 1;
}
+/*
static void asm_ledon()
{
__asm
BANKSEL PORTC
MOVLW 0XFF
MOVWF PORTC
- __endasm;
+ __endasm;
}
-
+*/
void main(void)
{
// =========
// START
// =========
-
+
+ //-----------------------------
+ //- Detect option pin 26
+ //-----------------------------
+
//-----------------------------
//- CONFIGURE PORT B
//-----------------------------
//-- Pins I/O: RB0,RB4 inputs, all the other are outputs
- TRISB = 0x11;
-
+ // 2012-04-02 wade: start
+ //if (option == 0)
+ //TRISB = 0x11;
+
+ // encoder Mode
+ //-- Pins I/O: RB0,RB2 inputs, all the other are outputs
+ // 2012-04-02 wade:start
+ TRISB = 0x05;
+ // 2012-04-02 wade:end
+ if (option == 1)
+ {
+ // wade : for testing
+ TRISA = 0x00;
+ RA0 = 1;
+ // wade : for testing
+ TRISB = 0x05;
+ RBIE = 0;
+ RB1 = 1;
+ }
+ // 2012-04-02 wade: end
//-- Pull-ups of port B enabled
//-- Prescaler of timer0 at 256
- //-- RBPU = 0, INTEDG=0, T0CS=0, T0SE=0, PSA=0, [PS2,PS1,PS0]=111
+ //-- RBPU = 0, INTEDG=0(1:rising edge, 0:falling edge), T0CS=0, T0SE=0, PSA=0, [PS2,PS1,PS0]=111
OPTION_REG = 0x07;
//----------------------------------------------
@@ -334,27 +440,42 @@ void main(void)
//-- Remove interruption flag, just in case it's activated
T0IF = 0; // Remove overflow flag
//-- Activate timer. Inside an interruption tick
- TMR0 = TICK;
+ // wade : start
+ if (option == 0)
+ TMR0 = TICK;
+ if (option == 1)
+ TMR0 = 0xFF;
+ // wade : end
//----------------------------------------------
//- CONFIGURATION OF TIMER 1
//----------------------------------------------
- //-- Activate timer
- T1CON = 0X31;
+ //-- Activate timer
+ // set prescaler
+ // wade : start
+ if (option == 0)
+ T1CON = 0X31;
+ // wade : end
//-- Zero value
TMR1HH = 0;
TMR1H = 0;
TMR1L = 0;
//-- Enable interruption
- TMR1IE = 1;
-
+ // wade : sart
+ if (option == 0)
+ TMR1IE = 1;
+ // wade : end
+
//----------------------------
//- Interruptions port B
//----------------------------
//-- Wait to port B get's stable
pause();
//-- Enable interruption of change on port B
- portb_int_enable();
+ // wade : start
+ if (option == 0)
+ portb_int_enable();
+ // wade : end
//------------------------------
//- INITIALIZE VARIABLES
@@ -379,8 +500,36 @@ void main(void)
//--------------------------
//- Interruption TIMER 0
//--------------------------
+ //T0IE = 1; // Activate interruption overflow TMR0
+ /// wade : start
T0IE = 1; // Activate interruption overflow TMR0
-
+
+ // wade : end
+
+ //--------------------------
+ //- Interruption INT RB0
+ //--------------------------
+ // wade : start
+ if (option == 1)
+ INTE = 1;
+ // wade : end
+ // wade : for testing
+ /*
+ for (i = 0; i <= 0x77; i++)
+ {
+ TXEN = 1;
+ for(j = 0; j < 0xFF; j++)
+ {
+ while (!TXIF);
+ TXREG = i;
+ while (!TXIF);
+ TXREG = j;
+ }
+ TXEN = 0;
+ }
+ */
+ // wade : for testing
+
//------------------------------------------
//- ACTIVATE GLOBAL INTERRUPTIONS
//- The party starts, now!!!
@@ -399,93 +548,109 @@ void main(void)
__asm
CLRWDT
__endasm;
-
// wade : start
// sci_sendchar(FCHANGE);
+ //sci_sendchar(0xFF);
+ //sci_sendchar(0xFF);
// wade : end
- //-- Analize serial port waiting to a frame
- if (RCIF == 1) // Yes--> Service of platform status
- {
- my_char = sci_readchar();
- if (my_char == FSTATUS)
- status_serv();
- }
-
- //------------------------------------------------------
- //- DEPENDING AUTOMATON STATUS, GO TO DIFFERENT ROUTINES
- //------------------------------------------------------
- if (status == STAT_WAITING_EVENT) // status = STAT_WAITING_EVENT?
+ if (option == 0)
{
- }
- else if (status == STAT_DEBOUNCE) // status = DEBOUNCE?
- {
- //----------------------------
- //- STATUS DEBOUNCING
- //----------------------------
- if (COUNTDEBOUNCE == 0)
+ //-- Analize serial port waiting to a frame
+ if (RCIF == 1) // Yes--> Service of platform status
+ {
+ my_char = sci_readchar();
+ if (my_char == FSTATUS)
+ status_serv();
+ }
+
+ //------------------------------------------------------
+ //- DEPENDING AUTOMATON STATUS, GO TO DIFFERENT ROUTINES
+ //------------------------------------------------------
+ if (status == STAT_WAITING_EVENT) // status = STAT_WAITING_EVENT?
{
- //-- End of debounce
- //-- Remove interruption flag of port B: to clean. We do not want or need
- //-- what came during that time
- RBIF = 0;
- //-- input_new = input status
- input_new = read_input();
- //-- Compare new input with stable input
- if (input_new == input)
+ }
+ else if (status == STAT_DEBOUNCE) // status = DEBOUNCE?
+ {
+ //----------------------------
+ //- STATUS DEBOUNCING
+ //----------------------------
+ if (COUNTDEBOUNCE == 0)
{
- //-- It came an spurious pulse (change with a duration
- //-- lower than debounce time). It's ignored.
- //-- We continue like if nothing happened
- //-- The value of the counter should be: actual + TIMESTAMP
- //-- TMR1 = TIMR1 + TIMESTAMP
- TMR1L = TMR1L + TIMESTAMP_L;
- //-- Add carry, if any
- if (C == 1) //-- Yes--> Add it to high part
- TMR1H++;
- TMR1H = TMR1H + TIMESTAMP_H;
- //-- Add carry, if any
- if (C == 1) //-- Yes--> Add it to "higher weight" part
- TMR1HH++;
- TMR1HH = TMR1HH + TIMESTAMP_HH;
- //-- Change status to waiting event
- status = STAT_WAITING_EVENT;
- //-- Activate interruption port B
- portb_int_enable();
+ //-- End of debounce
+ //-- Remove interruption flag of port B: to clean. We do not want or need
+ //-- what came during that time
+ RBIF = 0;
+ //-- input_new = input status
+ input_new = read_input();
+ //-- Compare new input with stable input
+ if (input_new == input)
+ {
+ //-- It came an spurious pulse (change with a duration
+ //-- lower than debounce time). It's ignored.
+ //-- We continue like if nothing happened
+ //-- The value of the counter should be: actual + TIMESTAMP
+ //-- TMR1 = TIMR1 + TIMESTAMP
+ TMR1L = TMR1L + TIMESTAMP_L;
+ //-- Add carry, if any
+ if (C == 1) //-- Yes--> Add it to high part
+ TMR1H++;
+ TMR1H = TMR1H + TIMESTAMP_H;
+ //-- Add carry, if any
+ if (C == 1) //-- Yes--> Add it to "higher weight" part
+ TMR1HH++;
+ TMR1HH = TMR1HH + TIMESTAMP_HH;
+ //-- Change status to waiting event
+ status = STAT_WAITING_EVENT;
+ //-- Activate interruption port B
+ portb_int_enable();
+ }
+ else
+ {
+ //-- input!=input_new: Happened an stable change
+ //-- Store new stable input
+ input = input_new;
+ //-- Change to status FRAMEX to send frame with the event
+ status = STAT_FRAMEX;
+ }
}
- else
- {
- //-- input!=input_new: Happened an stable change
- //-- Store new stable input
- input = input_new;
- //-- Change to status FRAMEX to send frame with the event
- status = STAT_FRAMEX;
+ }
+ else if (status == STAT_FRAMEX) // status = FRAMEX?
+ {
+ //----------------------------
+ //- STATUS FRAMEX
+ //----------------------------
+ //-- Send frame of changing input
+ //-- First the frame identifier
+ sci_sendchar(FCHANGE);
+ //-- Send push button status
+ sci_sendchar(input);
+ //-- Send timestamp
+ sci_sendchar(TIMESTAMP_HH);
+ sci_sendchar(TIMESTAMP_H);
+ sci_sendchar(TIMESTAMP_L);
+ //-- Change to next status
+ status = STAT_WAITING_EVENT;
+ //-- Update led status, depending on stable input status
+ update_led();
+ //-- Activate port B interruption
+ portb_int_enable();
+ }
+ } // end of if (option == 0)
+ if (option == 1)
+ {
+ if (RCIF == 1) // if PC send a command from serial port.
+ {
+ T0IE = 0;
+ my_char = sci_readchar();
+ if (my_char == command_port_scanning)
+ {
+ sci_sendchar(command_port_scanning);
}
+ T0IE = 1;
}
}
- else if (status == STAT_FRAMEX) // status = FRAMEX?
- {
- //----------------------------
- //- STATUS FRAMEX
- //----------------------------
- //-- Send frame of changing input
- //-- First the frame identifier
- sci_sendchar(FCHANGE);
- //-- Send push button status
- sci_sendchar(input);
- //-- Send timestamp
- sci_sendchar(TIMESTAMP_HH);
- sci_sendchar(TIMESTAMP_H);
- sci_sendchar(TIMESTAMP_L);
- //-- Change to next status
- status = STAT_WAITING_EVENT;
- //-- Update led status, depending on stable input status
- update_led();
- //-- Activate port B interruption
- portb_int_enable();
- }
-
- }
+ } // end of while
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]