fpga.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // insert cool lenghty disclaimer here
  2. // fpga.c: FPGA (re)programming
  3. // XXX TODO move SPI functions to fpga_spi.c!
  4. /*
  5. FPGA pin mapping
  6. ================
  7. PROG_B PD3 OUT
  8. CCLK PD4 OUT
  9. INIT_B PD7 IN
  10. DIN PC7 OUT
  11. DONE PA3 IN
  12. */
  13. #include <avr/pgmspace.h>
  14. #include <util/delay.h>
  15. #include "fpga.h"
  16. #include "config.h"
  17. #include "uart.h"
  18. #include "sdcard.h"
  19. #include "diskio.h"
  20. #include "integer.h"
  21. #include "ff.h"
  22. #include "fileops.h"
  23. #include "fpga_spi.h"
  24. #include "spi.h"
  25. #include "avrcompat.h"
  26. /*DWORD get_fattime(void) {
  27. return 0L;
  28. }*/
  29. void set_prog_b(uint8_t val) {
  30. if(val) {
  31. PORTD |= _BV(PD3);
  32. } else {
  33. PORTD &= ~_BV(PD3);
  34. }
  35. }
  36. void set_cclk(uint8_t val) {
  37. if(val) {
  38. PORTD |= _BV(PD4);
  39. } else {
  40. PORTD &= ~_BV(PD4);
  41. }
  42. }
  43. void fpga_init() {
  44. DDRD &= ~_BV(PD7); // PD7 is input
  45. DDRC = _BV(PC7); // for FPGA config, PC7 is output
  46. DDRD |= _BV(PD3) | _BV(PD4); // PD3, PD4 are outputs
  47. DDRA = ~_BV(PA3); // PA3 is input <- DONE
  48. set_cclk(0); // initial clk=0
  49. }
  50. int fpga_get_done(void) {
  51. return PINA & _BV(PA3);
  52. }
  53. void fpga_postinit() {
  54. DDRA |= _BV(PA0) | _BV(PA1) | _BV(PA2) | _BV(PA4) | _BV(PA5) | _BV(PA6); // MAPPER+NEXTADDR output
  55. DDRB |= _BV(PB2) | _BV(PB1) | _BV(PB0); // turn PB2 into output, enable AVR_BANK
  56. DDRD |= _BV(PD7); // turn PD7 into output
  57. }
  58. void fpga_pgm(uint8_t* filename) {
  59. int MAXRETRIES = 10;
  60. int retries = MAXRETRIES;
  61. do {
  62. set_prog_b(0);
  63. uart_putc('P');
  64. set_prog_b(1);
  65. loop_until_bit_is_set(PIND, PD7);
  66. uart_putc('p');
  67. UINT bytes_read;
  68. // open configware file
  69. file_open(filename, FA_READ);
  70. if(file_res) {
  71. uart_putc('?');
  72. uart_putc(0x30+file_res);
  73. return;
  74. }
  75. for (;;) {
  76. bytes_read = file_read();
  77. if (file_res || bytes_read == 0) break; // error or eof
  78. for(int i=0; i<bytes_read; i++) {
  79. FPGA_SEND_BYTE_SERIAL(file_buf[i]);
  80. }
  81. }
  82. file_close();
  83. _delay_ms(100);
  84. } while (!fpga_get_done() && retries--);
  85. if(!fpga_get_done()) {
  86. dprintf("FPGA failed to configure after %d tries.\n", MAXRETRIES);
  87. _delay_ms(50);
  88. }
  89. fpga_postinit();
  90. }
  91. void set_avr_ena(uint8_t val) {
  92. if(val) { // shared mode
  93. PORTD |= _BV(PD7);
  94. // Disable SPI double speed mode -> clock = f/4
  95. SPSR = 0;
  96. dprintf("SPI slow\n");
  97. } else { // avr only
  98. PORTD &= ~_BV(PD7);
  99. // Enable SPI double speed mode -> clock = f/2
  100. SPSR = _BV(SPI2X);
  101. dprintf("SPI fast\n");
  102. }
  103. }
  104. void set_avr_mapper(uint8_t val) {
  105. SPI_SS_HIGH();
  106. FPGA_SS_LOW();
  107. spiTransferByte(0x30 | (val & 0x0f));
  108. FPGA_SS_HIGH();
  109. SPI_SS_LOW();
  110. }
  111. void set_avr_bank(uint8_t val) {
  112. SPI_SS_HIGH();
  113. FPGA_SS_LOW();
  114. spiTransferByte(0x00); // SET ADDRESS
  115. spiTransferByte(val * 0x20); // select chip
  116. spiTransferByte(0x00); // select chip
  117. spiTransferByte(0x00); // select chip
  118. FPGA_SS_HIGH();
  119. SPI_SS_LOW();
  120. }
  121. uint8_t fpga_test() {
  122. spi_fpga();
  123. spiTransferByte(0xF0); // TEST
  124. uint8_t result = spiTransferByte(0x00);
  125. spi_none();
  126. return result;
  127. }