/** Removes access to the target's NVM controller and physically disables the target's physical PDI interface. */ void XMEGANVM_DisablePDI(void) { XMEGANVM_WaitWhileNVMBusBusy(); /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(0x00); /* Do it twice to make sure it takes effect (silicon bug?) */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(0x00); XPROGTarget_DisableTargetPDI(); }
/** Removes access to the target's NVM controller and physically disables the target's physical PDI interface. */ void XMEGANVM_DisablePDI(void) { XMEGANVM_WaitWhileNVMBusBusy(); /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run - must perform this until the * change takes effect, as in some cases it takes multiple writes (silicon bug?). */ do { /* Clear reset register */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(0x00); /* Read back the reset register, check to see if it took effect */ XPROGTarget_SendByte(PDI_CMD_LDCS | PDI_RESET_REG); } while (XPROGTarget_ReceiveByte() != 0x00); XPROGTarget_DisableTargetPDI(); }
/** Handler for the XPROG LEAVE_PROGMODE command to terminate the PDI programming connection with * the attached device. */ static void XPROGProtocol_LeaveXPROGMode(void) { Endpoint_ClearOUT(); Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPNUM); Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN); if (XPROG_SelectedProtocol == XPRG_PROTOCOL_PDI) { XMEGANVM_WaitWhileNVMBusBusy(); /* Clear the RESET key in the RESET PDI register to allow the XMEGA to run */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(0x00); /* Do it twice to make sure it takes affect (silicon bug?) */ XPROGTarget_SendByte(PDI_CMD_STCS | PDI_RESET_REG); XPROGTarget_SendByte(0x00); XPROGTarget_DisableTargetPDI(); } else { TINYNVM_WaitWhileNVMBusBusy(); /* Clear the NVMEN bit in the TPI CONTROL register to disable TPI mode */ XPROGTarget_SendByte(TPI_CMD_SSTCS | TPI_CTRL_REG); XPROGTarget_SendByte(0x00); XPROGTarget_DisableTargetTPI(); } Endpoint_Write_Byte(CMD_XPROG); Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE); Endpoint_Write_Byte(XPRG_ERR_OK); Endpoint_ClearIN(); }
/*! \brief Main function. Execution starts here. */ int main(void) { uint32_t serial_number[4]; // Read Device-ID from SAM3U. Do this before enabling interrupts etc. flash_read_unique_id(serial_number, sizeof(serial_number)); configure_console(); irq_initialize_vectors(); cpu_irq_enable(); // Initialize the sleep manager sleepmgr_init(); #if !SAMD21 && !SAMR21 sysclk_init(); board_init(); #else system_init(); #endif //Tri-state XPROG pins XPROGTarget_DisableTargetPDI(); //Convert serial number to ASCII for USB Serial number for(unsigned int i = 0; i < 4; i++){ sprintf(usb_serial_number+(i*8), "%08x", (unsigned int)serial_number[i]); } usb_serial_number[32] = 0; printf("ChipWhisperer-Lite Online. Firmware build: %s/%s\n", __TIME__, __DATE__); printf("Serial number: %s\n", usb_serial_number); /* Enable SMC */ pmc_enable_periph_clk(ID_SMC); gpio_configure_pin(PIN_EBI_DATA_BUS_D0, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_DATA_BUS_D1, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_DATA_BUS_D2, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_DATA_BUS_D3, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_DATA_BUS_D4, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_DATA_BUS_D5, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_DATA_BUS_D6, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_DATA_BUS_D7, PIN_EBI_DATA_BUS_FLAG1); gpio_configure_pin(PIN_EBI_NRD, PIN_EBI_NRD_FLAGS); gpio_configure_pin(PIN_EBI_NWE, PIN_EBI_NWE_FLAGS); gpio_configure_pin(PIN_EBI_NCS0, PIN_EBI_NCS0_FLAGS); /* We don't use address mapping so don't enable this */ /* gpio_configure_pin(PIN_EBI_ADDR_BUS_A1, PIN_EBI_ADDR_BUS_FLAG1); gpio_configure_pin(PIN_EBI_ADDR_BUS_A2, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A3, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A4, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A5, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A6, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A7, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A8, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A9, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A10, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A11, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A12, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A13, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A14, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A15, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A16, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A17, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A18, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A19, PIN_EBI_ADDR_BUS_FLAG2); gpio_configure_pin(PIN_EBI_ADDR_BUS_A20, PIN_EBI_ADDR_BUS_FLAG2); */ /* Configure EBI I/O for PSRAM connection */ printf("Setting up FPGA Communication\n"); /* complete SMC configuration between PSRAM and SMC waveforms. */ smc_set_setup_timing(SMC, 0, SMC_SETUP_NWE_SETUP(0) | SMC_SETUP_NCS_WR_SETUP(1) | SMC_SETUP_NRD_SETUP(1) | SMC_SETUP_NCS_RD_SETUP(1)); smc_set_pulse_timing(SMC, 0, SMC_PULSE_NWE_PULSE(1) | SMC_PULSE_NCS_WR_PULSE(1) | SMC_PULSE_NRD_PULSE(3) | SMC_PULSE_NCS_RD_PULSE(1)); smc_set_cycle_timing(SMC, 0, SMC_CYCLE_NWE_CYCLE(2) | SMC_CYCLE_NRD_CYCLE(4)); smc_set_mode(SMC, 0, SMC_MODE_READ_MODE | SMC_MODE_WRITE_MODE | SMC_MODE_DBW_BIT_8); ui_init(); // Start USB stack to authorize VBus monitoring udc_start(); /* Enable PCLK0 at 96 MHz */ genclk_enable_config(GENCLK_PCK_0, GENCLK_PCK_SRC_MCK, GENCLK_PCK_PRES_1); //Following is 60MHz version //genclk_enable_config(GENCLK_PCK_0, GENCLK_PCK_SRC_PLLBCK, GENCLK_PCK_PRES_4); printf("Event Loop Entered, waiting...\n"); // The main loop manages only the power mode // because the USB management is done by interrupt while (true) { sleepmgr_enter_sleep(); } }