Libre RISC-V Mailing list Archives (accessible via public-inbox)
 help / color / Atom feed
From: Luke Kenneth Casson Leighton <lkcl@lkcl.net>
To: Libre-RISCV General Development <libre-riscv-dev@lists.libre-riscv.org>
Subject: [libre-riscv-dev] pinmux to generate interfaces (with no pinmux)
Date: Sat, 9 May 2020 10:59:13 +0100
Message-ID: <CAPweEDyYQ7KxxQnT1duphfjV94Zwh2xO50rDeoWp9ZTQ=VjxFA@mail.gmail.com> (raw)
In-Reply-To: <CAPweEDwwi_xMFa+DnTEpvwd-LbF6ebA2=dd_RtsGDVQH5CnLQg@mail.gmail.com>

transferring this to the list

https://git.libre-soc.org/?p=pinmux.git


On Sat, May 9, 2020 at 9:41 AM Luke Kenneth Casson Leighton
<lkcl@lkcl.net> wrote:
>
> $ python ./src/pinmux_generator.py -s i_class -v -o i_class
> $ python ./src/pinmux_generator.py  -v -o i_class
>
> then ignore the bsv_src and examine i_class.mdwn.

same for minitest and microtest.

note: for EINT, GPIO and PWM because its naming is a different
convention (auto-repeated numbering of a single function - PWM0, PWM1,
PWM2) you do *not* specify the 1st argument.

   ps.gpio("", ('A', 1), 0, 0, 3)

NOT  ps.gpio("A", ('A', 1), 0, 0, 3)
or    ps.gpio("0", ('A', 1), 0, 0, 3)

this means "add GPIOA" starting from position 1, starting from
numbering 0 (GPIOA_A0..), and add 3 of them.  result:

## Bank A (3 pins, width 4)

| Pin | Mux0        | Mux1        | Mux2        | Mux3        |
| --- | ----------- | ----------- | ----------- | ----------- |
|   0 |             | A UART0_TX  |             |             |
|   1 | A GPIOA_A0  | A UART0_RX  | A TWI0_SDA  |             |
|   2 | A GPIOA_A1  | A UART1_TX  | A TWI0_SCL  |             |
|   3 | A GPIOA_A2  | A UART1_RX  |             | A TWI0_SDA  |



ps.gpio("", ('A', 0), 0, 1, 3)

this means "start numbering from 1" (GPIOA_A1/2/3)

result:

## Bank A (3 pins, width 4)

| Pin | Mux0        | Mux1        | Mux2        | Mux3        |
| --- | ----------- | ----------- | ----------- | ----------- |
|   0 | A GPIOA_A1  | A UART0_TX  |             |             |
|   1 | A GPIOA_A2  | A UART0_RX  | A TWI0_SDA  |             |
|   2 | A GPIOA_A3  | A UART1_TX  | A TWI0_SCL  |             |
|   3 |             | A UART1_RX  |             |             |


unfortunately you can't place GPIO pins in Mux1, Mux2 or Mux3 columns
(i just tried) - this is undesirable anyway because you *want* GPIO to
be in the Mux0 column.


however you _can_ place uart, i2c etc. in Mux0:

    ps.uart("0", ('A', 0), 0)   <=== Mux0 column
    ps.uart("1", ('A', 2), 1)   <=== Mux1 column

result:

## Bank A (3 pins, width 4)

| Pin | Mux0        | Mux1        | Mux2        | Mux3        |
| --- | ----------- | ----------- | ----------- | ----------- |
|   0 | A UART0_TX  |             |             |             |
|   1 | A UART0_RX  |             | A TWI0_SDA  |             |
|   2 |             | A UART1_TX  | A TWI0_SCL  |             |
|   3 |             | A UART1_RX  |             | A TWI0_SDA  |


so we will want something like:

def pinspec():
    pinbanks = {
        'A': (10, 1), <<<--- only one column (no pinmux, effectively)
    }
   ....
   ....
    ps.gpio("", ('A', 0), 0, 0, 3)  # 3 pins, bank A row 0+1+2, starting in col0
    ps.uart("0", ('A', 4), 0)        # UART0 in bank A row 4+5, col0
    ps.uart("1", ('A', 6), 0)        # UART1 in bank A row 6+7, col0
    ps.i2c("0", ('A', 8), 0)         # TWI0 in bank A row 8+9, col0

which will generate this:

## Bank A (10 pins, width 1)

| Pin | Mux0        | Mux1        | Mux2        | Mux3        |
| --- | ----------- | ----------- | ----------- | ----------- |
|   0 | A GPIOA_A0  |
|   1 | A GPIOA_A1  |
|   2 | A GPIOA_A2  |
|   4 | A UART0_TX  |
|   5 | A UART0_RX  |
|   6 | A UART1_TX  |
|   7 | A UART1_RX  |
|   8 | A TWI0_SDA  |
|   9 | A TWI0_SCL  |

ignore the extra headings they are just a "print" statement, hard-coded.


test scenarios are specified with ps.add_scenario().  for each
"customer scenario" add what interfaces are desired by the customer,
and the add_scenario() function will *automatically go hunting for
that interface*.

in a multiplexed design this allows you to make damn sure that *ALL*
scenarios are covered by the chip.  design something that's not going
to cover a potential (or actual) customer's requirements and you just
wasted USD $20 million.

the usefulness of the add_scenario() function in our case is the
auto-generation of the documentation (markdown file) which "describes"
the customer scenario in its own section.


there's plenty of examples (c_class, i_class, minitest, microtest) -
just bear in mind *move slowly and incrementally*.  add just the one
function at a time, or start straight away from minitest or something.

btw *sigh* you'll need to add the new spec actually to src/spec/__init__.py:
from spec import m_class
from spec import c_class
from spec import i_class
from spec import minitest
from spec import microtest
from spec.gen import specgen
from spec.testing import dummytest

modules = {'m_class': m_class,
           'c_class': c_class,
           'i_class': i_class,
           'minitest': minitest,
           'microtest': microtest
           }


adding a new pinfunction is in src/spec/pinfunctions.py:

note that each interface function returns *two* lists:

* list of all pins (including those below)
* list of pins that are part of a bi-directional bus under the control
of a "direction" pin

note therefore that ulpi() has a bug :)

def ulpi(suffix, bank):
    ulpipins = ['CK+', 'DIR+', 'STP+', 'NXT+']
    for i in range(8):
        ulpipins.append('D%d*' % i)
    return (ulpipins, [])

should be similar to nspi and emmc.


basically, to add LPC as an interface, cookie-cut cut/paste emmc or nspi.

oh - it uses python2, and it's fine that way (there's nothing special
about it), so please don't spend time converting it to python3, it'll
take too long.

l.

_______________________________________________
libre-riscv-dev mailing list
libre-riscv-dev@lists.libre-riscv.org
http://lists.libre-riscv.org/mailman/listinfo/libre-riscv-dev

           reply index

Thread overview: expand[flat|nested]  mbox.gz  Atom feed
 [parent not found: <CAPweEDwwi_xMFa+DnTEpvwd-LbF6ebA2=dd_RtsGDVQH5CnLQg@mail.gmail.com>]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAPweEDyYQ7KxxQnT1duphfjV94Zwh2xO50rDeoWp9ZTQ=VjxFA@mail.gmail.com' \
    --to=lkcl@lkcl.net \
    --cc=libre-riscv-dev@lists.libre-riscv.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Libre RISC-V Mailing list Archives (accessible via public-inbox)

Archives are clonable: git clone --mirror https://inbox.libre-soc.org/libre-riscv-dev

Example config snippet for mirrors


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git