// Download the fpga image starting at FpgaImage and with length FpgaImageLen bytes // If bytereversal is set: reverse the byte order in each 4-byte word static void DownloadFPGA(const char *FpgaImage, int FpgaImageLen, int bytereversal) { int i=0; AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON; HIGH(GPIO_FPGA_ON); // ensure everything is powered on SpinDelay(50); LED_D_ON(); // These pins are inputs AT91C_BASE_PIOA->PIO_ODR = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // PIO controls the following pins AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // Enable pull-ups AT91C_BASE_PIOA->PIO_PPUER = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // setup initial logic state HIGH(GPIO_FPGA_NPROGRAM); LOW(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_DIN); // These pins are outputs AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_NPROGRAM | GPIO_FPGA_CCLK | GPIO_FPGA_DIN; // enter FPGA configuration mode LOW(GPIO_FPGA_NPROGRAM); SpinDelay(50); HIGH(GPIO_FPGA_NPROGRAM); i=100000; // wait for FPGA ready to accept data signal while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) { i--; } // crude error indicator, leave both red LEDs on and return if (i==0){ LED_C_ON(); LED_D_ON(); return; } if(bytereversal) { /* This is only supported for uint32_t aligned images */ if( ((int)FpgaImage % sizeof(uint32_t)) == 0 ) { i=0; while(FpgaImageLen-->0) DownloadFPGA_byte(FpgaImage[(i++)^0x3]); /* Explanation of the magic in the above line: * i^0x3 inverts the lower two bits of the integer i, counting backwards * for each 4 byte increment. The generated sequence of (i++)^3 is * 3 2 1 0 7 6 5 4 11 10 9 8 15 14 13 12 etc. pp. */ } } else { while(FpgaImageLen-->0) DownloadFPGA_byte(*FpgaImage++); } // continue to clock FPGA until ready signal goes high i=100000; while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) { HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); } // crude error indicator, leave both red LEDs on and return if (i==0){ LED_C_ON(); LED_D_ON(); return; } LED_D_OFF(); }
// Download the fpga image starting at current stream position with length FpgaImageLen bytes static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { Dbprintf("DownloadFPGA(len: %d)", FpgaImageLen); int i=0; AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON; HIGH(GPIO_FPGA_ON); // ensure everything is powered on SpinDelay(50); LED_D_ON(); // These pins are inputs AT91C_BASE_PIOA->PIO_ODR = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // PIO controls the following pins AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // Enable pull-ups AT91C_BASE_PIOA->PIO_PPUER = GPIO_FPGA_NINIT | GPIO_FPGA_DONE; // setup initial logic state HIGH(GPIO_FPGA_NPROGRAM); LOW(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_DIN); // These pins are outputs AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_NPROGRAM | GPIO_FPGA_CCLK | GPIO_FPGA_DIN; // enter FPGA configuration mode LOW(GPIO_FPGA_NPROGRAM); SpinDelay(50); HIGH(GPIO_FPGA_NPROGRAM); i=100000; // wait for FPGA ready to accept data signal while ((i) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT ) ) ) { i--; } // crude error indicator, leave both red LEDs on and return if (i==0){ LED_C_ON(); LED_D_ON(); return; } for(i = 0; i < FpgaImageLen; i++) { int b = get_from_fpga_stream(bitstream_version, compressed_fpga_stream, output_buffer); if (b < 0) { Dbprintf("Error %d during FpgaDownload", b); break; } DownloadFPGA_byte(b); } // continue to clock FPGA until ready signal goes high i=100000; while ( (i--) && ( !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE ) ) ) { HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); } // crude error indicator, leave both red LEDs on and return if (i==0){ LED_C_ON(); LED_D_ON(); return; } LED_D_OFF(); }