;------------------------------------------------------------------------------ ; Manchester University ARM/Xilinx board software ; Off-board Flash ROM programming code ; ; J. Garside November 2001 Maker EQU 0 Version EQU 0 day EQU 21 month EQU 11 year EQU 01 GET header.s ; Register definitions etc. ; GET link_addresses.s ; Addresses (etc.) of programmes AREA flash, CODE, READONLY ENTRY Flash_prog B Flash_prog_start ; ; Pack version & date into 32 bits Version_ID DCD Maker*&1000000 + Version*&10000 + day*&800 + month*&80 + year DCB "AT91 Off-board Flash ROM programmer version 0.0 " DCB "J. Garside, (c) University of Manchester " DCB "November 2001" ALIGN Prog_host_link DCD US0_base ; Flash_prog_start ; Initialise things ; adrl r0, XPIO_config ; Six PIOs ; bl spartan_load ; Configure Spartan device bl XPIO_init ; Initialise PIO states ; Set baud rates ; Poll both UARTs to find first character with no errors ; save pointer to it (R11) ; Print appropriate message? mov r9, #0 ; All addresses writeable ; R10 not needed here ldr r11, Prog_host_link ; Pointer to UART GET fp1.s ; Main body of code ;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------ ; Send character in R0 to serial line #0 Prog_Host_out stmfd sp!, {r2, lr} ; Prog_Host_out1 ldr r2, [r11, #US_CSR] ; Pass byte to transmit in R0 tst r2, #TxRdy ; Test if ready to transmit beq Prog_Host_out1 ; Prog_Host_out2 str r0, [r11, #US_THR] ; Send character ldmfd sp!, {r2, pc} ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Get character from serial line #0 into R0 Prog_Host_in stmfd sp!, {lr} ; Prog_Host_in1 ldr r0, [r11, #US_CSR] ; tst r0, #RxRdy ; Receiver ready? beq Prog_Host_in1 ; Prog_Host_in_rdy ldr r0, [r11, #US_RHR] ; Upper bits read as 0 ldmfd sp!, {pc} ; Return byte in r0 ;------------------------------------------------------------------------------ ; Wait for addressed location/R1 to contain R0 ; Timeout count in R5 ; Returns R5 = 0 if timeout, else R5 <> 0 ; Corrupts R2, R3 flash_wtr ldr r3, SLit_Spartan_base ; Point at PIO mov r2, #&FF ; Data bus to input strb r2, [r3, #prog_SB0_ctrl]; Low byte strb r2, [r3, #prog_VS0_ctrl]; High byte ldrb r2, [r3, #prog_SA1_data]; bic r2, r2, #&02 ; Assert nCS strb r2, [r3, #prog_SA1_data]; ldrb r2, [r3, #prog_SA0_data]; bic r2, r2, #&20 ; Assert nOE strb r2, [r3, #prog_SA0_data]; flash_wtr1 ldrb r2, [r3, #prog_SB0_data]; subs r5, r5, #1 ; Decrement timeout cmpne r2, r0 ; bne flash_wtr1 ; Wait for values to match ldrb r2, [r3, #prog_SA0_data]; orr r2, r2, #&20 ; Remove nOE strb r2, [r3, #prog_SA0_data]; ldrb r2, [r3, #prog_SA1_data]; orr r2, r2, #&02 ; Remove nCS strb r2, [r3, #prog_SA1_data]; mov pc, lr ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - flash_w_hword stmfd sp!, {r0-r3, lr} ; ldr r3, SLit_Spartan_base ; Point at PIO strb r0, [r3, #prog_SB0_data]; Data to output latches mov r0, r0, lsr #8 ; High byte strb r0, [r3, #prog_VS0_data]; mov r0, #&3B ; Control inactive strb r0, [r3, #prog_SA0_data]; mov r0, #&00 ; Data bus to output strb r0, [r3, #prog_SB0_ctrl]; Low byte strb r0, [r3, #prog_VS0_ctrl]; High byte mov r2, #8 ; Reverse in bytes mov r0, r1, lsr #1 ; A0 is not interesting bl bit_rev ; A[8:1] strb r0, [r3, #prog_SB1_data]; mov r0, r1, lsr #9 ; bl bit_rev ; A[16:9] strb r0, [r3, #prog_VS1_data] mov r0, r1, lsr #17 ; bl bit_rev ; A[21:17] and r0, r0, #&F8 ; Ensure upper bits clear orr r0, r0, #&01 ; Don't pulse reset strb r0, [r3, #prog_SA1_data]; nCS asserted mov r2, #&2B ; Assert nWE strb r2, [r3, #prog_SA0_data]; mov r2, #&3B ; Remove nWE strb r2, [r3, #prog_SA0_data]; orr r0, r0, #&02 ; nCS strb r0, [r3, #prog_SA1_data]; nCS removed ldmfd sp!, {r0-r3, pc} ; ; Internal ; strh r0, [r10, r1] ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Remote flash memory read routine ; Byte data into R0, address in R1 flash_r_byte stmfd sp!, {r1-r3, lr} ; ldr r3, SLit_Spartan_base ; Point at PIO mov r0, #&3B ; Control inactive strb r0, [r3, #prog_SA0_data]; mov r0, #&FF ; Data bus to input strb r0, [r3, #prog_SB0_ctrl]; Low byte strb r0, [r3, #prog_VS0_ctrl]; High byte mov r2, #8 ; Reverse in bytes mov r0, r1, lsr #1 ; A0 is not interesting bl bit_rev ; A[8:1] strb r0, [r3, #prog_SB1_data]; mov r0, r1, lsr #9 ; bl bit_rev ; A[16:9] strb r0, [r3, #prog_VS1_data] mov r0, r1, lsr #17 ; bl bit_rev ; A[21:17] tst r1, #1 ; Odd or even byte? and r0, r0, #&F8 ; Ensure upper bits clear orr r1, r0, #&01 ; Don't pulse reset strb r1, [r3, #prog_SA1_data]; nCS asserted mov r2, #&1B ; Assert nOE strb r2, [r3, #prog_SA0_data]; ldreqb r0, [r3, #prog_SB0_data]; Even byte ldrneb r0, [r3, #prog_VS0_data]; or odd byte mov r2, #&3B ; Remove nOE strb r2, [r3, #prog_SA0_data]; orr r1, r1, #&02 ; nCS strb r1, [r3, #prog_SA1_data]; nCS removed ldmfd sp!, {r1-r3, pc} ; ; Internal ; ldrb r0, [r10, r1] ;------------------------------------------------------------------------------ ; ;flash_ID_call ldr r3, SLit_Spartan_base ; Point at PIO ; ; mov r2, #8 ; Reverse in bytes ; ; mov r0, r1, lsr #1 ; A0 is not interesting ; bl bit_rev ; A[8:1] ; strb r0, [r3, #prog_SB1_data]; ; ; mov r0, r1, lsr #9 ; ; bl bit_rev ; A[16:9] ; strb r0, [r3, #prog_VS1_data] ; ; mov r0, r1, lsr #17 ; ; bl bit_rev ; A[21:17] ; and r0, r0, #&F8 ; Ensure upper bits clear ; orr r0, r0, #&03 ; Don't pulse reset ; strb r0, [r3, #prog_SA1_data]; No nCS yet ; ; mov r2, #&FF ; Data bus to input ; strb r2, [r3, #prog_SB0_ctrl]; Low byte ; strb r2, [r3, #prog_VS0_ctrl]; High byte ; ; ldrb r2, [r3, #prog_SA1_data]; ; bic r2, r2, #&02 ; Assert nCS ; strb r2, [r3, #prog_SA1_data]; ; ; ldrb r2, [r3, #prog_SA0_data]; ; bic r2, r2, #&20 ; Assert nOE ; strb r2, [r3, #prog_SA0_data]; ; ; ldrb r1, [r3, #prog_SB0_data]; Return this value ; ; ldrb r2, [r3, #prog_SA0_data]; ; orr r2, r2, #&20 ; Remove nOE ; strb r2, [r3, #prog_SA0_data]; ; ; ldrb r2, [r3, #prog_SA1_data]; ; orr r2, r2, #&02 ; Remove nCS ; strb r2, [r3, #prog_SA1_data]; ; ; mov pc, lr ; ; ;------------------------------------------------------------------------------ bit_rev stmfd sp!, {r1, r2} ; Bit reverse lower R2 bits in R0 mov r1, #0 ; Accumulator bit_rev1 movs r0, r0, lsr #1 ; LSB into carry adc r1, r1, r1 ; Shift left from carry subs r2, r2, #1 ; bhi bit_rev1 ; mov r0, r1 ; ldmfd sp!, {r1, r2} ; mov pc, lr ; ;------------------------------------------------------------------------------ ; Temporary routine for initialising Spartan device (as 6 PIOs) for ; remote flash ROM reading, writing and erasing XPIO_init stmfd sp!, {r0, r1} ; ldr r1, SLit_Spartan_base ; Spartan address mov r0, #&FF ; strb r0, [r1, #prog_SB0_ctrl]; Data 0..7 strb r0, [r1, #prog_VS0_ctrl]; Data 8..15 mov r0, #&3B strb r0, [r1, #prog_SA0_data]; Address 0, nWR1, nRD, etc. mov r0, #&43 strb r0, [r1, #prog_SA0_ctrl]; Address 0, nWR1, nRD, etc. mov r0, #&00 strb r0, [r1, #prog_SB1_data]; Address 1..8 strb r0, [r1, #prog_SB1_ctrl]; strb r0, [r1, #prog_VS1_data]; Address 9..16 strb r0, [r1, #prog_VS1_ctrl]; mov r0, #&07 ; strb r0, [r1, #prog_SA1_data]; Address 17:21, nCS, nReset mov r0, #&04 ; strb r0, [r1, #prog_SA1_ctrl] ldmfd sp!, {r0, r1} ; mov pc, lr ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SLit_Spartan_base DCD SPARTAN_base SLit_PIO_base DCD PIO_base ;------------------------------------------------------------------------------ END