📄 avrsms.asm
字号:
;===========================================================
;
; Eversmith - AVRSMS Version 0.56
; Coypright (c) 2003
; Martin Thomas - eversmith@heizung-thomas.de
;
;===========================================================
; Sends GSM Short Messages (SMS) if a Push-
; Button connected to PORTA was closed (grounded)
; Message is the Message given thru the Menu
; followed by the Number of the Input-Port-Pin
; Destination Number is editable thru the Menu
; Receives GSM Short Messages (SMS) and takes actions
; like switching output pins or sending status SMS
; See manual.pdf for more information.
;===========================================================
; For ATMEL AVR controllers connected to
; a AT-command compatible GSM-Modem/Mobile Phone.
; Tested with Siemens S35 GSM-Phone, Siemens
; TC35 Terminal GSM-"Modem" and ATmega16.
;===========================================================
;
; Copyright (2003) Martin Thomas, Kaiserslautern, Germany
; This Software is distributed under the Aladdin Free Public
; License (AFPL) Read the file license.txt included in the
; distibution-package.
;
; - No commercial use of this software, modifications of this
; software or parts (subroutines) of this software.
; You cannot therefore modify the software and then sell it.
; - Free to use and redistribute as long as you include
; all source-code from the software you derived
; from this package and the package itself (code, documents
; and license) in your distribution.
; - You have to keep all copyright notices in the code.
;
; Send an e-mail to eversmith@heizung-thomas.de if you
; need a commercial license.
;
;===========================================================
;
; credits to:
; for Tools:
; - T. Kloppenburg (Delay-Loop-Generator)
; - Br@y (Br@y Terminal)
; - Claudio Lanconelli (PonyProg2000 Programmer)
; - Stefan Frings (smstools, used for debugging)
; - ATMEL (for the free AVR Studio)
; for Code-Snippets:
; - Jack Tidwell (UART FIFO-Code is based on his code)
; for Documents:
; - SIEMENS ("SMS with the SMS PDU-mode" document)
;
;===========================================================
; TODOs in no particular order:
; - SIM-Card PIN handling (at+cpin)
; - UART Flushing at "needed" places
; - Modem "alive" check - not that important
; because of the timeouts
; - Modem and AVR sleep modes, power-saving (DTE pin)
; (check how incoming SMS can wake up to avoid
; wakeing up the ME every xx seconds for polling)
; - More messages and numbers
; - EEPROM high endurace (AVR app-note)
; - AVRProg bootloader (check code agains Butterfly code)
; - ATmega162 with 2 UARTS or additional Software-Uart
; for debug-output and user interaction
; - Software handshaking at UART (Xon/Xoff)
; - Code cleanup
; - TAP Mode (maybe in a different application)
;===========================================================
; A Warning: This issue took about half a day: before you
; test extended versions let the ATMEL Compiler run without
; the option "Wrap relative jumps" an inspect the output.
; Replace rcalls causing errors or warnings by calls (rjmp/jmp)
;===========================================================
; best viewed with Tabwidth 4 in AVRStuido 4
; ATMEL-Design-Notes Definitions
.nolist
.include "m16def.inc"
.list
.include "globals.inc"
;=========================================
; Constants/Limits
.equ MAXMSGSIZE = 150 ; max size for SMS is 160, limited here
.equ MAXNUMSIZE = 20
.equ MAXWORKBYTES = MAXMSGSIZE+10 ; add 10 chars (paranoia)
;=========================================
; SRAM Labels
; Universal Work-Area - see also PDU.asm for "aliased"
; use of this area
.dseg
Work1: .byte MAXWORKBYTES
;=========================================
; EEPROM Labels
; EEprom-Size=512 Bytes on ATMega16
.eseg
; Init EEprom Storage
.eseg
Dummy: .db $00,$00 ; EEPROM corruption protection
; "do not use Byte $00 of the EEPROM"
; keeps message 1
EEMessage: .byte MAXMSGSIZE+1
Dummy2: .byte 2
; keeps the destination umber 1
EENumber: .byte MAXNUMSIZE+1
Dummy3: .byte 2
; ME device type (accessed in PDU.asm too)
EEMEType: .byte 1
Dummy4: .byte 2
;===========================================================
; Code/Program Segment
.CSEG
.org 0x0000 ; Places the following code from address 0x0000
jmp RESET ; to Reset Handler
.org OVF0addr
jmp TIM0OVF ; to Timer0 Overflow Interrupt-Handler
.org URXCaddr
jmp UART1RXISR ; to USART RX Complete Handler - UART.asm
.org $02A ; for ATMega16
RESET:
; Init Stack
ldi r16, LOW(RAMEND) ; LOW-Byte of upper RAM-Adress
out SPL, r16
ldi r16, HIGH(RAMEND) ; HIGH-Byte of upper RAM-Adress
out SPH, r16
; Init the Ports - see keys.asm and switches.asm
; for details of the port handling.
; This is only to get a "clean" start
; Init Port A all Inputs - active LOW
clr r16
out DDRA,r16 ; all inputs
ser r16
out PORTA,r16 ; enable all pullups
; Init Port C as Output - active LOW
; remember to disable JTAG via fuse-settings to
; use all pins of PortC of an ATmega16
ser r16
out DDRC,r16 ; all outputs
out PORTC,r16 ; all high (=inactive)
nop ; sync
; Init Outputs (Relais/LEDS)
call SwitchInit ; in switches.asm
; init Keys and debouncing
call KeysInit ; in keys.asm
; Check for valid Passcode in EEPROM or set default
; as given in .db SMSDEFAULTCODE in PDU.asm
call SMSCheckCodeInEEprom ; in PDU.asm
; Init SMS-Polling
call SMSPollInit ; in PDU.asm
call SMSReqInit ; in PDU.asm
;;;rcall GetPasscode ;;;;dbg
;;;call SMSDebugProcessMsg ;;;;dbg
;;;rjmp MDD ;;;;dbg
; Init Timer0
cli ; disable all Interrupts
ldi r16,(1<<CS02)|(0<<CS01)|(1<<CS00) ; Timer0 Prescaler = 1024
;;;ldi r16,(0<<CS02)|(1<<CS01)|(0<<CS00) ; Timer0 Prescaler = 8 dbg
;;;ldi r16,(0<<CS02)|(0<<CS01)|(1<<CS00) ; Timer0 Prescaler = 1 dbg
out TCCR0,r16 ; set Timer0 Prescaler
ldi r16,(1<<TOV0)
out TIMSK,r16 ; enable overflow interrupt
ldi r16,T0PRESET
out TCNT0,r16 ; preset timer
sei ; enable all Interrupts
; Init U(S)ART
call UARTInit ; in UART.asm
jmp MAIN
;===========================================================
; INCLUDES
; EEProm access:
.include "eeprom.asm"
; UART handling
.include "UART.asm"
; User-Interface via UART
.include "MenuUart.asm"
; PDU handling
.include "PDU.asm"
; (GSM-)Modem handling
.include "modem.asm"
; Input-Keys (debouncing)
.include "keys.asm"
; Switches (Output-Pin)-Control
.include "switches.asm"
; all calls to subroutines located in the include
; files should be done via calls not rcalls to
; avoid problems, since the number of words in all
; includes is above the limit of a relative call
; or relative jmp.
;===========================================================
;===========================================================
; Main Loop - handles the "state machine" or "message loop"
MAIN:
MAINLOOP:
; Debugging:
; call MenuUartGetByte
; cpi r17,27 ; Menu appers on Escape-Key
; brne MAINLOOP
; rcall MAINMENU
; rjmp MAIN_CONT
; Dbg-End
; for incoming messages
lds r17,SMSPollFlag
tst r17
breq MAIN_NOPOLL
call SMSProcessUnread
call SMSPollInit ; reset counter and flag
MAIN_NOPOLL:
MDD: ; debug label
lds r17,SMSReq
tst r17
breq MAIN_NOSMSRequest
rcall MAINProcRequests
MAIN_NOSMSRequest:
; for inputs/keys (outgoing messages)
lds r17,KeyOnMsg ; load Key-"on"-Messages
andi r17,0b01111111 ; mask Pin7 (menu-button)
cpi r17,$00 ; got an "on" messages ?
breq MAIN_NOSEND ; no - skip sending
rcall MAINSENDKEYMSG ; send SMS messages
MAIN_NOSEND:
; Menu request
lds r17,KeyOnMsg ; load Key-"on"-Messages
sbrs r17,7 ; ground PA7 to enter menu
rjmp MAIN_CONT ; menu not requestet
rcall MAINMENU ; show menu
MAIN_CONT:
rjmp MAINLOOP
;=========================================
; Set LEDs connected to PORTC to value
; given in r21 - Debugging
DebugLEDS:
push r21
com r21
out PORTC,r21
pop r21
ret
;=========================================
; Process the Requests from SMS-deliver
;=========================================
MAINProcRequests:
push r16
push r17
push r18
push r19
push YL
push YH
push ZL
push ZH
lds r17,SMSReq ; load request, case (r17)
; send Status
cpi r17,'S'
brne MPR_N1
rcall MainSendStatus ; see below
rjmp MPR_end
MPR_N1: ; Swich Port
; "normal people" start counting from 1
; so the AVR PIN(parameter-1) is switched
cpi r17,'P'
brne MRP_N2
lds r18,SMSRp1
swap r18
andi r18,0b00001111 ; extract Pin-Number
ldi r16,0b00000001
; check Number
cpi r16,$09
brge MPR_end
cpi r16,$01
brlo MPR_end
MPR_N1_ROL:
tst r18
breq MPR_N1_BREAK
lsl r16
dec r18
rjmp MPR_N1_ROL
;lsr r16 ; an one already at input
MPR_N1_BREAK:
lsr r16 ; it has been one so far
lds r18,SMSRp1 ; load parameter again
sbrc r18,0 ; skip if bit0 is cleared (=off)
call SwitchOn ; Toogle Switches
sbrs r18,0 ; skip if bit0 is set (=on)
call SwitchOff
rjmp MPR_end
MRP_N2: ; all on
cpi r17,'A'
brne MPR_N3
com r16
call SwitchOn
rjmp MPR_end
MPR_N3: ; all off
cpi r17,'Z'
brne MPR_N4
com r16
call SwitchOff
rjmp MPR_end
MPR_N4:
MPR_end:
call SMSReqInit ; clear request poll timer to give
; user time to unplug terminal and
; plug modem
pop ZH
pop ZL
pop YH
pop YL
pop r19
pop r18
pop r17
pop r16
ret
;=========================================
; MainSendStatus
; sends a status SMS to destination
; number stored in EEprom at EENUMBER
MainSendStatus:
push r17
push r18
push r19
push YL
push YH
push ZL
push ZH
; copy start of message from flash to ram
ldi ZL,LOW(2*STATUSALIVE); Pointer Z to Message in Flash
ldi ZH,HIGH(2*STATUSALIVE)
ldi YL,LOW(Work1)
ldi YH,HIGH(Work1)
call EEFlashSeqToRam
ldi YL,LOW(Work1)
ldi YH,HIGH(Work1)
;;;call MenuUartSendRamSeq
; Status of outputs as Bit-Field
ldi r18,0b00000001
MPR_SO_L1:
in r19,SWPORT ; load state of output-port (PORTC)
and r19,r18
tst r19 ; if bit is 0 then ON (inv. logic)
breq MPR_SO_ON
ldi r17,'0'
rjmp MPR_SO_L1b
MPR_SO_ON:
ldi r17,'1'
MPR_SO_L1b:
call PDUAddCharRam
clc
rol r18
brcc MPR_SO_L1
; add string " Inp.: " to Message
ldi r17,' '
call PDUAddCharRam
ldi r17,'I'
call PDUAddCharRam
ldi r17,'n'
call PDUAddCharRam
ldi r17,'p'
call PDUAddCharRam
ldi r17,'.'
call PDUAddCharRam
ldi r17,':'
call PDUAddCharRam
ldi r17,' '
call PDUAddCharRam
; Status of outputs as Bit-Field
ldi r18,0b00000001
MPR_SI_L1:
in r19,KEYPIN ; load state of key-port (PINA)
and r19,r18
tst r19 ; if bit is 0 then ON (inv. logic)
breq MPR_SI_ON ; Pull-Ups on by default
ldi r17,'0'
rjmp MPR_SI_L1b
MPR_SI_ON:
ldi r17,'1'
MPR_SI_L1b:
call PDUAddCharRam
clc
rol r18
brcc MPR_SI_L1
ldi YL,LOW(Work1)
ldi YH,HIGH(Work1)
; Input to SMSSendRAM:
ldi XL,LOW(Work1)
ldi XH,HIGH(Work1) ; X points on RAM-String to send
ldi YL,LOW(EENUMBER) ; Pointer Y to Number in EEprom
ldi YH,HIGH(EENUMBER)
call SMSSendRam
pop ZH
pop ZL
pop YH
pop YL
pop r19
pop r18
pop r17
ret
STATUSALIVE:
.db "Eversmith Status Outp.: ",$00,$00
;=========================================
; Send SMSes for changed Input-Pin-States
;=========================================
; Grounding pins PA0-PA3 will send the text stored
; in EEprom at location EEMESSAGE followed by the
; Pin-Number+1. I.e. EEMESSAGE="ABC switched : "
; and grounding PA1 results in message
; "ABC switched : 2", message is sent to number
; stored in EEprom at location EENUMBER
;
; Grounding pin PA4 will send the text stored at
; location WORK1 in RAM/dseg to number stored in
; EEprom at location EENUMBER (Default Text copied
; from FLASH/cseg at location MAINDEFAULTSEND
;
; No messages will be sent when grounding PA5-PA7
; only "On" messages will be send (=grounding)
MAINSENDKEYMSG:
push r16
push r17
push r20
push r21
push XL
push XH
push YL
push YH
push ZL
push ZH
lds r20,KeyOnMsg
sbrc r20,0
rjmp SEND1 ; Pin number 0 of input port
sbrc r20,1
rjmp SEND2 ; Pin number 1 of input port
sbrc r20,2
rjmp SEND3 ; Pin number 2 of input port
sbrc r20,3
rjmp SEND4 ; Pin number 3 of input port
sbrc r20,4
rjmp SEND5 ; Pin number 4 of input port
; only bit done here are 0-4 so mark all other
; key-messages as done and return
ldi r16,0b11000000
call KeysClearOnMsg
rjmp SKM_End
SEND1:
ldi r17,'1' ; add '1' to Message
ldi r16,0b00000001 ; clear Message
call KeysClearOnMsg ; (TODO: better on send succes only)
rjmp SKM_ALL
SEND2:
ldi r17,'2' ; add '2' to Message
ldi r16,0b00000010 ; clear Message
call KeysClearOnMsg ; (TODO: better on send succes only)
rjmp SKM_ALL
SEND3:
ldi r17,'3' ; add '2' to Message
ldi r16,0b00000100 ; clear Message
call KeysClearOnMsg ; (TODO: better on send succes only)
rjmp SKM_ALL
SEND4:
ldi r17,'4' ; add '3' to Message
ldi r16,0b00001000 ; clear Message
call KeysClearOnMsg ; (TODO: better on send succes only)
SKM_ALL:
; Input to SMSSendEEprom:
; Pointer X to Message in EEprom
ldi XL,LOW(EEMESSAGE)
ldi XH,HIGH(EEMESSAGE)
; Pointer Y to Number in EEprom
ldi YL,LOW(EENUMBER)
ldi YH,HIGH(EENUMBER)
call SMSSendEeprom ; charcter in r17 is added to message
; error indication with leds via switches.asm
rjmp SKM_CheckResult
SEND5:
; send a message from dseg default copied from cseg
; copy default from flash to ram, all strings must be
; $00 terminated
ldi ZL,LOW(2*MAINDEFAULTSEND); Pointer Z to Message in Flash
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -