lambdaconcept_ecpix5: Add initial Video support at 640x480 (with Terminal/Framebuffer).

I2C intialization code adapted from https://github.com/ultraembedded/ecpix-5.

Tested with:
- python3 -m litex_boards.targets.lambdaconcept_ecpix5 --cpu-type=firev --with-video-terminal --build --load
- python3 -m litex_boards.targets.lambdaconcept_ecpix5 --cpu-type=firev --with-video-framebuffer --build --load

        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

 (c) Copyright 2012-2022 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs

 BIOS built on Mar  8 2022 15:34:22
 BIOS CRC passed (c7fe9ecd)

 Migen git sha1: ac70301
 LiteX git sha1: 7ebc7625

--=============== SoC ==================--
CPU:		FireV-STANDARD @ 75MHz
BUS:		WISHBONE 32-bit @ 4GiB
CSR:		32-bit data
ROM:		128KiB
SRAM:		8KiB
L2:		8KiB
SDRAM:		524288KiB 16-bit @ 300MT/s (CL-6 CWL-5)

--========== Initialization ============--
Initializing SDRAM @0x40000000...
Switching SDRAM to software control.
Read leveling:
  m0, b00: |01110000| delays: 02+-01
  m0, b01: |00000000| delays: -
  m0, b02: |00000000| delays: -
  m0, b03: |00000000| delays: -
  best: m0, b00 delays: 02+-01
  m1, b00: |01110000| delays: 02+-01
  m1, b01: |00000000| delays: -
  m1, b02: |00000000| delays: -
  m1, b03: |00000000| delays: -
  best: m1, b00 delays: 02+-01
Switching SDRAM to hardware control.
Memtest at 0x40000000 (2.0MiB)...
  Write: 0x40000000-0x40200000 2.0MiB
   Read: 0x40000000-0x40200000 2.0MiB
Memtest OK
Memspeed at 0x40000000 (Sequential, 2.0MiB)...
  Write speed: 13.6MiB/s
   Read speed: 23.4MiB/s

--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
No boot medium found

--============= Console ================--

litex> ident
Ident: LiteX SoC on ECPIX-5 2022-03-08 15:34:19
This commit is contained in:
Florent Kermarrec 2022-03-08 15:40:17 +01:00
parent 39e4e211bb
commit f52a915487
2 changed files with 126 additions and 8 deletions

View File

@ -1,7 +1,7 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2020-2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
@ -137,6 +137,20 @@ _io = [
Subsignal("data", Pins("M26 L25 L26 K25 K26 J23 P25 H25")),
IOStandard("LVCMOS33")
),
# HDMI / IT6613
("hdmi", 0,
Subsignal("r", Pins("AD26 AE25 AF25 AE26 E10 D11 D10 C10 D9 E8 H5 J4")),
Subsignal("g", Pins("AA23 AA22 AA24 AA25 E1 F2 F1 D17 D16 E16 J6 H6")),
Subsignal("b", Pins("AD25 AC26 AB24 AB25 B3 C3 D3 B1 C8 D2 D1 E3")),
Subsignal("de", Pins("A3")),
Subsignal("clk", Pins("C1")),
Subsignal("vsync", Pins("A4")),
Subsignal("hsync", Pins("B4")),
Subsignal("sda", Pins("E17")),
Subsignal("scl", Pins("C17")),
IOStandard("LVCMOS33")
),
]
# Connectors ---------------------------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2020-2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import os
@ -21,6 +21,8 @@ from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litex.soc.cores.video import VideoDVIPHY
from litex.soc.cores.bitbang import I2CMaster
from litedram.modules import MT41K256M16
from litedram.phy import ECP5DDRPHY
@ -78,8 +80,13 @@ class _CRG(Module):
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, device="85F", sys_clk_freq=int(75e6), with_ethernet=False,
with_etherbone=False, with_led_chaser=True, **kwargs):
def __init__(self, device="85F", sys_clk_freq=int(75e6),
with_ethernet = False,
with_etherbone = False,
with_video_terminal = False,
with_video_framebuffer = False,
with_led_chaser = True,
**kwargs):
platform = ecpix5.Platform(device=device, toolchain="trellis")
# SoCCore ----------------------------------------------------------------------------------
@ -114,6 +121,98 @@ class BaseSoC(SoCCore):
if with_etherbone:
self.add_etherbone(phy=self.ethphy)
# HDMI -------------------------------------------------------------------------------------
if with_video_terminal or with_video_framebuffer:
# PHY + IT6613 I2C initialization.
hdmi_pads = platform.request("hdmi")
self.submodules.videophy = VideoDVIPHY(hdmi_pads, clock_domain="init")
self.submodules.videoi2c = I2CMaster(hdmi_pads)
# I2C initialization adapted from https://github.com/ultraembedded/ecpix-5
# Copyright (c) 2020 https://github.com/ultraembedded
# Adapted from C to Python.
REG_TX_SW_RST = 0x04
B_ENTEST = (1<<7)
B_REF_RST = (1<<5)
B_AREF_RST = (1<<4)
B_VID_RST = (1<<3)
B_AUD_RST = (1<<2)
B_HDMI_RST = (1<<1)
B_HDCP_RST = (1<<0)
REG_TX_AFE_DRV_CTRL = 0x61
B_AFE_DRV_PWD = (1<<5)
B_AFE_DRV_RST = (1<<4)
B_AFE_DRV_PDRXDET = (1<<2)
B_AFE_DRV_TERMON = (1<<1)
B_AFE_DRV_ENCAL = (1<<0)
REG_TX_AFE_XP_CTRL = 0x62
B_AFE_XP_GAINBIT = (1<<7)
B_AFE_XP_PWDPLL = (1<<6)
B_AFE_XP_ENI = (1<<5)
B_AFE_XP_ER0 = (1<<4)
B_AFE_XP_RESETB = (1<<3)
B_AFE_XP_PWDI = (1<<2)
B_AFE_XP_DEI = (1<<1)
B_AFE_XP_DER = (1<<0)
REG_TX_AFE_ISW_CTRL = 0x63
B_AFE_RTERM_SEL = (1<<7)
B_AFE_IP_BYPASS = (1<<6)
M_AFE_DRV_ISW = (7<<3)
O_AFE_DRV_ISW = 3
B_AFE_DRV_ISWK = 7
REG_TX_AFE_IP_CTRL = 0x64
B_AFE_IP_GAINBIT = (1<<7)
B_AFE_IP_PWDPLL = (1<<6)
M_AFE_IP_CKSEL = (3<<4)
O_AFE_IP_CKSEL = 4
B_AFE_IP_ER0 = (1<<3)
B_AFE_IP_RESETB = (1<<2)
B_AFE_IP_ENC = (1<<1)
B_AFE_IP_EC1 = (1<<0)
REG_TX_HDMI_MODE = 0xC0
B_TX_HDMI_MODE = 1
B_TX_DVI_MODE = 0
REG_TX_GCP = 0xC1
B_CLR_AVMUTE = 0
B_SET_AVMUTE = 1
B_TX_SETAVMUTE = (1<<0)
B_BLUE_SCR_MUTE = (1<<1)
B_NODEF_PHASE = (1<<2)
B_PHASE_RESYNC = (1<<3)
self.videoi2c.add_init(addr=0x4c, init=[
# Reset.
(REG_TX_SW_RST, B_REF_RST | B_VID_RST | B_AUD_RST | B_AREF_RST | B_HDCP_RST),
(REG_TX_SW_RST, 0),
# Select DVI Mode.
(REG_TX_HDMI_MODE, B_TX_DVI_MODE),
# Configure Clks.
(REG_TX_SW_RST, B_AUD_RST | B_AREF_RST | B_HDCP_RST),
(REG_TX_AFE_DRV_CTRL, B_AFE_DRV_RST),
(REG_TX_AFE_XP_CTRL, 0x18),
(REG_TX_AFE_ISW_CTRL, 0x10),
(REG_TX_AFE_IP_CTRL, 0x0C),
# Enable Clks.
(REG_TX_AFE_DRV_CTRL, 0),
# Enable Video.
(REG_TX_GCP, 0),
])
# Video Terminal/Framebuffer.
if with_video_terminal:
self.add_video_terminal(phy=self.videophy, timings="640x480@75Hz", clock_domain="init")
if with_video_framebuffer:
self.add_video_framebuffer(phy=self.videophy, timings="640x480@75Hz", clock_domain="init")
# Leds -------------------------------------------------------------------------------------
if with_led_chaser:
leds_pads = []
@ -138,6 +237,9 @@ def main():
ethopts = parser.add_mutually_exclusive_group()
ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.")
ethopts.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support.")
viopts = parser.add_mutually_exclusive_group()
viopts.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (HDMI).")
viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (HDMI).")
builder_args(parser)
soc_core_args(parser)
@ -145,10 +247,12 @@ def main():
args = parser.parse_args()
soc = BaseSoC(
device = args.device,
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
device = args.device,
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
with_video_terminal = args.with_video_terminal,
with_video_framebuffer = args.with_video_framebuffer,
**soc_core_argdict(args)
)
if args.with_sdcard: