PYNQ Arduino IOPで2つのUARTを使う

UART0はデフォルトで入っている

1. Chipkit GPIO[15:0]の16bitの2つを削って、14bitとする。


2. UART1を追加


自動配線だとMicroBlazeに配線されないので、Arduino IOP内のAXI Interconnectにつなぐように手動で配線する。UARTLITE0を参考にすればいい。
あとAXI InterconnetのMaster interfacesのEnable Register Sliceの設定をNoneからOuterにする。

3. top.vを手で編集

86c86,88
<     sws_2bits_tri_i);
---
>     sws_2bits_tri_i,
>     uart_rtl_0_rxd,
>     uart_rtl_0_txd);
132c134
<   inout [15:0]ck_gpio_tri_io;
---
>   inout [13:0]ck_gpio_tri_io;
161a164,165
>   input uart_rtl_0_rxd;
>   output uart_rtl_0_txd;
206,209c210,213
<   wire [15:0]ck_gpio_tri_i;
<   wire [15:0]ck_gpio_tri_io;
<   wire [15:0]ck_gpio_tri_o;
<   wire [15:0]ck_gpio_tri_t;
---
>   wire [13:0]ck_gpio_tri_i;
>   wire [13:0]ck_gpio_tri_io;
>   wire [13:0]ck_gpio_tri_o;
>   wire [13:0]ck_gpio_tri_t;
279a284,285
>   wire uart_rtl_0_rxd;
>   wire uart_rtl_0_txd;
284c290
< 	for (i=0; i < 16; i=i+1)
---
> 	for (i=0; i < 14; i=i+1)
431,433c437,439
<     .ck_gpio_tri_i({ck_gpio_tri_i[15],ck_gpio_tri_i[14],ck_gpio_tri_i[13],ck_gpio_tri_i[12],ck_gpio_tri_i[11],ck_gpio_tri_i[10],ck_gpio_tri_i[9],ck_gpio_tri_i[8],ck_gpio_tri_i[7],ck_gpio_tri_i[6],ck_gpio_tri_i[5],ck_gpio_tri_i[4],ck_gpio_tri_i[3],ck_gpio_tri_i[2],ck_gpio_tri_i[1],ck_gpio_tri_i[0]}),
<     .ck_gpio_tri_o({ck_gpio_tri_o[15],ck_gpio_tri_o[14],ck_gpio_tri_o[13],ck_gpio_tri_o[12],ck_gpio_tri_o[11],ck_gpio_tri_o[10],ck_gpio_tri_o[9],ck_gpio_tri_o[8],ck_gpio_tri_o[7],ck_gpio_tri_o[6],ck_gpio_tri_o[5],ck_gpio_tri_o[4],ck_gpio_tri_o[3],ck_gpio_tri_o[2],ck_gpio_tri_o[1],ck_gpio_tri_o[0]}),
<     .ck_gpio_tri_t({ck_gpio_tri_t[15],ck_gpio_tri_t[14],ck_gpio_tri_t[13],ck_gpio_tri_t[12],ck_gpio_tri_t[11],ck_gpio_tri_t[10],ck_gpio_tri_t[9],ck_gpio_tri_t[8],ck_gpio_tri_t[7],ck_gpio_tri_t[6],ck_gpio_tri_t[5],ck_gpio_tri_t[4],ck_gpio_tri_t[3],ck_gpio_tri_t[2],ck_gpio_tri_t[1],ck_gpio_tri_t[0]}),
---
>     .ck_gpio_tri_i({ck_gpio_tri_i[13],ck_gpio_tri_i[12],ck_gpio_tri_i[11],ck_gpio_tri_i[10],ck_gpio_tri_i[9],ck_gpio_tri_i[8],ck_gpio_tri_i[7],ck_gpio_tri_i[6],ck_gpio_tri_i[5],ck_gpio_tri_i[4],ck_gpio_tri_i[3],ck_gpio_tri_i[2],ck_gpio_tri_i[1],ck_gpio_tri_i[0]}),
>     .ck_gpio_tri_o({ck_gpio_tri_o[13],ck_gpio_tri_o[12],ck_gpio_tri_o[11],ck_gpio_tri_o[10],ck_gpio_tri_o[9],ck_gpio_tri_o[8],ck_gpio_tri_o[7],ck_gpio_tri_o[6],ck_gpio_tri_o[5],ck_gpio_tri_o[4],ck_gpio_tri_o[3],ck_gpio_tri_o[2],ck_gpio_tri_o[1],ck_gpio_tri_o[0]}),
>     .ck_gpio_tri_t({ck_gpio_tri_t[13],ck_gpio_tri_t[12],ck_gpio_tri_t[11],ck_gpio_tri_t[10],ck_gpio_tri_t[9],ck_gpio_tri_t[8],ck_gpio_tri_t[7],ck_gpio_tri_t[6],ck_gpio_tri_t[5],ck_gpio_tri_t[4],ck_gpio_tri_t[3],ck_gpio_tri_t[2],ck_gpio_tri_t[1],ck_gpio_tri_t[0]}),
489c495,497
<     .sws_2bits_tri_i(sws_2bits_tri_i));
---
>     .sws_2bits_tri_i(sws_2bits_tri_i),
>     .uart_rtl_0_rxd(uart_rtl_0_rxd),
>     .uart_rtl_0_txd(uart_rtl_0_txd));

4. I/O Ports(top.xdc)を編集

Chipkit上での位置:IO40->RX, IO41->TX

5. XilinxSDK上でのコード

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xuartlite.h"
#include "xuartlite_l.h"
#include "xio_switch.h"
#define UARTLITE_DEVICE_ID	XPAR_UARTLITE_0_DEVICE_ID
#define UARTLITE_DEVICE2_ID	XPAR_UARTLITE_1_DEVICE_ID

XUartLite UartLite;
XUartLite UartLite2;

int main()
{
	init_platform();
	init_io_switch();
	set_pin(0,UART0_RX);
	set_pin(1,UART0_TX);

	int Status;
	Status = XUartLite_Initialize(&UartLite, UARTLITE_DEVICE_ID);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}
	Status = XUartLite_Initialize(&UartLite2, UARTLITE_DEVICE2_ID);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	print("hello world");

	unsigned char *hoge = "a";
	while(1){
		XUartLite_Send(&UartLite, hoge, 1);
		XUartLite_Send(&UartLite2, hoge, 1);
		usleep(1000*1000);
	}

	cleanup_platform();
	return 0;
}