adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
439 stars 328 forks source link

Pin numbers for Rock 4C Plus not available #656

Closed MathijsNL closed 1 year ago

MathijsNL commented 1 year ago

I am using the library on a Rock 4C Plus. I am trying to use GPIO 73 and 74 (pin 31 and 29)

Blinka version = '8.15.2' Python version = 3.8.10 OS = Ubuntu 20.04 arm64

>>> board.board_id
'ROCK_PI_4C+'

Pin assignment:

outPin = board.B1
AttributeError: module 'board' has no attribute 'B1'

As I understand the mapping is available here: https://github.com/adafruit/Adafruit_Blinka/blob/main/src/adafruit_blinka/microcontroller/rockchip/rk3399/pin.py#L24-L25

My assumption is that I need to use pin board.B1 and board.B2, but they don't show up. All available pins are shown below:

board.ADC_IN0   board.D27       board.D8        board.SDA7
board.CS        board.D28       board.I2C(      board.SPI(
board.D10       board.D29       board.MISO      board.UART2_RX
board.D11       board.D3        board.MOSI      board.UART2_TX
board.D12       board.D31       board.PWM0      board.UART4_RX
board.D13       board.D32       board.SCK       board.UART4_TX
board.D15       board.D33       board.SCL       board.UART_RX
board.D16       board.D35       board.SCL2      board.UART_TX
board.D18       board.D36       board.SCL6      board.ap_board
board.D19       board.D37       board.SCL7      board.board_id
board.D21       board.D38       board.SCLK      board.detector
board.D22       board.D40       board.SDA       board.pin
board.D23       board.D5        board.SDA2      board.sys
board.D24       board.D7        board.SDA6

board.pin
<module 'adafruit_blinka.microcontroller.rockchip.rk3399_t.pin' from '/home/rock/.local/lib/python3.8/site-packages/adafruit_blinka/microcontroller/rockchip/rk3399_t/pin.py'

@wgroeneveld Tagging you if you don't mind. Do you happen to know what the problem is?

makermelissa commented 1 year ago

It's likely related to this: https://github.com/adafruit/Adafruit_Blinka/pull/651#issuecomment-1439630083, meaning the pinout is was added incorrectly for your board. I'm guessing your board is a production board (the one that was used to figure out the pinout wasn't), so maybe with your help, we could get it working (hopefully with both versions). If we can't get it working with both versions, I'd prefer the production board be the one that works.

MathijsNL commented 1 year ago

I can confirm my 4C+ is version 1.2.

Will see what I can do about the mapping and board version detection.

Edit: @makermelissa Do you have any tips on how to change the pin.py to test the different GPIOS?

What I don't get is for example pin 73 and 74 are defined but they don't show up in the board info:

GPIO2_B1 = Pin(73)
GPIO2_B2 = Pin(74)
makermelissa commented 1 year ago

My best tips are in this guide: https://learn.adafruit.com/adding-a-single-board-computer-to-blinka

MathijsNL commented 1 year ago

Just documenting things in here for reference.

Edit: about 35% of all the lines can be controlled directly, for the missing pins it is probably needed to disable UART/I2C/SPI Edit2: it was the other way around, UART/I2C/SPI had to be enabled in order to control the pins. Only missing about 2 or 3 pins now.

@makermelissa when adding pins do I have to specify the chipnumber and line number? In some of the files there is a single number for most pins and for some others it has 2. Or is there a way to convert chip and line number to one number? (Nevermind figured it out, gpiochip number * 32 + line number).

MathijsNL commented 1 year ago

Almost there I guess, just a few questions remaining:

If there is a way to distinguish between ROCK_PI_4_C_PLUS < 1.2 and ROCK_PI_4_C_PLUS > 1.2 I think this is probably the place to add it?

elif board_id == ap_board.ROCK_PI_4_C_PLUS:
    if check_4cplus_version() >= 1.2:
        from adafruit_blinka.board.radxa.rockpi4cplus import *
    else:
        from adafruit_blinka.board.radxa.rockpi4cplus_legacy import *

In the end it really was not needed to test each pin with a LED, but I think the extra confirmation won't hurt.

makermelissa commented 1 year ago

Hi, board detection is handled by https://github.com/adafruit/Adafruit_Python_PlatformDetect

I have a guide for that as well here: https://learn.adafruit.com/adding-a-single-board-computer-to-platformdetect-for-blinka

As for the SPI question, I'm not that familiar with the ROCK Pi boards. SPI isn't usually hooked to TX, which is for the Serial UART. Usually it's connected to SCK, MOSI, MISO, and CE. However, some board allow pins to have multiple modes, so if the TX pin can function as one of the SPI pins, then that may be the case that you would hook it up there.

I think having a legacy option like you proposed would be a good way to do it.

MathijsNL commented 1 year ago

Thanks for linking the info about Platformdetect. Will try to do that over the weekend.

In the meantime I forked the Blinka repo and made the required changes to the board and pin file.

https://github.com/MathijsNL/Adafruit_Blinka/commits?author=MathijsNL

A few questions remain:

I think the RK3399 platform is also using an older pin mapping but I will finish this issue first and then look into that in a separate issue.

makermelissa commented 1 year ago
  • Should board file aliases point to the first occurrence of a function? So if SPI1 and SPI2 are available it should point to 1?

I usually do whatever is likely to be enabled by default. If both, then just whatever matches best with the Raspberry Pi pinout (see https://pinout.xyz/).

  • Can I do a PR for the board and pin file changes if the files are according to Radxa specs, or do the files require checking with hardware?

Since I don't have any hardware to verify, it would be awesome if you could at least check some of the pins to make sure you're on track. That way somebody doesn't go to use it and is disappointed if nothing works.

  • It seems Radxa has the same pin layout and GPIO numbering for the complete Rock4 series. Is it preferred for each platform to have their own pin file, or can they share a single pin file if they are exactly the same?

Yes, they can share a pin file (and even a board file if applicable). We did that on some of the other microcontrollers and boards.

I think the RK3399 platform is also using an older pin mapping but I will finish this issue first and then look into that in a separate issue.

Awesome. Thanks for your help.

MathijsNL commented 1 year ago

I usually do whatever is likely to be enabled by default.

Sounds logical, I will check it like that.

if you could at least check some of the pins

I will try to do a simple IO test for digital outputs on all the pins with a led and test the UART. I think that should be a good starting point.

Yes, they can share a pin file (and even a board file if applicable).

That is nice, I have a Rock4B+ and a Rock4C+ available for testing so this could go very quick once the 4C+ is fixed.

MathijsNL commented 1 year ago

To test the GPIOs I made this streamlit app that will show the status of each GPIO Streamlit gist

I am not too sure about how the Rock GPIOs should work, but I needed a pull down resistor on most pins. With all pins in INPUT mode there are a lot of pins still showing True. It seems that it is not possible to set pull up / down on the GPIOs.

Good news is that all the pins are working both as output and input. Only D26 is not working as expected yet, but it is also not documented by Radxa it seems.

Value   Pin# L Pin# R Value R _
- D1 D2 -
True D3 D4 -
True D5 D6 -
True D7 D8 True
- D9 D10 True
False D11 D12 True
False D13 D14 -
False D15 D16 False
- D17 D18 False
True D19 D20 -
True D21 D22 False
True D23 D24 True
- D25 D26 -
True D27 D28 True
True D29 D30 -
True D31 D32 True
True D33 D34 -
True D35 D36 -
False D37 D38 True
- D39 D40 True
makermelissa commented 1 year ago

Oh, that's a really cool way to do it. That's fine if you can't get all of the inputs working. Some of the boards just work like that and do require a pull up or pull down resistor.. At least since they are all working as outputs, you know they are mapped correctly, which was my main concern.

Gerriko commented 1 year ago

Is it possible to expand the pin definitions to explain use for SPI, I2C and UART. I ran one of the Blinka GPIO examples and it spits this useful table out for me:

hello blinka! Found system type: ROCK_PI_4C+ (sys.platform linux implementation cpython) board contents: ['ADC_IN0', 'CS', 'D10', 'D11', 'D12', 'D13', 'D15', 'D16', 'D18', 'D19', 'D21', 'D22', 'D23', 'D24', 'D27', 'D28', 'D29', 'D3', 'D31', 'D32', 'D33', 'D35', 'D36', 'D37', 'D38', 'D40', 'D5', 'D7', 'D8', 'I2C', 'MISO', 'MOSI', 'PWM0', 'PWM1', 'SCK', 'SCL', 'SCL2', 'SCL6', 'SCL7', 'SCLK', 'SDA', 'SDA2', 'SDA6', 'SDA7', 'SPI', 'UART2_RX', 'UART2_TX', 'UART4_RX', 'UART4_TX', 'UART_RX', 'UART_TX', 'blinka', 'builtins', 'cached', 'doc', 'file', 'loader', 'name', 'package', 'repo', 'spec', 'version', 'ap_board', 'board_id', 'detector', 'pin', 'sys']

I then tried running the PN532 example for Blinka but it throws an error because of the use of board.xxxx pin definitions:

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)

Maybe we need some sort of pin definition file for the Rock4 to be able to handle these examples without error.

PS. Just to confirm that if I use the appropriate Dxx pin numbers for SCK, MOSI and MISO, the PN532 example works.

makermelissa commented 1 year ago

@Gerriko make sure you have SPI enabled. Part of the issue is that Blinka was built to kind of emulate the basic CircuitPython modules and it typically only has a single I2C and SPI port (with the exception of boards like the pico where it's configurable). To easily get around this limitation, we have the Extended Bus library here: https://github.com/adafruit/Adafruit_Python_Extended_Bus. It allows you to easily use any /dev/spidexX.X devices by directly initializing them and faking anything the base system thinks it needs. It also works for I2C in the same manner.

Gerriko commented 1 year ago

I have just discovered the reason for my SPI error noted above. In the boards file for the Rock4 (https://github.com/adafruit/Adafruit_Blinka/blob/main/src/adafruit_blinka/board/radxa/rockpi4.py) the pin assignments are incorrect for SPI:

SCLK should be D23 and not D19 MOSI should be D19 and not D21 MISO should be D21 and not D23

MathijsNL commented 1 year ago

@Gerriko Thanks for spotting this error. I made a PR for it.

makermelissa commented 1 year ago

Fixed by #674.