This shows you the differences between two versions of the page.
flink_example_1 [2015/03/28 08:17] ursgraf |
flink_example_1 [2016/02/25 13:32] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== flink on Phytec PCM032 Board (mpc5200) ====== | ||
- | The following example describes in detail how a Phytec PCM032 Board containing a mpc5200 and a FPGA is configured to be used with flink. The FPGA will contain a single channel PWM module and a single channel GPIO modul. flink was tested with the FPGA on the mpc5200io module as well as with an external FPGA connected through a SPI interface. | ||
- | ===== External FPGA connected through SPI interface ===== | ||
- | The pmc5200 offers a dedicated SPI (8 bit transfers) which can be routed onto the pins of the timer group or the PSC3 group. The PSC1, PSC2, PSC3 or PSC6 can operate as an SPI with 32 bit transfers. | ||
- | |||
- | ==== Setup ==== | ||
- | * Configure the board with a working Linux kernel and root file system or use the system described in [[http:// | ||
- | * Make sure that the device tree blob is up-to-date. It must contain a node for the hardware SPI (spi@f00) or a PSC-SPI (e.g. spi: psc@2000). | ||
- | * Get necessary sources for the flink project.< | ||
- | git clone https:// | ||
- | git clone https:// | ||
- | |||
- | ==== Configure the FPGA ==== | ||
- | Proceed as described in [[flink_vhdl|flink VHDL]]. | ||
- | * In 5: add a block //gpio// and a block //pwm// to the system. Leave the standard values as they are except for the PWM module, whose base clock depends on your FPGA clock. Set '' | ||
- | * In 6: set the '' | ||
- | * After 10: the system should now look like: [{{ spi_qsys.png? | ||
- | Connect the FPGA with the SPI pins on the mpc5200. | ||
- | |||
- | ==== Loading the kernel modules ==== | ||
- | There are several ways to properly drive the SPI from the mpc5200. | ||
- | |||
- | === Configure pin multiplexing === | ||
- | The hardware SPI and can be routed onto several different pin groups. The PSC-SPI needs configuring of the port configuration register. Our current UBoot does not yet fully suppport device tree configuration, | ||
- | < | ||
- | // use these declarations for platform specific initialization | ||
- | static const struct of_device_id mpc52xx_gpio_simple[] = { | ||
- | { .compatible = " | ||
- | {} | ||
- | }; | ||
- | struct mpc52xx_gpio __iomem *gpio; | ||
- | struct device_node *np; | ||
- | u32 portConfig; | ||
- | u8 pscNum = 2; // set to 1,2,3 or 6 | ||
- | |||
- | // use in case a PSC serves as SPI | ||
- | // set port configuration register of mpc5200 | ||
- | np = of_find_matching_node(NULL, | ||
- | gpio = of_iomap(np, | ||
- | of_node_put(np); | ||
- | if (!gpio) { | ||
- | printk(KERN_ERR "%s() failed, expect abnormal behavior\n", | ||
- | return -1; | ||
- | } | ||
- | portConfig = in_be32(& | ||
- | #if defined(DBG) | ||
- | printk(KERN_DEBUG "[%s] Current port config = 0x%x\n", | ||
- | #endif | ||
- | if (pscNum == 6) { | ||
- | portConfig |= 0x00700060; | ||
- | } else if (pscNum >= 1 && pscNum <= 3) { | ||
- | portConfig &= ~(7 << ((pscNum-1)*4)); | ||
- | portConfig |= 6 << ((pscNum-1)*4); | ||
- | } else { | ||
- | printk(KERN_ERR "[%s] Wrong PSC number\n", | ||
- | return -1; | ||
- | } | ||
- | out_be32(& | ||
- | #if defined(DBG) | ||
- | printk(KERN_DEBUG "[%s] New port config = 0x%x\n", | ||
- | #endif | ||
- | iounmap(gpio); | ||
- | </ | ||
- | Similarly you could configure the PSC3 group that the hardware SPI is output on the pins PSC3_6 .. PSC3_9. In our system this is already done by UBoot. | ||
- | |||
- | === Build into kernel === | ||
- | Compile kernel modules (see [[software: | ||
- | |||
- | === Load manually === | ||
- | When loading the driver manually add the following code to the '' | ||
- | < | ||
- | struct spi_master *master; | ||
- | struct spi_device *dev; | ||
- | master = spi_busnum_to_master(num); | ||
- | if (!master) { | ||
- | printk(KERN_ERR "[%s] No master for this bus number\n", | ||
- | goto exit; | ||
- | } | ||
- | dev = spi_new_device(master, | ||
- | </ | ||
- | '' | ||
- | < | ||
- | static struct spi_board_info flinkInfo = { | ||
- | .modalias = " | ||
- | .max_speed_hz = 2000000, | ||
- | .mode = SPI_MODE_1 | ||
- | }; | ||
- | </ | ||
- | When working with a PSC-SPI you would configure it to run with truly 32 bit transfers. Add the following lines: | ||
- | < | ||
- | dev = spi_new_device(master, | ||
- | dev-> | ||
- | spi_setup(dev); | ||
- | </ | ||
- | Finally, compile kernel modules (see [[software: | ||
- | < | ||
- | insmod flink.ko | ||
- | insmod flink_spi.ko | ||
- | </ | ||
- | As we specified an info subdevice we can ommit the memory length when loading '' | ||
- | |||
- | ==== flink library and application ==== | ||
- | Compile the flink library (see [[software: | ||
- | |||
- | ===== Onboard FPGA connected through Local Plus Bus ===== | ||
- | |||
- | === Setup === | ||
- | * Configure the board with a working Linux kernel and root file system or use the system described in [[software: | ||
- | * Make sure that the device tree blob is up-to-date. It must contain a node for the FPGA sitting on the local plus bus. | ||
- | * Get necessary sources for the flink project.< | ||
- | git clone https:// | ||
- | git clone https:// | ||
- | |||
- | === Configure the FPGA === | ||
- | Proceed as described in [[flink_vhdl|flink VHDL]]. | ||
- | * In 5: add a block //gpio// and a block //pwm// to the system. Also add a // | ||
- | * In 6: set the '' | ||
- | * After 10: the system should now look like: [{{ lpb_qsys.png? | ||
- | * In 15: assign the pins as follows: | ||
- | |||
- | ^signal^dir^pin^ | ||
- | |clk_clk|in|PIN_H2| | ||
- | |lpb_ack_n|out|PIN_T11| | ||
- | |lpb_ad[31]|bidir|PIN_T6| | ||
- | |lpb_ad[30]|bidir|PIN_N8| | ||
- | |lpb_ad[29]|bidir|PIN_R9| | ||
- | |lpb_ad[28]|bidir|PIN_T9| | ||
- | |lpb_ad[27]|bidir|PIN_R8| | ||
- | |lpb_ad[26]|bidir|PIN_T8| | ||
- | |lpb_ad[25]|bidir|PIN_L8| | ||
- | |lpb_ad[24]|bidir|PIN_L7| | ||
- | |lpb_ad[23]|bidir|PIN_R7| | ||
- | |lpb_ad[22]|bidir|PIN_T7| | ||
- | |lpb_ad[21]|bidir|PIN_R5| | ||
- | |lpb_ad[20]|bidir|PIN_T5| | ||
- | |lpb_ad[19]|bidir|PIN_R4| | ||
- | |lpb_ad[18]|bidir|PIN_T4| | ||
- | |lpb_ad[17]|bidir|PIN_P4| | ||
- | |lpb_ad[16]|bidir|PIN_P5| | ||
- | |lpb_ad[15]|bidir|PIN_R3| | ||
- | |lpb_ad[14]|bidir|PIN_T3| | ||
- | |lpb_ad[13]|bidir|PIN_P11| | ||
- | |lpb_ad[12]|bidir|PIN_N11| | ||
- | |lpb_ad[11]|bidir|PIN_L11| | ||
- | |lpb_ad[10]|bidir|PIN_M11| | ||
- | |lpb_ad[9]|bidir|PIN_R14| | ||
- | |lpb_ad[8]|bidir|PIN_T14| | ||
- | |lpb_ad[7]|bidir|PIN_R13| | ||
- | |lpb_ad[6]|bidir|PIN_T13| | ||
- | |lpb_ad[5]|bidir|PIN_R12| | ||
- | |lpb_ad[4]|bidir|PIN_T12| | ||
- | |lpb_ad[3]|bidir|PIN_P13| | ||
- | |lpb_ad[2]|bidir|PIN_P12| | ||
- | |lpb_ad[1]|bidir|PIN_K10| | ||
- | |lpb_ad[0]|bidir|PIN_K11| | ||
- | |lpb_ale_n|in|PIN_R11| | ||
- | |lpb_cs_n[0]|in|PIN_N10| | ||
- | |lpb_int|out|PIN_R6| | ||
- | |lpb_oe_n|in|PIN_L9| | ||
- | |lpb_rdwr_n|in|PIN_L10| | ||
- | |lpb_ts_n|in|PIN_T10| | ||
- | |reset_reset_n|in|PIN_N9| | ||
- | |||
- | The pins for the PWM output and the GPIO have to be assigned according to your hardware. The FPGA can be loaded through the onboard PROM or through serial loading from the processor, see [[http:// | ||
- | |||
- | ==== Loading the kernel modules ==== | ||
- | Compile the Linux kernel modules ([[flink_linux|flink Linux Kernel Modules]]), transfer them to the target and load them with | ||
- | < | ||
- | insmod flink.ko | ||
- | insmod flink_lpb.ko | ||
- | </ | ||
- | As we specified an info subdevice we can ommit the memory length when loading '' | ||
- | |||
- | ==== flink library and application ==== | ||
- | This step is the same as described under using the SPI. |