概要
micropythonでshrike-lite、やってみた。
micropythonからspiでコードを送り、fpgaでモールスを表示する。
手順
fpgaのビットストリームを作る。
(* top *) module top ((* iopad_external_pin, clkbuf_inhibit *) input clk,
(* iopad_external_pin *) output clk_en,
(* iopad_external_pin *) input rst_n,
(* iopad_external_pin *) input spi_ss_n,
(* iopad_external_pin *) input spi_sck,
(* iopad_external_pin *) input spi_mosi,
(* iopad_external_pin *) output spi_miso,
(* iopad_external_pin *) output spi_miso_en,
(* iopad_external_pin *) output reg led,
(* iopad_external_pin *) output led_en
);
localparam integer CLK = 50_000_000;
localparam integer DOT_TIME = CLK / 5;
localparam integer DASH_TIME = (CLK / 5) * 3;
localparam IDLE = 2'd0,
ON = 2'd1,
OFF = 2'd2;
reg [7:0] morse_pattern;
reg [3:0] morse_len;
reg [1:0] state;
reg [31:0] counter;
reg [3:0] index;
reg led_reg;
reg [7:0] tx_data_reg;
wire curr_is_dash = morse_pattern[morse_len - 1 - index];
wire [31:0] curr_on_time = curr_is_dash ? DASH_TIME : DOT_TIME;
wire [7:0] data;
wire data_valid;
wire [7:0] rx_data_wire;
wire rx_valid_pulse;
assign data = rx_data_wire;
assign data_valid = rx_valid_pulse;
assign led_en = 1'b1;
assign clk_en = 1'b1;
spi_target #(.CPOL(1'b0), .CPHA(1'b0), .WIDTH(8), .LSB(1'b0))
u_spi_target (.i_clk(clk), .i_rst_n(rst_n), .i_enable(1'b1), .i_ss_n(spi_ss_n), .i_sck(spi_sck), .i_mosi(spi_mosi), .o_miso(spi_miso),
.o_miso_oe(spi_miso_en), .o_rx_data(rx_data_wire), .o_rx_data_valid(rx_valid_pulse), .i_tx_data(tx_data_reg), .o_tx_data_hold());
initial
begin
state = IDLE;
counter = 32'd0;
index = 4'd0;
led = 1'b0;
morse_pattern = 8'd0;
morse_len = 4'd0;
tx_data_reg = 8'd1;
end
always @(posedge clk)
begin
case (state)
IDLE:
begin
led <= 1'b0;
counter <= 32'd0;
index <= 4'd0;
if (data_valid)
begin
case (data)
"A", "a": begin morse_pattern <= 8'b0000_0001; morse_len <= 4'd2; end // .-
"B", "b": begin morse_pattern <= 8'b0000_1000; morse_len <= 4'd4; end // -...
"C", "c": begin morse_pattern <= 8'b0000_1010; morse_len <= 4'd4; end // -.-.
"D", "d": begin morse_pattern <= 8'b0000_0100; morse_len <= 4'd3; end // -..
"E", "e": begin morse_pattern <= 8'b0000_0000; morse_len <= 4'd1; end // .
"F", "f": begin morse_pattern <= 8'b0000_0010; morse_len <= 4'd4; end // ..-.
"G", "g": begin morse_pattern <= 8'b0000_0110; morse_len <= 4'd3; end // --.
"H", "h": begin morse_pattern <= 8'b0000_0000; morse_len <= 4'd4; end // ....
"I", "i": begin morse_pattern <= 8'b0000_0000; morse_len <= 4'd2; end // ..
"J", "j": begin morse_pattern <= 8'b0000_0111; morse_len <= 4'd4; end // .---
"K", "k": begin morse_pattern <= 8'b0000_0101; morse_len <= 4'd3; end // -.-
"L", "l": begin morse_pattern <= 8'b0000_0100; morse_len <= 4'd4; end // .-..
"M", "m": begin morse_pattern <= 8'b0000_0011; morse_len <= 4'd2; end // --
"N", "n": begin morse_pattern <= 8'b0000_0010; morse_len <= 4'd2; end // -.
"O", "o": begin morse_pattern <= 8'b0000_0111; morse_len <= 4'd3; end // ---
"P", "p": begin morse_pattern <= 8'b0000_0110; morse_len <= 4'd4; end // .--.
"Q", "q": begin morse_pattern <= 8'b0000_1101; morse_len <= 4'd4; end // --.-
"R", "r": begin morse_pattern <= 8'b0000_0010; morse_len <= 4'd3; end // .-.
"S", "s": begin morse_pattern <= 8'b0000_0000; morse_len <= 4'd3; end // ...
"T", "t": begin morse_pattern <= 8'b0000_0001; morse_len <= 4'd1; end // -
"U", "u": begin morse_pattern <= 8'b0000_0001; morse_len <= 4'd3; end // ..-
"V", "v": begin morse_pattern <= 8'b0000_0001; morse_len <= 4'd4; end // ...-
"W", "w": begin morse_pattern <= 8'b0000_0011; morse_len <= 4'd3; end // .--
"X", "x": begin morse_pattern <= 8'b0000_1001; morse_len <= 4'd4; end // -..-
"Y", "y": begin morse_pattern <= 8'b0000_1011; morse_len <= 4'd4; end // -.--
"Z", "z": begin morse_pattern <= 8'b0000_1100; morse_len <= 4'd4; end // --..
"0": begin morse_pattern <= 8'b0001_1111; morse_len <= 4'd5; end // -----
"1": begin morse_pattern <= 8'b0000_1111; morse_len <= 4'd5; end // .----
"2": begin morse_pattern <= 8'b0000_0111; morse_len <= 4'd5; end // ..---
"3": begin morse_pattern <= 8'b0000_0011; morse_len <= 4'd5; end // ...--
"4": begin morse_pattern <= 8'b0000_0001; morse_len <= 4'd5; end // ....-
"5": begin morse_pattern <= 8'b0000_0000; morse_len <= 4'd5; end // .....
"6": begin morse_pattern <= 8'b0001_0000; morse_len <= 4'd5; end // -....
"7": begin morse_pattern <= 8'b0001_1000; morse_len <= 4'd5; end // --...
"8": begin morse_pattern <= 8'b0001_1100; morse_len <= 4'd5; end // ---..
"9": begin morse_pattern <= 8'b0001_1110; morse_len <= 4'd5; end // ----.
default: begin morse_pattern <= 8'd0; morse_len <= 4'd0; end
endcase
case (data)
"A","a","B","b","C","c","D","d","E","e","F","f","G","g","H","h","I","i",
"J","j","K","k","L","l","M","m","N","n","O","o","P","p","Q","q","R","r",
"S","s","T","t","U","u","V","v","W","w","X","x","Y","y","Z","z",
"0","1","2","3","4","5","6","7","8","9":
state <= ON;
default:
state <= IDLE;
endcase
end
end
ON:
begin
led <= 1'b1;
counter <= counter + 32'd1;
if (counter >= curr_on_time)
begin
counter <= 32'd0;
state <= OFF;
end
end
OFF:
begin
led <= 1'b0;
counter <= counter + 32'd1;
if (counter >= DOT_TIME)
begin
counter <= 32'd0;
if (index + 1 >= morse_len)
begin
index <= 4'd0;
state <= IDLE;
end
else
begin
index <= index + 4'd1;
state <= ON;
end
end
end
default:
state <= IDLE;
endcase
end
endmodule
spi_morse.binにして、usbメモリーに入れる。
main.pyを書く。
from machine import Pin, SPI
import time
import shrike
import sys
import math
import struct
import uselect
SCK = 2
CS = 1
MOSI = 3
MISO = 0
FPGA_RESET = 14
shrike.reset()
shrike.flash("spi_mors.bin")
reset_pin = Pin(FPGA_RESET, Pin.OUT, value = 1)
reset_pin.value(0)
time.sleep_ms(100)
reset_pin.value(1)
time.sleep_ms(100)
cs = Pin(CS, Pin.OUT, value = 1)
spi = SPI(0, baudrate = 1_000_000, polarity = 0, phase = 0, bits = 8, firstbit = SPI.MSB, sck = Pin(SCK), mosi = Pin(MOSI), miso = Pin(MISO))
def send(value):
tx = bytes([value])
rx = bytearray(1)
cs.value(0)
spi.write_readinto(tx, rx)
cs.value(1)
実行結果
>
send(ord('S'))
>>> send(ord('S'))
send(ord('O'))
>>> send(ord('O'))
send(ord('S'))
>>> send(ord('S'))
send(ord('O'))
>>> send(ord('O'))
send(ord('S'))
>>> send(ord('S'))
send(ord('O'))
>>> send(ord('O'))
以上。