;; ;; mur.sat ;; ;; Somewhen in the year 2011, mur.at will have a nano satellite launched ;; into a low earth orbit (310 km above the surface of our planet). The ;; satellite itself is a TubeSat personal satellite kit, developed and ;; launched by interorbital systems. mur.sat is a joint venture of mur.at, ;; ESC im Labor and realraum. ;; ;; Please visit the project hompage at sat.mur.at for further information. ;; ;; ;; Copyright (C) 2011 Christian Pointner ;; ;; This file is part of mur.sat. ;; ;; mur.sat 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 3 of the License, or ;; any later version. ;; ;; mur.sat 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 mur.sat. If not, see . ;; ;; ------------------------------------- ;; PREAMBLE LIST p=12F635 include "p12f635.inc" __config _WUREN_OFF & _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT ;; ------------------------------------- ;; DEFINES ;; constants DOT EQU .256 - .29 DASH EQU .256 - .87 ESPACE EQU .256 - .29 CSPACE EQU .256 - .87 WSPACE EQU .256 - .203 ENABLE_TIME EQU .256 - .10 BCONINT_DEF EQU .10 ; *2 = Beacon Interval in seconds ;; I/O Pins CWENABLE EQU GP0 CWOUT EQU GP1 SCLK EQU GP2 SDAT EQU GP4 ;; variables ;; page 0 only ELEMENT EQU H'0040' ELECNT EQU H'0041' CHAR EQU H'0042' PARITY EQU H'0043' CHARCNT EQU H'0044' PENTLE0 EQU H'0045' PENTLE1 EQU H'0046' PENTLECNT EQU H'0047' BUF EQU H'0050' ;; all pages BEACON_INT EQU H'0079' STATE EQU H'007A' BEACONCNTH EQU H'007B' BEACONCNTL EQU H'007C' SECCNT EQU H'007D' W_TEMP EQU H'007E' STATUS_TEMP EQU H'007F' ;; bits STATE safe EQU .0 ;; ------------------------------------- ;; Reset Vector org .0 goto init ;; ------------------------------------- ;; Interrupt Vector org .4 ;; save context movwf W_TEMP swapf STATUS,W movwf STATUS_TEMP bcf STATUS,RP0 bcf STATUS,RP1 btfsc PIR1,TMR1IF goto tmr1_int ext_int ;; TODO: read bit from GPIO,SDAT and add to received string goto interrupt_end tmr1_int bcf PIR1,TMR1IF btfsc STATE,safe ; safe mode -> disable scheduler goto disable_tmr1 movf SECCNT,w btfss STATUS,Z decf SECCNT,f goto interrupt_end disable_tmr1 bcf T1CON,TMR1ON movf BEACON_INT,w movwf SECCNT interrupt_end ;; restore context swapf STATUS_TEMP,W movwf STATUS swapf W_TEMP,F swapf W_TEMP,W retfie ;; ------------------------------------- ;; INIT init ;; bank 1 bsf STATUS,RP0 bcf STATUS,RP1 movlw b'10000011' movwf OPTION_REG movlw b'11111100' movwf TRISIO movlw b'00000001' movwf PIE1 movlw b'00000000' movwf OSCCON bcf STATUS,RP0 ;; bank 0 clrf TMR1L clrf TMR1H movlw b'00000110' movwf T1CON movlw b'01000000' ; enable external interrupt bit4 movwf INTCON movlw b'00000111' movwf CMCON0 bcf GPIO,CWOUT bcf GPIO,CWENABLE movf BEACON_INT,w movwf SECCNT clrf STATE ; TODO: read State from EEPROM clrf BEACONCNTL ; TODO: read Beaconcnt from EEPROM clrf BEACONCNTH movlw BCONINT_DEF ; TODO: read Beacon Interval from EEPROM movwf BEACON_INT btfss STATE,safe ; safe mode -> disable scheduler bsf T1CON,TMR1ON bsf INTCON,GIE goto main ;; ------------------------------------- ;; TABLES ;; Morse Codes: 0=dot, 1=dash getcw addwf PCL,f nop retlw b'00010000' ; ! retlw b'01001000' ; " retlw b'00000000' ; # retlw b'00010010' ; $ retlw b'00000000' ; % retlw b'01000000' ; & retlw b'01111000' ; ' retlw b'10110000' ; ( retlw b'10110100' ; ) retlw b'00000000' ; * retlw b'01010000' ; + retlw b'11001100' ; , retlw b'10000100' ; - retlw b'01010100' ; . retlw b'10010000' ; / retlw b'11111000' ; 0 retlw b'01111000' ; 1 retlw b'00111000' ; 2 retlw b'00011000' ; 3 retlw b'00001000' ; 4 retlw b'00000000' ; 5 retlw b'10000000' ; 6 retlw b'11000000' ; 7 retlw b'11100000' ; 8 retlw b'11110000' ; 9 retlw b'11100000' ; : retlw b'10101000' ; ; retlw b'00010100' ; < retlw b'10001000' ; = retlw b'10001010' ; > retlw b'00110000' ; ? retlw b'01000000' ; @ retlw b'01000000' ; A retlw b'10000000' ; B retlw b'10100000' ; C retlw b'10000000' ; D retlw b'00000000' ; E retlw b'00100000' ; F retlw b'11000000' ; G retlw b'00000000' ; H retlw b'00000000' ; I retlw b'01110000' ; J retlw b'10100000' ; K retlw b'01000000' ; L retlw b'11000000' ; M retlw b'10000000' ; N retlw b'11100000' ; O retlw b'01100000' ; P retlw b'11010000' ; Q retlw b'01000000' ; R retlw b'00000000' ; S retlw b'10000000' ; T retlw b'00100000' ; U retlw b'00010000' ; V retlw b'01100000' ; W retlw b'10010000' ; X retlw b'10110000' ; Y retlw b'11000000' ; Z ;; Morse Code Length getcwlen addwf PCL,f nop retlw .5 ; ! retlw .6 ; " retlw .0 ; # retlw .7 ; $ retlw .0 ; % retlw .5 ; & retlw .6 ; ' retlw .5 ; ( retlw .6 ; ) retlw .0 ; * retlw .5 ; + retlw .6 ; , retlw .6 ; - retlw .6 ; . retlw .5 ; / retlw .5 ; 0 retlw .5 ; 1 retlw .5 ; 2 retlw .5 ; 3 retlw .5 ; 4 retlw .5 ; 5 retlw .5 ; 6 retlw .5 ; 7 retlw .5 ; 8 retlw .5 ; 9 retlw .6 ; : retlw .6 ; ; retlw .6 ; < retlw .5 ; = retlw .7 ; > retlw .6 ; ? retlw .6 ; @ retlw .2 ; A retlw .4 ; B retlw .4 ; C retlw .3 ; D retlw .1 ; E retlw .4 ; F retlw .3 ; G retlw .4 ; H retlw .2 ; I retlw .4 ; J retlw .3 ; K retlw .4 ; L retlw .2 ; M retlw .2 ; N retlw .3 ; O retlw .4 ; P retlw .4 ; Q retlw .3 ; R retlw .3 ; S retlw .1 ; T retlw .3 ; U retlw .4 ; V retlw .3 ; W retlw .4 ; X retlw .4 ; Y retlw .4 ; Z ;; Base32 Code base32 addwf PCL,f retlw 'A' - ' ' retlw 'B' - ' ' retlw 'C' - ' ' retlw 'D' - ' ' retlw 'E' - ' ' retlw 'F' - ' ' retlw 'G' - ' ' retlw 'H' - ' ' retlw 'I' - ' ' retlw 'J' - ' ' retlw 'K' - ' ' retlw 'L' - ' ' retlw 'M' - ' ' retlw 'N' - ' ' retlw 'O' - ' ' retlw 'P' - ' ' retlw 'Q' - ' ' retlw 'R' - ' ' retlw 'S' - ' ' retlw 'T' - ' ' retlw 'U' - ' ' retlw 'V' - ' ' retlw 'W' - ' ' retlw 'X' - ' ' retlw 'Y' - ' ' retlw 'Z' - ' ' retlw '2' - ' ' retlw '3' - ' ' retlw '4' - ' ' retlw '5' - ' ' retlw '6' - ' ' retlw '7' - ' ' ;; fixed strings callsign addwf PCL,f nop retlw 'R' - ' ' retlw 'U' - ' ' retlw 'M' - ' ' retlw '6' - ' ' retlw 'E' - ' ' retlw 'O' - ' ' ;; ------------------------------------- ;; SUBROUTINES dottime movwf TMR0 bcf INTCON,T0IF dot_inner btfss INTCON,T0IF goto dot_inner return ;; ------------------------------------- send_char movwf CHAR call getcw movwf ELEMENT movf CHAR,w call getcwlen movwf ELECNT movf ELECNT,f btfsc STATUS,Z return movf CHAR,w xorwf PARITY,f char_next_element bsf GPIO,CWOUT btfss ELEMENT,7 movlw DOT btfsc ELEMENT,7 movlw DASH call dottime bcf GPIO,CWOUT rlf ELEMENT,f decfsz ELECNT,f goto char_espace return char_espace movlw ESPACE call dottime goto char_next_element ;; ------------------------------------- send_callsign movlw .6 movwf CHARCNT callsign_next_char call callsign call send_char decfsz CHARCNT,f goto callsign_cspace return callsign_cspace movlw CSPACE call dottime movf CHARCNT,w goto callsign_next_char ;; ------------------------------------- send_base32 movwf PENTLECNT case0 rrf INDF,w movwf PENTLE0 rrf PENTLE0,f rrf PENTLE0,w andlw b'00011111' call base32 call send_char decfsz PENTLECNT,f goto case1 return case1 movlw CSPACE call dottime rlf INDF,w movwf PENTLE0 rlf PENTLE0,w andlw b'00011100' movwf PENTLE0 incf FSR,f swapf INDF,w movwf PENTLE1 rrf PENTLE1,f rrf PENTLE1,w andlw b'00000011' iorwf PENTLE0,w call base32 call send_char decfsz PENTLECNT,f goto case2 return case2 movlw CSPACE call dottime rrf INDF,w andlw b'00011111' call base32 call send_char decfsz PENTLECNT,f goto case3 return case3 movlw CSPACE call dottime swapf INDF,w andlw b'00010000' movwf PENTLE0 incf FSR,f swapf INDF,w andlw b'00001111' iorwf PENTLE0,w call base32 call send_char decfsz PENTLECNT,f goto case4 return case4 movlw CSPACE call dottime rlf INDF,w andlw b'00011110' movwf PENTLE0 incf FSR,f btfsc INDF,7 bsf PENTLE0,0 movf PENTLE0,w call base32 call send_char decfsz PENTLECNT,f goto case5 return case5 movlw CSPACE call dottime rrf INDF,w movwf PENTLE0 rrf PENTLE0,w andlw b'00011111' call base32 call send_char decfsz PENTLECNT,f goto case6 return case6 movlw CSPACE call dottime swapf INDF,w movwf PENTLE0 rrf PENTLE0,w andlw b'00011000' movwf PENTLE0 incf FSR,f swapf INDF,w movwf PENTLE1 rrf PENTLE1,w andlw b'00000111' iorwf PENTLE0,w call base32 call send_char decfsz PENTLECNT,f goto case7 return case7 movlw CSPACE call dottime movf INDF,w andlw b'00011111' call base32 call send_char decfsz PENTLECNT,f goto caseend return caseend movlw CSPACE call dottime incf FSR,f goto case0 ;; ------------------------------------- send_parity movf PARITY,w btfsc PARITY,5 xorlw b'00000001' andlw b'00011111' call base32 call send_char return ;; ------------------------------------- send_beacon bsf GPIO,CWENABLE movlw ENABLE_TIME call dottime clrf PARITY ;; CALLSIGN call send_callsign ;; ------- movlw WSPACE call dottime ;; BEACON CNT movlw BEACONCNTH movwf FSR movlw .3 call send_base32 ;; ------- movlw WSPACE call dottime ;; PARITY call send_parity incfsz BEACONCNTL,f goto beacon_end incf BEACONCNTH,f ;; TODO write new cnt value to EEPROM beacon_end bcf GPIO,CWENABLE return ;; ------------------------------------- ;; MAINLOOP main ;; this gets called after reset and whenever a wakeup occured ;; (after TMR1 overrun or interrupt on GP2) movf SECCNT,f btfss STATUS,Z goto powerdown ;; this gets called every 2*BEACON_INT seconds movf BEACON_INT,w movwf SECCNT call send_beacon powerdown sleep nop goto main ;; ------------------------------------- ;; END end