mirror of
git://projects.qi-hardware.com/openwrt-xburst.git
synced 2024-12-28 15:28:57 +02:00
add new dfboot loader - a complete revison of romboot code.
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@7492 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
2f8d658a22
commit
3b9260da79
35
target/linux/at91-2.6/image/dfboot/Makefile
Normal file
35
target/linux/at91-2.6/image/dfboot/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright (C) 2006 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
# $Id$
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=dfboot
|
||||
PKG_VERSION:=0.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
CFLAGS="$(TARGET_CFLAGS)"
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
dd if=$(PKG_BUILD_DIR)/binary/dfboot.bin of=$(PKG_BUILD_DIR)/binary/dfboot.block bs=32k count=1 conv=sync
|
||||
endef
|
||||
|
||||
$(eval $(call Build/DefaultTargets))
|
94
target/linux/at91-2.6/image/dfboot/src/Makefile
Normal file
94
target/linux/at91-2.6/image/dfboot/src/Makefile
Normal file
@ -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
|
77
target/linux/at91-2.6/image/dfboot/src/_udivsi3.S
Normal file
77
target/linux/at91-2.6/image/dfboot/src/_udivsi3.S
Normal file
@ -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" */
|
88
target/linux/at91-2.6/image/dfboot/src/_umodsi3.S
Normal file
88
target/linux/at91-2.6/image/dfboot/src/_umodsi3.S
Normal file
@ -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" */
|
75
target/linux/at91-2.6/image/dfboot/src/asm_isr.S
Normal file
75
target/linux/at91-2.6/image/dfboot/src/asm_isr.S
Normal file
@ -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}^
|
||||
|
75
target/linux/at91-2.6/image/dfboot/src/asm_mci_isr.S
Normal file
75
target/linux/at91-2.6/image/dfboot/src/asm_mci_isr.S
Normal file
@ -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}^
|
||||
|
595
target/linux/at91-2.6/image/dfboot/src/at45.c
Normal file
595
target/linux/at91-2.6/image/dfboot/src/at45.c
Normal file
@ -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;
|
||||
}
|
||||
|
BIN
target/linux/at91-2.6/image/dfboot/src/binary/DataflashBoot-1.05.bin
Executable file
BIN
target/linux/at91-2.6/image/dfboot/src/binary/DataflashBoot-1.05.bin
Executable file
Binary file not shown.
361
target/linux/at91-2.6/image/dfboot/src/com.c
Normal file
361
target/linux/at91-2.6/image/dfboot/src/com.c
Normal file
@ -0,0 +1,361 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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 */
|
||||
|
||||
unsigned int usa[2] = {(unsigned int)AT91C_BASE_DBGU, (unsigned int)AT91C_ALTERNATE_USART};
|
||||
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<2; 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 (!port_detected) {
|
||||
if (us == usa[0]) {
|
||||
us = usa[1];
|
||||
}
|
||||
else {
|
||||
us = usa[0];
|
||||
}
|
||||
}
|
||||
if(AT91F_US_RxReady((AT91PS_USART)us)) {
|
||||
port_detected = 1;
|
||||
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;
|
||||
}
|
28
target/linux/at91-2.6/image/dfboot/src/com.h
Normal file
28
target/linux/at91-2.6/image/dfboot/src/com.h
Normal file
@ -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
|
||||
|
18
target/linux/at91-2.6/image/dfboot/src/config.h
Normal file
18
target/linux/at91-2.6/image/dfboot/src/config.h
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
#ifndef _CONFIG_H
|
||||
#define _CONFIG_H
|
||||
|
||||
//#define PAGESZ_1056 1
|
||||
#undef PAGESZ_1056
|
||||
#define SPI_LOW_SPEED 1
|
||||
#define AT91C_DELAY_TO_BOOT 15000
|
||||
//#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
|
144
target/linux/at91-2.6/image/dfboot/src/cstartup_ram.S
Normal file
144
target/linux/at91-2.6/image/dfboot/src/cstartup_ram.S
Normal file
@ -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
|
208
target/linux/at91-2.6/image/dfboot/src/dataflash.c
Normal file
208
target/linux/at91-2.6/image/dfboot/src/dataflash.c
Normal file
@ -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);
|
||||
}
|
||||
|
181
target/linux/at91-2.6/image/dfboot/src/dataflash.h
Normal file
181
target/linux/at91-2.6/image/dfboot/src/dataflash.h
Normal file
@ -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
|
28
target/linux/at91-2.6/image/dfboot/src/div0.c
Normal file
28
target/linux/at91-2.6/image/dfboot/src/div0.c
Normal file
@ -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);
|
||||
}
|
19
target/linux/at91-2.6/image/dfboot/src/elf32-littlearm.lds
Normal file
19
target/linux/at91-2.6/image/dfboot/src/elf32-littlearm.lds
Normal file
@ -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) }
|
||||
}
|
500
target/linux/at91-2.6/image/dfboot/src/embedded_services.h
Normal file
500
target/linux/at91-2.6/image/dfboot/src/embedded_services.h
Normal file
@ -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
|
||||
|
@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
# This is a Softfloat version of gcc for ARM suitable to compile U-Boot.
|
||||
# It was compiled using crosstool-0.42 using
|
||||
export GCCROOT=/usr/local/arm
|
||||
export GCC_VERSION=3.4.5
|
||||
export GLIBC_VERSION=2.3.6
|
||||
export CROSS_CHAIN=gcc-$GCC_VERSION-glibc-$GLIBC_VERSION
|
||||
export PATH=$PATH:$GCCROOT/$CROSS_CHAIN/arm-softfloat-linux-gnu/bin
|
||||
export CROSS_COMPILE=arm-softfloat-linux-gnu-
|
@ -0,0 +1,379 @@
|
||||
//*---------------------------------------------------------------------------
|
||||
//* 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 : AT91C_MCI_Device.h
|
||||
//* Object : Data Flash Atmel Description File
|
||||
//* Translator :
|
||||
//*
|
||||
//* 1.0 26/11/02 FB : Creation
|
||||
//*---------------------------------------------------------------------------
|
||||
|
||||
#ifndef AT91C_MCI_Device_h
|
||||
#define AT91C_MCI_Device_h
|
||||
|
||||
#include "AT91RM9200.h"
|
||||
#include "lib_AT91RM9200.h"
|
||||
|
||||
typedef unsigned int AT91S_MCIDeviceStatus;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AT91C_CARD_REMOVED 0
|
||||
#define AT91C_MMC_CARD_INSERTED 1
|
||||
#define AT91C_SD_CARD_INSERTED 2
|
||||
|
||||
#define AT91C_NO_ARGUMENT 0x0
|
||||
|
||||
#define AT91C_FIRST_RCA 0xCAFE
|
||||
#define AT91C_MAX_MCI_CARDS 10
|
||||
|
||||
#define AT91C_BUS_WIDTH_1BIT 0x00
|
||||
#define AT91C_BUS_WIDTH_4BITS 0x02
|
||||
|
||||
/* Driver State */
|
||||
#define AT91C_MCI_IDLE 0x0
|
||||
#define AT91C_MCI_TIMEOUT_ERROR 0x1
|
||||
#define AT91C_MCI_RX_SINGLE_BLOCK 0x2
|
||||
#define AT91C_MCI_RX_MULTIPLE_BLOCK 0x3
|
||||
#define AT91C_MCI_RX_STREAM 0x4
|
||||
#define AT91C_MCI_TX_SINGLE_BLOCK 0x5
|
||||
#define AT91C_MCI_TX_MULTIPLE_BLOCK 0x6
|
||||
#define AT91C_MCI_TX_STREAM 0x7
|
||||
|
||||
/* TimeOut */
|
||||
#define AT91C_TIMEOUT_CMDRDY 30
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MMC & SDCard Structures
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*-----------------------------------------------*/
|
||||
/* SDCard Device Descriptor Structure Definition */
|
||||
/*-----------------------------------------------*/
|
||||
typedef struct _AT91S_MciDeviceDesc
|
||||
{
|
||||
volatile unsigned char state;
|
||||
unsigned char SDCard_bus_width;
|
||||
|
||||
} AT91S_MciDeviceDesc, *AT91PS_MciDeviceDesc;
|
||||
|
||||
/*---------------------------------------------*/
|
||||
/* MMC & SDCard Structure Device Features */
|
||||
/*---------------------------------------------*/
|
||||
typedef struct _AT91S_MciDeviceFeatures
|
||||
{
|
||||
unsigned char Card_Inserted; // (0=AT91C_CARD_REMOVED) (1=AT91C_MMC_CARD_INSERTED) (2=AT91C_SD_CARD_INSERTED)
|
||||
unsigned int Relative_Card_Address; // RCA
|
||||
unsigned int Max_Read_DataBlock_Length; // 2^(READ_BL_LEN) in CSD
|
||||
unsigned int Max_Write_DataBlock_Length; // 2^(WRITE_BL_LEN) in CSD
|
||||
unsigned char Read_Partial; // READ_BL_PARTIAL
|
||||
unsigned char Write_Partial; // WRITE_BL_PARTIAL
|
||||
unsigned char Erase_Block_Enable; // ERASE_BLK_EN
|
||||
unsigned char Read_Block_Misalignment; // READ_BLK_MISALIGN
|
||||
unsigned char Write_Block_Misalignment; // WRITE_BLK_MISALIGN
|
||||
unsigned char Sector_Size; // SECTOR_SIZE
|
||||
unsigned int Memory_Capacity; // Size in bits of the device
|
||||
|
||||
} AT91S_MciDeviceFeatures, *AT91PS_MciDeviceFeatures ;
|
||||
|
||||
/*---------------------------------------------*/
|
||||
/* MCI Device Structure Definition */
|
||||
/*---------------------------------------------*/
|
||||
typedef struct _AT91S_MciDevice
|
||||
{
|
||||
AT91PS_MciDeviceDesc pMCI_DeviceDesc; // MCI device descriptor
|
||||
AT91PS_MciDeviceFeatures pMCI_DeviceFeatures;// Pointer on a MCI device features array
|
||||
}AT91S_MciDevice, *AT91PS_MciDevice;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MCI_CMD Register Value
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_POWER_ON_INIT (0 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_INIT | AT91C_MCI_OPDCMD)
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
// Class 0 & 1 commands: Basic commands and Read Stream commands
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AT91C_GO_IDLE_STATE_CMD (0 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE )
|
||||
#define AT91C_MMC_GO_IDLE_STATE_CMD (0 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_OPDCMD)
|
||||
#define AT91C_MMC_SEND_OP_COND_CMD (1 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_OPDCMD)
|
||||
#define AT91C_ALL_SEND_CID_CMD (2 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_136 )
|
||||
#define AT91C_MMC_ALL_SEND_CID_CMD (2 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_136 | AT91C_MCI_OPDCMD)
|
||||
#define AT91C_SET_RELATIVE_ADDR_CMD (3 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_MMC_SET_RELATIVE_ADDR_CMD (3 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT | AT91C_MCI_OPDCMD)
|
||||
|
||||
#define AT91C_SET_DSR_CMD (4 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_NO | AT91C_MCI_MAXLAT ) // no tested
|
||||
|
||||
#define AT91C_SEL_DESEL_CARD_CMD (7 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_SEND_CSD_CMD (9 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_136 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_SEND_CID_CMD (10 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_136 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_MMC_READ_DAT_UNTIL_STOP_CMD (11 | AT91C_MCI_TRTYP_STREAM| AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRDIR | AT91C_MCI_TRCMD_START | AT91C_MCI_MAXLAT )
|
||||
|
||||
#define AT91C_STOP_TRANSMISSION_CMD (12 | AT91C_MCI_TRCMD_STOP | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_STOP_TRANSMISSION_SYNC_CMD (12 | AT91C_MCI_TRCMD_STOP | AT91C_MCI_SPCMD_SYNC | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_SEND_STATUS_CMD (13 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_GO_INACTIVE_STATE_CMD (15 | AT91C_MCI_RSPTYP_NO )
|
||||
|
||||
//*------------------------------------------------
|
||||
//* Class 2 commands: Block oriented Read commands
|
||||
//*------------------------------------------------
|
||||
|
||||
#define AT91C_SET_BLOCKLEN_CMD (16 | AT91C_MCI_TRCMD_NO | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT )
|
||||
#define AT91C_READ_SINGLE_BLOCK_CMD (17 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_START | AT91C_MCI_TRTYP_BLOCK | AT91C_MCI_TRDIR | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_READ_MULTIPLE_BLOCK_CMD (18 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_START | AT91C_MCI_TRTYP_MULTIPLE | AT91C_MCI_TRDIR | AT91C_MCI_MAXLAT)
|
||||
|
||||
//*--------------------------------------------
|
||||
//* Class 3 commands: Sequential write commands
|
||||
//*--------------------------------------------
|
||||
|
||||
#define AT91C_MMC_WRITE_DAT_UNTIL_STOP_CMD (20 | AT91C_MCI_TRTYP_STREAM| AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 & ~(AT91C_MCI_TRDIR) | AT91C_MCI_TRCMD_START | AT91C_MCI_MAXLAT ) // MMC
|
||||
|
||||
//*------------------------------------------------
|
||||
//* Class 4 commands: Block oriented write commands
|
||||
//*------------------------------------------------
|
||||
|
||||
#define AT91C_WRITE_BLOCK_CMD (24 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_START | (AT91C_MCI_TRTYP_BLOCK & ~(AT91C_MCI_TRDIR)) | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_WRITE_MULTIPLE_BLOCK_CMD (25 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_START | (AT91C_MCI_TRTYP_MULTIPLE & ~(AT91C_MCI_TRDIR)) | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_PROGRAM_CSD_CMD (27 | AT91C_MCI_RSPTYP_48 )
|
||||
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 6 commands: Group Write protect
|
||||
//*----------------------------------------
|
||||
|
||||
#define AT91C_SET_WRITE_PROT_CMD (28 | AT91C_MCI_RSPTYP_48 )
|
||||
#define AT91C_CLR_WRITE_PROT_CMD (29 | AT91C_MCI_RSPTYP_48 )
|
||||
#define AT91C_SEND_WRITE_PROT_CMD (30 | AT91C_MCI_RSPTYP_48 )
|
||||
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 5 commands: Erase commands
|
||||
//*----------------------------------------
|
||||
|
||||
#define AT91C_TAG_SECTOR_START_CMD (32 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_TAG_SECTOR_END_CMD (33 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_MMC_UNTAG_SECTOR_CMD (34 | AT91C_MCI_RSPTYP_48 )
|
||||
#define AT91C_MMC_TAG_ERASE_GROUP_START_CMD (35 | AT91C_MCI_RSPTYP_48 )
|
||||
#define AT91C_MMC_TAG_ERASE_GROUP_END_CMD (36 | AT91C_MCI_RSPTYP_48 )
|
||||
#define AT91C_MMC_UNTAG_ERASE_GROUP_CMD (37 | AT91C_MCI_RSPTYP_48 )
|
||||
#define AT91C_ERASE_CMD (38 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT )
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 7 commands: Lock commands
|
||||
//*----------------------------------------
|
||||
|
||||
#define AT91C_LOCK_UNLOCK (42 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT) // no tested
|
||||
|
||||
//*-----------------------------------------------
|
||||
// Class 8 commands: Application specific commands
|
||||
//*-----------------------------------------------
|
||||
|
||||
#define AT91C_APP_CMD (55 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_GEN_CMD (56 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT) // no tested
|
||||
|
||||
#define AT91C_SDCARD_SET_BUS_WIDTH_CMD (6 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_SDCARD_STATUS_CMD (13 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_SDCARD_SEND_NUM_WR_BLOCKS_CMD (22 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_SDCARD_SET_WR_BLK_ERASE_COUNT_CMD (23 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_SDCARD_APP_OP_COND_CMD (41 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO )
|
||||
#define AT91C_SDCARD_SET_CLR_CARD_DETECT_CMD (42 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_SDCARD_SEND_SCR_CMD (51 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
|
||||
#define AT91C_SDCARD_APP_ALL_CMD (AT91C_SDCARD_SET_BUS_WIDTH_CMD +\
|
||||
AT91C_SDCARD_STATUS_CMD +\
|
||||
AT91C_SDCARD_SEND_NUM_WR_BLOCKS_CMD +\
|
||||
AT91C_SDCARD_SET_WR_BLK_ERASE_COUNT_CMD +\
|
||||
AT91C_SDCARD_APP_OP_COND_CMD +\
|
||||
AT91C_SDCARD_SET_CLR_CARD_DETECT_CMD +\
|
||||
AT91C_SDCARD_SEND_SCR_CMD)
|
||||
|
||||
//*----------------------------------------
|
||||
//* Class 9 commands: IO Mode commands
|
||||
//*----------------------------------------
|
||||
|
||||
#define AT91C_MMC_FAST_IO_CMD (39 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_MAXLAT)
|
||||
#define AT91C_MMC_GO_IRQ_STATE_CMD (40 | AT91C_MCI_SPCMD_NONE | AT91C_MCI_RSPTYP_48 | AT91C_MCI_TRCMD_NO | AT91C_MCI_MAXLAT)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Functions returnals
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_CMD_SEND_OK 0 // Command ok
|
||||
#define AT91C_CMD_SEND_ERROR -1 // Command failed
|
||||
#define AT91C_INIT_OK 2 // Init Successfull
|
||||
#define AT91C_INIT_ERROR 3 // Init Failed
|
||||
#define AT91C_READ_OK 4 // Read Successfull
|
||||
#define AT91C_READ_ERROR 5 // Read Failed
|
||||
#define AT91C_WRITE_OK 6 // Write Successfull
|
||||
#define AT91C_WRITE_ERROR 7 // Write Failed
|
||||
#define AT91C_ERASE_OK 8 // Erase Successfull
|
||||
#define AT91C_ERASE_ERROR 9 // Erase Failed
|
||||
#define AT91C_CARD_SELECTED_OK 10 // Card Selection Successfull
|
||||
#define AT91C_CARD_SELECTED_ERROR 11 // Card Selection Failed
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MCI_SR Errors
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_MCI_SR_ERROR (AT91C_MCI_UNRE |\
|
||||
AT91C_MCI_OVRE |\
|
||||
AT91C_MCI_DTOE |\
|
||||
AT91C_MCI_DCRCE |\
|
||||
AT91C_MCI_RTOE |\
|
||||
AT91C_MCI_RENDE |\
|
||||
AT91C_MCI_RCRCE |\
|
||||
AT91C_MCI_RDIRE |\
|
||||
AT91C_MCI_RINDE)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// OCR Register
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_VDD_16_17 (1 << 4)
|
||||
#define AT91C_VDD_17_18 (1 << 5)
|
||||
#define AT91C_VDD_18_19 (1 << 6)
|
||||
#define AT91C_VDD_19_20 (1 << 7)
|
||||
#define AT91C_VDD_20_21 (1 << 8)
|
||||
#define AT91C_VDD_21_22 (1 << 9)
|
||||
#define AT91C_VDD_22_23 (1 << 10)
|
||||
#define AT91C_VDD_23_24 (1 << 11)
|
||||
#define AT91C_VDD_24_25 (1 << 12)
|
||||
#define AT91C_VDD_25_26 (1 << 13)
|
||||
#define AT91C_VDD_26_27 (1 << 14)
|
||||
#define AT91C_VDD_27_28 (1 << 15)
|
||||
#define AT91C_VDD_28_29 (1 << 16)
|
||||
#define AT91C_VDD_29_30 (1 << 17)
|
||||
#define AT91C_VDD_30_31 (1 << 18)
|
||||
#define AT91C_VDD_31_32 (1 << 19)
|
||||
#define AT91C_VDD_32_33 (1 << 20)
|
||||
#define AT91C_VDD_33_34 (1 << 21)
|
||||
#define AT91C_VDD_34_35 (1 << 22)
|
||||
#define AT91C_VDD_35_36 (1 << 23)
|
||||
#define AT91C_CARD_POWER_UP_BUSY (1 << 31)
|
||||
|
||||
#define AT91C_MMC_HOST_VOLTAGE_RANGE (AT91C_VDD_27_28 +\
|
||||
AT91C_VDD_28_29 +\
|
||||
AT91C_VDD_29_30 +\
|
||||
AT91C_VDD_30_31 +\
|
||||
AT91C_VDD_31_32 +\
|
||||
AT91C_VDD_32_33)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CURRENT_STATE & READY_FOR_DATA in SDCard Status Register definition (response type R1)
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define AT91C_SR_READY_FOR_DATA (1 << 8) // corresponds to buffer empty signalling on the bus
|
||||
#define AT91C_SR_IDLE (0 << 9)
|
||||
#define AT91C_SR_READY (1 << 9)
|
||||
#define AT91C_SR_IDENT (2 << 9)
|
||||
#define AT91C_SR_STBY (3 << 9)
|
||||
#define AT91C_SR_TRAN (4 << 9)
|
||||
#define AT91C_SR_DATA (5 << 9)
|
||||
#define AT91C_SR_RCV (6 << 9)
|
||||
#define AT91C_SR_PRG (7 << 9)
|
||||
#define AT91C_SR_DIS (8 << 9)
|
||||
|
||||
#define AT91C_SR_CARD_SELECTED (AT91C_SR_READY_FOR_DATA + AT91C_SR_TRAN)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MMC CSD register header File
|
||||
// AT91C_CSD_xxx_S for shift value
|
||||
// AT91C_CSD_xxx_M for mask value
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// First Response INT <=> CSD[3] : bits 0 to 31
|
||||
#define AT91C_CSD_BIT0_S 0 // [0:0]
|
||||
#define AT91C_CSD_BIT0_M 0x01
|
||||
#define AT91C_CSD_CRC_S 1 // [7:1]
|
||||
#define AT91C_CSD_CRC_M 0x7F
|
||||
#define AT91C_CSD_MMC_ECC_S 8 // [9:8] reserved for MMC compatibility
|
||||
#define AT91C_CSD_MMC_ECC_M 0x03
|
||||
#define AT91C_CSD_FILE_FMT_S 10 // [11:10]
|
||||
#define AT91C_CSD_FILE_FMT_M 0x03
|
||||
#define AT91C_CSD_TMP_WP_S 12 // [12:12]
|
||||
#define AT91C_CSD_TMP_WP_M 0x01
|
||||
#define AT91C_CSD_PERM_WP_S 13 // [13:13]
|
||||
#define AT91C_CSD_PERM_WP_M 0x01
|
||||
#define AT91C_CSD_COPY_S 14 // [14:14]
|
||||
#define AT91C_CSD_COPY_M 0x01
|
||||
#define AT91C_CSD_FILE_FMT_GRP_S 15 // [15:15]
|
||||
#define AT91C_CSD_FILE_FMT_GRP_M 0x01
|
||||
// reserved 16 // [20:16]
|
||||
// reserved 0x1F
|
||||
#define AT91C_CSD_WBLOCK_P_S 21 // [21:21]
|
||||
#define AT91C_CSD_WBLOCK_P_M 0x01
|
||||
#define AT91C_CSD_WBLEN_S 22 // [25:22]
|
||||
#define AT91C_CSD_WBLEN_M 0x0F
|
||||
#define AT91C_CSD_R2W_F_S 26 // [28:26]
|
||||
#define AT91C_CSD_R2W_F_M 0x07
|
||||
#define AT91C_CSD_MMC_DEF_ECC_S 29 // [30:29] reserved for MMC compatibility
|
||||
#define AT91C_CSD_MMC_DEF_ECC_M 0x03
|
||||
#define AT91C_CSD_WP_GRP_EN_S 31 // [31:31]
|
||||
#define AT91C_CSD_WP_GRP_EN_M 0x01
|
||||
|
||||
// Seconde Response INT <=> CSD[2] : bits 32 to 63
|
||||
#define AT91C_CSD_v21_WP_GRP_SIZE_S 0 // [38:32]
|
||||
#define AT91C_CSD_v21_WP_GRP_SIZE_M 0x7F
|
||||
#define AT91C_CSD_v21_SECT_SIZE_S 7 // [45:39]
|
||||
#define AT91C_CSD_v21_SECT_SIZE_M 0x7F
|
||||
#define AT91C_CSD_v21_ER_BLEN_EN_S 14 // [46:46]
|
||||
#define AT91C_CSD_v21_ER_BLEN_EN_M 0x01
|
||||
|
||||
#define AT91C_CSD_v22_WP_GRP_SIZE_S 0 // [36:32]
|
||||
#define AT91C_CSD_v22_WP_GRP_SIZE_M 0x1F
|
||||
#define AT91C_CSD_v22_ER_GRP_SIZE_S 5 // [41:37]
|
||||
#define AT91C_CSD_v22_ER_GRP_SIZE_M 0x1F
|
||||
#define AT91C_CSD_v22_SECT_SIZE_S 10 // [46:42]
|
||||
#define AT91C_CSD_v22_SECT_SIZE_M 0x1F
|
||||
|
||||
#define AT91C_CSD_C_SIZE_M_S 15 // [49:47]
|
||||
#define AT91C_CSD_C_SIZE_M_M 0x07
|
||||
#define AT91C_CSD_VDD_WMAX_S 18 // [52:50]
|
||||
#define AT91C_CSD_VDD_WMAX_M 0x07
|
||||
#define AT91C_CSD_VDD_WMIN_S 21 // [55:53]
|
||||
#define AT91C_CSD_VDD_WMIN_M 0x07
|
||||
#define AT91C_CSD_RCUR_MAX_S 24 // [58:56]
|
||||
#define AT91C_CSD_RCUR_MAX_M 0x07
|
||||
#define AT91C_CSD_RCUR_MIN_S 27 // [61:59]
|
||||
#define AT91C_CSD_RCUR_MIN_M 0x07
|
||||
#define AT91C_CSD_CSIZE_L_S 30 // [63:62] <=> 2 LSB of CSIZE
|
||||
#define AT91C_CSD_CSIZE_L_M 0x03
|
||||
|
||||
// Third Response INT <=> CSD[1] : bits 64 to 95
|
||||
#define AT91C_CSD_CSIZE_H_S 0 // [73:64] <=> 10 MSB of CSIZE
|
||||
#define AT91C_CSD_CSIZE_H_M 0x03FF
|
||||
// reserved 10 // [75:74]
|
||||
// reserved 0x03
|
||||
#define AT91C_CSD_DSR_I_S 12 // [76:76]
|
||||
#define AT91C_CSD_DSR_I_M 0x01
|
||||
#define AT91C_CSD_RD_B_MIS_S 13 // [77:77]
|
||||
#define AT91C_CSD_RD_B_MIS_M 0x01
|
||||
#define AT91C_CSD_WR_B_MIS_S 14 // [78:78]
|
||||
#define AT91C_CSD_WR_B_MIS_M 0x01
|
||||
#define AT91C_CSD_RD_B_PAR_S 15 // [79:79]
|
||||
#define AT91C_CSD_RD_B_PAR_M 0x01
|
||||
#define AT91C_CSD_RD_B_LEN_S 16 // [83:80]
|
||||
#define AT91C_CSD_RD_B_LEN_M 0x0F
|
||||
#define AT91C_CSD_CCC_S 20 // [95:84]
|
||||
#define AT91C_CSD_CCC_M 0x0FFF
|
||||
|
||||
// Fourth Response INT <=> CSD[0] : bits 96 to 127
|
||||
#define AT91C_CSD_TRANS_SPEED_S 0 // [103:96]
|
||||
#define AT91C_CSD_TRANS_SPEED_M 0xFF
|
||||
#define AT91C_CSD_NSAC_S 8 // [111:104]
|
||||
#define AT91C_CSD_NSAC_M 0xFF
|
||||
#define AT91C_CSD_TAAC_S 16 // [119:112]
|
||||
#define AT91C_CSD_TAAC_M 0xFF
|
||||
// reserved 24 // [121:120]
|
||||
// reserved 0x03
|
||||
#define AT91C_CSD_MMC_SPEC_VERS_S 26 // [125:122] reserved for MMC compatibility
|
||||
#define AT91C_CSD_MMC_SPEC_VERS_M 0x0F
|
||||
#define AT91C_CSD_STRUCT_S 30 // [127:126]
|
||||
#define AT91C_CSD_STRUCT_M 0x03
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
||||
|
2745
target/linux/at91-2.6/image/dfboot/src/include/AT91RM9200.h
Normal file
2745
target/linux/at91-2.6/image/dfboot/src/include/AT91RM9200.h
Normal file
File diff suppressed because it is too large
Load Diff
2437
target/linux/at91-2.6/image/dfboot/src/include/AT91RM9200.inc
Normal file
2437
target/linux/at91-2.6/image/dfboot/src/include/AT91RM9200.inc
Normal file
File diff suppressed because it is too large
Load Diff
2401
target/linux/at91-2.6/image/dfboot/src/include/AT91RM9200_inc.h
Normal file
2401
target/linux/at91-2.6/image/dfboot/src/include/AT91RM9200_inc.h
Normal file
File diff suppressed because it is too large
Load Diff
49
target/linux/at91-2.6/image/dfboot/src/include/led.h
Normal file
49
target/linux/at91-2.6/image/dfboot/src/include/led.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* (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
|
||||
*/
|
||||
|
||||
#ifndef __LED_H
|
||||
#define __LED_H
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void LED_init (void);
|
||||
extern void LED_set(unsigned int led);
|
||||
extern void red_LED_on(void);
|
||||
extern void red_LED_off(void);
|
||||
extern void green_LED_on(void);
|
||||
extern void green_LED_off(void);
|
||||
extern void yellow_LED_on(void);
|
||||
extern void yellow_LED_off(void);
|
||||
extern void LED_blink(unsigned int led);
|
||||
#else
|
||||
.extern LED_init
|
||||
.extern LED_set
|
||||
.extern LED_blink
|
||||
.extern red_LED_on
|
||||
.extern red_LED_off
|
||||
.extern yellow_LED_on
|
||||
.extern yellow_LED_off
|
||||
.extern green_LED_on
|
||||
.extern green_LED_off
|
||||
#endif
|
||||
#endif
|
2978
target/linux/at91-2.6/image/dfboot/src/include/lib_AT91RM9200.h
Normal file
2978
target/linux/at91-2.6/image/dfboot/src/include/lib_AT91RM9200.h
Normal file
File diff suppressed because it is too large
Load Diff
165
target/linux/at91-2.6/image/dfboot/src/init.c
Normal file
165
target/linux/at91-2.6/image/dfboot/src/init.c
Normal file
@ -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();
|
||||
|
||||
}
|
||||
|
4
target/linux/at91-2.6/image/dfboot/src/jump.S
Normal file
4
target/linux/at91-2.6/image/dfboot/src/jump.S
Normal file
@ -0,0 +1,4 @@
|
||||
.global Jump
|
||||
|
||||
Jump: mov pc, r0
|
||||
|
103
target/linux/at91-2.6/image/dfboot/src/led.c
Normal file
103
target/linux/at91-2.6/image/dfboot/src/led.c
Normal file
@ -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;
|
||||
}
|
810
target/linux/at91-2.6/image/dfboot/src/main.c
Normal file
810
target/linux/at91-2.6/image/dfboot/src/main.c
Normal file
@ -0,0 +1,810 @@
|
||||
/*----------------------------------------------------------------------------
|
||||
* 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 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
|
||||
}
|
||||
}
|
||||
|
43
target/linux/at91-2.6/image/dfboot/src/main.h
Normal file
43
target/linux/at91-2.6/image/dfboot/src/main.h
Normal file
@ -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
|
||||
|
743
target/linux/at91-2.6/image/dfboot/src/mci_device.c
Normal file
743
target/linux/at91-2.6/image/dfboot/src/mci_device.c
Normal file
@ -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);
|
||||
}
|
||||
|
18
target/linux/at91-2.6/image/dfboot/src/stdio.h
Normal file
18
target/linux/at91-2.6/image/dfboot/src/stdio.h
Normal file
@ -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, ...);
|
Loading…
Reference in New Issue
Block a user