⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdu.asm

📁 Eversmith_-_AVRSMS for pdu mode
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;==========================================================
; This is a part of: Eversmith - AVRSMS
; 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. See main-file for more infor-
; mation and license.
;==========================================================
; - PDU generation and transmit to ME
; - PDU decoding of received SMS-PDUs
;
; Based on: Siemens Developers-Guide "SMS with PDU-Mode"
; 	Version 1.2, Jul 30, 1997 ("google" for it)
;
; Modem is connected to USART1
;
; Search the lines "*Siemens only" if you don't use a 
; Siemens GSM ME (like Nokia or Ericsson) and read the 
; comments. Test for user-configuration in V0.56...

;----------------------------------------------------------
; Maximum memory index that will be read from the GSM-
; device by AT+CMGR=x (x=1...CMGRMAXIDX) 
; (see Subroutine SMSProcessUnread)
;;; for debuging: changed from 15 to 10
.equ CMGRMAXIDX=10	

;----------------------------------------------------------
; Maximum length of decoded PDU (rest is ignored) in SMSPARSEMAXLEN
; this means the number of digits in the senders number + 
; the number of chars in the message + 2 for separator \r($0D) and lineend \0
; eg:491711234567\nABCDEFG\0 = 21
; (see Subroutine SMSDecodePDUtoRAM)
.equ SMSPARSEMAXLEN = 60

;----------------------------------------------------------
; a work area to store Messages to send and received 
; SMSes - PDUs are generated on the fly so the
; area can be shared but take care to avoid side-effects
; 
;(a) either create a local area:
;;.equ SMSWorkAreaMAX = 160
;;.DSEG
;;SMSWorkArray: .byte SMSWorkAreaMax
;;.equ SMSWorkArea = SMSWorkArray
;(b) or use shared area reserved in avrsms.asm
; Work1 must be assigned to a ram-area (dseg) before
; using it here (see map-file if in doubt)
.equ SMSWorkArea = Work1

;----------------------------------------------------------
; Poll-Intervall
; the ME will be polled every SMSPOLLINT seconds
; for incoming SMS
.equ SMSPOLLINT = 30

.CSEG
;----------------------------------------------------------
; PDUUartSend - Sends a byte to UART (GSM Modem)
;----------------------------------------------------------
; 
; Inputs:
;	r16 - Byte to send
;
; Ouputs:
;	none
PDUUartSendByte:
	call UART1SendByte
	ret		
		
;----------------------------------------------------------
; PDUStrLenRam - calculated length of Null-term. string in
;	SRAM
;----------------------------------------------------------
;
; Inputs:
;  Y-Register = Pointer to String
;
; Output:
;  r17 = length of string (without terminating Null)
;
PDUStrLenRam:
	push r16
	push YL
	push YH

	ldi r17,$00
PDUStrLenRam_L1:
	ld r16, Y+
	tst r16
	breq PDUStrLenRam_End
	inc r17
	rjmp PDUStrLenRam_L1

PDUStrLenRam_End:
	pop YH
	pop YL
	pop r16
	ret

;----------------------------------------------------------
; PDUAddCharRam - Adds a character to a Null-terminated
; string in SRAM
;----------------------------------------------------------
;
; Inputs:
;  Y-Register = Pointer to String in SRAM
;  r17 = Character to add
;
; Output:
;  none
;
PDUAddCharRam:
	push r16
	push YL
	push YH

PDUACR_L1:
	ld r16,Y+
	tst r16			; test for Null
	breq PDUACR_End
	rjmp PDUACR_L1
PDUACR_End:
	st -Y,r17		; add character at eof
	adiw YH:YL,$01
	ldi r16,$00
	st Y,r16		; store terminating 0

	pop YH
	pop YL
	pop r16
	ret

;----------------------------------------------------------
; PDUHexAsciiLow - converts low nibble of byte to
; 	ASCII HEX-char
;----------------------------------------------------------
;	based on code form the AVR Assembler tutorial
;	TODO: add URL here
;
; Input:
;  r17 = input byte
;
; Output:
;  r16 = charcater rep. for low nibble

PDUHexAsciiLow:
	mov r16, r17
	andi r16, $0F	; only low nibble
	subi r16,-'0' 	; r16=r16+'0'
	cpi r16,'9'+1 	; larger than '9'
	brcs PDUHexAsciiLow_L1 ; no -> jump
	subi r16,-7 	; r16=r16+7  ('0'=$30, '9'=$39, 'A'=$41, 'F'=$46)
PDUHexAsciiLow_L1:
	ret 

;----------------------------------------------------------
; PDUHexAsciiHigh - converts high nibble of byte to
; 	ASCII HEX-char
;----------------------------------------------------------
;
; Input:
;  r17 = input byte
;
; Output:
;  r16 = charcater rep. for high nibble

PDUHexAsciiHigh:
	push r17
	swap r17
	rcall PDUHexAsciiLow
	pop r17
	ret

;----------------------------------------------------------
; PDUUartSendHex - Send a byte to UART Hex-encoded
;----------------------------------------------------------
;
; Input:
;  r17 = input byte
;
; Output:
;  goes to UART

PDUUartSendHex:
	push r16
	rcall PDUHexAsciiHigh
	rcall PDUUartSendByte
	rcall PDUHexAsciiLow
	rcall PDUUartSendByte
	pop r16
	ret

;----------------------------------------------------------
; PDUSendHeader - Sends the PDU header (destination-number 
; etc.) to UART
;----------------------------------------------------------
; depends on EEReadPlus from eeprom.asm
;
; Inputs:
;  r24 = Destination Number in EEPROM low (Data null terminated)
;  r25 = Destination Number in EEPROM high
;
; Output:
;  Data goes to UART
;
; Side-effects:
;  implicit from EEReadPlus
PDUSendHeader:
	push r16	; used by UartSend/Convert
	push r17	; used by Convert
	push r18	; counter
	push r19	; work num
	push r20	; work num
	push r24
	push r25


; SCA Len = 0 = use SMSC number stored in ME
	ldi r17,$00
	rcall PDUUartSendHex

; PDU-Type:
; VPF=16 validity relativ 
; MTI=1  SMS-Submit MS->SMSC
  	ldi r17,16+1
	rcall PDUUartSendHex

; Message Reference MR=0
	ldi r17,$00
	rcall PDUUartSendHex

; Orginator Adress Length
	call EESeqLen			; load length in r17
	rcall PDUUartSendHex	; send length in r17 as octet

; Orginator Adress type of number
; ALWAYS "number international" = int. acc. code prefixes number
	ldi r16,'9'
	rcall PDUUartSendByte
	ldi r16,'1'
	rcall PDUUartSendByte

; Orginator Adress Number
	ldi r18,$01
PSH_L1:
	; read 
	call EEReadPlus		; read first half of octet (high) in r16
	mov r19,r16			; store first half octet in r19
	tst r19				; end of number?
	breq PSH_End
	call EEReadPlus		; read second half of octet (low) in r16
	mov r20,r16			; store second half in r20
	tst r16				; end of number?
	brne PSH_L2			; no->jump to write
	ldi r20,$0F			; fill with $0F if odd(ungrade)
	ldi r18,$00			; mark end
	
PSH_L2:
	; write second half off octet
	mov r17,r20			; write second half first
	rcall PDUHexAsciiLow
	rcall PDUUartSendByte
	mov r17,r19			; write first half
	rcall PDUHexAsciiLow
	rcall PDUUartSendByte
	tst r18
	brne PSH_L1
PSH_End:

; PID always 00h
	ldi r17,$00
	rcall PDUUartSendHex

; coding-scheme
; coding group (bits 7-4) = 1111
; data-coding 7 bit (bit 2 cleared)
; class 1 ME (bit 0 set, bit 1 cleared)
	ldi r17,0b11110001
	rcall PDUUartSendHex

; validity period
.equ MAXDAYSVALID = 4
	ldi r17,166+MAXDAYSVALID
	rcall PDUUartSendHex

	pop r25
	pop r24
	pop r20
	pop r19
	pop r18
	pop r17
	pop r16
	ret

;----------------------------------------------------------
; PDUHeaderLen - Calculates the length of the header
;----------------------------------------------------------
; depends on EEReadPlus from eeprom.asm
;
; Inputs:
;  r24 = Destination Number in EEPROM low (Data null terminated)
;  r25 = Destination Number in EEPROM high
;
; Output:
;  r22 = length of the header (0 if emphty or Error)
;
PDUHeaderLen:
	push r16
	push r24
	push r25

	ldi r22,$00			; init counter

	; initial empty protection:
	call EEReadByte
	cpi r16,$FF			; default EEprom content ofter chip-erase
	breq PHL_END
		
; number length
PHL_L1:
	call EEReadPlus		; read byte
	inc r22				; increment counter
	tst r16				; test for end-of-string
	brne PHL_L1			; no - read more
	dec r22				; decrement because the $00 has been counted

; needed bytes (devide by 2):
	clc					; clear carry
	ror r22				; rotate right (devide by 2)
	brcc PHL_L2			; if r22 mod 2 == 0 skip
	inc r22				; count modulo 

PHL_L2:
; 	rest of the header
	;; According to the Siemens TC35-Documentation the SCA (length 
	;; and number) does not count to the pdu-length for at+cgms, 
	;; so the SCA-byte does not count here
	;; no! ; inc r22	; SCA length byte
	inc r22	; PDU-type
	inc r22	; Msg.-reference
	inc r22 ; Orginator Adress length
	inc r22 ; Org. adr. type of number
	nop		; Length of dest.-number already calculated above
	inc r22 ; PID
	inc r22 ; Coding-scheme
	inc r22 ; validity period
	rjmp PHL_END

PHL_END:
	pop r25
	pop r24
	pop r16
	ret

;----------------------------------------------------------
; PDUSendText - Sends UDL/UD (the Text) to UART
;----------------------------------------------------------
;
; Inputs:
;  Y-Register = SMS Text in RAM (Null terminated)
;
; Output:
;	r24 - bytes in PDU by UDL and UD in bytes
;	Data goes to UART
;
; Output:
;  goes to UART

; TODO: well - this code looks strange and it is strange,
;	it needs some clean-up, but, it works

PDUSendText:
	push r16
	push r17
	push r18
	push r19
	push r20
	push r21
	push r22
	push r23
	push YL
	push YH

; Data length UDL
	rcall PDUStrLenRam		; len of message into r17
	rcall PDUUartSendHex	; send r17 as hex
	ldi r24,$01				; init PDU byte count

; Data UD 7bit encoded 
.def PDU_lens = r18		; work byte
.def PDU_t = r17		; work byte
.def PDU_n = r19    	; next byte
.def PDU_avn = r20		; bits avail in next byte
.def PDU_avt = r21		; bits avail in work byte
.def PDU_i   = r22		; counter
.def PDU_j   = r23		; counter

	mov PDU_lens,r17	; save len
	inc PDU_lens

	ldi PDU_avn,$00
	ldi PDU_avt,$01
	clc
	ld PDU_t, Y+
	; andi PDU_t,$ff; 0b01111111	; clear 7th bit
	ldi PDU_i,$01
PDU_brmain:
	ldi PDU_j,$00
	cpi PDU_avt,8
	brlo PDU_br2
	ldi PDU_avt,1
	ld PDU_t, Y+
	inc PDU_i
PDU_br2:
	cp PDU_j,PDU_avt
	breq PDU_br3
	clc
	rol PDU_t
	inc PDU_j
	rjmp PDU_br2
PDU_br3:
	ld PDU_n,Y+
	inc PDU_i
	ldi PDU_avn,1
	ldi PDU_j,0
PDU_br4:
	cp PDU_j,PDU_avt
	breq PDU_br5
	ror PDU_n
	ror PDU_t
	inc PDU_avn
	inc PDU_j
	rjmp PDU_br4
PDU_br5:
	; send r17=PDU_t
	rcall PDUUartSendHex
	inc r24
	mov PDU_t,PDU_n
	mov PDU_avt,PDU_avn
	cp PDU_i,PDU_lens
	brlo PDU_brmain
	
	pop YH
	pop YL
	pop r23
	pop r22
	pop r21
	pop r20
	pop r19
	pop r18
	pop r17
	pop r16
	ret


;----------------------------------------------------------------------
; PDUDataLen - Calculates the length of the User Data (with length UDL)
;----------------------------------------------------------------------
;
; Inputs:
;  YL = Message in SRAM low (Data null terminated)
;  YH = Message in SRAM high
;
; Output:
;  r23 = length of the user UD in PDU including length UDL
;
PDUDataLen:
	push r16
	push r17
	push ZL
	push ZH
	
	; get Number of characters in message:
	rcall PDUStrLenRam	; len goes into r17

	clr ZL
	clr ZH
	; Number of bits in message (7 per char)
	; (MUL not supported on 8515)
PDL_MUL:
	cpi r17,$00
	breq PDL_MULEND
	adiw ZH:ZL,$07
	dec r17
	rjmp PDL_MUL
PDL_MULEND:

	; devide Word in Z-Register by 8
	ldi r16,$00
PDL_DIV:
	cpi ZH,$00
	brne PDL_DIV1
	cpi ZL,$08
	brlo PDL_DIV2
PDL_DIV1:
	sbiw ZH:ZL,$08
	inc r16
	rjmp PDL_DIV
; if modulo!=0 add one to length
PDL_DIV2:
	cpi ZL,$00
	breq PDL_DIVFIN

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -