Merge pull request #2593 from Akury83/master
[RRG-proxmark3.git] / armsrc / fpgaloader.c
blobbf7ad765b5ce69f75bd4a86ea4440429943d4783
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Jonathan Westhues, April 2006
3 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // See LICENSE.txt for the text of the license.
16 //-----------------------------------------------------------------------------
17 // Routines to load the FPGA image, and then to configure the FPGA's major
18 // mode once it is configured.
19 //-----------------------------------------------------------------------------
20 #include "fpgaloader.h"
22 #include "proxmark3_arm.h"
23 #include "appmain.h"
24 #include "BigBuf.h"
25 #include "ticks.h"
26 #include "dbprint.h"
27 #include "util.h"
28 #include "fpga.h"
29 #include "string.h"
31 #include "lz4.h" // uncompress
33 typedef struct {
34 LZ4_streamDecode_t *lz4StreamDecode;
35 char *next_in;
36 int avail_in;
37 } lz4_stream_t;
39 typedef lz4_stream_t *lz4_streamp_t;
41 // remember which version of the bitstream we have already downloaded to the FPGA
42 static int downloaded_bitstream = FPGA_BITSTREAM_UNKNOWN;
44 // this is where the bitstreams are located in memory:
45 extern uint32_t _binary_obj_fpga_all_bit_z_start[], _binary_obj_fpga_all_bit_z_end[];
47 static uint8_t *fpga_image_ptr = NULL;
48 static uint32_t uncompressed_bytes_cnt;
50 //-----------------------------------------------------------------------------
51 // Set up the Serial Peripheral Interface as master
52 // Used to write the FPGA config word
53 // May also be used to write to other SPI attached devices like an LCD
54 //-----------------------------------------------------------------------------
55 static void DisableSpi(void) {
56 //* Reset all the Chip Select register
57 AT91C_BASE_SPI->SPI_CSR[0] = 0;
58 AT91C_BASE_SPI->SPI_CSR[1] = 0;
59 AT91C_BASE_SPI->SPI_CSR[2] = 0;
60 AT91C_BASE_SPI->SPI_CSR[3] = 0;
62 // Reset the SPI mode
63 AT91C_BASE_SPI->SPI_MR = 0;
65 // Disable all interrupts
66 AT91C_BASE_SPI->SPI_IDR = 0xFFFFFFFF;
68 // SPI disable
69 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
72 void SetupSpi(int mode) {
73 // PA1 -> SPI_NCS3 chip select (MEM)
74 // PA10 -> SPI_NCS2 chip select (LCD)
75 // PA11 -> SPI_NCS0 chip select (FPGA)
76 // PA12 -> SPI_MISO Master-In Slave-Out
77 // PA13 -> SPI_MOSI Master-Out Slave-In
78 // PA14 -> SPI_SPCK Serial Clock
80 // Disable PIO control of the following pins, allows use by the SPI peripheral
81 AT91C_BASE_PIOA->PIO_PDR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
83 // Peripheral A
84 AT91C_BASE_PIOA->PIO_ASR = GPIO_NCS0 | GPIO_MISO | GPIO_MOSI | GPIO_SPCK;
86 // Peripheral B
87 //AT91C_BASE_PIOA->PIO_BSR |= GPIO_NCS2;
89 //enable the SPI Peripheral clock
90 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
91 // Enable SPI
92 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
94 switch (mode) {
95 case SPI_FPGA_MODE:
96 AT91C_BASE_SPI->SPI_MR =
97 (0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
98 (0xE << 16) | // Peripheral Chip Select (selects FPGA SPI_NCS0 or PA11)
99 (0 << 7) | // Local Loopback Disabled
100 AT91C_SPI_MODFDIS | // Mode Fault Detection disabled
101 (0 << 2) | // Chip selects connected directly to peripheral
102 AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
103 AT91C_SPI_MSTR; // Master Mode
105 AT91C_BASE_SPI->SPI_CSR[0] =
106 (1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
107 (1 << 16) | // Delay Before SPCK (1 MCK period)
108 (6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud
109 AT91C_SPI_BITS_16 | // Bits per Transfer (16 bits)
110 (0 << 3) | // Chip Select inactive after transfer
111 AT91C_SPI_NCPHA | // Clock Phase data captured on leading edge, changes on following edge
112 (0 << 0); // Clock Polarity inactive state is logic 0
113 break;
115 case SPI_LCD_MODE:
116 AT91C_BASE_SPI->SPI_MR =
117 ( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
118 (0xB << 16) | // Peripheral Chip Select (selects LCD SPI_NCS2 or PA10)
119 ( 0 << 7) | // Local Loopback Disabled
120 ( 1 << 4) | // Mode Fault Detection disabled
121 ( 0 << 2) | // Chip selects connected directly to peripheral
122 ( 0 << 1) | // Fixed Peripheral Select
123 ( 1 << 0); // Master Mode
125 AT91C_BASE_SPI->SPI_CSR[2] =
126 ( 1 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
127 ( 1 << 16) | // Delay Before SPCK (1 MCK period)
128 ( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24MHz/6 = 4M baud
129 AT91C_SPI_BITS_9 | // Bits per Transfer (9 bits)
130 ( 0 << 3) | // Chip Select inactive after transfer
131 ( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
132 ( 0 << 0); // Clock Polarity inactive state is logic 0
133 break;
135 default:
136 DisableSpi();
137 break;
141 //-----------------------------------------------------------------------------
142 // Set up the synchronous serial port with the set of options that fits
143 // the FPGA mode. Both RX and TX are always enabled.
144 //-----------------------------------------------------------------------------
145 void FpgaSetupSsc(uint16_t fpga_mode) {
146 // First configure the GPIOs, and get ourselves a clock.
147 AT91C_BASE_PIOA->PIO_ASR =
148 GPIO_SSC_FRAME |
149 GPIO_SSC_DIN |
150 GPIO_SSC_DOUT |
151 GPIO_SSC_CLK;
152 AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
154 AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SSC);
156 // Now set up the SSC proper, starting from a known state.
157 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
159 // RX clock comes from TX clock, RX starts on Transmit Start,
160 // data and frame signal is sampled on falling edge of RK
161 AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(1) | SSC_CLOCK_MODE_START(1);
163 // 8, 16 or 32 bits per transfer, no loopback, MSB first, 1 transfer per sync
164 // pulse, no output sync
165 if (((fpga_mode & FPGA_MAJOR_MODE_MASK) == FPGA_MAJOR_MODE_HF_READER) &&
166 (FpgaGetCurrent() == FPGA_BITSTREAM_HF || FpgaGetCurrent() == FPGA_BITSTREAM_HF_15)) {
167 AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(16) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
168 } else {
169 AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
172 // TX clock comes from TK pin, no clock output, outputs change on rising edge of TK,
173 // TF (frame sync) is sampled on falling edge of TK, start TX on rising edge of TF
174 AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
176 // tx framing is the same as the rx framing
177 AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR;
179 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
182 //-----------------------------------------------------------------------------
183 // Set up DMA to receive samples from the FPGA. We will use the PDC, with
184 // a single buffer as a circular buffer (so that we just chain back to
185 // ourselves, not to another buffer).
186 //-----------------------------------------------------------------------------
187 bool FpgaSetupSscDma(uint8_t *buf, uint16_t len) {
188 if (buf == NULL) return false;
190 FpgaDisableSscDma();
191 AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) buf; // transfer to this memory address
192 AT91C_BASE_PDC_SSC->PDC_RCR = len; // transfer this many bytes
193 AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) buf; // next transfer to same memory address
194 AT91C_BASE_PDC_SSC->PDC_RNCR = len; // ... with same number of bytes
195 FpgaEnableSscDma();
196 return true;
199 //----------------------------------------------------------------------------
200 // Uncompress (inflate) the FPGA data. Returns one decompressed byte with each call.
201 //----------------------------------------------------------------------------
202 static int get_from_fpga_combined_stream(lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) {
203 if (fpga_image_ptr == output_buffer + FPGA_RING_BUFFER_BYTES) { // need more data
204 fpga_image_ptr = output_buffer;
205 int cmp_bytes;
206 memcpy(&cmp_bytes, compressed_fpga_stream->next_in, sizeof(int));
207 compressed_fpga_stream->next_in += 4;
208 compressed_fpga_stream->avail_in -= cmp_bytes + 4;
209 int res = LZ4_decompress_safe_continue(compressed_fpga_stream->lz4StreamDecode,
210 compressed_fpga_stream->next_in,
211 (char *)output_buffer,
212 cmp_bytes,
213 FPGA_RING_BUFFER_BYTES);
214 if (res <= 0) {
215 Dbprintf("inflate returned: %d", res);
216 return res;
218 compressed_fpga_stream->next_in += cmp_bytes;
220 uncompressed_bytes_cnt++;
221 return *fpga_image_ptr++;
224 static int bitstream_target_to_index(FPGA_config bitstream_target) {
225 static int8_t bitstream_index_map[FPGA_CONFIG_COUNT] = {-1};
227 // Initialize
228 if (bitstream_index_map[FPGA_BITSTREAM_UNKNOWN] == -1) {
229 bitstream_index_map[FPGA_BITSTREAM_UNKNOWN] = 0;
231 for (size_t i = 0; i < g_fpga_bitstream_num; i++) {
232 FPGA_VERSION_INFORMATION info = g_fpga_version_information[i];
233 bitstream_index_map[info.target_config] = i;
237 return bitstream_index_map[bitstream_target];
240 //----------------------------------------------------------------------------
241 // Undo the interleaving of several FPGA config files. FPGA config files
242 // are combined into one big file:
243 // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
244 //----------------------------------------------------------------------------
245 static int get_from_fpga_stream(int bitstream_target, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) {
246 int bitstream_index = bitstream_target_to_index(bitstream_target);
247 while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % g_fpga_bitstream_num != bitstream_index) {
248 // skip undesired data belonging to other bitstream_targets
249 get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
252 return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
255 //----------------------------------------------------------------------------
256 // Initialize decompression of the respective (HF or LF) FPGA stream
257 //----------------------------------------------------------------------------
258 static bool reset_fpga_stream(int bitstream_target, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) {
259 uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
261 uncompressed_bytes_cnt = 0;
263 // initialize z_stream structure for inflate:
264 compressed_fpga_stream->next_in = (char *)_binary_obj_fpga_all_bit_z_start;
265 compressed_fpga_stream->avail_in = (uint32_t)_binary_obj_fpga_all_bit_z_end - (uint32_t)_binary_obj_fpga_all_bit_z_start;
267 int res = LZ4_setStreamDecode(compressed_fpga_stream->lz4StreamDecode, NULL, 0);
268 if (res == 0)
269 return false;
271 fpga_image_ptr = output_buffer + FPGA_RING_BUFFER_BYTES;
273 for (uint16_t i = 0; i < FPGA_BITSTREAM_FIXED_HEADER_SIZE; i++)
274 header[i] = get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer);
276 // Check for a valid .bit file (starts with bitparse_fixed_header)
277 if (memcmp(bitparse_fixed_header, header, FPGA_BITSTREAM_FIXED_HEADER_SIZE) == 0)
278 return true;
280 return false;
283 static void DownloadFPGA_byte(uint8_t w) {
284 #define SEND_BIT(x) { if(w & (1<<x) ) HIGH(GPIO_FPGA_DIN); else LOW(GPIO_FPGA_DIN); HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); }
285 SEND_BIT(7);
286 SEND_BIT(6);
287 SEND_BIT(5);
288 SEND_BIT(4);
289 SEND_BIT(3);
290 SEND_BIT(2);
291 SEND_BIT(1);
292 SEND_BIT(0);
295 // Download the fpga image starting at current stream position with length FpgaImageLen bytes
296 static void DownloadFPGA(int bitstream_target, int FpgaImageLen, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) {
297 int i = 0;
298 #if !defined XC3
299 AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
300 AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_ON;
301 HIGH(GPIO_FPGA_ON); // ensure everything is powered on
302 #endif
304 SpinDelay(50);
306 LED_D_ON();
308 // These pins are inputs
309 AT91C_BASE_PIOA->PIO_ODR =
310 GPIO_FPGA_NINIT |
311 GPIO_FPGA_DONE;
312 // PIO controls the following pins
313 AT91C_BASE_PIOA->PIO_PER =
314 GPIO_FPGA_NINIT |
315 #if defined XC3
316 //3S100E M2 & M3 PIO ENA
317 GPIO_SPCK |
318 GPIO_MOSI |
319 #endif
320 GPIO_FPGA_DONE;
322 // Enable pull-ups
323 AT91C_BASE_PIOA->PIO_PPUER =
324 GPIO_FPGA_NINIT |
325 GPIO_FPGA_DONE;
327 // setup initial logic state
328 HIGH(GPIO_FPGA_NPROGRAM);
329 LOW(GPIO_FPGA_CCLK);
330 LOW(GPIO_FPGA_DIN);
331 // These pins are outputs
332 AT91C_BASE_PIOA->PIO_OER =
333 GPIO_FPGA_NPROGRAM |
334 GPIO_FPGA_CCLK |
335 #if defined XC3
336 //3S100E M2 & M3 OUTPUT ENA
337 GPIO_SPCK |
338 GPIO_MOSI |
339 #endif
340 GPIO_FPGA_DIN;
342 #if defined XC3
343 //3S100E M2 & M3 OUTPUT HIGH
344 HIGH(GPIO_SPCK);
345 HIGH(GPIO_MOSI);
346 #endif
348 // enter FPGA configuration mode
349 LOW(GPIO_FPGA_NPROGRAM);
350 SpinDelay(50);
351 HIGH(GPIO_FPGA_NPROGRAM);
353 i = 100000;
354 // wait for FPGA ready to accept data signal
355 while ((i) && (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_NINIT))) {
356 i--;
359 // crude error indicator, leave both red LEDs on and return
360 if (i == 0) {
361 LED_C_ON();
362 LED_D_ON();
363 return;
366 #if defined XC3
367 //3S100E M2 & M3 RETURN TO NORMAL
368 LOW(GPIO_SPCK);
369 LOW(GPIO_MOSI);
370 AT91C_BASE_PIOA->PIO_PDR = GPIO_SPCK | GPIO_MOSI;
371 #endif
373 for (i = 0; i < FpgaImageLen; i++) {
374 int b = get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer);
375 if (b < 0) {
376 Dbprintf("Error %d during FpgaDownload", b);
377 break;
379 DownloadFPGA_byte(b);
382 // continue to clock FPGA until ready signal goes high
383 i = 100000;
384 while ((i--) && (!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_FPGA_DONE))) {
385 HIGH(GPIO_FPGA_CCLK);
386 LOW(GPIO_FPGA_CCLK);
388 // crude error indicator, leave both red LEDs on and return
389 if (i == 0) {
390 LED_C_ON();
391 LED_D_ON();
392 return;
394 LED_D_OFF();
397 /* Simple Xilinx .bit parser. The file starts with the fixed opaque byte sequence
398 * 00 09 0f f0 0f f0 0f f0 0f f0 00 00 01
399 * After that the format is 1 byte section type (ASCII character), 2 byte length
400 * (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
401 * length.
403 static int bitparse_find_section(int bitstream_target, char section_name, uint32_t *section_length, lz4_streamp_t compressed_fpga_stream, uint8_t *output_buffer) {
405 #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
407 int result = 0;
408 uint16_t numbytes = 0;
409 while (numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH) {
410 char current_name = get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer);
411 numbytes++;
412 uint32_t current_length = 0;
413 if (current_name < 'a' || current_name > 'e') {
414 /* Strange section name, abort */
415 break;
417 current_length = 0;
418 switch (current_name) {
419 case 'e':
420 /* Four byte length field */
421 current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 24;
422 current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 16;
423 current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 8;
424 current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 0;
425 numbytes += 4;
426 if (current_length > 300 * 1024) {
427 /* section e should never exceed about 300KB, if the length is too big limit it but still send the bitstream just in case */
428 current_length = 300 * 1024;
430 break;
431 default: /* Two byte length field */
432 current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 8;
433 current_length += get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer) << 0;
434 numbytes += 2;
435 if (current_length > 64) {
436 /* if text field is too long, keep it but truncate it */
437 current_length = 64;
441 if (current_name == section_name) {
442 /* Found it */
443 *section_length = current_length;
444 result = 1;
445 break;
448 for (uint32_t i = 0; i < current_length && numbytes < MAX_FPGA_BIT_STREAM_HEADER_SEARCH; i++) {
449 get_from_fpga_stream(bitstream_target, compressed_fpga_stream, output_buffer);
450 numbytes++;
453 return result;
456 //----------------------------------------------------------------------------
457 // Change FPGA image status, if image loaded.
458 // bitstream_target is your new fpga image version
459 // return true if can change.
460 // return false if image is unloaded.
461 //----------------------------------------------------------------------------
462 #if defined XC3
463 static bool FpgaConfCurrentMode(int bitstream_target) {
464 // fpga "XC3S100E" image merge
465 // If fpga image is no init
466 // We need load hf_lf_allinone.bit
467 if (downloaded_bitstream != FPGA_BITSTREAM_UNKNOWN) {
468 // test start
469 // PIO controls the following pins
470 AT91C_BASE_PIOA->PIO_PER = GPIO_FPGA_SWITCH;
471 // These pins are outputs
472 AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_SWITCH;
474 // try to turn off antenna
475 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
477 if (bitstream_target == FPGA_BITSTREAM_LF) {
478 LOW(GPIO_FPGA_SWITCH);
479 } else {
480 HIGH(GPIO_FPGA_SWITCH);
482 // update downloaded_bitstream
483 downloaded_bitstream = bitstream_target;
484 // turn off antenna
485 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
486 return true;
488 return false;
490 #endif
492 //----------------------------------------------------------------------------
493 // Check which FPGA image is currently loaded (if any). If necessary
494 // decompress and load the correct (HF or LF) image to the FPGA
495 //----------------------------------------------------------------------------
496 void FpgaDownloadAndGo(int bitstream_target) {
498 // check whether or not the bitstream is already loaded
499 if (downloaded_bitstream == bitstream_target) {
500 FpgaEnableTracing();
501 return;
504 #if defined XC3
505 // If we can change image version
506 // direct return.
507 if (FpgaConfCurrentMode(bitstream_target)) {
508 return;
510 #endif
512 // Send waiting time extension request as this will take a while
513 send_wtx(FPGA_LOAD_WAIT_TIME);
515 bool verbose = (g_dbglevel > 3);
517 // make sure that we have enough memory to decompress
518 BigBuf_free();
519 BigBuf_Clear_ext(verbose);
521 lz4_stream_t compressed_fpga_stream;
522 LZ4_streamDecode_t lz4StreamDecode_body = {{ 0 }};
523 compressed_fpga_stream.lz4StreamDecode = &lz4StreamDecode_body;
524 uint8_t *output_buffer = BigBuf_malloc(FPGA_RING_BUFFER_BYTES);
526 if (!reset_fpga_stream(bitstream_target, &compressed_fpga_stream, output_buffer))
527 return;
529 uint32_t bitstream_length;
530 if (bitparse_find_section(bitstream_target, 'e', &bitstream_length, &compressed_fpga_stream, output_buffer)) {
531 DownloadFPGA(bitstream_target, bitstream_length, &compressed_fpga_stream, output_buffer);
532 downloaded_bitstream = bitstream_target;
535 #if defined XC3
536 // first download fpga image to hf
537 // we need to change fpga status to hf
538 FpgaConfCurrentMode(bitstream_target);
539 #endif
541 // turn off antenna
542 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
544 // free eventually allocated BigBuf memory
545 BigBuf_free();
546 BigBuf_Clear_ext(false);
549 //-----------------------------------------------------------------------------
550 // Send a 16 bit command/data pair to the FPGA.
551 // The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
552 // where C is the 4 bit command and D is the 12 bit data
554 // @params cmd and v gets OR:ED over each other. Take careful note of overlapping bits.
555 //-----------------------------------------------------------------------------
556 void FpgaSendCommand(uint16_t cmd, uint16_t v) {
557 SetupSpi(SPI_FPGA_MODE);
558 while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
559 AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data
560 while (!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF)) {}; // wait till transfer is complete
562 //-----------------------------------------------------------------------------
563 // Write the FPGA setup word (that determines what mode the logic is in, read
564 // vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to
565 // avoid changing this function's occurrence everywhere in the source code.
566 //-----------------------------------------------------------------------------
567 void FpgaWriteConfWord(uint16_t v) {
568 FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
571 //-----------------------------------------------------------------------------
572 // enable/disable FPGA internal tracing
573 //-----------------------------------------------------------------------------
574 void FpgaEnableTracing(void) {
575 FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 1);
578 void FpgaDisableTracing(void) {
579 FpgaSendCommand(FPGA_CMD_TRACE_ENABLE, 0);
582 //-----------------------------------------------------------------------------
583 // Set up the CMOS switches that mux the ADC: four switches, independently
584 // closable, but should only close one at a time. Not an FPGA thing, but
585 // the samples from the ADC always flow through the FPGA.
586 //-----------------------------------------------------------------------------
587 void SetAdcMuxFor(uint32_t whichGpio) {
589 #ifndef WITH_FPC_USART
590 // When compiled without FPC USART support
591 AT91C_BASE_PIOA->PIO_OER =
592 GPIO_MUXSEL_HIPKD |
593 GPIO_MUXSEL_LOPKD |
594 GPIO_MUXSEL_LORAW |
595 GPIO_MUXSEL_HIRAW;
597 AT91C_BASE_PIOA->PIO_PER =
598 GPIO_MUXSEL_HIPKD |
599 GPIO_MUXSEL_LOPKD |
600 GPIO_MUXSEL_LORAW |
601 GPIO_MUXSEL_HIRAW;
603 LOW(GPIO_MUXSEL_HIPKD);
604 LOW(GPIO_MUXSEL_LOPKD);
605 LOW(GPIO_MUXSEL_HIRAW);
606 LOW(GPIO_MUXSEL_LORAW);
607 HIGH(whichGpio);
608 #else
609 if ((whichGpio == GPIO_MUXSEL_LORAW) || (whichGpio == GPIO_MUXSEL_HIRAW))
610 return;
611 // FPC USART uses HIRAW/LOWRAW pins, so they are excluded here.
612 AT91C_BASE_PIOA->PIO_OER = GPIO_MUXSEL_HIPKD | GPIO_MUXSEL_LOPKD;
613 AT91C_BASE_PIOA->PIO_PER = GPIO_MUXSEL_HIPKD | GPIO_MUXSEL_LOPKD;
614 LOW(GPIO_MUXSEL_HIPKD);
615 LOW(GPIO_MUXSEL_LOPKD);
616 HIGH(whichGpio);
617 #endif
621 void Fpga_print_status(void) {
622 DbpString(_CYAN_("Current FPGA image"));
623 Dbprintf(" mode.................... %s", g_fpga_version_information[bitstream_target_to_index(downloaded_bitstream)]);
626 int FpgaGetCurrent(void) {
627 return downloaded_bitstream;
630 // Turns off the antenna,
631 // log message
632 // if HF, Disable SSC DMA
633 // turn off trace and leds off.
634 void switch_off(void) {
635 if (g_dbglevel > 3) {
636 Dbprintf("switch_off");
639 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
640 if (downloaded_bitstream == FPGA_BITSTREAM_HF || downloaded_bitstream == FPGA_BITSTREAM_HF_15) {
641 FpgaDisableSscDma();
644 set_tracing(false);
645 LEDsoff();