|
| 1 | +import os |
| 2 | +import subprocess |
| 3 | + |
| 4 | +from nmigen import * |
| 5 | +from nmigen.build import * |
| 6 | +from nmigen.vendor.intel import * |
| 7 | +from .resources import * |
| 8 | + |
| 9 | + |
| 10 | +__all__ = ["Chameleon96Platform"] |
| 11 | + |
| 12 | + |
| 13 | +class Chameleon96Platform(IntelPlatform): |
| 14 | + device = "5CSEBA6" # Cyclone V SE 110K LEs |
| 15 | + package = "U19" # UBGA-484 |
| 16 | + speed = "I7" |
| 17 | + default_clk = "cyclonev_oscillator" |
| 18 | + resources = [ |
| 19 | + # WIFI and BT LEDs |
| 20 | + *LEDResources( |
| 21 | + pins="Y19 Y20", |
| 22 | + attrs=Attrs(io_standard="2.5 V")), |
| 23 | + |
| 24 | + # TDA19988 HDMI transmitter |
| 25 | + Resource("tda19988", 0, |
| 26 | + Subsignal("vpa", Pins(" W8 W7 V6 V5 U6 ", dir="o")), # bits 3 to 7 |
| 27 | + Subsignal("vpb", Pins("AB5 AA5 AA8 AB8 AB9 Y11", dir="o")), # bits 2 to 7 |
| 28 | + Subsignal("vpc", Pins(" W6 Y5 AB7 AA7 AA6", dir="o")), # bits 3 to 7 |
| 29 | + Subsignal("pclk", Pins("AB10", dir="o")), |
| 30 | + Subsignal("hsync", Pins("V10 ", dir="o")), |
| 31 | + Subsignal("vsync", Pins("V7 ", dir="o")), |
| 32 | + Subsignal("de", Pins("Y8 ", dir="o")), |
| 33 | + Attrs(io_standard="1.8 V") |
| 34 | + ), |
| 35 | + |
| 36 | + I2CResource("tda19988_i2c", 0, |
| 37 | + scl="U7", sda="U10", |
| 38 | + attrs=Attrs(io_standard="1.8 V"), |
| 39 | + ), |
| 40 | + |
| 41 | + Resource("tda19988_i2s", 0, |
| 42 | + Subsignal("mclk", Pins("V11 ", dir="o")), # OSC_IN/AP3 |
| 43 | + Subsignal("txd", Pins("AA11", dir="o")), # AP1 |
| 44 | + Subsignal("txc", Pins("W11 ", dir="o")), # ACLK |
| 45 | + Subsignal("txfs", Pins("V9 ", dir="o")), # AP0 |
| 46 | + Attrs(io_standard="1.8 V") |
| 47 | + ), |
| 48 | + |
| 49 | + # Wifi and BT module |
| 50 | + *SDCardResources("wifi", 0, |
| 51 | + clk="AB20", cmd="AB18", dat0="Y14", dat1="AB19", dat2="AA18", dat3="AB15", |
| 52 | + attrs=Attrs(io_standard="1.8 V"), |
| 53 | + ), |
| 54 | + |
| 55 | + Resource("bt", 0, |
| 56 | + Subsignal("host_wake", Pins("AB12", dir="o")), |
| 57 | + Attrs(io_standard="1.8 V"), |
| 58 | + ), |
| 59 | + |
| 60 | + Resource("bt_i2s", 0, |
| 61 | + Subsignal("txd", Pins("Y15 ", dir="o")), # BT_PCM_IN |
| 62 | + Subsignal("rxd", Pins("Y16 ", dir="i")), # BT_PCM_OUT |
| 63 | + Subsignal("txc", Pins("AA13", dir="i")), # BT_PCM_CLK |
| 64 | + Subsignal("txfs", Pins("AB13", dir="i")), # BT_PCM_SYNC |
| 65 | + Attrs(io_standard="1.8 V"), |
| 66 | + ), |
| 67 | + |
| 68 | + UARTResource("bt_uart", 0, |
| 69 | + rx="AB14", cts="AB17", tx="AA15", rts="AA16", role="dte", |
| 70 | + attrs=Attrs(io_standard="1.8 V"), |
| 71 | + ), |
| 72 | + ] |
| 73 | + |
| 74 | + connectors = [ |
| 75 | + # J3, 2x20 expansion port |
| 76 | + Connector("J", 3, |
| 77 | + "- - Y13 - W14 - C5 - C6 -" |
| 78 | + "- - - - - E5 - F5 - A6" |
| 79 | + "- A5 - - - - - - - -" |
| 80 | + "- - - - - - - - - -" |
| 81 | + ), |
| 82 | + |
| 83 | + # J8, 2x30 high speed expansion port (MIPI CSI) |
| 84 | + Connector("J", 8, |
| 85 | + "- V16 - U17 - - - V17 - W18" |
| 86 | + "- - - U18 W12 V19 - - - -" |
| 87 | + "- - - - - - - - - -" |
| 88 | + "- - - - - - - - - -" |
| 89 | + "- - - - - - - - - -" |
| 90 | + "- - - - - - - - - -" |
| 91 | + ), |
| 92 | + ] |
| 93 | + |
| 94 | + def toolchain_program(self, products, name): |
| 95 | + quartus_pgm = os.environ.get("QUARTUS_PGM", "quartus_pgm") |
| 96 | + with products.extract("{}.sof".format(name)) as bitstream_filename: |
| 97 | + # The @2 selects the second device in the JTAG chain, because this chip |
| 98 | + # puts the ARM cores first. |
| 99 | + subprocess.check_call([quartus_pgm, "--haltcc", "--mode", "JTAG", |
| 100 | + "--operation", "P;" + bitstream_filename + "@2"]) |
| 101 | + |
| 102 | + |
| 103 | +if __name__ == "__main__": |
| 104 | + from .test.blinky import Blinky |
| 105 | + Chameleon96Platform().build(Blinky(), do_program=True) |
0 commit comments