Sunteți pe pagina 1din 9

@ Miles Histand @ ECE 372 @ Monday, July 14, 2013 9 AM @ @ This program uses the ARM instruction encoding

to communicate with the @ Zeus board PXA270 Microprocessor. Specifically, this program will: @ @ 1. Use interrupt procedures to respond to a pushbutton signal on GPIO<73> @ and activate the UART2 communication with the RC Systems 2660 Speech @ synthesis board connected to the COM2 port on the Zeus board. @ 2. Use the serial interface UART to send character data to the RC2660, @ implementing the auto-BAUD rate capability, and activate the speech syn thesis @ board to speak the string of characters. @ 3. Using the RTAR alarm register along with other registers, make the speech @ synthesizer speak the message every 60 seconds. @ @ Note: This program was written exclusively by Miles Histand without assistance @ by anyone. .text .global _start _start: @ Section of .EQU space to minimize time to reWRITE register locations for @ different Zeus boards .EQU GAFR2_L,0x40E00064 > .EQU GAFR0_L,0x40E00054 GPIO<10> @ Alternate function for GPIO<73 @ Alternate function address for

.EQU MESSAGE_LEN, (MESSAGE_END-MESSAGE) @ Equation for counting the characters i n message @ for BUTTON and general .EQU GPDR2,0x40E00014 n .EQU GRER2,0x40E00038 n .EQU GEDR2,0x40E00050 n .EQU ICMR,0x40D00004 tion .EQU GAFR2_L,0x40E00064 .EQU ICIP,0x40D00000 @ for UART .EQU GRER3,0x40E00130 on .EQU GEDR3,0x40E00148 on .EQU LCR,0x10800006 .EQU DLL,0x10800000 .EQU DLM,0x10800002 .EQU IER,0x10800002 .EQU FCR,0x10800004 .EQU LSR,0x1080000A nterrupt .EQU MSR,0x1080000C @ GPDR2 for GPIO<73> pin register memory locatio @ GRER2 for GPIO<73> pin register memory locatio @ GEDR2 for GPIO<73> pin register memory locatio @ Interrupt Controller Mask Register memory loca @ GAFR2_L Alternate Function pin for GPIO<73> @ IRQ Pending register memory location @ GRER3 for GPIO<115> pin register memory locati @ GEDR3 for GPIO<115> pin register memory locati @ @ @ @ @ @ Line Control register memory location Divisor Low register memory location Divisor High register memory location Interrupt Enable Register memory location FIFO Control Register memory location LSR memory location to check bit 5 THR-empty i

@ MSR memory location to check bit 4 CTS# input

interrupt .EQU MCR,0x10800008 ster .EQU TMT,0x10800000

@ MCR memory location for MCR Modem Control regi @ UART Transmit buffer

@ UART: two cases if UART is at either GPIO<115> or GPIO<10> .EQU GAFR3_U,0x40E00070 @ GAFR3_U Alternate Function pin for GPIO<115> .EQU GAFR0_L,0x40E00054 @ GAFR0_L Alternate Function pin for GPIO<10> .EQU GRER0,0x40E00030 @ GRER0 for GPIO<10> pin register memory locatio n .EQU GEDR0,0x40E00048 @ GEDR0 for GPIO<10> pin register memory locatio n .EQU PIN115,0xFFF3FFFF @ word to modify bits 18 and 19 for UART GPIO<11 5> .EQU PIN10, 0xFFFFF3FF @ word to modify bits 10 and 11 for UART GPIO<10 > .EQU GRER0BIT_10,0x00000400 @ word to set bit 10 for rising edge detect for GRER0 @ when UART Interrupt is at GPIO<10> @ for Alarm .EQU OSCC,0x41300008 on .EQU RTSR,0x40900008 ion .EQU RTAR,0x40900004 .EQU RCNR,0x40900000 @ OSCC oscillator register address memory locati @ Real Time Status Register address memory locat @ Real Time Alarm Register memory location @ RCNR register memory location

@ change alternate function of GPIO<73> from 10 to 00 LDR R0, =GAFR2_L L containing button pin LDR R1,[R0] urrent value LDR R2, =0xFFF3FFFF :18 to change alternate function 73> pin AND R1,R1,R2 s 19:18 in GAFR2_L STR R1,[R0] k to GAFR2_L @ R0 = pointer to GAFR2_ @ READ GAFR2_L c @ Value to clear bits 19 @ GPIO < @ MODIFY by clearing bit @ WRITE word bac

@ change alternate function of GPIO<10> from 10 to 00 for UART LDR R0, =GAFR0_L _L containing UART LDR R1,[R0] urrent value LDR R2, =0xFFCFFFFF :20 to change alternate function 10> pin AND R1,R1,R2 s 21:20 in GAFR0_L STR R1,[R0] k to GAFR0_L @ and initialize GPIO<73> as input (Button) @ R0 = pointer to GAFR20 @ READ GAFR0_L c @ Value to clear bits 21 @ GPIO < @ MODIFY by clearing bit @ WRITE word bac

LDR R0,=GPDR2 LDR R1,[R0] BIC R1,R1,#0x200 STR R1,[R0]

@ @ @ @ @

load pointer to GPDR2 address READ GPDR2 to get current value clear bit 9 in GPDR2 to make sure GPIO<73> is an input WRITE word back to GPDR2

@ Initialize GRER2 register to make GPIO<73> as rising edge detect LDR LDR MOV ORR STR R0,=GRER2 R1,[R0] R2,#0x200 R1,R1,R2 R1,[R0] @ @ @ @ @ load address of GRER2 register READ contents of GRER2 register load mask to set bit 9 set bit 9 for rising edge detect WRITE word back to GRER2 register

@ Initialize GPIO<10> as rising edge interrupt input for COM2 UART driving RC866 0 LDR R0,=GRER0 r LDR R1,[R0] r LDR R2,=GRER0BIT_10 ORR R1,R1,R2 ng edge detect STR R1,[R0] @ word to set bit 10 to enable GPIO<10> @ set bit 19 to enable GPIO<10> for risi @ WRITE back to GRER0 @ READ contents of GRER0 registe @ load address to point to GRER0 registe

@ IRQ reset value is desired ICLR[10] value, so no word sent @ DIM bit reset value of ICCR is desired value, so no word sent LDR R0,=ICMR LDR R1,[R0] LDR R2, =0x80000400 arm) ORR R1, R1, R2 STR R1, [R0] @ MODIFY set bit 10 to unmask IM10 @ WRITE word back to ICMR register @ load address of mask ICMR register @ READ value of ICMR register @ load value to unmask bit 10 (UART and @ Button) and 31 (RTC Al

@ Initialize OSCC register to use 32,768 KHz Oscillator for real time gauge LDR R0,=OSCC LDR R1,[R0] ORR R1,R1,#2 2,768 kHz signal STR R1,[R0] @ Initialize RTC Alarm Interrupt Enable LDR R0,=RTSR LDR R1,[R0] MOV R2,#0x4 ORR R1,R1,R2 errupt enable STR R1,[R0] @ load pointer to RTSR @ READ contents of RTSR @ word to enable alarm interrupt @ MODIFY set bit 3 to RTSR for alarm int @ WRITE word back to memory @ load pointer to OSCC register @ READ contents of OSCC register @ MODIFY set bit 1 of OSCC to activate 3 @ WRITE word back to memory

@ Initialize Real Time Alarm Register to set for 10 seconds LDR R0,=RTAR MOV R1,#10 STR R1,[R0] @ load pointer to RTAR @ load value (10s) for Alarm @ WRITE word back to memory

@ Initialize RCNR (Real Time Clock Timer) LDR R0,=RCNR MOV R1,#0 r STR R1,[R0] @ Initialize UART @ Set DLAB bit in LCR to access BAUD rate divisor LDR R0,=LCR MOV R1,#0x83 parity, 1 stop bit STRB R1,[R0] @ Load divisor value to give 38.4kb/s LDR R0,=DLL MOV R1,#0x18 or STRB R1,[R0] LDR R0,=DLM register MOV R1,#0x0 8x Divisor STRB R1,[R0] @ WRITE to DLL register @ access address to point to DLM @ value to WRITE to DLM for #0x1 @ WRITE to DLM register @ point to DLL register @ value to WRITE to DLL for #0x18x Divis @ point to LCR register @ byte for Divisor enable=1, 8 bits, no @ WRITE byte to Line Control Register @ WRITE word back to memory @ load pointer to RCNR @ clear value RCNR to reset time

@ Toggle back to UART's DLAB 0 to access Tx and Rx register LDR R0,=LCR MOV R1,#0x03 parity, 1 stop bits STRB R1,[R0] @ Disable FIFO LDR R0,=FCR MOV R1,#0x0 STRB R1,[R0] @ point to FCR register @ value to disable FIFO and clear FIFO @ WRITE to FCR @ point to LCR register @ value for Divisor enable=0, 8 bits, no @ WRITE back to LCR

@ Hook IRQ procedure address and install own INT_Manager MOV R1, #0x18 LDR R2, [R1] r LDR R3, =0xFFF AND R2, R2, R3 ADD R2, R2, #0x20 LDR R3, [R2] l STR R3, BOOT LDR R0, =INT_Manager e STR R0, [R2] @ Save this address in literal pool @ save bootloader IRQ address for later @ load address of our interrupt procedur @ @ @ @ @ @ @ table 0x18 construct mask mask everything except offset of instruction Build address for IRQ procedure in literal pool READ BOOT IRQ address from literal poo @ load IRQ interrupt vector address 0x18 @ READ instructioin from interrupt vecto

@ make sure IRQ interrupt on processor is enabled, i.e. clear bit 7 in @ CPSR MRS R3, CPSR BIC R3, R3, #0x80 MSR CPSR_c,R3 Loop: NOP B Loop @ copy CPSR to R3 @ CLEAR bit 7 (IRQ enable bit) @ WRITE back to lower 8 bits of CPSR @ mimic main program waiting for @ interrupt @ chaining button interrupt proc

INT_Manager: edure @ Test for ICIP interrupt STMFD SP!,{R0-R5,LR} cedure on stack LDR R0,=ICIP ing register (ICIP) LDR R1,[R0] TST R1,#0x400 upt on IP<10> BEQ RETURN Return to Bootloader @ Test for UART interrupt LDR R0,=GEDR0 UART LDR R1,[R0] TST R1,#0x400 BNE Speech_Service for button press @ Test for button press LDR R0,=GEDR2 GEDR2) LDR R1,[R0] TST R1,#0x200 BNE BUTTON_Push RT @ Test for Alarm LDR R0, =0x40900008 LDR R1,[R0] TST R1, #1 ed? BNE Alarm_Svc RETURN: LDMFD SP!,{R0-R5,LR} LDR PC,BOOT t BUTTON_Push: @ Reset GEDR2 register MOV R1,#0x200

@ Save used registers to be used for pro @ load pointer to Interrupt Pend @ READ ICIP register @ Check if GPIO 119:2 IRQ Interr @ No, must be other IRQ.

@ load pointer to GEDR0 Edge detect for @ READ GEDR0 register @ check for UART interrupt on bit 10 @ If so, send a character. If not, check

@ load pointer to Edge Detect register ( @ READ GEDR2 register @ Check bit 9 = 1 @ If so, go to BUTTON_Push to prepare UA

@ load RTSR @ read value RTSR @ edge rise for our alarm detect @ alarm status edge rise. Startup UART

@ Go to Bootloader system defaul

@ Value to clear bit 9 of GEDR2 register

STR R1,[R0]

@ WRITE to GEDR2 to turn off

@ Enable Tx interrupt and enable modem status change interrupt LDR R0,=IER MOV R1,#0x0A e (bit 3=1) ) STRB R1,[R0] @ WRITE to IER register @ Initialize MCR (Modem Control Register) to enable UART Interrupt and assert CT S# LDR R0,=MCR @ load pointer to MCR register MOV R1,#0x0A @ value to WRITE to MCR register (INT ou tput enable and @ RTS# Output control STRB R1,[R0] @ WRITE to MCR register LDMFD SP!,{R0-R5,LR} @ Restore registers from stack and SUBS PC,LR,#4 @ return to Wait Loop for next interrupt @ Alarm service Alarm_Svc: @ Turn off Alarm interrupt LDR R0, =0x40900008 LDR R1, [R0] MOV R2, #0b1 nterrupt ORR R1, R1, R2 STR R1, [R0] @ load pointer to RTSR @ read RTSR @ Mask to reset bit 2 of RTSR alarm @ in order to turn off i @ CLEAR bit @ WRITE back to RTSR in memory @ point to IER register @ value for Modem Status Interrupt enabl @ and Tx enable (bit 1=1

@ Enable Tx interrupt and enable modem status change interrupt LDR R0,=IER MOV R1,#0x0A e (bit 3=1) ) STRB R1,[R0] @ WRITE to IER register @ Initialize MCR (Modem Control Register) to enable UART Interrupt and assert CT S# LDR R0,=MCR @ load pointer to MCR register MOV R1,#0x0A @ value to WRITE to MCR register (INT ou tput enable and @ RTS# Output control STRB R1,[R0] @ WRITE to MCR register LDMFD SP!,{R0-R5,LR} @ Restore registers from stack and SUBS PC,LR,#4 @ return to Wait Loop for next interrupt @ Reset Alarm timer LDR LDR AND STR R0, R1, R1, R1, =0x40900000 [R0] R1, #0 [R0] @ @ @ @ load pointer to RCNR read contents of RCNR clear RCNR to reset timer write word back to memory @ point to IER register @ value for Modem Status Interrupt enabl @ and Tx enable (bit 1=1

@ Initialize Real Time Alarm Register to set for 10 seconds LDR R0,=RTAR MOV R1,#10 STR R1,[R0] Speech_Service: LDR R0,=MSR mov R3,#0x10 @LDRB R3,[R0] TST R3,#0x10 BEQ NOCTS @ CTS# YES, check for THR LDR R0,=LSR asserted) LDRB R1,[R0] TST R1,#0x20 BEQ GOTO_wait e B SEND @ CTS# NO, check for THR NOCTS: LDR R0,=LSR LDRB R1,[R0] TST R1,#0x20 BEQ GOTO_wait @ point to Line Status Register @ READ contents of LSR @ THR asserted? @ if not, return to wait loop since @ (CTS# AND THR)# @ CTS# AND THR# @ Else CTS# AND THR, send character @ Point to Line Status Register (CTS# is @ READ contents of Line Status Register @ Has THR been asserted? @ If not, return to wait loop for THR ready sinc @ point to Modem Status Register @ forcing R3 to have 10 so CTS# is always active READ contents of MSR @ Find out if CTS# has been asserted @ CTS# no, check for THR empty @ load pointer to RTAR @ load value (10s) for Alarm @ WRITE word back to memory

@ CTS# NO, THR YES @ Mask THR so continuous interrupt of THR empty doesn't stall program LDR R4,=IER MOV R5,#0x08 STRB R5,[R4] B GOTO_wait @ point to Interrupt Enable Register @ Value to mask THR interrupt and keep interrupt @ enabled for CTS# @ WRITE back to IER

SEND: @ Unmask THR to enable interrupt for next character LDR R4,=IER MOV R5,#0x0A ts STRB R5,[R4] @ transmit a character LDR R0,=CHAR_PTR LDR R1,[R0] LDR R2,=CHAR_COUNT @ point to MESSAGE pointer in memory @ R1=address of character @ R2=address of counter location @ WRITE back to IER @ point to Interrupt Enable Register @ value to enable THR and other interrup

LDR R3,[R2] LDRB R4,[R1],#1 acter STR R1,[R0] acter pointer LDR R5,=TMT STRB R4,[R5] t source

@ Get current value of counter @ READ character to send, increment to next char @ Get incremented address back into char @ location @ point to transmit buffer @ WRITE to transmit buffer (clears TDRQ interrup @ until THR empty

@ prepare to transmit next character SUBS R3,R3,#1 STR R3,[R2] BNE GOTO_wait @ @ @ @ decrement counter WRITE count value back to memory If count value is greater or equal to 0, get more characters

@ go to beginning of message and restart counter LDR R3,=MESSAGE STR R3,[R0] MOV R3, #MESSAGE_LEN ) STR R3,[R2] @ WRITE value back into memory @ Reset edge detect register (turn off GEDR0 for UART LDR R0,=GEDR0 MOV R1,#0x400 STR R1,[R0] @ Disable UART interrrupt LDR R0,=MCR LDRB R1,[R0] BIC R1,#0x08 STRB R1,[R0] @ point to Modem Control Register @ READ value of MCR @ Clear bit 3 to disable UART interrupt @ WRITE back to MCR @ load pointer to GEDR0 Edge detect for UART @ Value to clear bit 10 of GEDR0 register @ WRITE to GEDR0 to turn off @ get address of start of string @ Write to CHAR_PTR location in memory @ get original message length (no. of characters

@ Disable Tx interrupt and disable modem status change interrupt LDR R0,=IER LDRB R1,[R0] BIC R1,R1,#0x02 control) BIC R1,R1,#0x08 terrupt (bit 3=0) STRB R1,[R0] @ Branch to wait loop GOTO_wait: LDMFD SP!,{R0-R5,LR} er SUBS PC,LR,#4 @ Return to original program. @ restore original registers from stack @ as well as Link Regist @ point to IER register @ READ contents of IER bits 7:0 @ clear bit 1 to disable Tx (RTS output @ clear bit 3 to disable Modem Status In @ WRITE to IER register

BOOT: .word 0x0 address .data .align 2 bytes alignment)

@ space to store bootloader IRQ @ 2^n alignment n = 2, hence word align (.align 4 == 16

@ put align wherever we want tha t following data to be aligned @ by "data", meaning anything start with a label MESSAGE: .byte 0x01 @ control 'A' .ascii "1o" @ vader void .byte 0x01 @ ctrl - A .ascii "9v" @ volume .ascii "Test." @ phrase .ascii "\n\r" @ CR, start speaking MESSAGE_END: .byte 0x0 .align 2 @ will mis-align without this (SIGBUS CHAR_PTR: CHAR_COUNT: .end .word MESSAGE .word MESSAGE_LEN @ Counter for number of characters to send

S-ar putea să vă placă și