add new dfboot loader - a complete revison of romboot code.

SVN-Revision: 7492
This commit is contained in:
Hamish Guthrie 2007-06-04 17:41:40 +00:00
parent e970f61273
commit 3266668cae
31 changed files with 15410 additions and 0 deletions

View 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))

View 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

View 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" */

View 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" */

View 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}^

View 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}^

View 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;
}

View 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;
}

View 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

View 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

View 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

View 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);
}

View 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

View 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);
}

View 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) }
}

View 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

View File

@ -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-

View File

@ -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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View 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

File diff suppressed because it is too large Load Diff

View 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();
}

View File

@ -0,0 +1,4 @@
.global Jump
Jump: mov pc, r0

View 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;
}

View 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
}
}

View 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

View 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);
}

View 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, ...);