From 278c783d54684e4227edc2bf109cce64c5170f23 Mon Sep 17 00:00:00 2001 From: drowe67 Date: Thu, 25 Jun 2009 09:07:11 +0000 Subject: [PATCH] wispcarb - mods for EV battery tetsing git-svn-id: https://svn.code.sf.net/p/freetel/code@26 01035d8c-6547-0410-b346-abe4f91aad63 --- wispcar/README | 11 + wispcar/batt_test.m | 14 + wispcar/batt_test.sh | 44 ++ wispcar/caliba.m | 29 ++ wispcar/calibb.m | 29 ++ wispcar/documentation.txt | 7 +- wispcar/log2octave.sh | 8 + wispcar/stty | Bin 0 -> 48377 bytes wispcar/wispcar.asm | 35 +- wispcar/wispcarb.asm | 1020 +++++++++++++++++++++++++++++++++++++ 10 files changed, 1188 insertions(+), 9 deletions(-) create mode 100644 wispcar/README create mode 100644 wispcar/batt_test.m create mode 100755 wispcar/batt_test.sh create mode 100644 wispcar/caliba.m create mode 100644 wispcar/calibb.m create mode 100755 wispcar/log2octave.sh create mode 100755 wispcar/stty create mode 100755 wispcar/wispcarb.asm diff --git a/wispcar/README b/wispcar/README new file mode 100644 index 00000000..2d8aede4 --- /dev/null +++ b/wispcar/README @@ -0,0 +1,11 @@ +wispcar README +-------------- + +David Rowe 22 June 2009 + +stty is a WRT54GL OpenWRT binary utility some one had compiled on the web, used +for setting serial port speeds + +wispcar.asm is the original code as per the blog post: http://www.rowetel.com/blog/?p=68 + +wispcarb.asm has a mod to the watchdog timer to stay off, used for battery testing diff --git a/wispcar/batt_test.m b/wispcar/batt_test.m new file mode 100644 index 00000000..7d8d7610 --- /dev/null +++ b/wispcar/batt_test.m @@ -0,0 +1,14 @@ +% batt_test.m +% David Rowe 23 June 2009 +% Plot battery test results + +function batt_test(f) + d = load(f); + mins = d(:,1)*60 + d(:,2); + mins = mins - mins(1); + plot(mins, 0.072*d(:,4) + 0.82,'*'); + xlabel('time (min)'); ylabel('V'); + axis([0 60 11 13]) + grid +endfunction + diff --git a/wispcar/batt_test.sh b/wispcar/batt_test.sh new file mode 100755 index 00000000..e7d472fb --- /dev/null +++ b/wispcar/batt_test.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# batt_test.sh +# David Rowe 22 June 2009 + +if [ $# -ne 2 ] +then + echo "usage ./batt_test.sh cutoff_Vcode logfile" + exit 0 +fi + +/home/stty -F /dev/tts/1 speed 4800 > /dev/null + +rm -f $2 + +# sample initial voltage + +dd if=/dev/tts/1 bs=1 count=36 1>w 2>/dev/null& +echo -n 'w' > /dev/tts/1 +sleep 2 +v=`cut -f 2 -d ' ' w` +echo $v + +# stop when voltage reaches a threshold + +while [ $v -gt $1 ] +do + + # sample voltage + + dd if=/dev/tts/1 bs=1 count=36 1>w 2>/dev/null& + echo -n 'w' > /dev/tts/1 + sleep 2 + v=`cut -f 2 -d ' ' w` + i=`cut -f 3 -d ' ' w` + echo $v $i + + echo -n `date` ' ' >> $2 + echo $v $i >> $2 + + sleep 5 + +done + + diff --git a/wispcar/caliba.m b/wispcar/caliba.m new file mode 100644 index 00000000..3c648b95 --- /dev/null +++ b/wispcar/caliba.m @@ -0,0 +1,29 @@ +% 0.1 ohm current sense resistor 20 June 2009 + +% Vbatt V0.1 I VbattADC IADC +d = [ +[ 8.0 0.121 1.15 36 99] +[ 8.9 0.134 1.27 41 109] +[ 9.8 0.148 1.40 44 121] +[ 11.1 0.167 1.58 50 136] +[ 12.7 0.191 1.80 58 153] +[ 13.1 0.198 1.87 59 159] +] + +figure(1) +plot(d(:,1), d(:,4)) +ylabel("ADC V"); xlabel("Vbatt (V)"); + +figure(2) +plot(d(:,3), d(:,5)) +ylabel('ADC I'); xlabel('I (A)'); + +figure(3) +plot(d(:,2), d(:,3)) +xlabel('Vsense I'); ylabel('I (A)'); + +figure(4) +plot(d(:,2), d(:,5)) +xlabel('Vsense I'); ylabel('ADC I'); +grid + diff --git a/wispcar/calibb.m b/wispcar/calibb.m new file mode 100644 index 00000000..3600688b --- /dev/null +++ b/wispcar/calibb.m @@ -0,0 +1,29 @@ +% 0.1 ohm current sense resistor 20 June 2009 + +% Vbatt VbattADC IADC +d = [ +[ 9.2 118 ] +[ 10.0 129 ] +[ 11.1 142 ] +[ 12.2 156 ] +[ 13.2 169 ] +[ 14.0 179 ] +] + +d1 = [ +[ 12.12 157 ] +[ 12.00 155 ] +[ 11.86 153 ] +[ 11.68 151 ] +[ 11.47 148 ] +] + +figure(1) +plot(d(:,1), d(:,2)) +hold on +plot(d1(:,1), d1(:,2),'g') +hold off +ylabel("ADC V"); xlabel("Vbatt (V)"); +grid +axis([11 13 140 170]) + diff --git a/wispcar/documentation.txt b/wispcar/documentation.txt index 7aff1113..26e7de39 100644 --- a/wispcar/documentation.txt +++ b/wispcar/documentation.txt @@ -60,7 +60,7 @@ Project Plan [ ] Brown out test + vary Vbat from 30V down to 2V 10 times + make sure PIC does not hang - + Specs: ----- @@ -168,6 +168,11 @@ TODO List [X] pinout of BC548 [ ] connect + & - together on unsued op-amp sections [X] TAPR open harwdare license +[ ] PCB ideas + [ ] extra pads for zener to drop input voltage + [ ] extra pads for general prototyping + [ ] break out extra op amp pins + + dont hard-tie them [X] svn repository + with datasheet pdfs ? diff --git a/wispcar/log2octave.sh b/wispcar/log2octave.sh new file mode 100755 index 00000000..7067eb85 --- /dev/null +++ b/wispcar/log2octave.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# log2octave.sh +# David Rowe 23 June 2009 + +# strip out time stamp and voltage into four columns so octave batt_test.m +# can read + +cut -f 4,8 -d ' ' $1 | sed -e 's/:/ /g' > $1.oct diff --git a/wispcar/stty b/wispcar/stty new file mode 100755 index 0000000000000000000000000000000000000000..d350fcde517651c56e5f5b09fcc248c71d915de8 GIT binary patch literal 48377 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 ; VARIABLES --------------------------------------------------------------------- @@ -683,10 +692,23 @@ sleep_cont ; START MAIN LOOP ----------------------------------------------- -main +main + call inch_n_delay ; RS232 RX and 1 second delay - ; sample AN[0] (voltage) + ; sample V, I, and print if we received a 'w' or a ' ' + + movlw 'w' + subwf SERBUFI,0 + btfsc STATUS,Z ; skip if SERBUFI != 'w' + goto sample + + movlw '.' + subwf SERBUFI,0 + btfss STATUS,Z ; skip if SERBUFI == ' ' + goto no_print + ; sample AN[0] (voltage) +sample movlw b'10110001' movwf ADCON0 bsf ADCON0,1 ; start A/D conversion @@ -848,10 +870,7 @@ wait_adc_i movlw '\n' call outch_n - ; RS232 RX and 1 second delay - - call inch_n_delay - +no_print ; has watchdog fired (wd_timeout == 0) ? movf wd_timeout,1 diff --git a/wispcar/wispcarb.asm b/wispcar/wispcarb.asm new file mode 100755 index 00000000..aec22c43 --- /dev/null +++ b/wispcar/wispcarb.asm @@ -0,0 +1,1020 @@ +; wispcarb.asm +; David Rowe June 2009 +; +; WISPCAR modified for EV battery testing. When watchdog fires PowerSwitch +; (pin 6) stays off until the host sends a "w". This switches off current +; to the battery under test if the host side dies. This mod is just a hack +; for now. +; +; +; PIC12F510 Assembler program, MPLAB V8.10 IDE used to build. +; +; ******************************************************** +; * Wifi Station Power Controller And Reporter - WiSPCaR * +; ******************************************************** +; +;--------------------------------------------------------------------- +; Copyright (C) 2008 David Rowe +; +; This program is free software; you can redistribute it and/or modify +; it under the terms of the GNU General Public License as published by +; the Free Software Foundation; either version 2 of the License, or +; (at your option) any later version. +; +; This program 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 General Public License for more details. +; +; You should have received a copy of the GNU General Public License +; along with this program; if not, write to the Free Software +; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +; USA +;--------------------------------------------------------------------- +; +; FUNCTIONS +; ========= +; +; 1/ Monitor Voltage +; 2/ Monitor Current +; 3/ Watchdog timer +; 4/ Sleep timer +; +; +; PINOUT +; ====== +; ____ ____ +; | \/ | +; Vcc --| 1 8 |-- GND +; | | +; Spare I/O --| 2 7 |-- Vsense (in) +; | | +; RS232 Tx (out) --| 3 6 |-- PowerSwitch (out) +; | | +; RS232 Rx (in) --| 4 5 |-- Isense (in) +; |__________| +; +; +; Pin | Function | PIC Name +; -----|-------------|--------- +; 2 | Spare I/O | GP5 +; 3 | RS232 Tx | GP4 +; 4 | RS232 Rx | GP3 +; 5 | Isense | AN2 +; 6 | PowerSwitch | GP1 +; 7 | Vsense | AN0 +; +; +; PIC PROGRAMMING OPTIONS +; ======================= +; +; 8MHz clock, MCLRE=I/O, INTOSC +; +; +; 4800 BAUD RS232 OUTPUT +; ====================== +; +; The following line is printed every time you send 'w' or '.', if you +; send nothing to wispcar it will remain silent. The specific chars +; minimise the chance of wispcar interfering with your boot loader. +; +; Name of script on host that parses this line +; | Vsense +; | | Isense +; | | | char received (ASCII) +; | | | | Last char received (decimal) +; | | | | | Watchdog timeout counter +; | | | | | | Watchdog fire counter +; | | | | | | | Sleep state machine state +; | | | | | | | | Sleep timeout counter +; | | | | | | | | | +; wispcar 040 031 - 032 012 000 0 000 w---reason for last restart +; b - Wispcar (re)booted +; w - watchdog timer fired +; s - we went to sleep +; - - restart flag reset +; +; COMMANDS +; ======== +; +; 1/ Send a 'w' every WD_TIMEOUT seconds to prevent Watchdog timer +; firing and cutting power. +; +; 2/ Send a '.' to report status without resetting watchdog. +; +; 3/ Send the string 'sleepxyz' to cut the power for xyz seconds, +; where x,y and z are digits in the range 0-9. If any part of the +; string is invalid it will be ignored. Wait 5 seconds and start +; again. +; +; 4/ Wispcar cannot rx and tx RS232 at the same time. Wait until after +; the current output has finished to send the next command. It is best to +; wait until just after the output line is received by the host, then +; send your command. If the command (such as sleep) gets messed up, +; just wait 5 seconds and wispcar will reset it's internal state +; machine. You can then try again. +; +; 4/ The final field is reset to a space when a 'w' is sent to +; Wispcar. This field lets the host know just _why_ it was rebooted. + + +#include + +; VARIABLES --------------------------------------------------------------------- + +TEMP equ 0x10 +SERBUF equ 0x11 ; RS232 char to transmit +count equ 0x12 ; temp reg used by "BIN2BCD" and "baud" routines +BIN equ 0x13 +huns equ 0x14 +tens equ 0x15 +ones equ 0x16 +thirty equ 0x17 ; constant set to (guess what) 30 +SERBUFI equ 0x18 ; last RS232 character we received +wd_timeout equ 0x19 ; current watchdog timer value (in secs) + ; when this hits zero we turn the power off +wd_fire equ 0x1a ; count down timer when watchdog fires (in secs) +restart_flag equ 0x1b ; tells host why we just restarted (WD or sleep) + +sleep_state equ 0x1c +sleep_timeout equ 0x1d ; current value of sleep time out (in secs) + ; measures time between rx-ed chars in + ; s-l-e-e-p-x-y-z sequence. + ; If this hits zero (like s-l- (BIG GAP)) + ; we assume sleep command + ; was invalid and we reset the input state machine + + ; three digit sleep time (up to 999 secs) + ; these count down to zero while we are sleeping + ; when count down hits 0 power is switched back on + +sleeping equ 0x1e ; asserted if we are sleeping (power off) + +; following variables are in bank1, which makes life difficult.... + +d1 equ 0x10 +d2 equ 0x11 +d3 equ 0x12 + +x equ 0x13 ; sleep time (hundreds of secs) +y equ 0x14 ; sleep time (tens of secs) +z equ 0x15 ; sleep time (secs) + +; CONSTANTS --------------------------------------------------------------------- + +WD_TIMEOUT equ d'18' ; watchdog timeout in seconds +WD_FIRE equ d'5' ; watchdog firing time in seconds + ; how long power is cut off to host + +SLEEP_TIMEOUT equ d'5' ; timeout between rx-ed chars in sleep input + ; sequence. + +; Values for restart_flag - tell host why we just cut power after we woke up + +BOOT_FLAG equ 'b' ; Wispcar just rebooted +WD_FLAG equ 'w' ; Watchdog fired +SLEEP_FLAG equ 's' ; We slept + +; START PROGRAM ---------------------------------------------------------------- + +; set up osc cal (temp code just for experimenting) +; TODO - FIX ME for general case + + movlw 16 + movwf OSCCAL + +; configure AN[1:0] as analog inputs + + movlw b'10110001' + movwf ADCON0 + +; configure GP[3] as digital input (RS232 RX) +; configure GP[4] as digital output (RS232 TX) +; configure GP[1] as digital output (PowerSwitch) + +; disble the comparitor so we can use GP[1] + + bcf CM1CON0,3 + + ; set up GPIO directions + + movlw b'00001101' + tris GPIO + +; turn on PowerSwitch + + bsf GPIO,1 + +; set up a convenient constant + + movlw h'30' + movwf thirty + +; init watchdog + + movlw WD_TIMEOUT + movwf wd_timeout + clrf wd_fire + +; init sleep + + clrf sleep_state + clrf sleeping + clrf sleep_timeout + bsf FSR,5 ; x,y,z are in bank 1 (grumble) + clrf x + clrf y + clrf z + bcf FSR,5 ; x,y,z are in bank 1 (grumble) + +; init restart_flag + + movlw BOOT_FLAG + movwf restart_flag + + goto main + +; START FUNCTIONS ------------------------------------------------------------ + +; BIN2BCD +; +; Convert 8 bit value in BIN to a 3 digit decimal value. +; +; in.......: BIN +; out......: huns, tens, ones +; Reference: http://www.piclist.com/techref/microchip/math/radix/b2a-8b3d-ab.htm +; +; Uses temp reg 'count' + +; uses ADD-3 algorithm + +BIN2BCD + movlw 8 + movwf count + clrf huns + clrf tens + clrf ones +BCDADD3 + movlw 5 + subwf huns, 0 + btfsc STATUS, C + CALL ADD3HUNS + + movlw 5 + subwf tens, 0 + btfsc STATUS, C + CALL ADD3TENS + + movlw 5 + subwf ones, 0 + btfsc STATUS, C + CALL ADD3ONES + + decf count, 1 + bcf STATUS, C + rlf BIN, 1 + rlf ones, 1 + btfsc ones,4 ; + CALL CARRYONES + rlf tens, 1 + + btfsc tens,4 ; + CALL CARRYTENS + rlf huns,1 + bcf STATUS, C + + movf count, 0 + btfss STATUS, Z + GOTO BCDADD3 + + movf huns, 0 ; add ASCII Offset + addwf thirty, 0 + movwf huns + + movf tens, 0 ; add ASCII Offset + addwf thirty, 0 + movwf tens + + movf ones, 0 ; add ASCII Offset + addwf thirty, 0 + movwf ones + + retlw 0 + +ADD3HUNS + movlw 3 + addwf huns,1 + retlw 0 + +ADD3TENS + movlw 3 + addwf tens,1 + retlw 0 + +ADD3ONES + movlw 3 + addwf ones,1 + retlw 0 + +CARRYONES + bcf ones, 4 + bsf STATUS, C + retlw 0 + +CARRYTENS + bcf tens, 4 + bsf STATUS, C + retlw 0 + +; INCH_N is from "PIC Software UART Routines" +; John Massa, Datadog Systems (C) 2005 + +; ******************************************************************** +; INCH_N +; THIS ROUTINE INPUTS RS232 DATA USING AN INVERTER, LIKE THE MAX232. +; THIS ROUTINE USES A 8-DATA BIT PER CHARACTER PROTOCOL +; GPIO,0 = RX (MARK = 1, SPACE = 0). +; TO RECIEVE A CHARACTER, CALL inch_n, THE RECEIVED CHARACTER IS PLACED +; IN THE REG 'W' AND IN THE REG 'SERBUF'. +; THE RECEIVED CHARACTER WILL ECHO IF 'RETLW 0' IS REM-ED OUT. +; VARIABLES USED: REG 'TEMP' AND REG 'SERBUF' BOTH VARIABLES ARE +; SHARED WITH THE 'outch_n' ROUTINE. +; ROUTINES CALLED: 'half_baud'AND 'baud' TO SET THE BAUD-RATE +; ******************************************************************** + +; Modified by David Rowe May 2008 to combine a 1 second delay with +; character reception. + +inch_n_delay + + ; clear previous rx char + + movlw '-' + movwf SERBUFI + + ; init delay loop for 1999996 cycles + + bsf FSR,5 ; d1, d2, d3 in Bank 1 (groan) + movlw 0x11 + movwf d1 + movlw 0x5D + movwf d2 + movlw 0x05 + movwf d3 + +wait_for_start + bcf FSR,5 ; just in case goto below fires + btfss GPIO,3 ; SKIP UNLESS WE GET A START BIT = 1 (A "MARK") + goto start_serial ; start bit - process character + + ; process delay loop while we look for start bit + + bsf FSR,5 + decfsz d1, f + goto $+2 + decfsz d2, f + goto $+2 + decfsz d3, f + goto wait_for_start + + ; delay finished + + bcf FSR,5 + retlw 0 + +start_serial + bsf GPIO,5 + bcf GPIO,5 + + movlw 8 ; START SERIAL INPUT SEQUENCE + movwf TEMP ; COLLECT 8 DATA BITS + clrf SERBUFI ; CLEAR SERIAL CHARACTER BUFFER + call half_baud ; DELAY FOR ONE HALF BAUD TIME + btfsc GPIO,3 ; FALL THRU IF START BIT STILL = 1 (A "MARK") + goto wait_for_start ; ELSE IT WAS JUST A NOISE SPIKE, KEEP LOOKING +inch_n1 + call baud ; DELAY ONE BAUD-BIT TIME ( = 1/BAUD-RATE) + bcf STATUS,0 ; CLEAR THE CARRY BIT + rrf SERBUFI,F ; ROTATE CRY -> MSB, ROTATE MSB RIGHT + btfsc GPIO,3 ; IS IT A "MARK" ? + bsf SERBUFI,7 ; ...SKIP IF YES, ELSE SET BIT TO LOGIC '1' + decfsz TEMP,F ; EIGHT COUNTS YET? + goto inch_n1 ; ...NO, GET ANOTHER BIT + call baud ; DELAY FOR THE STOP BIT + movf SERBUFI,W ; PUT THE RECEIVED CHARACTER IN REG 'W' + + ; process received character, this can be considered an "event + ; handler" for rx-chars. We expect either a 'w' to reset the + ; watchdog or a tightly defined sequence of sleep characters. + + movlw 'w' + subwf SERBUFI,0 ; is it a 'w' for watchdog reset? + btfss STATUS,Z ; skip if received char matches + goto handle_sleepin ; only process sleep input if not a 'w' + + ; handle 'w' input + + ; Note if we are sleeping or WD is firing we will keep power + ; off and receiving 'w' will have no effect. Unlikely unless + ; device sending rx chars is powered indepednantly (ie during + ; testing). + + movlw WD_TIMEOUT ; reset watchdog timer + movwf wd_timeout + + ; DR June 2009 - mods + bsf GPIO,1 + + movlw '-' ; clear reboot flag + movwf restart_flag + + clrf sleep_state ; reset sleep state machine for good measure + clrf sleep_timeout ; just in case we get s-l-w-e-e-p or something + + goto wait_for_start + +handle_sleepin + call sleep_input + goto wait_for_start + +; OUTCH_N and BAUD are from "PIC Software UART Routines" +; John Massa, Datadog Systems (C) 2005 + +;********************************************************************* +; OUTCH_N +; THIS ROUTINE OUTPUTS RS232 DATA THROUGH AN INVERTER. +; THIS ROUTINE USES AN 8-DATA BIT PER CHARACTER PROTOCOL. +; TO PRINT A CHARACTER, LOAD BYTE INTO REG 'W' AND CALL outch_n. +; GPIO,1 = TX (MARK = 1, SPACE = 0) ; USE INVERTER ON THE OUTPUT +; VARIABLES USED: REG 'TEMP' AND SHARE REG 'SERBUF' WITH THE ROUTINE +; 'inch_n' +; CALLS THE ROUTINE 'baud' TO SET THE BAUD-RATE TIMING. +;********************************************************************* + +outch_n ; THIS ROUTINE USES 8 DATA BITS + movwf SERBUF ; SERBUF CONTAINS CHARACTER TO XMT + movlw 8 ; THE CHARACTER HAS 8 BITS + movwf TEMP + bcf GPIO,4 ; SET START-BIT TO A "SPACE" + call baud ; WAIT ONE BAUD TIME +outch_n1 + rrf SERBUF,F ; ROTATE THE FIRST BIT INTO CARRY + btfss STATUS,0 ; TEST THE CARRY BIT + bcf GPIO,4 ; IF BIT IS 0 SET OUTPUT PIN TO A "0" (SPACE) + btfsc STATUS,0 ; TEST THE CARRY BIT AGAIN + bsf GPIO,4 ; IF BIT IS 1 SET OUTPUT PIN TO A "1" (MARK) + call baud ; ONE BAUD-BIT DELAY + decfsz TEMP,F ; IF COUNT IS ZERO THEN XMIT A STOP BIT + goto outch_n1 ; ...ELSE XMIT NEXT BIT + rrf SERBUF,F ; ROTATE CARRY, GET THE MSB BACK INTO BIT 7 + bsf GPIO,4 ; SET PIN TO A 1 (A "MARK") FOR THE STOP BIT + call baud ; FIRST BAUD-BIT DELAY + call baud ; SECOND BAUD-BIT DELAY + retlw 0 ; RETURN WITH THE CHARACTER IN SERBUF + +; ******************************************************************** +; BAUD ROUTINE @ 4 MHz +; BAUD RATE: CONSTANT: +; 1200 Baud D'137' +; 2400 Baud D'68' +; 4800 Baud D'34' +; 9600 Baud D'16' +; 19200 Baud D'8' +; 38400 Baud and up - use 'NOP' delays +; VARIABLES USED: REG 'count' +; ROUTINES CALLED: NONE +; ******************************************************************** + +baud ; AT 2400 BAUD THE PERIOD IS 416.6 US + ; CLK = 4MHz + movlw D'68' ; 1 US (BAUD RATE CONSTANT) + movwf count ; 1 US +baud1 + decfsz count,F ; 1 US (+ 1 US MORE IF SKIP) + goto baud1 ; 2 US + ; FALL THRU...AFTER 1+1+3x68+1 = 207 US +half_baud + movlw D'68' ; 1 US + movwf count ; 1 US +hbaud1 + decfsz count,F ; 1 US (+ 1 US MORE IF SKIP) + goto hbaud1 ; 2 US + retlw 0 ; ...AFTER 1+1+3x68+1 = 207 US (X2=414 US) + +; http://www.piclist.com/techref/piclist/codegen/delay.htm +; Delay = 1 seconds +; Clock frequency = 8 MHz + +; Actual delay = 1 seconds = 2000000 cycles +; Error = 0 % + +delay + ;1999996 cycles + bsf FSR,5 + movlw 0x11 + movwf d1 + movlw 0x5D + movwf d2 + movlw 0x05 + movwf d3 +Delay_0 + decfsz d1, f + goto $+2 + decfsz d2, f + goto $+2 + decfsz d3, f + goto Delay_0 + + ;4 cycles + goto $+1 + goto $+1 + + bcf FSR,5 + retlw 0 + +; sleep input state machine +; +; we expect the chars s-l-e-e-p-x-y-z where xyz are digits +; if wrong char received reset +; if 5 sec timout between chars reset +; if xyz are not digits reset + +sleep_input + + ; big case statement to work out what state we are in + + movlw 0 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 's' + goto sleep_state_s + movlw 1 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 'l' + goto sleep_state_l + movlw 2 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 'e1' + goto sleep_state_e1 + movlw 3 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 'e2' + goto sleep_state_e2 + movlw 4 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 'p' + goto sleep_state_p + movlw 5 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 'x' + goto sleep_state_x + movlw 6 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 'y' + goto sleep_state_y + movlw 7 + subwf sleep_state,0 + btfsc STATUS,Z ; Z set if in state 'z' + goto sleep_state_z + + ; should never get here but just in case + + goto sleep_reset + + ; if we have rx-ed a 's' continue to next state +sleep_state_s + movlw 's' + subwf SERBUFI,0 + btfss STATUS,Z ; Z set if we received a 's' + goto sleep_reset + goto sleep_cont + + ; if we have rx-ed a 'l' continue to next state +sleep_state_l + movlw 'l' + subwf SERBUFI,0 + btfss STATUS,Z ; Z set if we received a 'l' + goto sleep_reset + goto sleep_cont + + ; if we have rx-ed a 'e' continue to next state +sleep_state_e1 + movlw 'e' + subwf SERBUFI,0 + btfss STATUS,Z ; Z set if we received a 'e' + goto sleep_reset + goto sleep_cont + + ; if we have rx-ed a 'e' continue to next state +sleep_state_e2 + movlw 'e' + subwf SERBUFI,0 + btfss STATUS,Z ; Z set if we received a 'e' + goto sleep_reset + goto sleep_cont + + ; if we have rx-ed a 'p' continue to next state +sleep_state_p + movlw 'p' + subwf SERBUFI,0 + btfss STATUS,Z ; Z set if we received a 'p' + goto sleep_reset + goto sleep_cont + + ; if we have rx-ed a digit 0-9 continue to next state +sleep_state_x + + ; check if >= '0' + movlw '0' + subwf SERBUFI,0 + btfss STATUS,C ; C set if valid + goto sleep_reset + + ; check if x <= 9 + bsf FSR,5 ; x is in bank 1 + movwf x + movlw d'10' + subwf x,0 + bcf FSR,5 + btfsc STATUS,C ; C reset if valid + goto sleep_reset + goto sleep_cont + + ; if we have rx-ed a digit 0-9 continue to next state +sleep_state_y + + ; check if >= '0' + movlw '0' + subwf SERBUFI,0 + btfss STATUS,C ; C set if valid + goto sleep_reset + + ; check if y <= 9 + bsf FSR,5 ; y is in bank 1 + movwf y + movlw d'10' + subwf y,0 + bcf FSR,5 + btfsc STATUS,C ; C reset if valid + goto sleep_reset + goto sleep_cont + + ; if we have rx-ed a digit 0-9 continue to next state +sleep_state_z + + ; check if >= '0' + movlw '0' + subwf SERBUFI,0 + btfss STATUS,C ; C set if valid + goto sleep_reset + + ; check if z <= 9 + bsf FSR,5 ; z is in bank 1 + movwf z + movlw d'10' + subwf z,0 + bcf FSR,5 + btfsc STATUS,C ; C reset if valid + goto sleep_reset + + ; OK we made it! Lets go to SLEEP, ZZZZZzzzzzzzzzz + + clrf sleep_state + clrf sleep_timeout + movlw 1 + movwf sleeping + bcf GPIO,1 ; power switch off + + retlw 0 + + ; we bombed out in rx-ing sleep string +sleep_reset + clrf sleep_state + clrf sleep_timeout + retlw 0 + + ; increment to next state, and reset sleep timeout +sleep_cont + incf sleep_state,1 + movlw SLEEP_TIMEOUT + movwf sleep_timeout + retlw 0 + +; START MAIN LOOP ----------------------------------------------- + +main + call inch_n_delay ; RS232 RX and 1 second delay + + ; sample V, I, and print if we received a 'w' or a ' ' + + movlw 'w' + subwf SERBUFI,0 + btfsc STATUS,Z ; skip if SERBUFI != 'w' + goto sample + + movlw '.' + subwf SERBUFI,0 + btfss STATUS,Z ; skip if SERBUFI == ' ' + goto no_print + + ; sample AN[0] (voltage) +sample + movlw b'10110001' + movwf ADCON0 + bsf ADCON0,1 ; start A/D conversion +wait_adc_v + btfsc ADCON0,1 ; skip if A/D conversion finished + goto wait_adc_v + + ; print 'wispcar' to get host to call script called wispcar. + ; This script can then parse wispcar output + + movlw 'w' + call outch_n + movlw 'i' + call outch_n + movlw 's' + call outch_n + movlw 'p' + call outch_n + movlw 'c' + call outch_n + movlw 'a' + call outch_n + movlw 'r' + call outch_n + movlw ' ' + call outch_n + + ; print voltage to RS232 + + movf ADRES, 0 + movwf BIN + call BIN2BCD ; convert voltage to decimal ASCII + + movf huns, 0 + call outch_n + movf tens, 0 + call outch_n + movf ones, 0 + call outch_n + + ; print space + + movlw ' ' + call outch_n + + ; sample AN[1] (current) + + movlw b'10111001' + movwf ADCON0 + bsf ADCON0,1 ; start A/D conversion +wait_adc_i + btfsc ADCON0,1 ; skip if A/D conversion finished + goto wait_adc_i + + ; print current to RS232 + + movf ADRES, 0 + movwf BIN + call BIN2BCD ; convert current to decimal & ASCII + + movf huns, 0 + call outch_n + movf tens, 0 + call outch_n + movf ones, 0 + call outch_n + + ; print rx char + + movlw ' ' + call outch_n + movf SERBUFI, 0 + call outch_n + + ; print rx char in dec + + movlw ' ' + call outch_n + movf SERBUFI, 0 + movwf BIN + call BIN2BCD ; convert rx char to decimal & ASCII + + movf huns, 0 + call outch_n + movf tens, 0 + call outch_n + movf ones, 0 + call outch_n + + ; print wd_timeout in dec + + movlw ' ' + call outch_n + movf wd_timeout, 0 + movwf BIN + call BIN2BCD + + movf huns, 0 + call outch_n + movf tens, 0 + call outch_n + movf ones, 0 + call outch_n + + ; print wd_fire in dec + + movlw ' ' + call outch_n + movf wd_fire, 0 + movwf BIN + call BIN2BCD + + movf huns, 0 + call outch_n + movf tens, 0 + call outch_n + movf ones, 0 + call outch_n + + ; print sleep_state + + movlw ' ' + call outch_n + movlw '0' + addwf sleep_state,0 + call outch_n + + ; print sleep timer in dec + + movlw ' ' + call outch_n + movlw '0' ; print x + bsf FSR,5 + addwf x,0 + bcf FSR,5 + call outch_n + movlw '0' ; print y + bsf FSR,5 + addwf y,0 + bcf FSR,5 + call outch_n + movlw '0' ; print z + bsf FSR,5 + addwf z,0 + bcf FSR,5 + call outch_n + + ; print restart_flag + + movlw ' ' + call outch_n + movf restart_flag, 0 + call outch_n + + ; print CR-LF + + movlw '\r' + call outch_n + movlw '\n' + call outch_n + +no_print + ; has watchdog fired (wd_timeout == 0) ? + + movf wd_timeout,1 + btfsc STATUS,Z ; skip if not fired + goto watchdog_firing ; Yes? Then goto watchdog firing code + + ; are we sleeping (sleeping == 1)? + + movf sleeping,1 + btfss STATUS,Z ; skip if not sleeping + goto snooze ; Yes? Then goto sleeping code + + ; No? Then count down watchdog + + movlw 1 + subwf wd_timeout,1 + + ; Has watchdog just fired (wd_timeout == 0)? + + btfss STATUS,Z ; skip if wd_countdown is zero + goto dec_sleeptimeout ; No - continue + + ; Yes - start watchdog firing code + + bcf GPIO,1 ; PowerSwitch Off + movlw WD_FIRE + movwf wd_fire + goto main + +dec_sleeptimeout + ; has sleep state machine accepted a rx char? + + movf sleep_state,1 + btfsc STATUS,Z + goto main ; No? Then continue processing + + decfsz sleep_timeout,1 + goto main + + ; sleep state machine timeout, reset state machine + clrf sleep_state + goto main + + ; watchdog firing code + +watchdog_firing + + movlw 1 + + ; DR June 2009 - make watchdog fire forerver, cutting power + ; from battery indefinately until host returns + subwf wd_fire,0 + + ; watchdog firing complete? (wd_fire == 0)? + + btfss STATUS,Z ; skip if wd_fire is zero + goto main ; No - continue + + ; Yes - reset watchdog + + bsf GPIO,1 ; PowerSwitch On + movlw WD_TIMEOUT + movwf wd_timeout + + ; Indicate WD has fired since last 'w' sent by host. A rx of + ; 'w' resets this flag. + + movlw WD_FLAG + movwf restart_flag + + goto main + + ; sleeping code + ; sleep for xyz seconds, need to count down in decimal +snooze + ; 3 digit decimal count down timer xyz, e.g. 999, 998,...001,000 + ; it's time's like these I wonder why I volunteered for this project!! :-) + ; see countdown.c for C version of this algorithm + + bsf FSR,5 + movf z,1 + btfss STATUS,Z + goto z_not_zero + movf y,1 + btfss STATUS,Z + goto y_not_zero + movf x,1 + btfss STATUS,Z + goto x_not_zero + + ; x=y=z=0 so we are finished + + bcf FSR,5 + goto sleep_finished + +z_not_zero + decf z,1 + goto continue_sleep + +y_not_zero + decf y,1 + movlw 9 + movwf z + goto continue_sleep + +x_not_zero + decf x,1 + movlw 9 + movwf y + movwf z + goto continue_sleep + + ; sleep finished + +sleep_finished + bsf GPIO,1 ; PowerSwitch On + movlw WD_TIMEOUT ; reset watchdog for good measure + movwf wd_timeout + clrf wd_fire + clrf sleep_timeout ; clear sleep timeout counter + clrf sleeping ; clear sleep flag + + ; Indicate we have just woken up from a sleep. A rx of 'w' + ; resets this. + + movlw SLEEP_FLAG + movwf restart_flag + goto main + +continue_sleep + bcf FSR,5 + goto main + +; END MAIN LOOP ----------------------------------------------- + + end + + -- 2.25.1