# Overview  
This project is designed for the IMXRT1050-EVKB.
It demonstrates 16-bit parallel transfers on fixed update clock using the FlexIO peripheral.
DMA transfers are used to fill the FlexIO Shift Buffer.

## Use case:  
Precisely-timed writes to 16 pins to drive the data lines of a parallel-load DAC.
FlexIO peripheral also provides DAC latch clock.
(17 pins are needed, and so FLEXIO2 peripheral must be used, due to 16-pin limitation of FLEXIO1).

**Note**: 
The goal was to perform updates at 10 MHz. 
The FlexIO clock output can certainly provide a 10 MHz square wave, 
  but the parallel data updates could not keep up.
It turns out that the DMA peripheral is clocked by the IPG_CLK with a maximum frequency of 150 MHz. 
The RT1050 Reference Manual does not include a section on eDMA Performance, 
  but the K66 Reference Manual does.
According to Table 24-5, the peak request rate for DMA transfers 
  requires about 17 cycles of the IPG_CLK.
This works out to a maximum DMA trigger frequency of 150 MHz/17 = 8.8 MHz.

In practice, I found 6 MHz to be a reliable maximum update rate. 
Any mentions of 10 MHz update rates in the following project description 
  should be interpreted as "maximum update rate."

## Setup:  
In order to produce a 10 MHz sample clock to the DAC CLK input, 
  edges (output toggles) need to be triggered at 20 MHz. 
However, the FlexIO shifter should only be updated at 10 MHz
  (one DAC sample per DAC CLK rising edge). 
So we use chained timers:
Timer 0 toggles with a `TIMER_CMP_VALUE = (FLEXIO_CLOCK_HZ / (2 * DAC_SAMPLE_RATE_HZ) - 1)`.
This signal is output to `DAC_CLK_PIN`.

Timer 1 counts the compare events from Timer 0 (see its `triggerSelect` assignment),
and has a compare value of 1, so divides Timer 0 by 2. 
Timer 1 is used to trigger the Shifter update.

DMA Requests are set up so that the FlexIO triggers a DMA update to its Shift Buffer
  when the Shifter Status Flag becomes set 
  (i.e. when SHIFTBUF has been transferred to the Shifter, and the SHIFTBUF is empty).

# SDK version
Version: 2.16.000

# Toolchain supported
GCC ARM Embedded 13.2.1  
MCUXpresso 11.10.0  

# Hardware requirements
Mini/micro USB cable  
IMXRT1050-EVKB  
Personal Computer  
Oscilloscope (optional)  

# Board settings
No special settings are required.

For use with the IMXRT1050-EVKB board, 
  the FlexIO pins have been routed to the 40-pin J8 connector 
  (intended for connection to a TFT LCD display). 
A [40-pin FPC to 2x20 IDC adapter](https://www.digikey.com/en/products/detail/adafruit-industries-llc/4905/14205159) 
  is convenient for easy probing of the FlexIO output signals.
The IMXRT1050-EVKB Schematics label these signals as `LCDIF_`, so I've included those labels here too
  for easy identification on the NXP schematic.

| DAC Signal  | PORT_PIN    | FLEXIO2 | MCU Pin | LCDIF_   | J8 |
|---------|------------|---------|---------|---------|----|
| D0      | GPIO_B0_00 | 0       | D7      | CLK     | 30 |
| D1      | GPIO_B0_01 | 1       | E7      | ENABLE  | 34 |
| D2      | GPIO_B0_02 | 2       | E8      | HSYNC   | 32 |
| D3      | GPIO_B0_03 | 3       | D8      | VSYNC   | 33 |
| D4      | GPIO_B0_04 | 4       | C8      | D0      | 24 |
| D5      | GPIO_B0_05 | 5       | B8      | D1      | 25 |
| D6      | GPIO_B0_06 | 6       | A8      | D2      | 26 |
| D7      | GPIO_B0_07 | 7       | A9      | D3      | 27 |
| D8      | GPIO_B0_08 | 8       | B9      | D4      | 28 |
| D9      | GPIO_B0_09 | 9       | C9      | D5      | 15 |
| D10     | GPIO_B0_10 | 10      | D9      | D6      | 16 |
| D11     | GPIO_B0_11 | 11      | A10     | D7      | 17 |
| D12     | GPIO_B0_12 | 12      | C10     | D8      | 18 |
| D13     | GPIO_B0_13 | 13      | D10     | D9      | 19 |
| D14     | GPIO_B0_14 | 14      | E10     | D10     | 20 |
| D15     | GPIO_B0_15 | 15      | E11     | D11     | 8  |
| DAC_CLK | GPIO_B1_00 | 16      | A11     | D12     | 9  |
| GND     |            |         |         |         | 3  |
| GND     |            |         |         |         | 36 |
| GND     |            |         |         |         | 29 |


# Prepare the Demo
1. Connect a USB cable between the host PC and the OpenSDA USB port on the target board.  
(Alternatively you can use the JTAG connector J21 and provide power with a USB connection at J9.
You'll need to configure J1 with a jumper across `3-4` to select the `5V_USB_OTG` as the 5V system power source.)
2. Download the program to the target board.
3. Either press the reset button on your board or launch the debugger in your IDE to begin running the demo.

Connect some of the signals listed above to an oscilloscope.
DAC_CLK should provide a 6 MHz, 50% duty cycle clock.
D0, D1, D2, D3 should provide a parallel data, updated at 6 MHz, following the pattern in `waveform_buffer`:

| `waveform_buffer` Data   | D2 | D1 | D0 |
| ------ | -- | -- | -- |
| 0x0000 | 0  | 0  | 0  |
| 0xAAAA | 0  | 1  | 0  |
| 0x5555 | 1  | 0  | 1  |
| 0xF0F0 | 0  | 0  | 0  |
| 0x0F0F | 1  | 1  | 1  |

You should see something like below:  
![Oscilloscope capture of DAC CLK, D0, D1, and D2](FlexIO_ParallelOut.png)

CH1 represents the DAC_CLK (50% duty cycle).  
CH2 represents D0 (bit pattern 0, 0, 1, 0, 1).  
CH3 represents D1 (bit pattern 0, 1, 0, 0, 1)  
CH4 represents D2 (bit pattern 0, 0, 1, 0, 1)  

Data is updated on the falling edge of the CH1 DAC_CLK.
