?? uartinterfaceasm.s
字號:
; Module Name: UartInterfaceAsm.S
; Module Date: 05/24/2004
; Module Auth: John Orlando
; Copyright (c) 2004 John Orlando All Rights Reserved
;
; Description: This module provides an interrupt service routine
; for accessing the mega8's UART receive register. This is
; done specially since we want to be able to signal to the
; currently running routine that serial data needs to be handled.
#include <avr/io.h>
#include "Events.h"
.extern Exec_eventFifo ; This gives the ability to indicate which
; action to take upon being interrupted.
.extern Exec_eventFifoHead
.extern UIMgr_rxFifoHead ; This allows access to the head of the rx fifo
.extern UIMgr_rxFifo ; This allows access to the rx fifo itself...
#define UI_MGR_RX_FIFO_MASK 31 ; This needs to correspond to the value in UIMgr.c
tmpReg = 0
zeroReg = 1
r20 = 20
r21 = 21
r22 = 22
r23 = 23
r24 = 24
r25 = 25
r26 = 26
r27 = 27
r28 = 28
r29 = 29
r30 = 30
r31 = 31
.section .text
.global SIG_UART_RECV
;***********************************************************
; Function Name: <interrupt handler for UART receive complete>
; Function Description: This function is responsible reading
; a byte from the UART, and writing it to the UIMgr_rxFifo.
; This all needs to be done in assembly (instead of C)
; because we are using the T flag in the SREG to indicate
; to the currently executing routine that an event needs
; to be processed. If written in C, the SREG would get
; restored as the last thing (from the stack), and thus
; the T flag would be written with its inital value. When
; the ISR is written in assembly, we can do whatever we
; want, including setting the T flag after the SREG is
; restored. NOTE: This routine was originally written in
; C, then compiled with GCC. The resultant output was
; studied to create this routine.
; Inputs: none
; Outputs: none
;***********************************************************
SIG_UART_RECV:
push zeroReg
push tmpReg
in tmpReg, _SFR_IO_ADDR(SREG) ; save the status reg
push tmpReg
clr zeroReg
push r20 ; save the contents of needed regs
push r21
push r24
push r30 ; save the Z register so we
push r31 ; can use it to access the rx fifo
push r28
push r29
in r28,_SFR_IO_ADDR(SPL)
in r29,_SFR_IO_ADDR(SPH)
sbiw r28,2
out _SFR_IO_ADDR(SPH),r29
out _SFR_IO_ADDR(SPL),r28
in r20,_SFR_IO_ADDR(UDR) ; read the serial byte
; Store the received serial byte in the rx fifo
lds r21,UIMgr_rxFifoHead
ldi r24,lo8(UIMgr_rxFifo)
ldi r25,hi8(UIMgr_rxFifo)
movw r30,r24
add r30,r21 ; r31:r30 should now point to the next free spot in the fifo
adc r31,zeroReg ; not sure what this is for...
st z,r20 ; z is all set now...store the data into the fifo
inc r21
andi r21,UI_MGR_RX_FIFO_MASK ; handle wrapping of the rx fifo
sts UIMgr_rxFifoHead,r21
; Store the event in the event fifo
ldi r20,EV_SERIAL_DATA_RECEIVED
lds r21,Exec_eventFifoHead
ldi r24,lo8(Exec_eventFifo)
ldi r25,hi8(Exec_eventFifo)
movw r30,r24
add r30,r21 ; r31:r30 should now point to the next free spot in the fifo
adc r31,zeroReg ; not sure what this is for...
st z,r20 ; z is all set now...store the data into the fifo
inc r21
andi r21,EXEC_EVENT_FIFO_MASK ; handle wrapping of the event fifo
sts Exec_eventFifoHead,r21
; All done now...restore everything...
adiw r28,2
cli ; Not sure why we disable ints here...
out _SFR_IO_ADDR(SPH),r29
out _SFR_IO_ADDR(SPL),r28
pop r29
pop r28
pop r31
pop r30
pop r24
pop r21
pop r20
pop tmpReg
out _SFR_IO_ADDR(SREG),tmpReg
pop tmpReg
pop zeroReg
set ; As the last thing, set the T
; flag to indicate to the currently
; executing routine there is something
; to handle.
reti
.end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -