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