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