#include "usb.h" #include "io.h" #include "buffer.h" #include "bootload.h" #include "jtag.h" #ifdef AVR_CORE #include #include #include #include "usbdrv.h" #endif #ifdef STM_CORE #include #include "../source_stm_only/stm_init.h" #endif int main(void) { #ifdef AVR_CORE //set watch dog timer with 1 second timer wdt_enable(WDTO_1S); /* Even if you don't use the watchdog, turn it off here. On newer devices, * the status of the watchdog (on/off, period) is PRESERVED OVER RESET! */ /* RESET status: all port bits are inputs without pull-up. * That's the way we need D+ and D-. Therefore we don't need any * additional hardware initialization. */ //initialize V-usb driver before interupts enabled and entering main loop usbInit(); //disconnect from host enforce re-enumeration, interupts must be disabled during this. usbDeviceDisconnect(); //fake USB disconnect for over 250ms uint8_t index = 0; while(--index){ //loop 256 times wdt_reset(); //keep wdt happy during this time _delay_ms(1); //delay 256msec } //reconnect to host usbDeviceConnect(); //enable interrupts sei(); #endif #ifdef STM_CORE //remap system memory (including vector table) // SYSCFG->CFGR1 = 0x00000002; //boot value (BOOT1:0 = 0b10 // SYSCFG->CFGR1 = 0x00000001; //map sysmem bootloader to 0x00000000 //SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE_ | 0x0001; //jump to bootloader // jump_to_bootloader(); // jump_to_addr(0x1FFFC519); //System is running at reset defaults //Default clock is in operation //Change system clock as needed init_clock(); //now enable GPIO and set //trying to move to 48Mhz clock for all STM32 cores //If >24Mhz SYSCLK, must add wait state to flash //can also enable prefetch buffer FLASH->ACR = FLASH_ACR_PRFTBE | 0x0001; //switch to 48Mhz RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW) | RCC_CFGR_SW_PLL; //Initialize periphery clocks as needed init_usb_clock(); //Initialize WDT, core features, etc //enable interrupts __enable_irq(); //clear's processor PRIMASK register bit to allow interrupts to be taken //I think this gets done automatically when enabling individual IRQs //Initialize io, periphery, etc //setup LED as outputs and turn them on //setup user switch as input init_usb(); //Initialize board/system #endif //intialize i/o and LED to pullup state io_reset(); //this is just a quick hack to allow measuring HSE with a scope w/o loading the circuit with probes. //#define DRIVE_MCO #ifdef DRIVE_MCO //drive HSE (8Mhz) divided by 8 = 1Mhz for crystal load capacitor calibration RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_MCOPRE) | RCC_CFGR_MCOPRE_DIV8; /* MCO prescaler = div 8 */ //RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_MCOPRE) | RCC_CFGR_MCOPRE_DIV16; /* MCO prescaler = div 16 */ RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_MCO) | RCC_CFGR_MCO_HSE; /* MCO source HSE */ //enable GPIO pin PA8 MCO AF0 //RCC->AHBENR |= RCC_AHBENR_GPIOAEN; //CTL_ENABLE(); nes_init(); //GPIOA->MODER = MODER_AF << (2*8U); //set PA8 to AF GPIOA->MODER = 0x28020000; //set PA14, PA13, (SWD) & PA8 (MCO) to AF //AF0 is the default value of GPIOx_AFRH/L registers so MCO is already selected as AF in use #endif //initialize jtag engine to be off pbje_status = PBJE_OFF; //================= //MAIN LOOP //================= while (1) { #ifdef AVR_CORE //pet the watch doggie to keep him happy wdt_reset(); //must call at regular intervals no longer than 50msec //keeps 8Byte EP buffer moving from what I understand usbPoll(); #endif //check buffer status' and instruct them to //flash/dump as needed to keep data moving //currently assuming this operation doesn't take longer //than 50msec to meet usbPoll's req't //considering using a timer counter interupt to call //usbPoll more often but going to see how speed is //impacted first.. //256Bytes * 20usec Tbp = 5.12msec programming time //+ cpu operations that can't be hid behind flash wait time //another thought would be to call usbPoll mid programming //a few times to prevent incoming data from being delayed too long update_buffers(); //if paul's basic jtag engine "PBJE" is running, main //thread needs to call engine at periodic intervals to keep it //running. if (pbje_status != PBJE_OFF) { jtag_run_pbje(); } } }