Skip to content

Commit

Permalink
Support for running from on-chip high speed oscillator (HOCO). The ta…
Browse files Browse the repository at this point in the history
…rget development board has no external clocks, so use onboard high speed clock (HOCO).
  • Loading branch information
dgarske committed Feb 22, 2024
1 parent 9c08af7 commit 0c4793e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 36 deletions.
8 changes: 8 additions & 0 deletions docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -1775,6 +1775,14 @@ Tested on the RX65N Target Board that includes an onboard E2 Lite emulator.

Default UART Serial output on PC3 via PMOD1-IO0 at Pin 9. This requires an external TTL UART to USB adapter. This feaure is enabled with `DEBUG_UART=1`.

Example Boot Output (with DEBUG_UART=1):

```
wolfBoot HAL Init
Boot partition: 0xFFE00000
Image size 27108
```

Default Onboard Flash Memory Layout (2MB) (64KB sector):

| Description | Address | Size |
Expand Down
140 changes: 106 additions & 34 deletions hal/rx65n.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
/* System Registers */
#define SYSTEM_BASE (0x80000)

#define SYS_SYSCR0 (*(volatile uint16_t *)(SYSTEM_BASE + 0x06))
#define SYS_SYSCR0_EXBE ENDIAN_BIT16(1) /* External Bus Enable */

#define SYS_MSTPCRB (*(volatile uint32_t *)(SYSTEM_BASE + 0x14)) /* Module Stop Control 0=release, 1=stop */

#define SYS_SCKCR (*(volatile uint32_t *)(SYSTEM_BASE + 0x20)) /* System Clock Control Register */
Expand Down Expand Up @@ -64,6 +67,9 @@
#define SYS_PLLCR2 (*(volatile uint8_t *)(SYSTEM_BASE + 0x2A))
#define SYS_PLLCR2_PLLEN ENDIAN_BIT8(0) /* PLL Stop Control: 0=PLL operating, 1=PLL stopped */

#define SYS_BCKCR (*(volatile uint8_t *)(SYSTEM_BASE + 0x30))
#define SYS_BCKCR_BCLKDIV ENDIAN_BIT8(0) /* 0=BCLK, 1= 1/2 BCLK */

#define SYS_MOSCCR (*(volatile uint8_t *)(SYSTEM_BASE + 0x32))
#define SYS_MOSCCR_MOSTP ENDIAN_BIT8(0) /* Main-clock osc: 0=operating, 1=stopped */

Expand All @@ -74,7 +80,9 @@
#define SYS_LOCOCR_LCSTP ENDIAN_BIT8(0) /* Low-Speed On-Chip Oscillator Control: 0=On, 1=Off */

#define SYS_HOCOCR (*(volatile uint8_t *)(SYSTEM_BASE + 0x36))
#define SYS_HOCOCR_HCSTP ENDIAN_BIT8(0) /* High Speed On-Chip Osc - 1=STOPPED */
#define SYS_HOCOCR_HCSTP ENDIAN_BIT8(0) /* High Speed On-Chip Osc - 1=STOPPED */
#define SYS_HOCOCR2 (*(volatile uint8_t *)(SYSTEM_BASE + 0x37))
#define SYS_HOCOCR2_HCFRQ(n) ENDIAN_VAL8(n, 0) /* 0=16MHz, 1=18MHz, 2=20MHz */

#define SYS_OSCOVFSR (*(volatile uint8_t *)(SYSTEM_BASE + 0x3C))
#define SYS_OSCOVFSR_MOOVF ENDIAN_BIT8(0) /* Main clock */
Expand Down Expand Up @@ -123,22 +131,28 @@
/* Serial Communication Interface */
#define SCI_BASE(n) (0x8A000 + ((n) * 0x20))
#define SCI_SMR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x00))
#define SCI_BRR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x01)) /* Bit Rate Reg < 255 */
#define SCI_SCR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x02))
#define SCI_TDR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x03)) /* Transmit Data Register */
#define SCI_SSR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x04))
#define SCI_RDR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x05)) /* Receive Data Register */
#define SCI_SCMR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x06))

#define SCI_SMR_CKS(clk) (clk & 0x3) /* 0=PCLK, 1=PCLK/4, 2=PCLK/16, 3=PCLK/64 */
#define SCI_SMR_STOP ENDIAN_BIT8(3) /* 0=1 stop bit */
#define SCI_SMR_CHR ENDIAN_BIT8(6) /* 0=8-bit */
#define SCI_SCMR_CHR1 ENDIAN_BIT8(4) /* 1=8-bit */
#define SCI_BRR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x01)) /* Bit Rate Reg < 255 */
#define SCI_SCR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x02))
#define SCI_SCR_RE ENDIAN_BIT8(4)
#define SCI_SCR_TE ENDIAN_BIT8(5)
#define SCI_TDR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x03)) /* Transmit Data Register */
#define SCI_SSR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x04))
#define SCI_SSR_TEND ENDIAN_BIT8(2) /* Transmit End Flag */
#define SCI_SSR_RDRF ENDIAN_BIT8(6) /* Receive Data Full Flag */
#define SCI_SSR_TDRE ENDIAN_BIT8(7) /* Transmit Data Empty Flag */
#define SCI_RDR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x05)) /* Receive Data Register */
#define SCI_SCMR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x06))
#define SCI_SCMR_CHR1 ENDIAN_BIT8(4) /* 1=8-bit */
#define SCI_SEMR(n) (*(volatile uint8_t *)(SCI_BASE(n) + 0x08))
#define SCI_SEMR_ASC0 ENDIAN_BIT8(0) /* Asynchronous Mode Clock Source Select 0=external clock input */
#define SCI_SEMR_BRME ENDIAN_BIT8(2) /* Bit Rate Modulation Enable */
#define SCI_SEMR_ABCS ENDIAN_BIT8(4) /* Asynchronous Mode Base Clock Select */
#define SCI_SEMR_NFEN ENDIAN_BIT8(5) /* Digital Noise Filter Function Enable */
#define SCI_SEMR_BGDM ENDIAN_BIT8(6) /* Baud Rate Generator Double-Speed Mode Select */
#define SCI_SEMR_RXDESEL ENDIAN_BIT8(7) /* Asynchronous Start Bit Edge Detection Select */

/* MPC (Multi-Function Pin Controller) */
#define MPC_PWPR (*(volatile uint8_t *)(0x8C11F))
Expand Down Expand Up @@ -198,10 +212,25 @@ void uart_init(void)
MPC_PWPR &= ~(MPC_PWPR_PFSWE | MPC_PWPR_B0WI);
MPC_PWPR |= MPC_PWPR_PFSWE;

/* 8-bit, 1-stop, no parity, cks=3 (/64) */
SCI_SMR(DEBUG_UART_SCI) = SCI_SMR_CKS(3);
/* baud rate */
SCI_BRR(DEBUG_UART_SCI) = (PCLKB / 64 / DEBUG_BAUD_RATE);
/* baud rate table: */
/* divisor, abcs, bgdm, cks
* 8, 1, 1, 0
* 16, 0, 1, 0
* 32, 0, 0, 0
* 64, 0, 1, 1
* 128, 0, 0, 1
* 256, 0, 1, 2
* 512, 0, 0, 2 (using this one)
* 1024, 0, 1, 3
* 2048, 0, 0, 3
*/

/* 8-bit, 1-stop, no parity, cks=2 (/512), bgdm=0, abcs=0 */
SCI_BRR(DEBUG_UART_SCI) = (PCLKB / (512 * DEBUG_BAUD_RATE)) - 1;
SCI_SEMR(DEBUG_UART_SCI) &= ~SCI_SEMR_ABCS;
SCI_SEMR(DEBUG_UART_SCI) &= ~SCI_SEMR_BGDM;
SCI_SMR(DEBUG_UART_SCI) = SCI_SMR_CKS(2);
SCI_SCMR(DEBUG_UART_SCI) |= SCI_SCMR_CHR1;
/* Enable TX/RX */
SCI_SCR(DEBUG_UART_SCI) = (SCI_SCR_RE | SCI_SCR_TE);
}
Expand All @@ -221,26 +250,48 @@ void uart_write(const char* buf, uint32_t sz)
#endif /* DEBUG_UART */

/* LOCO clock is used out of reset */
/* This function This will switch to using main-clock with PLL oscillator at 240MHz */
/* This function will switch to using on-chip HOCO through PLL at 240MHz */
#define CFG_CKSEL 1 /* 0=LOCO, 1=HOCO, 2=Main, 3=Sub, 4=PLL */
#define CFD_PLL_DIV (0)
#define CFG_PLL_MUL (15.0)

void hal_clk_init(void)
{
uint32_t reg, i;
uint16_t stc;
uint8_t cksel = CFG_CKSEL;

PROTECT_OFF(); /* write protect off */

/* ---- High Speed OSC (HOCO) ---- */
#if CFG_CKSEL == 1
if (SYS_HOCOCR & SYS_HOCOCR_HCSTP) {
/* Turn off power to HOCO */
SYS_HOCOPCR |= SYS_HOCOPCR_HOCOPCNT;
}
else {
/* Wait for HOCO oscisllator stabilization */
while ((SYS_OSCOVFSR & SYS_OSCOVFSR_HCOVF) == 0) { RX_NOP(); }
/* Turn on power to HOCO */
SYS_HOCOPCR &= ~SYS_HOCOPCR_HOCOPCNT;
/* Stop HOCO */
SYS_HOCOCR |= SYS_HOCOCR_HCSTP;
/* Wait for HOCO to stop */
while (SYS_OSCOVFSR & SYS_OSCOVFSR_HCOVF) { RX_NOP(); }

/* Set 16MHz */
SYS_HOCOCR2 = SYS_HOCOCR2_HCFRQ(0);

/* Enable HOCO */
SYS_HOCOCR &= ~SYS_HOCOCR_HCSTP;
reg = SYS_HOCOCR; /* dummy ready (required) */
}
/* Wait for HOCO oscisllator stabilization */
while ((SYS_OSCOVFSR & SYS_OSCOVFSR_HCOVF) == 0) { RX_NOP(); }
#else
if (SYS_HOCOCR & SYS_HOCOCR_HCSTP) {
/* Turn off power to HOCO */
SYS_HOCOPCR |= SYS_HOCOPCR_HOCOPCNT;
}
#endif

/* ---- Main-Clock ---- */
/* MOFXIN=0 (not controlled), MODRV2=0 (24MHz), MOSEL=0 (resonator) */
#if CFG_CKSEL == 2
/* MOFXIN=0 (not controlled), MODRV2=0 (24MHz), MOSEL=0 (resonator) */
SYS_MOFCR = 0;

/* OSC stabilization time (9.98 ms * (264 kHZ) + 16)/32 = 82.83) */
Expand All @@ -250,6 +301,12 @@ void hal_clk_init(void)
SYS_MOSCCR = 0;
reg = SYS_MOSCCR; /* dummy read (required) */
while (SYS_MOSCCR != 0) { RX_NOP(); }
#else
/* Stop main clock */
SYS_MOSCCR = SYS_MOSCCR_MOSTP;
reg = SYS_MOSCCR; /* dummy read (required) */
while ((SYS_OSCOVFSR & SYS_OSCOVFSR_MOOVF) != 0) { RX_NOP(); }
#endif

/* ---- RTC Clock ---- */
if ((SYS_RSTSR1 & SYS_RSTSR1_CWSF) == 0) { /* cold start */
Expand All @@ -267,23 +324,34 @@ void hal_clk_init(void)
}

/* ---- Sub-Clock OSC ---- */
#if CFG_CKSEL == 3
/* TODO: Add support for running from sub-clock */
#else
/* Stop the sub-clock */
SYS_SOSCCR = SYS_SOSCCR_SOSTP;
reg = SYS_SOSCCR; /* dummy read (required) */
while ((SYS_OSCOVFSR & SYS_OSCOVFSR_SOOVF) != 0) { RX_NOP(); }
#endif

/* ---- PLL OSC ---- */
#if CFG_CKSEL == 1 || CFG_CKSEL == 2
/* ---- PLL ---- */
/* Frequency Multiplication Factor */
#define CFG_PLL_MUL (10.0)
#if CFG_CKSEL == 2
#define PLL_SRCSEL /* main */
#else
#define PLL_SRCSEL SYS_PLLCR_PLLSRCSEL /* HOCO */
#endif
#define PLL_MUL_STC (((uint8_t)((float)CFG_PLL_MUL * 2.0)) - 1)
reg = (
SYS_PLLCR_PLIDIV(0) | /* no div */
SYS_PLLCR_PLLSRCSEL | /* main clock osc */
SYS_PLLCR_STC(PLL_MUL_STC) /* multiplier */
SYS_PLLCR_PLIDIV(CFD_PLL_DIV) | /* no div */
PLL_SRCSEL | /* clock source (0=main, 1=HOCO */
SYS_PLLCR_STC(PLL_MUL_STC) /* multiplier */
);
SYS_PLLCR = reg;
SYS_PLLCR2 = 0;
SYS_PLLCR2 = 0; /* enable PLL */
while ((SYS_OSCOVFSR & SYS_OSCOVFSR_PLOVF) == 0) { RX_NOP(); }
cksel = 4; /* PLL */
#endif

/* ---- FLASH ---- */
/* Flash Wait Cycles (1=50-100MHz, 2= >100MHz) */
Expand All @@ -293,31 +361,35 @@ void hal_clk_init(void)

/* ---- Clock Select ---- */
reg = (
SYS_SCKCR_ICK(1) | /* System Clock (ICK)=1: 1/2 = 120MHz */
SYS_SCKCR_BCK(1) | /* External Bus Clock (BCK)=1: 1/2 = 120MHz */
SYS_SCKCR_FCK(4) | /* Flash-IF Clock FCK=2: 1/4 = 60MHz */
SYS_SCKCR_ICK(1) | /* System Clock (ICK)=1: 1/2 = 120MHz */
SYS_SCKCR_BCK(1) | /* External Bus Clock (BCK)=1: 1/2 = 120MHz */
SYS_SCKCR_FCK(2) | /* Flash-IF Clock FCK=2: 1/4 = 60MHz */
SYS_SCKCR_PCKA(1) | /* Peripheral Module Clock A (PCKA)=1: 1/2 = 120MHz */
SYS_SCKCR_PCKB(2) | /* Peripheral Module Clock D (PCKB)=2: 1/4 = 60MHz */
SYS_SCKCR_PCKC(2) | /* Peripheral Module Clock C (PCKC)=2: 1/4 = 60MHz */
SYS_SCKCR_PCKD(2) | /* Peripheral Module Clock D (PCKD)=2: 1/4 = 60MHz */
SYS_SCKCR_PSTOP1 | /* BLKD Pin Output (PSTOP1): 0=Disabled */
SYS_SCKCR_PSTOP1 | /* BCLK Pin Output (PSTOP1): 0=Disabled */
SYS_SCKCR_PSTOP0 /* SDCLK Pin Output (PSTOP0): 0=Disabled */
);
SYS_SCKCR = reg;
reg = SYS_SCKCR; /* dummy read (required) */

#if CFG_CKSEL == 2 /* USB only on main clock */
/* USB Clock=4: 1/5 = 48MHz */
SYS_SCKCR2 |= SYS_SCKCR2_UCK(4);
reg = SYS_SCKCR2; /* dummy read (required) */
#endif

/* Clock Source = PLL */
SYS_SCKCR3 = SYS_SCKCR3_CKSEL(4);
/* Clock Source */
SYS_SCKCR3 = SYS_SCKCR3_CKSEL(cksel);
reg = SYS_SCKCR3; /* dummy read (required) */

/* ---- Low Speed OSC (LOCO) ---- */
/* Disable Low Speed Oscillator */
#if CFG_CKSEL != 0
/* Disable on-chip Low Speed Oscillator */
SYS_LOCOCR |= SYS_LOCOCR_LCSTP;
hal_delay_us(25);
#endif

PROTECT_ON(); /* write protect on */
}
Expand Down
4 changes: 2 additions & 2 deletions src/boot_renesas.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void do_boot(const uint32_t *app_offset)
(void) app_sp;
(void) app_entry;
#if defined(__RX__)

/* TOOD: Add jump */
#elif defined(__CCRX__)
longJump(app_offset);
#elif defined(_RENESAS_RA_)
Expand All @@ -60,7 +60,7 @@ void do_boot(const uint32_t *app_offset)
__asm__ ("ldr r3, [%0]" ::"r"(app_sp));
__asm__ ("mov sp, r3");

/*
/*
* address of Reset Handler is stored in Vector table[] that is defined in startup.c.
* The vector for Reset Handler is placed right after Initial Stack Pointer.
* The application assumes to start from 0x10200.
Expand Down

0 comments on commit 0c4793e

Please sign in to comment.