Hier comes the announced patch: 1. It allows the use of the second flash in the 512k devices. 2. It solves a possible problem with a late PIT-initalisation. 3. It improves the startup-time and prevents changes in the holly system-clock when booting from a boot-monitor. 4. It removes a spaces at the end of the line.
Index: packages/devs/flash/arm/at91/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/arm/at91/current/ChangeLog,v retrieving revision 1.9 diff -u -r1.9 ChangeLog --- packages/devs/flash/arm/at91/current/ChangeLog 3 Nov 2008 08:41:59 -0000 1.9 +++ packages/devs/flash/arm/at91/current/ChangeLog 4 Jun 2009 07:30:43 -0000 @@ -1,3 +1,7 @@ +2009-06-03 Oliver Munz <m...@speag.ch> + + * src/at91_flash.c (Add support for 512kByte-devices. + 2008-11-03 Gabor Toeroek <tgabo...@gmail.com> * src/at91_flash.c (flash_hwr_init): Add partial support for Index: packages/devs/flash/arm/at91/current/src/at91_flash.c =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/flash/arm/at91/current/src/at91_flash.c,v retrieving revision 1.9 diff -u -r1.9 at91_flash.c --- packages/devs/flash/arm/at91/current/src/at91_flash.c 3 Nov 2008 08:41:59 -0000 1.9 +++ packages/devs/flash/arm/at91/current/src/at91_flash.c 4 Jun 2009 07:30:43 -0000 @@ -2,7 +2,7 @@ // // at91_flash.c // -// Flash programming for the at91 devices which have the +// Flash programming for the at91 devices which have the // Embedded Flash Controller. // //========================================================================== @@ -41,11 +41,11 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): gthomas -// Contributors: gthomas, dmoseley, Andrew Lunn, Oliver Munz -// Date: 2000-07-26 -// Purpose: -// Description: -// +// Contributors: gthomas, dmoseley, Andrew Lunn, Oliver Munz, Kasim Malla +// Date: 2009-06-03 +// Purpose: +// Description: +// //####DESCRIPTIONEND#### // //========================================================================== @@ -53,7 +53,7 @@ #include <pkgconf/hal.h> #include <pkgconf/devs_flash_at91.h> -#include <cyg/hal/hal_io.h> +#include <cyg/hal/hal_io.h> #include <cyg/hal/hal_intr.h> #include <cyg/infra/cyg_ass.h> @@ -62,7 +62,8 @@ #include <string.h> -#define FLASH_TIMEOUT 100000 +#define FLASH_TIMEOUT 100000 /* Stupid timeout depends of the CPU clock speed... */ +#define AT91_FLASH_FMCN_VALUE (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 15 / 10000000 + 1) #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING static cyg_uint32 sector_size; @@ -70,50 +71,169 @@ // Disable the flash controller from erasing the page before // programming it -static void + +#ifdef AT91_MC_FMR1 + #define PAGE_AT_WITCH_WE_USE_THE_EFC1 1024 + #define SECTOR_AT_WITCH_WE_USE_THE_EFC1 16 +#endif + + +static void flash_erase_before_write_disable (void) { cyg_uint32 fmr; - + HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr); fmr = fmr | AT91_MC_FMR_NEBP; HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr); +#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */ + HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, fmr); +#endif } // Enable the flash controller to erase the page before programming // it -static void -flash_erase_before_write_enable (void) +static void +flash_erase_before_write_enable (void) { - + cyg_uint32 fmr; HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, fmr); fmr = fmr & ~((cyg_uint32) AT91_MC_FMR_NEBP); HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, fmr); +#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */ + HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, fmr); +#endif +} + +#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */ + +// Is the flash controller ready to accept the next command? +static __inline__ cyg_bool +flash_controller_is_ready(cyg_uint32 page) +CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command"); + +static __inline__ cyg_bool +flash_controller_is_ready(cyg_uint32 page) +{ + cyg_uint32 fsr; + + if (page < PAGE_AT_WITCH_WE_USE_THE_EFC1){ + HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr); + } else { + HAL_READ_UINT32(AT91_MC+AT91_MC_FSR1, fsr); + } + return (fsr & AT91_MC_FSR_FRDY ? true : false); +} + +// Busy loop waiting for the controller to finish the command. +// Wait a maximum of timeout loops and then return an error. +static __inline__ int +flash_wait_for_controller (cyg_uint32 page, cyg_uint32 timeout) +CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command"); + +static __inline__ int +flash_wait_for_controller (cyg_uint32 page, cyg_uint32 timeout) +{ + while (!flash_controller_is_ready(page)){ + timeout--; + if (!timeout) { + return FLASH_ERR_DRV_TIMEOUT; + } + } + return FLASH_ERR_OK; +} + + +// Execute one command on the flash controller. This code should +// probably not be in flash + +static int +flash_run_command(cyg_uint32 address, + cyg_uint32 command, + cyg_uint32 timeout) +CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command"); + +static int +flash_run_command(cyg_uint32 address, + cyg_uint32 command, + cyg_uint32 timeout) +{ + cyg_uint32 retcode; + cyg_uint32 fsr; + cyg_uint32 mask; + cyg_uint32 page; + + page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) / + flash_info.block_size; + + // Wait for the last command to finish + retcode = flash_wait_for_controller(page, timeout); + if (retcode != FLASH_ERR_OK){ + return retcode; + } + + HAL_DISABLE_INTERRUPTS(mask); + + if (page < PAGE_AT_WITCH_WE_USE_THE_EFC1){ + HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR, + command | + ((page & AT91_MC_FCR_PAGE_MASK) << AT91_MC_FCR_PAGE_SHIFT) | + AT91_MC_FCR_KEY); + } else { + HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR1, + command | + (((page - PAGE_AT_WITCH_WE_USE_THE_EFC1) & AT91_MC_FCR_PAGE_MASK) << AT91_MC_FCR_PAGE_SHIFT) | + AT91_MC_FCR_KEY); + } + + retcode = flash_wait_for_controller(page, timeout); + + HAL_RESTORE_INTERRUPTS(mask); + + if (retcode != FLASH_ERR_OK){ + return retcode; + } + + // Check for an error + if (page < PAGE_AT_WITCH_WE_USE_THE_EFC1){ + HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr); + } else { + HAL_READ_UINT32(AT91_MC+AT91_MC_FSR1, fsr); + } + + if ((fsr & AT91_MC_FSR_LOCKE) == AT91_MC_FSR_LOCKE) + return FLASH_ERR_PROTECT; + if ((fsr & AT91_MC_FSR_PROGE) == AT91_MC_FSR_PROGE) + return FLASH_ERR_PROGRAM; + + return FLASH_ERR_OK; } +#else /* not at91sam7x512 */ + // Is the flash controller ready to accept the next command? -static __inline__ cyg_bool -flash_controller_is_ready(void) +static __inline__ cyg_bool +flash_controller_is_ready(void) CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command"); -static __inline__ cyg_bool -flash_controller_is_ready(void) +static __inline__ cyg_bool +flash_controller_is_ready(void) { cyg_uint32 fsr; - + HAL_READ_UINT32(AT91_MC+AT91_MC_FSR, fsr); return (fsr & AT91_MC_FSR_FRDY ? true : false); } // Busy loop waiting for the controller to finish the command. // Wait a maximum of timeout loops and then return an error. -static __inline__ int -flash_wait_for_controller (cyg_uint32 timeout) +static __inline__ int +flash_wait_for_controller (cyg_uint32 timeout) CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command"); -static __inline__ int +static __inline__ int flash_wait_for_controller (cyg_uint32 timeout) { while (!flash_controller_is_ready()){ @@ -128,34 +248,34 @@ // Execute one command on the flash controller. This code should // probably not be in flash -static int -flash_run_command(cyg_uint32 address, - cyg_uint32 command, - cyg_uint32 timeout) +static int +flash_run_command(cyg_uint32 address, + cyg_uint32 command, + cyg_uint32 timeout) CYGBLD_ATTRIB_SECTION(".2ram.flash_run_command"); -static int -flash_run_command(cyg_uint32 address, - cyg_uint32 command, - cyg_uint32 timeout) +static int +flash_run_command(cyg_uint32 address, + cyg_uint32 command, + cyg_uint32 timeout) { cyg_uint32 retcode; cyg_uint32 fsr; cyg_uint32 mask; cyg_uint32 page; - - page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) / + + page = ((cyg_uint32) address - (cyg_uint32) flash_info.start) / flash_info.block_size; - + // Wait for the last command to finish retcode = flash_wait_for_controller(timeout); if (retcode != FLASH_ERR_OK){ return retcode; } - + HAL_DISABLE_INTERRUPTS(mask); - - HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR, + + HAL_WRITE_UINT32(AT91_MC+AT91_MC_FCR, command | ((page & AT91_MC_FCR_PAGE_MASK) << AT91_MC_FCR_PAGE_SHIFT) | AT91_MC_FCR_KEY); @@ -179,15 +299,18 @@ return FLASH_ERR_OK; } +#endif + + // The flash is embedded in the CPU package. So return the chip // ID. This allows us to determine if the chip is one we support and // the size of the flash -int flash_query(void *data) +int flash_query(void *data) { cyg_uint32 chipID1r; - + HAL_READ_UINT32(AT91_DBG+AT91_DBG_C1R, chipID1r); - + memcpy(data, &chipID1r, sizeof(chipID1r)); return FLASH_ERR_OK; } @@ -197,14 +320,13 @@ // the number of blocks. The query function returns the chip ID 1 // register which tells us about the CPU we are running on, the flash // size etc. Use this information to determine we have a valid setup. -int +int flash_hwr_init(void){ cyg_uint32 chipID1r; cyg_uint32 flash_mode; - cyg_uint8 fmcn; cyg_uint32 lock_bits; - + flash_query (&chipID1r); if ((chipID1r & AT91_DBG_C1R_CPU_MASK) != AT91_DBG_C1R_ARM7TDMI) @@ -215,10 +337,10 @@ ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7XC) && ((chipID1r & AT91_DBG_C1R_ARCH_MASK) != AT91_DBG_C1R_ARCH_AT91SAM7SExx)) goto out; - + if ((chipID1r & AT91_DBG_C1R_FLASH_MASK) == AT91_DBG_C1R_FLASH_0K) goto out; - + if ((chipID1r & AT91_DBG_C1R_NVPTYP_MASK) != AT91_DBG_C1R_NVPTYP_ROMFLASH) { @@ -243,19 +365,20 @@ flash_info.blocks = 1024; lock_bits = 16; break; + case AT91_DBG_C1R_FLASH_512K: + flash_info.block_size = 256; #ifdef AT91_MC_FMR1 - case AT91_DBG_C1R_FLASH_512K: - flash_info.block_size = 256; - flash_info.blocks = 1024; - lock_bits = 16; - (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks"); - //flash_info.blocks = 2048; - //lock_bits = 32; - break; + flash_info.blocks = 2048; + lock_bits = 32; +#else + flash_info.blocks = 1024; + lock_bits = 16; + (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks"); #endif - default: - goto out; - } + break; + default: + goto out; + } } else { // if there is both flash & ROM then: ROM=AT91_DBG_C1R_FLASH, flash=AT91_DBG_C1R_FLASH2 switch (chipID1r & AT91_DBG_C1R_FLASH2_MASK) { @@ -279,44 +402,41 @@ flash_info.blocks = 1024; lock_bits = 16; break; -#ifdef AT91_MC_FMR1 case AT91_DBG_C1R_FLASH2_512K: flash_info.block_size = 256; +#ifdef AT91_MC_FMR1 + flash_info.blocks = 2048; + lock_bits = 32; +#else flash_info.blocks = 1024; lock_bits = 16; (*flash_info.pf)("at91_flash: Only EFC0 is supported for writes and locks"); - //flash_info.blocks = 2048; - //lock_bits = 32; - break; #endif - default: - goto out; - } + break; + default: + goto out; + } } flash_info.buffer_size = 0; flash_info.start = (void *) 0x00100000; - flash_info.end = (void *)(((cyg_uint32) flash_info.start) + + flash_info.end = (void *)(((cyg_uint32) flash_info.start) + flash_info.block_size * flash_info.blocks); #ifdef CYGBLD_DEV_FLASH_AT91_LOCKING sector_size = flash_info.block_size * flash_info.blocks / lock_bits; #endif // Set the FLASH clock to 1.5 microseconds based on the MCLK. This // assumes the CPU is still running from the PLL clock as defined in - // the HAL CDL and the HAL startup code. - fmcn = CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 1.5 / 1000000 + 0.999999; // We must round up! + // the HAL CDL and the HAL startup code. HAL_READ_UINT32(AT91_MC+AT91_MC_FMR, flash_mode); flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK; - flash_mode = flash_mode | (fmcn << AT91_MC_FMR_FMCN_SHIFT); + flash_mode = flash_mode | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT); HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR, flash_mode); #ifdef AT91_MC_FMR1 - HAL_READ_UINT32(AT91_MC+AT91_MC_FMR1, flash_mode); - flash_mode = flash_mode & ~AT91_MC_FMR_FMCN_MASK; - flash_mode = flash_mode | (fmcn << AT91_MC_FMR_FMCN_SHIFT); HAL_WRITE_UINT32(AT91_MC+AT91_MC_FMR1, flash_mode); #endif - + return FLASH_ERR_OK; - + out: (*flash_info.pf)("Can't identify FLASH, sorry, ChipID1 %x\n", chipID1r ); @@ -326,26 +446,26 @@ // Erase a block. The flash controller does not have a command to // erase a block. So instead we setup the controller to do a program // writing all 0xff with an erase operation first. -int -flash_erase_block (volatile unsigned long block) +int +flash_erase_block (volatile unsigned long block) { cyg_uint32 retcode; cyg_uint32 *buffer; cyg_uint32 *end; - + buffer = (cyg_uint32 *) block; end = (cyg_uint32 *) (block + flash_info.block_size); - - while (buffer < end){ + + while (buffer < end){ *buffer = (cyg_uint32) 0xffffffff; buffer++; } - + flash_erase_before_write_enable(); - retcode = flash_run_command(block, - AT91_MC_FCR_START_PROG, + retcode = flash_run_command(block, + AT91_MC_FCR_START_PROG, FLASH_TIMEOUT); - + return retcode; } @@ -354,29 +474,29 @@ // checks that these conditions are upheld. It would be possible to // perform extra reads and masking operation to support writing to // none word assigned addresses or not multiple or a word length. -int +int flash_program_buf (volatile unsigned long addr, unsigned long *data, int len) { cyg_uint32 retcode; volatile unsigned long *target; - + CYG_ASSERT(len % 4 == 0, "Only word writes allowed by current code"); CYG_ASSERT(addr % 4 == 0, "Address must be word aligned for current code"); - + target = (volatile unsigned long *)addr; - + while (len > 0) { *target = *data; data++; target++; len = len - sizeof(unsigned long); } - + flash_erase_before_write_disable(); - retcode = flash_run_command(addr, - AT91_MC_FCR_START_PROG, + retcode = flash_run_command(addr, + AT91_MC_FCR_START_PROG, FLASH_TIMEOUT); - + return retcode; } @@ -390,15 +510,24 @@ cyg_uint32 sector; cyg_uint32 retcode; cyg_uint32 status; - - sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) / + + sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) / sector_size; - + +#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */ + if (sector < SECTOR_AT_WITCH_WE_USE_THE_EFC1){ + HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status); + } else { + HAL_READ_UINT32(AT91_MC + AT91_MC_FSR1, status); + sector = sector - SECTOR_AT_WITCH_WE_USE_THE_EFC1; + } +#else HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status); - +#endif + if (status & (1 << (sector + 16))){ - retcode = flash_run_command(block, - AT91_MC_FCR_UNLOCK, + retcode = flash_run_command(block, + AT91_MC_FCR_UNLOCK, FLASH_TIMEOUT); return retcode; } else { @@ -415,24 +544,33 @@ cyg_uint32 sector; cyg_uint32 retcode; cyg_uint32 status; - - sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) / + + sector = (((cyg_uint32) block) - (cyg_uint32) flash_info.start) / sector_size; +#ifdef AT91_MC_FMR1 /* or in other words at91sam7x512 */ + if (sector < SECTOR_AT_WITCH_WE_USE_THE_EFC1){ + HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status); + } else { + HAL_READ_UINT32(AT91_MC + AT91_MC_FSR1, status); + sector = sector - SECTOR_AT_WITCH_WE_USE_THE_EFC1; + } +#else HAL_READ_UINT32(AT91_MC + AT91_MC_FSR, status); - +#endif + if (!(status & (1 << (sector + 16)))){ - retcode = flash_run_command(block, - AT91_MC_FCR_LOCK, + retcode = flash_run_command(block, + AT91_MC_FCR_LOCK, FLASH_TIMEOUT); - + return retcode; } else { return FLASH_ERR_OK; } } -#endif - +#endif + // Map a hardware status to a package error. NOP since the errors are // already mapped. int flash_hwr_map_error(int err){ Index: packages/hal/arm/at91/at91sam7s/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/at91sam7s/current/ChangeLog,v retrieving revision 1.21 diff -u -r1.21 ChangeLog --- packages/hal/arm/at91/at91sam7s/current/ChangeLog 3 Nov 2008 08:40:01 -0000 1.21 +++ packages/hal/arm/at91/at91sam7s/current/ChangeLog 4 Jun 2009 07:30:50 -0000 @@ -1,3 +1,8 @@ +2009-06-03 Oliver Munz o...@snr.ch + * Fix the the problem of switching the PCM-settings if + the PCM is allready up. And impruve the flash-controller + programming. + 2009-11-03 Gabor Toeroek <tgabo...@gmail.com> * cdl/hal_arm_at91sam7s.cdl Index: packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h,v retrieving revision 1.5 diff -u -r1.5 hal_platform_setup.h --- packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h 2 Sep 2008 05:37:51 -0000 1.5 +++ packages/hal/arm/at91/at91sam7s/current/include/hal_platform_setup.h 4 Jun 2009 07:30:50 -0000 @@ -43,10 +43,10 @@ //#####DESCRIPTIONBEGIN#### // // Author(s): gthomas -// Contributors:gthomas, asl -// Date: 2006-02-18 +// Contributors:gthomas, asl, Oliver Munz +// Date: 2009-06-03 // Purpose: AT91SAM7S platform specific support routines -// Description: +// Description: // Usage: #include <cyg/hal/hal_platform_setup.h> // //####DESCRIPTIONEND#### @@ -56,79 +56,109 @@ #include <cyg/hal/var_io.h> #include <cyg/hal/plf_io.h> -// Macro to initialise the Memory Controller - .macro _flash_init -__flash_init__: - ldr r0,=AT91_MC +#ifdef CYG_HAL_STARTUP_ROM + + +#define AT91_FLASH_FMCN_VALUE (CYGNUM_HAL_ARM_AT91_CLOCK_SPEED * 15 / 10000000 + 1) +#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK) +# define AT91_PMC_MOR_VALUE (AT91_PMC_MOR_OSCBYPASS) +#else +# define AT91_PMC_MOR_VALUE (AT91_PMC_MOR_OSCCOUNT(CYGNUM_HAL_ARM_AT91_PMC_MOR_OSCCOUNT) | AT91_PMC_MOR_MOSCEN) +#endif +#define AT91_PMC_PLLR_VALUE (AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER) | AT91_PMC_PLLR_PLLCOUNT(CYGNUM_HAL_ARM_AT91_PLL_COUNT) | AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1) | AT91_PMC_PLLR_USBDIV_1) +#define AT91_PMC_MCKR_VALUE (AT91_PMC_MCKR_PRES_CLK_2 | AT91_PMC_MCKR_PLL_CLK) + +#define AT91_PMC_FLASH_VALUE_SLOW (AT91_MC_FMR_2FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT)) #if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 60000000 // When the clock is running faster than 60MHz we need two wait states - ldr r1,=(AT91_MC_FMR_2FWS) -#else -# if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 30000000 +# define AT91_PMC_FLASH_VALUE AT91_PMC_FLASH_VALUE_SLOW +#else +# if CYGNUM_HAL_ARM_AT91_CLOCK_SPEED > 30000000 // When the clock is running faster than 30MHz we need a wait state - ldr r1,=(AT91_MC_FMR_1FWS) -# else +# define AT91_PMC_FLASH_VALUE (AT91_MC_FMR_1FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT)) +# else // We have a slow clock, no extra wait states are needed - ldr r1,=AT91_MC_FMR_0FWS -# endif +# define AT91_PMC_FLASH_VALUE (AT91_MC_FMR_0FWS | (AT91_FLASH_FMCN_VALUE << AT91_MC_FMR_FMCN_SHIFT)) +# endif #endif + + + +// Macro whit subroutines + .macro _subroutines + b subroutines_end + + +set_flash_from_r1: + push {lr} + ldr r0,=AT91_MC str r1,[r0,#AT91_MC_FMR] #if defined(AT91_MC_FMR1) - // If we have a second flash controller we need to set that up as well str r1,[r0,#AT91_MC_FMR1] #endif + pop {pc} + + +wait_for_flag_pcm_r0r1: + push {r2, lr} +wait_loop: + ldr r2,[r0,#AT91_PMC_SR] + ands r2,r1,r2 + beq wait_loop + pop {r2, pc} + + +subroutines_end: .endm + + + + // Macro to start the main clock. .macro _main_clock_init __main_clock_init__: ldr r0,=AT91_PMC - // Check that we have a stable clock before we start switching -wait_pmc_sr_0: - ldr r1,[r0,#AT91_PMC_SR] - ands r1,r1,#AT91_PMC_SR_MCKRDY - beq wait_pmc_sr_0 - - // Swap to the slow clock, just to be sure. - ldr r1,=(AT91_PMC_MCKR_PRES_CLK|AT91_PMC_MCKR_SLOW_CLK) - str r1,[r0,#AT91_PMC_MCKR] - -#if defined(CYGNUM_HAL_ARM_AT91_CLOCK_TYPE_EXTCLOCK) - ldr r1,=(AT91_PMC_MOR_OSCBYPASS) -#else - ldr r1,=(AT91_PMC_MOR_OSCCOUNT(CYGNUM_HAL_ARM_AT91_PMC_MOR_OSCCOUNT)|AT91_PMC_MOR_MOSCEN) -#endif - str r1,[r0,#AT91_PMC_MOR] - + ldr r2,=AT91_PMC_MOR_VALUE // Load our PMC settings in registers + ldr r3,=AT91_PMC_PLLR_VALUE + ldr r4,=AT91_PMC_MCKR_VALUE + + ldr r5,[r0,#AT91_PMC_MOR] // Test if the PMC is allready up + cmp r2, r5 + bne set_pcm_registers // Do the init + ldr r5,[r0,#AT91_PMC_PLLR] + cmp r3, r5 + bne set_pcm_registers // Do the init + ldr r5,[r0,#AT91_PMC_MCKR] + cmp r4, r5 + bne set_pcm_registers // Do the init + b pmc_done // All registers are where we want it... + + // We have to set the PMC +set_pcm_registers: + str r2,[r0,#AT91_PMC_MOR] // Wait for oscilator start timeout -wait_pmc_sr_1: - ldr r1,[r0,#AT91_PMC_SR] - ands r1,r1,#AT91_PMC_SR_MOSCS - beq wait_pmc_sr_1 + ldr r1, =AT91_PMC_SR_MOSCS + bl wait_for_flag_pcm_r0r1 // Set the PLL multiplier and divider. 16 slow clocks go by // before the LOCK bit is set. */ - ldr r1,=((AT91_PMC_PLLR_DIV(CYGNUM_HAL_ARM_AT91_PLL_DIVIDER))|(AT91_PMC_PLLR_PLLCOUNT(CYGNUM_HAL_ARM_AT91_PLL_COUNT))|(AT91_PMC_PLLR_MUL(CYGNUM_HAL_ARM_AT91_PLL_MULTIPLIER-1))) - str r1,[r0,#AT91_PMC_PLLR] - + str r3,[r0,#AT91_PMC_PLLR] // Wait for PLL locked indication -wait_pmc_sr_2: - ldr r1,[r0,#AT91_PMC_SR] - ands r1,r1,#AT91_PMC_SR_LOCK - beq wait_pmc_sr_2 + ldr r1, =AT91_PMC_SR_LOCK + bl wait_for_flag_pcm_r0r1 // Enable the PLL clock and set the prescale to 2 */ - ldr r1,=(AT91_PMC_MCKR_PRES_CLK_2|AT91_PMC_MCKR_PLL_CLK) - str r1,[r0,#AT91_PMC_MCKR] - + str r4,[r0,#AT91_PMC_MCKR] // Wait for the MCLK ready indication -wait_pmc_sr_3: - ldr r1,[r0,#AT91_PMC_SR] - ands r1,r1,#AT91_PMC_SR_MCKRDY - beq wait_pmc_sr_3 + ldr r1, =AT91_PMC_SR_MCKRDY + bl wait_for_flag_pcm_r0r1 + +pmc_done: .endm + // Remap the flash from address 0x0 and place RAM there instead. .macro _remap_flash __remap_flash: @@ -137,7 +167,7 @@ ldr r2,[r0] // Save away copies so we can restore them ldr r3,[r1] ldr r4,=0xffffff - eor r4,r3,r4 // XOR the contents of 0x20004 + eor r4,r3,r4 // XOR the contents of 0x20004 str r4,[r1] // and write it ldr r5,[r0] // Read from low memory cmp r5,r4 @@ -148,11 +178,16 @@ remap_done: str r3,[r1] // restore the value we changed .endm - -#if defined(CYG_HAL_STARTUP_ROM) - .macro _setup - _flash_init + + + .macro _setup //The "main" of the macros... + _subroutines + ldr sp,.__startup_stack + ldr r1,=AT91_PMC_FLASH_VALUE_SLOW // May be we run >60Mhz at the moment + bl set_flash_from_r1 _main_clock_init + ldr r1,=AT91_PMC_FLASH_VALUE + bl set_flash_from_r1 _remap_flash .endm Index: packages/hal/arm/at91/at91sam7s/current/include/plf_io.h =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/at91sam7s/current/include/plf_io.h,v retrieving revision 1.10 diff -u -r1.10 plf_io.h --- packages/hal/arm/at91/at91sam7s/current/include/plf_io.h 3 Nov 2008 08:40:01 -0000 1.10 +++ packages/hal/arm/at91/at91sam7s/current/include/plf_io.h 4 Jun 2009 07:30:50 -0000 @@ -41,9 +41,9 @@ // // Author(s): tkoeller // Contributors: andrew lunn, Oliver Munz -// Date: 2005-12-31 +// Date: 2009-06-03 // Purpose: Atmel AT91SAM7S board specific registers -// Description: +// Description: // Usage: #include <cyg/hal/plf_io.h> // //####DESCRIPTIONEND#### @@ -62,7 +62,7 @@ #define AT91_SPI AT91_SPI0 -// DMA registers +// DMA registers #define AT91_SPI_RPR 0x100 // Receive Pointer Register #define AT91_SPI_RCR 0x104 // Receive Counter Register #define AT91_SPI_TPR 0x108 // Transmit Pointer Register @@ -92,8 +92,8 @@ // Define USART2 to be the debug UART. It is similar enough to a USART // that both the hal_diag and interrupt driven driver will work. // However trying to change parity, start/stop bits etc will not work. -#define CYGNUM_HAL_INTERRUPT_USART2 CYGNUM_HAL_INTERRUPT_DBG -#define AT91_USART2 AT91_DBG +#define CYGNUM_HAL_INTERRUPT_USART2 CYGNUM_HAL_INTERRUPT_DBG +#define AT91_USART2 AT91_DBG #ifndef __ASSEMBLER__ #ifdef CYGBLD_HAL_ARM_AT91_BAUD_DYNAMIC @@ -108,7 +108,7 @@ #define AT91_US_TCR 0x10C // Transmit Counter Register #define AT91_US_NRPR 0x110 // Next Receive Pointer Register #define AT91_US_NRCR 0x114 // Next Receive Counter Register -#define AT91_US_NTPR 0x118 // Next Transmit Pointer Register +#define AT91_US_NTPR 0x118 // Next Transmit Pointer Register #define AT91_US_NTCR 0x11C // Next Transmit Counter Register #define AT91_US_PTCR 0x120 // PDC Transfer Control Register #define AT91_US_PTSR 0x124 // PDC Transfer Status Register @@ -175,16 +175,19 @@ // CAN - Controller Area Network -#define AT91_CAN 0xFFFD0000 +#define AT91_CAN 0xFFFD0000 #endif #if defined(CYGHWR_HAL_ARM_AT91SAM7_at91sam7x512) || \ defined(CYGHWR_HAL_ARM_AT91SAM7_at91sam7s512) || \ defined(CYGHWR_HAL_ARM_AT91SAM7_at91sam7se512) -#define AT91_MC_FMR0 0x60 -#define AT91_MC_FMR1 0x70 -#define AT91_MC_FMR AT91_MC_FMR0 +#define AT91_MC_FMR0 AT91_MC_FMR +#define AT91_MC_FCR0 AT91_MC_FCR +#define AT91_MC_FSR0 AT91_MC_FSR +#define AT91_MC_FMR1 (AT91_MC_FMR + 0x10) +#define AT91_MC_FCR1 (AT91_MC_FCR + 0x10) +#define AT91_MC_FSR1 (AT91_MC_FSR + 0x10) #endif //---------------------------------------------------------------------- @@ -199,9 +202,9 @@ extern void hal_plf_eth_init(void); #define HAL_PLF_ETH_INIT() \ hal_plf_eth_init() -#endif +#endif -#endif //__ASSEMBLER__ +#endif //__ASSEMBLER__ #endif //CYGONCE_HAL_PLF_IO_H Index: packages/hal/arm/at91/var/current/ChangeLog =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/ChangeLog,v retrieving revision 1.44 diff -u -r1.44 ChangeLog --- packages/hal/arm/at91/var/current/ChangeLog 3 Nov 2008 08:39:26 -0000 1.44 +++ packages/hal/arm/at91/var/current/ChangeLog 4 Jun 2009 07:30:52 -0000 @@ -1,3 +1,9 @@ +2009-06-03 Oliver Munz o...@snr.ch + * Fix the a problem in the kernel delay_us, if the PIT is initalised + later then the periode. If the PIT has a big periode (after reset) + and has to be set to a lower periode one has to be sure that the counter + is lower then the periode value one want to set... + 2008-11-03 Gabor Toeroek <tgabo...@gmail.com> * include/var_io.h: Added defines for AT91SAM7SE. Index: packages/hal/arm/at91/var/current/src/timer_pit.c =================================================================== RCS file: /cvs/ecos/ecos/packages/hal/arm/at91/var/current/src/timer_pit.c,v retrieving revision 1.4 diff -u -r1.4 timer_pit.c --- packages/hal/arm/at91/var/current/src/timer_pit.c 20 Feb 2007 21:33:03 -0000 1.4 +++ packages/hal/arm/at91/var/current/src/timer_pit.c 4 Jun 2009 07:30:52 -0000 @@ -39,9 +39,9 @@ // // Author(s): asl, Oliver Munz // Contributors: asl, Oliver Munz -// Date: 2006-02-12 +// Date: 2009-06-03 // Purpose: Clock support using the PIT -// Description: +// Description: // //####DESCRIPTIONEND#### // @@ -57,21 +57,48 @@ // ------------------------------------------------------------------------- // Use system clock void -hal_clock_initialize(cyg_uint32 period) -{ - cyg_uint32 sr; - - CYG_ASSERT(CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PITC, - "Invalid timer interrupt"); - - /* Set Period Interval timer and enable interrupt */ - HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), - (period - 1) | - AT91_PITC_PIMR_PITEN | - AT91_PITC_PIMR_PITIEN); - - // Read the status register to clear any pending interrupt - HAL_READ_UINT32(AT91_PITC + AT91_PITC_PISR, sr); +hal_clock_initialize(cyg_uint32 period){ + + cyg_uint32 ir; + cyg_uint32 pimr; + + CYG_ASSERT(CYGNUM_HAL_INTERRUPT_RTC == CYGNUM_HAL_INTERRUPT_PITC, + "Invalid timer interrupt"); + CYG_ASSERT(period <= AT91_PITC_VALUE_MASK, + "Invalid timer period"); + + pimr = (period - 1); /* This is what we want */ + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); /* Counter */ + ir = ir & AT91_PITC_VALUE_MASK; /* The current counts */ + + do { /* Test if the new PITC-Moduls is overrun by the counter */ + + if (ir > pimr){ /* If the counter is already to high */ + + pimr = (ir + 100) & AT91_PITC_VALUE_MASK; /* Set the comparator a head */ + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), + pimr | AT91_PITC_PIMR_PITEN); + } + if (ir < (period - 1)){ /* If we can try it */ + + pimr = (period - 1); /* This is what we want */ + /* Set the real Period Interval timer */ + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), + pimr | AT91_PITC_PIMR_PITEN); + } + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, pimr); /* The real value */ + pimr = pimr & AT91_PITC_VALUE_MASK; /* Value */ + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); /* Counter */ + ir = ir & AT91_PITC_VALUE_MASK; /* The current counts */ + + } while (ir > (period -1) || pimr != (period - 1)); // Is it correct? + + /* Enable interrupt */ + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), (period - 1) | + AT91_PITC_PIMR_PITEN | AT91_PITC_PIMR_PITIEN); + + /* Read the status register to clear any pending interrupt */ + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PISR, ir); } // This routine is called during a clock interrupt. @@ -80,14 +107,14 @@ { cyg_uint32 reg; cyg_uint32 pimr; - + CYG_ASSERT(period < AT91_PITC_VALUE_MASK, "Invalid HAL clock configuration"); - + // Check that the PIT has the right period. HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR), pimr); if ((pimr & AT91_PITC_VALUE_MASK) != (period - 1)) { - HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), - (period - 1) | + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), + (period - 1) | AT91_PITC_PIMR_PITEN | AT91_PITC_PIMR_PITIEN); } @@ -104,14 +131,14 @@ { cyg_uint32 ir; cyg_uint32 pimr; - + // Check that the PIT is running. If not start it. HAL_READ_UINT32((AT91_PITC + AT91_PITC_PIMR),pimr); if (!(pimr & AT91_PITC_PIMR_PITEN)) { - HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), + HAL_WRITE_UINT32((AT91_PITC + AT91_PITC_PIMR), AT91_PITC_VALUE_MASK | AT91_PITC_PIMR_PITEN); } - + HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIIR, ir); *pvalue = ir & AT91_PITC_VALUE_MASK; } @@ -126,23 +153,23 @@ cyg_int64 ticks; cyg_uint32 val1, val2; cyg_uint32 piv; - + // Calculate how many PIT ticks the required number of microseconds // equate to. We do this calculation in 64 bit arithmetic to avoid // overflow. - ticks = (((cyg_uint64)usecs) * + ticks = (((cyg_uint64)usecs) * ((cyg_uint64)CYGNUM_HAL_ARM_AT91_CLOCK_SPEED))/16/1000000LL; - - // Calculate the wrap around period. + + // Calculate the wrap around period. HAL_READ_UINT32(AT91_PITC + AT91_PITC_PIMR, piv); - piv = (piv & AT91_PITC_VALUE_MASK) - 1; - + piv = (piv & AT91_PITC_VALUE_MASK) - 1; + hal_clock_read(&val1); while (ticks > 0) { hal_clock_read(&val2); if (val2 < val1) ticks -= ((piv + val2) - val1); //overflow occurred - else + else ticks -= (val2 - val1); val1 = val2; }