]> rtime.felk.cvut.cz Git - fpga/lx-cpu1/lx-rocon.git/blob - sw/app/rocon/appl_fpga.c
67ed35bdf87350edf877925f73bb0850ad9c6484
[fpga/lx-cpu1/lx-rocon.git] / sw / app / rocon / appl_fpga.c
1 #include <types.h>
2 #include <cpu_def.h>
3 #include <system_def.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <endian.h>
7 #include <hal_gpio.h>
8
9 #include "appl_defs.h"
10 #include "appl_version.h"
11 #include "appl_fpga.h"
12
13 #define SWAB32(x) ((x >> 24) | ((x & 0x00FF0000) >> 8) | ((x & 0x0000FF00) << 8) | (x << 24))
14
15 /* Registers in FPGA */
16 volatile uint32_t *tumbl_control = (volatile uint32_t *)FPGA_TUMBL_CONTROL_REG;
17 volatile uint32_t *tumbl_trace_kick = (volatile uint32_t *)FPGA_TUMBL_TRACE_KICK_REG;
18 volatile uint32_t *tumbl_pc = (volatile uint32_t *)FPGA_TUMBL_PC;
19 volatile uint32_t *tumbl_base = (volatile uint32_t *)FPGA_TUMBL_IMEM_BASE;
20 volatile uint32_t *tumbl_imem = (volatile uint32_t *)FPGA_TUMBL_IMEM_BASE;
21 volatile uint32_t *tumbl_dmem = (volatile uint32_t *)FPGA_TUMBL_DMEM_BASE;
22
23 volatile struct irc_register *irc1 = (volatile struct irc_register *)FPGA_IRC1_BASE;
24 volatile struct irc_register *irc2 = (volatile struct irc_register *)FPGA_IRC2_BASE;
25 volatile struct irc_register *irc3 = (volatile struct irc_register *)FPGA_IRC3_BASE;
26 volatile struct irc_register *irc4 = (volatile struct irc_register *)FPGA_IRC4_BASE;
27
28 /* Variables for configuration */
29 volatile uint16_t *fpga_configure_line = (volatile uint16_t *)0x8003FFFC;
30 int fpga_configured = 0;
31 int fpga_reconfiguration_locked = 1;
32
33 /* BUS calibration - registers to measure the delay necessary for reading and writing */
34 volatile uint32_t *fpga_bus_calib_read1 = (volatile uint32_t *)0x8003FFF0;
35 volatile uint32_t *fpga_bus_calib_read2 = (volatile uint32_t *)0x8003FFF4;
36
37 volatile uint32_t *fpga_bus_calib_write1 = (volatile uint32_t *)0x8003FFF8;
38 volatile uint32_t *fpga_bus_calib_write2 = (volatile uint32_t *)0x8003FFFC;
39
40 /* BUS calibration - values (shifting all bits) */
41 #define CALIB_VAL1 0xAAAAAAAA
42 #define CALIB_VAL2 0x55555555
43
44 void appl_fpga_init()
45 {
46   /* Initialze EMC for FPGA */
47
48   /* Settings:
49    * 32 bus width
50    * CS polarity: LOW (ATTENTION: Must match FPGA setup)
51    * Byte line state: Reads are only 32 bits
52    * Extended wait: off
53    * Buffer: disabled
54    * Write protection: disabled
55    */
56   LPC_EMC->StaticConfig0 = 0x00000002;
57
58   /* Delays - not calibrated at this point
59    * We're running on 72 MHz, FPGA bus is running on 100 MHz async.
60    * Read: 32 cycles
61    * Write: 33 cycles
62    * Turnaround: 2 cycles (cca. 28 ns)
63    */
64   LPC_EMC->StaticWaitRd0 = 0x1F;
65   LPC_EMC->StaticWaitWr0 = 0x1F;
66   LPC_EMC->StaticWaitTurn0 = 0x01;
67
68   /* Shift addresses by 2 (32-bit bus) */
69   LPC_SC->SCS &= 0xFFFFFFFE;
70
71   printf("EMC for FPGA initialized!\n");
72 }
73
74 int appl_fpga_tumbl_set_reset(int reset)
75
76   int i;
77   
78   if (reset)
79     *tumbl_control |= FPGA_TUMBL_CONTROL_REG_RESET_BIT;
80   else
81     *tumbl_control &= ~FPGA_TUMBL_CONTROL_REG_RESET_BIT;
82   return 0;
83 }
84
85 int appl_fpga_tumbl_set_halt(int halt)
86 {
87   if (halt)
88     *tumbl_control |= FPGA_TUMBL_CONTROL_REG_HALT_BIT; 
89   else
90     *tumbl_control &= ~FPGA_TUMBL_CONTROL_REG_HALT_BIT;
91   
92   return 0;
93 }
94
95 int appl_fpga_tumbl_set_trace(int trace)
96 {  
97   if (trace)
98     *tumbl_control |= FPGA_TUMBL_CONTROL_REG_TRACE_BIT; 
99   else
100     *tumbl_control &= ~FPGA_TUMBL_CONTROL_REG_TRACE_BIT;
101   
102   return 0;
103 }
104
105 int appl_fpga_tumbl_kick_trace()
106 {
107   int i;
108   
109   *tumbl_trace_kick = 1;
110   __memory_barrier();
111
112   /* Make sure it's processed */
113   for (i = 0; i < 32; i++)
114   {}
115   
116   __memory_barrier();
117   printf("Tumbl PC: 0x%08X\n", (unsigned int) *tumbl_pc);
118   return 0;
119 }
120
121 void appl_fpga_tumbl_write(unsigned int offset, unsigned char *ptr, int len)
122 {
123   int i;
124   unsigned int *iptr = (unsigned int *)ptr;
125   
126   for (i = 0; i < len / 4; i++)
127     tumbl_base[(offset / 4) + i] = SWAB32(iptr[i]);
128 }
129
130 /* 
131  * Bus calibration - functions can be called via USB interface
132  * Proper usage:
133  * 1) Calibrate read
134  * 2) Calibrate write
135  * 3) Set turnaround
136  *      bus is not pipelined, therefore
137  *      just necessary delay for I/O to enter
138  *      high impedance state (synchronous clocking => only 1 cycle necessary)
139  */
140
141 /* Cannot be on stack due to memory barrier for gcc */
142 static uint32_t a, b;
143
144 int appl_fpga_calibrate_bus_read()
145 {
146   int i;
147   
148   /* Set the delays are set to highest (default) value */
149   LPC_EMC->StaticWaitRd0 = 0x1F;
150   
151   while (LPC_EMC->StaticWaitRd0 >= 0)
152   {
153     for (i = 0; i < 1024; i++)
154     {
155       /* Reset the values */
156       __memory_barrier();
157       a = 0xFFFFFFFF;
158       b = 0xFFFFFFFF;
159       __memory_barrier();
160       /* Read the values several times - so there are two flips at least
161        * NOTE: SDRAM reads / writes may occur in between!
162        */
163       a = *fpga_bus_calib_read1;
164       b = *fpga_bus_calib_read2;
165       a = *fpga_bus_calib_read1;
166       b = *fpga_bus_calib_read2;
167       a = *fpga_bus_calib_read1;
168       b = *fpga_bus_calib_read2;
169       a = *fpga_bus_calib_read1;
170       b = *fpga_bus_calib_read2;
171       __memory_barrier();
172       
173       /* Verify */
174       if (a != CALIB_VAL1 || b != CALIB_VAL2)
175       {
176         if (LPC_EMC->StaticWaitRd0 == 0x1F)
177         {
178           printf("ERROR: FPGA bus is not working properly!\n"); 
179           return 1;
180         }
181         else
182         {
183           LPC_EMC->StaticWaitRd0++;
184           printf("FPGA bus: StaticWaitRd0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitRd0);
185           return 0;
186         }
187       }
188     }
189     
190     /* We're good, lower it */
191     if (LPC_EMC->StaticWaitRd0 == 0)
192     {
193       printf("FPGA bus: StaticWaitRd0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitRd0);
194       break;
195     }
196     else
197       LPC_EMC->StaticWaitRd0--;
198   }
199
200   return 0;
201 }
202
203 int appl_fpga_calibrate_bus_write()
204 {
205   int i;
206   
207   /* Set the delays are set to highest (default) value */
208   LPC_EMC->StaticWaitWr0 = 0x1F;
209
210   while (LPC_EMC->StaticWaitWr0 >= 0)
211   {
212     for (i = 0; i < 1024; i++)
213     {
214       /* Make sure there is nothing other going on */
215       __memory_barrier();
216       *fpga_bus_calib_write1 = 0x00000000;
217       *fpga_bus_calib_write2 = 0x00000000;
218       __memory_barrier();
219       a = 0xFFFFFFFF;
220       b = 0xFFFFFFFF;
221       __memory_barrier();
222       /* Write the values several times - so there are two flips at least
223        * NOTE: SDRAM reads / writes may occur in between!
224        */
225       *fpga_bus_calib_write1 = CALIB_VAL1;
226       *fpga_bus_calib_write2 = CALIB_VAL2;
227       *fpga_bus_calib_write1 = CALIB_VAL1;
228       *fpga_bus_calib_write2 = CALIB_VAL2;
229       *fpga_bus_calib_write1 = CALIB_VAL1;
230       *fpga_bus_calib_write2 = CALIB_VAL2;
231       *fpga_bus_calib_write1 = CALIB_VAL1;
232       *fpga_bus_calib_write2 = CALIB_VAL2;
233       /* 
234        * Strongly ordered memory
235        * GCC is blocked by volatilness
236        */
237       __memory_barrier();
238       a = *fpga_bus_calib_write1;
239       b = *fpga_bus_calib_write2;
240       __memory_barrier();
241       
242       /* Verify */
243       if (a != CALIB_VAL1 || b != CALIB_VAL2)
244       {
245         if (LPC_EMC->StaticWaitWr0 == 0x1F)
246         {
247           printf("ERROR: FPGA bus is not working properly!\n");
248           printf("a = 0x%08X, b = 0x%08X\n", (unsigned int) a, (unsigned int) b);
249           return 1;
250         }
251         else
252         {
253           LPC_EMC->StaticWaitWr0++;
254           printf("FPGA bus: StaticWaitWr0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitWr0);
255           return 0;
256         }
257       }
258     }
259     
260     /* We're good, lower it */
261     if (LPC_EMC->StaticWaitWr0 == 0)
262     {
263       printf("FPGA bus: StaticWaitWr0 set to 0x%02X\n", (unsigned int) LPC_EMC->StaticWaitWr0);
264       break;
265     }
266     else
267       LPC_EMC->StaticWaitWr0--;
268   }
269
270   return 0;
271 }
272
273 void appl_fpga_set_reconfiguration_lock(int lock)
274 {
275   fpga_reconfiguration_locked = lock;
276 }
277
278 int appl_fpga_get_reconfiguration_lock()
279 {
280   return fpga_reconfiguration_locked;
281 }
282
283 int appl_fpga_configure()
284 {
285   int i, j;
286   uint16_t *data;
287   char *magic;
288   uint32_t size;
289
290   if (fpga_configured && fpga_reconfiguration_locked)
291     return FPGA_CONF_ERR_RECONF_LOCKED;
292
293   /* Make sure INIT_B is set as input */
294   hal_gpio_direction_input(XC_INIT_PIN);
295
296   /* PROGRAM_B to low */
297   hal_gpio_set_value(XC_PROGRAM_PIN, 0);
298
299   /* SUSPEND to low (permamently) */
300   hal_gpio_set_value(XC_SUSPEND_PIN, 0);
301
302   /* Wait some cycles (minimum: 500 ns) */
303   for (i = 0; i < 4096; i++)
304     {}
305
306   /* PROGRAM_B to high */
307   hal_gpio_set_value(XC_PROGRAM_PIN, 1);
308
309   /* Wait for INIT_B to be high */
310   j = 0;
311
312   while (!hal_gpio_get_value(XC_INIT_PIN))
313   {
314     if (j >= 4096)
315     {
316       hal_gpio_set_value(XC_SUSPEND_PIN, 1);
317       return FPGA_CONF_ERR_RESET_FAIL;
318     }
319
320     j++;
321   }
322   
323   /* Use highest EMC delays */
324   LPC_EMC->StaticWaitRd0 = 0x1F;
325   LPC_EMC->StaticWaitWr0 = 0x1F;
326
327   /* Assert RWDR to WRITE */
328   hal_gpio_set_value(XC_RDWR_PIN, 0);
329
330   /* Send bin file (NOTE: Bits must be reversed!) via EMC)
331    *
332    * Embedded steps:
333    * 1) sync
334    * 2) device ID check
335    * 3) send configuration data
336    * 4) crc check
337    *
338    * INIT_B is LOW in case of a failure
339    * DONE is HIGH in case of a success
340    *
341    * When DONE is HIGH, deassert RWDR and do GPIO reconfiguration:
342    *
343    * GPIOs need to be reconfigured:
344    *
345    * INIT_B - used as reset, triggered LOW right after startup,
346    *          change from input to output (OUTPUT DRAIN)
347    */
348
349   /* Get size */
350   magic = (char *)FPGA_CONFIGURATION_FILE_ADDRESS;
351
352   if (magic[0] != 'F' || magic[1] != 'P' || magic[2] != 'G' || magic[3] != 'A')
353   {
354     hal_gpio_set_value(XC_SUSPEND_PIN, 1);
355     return 1;
356   }
357
358   size = (*(uint32_t *)(FPGA_CONFIGURATION_FILE_ADDRESS + 4)) >> 1;
359   data = (uint16_t *)(FPGA_CONFIGURATION_FILE_ADDRESS + 4 + sizeof(uint32_t));
360
361   /* Periodically check for failure */
362   i = 0;
363   j = 0;
364
365   while (i < size)
366   {
367     *fpga_configure_line = *data;
368
369     if (j >= 128)
370     {
371       /* Check state */
372       if (!hal_gpio_get_value(XC_INIT_PIN))
373       {
374         hal_gpio_set_value(XC_SUSPEND_PIN, 1);
375         return FPGA_CONF_ERR_WRITE_ERR;
376       }
377
378       j = 0;
379     }
380
381     j++;
382     i++;
383     data++;
384   }
385
386   /* We're done, deassert RDWR */
387   hal_gpio_set_value(XC_RDWR_PIN, 1);
388
389   while (!hal_gpio_get_value(XC_DONE_PIN))
390   {
391     if (!hal_gpio_get_value(XC_INIT_PIN))
392     {
393       hal_gpio_set_value(XC_SUSPEND_PIN, 1);
394       return FPGA_CONF_ERR_CRC_ERR;
395     }
396   }
397
398   /* Issue startup clocks with data all 1s (at least 8 recommended) */
399   for (i = 0; i < 16; i++)
400     *fpga_configure_line = 0xFFFF;
401
402   /* In our design, INIT_B is used as reset, convert it to output, and trigger it */
403   hal_gpio_direction_output(XC_INIT_PIN, 0);
404
405   /* Hold it for some time */
406   for (i = 0; i < 128; i++)
407     {}
408     
409   /* Use EMC delays obtained through calibration */
410   LPC_EMC->StaticWaitRd0 = 0x04;
411   LPC_EMC->StaticWaitWr0 = 0x01;
412
413   /* Lift the reset */
414   hal_gpio_direction_output(XC_INIT_PIN, 1);
415   
416    /* Give it some time */
417   for (i = 0; i < 1024; i++)
418     {}
419   
420   fpga_configured = 1;
421   printf("FPGA configured!\n");
422   return FPGA_CONF_SUCESS;
423 }