[[Glasgow Notes]]
## Using in-fifo/out-fifo to stream data to/from Glasgow
### Build
The in-fifo is requested using `iface.get_in_fifo()`
Its class is: `glasgow.access.direct.multiplexer._FIFOWritePort`
(see [[glasgow Multiplexer]])
Options:
- `auto_flush`. Default = True. We found that using `auto_flush = False` better optimized our usage of USB bandwidth because partial USB packets were not transmitted.
The out-fifo is requested using `iface.get_out_fifo()`
```python
def build(self, target, args):
self.mux_interface = iface = target.multiplexer.claim_interface(self, args)
iface.add_subtarget(Subtarget(
pads=iface.get_pads(args, pins=self.__pins),
in_fifo=iface.get_in_fifo(),
out_fifo=iface.get_out_fifo(),
))
```
### Amaranth
The Amaranth `Elaboratable` is initialized with `self.in_fifo = in_fifo` and `self.out_fifo = out_fifo`.
To write data to the in_fifo (from Glasgow to PC):
- `w_rdy` must be True if anything is to be written
- `w_data` is set to the value or signal to write
- `w_en` is set True to allow the write
Example:
```python
with m.If(self.in_fifo.w_rdy):
m.d.comb += [
self.in_fifo.w_data.eq(data),
self.in_fifo.w_en.eq(1),
]
```
To read data from the out_fifo (from PC to Glasgow):
- `r_en` must be set True
- `r_rdy` must be True if anything is to be written
- `r_data` is the value read from the out-fifo
Example:
```python
m.d.comb += [self.out_fifo.r_en.eq(1)]
with m.If(self.out_fifo.r_rdy):
m.d.sync += [
data.eq(self.out_fifo.r_data),
]
```
### Run/Interact
To read the data continuously when the applet runs:
```python
async def run(self, device, args):
iface = await device.demultiplexer.claim_interface(self, self.mux_interface, args)
while True:
raw_data = await iface.read()
data = raw_data.tolist()
print(data)
```
The raw data is a [memview](https://docs.python.org/3/library/stdtypes.html#memoryview)
To write data while the applet runs:
```python
await iface.write(data)
```
`data` can be a single value or a list of values, it will be converted to bytes
### iface.read
Options:
- flush: default = True. If True, run `iface.flush()` as the first step of `iface.read()`
### iface.flush
Options:
- wait: default = False. If False, `iface.flush()` will not block other tasks