diff --git a/radio/src/Makefile b/radio/src/Makefile index 0aef1c9b1..f3a3e5928 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -587,7 +587,8 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) PULSESSRC = protocols/pulses_arm.cpp protocols/ppm_arm.cpp protocols/pxx_arm.cpp protocols/dsm2_arm.cpp CPPSRC += audio_arm.cpp haptic.cpp gui/view_about.cpp CPPSRC += targets/sky9x/pwr_driver.cpp targets/sky9x/adc_driver.cpp targets/sky9x/rotenc_driver.cpp targets/sky9x/eeprom_driver.cpp targets/sky9x/pulses_driver.cpp targets/sky9x/keys_driver.cpp targets/sky9x/audio_driver.cpp targets/sky9x/buzzer_driver.cpp targets/sky9x/haptic_driver.cpp targets/sky9x/sdcard_driver.cpp targets/sky9x/massstorage.cpp - + CPPSRC += loadboot.cpp + ifeq ($(SDCARD), YES) CPPDEFS += -DVOICE INCDIRS += FatFs FatFs/option @@ -1113,20 +1114,32 @@ all: begin gccversion sizebefore build sizeafter end # Change the build target to build a HEX file or a library. ifeq ($(ARCH), AVR) build: stamp_header tra lbm allsrc.cpp elf remallsrc hex -else ifeq ($(PCB), TARANIS) +else ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO TARANIS)) build: stamp_header tra lbm bootloader.lbm allsrc.cpp elf remallsrc bin else build: stamp_header tra lbm allsrc.cpp elf remallsrc bin endif # build bootloader +ifeq ($(PCB), TARANIS) bootloader.lbm: bootloader/bootloader_ramBoot.bin test -z "$$(find $^ -size +32k)" - $(BIN2LBM) $^ $@ + $(BIN2LBM) $^ $@ .PHONY bootloader/bootloader_ramBoot.bin: @echo "Building bootloader..." $(MAKE) -C bootloader PCB=$(PCB) PCBREV=$(PCBREV) +else ifeq ($(PCB), 9XRPRO) +bootloader.lbm: + @echo "Fetching Mike's bootloader..." + wget https://ersky9x.googlecode.com/svn/trunk/src/bootloader/bootflash8.lbm + mv bootflash8.lbm $@ +else ifeq ($(PCB), SKY9X) +bootloader.lbm: + @echo "Fetching Mike's bootloader..." + wget https://ersky9x.googlecode.com/svn/trunk/src/bootloader/bootflash4.lbm + mv bootflash4.lbm $@ +endif tra: translations/en.h translations/cz.h translations/de.h translations/es.h translations/fi.h translations/fr.h translations/it.h translations/pl.h translations/pt.h translations/se.h lbm: fonts bitmaps/sticks.lbm diff --git a/radio/src/loadboot.cpp b/radio/src/loadboot.cpp index 0d27705ff..947b75d05 100644 --- a/radio/src/loadboot.cpp +++ b/radio/src/loadboot.cpp @@ -61,16 +61,22 @@ void bwdt_reset() { IWDG->KR = 0xAAAA; // reload } +#endif +#if defined(PCBTARANIS) +// TODO needed? __attribute__ ((section(".bootrodata"), used)) void _bootStart(void); +#endif +#if defined(PCBTARANIS) __attribute__ ((section(".isr_boot_vector"), used)) const uint32_t BootVectors[] = { (uint32_t) &_estack, (uint32_t) (void (*)(void)) ((unsigned long) &_bootStart) }; +#endif +#if defined(PCBTARANIS) __attribute__ ((section(".bootrodata.*"), used)) - #elif defined(PCBSKY9X) __attribute__ ((section(".bootrodata"), used)) #endif @@ -80,9 +86,7 @@ const uint8_t BootCode[] = { }; #if defined(PCBTARANIS) - __attribute__ ((section(".bootrodata"), used)) - void _bootStart() { RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // Enable portC clock @@ -121,7 +125,8 @@ void _bootStart() } } -// run_application() ; + +// run_application() ; asm(" mov.w r1, #134217728"); // 0x8000000 asm(" add.w r1, #32768"); diff --git a/radio/src/targets/sky9x/board_lowlevel.c b/radio/src/targets/sky9x/board_lowlevel.c index a97fde941..49d3a1b53 100644 --- a/radio/src/targets/sky9x/board_lowlevel.c +++ b/radio/src/targets/sky9x/board_lowlevel.c @@ -177,37 +177,66 @@ static uint32_t BOARD_ConfigurePmc(void) // timeout = 0; // while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT)); - // Switch to PLLA as main clock 36MHz + // Switch to PLLA as main clock 36MHz PMC->PMC_MCKR = BOARD_MCKR; timeout = 0; while (!(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT)); #endif - return 36000000L ; // Master_frequency + return 36000000L; // Master_frequency } void revert_osc() { - register uint32_t timeout = 0 ; - register Pmc *pmcptr ; + register uint32_t timeout = 0; + register Pmc *pmcptr; - pmcptr = PMC ; + pmcptr = PMC; - - // Switch back to the internal oscillator - pmcptr->CKGR_MOR = (0x37 << 16) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN ; + // Switch back to the internal oscillator + pmcptr->CKGR_MOR = (0x37 << 16) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN; timeout = 0; while (!(pmcptr->PMC_SR & PMC_SR_MOSCSELS) && (++timeout < CLOCK_TIMEOUT)); pmcptr->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS) | PMC_MCKR_CSS_SLOW_CLK; timeout = 0; while (!(pmcptr->PMC_SR & PMC_SR_MCKRDY) && (++timeout < CLOCK_TIMEOUT)); - - pmcptr->CKGR_PLLAR = 1 << 29 ; // Stop PLLA - + pmcptr->CKGR_PLLAR = 1 << 29; // Stop PLLA } +#if defined(BOOT) +// extern void sam_bootx( void ) ; +// extern void dispUSB( void ) ; +// extern uint32_t init +// ReadTrims( void ) ; +// extern void run_application( void ) ; + +static void lowLevelUsbCheck( void ) +{ + PMC->PMC_PCER0 = (1<PIO_PER = PIO_PC25 ; // Enable bit C25 (USB-detect) + + uint32_t i ; + for ( i = 0 ; i < 50 ; i += 1 ) { + __asm("nop") ; + } + + for ( i = 0 ; i < 10 ; i += 1 ) { + if ( PIOC->PIO_PDSR & 0x02000000 ) { + PMC->PMC_PCDR0 = (1<EEFC_FMR = (1 << 8) ; +#if defined(BOOT) + lowLevelUsbCheck() ; +#endif - /** Configure PMC */ + // Set 2 cycle (1 WS) for Embedded Flash Access + // Max clock is 38 MHz (1.8V VVDCORE) + EFC->EEFC_FMR = (1 << 8) ; + + // Configure PMC return BOARD_ConfigurePmc(); } diff --git a/radio/src/targets/sky9x/board_sky9x.cpp b/radio/src/targets/sky9x/board_sky9x.cpp index 1492bf1fa..c79c04190 100644 --- a/radio/src/targets/sky9x/board_sky9x.cpp +++ b/radio/src/targets/sky9x/board_sky9x.cpp @@ -556,8 +556,19 @@ void i2cInit() NVIC_EnableIRQ(TWI0_IRQn) ; } +extern const uint8_t BootCode[]; + void boardInit() { + // TODO this is not clean, completely unuseful, but prevents the bootloader from being optimized away... + uint8_t dummy[3]; + memcpy(&dummy, BootCode, sizeof(dummy)); + for (unsigned int i=0; iRSTC_SR; diff --git a/radio/src/targets/sky9x/core_cm3.c b/radio/src/targets/sky9x/core_cm3.c index ad33139f5..debdb3090 100644 --- a/radio/src/targets/sky9x/core_cm3.c +++ b/radio/src/targets/sky9x/core_cm3.c @@ -68,6 +68,8 @@ uint32_t __REV(uint32_t value) ; void revert_osc( void ) ; void sam_boot( void ) ; +void sam_bootx( void ) ; +void run_application( void ) ; /* ################### Compiler specific Intrinsics ########################### */ @@ -459,6 +461,7 @@ uint32_t __STREXW(uint32_t value, uint32_t *addr) #elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/ /* GNU gcc specific functions */ +#if !defined(BOOT) /** * @brief Return the Process Stack Pointer * @@ -633,7 +636,7 @@ void __set_CONTROL(uint32_t control) { __ASM volatile ("MSR control, %0" : : "r" (control) ); } - +#endif /** * @brief Reverse byte order in integer value @@ -651,6 +654,7 @@ uint32_t __REV(uint32_t value) return(result); } +#if !defined(BOOT) /** * @brief Reverse byte order in unsigned short value * @@ -797,10 +801,28 @@ uint32_t __STREXW(uint32_t value, uint32_t *addr) __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); return(result); } +#endif +#if defined(BOOT) +void run_application() +{ + __ASM(" mov.w r1, #4227072"); // 0x408000 + __ASM(" movw r0, #60680"); // 0xED08 + __ASM(" movt r0, #57344"); // 0xE000 + __ASM(" str r1, [r0, #0]"); // Set the VTOR + __ASM("ldr r0, [r1, #0]"); // Stack pointer value + __ASM("msr msp, r0"); // Set it + __ASM("ldr r0, [r1, #4]"); // Reset address + __ASM("mov.w r1, #1"); + __ASM("orr r0, r1"); // Set lsbit + __ASM("bx r0"); // Execute application +} +#endif + +#if !defined(BOOT) void sam_boot() { - revert_osc() ; + revert_osc() ; __ASM(" mov.w r1, #8388608"); __ASM(" movw r0, #60680"); @@ -816,8 +838,26 @@ void sam_boot() __ASM("orr r0, r3"); __ASM("bx r0"); } +#endif - +#if defined(BOOT) +void sam_bootx() +{ + __ASM(" mov.w r1, #8388608"); + __ASM(" movw r0, #60680"); + __ASM(" movt r0, #57344"); + __ASM(" str r1, [r0, #0]"); // Set the VTOR + + __ASM("mov.w r3, #0"); + __ASM("movt r3, #128"); + __ASM("ldr r0, [r3, #0]"); + __ASM("msr msp, r0"); + __ASM("ldr r0, [r3, #4]"); + __ASM("mov.w r3, #1"); + __ASM("orr r0, r3"); + __ASM("bx r0"); +} +#endif #elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/ /* TASKING carm specific functions */ diff --git a/radio/src/targets/sky9x/sam3s4c_flash.ld b/radio/src/targets/sky9x/sam3s4c_flash.ld index 247bf4b1b..083dc52d9 100644 --- a/radio/src/targets/sky9x/sam3s4c_flash.ld +++ b/radio/src/targets/sky9x/sam3s4c_flash.ld @@ -71,15 +71,16 @@ SECTIONS */ .text : { - FILL(0xFFFF) + FILL(0xFFFF) - CREATE_OBJECT_SYMBOLS + CREATE_OBJECT_SYMBOLS *(.bootrodata) *(.bootrodata.*) . = ALIGN(32768); /* Align the start of the exidx part */ _stext = .; /* Provide the name for the start of this section */ + KEEP(*(.vectors)) *(.text) diff --git a/radio/src/targets/sky9x/sam3s8c_flash.ld b/radio/src/targets/sky9x/sam3s8c_flash.ld index 38943f5d9..ee9bdc22d 100644 --- a/radio/src/targets/sky9x/sam3s8c_flash.ld +++ b/radio/src/targets/sky9x/sam3s8c_flash.ld @@ -71,9 +71,15 @@ SECTIONS */ .text : { - _stext = .; /* Provide the name for the start of this section */ + FILL(0xFFFF) CREATE_OBJECT_SYMBOLS + + *(.bootrodata) + *(.bootrodata.*) + + . = ALIGN(32768); /* Align the start of the exidx part */ + _stext = .; /* Provide the name for the start of this section */ KEEP(*(.vectors)) *(.text)