[chronojump] Updated encoder firmware, scannable



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]