Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

framework_inputmodule: Add new rp2040 based board #8233

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

JohnAZoidberg
Copy link

@JohnAZoidberg JohnAZoidberg commented Jul 29, 2023

I'm just experimenting with circuitpython and I thought it would be fun to add support for our upcoming keyboard and LED matrix modules.

One thing I can't figure out is how to get the CIRCUITPY drive to pop up.
So far I'm only able to interact using the repl. It works to turn on the capslock LED and PWM backlight brightness.

Hardware: https://github.com/FrameworkComputer/inputmodules

Comment on lines 4 to 23
//#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)

// External flash W25Q80DV
#define EXTERNAL_FLASH_QSPI_DUAL
#if QSPI_FLASH_FILESYSTEM
//#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 00)
//#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21)
//#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22)
//#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23)
//#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19)
//#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20)
#endif

#define CIRCUITPY_DRIVE_LABEL "CIRCUITPY"
#define CIRCUITPY_BOOT_COUNTER 1
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (0x4000)

#define BOARD_HAS_CRYSTAL 1

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
//#define BOARD_FLASH_SIZE (FLASH_SIZE - 0x4000 - CIRCUITPY_INTERNAL_NVM_SIZE)
// External flash W25Q80DV
#define EXTERNAL_FLASH_QSPI_DUAL
#if QSPI_FLASH_FILESYSTEM
//#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 00)
//#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 21)
//#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 22)
//#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 23)
//#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19)
//#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20)
#endif
#define CIRCUITPY_DRIVE_LABEL "CIRCUITPY"
#define CIRCUITPY_BOOT_COUNTER 1
#define FLASH_SIZE (0x100000)
#define FLASH_PAGE_SIZE (0x4000)
#define BOARD_HAS_CRYSTAL 1

You can delete all this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look at other existing RP2040 boards, such as KB2040 and QT Py RP2040.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially I copied it from the QT Py RP2040. But the flash chip is different. So that config won't even run.
Once I change the flash chip description to the correct one, it runs but there's no folder.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do other boards show CIRCUITPY? (Just making sure there's nothing weird about your host system.)

Do take away the lines above; they are for an nRF board, and maybe some other things, not RP2040. Your mpconfigboard.h should look at a lot the Feather or QT Py RP2040.

You can try re-creating CIRCUITPY from the REPL:

import storage
storage.erase_filesystem()

but I'm thinking there might be something else wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the W25Q80DV chip is 8Mbit = 1 megabyte.

By default, CircuitPython allocates the first 1MB for the firmware and the remaining portion for the CIRCUITPY drive. In this case, that means there's no left over space, so the CIRCUITPY drive can't be formatted or mounted.

You can check out the raspberry pi pico w board definition for how to change this default. That board allocates a LARGER space for the firmware. You would try allocating LESS such as 900*1024 (900k), as the size of the english-language raspberry pi pico circuitpython firmware seems to be about 804kB at the moment.

(if your hardware design is not finalized, I'd urge you to consider upgrading to a 16Mbit / 2MByte flash part if possible)

here are the relevant bits from ports/raspberrypi/boards/raspberry_pi_pico_w:
mpconfigboard.mk:

# Must be accompanied by a linker script change
CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)'

link.ld:

firmware_size = 1532k;

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do other boards show CIRCUITPY? (Just making sure there's nothing weird about your host system.)

Yep. QT Py 2040 works.

By default, CircuitPython allocates the first 1MB for the firmware and the remaining portion for the CIRCUITPY drive. In this case, that means there's no left over space, so the CIRCUITPY drive can't be formatted or mounted.

Ohh thanks. Yeah that must be it. Currently our flash size is only 1M. I'll try it later.

It's not really a dev board, so it's not a priority to run circuitpython. But we want to enable users to write their own firmware. We'll take it into consideration.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The boards are not meant for general purpose IO, so we don't need many of the circuitpy modules.
I removed a bunch of them to get the fw size below 512K. Now there's plenty of space for the CIRCUITPY drive and it does work!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can I also limit the maximum size of the CIRCUITPY drive? It doesn't seem quite as straight forward. And the code comments say it expects at least 2M of flash to work.
My reason is that we put the serial number in the last sector of flash 1M-4096B. We'll lock this sector but I'm afraid the circuitpy drive might not handle this properly.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do this for the Teensy 4.x as well. I think we use a linker script setting there. On RP2040 we'll likely want a compile time option because RP2040 CP detects flash size automatically.

If you need a tester, I'm very interested in a Framework laptop. :-)

Signed-off-by: Daniel Schaefer <dhs@frame.work>
Signed-off-by: Daniel Schaefer <dhs@frame.work>
Memory region         Used Size  Region Size  %age Used
  FLASH_FIRMWARE:      472304 B       512 KB     90.08%
             RAM:       45952 B       256 KB     17.53%
       SCRATCH_Y:          0 GB         4 KB      0.00%
       SCRATCH_X:          2 KB         4 KB     50.00%

Signed-off-by: Daniel Schaefer <dhs@frame.work>
@@ -0,0 +1,64 @@
USB_VID = 0x32AC
USB_PID = 0x0013
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: I think I want to rename the board and use a different PID.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to draft.

@dhalbert dhalbert marked this pull request as draft August 2, 2023 12:19
@JohnAZoidberg JohnAZoidberg changed the title fwk_keyboard: Add new rp2040 based board framework_inputmodule: Add new rp2040 based board Aug 9, 2023
@@ -99,11 +99,15 @@ void port_internal_flash_flush(void) {
// Make sure we don't have an interrupt while we do flash operations.
common_hal_mcu_disable_interrupts();
// and audio DMA must be paused as well
#if CIRCUITPY_AUDIOCORE
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a separate PR for this: #8271

@jepler
Copy link
Member

jepler commented Aug 9, 2023

I don't know how durable your "serial number in flash" concept will be, but it doesn't mean it's not worth trying. For instance, we advise folks that in extreme circumstances they can run a program that erases all flash content: https://learn.adafruit.com/adafruit-feather-rp2040-pico/circuitpython#flash-resetting-uf2-3091244 (this is nuke.c from pico-examples, I think)

at a guess you'll at least need to revise these two in raspberrypi/supervisor/internal_flash.c

Probably fix by defining TOTAL_FLASH_MINIMUM as 1024*1024-4096 in mpconfigboard.mk:

#if !defined(TOTAL_FLASH_MINIMUM)
#define TOTAL_FLASH_MINIMUM (2 * 1024 * 1024)
#endif

Probably fix by introducing a new constant, defined to 0 in mpconfigport.h if not otherwise defined, and defined to 4096 in your board, and subtracting it from _flash_size:

uint32_t supervisor_flash_get_block_count(void) {
    return (_flash_size - CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR) / FILESYSTEM_BLOCK_SIZE;
}

@dhalbert
Copy link
Collaborator

dhalbert commented Aug 9, 2023

The RP2040, as you know, doesn't have a unique serial number. However, some or all of the external flash chips do:
https://stackoverflow.com/questions/72594333/arduino-rp2040-pico-unique-id
https://forums.raspberrypi.com/viewtopic.php?t=331910
etc.

So you can use that instead, and other people have done so. And it won't be erased by the nuke UF2. (And you won't need the extra settings above.)

@dhalbert
Copy link
Collaborator

dhalbert commented Aug 9, 2023

CircuitPython can access the flash UID by microcontroller.cpu.uid: https://docs.circuitpython.org/en/latest/shared-bindings/microcontroller/index.html#microcontroller.Processor.uid

The code we use to fetch it is here:

void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
pico_unique_board_id_t retrieved_id;
pico_get_unique_board_id(&retrieved_id);
memcpy(raw_id, retrieved_id.id, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH);
}
:

@jepler jepler added the board New board or update to a single board label Aug 22, 2023
@dhalbert
Copy link
Collaborator

dhalbert commented Jul 2, 2024

@JohnAZoidberg Hi - is this project still in process?

{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO26) },
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO27) },

{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
// Add GP6 and GP7
{ MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) },
{ MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) },
// KSO Pins (Key Scan Output)
{ MP_ROM_QSTR(MP_QSTR_KSO0), MP_ROM_PTR(&pin_GPIO8) },
{ MP_ROM_QSTR(MP_QSTR_KSO1), MP_ROM_PTR(&pin_GPIO9) },
{ MP_ROM_QSTR(MP_QSTR_KSO2), MP_ROM_PTR(&pin_GPIO10) },
{ MP_ROM_QSTR(MP_QSTR_KSO3), MP_ROM_PTR(&pin_GPIO11) },
{ MP_ROM_QSTR(MP_QSTR_KSO4), MP_ROM_PTR(&pin_GPIO12) },
{ MP_ROM_QSTR(MP_QSTR_KSO5), MP_ROM_PTR(&pin_GPIO13) },
{ MP_ROM_QSTR(MP_QSTR_KSO6), MP_ROM_PTR(&pin_GPIO14) },
{ MP_ROM_QSTR(MP_QSTR_KSO7), MP_ROM_PTR(&pin_GPIO15) },
// Additional KSO pins
{ MP_ROM_QSTR(MP_QSTR_KSO8), MP_ROM_PTR(&pin_GPIO21) },
{ MP_ROM_QSTR(MP_QSTR_KSO9), MP_ROM_PTR(&pin_GPIO20) },
{ MP_ROM_QSTR(MP_QSTR_KSO10), MP_ROM_PTR(&pin_GPIO19) },
{ MP_ROM_QSTR(MP_QSTR_KSO11), MP_ROM_PTR(&pin_GPIO18) },
{ MP_ROM_QSTR(MP_QSTR_KSO12), MP_ROM_PTR(&pin_GPIO17) },
{ MP_ROM_QSTR(MP_QSTR_KSO13), MP_ROM_PTR(&pin_GPIO16) },
{ MP_ROM_QSTR(MP_QSTR_KSO14), MP_ROM_PTR(&pin_GPIO23) },
{ MP_ROM_QSTR(MP_QSTR_KSO15), MP_ROM_PTR(&pin_GPIO22) },
// MUX pins (Multiplexer control)
{ MP_ROM_QSTR(MP_QSTR_MUX_ENABLE), MP_ROM_PTR(&pin_GPIO4) },
{ MP_ROM_QSTR(MP_QSTR_MUX_A), MP_ROM_PTR(&pin_GPIO1) },
{ MP_ROM_QSTR(MP_QSTR_MUX_B), MP_ROM_PTR(&pin_GPIO2) },
{ MP_ROM_QSTR(MP_QSTR_MUX_C), MP_ROM_PTR(&pin_GPIO3) },
{ MP_ROM_QSTR(MP_QSTR_BOOT_DONE), MP_ROM_PTR(&pin_GPIO5) },

Adding in the missing changes I believe are necessary to get the board working from FrameworkComputer/Framework_Inputmodule_CircuitPython#2 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
board New board or update to a single board
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants