Difference between revisions of "USB FPGA CODE"

From ElphelWiki
Jump to: navigation, search
m (FPGA code to accomodate USB host module)
 
(16 intermediate revisions by one other user not shown)
Line 1: Line 1:
In compressor where there are many registers you can not drive all of them from 9 degrees - there will be interferience because of the ground bounce on the power lines, so I spread registers between 0,90,180,270.
+
See discussion also
 +
==FPGA code to accomodate USB host module==
 +
The code of the JPEG branch of the model 333 camera is modified (in rev 333100e) to accomodate new USB host module currently under development. These modifications also provide vector interrupts (from up to 16 sources) and simplifies the use of 6 FPGA pins connected to the inter-board connector J2 (and so available at the extension boards).
  
Probably it is not a problem for USB as it is much smaller than compressor, but still it is better to be able to use several clocks, and they are already availbale for 125MHz.
+
===Vector Interrupts===
 +
Axis ETRAX100LX processor [http://developer.axis.com/doc/old/hardware/etrax100lx/des_ref.html] supports two modes for external interrupts - with internally generated vector number and with externally generated. In the latter case CPU generates INTA pulse and the peripheral places an 8-bit vector code on the data bus. New (>=333100e) FPGA code supports both modes, for each of 16 intrerrupts individual vector code can be programmed. Four locations in the FPGA address space (CSP0,CSP4) are writable to control interrupts_vector333 module:
  
So this is why it is better to put most of the logic in USB at 125 MHz, and only on the PHY side - 48MHz (after DCM)
+
====Reset Interrupt Requests====
 +
  #define  X313_WA_IRQ_RST  0x1c // reset selected interrupt bits
 +
This register resets the selected bits (having ones in a word written to this location) of the source interrupt request register that is positive edge triggered from asynchronous signal in FPGA and reset by either of two reasons:
 +
* writing to the X313_WA_IRQ_RST (0x1c) register with ones in the bits to be reset and
 +
* servicing ''this''interrupt with externally generated vector number. When the INTA is generated the interrupt request bit that caused the interrupt (or at least the one which had  it's number placed on data bus in responce to INTA) is reset so software does not need to do it again.
  
Because from the external generator we allready use all outputs:
+
====Interrupt MAsk Register====
Xtal is 20MHz - it goes to CPU
+
  #define  X313_WA_IRQ_DIS  0x1d // disable selected interrupt bits (mask)
1 PLL (25 MHz) ->Ethernet PHY
+
  #define  X313_WA_IRQ_ENA  0x1e // enable selected interrupt bits
1 PLL (125MHz) - SDRAM, compressor
+
These two locations control the interrupt mask register. Ones written to X313_WA_IRQ_DIS '''disable''' propagation of the interrupt(s) in the selected bit(s), ones written to X313_WA_IRQ_ENA '''enable''' them. After initial FPGA configuration all the interrupts are disabled. Enabling and disabling individual interrupt bits do not change the status of the interrupt requests, so if the interrupt causing event happened while this interrupt was disabled (masked out) and enabled later, the interrupt request to the CPU will be generated.
1 PLL (6..48MHz) - sensor. We cannot rely on 48MHz as different sensor boards may need different clock speeds
 
  
It is still possinble to drive sensor from frequency divider from the 125MHz but it is more convinient to have it independent.
+
====Programming Interrupt Vectors====
Other option for USB - use only xtal 20Mhz that will not change and run DCM from 20MHz to make 48MHz.
+
#define  X313_WA_IRQ_WVECT 0x1f // write vector number (in bits [0:7], [11:8] - interrupt number (0..15)
 +
In responce to the INTA pulse from the CPU (it will be generated if "extrernally generated vector number" is selected) one of the 16 pre-programmed 8-bit vectors will be placed on the data bus. You need to initialize the vectors before using them, initially all vectors are zeros. To program particular interrupt vector you need to combine the 8-bit vector for the selected interrupt and the interrupt bit number (0..15) by shifting the latter left by 8 and writing the 12-bit result to X313_WA_IRQ_WVECT.
  
clk0 is 120Mhz
+
If more than 1 interrupt are active (not reset and not masked) the one with the lower number will have higher priority.
  
It is, but with Theora it is 125 MHz and we will change it in configuration file, it will be 125, not 120. And it is also better not to tie fixed 48MHz for USB to this 120/125 to have some freedom in running different system frequencies. The best source for USB will be 20Mhz->DCM->48MHz
+
When servicing one of the simultaneously active interrupts only one will be reset by INTA (the one that is being served), so immidiately after returning from servicing one request, CPU will generate INTA to serve the next remaining one.
 +
====Interrupt Map====
 +
Currently the following interrupts exist in the FPGA code of the Model 333 camera
 +
{| border="1" cellpadding="2"
 +
|-
 +
| bit || vector || FPGA || Driver  || Used? || Description
 +
|-
 +
| 0 || || vacts || VACT || Y || frame sync
 +
|-
 +
| 1 || || trig_irq || XINT ||N || external trigger
 +
|-
 +
| 2 || || xfer_over_irq || XFEROVR || N || frame acquisition over
 +
|-
 +
| 3 || || sr_sensortrig[2] || DONE || N || level, reset by writing to sensor triggering command register (FPGA != driver!)
 +
|-
 +
| 4 || || compressor_eot || EOT || N || Frame Sync
 +
|-
 +
| 5 || || dcc_rdy || DCC || N || (Next 128 16-bit DC components (and HF too) are ready (or the partial block - last in frame).)
 +
|-
 +
| 6 || ||compressor_done_input || DONE_INPUT || N || will go high after EOT and persist until DCT is enabled (source reset by compressor)
 +
|-
 +
| 7 || ||compressor_done_compress || DONE_COMPRESS || Y || will go high after all data is sent out (source reset by compressor)
 +
|-
 +
| 8 || ||usb_irqs[0] || --- || N || USB interrupt 0
 +
|-
 +
| 9 || ||usb_irqs[1] || --- || N || USB interrupt 1
 +
|-
 +
|10 || ||usb_irqs[2] || --- || N || USB interrupt 2
 +
|-
 +
|11 || ||usb_irqs[3] || --- || N || USB interrupt 3
 +
|-
 +
|12 || ||usb_irqs[4] || --- || N || USB interrupt 4
 +
|-
 +
|13 || ||usb_irqs[5] || --- || N || USB interrupt 5
 +
|-
 +
|14 || || --- || --- || N || ---
 +
|-
 +
|15 || || --- || --- || N || ---
 +
|-
 +
|}
  
I think it is possble.but need test.
+
==== Reading Interrupt Status ====
 +
It is possible to read the current state of all 16 possible interrupts throuhg the 32-bit register
 +
#define X313__RA__IRQS  0x11    // read interrupt register
 +
The lower 16 bits are masked interrupt requests - those that OR-ed define the interrupt request to the CPU.
  
But this is a goal
+
The 16 highest bits are the same interrupt bits before the mask, so they are set for all the same bits in the lower 16 and possiblyy some other interrupt bits that are triggered but masked out.
  
You may use just 2 - 0 and 90, and then just put:
+
=== I/O pins control ===
 +
FPGA on the model 333 main board traditionally has 6 pins connected to the inter-board 16-pin connector J2. "Traditionally" because the same pins were used in earlier models 303 and 313. Previously these pins were designated for the particular functions, but it turned out that it is more convinient to have a uniform interface to control all of them. State (0/1) of each pin can be read by software as a 6-bit word at address 0x70, each pin can individually and dynamically be programmed as an input or an output and in the latter case output particular bit.
  
always @ (posedge clk90)  
+
In addition to per-bit software control of the I/O pins the six_ios module also can delegate direct control to one of 3 possible FPGA additionlal modules, currently USB host interface is under development.
 +
{| border="1" cellpadding="2"
 +
|-
 +
| bit || FPGA name || PCB name|| conector (J2) pin
 +
|-
 +
| 0 || SCL1 || EXT_SCL || 1
 +
|-
 +
| 1 || SDA1 || EXT_SDA || 2
 +
|-
 +
| 2 || XRST || EXT_RST || 3
 +
|-
 +
| 3 || AUXCLK ||EXT_CLK || 4
 +
|-
 +
| 4 || EXPS ||EXT_EXPOS || 5
 +
|-
 +
| 5 || TRIG || EXT_TRIG || 6
 +
|-
 +
|}
  
always @ (negedge clk90)
+
Output functions of these pins are controlled by writing a 14-bit to location 0x70 in the FPGA address space. Two MSBs (13:12) control the multiplexer that selects the source of the pin control:
  
Because now I don't remember if all 4 are actually present on chip.
+
0 - I/O pins are controlled by buts [11:0] of the same control word
 +
1 - I/O pins are controlled by source "A" - USB module. Two sets of 6-bit data buses are provide - one - for per-bit direction (0 - input, 1 - output), the other - for the value (disregarded in input mode).
 +
2 - I/O pins are controlled by source "B" (not assigned yet)
 +
3 - I/O pins are controlled by source "C" (not assigned yet)
  
Maybe it is just 0, 90, 270? or 0, 90, 180 - just don't remember.
+
Lower significant bits make pairs that control each individual pins (provided that bits 12 and 13 are both zeros - see above). In each pair the lower bit provides the pin value (output mode only), the higher - pin direction (0-input), 1 - output.
  
Also the interface to the CPU shoul be consistent with the current one, and not use large address space - just
+
So writing 0x1000 selects USB as a source (12 LSBs are ignored), 0xb will program pin 0 (SCL1) to output "1", pin 1 (SDA1) - to output "0", all the rest pins will be used as inputs.
  
It is possible to use interrupts, yes. How many bits?
 
  
We can add more - anyway date is read in in 32 bit words.
+
Reading from address 0x70 will return current state or the pins as a 6-bit word in any mode.
 
 
8 was selected fro vector interrupts, but now it is not used as there were some problems with ETRAX software. We should probably restore vector interrupt functionality as there are too many different sources for the interrupts now. Use INTA to put 8 bit on the bus.
 
 
 
interrupts no use state words?
 
I think beterr use state word register?
 
 
 
Now most are how they are just by historical reasons. There is already a mess, but it should be fixed from both sides - software driver and ISR, and FPGA.
 
 
 
But first we need to make sure that vector interrupts now work with ETRAX as expected, then modify the FPGA code and drivers to use it. I had vector interrupts even in model 303 camera, but later removed it having problem with it in software. Some problems were gone wiyth newer kernel but I haven't restored vector interrupts back.
 
 
 
The interrupts mask and other register is 8 bit, I want modi to 16 bit,ok?
 
 
 
I don't think it is really necessary, what we can do is just have a single (vector) interrupt for USB and have a separate 5-bit register in your module that will be polled to find out the exact source of the interrupt.
 
 
 
Use a single (vector) interrupt
 
 
 
For now - just have a single (1-bit) line and your register. We will have to change current 1-interrupt module to vector interrupts anyway. And for that we have just 8 bits, but you will use just 1.
 
 
 
So we can work independently
 
 
 
You may use bit 5, but it is easy to change. You see there are now 2 different code bases for 333 - with MJPEG and Ogg Theora, I will need to verify that the same number is free in both.
 

Latest revision as of 04:36, 16 December 2005

See discussion also

FPGA code to accomodate USB host module

The code of the JPEG branch of the model 333 camera is modified (in rev 333100e) to accomodate new USB host module currently under development. These modifications also provide vector interrupts (from up to 16 sources) and simplifies the use of 6 FPGA pins connected to the inter-board connector J2 (and so available at the extension boards).

Vector Interrupts

Axis ETRAX100LX processor [1] supports two modes for external interrupts - with internally generated vector number and with externally generated. In the latter case CPU generates INTA pulse and the peripheral places an 8-bit vector code on the data bus. New (>=333100e) FPGA code supports both modes, for each of 16 intrerrupts individual vector code can be programmed. Four locations in the FPGA address space (CSP0,CSP4) are writable to control interrupts_vector333 module:

Reset Interrupt Requests

 #define   X313_WA_IRQ_RST   0x1c // reset selected interrupt bits

This register resets the selected bits (having ones in a word written to this location) of the source interrupt request register that is positive edge triggered from asynchronous signal in FPGA and reset by either of two reasons:

  • writing to the X313_WA_IRQ_RST (0x1c) register with ones in the bits to be reset and
  • servicing thisinterrupt with externally generated vector number. When the INTA is generated the interrupt request bit that caused the interrupt (or at least the one which had it's number placed on data bus in responce to INTA) is reset so software does not need to do it again.

Interrupt MAsk Register

 #define   X313_WA_IRQ_DIS   0x1d // disable selected interrupt bits (mask)
 #define   X313_WA_IRQ_ENA   0x1e // enable selected interrupt bits

These two locations control the interrupt mask register. Ones written to X313_WA_IRQ_DIS disable propagation of the interrupt(s) in the selected bit(s), ones written to X313_WA_IRQ_ENA enable them. After initial FPGA configuration all the interrupts are disabled. Enabling and disabling individual interrupt bits do not change the status of the interrupt requests, so if the interrupt causing event happened while this interrupt was disabled (masked out) and enabled later, the interrupt request to the CPU will be generated.

Programming Interrupt Vectors

#define   X313_WA_IRQ_WVECT 0x1f // write vector number (in bits [0:7], [11:8] - interrupt number (0..15)

In responce to the INTA pulse from the CPU (it will be generated if "extrernally generated vector number" is selected) one of the 16 pre-programmed 8-bit vectors will be placed on the data bus. You need to initialize the vectors before using them, initially all vectors are zeros. To program particular interrupt vector you need to combine the 8-bit vector for the selected interrupt and the interrupt bit number (0..15) by shifting the latter left by 8 and writing the 12-bit result to X313_WA_IRQ_WVECT.

If more than 1 interrupt are active (not reset and not masked) the one with the lower number will have higher priority.

When servicing one of the simultaneously active interrupts only one will be reset by INTA (the one that is being served), so immidiately after returning from servicing one request, CPU will generate INTA to serve the next remaining one.

Interrupt Map

Currently the following interrupts exist in the FPGA code of the Model 333 camera

bit vector FPGA Driver Used? Description
0 vacts VACT Y frame sync
1 trig_irq XINT N external trigger
2 xfer_over_irq XFEROVR N frame acquisition over
3 sr_sensortrig[2] DONE N level, reset by writing to sensor triggering command register (FPGA != driver!)
4 compressor_eot EOT N Frame Sync
5 dcc_rdy DCC N (Next 128 16-bit DC components (and HF too) are ready (or the partial block - last in frame).)
6 compressor_done_input DONE_INPUT N will go high after EOT and persist until DCT is enabled (source reset by compressor)
7 compressor_done_compress DONE_COMPRESS Y will go high after all data is sent out (source reset by compressor)
8 usb_irqs[0] --- N USB interrupt 0
9 usb_irqs[1] --- N USB interrupt 1
10 usb_irqs[2] --- N USB interrupt 2
11 usb_irqs[3] --- N USB interrupt 3
12 usb_irqs[4] --- N USB interrupt 4
13 usb_irqs[5] --- N USB interrupt 5
14 --- --- N ---
15 --- --- N ---

Reading Interrupt Status

It is possible to read the current state of all 16 possible interrupts throuhg the 32-bit register

#define X313__RA__IRQS  	0x11    // read interrupt register

The lower 16 bits are masked interrupt requests - those that OR-ed define the interrupt request to the CPU.

The 16 highest bits are the same interrupt bits before the mask, so they are set for all the same bits in the lower 16 and possiblyy some other interrupt bits that are triggered but masked out.

I/O pins control

FPGA on the model 333 main board traditionally has 6 pins connected to the inter-board 16-pin connector J2. "Traditionally" because the same pins were used in earlier models 303 and 313. Previously these pins were designated for the particular functions, but it turned out that it is more convinient to have a uniform interface to control all of them. State (0/1) of each pin can be read by software as a 6-bit word at address 0x70, each pin can individually and dynamically be programmed as an input or an output and in the latter case output particular bit.

In addition to per-bit software control of the I/O pins the six_ios module also can delegate direct control to one of 3 possible FPGA additionlal modules, currently USB host interface is under development.

bit FPGA name PCB name conector (J2) pin
0 SCL1 EXT_SCL 1
1 SDA1 EXT_SDA 2
2 XRST EXT_RST 3
3 AUXCLK EXT_CLK 4
4 EXPS EXT_EXPOS 5
5 TRIG EXT_TRIG 6

Output functions of these pins are controlled by writing a 14-bit to location 0x70 in the FPGA address space. Two MSBs (13:12) control the multiplexer that selects the source of the pin control:

0 - I/O pins are controlled by buts [11:0] of the same control word 1 - I/O pins are controlled by source "A" - USB module. Two sets of 6-bit data buses are provide - one - for per-bit direction (0 - input, 1 - output), the other - for the value (disregarded in input mode). 2 - I/O pins are controlled by source "B" (not assigned yet) 3 - I/O pins are controlled by source "C" (not assigned yet)

Lower significant bits make pairs that control each individual pins (provided that bits 12 and 13 are both zeros - see above). In each pair the lower bit provides the pin value (output mode only), the higher - pin direction (0-input), 1 - output.

So writing 0x1000 selects USB as a source (12 LSBs are ignored), 0xb will program pin 0 (SCL1) to output "1", pin 1 (SDA1) - to output "0", all the rest pins will be used as inputs.


Reading from address 0x70 will return current state or the pins as a 6-bit word in any mode.