diff options
Diffstat (limited to 'target/linux/at91/image/dfboot/src/.svn/text-base')
22 files changed, 4384 insertions, 0 deletions
diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/Makefile.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/Makefile.svn-base new file mode 100644 index 0000000..ff92e0d --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/Makefile.svn-base @@ -0,0 +1,94 @@ +# Makefile for DataFlashBoot.bin +# Must use toolchain with H/W FLoating Point + +BASENAME=dfboot +BINNAME=$(BASENAME).bin +OUTNAME=$(BASENAME).out +LSSNAME=$(BASENAME).lss +MAPNAME=$(BASENAME).map + +BASENAME2=dfbptest +BINNAME2=$(BASENAME2).bin +OUTNAME2=$(BASENAME2).out +LSSNAME2=$(BASENAME2).lss +MAPNAME2=$(BASENAME2).map + +INCPATH=include + +CFLAGS_LOCAL=-Os -Wall -I$(INCPATH) +BUILD=$(CC) $(CFLAGS) $(CFLAGS_LOCAL) + +LDFLAGS+=-T elf32-littlearm.lds -Ttext 0 +LINK=$(LD) $(LDFLAGS) + +OBJS=objs/cstartup_ram.o objs/at45.o objs/com.o objs/dataflash.o\ + objs/div0.o objs/init.o objs/main.o objs/asm_isr.o objs/asm_mci_isr.o\ + objs/mci_device.o objs/jump.o objs/_udivsi3.o objs/_umodsi3.o + +OBJS2=objs/cstartup_ram.o objs/at45.o objs/com.o objs/dataflash.o\ + objs/div0.o objs/init.o objs/ptmain.o objs/asm_isr.o objs/asm_mci_isr.o\ + objs/mci_device.o objs/jump.o objs/_udivsi3.o objs/_umodsi3.o + +I=config.h com.h dataflash.h embedded_services.h main.h stdio.h include/AT91RM9200.h include/lib_AT91RM9200.h + +all:clean $(BASENAME) $(BASENAME2) + +$(BASENAME): $(OBJS) + $(LINK) -n -o $(OUTNAME) $(OBJS) + $(OBJCOPY) $(OUTNAME) -O binary $(BINNAME) + $(OBJDUMP) -h -s $(OUTNAME) > $(LSSNAME) + $(NM) -n $(OUTNAME) | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $(MAPNAME) + cp $(BINNAME) binary + +$(BASENAME2): $(OBJS2) + $(LINK) -n -o $(OUTNAME2) $(OBJS2) + $(OBJCOPY) $(OUTNAME2) -O binary $(BINNAME2) + $(OBJDUMP) -h -s $(OUTNAME2) > $(LSSNAME2) + $(NM) -n $(OUTNAME2) | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)' > $(MAPNAME2) + cp $(BINNAME2) binary + +# C objects here +objs/at45.o: at45.c $(I) + $(BUILD) -c -o objs/at45.o at45.c +objs/com.o: com.c $(I) + $(BUILD) -c -o objs/com.o com.c +objs/dataflash.o: dataflash.c $(I) + $(BUILD) -c -o objs/dataflash.o dataflash.c +objs/mci_device.o: mci_device.c $(I) + $(BUILD) -c -o objs/mci_device.o mci_device.c +objs/div0.o: div0.c $(I) + $(BUILD) -c -o objs/div0.o div0.c +objs/init.o: init.c $(I) + $(BUILD) -c -o objs/init.o init.c +objs/main.o: main.c $(I) + $(BUILD) -c -o objs/main.o main.c +objs/ptmain.o: main.c $(I) + $(BUILD) -c -D PRODTEST -o objs/ptmain.o main.c + +# ASM objects here +objs/asm_isr.o: asm_isr.S + $(BUILD) -c -o objs/asm_isr.o asm_isr.S +objs/asm_mci_isr.o: asm_mci_isr.S + $(BUILD) -c -o objs/asm_mci_isr.o asm_mci_isr.S +objs/cstartup_ram.o: cstartup_ram.S + $(BUILD) -c -o objs/cstartup_ram.o cstartup_ram.S +objs/jump.o: jump.S + $(BUILD) -c -o objs/jump.o jump.S +objs/_udivsi3.o: _udivsi3.S + $(BUILD) -c -o objs/_udivsi3.o _udivsi3.S +objs/_umodsi3.o: _umodsi3.S + $(BUILD) -c -o objs/_umodsi3.o _umodsi3.S + +install: $(BINNAME) $(BINNAME2) + cp $(BINNAME) binary + cp $(BINNAME2) binary + +clean: + rm -f *~ + rm -f objs/* + rm -f *.out + rm -f *.bin + rm -f *.lss + rm -f *.map + rm -f .unpacked + mkdir -p objs diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/_udivsi3.S.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/_udivsi3.S.svn-base new file mode 100644 index 0000000..2cdcd48 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/_udivsi3.S.svn-base @@ -0,0 +1,77 @@ +/* # 1 "libgcc1.S" */ +@ libgcc1 routines for ARM cpu. +@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) +dividend .req r0 +divisor .req r1 +result .req r2 +curbit .req r3 +/* ip .req r12 */ +/* sp .req r13 */ +/* lr .req r14 */ +/* pc .req r15 */ + .text + .globl __udivsi3 + .type __udivsi3 ,function + .align 0 + __udivsi3 : + cmp divisor, #0 + beq Ldiv0 + mov curbit, #1 + mov result, #0 + cmp dividend, divisor + bcc Lgot_result +Loop1: + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. + cmp divisor, #0x10000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #4 + movcc curbit, curbit, lsl #4 + bcc Loop1 +Lbignum: + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. + cmp divisor, #0x80000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #1 + movcc curbit, curbit, lsl #1 + bcc Lbignum +Loop3: + @ Test for possible subtractions, and note which bits + @ are done in the result. On the final pass, this may subtract + @ too much from the dividend, but the result will be ok, since the + @ "bit" will have been shifted out at the bottom. + cmp dividend, divisor + subcs dividend, dividend, divisor + orrcs result, result, curbit + cmp dividend, divisor, lsr #1 + subcs dividend, dividend, divisor, lsr #1 + orrcs result, result, curbit, lsr #1 + cmp dividend, divisor, lsr #2 + subcs dividend, dividend, divisor, lsr #2 + orrcs result, result, curbit, lsr #2 + cmp dividend, divisor, lsr #3 + subcs dividend, dividend, divisor, lsr #3 + orrcs result, result, curbit, lsr #3 + cmp dividend, #0 @ Early termination? + movnes curbit, curbit, lsr #4 @ No, any more bits to do? + movne divisor, divisor, lsr #4 + bne Loop3 +Lgot_result: + mov r0, result + mov pc, lr +Ldiv0: + str lr, [sp, #-4]! + bl __div0 (PLT) + mov r0, #0 @ about as wrong as it could be + ldmia sp!, {pc} + .size __udivsi3 , . - __udivsi3 +/* # 235 "libgcc1.S" */ +/* # 320 "libgcc1.S" */ +/* # 421 "libgcc1.S" */ +/* # 433 "libgcc1.S" */ +/* # 456 "libgcc1.S" */ +/* # 500 "libgcc1.S" */ +/* # 580 "libgcc1.S" */ diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/_umodsi3.S.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/_umodsi3.S.svn-base new file mode 100644 index 0000000..e4aebe8 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/_umodsi3.S.svn-base @@ -0,0 +1,88 @@ +/* # 1 "libgcc1.S" */ +@ libgcc1 routines for ARM cpu. +@ Division routines, written by Richard Earnshaw, (rearnsha@armltd.co.uk) +/* # 145 "libgcc1.S" */ +dividend .req r0 +divisor .req r1 +overdone .req r2 +curbit .req r3 +/* ip .req r12 */ +/* sp .req r13 */ +/* lr .req r14 */ +/* pc .req r15 */ + .text + .globl __umodsi3 + .type __umodsi3 ,function + .align 0 + __umodsi3 : + cmp divisor, #0 + beq Ldiv0 + mov curbit, #1 + cmp dividend, divisor + movcc pc, lr +Loop1: + @ Unless the divisor is very big, shift it up in multiples of + @ four bits, since this is the amount of unwinding in the main + @ division loop. Continue shifting until the divisor is + @ larger than the dividend. + cmp divisor, #0x10000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #4 + movcc curbit, curbit, lsl #4 + bcc Loop1 +Lbignum: + @ For very big divisors, we must shift it a bit at a time, or + @ we will be in danger of overflowing. + cmp divisor, #0x80000000 + cmpcc divisor, dividend + movcc divisor, divisor, lsl #1 + movcc curbit, curbit, lsl #1 + bcc Lbignum +Loop3: + @ Test for possible subtractions. On the final pass, this may + @ subtract too much from the dividend, so keep track of which + @ subtractions are done, we can fix them up afterwards... + mov overdone, #0 + cmp dividend, divisor + subcs dividend, dividend, divisor + cmp dividend, divisor, lsr #1 + subcs dividend, dividend, divisor, lsr #1 + orrcs overdone, overdone, curbit, ror #1 + cmp dividend, divisor, lsr #2 + subcs dividend, dividend, divisor, lsr #2 + orrcs overdone, overdone, curbit, ror #2 + cmp dividend, divisor, lsr #3 + subcs dividend, dividend, divisor, lsr #3 + orrcs overdone, overdone, curbit, ror #3 + mov ip, curbit + cmp dividend, #0 @ Early termination? + movnes curbit, curbit, lsr #4 @ No, any more bits to do? + movne divisor, divisor, lsr #4 + bne Loop3 + @ Any subtractions that we should not have done will be recorded in + @ the top three bits of "overdone". Exactly which were not needed + @ are governed by the position of the bit, stored in ip. + @ If we terminated early, because dividend became zero, + @ then none of the below will match, since the bit in ip will not be + @ in the bottom nibble. + ands overdone, overdone, #0xe0000000 + moveq pc, lr @ No fixups needed + tst overdone, ip, ror #3 + addne dividend, dividend, divisor, lsr #3 + tst overdone, ip, ror #2 + addne dividend, dividend, divisor, lsr #2 + tst overdone, ip, ror #1 + addne dividend, dividend, divisor, lsr #1 + mov pc, lr +Ldiv0: + str lr, [sp, #-4]! + bl __div0 (PLT) + mov r0, #0 @ about as wrong as it could be + ldmia sp!, {pc} + .size __umodsi3 , . - __umodsi3 +/* # 320 "libgcc1.S" */ +/* # 421 "libgcc1.S" */ +/* # 433 "libgcc1.S" */ +/* # 456 "libgcc1.S" */ +/* # 500 "libgcc1.S" */ +/* # 580 "libgcc1.S" */ diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/asm_isr.S.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/asm_isr.S.svn-base new file mode 100644 index 0000000..8d1d52e --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/asm_isr.S.svn-base @@ -0,0 +1,75 @@ +#include "AT91RM9200_inc.h" + +#define ARM_MODE_USER 0x10 +#define ARM_MODE_FIQ 0x11 +#define ARM_MODE_IRQ 0x12 +#define ARM_MODE_SVC 0x13 +#define ARM_MODE_ABORT 0x17 +#define ARM_MODE_UNDEF 0x1B +#define ARM_MODE_SYS 0x1F + +#define I_BIT 0x80 +#define F_BIT 0x40 +#define T_BIT 0x20 + + +/* ----------------------------------------------------------------------------- + AT91F_ASM_SPI_Handler + --------------------- + Handler called by the AIC + + Save context + Call C handler + Restore context + ----------------------------------------------------------------------------- */ + +.global AT91F_ST_ASM_HANDLER + +AT91F_ST_ASM_HANDLER: +/* Adjust and save LR_irq in IRQ stack */ + sub r14, r14, #4 + stmfd sp!, {r14} + +/* Write in the IVR to support Protect Mode + No effect in Normal Mode + De-assert the NIRQ and clear the source in Protect Mode */ + ldr r14, =AT91C_BASE_AIC + str r14, [r14, #AIC_IVR] + +/* Save SPSR and r0 in IRQ stack */ + mrs r14, SPSR + stmfd sp!, {r0, r14} + +/* Enable Interrupt and Switch in SYS Mode */ + mrs r0, CPSR + bic r0, r0, #I_BIT + orr r0, r0, #ARM_MODE_SYS + msr CPSR_c, r0 + +/* Save scratch/used registers and LR in User Stack */ + stmfd sp!, { r1-r3, r12, r14} + + ldr r1, =AT91F_ST_HANDLER + mov r14, pc + bx r1 + +/* Restore scratch/used registers and LR from User Stack */ + ldmia sp!, { r1-r3, r12, r14} + +/* Disable Interrupt and switch back in IRQ mode */ + mrs r0, CPSR + bic r0, r0, #ARM_MODE_SYS + orr r0, r0, #I_BIT | ARM_MODE_IRQ + msr CPSR_c, r0 + +/* Mark the End of Interrupt on the AIC */ + ldr r0, =AT91C_BASE_AIC + str r0, [r0, #AIC_EOICR] + +/* Restore SPSR_irq and r0 from IRQ stack */ + ldmia sp!, {r0, r14} + msr SPSR_cxsf, r14 + +/* Restore adjusted LR_irq from IRQ stack directly in the PC */ + ldmia sp!, {pc}^ + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/asm_mci_isr.S.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/asm_mci_isr.S.svn-base new file mode 100644 index 0000000..0f66fc0 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/asm_mci_isr.S.svn-base @@ -0,0 +1,75 @@ +#include <AT91RM9200_inc.h> + +#define ARM_MODE_USER 0x10 +#define ARM_MODE_FIQ 0x11 +#define ARM_MODE_IRQ 0x12 +#define ARM_MODE_SVC 0x13 +#define ARM_MODE_ABORT 0x17 +#define ARM_MODE_UNDEF 0x1B +#define ARM_MODE_SYS 0x1F + +#define I_BIT 0x80 +#define F_BIT 0x40 +#define T_BIT 0x20 + + +/* ----------------------------------------------------------------------------- + AT91F_ASM_MCI_Handler + --------------------- + Handler called by the AIC + + Save context + Call C handler + Restore context + ----------------------------------------------------------------------------- */ + +.global AT91F_ASM_MCI_Handler + +AT91F_ASM_MCI_Handler: +/* Adjust and save LR_irq in IRQ stack */ + sub r14, r14, #4 + stmfd sp!, {r14} + +/* Write in the IVR to support Protect Mode + No effect in Normal Mode + De-assert the NIRQ and clear the source in Protect Mode */ + ldr r14, =AT91C_BASE_AIC + str r14, [r14, #AIC_IVR] + +/* Save SPSR and r0 in IRQ stack */ + mrs r14, SPSR + stmfd sp!, {r0, r14} + +/* Enable Interrupt and Switch in SYS Mode */ + mrs r0, CPSR + bic r0, r0, #I_BIT + orr r0, r0, #ARM_MODE_SYS + msr CPSR_c, r0 + +/* Save scratch/used registers and LR in User Stack */ + stmfd sp!, { r1-r3, r12, r14} + + ldr r1, =AT91F_MCI_Handler + mov r14, pc + bx r1 + +/* Restore scratch/used registers and LR from User Stack */ + ldmia sp!, { r1-r3, r12, r14} + +/* Disable Interrupt and switch back in IRQ mode */ + mrs r0, CPSR + bic r0, r0, #ARM_MODE_SYS + orr r0, r0, #I_BIT | ARM_MODE_IRQ + msr CPSR_c, r0 + +/* Mark the End of Interrupt on the AIC */ + ldr r0, =AT91C_BASE_AIC + str r0, [r0, #AIC_EOICR] + +/* Restore SPSR_irq and r0 from IRQ stack */ + ldmia sp!, {r0, r14} + msr SPSR_cxsf, r14 + +/* Restore adjusted LR_irq from IRQ stack directly in the PC */ + ldmia sp!, {pc}^ + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/at45.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/at45.c.svn-base new file mode 100644 index 0000000..8830d7e --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/at45.c.svn-base @@ -0,0 +1,595 @@ +/*---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support - ROUSSET - + *---------------------------------------------------------------------------- + * The software is delivered "AS IS" without warranty or condition of any + * kind, either express, implied or statutory. This includes without + * limitation any warranty or condition with respect to merchantability or + * fitness for any particular purpose, or against the infringements of + * intellectual property rights of others. + *---------------------------------------------------------------------------- + * File Name : at45c.h + * Object : + * + * 1.0 10/12/03 HIi : Creation. + * 1.01 03/05/04 HIi : Bug Fix in AT91F_DataFlashWaitReady() Function. + *---------------------------------------------------------------------------- + */ +#include "config.h" +#include "stdio.h" +#include "AT91RM9200.h" +#include "lib_AT91RM9200.h" +#include "dataflash.h" +#include "main.h" + + +/*----------------------------------------------------------------------------*/ +/* \fn AT91F_SpiInit */ +/* \brief SPI Low level Init */ +/*----------------------------------------------------------------------------*/ +void AT91F_SpiInit(void) { + /* Configure PIOs */ + AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | + AT91C_PA1_MOSI | AT91C_PA5_NPCS2 | + AT91C_PA6_NPCS3 | AT91C_PA0_MISO | + AT91C_PA2_SPCK; + AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | + AT91C_PA1_MOSI | AT91C_PA5_NPCS2 | + AT91C_PA6_NPCS3 | AT91C_PA0_MISO | + AT91C_PA2_SPCK; + /* Enable CLock */ + AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI; + + /* Reset the SPI */ + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST; + + /* Configure SPI in Master Mode with No CS selected !!! */ + AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS; + + /* Configure CS0 and CS3 */ + *(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | + (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | + ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); + *(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | + (AT91C_SPI_DLYBCT & DATAFLASH_TCHS) | + ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8); +} + + +/*----------------------------------------------------------------------------*/ +/* \fn AT91F_SpiEnable */ +/* \brief Enable SPI chip select */ +/*----------------------------------------------------------------------------*/ +static void AT91F_SpiEnable(int cs) { + switch(cs) { + case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */ + AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; + AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH << 16) & AT91C_SPI_PCS); + break; + case 3: /* Configure SPI CS3 for Serial DataFlash Card */ + /* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */ + AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7; /* Set in PIO mode */ + AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7; /* Configure in output */ + /* Clear Output */ + AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7; + /* Configure PCS */ + AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF; + AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS); + break; + } + + /* SPI_Enable */ + AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; +} + +/*----------------------------------------------------------------------------*/ +/* \fn AT91F_SpiWrite */ +/* \brief Set the PDC registers for a transfert */ +/*----------------------------------------------------------------------------*/ +static unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc) +{ + unsigned int timeout; + + AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; + + /* Initialize the Transmit and Receive Pointer */ + AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ; + AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ; + + /* Intialize the Transmit and Receive Counters */ + AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size; + AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size; + + if ( pDesc->tx_data_size != 0 ) { + /* Initialize the Next Transmit and Next Receive Pointer */ + AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ; + AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ; + + /* Intialize the Next Transmit and Next Receive Counters */ + AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ; + AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ; + } + + /* ARM simple, non interrupt dependent timer */ + timeout = 0; + + AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN; + while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF)); + + AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS; + + if (timeout >= AT91C_DATAFLASH_TIMEOUT){ + return AT91C_DATAFLASH_ERROR; + } + + return AT91C_DATAFLASH_OK; +} + + +/*----------------------------------------------------------------------*/ +/* \fn AT91F_DataFlashSendCommand */ +/* \brief Generic function to send a command to the dataflash */ +/*----------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_DataFlashSendCommand( + AT91PS_DataFlash pDataFlash, + unsigned char OpCode, + unsigned int CmdSize, + unsigned int DataflashAddress) +{ + unsigned int adr; + + /* process the address to obtain page address and byte address */ + adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) + << pDataFlash->pDevice->page_offset) + + (DataflashAddress % (pDataFlash->pDevice->pages_size)); + + /* fill the command buffer */ + pDataFlash->pDataFlashDesc->command[0] = OpCode; + if (pDataFlash->pDevice->pages_number >= 16384) + { + pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24); + pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16); + pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8); + pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF); + } + else + { + pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16); + pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8); + pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ; + pDataFlash->pDataFlashDesc->command[4] = 0; + } + pDataFlash->pDataFlashDesc->command[5] = 0; + pDataFlash->pDataFlashDesc->command[6] = 0; + pDataFlash->pDataFlashDesc->command[7] = 0; + + /* Initialize the SpiData structure for the spi write fuction */ + pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ; + pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize ; + pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ; + pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize ; + + return AT91F_SpiWrite(pDataFlash->pDataFlashDesc); +} + + +/*----------------------------------------------------------------------*/ +/* \fn AT91F_DataFlashGetStatus */ +/* \brief Read the status register of the dataflash */ +/*----------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc) +{ + AT91S_DataFlashStatus status; + + /* first send the read status command (D7H) */ + pDesc->command[0] = DB_STATUS; + pDesc->command[1] = 0; + + pDesc->DataFlash_state = GET_STATUS; + pDesc->tx_data_size = 0 ; /* Transmit the command and receive response */ + pDesc->tx_cmd_pt = pDesc->command ; + pDesc->rx_cmd_pt = pDesc->command ; + pDesc->rx_cmd_size = 2 ; + pDesc->tx_cmd_size = 2 ; + status = AT91F_SpiWrite (pDesc); + + pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1); + return status; +} + +/*----------------------------------------------------------------------------- + * Function Name : AT91F_DataFlashWaitReady + * Object : wait for dataflash ready (bit7 of the status register == 1) + * Input Parameters : DataFlash Service and timeout + * Return value : DataFlash status "ready or not" + *----------------------------------------------------------------------------- + */ +static AT91S_DataFlashStatus AT91F_DataFlashWaitReady( + AT91PS_DataflashDesc pDataFlashDesc, + unsigned int timeout) +{ + pDataFlashDesc->DataFlash_state = IDLE; + do { + AT91F_DataFlashGetStatus(pDataFlashDesc); + timeout--; + } + while(((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0)); + + if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) + return AT91C_DATAFLASH_ERROR; + + return AT91C_DATAFLASH_OK; +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_DataFlashContinuousRead */ +/* Object : Continuous stream Read */ +/* Input Parameters : DataFlash Service */ +/* : <src> = dataflash address */ +/* : <*dataBuffer> = data buffer pointer */ +/* : <sizeToRead> = data buffer size */ +/* Return value : State of the dataflash */ +/*------------------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_DataFlashContinuousRead( + AT91PS_DataFlash pDataFlash, + int src, + unsigned char *dataBuffer, + int sizeToRead ) +{ + AT91S_DataFlashStatus status; + /* Test the size to read in the device */ + if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number))) + return AT91C_DATAFLASH_MEMORY_OVERFLOW; + + pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer; + pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead; + pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer; + pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead; + + status = AT91F_DataFlashSendCommand(pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src); + /* Send the command to the dataflash */ + return(status); +} + + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_MainMemoryToBufferTransfer */ +/* Object : Read a page in the SRAM Buffer 1 or 2 */ +/* Input Parameters : DataFlash Service */ +/* : Page concerned */ +/* : */ +/* Return value : State of the dataflash */ +/*------------------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfer( + AT91PS_DataFlash pDataFlash, + unsigned char BufferCommand, + unsigned int page) +{ + int cmdsize; + /* Test if the buffer command is legal */ + if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF)) + return AT91C_DATAFLASH_BAD_COMMAND; + + /* no data to transmit or receive */ + pDataFlash->pDataFlashDesc->tx_data_size = 0; + cmdsize = 4; + if (pDataFlash->pDevice->pages_number >= 16384) + cmdsize = 5; + return(AT91F_DataFlashSendCommand(pDataFlash, BufferCommand, cmdsize, + page*pDataFlash->pDevice->pages_size)); +} + + + +/*----------------------------------------------------------------------------- */ +/* Function Name : AT91F_DataFlashWriteBuffer */ +/* Object : Write data to the internal sram buffer 1 or 2 */ +/* Input Parameters : DataFlash Service */ +/* : <BufferCommand> = command to write buffer1 or buffer2 */ +/* : <*dataBuffer> = data buffer to write */ +/* : <bufferAddress> = address in the internal buffer */ +/* : <SizeToWrite> = data buffer size */ +/* Return value : State of the dataflash */ +/*------------------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer( + AT91PS_DataFlash pDataFlash, + unsigned char BufferCommand, + unsigned char *dataBuffer, + unsigned int bufferAddress, + int SizeToWrite ) +{ + int cmdsize; + /* Test if the buffer command is legal */ + if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE)) + return AT91C_DATAFLASH_BAD_COMMAND; + + /* buffer address must be lower than page size */ + if (bufferAddress > pDataFlash->pDevice->pages_size) + return AT91C_DATAFLASH_BAD_ADDRESS; + + /* Send first Write Command */ + pDataFlash->pDataFlashDesc->command[0] = BufferCommand; + pDataFlash->pDataFlashDesc->command[1] = 0; + if (pDataFlash->pDevice->pages_number >= 16384) + { + pDataFlash->pDataFlashDesc->command[2] = 0; + pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ; + pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ; + cmdsize = 5; + } + else + { + pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ; + pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ; + pDataFlash->pDataFlashDesc->command[4] = 0; + cmdsize = 4; + } + + pDataFlash->pDataFlashDesc->tx_cmd_pt = pDataFlash->pDataFlashDesc->command ; + pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ; + pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ; + pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ; + + pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ; + pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ; + pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite ; + pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ; + + return AT91F_SpiWrite(pDataFlash->pDataFlashDesc); +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_PageErase */ +/* Object : Read a page in the SRAM Buffer 1 or 2 */ +/* Input Parameters : DataFlash Service */ +/* : Page concerned */ +/* : */ +/* Return value : State of the dataflash */ +/*------------------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_PageErase( + AT91PS_DataFlash pDataFlash, + unsigned int page) +{ + int cmdsize; + /* Test if the buffer command is legal */ + /* no data to transmit or receive */ + pDataFlash->pDataFlashDesc->tx_data_size = 0; + + cmdsize = 4; + if (pDataFlash->pDevice->pages_number >= 16384) + cmdsize = 5; + return(AT91F_DataFlashSendCommand(pDataFlash, DB_PAGE_ERASE, cmdsize, + page*pDataFlash->pDevice->pages_size)); +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_WriteBufferToMain */ +/* Object : Write buffer to the main memory */ +/* Input Parameters : DataFlash Service */ +/* : <BufferCommand> = command to send to buf1 or buf2 */ +/* : <dest> = main memory address */ +/* Return value : State of the dataflash */ +/*------------------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_WriteBufferToMain ( + AT91PS_DataFlash pDataFlash, + unsigned char BufferCommand, + unsigned int dest ) +{ + int cmdsize; + /* Test if the buffer command is correct */ + if ((BufferCommand != DB_BUF1_PAGE_PGM) && + (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) && + (BufferCommand != DB_BUF2_PAGE_PGM) && + (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) ) + return AT91C_DATAFLASH_BAD_COMMAND; + + /* no data to transmit or receive */ + pDataFlash->pDataFlashDesc->tx_data_size = 0; + + cmdsize = 4; + if (pDataFlash->pDevice->pages_number >= 16384) + cmdsize = 5; + /* Send the command to the dataflash */ + return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest)); +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_PartialPageWrite */ +/* Object : Erase partially a page */ +/* Input Parameters : <page> = page number */ +/* : <AdrInpage> = adr to begin the fading */ +/* : <length> = Number of bytes to erase */ +/*------------------------------------------------------------------------------*/ +static AT91S_DataFlashStatus AT91F_PartialPageWrite ( + AT91PS_DataFlash pDataFlash, + unsigned char *src, + unsigned int dest, + unsigned int size) +{ + unsigned int page; + unsigned int AdrInPage; + + page = dest / (pDataFlash->pDevice->pages_size); + AdrInPage = dest % (pDataFlash->pDevice->pages_size); + + /* Read the contents of the page in the Sram Buffer */ + AT91F_MainMemoryToBufferTransfer(pDataFlash, DB_PAGE_2_BUF1_TRF, page); + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + + /*Update the SRAM buffer */ + AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size); + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + + /* Erase page if a 128 Mbits device */ + if (pDataFlash->pDevice->pages_number >= 16384) + { + AT91F_PageErase(pDataFlash, page); + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + } + + /* Rewrite the modified Sram Buffer in the main memory */ + return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, + (page*pDataFlash->pDevice->pages_size))); +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_DataFlashWrite */ +/* Object : */ +/* Input Parameters : <*src> = Source buffer */ +/* : <dest> = dataflash adress */ +/* : <size> = data buffer size */ +/*------------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashWrite( + AT91PS_DataFlash pDataFlash, + unsigned char *src, + int dest, + int size ) +{ + unsigned int length; + unsigned int page; + unsigned int status; + + AT91F_SpiEnable(pDataFlash->pDevice->cs); + + if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number))) + return AT91C_DATAFLASH_MEMORY_OVERFLOW; + + /* If destination does not fit a page start address */ + if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0 ) { + length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size))); + + if (size < length) + length = size; + + if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length)) + return AT91C_DATAFLASH_ERROR; + + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + + /* Update size, source and destination pointers */ + size -= length; + dest += length; + src += length; + } + + while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) + { + /* program dataflash page */ + page = (unsigned int)dest / (pDataFlash->pDevice->pages_size); + + status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, + 0, pDataFlash->pDevice->pages_size); + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + + status = AT91F_PageErase(pDataFlash, page); + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + if (!status) + return AT91C_DATAFLASH_ERROR; + + status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest); + if(!status) + return AT91C_DATAFLASH_ERROR; + + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + + /* Update size, source and destination pointers */ + size -= pDataFlash->pDevice->pages_size ; + dest += pDataFlash->pDevice->pages_size ; + src += pDataFlash->pDevice->pages_size ; + } + + /* If still some bytes to read */ + if ( size > 0 ) { + /* program dataflash page */ + if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) ) + return AT91C_DATAFLASH_ERROR; + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + } + return AT91C_DATAFLASH_OK; +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_DataFlashRead */ +/* Object : Read a block in dataflash */ +/* Input Parameters : */ +/* Return value : */ +/*------------------------------------------------------------------------------*/ +int AT91F_DataFlashRead( + AT91PS_DataFlash pDataFlash, + unsigned long addr, + unsigned long size, + char *buffer) +{ + unsigned long SizeToRead; + + AT91F_SpiEnable(pDataFlash->pDevice->cs); + + if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK) + return -1; + + while (size) + { + SizeToRead = (size < 0x8000)? size:0x8000; + + if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT) + != AT91C_DATAFLASH_OK) + return -1; + + if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (unsigned char *)buffer, + SizeToRead) != AT91C_DATAFLASH_OK) + return -1; + + size -= SizeToRead; + addr += SizeToRead; + buffer += SizeToRead; + } + + return AT91C_DATAFLASH_OK; +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_DataflashProbe */ +/* Object : */ +/* Input Parameters : */ +/* Return value : Dataflash status register */ +/*------------------------------------------------------------------------------*/ +int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc) +{ + AT91F_SpiEnable(cs); + AT91F_DataFlashGetStatus(pDesc); + return ((pDesc->command[1] == 0xFF)? 0: (pDesc->command[1] & 0x3C)); +} + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_DataFlashErase */ +/* Object : */ +/* Input Parameters : <*pDataFlash> = Device info */ +/*------------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashErase(AT91PS_DataFlash pDataFlash) +{ + unsigned int page; + unsigned int status; + + AT91F_SpiEnable(pDataFlash->pDevice->cs); + + for(page=0; page < pDataFlash->pDevice->pages_number; page++) + { + /* Erase dataflash page */ + if ((page & 0x00FF) == 0) + printf("\rERA %d/%d", page, pDataFlash->pDevice->pages_number); + status = AT91F_PageErase(pDataFlash, page); + AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_DATAFLASH_TIMEOUT); + if (!status) + return AT91C_DATAFLASH_ERROR; + } + + return AT91C_DATAFLASH_OK; +} + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/com.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/com.c.svn-base new file mode 100644 index 0000000..aacfb55 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/com.c.svn-base @@ -0,0 +1,368 @@ +/*---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support - ROUSSET - + *---------------------------------------------------------------------------- + * The software is delivered "AS IS" without warranty or condition of any + * kind, either express, implied or statutory. This includes without + * limitation any warranty or condition with respect to merchantability or + * fitness for any particular purpose, or against the infringements of + * intellectual property rights of others. + *---------------------------------------------------------------------------- + * File Name : com.c + * Object : + * Creation : HIi 03/27/2003 + * + *---------------------------------------------------------------------------- + */ +#include "AT91RM9200.h" +#include "lib_AT91RM9200.h" +#include "config.h" +#include "com.h" +#include "stdio.h" + +static char erase_seq[] = "\b \b"; /* erase sequence */ + +#define MAX_UARTS 1 + +//unsigned int usa[2] = {(unsigned int)AT91C_BASE_DBGU, (unsigned int)AT91C_ALTERNATE_USART}; +unsigned int usa[1] = {(unsigned int)AT91C_BASE_DBGU}; +unsigned int us; +int port_detected; + +void at91_init_uarts(void) +{ + int i; + + port_detected = 0; + AT91F_DBGU_CfgPIO(); + AT91F_US0_CfgPIO(); + AT91F_US0_CfgPMC(); + + for(i=0; i<MAX_UARTS; i++) { + us = usa[i]; + AT91F_US_ResetRx((AT91PS_USART)us); + AT91F_US_ResetTx((AT91PS_USART)us); + + // Configure DBGU + AT91F_US_Configure( + (AT91PS_USART)us, // DBGU base address + AT91C_MASTER_CLOCK, // 60 MHz + AT91C_US_ASYNC_MODE, // mode Register to be programmed + 115200, // baudrate to be programmed + 0 // timeguard to be programmed + ); + + // Enable Transmitter + AT91F_US_EnableTx((AT91PS_USART)us); + // Enable Receiver + AT91F_US_EnableRx((AT91PS_USART)us); + } + us = usa[0]; +} + +int at91_serial_putc(int ch) +{ + if (ch == '\n') + at91_serial_putc('\r'); + while (!AT91F_US_TxReady((AT91PS_USART)us)); + AT91F_US_PutChar((AT91PS_USART)us, (char)ch); + return ch; +} + +/* This getc is modified to be able work on more than one port. On certain + * boards (i.e. Figment Designs VersaLink), the debug port is not available + * once the unit is in it's enclosure, so, if one needs to get into dfboot + * for any reason it is impossible. With this getc, it scans between the debug + * port and another port and once it receives a character, it sets that port + * as the debug port. */ +int at91_serial_getc() +{ + while(1) { +#if 0 + if (!port_detected) { + if (us == usa[0]) { + us = usa[1]; + } + else { + us = usa[0]; + } + } +#endif + if(AT91F_US_RxReady((AT91PS_USART)us)) { +#if 0 + port_detected = 1; +#endif + return((int)AT91F_US_GetChar((AT91PS_USART)us)); + } + } +} + +/*----------------------------------------------------------------------------- + * Function Name : AT91F_ReadLine() + * Object : + * Input Parameters : + * Return value : + *----------------------------------------------------------------------------- + */ +int AT91F_ReadLine (const char *const prompt, char *console_buffer) +{ + char *p = console_buffer; + int n = 0; /* buffer index */ + int plen = strlen (prompt); /* prompt length */ + int col; /* output column cnt */ + char c; + + /* print prompt */ + if (prompt) + printf(prompt); + col = plen; + + for (;;) { + c = getc(); + + switch (c) { + case '\r': /* Enter */ + case '\n': + *p = '\0'; + puts ("\n"); + return (p - console_buffer); + + case 0x03: /* ^C - break */ + console_buffer[0] = '\0'; /* discard input */ + return (-1); + + case 0x08: /* ^H - backspace */ + case 0x7F: /* DEL - backspace */ + if (n) { + --p; + printf(erase_seq); + col--; + n--; + } + continue; + + default: + /* + * Must be a normal character then + */ + if (n < (AT91C_CB_SIZE -2)) + { + ++col; /* echo input */ + putc(c); + *p++ = c; + ++n; + } + else + { /* Buffer full */ + putc('\a'); + } + } + } +} + + +/*----------------------------------------------------------------------------- + * Function Name : AT91F_WaitKeyPressed() + * Object : + * Input Parameters : + * Return value : + *----------------------------------------------------------------------------- + */ +void AT91F_WaitKeyPressed(void) +{ + int c; + puts("KEY"); + c = getc(); + putc('\n'); +} + +int puts(const char *str) +{ + while(*str != 0) { + at91_serial_putc(*str); + str++; + } + return 1; +} + +int putc(int c) +{ + return at91_serial_putc(c); +} + +int putchar(c) +{ + return putc(c); +} + +int getc() +{ + return at91_serial_getc(); +} + +int strlen(const char *str) +{ + int len = 0; + + if(str == (char *)0) + return 0; + + while(*str++ != 0) + len++; + + return len; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define LEFT 4 /* left justified */ +#define LARGE 8 /* use 'ABCDEF' instead of 'abcdef' */ + +#define do_div(n,base) ({ \ + int __res; \ + __res = ((unsigned) n) % (unsigned) base; \ + n = ((unsigned) n) / (unsigned) base; \ + __res; \ +}) + +static int number(int num, int base, int size, + int precision, int type) +{ + char c, sign, tmp[66]; + const char *digits="0123456789ABCDEF"; + int i; + + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 16) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + + if(type & SIGN && num < 0) + { + sign = '-'; + num = -num; + size--; + } + + i = 0; + if(num == 0) + tmp[i++] = digits[0]; + else while(num != 0) + tmp[i++] = digits[do_div(num, base)]; + + if(i > precision) + precision = i; + size -= precision; + + if(!(type&(ZEROPAD+LEFT))) + while(size-->0) + putc(' '); + + if(sign) + putc(sign); + + if (!(type & LEFT)) + while (size-- > 0) + putc(c); + + while (i < precision--) + putc('0'); + + while (i-- > 0) + putc(tmp[i]); + + while (size-- > 0) + putc(' ');; + + return 1; +} + +int hvfprintf(const char *fmt, va_list va) +{ + char *s; + + do { + if(*fmt == '%') { + bool done = false; + + int type = 0; + int precision = 0; + + do { + fmt++; + switch(*fmt) { + case '0' : + if(!precision) + type |= ZEROPAD; + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + case '8' : + case '9' : + precision = precision * 10 + (*fmt - '0'); + break; + case '.' : + break; + case 's' : + s = va_arg(va, char *); + if(!s) + puts("<NULL>"); + else + puts(s); + done = true; + break; + case 'c' : + putc(va_arg(va, int)); + done = true; + break; + case 'd' : + number(va_arg(va, int), 10, 0, precision, type); + done = true; + break; + case 'x' : + case 'X' : + number(va_arg(va, int), 16, 0, precision, type); + done = true; + break; + case '%' : + putc(*fmt); + done = true; + default: + putc('%'); + putc(*fmt); + done = true; + break; + } + } while(!done); + } else if(*fmt == '\\') { + fmt++; + if(*fmt == 'r') { + putc('\r'); + } else if(*fmt == 'n') { + putc('\n'); + } + } else { + putc(*fmt); + } + fmt++; + } while(*fmt != 0); + + return 0; +} + +int printf(const char *fmt, ...) +{ + va_list ap; + int i; + + va_start(ap, fmt); + i = hvfprintf(fmt, ap); + va_end(ap); + + return i; +} diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/com.h.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/com.h.svn-base new file mode 100644 index 0000000..7af09e4 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/com.h.svn-base @@ -0,0 +1,28 @@ +/*---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support - ROUSSET - + *---------------------------------------------------------------------------- + * The software is delivered "AS IS" without warranty or condition of any + * kind, either express, implied or statutory. This includes without + * limitation any warranty or condition with respect to merchantability or + * fitness for any particular purpose, or against the infringements of + * intellectual property rights of others. + *---------------------------------------------------------------------------- + * File Name : com.h + * Object : + * + * 1.0 27/03/03 HIi : Creation + *---------------------------------------------------------------------------- + */ +#ifndef com_h +#define com_h + +#define AT91C_CB_SIZE 20 /* size of the console buffer */ + +/* Escape sequences */ +#define ESC \033 + +extern int AT91F_ReadLine (const char *const prompt, char *console_buffer); +extern void AT91F_WaitKeyPressed(void); + +#endif + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/config.h.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/config.h.svn-base new file mode 100644 index 0000000..3be8d49 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/config.h.svn-base @@ -0,0 +1,17 @@ + +#ifndef _CONFIG_H +#define _CONFIG_H + +//#define PAGESZ_1056 1 +#undef PAGESZ_1056 +#define SPI_LOW_SPEED 1 +#define AT91C_DELAY_TO_BOOT 1500 + +#define CRC_RETRIES 0x100 + +#define AT91C_MASTER_CLOCK 59904000 +#define AT91C_BAUD_RATE 115200 + +#define AT91C_ALTERNATE_USART AT91C_BASE_US0 + +#endif diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/cstartup_ram.S.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/cstartup_ram.S.svn-base new file mode 100644 index 0000000..2239000 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/cstartup_ram.S.svn-base @@ -0,0 +1,144 @@ +#include "AT91RM9200_inc.h" + +/*--------------------------- +ARM Core Mode and Status Bits +---------------------------*/ +.section start + .text + +#define ARM_MODE_USER 0x10 +#define ARM_MODE_FIQ 0x11 +#define ARM_MODE_IRQ 0x12 +#define ARM_MODE_SVC 0x13 +#define ARM_MODE_ABORT 0x17 +#define ARM_MODE_UNDEF 0x1B +#define ARM_MODE_SYS 0x1F + +#define I_BIT 0x80 +#define F_BIT 0x40 +#define T_BIT 0x20 + +/*---------------------------------------------------------------------------- + Area Definition +---------------- + Must be defined as function to put first in the code as it must be mapped + at offset 0 of the flash EBI_CSR0, ie. at address 0 before remap. +_---------------------------------------------------------------------------*/ + + .align 4 + .globl _start +_start: + +/*---------------------------------------------------------------------------- + Exception vectors ( before Remap ) +------------------------------------ + These vectors are read at address 0. + They absolutely requires to be in relative addresssing mode in order to + guarantee a valid jump. For the moment, all are just looping (what may be + dangerous in a final system). If an exception occurs before remap, this + would result in an infinite loop. +----------------------------------------------------------------------------*/ + b reset /* reset */ + b undefvec /* Undefined Instruction */ + b swivec /* Software Interrupt */ + b pabtvec /* Prefetch Abort */ + b dabtvec /* Data Abort */ + b rsvdvec /* reserved */ + b aicvec /* IRQ : read the AIC */ + b fiqvec /* FIQ */ + +undefvec: +swivec: +pabtvec: +dabtvec: +rsvdvec: +aicvec: +fiqvec: + b undefvec + +reset: + +#define MEMEND 0x00004000 + +/* ---------------------------- + Setup the stack for each mode +---------------------------- */ + +#define IRQ_STACK_SIZE 0x10 +#define FIQ_STACK_SIZE 0x04 +#define ABT_STACK_SIZE 0x04 +#define UND_STACK_SIZE 0x04 +#define SVC_STACK_SIZE 0x10 +#define USER_STACK_SIZE 0x400 + + ldr r0,= MEMEND + +/*- Set up Supervisor Mode and set Supervisor Mode Stack*/ + msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT + mov r13, r0 /* Init stack Undef*/ + sub r0, r0, #SVC_STACK_SIZE + +/*- Set up Interrupt Mode and set IRQ Mode Stack*/ + msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT + mov r13, r0 /* Init stack IRQ*/ + sub r0, r0, #IRQ_STACK_SIZE + +/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/ + msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT + mov r13, r0 /* Init stack FIQ*/ + sub r0, r0, #FIQ_STACK_SIZE + +/*- Set up Abort Mode and set Abort Mode Stack*/ + msr CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT + mov r13, r0 /* Init stack Abort*/ + sub r0, r0, #ABT_STACK_SIZE + +/*- Set up Undefined Instruction Mode and set Undef Mode Stack*/ + msr CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT + mov r13, r0 /* Init stack Undef*/ + sub r0, r0, #UND_STACK_SIZE + +/*- Set up user Mode and set System Mode Stack*/ + msr CPSR_c, #ARM_MODE_SYS | I_BIT | F_BIT + bic r0, r0, #3 /* Insure word alignement */ + mov sp, r0 /* Init stack System */ + + + ldr r0, = AT91F_LowLevelInit + mov lr, pc + bx r0 + +/*---------------------------------------- + Read/modify/write CP15 control register +----------------------------------------*/ + mrc p15, 0, r0, c1, c0,0 /* read cp15 control registre (cp15 r1) in r0 */ + ldr r3,= 0xC0000080 /* Reset bit :Little Endian end fast bus mode */ + ldr r4,= 0xC0001000 /* Set bit :Asynchronous clock mode, Not Fast Bus, I-Cache enable */ + bic r0, r0, r3 + orr r0, r0, r4 + mcr p15, 0, r0, c1, c0,0 /* write r0 in cp15 control registre (cp15 r1) */ + +/* Enable interrupts */ + msr CPSR_c, #ARM_MODE_SYS | F_BIT + +/*------------------------------------------------------------------------------ +- Branch on C code Main function (with interworking) +---------------------------------------------------- +- Branch must be performed by an interworking call as either an ARM or Thumb +- _start function must be supported. This makes the code not position- +- independent. A Branch with link would generate errors +----------------------------------------------------------------------------*/ + +/*- Branch to _start by interworking*/ + ldr r4, = main + mov lr, pc + bx r4 + +/*----------------------------------------------------------------------------- +- Loop for ever +--------------- +- End of application. Normally, never occur. +- Could jump on Software Reset ( B 0x0 ). +------------------------------------------------------------------------------*/ +End: + b End diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/dataflash.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/dataflash.c.svn-base new file mode 100644 index 0000000..5e54460 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/dataflash.c.svn-base @@ -0,0 +1,208 @@ +/*---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support - ROUSSET - + *---------------------------------------------------------------------------- + * The software is delivered "AS IS" without warranty or condition of any + * kind, either express, implied or statutory. This includes without + * limitation any warranty or condition with respect to merchantability or + * fitness for any particular purpose, or against the infringements of + * intellectual property rights of others. + *---------------------------------------------------------------------------- + * File Name : dataflash.c + * Object : High level functions for the dataflash + * Creation : HIi 10/10/2003 + *---------------------------------------------------------------------------- + */ +#include "config.h" +#include "stdio.h" +#include "dataflash.h" + + +AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS]; +static AT91S_DataFlash DataFlashInst; + +int cs[][CFG_MAX_DATAFLASH_BANKS] = { + {CFG_DATAFLASH_LOGIC_ADDR_CS0, 0}, /* Logical adress, CS */ + {CFG_DATAFLASH_LOGIC_ADDR_CS3, 3} +}; + +int AT91F_DataflashInit(void) +{ + int i; + int dfcode; + int Nb_device = 0; + + AT91F_SpiInit(); + + for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { + dataflash_info[i].id = 0; + dataflash_info[i].Device.pages_number = 0; + dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc); + + switch (dfcode) { + case AT45DB161: + dataflash_info[i].Device.pages_number = 4096; + dataflash_info[i].Device.pages_size = 528; + dataflash_info[i].Device.page_offset = 10; + dataflash_info[i].Device.byte_mask = 0x300; + dataflash_info[i].Device.cs = cs[i][1]; + dataflash_info[i].Desc.DataFlash_state = IDLE; + dataflash_info[i].logical_address = cs[i][0]; + dataflash_info[i].id = dfcode; + Nb_device++; + break; + + case AT45DB321: + dataflash_info[i].Device.pages_number = 8192; + dataflash_info[i].Device.pages_size = 528; + dataflash_info[i].Device.page_offset = 10; + dataflash_info[i].Device.byte_mask = 0x300; + dataflash_info[i].Device.cs = cs[i][1]; + dataflash_info[i].Desc.DataFlash_state = IDLE; + dataflash_info[i].logical_address = cs[i][0]; + dataflash_info[i].id = dfcode; + Nb_device++; + break; + + case AT45DB642: + dataflash_info[i].Device.pages_number = 8192; + dataflash_info[i].Device.pages_size = 1056; + dataflash_info[i].Device.page_offset = 11; + dataflash_info[i].Device.byte_mask = 0x700; + dataflash_info[i].Device.cs = cs[i][1]; + dataflash_info[i].Desc.DataFlash_state = IDLE; + dataflash_info[i].logical_address = cs[i][0]; + dataflash_info[i].id = dfcode; + Nb_device++; + break; + case AT45DB128: + dataflash_info[i].Device.pages_number = 16384; + dataflash_info[i].Device.pages_size = 1056; + dataflash_info[i].Device.page_offset = 11; + dataflash_info[i].Device.byte_mask = 0x700; + dataflash_info[i].Device.cs = cs[i][1]; + dataflash_info[i].Desc.DataFlash_state = IDLE; + dataflash_info[i].logical_address = cs[i][0]; + dataflash_info[i].id = dfcode; + Nb_device++; + break; + default: + break; + } + } + return (Nb_device); +} + + +void AT91F_DataflashPrintInfo(void) +{ + int i; + for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) { + if (dataflash_info[i].id != 0) { + printf ("DF:AT45DB"); + switch (dataflash_info[i].id) { + case AT45DB161: + printf ("161"); + break; + + case AT45DB321: + printf ("321"); + break; + + case AT45DB642: + printf ("642"); + break; + case AT45DB128: + printf ("128"); + break; + } + + printf ("\n# PG: %6d\n" + "PG SZ: %6d\n" + "SZ=%8d bytes\n" + "ADDR: %08X\n", + (unsigned int) dataflash_info[i].Device.pages_number, + (unsigned int) dataflash_info[i].Device.pages_size, + (unsigned int) dataflash_info[i].Device.pages_number * + dataflash_info[i].Device.pages_size, + (unsigned int) dataflash_info[i].logical_address); + } + } +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : AT91F_DataflashSelect */ +/* Object : Select the correct device */ +/*------------------------------------------------------------------------------*/ +static AT91PS_DataFlash AT91F_DataflashSelect(AT91PS_DataFlash pFlash, + unsigned int *addr) +{ + char addr_valid = 0; + int i; + + for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) + if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) { + addr_valid = 1; + break; + } + if (!addr_valid) { + pFlash = (AT91PS_DataFlash) 0; + return pFlash; + } + pFlash->pDataFlashDesc = &(dataflash_info[i].Desc); + pFlash->pDevice = &(dataflash_info[i].Device); + *addr -= dataflash_info[i].logical_address; + return (pFlash); +} + + +/*------------------------------------------------------------------------------*/ +/* Function Name : read_dataflash */ +/* Object : dataflash memory read */ +/*------------------------------------------------------------------------------*/ +int read_dataflash(unsigned long addr, unsigned long size, char *result) +{ + unsigned int AddrToRead = addr; + AT91PS_DataFlash pFlash = &DataFlashInst; + + pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead); + if (pFlash == 0) + return -1; + + return (AT91F_DataFlashRead(pFlash, AddrToRead, size, result)); +} + + +/*-----------------------------------------------------------------------------*/ +/* Function Name : write_dataflash */ +/* Object : write a block in dataflash */ +/*-----------------------------------------------------------------------------*/ +int write_dataflash(unsigned long addr_dest, unsigned int addr_src, + unsigned int size) +{ + unsigned int AddrToWrite = addr_dest; + AT91PS_DataFlash pFlash = &DataFlashInst; + + pFlash = AT91F_DataflashSelect(pFlash, &AddrToWrite); + if (AddrToWrite == -1) + return -1; + + return AT91F_DataFlashWrite(pFlash, (unsigned char *) addr_src, AddrToWrite, size); +} + +/*-----------------------------------------------------------------------------*/ +/* Function Name : erase_dataflash */ +/* Object : Erase entire dataflash */ +/*-----------------------------------------------------------------------------*/ +int erase_dataflash(unsigned long addr_dest) +{ + unsigned int AddrToWrite = addr_dest; + AT91PS_DataFlash pFlash = &DataFlashInst; + + pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite); + if (AddrToWrite == -1) + return -1; + + return AT91F_DataFlashErase(pFlash); +} + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/dataflash.h.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/dataflash.h.svn-base new file mode 100644 index 0000000..8fab63f --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/dataflash.h.svn-base @@ -0,0 +1,181 @@ +//*--------------------------------------------------------------------------- +//* ATMEL Microcontroller Software Support - ROUSSET - +//*--------------------------------------------------------------------------- +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*--------------------------------------------------------------------------- +//* File Name : AT91_SpiDataFlash.h +//* Object : Data Flash Atmel Description File +//* Translator : +//* +//* 1.0 03/04/01 HI : Creation +//* +//*--------------------------------------------------------------------------- + +#ifndef _DataFlash_h +#define _DataFlash_h + +/* Max value = 15Mhz to be compliant with the Continuous array read function */ +#ifdef SPI_LOW_SPEED +#define AT91C_SPI_CLK 14976000/4 +#else +#define AT91C_SPI_CLK 14976000 +#endif + +/* AC characteristics */ +/* DLYBS = tCSS= 250ns min and DLYBCT = tCSH = 250ns */ + +#define DATAFLASH_TCSS (0xf << 16) /* 250ns 15/60000000 */ +#define DATAFLASH_TCHS (0x1 << 24) /* 250ns 32*1/60000000 */ + + +#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0 : NPCS0 %1110 */ +#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3 : NPCS3 %0111 */ + +#define CFG_MAX_DATAFLASH_BANKS 2 +#define CFG_DATAFLASH_LOGIC_ADDR_CS0 0xC0000000 +#define CFG_DATAFLASH_LOGIC_ADDR_CS3 0xD0000000 + +typedef struct { + unsigned long base; /* logical base address for a bank */ + unsigned long size; /* total bank size */ + unsigned long page_count; + unsigned long page_size; + unsigned long id; /* device id */ +} dataflash_info_t; + +typedef unsigned int AT91S_DataFlashStatus; + +/*----------------------------------------------------------------------*/ +/* DataFlash Structures */ +/*----------------------------------------------------------------------*/ + +/*---------------------------------------------*/ +/* DataFlash Descriptor Structure Definition */ +/*---------------------------------------------*/ +typedef struct _AT91S_DataflashDesc { + unsigned char *tx_cmd_pt; + unsigned int tx_cmd_size; + unsigned char *rx_cmd_pt; + unsigned int rx_cmd_size; + unsigned char *tx_data_pt; + unsigned int tx_data_size; + unsigned char *rx_data_pt; + unsigned int rx_data_size; + volatile unsigned char DataFlash_state; + unsigned char command[8]; +} AT91S_DataflashDesc, *AT91PS_DataflashDesc; + +/*---------------------------------------------*/ +/* DataFlash device definition structure */ +/*---------------------------------------------*/ +typedef struct _AT91S_Dataflash { + int pages_number; /* dataflash page number */ + int pages_size; /* dataflash page size */ + int page_offset; /* page offset in command */ + int byte_mask; /* byte mask in command */ + int cs; +} AT91S_DataflashFeatures, *AT91PS_DataflashFeatures; + + +/*---------------------------------------------*/ +/* DataFlash Structure Definition */ +/*---------------------------------------------*/ +typedef struct _AT91S_DataFlash { + AT91PS_DataflashDesc pDataFlashDesc; /* dataflash descriptor */ + AT91PS_DataflashFeatures pDevice; /* Pointer on a dataflash features array */ +} AT91S_DataFlash, *AT91PS_DataFlash; + + +typedef struct _AT91S_DATAFLASH_INFO { + + AT91S_DataflashDesc Desc; + AT91S_DataflashFeatures Device; /* Pointer on a dataflash features array */ + unsigned long logical_address; + unsigned int id; /* device id */ +} AT91S_DATAFLASH_INFO, *AT91PS_DATAFLASH_INFO; + + +/*-------------------------------------------------------------------------------------------------*/ + +#define AT45DB161 0x2c +#define AT45DB321 0x34 +#define AT45DB642 0x3c +#define AT45DB128 0x10 + +#define AT91C_DATAFLASH_TIMEOUT 20000 /* For AT91F_DataFlashWaitReady */ + +/* DataFlash return value */ +#define AT91C_DATAFLASH_BUSY 0x00 +#define AT91C_DATAFLASH_OK 0x01 +#define AT91C_DATAFLASH_ERROR 0x02 +#define AT91C_DATAFLASH_MEMORY_OVERFLOW 0x03 +#define AT91C_DATAFLASH_BAD_COMMAND 0x04 +#define AT91C_DATAFLASH_BAD_ADDRESS 0x05 + + +/* Driver State */ +#define IDLE 0x0 +#define BUSY 0x1 +#define ERROR 0x2 + +/* DataFlash Driver State */ +#define GET_STATUS 0x0F + +/*-------------------------------------------------------------------------------------------------*/ +/* Command Definition */ +/*-------------------------------------------------------------------------------------------------*/ + +/* READ COMMANDS */ +#define DB_CONTINUOUS_ARRAY_READ 0xE8 /* Continuous array read */ +#define DB_BURST_ARRAY_READ 0xE8 /* Burst array read */ +#define DB_PAGE_READ 0xD2 /* Main memory page read */ +#define DB_BUF1_READ 0xD4 /* Buffer 1 read */ +#define DB_BUF2_READ 0xD6 /* Buffer 2 read */ +#define DB_STATUS 0xD7 /* Status Register */ + +/* PROGRAM and ERASE COMMANDS */ +#define DB_BUF1_WRITE 0x84 /* Buffer 1 write */ +#define DB_BUF2_WRITE 0x87 /* Buffer 2 write */ +#define DB_BUF1_PAGE_ERASE_PGM 0x83 /* Buffer 1 to main memory page program with built-In erase */ +#define DB_BUF1_PAGE_ERASE_FASTPGM 0x93 /* Buffer 1 to main memory page program with built-In erase, Fast program */ +#define DB_BUF2_PAGE_ERASE_PGM 0x86 /* Buffer 2 to main memory page program with built-In erase */ +#define DB_BUF2_PAGE_ERASE_FASTPGM 0x96 /* Buffer 1 to main memory page program with built-In erase, Fast program */ +#define DB_BUF1_PAGE_PGM 0x88 /* Buffer 1 to main memory page program without built-In erase */ +#define DB_BUF1_PAGE_FASTPGM 0x98 /* Buffer 1 to main memory page program without built-In erase, Fast program */ +#define DB_BUF2_PAGE_PGM 0x89 /* Buffer 2 to main memory page program without built-In erase */ +#define DB_BUF2_PAGE_FASTPGM 0x99 /* Buffer 1 to main memory page program without built-In erase, Fast program */ +#define DB_PAGE_ERASE 0x81 /* Page Erase */ +#define DB_BLOCK_ERASE 0x50 /* Block Erase */ +#define DB_PAGE_PGM_BUF1 0x82 /* Main memory page through buffer 1 */ +#define DB_PAGE_FASTPGM_BUF1 0x92 /* Main memory page through buffer 1, Fast program */ +#define DB_PAGE_PGM_BUF2 0x85 /* Main memory page through buffer 2 */ +#define DB_PAGE_FastPGM_BUF2 0x95 /* Main memory page through buffer 2, Fast program */ + +/* ADDITIONAL COMMANDS */ +#define DB_PAGE_2_BUF1_TRF 0x53 /* Main memory page to buffer 1 transfert */ +#define DB_PAGE_2_BUF2_TRF 0x55 /* Main memory page to buffer 2 transfert */ +#define DB_PAGE_2_BUF1_CMP 0x60 /* Main memory page to buffer 1 compare */ +#define DB_PAGE_2_BUF2_CMP 0x61 /* Main memory page to buffer 2 compare */ +#define DB_AUTO_PAGE_PGM_BUF1 0x58 /* Auto page rewrite throught buffer 1 */ +#define DB_AUTO_PAGE_PGM_BUF2 0x59 /* Auto page rewrite throught buffer 2 */ + +/*-------------------------------------------------------------------------------------------------*/ + +extern AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS]; + +extern void AT91F_SpiInit(void); +extern int AT91F_DataflashProbe(int i, AT91PS_DataflashDesc pDesc); +extern int AT91F_DataFlashRead(AT91PS_DataFlash, unsigned long , unsigned long, char *); +extern AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash ,unsigned char *, int, int); +extern AT91S_DataFlashStatus AT91F_DataFlashErase(AT91PS_DataFlash pDataFlash); +extern int AT91F_DataflashInit(void); +extern void AT91F_DataflashPrintInfo(void); +extern int read_dataflash(unsigned long addr, unsigned long size, char *result); +extern int write_dataflash(unsigned long addr_dest, unsigned int addr_src, unsigned int size); +extern int erase_dataflash(unsigned long addr_dest); + +#endif diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/div0.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/div0.c.svn-base new file mode 100644 index 0000000..d6fd90e --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/div0.c.svn-base @@ -0,0 +1,28 @@ +/* + * (C) Copyright 2002 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* Replacement (=dummy) for GNU/Linux division-by zero handler */ +void __div0 (void) +{ + while(-1); +} diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/elf32-littlearm.lds.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/elf32-littlearm.lds.svn-base new file mode 100644 index 0000000..4d4efb6 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/elf32-littlearm.lds.svn-base @@ -0,0 +1,19 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : { *(.text) } + + . = ALIGN(4); + .rodata : { *(.rodata) } + + . = ALIGN(4); + .data : { *(.data) } + + . = ALIGN(4); + .bss : { *(.bss) } +}
\ No newline at end of file diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/embedded_services.h.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/embedded_services.h.svn-base new file mode 100644 index 0000000..956b9ed --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/embedded_services.h.svn-base @@ -0,0 +1,500 @@ +//*---------------------------------------------------------------------------- +//* ATMEL Microcontroller Software Support - ROUSSET - +//*---------------------------------------------------------------------------- +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*---------------------------------------------------------------------------- +//* File Name : embedded_sevices.h +//* Object : Header File with all the embedded software services definitions +//* +//* 1.0 24 Jan 2003 FB : Creation +//*---------------------------------------------------------------------------- +#ifndef embedded_sevices_h +#define embedded_sevices_h + +#include "AT91RM9200.h" + +#define AT91C_BASE_ROM (char *)0x00100000 + +/* Return values */ +#define AT91C_BUFFER_SUCCESS 0 +#define AT91C_BUFFER_ERROR_SHIFT 16 +#define AT91C_BUFFER_ERROR (0x0F << AT91C_BUFFER_ERROR_SHIFT) + +#define AT91C_BUFFER_OVERFLOW (0x01 << AT91C_BUFFER_ERROR_SHIFT) +#define AT91C_BUFFER_UNDERRUN (0x02 << AT91C_BUFFER_ERROR_SHIFT) + +typedef unsigned int AT91S_BufferStatus; + +struct _AT91S_Pipe; + +// This structure is a virtual object of a buffer +typedef struct _AT91S_Buffer +{ + struct _AT91S_Pipe *pPipe; + void *pChild; + + // Functions invoked by the pipe + AT91S_BufferStatus (*SetRdBuffer) (struct _AT91S_Buffer *pSBuffer, char *pBuffer, unsigned int Size); + AT91S_BufferStatus (*SetWrBuffer) (struct _AT91S_Buffer *pSBuffer, char const *pBuffer, unsigned int Size); + AT91S_BufferStatus (*RstRdBuffer) (struct _AT91S_Buffer *pSBuffer); + AT91S_BufferStatus (*RstWrBuffer) (struct _AT91S_Buffer *pSBuffer); + char (*MsgWritten) (struct _AT91S_Buffer *pSBuffer, char const *pBuffer); + char (*MsgRead) (struct _AT91S_Buffer *pSBuffer, char const *pBuffer); + // Functions invoked by the peripheral + AT91S_BufferStatus (*GetWrBuffer) (struct _AT91S_Buffer *pSBuffer, char const **pData, unsigned int *pSize); + AT91S_BufferStatus (*GetRdBuffer) (struct _AT91S_Buffer *pSBuffer, char **pData, unsigned int *pSize); + AT91S_BufferStatus (*EmptyWrBuffer) (struct _AT91S_Buffer *pSBuffer, unsigned int size); + AT91S_BufferStatus (*FillRdBuffer) (struct _AT91S_Buffer *pSBuffer, unsigned int size); + char (*IsWrEmpty) (struct _AT91S_Buffer *pSBuffer); + char (*IsRdFull) (struct _AT91S_Buffer *pSBuffer); +} AT91S_Buffer, *AT91PS_Buffer; + +// =========================================================================================== +// SimpleBuffer definition +// +// This structure is pointed by pRealBuffer field in the SBuffer +// It contains usefull information for a real implementation of +// a SBuffer object. +// The application just create an instance of SSBUffer and SBuffer, +// call OpenSimpleBuffer, and continue using SBuffer instance + +typedef struct _AT91S_SBuffer +{ + AT91S_Buffer parent; + char *pRdBuffer; + char const *pWrBuffer; + unsigned int szRdBuffer; + unsigned int szWrBuffer; + unsigned int stRdBuffer; + unsigned int stWrBuffer; +} AT91S_SBuffer, *AT91PS_SBuffer; + +typedef AT91PS_Buffer (*AT91PF_OpenSBuffer) (AT91PS_SBuffer); + +// This function is called by the application +extern AT91PS_Buffer AT91F_OpenSBuffer(AT91PS_SBuffer pBuffer); + +// Functions invoked by the pipe +extern AT91S_BufferStatus AT91F_SbSetRdBuffer (AT91PS_Buffer pBuffer, char *pData, unsigned int Size); +extern AT91S_BufferStatus AT91F_SbSetWrBuffer (AT91PS_Buffer pBuffer, char const *pData, unsigned int Size); +extern AT91S_BufferStatus AT91F_SbRstRdBuffer (AT91PS_Buffer pBuffer); +extern AT91S_BufferStatus AT91F_SbRstWrBuffer (AT91PS_Buffer pBuffer); +extern char AT91F_SbMsgWritten (AT91PS_Buffer pBuffer, char const *pMsg); +extern char AT91F_SbMsgRead (AT91PS_Buffer pBuffer, char const *pMsg); +// Functions invoked by the peripheral +extern AT91S_BufferStatus AT91F_SbGetWrBuffer (AT91PS_Buffer pBuffer, char const **pData, unsigned int *pSize); +extern AT91S_BufferStatus AT91F_SbGetRdBuffer (AT91PS_Buffer pBuffer, char **pData, unsigned int *pSize); +extern AT91S_BufferStatus AT91F_SbEmptyWrBuffer(AT91PS_Buffer pBuffer, unsigned int size); +extern AT91S_BufferStatus AT91F_SbFillRdBuffer (AT91PS_Buffer pBuffer, unsigned int size); +extern char AT91F_SbIsWrEmpty (AT91PS_Buffer pBuffer); +extern char AT91F_SbIsRdFull (AT91PS_Buffer pBuffer); + +#ifdef DBG_DRV_BUFFER +extern char const *AT91F_SbGetError(AT91S_BufferStatus errorNumber); +#endif + + +#define AT91C_OPEN_CTRLTEMPO_SUCCESS 0 +#define AT91C_ERROR_OPEN_CTRLTEMPO 1 +#define AT91C_START_OK 2 +#define AT91C_STOP_OK 3 +#define AT91C_TIMEOUT_REACHED 4 + +typedef enum _AT91E_SvcTempo { + AT91E_SVCTEMPO_DIS, + AT91E_SVCTEMPO_EN +} AT91E_SvcTempo; + +typedef unsigned int AT91S_TempoStatus; + +// AT91S_SvcTempo +typedef struct _AT91S_SvcTempo +{ + + // Methods: + AT91S_TempoStatus (*Start) ( + struct _AT91S_SvcTempo *pSvc, + unsigned int timeout, + unsigned int reload, + void (*callback) (AT91S_TempoStatus, void *), + void *pData); + AT91S_TempoStatus (*Stop) (struct _AT91S_SvcTempo *pSvc); + + struct _AT91S_SvcTempo *pPreviousTempo; + struct _AT91S_SvcTempo *pNextTempo; + + // Data + unsigned int TickTempo; //* timeout value + unsigned int ReloadTempo;//* Reload value for periodic execution + void (*TempoCallback)(AT91S_TempoStatus, void *); + void *pPrivateData; + AT91E_SvcTempo flag; +} AT91S_SvcTempo, *AT91PS_SvcTempo; + + +// AT91S_CtrlTempo +typedef struct _AT91S_CtlTempo +{ + // Members: + + // Start and stop for Timer hardware + AT91S_TempoStatus (*CtlTempoStart) (void *pTimer); + AT91S_TempoStatus (*CtlTempoStop) (void *pTimer); + + // Start and stop for Tempo service + AT91S_TempoStatus (*SvcTempoStart) ( + struct _AT91S_SvcTempo *pSvc, + unsigned int timeout, + unsigned int reload, + void (*callback) (AT91S_TempoStatus, void *), + void *pData); + AT91S_TempoStatus (*SvcTempoStop) (struct _AT91S_SvcTempo *pSvc); + AT91S_TempoStatus (*CtlTempoSetTime)(struct _AT91S_CtlTempo *pCtrl, unsigned int NewTime); + AT91S_TempoStatus (*CtlTempoGetTime)(struct _AT91S_CtlTempo *pCtrl); + AT91S_TempoStatus (*CtlTempoIsStart)(struct _AT91S_CtlTempo *pCtrl); + AT91S_TempoStatus (*CtlTempoCreate) ( + struct _AT91S_CtlTempo *pCtrl, + struct _AT91S_SvcTempo *pTempo); + AT91S_TempoStatus (*CtlTempoRemove) ( + struct _AT91S_CtlTempo *pCtrl, + struct _AT91S_SvcTempo *pTempo); + AT91S_TempoStatus (*CtlTempoTick) (struct _AT91S_CtlTempo *pCtrl); + + // Data: + + void *pPrivateData; // Pointer to devived class + void const *pTimer; // hardware + AT91PS_SvcTempo pFirstTempo; + AT91PS_SvcTempo pNewTempo; +} AT91S_CtlTempo, *AT91PS_CtlTempo; +typedef AT91S_TempoStatus (*AT91PF_OpenCtlTempo) ( AT91PS_CtlTempo, void const *); + +// This function is called by the application. +extern AT91S_TempoStatus AT91F_OpenCtlTempo( AT91PS_CtlTempo pCtrlTempo, void const *pTempoTimer ); + +extern AT91S_TempoStatus AT91F_STStart (void *); +extern AT91S_TempoStatus AT91F_STStop (void *); +extern AT91S_TempoStatus AT91F_STSetTime (AT91PS_CtlTempo, unsigned int); +extern AT91S_TempoStatus AT91F_STGetTime (AT91PS_CtlTempo); +extern AT91S_TempoStatus AT91F_STIsStart (AT91PS_CtlTempo); +extern AT91S_TempoStatus AT91F_CtlTempoCreate (AT91PS_CtlTempo, AT91PS_SvcTempo); +extern AT91S_TempoStatus AT91F_CtlTempoRemove (AT91PS_CtlTempo, AT91PS_SvcTempo); +extern AT91S_TempoStatus AT91F_CtlTempoTick (AT91PS_CtlTempo); +extern AT91S_TempoStatus AT91F_SvcTempoStart ( + AT91PS_SvcTempo pSvc, + unsigned int timeout, + unsigned int reload, + void (*callback) (AT91S_TempoStatus, void *), + void *pData); +extern AT91S_TempoStatus AT91F_SvcTempoStop (AT91PS_SvcTempo); + + +// Following types are defined in another header files +struct _AT91S_Buffer; + +// Constants: +#define AT91C_COMMSVC_SUCCESS 0 +#define AT91C_COMMSVC_ERROR_SHIFT 8 +#define AT91C_COMMSVC_ERROR (0x0f << AT91C_COMMSVC_ERROR_SHIFT) + +typedef unsigned int AT91S_SvcCommStatus; + +// AT91S_Service definition +// This structure is an abstraction of a communication peripheral +typedef struct _AT91S_Service +{ + // Methods: + AT91S_SvcCommStatus (*Reset) (struct _AT91S_Service *pService); + AT91S_SvcCommStatus (*StartTx)(struct _AT91S_Service *pService); + AT91S_SvcCommStatus (*StartRx)(struct _AT91S_Service *pService); + AT91S_SvcCommStatus (*StopTx) (struct _AT91S_Service *pService); + AT91S_SvcCommStatus (*StopRx) (struct _AT91S_Service *pService); + char (*TxReady)(struct _AT91S_Service *pService); + char (*RxReady)(struct _AT91S_Service *pService); + // Data: + struct _AT91S_Buffer *pBuffer; // Link to a buffer object + void *pChild; +} AT91S_SvcComm, *AT91PS_SvcComm; + +// Constants: +#define AT91C_XMODEM_SOH 0x01 /* Start of Heading for 128 bytes */ +#define AT91C_XMODEM_STX 0x02 /* Start of heading for 1024 bytes */ +#define AT91C_XMODEM_EOT 0x04 /* End of transmission */ +#define AT91C_XMODEM_ACK 0x06 /* Acknowledge */ +#define AT91C_XMODEM_NAK 0x15 /* Negative Acknowledge */ +#define AT91C_XMODEM_CRCCHR 'C' + +#define AT91C_XMODEM_PACKET_SIZE 2 // packet + packetCRC +#define AT91C_XMODEM_CRC_SIZE 2 // crcLSB + crcMSB +#define AT91C_XMODEM_DATA_SIZE_SOH 128 // data 128 corresponding to SOH header +#define AT91C_XMODEM_DATA_SIZE_STX 1024 // data 1024 corresponding to STX header + +//* Following structure is used by SPipe to refer to the USB device peripheral endpoint +typedef struct _AT91PS_SvcXmodem { + + // Public Methods: + AT91S_SvcCommStatus (*Handler) (struct _AT91PS_SvcXmodem *, unsigned int); + AT91S_SvcCommStatus (*StartTx) (struct _AT91PS_SvcXmodem *, unsigned int); + AT91S_SvcCommStatus (*StopTx) (struct _AT91PS_SvcXmodem *, unsigned int); + + // Private Methods: + AT91S_SvcCommStatus (*ReadHandler) (struct _AT91PS_SvcXmodem *, unsigned int csr); + AT91S_SvcCommStatus (*WriteHandler) (struct _AT91PS_SvcXmodem *, unsigned int csr); + unsigned short (*GetCrc) (char *ptr, unsigned int count); + char (*CheckHeader) (unsigned char currentPacket, char *packet); + char (*CheckData) (struct _AT91PS_SvcXmodem *); + + AT91S_SvcComm parent; // Base class + AT91PS_USART pUsart; + + AT91S_SvcTempo tempo; // Link to a AT91S_Tempo object + + char *pData; + unsigned int dataSize; // = XMODEM_DATA_STX or XMODEM_DATA_SOH + char packetDesc[AT91C_XMODEM_PACKET_SIZE]; + unsigned char packetId; // Current packet + char packetStatus; + char isPacketDesc; + char eot; // end of transmition +} AT91S_SvcXmodem, *AT91PS_SvcXmodem; + +typedef AT91PS_SvcComm (*AT91PF_OpenSvcXmodem) ( AT91PS_SvcXmodem, AT91PS_USART, AT91PS_CtlTempo); + +// This function is called by the application. +extern AT91PS_SvcComm AT91F_OpenSvcXmodem( AT91PS_SvcXmodem, AT91PS_USART, AT91PS_CtlTempo); + +extern unsigned short AT91F_SvcXmodemGetCrc (char *ptr, unsigned int count); +extern char AT91F_SvcXmodemCheckHeader(unsigned char currentPacket, char *packet); +extern char AT91F_SvcXmodemCheckData (AT91PS_SvcXmodem pSvcXmodem); +extern AT91S_SvcCommStatus AT91F_SvcXmodemReadHandler(AT91PS_SvcXmodem pSvcXmodem, unsigned int csr); +extern AT91S_SvcCommStatus AT91F_SvcXmodemWriteHandler(AT91PS_SvcXmodem pSvcXmodem, unsigned int csr); +extern AT91S_SvcCommStatus AT91F_SvcXmodemStartTx(AT91PS_SvcComm pSvcComm); +extern AT91S_SvcCommStatus AT91F_SvcXmodemStopTx(AT91PS_SvcComm pSvcComm); +extern AT91S_SvcCommStatus AT91F_SvcXmodemStartRx(AT91PS_SvcComm pSvcComm); +extern AT91S_SvcCommStatus AT91F_SvcXmodemStopRx(AT91PS_SvcComm pSvcComm); +extern char AT91F_SvcXmodemTxReady(AT91PS_SvcComm pService); +extern char AT91F_SvcXmodemRxReady(AT91PS_SvcComm pSvcComm); + + +// Constants: +#define AT91C_PIPE_SUCCESS 0 +#define AT91C_PIPE_ERROR_SHIFT 8 +#define AT91C_PIPE_ERROR (0x0F << AT91C_PIPE_ERROR_SHIFT) + +#define AT91C_PIPE_OPEN_FAILED (1 << AT91C_PIPE_ERROR_SHIFT) +#define AT91C_PIPE_WRITE_FAILED (2 << AT91C_PIPE_ERROR_SHIFT) +#define AT91C_PIPE_WRITE_ABORTED (3 << AT91C_PIPE_ERROR_SHIFT) +#define AT91C_PIPE_READ_FAILED (4 << AT91C_PIPE_ERROR_SHIFT) +#define AT91C_PIPE_READ_ABORTED (5 << AT91C_PIPE_ERROR_SHIFT) +#define AT91C_PIPE_ABORT_FAILED (6 << AT91C_PIPE_ERROR_SHIFT) +#define AT91C_PIPE_RESET_FAILED (7 << AT91C_PIPE_ERROR_SHIFT) + +/* _AT91S_Pipe stucture */ +typedef unsigned int AT91S_PipeStatus; + +typedef struct _AT91S_Pipe +{ + // A pipe is linked with a peripheral and a buffer + AT91PS_SvcComm pSvcComm; + AT91PS_Buffer pBuffer; + + // Callback functions with their arguments + void (*WriteCallback) (AT91S_PipeStatus, void *); + void (*ReadCallback) (AT91S_PipeStatus, void *); + void *pPrivateReadData; + void *pPrivateWriteData; + + // Pipe methods + AT91S_PipeStatus (*Write) ( + struct _AT91S_Pipe *pPipe, + char const * pData, + unsigned int size, + void (*callback) (AT91S_PipeStatus, void *), + void *privateData); + AT91S_PipeStatus (*Read) ( + struct _AT91S_Pipe *pPipe, + char *pData, + unsigned int size, + void (*callback) (AT91S_PipeStatus, void *), + void *privateData); + AT91S_PipeStatus (*AbortWrite) ( + struct _AT91S_Pipe *pPipe); + AT91S_PipeStatus (*AbortRead) ( + struct _AT91S_Pipe *pPipe); + AT91S_PipeStatus (*Reset) ( + struct _AT91S_Pipe *pPipe); + char (*IsWritten) ( + struct _AT91S_Pipe *pPipe, + char const *pVoid); + char (*IsReceived) ( + struct _AT91S_Pipe *pPipe, + char const *pVoid); +} AT91S_Pipe, *AT91PS_Pipe; + +// types used in AT91S_Pipe +typedef AT91PS_Pipe (*AT91PF_OpenPipe) (AT91PS_Pipe, AT91PS_SvcComm, AT91PS_Buffer); +typedef void (*AT91PF_PipeWriteCallBack) (AT91S_PipeStatus, void *); +typedef void (*AT91PF_PipeReadCallBack) (AT91S_PipeStatus, void *); +typedef AT91S_PipeStatus (*AT91PF_PipeWrite) (AT91PS_Pipe, char const *, unsigned int, void (*) (AT91S_PipeStatus, void *), void *); +typedef AT91S_PipeStatus (*AT91PF_PipeRead) (AT91PS_Pipe, char const *, unsigned int, void (*) (AT91S_PipeStatus, void *), void *); +typedef AT91S_PipeStatus (*AT91PF_PipeAbortWrite) (AT91PS_Pipe); +typedef AT91S_PipeStatus (*AT91PF_PipeAbortRead) (AT91PS_Pipe); +typedef AT91S_PipeStatus (*AT91PF_PipeReset) (AT91PS_Pipe); +typedef char (*AT91PF_PipeIsWritten) (AT91PS_Pipe, char const *); +typedef char (*AT91PF_PipeIsReceived) (AT91PS_Pipe, char const *); + +// This function is called by the application +extern AT91PS_Pipe AT91F_OpenPipe( + AT91PS_Pipe pPipe, + AT91PS_SvcComm pSvcComm, + AT91PS_Buffer pBuffer); + +// Following functions are called through AT91S_Pipe pointers + +extern AT91S_PipeStatus AT91F_PipeWrite( + AT91PS_Pipe pPipe, + char const *pVoid, + unsigned int size, + AT91PF_PipeWriteCallBack callback, + void *privateData); +extern AT91S_PipeStatus AT91F_PipeRead( + AT91PS_Pipe pPipe, + char *pVoid, + unsigned int Size, + AT91PF_PipeReadCallBack callback, + void *privateData); +extern AT91S_PipeStatus AT91F_PipeAbortWrite(AT91PS_Pipe pPipe); +extern AT91S_PipeStatus AT91F_PipeAbortRead(AT91PS_Pipe pPipe); +extern AT91S_PipeStatus AT91F_PipeReset(AT91PS_Pipe pPipe); +extern char AT91F_PipeMsgWritten(AT91PS_Pipe pPipe, char const *pVoid); +extern char AT91F_PipeMsgReceived(AT91PS_Pipe pPipe, char const *pVoid); + +#ifdef DBG_DRV_PIPE +// This function parse the error number and return a string +// describing the error message +extern char const *AT91F_PipeGetError(AT91S_PipeStatus msgId); +#endif + +extern const unsigned char bit_rev[256]; + +extern void CalculateCrc32(const unsigned char *,unsigned int, unsigned int *); +extern void CalculateCrc16(const unsigned char *, unsigned int , unsigned short *); +extern void CalculateCrcHdlc(const unsigned char *, unsigned int, unsigned short *); +extern void CalculateCrc16ccitt(const unsigned char *, unsigned int , unsigned short *); + +typedef const unsigned char* AT91PS_SVC_CRC_BIT_REV ; + +typedef void (*AT91PF_SVC_CRC32) (const unsigned char *, unsigned int, unsigned int *); +typedef void (*AT91PF_SVC_CRC16) (const unsigned char *, unsigned int, unsigned short *); +typedef void (*AT91PF_SVC_CRCHDLC) (const unsigned char *, unsigned int, unsigned short *); +typedef void (*AT91PF_SVC_CRCCCITT)(const unsigned char *, unsigned int , unsigned short *); + + +typedef short (*AT91PF_Sinus) (int angle); +typedef const short * AT91PS_SINE_TAB; + +extern short AT91F_Sinus(int angle); +extern const short AT91C_SINUS180_TAB[256]; + + +typedef void (TypeAICHandler) (void) ; + + +// ROM BOOT Structure Element Definition (liv v2) +typedef struct _AT91S_MEMCDesc +{ + AT91PS_MC memc_base ; /* Peripheral base */ + unsigned char periph_id ; /* MC Peripheral Identifier */ +} AT91S_MEMCDesc, *AT91PS_MEMCDesc ; + +typedef struct _AT91S_Pio2Desc +{ + AT91PS_PIO pio_base ; /* Base Address */ + unsigned char periph_id ; /* Peripheral Identifier */ + unsigned char pio_number ; /* Total Pin Number */ +} AT91S_Pio2Desc, *AT91PS_Pio2Desc ; + +typedef struct _AT91S_SPIDesc +{ + AT91PS_SPI spi_base ; + const AT91PS_PIO pio_base ; + unsigned char periph_id ; + unsigned char pin_spck ; + unsigned char pin_miso ; + unsigned char pin_mosi ; + unsigned char pin_npcs[4] ; +} AT91S_SPIDesc, *AT91PS_SPIDesc ; + +typedef struct _AT91S_USART2Desc +{ + AT91PS_USART usart_base ; /* Peripheral base */ + const AT91PS_PIO pio_base ; /* IO controller descriptor */ + unsigned int pin_rxd ; /* RXD pin number in the PIO */ + unsigned int pin_txd ; /* TXD pin number in the PIO */ + unsigned int pin_sck ; /* SCK pin number in the PIO */ + unsigned int pin_rts ; /* RTS pin number in the PIO */ + unsigned int pin_cts ; /* CTS pin number in the PIO */ + unsigned int pin_dtr ; /* DTR pin number in the PIO */ + unsigned int pin_ri ; /* RI pin number in the PIO */ + unsigned int pin_dsr ; /* DSR pin number in the PIO */ + unsigned int pin_dcd ; /* DCD pin number in the PIO */ + unsigned int periph_id ; /* USART Peripheral Identifier */ +} AT91S_USART2Desc, *AT91PS_USART2Desc ; + +typedef struct _AT91S_TWIDesc +{ + AT91PS_TWI TWI_base ; + const AT91PS_PIO pio_base ; + unsigned int pin_sck ; + unsigned int pin_sda ; + unsigned int periph_id; +}AT91S_TWIDesc, *AT91PS_TWIDesc; + +typedef struct _AT91S_STDesc +{ + AT91PS_ST st_base ; /* Peripheral base address */ + TypeAICHandler *AsmSTHandler ; /* Assembly interrupt handler */ + unsigned char PeriphId ; /* Peripheral Identifier */ +} AT91S_STDesc, *AT91PS_STDesc; + +typedef struct _AT91S_RomBoot { + const unsigned int version; + // Peripheral descriptors + const AT91S_MEMCDesc MEMC_DESC; + const AT91S_STDesc SYSTIMER_DESC; + const AT91S_Pio2Desc PIOA_DESC; + const AT91S_Pio2Desc PIOB_DESC; + const AT91S_USART2Desc DBGU_DESC; + const AT91S_USART2Desc USART0_DESC; + const AT91S_USART2Desc USART1_DESC; + const AT91S_USART2Desc USART2_DESC; + const AT91S_USART2Desc USART3_DESC; + const AT91S_TWIDesc TWI_DESC; + const AT91S_SPIDesc SPI_DESC; + + // Objects entry + const AT91PF_OpenPipe OpenPipe; + const AT91PF_OpenSBuffer OpenSBuffer; + const unsigned int reserved1; + const AT91PF_OpenSvcXmodem OpenSvcXmodem; + const AT91PF_OpenCtlTempo OpenCtlTempo; + const unsigned int reserved2; + const unsigned int reserved3; + const unsigned int reserved4; + const AT91PF_SVC_CRC16 CRC16; + const AT91PF_SVC_CRCCCITT CRCCCITT; + const AT91PF_SVC_CRCHDLC CRCHDLC; + const AT91PF_SVC_CRC32 CRC32; + const AT91PS_SVC_CRC_BIT_REV Bit_Reverse_Array; + const AT91PS_SINE_TAB SineTab; + const AT91PF_Sinus Sine; +} AT91S_RomBoot, *AT91PS_RomBoot; + +#define AT91C_ROM_BOOT_ADDRESS ((const AT91S_RomBoot *) ( *((unsigned int *) (AT91C_BASE_ROM + 0x20))) ) + +#endif + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/init.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/init.c.svn-base new file mode 100644 index 0000000..4088973 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/init.c.svn-base @@ -0,0 +1,165 @@ +//*---------------------------------------------------------------------------- +//* ATMEL Microcontroller Software Support - ROUSSET - +//*---------------------------------------------------------------------------- +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*---------------------------------------------------------------------------- +//* File Name : init.c +//* Object : Low level initialisations written in C +//* Creation : HIi 10/10/2003 +//* +//*---------------------------------------------------------------------------- +#include "config.h" +#include "AT91RM9200.h" +#include "lib_AT91RM9200.h" +#include "stdio.h" + +//*---------------------------------------------------------------------------- +//* \fn AT91F_DataAbort +//* \brief This function reports an Abort +//*---------------------------------------------------------------------------- +static void AT91F_SpuriousHandler() +{ + puts("ISI"); + while (1); +} + + +//*---------------------------------------------------------------------------- +//* \fn AT91F_DataAbort +//* \brief This function reports an Abort +//*---------------------------------------------------------------------------- +static void AT91F_DataAbort() +{ + puts("IDA"); + while (1); +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_FetchAbort +//* \brief This function reports an Abort +//*---------------------------------------------------------------------------- +static void AT91F_FetchAbort() +{ + puts("IFA"); + while (1); +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_UndefHandler +//* \brief This function reports that no handler have been set for current IT +//*---------------------------------------------------------------------------- +static void AT91F_UndefHandler() +{ + puts("IUD"); + while (1); +} + + +//*-------------------------------------------------------------------------------------- +//* Function Name : AT91F_InitSdram +//* Object : Initialize the SDRAM +//* Input Parameters : +//* Output Parameters : +//*-------------------------------------------------------------------------------------- +static void AT91F_InitSdram() +{ + int *pRegister; + + //* Configure PIOC as peripheral (D16/D31) + + AT91F_PIO_CfgPeriph( + AT91C_BASE_PIOC, // PIO controller base address + 0xFFFF0030, + 0 + ); + + //*Init SDRAM + pRegister = (int *)0xFFFFFF98; + *pRegister = 0x2188c155; + pRegister = (int *)0xFFFFFF90; + *pRegister = 0x2; + pRegister = (int *)0x20000000; + *pRegister = 0; + pRegister = (int *)0xFFFFFF90; + *pRegister = 0x4; + pRegister = (int *)0x20000000; + *pRegister = 0; + *pRegister = 0; + *pRegister = 0; + *pRegister = 0; + *pRegister = 0; + *pRegister = 0; + *pRegister = 0; + *pRegister = 0; + pRegister = (int *)0xFFFFFF90; + *pRegister = 0x3; + pRegister = (int *)0x20000080; + *pRegister = 0; + + pRegister = (int *)0xFFFFFF94; + *pRegister = 0x2e0; + pRegister = (int *)0x20000000; + *pRegister = 0; + + pRegister = (int *)0xFFFFFF90; + *pRegister = 0x00; + pRegister = (int *)0x20000000; + *pRegister = 0; +} + + +//*---------------------------------------------------------------------------- +//* \fn AT91F_InitFlash +//* \brief This function performs low level HW initialization +//*---------------------------------------------------------------------------- +static void AT91F_InitMemories() +{ + int *pEbi = (int *)0xFFFFFF60; + + //* Setup MEMC to support all connected memories (CS0 = FLASH; CS1=SDRAM) + pEbi = (int *)0xFFFFFF60; + *pEbi = 0x00000002; + + //* CS0 cs for flash + pEbi = (int *)0xFFFFFF70; + *pEbi = 0x00003284; + + AT91F_InitSdram(); +} + + + +//*---------------------------------------------------------------------------- +//* \fn AT91F_LowLevelInit +//* \brief This function performs very low level HW initialization +//*---------------------------------------------------------------------------- +void AT91F_LowLevelInit(void) +{ + int i; + + // Init Interrupt Controller + AT91F_AIC_Open( + AT91C_BASE_AIC, // pointer to the AIC registers + AT91C_AIC_BRANCH_OPCODE, // IRQ exception vector + AT91F_UndefHandler, // FIQ exception vector + AT91F_UndefHandler, // AIC default handler + AT91F_SpuriousHandler, // AIC spurious handler + 0); // Protect mode + + // Perform 8 End Of Interrupt Command to make sýre AIC will not Lock out nIRQ + for(i=0; i<8; i++) + AT91F_AIC_AcknowledgeIt(AT91C_BASE_AIC); + + AT91F_AIC_SetExceptionVector((unsigned int *)0x0C, AT91F_FetchAbort); + AT91F_AIC_SetExceptionVector((unsigned int *)0x10, AT91F_DataAbort); + AT91F_AIC_SetExceptionVector((unsigned int *)0x4, AT91F_UndefHandler); + + //Initialize SDRAM and Flash + AT91F_InitMemories(); + +} + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/jump.S.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/jump.S.svn-base new file mode 100644 index 0000000..cc69311 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/jump.S.svn-base @@ -0,0 +1,4 @@ +.global Jump + +Jump: mov pc, r0 + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/led.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/led.c.svn-base new file mode 100644 index 0000000..40d4911 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/led.c.svn-base @@ -0,0 +1,103 @@ +/* + * (C) Copyright 2006 + * Atmel Nordic AB <www.atmel.com> + * Ulf Samuelsson <ulf@atmel.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <AT91RM9200.h> + +#define GREEN_LED AT91C_PIO_PB0 +#define YELLOW_LED AT91C_PIO_PB1 +#define RED_LED AT91C_PIO_PB2 + +void LED_set(unsigned int led) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; + PIOB->PIO_SODR = (led ^ 0x7) & 0x7; // All 0's => Set PIO high => OFF + PIOB->PIO_CODR = led & 0x7; // All 1's => Set PIO low => ON +} + +void green_LED_on(void) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; +// PIOB->PIO_CODR = GREEN_LED; + PIOB->PIO_CODR = (1 << 0); +} + +void yellow_LED_on(void) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; +// PIOB->PIO_CODR = YELLOW_LED; + PIOB->PIO_CODR = (1 << 1); +} + +void red_LED_on(void) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; +// PIOB->PIO_CODR = RED_LED; + PIOB->PIO_CODR = (1 << 2); +} + +void green_LED_off(void) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; +// PIOB->PIO_SODR = GREEN_LED; + PIOB->PIO_SODR = (1 << 0); +} + +void yellow_LED_off(void) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; +// PIOB->PIO_SODR = YELLOW_LED; + PIOB->PIO_SODR = (1 << 1); +} + +void red_LED_off(void) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; +// PIOB->PIO_SODR = RED_LED; + PIOB->PIO_SODR = (1 << 2); +} + +void LED_blink(unsigned int led) +{ + volatile int i,j; + for(i = 0; i < 5; i++) { + LED_set((1 << led)&0x7); + for(j= 0; j < 200000; j++); + LED_set(0); + for(j= 0; j < 200000; j++); + } +} + + +void LED_init (void) +{ + AT91PS_PIO PIOB = AT91C_BASE_PIOB; + AT91PS_PMC PMC = AT91C_BASE_PMC; + PMC->PMC_PCER = (1 << AT91C_ID_PIOB); // Enable PIOB clock + // Disable peripherals on LEDs + PIOB->PIO_PER = AT91C_PIO_PB2 | AT91C_PIO_PB1 | AT91C_PIO_PB0; + // Enable pins as outputs + PIOB->PIO_OER = AT91C_PIO_PB2 | AT91C_PIO_PB1 | AT91C_PIO_PB0; + // Turn all LEDs OFF + PIOB->PIO_SODR = AT91C_PIO_PB2 | AT91C_PIO_PB1 | AT91C_PIO_PB0; +} diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/main.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/main.c.svn-base new file mode 100644 index 0000000..c0705de --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/main.c.svn-base @@ -0,0 +1,811 @@ +/*---------------------------------------------------------------------------- + * ATMEL Microcontroller Software Support - ROUSSET - + *---------------------------------------------------------------------------- + * The software is delivered "AS IS" without warranty or condition of any + * kind, either express, implied or statutory. This includes without + * limitation any warranty or condition with respect to merchantability or + * fitness for any particular purpose, or against the infringements of + * intellectual property rights of others. + *---------------------------------------------------------------------------- + * File Name : main.c + * Object : + * Creation : HIi 10/10/2003 + * Modif : HIi 15/06/2004 : add crc32 to verify the download + * from dataflash + * : HIi 21/09/2004 : Set first PLLA to 180Mhz and MCK to + * 60Mhz to speed up dataflash boot (15Mhz) + * : MLC 12/04/2005 : Modify SetPLL() to avoid errata + * : USA 30/12/2005 : Change to page Size 1056 + * Change startaddress to C0008400 + * Change SPI Speed to ~4 Mhz + * Add retry on CRC Error + *---------------------------------------------------------------------------- + */ +#include "config.h" +#include "stdio.h" +#include "AT91RM9200.h" +#include "lib_AT91RM9200.h" +#include "com.h" +#include "main.h" +#include "dataflash.h" +#include "AT91C_MCI_Device.h" + +#define DEBUGOUT +#define XMODEM +#define MEMDISP + +#ifdef PAGESZ_1056 +#define PAGESIZE 1056 +#else +#define PAGESIZE 1024 +#endif + +#define AT91C_SDRAM_START 0x20000000 +#define AT91C_BOOT_ADDR 0x21F00000 +#define AT91C_BOOT_SIZE 128*PAGESIZE +#ifdef PAGESZ_1056 +#define AT91C_BOOT_DATAFLASH_ADDR 0xC0008400 +#else +#define AT91C_BOOT_DATAFLASH_ADDR 0xC0008000 +#endif +#define AT91C_PLLA_VALUE 0x237A3E5A // crystal= 18.432MHz - fixes BRG error at 115kbps +//#define AT91C_PLLA_VALUE 0x2026BE04 // crystal= 18.432MHz +//#define AT91C_PLLA_VALUE 0x202CBE01 // crystal= 4MHz + + + +#define DISP_LINE_LEN 16 + +// Reason for boot failure +#define IMAGE_BAD_SIZE 0 +#define IMAGE_READ_FAILURE 1 +#define IMAGE_CRC_ERROR 2 +#define IMAGE_ERROR 3 +#define SUCCESS -1 + +/* prototypes*/ +extern void AT91F_ST_ASM_HANDLER(void); +extern void Jump(unsigned int addr); + +const char *menu_dataflash[] = { +#ifdef XMODEM + "1: P DFboot\n", + "2: P U-Boot\n", +#endif + "3: P SDCard\n", +#ifdef PAGESZ_1056 + "4: R UBOOT\n", +#else + "4: R UBOOT\n", +#endif +#ifdef XMODEM + "5: P DF [addr]\n", +#endif + "6: RD DF [addr]\n", + "7: E DF\n" +}; +#ifdef XMODEM +#define MAXMENU 7 +#else +#define MAXMENU 4 +#endif + +char message[20]; +#ifdef XMODEM +volatile char XmodemComplete = 0; +#endif +unsigned int StTick = 0; + +AT91S_RomBoot const *pAT91; +#ifdef XMODEM +AT91S_SBuffer sXmBuffer; +AT91S_SvcXmodem svcXmodem; +AT91S_Pipe xmodemPipe; +#endif +AT91S_CtlTempo ctlTempo; + + +//*-------------------------------------------------------------------------------------- +//* Function Name : GetTickCount() +//* Object : Return the number of systimer tick +//* Input Parameters : +//* Output Parameters : +//*-------------------------------------------------------------------------------------- +unsigned int GetTickCount(void) +{ + return StTick; +} + +#ifdef XMODEM +//*-------------------------------------------------------------------------------------- +//* Function Name : AT91_XmodemComplete() +//* Object : Perform the remap and jump to appli in RAM +//* Input Parameters : +//* Output Parameters : +//*-------------------------------------------------------------------------------------- +static void AT91_XmodemComplete(AT91S_PipeStatus status, void *pVoid) +{ + /* stop the Xmodem tempo */ + svcXmodem.tempo.Stop(&(svcXmodem.tempo)); + XmodemComplete = 1; +} + + +//*-------------------------------------------------------------------------------------- +//* Function Name : AT91F_XmodemProtocol(AT91S_PipeStatus status, void *pVoid) +//* Object : Xmodem dispatcher +//* Input Parameters : +//* Output Parameters : +//*-------------------------------------------------------------------------------------- +static void XmodemProtocol(AT91S_PipeStatus status, void *pVoid) +{ + AT91PS_SBuffer pSBuffer = (AT91PS_SBuffer) xmodemPipe.pBuffer->pChild; + AT91PS_USART pUsart = svcXmodem.pUsart; + + if (pSBuffer->szRdBuffer == 0) { + /* Start a tempo to wait the Xmodem protocol complete */ + svcXmodem.tempo.Start(&(svcXmodem.tempo), 10, 0, AT91_XmodemComplete, pUsart); + } +} +#endif + +//*-------------------------------------------------------------------------------------- +//* Function Name : irq1_c_handler() +//* Object : C Interrupt handler for Interrutp source 1 +//* Input Parameters : none +//* Output Parameters : none +//*-------------------------------------------------------------------------------------- +void AT91F_ST_HANDLER(void) +{ + volatile unsigned int csr = *AT91C_DBGU_CSR; +#ifdef XMODEM + unsigned int error; +#endif + + if (AT91C_BASE_ST->ST_SR & 0x01) { + StTick++; + ctlTempo.CtlTempoTick(&ctlTempo); + return; + } + +#ifdef XMODEM + error = AT91F_US_Error((AT91PS_USART)AT91C_BASE_DBGU); + if (csr & error) { + /* Stop previous Xmodem transmition*/ + *(AT91C_DBGU_CR) = AT91C_US_RSTSTA; + AT91F_US_DisableIt((AT91PS_USART)AT91C_BASE_DBGU, AT91C_US_ENDRX); + AT91F_US_EnableIt((AT91PS_USART)AT91C_BASE_DBGU, AT91C_US_RXRDY); + + } + + else if (csr & (AT91C_US_TXRDY | AT91C_US_ENDTX | AT91C_US_TXEMPTY | + AT91C_US_RXRDY | AT91C_US_ENDRX | AT91C_US_TIMEOUT | + AT91C_US_RXBUFF)) { + if ( !(svcXmodem.eot) ) + svcXmodem.Handler(&svcXmodem, csr); + } +#endif +} + + +//*----------------------------------------------------------------------------- +//* Function Name : AT91F_DisplayMenu() +//* Object : +//* Input Parameters : +//* Return value : +//*----------------------------------------------------------------------------- +static int AT91F_DisplayMenu(void) +{ + int i, mci_present = 0; + printf("\nDF LOADER %s %s %s\n",AT91C_VERSION,__DATE__,__TIME__); + AT91F_DataflashPrintInfo(); + mci_present = AT91F_MCI_Init(); + for(i = 0; i < MAXMENU; i++) { + puts(menu_dataflash[i]); + } + return mci_present; +} + + +//*----------------------------------------------------------------------------- +//* Function Name : AsciiToHex() +//* Object : ascii to hexa conversion +//* Input Parameters : +//* Return value : +//*----------------------------------------------------------------------------- +static unsigned int AsciiToHex(char *s, unsigned int *val) +{ + int n; + + *val=0; + + if(s[0] == '0' && ((s[1] == 'x') || (s[1] == 'X'))) + s+=2; + n = 0; + while((n < 8) && (s[n] !=0)) + { + *val <<= 4; + if ( (s[n] >= '0') && (s[n] <='9')) + *val += (s[n] - '0'); + else + if ((s[n] >= 'a') && (s[n] <='f')) + *val += (s[n] - 0x57); + else + if ((s[n] >= 'A') && (s[n] <='F')) + *val += (s[n] - 0x37); + else + return 0; + n++; + } + + return 1; +} + + +#ifdef MEMDISP +//*----------------------------------------------------------------------------- +//* Function Name : AT91F_MemoryDisplay() +//* Object : Display the content of the dataflash +//* Input Parameters : +//* Return value : +//*----------------------------------------------------------------------------- +static int AT91F_MemoryDisplay(unsigned int addr, unsigned int length) +{ + unsigned long i, nbytes, linebytes; + char *cp; +// unsigned int *uip; +// unsigned short *usp; + unsigned char *ucp; + char linebuf[DISP_LINE_LEN]; + +// nbytes = length * size; + nbytes = length; + do + { +// uip = (unsigned int *)linebuf; +// usp = (unsigned short *)linebuf; + ucp = (unsigned char *)linebuf; + + printf("%08x:", addr); + linebytes = (nbytes > DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; + if((addr & 0xF0000000) == 0x20000000) { + for(i = 0; i < linebytes; i ++) { + linebuf[i] = *(char *)(addr+i); + } + } else { + read_dataflash(addr, linebytes, linebuf); + } + for (i=0; i<linebytes; i++) + { +/* if (size == 4) + printf(" %08x", *uip++); + else if (size == 2) + printf(" %04x", *usp++); + else +*/ + printf(" %02x", *ucp++); +// addr += size; + addr++; + } + printf(" "); + cp = linebuf; + for (i=0; i<linebytes; i++) { + if ((*cp < 0x20) || (*cp > 0x7e)) + printf("."); + else + printf("%c", *cp); + cp++; + } + printf("\n"); + nbytes -= linebytes; + } while (nbytes > 0); + return 0; +} +#endif + +//*-------------------------------------------------------------------------------------- +//* Function Name : AT91F_SetPLL +//* Object : Set the PLLA to 180Mhz and Master clock to 60 Mhz +//* Input Parameters : +//* Output Parameters : +//*-------------------------------------------------------------------------------------- +static unsigned int AT91F_SetPLL(void) +{ + AT91_REG tmp; + AT91PS_PMC pPmc = AT91C_BASE_PMC; + AT91PS_CKGR pCkgr = AT91C_BASE_CKGR; + + pPmc->PMC_IDR = 0xFFFFFFFF; + + /* -Setup the PLL A */ + pCkgr->CKGR_PLLAR = AT91C_PLLA_VALUE; + + while (!(*AT91C_PMC_SR & AT91C_PMC_LOCKA)); + + /* - Switch Master Clock from PLLB to PLLA/3 */ + tmp = pPmc->PMC_MCKR; + /* See Atmel Errata #27 and #28 */ + if (tmp & 0x0000001C) { + tmp = (tmp & ~0x0000001C); + pPmc->PMC_MCKR = tmp; + while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY)); + } + if (tmp != 0x00000202) { + pPmc->PMC_MCKR = 0x00000202; + if ((tmp & 0x00000003) != 0x00000002) + while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY)); + } + + return 1; +} + + +//*-------------------------------------------------------------------------------------- +//* Function Name : AT91F_ResetRegisters +//* Object : Restore the initial state to registers +//* Input Parameters : +//* Output Parameters : +//*-------------------------------------------------------------------------------------- +static unsigned int AT91F_ResetRegisters(void) +{ + volatile int i = 0; + + /* set the PIOs in input*/ + /* This disables the UART output, so dont execute for now*/ + +#ifndef DEBUGOUT + *AT91C_PIOA_ODR = 0xFFFFFFFF; /* Disables all the output pins */ + *AT91C_PIOA_PER = 0xFFFFFFFF; /* Enables the PIO to control all the pins */ +#endif + + AT91F_AIC_DisableIt (AT91C_BASE_AIC, AT91C_ID_SYS); + /* close all peripheral clocks */ + +#ifndef DEBUGOUT + AT91C_BASE_PMC->PMC_PCDR = 0xFFFFFFFC; +#endif + /* Disable core interrupts and set supervisor mode */ + __asm__ ("msr CPSR_c, #0xDF"); //* ARM_MODE_SYS(0x1F) | I_BIT(0x80) | F_BIT(0x40) + /* Clear all the interrupts */ + *AT91C_AIC_ICCR = 0xffffffff; + + /* read the AIC_IVR and AIC_FVR */ + i = *AT91C_AIC_IVR; + i = *AT91C_AIC_FVR; + + /* write the end of interrupt control register */ + *AT91C_AIC_EOICR = 0; + + return 1; +} + + +static int AT91F_LoadBoot(void) +{ +// volatile unsigned int crc1 = 0, crc2 = 0; + volatile unsigned int SizeToDownload = 0x21400; + volatile unsigned int AddressToDownload = AT91C_BOOT_ADDR; + +#if 0 + /* Read vector 6 to extract size to load */ + if (read_dataflash(AT91C_BOOT_DATAFLASH_ADDR, 32, + (char *)AddressToDownload) != AT91C_DATAFLASH_OK) + { + printf("Bad Code Size\n"); + return IMAGE_BAD_SIZE; + } + /* calculate the size to download */ + SizeToDownload = *(int *)(AddressToDownload + AT91C_OFFSET_VECT6); +#endif + +// printf("\nLoad UBOOT from dataflash[%x] to SDRAM[%x]\n", +// AT91C_BOOT_DATAFLASH_ADDR, AT91C_BOOT_ADDR); + if (read_dataflash(AT91C_BOOT_DATAFLASH_ADDR, SizeToDownload + 8, + (char *)AddressToDownload) != AT91C_DATAFLASH_OK) + { + printf("F DF RD\n"); + return IMAGE_READ_FAILURE; + } +#if 0 + pAT91->CRC32((const unsigned char *)AT91C_BOOT_ADDR, + (unsigned int)SizeToDownload , (unsigned int *)&crc2); + crc1 = (int)(*(char *)(AddressToDownload + SizeToDownload)) + + (int)(*(char *)(AddressToDownload + SizeToDownload + 1) << 8) + + (int)(*(char *)(AddressToDownload + SizeToDownload + 2) << 16) + + (int)(*(char *)(AddressToDownload + SizeToDownload + 3) << 24); + + /* Restore the value of Vector 6 */ + *(int *)(AddressToDownload + AT91C_OFFSET_VECT6) = + *(int *)(AddressToDownload + SizeToDownload + 4); + + if (crc1 != crc2) { + printf("DF CRC bad %x != %x\n",crc1,crc2); + return IMAGE_CRC_ERROR; + } +#endif + return SUCCESS; +} + +static int AT91F_StartBoot(void) +{ + int sts; + if((sts = AT91F_LoadBoot()) != SUCCESS) return sts; +// printf("\n"); +// printf("PLLA[180MHz], MCK[60Mhz] ==> Start UBOOT\n"); + if (AT91F_ResetRegisters()) + { + printf("Jump"); + Jump(AT91C_BOOT_ADDR); +// LED_blink(0); + } + return IMAGE_ERROR; +} + +#if 0 +static void AT91F_RepeatedStartBoot(void) +{ + int i; + for(i = 0; i < CRC_RETRIES; i++) { + if(AT91F_StartBoot() != IMAGE_CRC_ERROR){ +// LED_blink(1); + return; + } + } + return; +} +#endif + +#define TRUE 1 +#define FALSE 0 +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_VERSION 1 + +struct trx_header { + unsigned int magic; + unsigned int len; + unsigned int crc32; + unsigned int flag_version; + unsigned int offsets[3]; +}; + +#define AT91C_MCI_TIMEOUT 1000000 + +extern AT91S_MciDevice MCI_Device; +extern void AT91F_MCIDeviceWaitReady(unsigned int); +extern int AT91F_MCI_ReadBlockSwab(AT91PS_MciDevice, int, unsigned int *, int); + +int Program_From_MCI(void) +{ + int i; + unsigned int Max_Read_DataBlock_Length; + int block = 0; + int buffer = AT91C_DOWNLOAD_BASE_ADDRESS; + int bufpos = AT91C_DOWNLOAD_BASE_ADDRESS; + int NbPage = 0; + struct trx_header *p; + + p = (struct trx_header *)bufpos; + + Max_Read_DataBlock_Length = MCI_Device.pMCI_DeviceFeatures->Max_Read_DataBlock_Length; + + AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); + + AT91F_MCI_ReadBlockSwab(&MCI_Device, block*Max_Read_DataBlock_Length, (unsigned int *)bufpos, Max_Read_DataBlock_Length); + + if (p->magic != TRX_MAGIC) { + printf("Inv IMG 0x%08x\n", p->magic); + return FALSE; + } + + printf("RDSD"); + AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC7 | AT91C_PIO_PC15 | AT91C_PIO_PC8 | AT91C_PIO_PC14; + for (i=0; i<(p->len/512); i++) { + AT91F_MCI_ReadBlockSwab(&MCI_Device, block*Max_Read_DataBlock_Length, (unsigned int *)bufpos, Max_Read_DataBlock_Length); + block++; + bufpos += Max_Read_DataBlock_Length; + } + + NbPage = 0; + i = dataflash_info[0].Device.pages_number; + while(i >>= 1) + NbPage++; + i = ((p->offsets[1] - p->offsets[0])/ 512) + 1 + (NbPage << 13) + (dataflash_info[0].Device.pages_size << 17); + *(int *)(buffer + p->offsets[0] + AT91C_OFFSET_VECT6) = i; + + printf(" WDFB"); + AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC7 | AT91C_PIO_PC15 | AT91C_PIO_PC14; + AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC8; + write_dataflash(0xc0000000, buffer + p->offsets[0], p->offsets[1] - p->offsets[0]); + printf(" WUB"); + AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC7 | AT91C_PIO_PC15; + AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC8 | AT91C_PIO_PC14; + write_dataflash(0xc0008000, buffer + p->offsets[1], p->offsets[2] - p->offsets[1]); + printf(" WKRFS"); + AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC8 | AT91C_PIO_PC15; + AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC7 | AT91C_PIO_PC14; + write_dataflash(0xc0042000, buffer + p->offsets[2], p->len - p->offsets[2]); + AT91C_BASE_PIOC->PIO_CODR = AT91C_PIO_PC8 | AT91C_PIO_PC14; + AT91C_BASE_PIOC->PIO_SODR = AT91C_PIO_PC7 | AT91C_PIO_PC15; + return TRUE; +} + +//*---------------------------------------------------------------------------- +//* Function Name : main +//* Object : Main function +//* Input Parameters : none +//* Output Parameters : True +//*---------------------------------------------------------------------------- +int main(void) +{ +#ifdef XMODEM + AT91PS_Buffer pXmBuffer; + AT91PS_SvcComm pSvcXmodem; +#endif + AT91S_SvcTempo svcBootTempo; // Link to a AT91S_Tempo object + unsigned int ix; + volatile unsigned int AddressToDownload, SizeToDownload; + unsigned int DeviceAddress = 0; + char command = 0; +#ifdef XMODEM + volatile int i = 0; + unsigned int crc1 = 0, crc2 = 0; + volatile int device; + int NbPage; +#endif + volatile int Nb_Device = 0; + int mci_present = 0; + + pAT91 = AT91C_ROM_BOOT_ADDRESS; + + if (!AT91F_SetPLL()) + { + printf("F SetPLL"); + while(1); + } + + at91_init_uarts(); + + /* Tempo Initialisation */ + pAT91->OpenCtlTempo(&ctlTempo, (void *) &(pAT91->SYSTIMER_DESC)); + ctlTempo.CtlTempoStart((void *) &(pAT91->SYSTIMER_DESC)); + + // Attach the tempo to a tempo controler + ctlTempo.CtlTempoCreate(&ctlTempo, &svcBootTempo); +// LED_init(); +// LED_blink(2); + +#ifdef XMODEM + /* Xmodem Initialisation */ + pXmBuffer = pAT91->OpenSBuffer(&sXmBuffer); + pSvcXmodem = pAT91->OpenSvcXmodem(&svcXmodem, + (AT91PS_USART)AT91C_BASE_DBGU, &ctlTempo); + pAT91->OpenPipe(&xmodemPipe, pSvcXmodem, pXmBuffer); +#endif + + /* System Timer initialization */ + AT91F_AIC_ConfigureIt( + AT91C_BASE_AIC, // AIC base address + AT91C_ID_SYS, // System peripheral ID + AT91C_AIC_PRIOR_HIGHEST, // Max priority + AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, // Level sensitive + AT91F_ST_ASM_HANDLER + ); + /* Enable ST interrupt */ + AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS); + +#ifndef PRODTEST + /* Start tempo to start Boot in a delay of + * AT91C_DELAY_TO_BOOT sec if no key pressed */ + svcBootTempo.Start(&svcBootTempo, AT91C_DELAY_TO_BOOT, + 0, AT91F_StartBoot, NULL); +#endif + + while(1) + { + while(command == 0) + { + AddressToDownload = AT91C_DOWNLOAD_BASE_ADDRESS; + SizeToDownload = AT91C_DOWNLOAD_MAX_SIZE; + DeviceAddress = 0; + + /* try to detect Dataflash */ + if (!Nb_Device) + Nb_Device = AT91F_DataflashInit(); + + mci_present = AT91F_DisplayMenu(); + +#ifdef PRODTEST + if (mci_present) { + if (Program_From_MCI()) + AT91F_StartBoot(); + } +#endif + + message[0] = 0; + AT91F_ReadLine ("Enter: ", message); + +#ifndef PRODTEST + /* stop tempo ==> stop autoboot */ + svcBootTempo.Stop(&svcBootTempo); +#endif + + command = message[0]; + for(ix = 1; (message[ix] == ' ') && (ix < 12); ix++); // Skip some whitespace + + if(!AsciiToHex(&message[ix], &DeviceAddress) ) + DeviceAddress = 0; // Illegal DeviceAddress + + switch(command) + { +#ifdef XMODEM + case '1': + case '2': + case '5': + if(command == '1') { + DeviceAddress = 0xC0000000; +// printf("Download DataflashBoot.bin to [0x%x]\n", DeviceAddress); + } else if(command == '2') { + DeviceAddress = AT91C_BOOT_DATAFLASH_ADDR; +// printf("Download u-boot.bin to [0x%x]\n", DeviceAddress); + } else { +// printf("Download Dataflash to [0x%x]\n", DeviceAddress); + } + switch(DeviceAddress & 0xFF000000) + { + case CFG_DATAFLASH_LOGIC_ADDR_CS0: + if (dataflash_info[0].id == 0){ + printf("No DF"); + AT91F_WaitKeyPressed(); + command = 0; + } + + device = 0; + break; + + case CFG_DATAFLASH_LOGIC_ADDR_CS3: + if (dataflash_info[1].id == 0){ + printf("No DF"); + AT91F_WaitKeyPressed(); + command = 0; + } + device = 1; + break; + + default: + command = 0; + break; + } + break; +#endif + + case '3': + if (mci_present) + Program_From_MCI(); + command = 0; + break; + + case '4': + AT91F_StartBoot(); + command = 0; + break; + +#ifdef MEMDISP + case '6': + do + { + AT91F_MemoryDisplay(DeviceAddress, 256); + AT91F_ReadLine (NULL, message); + DeviceAddress += 0x100; + } + while(message[0] == '\0'); + command = 0; + break; +#endif + + case '7': + switch(DeviceAddress & 0xFF000000) + { + case CFG_DATAFLASH_LOGIC_ADDR_CS0: + break; + case CFG_DATAFLASH_LOGIC_ADDR_CS3: + break; + default: + command = 0; + break; + } + + if (command != 0) { + AT91F_ReadLine ("RDY ERA\nSure?", + message); + if(message[0] == 'Y' || message[0] == 'y') { + erase_dataflash(DeviceAddress & 0xFF000000); +// printf("Erase complete\n\n"); + } +// else +// printf("Erase aborted\n"); + } + command = 0; + + break; + + default: + command = 0; + break; + } + } +#ifdef XMODEM + for(i = 0; i <= AT91C_DOWNLOAD_MAX_SIZE; i++) + *(unsigned char *)(AddressToDownload + i) = 0; + + xmodemPipe.Read(&xmodemPipe, (char *)AddressToDownload, + SizeToDownload, XmodemProtocol, 0); + while(XmodemComplete !=1); + SizeToDownload = (unsigned int)((svcXmodem.pData) - + (unsigned int)AddressToDownload); + + /* Modification of vector 6 */ + if ((DeviceAddress == CFG_DATAFLASH_LOGIC_ADDR_CS0)) { + // Vector 6 must be compliant to the BootRom description (ref Datasheet) + NbPage = 0; + i = dataflash_info[device].Device.pages_number; + while(i >>= 1) + NbPage++; + i = (SizeToDownload / 512)+1 + (NbPage << 13) + + (dataflash_info[device].Device.pages_size << 17); //+4 to add crc32 + SizeToDownload = 512 * (i &0xFF); + } + else + { + /* Save the contents of vector 6 ==> will be restored + * at boot time (AT91F_StartBoot) */ + *(int *)(AddressToDownload + SizeToDownload + 4) = + *(int *)(AddressToDownload + AT91C_OFFSET_VECT6); + /* Modify Vector 6 to contain the size of the + * file to copy (Dataflash -> SDRAM)*/ + i = SizeToDownload; + } + + *(int *)(AddressToDownload + AT91C_OFFSET_VECT6) = i; +// printf("\nModification of Arm Vector 6 :%x\n", i); + +// printf("\nWrite %d bytes in DataFlash [0x%x]\n",SizeToDownload, DeviceAddress); + crc1 = 0; + pAT91->CRC32((const unsigned char *)AddressToDownload, SizeToDownload , &crc1); + + /* Add the crc32 at the end of the code */ + *(char *)(AddressToDownload + SizeToDownload) = (char)(crc1 & 0x000000FF); + *(char *)(AddressToDownload + SizeToDownload + 1) = (char)((crc1 & 0x0000FF00) >> 8); + *(char *)(AddressToDownload + SizeToDownload + 2) = (char)((crc1 & 0x00FF0000) >> 16); + *(char *)(AddressToDownload + SizeToDownload + 3) = (char)((crc1 & 0xFF000000) >> 24); + + /* write dataflash */ + write_dataflash (DeviceAddress, AddressToDownload, (SizeToDownload + 8)); + + /* clear the buffer before read */ + for(i=0; i <= SizeToDownload; i++) + *(unsigned char *)(AddressToDownload + i) = 0; + + /* Read dataflash to check the validity of the data */ + read_dataflash (DeviceAddress, (SizeToDownload + 4), (char *)(AddressToDownload)); + + printf("VFY: "); + crc2 = 0; + + pAT91->CRC32((const unsigned char *)AddressToDownload, SizeToDownload , &crc2); + crc1 = (int)(*(char *)(AddressToDownload + SizeToDownload)) + + (int)(*(char *)(AddressToDownload + SizeToDownload + 1) << 8) + + (int)(*(char *)(AddressToDownload + SizeToDownload + 2) << 16) + + (int)(*(char *)(AddressToDownload + SizeToDownload + 3) << 24); + + if (crc1 != crc2) + printf("ERR"); + else + printf("OK"); + + command = 0; + XmodemComplete = 0; + AT91F_WaitKeyPressed(); +#endif + } +} + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/main.h.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/main.h.svn-base new file mode 100644 index 0000000..a8cd325 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/main.h.svn-base @@ -0,0 +1,43 @@ +//*---------------------------------------------------------------------------- +//* ATMEL Microcontroller Software Support - ROUSSET - +//*---------------------------------------------------------------------------- +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*---------------------------------------------------------------------------- +//* File Name : main.h +//* Object : +//* +//* 1.0 27/03/03 HIi : Creation +//* 1.01 03/05/04 HIi : AT9C_VERSION incremented to 1.01 +//* 1.02 15/06/04 HIi : AT9C_VERSION incremented to 1.02 ==> +//* Add crc32 to verify dataflash download +//* 1.03 18/04/05 MLC : AT91C_VERSION incremented to 1.03g +//* Repeat boot on CRC Failure +//* Change Page Size to 1056 +//* Reduce SPI speed to 4 Mbit +//* Change U-Boot boot address to a 1056 byte page boundary +//* 1.04 30/04/05 USA : AT91C_VERSION incremented to 1.04 +//* 1.05 07/08/06 USA : AT91C_VERSION incremented to 1.05 +//* Will only support loading Dataflashboot.bin and U-Boot +//*---------------------------------------------------------------------------- + +#ifndef main_h +#define main_h + +#include "embedded_services.h" + +#define AT91C_DOWNLOAD_BASE_ADDRESS 0x20000000 +#define AT91C_DOWNLOAD_MAX_SIZE 0x00040000 + +#define AT91C_OFFSET_VECT6 0x14 //* Offset for ARM vector 6 + +#define AT91C_VERSION "VER 1.05" + + +// Global variables and functions definition +extern unsigned int GetTickCount(void); +#endif + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/mci_device.c.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/mci_device.c.svn-base new file mode 100644 index 0000000..cce74a3 --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/mci_device.c.svn-base @@ -0,0 +1,743 @@ +//*---------------------------------------------------------------------------- +//* ATMEL Microcontroller Software Support - ROUSSET - +//*---------------------------------------------------------------------------- +//* The software is delivered "AS IS" without warranty or condition of any +//* kind, either express, implied or statutory. This includes without +//* limitation any warranty or condition with respect to merchantability or +//* fitness for any particular purpose, or against the infringements of +//* intellectual property rights of others. +//*---------------------------------------------------------------------------- +//* File Name : mci_device.c +//* Object : TEST DataFlash Functions +//* Creation : FB 26/11/2002 +//* +//*---------------------------------------------------------------------------- + +#include <AT91C_MCI_Device.h> +#include "stdio.h" + +#define AT91C_MCI_TIMEOUT 1000000 /* For AT91F_MCIDeviceWaitReady */ +#define BUFFER_SIZE_MCI_DEVICE 512 +#define MASTER_CLOCK 60000000 +#define FALSE 0 +#define TRUE 1 + +//* External Functions +extern void AT91F_ASM_MCI_Handler(void); +//* Global Variables +AT91S_MciDeviceFeatures MCI_Device_Features; +AT91S_MciDeviceDesc MCI_Device_Desc; +AT91S_MciDevice MCI_Device; + +#undef ENABLE_WRITE +#undef MMC + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_SendCommand +//* \brief Generic function to send a command to the MMC or SDCard +//*---------------------------------------------------------------------------- +int AT91F_MCI_SendCommand ( + AT91PS_MciDevice pMCI_Device, + unsigned int Cmd, + unsigned int Arg) +{ + unsigned int error,status; + //unsigned int tick=0; + + // Send the command + AT91C_BASE_MCI->MCI_ARGR = Arg; + AT91C_BASE_MCI->MCI_CMDR = Cmd; + + // wait for CMDRDY Status flag to read the response + do + { + status = AT91C_BASE_MCI->MCI_SR; + //tick++; + } + while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); + + // Test error ==> if crc error and response R3 ==> don't check error + error = (AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR; + if(error != 0 ) + { + // if the command is SEND_OP_COND the CRC error flag is always present (cf : R3 response) + if ( (Cmd != AT91C_SDCARD_APP_OP_COND_CMD) && (Cmd != AT91C_MMC_SEND_OP_COND_CMD) ) + return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); + else + { + if (error != AT91C_MCI_RCRCE) + return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); + } + } + return AT91C_CMD_SEND_OK; +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_SDCard_SendAppCommand +//* \brief Specific function to send a specific command to the SDCard +//*---------------------------------------------------------------------------- +int AT91F_MCI_SDCard_SendAppCommand ( + AT91PS_MciDevice pMCI_Device, + unsigned int Cmd_App, + unsigned int Arg ) +{ + unsigned int status; + //unsigned int tick=0; + + // Send the CMD55 for application specific command + AT91C_BASE_MCI->MCI_ARGR = (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address << 16 ); + AT91C_BASE_MCI->MCI_CMDR = AT91C_APP_CMD; + + // wait for CMDRDY Status flag to read the response + do + { + status = AT91C_BASE_MCI->MCI_SR; + //tick++; + } + while( !(status & AT91C_MCI_CMDRDY) );//&& (tick<100) ); + + // if an error occurs + if (((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR) != 0 ) + return ((AT91C_BASE_MCI->MCI_SR) & AT91C_MCI_SR_ERROR); + + // check if it is a specific command and then send the command + if ( (Cmd_App && AT91C_SDCARD_APP_ALL_CMD) == 0) + return AT91C_CMD_SEND_ERROR; + + return( AT91F_MCI_SendCommand(pMCI_Device,Cmd_App,Arg) ); +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_GetStatus +//* \brief Addressed card sends its status register +//*---------------------------------------------------------------------------- +int AT91F_MCI_GetStatus(AT91PS_MciDevice pMCI_Device,unsigned int relative_card_address) +{ + if (AT91F_MCI_SendCommand(pMCI_Device, + AT91C_SEND_STATUS_CMD, + relative_card_address <<16) == AT91C_CMD_SEND_OK) + return (AT91C_BASE_MCI->MCI_RSPR[0]); + + return AT91C_CMD_SEND_ERROR; +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_Device_Handler +//* \brief MCI C interrupt handler +//*---------------------------------------------------------------------------- +void AT91F_MCI_Device_Handler( + AT91PS_MciDevice pMCI_Device, + unsigned int status) +{ + // If End of Tx Buffer Empty interrupt occurred + if ( status & AT91C_MCI_TXBUFE ) + { + AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_TXBUFE; + AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTDIS; + + pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; + } // End of if AT91C_MCI_TXBUFF + + // If End of Rx Buffer Full interrupt occurred + if ( status & AT91C_MCI_RXBUFF ) + { + AT91C_BASE_MCI->MCI_IDR = AT91C_MCI_RXBUFF; + AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTDIS; + + pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_IDLE; + } // End of if AT91C_MCI_RXBUFF + +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_Handler +//* \brief MCI Handler +//*---------------------------------------------------------------------------- +void AT91F_MCI_Handler(void) +{ + int status; + + status = ( AT91C_BASE_MCI->MCI_SR & AT91C_BASE_MCI->MCI_IMR ); + + AT91F_MCI_Device_Handler(&MCI_Device,status); +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_ReadBlock +//* \brief Read an ENTIRE block or PARTIAL block +//*---------------------------------------------------------------------------- +int AT91F_MCI_ReadBlock( + AT91PS_MciDevice pMCI_Device, + int src, + unsigned int *dataBuffer, + int sizeToRead ) +{ + //////////////////////////////////////////////////////////////////////////////////////////// + if(pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) + return AT91C_READ_ERROR; + + if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) + return AT91C_READ_ERROR; + + if ( (src + sizeToRead) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) + return AT91C_READ_ERROR; + + // If source does not fit a begin of a block + if ( (src % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) + return AT91C_READ_ERROR; + + // Test if the MMC supports Partial Read Block + // ALWAYS SUPPORTED IN SD Memory Card + if( (sizeToRead < pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) + && (pMCI_Device->pMCI_DeviceFeatures->Read_Partial == 0x00) ) + return AT91C_READ_ERROR; + + if( sizeToRead > pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) + return AT91C_READ_ERROR; + //////////////////////////////////////////////////////////////////////////////////////////// + + // Init Mode Register + AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); + + if (sizeToRead %4) + sizeToRead = (sizeToRead /4)+1; + else + sizeToRead = sizeToRead/4; + + AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); + AT91C_BASE_PDC_MCI->PDC_RPR = (unsigned int)dataBuffer; + AT91C_BASE_PDC_MCI->PDC_RCR = sizeToRead; + + // Send the Read single block command + if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_READ_SINGLE_BLOCK_CMD, src) != AT91C_CMD_SEND_OK ) + return AT91C_READ_ERROR; + + pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_RX_SINGLE_BLOCK; + + // Enable AT91C_MCI_RXBUFF Interrupt + AT91C_BASE_MCI->MCI_IER = AT91C_MCI_RXBUFF; + + // (PDC) Receiver Transfer Enable + AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_RXTEN; + + return AT91C_READ_OK; +} + + +#ifdef ENABLE_WRITE +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_WriteBlock +//* \brief Write an ENTIRE block but not always PARTIAL block !!! +//*---------------------------------------------------------------------------- +int AT91F_MCI_WriteBlock( + AT91PS_MciDevice pMCI_Device, + int dest, + unsigned int *dataBuffer, + int sizeToWrite ) +{ + //////////////////////////////////////////////////////////////////////////////////////////// + if( pMCI_Device->pMCI_DeviceDesc->state != AT91C_MCI_IDLE) + return AT91C_WRITE_ERROR; + + if( (AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address) & AT91C_SR_READY_FOR_DATA) != AT91C_SR_READY_FOR_DATA) + return AT91C_WRITE_ERROR; + + if ( (dest + sizeToWrite) > pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity ) + return AT91C_WRITE_ERROR; + + // If source does not fit a begin of a block + if ( (dest % pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) != 0 ) + return AT91C_WRITE_ERROR; + + // Test if the MMC supports Partial Write Block + if( (sizeToWrite < pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length) + && (pMCI_Device->pMCI_DeviceFeatures->Write_Partial == 0x00) ) + return AT91C_WRITE_ERROR; + + if( sizeToWrite > pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length ) + return AT91C_WRITE_ERROR; + //////////////////////////////////////////////////////////////////////////////////////////// + + // Init Mode Register + AT91C_BASE_MCI->MCI_MR |= ((pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length << 16) | AT91C_MCI_PDCMODE); + + if (sizeToWrite %4) + sizeToWrite = (sizeToWrite /4)+1; + else + sizeToWrite = sizeToWrite/4; + + // Init PDC for write sequence + AT91C_BASE_PDC_MCI->PDC_PTCR = (AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS); + AT91C_BASE_PDC_MCI->PDC_TPR = (unsigned int) dataBuffer; + AT91C_BASE_PDC_MCI->PDC_TCR = sizeToWrite; + + // Send the write single block command + if ( AT91F_MCI_SendCommand(pMCI_Device, AT91C_WRITE_BLOCK_CMD, dest) != AT91C_CMD_SEND_OK) + return AT91C_WRITE_ERROR; + + pMCI_Device->pMCI_DeviceDesc->state = AT91C_MCI_TX_SINGLE_BLOCK; + + // Enable AT91C_MCI_TXBUFE Interrupt + AT91C_BASE_MCI->MCI_IER = AT91C_MCI_TXBUFE; + + // Enables TX for PDC transfert requests + AT91C_BASE_PDC_MCI->PDC_PTCR = AT91C_PDC_TXTEN; + + return AT91C_WRITE_OK; +} +#endif + +#ifdef MMC +//*------------------------------------------------------------------------------------------------------------ +//* \fn AT91F_MCI_MMC_SelectCard +//* \brief Toggles a card between the Stand_by and Transfer states or between Programming and Disconnect states +//*------------------------------------------------------------------------------------------------------------ +int AT91F_MCI_MMC_SelectCard(AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address) +{ + int status; + + //* Check if the MMC card chosen is already the selected one + status = AT91F_MCI_GetStatus(pMCI_Device,relative_card_address); + + if (status < 0) + return AT91C_CARD_SELECTED_ERROR; + + if ((status & AT91C_SR_CARD_SELECTED) == AT91C_SR_CARD_SELECTED) + return AT91C_CARD_SELECTED_OK; + + //* Search for the MMC Card to be selected, status = the Corresponding Device Number + status = 0; + while( (pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address != relative_card_address) + && (status < AT91C_MAX_MCI_CARDS) ) + status++; + + if (status > AT91C_MAX_MCI_CARDS) + return AT91C_CARD_SELECTED_ERROR; + + if (AT91F_MCI_SendCommand( pMCI_Device, + AT91C_SEL_DESEL_CARD_CMD, + pMCI_Device->pMCI_DeviceFeatures[status].Relative_Card_Address << 16) == AT91C_CMD_SEND_OK) + return AT91C_CARD_SELECTED_OK; + return AT91C_CARD_SELECTED_ERROR; +} +#endif + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_GetCSD +//* \brief Asks to the specified card to send its CSD +//*---------------------------------------------------------------------------- +int AT91F_MCI_GetCSD (AT91PS_MciDevice pMCI_Device, unsigned int relative_card_address , unsigned int * response) +{ + + if(AT91F_MCI_SendCommand(pMCI_Device, + AT91C_SEND_CSD_CMD, + (relative_card_address << 16)) != AT91C_CMD_SEND_OK) + return AT91C_CMD_SEND_ERROR; + + response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; + response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; + response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; + response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; + + return AT91C_CMD_SEND_OK; +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_SetBlocklength +//* \brief Select a block length for all following block commands (R/W) +//*---------------------------------------------------------------------------- +int AT91F_MCI_SetBlocklength(AT91PS_MciDevice pMCI_Device,unsigned int length) +{ + return( AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_BLOCKLEN_CMD, length) ); +} + +#ifdef MMC +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_MMC_GetAllOCR +//* \brief Asks to all cards to send their operations conditions +//*---------------------------------------------------------------------------- +int AT91F_MCI_MMC_GetAllOCR (AT91PS_MciDevice pMCI_Device) +{ + unsigned int response =0x0; + + while(1) + { + response = AT91F_MCI_SendCommand(pMCI_Device, + AT91C_MMC_SEND_OP_COND_CMD, + AT91C_MMC_HOST_VOLTAGE_RANGE); + if (response != AT91C_CMD_SEND_OK) + return AT91C_INIT_ERROR; + + response = AT91C_BASE_MCI->MCI_RSPR[0]; + + if ( (response & AT91C_CARD_POWER_UP_BUSY) == AT91C_CARD_POWER_UP_BUSY) + return(response); + } +} +#endif + +#ifdef MMC +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_MMC_GetAllCID +//* \brief Asks to the MMC on the chosen slot to send its CID +//*---------------------------------------------------------------------------- +int AT91F_MCI_MMC_GetAllCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) +{ + int Nb_Cards_Found=-1; + + while(1) + { + if(AT91F_MCI_SendCommand(pMCI_Device, + AT91C_MMC_ALL_SEND_CID_CMD, + AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) + return Nb_Cards_Found; + else + { + Nb_Cards_Found = 0; + //* Assignation of the relative address to the MMC CARD + pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Relative_Card_Address = Nb_Cards_Found + AT91C_FIRST_RCA; + //* Set the insert flag + pMCI_Device->pMCI_DeviceFeatures[Nb_Cards_Found].Card_Inserted = AT91C_MMC_CARD_INSERTED; + + if (AT91F_MCI_SendCommand(pMCI_Device, + AT91C_MMC_SET_RELATIVE_ADDR_CMD, + (Nb_Cards_Found + AT91C_FIRST_RCA) << 16) != AT91C_CMD_SEND_OK) + return AT91C_CMD_SEND_ERROR; + + //* If no error during assignation address ==> Increment Nb_cards_Found + Nb_Cards_Found++ ; + } + } +} +#endif +#ifdef MMC +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_MMC_Init +//* \brief Return the MMC initialisation status +//*---------------------------------------------------------------------------- +int AT91F_MCI_MMC_Init (AT91PS_MciDevice pMCI_Device) +{ + unsigned int tab_response[4]; + unsigned int mult,blocknr; + unsigned int i,Nb_Cards_Found=0; + + //* Resets all MMC Cards in Idle state + AT91F_MCI_SendCommand(pMCI_Device, AT91C_MMC_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); + + if(AT91F_MCI_MMC_GetAllOCR(pMCI_Device) == AT91C_INIT_ERROR) + return AT91C_INIT_ERROR; + + Nb_Cards_Found = AT91F_MCI_MMC_GetAllCID(pMCI_Device,tab_response); + if (Nb_Cards_Found != AT91C_CMD_SEND_ERROR) + { + //* Set the Mode Register + AT91C_BASE_MCI->MCI_MR = AT91C_MCI_MR_PDCMODE; + + for(i = 0; i < Nb_Cards_Found; i++) + { + if (AT91F_MCI_GetCSD(pMCI_Device, + pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address, + tab_response) != AT91C_CMD_SEND_OK) + pMCI_Device->pMCI_DeviceFeatures[i].Relative_Card_Address = 0; + else + { + pMCI_Device->pMCI_DeviceFeatures[i].Max_Read_DataBlock_Length = 1 << ((tab_response[1] >> AT91C_CSD_RD_B_LEN_S) & AT91C_CSD_RD_B_LEN_M ); + pMCI_Device->pMCI_DeviceFeatures[i].Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); + pMCI_Device->pMCI_DeviceFeatures[i].Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v22_SECT_SIZE_S) & AT91C_CSD_v22_SECT_SIZE_M ); + pMCI_Device->pMCI_DeviceFeatures[i].Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; + pMCI_Device->pMCI_DeviceFeatures[i].Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; + + // None in MMC specification version 2.2 + pMCI_Device->pMCI_DeviceFeatures[i].Erase_Block_Enable = 0; + + pMCI_Device->pMCI_DeviceFeatures[i].Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; + pMCI_Device->pMCI_DeviceFeatures[i].Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; + + //// Compute Memory Capacity + // compute MULT + mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); + // compute MSB of C_SIZE + blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; + // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR + blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); + + pMCI_Device->pMCI_DeviceFeatures[i].Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures[i].Max_Read_DataBlock_Length * blocknr; + //// End of Compute Memory Capacity + + } // end of else + } // end of for + + return AT91C_INIT_OK; + } // end of if + + return AT91C_INIT_ERROR; +} +#endif + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_SDCard_GetOCR +//* \brief Asks to all cards to send their operations conditions +//*---------------------------------------------------------------------------- +int AT91F_MCI_SDCard_GetOCR (AT91PS_MciDevice pMCI_Device) +{ + unsigned int response =0x0; + + // The RCA to be used for CMD55 in Idle state shall be the card's default RCA=0x0000. + pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = 0x0; + + while( (response & AT91C_CARD_POWER_UP_BUSY) != AT91C_CARD_POWER_UP_BUSY ) + { + response = AT91F_MCI_SDCard_SendAppCommand(pMCI_Device, + AT91C_SDCARD_APP_OP_COND_CMD, + AT91C_MMC_HOST_VOLTAGE_RANGE); + if (response != AT91C_CMD_SEND_OK) + return AT91C_INIT_ERROR; + + response = AT91C_BASE_MCI->MCI_RSPR[0]; + } + + return(AT91C_BASE_MCI->MCI_RSPR[0]); +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_SDCard_GetCID +//* \brief Asks to the SDCard on the chosen slot to send its CID +//*---------------------------------------------------------------------------- +int AT91F_MCI_SDCard_GetCID (AT91PS_MciDevice pMCI_Device, unsigned int *response) +{ + if(AT91F_MCI_SendCommand(pMCI_Device, + AT91C_ALL_SEND_CID_CMD, + AT91C_NO_ARGUMENT) != AT91C_CMD_SEND_OK) + return AT91C_CMD_SEND_ERROR; + + response[0] = AT91C_BASE_MCI->MCI_RSPR[0]; + response[1] = AT91C_BASE_MCI->MCI_RSPR[1]; + response[2] = AT91C_BASE_MCI->MCI_RSPR[2]; + response[3] = AT91C_BASE_MCI->MCI_RSPR[3]; + + return AT91C_CMD_SEND_OK; +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_SDCard_SetBusWidth +//* \brief Set bus width for SDCard +//*---------------------------------------------------------------------------- +int AT91F_MCI_SDCard_SetBusWidth(AT91PS_MciDevice pMCI_Device) +{ + volatile int ret_value; + char bus_width; + + do + { + ret_value =AT91F_MCI_GetStatus(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address); + } + while((ret_value > 0) && ((ret_value & AT91C_SR_READY_FOR_DATA) == 0)); + + // Select Card + AT91F_MCI_SendCommand(pMCI_Device, + AT91C_SEL_DESEL_CARD_CMD, + (pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address)<<16); + + // Set bus width for Sdcard + if(pMCI_Device->pMCI_DeviceDesc->SDCard_bus_width == AT91C_MCI_SCDBUS) + bus_width = AT91C_BUS_WIDTH_4BITS; + else bus_width = AT91C_BUS_WIDTH_1BIT; + + if (AT91F_MCI_SDCard_SendAppCommand(pMCI_Device,AT91C_SDCARD_SET_BUS_WIDTH_CMD,bus_width) != AT91C_CMD_SEND_OK) + return AT91C_CMD_SEND_ERROR; + + return AT91C_CMD_SEND_OK; +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_SDCard_Init +//* \brief Return the SDCard initialisation status +//*---------------------------------------------------------------------------- +int AT91F_MCI_SDCard_Init (AT91PS_MciDevice pMCI_Device) +{ + unsigned int tab_response[4]; + unsigned int mult,blocknr; + + AT91F_MCI_SendCommand(pMCI_Device, AT91C_GO_IDLE_STATE_CMD, AT91C_NO_ARGUMENT); + + if(AT91F_MCI_SDCard_GetOCR(pMCI_Device) == AT91C_INIT_ERROR) + return AT91C_INIT_ERROR; + + if (AT91F_MCI_SDCard_GetCID(pMCI_Device,tab_response) == AT91C_CMD_SEND_OK) + { + pMCI_Device->pMCI_DeviceFeatures->Card_Inserted = AT91C_SD_CARD_INSERTED; + + if (AT91F_MCI_SendCommand(pMCI_Device, AT91C_SET_RELATIVE_ADDR_CMD, 0) == AT91C_CMD_SEND_OK) + { + pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address = (AT91C_BASE_MCI->MCI_RSPR[0] >> 16); + if (AT91F_MCI_GetCSD(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Relative_Card_Address,tab_response) == AT91C_CMD_SEND_OK) + { + pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length = 1 << ((tab_response[1] >> AT91C_CSD_RD_B_LEN_S) & AT91C_CSD_RD_B_LEN_M ); + pMCI_Device->pMCI_DeviceFeatures->Max_Write_DataBlock_Length = 1 << ((tab_response[3] >> AT91C_CSD_WBLEN_S) & AT91C_CSD_WBLEN_M ); + pMCI_Device->pMCI_DeviceFeatures->Sector_Size = 1 + ((tab_response[2] >> AT91C_CSD_v21_SECT_SIZE_S) & AT91C_CSD_v21_SECT_SIZE_M ); + pMCI_Device->pMCI_DeviceFeatures->Read_Partial = (tab_response[1] >> AT91C_CSD_RD_B_PAR_S) & AT91C_CSD_RD_B_PAR_M; + pMCI_Device->pMCI_DeviceFeatures->Write_Partial = (tab_response[3] >> AT91C_CSD_WBLOCK_P_S) & AT91C_CSD_WBLOCK_P_M; + pMCI_Device->pMCI_DeviceFeatures->Erase_Block_Enable = (tab_response[3] >> AT91C_CSD_v21_ER_BLEN_EN_S) & AT91C_CSD_v21_ER_BLEN_EN_M; + pMCI_Device->pMCI_DeviceFeatures->Read_Block_Misalignment = (tab_response[1] >> AT91C_CSD_RD_B_MIS_S) & AT91C_CSD_RD_B_MIS_M; + pMCI_Device->pMCI_DeviceFeatures->Write_Block_Misalignment = (tab_response[1] >> AT91C_CSD_WR_B_MIS_S) & AT91C_CSD_WR_B_MIS_M; + + //// Compute Memory Capacity + // compute MULT + mult = 1 << ( ((tab_response[2] >> AT91C_CSD_C_SIZE_M_S) & AT91C_CSD_C_SIZE_M_M) + 2 ); + // compute MSB of C_SIZE + blocknr = ((tab_response[1] >> AT91C_CSD_CSIZE_H_S) & AT91C_CSD_CSIZE_H_M) << 2; + // compute MULT * (LSB of C-SIZE + MSB already computed + 1) = BLOCKNR + blocknr = mult * ( ( blocknr + ( (tab_response[2] >> AT91C_CSD_CSIZE_L_S) & AT91C_CSD_CSIZE_L_M) ) + 1 ); + + pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity = pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length * blocknr; + //// End of Compute Memory Capacity + printf("SD-Card: %d Bytes\n\r", pMCI_Device->pMCI_DeviceFeatures->Memory_Capacity); + + if( AT91F_MCI_SDCard_SetBusWidth(pMCI_Device) == AT91C_CMD_SEND_OK ) + { + if (AT91F_MCI_SetBlocklength(pMCI_Device,pMCI_Device->pMCI_DeviceFeatures->Max_Read_DataBlock_Length) == AT91C_CMD_SEND_OK) + return AT91C_INIT_OK; + } + } + } + } + return AT91C_INIT_ERROR; +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_CfgDevice +//* \brief This function is used to initialise MMC or SDCard Features +//*---------------------------------------------------------------------------- +void AT91F_CfgDevice(void) +{ + // Init Device Structure + + MCI_Device_Features.Relative_Card_Address = 0; + MCI_Device_Features.Card_Inserted = AT91C_CARD_REMOVED; + MCI_Device_Features.Max_Read_DataBlock_Length = 0; + MCI_Device_Features.Max_Write_DataBlock_Length = 0; + MCI_Device_Features.Read_Partial = 0; + MCI_Device_Features.Write_Partial = 0; + MCI_Device_Features.Erase_Block_Enable = 0; + MCI_Device_Features.Sector_Size = 0; + MCI_Device_Features.Memory_Capacity = 0; + + MCI_Device_Desc.state = AT91C_MCI_IDLE; + MCI_Device_Desc.SDCard_bus_width = AT91C_MCI_SCDBUS; + + // Init AT91S_DataFlash Global Structure, by default AT45DB choosen !!! + MCI_Device.pMCI_DeviceDesc = &MCI_Device_Desc; + MCI_Device.pMCI_DeviceFeatures = &MCI_Device_Features; + +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCI_Init +//* \brief Initialsise Card +//*---------------------------------------------------------------------------- +int AT91F_MCI_Init(void) +{ + +/////////////////////////////////////////////////////////////////////////////////////////// +// MCI Init : common to MMC and SDCard +/////////////////////////////////////////////////////////////////////////////////////////// + + // Set up PIO SDC_TYPE to switch on MMC/SDCard and not DataFlash Card + AT91F_PIO_CfgOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); + AT91F_PIO_SetOutput(AT91C_BASE_PIOB,AT91C_PIO_PB7); + + // Init MCI for MMC and SDCard interface + AT91F_MCI_CfgPIO(); + AT91F_MCI_CfgPMC(); + AT91F_PDC_Open(AT91C_BASE_PDC_MCI); + + // Disable all the interrupts + AT91C_BASE_MCI->MCI_IDR = 0xFFFFFFFF; + + // Init MCI Device Structures + AT91F_CfgDevice(); + + // Configure MCI interrupt + AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, + AT91C_ID_MCI, + AT91C_AIC_PRIOR_HIGHEST, + AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, + AT91F_ASM_MCI_Handler); + + // Enable MCI interrupt + AT91F_AIC_EnableIt(AT91C_BASE_AIC,AT91C_ID_MCI); + + // Enable Receiver + AT91F_US_EnableRx((AT91PS_USART) AT91C_BASE_DBGU); + + AT91F_MCI_Configure(AT91C_BASE_MCI, + AT91C_MCI_DTOR_1MEGA_CYCLES, + AT91C_MCI_MR_PDCMODE, // 15MHz for MCK = 60MHz (CLKDIV = 1) + AT91C_MCI_SDCARD_4BITS_SLOTA); + + if(AT91F_MCI_SDCard_Init(&MCI_Device) != AT91C_INIT_OK) + return FALSE; + else + return TRUE; + +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_MCIDeviceWaitReady +//* \brief Wait for MCI Device ready +//*---------------------------------------------------------------------------- +void AT91F_MCIDeviceWaitReady(unsigned int timeout) +{ + volatile int status; + + do + { + status = AT91C_BASE_MCI->MCI_SR; + timeout--; + } + while( !(status & AT91C_MCI_NOTBUSY) && (timeout>0) ); +} + +unsigned int swab32(unsigned int data) +{ + unsigned int res = 0; + + res = (data & 0x000000ff) << 24 | + (data & 0x0000ff00) << 8 | + (data & 0x00ff0000) >> 8 | + (data & 0xff000000) >> 24; + + return res; +} + +//*-------------------------------------------------------------------- +//* \fn AT91F_MCI_ReadBlockSwab +//* \brief Read Block and swap byte order +//*-------------------------------------------------------------------- +int AT91F_MCI_ReadBlockSwab( + AT91PS_MciDevice pMCI_Device, + int src, + unsigned int *databuffer, + int sizeToRead) +{ + int i; + unsigned char *buf = (unsigned char *)databuffer; + + //* Read Block 1 + for(i=0;i<BUFFER_SIZE_MCI_DEVICE;i++) + *buf++ = 0x00; + AT91F_MCI_ReadBlock(&MCI_Device,src,databuffer,sizeToRead); + + //* Wait end of Read + AT91F_MCIDeviceWaitReady(AT91C_MCI_TIMEOUT); + + { + int index; + unsigned int *uiBuffer = databuffer; + + for(index = 0; index < 512/4; index++) + uiBuffer[index] = swab32(uiBuffer[index]); + } + return(1); +} + diff --git a/target/linux/at91/image/dfboot/src/.svn/text-base/stdio.h.svn-base b/target/linux/at91/image/dfboot/src/.svn/text-base/stdio.h.svn-base new file mode 100644 index 0000000..e4e35ec --- /dev/null +++ b/target/linux/at91/image/dfboot/src/.svn/text-base/stdio.h.svn-base @@ -0,0 +1,18 @@ +#include <stdarg.h> +#include <stdbool.h> + +#ifndef NULL +#define NULL ((void *)0) +#endif + +void at91_init_uarts(void); +int puts(const char *str); +int putc(int c); +int putchar(int c); +int getc(); + +int strlen(const char *str); + +int hvfprintf(const char *fmt, va_list ap); + +int printf(const char *fmt, ...); |