renesas-ra/boards/WEACT_RA4M1_CORE: Add board profile.
Summary
Adds renesas port board profile for WeAct RA4M1 CORE board.
As described in https://github.com/WeActStudio/WeActStudio.RA4M1_64Pin_CoreBoard and available for purchase from the likes of https://www.aliexpress.com/item/1005006103872563.html
The board and peripherals have been configured with Renesas FSP Smart Configurator v4.4.0 and it was originally based on the existing EK_RA4M1 board.
Testing
With the latest changes the USB port works via standard TinyUSB integration.
mpremote and repl also works to the uart wired up to the debug port.
I've left this PR as two separate commits showing with internal clock configuration and then updated to use the external xtal. The internal one was easier to get going so might serve as a useful example in future.
@robert-hh I've attempted to get my WeAct board going with USB but it's not working yet - shared here for reference however.
To compare, here's my modified to enable USB copy of the EK_RA4W1 board profile which does work with native USB once a suitable cable has been made and connected to the right pins.
I managed to set the clock using the 16Mhz crystal by setting the divider=2, multiply=6. It seems that this combination cannot be set using the smart configurator. config file bsp_clock_cfg.h below. I tried div=4, mul=12 as well, but that did not work.
I see that you use LFS1 for the file system. But there is not startup code to initialize the fs for LFS1. At least I did not find it. If it exists, it will be used. But how did you create the file system?
/* generated configuration header file - do not edit */
#ifndef BSP_CLOCK_CFG_H_
#define BSP_CLOCK_CFG_H_
#define BSP_CFG_CLOCKS_SECURE (0)
#define BSP_CFG_CLOCKS_OVERRIDE (0)
#define BSP_CFG_XTAL_HZ (16000000) /* XTAL 16000000Hz */
#define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */
#define BSP_CFG_HOCO_FREQUENCY (0) /* HOCO 24MHz */
#define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL Div /2 */
#define BSP_CFG_PLL_MUL BSP_CLOCKS_PLL_MUL(6U, 0U) /* PLL Mul x6 */
#define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* Clock Src: PLL */
#define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */
#define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKA Div /1 */
#define BSP_CFG_PCLKB_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* PCLKB Div /2 */
#define BSP_CFG_PCLKC_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKC Div /1 */
#define BSP_CFG_PCLKD_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKD Div /1 */
#define BSP_CFG_FCLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_2) /* FCLK Div /2 */
#define BSP_CFG_CLKOUT_SOURCE (BSP_CLOCKS_CLOCK_DISABLED) /* CLKOUT Disabled */
#define BSP_CFG_CLKOUT_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* CLKOUT Div /1 */
#define BSP_CFG_UCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* UCLK Src: PLL */
#endif /* BSP_CLOCK_CFG_H_ */
@andrewleech I tried to build your PR in the usual renesas-ra build environment, but no lock. I get tons of errors, starting with:
In file included from ../../lib/fsp/ra/fsp/inc/api/bsp_api.h:32,
from ./RA4M1_hal.h:32,
from ./mpconfigboard_common.h:32,
from ./mpconfigport.h:34,
from ../../py/mpconfig.h:91,
from ../../py/mpstate.h:31,
from ../../py/mpstate.c:27:
boards/WEACT_RA4M1_CORE/ra_cfg/fsp_cfg/bsp/bsp_cfg.h:4: error: unterminated #ifdef
4 | #ifdef __cplusplus
Edit: It the file boards/WEACT_RA4M1_CORE/ra_cfg/fsp_cfg/bsp/bsp_cfg.h which is incomplete, and more. So better check the status of the uploaded files. Or push the again. Something may be wrong on github.
I managed to set the clock using the 16Mhz crystal by setting the divider=2, multiply=6. It seems that this combination cannot be set using the smart configurator.
Oh interesting, I saw that in your files and assumed it was a typo when I couldn't select it in the configurator tool. I'll give it a go and if it fixes the issue it'll be worth a bug report to renesas!
I didn't mean to enable LFS1 it was supposed to be LFS2, I'll fix that. The filesystem wasn't actually working but I hadn't bothered fixing it yet. Should have mentioned as such in the top post :-)
Oh interesting, I saw that in your files and assumed it was a typo when I couldn't select it in the configurator tool. I'll give it a go and if it fixes the issue it'll be worth a bug report to renesas!
The strange thing is: The data sheet say 8 to 31 for the PLL multiplicator. But I had chosen 2/6 without looking into the data sheet, and it worked. While 4/12 did not. But 4/12 is a conflict with another part of the PLL table 8.1, where div by 4 only can be used for output frequencies up to 32Mhz. With 2/8 the output frequency is 64 MHz. The MCU works at the speed. So it may be worth to check, whether the UART and USB clock section can be set to work with 64 MHz. While an internal PLL output frequency before division of 96MHz (6 * 16) is well within specs of table 8.1, the input of 16Mhz for the PLL section is not. In table 8.1 the upper limit for PLL input is 12.5 MHz. So the Weact Board design is outside the specs.-
I didn't mean to enable LFS1 it was supposed to be LFS2, I'll fix that. The filesystem wasn't actually working but I hadn't bothered fixing it yet. Should have mentioned as such in the top post :-)
I used LFS1 because the code size is way smaller and the file system itself is small. Expecting #8381 to be merged soon, I wanted to keep as much as possible flash size for the ROMFS. Note that even if the current RA firmware uses an LFSx file system if it exists, there is no C-Code to create one if it's missing. That is done only for FAT. Because of that I made the PR to expose the Flash block device to Python. Then, Python code e.g. in a _boot.py script can be used instead. see #16381. The sample script there also support FAT. As the next step the startup support C code for FAT can be dropped, and the check for the boot mode can be moved to _boot.py as well.
Edit: Please upload the PR files again. On github the files are corrupted and the firmware cannot be built.
I raised an issue at the WEACT repository for this board about the crystal frequency. It definitely does not change existing boards, but maybe it's a help for people running into a problem.
Oh geez the clock circuits in this MCU are rather confusing and limiting.
So it says it accepts an internal xtal up to 20mhz, at 5v. Input voltage of 2.4v only supports up to 8mhz. Not sure quite what that means for 3.3v input.
The pll only allows input between 4 and 12.5mhz
The USB clock only allows running at 48mhz and I'm pretty sure it doesn't have any kind of mult/div of it's own.
Oh, and down further in the USB clock selection register section it says you can only use HOCO input to USB for device mode, not for OTG/Host. That shouldn't matter for us though at this point, however I was actually planning on starting work on basic host mode support tomorrow for TinyUSB.
So yes I'd say you're right that weact have made a tricky selection of 16mhz xtal, while it looks like it should be fine when you read the first spec line (xtal up to 20mhz) the devil of the detail looks like it really can't be used in practice.
The PLL looks strange. I would have expected the /2 /4 divider at the input, but actually it's at the output of PLL. Maybe to ensure a 50% duty cycle. From the values at table 8.1 one can conclude that the output frequency range of the PLL is 48MHz to 128MHz (/2 output range 24MHz to 64MHz). I would have expected that the /4 range then is 12MHz to 32MHz, but it's 24Mhz to 32Mhz. Its interesting to look at the schematics of the Arduino RA4M1 board. It shows a 16Mhz crystal for the clock, but crossed out in red. It seems they do not assemble or support it any more. https://docs.arduino.cc/resources/schematics/ABX00080-schematics.pdf Edit: There is also a RA4M1 board by Seeed without a crystal. The schematics show a 12MHz crystal crossed out in red, https://files.seeedstudio.com/wiki/XIAO-R4AM1/res/XIAO-RA4M1_SCH_PDF_v1.0_240719.pdf
I've pushed what's hopefully a cleaner version of the code, though I still wasn't able to get USB working. I say cleaner in that I think it's not truncated, but it's failing / crashing the code format checks! The auto-gen code is pretty messy.
Overriding the clocks to /2 x6 does get the UART working but not the USB. If I set the CPU to this pll output but USB to HOCO I get bus / hard faults at startup.
The other RA4W1 board I've wired USB onto works with no XTAL, it's HOCO for both.
This weact board, if you restart with MD button held it does jump into RA USB bootloader, visible on USB, so the pinout are right.
Debugger shows the TinyUSB startup code is being run. I get interrupts and connect/disconnect functions called when I connect disconnect the USB cable. I've swapped to different cables. I've tried direct to PC and via hub.
PC never shows anything at all enumerating at all.
I could download and build the firmware. So the files seem not to be truncated. REPL comes up at UART, but no sign of life at USB. I switched the file system to LFS1, because the code size is 6.5k smaller.
I assume you checked running both MCU and USB from the HOCO clock. You could check the real clock by enabling the clockout pin. Enabling CLKOUT and setting the clock source to PLL to enable the XTAL, I get a main clock of 16.001Mhz, and a HOCO clock of 48.004 MHz. So that matches, Note: The temperture drift of the HOCO seems pretty low. Cooling it down I get 48.008Mhz, heating it up I get 47.995Mhz. So HOCO seems fine.
Yes I too checked divided xtal on clkout and it was accurate. I initially tried HOCO for both as that's how the W1 is configured where I've got USB working! Even going back and comparing the changes I made to enable USB on W1 and trying to replicate that here for the M1 hasn't helped.
There's a TinyUSB example for M1 too which I scanned through and didn't find anything else amis; I should try to just compile and run that example actually to see if it works.
I tested a tinyusb example directly on my weact board and couldn't make that work either. There are two RA4M1 board profiles there:
anl@STEP:~/tinyusb/examples/device/cdc_msc$ make BOARD=ra4m1_ek
anl@STEP:~/tinyusb/examples/device/cdc_msc$ make BOARD=uno_r4
The official EK-RA4M1 has a 12Mhz crystal as opposed to the 16Mhz on this board. For 12Mhz the PLL is configured by defatul as /2 x8 to get a 48Mhz PLL to run everything. I reconfigured the tinyusb bsp for this to 16Mhz with /4 x12 to get 48Mhz with all the other clock settings the same. compiled and flashed via the USB bootloader and the official RenesasFlash Programmer. The fact the bootloader works shows the USB hardware can work, but after flashed I had no sign of life from the unit; no USB device shows up at all.
diff --git a/hw/bsp/ra/boards/ra4m1_ek/fsp_cfg/bsp_clock_cfg.h b/hw/bsp/ra/boards/ra4m1_ek/fsp_cfg/bsp_clock_cfg.h
index 554126523..526a51560 100644
--- a/hw/bsp/ra/boards/ra4m1_ek/fsp_cfg/bsp_clock_cfg.h
+++ b/hw/bsp/ra/boards/ra4m1_ek/fsp_cfg/bsp_clock_cfg.h
@@ -3,11 +3,11 @@
#define BSP_CLOCK_CFG_H_
#define BSP_CFG_CLOCKS_SECURE (0)
#define BSP_CFG_CLOCKS_OVERRIDE (0)
-#define BSP_CFG_XTAL_HZ (12000000) /* XTAL 12000000Hz */
+#define BSP_CFG_XTAL_HZ (16000000) /* XTAL 12000000Hz */
#define BSP_CFG_PLL_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_MAIN_OSC) /* PLL Src: XTAL */
#define BSP_CFG_HOCO_FREQUENCY (0) /* HOCO 24MHz */
-#define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_2) /* PLL Div /2 */
-#define BSP_CFG_PLL_MUL (BSP_CLOCKS_PLL_MUL(8u,0u)) /* PLL Mul x8 */
+#define BSP_CFG_PLL_DIV (BSP_CLOCKS_PLL_DIV_4) /* PLL Div /2 */
+#define BSP_CFG_PLL_MUL (BSP_CLOCKS_PLL_MUL(12u,0u)) /* PLL Mul x8 */
#define BSP_CFG_CLOCK_SOURCE (BSP_CLOCKS_SOURCE_CLOCK_PLL) /* Clock Src: PLL */
#define BSP_CFG_ICLK_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* ICLK Div /1 */
#define BSP_CFG_PCLKA_DIV (BSP_CLOCKS_SYS_CLOCK_DIV_1) /* PCLKA Div /1 */
(END)
The uno_r4 is actually configured for no XTAL, using the internal clocks instead. So this should rule out mis-configuration of clocks; unfortunately it too shows nothing on the USB when running.
Oh, ignore that last message. I just found the uno_r4 bsp had an updated linker to make space for the arduino bootloader. I got rid of that, recompiled, flash, ta-da tinyusb device pops up!
oof, I tried diffing and copying line by line changes between the uno_r4 board profile to the ek one (in tinyusb) and ended up with the ek one being identical to the uno and it still not working!
Finally found the critical difference elsewhere in the codebase!
Thanks. It works. It would be fine to get the other Renesas boards to support USB as well.
It seems I had tried once to use a frozen _boot.py for mounting the flash file system instead of the internal code in main.c. That would be the same approach as in the other ports except STM32. But that would be a different PR.
The othe official EK boards don't have real USB connected, at least not the ones I've checked. They've got 2 USB conenctors... one goes direct to a Jlink, the other goes to a usb-uart chip that then goes to the repl uart. The native usb on-chip is not exposed....
At the EK-RA6M2 which I have here the MCU's USB is connected to the device USB port. SO it could work. I have to dig into the data sheet for proper clock settings.
@robert-hh FWIW I originally used their GUI tool to configure the clock domains and export the auto-gen code needed
I've since trimmed out all the extra / unused auto-gen files for this PR.
The clock settings for USB of the RA6M2 look right. But the USR IRQs are not defined. So there is more missing than a proper clock.
Yeah I had to manually figure out & define the set of usb IRQ's myself by referencing the arduino board.