LED Pattern

Implement a simple visual pattern using the onboard LEDs, a sine wave stored in LUTs, and PWM.


In [1]:
%%HTML
<video width="320" height="240" controls>
  <source src="images/pattern.mp4" type="video/mp4">
</video>



In [2]:
import sys
import magma as m
m.set_mantle_target("ice40")
import mantle
from loam.boards.icestick import IceStick
import math

icestick = IceStick()
icestick.Clock.on()
icestick.D1.on()
icestick.D2.on()
icestick.D3.on()
icestick.D4.on()
icestick.D5.on()

main = icestick.main()

nbits = 6
count = mantle.Counter(nbits, cout=False)
rombits = [[] for _ in range(0, nbits)]
for i in range(0, 2**nbits):
    value = int(2**nbits * (.5 + .5 * math.sin(float(i) / (2**nbits - 1) * 2 * math.pi)))
    for i, bit in enumerate(m.bitutils.int2seq(value, nbits)):
        rombits[i].append(bit)

for i, led in enumerate([main.D1, main.D2, main.D5, main.D3, main.D4]):
    roms = [m.uncurry(mantle.LUT6(bits[i*(2**nbits // 5):] + bits[:i*(2**nbits // 5)])) for bits in rombits]

    clock_enable = mantle.Counter(18)
    rom_counter = mantle.Counter(nbits, cout=False, has_ce=True)
    m.wire(rom_counter.CE, clock_enable.COUT)
    for rom in roms:
        m.wire(rom.I, rom_counter.O)

    ult = mantle.ULT(nbits)
    m.wire(ult.I0, count.O)
    m.wire(ult.I1, m.join(roms).O)
    m.wire(ult.O, led)


m.compile("build/sin_leds", main)


import lattice ice40
import lattice mantle40

In [3]:
%%bash
cd build
yosys -q -p 'synth_ice40 -top main -blif sin_leds.blif' sin_leds.v
arachne-pnr -q -d 1k -o sin_leds.txt -p sin_leds.pcf sin_leds.blif 
icepack sin_leds.txt sin_leds.bin
iceprog sin_leds.bin


init..
cdone: high
reset..
cdone: low
flash ID: 0x20 0xBA 0x16 0x10 0x00 0x00 0x23 0x64 0x34 0x65 0x03 0x00 0x71 0x00 0x26 0x27 0x12 0x16 0xD3 0xE4
file size: 32220
erase 64kB sector at 0x000000..
programming..
reading..
VERIFY OK
cdone: high
Bye.