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

📄 pdu.asm

📁 Eversmith_-_AVRSMS for pdu mode
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	inc r22				; increment char counter

	rcall PDUReadOctet	; r17 = PID 
	tst r16				; test for error during PDUReadOctet
	brne SD_to			; if r16!=0 goto error
	
	rcall PDUReadOctet	; r17 = DCS (Coding Scheme)
	tst r16				; test for error during PDUReadOctet
	brne SD_to			; if r16!=0 goto error
	
	; test for  8-Bit Alphabet - it's not supported
	sbrs r17,(1<<2)		; skip if bit is set
	;rjmp SD_to			;;; TODO: jump of 8-Bit Alphabet

	; skip the 7 time octets (Y M D H M Sc TZ)
	ldi r18,7
SD_TM_L1:
	rcall PDUReadOctet	
	tst r16				
	brne SD_to
	dec r18
	tst r18
	brne SD_TM_L1

	
	rcall PDUReadOctet	; r17 = UDL  User Data Length
	tst r16				; test for error during PDUReadOctet
	brne SD_to			; if r16!=0 goto error
	mov r18,r17			; store UDL in r18
	;;;mov r16,r17
	;;;rcall ModemSendItoA ; dbg

	; and now - the funny part...
					;   r16 = error flag
					;	r18 = i=udl = counter
	clr r20			;	r20 = bit=0;
	clr r21			;	r21 = avail=0;
	ser r17			;   r17 = stream
					;   r19 = out
	clr r6			;   store carry in bit 0 of r6 -> carry=0;
	clr r22			;   character counter

SD_decl2:
	tst r21
	brne SD_decl3	; if (avail!=0) goto decl3;
					; if (hl=='\0') goto exit;
					; hh=pdu[cnt++];
					; hl=pdu[cnt++];
	rcall PDUReadOctet	; r17 = stream=octet2int(hh,hl);
	tst r16			; test for error during PDUReadOctet
	brne SD_to		; if r16!=0 goto error
	ldi r21,8		; avail=8;
SD_decl3:
	ror r6			; restore carry
	ror r17			; ROR(&stream,&carry);
	ror r19			; ROR(&out,&carry);
	rol r6			; store carry
	dec r21			; avail--;
	inc r20			; bit++;
	cpi r20,7		; if (bit<7) goto decl4;
	brlo SD_decl4	
	ror r6			; restore carry
	clc				; carry=0;
	ror r19			; rotate right through carry - ROR(&out,&carry);
	rol r6			; store carry
	cpi r22,SMSPARSEMAXLEN-1
	breq SD_skipstore
	st Y+,r19		; printf("%c",out);
	inc r22			; inc char - counter
SD_skipstore:
	clr r19			; out=0;
	clr r20			; bit=0;
	dec r18			; i--;
	tst r18
	breq SD_P_End	; if (i==0) goto exit;
SD_decl4:
	rjmp SD_decl2	; goto decl2;

SD_P_End:
	ldi r20,$00		; success return value
	rjmp SD_end

SD_to:
	ldi r20,$01

SD_end:
	; store terminating null to string
	ldi r16,$00
	st Y,r16

	pop YH
	pop YL
	pop r22
	pop r21
	pop r19
	pop r18
	pop r17
	pop r16
	pop r6
ret

;-----------------------------------------------------------
; SMSParse
;-----------------------------------------------------------
; Reads the answer from AT+CMGR
;
; Input
; Y-Registers: Point to SRAM-Area with at least SMSPARSMAXCHAR
;		bytes
;
;  Output:
;  r20 = 0 success or !=0 if error
;  *Y=<sendernumber>\t<message>\0	
;
; Answer is: +CMGR:<stat>,<data>,<len>$0D$A
; <stat>=0 means new or unread Message
; if len!=0 followed by the PDU 
; all followed by $0D$0A and again $0D$0A 
; last OK$0D$0A

SMSParse:
	push r16
	push r17
	push r19
	push YL
	push YH

	; skip to character after ':' from "+CMGR:"
	ldi r16,':'
	call ModemUartWaitChar
	cpi r20,$01
	brne SMSP_Error
	
	; read <stat>
	; ATOI reads the ',' after the last digit of <stat>
	call ModemReadATOI		; read message <stat>
	;;; rcall ModemSendItoA		; dbg - echo 
	; stat=0 indicates unread or empty message 
	cpi r16,$00
	brne SMSP_End			; jump to return if stat != 0

	; skip <data> field
	ldi r16,','
	call ModemUartWaitChar
	cpi r20,$01
	brne SMSP_Error
	
	; read the message length
	; ATOI reads the $0D after the last digit <len>
	call ModemReadATOI			; read message <len>
	;;; rcall ModemSendItoA		; dbg
	; check for empty message
	cpi r16,$00
	breq SMSP_END			; yes - no further parsing

	; read message pdu data
	; skip to $0A character (after the <len>$0D)
	ldi r16,$0A
	call ModemUartWaitChar
	cpi r20,$01
	brne SMSP_Error			; jump to return if timeouted
	
	rcall SMSDecodePDUtoRAM	; reads PDU from UART to RAM at Y, error-code in r20
	rjmp SMSP_End

SMSP_Error:
	ldi r20,$01

SMSP_End:
	pop YH
	pop YL
	pop r19
	pop r17
	pop r16
	ret

;-----------------------------------------------------------
; SMSProcessUnread 
;-----------------------------------------------------------
; Reads SMSes from the Mobile Device Storage
; if message is marked unread (=new message) messages
; gets parsed, all messages are deleted from ME storage
; after processing to free memory for new messages
;
;  Output:
;  r20 - Result Code (not impl.)
;
; Command to read a Message: AT+CMGR=<idx> where idx=1..CMGRMAXIDX
; on Siemens TC35

SMSProcessUnread:
	push r16
	push r17
	push r20
	push YL
	push YH
	push ZL
	push ZH

	ldi r17,$01

	call ModemUartFlush		; flush the UART Read-Buffer
	rcall SMSSetPDUMode 	; set to SMS Format to PDU Mode
	
SMSPU_L1:
	; send Read Command "at+cgmr="
	ldi ZL,LOW(2*GSM_CMGR)
   	ldi ZH,HIGH(2*GSM_CMGR)
	call ModemSendCmdFlash
	mov r16,r17				; copy Message Index 
	call ModemSendItoA		; send Message Index in ME-Memory as ASCII
	ldi r16,$0D
	rcall PDUUartSendByte	; send <CR> 0x0d '\r'
	ldi YL,LOW(SMSWorkArea)
	ldi YH,HIGH(SMSWorkArea)
	rcall SMSParse			; Read and Parse Answer PDU
	;;rcall MenuUartSendRamSeq ; dbg
	tst r20					; return of 0 in r20 indicates success
	brne SMS_PU_FAIL		; branch if failed
		
	rcall SMSProcessMsg		; call the function that processes
							; the parsing-result at Y (Number\nMessage\0)

	; rcall ModemUartFlush	; flush the UART
SMS_PU_FAIL:
	call ModemUartWaitOK	; Wait for "OK" from modem
	; delete the Message from ME-Memory
	; send Delete Command "at+cmgd="
	ldi ZL,LOW(2*GSM_CMGD)
   	ldi ZH,HIGH(2*GSM_CMGD)
	call ModemSendCmdFlash
	; send Message Index in ME-Memory
	mov r16,r17
	call ModemSendItoA
	; send <CR> 0x0d '\r'
	ldi r16,$0D
	rcall PDUUartSendByte
	call ModemUartWaitOK
	call ModemUartFlush		; flush the UART
	
	lds r16,SMSReq			; test if something is to be done
	tst r16
	brne SMSPU_End			; break loop

	inc r17
	cpi r17,CMGRMAXIDX+1
	brlo SMSPU_L1

SMSPU_End:

	pop ZH
	pop ZL
	pop YH
	pop YL
	pop r20
	pop r17
	pop r16
ret

; Read SMS from ME Storage
GSM_CMGR:
.db "AT+CMGR=",$00,$00
; Delete SMS in ME Storage
GSM_CMGD:
.db "AT+CMGD=",$00,$00

;--------------------------------------------------------
; SMSCheckCodeInEEprom
; Checks it the fist byte in EEProm at postion
; EEPASSCODE is a $FF (Chip-Erase EEprom content)
; and if empty set to a default Passcode located at 
; label SMSDEFAULTCODE in program flash memory 
SMSCheckCodeInEEprom:
	push r16
	push r24
	push r25
	push ZL
	push ZH
	
	ldi r24,LOW(EEPASSCODE)		; r25:r24 Pointer to Passcode in 
	ldi r25,HIGH(EEPASSCODE)	; EEPROM 
	call EEReadByte			; load first char of code
	cpi r16,$FF				; compare with $FF (empty)
	brne SMSCC_end			; not $FF -> branch
	ldi ZL,LOW(2*SMSDEFAULTCODE)	; load address of
	ldi ZH,HIGH(2*SMSDEFAULTCODE)	; default code
	cli
	call EEWriteSeqFromFlash	; copy Flash Z to EEprom r25:r24
	sei

SMSCC_end:
	pop ZH
	pop ZL
	pop r25
	pop r24
	pop r16
	ret

SMSDEFAULTCODE:
.db "9999",$00,$00

;=========================================
; EEPROM Labels for PASSCODE
.eseg
EEPassCode:	.byte 6
.cseg

;--------------------------------------------------------
; SMSProcessMsg
; Process the Message Stored in Y
; Format Number\rMessage\0
;
; the parese the message for the following
; <code><space><commandchar><space><parameters> 
; cchar	par    partyp    does 
;  S    ID     char      SMSReq="S", SMSRp1=ID as char
;  L    ID     char      SMSReq="L", SMSRp1=ID as char
;  N    ONSw   Bit-Mask  SMSReq="N", SMSRp1=OnSW as byte
;  F    OFFSw  Bit-Mask  SMSReq="F", SMSRp1=OffSW as byte
;  A    -      -         SMSReq="T"
;  Z    -      -         SMSReq="Z"
;  P    Pinnumber+1,State  SMSReq="P", SMSP1=UpperNibble=Pnum,LN=state 0|1
;
; 1  S = send (S)tatus
; 2  L = (L)og-Level (for sending Status)
; 3  N = Switch o(N)  all Pins with 1 in Mask LSB first
; 4  F = Switch o(F)f     - " -
; 5  A = Switch (A)ll Pins on
; 6  Z = Switch all Pins off - (Z)ero
; 7  P = Swich one (P)in 

SMSProcessMsg:
	push r16
	push r17
	push r18
	push r24
	push r25
	push YL
	push YH

	;;;; call MenuUartSendRamSeq ;;;; dbg

	; out of reach workaround
	rjmp SPro_L1
SPro_End2:
	jmp SPro_End

SPro_L1:
	; skip number and go to Message (after separtor $0D)
	ld r16,Y+
	cpi r16,$0D
	breq SPro_Msg	; found separtor -> goto processing
	cpi r16,$00		
	breq SPro_End2	; branch if End-Of-String
	cpi r16,$FF		
	breq SPro_End2	; paranoia
	rjmp SPro_L1	; loop

SPro_Msg:
	; check for valid SMS code
	ldi r24,LOW(EEPassCode)		; pointer to passcode
	ldi r25,HIGH(EEPassCode)
	clr r18				; init counter

SPro_CodeL1:
	call EEReadPlus		; read byte from EEprom at r25:r24 in r16
						; and increment r25:r24
	ld r17,Y+			; get character from Message
	tst r17				; already end of text?
	breq SPro_End2		; yes - branch
	cp r17,r16			; compare
	brne SPro_End2		; branch if wrong Password
	inc r18
	cpi r18,$04			; code is 4 chars long
	brne SPro_CodeL1	; until code processed

	ld r17,Y+			; skip Code/Command separator ($0D)
	tst r17
	breq SPro_End2

	clr r17
	sts SMSReq,r17		; init to "no Request"
	sts SMSRp1,r17		; clear parameter

	ld r17,Y+			; load Command Char
	tst r17
	breq SPro_End2

	; case (r17):
SPro_r1: 		; Status
	cpi r17,'S'
	brne SPro_r2
	sts SMSReq,r17
	clr r16
	sts SMSRp1,r16		; default to no parameter
	ld r17,Y+			; skip separator
	tst r17				; test for EOL
	breq SPRO_End2
	ld r17,Y+			; load parameter
	tst r17				; test for "no parameter"
	breq SPro_End
	sts SMSRp1,r17		; store parameter
	rjmp SPro_End2		; break
SPro_r2:		; Log-level
	cpi r17,'L'
	brne SPro_r3
	ld r17,Y+			; skip separator
	tst r17				; test for EOL
	breq SPro_End
	ld r17,Y+			; load parameter
	tst r17				; test for "no parameter"
	breq SPro_End
	sts SMSRp1,r17		; store parameter
	ldi r16,'L'
	sts SMSReq,r16
	rjmp SPro_End		; break
SPro_r3: 		; oN - Mask
	cpi r17,'N'
	brne SPro_r4
SPro_r4:
	cpi r17,'F' ; oFf - Mask
	brne SPro_r5
SPro_r5:		; Set-All
	cpi r17,'A'
	brne SPro_r6
	sts SMSReq,r17
	rjmp SPro_End
SPro_r6: 		; Zero-All
	cpi r17,'Z'
	brne SPro_r7
	sts SMSReq,r17
	rjmp SPro_End
SPro_r7:		; Pin
	cpi r17,'P'
	brne SPro_r8
	ld r17,Y+			; skip separator
	tst r17				; test for EOL
	breq SPro_End
	ld r17,Y+			; load parameter Pin-Number(0-xxx)
	tst r17				; test for "no parameter"
	breq SPro_End
	subi r17,'0'		; make char to number
	andi r17,0b00001111 ; mask parameter > $0F
	swap r17			; put pin-number in upper nibble
	ld r16,Y+			; skip separator ($20)
	tst r16				; test for EOL
	breq SPro_End
	ld r16,Y+			; load parameter switch value
	tst r16				; test for "no parameter"
	breq SPro_End
	subi r16,'0'		; make char to number
	andi r16,0b00000001	; mask
	or r17,r16			; Pin to upper nibble, switch-state to lower
	sts SMSRp1,r17		; store parameter
	ldi r17,'P'
	sts SMSReq,r17
	rjmp SPro_End
SPro_r8:
	
SPro_End:
	
	;;; call MAINProcRequests ;;; dbg

	pop YH
	pop YL
	pop r25
	pop r24
	pop r18
	pop r17
	pop r16
	ret

; Process - Flags
.dseg
SMSReq:	.byte 1
SMSRp1: .byte 1

.cseg
;--------------------------------------------------------
; SMSDebugProcessMsg
; Test Process copy message from Flash to Ram at Y
; Format Number\nMessage\0
SMSDebugProcessMsg:
	push YL
	push YH	
	push ZL
	push ZH
	ldi ZL,LOW(2*SMSTestMsg)	; source
	ldi ZH,HIGH(2*SMSTestMsg)
	ldi YL,LOW(SMSWorkArea)		; destination
	ldi YH,HIGH(SMSWorkArea)
	call EEFlashSeqToRAM		; copy
	rcall SMSProcessMsg			; test processing
	pop ZH
	pop ZL
	pop YH
	pop YL
ret

SMSTestMsg:
.db "+49171123456",$0D,"9999 P 5 1",$00
;;.db "+49171123456",$0D,"9999 S",$00

⌨️ 快捷键说明

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