+bool FpgaSetupSscDma(uint8_t *buf, int len) {
+ if (buf == NULL) return false;
+
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; // Disable DMA Transfer
+ AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
+ AT91C_BASE_PDC_SSC->PDC_RCR = len; // transfer this many bytes
+ AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; // next transfer to same memory address
+ AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes
+ AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTEN; // go!
+ return true;
+}
+
+
+//----------------------------------------------------------------------------
+// Uncompress (inflate) the FPGA data. Returns one decompressed byte with
+// each call.
+//----------------------------------------------------------------------------
+static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer)
+{
+ if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
+ compressed_fpga_stream->next_out = output_buffer;
+ compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
+ fpga_image_ptr = output_buffer;
+ int res = inflate(compressed_fpga_stream, Z_SYNC_FLUSH);
+
+ if (res != Z_OK)
+ Dbprintf("inflate returned: %d, %s", res, compressed_fpga_stream->msg);
+
+ if (res < 0)
+ return res;
+ }
+
+ ++uncompressed_bytes_cnt;
+
+ return *fpga_image_ptr++;
+}
+
+//----------------------------------------------------------------------------
+// Undo the interleaving of several FPGA config files. FPGA config files
+// are combined into one big file:
+// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
+//----------------------------------------------------------------------------
+static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
+{
+ while((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % FPGA_BITSTREAM_MAX != (bitstream_version - 1)) {
+ // skip undesired data belonging to other bitstream_versions
+ get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
+ }
+
+ return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
+}
+
+
+static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size)
+{
+ return BigBuf_malloc(items*size);
+}
+
+
+static void fpga_inflate_free(voidpf opaque, voidpf address)
+{
+ // free eventually allocated BigBuf memory
+ BigBuf_free(); BigBuf_Clear_ext(false);
+}
+
+
+//----------------------------------------------------------------------------
+// Initialize decompression of the respective (HF or LF) FPGA stream
+//----------------------------------------------------------------------------
+static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer)