📄 pdu.asm
字号:
inc r16
PDL_DIVFIN:
inc r16 ; add one byte for the udl
mov r23,r16
pop ZH
pop ZL
pop r17
pop r16
ret
;----------------------------------------------------------
; SMSSetPDUMode
;----------------------------------------------------------
; sets ME to PDU Mode - this seems to be default on all
; devices
SMSSetPDUMode:
push ZL
push ZH
ldi ZL,LOW(2*GSM_CMGF)
ldi ZH,HIGH(2*GSM_CMGF)
call ModemSendCmdFlash
call ModemUartWaitOK ; result of wait ok goes to r20
pop ZH
pop ZL
ret
; GSM Select Message Format to PDU-Mode
GSM_CMGF:
.db "AT+CMGF=0",$0D,$00,$00
;----------------------------------------------------------
; SMSSendRam
;----------------------------------------------------------
; Sends an SMS, Text in RAM, Number in EEPROM-Memory
;
; Inputs:
; Y-Registers: Pointer to Destination Number in EEprom
; X-Registers: Pointer to Message in SRAM
;
; Output:
; goes to Modem-UART
; r20 = result from wait for "OK" ($01=got OK)
;
; Side-Effects:
; Workarea in SRAM (SMSWorkArea) will be overwritten with SMS-Text
SMSSendRam:
push r16 ; for ItoA
push r18 ; temp storage for YL
push r19 ; temp storage for YH
push r22 ; len result
push r23 ; len result
push r24 ; r25:r24 used as Pointer
push r25
push YL
push YH
push ZL
push ZH
ldi r21,$00 ; set error indicator -> cleared on success
; --- calculate total PDU length for Send Command ---
; calculate header length
mov r24,YL ; let r25:r24 point to dest.-number
mov r25,YH ; in eeprom
rcall PDUHeaderLen ; == Header-Len in r22
tst r22 ; if header-len=0 exit
breq SMSSendR_end
; calculate message length (including UDL octet)
mov r18,YL ; save YH:YL to r19:r18
mov r19,YH
mov YL,XL ; let Y-Registers point to
mov YH,XH ; message in RAM
rcall PDUDataLen ; == Message at Y -> Data-Len in r23
;;;mov r16,r23 ;;; debug: print UDL (including the UDL octet)
;;;rcall ModemSendItoA ;;; debug
tst r23
breq SMSSendR_end ; if data-len=0 exit
; total length
add r22,r23 ; total PDU-Length now in r22
rcall SMSSetPDUMode ; set to SMS Format to PDU Mode
; --- send "at+cgms=" ---
ldi ZL,LOW(2*GSM_CMGS)
ldi ZH,HIGH(2*GSM_CMGS)
call ModemSendCmdFlash
; send PDU-length as ASCII
mov r16,r22 ; copy total Len of PDU in r16
call ModemSendItoA ; send total Length from r16 as ASCII
; send <CR> 0x0d
ldi r16,$0D
rcall PDUUartSendByte
ldi r24,LOW(EEMEType)
ldi r25,HIGH(EEMEType)
call EEReadByte ; get ME Type from EEProm
cpi r16,MESiemensAT
brne SMSSR_noprompt ; skip wait from prompt if not SiemensAT
;*************************************
; --- wait for PDU prompt ---
; ('>' on Siemens S35 and TC35)
; the Siemens manual recommends waiting for the prompt - so it's
; implemented here. According to manuals for Erricson and Nokia
; those devices do not give a prompt
ldi r16,'>' ; *Siemens only
call ModemUartWaitChar ; *Siemens only -- same result code as ModemUartWaitOK
cpi r20,$01 ; *Siemens only
brne SMSsendR_end ; *Siemens only
;*************************************
SMSSR_noprompt:
; --- send PDU ---
; send header
mov r24,r18 ; r19:r18 is a copy of the input Y-Registers
mov r25,r19 ; (pointer to destination-number)
rcall PDUSendHeader
; send data
mov YL,XL ; copy X to Y
mov YH,XH
rcall PDUSendText ; Y points to message in SRAM
; send <CTRL-Z> $1A 0x1A
ldi r16,$1A
rcall PDUUartSendByte
call ModemUartWaitOK ; result of wait ok goes to r20
SMSSendR_end:
pop ZH
pop ZL
pop YH
pop YL
pop r25
pop r24
pop r23
pop r22
pop r19
pop r18
pop r16
ret
; GSM Send SMS AT-command:
GSM_CMGS:
.db "AT+CMGS=",$00,$00
;----------------------------------------------------------
; SMSSendEeprom
;----------------------------------------------------------
; Sends an SMS, Text and Number in EEPROM-Memory
;
; Inputs:
; Y-Registers: Pointer to Destination Number in EEprom
; X-Registers: Pointer to Message in EEprom
; r17 character that will by added to Message
; if r17=$00 no character will be added
;
; Output:
; goes to Modem-UART
; r20 = result from wait for "OK" ($01=got OK)
;
; Side-Effects:
; Workarea in SRAM (SMSWorkArea) will be overwritten with SMS-Text
SMSSendEeprom:
push r18
push r19
push r24
push r25
push XL
push XH
push YL
push YH
mov r18,YL ; backup Y
mov r19,YH
; Copy Message from EEprom to SRAM
mov r24,XL
mov r25,XH
ldi YL,LOW(SMSWorkArea)
ldi YH,HIGH(SMSWorkArea)
call EEReadSeqToRam ; Copy Message from EEprom r25:r24 to SRAM Y
; add character in r17 to Message if r17!=0
tst r17 ; test if character byte is $00
breq SMSSENDee_L1 ; yes -> jump, don't add
ldi YL,LOW(SMSWorkArea)
ldi YH,HIGH(SMSWorkArea)
rcall PDUAddCharRam ; add char in r17 to string in ram at Y
SMSSENDee_L1:
ldi XL,LOW(SMSWorkArea) ; SMS-Message in dseg at X
ldi XH,HIGH(SMSWorkArea)
mov YL,r18 ; SMS-Number in eseg at Y
mov YH,r19 ; restored from r19:r18
; SMSSendRam Inputs:
; Y-Registers: Pointer to Destination Number in EEprom
; X-Registers: Pointer to Message in SRAM
rcall SMSSendRam
pop YH
pop YL
pop XH
pop XL
pop r25
pop r24
pop r19
pop r18
ret
;----------------------------------------------------------
; SMSSendFlash
;----------------------------------------------------------
; Sends an SMS, Text in Flash and Number in EEPROM-Memory
;
; Inputs:
; Y-Registers: Pointer to Destination Number in EEprom
; Z-Registers: Pointer to Message in Flash
; all null-terminted
; r17 character that will by added to Message
; if r17=$00 no character will be added
;
; Output:
; goes to Modem-UART
; r20 = result from wait for "OK" ($01=got OK)
;
; Side-Effects:
; Workarea in SRAM (SMSWorkArea) will be overwritten with SMS-Text
SMSSendFlash:
push r18
push r19
push XL
push XH
push YL
push YH
push ZL
push ZH
mov r18,YL ; backup Y
mov r19,YH
; Copy Message from EEprom to SRAM
ldi YL,LOW(SMSWorkArea)
ldi YH,HIGH(SMSWorkArea)
call EEFlashSeqToRAM ; Copy Message from Flash Z to SRAM Y
; add character in r17 to Message if r17!=0
tst r17 ; test if character byte is $00
breq SMSSENDFl_L1 ; yes -> jump, don't add
ldi YL,LOW(SMSWorkArea)
ldi YH,HIGH(SMSWorkArea)
rcall PDUAddCharRam ; add char in r17 to string in ram at Y
SMSSENDFl_L1:
ldi XL,LOW(SMSWorkArea) ; SMS-Message in dseg at X
ldi XH,HIGH(SMSWorkArea)
mov YL,r18 ; SMS-Number in eseg at Y
mov YH,r19 ; restored from r19:r18
; SMSSendRam Inputs:
; Y-Registers: Pointer to Destination Number in EEprom
; X-Registers: Pointer to Message in SRAM
rcall SMSSendRam
pop ZH
pop ZL
pop YH
pop YL
pop XH
pop XL
pop r19
pop r18
ret
;-----------------------------------------------------------
; SMS Poll-Count
;-----------------------------------------------------------
; called by the timer0 overflow interrupt handler
; in avrsms.asm, so this is called every 10 ms
; (see globals.inc and avrsms.inc)
;
; Modem should be polled every SMSPOLLINT seconds
;
; Number of calls to this routine to flag a Poll:
; SMSPOLLINT[sec]/0,01[sec] = SMSPOLLINT*100
; with counters: SMSCnt0_max*SMSCnt1_max=SMSPOLLINT*100
; SMSCnt0_max is 255 ($FF) -> SMSCnt1_max=SMSPOLLINT*100/$ff
; sample for SMSPOLLINT=30sec: 255*Cnt1_max=30*100 => Cnt1_max=12
SMSPollCount:
push r16
push r17
push r18
lds r16,SMSCnt0
lds r17,SMSCnt1
inc r16 ; inc first counter
cpi r16,$FF ; SMSCnt0_max
brne SPC_Store ; branch of below
clr r16 ; clear counter
inc r17 ; inc second counter
cpi r17,SMSPOLLINT*100/$FF ; SMSCnt1_max, see comment
brne SPC_Store ; branch of below
ser r18
sts SMSPollFlag,r18 ; set poll-state-flag
clr r17 ; clear counter
SPC_Store:
sts SMSCnt0,r16
sts SMSCnt1,r17
pop r18
pop r17
pop r16
ret
; initialize poll-counting
SMSPollInit:
push r16
clr r16
cli
sts SMSCnt0,r16 ; Inits Poll-Counter
sts SMSCnt1,r16 ; Inits Poll-Counter
sts SMSPollFlag,r16 ; Inits Poll-Flag
sei
pop r16
ret
; initialize sms requesting (= clear message "queue")
SMSReqInit:
push r16
clr r16
cli
sts SMSReq,r16 ; Inits Req-Command
sts SMSRp1,r16 ; Inits Req-Parameter
sei
pop r16
ret
;--Polling and Request valiables in SRAM
.dseg
SMSPollFlag: .byte 1
SMSCnt0: .byte 1
SMSCnt1: .byte 1
.cseg
;-----------------------------------------------------------
; Octet2Byte
;-----------------------------------------------------------
; converts Hex-Octet to byte
;
; Input r18:r17 - Hex-Characters High-Nibble-Char:Low-N-C
;
; Output r17 - resulting byte
;
; int i=(int)h-'0'; if (i>9) i-=7; return i
Octet2Byte:
push r18
subi r18,'0' ; char to dez
cpi r18,10
brlo O2B_L1
subi r18,7
O2B_L1:
andi r18,$0F ; paranoia
swap r18 ; 4 * lsl r17
subi r17,'0'
cpi r17,10
brlo O2B_L2
subi r17,7
O2B_L2:
add r17,r18
pop r18
ret
;-----------------------------------------------------------
; PDUReadOctet
;-----------------------------------------------------------
; read Octet from UART and converts Hex-Octet to byte
;
; Input from Modem-Uart
;
; Output r17 - resulting byte
; r16 - $00 no problem, $01 some problem (timeout)
;
PDUReadOctet:
push r18
call ModemUartReadByteDTO ; read byte with default timeout
brcs PRO_to ; branch if timeout
mov r18,r17 ; r18 high nibble
call ModemUartReadByteDTO ;
brcs PRO_to ; r17 low nibble
rcall Octet2Byte ; r17 = scalen
clr r16
rjmp PRO_end
PRO_to:
ldi r16,$01
PRO_end:
pop r18
ret
;-----------------------------------------------------------
; SMSDecodePDUtoRAM - reads PDU from ME and decodes to RAM
;-----------------------------------------------------------
;
; Inputs:
; data for Modem UART
; Y : Points to RAM-Areas for decoded message
;
; Outputs:
; r20 = $00 - No Problem
; = $01 - UART Timeout
; = $xx - error in alpabet (so far only 7-bit supported)
; = $xx - "general error"
;
;0791947101670000040C9194714117325400003090501024854006CDA0949A7402
SMSDecodePDUtoRAM:
push r6
push r16
push r17
push r18
push r19
push r21
push r22
push YL
push YH
; "Relative branch out of reach" workaround
; for SD_to
rjmp SD_L0
SD_to2:
rjmp SD_to
SD_L0:
; end of workaround - to be honest - the whole thing
; is a large work around nothing
ldi r22,$00
st Y,r22 ; init RAM-Array to zero length
clr r22 ; init char counter
;;; ldi r20,$00
; read SCA-Len
rcall PDUReadOctet ; r17 = scalen in octets
tst r16 ; test for error during PDUReadOctet
brne SD_to2 ; if r16!=0 goto error
; skip SCA Type and Number
mov r18,r17 ; copy scalen as counter to r18
SD_SCA_L1:
rcall PDUReadOctet ; read octet
tst r16 ; error test
brne SD_to2
dec r18 ; dec octet counter
tst r18
brne SD_SCA_L1 ; loop until all octets read
; PDU-Mode
rcall PDUReadOctet ; r17 = pdumode
tst r16 ; test for error during PDUReadOctet
brne SD_to2 ; if r16!=0 goto error
; orginator-adress-len (without type octet)
; Len:12 Type:91 Number:947141272143 =+491714721234
rcall PDUReadOctet ; r17 = oalen (number of digits)
tst r16 ; test for error during PDUReadOctet
brne SD_to2 ; if r16!=0 goto error
mov r18,r17 ; store oalen as counter in r18
; read orginator adress type of number
rcall PDUReadOctet ; r17 = oatype (type and number in chars)
tst r16 ; test for error during PDUReadOctet
brne SD_to2 ; if r16!=0 goto error
cpi r17,$91 ; test of international ($91)
brne SD_OA_Nat ; branch if national
ldi r16,'+'
st Y+,r16 ; store internationel prefix "+"
inc r22 ; increment char counter
SD_OA_Nat:
SD_OA_L1:
; read number
call ModemUartReadByteDTO ; read byte into r17 with
; default timeout
brcs SD_to2 ; branch if timeout
mov r16,r17
call ModemUartReadByteDTO ; read byte in r17
brcs SD_to2 ; branch if timeout
st Y+,r17 ; store "swapped" 2nd char in octet first
inc r22 ; increment char counter
cpi r16,'F' ; skip "End-Mark" (occures when oalen is an odd number)
breq SD_OA_SF
st Y+,r16 ; 1st char in octet last
inc r22 ; increment char counter
SD_OA_SF:
subi r18,2
cpi r18,$01 ; all read?
brge SD_OA_L1 ; no -> go on
ldi r16,$0D ; store separator '\r' in ram
st Y+,r16
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -