From 120be30fdef749f0d58e739836b40df2ee517bef Mon Sep 17 00:00:00 2001 From: Martin Peach Date: Tue, 17 Oct 2006 20:26:50 +0000 Subject: The PIC version of the arduino svn path=/trunk/externals/hardware/arduino/; revision=6128 --- PICduino/f767duino.asm | 1810 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1810 insertions(+) create mode 100755 PICduino/f767duino.asm (limited to 'PICduino/f767duino.asm') diff --git a/PICduino/f767duino.asm b/PICduino/f767duino.asm new file mode 100755 index 0000000..57a5a0b --- /dev/null +++ b/PICduino/f767duino.asm @@ -0,0 +1,1810 @@ +;******************************************************** +; * +; Filename: f767duino.asm * +; Date: 20061016 * +; File Version: 0.6 * +; Fixed a bug in receive interrupt handler and * +; buffer increment * +; Date: 20061012 * +; File Version: 0.5 * +; Using shadow registers for tris * +; registers to avoid bcf and bsf instructions * +; Date: 20061012 * +; File Version: 0.4 * +; Fixed another bug. Digital out still doesn't * +; work. Next try using shadow registers for tris * +; registers to avoid bcf and bsf instructions * +; Date: 20061011 * +; File Version: 0.3 * +; fixed a couple of bugs. Now analog input works * +; Date: 20060927 * +; File Version: 0.2 * +; completed port to PIC asm * +; Date: 20060921 * +; File Version: 0.1 * +; * +; Author: Martin Peach * +; * +; * +;******************************************************** +; * +; Files required: P16F767.INC * +; * +; * +;************************************************************************************************ +; * +; This is an implementation of the Arduino using a PIC16F767 instead of an ATmega8. * +; See PICduino.CKT for the schematic. * +; * +;************************************************************************************************ +;___Arduino_Pin_Name____=___PIC_Pin_Name____* +; DigitalPin0 RXD = RC7 * +; DigitalPin1 TXD = RC6 * +; DigitalPin2 = RC5 * +; DigitalPin3 = RC4 * +; DigitalPin4 = RC3 * +; DigitalPin5 = RB0 * +; DigitalPin6 = RB4 * +; DigitalPin7 = RB7 * +; DigitalPin8 = RB6 * +; DigitalPin9 PWM = RB5 * +; DigitalPin10 PWM = RC2 * +; DigitalPin11 PWM = RC1 * +; DigitalPin12 = RC0 * +; DigitalPin13 = RB1 * +; AnalogInput0 = RA0/AN0 * +; AnalogInput1 = RA1/AN1 * +; AnalogInput2 = RA2/AN2 * +; AnalogInput3 = RA5/AN4 * +; AnalogInput4 = RB2/AN8 * +; AnalogInput5 = RB3/AN9 * +; VRef = RA3/AN3 * +; * +; Timing parameters: +; FOsc = 14745600Hz +; TOsc = 67.8ns +; Tad = 2.17us, Tcnv = 26.04us +; ADC needs 20us (~10Tad) to charge the sampling capacitor + 2Tad(~5us) after each conversion +;******************************************** +; This is based on Pd_firmware_pde +; Copyright (C) 2006 Hans-Christoph Steiner +; This library is free software; you can redistribute it and/or +; modify it under the terms of the GNU Lesser General Public +; License as published by the Free Software Foundation; either +; version 2.1 of the License, or (at your option) any later version. +; +; This library is distributed in the hope that it will be useful, +; but WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +; Lesser General Public License for more details. +; +; You should have received a copy of the GNU Lesser General +; Public License along with this library; if not, write to the +; Free Software Foundation, Inc., 59 Temple Place, Suite 330, +; Boston, MA 02111-1307 USA +; +; ----------------------------- +; Firmata, the Arduino firmware +; ----------------------------- +; +; Firmata turns the Arduino into a Plug-n-Play sensorbox, servo +; controller, and/or PWM motor/lamp controller. +; +; It was originally designed to work with the Pd object [arduino] +; which is included in Pd-extended. This firmware is intended to +; work with any host computer software package. It can easily be +; used with other programs like Max/MSP, Processing, or whatever can +; do serial communications.; +; @authors: Hans-Christoph Steiner +; help with protocol redesign: Jamie Allen +; key bugfixes: Georg Holzmann +; Gerda Strobl +; @date: 2006-05-19 +; @locations: STEIM, Amsterdam, Netherlands +; IDMI/Polytechnic University, Brookyn, NY, USA +; Electrolobby Ars Electronica, Linz, Austria +; +; +; TODO: add pulseIn functionality +; TODO: add software PWM for servos, etc (servo.h or pulse.h) +; TODO: redesign protocol to accomodate boards with more I/Os +; TODO: +; TODO: add "outputMode all 0/1" command +; TODO: add cycle markers to mark start of analog, digital, pulseIn, and PWM +; +; ========================================================================= + list p=16f767 ; list directive to define processor + #include ; processor specific variable definitions + + __CONFIG _CONFIG1, _CP_OFF & _CCP2_RC1 & _DEBUG_OFF & _VBOR_2_0 & _BOREN_0 & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _HS_OSC + __CONFIG _CONFIG2, _BORSEN_0 & _IESO_OFF & _FCMEN_OFF + +; === CONSTANTS =========================================================== +B19200 equ d'47' ; time constant for baud rate generator +B9600 equ d'95' ; time constant for baud rate generator +; firmware version numbers. The protocol is still changing, so these version +; numbers are important +MAJOR_VERSION equ 0 +MINOR_VERSION equ 1 +; firmata protocol +; =============== +; data: 0-127 +; control: 128-255 +; computer->Arduino commands +; -------------------- +; 128-129 UNUSED +SET_PIN_ZERO_TO_IN equ d'130' ; set digital pin 0 to INPUT +SET_PIN_ONE_TO_IN equ d'131' ; set digital pin 1 to INPUT +SET_PIN_TWO_TO_IN equ d'132' ; set digital pin 2 to INPUT +SET_PIN_THREE_TO_IN equ d'133' ; set digital pin 3 to INPUT +SET_PIN_FOUR_TO_IN equ d'134' ; set digital pin 4 to INPUT +SET_PIN_FIVE_TO_IN equ d'135' ; set digital pin 5 to INPUT +SET_PIN_SIX_TO_IN equ d'136' ; set digital pin 6 to INPUT +SET_PIN_SEVEN_TO_IN equ d'137' ; set digital pin 7 to INPUT +SET_PIN_EIGHT_TO_IN equ d'138' ; set digital pin 8 to INPUT +SET_PIN_NINE_TO_IN equ d'139' ; set digital pin 9 to INPUT +SET_PIN_TEN_TO_IN equ d'140' ; set digital pin 10 to INPUT +SET_PIN_ELEVEN_TO_IN equ d'141' ; set digital pin 11 to INPUT +SET_PIN_TWELVE_TO_IN equ d'142' ; set digital pin 12 to INPUT +SET_PIN_THIRTEEN_TO_IN equ d'143' ; set digital pin 13 to INPUT +; 144-149 UNUSED +DISABLE_DIGITAL_INPUTS equ d'150' ; disable reporting of digital inputs +ENABLE_DIGITAL_INPUTS equ d'151' ; enable reporting of digital inputs +; 152-159 UNUSED +ZERO_ANALOG_INS equ d'160' ; disable reporting on all analog ins +ONE_ANALOG_IN equ d'161' ; enable reporting for 1 analog in (0) +TWO_ANALOG_INS equ d'162' ; enable reporting for 2 analog ins (0,1) +THREE_ANALOG_INS equ d'163' ; enable reporting for 3 analog ins (0-2) +FOUR_ANALOG_INS equ d'164' ; enable reporting for 4 analog ins (0-3) +FIVE_ANALOG_INS equ d'165' ; enable reporting for 5 analog ins (0-4) +SIX_ANALOG_INS equ d'166' ; enable reporting for 6 analog ins (0-5) +; 167-199 UNUSED +SET_PIN_ZERO_TO_OUT equ d'200' ; set digital pin 0 to OUTPUT +SET_PIN_ONE_TO_OUT equ d'201' ; set digital pin 1 to OUTPUT +SET_PIN_TWO_TO_OUT equ d'202' ; set digital pin 2 to OUTPUT +SET_PIN_THREE_TO_OUT equ d'203' ; set digital pin 3 to OUTPUT +SET_PIN_FOUR_TO_OUT equ d'204' ; set digital pin 4 to OUTPUT +SET_PIN_FIVE_TO_OUT equ d'205' ; set digital pin 5 to OUTPUT +SET_PIN_SIX_TO_OUT equ d'206' ; set digital pin 6 to OUTPUT +SET_PIN_SEVEN_TO_OUT equ d'207' ; set digital pin 7 to OUTPUT +SET_PIN_EIGHT_TO_OUT equ d'208' ; set digital pin 8 to OUTPUT +SET_PIN_NINE_TO_OUT equ d'209' ; set digital pin 9 to OUTPUT +SET_PIN_TEN_TO_OUT equ d'210' ; set digital pin 10 to OUTPUT +SET_PIN_ELEVEN_TO_OUT equ d'211' ; set digital pin 11 to OUTPUT +SET_PIN_TWELVE_TO_OUT equ d'212' ; set digital pin 12 to OUTPUT +SET_PIN_THIRTEEN_TO_OUT equ d'213' ; set digital pin 13 to OUTPUT +; 214-228 UNUSED +OUTPUT_TO_DIGITAL_PINS equ d'229' ; next two bytes set digital output data +; 230-239 UNUSED +REPORT_VERSION equ d'240' ; return the firmware version +; 240-249 UNUSED +DISABLE_PWM equ d'250' ; next byte sets pin # to disable +ENABLE_PWM equ d'251' ; next two bytes set pin # and duty cycle +DISABLE_SOFTWARE_PWM equ d'252' ; next byte sets pin # to disable +ENABLE_SOFTWARE_PWM equ d'253' ; next two bytes set pin # and duty cycle +SET_SOFTWARE_PWM_FREQ equ d'254' ; set master frequency for software PWMs +; 255 UNUSED +;*************** +; two byte digital output data format +; ---------------------- +; 0 get ready for digital input bytes (229) +; 1 digitalOut 7-13 bitmask +; 2 digitalOut 0-6 bitmask +; two byte PWM data format +; ---------------------- +; 0 get ready for digital input bytes (ENABLE_SOFTWARE_PWM/ENABLE_PWM) +; 1 pin # +; 2 duty cycle expressed as 1 byte (255 = 100%) +; digital input message format +; ---------------------- +; 0 digital input marker (255/11111111) +; 1 digital read from Arduino // 7-13 bitmask +; 2 digital read from Arduino // 0-6 bitmask +; analog input message format +; ---------------------- +; 0 analog input marker +; 1 high byte from analog input pin 0 +; 2 low byte from analog input pin 0 +; 3 high byte from analog input pin 1 +; 4 low byte from analog input pin 1 +; 5 high byte from analog input pin 2 +; 6 low byte from analog input pin 2 +; 7 high byte from analog input pin 3 +; 8 low byte from analog input pin 3 +; 9 high byte from analog input pin 4 +; 10 low byte from analog input pin 4 +; 11 high byte from analog input pin 5 +; 12 low byte from analog input pin 5 +TOTAL_DIGITAL_PINS equ d'14' + +INPUT equ d'0' ; these aren't defined in Pd_firmware.pde +OUTPUT equ d'1' ; these aren't defined in Pd_firmware.pde +; for comparing along with INPUT and OUTPUT +PWM equ d'2' + +; maximum number of post-command data bytes +MAX_DATA_BYTES equ d'2' + +; == VARIABLES ============================================================ +; this flag says the next serial input will be data +;byte waitForData = 0; +waitForData equ 0x20 ; initialize to 0; +;byte executeMultiByteCommand = 0; // command to execute after getting multi-byte data +executeMultiByteCommand equ 0x21 ; initialize to 0 +;byte storedInputData[MAX_DATA_BYTES] = {0,0}; // multi-byte data +storedInputData0 equ 0x22 ; initialize to 0,0 +storedInputData1 equ 0x23 ; initialize to 0,0 +; this flag says the first data byte for the digital outs is next +;boolean firstInputByte = false; +firstInputByte equ 0x24 ; initialize to 0 +; this int serves as a bit-wise array to store pin status +; 0 = INPUT, 1 = OUTPUT +; int digitalPinStatus; +digitalPinStatusHi equ 0x25 ; initialize to 0,0 +digitalPinStatusLo equ 0x26 ; initialize to 0,0 +; this byte stores the status of whether PWM is on or not +; bit 9 = PWM0, bit 10 = PWM1, bit 11 = PWM2 +; the rest of the bits are unused and should remain 0 +;int pwmStatus; +pwmStatusHi equ 0x27 ; initialize to 0,0 +pwmStatusLo equ 0x28 ; initialize to 0,0 +; this byte stores the status of whether software PWM is on or not +; 00000010 00000000 means bit 10 is softWarePWM enabled +;int softPwmStatus; +softPwmStatusHi equ 0x29 ; initialize to 0,0 +softPwmStatusLo equ 0x2A ; initialize to 0,0 +;boolean digitalInputsEnabled = true; +digitalInputsEnabled equ 0x2B ; initialize to 1 +;byte analogInputsEnabled = 6; +analogInputsEnabled equ 0x2C ; initialize to 6; +;byte analogPin; +analogPin equ 0x2D ; +;int analogData; +analogDataHi equ 0x2E ; +analogDataLo equ 0x2F ; +rxBuf equ 0x40 ; +rxBufEnd equ 0x50 ; +i equ 0x51 ; local variable in setup() +pin equ 0x52 ; pin number for pinMode() +mode equ 0x53 ; pin mode for pinMode() +maskHi equ 0x54 +maskLo equ 0x55 +rxWrPtr equ 0x56 +rxRdPtr equ 0x57 +inputData equ 0x58 +digitalPin equ 0x59 +transmitByte equ 0x5A +digitalData equ 0x5B +fsr_temp equ 0x70 ; variable used for context saving +w_temp equ 0x71 ; variable used for context saving +status_temp equ 0x72 ; variable used for context saving +pclath_temp equ 0x73 ; variable used for context saving +trisa_shadow equ 0x74 +trisb_shadow equ 0x75 +trisc_shadow equ 0x76 +portb_shadow equ 0x77 +portc_shadow equ 0x78 +; ========================================================================= + ORG 0x000 ; processor reset vector + goto setup ; go to beginning of program +; ========================================================================= + ORG 0x004 ; interrupt vector location + movwf w_temp ; save off current W register contents + movf STATUS,w ; move status register into W register + movwf status_temp ; save off contents of STATUS register + movf PCLATH,w ; move pclath register into w register + movwf pclath_temp ; save off contents of PCLATH register + + btfss PIR1,RCIF + goto intout +;receive interrupt +; 6. Flag bit RCIF will be set when reception is complete and an interrupt will be generated if enable bit RCIE is set. +; 7. Read the RCSTA register to get the ninth bit (if enabled) and determine if any error occurred during reception. + bcf STATUS,RP0 ; bank 0 + movf RCSTA,w + andlw b'00000110' ; Framing, Overrun Errors + btfss STATUS,Z + goto RxError +; 8. Read the 8-bit received data by reading the RCREG register. +; handle the character by saving it into rxBuf and incrementing rxWrPtr + movf FSR,w ; first save FSR + movwf fsr_temp + movf rxWrPtr,w ; get the pointer to the buffer + movwf FSR ; into FSR + movf RCREG,w ; read the character + movwf INDF ; store it in the buffer + movf fsr_temp,w ; restore FSR + movwf FSR + incf rxWrPtr,f ; point to next slot in buffer + movlw rxBufEnd ; check for end of buffer + xorwf rxWrPtr,w + btfss STATUS,Z + goto intout ; not yet at end + movlw rxBuf ; reset pointer to start of buffer + movwf rxWrPtr +intout + movf pclath_temp,w ; retrieve copy of PCLATH register + movwf PCLATH ; restore pre-isr PCLATH register contents + movf status_temp,w ; retrieve copy of STATUS register + movwf STATUS ; restore pre-isr STATUS register contents + swapf w_temp,f + swapf w_temp,w ; restore pre-isr W register contents + retfie ; return from interrupt +; 9. If any error occurred, clear the error by clearing enable bit CREN. +RxError + bcf RCSTA,CREN + movf RCREG,w + bsf RCSTA,CREN + goto intout + +; ========================================================================= +; +; ------------------------------------------------------------------------- +;void setup() +;{ +setup + clrf waitForData ; init all the variables + clrf executeMultiByteCommand + clrf storedInputData0 + clrf storedInputData1 + clrf firstInputByte + clrf digitalPinStatusHi + clrf digitalPinStatusLo + clrf pwmStatusHi + clrf pwmStatusLo + clrf softPwmStatusHi + clrf softPwmStatusLo + movlw 1 + movwf digitalInputsEnabled ; initialize to 1 + movlw 6 + movwf analogInputsEnabled ; initialize to 6; + movlw rxBuf + movwf rxWrPtr + movwf rxRdPtr + clrf portb_shadow + clrf portc_shadow + clrf PORTB ; PORTB is cleared anyway at reset + clrf PORTC ; PORTC is cleared anyway at reset + movlw 0xFF ; all inputs (they are anyway after reset) + bsf STATUS,RP0 ; bank 1 + movwf TRISA + movwf trisa_shadow + movwf TRISB + movwf trisb_shadow + movwf TRISC + movwf trisc_shadow + bcf STATUS,RP0 ; bank 0 +; byte i; +; +; beginSerial(19200); + call beginSerial_19200 +; for(i=0; i> 7); // bitshift the big stuff into the output byte + rlf analogDataLo,w ; bit7 into C + rlf analogDataHi,w ; C into bit0 + andlw b'00000111' ; only 10 bits + call printByte +; printByte(analogData % 128); // mod by 32 for the small byte + movf analogDataLo,w + andlw b'01111111' + call printByte +; checkForInput(); + call checkForInput + incf analogPin,f + goto lp_2 +; } +;} +; +; ============subroutines====================================================== +; +; ------------------------------------------------------------------------- +; this function checks to see if there is data waiting on the serial port +; then processes all of the stored data +;void checkForInput() +;{ +checkForInput + movf rxWrPtr,w + xorwf rxRdPtr,w + btfsc STATUS,Z + return +; if(serialAvailable()) +; { +; while(serialAvailable()) +; { + movf rxRdPtr,w + movwf FSR + movf INDF,w +; processInput( (byte)serialRead() ); + call processInput + incf rxRdPtr,f + movlw rxBufEnd + xorwf rxRdPtr,w + btfss STATUS,Z + goto checkForInput + movlw rxBuf ; wrap to start of buffer + movwf rxRdPtr + goto checkForInput +; } +; } +;} +; ------------------------------------------------------------------------- +; printByte: on entry w contains the byte to send +printByte + bsf STATUS,RP0 ; bank 1 + btfss TXSTA,TRMT + goto $-1 + bcf STATUS,RP0 ; bank 0 + movwf TXREG + return +; ------------------------------------------------------------------------- +beginSerial_19200 ; setup USART for 19200 asynchronous receive and transmit, 8bitsNoParity1Stop +; Bits TRISC<7:6> have to be set in order to configure pins RC6/TX/CK and RC7/RX/DT as the USART. +; (They are set at reset) + bsf STATUS,RP0 ; bank 1 +; When setting up an Asynchronous Transmission, follow these steps: +; 1. Initialize the SPBRG register for the appropriate baud rate. If a high-speed baud rate is desired, +; set bit BRGH (see Section 11.1 “AUSART Baud Rate Generator (BRG)”). +; * * * For 14.745600MHz crystal clock, SPBRG=47, BRGH=1 gives 19200 baud. * * * + movlw B19200 ; = d'47' + movwf SPBRG + bsf TXSTA,BRGH +; 2. Enable the asynchronous serial port by clearing bit SYNC and setting bit SPEN. + bcf STATUS,RP0 ; bank 0 + bsf RCSTA,SPEN +; 3. If interrupts are desired, then set enable bit TXIE. +; 4. If 9-bit transmission is desired, then set transmit bit TX9. +; 5. Enable the transmission by setting bit TXEN which will also set bit TXIF. + bsf STATUS,RP0 ; bank 1 + bsf TXSTA,TXEN +; 6. If 9-bit transmission is selected, the ninth bit should be loaded in bit TX9D. +; 7. Load data to the TXREG register (starts transmission). +; 8. If using interrupts, ensure that GIE and PEIE (bits 7 and 6) of the INTCON register are set. +;When setting up an Asynchronous Reception, follow these steps: +; 1. Initialize the SPBRG register for the appropriate baud rate. If a high-speed baud rate is desired, +; set bit BRGH (see Section 11.1 “AUSART Baud Rate Generator (BRG)”). +; 2. Enable the asynchronous serial port by clearing bit SYNC and setting bit SPEN. +; 3. If interrupts are desired, then set enable bit RCIE. + bsf PIE1,RCIE +; 4. If 9-bit reception is desired, then set bit RX9. +; 5. Enable the reception by setting bit CREN. + bcf STATUS,RP0 ; bank 0 + bsf RCSTA,CREN +; 6. Flag bit RCIF will be set when reception is complete and an interrupt will be generated if enable bit RCIE is set. +; 7. Read the RCSTA register to get the ninth bit (if enabled) and determine if any error occurred during reception. +; 8. Read the 8-bit received data by reading the RCREG register. +; 9. If any error occurred, clear the error by clearing enable bit CREN. +; 10. If using interrupts, ensure that GIE and PEIE (bits 7 and 6) of the INTCON register are set. + bsf INTCON,PEIE + bsf INTCON,GIE + return +; ------------------------------------------------------------------------- +;void transmitDigitalInput(byte startPin) +;{ +transmitDigitalInput ; on entry w contains startPin +; byte i; +; byte digitalPin; +;// byte digitalPinBit; +; byte transmitByte = 0; + clrf transmitByte +; byte digitalData; +; + movwf digitalPin + movwf i + clrf maskLo + clrf maskHi + bsf STATUS,C +tdilp_1 ; set up the mask with bit startPin set + rlf maskLo,f + rlf maskHi,f + movf i,f + btfsc STATUS,Z + goto tdi_1 ; mask is at startPin + decf i,f + goto tdilp_1 +; for(i=0;i<7;++i) +; { +tdi_2 +; digitalPin = i+startPin; + incf i,f ; ++i + movlw d'7' + xorwf i,w ; i == 7? + btfsc STATUS,Z + goto tdi_3 ; yes + incf digitalPin,f ; no + bcf STATUS,C + rlf maskLo,f + rlf maskHi,f +;/* digitalPinBit = OUTPUT << digitalPin; +;// only read the pin if its set to input +;if(digitalPinStatus & digitalPinBit) { +;digitalData = 0; // pin set to OUTPUT, don't read +;} +;else if( (digitalPin >= 9) && (pwmStatus & (1 << digitalPin)) ) { +;digitalData = 0; // pin set to PWM, don't read +;}*/ +; if( !(digitalPinStatus & (1 << digitalPin)) ) +tdi_1 + movf digitalPinStatusLo,w + andwf maskLo,w ; maskLo is lowbyte of 1<= 9) && (pin <= 11) ) +; { +; ------------------------------------------------------------------------- +setPinToPwmOrNo + movlw PWM + xorwf mode,w + btfsc STATUS,Z + return ; no more choices + goto setPinToPwm +; digitalPinStatus = digitalPinStatus | (1 << pin); +; pwmStatus = pwmStatus | (1 << pin); +; pinMode(pin,OUTPUT); +; ------------------------------------------------------------------------- +setPinZeroToPWM ; pin0 is RX!!! Don't allow this to happen! TRISC.7 must be 1 +; bsf digitalPinStatusLo,0 +; bsf pwmStatusLo,0 +; bcf trisc_shadow,7 +; goto write_trisc +; bsf STATUS,RP0 ; bank 1 +; bcf TRISC,7 +; bcf STATUS,RP0 ; bank 0 + return +; ------------------------------------------------------------------------- +setPinOneToPWM ; pin1 is TX!!!! Don't allow this to happen! TRISC.6 must be 1 +; bsf digitalPinStatusLo,1 +; bsf pwmStatusLo,1 +; bcf trisc_shadow,6 +; goto write_trisc +; bsf STATUS,RP0 ; bank 1 +; bcf TRISC,6 +; bcf STATUS,RP0 ; bank 0 + return +; ------------------------------------------------------------------------- +setPinTwoToPWM + bsf digitalPinStatusLo,2 + bsf pwmStatusLo,2 + bcf trisc_shadow,5 + goto write_trisc +; ------------------------------------------------------------------------- +setPinThreeToPWM + bsf digitalPinStatusLo,3 + bsf pwmStatusLo,3 + bcf trisc_shadow,4 + goto write_trisc +; ------------------------------------------------------------------------- +setPinFourToPWM + bsf digitalPinStatusLo,4 + bsf pwmStatusLo,4 + bcf trisc_shadow,3 + goto write_trisc +; ------------------------------------------------------------------------- +setPinFiveToPWM + bsf digitalPinStatusLo,5 + bsf pwmStatusLo,5 + bcf trisb_shadow,0 + goto write_trisb +; ------------------------------------------------------------------------- +setPinSixToPWM + bsf digitalPinStatusLo,6 + bsf pwmStatusLo,6 + bcf trisb_shadow,4 + goto write_trisb +; ------------------------------------------------------------------------- +setPinSevenToPWM + bsf digitalPinStatusLo,7 + bsf pwmStatusLo,7 + bcf trisb_shadow,7 + goto write_trisb +; ------------------------------------------------------------------------- +setPinEightToPWM + bsf digitalPinStatusHi,0 + bsf pwmStatusHi,0 + bcf trisb_shadow,6 + goto write_trisb +; ------------------------------------------------------------------------- +setPinNineToPWM + bsf digitalPinStatusHi,1 + bsf pwmStatusHi,1 + bcf trisb_shadow,5 + goto write_trisb +; ------------------------------------------------------------------------- +setPinTenToPWM + bsf digitalPinStatusHi,2 + bsf pwmStatusHi,2 + bcf trisc_shadow,2 + goto write_trisc +; ------------------------------------------------------------------------- +setPinElevenToPWM + bsf digitalPinStatusHi,3 + bsf pwmStatusHi,3 + bcf trisc_shadow,1 + goto write_trisc +; ------------------------------------------------------------------------- +setPinTwelveToPWM + bsf digitalPinStatusHi,4 + bsf pwmStatusHi,4 + bcf trisc_shadow,0 + goto write_trisc +; ------------------------------------------------------------------------- +setPinThirteenToPWM + bsf digitalPinStatusHi,5 + bsf pwmStatusHi,5 + bcf trisb_shadow,1 + goto write_trisb +; } +;} +; return +; ------------------------------------------------------------------------- +; +;void setSoftPwm (int pin, byte pulsePeriod) { +; byte i; +; /* for(i=0; i<7; ++i) { +; mask = 1 << i; +; if(digitalPinStatus & mask) { +; digitalWrite(i, inputData & mask); +; } +; } +; */ +; //read timer type thing +; +; //loop through each pin, turn them on if selected +; //softwarePWMStatus +; //check timer type thing against pulsePeriods for each pin +; //throw pin low if expired +;} +; +; ------------------------------------------------------------------------- +;void setSoftPwmFreq(byte freq) { +;} +; +; +; ------------------------------------------------------------------------- +;void disSoftPwm(int pin) { +; //throw pin low +; +;} +; +write_portc + movf portc_shadow,w + movwf PORTC + return +write_portb + movf portb_shadow,w + movwf PORTB + return +; ------------------------------------------------------------------------- +digitalWrite0 ; write carry bit to digital pin 0 (Pin0 is RX!!!) + bsf portc_shadow,7 + btfss STATUS,C + bcf portc_shadow,7 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite1 ; write carry bit to digital pin 1 (Pin1 is tX!!!) + bsf portc_shadow,6 + btfss STATUS,C + bcf portc_shadow,6 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite2 ; write carry bit to digital pin 2 + bsf portc_shadow,5 + btfss STATUS,C + bcf portc_shadow,5 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite3 ; write carry bit to digital pin 3 + bsf portc_shadow,4 + btfss STATUS,C + bcf portc_shadow,4 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite4 ; write carry bit to digital pin 4 + bsf portc_shadow,3 + btfss STATUS,C + bcf portc_shadow,3 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite5 ; write carry bit to digital pin 5 + bsf portb_shadow,0 + btfss STATUS,C + bcf portb_shadow,0 + goto write_portb +; ------------------------------------------------------------------------- +digitalWrite6 ; write carry bit to digital pin 6 + bsf portb_shadow,4 + btfss STATUS,C + bcf portb_shadow,4 + goto write_portb +; ------------------------------------------------------------------------- +digitalWrite7 ; write carry bit to digital pin 7 + bsf portb_shadow,7 + btfss STATUS,C + bcf portb_shadow,7 + goto write_portb +; ------------------------------------------------------------------------- +digitalWrite8 ; write carry bit to digital pin 8 + bsf portb_shadow,6 + btfss STATUS,C + bcf portb_shadow,6 + goto write_portb +; ------------------------------------------------------------------------- +digitalWrite9 ; write carry bit to digital pin 9 + bsf portb_shadow,5 + btfss STATUS,C + bcf portb_shadow,5 + goto write_portb +; ------------------------------------------------------------------------- +digitalWrite10 ; write carry bit to digital pin 10 + bsf portc_shadow,2 + btfss STATUS,C + bcf portc_shadow,2 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite11 ; write carry bit to digital pin 11 + bsf portc_shadow,1 + btfss STATUS,C + bcf portc_shadow,1 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite12 ; write carry bit to digital pin 12 + bsf portc_shadow,0 + btfss STATUS,C + bcf portc_shadow,0 + goto write_portc +; ------------------------------------------------------------------------- +digitalWrite13 ; write carry bit to digital pin 13 + bsf portb_shadow,1 + btfss STATUS,C + bcf portb_shadow,1 + goto write_portb +; +; +; ------------------------------------------------------------------------- +disableDigitalInputs + clrf digitalInputsEnabled + return +; ------------------------------------------------------------------------- +enableDigitalInputs + bsf digitalInputsEnabled,0 + return +; ------------------------------------------------------------------------- +setZeroAnalogIns + clrw + goto setAnalogIns +; ------------------------------------------------------------------------- +setOneAnalogIn + movlw d'1' + goto setAnalogIns +; ------------------------------------------------------------------------- +setTwoAnalogIns + movlw d'2' + goto setAnalogIns +; ------------------------------------------------------------------------- +setThreeAnalogIns + movlw d'3' + goto setAnalogIns +; ------------------------------------------------------------------------- +setFourAnalogIns + movlw d'4' + goto setAnalogIns +; ------------------------------------------------------------------------- +setFiveAnalogIns + movlw d'5' + goto setAnalogIns +; ------------------------------------------------------------------------- +setSixAnalogIns + movlw d'6' +; ------------------------------------------------------------------------- +setAnalogIns +; analogInputsEnabled = inputData - ZERO_ANALOG_INS; +; break; + movwf analogInputsEnabled + return +; ------------------------------------------------------------------------- +; case ENABLE_PWM: +enablePwm +; case ENABLE_SOFTWARE_PWM: +enableSoftPwm +; waitForData = 2; // 2 bytes needed (pin#, dutyCycle) + movlw d'2' + movwf waitForData +; executeMultiByteCommand = inputData; + movf inputData,w + movwf executeMultiByteCommand +; break; + return +; ------------------------------------------------------------------------- +; case DISABLE_PWM: +disablePwm +; case SET_SOFTWARE_PWM_FREQ: +setSoftPwmFreq +; case DISABLE_SOFTWARE_PWM: +disableSoftPwm +; waitForData = 1; // 1 byte needed (pin#) + movlw d'1' + movwf waitForData +; executeMultiByteCommand = inputData; + movf inputData,w + movwf executeMultiByteCommand +; break; + return +; ------------------------------------------------------------------------- +; case OUTPUT_TO_DIGITAL_PINS: // bytes to send to digital outputs +setOutputToDigitalPins +; firstInputByte = true; + bsf firstInputByte,0 +; break; + return +; ------------------------------------------------------------------------- +; case REPORT_VERSION: +reportVersion +; printByte(REPORT_VERSION); + movlw REPORT_VERSION + call printByte +; printByte(MAJOR_VERSION); + movlw MAJOR_VERSION + call printByte +; printByte(MINOR_VERSION); + movlw MINOR_VERSION + call printByte +; break; +; } +; } + return +;} +; +; ------------------------------------------------------------------------- +; processInput() is called whenever a byte is available on the +; Arduino's serial port. This is where the commands are handled. +; +;void processInput(byte inputData) +;{ +processInput ; on entry w contains a byte of input data from rxBuf +; int i; +; int mask; + movwf inputData ; save the new byte +; +; // a few commands have byte(s) of data following the command +; if( waitForData > 0) +; { + movf waitForData,f + btfsc STATUS,Z + goto pi_1 +; waitForData--; + decf waitForData,f +; storedInputData[waitForData] = inputData; + movlw storedInputData0 + addwf waitForData,w + movwf FSR + movf inputData,w + movwf INDF +; +; if(executeMultiByteCommand && (waitForData==0)) + movf executeMultiByteCommand,f + btfsc STATUS,Z + return ; executeMultiByteCommand == 0 + movf waitForData,f + btfss STATUS,Z + return ; waitForData != 0 +; { +; //we got everything + goto doMultiByteCommand +; ------------------------------------------------------------------------- +mb_enablePwm +; case ENABLE_PWM: ; 251 +; setPinMode(storedInputData[1],PWM); + movf storedInputData1,w + movwf pin + movlw PWM + movwf mode + call setPinMode +; analogWrite(storedInputData[1], storedInputData[0]); +; break; + goto pi_6 +; ------------------------------------------------------------------------- +mb_disablePwm +; case DISABLE_PWM: ; 250 +; setPinMode(storedInputData[0],INPUT); + movf storedInputData0,w + movwf pin + movlw INPUT + movwf mode + call setPinMode +; break; + goto pi_6 +; ------------------------------------------------------------------------- +mb_enableSoftPwm +; case ENABLE_SOFTWARE_PWM: ; 253 +; setPinMode(storedInputData[1],PWM); + movf storedInputData1,w + movwf pin + movlw PWM + movwf mode + call setPinMode +; setSoftPwm(storedInputData[1], storedInputData[0]); +; break; + goto pi_6 +; ------------------------------------------------------------------------- +mb_disableSoftPwm +; case DISABLE_SOFTWARE_PWM: ; 252 +; disSoftPwm(storedInputData[0]); +; break; + goto pi_6 +; ------------------------------------------------------------------------- +mb_setSoftPwmFreq +; case SET_SOFTWARE_PWM_FREQ: ; 254 +; setSoftPwmFreq(storedInputData[0]); +; break; + goto pi_6 +; } +; ------------------------------------------------------------------------- +pi_6 +; executeMultiByteCommand = 0; + clrf executeMultiByteCommand +; } + return +; } +; ------------------------------------------------------------------------- +; else if(inputData < 128) +; { +pi_1 + btfsc inputData,7 + goto doCommand +; if(firstInputByte) + movf pwmStatusLo,w + xorlw 0xFF + andwf digitalPinStatusLo,w + movwf maskLo + movf pwmStatusHi,w + xorlw 0xFF + andwf digitalPinStatusHi,w + movwf maskHi + btfss firstInputByte,0 + goto pi_8 +; { +; // output data for pins 7-13 +; for(i=7; i> 7)); +; } +; } +pi_06 +; firstInputByte = false; + clrf firstInputByte + return +; } +; else +pi_8 +; { // +; for(i=0; i<7; ++i) +; { +; mask = 1 << i; +; if( (digitalPinStatus & mask) && !(pwmStatus & mask) ) +; { +; digitalWrite(i, inputData & mask); + btfss maskLo,0 + goto pi_13 + bcf STATUS,C ; the data bit is zero + btfsc inputData,0 + bsf STATUS,C ; unless it's one + call digitalWrite0 +pi_13 + btfss maskLo,1 + goto pi_14 + bcf STATUS,C ; the data bit is zero + btfsc inputData,1 + bsf STATUS,C ; unless it's one + call digitalWrite1 +pi_14 + btfss maskLo,2 + goto pi_15 + bcf STATUS,C ; the data bit is zero + btfsc inputData,2 + bsf STATUS,C ; unless it's one + call digitalWrite2 +pi_15 + btfss maskLo,3 + goto pi_16 + bcf STATUS,C ; the data bit is zero + btfsc inputData,3 + bsf STATUS,C ; unless it's one + call digitalWrite3 +pi_16 + btfss maskLo,4 + goto pi_17 + bcf STATUS,C ; the data bit is zero + btfsc inputData,4 + bsf STATUS,C ; unless it's one + call digitalWrite4 +pi_17 + btfss maskLo,5 + goto pi_18 + bcf STATUS,C ; the data bit is zero + btfsc inputData,5 + bsf STATUS,C ; unless it's one + call digitalWrite5 +pi_18 + btfss maskLo,6 + goto pi_19 + bcf STATUS,C ; the data bit is zero + btfsc inputData,6 + bsf STATUS,C ; unless it's one + call digitalWrite6 +; } +; } +; } +pi_19 + return +; } + + ORG 0x400 ; table lookup works better when it doesn't cross a 256-byte page boundary +; ------------------------------------------------------------------------- +; else +; { +; inputData > 127 +; switch (inputData) +; { +doCommand + movlw HIGH commandTab + movwf PCLATH + movf inputData,w + andlw 0x7F ; skip the first 127 values + addwf PCL,f ; jump to command +commandTab +; 128-129 UNUSED + return ; 128 + return ; 129 + goto setPinZeroToIn ;SET_PIN_ZERO_TO_IN equ d'130' ; set digital pin 0 to INPUT + goto setPinOneToIn ;SET_PIN_ONE_TO_IN equ d'131' ; set digital pin 1 to INPUT + goto setPinTwoToIn ;SET_PIN_TWO_TO_IN equ d'132' ; set digital pin 2 to INPUT + goto setPinThreeToIn ;SET_PIN_THREE_TO_IN equ d'133' ; set digital pin 3 to INPUT + goto setPinFourToIn ;SET_PIN_FOUR_TO_IN equ d'134' ; set digital pin 4 to INPUT + goto setPinFiveToIn ;SET_PIN_FIVE_TO_IN equ d'135' ; set digital pin 5 to INPUT + goto setPinSixToIn ;SET_PIN_SIX_TO_IN equ d'136' ; set digital pin 6 to INPUT + goto setPinSevenToIn ;SET_PIN_SEVEN_TO_IN equ d'137' ; set digital pin 7 to INPUT + goto setPinEightToIn ;SET_PIN_EIGHT_TO_IN equ d'138' ; set digital pin 8 to INPUT + goto setPinNineToIn ;SET_PIN_NINE_TO_IN equ d'139' ; set digital pin 9 to INPUT + goto setPinTenToIn ;SET_PIN_TEN_TO_IN equ d'140' ; set digital pin 10 to INPUT + goto setPinElevenToIn ;SET_PIN_ELEVEN_TO_IN equ d'141' ; set digital pin 11 to INPUT + goto setPinTwelveToIn ;SET_PIN_TWELVE_TO_IN equ d'142' ; set digital pin 12 to INPUT + goto setPinThirteenToIn ;SET_PIN_THIRTEEN_TO_IN equ d'143' ; set digital pin 13 to INPUT +; 144-149 UNUSED + return ; 144 + return ; 145 + return ; 146 + return ; 147 + return ; 148 + return ; 149 + goto disableDigitalInputs ;DISABLE_DIGITAL_INPUTS equ d'150' ; disable reporting of digital inputs + goto enableDigitalInputs ;ENABLE_DIGITAL_INPUTS equ d'151' ; enable reporting of digital inputs +; 152-159 UNUSED + return ; 152 + return ; 153 + return ; 154 + return ; 155 + return ; 156 + return ; 157 + return ; 158 + return ; 159 + goto setZeroAnalogIns ;ZERO_ANALOG_INS equ d'160' ; disable reporting on all analog ins + goto setOneAnalogIn ;ONE_ANALOG_IN equ d'161' ; enable reporting for 1 analog in (0) + goto setTwoAnalogIns ;TWO_ANALOG_INS equ d'162' ; enable reporting for 2 analog ins (0,1) + goto setThreeAnalogIns ;THREE_ANALOG_INS equ d'163' ; enable reporting for 3 analog ins (0-2) + goto setFourAnalogIns ;FOUR_ANALOG_INS equ d'164' ; enable reporting for 4 analog ins (0-3) + goto setFiveAnalogIns ;FIVE_ANALOG_INS equ d'165' ; enable reporting for 5 analog ins (0-4) + goto setSixAnalogIns ;SIX_ANALOG_INS equ d'166' ; enable reporting for 6 analog ins (0-5) +; 167-199 UNUSED + return ; 167 + return ; 168 + return ; 169 + return ; 170 + return ; 171 + return ; 172 + return ; 173 + return ; 174 + return ; 175 + return ; 176 + return ; 177 + return ; 178 + return ; 179 + return ; 180 + return ; 181 + return ; 182 + return ; 183 + return ; 184 + return ; 185 + return ; 186 + return ; 187 + return ; 188 + return ; 189 + return ; 190 + return ; 191 + return ; 192 + return ; 193 + return ; 194 + return ; 195 + return ; 196 + return ; 197 + return ; 198 + return ; 199 + goto setPinZeroToOut ;SET_PIN_ZERO_TO_OUT equ d'200' ; set digital pin 0 to OUTPUT + goto setPinOneToOut ;SET_PIN_ONE_TO_OUT equ d'201' ; set digital pin 1 to OUTPUT + goto setPinTwoToOut ;SET_PIN_TWO_TO_OUT equ d'202' ; set digital pin 2 to OUTPUT + goto setPinThreeToOut ;SET_PIN_THREE_TO_OUT equ d'203' ; set digital pin 3 to OUTPUT + goto setPinFourToOut ;SET_PIN_FOUR_TO_OUT equ d'204' ; set digital pin 4 to OUTPUT + goto setPinFiveToOut ;SET_PIN_FIVE_TO_OUT equ d'205' ; set digital pin 5 to OUTPUT + goto setPinSixToOut ;SET_PIN_SIX_TO_OUT equ d'206' ; set digital pin 6 to OUTPUT + goto setPinSevenToOut ;SET_PIN_SEVEN_TO_OUT equ d'207' ; set digital pin 7 to OUTPUT + goto setPinEightToOut ;SET_PIN_EIGHT_TO_OUT equ d'208' ; set digital pin 8 to OUTPUT + goto setPinNineToOut ;SET_PIN_NINE_TO_OUT equ d'209' ; set digital pin 9 to OUTPUT + goto setPinTenToOut ;SET_PIN_TEN_TO_OUT equ d'210' ; set digital pin 10 to OUTPUT + goto setPinElevenToOut ;SET_PIN_ELEVEN_TO_OUT equ d'211' ; set digital pin 11 to OUTPUT + goto setPinTwelveToOut ;SET_PIN_TWELVE_TO_OUT equ d'212' ; set digital pin 12 to OUTPUT + goto setPinThirteenToOut ;SET_PIN_THIRTEEN_TO_OUT equ d'213' ; set digital pin 13 to OUTPUT +; 214-228 UNUSED + return ; 214 + return ; 215 + return ; 216 + return ; 217 + return ; 218 + return ; 219 + return ; 220 + return ; 221 + return ; 222 + return ; 223 + return ; 224 + return ; 225 + return ; 226 + return ; 227 + return ; 228 + goto setOutputToDigitalPins ;OUTPUT_TO_DIGITAL_PINS equ d'229' ; next two bytes set digital output data +; 230-239 UNUSED + return; 230 + return; 231 + return; 232 + return; 233 + return; 234 + return; 235 + return; 236 + return; 237 + return; 238 + return; 239 + goto reportVersion ;REPORT_VERSION equ d'240' ; return the firmware version +; 240-249 UNUSED + return ; 241 + return ; 242 + return ; 243 + return ; 244 + return ; 245 + return ; 246 + return ; 247 + return ; 248 + return ; 249 + goto disablePwm ;DISABLE_PWM equ d'250' ; next byte sets pin # to disable + goto enablePwm ;ENABLE_PWM equ d'251' ; next two bytes set pin # and duty cycle + goto disableSoftPwm ;DISABLE_SOFTWARE_PWM equ d'252' ; next byte sets pin # to disable + goto enableSoftPwm ;ENABLE_SOFTWARE_PWM equ d'253' ; next two bytes set pin # and duty cycle + goto setSoftPwmFreq ;SET_SOFTWARE_PWM_FREQ equ d'254' ; set master frequency for software PWMs +; 255 UNUSED + return ; 255 +; ------------------------------------------------------------------------- +digitalRead ; on entry digitalPin is the pin to read, returns value in carry + movlw HIGH digRdTab + movwf PCLATH + movf digitalPin,w + bcf STATUS,C + addwf PCL,f +digRdTab + goto digitalRead0 + goto digitalRead1 + goto digitalRead2 + goto digitalRead3 + goto digitalRead4 + goto digitalRead5 + goto digitalRead6 + goto digitalRead7 + goto digitalRead8 + goto digitalRead9 + goto digitalRead10 + goto digitalRead11 + goto digitalRead12 + goto digitalRead13 +; ------------------------------------------------------------------------- +setPinToIn +; digitalPinStatus = digitalPinStatus &~ (1 << pin); +; pwmStatus = pwmStatus &~ (1 << pin); +; pinMode(pin,INPUT); + movlw HIGH pinintab + movwf PCLATH + movf pin,w + addwf PCL,f +pinintab + goto setPinZeroToIn + goto setPinOneToIn + goto setPinTwoToIn + goto setPinThreeToIn + goto setPinFourToIn + goto setPinFiveToIn + goto setPinSixToIn + goto setPinSevenToIn + goto setPinEightToIn + goto setPinNineToIn + goto setPinTenToIn + goto setPinElevenToIn + goto setPinTwelveToIn + goto setPinThirteenToIn +; ------------------------------------------------------------------------- +setPinToOut + movlw HIGH pinoutTab + movwf PCLATH + movf pin,w + addwf PCL,f +pinoutTab + goto setPinZeroToOut + goto setPinOneToOut + goto setPinTwoToOut + goto setPinThreeToOut + goto setPinFourToOut + goto setPinFiveToOut + goto setPinSixToOut + goto setPinSevenToOut + goto setPinEightToOut + goto setPinNineToOut + goto setPinTenToOut + goto setPinElevenToOut + goto setPinTwelveToOut + goto setPinThirteenToOut +; ------------------------------------------------------------------------- +setPinToPwm + movlw HIGH pinpwmTab + movwf PCLATH + movf pin,w + addwf PCL,f +pinpwmTab + goto setPinZeroToPWM + goto setPinOneToPWM + goto setPinTwoToPWM + goto setPinThreeToPWM + goto setPinFourToPWM + goto setPinFiveToPWM + goto setPinSixToPWM + goto setPinSevenToPWM + goto setPinEightToPWM + goto setPinNineToPWM + goto setPinTenToPWM + goto setPinElevenToPWM + goto setPinTwelveToPWM + goto setPinThirteenToPWM +; ------------------------------------------------------------------------- +analogRead ; analogRead sets analogDataHi and analogDataLo according to analogPin + movlw HIGH analogRdTab + movwf PCLATH + movf analogPin,w + addwf PCL,f +analogRdTab + goto analogRead0 + goto analogRead1 + goto analogRead2 + goto analogRead3 + goto analogRead4 + goto analogRead5 +; ------------------------------------------------------------------------- +doMultiByteCommand +; switch(executeMultiByteCommand) +; { + movlw HIGH mbctab + movwf PCLATH + movlw DISABLE_PWM ; 250 + subwf executeMultiByteCommand,w ; remove offset of 250 + addwf PCL,f +mbctab + goto mb_disablePwm ; 250 + goto mb_enablePwm ; 251 + goto mb_disableSoftPwm ; 252 + goto mb_enableSoftPwm ; 253 + goto mb_setSoftPwmFreq ; 254 +; ------------------------------------------------------------------------- +; + END ; directive 'end of program' + -- cgit v1.2.1