Open hstarmans opened 7 years ago
You need to create a "packet" to send down to toggle the lights. The simple UART is typically configured for 115200. It has been awhile since I have looked at it, let me see if I can get some hardware setup this weekend and test.
Thank you for your reply, I guess I need something along the lines of;
import serial
ser=serial.Serial("/dev/ttyS0",timeout=1) # rasp2 "/dev/ttyAMA0"
ser.baudrate=115200
# first byte fixed at DE
# command: 1 read 2 write --> write so 2
# address byte:
# peripheral address 4 bit; set to ?
# memory address 28 bit; set to 0
# length of data: 4 bytes (does not seem to matter packet length fixed at 12)
# sequence byte fixed at CA
# data byte; 4 bytes, arbitrarily fixed at '11'
# hexdata='DE'+'command byte'+'address byte'*4+'length of data'+'CA'+'data byte'*4
for command in [b'\x01',b'\x02']: # command
for i in [0,1,15]: # peripheral address
per_adr=(i*16).to_bytes(1,byteorder='big')
for j in [0,1,2,16,30,31,32]: # memory address
mem_addr=(j).to_bytes(3,byteorder='big')
packet=b'\xDE'+command+per_adr+mem_addr+b'\x04'+b'\xCA'+b'\x11'*4
print("sending packet "+str(packet))
ser.write(packet)
#read possible reply
s=ser.read(12) # read reply
print("reply:"+s.decode())
ser.close()
As you might realize, the code does not work on a Raspberry Pi 2 and Raspberry Pi 3. Could you provide more info on the packet I should sent? Note: I also receive the following build warnings: signal is driven but no read: command_bridge_1_bytemon, command_bridge_1_bb_per_addr,command_bridge_1_error,command_bridge_1_controller_basic_1_tocnt, uartlite_1_fifo_fast_1_fbus_read_valid,uartlite_1_fifo_fast_2_fbus_full, signal is not driven: uartlite_1_fifo_fast_1_fbus_read_valid, uartlite_1_fifo_fast_2_fbus_clear
This is the code I use to generate the packets. I have not tested/used from a RPi (others have). I am not sure what code they used on the RPi.
Thank you for your reply. I do see changes now. I still don't receive any replies on UART but see changes on the LedDigits panel. If the reset pin is low; the number 8 is blinking on LED1 of the Leddigits test panel. If the reset pin is high; the Leddigits panel is off. If the reset pin is low and the value 0xFF is written to address 0x20, there are no changes. However, if the reset pin is put high again the number 8 remains. The led panel does not seem to be driven correctly via daisy chaining. As a result, I don't expect it to produce the right numbers. I have used the following code to test it:
import serial
import RPi.GPIO as GPIO
from time import sleep
from rhea.utils import CommandPacket
# connect to pin
GPIO.setmode(GPIO.BCM)
GPIO.setup(23,GPIO.OUT) # i use a different pin!! use gxsconn to get the correct pins
# reset low
GPIO.output(23,0) # this should already be the case
# connect to serial port
ser=serial.Serial("/dev/ttyAMA0",timeout=2) # rasp2 used
ser.baudrate=115200
wcommand=CommandPacket(rnw=False,address=0x20,vals=[0xFF])
ser.write(wcommand.rawbytes)
rcommand=CommandPacket(rnw=True,address=0x20,vals=None)
ser.write(rcommand.rawbytes)
# read from the serial buffer
ser.read()
# no value is received ; does not seem to work
GPIO.output(23,1)
# an 8 is visible on ledbank 1, if one does not write anything nothing is visible
I have spotted one bug:
# create the UART instance.
uart_inst = uartlite(
glbl, uart_fifo, serial_in=bcm14_txd, serial_out=bcm15_rxd,
fifosize=4
)
Should be:
# create the UART instance.
uart_inst = uartlite(
glbl, uart_fifo, serial_in=bcm15_rxd, serial_out=bcm14_txd,
fifosize=4
)
Compare the code from Icestick with the xula, look at the defintion of uartlite I have the following files: test_blinky_host_xula.py
from __future__ import print_function, division
import myhdl
from myhdl import Signal, intbv, instance, delay, StopSimulation, ResetSignal
from rhea.system import Global, Clock, Reset
from rhea.models.uart import UARTModel
from rhea.utils.test import run_testbench, tb_args, tb_default_args, tb_convert
from rhea.utils import CommandPacket
from rhea.utils.command_packet import PACKET_LENGTH
from xula_blinky_host import xula2_blinky_host
def test_ibh(args=None):
args = tb_default_args(args)
numbytes = 13
reset= ResetSignal(0, active=1, async=True)
clock = Clock(0, frequency=12e6)
glbl = Global(clock, None)
led = Signal(intbv(0)[8:])
pmod = Signal(intbv(0)[8:])
uart_tx = Signal(bool(0))
uart_rx = Signal(bool(0))
uart_dtr = Signal(bool(0)) # NOT USED
uart_rts = Signal(bool(0)) # NOT USED
uartmdl = UARTModel()
@myhdl.block
def bench_ibh():
tbclk = clock.gen()
tbmdl = uartmdl.process(glbl, uart_tx, uart_rx)
tbdut = xula2_blinky_host(clock, reset, led, uart_tx, uart_rx)
@instance
def tbstim():
yield delay(1000)
# send a write
pkt = CommandPacket(False, address=0x20, vals=[0xFF])
for bb in pkt.rawbytes:
uartmdl.write(bb)
waitticks = int((1/115200.) / 1e-9) * 10 * 28
yield delay(waitticks)
timeout = 100
# get the response packet
for ii in range(PACKET_LENGTH):
rb = uartmdl.read()
while rb is None and timeout > 0:
yield clock.posedge
rb = uartmdl.read()
timeout -= 1
if rb is None:
raise TimeoutError
yield delay(waitticks)
# the last byte should be the byte written
assert rb == 0xFF
yield delay(1000)
# send a read
pkt = CommandPacket(True, address=0x20, vals=None)
yield delay(1000)
raise StopSimulation
return tbclk, tbmdl, tbdut, tbstim
run_testbench(bench_ibh, args=args)
inst = xula2_blinky_host(
clock, reset, led,
uart_tx, uart_rx
)
#tb_convert(inst)
if __name__ == '__main__':
test_ibh(tb_args())
The tests pass. I use the following xula_blinky_host file. I would suggest to call this xula2. I have also defined a resetsignal in the function test_instance().
xula_blinky_host.py
import argparse
import subprocess
from pprint import pprint
from myhdl import Signal, intbv, always_seq, always_comb, ResetSignal, block, instances
from rhea import Global, Clock, Reset
from rhea.system import Barebone, FIFOBus
from rhea.cores.uart import uartlite
from rhea.cores.memmap import command_bridge
from rhea.cores.misc import glbl_timer_ticks
from rhea.build.boards import get_board
@block
def xula2_blinky_host(clock, reset, led, bcm14_txd, bcm15_rxd):
"""
The LEDs are controlled from the RPi over the UART
to the FPGA.
"""
glbl = Global(clock, reset)
ledreg = Signal(intbv(0)[8:])
# create the timer tick instance
tick_inst = glbl_timer_ticks(glbl, include_seconds=True)
# create the interfaces to the UART
uart_fifo = FIFOBus(width=8)
# create the memmap (CSR) interface
memmap = Barebone(glbl, data_width=32, address_width=32)
# create the UART instance.
uart_inst = uartlite(
glbl, uart_fifo, bcm15_rxd, bcm14_txd, fifosize=4
) #NOTE: switched 15_r and 14_t, icestick example does not specify fifosize
# create the packet command instance
cmd_inst = command_bridge(glbl, uart_fifo, memmap)
@always_seq(clock.posedge, reset=reset)
def beh_led_control():
memmap.done.next = not (memmap.write or memmap.read)
if memmap.write and memmap.mem_addr == 0x20:
ledreg.next = memmap.write_data
@always_comb
def beh_led_read():
if memmap.read and memmap.mem_addr == 0x20:
memmap.read_data.next = ledreg
else:
memmap.read_data.next = 0
# blink one of the LEDs
tone = Signal(intbv(0)[8:])
@always_seq(clock.posedge, reset=reset)
def beh_assign():
if glbl.tick_sec:
tone.next = (~tone) & 0x1
led.next = ledreg | tone[5:]
return instances()
def build(args):
brd = get_board('xula2_stickit_mb')
brd.add_port_name('led', 'pm3', slice(0, 8)) # NOTE: pm3 instead of pm2
brd.add_reset('reset', active=1, async=True, pins=('C16',)) # NOTE: use different pin
flow = brd.get_flow(top=xula2_blinky_host)
flow.run()
info = flow.get_utilization()
pprint(info)
def program(args):
subprocess.check_call(
["xsload",
"--fpga", "xilinx/xula2_stickit_mb.bit",
"-b", "xula2-lx25"]
)
def cliparse():
parser = argparse.ArgumentParser()
parser.add_argument("--build", default=False, action='store_true')
parser.add_argument("--test", default=False, action='store_true')
parser.add_argument("--program", default=False, action='store_true')
parser.add_argument("--walk", default=False, action='store_true')
args = parser.parse_args()
return args
def test_instance():
# check for basic syntax errors, use test_ice* to test
# functionality
xula2_blinky_host(
clock=Clock(0, frequency=12e6),
led=Signal(intbv(0)[8:]),
reset=ResetSignal(bool(0),active=1, async=True), #NOTE: not in original
bcm14_txd=Signal(bool(0)),
bcm15_rxd=Signal(bool(0)))
def main():
args = cliparse()
if args.test:
test_instance()
if args.build:
build(args)
if args.program:
program(args)
# @todo: add walk function
if __name__ == '__main__':
main()
Finally, I use the following file to test the code on a raspberry pi 2 with Python 3 and the latest rhea and myhdl. rasp2test.py
import serial
from rhea.utils import CommandPacket
ser=serial.Serial("/dev/ttyAMA0",timeout=2) #NOTE: used raspberry pi 2 for test
ser.baudrate=115200
w=CommandPacket(rnw=False,address=0x20,vals=[0xFF])
ser.write(w.rawbytes)
print(len(ser.read()))
r=CommandPacket(rnw=True,address=0x20,vals=None)
ser.write(r.rawbytes)
assert 0!=len(ser.read())
Conclusion:
@cfelton ; shall I change xula_blinky_host and add my rasptest and test_blinky_host_xula!? The pins of the xula2 seem to be flipped both in the definition and the uart test.
@hstarmans that is great you go it going!
Can you link the documentation that shows the names being flipped? It has been awhile and I don't recall if I was trying to standardize the UART signals always being from a certain perspective.
Go ahead and create a PR and I will review it.
Update Issue has been resolved, see my last two posts
Dear all,
I am trying to get xula_blinky_host.py working with a; Raspberry Pi 3B, Xula2-lx25, StickIt!-LedDigits and the Stickit!-MB v4. I have inserted the LedDigits in PM2. I am able to to run the LedDigitsTest, after changing the LedDigitsTest.UCF using xsconnect. I have verified the UART pins are working, by connecting chan 14 and 15 on the stickit board. I communicated via minicom and checked if I could receive echoes. I am able to create a bitstream from xula_blinky_host. If I upload this bitstream; nothing happens. The LedDigits module is off. This is not what i expect. I thought data could be written via uart to the xula2 and this would appear on the leddigit board on PM2. I can't write data.
Do the authors, @cfelton and @forumulator , have any advice on how to proceed!? Which settings should I use in minicom!? Should I try the example with a raspberry pi 2? What setup was used to verify the code!?
Notes: I use ubuntu 16.04.1, have a jumper on 5V-PWR and a jumper on GPIO-5V. The xula2-lx25 is connected via USB to the raspberry pi 3 or a raspberry pi 2 (tested both). I can only change the EEPROM via the Raspberry Pi 2. Similar question was asked in feb 2016 at the Xilinx forum.
Keep up the good work,
Rik