From 9e2ee0ee8d8a65bc14c2243cc69e8ad471da54b9 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 5 Aug 2018 11:00:35 +0100 Subject: [PATCH] add emmc to pinmux --- docs/AddingPeripherals.mdwn | 140 ++++++++++++++++++++++++++++++++++++ src/bsv/interface_decl.py | 1 + 2 files changed, 141 insertions(+) diff --git a/docs/AddingPeripherals.mdwn b/docs/AddingPeripherals.mdwn index 3aba0a7..359588f 100644 --- a/docs/AddingPeripherals.mdwn +++ b/docs/AddingPeripherals.mdwn @@ -919,6 +919,146 @@ by adding an emmc interface to Bank B: ps.flexbus2("", ('C', 0), 0) +We then need to generate the spec. At the top level the following command is +then run: + + $ python src/pinmux_generator.py -o i_class -s i_class + +Checking the resultant markdown file ./i\_class/i\_class.mdwn, we find that +several entries have been added at the required location: + +| Pin | Mux0 | Mux1 | Mux2 | Mux3 | +| --- | ----------- | ----------- | ----------- | ----------- | +| 28 | B GPIOB_B0 | B FB_AD2 | | B EMMC_CMD | +| 29 | B GPIOB_B1 | B FB_AD3 | | B EMMC_CLK | +| 30 | B GPIOB_B2 | B FB_AD4 | | B EMMC_D0 | +| 31 | B GPIOB_B3 | B FB_AD5 | | B EMMC_D1 | +| 32 | B GPIOB_B4 | B FB_AD6 | | B EMMC_D2 | +| 33 | B GPIOB_B5 | B FB_AD7 | | B EMMC_D3 | +| 34 | B GPIOB_B6 | B FB_CS0 | | B EMMC_D4 | +| 35 | B GPIOB_B7 | B FB_CS1 | | B EMMC_D5 | +| 36 | B GPIOB_B8 | B FB_ALE | | B EMMC_D6 | +| 37 | B GPIOB_B9 | B FB_OE | B FB_TBST | B EMMC_D7 | +| 38 | B GPIOB_B10 | B FB_RW | | | + +We also check i\_class/interfaces.txt to see if the single requested emmc +interface is there: + + gpiob 1 + eint 1 + mqspi 1 + emmc 1 <-- + uart 3 + +Also we examine the i\_class/emmc.txt file to check that it has the right +types of pin definitions: + + cmd out + clk out + d0 inout bus + d1 inout bus + d2 inout bus + d3 inout bus + d4 inout bus + d5 inout bus + d6 inout bus + d7 inout bus + +and we check the i\_class/pinmap.txt tab-separated file to see if it +contains the entries corresponding to the markdown table: + + 24 A 4 gpioa_a24 mspi1_ck jtag_tms mmc0_d0 + 25 A 4 gpioa_a25 mspi1_nss jtag_tdi mmc0_d1 + 26 A 4 gpioa_a26 mspi1_io0 jtag_tdo mmc0_d2 + 27 A 4 gpioa_a27 mspi1_io1 jtag_tck mmc0_d3 + 28 B 4 gpiob_b0 fb_ad2 emmc_cmd + 29 B 4 gpiob_b1 fb_ad3 emmc_clk + 30 B 4 gpiob_b2 fb_ad4 emmc_d0 + 31 B 4 gpiob_b3 fb_ad5 emmc_d1 + 32 B 4 gpiob_b4 fb_ad6 emmc_d2 + 33 B 4 gpiob_b5 fb_ad7 emmc_d3 + 34 B 4 gpiob_b6 fb_cs0 emmc_d4 + 35 B 4 gpiob_b7 fb_cs1 emmc_d5 + 36 B 4 gpiob_b8 fb_ale emmc_d6 + 37 B 4 gpiob_b9 fb_oe fb_tbst emmc_d7 + +This concludes this section as the purpose of the spec-generation side, +to create documentation and TSV files for the second phase, has been +fulfilled. Note that we did *not* declare in PinSpec that this +peripheral is to be added onto the fastbus, as by default peripherals +are added to a single AXI4-Lite interface. + +## Adding the code auto-generators. + +The next phase begins with adding class support to auto-generate the pinmux +code. Starting with the following command: + + $ python src/pinmux_generator.py -o i_class + +The first thing to do is look at i\_class/bsv\_src/pinmux.bsv, and search +for both PeripheralSideMMC and PeripheralSideEMMC. PeripheralSideMMC is +very short and compact: + + // interface declaration between MMC and pinmux + (*always_ready,always_enabled*) + interface PeripheralSideMMC; + interface Put#(Bit#(1)) cmd; + interface Put#(Bit#(1)) clk; + interface Put#(Bit#(4)) out; + interface Put#(Bit#(4)) out_en; + interface Get#(Bit#(4)) in; + endinterface + +whereas PeripheralSideEMMC is a mess: + + interface PeripheralSideEMMC; + interface Put#(Bit#(1)) cmd; + interface Put#(Bit#(1)) clk; + interface Put#(Bit#(1)) d0_out; + interface Put#(Bit#(1)) d0_outen; + interface Get#(Bit#(1)) d0_in; + interface Put#(Bit#(1)) d1_out; + interface Put#(Bit#(1)) d1_outen; + interface Get#(Bit#(1)) d1_in; + interface Put#(Bit#(1)) d2_out; + interface Put#(Bit#(1)) d2_outen; + interface Get#(Bit#(1)) d2_in; + ... + ... + endinterface + +To correct this, we need to create an InterfaceEMMC class in +src/bsv/interface\_decl.py that generates the right code. However on +close inspection, given that the format needed is identical (except for +the number of data lines), we can probably get away with using *exactly* +the same class: + + class Interfaces(InterfacesBase, PeripheralInterfaces): + + def __init__(self, pth=None): + InterfacesBase.__init__(self, Interface, pth, + {'gpio': InterfaceGPIO, + ... + ... + 'mmc': InterfaceSD, + 'emmc': InterfaceSD, <-- + 'fb': InterfaceFlexBus, + ... + +and after re-running the command the output looks like this: + + interface PeripheralSideEMMC; + interface Put#(Bit#(1)) cmd; + interface Put#(Bit#(1)) clk; + interface Put#(Bit#(8)) out; + interface Put#(Bit#(8)) out_en; + interface Get#(Bit#(8)) in; + endinterface + +Success! The class InterfaceSD appears to be sufficiently generic that +it could understand that it had been passed 8-pins worth of data with +exactly the same names, rather than 4. This is encouraging in the sense +that re-using the SD/MMC BSV generation code should also be as easy. # Conclusion diff --git a/src/bsv/interface_decl.py b/src/bsv/interface_decl.py index afc7be9..cf774d6 100644 --- a/src/bsv/interface_decl.py +++ b/src/bsv/interface_decl.py @@ -631,6 +631,7 @@ class Interfaces(InterfacesBase, PeripheralInterfaces): 'mspi': InterfaceNSPI, 'lcd': InterfaceLCD, 'mmc': InterfaceSD, + 'emmc': InterfaceSD, 'fb': InterfaceFlexBus, 'sdr': InterfaceSDRAM, 'qspi': InterfaceNSPI, -- 2.30.2