diff --git a/arch/risc-v/Kconfig b/arch/risc-v/Kconfig index 7eb73308ab2..78a333b6058 100644 --- a/arch/risc-v/Kconfig +++ b/arch/risc-v/Kconfig @@ -69,6 +69,12 @@ config ARCH_CHIP_MPFS ---help--- MicroChip Polarfire processor (RISC-V 64bit core with GCVX extensions). +config ARCH_CHIP_RV32M1 + bool "NXP RV32M1" + select ARCH_RV32IM + ---help--- + NXP RV32M1 processor (RISC-V Core with PULP extensions). + config ARCH_CHIP_RISCV_CUSTOM bool "Custom RISC-V chip" select ARCH_CHIP_CUSTOM @@ -107,6 +113,22 @@ config ARCH_CHIP default "esp32c3" if ARCH_CHIP_ESP32C3 default "c906" if ARCH_CHIP_C906 default "mpfs" if ARCH_CHIP_MPFS + default "rv32m1" if ARCH_CHIP_RV32M1 + +config ARCH_RISCV_INTXCPT_EXTENSIONS + bool "RISC-V Integer Context Extensions" + default n + ---help--- + RISC-V could be customized with extensions. Some Integer Context + Registers have to be saved and restored when Contexts switch. + +if ARCH_RISCV_INTXCPT_EXTENSIONS + +config ARCH_RISCV_INTXCPT_EXTREGS + int "Number of Extral RISC-V Integer Context Registers" + default 0 + +endif if ARCH_RV32IM source arch/risc-v/src/rv32im/Kconfig @@ -135,4 +157,7 @@ endif if ARCH_CHIP_MPFS source arch/risc-v/src/mpfs/Kconfig endif +if ARCH_CHIP_RV32M1 +source arch/risc-v/src/rv32m1/Kconfig +endif endif diff --git a/arch/risc-v/include/rv32im/irq.h b/arch/risc-v/include/rv32im/irq.h index b1ed3afdc0d..62b39566636 100644 --- a/arch/risc-v/include/rv32im/irq.h +++ b/arch/risc-v/include/rv32im/irq.h @@ -114,7 +114,12 @@ #define REG_INT_CTX_NDX 32 -#define INT_XCPT_REGS 33 +#ifdef CONFIG_ARCH_RISCV_INTXCPT_EXTREGS + #define INT_XCPT_REGS (33 + CONFIG_ARCH_RISCV_INTXCPT_EXTREGS) +#else + #define INT_XCPT_REGS 33 +#endif + #define INT_XCPT_SIZE (4 * INT_XCPT_REGS) #ifdef CONFIG_ARCH_FPU diff --git a/arch/risc-v/include/rv32m1/chip.h b/arch/risc-v/include/rv32m1/chip.h new file mode 100644 index 00000000000..3e9e6291c65 --- /dev/null +++ b/arch/risc-v/include/rv32m1/chip.h @@ -0,0 +1,24 @@ +/**************************************************************************** + * arch/risc-v/include/rv32m1/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_RV32M1_CHIP_H +#define __ARCH_RISCV_INCLUDE_RV32M1_CHIP_H + +#endif /* __ARCH_RISCV_INCLUDE_RV32M1_CHIP_H */ diff --git a/arch/risc-v/include/rv32m1/irq.h b/arch/risc-v/include/rv32m1/irq.h new file mode 100644 index 00000000000..6a1a9976e6d --- /dev/null +++ b/arch/risc-v/include/rv32m1/irq.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/risc-v/include/rv32m1/irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_RV32M1_IRQ_H +#define __ARCH_RISCV_INCLUDE_RV32M1_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#ifdef CONFIG_ARCH_CHIP_RV32M1_RI5CY +# include "rv32m1ri5cy_irq.h" +#elif defined(CONFIG_ARCH_CHIP_RV32M1_ZERORISCY) +# error "RV32M1 zeroriscy is not supported yet" +#else +# error "Unsupported RV32M1 cortex-m cores" +#endif + +#endif /* __ARCH_RISCV_INCLUDE_RV32M1_IRQ_H */ diff --git a/arch/risc-v/include/rv32m1/rv32m1ri5cy_irq.h b/arch/risc-v/include/rv32m1/rv32m1ri5cy_irq.h new file mode 100644 index 00000000000..eb556857fe2 --- /dev/null +++ b/arch/risc-v/include/rv32m1/rv32m1ri5cy_irq.h @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/risc-v/include/rv32m1/rv32m1ri5cy_irq.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_RV32M1_RV32M1RI5CY_IRQ_H +#define __ARCH_RISCV_INCLUDE_RV32M1_RV32M1RI5CY_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* RV32M1 RI5CY CPU throws four exceptions: + * -Reset, + * -Illegal Instruction, + * -ECALL Instruct Excecuted, + * -Load Store Unit Error. MCAUSE must be checked to + * figure out what kind of Error. + */ + +/* RISC-V standard exceptions alias with prefix RV32M1 **********************/ + +#define RV32M1_IRQ_ADDE_MISALIGNED MCAUSE_ADDE_MISALIGNED +#define RV32M1_IRQ_INST_ACCESS_FAULT MCAUSE_INST_ACCESS_FAULT +#define RV32M1_IRQ_ILLEGAL_INST MCAUSE_ILLEGAL_INST +#define RV32M1_IRQ_LOAD_MISALIGNED MCAUSE_LOAD_MISALIGNED +#define RV32M1_IRQ_LOAD_ACCESS_FAULT MCAUSE_LOAD_ACCESS_FAULT +#define RV32M1_IRQ_STORE_MISALIGNED MCAUSE_STORE_MISALIGNED +#define RV32M1_IRQ_STORE_ACCESS_FAULT MCAUSE_STORE_ACCESS_FAULT +#define RV32M1_IRQ_ECALL_U MCAUSE_ECALL_U +#define RV32M1_IRQ_ECALL_M MCAUSE_ECALL_M + +/* RV32M1 RI5CY Interrupts **************************************************/ + +/* IRQ 16- : (async event:interrupt=1) */ + +#define RV32M1_IRQ_ASYNC (16) +#define RV32M1_IRQ_MEXT (RV32M1_IRQ_ASYNC + 0) /* Machine External Int */ + +/* Machine Global External Interrupt */ + +#define RV32M1_IRQ_DMA0G0 (RV32M1_IRQ_MEXT + 0) /* DMA0 Group0, channel 0/4/8/12 */ +#define RV32M1_IRQ_DMA0G1 (RV32M1_IRQ_MEXT + 1) /* DMA0 Group1, channel 1/5/9/13 */ +#define RV32M1_IRQ_DMA0G2 (RV32M1_IRQ_MEXT + 2) /* DMA0 Group2, channel 2/6/10/14 */ +#define RV32M1_IRQ_DMA0G3 (RV32M1_IRQ_MEXT + 3) /* DMA0 Group3, channel 3/7/11/15 */ +#define RV32M1_IRQ_DMA0EER (RV32M1_IRQ_MEXT + 4) /* DAM0 Error */ +#define RV32M1_IRQ_CMC0 (RV32M1_IRQ_MEXT + 5) /* Core Mode Controller 0 */ +#define RV32M1_IRQ_MUA (RV32M1_IRQ_MEXT + 6) /* MU Side A */ +#define RV32M1_IRQ_USB0 (RV32M1_IRQ_MEXT + 7) /* USB0 */ +#define RV32M1_IRQ_USDHC0 (RV32M1_IRQ_MEXT + 8) /* SDHC0 */ +#define RV32M1_IRQ_I2S0 (RV32M1_IRQ_MEXT + 9) /* I2S0 */ +#define RV32M1_IRQ_FLEXIO0 (RV32M1_IRQ_MEXT + 10) /* FlexIO0 */ +#define RV32M1_IRQ_EMVSIM0 (RV32M1_IRQ_MEXT + 11) /* EMVSIM0 */ +#define RV32M1_IRQ_LPIT0 (RV32M1_IRQ_MEXT + 12) /* LPIT0 */ +#define RV32M1_IRQ_LPSPI0 (RV32M1_IRQ_MEXT + 13) /* LPSPI0 */ +#define RV32M1_IRQ_LPSPI1 (RV32M1_IRQ_MEXT + 14) /* LPSPI1 */ +#define RV32M1_IRQ_LPI2C0 (RV32M1_IRQ_MEXT + 15) /* LPI2C0 */ +#define RV32M1_IRQ_LPI2C1 (RV32M1_IRQ_MEXT + 16) /* LPI2C1 */ +#define RV32M1_IRQ_LPUART0 (RV32M1_IRQ_MEXT + 17) /* LPUART0 */ +#define RV32M1_IRQ_PORTA (RV32M1_IRQ_MEXT + 18) /* PORTA */ +#define RV32M1_IRQ_TPM0 (RV32M1_IRQ_MEXT + 19) /* TPM0 */ +#define RV32M1_IRQ_ADC0 (RV32M1_IRQ_MEXT + 20) /* ADC0 */ +#define RV32M1_IRQ_LPDAC0 (RV32M1_IRQ_MEXT + 21) /* LPDAC0 */ +#define RV32M1_IRQ_LPCMP0 (RV32M1_IRQ_MEXT + 22) /* LPCMP0 */ +#define RV32M1_IRQ_RTC (RV32M1_IRQ_MEXT + 23) /* RTC */ +#define RV32M1_IRQ_INTMUX0 (RV32M1_IRQ_MEXT + 24) /* INTMUX0 */ +#define RV32M1_IRQ_INTMUX1 (RV32M1_IRQ_MEXT + 25) /* INTMUX1 */ +#define RV32M1_IRQ_INTMUX2 (RV32M1_IRQ_MEXT + 26) /* INTMUX2 */ +#define RV32M1_IRQ_INTMUX3 (RV32M1_IRQ_MEXT + 27) /* INTMUX3 */ +#define RV32M1_IRQ_INTMUX4 (RV32M1_IRQ_MEXT + 28) /* INTMUX4 */ +#define RV32M1_IRQ_INTMUX5 (RV32M1_IRQ_MEXT + 29) /* INTMUX5 */ +#define RV32M1_IRQ_INTMUX6 (RV32M1_IRQ_MEXT + 30) /* INTMUX6 */ +#define RV32M1_IRQ_INTMUX7 (RV32M1_IRQ_MEXT + 31) /* INTMUX7 */ +#define RV32M1_IRQ_EWM (RV32M1_IRQ_MEXT + 32) /* EWM */ +# define RV32M1_IRQ_INTMUX RV32M1_IRQ_EWM +#define RV32M1_IRQ_FTFE_CC (RV32M1_IRQ_MEXT + 33) /* FTFE Command Complete */ +#define RV32M1_IRQ_FTFE_RC (RV32M1_IRQ_MEXT + 34) /* FTFE Read Collision */ +#define RV32M1_IRQ_LLWU0 (RV32M1_IRQ_MEXT + 35) /* Low leakage wake up 0 */ +#define RV32M1_IRQ_SPM (RV32M1_IRQ_MEXT + 36) /* SPM */ +#define RV32M1_IRQ_WDOG0 (RV32M1_IRQ_MEXT + 37) /* WDOG0 */ +#define RV32M1_IRQ_SCG (RV32M1_IRQ_MEXT + 38) /* SCG */ +#define RV32M1_IRQ_LPTMR0 (RV32M1_IRQ_MEXT + 39) /* LPTMR0 */ +#define RV32M1_IRQ_LPTMR1 (RV32M1_IRQ_MEXT + 40) /* LPTMR1 */ +#define RV32M1_IRQ_TPM1 (RV32M1_IRQ_MEXT + 41) /* TPM1 */ +#define RV32M1_IRQ_TMP2 (RV32M1_IRQ_MEXT + 42) /* TPM2 */ +#define RV32M1_IRQ_LPI2C2 (RV32M1_IRQ_MEXT + 43) /* LPI2C2 */ +#define RV32M1_IRQ_SPI2 (RV32M1_IRQ_MEXT + 44) /* SPI2 */ +#define RV32M1_IRQ_LPUART1 (RV32M1_IRQ_MEXT + 45) /* LPUART1 */ +#define RV32M1_IRQ_LPUART2 (RV32M1_IRQ_MEXT + 46) /* LPUART2 */ +#define RV32M1_IRQ_PORTB (RV32M1_IRQ_MEXT + 47) /* PORTB */ +#define RV32M1_IRQ_PORTC (RV32M1_IRQ_MEXT + 48) /* PORTC */ +#define RV32M1_IRQ_PORTD (RV32M1_IRQ_MEXT + 49) /* PORTD */ +#define RV32M1_IRQ_CAU3_TC (RV32M1_IRQ_MEXT + 50) /* CAU3 Task Complete */ +#define RV32M1_IRQ_CAU3_SV (RV32M1_IRQ_MEXT + 51) /* CAU3 Security Violation */ +#define RV32M1_IRQ_TRNG (RV32M1_IRQ_MEXT + 52) /* TRNG */ +#define RV32M1_IRQ_LPIT1 (RV32M1_IRQ_MEXT + 53) /* LPIT1 */ +#define RV32M1_IRQ_LPTMR2 (RV32M1_IRQ_MEXT + 54) /* LPTMR2 */ +#define RV32M1_IRQ_TPM3 (RV32M1_IRQ_MEXT + 55) /* TPM3 */ +#define RV32M1_IRQ_LPI2C3 (RV32M1_IRQ_MEXT + 56) /* LPI2C3 */ +#define RV32M1_IRQ_LPSPI3 (RV32M1_IRQ_MEXT + 57) /* LPSPI3 */ +#define RV32M1_IRQ_LPUART3 (RV32M1_IRQ_MEXT + 58) /* LPUART3 */ +#define RV32M1_IRQ_PORTE (RV32M1_IRQ_MEXT + 59) /* PORTE */ +#define RV32M1_IRQ_LPCMP1 (RV32M1_IRQ_MEXT + 60) /* LPCMP1 */ +#define RV32M1_IRQ_RF0_0 (RV32M1_IRQ_MEXT + 61) /* RF0 Interrupt 0 */ +#define RV32M1_IRQ_RF0_1 (RV32M1_IRQ_MEXT + 62) /* RF0 Interrupt 1 */ + +/* Total number of IRQs */ + +#define NR_IRQS (RV32M1_IRQ_RF0_1 + 1) + +#endif /* __ARCH_RISCV_INCLUDE_RV32M1_RV32M1RI5CY_IRQ_H */ diff --git a/arch/risc-v/include/rv64gc/irq.h b/arch/risc-v/include/rv64gc/irq.h index c9e51ed06ac..2852b0cdb51 100644 --- a/arch/risc-v/include/rv64gc/irq.h +++ b/arch/risc-v/include/rv64gc/irq.h @@ -115,7 +115,11 @@ #define REG_INT_CTX_NDX 32 -#define INT_XCPT_REGS 33 +#ifdef CONFIG_ARCH_RISCV_INTXCPT_EXTREGS + #define INT_XCPT_REGS (33 + CONFIG_ARCH_RISCV_INTXCPT_EXTREGS) +#else + #define INT_XCPT_REGS 33 +#endif #define INT_XCPT_SIZE (8 * INT_XCPT_REGS) diff --git a/arch/risc-v/src/rv32m1/Kconfig b/arch/risc-v/src/rv32m1/Kconfig new file mode 100644 index 00000000000..63b082ba96a --- /dev/null +++ b/arch/risc-v/src/rv32m1/Kconfig @@ -0,0 +1,170 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +comment "RV32M1 Configuration Options" + +choice + prompt "RV32M1 Chip Selection" + default ARCH_CHIP_RV32M1_RI5CY + depends on ARCH_CHIP_RV32M1 + +config ARCH_CHIP_RV32M1_RI5CY + bool "RV32M1_RI5CY" + select RV32M1_HAVE_ITCM + select RV32M1_HAVE_TSTMR + ---help--- + RV32M1 RI5CY, RV32IMC 256KB SRAM, 1MB FLASH. + +endchoice + +menu "RV32M1 Peripheral Support" + +# These "hidden" settings determine whether a peripheral option is available +# for the selected MCU + +config RV32M1_HAVE_LPUART0 + bool + default y + +config RV32M1_HAVE_LPUART1 + bool + default y + +config RV32M1_HAVE_LPUART2 + bool + default y + +config RV32M1_HAVE_LPUART3 + bool + default y + +config RV32M1_HAVE_ITCM + bool + default n + +config RV32M1_HAVE_TSTMR + bool + default y + +config RV32M1_LPUART + bool + default n + +config RV32M1_SERIALDRIVER + bool + default n + +# These are the peripheral selections proper + +config RV32M1_LPUART0 + bool "LPUART0" + default n + depends on RV32M1_HAVE_LPUART0 + select RV32M1_LPUART + +config RV32M1_LPUART1 + bool "LPUART1" + default n + depends on RV32M1_HAVE_LPUART1 + select RV32M1_LPUART + +config RV32M1_LPUART2 + bool "LPUART2" + default n + depends on RV32M1_HAVE_LPUART2 + select RV32M2_LPUART + +config RV32M1_LPUART3 + bool "LPUART3" + default n + depends on RV32M1_HAVE_LPUART3 + select RV32M2_LPUART + +config RV32M1_ITCM + bool "ITCM" + default n + depends on RV32M1_HAVE_ITCM + +config RV32M1_TSTMR + bool "TSTMR" + default n + depends on RV32M1_HAVE_TSTMR + +menu "LPUART Configuration" + depends on RV32M1_LPUART + +comment "LPUART Device Configuration" + +choice + prompt "LPUART0 Driver Configuration" + default RV32M1_LPUART0_SERIALDRIVER + depends on RV32M1_LPUART0 + +config RV32M1_LPUART0_SERIALDRIVER + bool "Standard serial driver" + select ARCH_HAVE_SERIAL_TERMIOS + select RV32M1_SERIALDRIVER + select LPUART0_SERIALDRIVER + +endchoice # LPUART0 Driver Configuration + +if RV32M1_LPUART0_SERIALDRIVER + +endif # RV32M1_LPUART0_SERIALDRIVER + +choice + prompt "LPUART1 Driver Configuration" + default RV32M1_LPUART1_SERIALDRIVER + depends on RV32M1_LPUART1 + +config RV32M1_LPUART1_SERIALDRIVER + bool "Standard serial driver" + select ARCH_HAVE_SERIAL_TERMIOS + select RV32M1_SERIALDRIVER + select LPUART1_SERIALDRIVER + +endchoice # LPUART1 Driver Configuration + +if RV32M1_LPUART1_SERIALDRIVER + +endif # RV32M1_LPUART1_SERIALDRIVER + +choice + prompt "LPUART2 Driver Configuration" + default RV32M1_LPUART2_SERIALDRIVER + depends on RV32M1_LPUART2 + +config RV32M1_LPUART2_SERIALDRIVER + bool "Standard serial driver" + select ARCH_HAVE_SERIAL_TERMIOS + select RV32M1_SERIALDRIVER + select LPUART2_SERIALDRIVER + +endchoice # LPUART2 Driver Configuration + +if RV32M1_LPUART2_SERIALDRIVER + +endif # RV32M1_LPUART2_SERIALDRIVER + +choice + prompt "LPUART3 Driver Configuration" + default RV32M1_LPUART3_SERIALDRIVER + depends on RV32M1_LPUART3 + +config RV32M1_LPUART3_SERIALDRIVER + bool "Standard serial driver" + select ARCH_HAVE_SERIAL_TERMIOS + select RV32M1_SERIALDRIVER + select LPUART3_SERIALDRIVER + +endchoice # LPUART3 Driver Configuration + +if RV32M1_LPUART3_SERIALDRIVER + +endif # RV32M1_LPUART3_SERIALDRIVER + +endmenu # LPUART Configuration Menu + +endmenu diff --git a/arch/risc-v/src/rv32m1/Make.defs b/arch/risc-v/src/rv32m1/Make.defs new file mode 100644 index 00000000000..cc0db880b61 --- /dev/null +++ b/arch/risc-v/src/rv32m1/Make.defs @@ -0,0 +1,51 @@ +############################################################################ +# arch/risc-v/src/rv32m1/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +# Specify our HEAD assembly file. This will be linked as +# the first object file, so it will appear at address 0 +HEAD_ASRC = rv32m1_vectors.S + +# Specify our general Assembly files +CHIP_ASRCS = rv32m1_head.S riscv_syscall.S + +# Specify C code within the common directory to be included +CMN_CSRCS += riscv_initialize.c riscv_swint.c +CMN_CSRCS += riscv_allocateheap.c riscv_createstack.c riscv_exit.c +CMN_CSRCS += riscv_assert.c riscv_blocktask.c riscv_copystate.c riscv_initialstate.c +CMN_CSRCS += riscv_interruptcontext.c riscv_modifyreg32.c riscv_puts.c +CMN_CSRCS += riscv_releasepending.c riscv_reprioritizertr.c riscv_copyfullstate.c +CMN_CSRCS += riscv_releasestack.c riscv_stackframe.c riscv_schedulesigaction.c +CMN_CSRCS += riscv_sigdeliver.c riscv_unblocktask.c riscv_usestack.c + +ifeq ($(CONFIG_STACK_COLORATION),y) +CMN_CSRCS += riscv_checkstack.c +endif + +ifeq ($(CONFIG_ARCH_HAVE_VFORK),y) +CMN_CSRCS += riscv_vfork.c +endif + +# Specify our C code within this directory to be included +CHIP_CSRCS = rv32m1_allocateheap.c rv32m1_clockconfig.c rv32m1_gpio.c +CHIP_CSRCS += rv32m1_idle.c rv32m1_irq.c rv32m1_irq_dispatch.c +CHIP_CSRCS += rv32m1_lowputc.c rv32m1_serial.c +CHIP_CSRCS += rv32m1_start.c rv32m1_timerisr.c +CHIP_CSRCS += rv32m1_pcc.c +CHIP_CSRCS += rv32m1_delay.c rv32m1_timersvc.c diff --git a/arch/risc-v/src/rv32m1/chip.h b/arch/risc-v/src/rv32m1/chip.h new file mode 100644 index 00000000000..28fd037be0c --- /dev/null +++ b/arch/risc-v/src/rv32m1/chip.h @@ -0,0 +1,60 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/chip.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_CHIP_H +#define __ARCH_RISCV_SRC_RV32M1_CHIP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include the chip capabilities file */ + +#include + +#ifndef __ASSEMBLY__ + +/* Include the chip interrupt definition file */ + +#include + +#endif + +/* Include the chip memmap */ + +#include "rv32m1_memorymap.h" + +/* Include the chip pinmap */ + +#include "hardware/rv32m1_pinmap.h" + +/* Include the chip pcc */ + +#include "hardware/rv32m1_pcc.h" + +/* Include the chip intmux */ + +#include "hardware/rv32m1_intmux.h" + +/* Incluce the linker file */ + +#include "rv32m1_linker.h" + +#endif /* __ARCH_RISCV_SRC_RV32M1_CHIP_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_eu.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_eu.h new file mode 100644 index 00000000000..c867df40f77 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_eu.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_eu.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_EU_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_EU_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_EU_INTPTEN_OFFSET 0x0000 /* Interrupt Enable */ +#define RV32M1_EU_INTPTPEND_OFFSET 0x0004 /* Interrupt Pending */ +#define RV32M1_EU_INTPTPENDSET_OFFSET 0x0008 /* Set Interrupt Pending */ +#define RV32M1_EU_INTPTPENDCLR_OFFSET 0x000c /* Clear Interrupt Pending */ +#define RV32M1_EU_INTPTSECURE_OFFSET 0x0010 /* Interrupt Secure */ +#define RV32M1_EU_INTPTPRI0_OFFSET 0x0014 /* Interrupt Priority 0 */ +#define RV32M1_EU_INTPTPRI1_OFFSET 0x0018 /* Interrupt Priority 1 */ +#define RV32M1_EU_INTPTPRI2_OFFSET 0x001c /* Interrupt Priority 2 */ +#define RV32M1_EU_INTPTPRI3_OFFSET 0x0020 /* Interrupt Priority 3 */ +#define RV32M1_EU_INTPTBASE_OFFSET 0x0024 /* Interrupt Priority Base */ +#define RV32M1_EU_INTPTENACTIVE_OFFSET 0x0028 /* Interrupt Active */ +#define RV32M1_EU_INTACTPRI0_OFFSET 0x002c /* Interrupt Active Priority 0 */ +#define RV32M1_EU_INTACTPRI1_OFFSET 0x0030 /* Interrupt Active Priority 1 */ +#define RV32M1_EU_INTACTPRI2_OFFSET 0x0034 /* Interrupt Active Priority 2 */ +#define RV32M1_EU_INTACTPRI3_OFFSET 0x0038 /* Interrupt Active Priority 2 */ +#define RV32M1_EU_EVENTEN_OFFSET 0x0040 /* Event Enable */ +#define RV32M1_EU_EVENTPEND_OFFSET 0x0044 /* Event Pending */ +#define RV32M1_EU_EVTPENDSET_OFFSET 0x0048 /* Set Event Pending */ +#define RV32M1_EU_EVTPENDCLR_OFFSET 0x004c /* Clear Event Pending */ +#define RV32M1_EU_SLPCTRL_OFFSET 0x0080 /* Sleep Control */ +#define RV32M1_EU_SLPSTAT_OFFST 0x0084 /* Sleep Status */ + +/* Register Addresses *******************************************************/ + +#define RV32M1_EU_INTPTEN (RV32M1_EU_BASE + RV32M1_EU_INTPTEN_OFFSET) +#define RV32M1_EU_INTPTPEND (RV32M1_EU_BASE + RV32M1_EU_INTPTPEND_OFFSET) +#define RV32M1_EU_INTPTPENDSET (RV32M1_EU_BASE + RV32M1_EU_INTPTPENDSET_OFFSET) +#define RV32M1_EU_INTPTPENDCLR (RV32M1_EU_BASE + RV32M1_EU_INTPTPENDCLR_OFFSET) +#define RV32M1_EU_INTPTSECURE (RV32M1_EU_BASE + RV32M1_EU_INTPTSECURE_OFFSET) +#define RV32M1_EU_INTPTPRI0 (RV32M1_EU_BASE + RV32M1_EU_INTPTPRI0_OFFSET) +#define RV32M1_EU_INTPTPRI1 (RV32M1_EU_BASE + RV32M1_EU_INTPTPRI1_OFFSET) +#define RV32M1_EU_INTPTPRI2 (RV32M1_EU_BASE + RV32M1_EU_INTPTPRI2_OFFSET) +#define RV32M1_EU_INTPTPRI3 (RV32M1_EU_BASE + RV32M1_EU_INTPTPRI3_OFFSET) +#define RV32M1_EU_INTPTBASE (RV32M1_EU_BASE + RV32M1_EU_INTPTBASE_OFFSET) +#define RV32M1_EU_INTPTENACTIVE (RV32M1_EU_BASE + RV32M1_EU_INTPTENACTIVE_OFFSET) +#define RV32M1_EU_INTACTPRI0 (RV32M1_EU_BASE + RV32M1_EU_INTACTPRI0_OFFSET) +#define RV32M1_EU_INTACTPRI1 (RV32M1_EU_BASE + RV32M1_EU_INTACTPRI1_OFFSET) +#define RV32M1_EU_INTACTPRI2 (RV32M1_EU_BASE + RV32M1_EU_INTACTPRI2_OFFSET) +#define RV32M1_EU_INTACTPRI3 (RV32M1_EU_BASE + RV32M1_EU_INTACTPRI3_OFFSET) +#define RV32M1_EU_EVENTEN (RV32M1_EU_BASE + RV32M1_EU_EVENTEN_OFFSET) +#define RV32M1_EU_EVENTPEND (RV32M1_EU_BASE + RV32M1_EU_EVENTPEND_OFFSET) +#define RV32M1_EU_EVTPENDSET (RV32M1_EU_BASE + RV32M1_EU_EVTPENDSET_OFFSET) +#define RV32M1_EU_EVTPENDCLR (RV32M1_EU_BASE + RV32M1_EU_EVTPENDCLR_OFFSET) +#define RV32M1_EU_SLPCTRL (RV32M1_EU_BASE + RV32M1_EU_SLPCTRL_OFFSET) +#define RV32M1_EU_SLPSTAT (RV32M1_EU_BASE + RV32M1_EU_SLPSTAT_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +#define EU_INTPTPRI_BITS (4) +#define EU_INTPTPRI0_SHIFT (0) +#define EU_INTPTPRI0_MASK (0x7 << EU_INTPTPRI0_SHIFT) + +#define EU_INTPRIBASE_IPBASE_SHIFT (0) +#define EU_INTPRIBASE_IPBASE_MASK (0xf << EU_INTPRIBASE_IPBASE_SHIFT) + +#define EU_SLPCTRL_SYSRSTREQST (1 << 31) + +#define EU_SLPCTRL_SLEEP_SHIFT (0) +#define EU_SLPCTRL_SLEEP_MASK (0x3 << EU_SLPCTRL_SLEEP_SHIFT) +#define EU_SLPCTRL_SLEEP (0x1 << EU_SLPCTRL_SLEEP_SHIFT) +#define EU_SLPCTRL_DEEP_SLEEP (0x2 << EU_SLPCTRL_SLEEP_SHIFT) + +#define EU_SLPSTAT_SLEEP_SHIFT (0) +#define EU_SLPSTAT_SLEEP_MASK (0x3 << EU_SLPSTAT_SLEEP_SHIFT) +#define EU_SLPSTAT_SLEEP (0x1 << EU_SLPSTAT_SLEEP_SHIFT) +#define EU_SLPSTAT_DEEP_SLEEP (0x2 << EU_SLPSTAT_SLEEP_SHIFT) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_EU_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_gpio.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_gpio.h new file mode 100644 index 00000000000..6043cc40da5 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_gpio.h @@ -0,0 +1,39 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_gpio.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_GPIO_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_GPIO_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_GPIO_PDOR_OFFSET 0x0000 /* Port Data Output */ +#define RV32M1_GPIO_PSOR_OFFSET 0x0004 /* Port Set Output */ +#define RV32M1_GPIO_PCOR_OFFSET 0x0008 /* Port Clear Output */ +#define RV32M1_GPIO_PTOR_OFFSET 0x000c /* Port Toggle Output */ +#define RV32M1_GPIO_PDIR_OFFSET 0x0010 /* Port Data Input */ +#define RV32M1_GPIO_PDDR_OFFSET 0x0014 /* Port Data Direction */ + +/* Register Bitfield Definitions ********************************************/ + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_GPIO_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_intmux.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_intmux.h new file mode 100644 index 00000000000..a608017f90e --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_intmux.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_intmux.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_INTMUX_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_INTMUX_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_INTMUX_CH0_CSR_OFFSET 0x0000 /* Control Status */ +#define RV32M1_INTMUX_CH0_VEC_OFFSET 0x0004 /* Vector Number */ +#define RV32M1_INTMUX_CH0_IER_OFFSET 0x0010 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH0_IPR_OFFSET 0x0020 /* Interrupt Pending */ +#define RV32M1_INTMUX_CH1_CSR_OFFSET 0x0040 /* Control Status */ +#define RV32M1_INTMUX_CH1_VEC_OFFSET 0x0044 /* Vector Number */ +#define RV32M1_INTMUX_CH1_IER_OFFSET 0x0050 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH1_IPR_OFFSET 0x0060 /* Interrupt Pending */ +#define RV32M1_INTMUX_CH2_CSR_OFFSET 0x0080 /* Control Status */ +#define RV32M1_INTMUX_CH2_VEC_OFFSET 0x0084 /* Vector Number */ +#define RV32M1_INTMUX_CH2_IER_OFFSET 0x0090 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH2_IPR_OFFSET 0x00a0 /* Interrupt Pending */ +#define RV32M1_INTMUX_CH3_CSR_OFFSET 0x00c0 /* Control Status */ +#define RV32M1_INTMUX_CH3_VEC_OFFSET 0x00c4 /* Vector Number */ +#define RV32M1_INTMUX_CH3_IER_OFFSET 0x00d0 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH3_IPR_OFFSET 0x00e0 /* Interrupt Pending */ +#define RV32M1_INTMUX_CH4_CSR_OFFSET 0x0100 /* Control Status */ +#define RV32M1_INTMUX_CH4_VEC_OFFSET 0x0104 /* Vector Number */ +#define RV32M1_INTMUX_CH4_IER_OFFSET 0x0110 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH4_IPR_OFFSET 0x0120 /* Interrupt Pending */ +#define RV32M1_INTMUX_CH5_CSR_OFFSET 0x0140 /* Control Status */ +#define RV32M1_INTMUX_CH5_VEC_OFFSET 0x0144 /* Vector Number */ +#define RV32M1_INTMUX_CH5_IER_OFFSET 0x0150 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH5_IPR_OFFSET 0x0160 /* Interrupt Pending */ +#define RV32M1_INTMUX_CH6_CSR_OFFSET 0x0180 /* Control Status */ +#define RV32M1_INTMUX_CH6_VEC_OFFSET 0x0184 /* Vector Number */ +#define RV32M1_INTMUX_CH6_IER_OFFSET 0x0190 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH6_IPR_OFFSET 0x01a0 /* Interrupt Pending */ +#define RV32M1_INTMUX_CH7_CSR_OFFSET 0x01c0 /* Control Status */ +#define RV32M1_INTMUX_CH7_VEC_OFFSET 0x01c4 /* Vector Number */ +#define RV32M1_INTMUX_CH7_IER_OFFSET 0x01d0 /* Interrupt Enable */ +#define RV32M1_INTMUX_CH7_IPR_OFFSET 0x01e0 /* Interrupt Pending */ + +#define INTMUX_CH_CSR_OFFSET 0x0000 /* Control Status */ +#define INTMUX_CH_VEC_OFFSET 0x0004 /* Vector Number */ +#define INTMUX_CH_IER_OFFSET 0x0010 /* Interrupt Enable */ +#define INTMUX_CH_IPR_OFFSET 0x0020 /* Interrupt Pending */ + +/* Register Address *********************************************************/ + +#define RV32M1_INTMUX0_CH_BASE(n) (RV32M1_INTMUX0_BASE + n * 0x40) +# define RV32M1_INTMUX_CH_BASE RV32M1_INTMUX0_CH_BASE + +/* Register Bitfield Definitions ********************************************/ + +#define INTMUX_CSR_IRQP (1 << 31) /* Bit31: Interrupt Request Pending */ +#define INTMUX_CSR_CHIN_SHIFT (8) /* Bit[11:8]: Channel Instance Number */ +#define INTMUX_CSR_CHIN_MASK (0xf << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN0 (0 << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN1 (1 << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN2 (2 << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN3 (3 << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN4 (4 << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN5 (5 << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN6 (6 << INTMUX_CSR_CHIN_SHIFT) +#define INTMUX_CSR_CHIN7 (7 << INTMUX_CSR_CHIN_SHIFT) + +#define INTMUX_CSR_IRQN_SHIFT (4) +#define INTMUX_CSR_IRQN_MASK (3 << INTMUX_CSR_IRQN_SHIFT) + +#define INTMUX_CSR_AND (1 << 1) +#define INTMUX_CSR_RST (1 << 0) + +#define INTMUX_VEC_VECN_SHIFT (2) +#define INTMUX_VEC_VECN_MASK (0xfff << INTMUX_VEC_VECN_SHIFT) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_INTMUX_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_lpit.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_lpit.h new file mode 100644 index 00000000000..d4b784cc2c4 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_lpit.h @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_lpit.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPIT_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPIT_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_LPIT_VERID_OFFSET 0x0000 /* Version ID */ +#define RV32M1_LPIT_PARAM_OFFSET 0x0004 /* Parameter */ +#define RV32M1_LPIT_MCR_OFFSET 0x0008 /* Module Control */ +#define RV32M1_LPIT_MSR_OFFSET 0x000c /* Module Status Register */ +#define RV32M1_LPIT_MIER_OFFSET 0x0010 /* Moduel Interrupt Enable */ +#define RV32M1_LPIT_SETTEN_OFFSET 0x0014 /* Set Timer Enable */ +#define RV32M1_LPIT_CLRTEN_OFFSET 0x0018 /* Clear Timer Enable */ +#define RV32M1_LPIT_TVAL0_OFFSET 0x0020 /* Timer Channel 0 Value */ +#define RV32M1_LPIT_CVAL0_OFFSET 0x0024 /* Current Timer Channel 0 Value */ +#define RV32M1_LPIT_TCTRL0_OFFSET 0x0028 /* Timer Channel 0 Control */ +#define RV32M1_LPIT_TVAL1_OFFSET 0x0030 /* Timer Channel 1 Value */ +#define RV32M1_LPIT_CVAL1_OFFSET 0x0034 /* Current Timer Channel 1 Value */ +#define RV32M1_LPIT_TCTRL1_OFFSET 0x0048 /* Timer Channel 1 Control */ +#define RV32M1_LPIT_TVAL2_OFFSET 0x0040 /* Timer Channel 2 Value */ +#define RV32M1_LPIT_CVAL2_OFFSET 0x0044 /* Current Timer Channel 2 Value */ +#define RV32M1_LPIT_TCTRL2_OFFSET 0x0048 /* Timer Channel 2 Control */ +#define RV32M1_LPIT_TVAL3_OFFSET 0x0050 /* Timer Channel 3 Value */ +#define RV32M1_LPIT_CVAL3_OFFSET 0x0054 /* Current Timer Channel 3 Value */ +#define RV32M1_LPIT_TCTRL3_OFFSET 0x0058 /* Timer Channel 3 Control */ + +/* Register Bitfield Definitions ********************************************/ + +#define LPIT_PARAM_EXT_TRIG_SHIFT (8) /* Bit[15:8]: Number of External Trigger Inputs */ +#define LPIT_PARAM_EXT_TRIG_MASK (0xff << LPIT_PARAM_EXT_TRIG_SHIFT) + +#define LPIT_PARAM_CHANNEL_SHIFT (0) /* Bit[7:0]: Number of Timer Channels */ +#define LPIT_PARAM_CHANNEL_MASK (0xff << LPIT_PARAM_CHANNEL_SHIFT) + +#define LPIT_MCR_DBG_EN (1 << 3) /* Stop Timer when in Debug Mode */ +#define LPIT_MCR_DOZE_EN (1 << 2) /* DOZE Mode Enable */ +#define LPIT_MCR_SW_RST (1 << 1) /* Software Reset Bit */ +#define LPIT_MCR_M_CEN (1 << 0) /* Module Clock Enable */ + +#define LPIT_MSR_TIF3 (1 << 3) /* Channel 3 Timer Interrupt Flag */ +#define LPIT_MSR_TIF2 (1 << 2) /* Channel 2 Timer Interrupt Flag */ +#define LPIT_MSR_TIF1 (1 << 1) /* Channel 1 Timer Interrupt Flag */ +#define LPIT_MSR_TIF0 (1 << 0) /* Channel 0 Timer Interrupt Flag */ + +#define LPIT_MIER_TIE3 (1 << 3) /* Channel 3 Timer Interrupt Enable */ +#define LPIT_MIER_TIE2 (1 << 2) /* Channel 2 Timer Interrupt Enable */ +#define LPIT_MIER_TIE1 (1 << 1) /* Channel 1 Timer Interrupt Enable */ +#define LPIT_MIER_TIE0 (1 << 0) /* Channel 0 Timer Interrupt Enable */ + +#define LPIT_TCTRL_TRG_SEL_SHIFT (27) /* Bit[27:24]: Trigger Select */ +#define LPIT_TCTRL_TRG_SEL_MASK (0xf << LPIT_TCTRL_TRG_SEL_SHIFT) +#define LPIT_TCTRL_TRG_SEL_CHAN0 (0 << LPIT_TCTRL_TRG_SEL_SHIFT) +#define LPIT_TCTRL_TRG_SEL_CHAN1 (1 << LPIT_TCTRL_TRG_SEL_SHIFT) +#define LPIT_TCTRL_TRG_SEL_CHAN2 (2 << LPIT_TCTRL_TRG_SEL_SHIFT) +#define LPIT_TCTRL_TRG_SEL_CHAN3 (3 << LPIT_TCTRL_TRG_SEL_SHIFT) + +#define LPIT_TCTRL_TRG_SRC_SHIFT (23) /* Bit23: Trigger Source */ +#define LPIT_TCTRL_TRG_SRC_MASK (1 << LPIT_TCTRL_TRG_SRC_SHIFT) +#define LPIT_TCTRL_TRG_SRC_EXTER (0 << LPIT_TCTRL_TRG_SRC_SHIFT) /* external */ +#define LPIT_TCTRL_TRG_SRC_INTER (1 << LPIT_TCTRL_TRG_SRC_SHIFT) /* internal */ + +#define LPIT_TCTRL_TROT (1 << 18) /* Timer Reload On Trigger */ +#define LPIT_TCTRL_TSOI (1 << 17) /* Timer Stop On Interrupt */ +#define LPIT_TCTRL_TSOT (1 << 16) /* Timer Start On Trigger */ + +#define LPIT_TCTRL_MODE_SHIFT (2) +#define LPIT_TCTRL_MODE_MASK (3 << LPIT_TCTRL_MODE_SHIFT) +#define LPIT_TCTRL_MODE_32PC (0 << LPIT_TCTRL_MODE_SHIFT) /* 32 Bit periodic Counter */ +#define LPIT_TCTRL_MODE_D16PC (1 << LPIT_TCTRL_MODE_SHIFT) /* Dual 16-bit periodic Counter */ +#define LPIT_TCTRL_MODE_32TA (2 << LPIT_TCTRL_MODE_SHIFT) /* 32 bit Trigger Accumulator */ +#define LPIT_TCTRL_MODE_32TIC (3 << LPIT_TCTRL_MODE_SHIFT) /* 32 bit Trigger Input Capture */ + +#define LPIT_TCTRL_CHAIN (1 << 1) /* Chain Channel */ +#define LPIT_TCTRL_T_EN (1 << 0) /* Timer Enable */ + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPIT_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_lptmr.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_lptmr.h new file mode 100644 index 00000000000..4e386583264 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_lptmr.h @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_lptmr.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPTMR_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPTMR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_LPTMR_CSR_OFFSET 0x0000 /* Control Status */ +#define RV32M1_LPTMR_PSR_OFFSET 0x0004 /* Prescale */ +#define RV32M1_LPTMR_CMR_OFFSET 0x0008 /* Compare */ +#define RV32M1_LPTMR_CNR_OFFSET 0x000c /* Counter */ + +/* Register Address *********************************************************/ + +#define RV32M1_LPTMR0_CSR (RV32M1_LPTMR0_BASE + RV32M1_LPTMR_CSR_OFFSET) +#define RV32M1_LPTMR0_PSR (RV32M1_LPTMR0_BASE + RV32M1_LPTMR_PSR_OFFSET) +#define RV32M1_LPTMR0_CMR (RV32M1_LPTMR0_BASE + RV32M1_LPTMR_CMR_OFFSET) +#define RV32M1_LPTMR0_CNR (RV32M1_LPTMR0_BASE + RV32M1_LPTMR_CNR_OFFSET) + +#define RV32M1_LPTMR1_CSR (RV32M1_LPTMR1_BASE + RV32M1_LPTMR_CSR_OFFSET) +#define RV32M1_LPTMR1_PSR (RV32M1_LPTMR1_BASE + RV32M1_LPTMR_PSR_OFFSET) +#define RV32M1_LPTMR1_CMR (RV32M1_LPTMR1_BASE + RV32M1_LPTMR_CMR_OFFSET) +#define RV32M1_LPTMR1_CNR (RV32M1_LPTMR1_BASE + RV32M1_LPTMR_CNR_OFFSET) + +#define RV32M1_LPTMR2_CSR (RV32M1_LPTMR2_BASE + RV32M1_LPTMR_CSR_OFFSET) +#define RV32M1_LPTMR2_PSR (RV32M1_LPTMR2_BASE + RV32M1_LPTMR_PSR_OFFSET) +#define RV32M1_LPTMR2_CMR (RV32M1_LPTMR2_BASE + RV32M1_LPTMR_CMR_OFFSET) +#define RV32M1_LPTMR2_CNR (RV32M1_LPTMR2_BASE + RV32M1_LPTMR_CNR_OFFSET) + +#ifdef CONFIG_ARCH_CHIP_RV32M1_RI5CY +# define RV32M1_LPTMR_BASE RV32M1_LPTMR0_BASE +# define RV32M1_IRQ_LPTMR RV32M1_IRQ_LPTMR0 +#else +# define RV32M1_LPTMR_BASE RV32M1_LPTMR2_BASE +# define RV32M1_IRQ_LPTMR RV32M1_IRQ_LPTMR2 +#endif + +#define RV32M1_LPTMR_CSR (RV32M1_LPTMR_BASE + RV32M1_LPTMR_CSR_OFFSET) +#define RV32M1_LPTMR_PSR (RV32M1_LPTMR_BASE + RV32M1_LPTMR_PSR_OFFSET) +#define RV32M1_LPTMR_CMR (RV32M1_LPTMR_BASE + RV32M1_LPTMR_CMR_OFFSET) +#define RV32M1_LPTMR_CNR (RV32M1_LPTMR_BASE + RV32M1_LPTMR_CNR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +#define LPTMR_CSR_TDRE (1 << 8) /* Timer DMA Request Enable */ +#define LPTMR_CSR_TCF (1 << 7) /* Timer Compare Flag */ +#define LPTMR_CSR_TIE (1 << 6) /* Timer Interrupt Flag */ + +#define LPTMR_CSR_TPS_SHIFT (4) /* Bit[5:4]: Timer Pin Select */ +#define LPTMR_CSR_TPS_MASK (3 << LPTMR_CSR_TPS_SHIFT) +#define LPTMR_CSR_TPS0 (0 << LPTMR_CSR_TPS_SHIFT) +#define LPTMR_CSR_TPS1 (1 << LPTMR_CSR_TPS_SHIFT) +#define LPTMR_CSR_TPS2 (2 << LPTMR_CSR_TPS_SHIFT) +#define LPTMR_CSR_TPS3 (3 << LPTMR_CSR_TPS_SHIFT) + +#define LPTMR_CSR_TPP (1 << 3) /* Timer Pin Polarity */ +#define LPTMR_CSR_TFC (1 << 2) /* Timer Free-Running Counter */ +#define LPTMR_CSR_TMS (1 << 1) /* Timer Mode Select */ +#define LPTMR_CSR_TEN (1 << 0) /* Timer Enable */ + +#define LPTMR_PSR_PRESCALE_SHIFT (3) /* Bit[6:3]: Prescale Value */ +#define LPTMR_PSR_PRESCALE_MASK (0xf << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV2 (0 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV4 (1 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV8 (2 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV16 (3 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV32 (4 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV64 (5 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV128 (6 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV256 (7 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV512 (8 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV1024 (9 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV2048 (10 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV4096 (11 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV8192 (12 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV16384 (13 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV32768 (14 << LPTMR_PSR_PRESCALE_SHIFT) +#define LPTMR_PSR_PRESCALE_DIV65536 (15 << LPTMR_PSR_PRESCALE_SHIFT) + +#define LPTMR_PSR_PBYP (1 << 2) /* Prescaler Bypass */ + +#define LPTMR_PSR_PCS_SHIFT (0) /* Bit[1:0]: Prescaler Clock Select */ +#define LPTMR_PSR_PCS_MASK (3 << LPTMR_PSR_PCS_SHIFT) +#define LPTMR_PSR_PCS_SIRCDIV3 (0 << LPTMR_PSR_PCS_SHIFT) +#define LPTMR_PSR_PCS_LPO (1 << LPTMR_PSR_PCS_SHIFT) /* LPO 1K Hz */ +#define LPTMR_PSR_PCS_RTC (2 << LPTMR_PSR_PCS_SHIFT) /* RTC 32768 Hz */ +#define LPTMR_PSR_PCS_RFOSC (3 << LPTMR_PSR_PCS_SHIFT) /* */ +# define LPTMR_PSR_PCS_SOSC LPTMR_PSR_PCS_RFOSC + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPTMR_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_lpuart.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_lpuart.h new file mode 100644 index 00000000000..1f986f16946 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_lpuart.h @@ -0,0 +1,254 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_lpuart.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPUART_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPUART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_LPUART_VERID_OFFSET 0x0000 /* Version ID */ +#define RV32M1_LPUART_PARAM_OFFSET 0x0004 /* Parameter */ +#define RV32M1_LPUART_GLOBAL_OFFSET 0x0008 /* Global */ +#define RV32M1_LPUART_PINCFG_OFFSET 0x000c /* Pin Configuration */ +#define RV32M1_LPUART_BAUD_OFFSET 0x0010 /* Baud Rate */ +#define RV32M1_LPUART_STAT_OFFSET 0x0014 /* Status */ +#define RV32M1_LPUART_CTRL_OFFSET 0x0018 /* Control */ +#define RV32M1_LPUART_DATA_OFFSET 0x001c /* Data */ +#define RV32M1_LPUART_MATCH_OFFSET 0x0020 /* Match Address */ +#define RV32M1_LPUART_MODIR_OFFSET 0x0024 /* Modem IrDA */ +#define RV32M1_LPUART_FIFO_OFFSET 0x0028 /* FIFO */ +#define RV32M1_LPUART_WATER_OFFSET 0x002c /* Watermark */ + +/* Register Addresses *******************************************************/ + +/* Register Bitfield Definitions ********************************************/ + +#define LPUART_PARAM_RXFIFO_SHIFT (8) +#define LPUART_PARAM_RXFIFO_MASK (0xff << LPUART_PARAM_RXFIFO_SHIFT) + +#define LPUART_PARAM_TXFIFO_SHIFT (8) +#define LPUART_PARAM_TXFIFO_MASK (0xff << LPUART_PARAM_TXFIFO_SHIFT) + +#define LPUART_GLOBAL_RST (1 << 1) + +#define LPUART_PINCFG_TRGSEL_SHIFT (0) +#define LPUART_PINCFG_TRGSEL_MASK (3 << LPUART_PINCFG_TRGSEL_SHIFT) +#define LPUART_PINCFG_TRGSEL_DISABLED (0 << LPUART_PINCFG_TRGSEL_SHIFT) +#define LPUART_PINCFG_TRGSEL_RXD (1 << LPUART_PINCFG_TRGSEL_SHIFT) +#define LPUART_PINCFG_TRGSEL_CTS (2 << LPUART_PINCFG_TRGSEL_SHIFT) +#define LPUART_PINCFG_TRGSEL_MTX (3 << LPUART_PINCFG_TRGSEL_SHIFT) + +#define LPUART_BAUD_MAEN1 (1 << 31) /* Bit31: Match Address Mode Enable 1 */ +#define LPUART_BAUD_MAEN2 (1 << 30) /* Bit30: Match Address Mode Enable 2 */ +#define LPUART_BAUD_M10 (1 << 29) /* Bit29: 10-bit Mode select */ + +#define LPUART_BAUD_OSR_SHIFT (24) /* Bit[28:24]: Oversampling Ratio */ +#define LPUART_BAUD_OSR_MASK (0x1f << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_DEFAULT (0 << LPUART_BAUD_OSR_SHIFT) /* ratio of 16 */ +#define LPUART_BAUD_OSR_1_RESERVED (1 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_2_RESERVED (2 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_4 (3 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_5 (4 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_6 (5 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_7 (6 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_8 (7 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_9 (8 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_10 (9 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_11 (10 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_12 (11 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_13 (12 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_14 (13 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_15 (14 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_16 (15 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_17 (16 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_18 (17 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_19 (18 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_20 (19 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_21 (20 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_22 (21 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_23 (22 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_24 (23 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_25 (24 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_26 (25 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_27 (26 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_28 (27 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_29 (28 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_30 (29 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_31 (30 << LPUART_BAUD_OSR_SHIFT) +#define LPUART_BAUD_OSR_32 (31 << LPUART_BAUD_OSR_SHIFT) + +#define LPUART_BAUD_TDMAE (1 << 23) /* Bit23: Transmitter DMA Enable */ +#define LPUART_BAUD_RDMAE (1 << 21) /* Bit22: Receiver Full DMA Enable */ +#define LPUART_BAUD_RIDMAE (1 << 20) /* Bit20: Receiver Idle DMA Enable */ +#define LPUART_BAUD_MATCFG_SHIFT (18) /* Bit[19:18]: Match Configuration */ +#define LPUART_BAUD_MATCFG_MASK (0x3 << LPUART_BAUD_MATCFG_SHIFT) +#define LPUART_BAUD_MATCFG_ADDR (0 << LPUART_BAUD_MATCFG_SHIFT) /* Address Match Wakeup */ +#define LPUART_BAUD_MATCFG_IDLE (1 << LPUART_BAUD_MATCFG_SHIFT) /* Idle Match Wakeup */ +#define LPUART_BAUD_MATCFG_ONOFF (2 << LPUART_BAUD_MATCFG_SHIFT) /* Match On and Match Off */ +#define LPUART_BAUD_MATCFG_RWU (3 << LPUART_BAUD_MATCFG_SHIFT) + +#define LPUART_BAUD_BOTHEDGE (1 << 17) /* Bit17: Both Edge Sampling */ +#define LPUART_BAUD_RESYNCDIS (1 << 16) /* Bit16: Resynchronization Disable */ +#define LPUART_BAUD_LBKDIE (1 << 15) /* Bit15: LIN Break Detect Interrupt Enable */ +#define LPUART_BAUD_RXEDGIE (1 << 14) /* Bit14: RX Input Active Edge Interrupt Enable */ +#define LPUART_BAUD_SBNS (1 << 13) /* Bit13: Stop Bit Number Select */ +# define LPUART_BAUD_SBNS_MASK (1 << 13) +# define LPUART_BAUD_SBNS_1 (0 << 13) +# define LPUART_BAUD_SBNS_2 (1 << 13) + +#define LPUART_BAUD_SBR_SHIFT (0) /* Bit[12:0]: Baud Rate Modulo Divisor */ +#define LPUART_BAUD_SBR_MASK (0x1fff << LPUART_BAUD_SBR_SHIFT) + +#define LPUART_STAT_LBKDIF (1 << 31) /* Bit31: LIN Break Detect Interrupt Flag */ +#define LPUART_STAT_RXEDGIF (1 << 30) /* Bit30: RXD Pin Active Edge Interrupt Flag */ +#define LPUART_STAT_MSBF (1 << 29) /* Bit29: MSB First */ +#define LPUART_STAT_RXINV (1 << 28) /* Bit28: Receive Data Inversion */ +#define LPUART_STAT_RWUID (1 << 27) /* Bit27: Receive Wake Up Idel Detect */ +#define LPUART_STAT_BRK13 (1 << 26) /* Bit26: Break Character Generation Length */ +#define LPUART_STAT_LBKDE (1 << 25) /* Bit25: Lin Break Detection Enable */ +#define LPUART_STAT_RAF (1 << 24) /* Bit24: Receiver Active Flag */ +#define LPUART_STAT_TDRE (1 << 23) /* Bit23: Transmit Data Register Empty Flag */ +#define LPUART_STAT_TC (1 << 22) /* Bit22: Transmission Complete Flag */ +#define LPUART_STAT_RDRF (1 << 21) /* Bit21: Receive Data Register Full Flag */ +#define LPUART_STAT_IDLE (1 << 20) /* Bit20: Idle Line Flag */ +#define LPUART_STAT_OR (1 << 19) /* Bit19: Receiver Overrun Flag */ +#define LPUART_STAT_NF (1 << 18) /* Bit18: Noise Flag */ +#define LPUART_STAT_FE (1 << 17) /* Bit17: Framing Error Flag */ +#define LPUART_STAT_PF (1 << 16) /* Bit16: Parity Error Flag */ +#define LPUART_STAT_MA1F (1 << 15) /* Bit15: Match 1 Flag */ +#define LPUART_STAT_MA2F (1 << 14) /* Bit14: Match 2 Flag */ + +#define LPUART_CTRL_R8T9 (1 << 31) /* Bit31: Receive Bit 8/Transmit Bit 9 */ +#define LPUART_CTRL_R9T8 (1 << 30) /* Bit30: Receive Bit 9/Transmit Bit 8 */ +#define LPUART_CTRL_TXDIR (1 << 29) /* Bit29: TXD Pin Direction In Single-Wire Mode */ +#define LPUART_CTRL_TXINV (1 << 28) /* Bit28: Transmit Data Inversion */ +#define LPUART_CTRL_ORIE (1 << 27) /* Bit27: Overrun Interrupt Enable */ +#define LPUART_CTRL_NEIE (1 << 26) /* Bit26: Noise Error Interrupt Enable */ +#define LPUART_CTRL_FEIE (1 << 25) /* Bit25: Framing Error Interrupt Enable */ +#define LPUART_CTRL_PEIE (1 << 24) /* Bit24: Parity Error Interrupt Enable */ +#define LPUART_CTRL_TIE (1 << 23) /* Bit23: Enable Interrupt if TDRE is 1 */ +#define LPUART_CTRL_TCIE (1 << 22) /* Bit22: Enable Interrupt if TC is 1 */ +#define LPUART_CTRL_RIE (1 << 21) /* Bit21: Receiver Interrupt Enable */ +#define LPUART_CTRL_ILIE (1 << 20) /* Bit20: Idle Line Interrupt Enable */ +#define LPUART_CTRL_TE (1 << 19) /* Bit19: Transmitter Enable */ +#define LPUART_CTRL_RE (1 << 18) /* Bit18: Receiver Enable */ +#define LPUART_CTRL_RWU (1 << 17) /* Bit17: Receiver Wakeup Control */ +#define LPUART_CTRL_SBK (1 << 16) /* Bit16: Send Break */ +#define LPUART_CTRL_MA1IE (1 << 15) /* Bit15: Match 1 Interrupt Enable */ +#define LPUART_CTRL_MA21E (1 << 14) /* Bit14: Match 2 Interrupt Enable */ +#define LPUART_CTRL_M7 (1 << 11) /* Bit11: 7-Bit Mode Select */ + +#define LPUART_CTRL_IDLECFG_SHIFT (8) /* Bit[10:8]: Idle Configuration */ +#define LPUART_CTRL_IDLECFG_MASK (0x7 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_1 (0 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_2 (1 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_4 (2 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_8 (3 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_16 (4 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_32 (5 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_64 (6 << LPUART_CTRL_IDLECFG_SHIFT) +#define LPUART_CTRL_IDLECFG_128 (7 << LPUART_CTRL_IDLECFG_SHIFT) + +#define LPUART_CTRL_LOOPS (1 << 7) /* Bit7: Loop Mode Select */ +#define LPUART_CTRL_DOZEEN (1 << 6) /* Bit6: Doze Enable */ +#define LPUART_CTRL_RSRC (1 << 5) /* Bit5: Receiver Source Select */ +#define LPUART_CTRL_M (1 << 4) /* Bit4: 9-Bit or 8-Bit Mode Select */ +# define LPUART_CTRL_M_MASK (1 << 4) +# define LPUART_CTRL_M8 (0 << 4) /* 8-Bit Mode */ +# define LPUART_CTRL_M9 (1 << 4) /* 9-Bit Mode */ + +#define LPUART_CTRL_WAKE_SHIFT (1 << 3) /* Bit3: Receiver Wakeup Method Select */ +#define LPUART_CTRL_WAKE_MASK (1 << LPUART_CTRL_WAKE_SHIFT) +#define LPUART_CTRL_WAKE_IDLE (0 << LPUART_CTRL_WAKE_SHIFT) +#define LPUART_CTRL_WAKE_ADRM (1 << LPUART_CTRL_WAKE_SHIFT) + +#define LPUART_CTRL_ILT (1 << 2) +#define LPUART_CTRL_PE (1 << 1) /* Bit1: Parity Enable */ + +#define LPUART_CTRL_PT_SHIFT (0) /* Bit0: Parity Type */ +#define LPUART_CTRL_PT_MASK (1 << LPUART_CTRL_PT_SHIFT) +#define LPUART_CTRL_PT_EVEN (0 << LPUART_CTRL_PT_SHIFT) +#define LPUART_CTRL_PT_ODD (1 << LPUART_CTRL_PT_SHIFT) + +#define LPUART_DATA_NOISY (1 << 15) /* Bit15: NOISY */ +#define LPUART_DATA_PARITYE (1 << 14) /* Bit14: Parity Error */ +#define LPUART_DATA_FRETSC (1 << 13) /* Bit13: Frame Error/Transmit Special Character */ +#define LPUART_DATA_RXEMPT (1 << 12) /* Bit12: Receive Buffer Empty */ +#define LPUART_DATA_IDLINE (1 << 11) /* Bit11: Idle Line */ + +#define LPUART_MATCH_MA2_SHIFT (16) +#define LPUART_MATCH_MA2_MASK (0x3ff << LPUART_MATCH_MA2_SHIFT) + +#define LPUART_MATCH_MA1_SHIFT (0) +#define LPUART_MATCH_MA1_MASK (0x3ff << LPUART_MATCH_MA1_SHIFT) + +/* REVISIT: MODIR */ + +#define LPUART_FIFO_TXEMPT (1 << 23) /* Bit23: TX Buffer/FIFO Empty */ +#define LPUART_FIFO_RXEMPT (1 << 22) /* Bit22: RX Buffer/FIFO Empty */ +#define LPUART_FIFO_TXOF (1 << 17) /* Bit17: TX Buffer Overflow */ +#define LPUART_FIFO_RXUF (1 << 16) /* Bit16: RX Buffer Underflow */ +#define LPUART_FIFO_TXFLUSH (1 << 15) /* Bit15: TX Buffer/FIFO Flush */ +#define LPUART_FIFO_RXFLUSH (1 << 14) /* Bit14: RX Buffer/FIFO Flush */ + +#define LPUART_FIFO_RXIDEN_SHIFT (10) /* Bit[12:10]: Receiver Idle Empty Enable */ +#define LPUART_FIFO_RXIDEN_MASK (0x7 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_DISABLED (0 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_RXRF1 (1 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_RXRF2 (2 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_RXRF4 (3 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_RXRF8 (4 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_RXRF16 (5 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_RXRF32 (6 << LPUART_FIFO_RXIDEN_SHIFT) +#define LPUART_FIFO_RXIDEN_RXRF64 (7 << LPUART_FIFO_RXIDEN_SHIFT) + +#define LPUART_FIFO_TXOFE (1 << 9) /* Bit9: TX FIFO Overflow Interrupt */ +#define LPUART_FIFO_RXUFE (1 << 8) /* Bit8: RXUF generate an Interrupt */ +#define LPUART_FIFO_TXFE (1 << 7) /* Bit7: TX FIFO Enable */ + +#define LPUART_FIFO_TXFIFOSIZE_SHIFT (4) /* Bit[6:4]: TX FIFO Depth */ +#define LPUART_FIFO_TXFIFOSIZE_MASK (0x7 << LPUART_FIFO_TXFIFOSIZE_SHIFT) + +#define LPUART_FIFO_RXFE (1 << 3) /* Bit3: RX FIFO Enable */ + +#define LPUART_FIFO_RXFIFOSIZE_SHIFT (0) /* Bit[2:0]: RX FIFO Depth */ +#define LPUART_FIFO_RXFIFOSIZE_MASK (0x7 << LPUART_FIFO_RXFIFOSIZE_SHIFT) + +#define LPUART_WATER_RXCOUNT_SHIFT (24) /* Bit[27:24]: Receive Counter */ +#define LPUART_WATER_RXCOUNT_MASK (0xf << LPUART_WATER_RXCOUNT_SHIFT) + +#define LPUART_WATER_RXWATER_SHIFT (16) /* Bit[18:16]: Receive Watermark */ +#define LPUART_WATER_RXWATER_MASK (0x7 << LPUART_WATER_RXWATER_SHIFT) + +#define LPUART_WATER_TXCOUNT_SHIFT (8) /* Bit[11:8]: Transmit Counter */ +#define LPUART_WATER_TXCOUNT_MASK (0xf << LPUART_WATER_TXCOUNT_SHIFT) + +#define LPUART_WATER_TXWATER_SHIFT (0) /* Bit[2:0]: Transmit Watermark */ +#define LPUART_WATER_TXWATER_MASK (0x7 << LPUART_WATER_TXWATER_SHIFT) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_LPUART_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_memorymap.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_memorymap.h new file mode 100644 index 00000000000..b545771dbda --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_memorymap.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_memorymap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_MEMORYMAP_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_RV32M1_RI5CY) +# include "rv32m1ri5cy_memorymap.h" +#elif defined(CONFIG_ARCH_CHIP_RV32M1_ZERORISCY) +# error "rv32m1 zero-riscy is to be continued..." +#else +# error "Unspported rv32m1 cortex-m cores" +#endif + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_MEMORYMAP_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_pcc.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_pcc.h new file mode 100644 index 00000000000..cd133b063af --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_pcc.h @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_pcc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PCC_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PCC_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_PCC0_LPIT0_OFFSET 0x00c0 +#define RV32M1_PCC0_LPUART0_OFFSET 0x0108 +#define RV32M1_PCC0_LPUART1_OFFSET 0x010c +#define RV32M1_PCC0_LPUART2_OFFSET 0x0110 +#define RV32M1_PCC0_PORTA_OFFSET 0x0118 +#define RV32M1_PCC0_PORTB_OFFSET 0x011c +#define RV32M1_PCC0_PORTC_OFFSET 0x0120 +#define RV32M1_PCC0_PORTD_OFFSET 0x0124 +#define RV32M1_PCC0_INTMUX0_OFFSET 0x013c + +#define RV32M2_PCC1_DMA1_OFFSET 0x0020 +#define RV32M1_PCC1_GPIOE_OFFSET 0x003c +#define RV32M1_PCC1_XRDC_PAC_OFFSET 0x0058 +#define RV32M1_PCC1_XRDC_MRC_OFFSET 0x005c +#define RV32M1_PCC1_SEMA42_1_OFFSET 0x006c +#define RV32M1_PCC1_DMAMUX1_OFFSET 0x0084 +#define RV32M1_PCC1_INTMUX1_OFFSET 0x0088 +#define RV32M1_PCC1_MUB_OFFSET 0x0090 +#define RV32M1_PCC1_CAU3_OFFSET 0x00a0 +#define RV32M1_PCC1_TRNG_OFFSET 0x00a4 +#define RV32M1_PCC1_LPIT1_OFFSET 0x00a8 +#define RV32M1_PCC1_TPM3_OFFSET 0x00b4 +#define RV32M1_PCC1_LPI2C3_OFFSET 0x00b8 +#define RV32M1_PCC1_LPSPI3_OFFSET 0x00d4 +#define RV32M1_PCC1_LPUART3_OFFSET 0x00d8 +#define RV32M1_PCC1_PORTE_OFFSET 0x00dc +#define RV32M1_PCC1_MTB_OFFSET 0x0200 +#define RV32M1_PCC1_EXT_CLK_OFFSET 0x0204 + +/* PCC0 Register Addresses **************************************************/ + +#define RV32M1_PCC_LPIT0 (RV32M1_PCC0_BASE + RV32M1_PCC0_LPIT0_OFFSET) +#define RV32M1_PCC_LPUART0 (RV32M1_PCC0_BASE + RV32M1_PCC0_LPUART0_OFFSET) +#define RV32M1_PCC_LPUART1 (RV32M1_PCC0_BASE + RV32M1_PCC0_LPUART1_OFFSET) +#define RV32M1_PCC_LPUART2 (RV32M1_PCC0_BASE + RV32M1_PCC0_LPUART2_OFFSET) +#define RV32M1_PCC_PORTA (RV32M1_PCC0_BASE + RV32M1_PCC0_PORTA_OFFSET) +#define RV32M1_PCC_PORTB (RV32M1_PCC0_BASE + RV32M1_PCC0_PORTB_OFFSET) +#define RV32M1_PCC_PORTC (RV32M1_PCC0_BASE + RV32M1_PCC0_PORTC_OFFSET) +#define RV32M1_PCC_PORTD (RV32M1_PCC0_BASE + RV32M1_PCC0_PORTD_OFFSET) +#define RV32M1_PCC_INTMUX0 (RV32M1_PCC0_BASE + RV32M1_PCC0_INTMUX0_OFFSET) + +/* PCC1 Register Addresses **************************************************/ + +#define RV32M1_PCC_DMA1 (RV32M1_PCC1_BASE + RV32M1_PCC1_DMA1_OFFSET) +#define RV32M1_PCC_GPIOE (RV32M1_PCC1_BASE + RV32M1_PCC1_GPIOE_OFFSET) +#define RV32M1_PCC_XRDC_PAC (RV32M1_PCC1_BASE + RV32M1_PCC1_XRDC_PAC_OFFSET) +#define RV32M1_PCC_XRDC_MRC (RV32M1_PCC1_BASE + RV32M1_PCC1_XRDC_MRC_OFFSET) +#define RV32M1_PCC_SEMA42_1 (RV32M1_PCC1_BASE + RV32M1_PCC1_SEMA42_1_OFFSET) +#define RV32M1_PCC_DMAMUX1 (RV32M1_PCC1_BASE + RV32M1_PCC1_DMAMUX1_OFFSET) +#define RV32M1_PCC_INTMUX1 (RV32M1_PCC1_BASE + RV32M1_PCC1_INTMUX1_OFFSET) +#define RV32M1_PCC_MUB (RV32M1_PCC1_BASE + RV32M1_PCC1_MUB_OFFSET) +#define RV32M1_PCC_CAU3 (RV32M1_PCC1_BASE + RV32M1_PCC1_CAU3_OFFSET) +#define RV32M1_PCC_TRNG (RV32M1_PCC1_BASE + RV32M1_PCC1_TRNG_OFFSET) +#define RV32M1_PCC_LPIT1 (RV32M1_PCC1_BASE + RV32M1_PCC1_LPIT1_OFFSET) +#define RV32M1_PCC_TPM3 (RV32M1_PCC1_BASE + RV32M1_PCC1_TPM3_OFFSET) +#define RV32M1_PCC_LPI2C3 (RV32M1_PCC1_BASE + RV32M1_PCC1_LPI2C3_OFFSET) +#define RV32M1_PCC_LPSPI3 (RV32M1_PCC1_BASE + RV32M1_PCC1_LPSPI3_OFFSET) +#define RV32M1_PCC_LPUART3 (RV32M1_PCC1_BASE + RV32M1_PCC1_LPUART3_OFFSET) +#define RV32M1_PCC_PORTE (RV32M1_PCC1_BASE + RV32M1_PCC1_PORTE_OFFSET) +#define RV32M1_PCC_MTB (RV32M1_PCC1_BASE + RV32M1_PCC1_MTB_OFFSET) +#define RV32M1_PCC_EXT_CLK (RV32M1_PCC1_BASE + RV32M1_PCC1_EXT_CLK_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +#define PCC_CLKCFG_PCD_SHIFT (0) +#define PCC_CLKCFG_PCD_MASK (7 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV1 (0 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV2 (1 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV3 (2 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV4 (3 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV5 (4 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV6 (5 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV7 (6 << PCC_CLKCFG_PCD_SHIFT) +#define PCC_CLKCFG_PCD_DIV8 (7 << PCC_CLKCFG_PCD_SHIFT) + +#define PCC_CLKCFG_FRAC (1 << 3) + +#define PCC_CLKCFG_PCS_SHIFT (24) +#define PCC_CLKCFG_PCS_MASK (7 << PCC_CLKCFG_PCS_SHIFT) +#define PCC_CLKCFG_PCS_EXTCLK (0 << PCC_CLKCFG_PCS_SHIFT) +#define PCC_CLKCFG_PCS_SOSC (1 << PCC_CLKCFG_PCS_SHIFT) +#define PCC_CLKCFG_PCS_SIRC (2 << PCC_CLKCFG_PCS_SHIFT) +#define PCC_CLKCFG_PCS_FIRC (3 << PCC_CLKCFG_PCS_SHIFT) +#define PCC_CLKCFG_PCS_LPFLL (6 << PCC_CLKCFG_PCS_SHIFT) + +#define PCC_CLKCFG_INUSE (1 << 29) + +#define PCC_CLKCFG_CGC (1 << 30) /* Bit30: Clock Gate Control */ + +#define PCC_CLKCFG_PR (1 << 31) /* Bit31: Present */ + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PCC_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_pinmap.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_pinmap.h new file mode 100644 index 00000000000..5d7a030ca14 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_pinmap.h @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_pinmap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PINMAP_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PINMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LPUARTs */ + +#define GPIO_LPUART0_RX_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN7) +#define GPIO_LPUART0_RX_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN25) +#define GPIO_LPUART0_RX_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2) +#define GPIO_LPUART0_TX_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN8) +#define GPIO_LPUART0_TX_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN26) +#define GPIO_LPUART0_TX_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3) +#define GPIO_LPUART0_RTS_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN10) +#define GPIO_LPUART0_RTS_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN24) +#define GPIO_LPUART0_RTS_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN4) +#define GPIO_LPUART0_CTS_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN9) +#define GPIO_LPUART0_CTS_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN22) +#define GPIO_LPUART0_CTS_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN1) + +#define GPIO_LPUART1_RX_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN2) +#define GPIO_LPUART1_RX_2 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN29) +#define GPIO_LPUART1_RX_3 (GPIO_ALT|GPIO_AF4|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN2) +#define GPIO_LPUART1_RX_4 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN25) +#define GPIO_LPUART1_TX_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN3) +#define GPIO_LPUART1_TX_2 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTC|GPIO_PIN30) +#define GPIO_LPUART1_TX_3 (GPIO_ALT|GPIO_AF4|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN3) +#define GPIO_LPUART1_TX_4 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN26) +#define GPIO_LPUART1_RTS_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN5) +#define GPIO_LPUART1_RTS_2 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN1) +#define GPIO_LPUART1_RTS_3 (GPIO_ALT|GPIO_AF4|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN4) +#define GPIO_LPUART1_RTS_4 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN28) +#define GPIO_LPUART1_CTS_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN4) +#define GPIO_LPUART1_CTS_2 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTD|GPIO_PIN0) +#define GPIO_LPUART1_CTS_3 (GPIO_ALT|GPIO_AF4|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN1) +#define GPIO_LPUART1_CTS_4 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN27) + +#define GPIO_LPUART2_RX_1 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN11) +#define GPIO_LPUART2_RX_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN18) +#define GPIO_LPUART2_RX_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN1) +#define GPIO_LPUART2_TX_1 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN12) +#define GPIO_LPUART2_TX_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN19) +#define GPIO_LPUART2_TX_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN0) +#define GPIO_LPUART2_RTS_1 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN14) +#define GPIO_LPUART2_RTS_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN21) +#define GPIO_LPUART2_RTS_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN31) +#define GPIO_LPUART2_CTS_1 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN13) +#define GPIO_LPUART2_CTS_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN20) +#define GPIO_LPUART2_CTS_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTA|GPIO_PIN30) + +#define GPIO_LPUART3_RX_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN28) +#define GPIO_LPUART3_RX_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN8) +#define GPIO_LPUART3_RX_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN29) +#define GPIO_LPUART3_TX_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN29) +#define GPIO_LPUART3_TX_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN9) +#define GPIO_LPUART3_TX_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN30) +#define GPIO_LPUART3_RTS_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN17) +#define GPIO_LPUART3_RTS_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN11) +#define GPIO_LPUART3_RTS_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN28) +#define GPIO_LPUART3_CTS_1 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTB|GPIO_PIN16) +#define GPIO_LPUART3_CTS_2 (GPIO_ALT|GPIO_AF3|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN10) +#define GPIO_LPUART3_CTS_3 (GPIO_ALT|GPIO_AF2|GPIO_PULLUP|GPIO_PORTE|GPIO_PIN27) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PINMAP_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_port.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_port.h new file mode 100644 index 00000000000..0e1cce78008 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_port.h @@ -0,0 +1,129 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_port.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PORT_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PORT_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_PORT_PCR0_OFFSET 0x0000 +#define RV32M1_PORT_PCR1_OFFSET 0x0004 +#define RV32M1_PORT_PCR2_OFFSET 0x0008 +#define RV32M1_PORT_PCR3_OFFSET 0x000c +#define RV32M1_PORT_PCR4_OFFSET 0x0010 +#define RV32M1_PORT_PCR5_OFFSET 0x0014 +#define RV32M1_PORT_PCR6_OFFSET 0x0018 +#define RV32M1_PORT_PCR7_OFFSET 0x001c +#define RV32M1_PORT_PCR8_OFFSET 0x0020 +#define RV32M1_PORT_PCR9_OFFSET 0x0024 +#define RV32M1_PORT_PCR10_OFFSET 0x0028 +#define RV32M1_PORT_PCR11_OFFSET 0x002c +#define RV32M1_PORT_PCR12_OFFSET 0x0030 +#define RV32M1_PORT_PCR13_OFFSET 0x0034 +#define RV32M1_PORT_PCR14_OFFSET 0x0038 +#define RV32M1_PORT_PCR15_OFFSET 0x003c +#define RV32M1_PORT_PCR16_OFFSET 0x0040 +#define RV32M1_PORT_PCR17_OFFSET 0x0044 +#define RV32M1_PORT_PCR18_OFFSET 0x0048 +#define RV32M1_PORT_PCR19_OFFSET 0x004c +#define RV32M1_PORT_PCR20_OFFSET 0x0050 +#define RV32M1_PORT_PCR21_OFFSET 0x0054 +#define RV32M1_PORT_PCR22_OFFSET 0x0058 +#define RV32M1_PORT_PCR23_OFFSET 0x005c +#define RV32M1_PORT_PCR24_OFFSET 0x0060 +#define RV32M1_PORT_PCR25_OFFSET 0x0064 +#define RV32M1_PORT_PCR26_OFFSET 0x0068 +#define RV32M1_PORT_PCR27_OFFSET 0x006c +#define RV32M1_PORT_PCR28_OFFSET 0x0070 +#define RV32M1_PORT_PCR29_OFFSET 0x0074 +#define RV32M1_PORT_PCR30_OFFSET 0x0078 +#define RV32M1_PORT_PCR31_OFFSET 0x007c +#define RV32M1_PORT_GPCLR_OFFSET 0x0080 /* Global Pin Control Low Register */ +#define RV32M1_PORT_GPCHR_OFFSET 0x0084 /* Global Pin Control High Register */ +#define RV32M1_PORT_GICLR_OFFSET 0x0088 /* Global Interrupt Control Low Regisgter */ +#define RV32M1_PORT_GICHR_OFFSET 0x008c /* Global Interrupt Control High Register */ +#define RV32M1_PORT_ISFR_OFFSET 0x00a0 /* Interrupt Status Flag */ + +/* Register Bitfield Definitions ********************************************/ + +#define PORT_PCR_ISF (1 << 24) /* Interrupt Status Flag, W1C */ + +#define PORT_PCR_IRQC_SHIFT (16) /* Bit[19:16]: Interrupt Configuration */ +#define PORT_PCR_IRQC_MASK (0xf << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_ISF_DISABLED (0 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_DMA_RISE (1 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_DMA_FALL (2 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_DMA_EDGE (3 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_4_RESERVED (4 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_FLG_RISE (5 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_FLG_FALL (6 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_FLG_EDGE (7 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_INT_LOW (8 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_INT_RISE (9 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_INT_FALL (10 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_INT_EDGE (11 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_INT_HIGH (12 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_ACT_TRIH (13 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_ACT_TRIL (14 << PORT_PCR_IRQC_SHIFT) +#define PORT_PCR_IRQC_15_RESERVED (15 << PORT_PCR_IRQC_SHIFT) + +#define PORT_PCR_LK (1 << 15) + +#define PORT_PCR_MUX_SHIFT (8) +#define PORT_PCR_MUX_MASK (0x7 << PORT_PCR_MUX_SHIFT) +#define PORT_PCR_MUX_ALT0 (0 << PORT_PCR_MUX_SHIFT) +# define PORT_PCR_MUX_ANALOG PORT_PCR_MUX_ALT0 +#define PORT_PCR_MUX_ALT1 (1 << PORT_PCR_MUX_SHIFT) +# define PORT_PCR_MUX_GPIO PORT_PCR_MUX_ALT1 +#define PORT_PCR_MUX_ALT2 (2 << PORT_PCR_MUX_SHIFT) +#define PORT_PCR_MUX_ALT3 (3 << PORT_PCR_MUX_SHIFT) +#define PORT_PCR_MUX_ALT4 (4 << PORT_PCR_MUX_SHIFT) +#define PORT_PCR_MUX_ALT5 (5 << PORT_PCR_MUX_SHIFT) +#define PORT_PCR_MUX_ALT6 (6 << PORT_PCR_MUX_SHIFT) +#define PORT_PCR_MUX_ALT7 (7 << PORT_PCR_MUX_SHIFT) + +#define PORT_PCR_ODE (1 << 5) /* Open Drain Enable */ +#define PORT_PCR_PFE (1 << 4) /* Passive Filter Enable */ +#define PORT_PCR_SRE (1 << 2) /* Slow Slew Rate Enable */ +#define PORT_PCR_PE (1 << 1) /* Pull Enable */ + +/* if 'PE' bit is enabled, + * 'PS' bit: 0 -> internal pull down, 1: internal pull up + */ + +#define PORT_PCR_PS (1 << 0) /* Pull Select */ + +#define PORT_GPC_WE_SHIFT (16) +#define PORT_GPC_WE_MASK (0xff << PORT_GPC_WE_SHIFT) + +#define PORT_GPC_WD_SHIFT (0) +#define PORT_GPC_WD_MASK (0xff << PORT_GPC_WE_SHIFT) + +#define PORT_GIC_WE_SHIFT (16) +#define PORT_GIC_WE_MASK (0xff << PORT_GPC_WE_SHIFT) + +#define PORT_GIC_WD_SHIFT (0) +#define PORT_GIC_WD_MASK (0xff << PORT_GPC_WE_SHIFT) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_PORT_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_scg.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_scg.h new file mode 100644 index 00000000000..002592dbc8c --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_scg.h @@ -0,0 +1,38 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_scg.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef ARCH_RISCV_SRC_RV32M1_CHIP_RV32M1_SCG_H +#define ARCH_RISCV_SRC_RV32M1_CHIP_RV32M1_SCG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#if defined(CONFIG_ARCH_CHIP_RV32M1_RI5CY) +# include "rv32m1ri5cy_scg.h" +#elif defined(CONFIG_ARCH_CHIP_RV32M1_ZERORISCY) +# error "rv32m1 zero-riscy is to be continued..." +#else +# error "Unspported rv32m1 cortex-m cores" +#endif + +#endif /* _ARCH_RISCV_SRC_RV32M1_CHIP_RV32M1_SCG_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_smc.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_smc.h new file mode 100644 index 00000000000..25f064a84c9 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_smc.h @@ -0,0 +1,114 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_smc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_SMC_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_SMC_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_SMC_VERID_OFFSET 0x0000 /* Version ID */ +#define RV32M1_SMC_PARAM_OFFSET 0x0004 /* Parameter */ +#define RV32M1_SMC_PMPROT_OFFSET 0x0008 /* Power Mode Protection */ +#define RV32M1_SMC_PMCTRL_OFFSET 0x0010 /* Power Mode Control */ +#define RV32M1_SMC_PMSTAT_OFFSET 0x0018 /* Power Mode Status */ +#define RV32M1_SMC_SRS_OFFSET 0x0020 /* System Reset Status */ +#define RV32M1_SMC_RPC_OFFSET 0x0024 /* Reset Pin Control */ +#define RV32M1_SMC_SSRS_OFFSET 0x0028 /* Sticky System Reset */ +#define RV32M1_SMC_SRIE_OFFSET 0x002c /* System Reset Interrupt Enable */ +#define RV32M1_SMC_SRIF_OFFSET 0x0030 /* System Reset Interrupt Flag */ +#define RV32M1_SMC_MR_OFFSET 0x0040 /* Mode Register */ +#define RV32M1_SMC_FM_OFFSET 0x0050 /* Force Mode Register */ +#define RV32M1_SMC_SRAMLPR_OFFSET 0x0060 /* SRAM Low Power */ +#define RV32M1_SMC_SRAMDSR_OFFSET 0x0064 /* SRAM Deep Sleep */ + +/* Register Address *********************************************************/ + +#if defined(CONFIG_ARCH_CHIP_RV32M1_RI5CY) +# define RV32M1_SMC_BASE RV32M1_SMC0_BASE +#else +# define RV32M1_SMC_BASE RV32M1_SMC1_BASE +#endif + +#define RV32M1_SMC_VERID (RV32M1_SMC_BASE + RV32M1_SMC_VERID_OFFSET) +#define RV32M1_SMC_PARAM (RV32M1_SMC_BASE + RV32M1_SMC_PARAM_OFFSET) +#define RV32M1_SMC_PMPROT (RV32M1_SMC_BASE + RV32M1_SMC_PMPROT_OFFSET) +#define RV32M1_SMC_PMCTRL (RV32M1_SMC_BASE + RV32M1_SMC_PMCTRL_OFFSET) +#define RV32M1_SMC_PMSTAT (RV32M1_SMC_BASE + RV32M1_SMC_PMSTAT_OFFSET) +#define RV32M1_SMC_SRS (RV32M1_SMC_BASE + RV32M1_SMC_SRS_OFFSET) +#define RV32M1_SMC_RPC (RV32M1_SMC_BASE + RV32M1_SMC_RPC_OFFSET) +#define RV32M1_SMC_SSRS (RV32M1_SMC_BASE + RV32M1_SMC_SSRS_OFFSET) +#define RV32M1_SMC_SRIE (RV32M1_SMC_BASE + RV32M1_SMC_SRIE_OFFSET) +#define RV32M1_SMC_SRIF (RV32M1_SMC_BASE + RV32M1_SMC_SRIF_OFFSET) +#define RV32M1_SMC_MR (RV32M1_SMC_BASE + RV32M1_SMC_MR_OFFSET) +#define RV32M1_SMC_FM (RV32M1_SMC_BASE + RV32M1_SMC_FM_OFFSET) +#define RV32M1_SMC_SRAMLPR (RV32M1_SMC_BASE + RV32M1_SMC_SRAMLPR_OFFSET) +#define RV32M1_SMC_SRAMDSR (RV32M1_SMC_BASE + RV32M1_SMC_SRAMDSR_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +#define SMC_PARAM_PWRD_INDPT (1 << 1) /* Bit1: Power Domains Independent */ + +#define SMC_PMPROT_AHSRUN (1 << 7) /* Bit7: Allow High Speed Run mode */ +#define SMC_PMPROT_AVLP (1 << 5) /* Bit5: Allow Very-Low-Power Mode */ +#define SMC_PMPROT_ALLS (1 << 3) /* Bit3: Allow Low-Leakage Stop Mode */ +#define SMC_PMPROT_AVLLS_SHIFT (0) /* Bit[1:0]: Allow Very-Low-Leakage Stop Mode */ +#define SMC_PMPROT_AVLLS_MASK (3 << SMC_PMPROT_AVLLS_SHIFT) +#define SMC_PMPROT_AVLLS_NOT_ALLOWED (0 << SMC_PMPROT_AVLLS_SHIFT) /* VLLS mode is dinied */ +#define SMC_PMPROT_AVLLS_0_1_ALLOWED (1 << SMC_PMPROT_AVLLS_SHIFT) /* VLLS0/1 mode is Allowded */ +#define SMC_PMPROT_AVLLS_2_3_ALLOWED (2 << SMC_PMPROT_AVLLS_SHIFT) /* VLLS2/3 mode is Allowed */ +#define SMC_PMPROT_AVLLS_ALL_ALLOWED (3 << SMC_PMPROT_AVLLS_SHIFT) /* VLSS0/1/2/3 mode is Allowed */ + +# define SMC_PMPROT_PM_ALL_ALLOWED \ + (SMC_PMPROT_AHSRUN | SMC_PMPROT_AVLP | \ + SMC_PMPROT_ALLS | SMC_PMPROT_AVLLS_ALL_ALLOWED) + +#define SMC_PMCTRL_PSTOPO_SHIFT (16) /* Bit[17:16]: Partial Stop Option */ +#define SMC_PMCTRL_PSTOPO_MASK (3 << SMC_PMCTRL_PSTOPO_SHIFT) +#define SMC_PMCTRL_PSTOPO_STOP (0 << SMC_PMCTRL_PSTOPO_SHIFT) +#define SMC_PMCTRL_PSTOPO_PSTOP1 (1 << SMC_PMCTRL_PSTOPO_SHIFT) +#define SMC_PMCTRL_PSTOPO_PSTOP2 (2 << SMC_PMCTRL_PSTOPO_SHIFT) +#define SMC_PMCTRL_PSTOPO_PSTOP3 (3 << SMC_PMCTRL_PSTOPO_SHIFT) + +#define SMC_PMCTRL_RUNM_SHIFT (8) /* Bit[9:8]: Run Mode Control */ +#define SMC_PMCTRL_RUNM_MASK (3 << SMC_PMCTRL_RUNM_SHIFT) +#define SMC_PMCTRL_RUNM_RUN (0 << SMC_PMCTRL_RUNM_SHIFT) +#define SMC_PMCTRL_RUNM_VLPR (2 << SMC_PMCTRL_RUNM_SHIFT) +#define SMC_PMCTRL_RUNM_HSRUN (3 << SMC_PMCTRL_RUNM_SHIFT) + +#define SMC_PMCTRL_STOPM_SHIFT (0) /* Bit[2:0]: Stop Mode Control */ +#define SMC_PMCTRL_STOPM_MASK (7 << SMC_PMCTRL_STOPM_SHIFT) +#define SMC_PMCTRL_STOPM_STOP (0 << SMC_PMCTRL_STOPM_SHIFT) +#define SMC_PMCTRL_STOPM_VLPS (2 << SMC_PMCTRL_STOPM_SHIFT) +#define SMC_PMCTRL_STOPM_LLS (3 << SMC_PMCTRL_STOPM_SHIFT) +#define SMC_PMCTRL_STOPM_VLLS_2_3 (4 << SMC_PMCTRL_STOPM_SHIFT) +#define SMC_PMCTRL_STOPM_VLLS_0_1 (6 << SMC_PMCTRL_STOPM_SHIFT) + +#define SMC_PMSTAT_PMSTAT_SHIFT (0) /* Bit[7:0]: Power Mode Status */ +#define SMC_PMSTAT_PMSTAT_MASK (0xff << SMC_PMSTAT_PMSTAT_SHIFT) +#define SMC_PMSTAT_RUN (0x01 << SMC_PMSTAT_PMSTAT_SHIFT) +#define SMC_PMSTAT_STOP (0x02 << SMC_PMSTAT_PMSTAT_SHIFT) +#define SMC_PMSTAT_VLPR (0x04 << SMC_PMSTAT_PMSTAT_SHIFT) +#define SMC_PMSTAT_HSRUN (0x80 << SMC_PMSTAT_PMSTAT_SHIFT) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_SMC_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_tstmr.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_tstmr.h new file mode 100644 index 00000000000..f82d9b05d1e --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_tstmr.h @@ -0,0 +1,56 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_tstmr.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_TSTMR_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_TSTMR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_TSTMR_LOW_OFFSET 0x0000 /* Time Stamp Timer Register Low */ +#define RV32M1_TSTMR_HIGH_OFFSET 0x0004 /* Time Stamp Timer Register High */ + +/* Register Address *********************************************************/ + +#define RV32M1_TSTMRA_LOW (RV32M1_TSTMRA_BASE + RV32M1_TSTMR_LOW_OFFSET) +#define RV32M1_TSTMRA_HIGH (RV32M1_TSTMRA_BASE + RV32M1_TSTMR_HIGH_OFFSET) + +#define RV32M1_TSTMRB_LOW (RV32M1_TSTMRB_BASE + RV32M1_TSTMR_LOW_OFFSET) +#define RV32M1_TSTMRB_HIGH (RV32M1_TSTMRB_BASE + RV32M1_TSTMR_HIGH_OFFSET) + +#ifdef CONFIG_ARCH_CHIP_RV32M1_RI5CY +# define RV32M1_TSTMR_BASE RV32M1_TSTMRA_BASE +#else +# define RV32M1_TSTMR_BASE RV32M1_TSTMRB_BASE +#endif + +#define RV32M1_TSTMR_LOW (RV32M1_TSTMR_BASE + RV32M1_TSTMR_LOW_OFFSET) +#define RV32M1_TSTMR_HIGH (RV32M1_TSTMR_BASE + RV32M1_TSTMR_HIGH_OFFSET) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_TSTMR_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1_wdog.h b/arch/risc-v/src/rv32m1/hardware/rv32m1_wdog.h new file mode 100644 index 00000000000..d7daaa5ae3f --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1_wdog.h @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1_wdog.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_WDOG_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_WDOG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Register Offsets *********************************************************/ + +#define RV32M1_WDOG_CS_OFFSET 0x0000 /* Control and Status */ +#define RV32M1_WDOG_CNT_OFFSET 0x0004 /* Counter */ +#define RV32M1_WDOG_TOVAL_OFFSET 0x0008 /* Timeout Value */ +#define RV32M1_WDOG_WIN_OFFSET 0x000c /* Window */ + +/* Register Address *********************************************************/ + +#if defined(CONFIG_ARCH_CHIP_RV32M1_RI5CY) +# define RV32M1_WDOG_BASE RV32M1_WDOG0_BASE +#elif defined(CONFIG_ARCH_CHIP_RV32M1_ZERORISCY) +# define RV32M1_WDOG_BASE RV32M1_WDOG1_BASE +#else +# error "Unsupported RV32M1 Watch dog" +#endif + +#define RV32M1_WDOG0_CS (RV32M1_WDOG0_BASE + RV32M1_WDOG_CS_OFFSET) +#define RV32M1_WDOG0_CNT (RV32M1_WDOG0_BASE + RV32M1_WDOG_CNT_OFFSET) +#define RV32M1_WDOG0_TOVAL (RV32M1_WDOG0_BASE + RV32M1_WDOG_TOVAL_OFFSET) +#define RV32M1_WDOG0_WIN (RV32M1_WDOG0_BASE + RV32M1_WDOG_WIN_OFFSET) + +#define RV32M1_WDOG_CS (RV32M1_WDOG_BASE + RV32M1_WDOG_CS_OFFSET) +#define RV32M1_WDOG_CNT (RV32M1_WDOG_BASE + RV32M1_WDOG_CNT_OFFSET) +#define RV32M1_WDOG_TOVAL (RV32M1_WDOG_BASE + RV32M1_WDOG_TOVAL_OFFSET) +#define RV32M1_WDOG_WIN (RV32M1_WDOG_BASE + RV32M1_WDOG_WIN_OFFSET) + +/* Register Bitfield Definitions ********************************************/ + +#define WDOG_CS_WIN (1 << 15) /* Bit15: Window */ +#define WDOG_CS_FLG (1 << 14) /* Bit14: Interrupt Flag */ +#define WDOG_CS_CMD32EN (1 << 13) /* Bit13: suport 32bit command */ +#define WDOG_CS_PRES (1 << 12) /* Bit12: Prescaler, '1' enables 256 prescaler */ +#define WDOG_CS_ULK (1 << 11) /* Bit11: Unlock status */ +#define WDOG_CS_RCS (1 << 10) /* Bit10: Reconfiguration Success */ + +#define WDOG_CS_CLK_SHIFT (8) /* Bit[9:8]: Watchdog Clock */ +#define WDOG_CS_CLK_MASK (3 << WDOG_CS_CLK_SHIFT) +#define WDOG_CS_CLK_BUS (0 << WDOG_CS_CLK_SHIFT) /* Bus Clock */ +#define WDOG_CS_CLK_LPO (1 << WDOG_CS_CLK_SHIFT) /* LPO Clock(1KHz) */ +#define WDOG_CS_CLK_INT (1 << WDOG_CS_CLK_SHIFT) /* Internal Clock */ +#define WDOG_CS_CLK_EXR (1 << WDOG_CS_CLK_SHIFT) /* External reference Clock */ + +#define WDOG_CS_EN (1 << 7) /* Bit7: Enable */ +#define WDOG_CS_INT (1 << 6) /* Bit6: Interrupt */ +#define WDOG_CS_UPDATE (1 << 5) /* Bit5: Allow updates */ + +#define WDOG_CS_TST_SHIFT (3) +#define WDOG_CS_TST_MASK (3 << WDOG_CS_TST_SHIFT) +#define WDOG_CS_TST_DISABLED (0 << WDOG_CS_TST_SHIFT) +#define WDOG_CS_TST_UEN (1 << WDOG_CS_TST_SHIFT) /* User Mode Enable */ +#define WDOG_CS_TST_TENL (2 << WDOG_CS_TST_SHIFT) /* Test Mode Enable with the low byte used */ +#define WDOG_CS_TST_TENH (3 << WDOG_CS_TST_SHIFT) /* Test Mode Enable with the high byte used */ + +#define WDOG_CS_DBG (1 << 2) /* Debug Enable */ +#define WDOG_CS_WAIT (1 << 1) /* Wait Enable */ +#define WDOG_CS_STOP (1 << 0) /* Stop Enable */ + +/* The unlock magic number */ + +#define WDOG_CNT_UNLOCK (0xd928c520) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1_WDOG_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_memorymap.h b/arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_memorymap.h new file mode 100644 index 00000000000..3de2c52f267 --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_memorymap.h @@ -0,0 +1,124 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_memorymap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1RI5CY_MEMORYMAP_H +#define __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1RI5CY_MEMORYMAP_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Bus Base Address *********************************************************/ + +#define RV32M1_AIPS0_BASE 0x40000000 +#define RV32M1_AIPS1_BASE 0x41000000 +#define RV32M1_FLEXRAM_BASE 0x48000000 +#define RV32M1_USB0RAM_BASE 0x48010000 +#define RV32M1_GPIO_BASE 0x48020000 +#define RV32M1_FLEXBUS_BASE 0xa0000000 +#define RV32M1_PPB0_BASE 0xe0000000 /* ARM SYS Modules */ +#define RV32M1_PPB1_BASE 0xf0000000 /* NXP SYS Modules */ + +/* AIPS0 Peripheral Offset **************************************************/ + +#define RV32M1_MSCM_OFFSET 0x00001000 +#define RV32M1_DMA0CTRL_OFFSET 0x00008000 +#define RV32M1_DMA0DESC_OFFSET 0x00009000 +#define RV32M1_SMC0_OFFSET 0x00020000 +#define RV32M1_FTFE_OFFSET 0x00023000 +#define RV32M1_WDOG0_OFFSET 0x0002a000 +#define RV32M1_PCC0_OFFSET 0x0002b000 +#define RV32M1_SCG_OFFSET 0x0002c000 +#define RV32M1_LPIT0_OFFSET 0x00030000 +#define RV32M1_LPTMR0_OFFSET 0x00032000 +#define RV32M1_LPTMR1_OFFSET 0x00033000 +#define RV32M1_TSTMRA_OFFSET 0x00034000 +#define RV32M1_LPUART0_OFFSET 0x00042000 +#define RV32M1_LPUART1_OFFSET 0x00043000 +#define RV32M1_LPUART2_OFFSET 0x00044000 +#define RV32M1_PORTA_OFFSET 0x00046000 +#define RV32M1_PORTB_OFFSET 0x00047000 +#define RV32M1_PORTC_OFFSET 0x00048000 +#define RV32M1_PORTD_OFFSET 0x00049000 +#define RV32M1_INTMUX0_OFFSET 0x0004f000 + +/* AIPS1 Peripheral Offset **************************************************/ + +#define RV32M1_GPIOE_OFFSET 0x0000f000 +#define RV32M1_PCC1_OFFSET 0x00027000 +#define RV32M1_LPTMR2_OFFSET 0x0002b000 +#define RV32M1_TSTMRB_OFFSET 0x0002c000 +#define RV32M1_RSIM_OFFSET 0x0002f000 +#define RV32M1_LPUART3_OFFSET 0x00036000 +#define RV32M1_PORTE_OFFSET 0x00037000 + +/* GPIO Peripheral Offset ***************************************************/ + +#define RV32M1_GPIOA_OFFSET 0x00000000 +#define RV32M1_GPIOB_OFFSET 0x00000040 +#define RV32M1_GPIOC_OFFSET 0x00000080 +#define RV32M1_GPIOD_OFFSET 0x000000c0 + +/* PPB0 Peripheral Offset ***************************************************/ + +#define RV32M1_EU0_OFFSET 0x00041000 /* Event Unit */ + +/* AIPS0 Peripheral Address *************************************************/ + +#define RV32M1_SMC0_BASE (RV32M1_AIPS0_BASE + RV32M1_SMC0_OFFSET) +#define RV32M1_FTFE_BASE (RV32M1_AIPS0_BASE + RV32M1_FTFE_OFFSET) +#define RV32M1_WDOG0_BASE (RV32M1_AIPS0_BASE + RV32M1_WDOG0_OFFSET) +#define RV32M1_PCC0_BASE (RV32M1_AIPS0_BASE + RV32M1_PCC0_OFFSET) +#define RV32M1_SCG_BASE (RV32M1_AIPS0_BASE + RV32M1_SCG_OFFSET) +#define RV32M1_LPIT0_BASE (RV32M1_AIPS0_BASE + RV32M1_LPIT0_OFFSET) +#define RV32M1_LPTMR0_BASE (RV32M1_AIPS0_BASE + RV32M1_LPTMR0_OFFSET) +#define RV32M1_LPTMR1_BASE (RV32M1_AIPS0_BASE + RV32M1_LPTMR0_OFFSET) +#define RV32M1_TSTMRA_BASE (RV32M1_AIPS0_BASE + RV32M1_TSTMRA_OFFSET) +#define RV32M1_LPUART0_BASE (RV32M1_AIPS0_BASE + RV32M1_LPUART0_OFFSET) +#define RV32M1_LPUART1_BASE (RV32M1_AIPS0_BASE + RV32M1_LPUART1_OFFSET) +#define RV32M1_LPUART2_BASE (RV32M1_AIPS0_BASE + RV32M1_LPUART2_OFFSET) +#define RV32M1_PORTA_BASE (RV32M1_AIPS0_BASE + RV32M1_PORTA_OFFSET) +#define RV32M1_PORTB_BASE (RV32M1_AIPS0_BASE + RV32M1_PORTB_OFFSET) +#define RV32M1_PORTC_BASE (RV32M1_AIPS0_BASE + RV32M1_PORTC_OFFSET) +#define RV32M1_PORTD_BASE (RV32M1_AIPS0_BASE + RV32M1_PORTD_OFFSET) +#define RV32M1_INTMUX0_BASE (RV32M1_AIPS0_BASE + RV32M1_INTMUX0_OFFSET) + +/* AIPS1 Peripheral Address *************************************************/ + +#define RV32M1_PORTE_BASE (RV32M1_AIPS1_BASE + RV32M1_PORTE_OFFSET) +#define RV32M1_PCC1_BASE (RV32M1_AIPS1_BASE + RV32M1_PCC1_OFFSET) +#define RV32M1_LPTMR2_BASE (RV32M1_AIPS1_BASE + RV32M1_LPTMR2_OFFSET) +#define RV32M1_TSTMRB_BASE (RV32M1_AIPS1_BASE + RV32M1_TSTMRB_OFFSET) +#define RV32M1_RSIM_BASE (RV32M1_AIPS1_BASE + RV32M1_RSIM_OFFSET) +#define RV32M1_LPUART3_BASE (RV32M1_AIPS1_BASE + RV32M1_LPUART3_OFFSET) +#define RV32M1_GPIOE_BASE (RV32M1_AIPS1_BASE + RV32M1_GPIOE_OFFSET) + +/* GPIO Peripheral Address **************************************************/ + +#define RV32M1_GPIOA_BASE (RV32M1_GPIO_BASE + RV32M1_GPIOA_OFFSET) +#define RV32M1_GPIOB_BASE (RV32M1_GPIO_BASE + RV32M1_GPIOB_OFFSET) +#define RV32M1_GPIOC_BASE (RV32M1_GPIO_BASE + RV32M1_GPIOC_OFFSET) +#define RV32M1_GPIOD_BASE (RV32M1_GPIO_BASE + RV32M1_GPIOD_OFFSET) + +/* PPB0 Peripheral Address **************************************************/ + +#define RV32M1_EU_BASE (RV32M1_PPB0_BASE + RV32M1_EU0_OFFSET) + +#endif /* __ARCH_RISCV_SRC_RV32M1_HARDWARE_RV32M1RI5CY_MEMORYMAP_H */ diff --git a/arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_scg.h b/arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_scg.h new file mode 100644 index 00000000000..bde0d4b2cce --- /dev/null +++ b/arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_scg.h @@ -0,0 +1,605 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/hardware/rv32m1ri5cy_scg.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef ARCH_RISCV_SRC_RV32M1_CHIP_RV32M1RI5CY_SCG_H +#define ARCH_RISCV_SRC_RV32M1_CHIP_RV32M1RI5CY_SCG_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define RV32M1_SCG_VERID_OFFSET 0x0000 /* Version Id */ +#define RV32M1_SCG_PARAM_OFFSET 0x0004 /* Parameter */ +#define RV32M1_SCG_CSR_OFFSET 0x0010 /* Clock Status */ +#define RV32M1_SCG_RCCR_OFFSET 0x0014 /* Run Clock Control */ +#define RV32M1_SCG_VCCR_OFFSET 0x0018 /* VLPR Clock Control */ +#define RV32M1_SCG_HCCR_OFFSET 0x001c /* HSRUN Clock Control */ +#define RV32M1_SCG_CLKOUTCNFG_OFFSET 0x0020 /* Clock Out Control */ +#define RV32M1_SCG_SOSCCSR_OFFSET 0x0100 /* System OSC Control Status */ +#define RV32M1_SCG_SOSCDIV_OFFSET 0x0104 /* System OSC Divider */ +#define RV32M1_SCG_SIRCCSR_OFFSET 0x0200 /* Slow IRC Control Status */ +#define RV32M1_SCG_SIRCDIV_OFFSET 0x0204 /* Slow IRC Divider */ +#define RV32M1_SCG_SIRCCFG_OFFSET 0x0208 /* Slow IRC Configuration */ +#define RV32M1_SCG_FIRCCSR_OFFSET 0x0300 /* Fast IRC Constrol Status */ +#define RV32M1_SCG_FIRCDIV_OFFSET 0x0304 /* Fast IRC Divider */ +#define RV32M1_SCG_FIRCCFG_OFFSET 0x0308 /* Fast IRC Configuration */ +#define RV32M1_SCG_FIRCTCFG_OFFSET 0x030c /* Fast IRC Trim Configuration */ +#define RV32M1_SCG_FIRCSTAT_OFFSET 0x0318 /* Fast IRC Status */ +#define RV32M1_SCG_ROSCCSR_OFFSET 0x0400 /* RTC OSC Control Status */ +#define RV32M1_SCG_LPFLLCSR_OFFSET 0x0500 /* Low Power FLL Control Status */ +#define RV32M1_SCG_LPFLLDIV_OFFSET 0x0504 /* Low Power FLL Divider */ +#define RV32M1_SCG_LPFLLCFG_OFFSET 0x0508 /* Low Power FLL Configuration */ +#define RV32M1_SCG_LPFLLTCFG_OFFSET 0x050c /* Low Power FLL Trim Configuration */ +#define RV32M1_SCG_LPFLLSTAT_OFFSET 0x0514 /* Low Power FLL Status */ + +#define RV32M1_SCG_VERID (RV32M1_SCG_BASE + RV32M1_SCG_VERID_OFFSET) +#define RV32M1_SCG_PARAM (RV32M1_SCG_BASE + RV32M1_SCG_PARAM_OFFSET) +#define RV32M1_SCG_CSR (RV32M1_SCG_BASE + RV32M1_SCG_CSR_OFFSET) +#define RV32M1_SCG_RCCR (RV32M1_SCG_BASE + RV32M1_SCG_RCCR_OFFSET) +#define RV32M1_SCG_VCCR (RV32M1_SCG_BASE + RV32M1_SCG_VCCR_OFFSET) +#define RV32M1_SCG_HCCR (RV32M1_SCG_BASE + RV32M1_SCG_HCCR_OFFSET) +#define RV32M1_SCG_CLKOUTCNFG (RV32M1_SCG_BASE + RV32M1_SCG_CLKOUTCNFG_OFFSET) +#define RV32M1_SCG_SOSCCSR (RV32M1_SCG_BASE + RV32M1_SCG_SOSCCSR_OFFSET) +#define RV32M1_SCG_SOSCDIV (RV32M1_SCG_BASE + RV32M1_SCG_SOSCDIV_OFFSET) +#define RV32M1_SCG_SIRCCSR (RV32M1_SCG_BASE + RV32M1_SCG_SIRCCSR_OFFSET) +#define RV32M1_SCG_SIRCDIV (RV32M1_SCG_BASE + RV32M1_SCG_SIRCDIV_OFFSET) +#define RV32M1_SCG_SIRCCFG (RV32M1_SCG_BASE + RV32M1_SCG_SIRCCFG_OFFSET) +#define RV32M1_SCG_FIRCCSR (RV32M1_SCG_BASE + RV32M1_SCG_FIRCCSR_OFFSET) +#define RV32M1_SCG_FIRCDIV (RV32M1_SCG_BASE + RV32M1_SCG_FIRCDIV_OFFSET) +#define RV32M1_SCG_FIRCCFG (RV32M1_SCG_BASE + RV32M1_SCG_FIRCCFG_OFFSET) +#define RV32M1_SCG_FIRCTCFG (RV32M1_SCG_BASE + RV32M1_SCG_FIRCTCFG_OFFSET) +#define RV32M1_SCG_FIRCSTAT (RV32M1_SCG_BASE + RV32M1_SCG_FIRCSTAT_OFFSET) +#define RV32M1_SCG_ROSCCSR (RV32M1_SCG_BASE + RV32M1_SCG_ROSCCSR_OFFSET) +#define RV32M1_SCG_LPFLLCSR (RV32M1_SCG_BASE + RV32M1_SCG_LPFLLCSR_OFFSET) +#define RV32M1_SCG_LPFLLDIV (RV32M1_SCG_BASE + RV32M1_SCG_LPFLLDIV_OFFSET) +#define RV32M1_SCG_LPFLLCFG (RV32M1_SCG_BASE + RV32M1_SCG_LPFLLCFG_OFFSET) +#define RV32M1_SCG_LPFLLTCFG (RV32M1_SCG_BASE + RV32M1_SCG_LPFLLTCFG_OFFSET) +#define RV32M1_SCG_LPFLLSTAT (RV32M1_SCG_BASE + RV32M1_SCG_LPFLLSTAT_OFFSET) + +#define SCG_PARAM_DIVPRES_SHIFT (27) /* Divier Present */ +#define SCG_PARAM_DIVPRES_MASK (0xf << SCG_PARAM_DIVPRES_SHIFT) +#define SCG_PARAM_DIVPRES_CORE (1 << 31) +#define SCG_PARAM_DIVPRES_EXT (1 << 29) +#define SCG_PARAM_DIVRRES_BUS (1 << 28) +#define SCG_PARAM_DIVPRES_SLOW (1 << 27) + +#define SCG_PARAM_CLKPRES_SHIFT (0) /* Clock Present */ +#define SCG_PARAM_CLKPRES_MASK (0xf << SCG_PARAM_CLKPRES_SHIFT) +#define SCG_PARAM_CLKPRES_LPFLL (1 << 5) /* Low Power FLL is present */ +#define SCG_PARAM_CLKPRES_ROSC (1 << 4) /* RTC OSC is present */ +#define SCG_PARAM_CLKPRES_FIRC (1 << 3) /* Fast IRC is present */ +#define SCG_PARAM_CLKPRES_SIRC (1 << 2) /* Slow IRQ is present */ +#define SCG_PARAM_CLKPRES_SOSC (1 << 1) /* System OSC is present */ + +#define SCG_CSR_SCS_SHIFT (24) /* System Clock Source */ +#define SCG_CSR_SCS_MASK (0xf << SCG_CSR_SCS_SHIFT) +#define SCG_CSR_SCS_SOSC (1 << SCG_CSR_SCS_SHIFT) /* System OSC as source */ +#define SCG_CSR_SCS_SIRC (2 << SCG_CSR_SCS_SHIFT) /* SIRC as source */ +#define SCG_CSR_SCS_FIRC (3 << SCG_CSR_SCS_SHIFT) /* FIRC as source */ +#define SCG_CSR_SCS_ROSC (4 << SCG_CSR_SCS_SHIFT) /* RTC OSC as source */ +#define SCG_CSR_SCS_LPFLL (5 << SCG_CSR_SCS_SHIFT) /* Low Power FLL as source */ + +#define SCG_CSR_DIVCORE_SHIFT (16) /* Core Clock Divide Ratio */ +#define SCG_CSR_DIVCORE_MASK (0xf << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV1 (0 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV2 (1 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV3 (2 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV4 (3 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV5 (4 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV6 (5 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV7 (6 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV8 (7 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV9 (8 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV10 (9 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV11 (10 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV12 (11 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV13 (12 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV14 (13 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV15 (14 << SCG_CSR_DIVCORE_SHIFT) +#define SCG_CSR_DIVCORE_DIV16 (15 << SCG_CSR_DIVCORE_SHIFT) + +#define SCG_CSR_DIVEXT_SHIFT (8) /* External Clock Divide Ratio */ +#define SCG_CSR_DIVEXT_MASK (0xf << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV1 (0 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV2 (1 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV3 (2 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV4 (3 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV5 (4 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV6 (5 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV7 (6 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV8 (7 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV9 (8 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV10 (9 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV11 (10 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV12 (11 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV13 (12 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV14 (13 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV15 (14 << SCG_CSR_DIVEXT_SHIFT) +#define SCG_CSR_DIVEXT_DIV16 (15 << SCG_CSR_DIVEXT_SHIFT) + +#define SCG_CSR_DIVBUS_SHIFT (4) /* Bus Clock Divide Ratio */ +#define SCG_CSR_DIVBUS_MASK (0xf << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV1 (0 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV2 (1 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV3 (2 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV4 (3 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV5 (4 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV6 (5 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV7 (6 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV8 (7 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV9 (8 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV10 (9 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV11 (10 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV12 (11 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV13 (12 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV14 (13 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV15 (14 << SCG_CSR_DIVBUS_SHIFT) +#define SCG_CSR_DIVBUS_DIV16 (15 << SCG_CSR_DIVBUS_SHIFT) + +#define SCG_CSR_DIVSLOW_SHIFT (0) /* Slow Clock Divide Ratio */ +#define SCG_CSR_DIVSLOW_MASK (0xf << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV1 (0 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV2 (1 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV3 (2 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV4 (3 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV5 (4 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV6 (5 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV7 (6 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV8 (7 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV9 (8 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV10 ( 9 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV11 (10 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV12 (11 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV13 (12 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV14 (13 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV15 (14 << SCG_CSR_DIVSLOW_SHIFT) +#define SCG_CSR_DIVSLOW_DIV16 (15 << SCG_CSR_DIVSLOW_SHIFT) + +#define SCG_RCCR_SCS_SHIFT (24) /* System Clock Source */ +#define SCG_RCCR_SCS_MASK (0xf << SCG_RCCR_SCS_SHIFT) +#define SCG_RCCR_SCS_SOSC (1 << SCG_RCCR_SCS_SHIFT) /* System OSC as source */ +#define SCG_RCCR_SCS_SIRC (2 << SCG_RCCR_SCS_SHIFT) /* SIRC as source */ +#define SCG_RCCR_SCS_FIRC (3 << SCG_RCCR_SCS_SHIFT) /* FIRC as source */ +#define SCG_RCCR_SCS_ROSC (4 << SCG_RCCR_SCS_SHIFT) /* RTC OSC as source */ +#define SCG_RCCR_SCS_LPFLL (5 << SCG_RCCR_SCS_SHIFT) /* Low Power FLL as source */ + +#define SCG_RCCR_DIVCORE_SHIFT (16) /* Core Clock Divide Ratio */ +#define SCG_RCCR_DIVCORE_MASK (0xf << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV1 (0 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV2 (1 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV3 (2 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV4 (3 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV5 (4 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV6 (5 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV7 (6 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV8 (7 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV9 (8 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV10 (9 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV11 (10 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV12 (11 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV13 (12 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV14 (13 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV15 (14 << SCG_RCCR_DIVCORE_SHIFT) +#define SCG_RCCR_DIVCORE_DIV16 (15 << SCG_RCCR_DIVCORE_SHIFT) + +#define SCG_RCCR_DIVEXT_SHIFT (8) /* External Clock Divide Ratio */ +#define SCG_RCCR_DIVEXT_MASK (0xf << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV1 (0 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV2 (1 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV3 (2 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV4 (3 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV5 (4 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV6 (5 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV7 (6 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV8 (7 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV9 (8 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV10 (9 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV11 (10 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV12 (11 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV13 (12 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV14 (13 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV15 (14 << SCG_RCCR_DIVEXT_SHIFT) +#define SCG_RCCR_DIVEXT_DIV16 (15 << SCG_RCCR_DIVEXT_SHIFT) + +#define SCG_RCCR_DIVBUS_SHIFT (4) /* Bus Clock Divide Ratio */ +#define SCG_RCCR_DIVBUS_MASK (0xf << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV1 (0 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV2 (1 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV3 (2 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV4 (3 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV5 (4 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV6 (5 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV7 (6 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV8 (7 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV9 (8 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV10 (9 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV11 (10 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV12 (11 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV13 (12 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV14 (13 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV15 (14 << SCG_RCCR_DIVBUS_SHIFT) +#define SCG_RCCR_DIVBUS_DIV16 (15 << SCG_RCCR_DIVBUS_SHIFT) + +#define SCG_RCCR_DIVSLOW_SHIFT (0) /* Slow Clock Divide Ratio */ +#define SCG_RCCR_DIVSLOW_MASK (0xf << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV1 (0 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV2 (1 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV3 (2 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV4 (3 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV5 (4 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV6 (5 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV7 (6 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV8 (7 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV9 (8 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV10 (9 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV11 (10 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV12 (11 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV13 (12 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV14 (13 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV15 (14 << SCG_RCCR_DIVSLOW_SHIFT) +#define SCG_RCCR_DIVSLOW_DIV16 (15 << SCG_RCCR_DIVSLOW_SHIFT) + +#define SCG_HCCR_SCS_SHIFT (24) /* System Clock Source */ +#define SCG_HCCR_SCS_MASK (0xf << SCG_HCCR_SCS_SHIFT) +#define SCG_HCCR_SCS_SOSC (1 << SCG_HCCR_SCS_SHIFT) /* System OSC as source */ +#define SCG_HCCR_SCS_SIRC (2 << SCG_HCCR_SCS_SHIFT) /* SIRC as source */ +#define SCG_HCCR_SCS_FIRC (3 << SCG_HCCR_SCS_SHIFT) /* FIRC as source */ +#define SCG_HCCR_SCS_ROSC (4 << SCG_HCCR_SCS_SHIFT) /* RTC OSC as source */ +#define SCG_HCCR_SCS_LPFLL (5 << SCG_HCCR_SCS_SHIFT) /* Low Power FLL as source */ + +#define SCG_HCCR_DIVCORE_SHIFT (16) /* Core Clock Divide Ratio */ +#define SCG_HCCR_DIVCORE_MASK (0xf << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV1 (0 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV2 (1 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV3 (2 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV4 (3 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV5 (4 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV6 (5 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV7 (6 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV8 (7 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV9 (8 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV10 (9 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV11 (10 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV12 (11 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV13 (12 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV14 (13 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV15 (14 << SCG_HCCR_DIVCORE_SHIFT) +#define SCG_HCCR_DIVCORE_DIV16 (15 << SCG_HCCR_DIVCORE_SHIFT) + +#define SCG_HCCR_DIVEXT_SHIFT (8) /* External Clock Divide Ratio */ +#define SCG_HCCR_DIVEXT_MASK (0xf << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV1 (0 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV2 (1 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV3 (2 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV4 (3 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV5 (4 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV6 (5 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV7 (6 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV8 (7 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV9 (8 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV10 (9 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV11 (10 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV12 (11 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV13 (12 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV14 (13 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV15 (14 << SCG_HCCR_DIVEXT_SHIFT) +#define SCG_HCCR_DIVEXT_DIV16 (15 << SCG_HCCR_DIVEXT_SHIFT) + +#define SCG_HCCR_DIVBUS_SHIFT (4) /* Bus Clock Divide Ratio */ +#define SCG_HCCR_DIVBUS_MASK (0xf << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV1 (0 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV2 (1 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV3 (2 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV4 (3 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV5 (4 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV6 (5 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV7 (6 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV8 (7 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV9 (8 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV10 (9 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV11 (10 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV12 (11 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV13 (12 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV14 (13 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV15 (14 << SCG_HCCR_DIVBUS_SHIFT) +#define SCG_HCCR_DIVBUS_DIV16 (15 << SCG_HCCR_DIVBUS_SHIFT) + +#define SCG_HCCR_DIVSLOW_SHIFT (0) /* Slow Clock Divide Ratio */ +#define SCG_HCCR_DIVSLOW_MASK (0xf << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV1 (0 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV2 (1 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV3 (2 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV4 (3 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV5 (4 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV6 (5 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV7 (6 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV8 (7 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV9 (8 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV10 (9 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV11 (10 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV12 (11 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV13 (12 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV14 (13 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV15 (14 << SCG_HCCR_DIVSLOW_SHIFT) +#define SCG_HCCR_DIVSLOW_DIV16 (15 << SCG_HCCR_DIVSLOW_SHIFT) + +#define SCG_SOSCCSR_ERR (1 << 26) /* Bit26: System OSC Clock Error */ +#define SCG_SOSCCSR_SEL (1 << 25) /* Bit25: System OSC Selected */ +#define SCG_SOSCCSR_VLD (1 << 24) /* Bit24: System OSC Valid */ +#define SCG_SOSCCSR_LK (1 << 23) /* Bit23: System OSC Lock */ +#define SCG_SOSCCSR_CMRE (1 << 17) /* Bit17: System OSC Monitor Reset Enable */ +#define SCG_SOSCCSR_ME (1 << 16) /* Bit16: System OSC Monitor Enable */ +#define SCG_SOSCCSR_LPEN (1 << 2) /* Bit2: System OSC Low Power Enable */ +#define SCG_SOSCCSR_STEN (1 << 1) /* Bit1: System OSC Stop Enable */ +#define SCG_SOSCCSR_EN (1 << 1) /* Bit0: System OSC Enable */ + +#define SCG_SOSCDIV_DIV3_SHIFT (16) +#define SCG_SOSCDIV_DIV3_MASK (7 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DISABLED (0 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DIVBY1 (1 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DIVBY2 (2 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DIVBY4 (3 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DIVBY8 (4 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DIVBY16 (5 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DIVBY32 (6 << SCG_SOSCDIV_DIV3_SHIFT) +#define SCG_SOSCDIV_DIV3_DIVBY64 (7 << SCG_SOSCDIV_DIV3_SHIFT) + +#define SCG_SOSCDIV_DIV2_SHIFT (8) +#define SCG_SOSCDIV_DIV2_MASK (7 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DISABLED (0 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DIVBY1 (1 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DIVBY2 (2 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DIVBY4 (3 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DIVBY8 (4 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DIVBY16 (5 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DIVBY32 (6 << SCG_SOSCDIV_DIV2_SHIFT) +#define SCG_SOSCDIV_DIV2_DIVBY64 (7 << SCG_SOSCDIV_DIV2_SHIFT) + +#define SCG_SOSCDIV_DIV1_SHIFT (0) +#define SCG_SOSCDIV_DIV1_MASK (7 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DISABLED (0 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DIVBY1 (1 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DIVBY2 (2 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DIVBY4 (3 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DIVBY8 (4 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DIVBY16 (5 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DIVBY32 (6 << SCG_SOSCDIV_DIV1_SHIFT) +#define SCG_SOSCDIV_DIV1_DIVBY64 (7 << SCG_SOSCDIV_DIV1_SHIFT) + +#define SCG_SIRCCSR_SEL (1 << 25) /* Bit25: Slow IRC Selected */ +#define SCG_SIRCCSR_VLD (1 << 24) /* Bit24: Slow IRC Valid */ +#define SCG_SIRCCSR_LK (1 << 23) /* Bit23: Lock */ +#define SCG_SIRCCSR_LPEN (1 << 2) /* Bit2: Slow IRC Low Power Enable */ +#define SCG_SIRCCSR_STEN (1 << 1) /* Bit3: Slow IRC Stop Enable */ +#define SCG_SIRCCSR_EN (1 << 0) /* Bit0: Slow IRC Enable */ + +#define SCG_SIRCDIV_DIV3_SHIFT (16) +#define SCG_SIRCDIV_DIV3_MASK (7 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DISABLED (0 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DIVBY1 (1 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DIVBY2 (2 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DIVBY4 (3 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DIVBY8 (4 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DIVBY16 (5 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DIVBY32 (6 << SCG_SIRCDIV_DIV3_SHIFT) +#define SCG_SIRCDIV_DIV3_DIVBY64 (7 << SCG_SIRCDIV_DIV3_SHIFT) + +#define SCG_SIRCDIV_DIV2_SHIFT (8) +#define SCG_SIRCDIV_DIV2_MASK (7 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DISABLED (0 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DIVBY1 (1 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DIVBY2 (2 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DIVBY4 (3 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DIVBY8 (4 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DIVBY16 (5 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DIVBY32 (6 << SCG_SIRCDIV_DIV2_SHIFT) +#define SCG_SIRCDIV_DIV2_DIVBY64 (7 << SCG_SIRCDIV_DIV2_SHIFT) + +#define SCG_SIRCDIV_DIV1_SHIFT (0) +#define SCG_SIRCDIV_DIV1_MASK (7 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DISABLED (0 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DIVBY1 (1 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DIVBY2 (2 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DIVBY4 (3 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DIVBY8 (4 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DIVBY16 (5 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DIVBY32 (6 << SCG_SIRCDIV_DIV1_SHIFT) +#define SCG_SIRCDIV_DIV1_DIVBY64 (7 << SCG_SIRCDIV_DIV1_SHIFT) + +#define SCG_SIRCCFG_RANGE_SHIFT (0) +#define SCG_SIRCCFG_RANGE_MASK (1 << SCG_SIRCCFG_RANGE_SHIFT) +#define SCG_SIRCCFG_RANGE_2MHZ (0 << SCG_SIRCCFG_RANGE_SHIFT) +#define SCG_SIRCCFG_RANGE_8MHZ (1 << SCG_SIRCCFG_RANGE_SHIFT) + +#define SCG_FIRCCSR_ERR (1 << 26) /* Bit26: Fast IRC Clock Error */ +#define SCG_FIRCCSR_SEL (1 << 25) /* Bit25: Fast IRC Selected */ +#define SCG_FIRCCSR_VLD (1 << 24) /* Bit24: Fast IRC Valid */ +#define SCG_FIRCCSR_LK (1 << 23) /* Bit23: Lock */ +#define SCG_FIRCCSR_TRUP (1 << 9) /* Bit9: Fast IRC Trim Update */ +#define SCG_FIRCCSR_TREN (1 << 8) /* Bit8: Fast IRC Trim Enable */ +#define SCG_FIRCCSR_REGOFF (1 << 3) /* Bit3: Fast IRC Regulator Off */ +#define SCG_FIRCCSR_LPEN (1 << 2) /* Bit2: Fast IRC Low Power Enable */ +#define SCG_FIRCCSR_STEN (1 << 1) /* Bit1: Fast IRC Stop Enable */ +#define SCG_FIRCCSR_EN (1 << 0) /* Bit0: Fast IRC Enable */ + +#define SCG_FIRCDIV_DIV3_SHIFT (16) +#define SCG_FIRCDIV_DIV3_MASK (7 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DISABLED (0 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DIVBY1 (1 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DIVBY2 (2 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DIVBY4 (3 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DIVBY8 (4 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DIVBY16 (5 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DIVBY32 (6 << SCG_FIRCDIV_DIV3_SHIFT) +#define SCG_FIRCDIV_DIV3_DIVBY64 (7 << SCG_FIRCDIV_DIV3_SHIFT) + +#define SCG_FIRCDIV_DIV2_SHIFT (8) +#define SCG_FIRCDIV_DIV2_MASK (7 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DISABLED (0 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DIVBY1 (1 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DIVBY2 (2 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DIVBY4 (3 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DIVBY8 (4 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DIVBY16 (5 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DIVBY32 (6 << SCG_FIRCDIV_DIV2_SHIFT) +#define SCG_FIRCDIV_DIV2_DIVBY64 (7 << SCG_FIRCDIV_DIV2_SHIFT) + +#define SCG_FIRCDIV_DIV1_SHIFT (0) +#define SCG_FIRCDIV_DIV1_MASK (7 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DISABLED (0 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DIVBY1 (1 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DIVBY2 (2 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DIVBY4 (3 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DIVBY8 (4 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DIVBY16 (5 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DIVBY32 (6 << SCG_FIRCDIV_DIV1_SHIFT) +#define SCG_FIRCDIV_DIV1_DIVBY64 (7 << SCG_FIRCDIV_DIV1_SHIFT) + +#define SCG_FIRCCFG_RANGE_SHIFT (0) +#define SCG_FIRCCFG_RANGE_MASK (3 << SCG_FIRCCFG_RANGE_SHIFT) +#define SCG_FIRCCFG_RANGE_48MHZ (0 << SCG_FIRCCFG_RANGE_SHIFT) +#define SCG_FIRCCFG_RANGE_52MHZ (1 << SCG_FIRCCFG_RANGE_SHIFT) +#define SCG_FIRCCFG_RANGE_56MHZ (2 << SCG_FIRCCFG_RANGE_SHIFT) +#define SCG_FIRCCFG_RANGE_60MHZ (3 << SCG_FIRCCFG_RANGE_SHIFT) + +/* FIRC Trim Configuration */ + +#define SCG_FIRCTCFG_TRIMDIV_SHIFT (8) /* Divide the System OSC down for Fast IRC Triming */ +#define SCG_FIRCTCFG_TRIMDIV_MASK (7 << SCG_FIRCTCFG_TRIMDIV_SHIFT) +#define SCG_FIRCTCFG_TRIMDIV_DIVBY1 (0 << SCG_FIRCTCFG_TRIMDIV_SHIFT) +#define SCG_FIRCTCFG_TRIMDIV_DIVBY128 (1 << SCG_FIRCTCFG_TRIMDIV_SHIFT) +#define SCG_FIRCTCFG_TRIMDIV_DIVBY256 (2 << SCG_FIRCTCFG_TRIMDIV_SHIFT) +#define SCG_FIRCTCFG_TRIMDIV_DIVBY512 (3 << SCG_FIRCTCFG_TRIMDIV_SHIFT) +#define SCG_FIRCTCFG_TRIMDIV_DIVBY1024 (4 << SCG_FIRCTCFG_TRIMDIV_SHIFT) +#define SCG_FIRCTCFG_TRIMDIV_DIVBY2048 (5 << SCG_FIRCTCFG_TRIMDIV_SHIFT) + +#define SCG_FIRCTCFG_TRIMSRC_SHIFT (0) /* Bit0: Trim Source */ +#define SCG_FIRCTCFG_TRIMSRC_MASK (3 << SCG_FIRCTCFG_TRIMSRC_SHIFT) +#define SCG_FIRCTCFG_TRIMSRC_SOSC (2 << SCG_FIRCTCFG_TRIMSRC_SHIFT) +#define SCG_FIRCTCFG_TRIMSRC_ROSC (3 << SCG_FIRCTCFG_TRIMSRC_SHIFT) + +#define SCG_FIRCSTAT_TRIMCOAR_SHIFT (8) +#define SCG_FIRCSTAT_TRIMCOAR_MASK (0x3f << SCG_FIRCSTAT_TRIMCOAR_SHIFT) + +#define SCG_FIRCSTAT_TRIMFINE_SHIFT (0) +#define SCG_FIRCSTAT_TRIMFINE_MASK (0x7f << SCG_FIRCSTAT_TRIMFINE_SHIFT) + +#define SCG_ROSCCSR_ERR (1 << 26) /* Bit26: RTC Clock Error */ +#define SCG_ROSCCSR_SEL (1 << 25) /* Bit25: RTC Selected */ +#define SCG_ROSCCSR_VLD (1 << 24) /* Bit24: RTC Valid */ +#define SCG_ROSCCSR_LK (1 << 23) /* Bit23: Lock */ +#define SCG_ROSCCSR_CMRE (1 << 17) /* Bit17: RTC Clock Monitor Reset Enable */ +#define SCG_ROSCCSR_CM (1 << 16) /* Bit16: RTC Clock Monitor Enable */ + +#define SCG_LPFLLCSR_ERR (1 << 26) /* Bit26: LPFLL Clock Error */ +#define SCG_LPFLLCSR_SEL (1 << 25) /* Bit25: LPFLL Selected */ +#define SCG_LPFLLCSR_VLD (1 << 24) /* Bit24: LPFLL Valid */ +#define SCG_LPFLLCSR_LK (1 << 23) /* Bit23: Lock */ +#define SCG_LPFLLCSR_CMRE (1 << 17) /* Bit17: LPFLL Clock Monitor Reset Enable */ +#define SCG_LPFLLCSR_CM (1 << 16) /* Bit16: LPFLL Clock Monitor */ +#define SCG_LPFLLCSR_TRMLOCK (1 << 10) /* Bit10: LPFLL Trim Lock */ +#define SCG_LPFLLCSR_TRUP (1 << 9) /* Bit9: LPFLL Trim Update */ +#define SCG_LPFLLCSR_TREN (1 << 8) /* Bit8: LPFLL Trim Enable */ +#define SCG_LPFLLCSR_STEN (1 << 1) /* Bit1: LPFLL Stop Enable */ +#define SCG_LPFLLCSR_EN (1 << 0) /* Bit0: LPFLL Enable */ + +#define SCG_LPFLLDIV_DIV3_SHIFT (16) +#define SCG_LPFLLDIV_DIV3_MASK (7 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DISABLED (0 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DIVBY1 (1 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DIVBY2 (2 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DIVBY4 (3 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DIVBY8 (4 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DIVBY16 (5 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DIVBY32 (6 << SCG_LPFLLDIV_DIV3_SHIFT) +#define SCG_LPFLLDIV_DIV3_DIVBY64 (7 << SCG_LPFLLDIV_DIV3_SHIFT) + +#define SCG_LPFLLDIV_DIV2_SHIFT (8) +#define SCG_LPFLLDIV_DIV2_MASK (7 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DISABLED (0 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DIVBY1 (1 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DIVBY2 (2 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DIVBY4 (3 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DIVBY8 (4 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DIVBY16 (5 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DIVBY32 (6 << SCG_LPFLLDIV_DIV2_SHIFT) +#define SCG_LPFLLDIV_DIV2_DIVBY64 (7 << SCG_LPFLLDIV_DIV2_SHIFT) + +#define SCG_LPFLLDIV_DIV1_SHIFT (0) +#define SCG_LPFLLDIV_DIV1_MASK (7 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DISABLED (0 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DIVBY1 (1 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DIVBY2 (2 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DIVBY4 (3 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DIVBY8 (4 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DIVBY16 (5 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DIVBY32 (6 << SCG_LPFLLDIV_DIV1_SHIFT) +#define SCG_LPFLLDIV_DIV1_DIVBY64 (7 << SCG_LPFLLDIV_DIV1_SHIFT) + +#define SCG_LPFLLCFG_RANGE_SHIFT (0) /* Bit[1:0]: Frequency Range */ +#define SCG_LPFLLCFG_RANGE_MASK (3 << SCG_LPFLLCFG_RANGE_SHIFT) +#define SCG_LPFLLCFG_RANGE_48MHZ (0 << SCG_LPFLLCFG_RANGE_SHIFT) +#define SCG_LPFLLCFG_RANGE_72MHZ (1 << SCG_LPFLLCFG_RANGE_SHIFT) + +#define SCG_LPFLLTCFG_LOCKW2LSB (1 << 16) /* Bit16: Lock LPFLL with 2 LSBS */ + +#define SCG_LPFLLTCFG_TRIMDIV_SHIFT (8) /* Bit[12:8]: LPFLL Trim Predivide */ +#define SCG_LPFLLTCFG_TRIMDIV_MASK (0x1f << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY1 (0 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY2 (1 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY3 (2 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY4 (3 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY5 (4 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY6 (5 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY7 (6 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY8 (7 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY9 (8 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY10 (9 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY11 (10 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY12 (11 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY13 (12 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY14 (13 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY15 (14 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY16 (15 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY17 (16 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY18 (17 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY19 (18 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY20 (19 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY21 (20 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY22 (21 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY23 (22 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY24 (23 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY25 (24 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY26 (25 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY27 (26 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY28 (27 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY29 (28 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY30 (29 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY31 (30 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) +#define SCG_LPFLLTCFG_TRIMDIV_BY32 (31 << SCG_LPFLLTCFG_TRIMDIV_SHIFT) + +#define SCG_LPFLLTCFG_TRIMSRC_SHIFT (0) +#define SCG_LPFLLTCFG_TRIMSRC_MASK (3 << SCG_LPFLLTCFG_TRIMSRC_SHIFT) +#define SCG_LPFLLTCFG_TRIMSRC_SIRC (0 << SCG_LPFLLTCFG_TRIMSRC_SHIFT) +#define SCG_LPFLLTCFG_TRIMSRC_FIRC (1 << SCG_LPFLLTCFG_TRIMSRC_SHIFT) +#define SCG_LPFLLTCFG_TRIMSRC_SOSC (2 << SCG_LPFLLTCFG_TRIMSRC_SHIFT) +#define SCG_LPFLLTCFG_TRIMSRC_ROSC (3 << SCG_LPFLLTCFG_TRIMSRC_SHIFT) + +#endif /* _ARCH_RISCV_SRC_RV32M1_CHIP_RV32M1RI5CY_SCG_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1.h b/arch/risc-v/src/rv32m1/rv32m1.h new file mode 100644 index 00000000000..35ff060995d --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1.h @@ -0,0 +1,43 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include "riscv_internal.h" + +/* Peripherals **************************************************************/ + +#include "chip.h" + +#include "rv32m1_clockconfig.h" +#include "rv32m1_pcc.h" +#include "rv32m1_gpio.h" + +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_allocateheap.c b/arch/risc-v/src/rv32m1/rv32m1_allocateheap.c new file mode 100644 index 00000000000..ee9ba52ffa9 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_allocateheap.c @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_allocateheap.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include "rv32m1.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: riscv_addregion + * + * Description: + * RAM may be added in non-contiguous chunks. This routine adds all chunks + * that may be used for heap. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void riscv_addregion(void) +{ +} +#endif diff --git a/arch/risc-v/src/rv32m1/rv32m1_clockconfig.c b/arch/risc-v/src/rv32m1/rv32m1_clockconfig.c new file mode 100644 index 00000000000..d11b4852f6b --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_clockconfig.c @@ -0,0 +1,663 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_clockconfig.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "riscv_arch.h" +#include "chip.h" +#include "hardware/rv32m1_scg.h" +#include "hardware/rv32m1_smc.h" +#include "rv32m1_clockconfig.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_modifyreg32 + ****************************************************************************/ + +static void rv32m1_modifyreg32(uint32_t addr, uint32_t bitclr, + uint32_t bitset) +{ + uint32_t regval = getreg32(addr); + regval &= ~bitclr; + regval |= bitset; + putreg32(regval, addr); +} + +/**************************************************************************** + * Name: rv32m1_sircfreq + ****************************************************************************/ + +static unsigned rv32m1_sircfreq(void) +{ + uint32_t regval = getreg32(RV32M1_SCG_SIRCCSR); + + /* If the SIRC is Invalid or Disabled */ + + if (!(regval & SCG_SIRCCSR_VLD)) + { + return 0u; + } + + regval = getreg32(RV32M1_SCG_SIRCCFG) & SCG_SIRCCFG_RANGE_MASK; + if (regval == SCG_SIRCCFG_RANGE_8MHZ) + { + return 8000000u; + } + + /* SIRC provides 2 options of frequency: 8MHz and 2MHz, + * In this case, it has to be 2MHz. + */ + + return 2000000u; +} + +/**************************************************************************** + * Name: rv32m1_fircfreq + ****************************************************************************/ + +static unsigned rv32m1_fircfreq(void) +{ + uint32_t regval = getreg32(RV32M1_SCG_FIRCCSR); + + /* If the FIRC is Invalid or Disabled */ + + if (!(regval & SCG_FIRCCSR_VLD)) + { + return 0u; + } + + regval = getreg32(RV32M1_SCG_FIRCCFG) & SCG_FIRCCFG_RANGE_MASK; + if (regval == SCG_FIRCCFG_RANGE_48MHZ) + { + return 48000000u; + } + + if (regval == SCG_FIRCCFG_RANGE_52MHZ) + { + return 52000000u; + } + + if (regval == SCG_FIRCCFG_RANGE_56MHZ) + { + return 56000000u; + } + + /* FIRC provides 4 options of frequency: 48MHz, 52MHz, 56MHz, 60MHz, + * In this case, it has to be 60MHz. + */ + + return 60000000u; +} + +/**************************************************************************** + * Name: rv32m1_lpfllfreq + ****************************************************************************/ + +static unsigned rv32m1_lpfllfreq(void) +{ + uint32_t regval = getreg32(RV32M1_SCG_LPFLLCSR); + + /* If the LPFLL is Invalid or Disabled */ + + if (!(regval & SCG_LPFLLCSR_VLD)) + { + return 0u; + } + + regval = getreg32(RV32M1_SCG_LPFLLCFG) & SCG_LPFLLCFG_RANGE_MASK; + if (regval == SCG_LPFLLCFG_RANGE_48MHZ) + { + return 48000000u; + } + + /* LPFLL provides 2 options of frequency: 48MHz, 72MHz, + * In this case, it has to be 72MHz. + */ + + return 72000000u; +} + +/**************************************************************************** + * Name: rv32m1_soscfreq + ****************************************************************************/ + +static unsigned rv32m1_soscfreq(void) +{ + uint32_t regval = getreg32(RV32M1_SCG_SOSCCSR); + + /* If the SOSC is Invalid or Disabled */ + + if (!(regval & SCG_SOSCCSR_VLD)) + { + return 0u; + } + +#ifdef RV32M1_BOARD_XTAL + return RV32M1_BOARD_XTAL; +#else + return 0u; +#endif +} + +/**************************************************************************** + * Name: rv32m1_lpocfreq + ****************************************************************************/ + +static unsigned rv32m1_lpocfreq(void) +{ + return 1000u; +} + +/**************************************************************************** + * Name: rv32m1_roscfreq + ****************************************************************************/ + +static unsigned rv32m1_roscfreq(void) +{ + uint32_t regval = getreg32(RV32M1_SCG_ROSCCSR); + + /* If the ROSC is Invalid or Disabled */ + + if (!(regval & SCG_ROSCCSR_VLD)) + { + return 0; + } + + return 32768u; +} + +/**************************************************************************** + * Name: rv32m1_corefreq + ****************************************************************************/ + +static unsigned rv32m1_corefreq(void) +{ + uint32_t scs; + uint32_t div; + + uint32_t regval = getreg32(RV32M1_SCG_ROSCCSR); + uint32_t freq = 0; + + scs = regval & SCG_CSR_SCS_MASK; + + switch (scs) + { + case SCG_CSR_SCS_SOSC: + freq = rv32m1_soscfreq(); + break; + + case SCG_CSR_SCS_SIRC: + freq = rv32m1_sircfreq(); + break; + + case SCG_CSR_SCS_FIRC: + freq = rv32m1_fircfreq(); + break; + + case SCG_CSR_SCS_ROSC: + freq = rv32m1_roscfreq(); + break; + + case SCG_CSR_SCS_LPFLL: + freq = rv32m1_lpfllfreq(); + break; + + default: + freq = 0; + break; + } + + div = (regval & SCG_CSR_DIVCORE_MASK) >> SCG_CSR_DIVCORE_SHIFT; + div += 1; + + return freq / div; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_clockconfig + ****************************************************************************/ + +void rv32m1_clockconfig(void) +{ + /* Initialize SIRC */ + + putreg32(SCG_SIRCDIV_DIV1_DISABLED | + SCG_SIRCDIV_DIV2_DIVBY1 | + SCG_SIRCDIV_DIV3_DIVBY1 , + RV32M1_SCG_SIRCDIV); + + /* 8MHZ is wanted */ + + putreg32(SCG_SIRCCFG_RANGE_8MHZ, RV32M1_SCG_SIRCCFG); + + /* Enable SIRC with Lower Power Mode support */ + + rv32m1_modifyreg32(RV32M1_SCG_SIRCCSR, 0, + SCG_SIRCCSR_EN | SCG_SIRCCSR_LPEN); + + /* Wait for SIRC to be valid */ + + while (!(getreg32(RV32M1_SCG_SIRCCSR) & SCG_SIRCCSR_VLD)) ; + + /* Switch to SIRC clock as System Clock */ + + putreg32(SCG_RCCR_SCS_SIRC | + SCG_RCCR_DIVCORE_DIV1 | + SCG_RCCR_DIVSLOW_DIV4 , + RV32M1_SCG_RCCR); + + /* Wait for SIRC as System Clock */ + + while ((getreg32(RV32M1_SCG_CSR) & SCG_CSR_SCS_MASK) != + SCG_CSR_SCS_SIRC); + + /* Initialize FIRC */ + + putreg32(SCG_FIRCDIV_DIV1_DIVBY1 | + SCG_FIRCDIV_DIV2_DIVBY1 | + SCG_FIRCDIV_DIV3_DIVBY1 , + RV32M1_SCG_FIRCDIV); + + /* 48MHz is wanted */ + + putreg32(SCG_FIRCCFG_RANGE_48MHZ, RV32M1_SCG_FIRCCFG); + + /* Enable FIRC */ + + rv32m1_modifyreg32(RV32M1_SCG_FIRCCSR, 0, SCG_FIRCCSR_EN); + + /* Wait for FIRC to be valid */ + + while (!(getreg32(RV32M1_SCG_FIRCCSR) & SCG_FIRCCSR_VLD)) ; + + /* Switch FIRC as the RUN Mode System Clock */ + + putreg32(SCG_RCCR_SCS_FIRC | + SCG_RCCR_DIVCORE_DIV1 | + SCG_RCCR_DIVBUS_DIV1 | + SCG_RCCR_DIVEXT_DIV1 | + SCG_RCCR_DIVSLOW_DIV4 , + RV32M1_SCG_RCCR); + + /* Wait for FIRC as System Clock */ + + while ((getreg32(RV32M1_SCG_CSR) & SCG_CSR_SCS_MASK) != + SCG_CSR_SCS_FIRC); + + /* Prepare LPFLL for HSRUN Mode */ + + putreg32(SCG_LPFLLDIV_DIV1_DIVBY1 | + SCG_LPFLLDIV_DIV2_DIVBY1 | + SCG_LPFLLDIV_DIV3_DIVBY1 , + RV32M1_SCG_LPFLLDIV); + + /* 72MHz is wanted */ + + putreg32(SCG_LPFLLCFG_RANGE_72MHZ, RV32M1_SCG_LPFLLCFG); + + /* Trim LPFLL input source */ + + rv32m1_modifyreg32(RV32M1_SCG_LPFLLTCFG, + SCG_LPFLLTCFG_TRIMDIV_MASK | + SCG_LPFLLTCFG_TRIMSRC_MASK, + SCG_LPFLLTCFG_TRIMDIV_BY4 | + SCG_LPFLLTCFG_TRIMSRC_SIRC); + + /* Enable LPFLL */ + + rv32m1_modifyreg32(RV32M1_SCG_LPFLLCSR, 0, SCG_LPFLLCSR_EN); + + /* Wait for LPFLL to be valid */ + + while (!(getreg32(RV32M1_SCG_LPFLLCSR) & SCG_LPFLLCSR_VLD)) ; + + /* Set LPFLL as the HSRUN Mode System Clock */ + + putreg32(SCG_HCCR_SCS_LPFLL | + SCG_HCCR_DIVCORE_DIV1 | + SCG_HCCR_DIVBUS_DIV1 | + SCG_HCCR_DIVEXT_DIV1 | + SCG_HCCR_DIVSLOW_DIV4 , + RV32M1_SCG_HCCR); + + /* Remove the power mode protection */ + + putreg32(SMC_PMPROT_PM_ALL_ALLOWED, RV32M1_SMC_PMPROT); + + /* Enable HSRUN Mode */ + + rv32m1_modifyreg32(RV32M1_SMC_PMCTRL, + SMC_PMCTRL_RUNM_MASK, + SMC_PMCTRL_RUNM_HSRUN); + + /* Wait for High Speed Run Mode stable */ + + while ((getreg32(RV32M1_SMC_PMSTAT) & SMC_PMSTAT_PMSTAT_MASK) != + SMC_PMSTAT_HSRUN); + + /* Wait for LPFLL as System Clock */ + + while ((getreg32(RV32M1_SCG_CSR) & SCG_CSR_SCS_MASK) != + SCG_CSR_SCS_LPFLL); +} + +/**************************************************************************** + * Name: rv32m1_clockfreq + * + * Description: + * Query the frequecy of a given clock source. + * + ****************************************************************************/ + +unsigned rv32m1_clockfreq(enum clk_e clk) +{ + uint32_t freq; + uint32_t div; + + switch (clk) + { + case CLK_SIRC: + return rv32m1_sircfreq(); + + case CLK_SIRCDIV1: + { + freq = rv32m1_sircfreq(); + div = (getreg32(RV32M1_SCG_SIRCDIV) & SCG_SIRCDIV_DIV1_MASK) >> + SCG_SIRCDIV_DIV1_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_SIRCDIV2: + { + freq = rv32m1_sircfreq(); + div = (getreg32(RV32M1_SCG_SIRCDIV) & SCG_SIRCDIV_DIV2_MASK) >> + SCG_SIRCDIV_DIV2_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_SIRCDIV3: + { + freq = rv32m1_sircfreq(); + div = (getreg32(RV32M1_SCG_SIRCDIV) & SCG_SIRCDIV_DIV3_MASK) >> + SCG_SIRCDIV_DIV3_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_FIRC: + return freq = rv32m1_fircfreq(); + + case CLK_FIRCDIV1: + { + freq = rv32m1_fircfreq(); + div = (getreg32(RV32M1_SCG_FIRCDIV) & SCG_FIRCDIV_DIV1_MASK) >> + SCG_FIRCDIV_DIV1_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_FIRCDIV2: + { + freq = rv32m1_fircfreq(); + div = (getreg32(RV32M1_SCG_FIRCDIV) & SCG_FIRCDIV_DIV2_MASK) >> + SCG_FIRCDIV_DIV2_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_FIRCDIV3: + { + freq = rv32m1_fircfreq(); + div = (getreg32(RV32M1_SCG_FIRCDIV) & SCG_FIRCDIV_DIV3_MASK) >> + SCG_FIRCDIV_DIV3_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_LPFLL: + return freq = rv32m1_lpfllfreq(); + + case CLK_LPFLLDIV1: + { + freq = rv32m1_lpfllfreq(); + div = (getreg32(RV32M1_SCG_LPFLLDIV) & SCG_LPFLLDIV_DIV1_MASK) >> + SCG_LPFLLDIV_DIV1_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_LPFLLDIV2: + { + freq = rv32m1_lpfllfreq(); + div = (getreg32(RV32M1_SCG_LPFLLDIV) & SCG_LPFLLDIV_DIV2_MASK) >> + SCG_LPFLLDIV_DIV2_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_LPFLLDIV3: + { + freq = rv32m1_lpfllfreq(); + div = (getreg32(RV32M1_SCG_LPFLLDIV) & SCG_LPFLLDIV_DIV3_MASK) >> + SCG_LPFLLDIV_DIV3_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_SOSC: + return rv32m1_soscfreq(); + + case CLK_SOSCDIV1: + { + freq = rv32m1_soscfreq(); + div = (getreg32(RV32M1_SCG_SOSCDIV) & SCG_SOSCDIV_DIV1_MASK) >> + SCG_LPFLLDIV_DIV1_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_SOSCDIV2: + { + freq = rv32m1_soscfreq(); + div = (getreg32(RV32M1_SCG_SOSCDIV) & SCG_SOSCDIV_DIV2_MASK) >> + SCG_LPFLLDIV_DIV2_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_SOSCDIV3: + { + freq = rv32m1_soscfreq(); + div = (getreg32(RV32M1_SCG_SOSCDIV) & SCG_SOSCDIV_DIV3_MASK) >> + SCG_LPFLLDIV_DIV3_SHIFT; + + /* If div is Zero, the clock source is disabled */ + + if (div == 0) + { + return 0u; + } + + return freq / (1 << (div - 1)); + } + break; + + case CLK_LPOC: + return rv32m1_lpocfreq(); + + case CLK_ROSC: + return rv32m1_roscfreq(); + + case CLK_CORE: + case CLK_PLAT: + case CLK_SYS: + return rv32m1_corefreq(); + + case CLK_BUS: + { + freq = rv32m1_corefreq(); + div = (getreg32(RV32M1_SCG_CSR) & SCG_CSR_DIVBUS_MASK) >> + SCG_CSR_DIVBUS_SHIFT; + + div += 1; + return freq / div; + } + break; + + case CLK_EXT: + { + freq = rv32m1_corefreq(); + div = (getreg32(RV32M1_SCG_CSR) & SCG_CSR_DIVEXT_MASK) >> + SCG_CSR_DIVEXT_SHIFT; + + div += 1; + return freq / div; + } + break; + + case CLK_SLOW: + { + freq = rv32m1_corefreq(); + div = (getreg32(RV32M1_SCG_CSR) & SCG_CSR_DIVSLOW_MASK) >> + SCG_CSR_DIVSLOW_SHIFT; + + div += 1; + return freq / div; + } + break; + + default: + return 0u; + } + + return 0u; +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_clockconfig.h b/arch/risc-v/src/rv32m1/rv32m1_clockconfig.h new file mode 100644 index 00000000000..a45658d7492 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_clockconfig.h @@ -0,0 +1,97 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_clockconfig.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_CLOCKCONFIG_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_CLOCKCONFIG_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +enum clk_e +{ + CLK_SIRC = 0x000, /* Slow IRC Clock */ + CLK_SIRCDIV1, + CLK_SIRCDIV2, + CLK_SIRCDIV3, + + CLK_FIRC = 0x100, /* Fast IRC Clock */ + CLK_FIRCDIV1, + CLK_FIRCDIV2, + CLK_FIRCDIV3, + + CLK_LPFLL = 0x200, /* Low Power FLL Cock */ + CLK_LPFLLDIV1, + CLK_LPFLLDIV2, + CLK_LPFLLDIV3, + + CLK_SOSC = 0x300, /* System Oscillator Clock */ + CLK_SOSCDIV1, + CLK_SOSCDIV2, + CLK_SOSCDIV3, + + CLK_LPOC = 0x400, /* LPO Clock */ + CLK_ROSC = 0x500, /* RTC Clock */ + + CLK_CORE = 0x600, + CLK_PLAT, + CLK_SYS, + + CLK_BUS = 0x700, + CLK_EXT = 0x800, + CLK_SLOW = 0x900, +}; + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +EXTERN void rv32m1_clockconfig(void); +EXTERN unsigned rv32m1_clockfreq(enum clk_e clk); + +#if defined(__cplusplus) +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_CLOCKCONFIG_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_delay.c b/arch/risc-v/src/rv32m1/rv32m1_delay.c new file mode 100644 index 00000000000..7a9d1c700c7 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_delay.c @@ -0,0 +1,236 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_delay.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "rv32m1.h" +#include "rv32m1_timersvc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Data Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_sw_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds in software + * way. The codes are copies of built-in up_mdelay. + * + ****************************************************************************/ + +static void up_sw_mdelay(unsigned int milliseconds) +{ + volatile unsigned int i; + volatile unsigned int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} + +/**************************************************************************** + * Name: up_sw_udelay + * + * Description: + * Delay inline for the requested number of microseconds in software + * way. The codes are copies of built-in up_udelay. + * + ****************************************************************************/ + +static void up_sw_udelay(unsigned int microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + + microseconds--; + } +} + +/**************************************************************************** + * Name: up_hw_delay + ****************************************************************************/ + +static void up_hw_delay(unsigned int period, unsigned int unit, + unsigned int ticks) +{ + uint32_t t; + uint32_t elapsed; + + /* The current value of timer */ + + uint32_t cval = rv32m1_timersvc_value(); + + /* The last value of timer */ + + uint32_t lval = cval; + + elapsed = 0; + + while (ticks > 0) + { + cval = rv32m1_timersvc_value(); + + if (cval != lval) + { + /* Accumulate the elapsed time */ + + elapsed += lval < cval ? cval - lval : cval + period - lval; + lval = cval; + + if (elapsed >= unit) + { + t = elapsed / unit; + elapsed -= t * unit; + + ticks -= t < ticks ? t : ticks; + } + } + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * System Clock Frequency of RV32M1 is variable, the built-in + * up_mdelay doesn't work very well for this chip. A Timer + * Service facilitates the delay function to get better accuracy. + * + * *** NOT multi-tasking friendly *** + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + uint32_t freq = rv32m1_timersvc_freq(); + uint32_t period = rv32m1_timersvc_period(); + + /* When Timer Service is up, and its frequency isn't less than 1KHz, + * the granularity of Timer Service can provide 1 ms accuracy. In + * other cases, sofware delay timer is preferred. + */ + + if (!rv32m1_timersvc_up() || freq < 1000u || !period) + { + up_sw_mdelay(milliseconds); + } + else + { + up_hw_delay(period, freq / 1000u, milliseconds); + } +} + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. + * System Clock Frequency of RV32M1 is variable, the built-in + * up_udelay doesn't work very well for this chip. A Timer + * Service facilitates the delay function to get better accuracy. + * + * *** NOT multi-tasking friendly *** + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + uint32_t freq = rv32m1_timersvc_freq(); + uint32_t period = rv32m1_timersvc_period(); + + /* When Timer Service is up, and its frequency isn't less than 1MHz, + * the granularity of Timer Service can provide 1 us accuracy. In + * other cases, sofware delay timer is preferred. + */ + + if (!rv32m1_timersvc_up() || freq < 1000000u || !period) + { + up_sw_udelay(microseconds); + } + else + { + up_hw_delay(period, freq / 1000000u, microseconds); + } +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_gpio.c b/arch/risc-v/src/rv32m1/rv32m1_gpio.c new file mode 100644 index 00000000000..6b71e34058f --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_gpio.c @@ -0,0 +1,798 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_gpio.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "riscv_arch.h" +#include "chip.h" +#include "hardware/rv32m1_port.h" +#include "hardware/rv32m1_gpio.h" +#include "rv32m1_pcc.h" +#include "rv32m1_gpio.h" + +/**************************************************************************** + * Pre-Processor Declarations + ****************************************************************************/ + +#define RV32M1_NGPIO_PORTS 5 + +/**************************************************************************** + * Data Type Definition + ****************************************************************************/ + +struct rv32m1_ctrlbase_s +{ + const uint32_t portbase; /* Port Configure Base */ + const uint32_t gpiobase; /* GPIO Configure Base */ + const uint32_t portgate; /* Port Clock Control Gate */ + const uint32_t gpiogate; /* GPIO Clock Control Gate */ + const uint32_t irq; /* IRQ Number */ + FAR sq_queue_t *isrchain; /* Interrupt Service Routine Chain */ +}; + +struct rv32m1_isr_s +{ + sq_entry_t link; + xcpt_t isr; + FAR void *arg; + uint32_t pin; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +#if RV32M1_NGPIO_PORTS > 0 +static sq_queue_t g_porta_isrchain = +{ + .head = NULL, + .tail = NULL +}; +#endif +#if RV32M1_NGPIO_PORTS > 1 +static sq_queue_t g_portb_isrchain = +{ + .head = NULL, + .tail = NULL +}; +#endif +#if RV32M1_NGPIO_PORTS > 2 +static sq_queue_t g_portc_isrchain = +{ + .head = NULL, + .tail = NULL +}; +#endif +#if RV32M1_NGPIO_PORTS > 3 +static sq_queue_t g_portd_isrchain = +{ + .head = NULL, + .tail = NULL +}; +#endif +#if RV32M1_NGPIO_PORTS > 4 +static sq_queue_t g_porte_isrchain = +{ + .head = NULL, + .tail = NULL +}; +#endif + +/* Base addresses for each GPIO block */ + +static struct rv32m1_ctrlbase_s g_ctrlbase[RV32M1_NGPIO_PORTS] = +{ +#if RV32M1_NGPIO_PORTS > 0 + { + .portbase = RV32M1_PORTA_BASE, + .gpiobase = RV32M1_GPIOA_BASE, + .portgate = RV32M1_PCC_PORTA, + .gpiogate = 0, + .irq = RV32M1_IRQ_PORTA, + .isrchain = &g_porta_isrchain, + }, +#endif +#if RV32M1_NGPIO_PORTS > 1 + { + .portbase = RV32M1_PORTB_BASE, + .gpiobase = RV32M1_GPIOB_BASE, + .portgate = RV32M1_PCC_PORTB, + .gpiogate = 0, + .irq = RV32M1_IRQ_PORTB, + .isrchain = &g_portb_isrchain, + }, +#endif +#if RV32M1_NGPIO_PORTS > 2 + { + .portbase = RV32M1_PORTC_BASE, + .gpiobase = RV32M1_GPIOC_BASE, + .portgate = RV32M1_PCC_PORTC, + .gpiogate = 0, + .irq = RV32M1_IRQ_PORTC, + .isrchain = &g_portc_isrchain, + }, +#endif +#if RV32M1_NGPIO_PORTS > 3 + { + .portbase = RV32M1_PORTD_BASE, + .gpiobase = RV32M1_GPIOD_BASE, + .portgate = RV32M1_PCC_PORTD, + .gpiogate = 0, + .irq = RV32M1_IRQ_PORTD, + .isrchain = &g_portd_isrchain, + }, +#endif +#if RV32M1_NGPIO_PORTS > 4 + { + .portbase = RV32M1_PORTE_BASE, + .gpiobase = RV32M1_GPIOE_BASE, + .portgate = RV32M1_PCC_PORTE, + .gpiogate = RV32M1_PCC_GPIOE, + .irq = RV32M1_IRQ_PORTE, + .isrchain = &g_porte_isrchain, + }, +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_modifyreg32 + ****************************************************************************/ + +static inline void rv32m1_modifyreg32(uint32_t addr, uint32_t bitclr, + uint32_t bitset) +{ + uint32_t regval = getreg32(addr); + regval &= ~bitclr; + regval |= bitset; + putreg32(regval, addr); +} + +/**************************************************************************** + * Name: rv32m1_gpio_irqconfig + ****************************************************************************/ + +static void rv32m1_gpio_irqconfig(uint32_t cfgset) +{ + uint32_t portbase; + + unsigned int port; + unsigned int pin; + + uint32_t irqc; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + + /* Get the port base address */ + + portbase = g_ctrlbase[port].portbase; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + irqc = (cfgset & GPIO_INT_MASK) >> GPIO_INT_SHIFT; + + /* Write '1' to clear Interrupt flag */ + + putreg32(pin << 1, portbase + RV32M1_PORT_ISFR_OFFSET); + + rv32m1_modifyreg32(portbase + (pin << 2), PORT_PCR_IRQC_MASK, + (irqc << PORT_PCR_IRQC_SHIFT) & PORT_PCR_IRQC_MASK); +} + +/**************************************************************************** + * Name: rv32m1_gpio_portconfig + ****************************************************************************/ + +static void rv32m1_gpio_portconfig(uint32_t cfgset) +{ + uint32_t portbase; + + unsigned int port; + unsigned int pin; + + uint32_t regval; + uint32_t cfg; + + /* No Sanity check of port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + + /* Get the port base address */ + + portbase = g_ctrlbase[port].portbase; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + regval = getreg32(portbase + (pin << 2)); + + cfg = cfgset & GPIO_PUPD_MASK; + + if (cfg == GPIO_FLOAT) + { + /* Float */ + + regval &= ~PORT_PCR_PE; + } + else + { + /* Pull Enable */ + + regval |= PORT_PCR_PE; + + if (cfg == GPIO_PULLUP) + { + /* Pull Up */ + + regval |= PORT_PCR_PS; + } + else + { + /* Pull Down */ + + regval &= ~PORT_PCR_PS; + } + } + + if (cfgset & GPIO_OPENDRAIN) + { + /* Open Drain Enable */ + + regval |= PORT_PCR_ODE; + } + else + { + /* Open Drain Disable */ + + regval &= ~PORT_PCR_ODE; + } + + if (cfgset & GPIO_FILTER) + { + /* Passive Filter Enable */ + + regval |= PORT_PCR_PFE; + } + else + { + /* Passive Filter Disable */ + + regval &= ~PORT_PCR_PFE; + } + + if (cfgset & GPIO_SSR) + { + /* Slow Slew Rate Enable */ + + regval |= PORT_PCR_SRE; + } + else + { + /* Fast Slew Rate Enable */ + + regval &= ~PORT_PCR_SRE; + } + + putreg32(regval, portbase + (pin << 2)); +} + +/**************************************************************************** + * Name: rv32m1_gpio_interrupt + ****************************************************************************/ + +LOCATE_ITCM +static int rv32m1_gpio_interrupt(int irq, FAR void *context, FAR void *arg) +{ + const FAR struct rv32m1_ctrlbase_s *ctrl; + const FAR sq_queue_t *isrchain; + const FAR sq_entry_t *e; + const FAR struct rv32m1_isr_s *priv; + + uint32_t portbase; + + uint32_t risf; /* the Read([red]) Interrupt status Flag */ + uint32_t wisf; /* The Interrupt status Flag to write back */ + + ctrl = (const FAR struct rv32m1_ctrlbase_s *)arg; + portbase = ctrl->portbase; + isrchain = ctrl->isrchain; + + risf = getreg32(portbase + RV32M1_PORT_ISFR_OFFSET); + wisf = 0; + + /* Enumerate gpio isr chain to dispatch services */ + + e = sq_peek(isrchain); + while (e) + { + priv = container_of(e, const struct rv32m1_isr_s, link); + + /* Dispatch services to whom has subcribed(registered) the + * corresponding pin. + */ + + if (risf & (1 << priv->pin)) + { + wisf |= 1 << priv->pin; + + /* Double check isr to avoid System Crash */ + + if (priv->isr) + { + priv->isr(irq, context, priv->arg); + } + } + + e = sq_next(e); + } + + /* Write '1' to clear corresponding Interrupt Status bit Flag */ + + putreg32(wisf, portbase + RV32M1_PORT_ISFR_OFFSET); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_gpio_config + ****************************************************************************/ + +int rv32m1_gpio_config(uint32_t cfgset) +{ + uint32_t gpiobase; + uint32_t portbase; + unsigned int port; + unsigned int pin; + unsigned int mode; + + irqstate_t flags; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return -EINVAL; + } + + /* Get the gpio and port base address */ + + gpiobase = g_ctrlbase[port].gpiobase; + portbase = g_ctrlbase[port].portbase; + + /* Get the pin number and select the port configuration register for that + * pin + */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Interrupts must be disabled from here on out so that we have mutually + * exclusive access to all of the GPIO configuration registers. + */ + + flags = enter_critical_section(); + + rv32m1_pcc_clock_enable(g_ctrlbase[port].portgate); + + /* Open the GPIO GATE if required */ + + if (g_ctrlbase[port].gpiogate) + { + rv32m1_pcc_clock_enable(g_ctrlbase[port].gpiogate); + } + + /* Cofigure Open Drain, Pull Up/Down, Filter and Slew Rate abilities */ + + rv32m1_gpio_portconfig(cfgset); + + mode = cfgset & GPIO_MODE_MASK; + + if (mode == GPIO_INPUT) + { + rv32m1_modifyreg32(portbase + (pin << 2), PORT_PCR_MUX_MASK, + PORT_PCR_MUX_GPIO); + rv32m1_modifyreg32(gpiobase + RV32M1_GPIO_PDDR_OFFSET, 1 << pin, 0); + + /* Always configure the irq on this pin, even if the irq configure + * could be None. + */ + + rv32m1_gpio_irqconfig(cfgset); + } + else if (mode == GPIO_OUTPUT) + { + rv32m1_modifyreg32(portbase + (pin << 2), PORT_PCR_MUX_MASK, + PORT_PCR_MUX_GPIO); + rv32m1_modifyreg32(gpiobase + RV32M1_GPIO_PDDR_OFFSET, 0, 1 << pin); + + /* Initialize the output value */ + + if (cfgset & GPIO_OUTPUT_SET) + { + putreg32(1 << pin, gpiobase + RV32M1_GPIO_PSOR_OFFSET); + } + else + { + putreg32(1 << pin, gpiobase + RV32M1_GPIO_PCOR_OFFSET); + } + } + else + { + uint32_t alt = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + + rv32m1_modifyreg32(portbase + (pin << 2), PORT_PCR_MUX_MASK, + (alt << PORT_PCR_MUX_SHIFT) & PORT_PCR_MUX_MASK); + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: rv32m1_gpio_write + ****************************************************************************/ + +void rv32m1_gpio_write(uint32_t cfgset, bool value) +{ + uint32_t gpiobase; + unsigned int port; + unsigned int pin; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return ; + } + + /* Get the gpio base address */ + + gpiobase = g_ctrlbase[port].gpiobase; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + if (value) + { + putreg32(1 << pin, gpiobase + RV32M1_GPIO_PSOR_OFFSET); + } + else + { + putreg32(1 << pin, gpiobase + RV32M1_GPIO_PCOR_OFFSET); + } +} + +/**************************************************************************** + * Name: rv32m1_gpio_toggle + ****************************************************************************/ + +void rv32m1_gpio_toggle(uint32_t cfgset) +{ + uint32_t gpiobase; + unsigned int port; + unsigned int pin; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return ; + } + + /* Get the gpio base address */ + + gpiobase = g_ctrlbase[port].gpiobase; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + putreg32(1 << pin, gpiobase + RV32M1_GPIO_PTOR_OFFSET); +} + +/**************************************************************************** + * Name: rv32m1_gpio_read + ****************************************************************************/ + +bool rv32m1_gpio_read(uint32_t cfgset) +{ + uint32_t gpiobase; + unsigned int port; + unsigned int pin; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return false; + } + + /* Get the gpio base address */ + + gpiobase = g_ctrlbase[port].gpiobase; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return (getreg32(gpiobase + RV32M1_GPIO_PDIR_OFFSET) & (1 << pin)) != 0; +} + +/**************************************************************************** + * Name: rv32m1_gpio_irqenable + ****************************************************************************/ + +void rv32m1_gpio_irqenable(uint32_t cfgset) +{ + uint32_t irq; + unsigned int port; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return ; + } + + /* Get the irq */ + + irq = g_ctrlbase[port].irq; + + /* Configure the irq on the pin */ + + rv32m1_gpio_irqconfig(cfgset); + + up_enable_irq(irq); +} + +/**************************************************************************** + * Name: rv32m1_gpio_irqdisable + ****************************************************************************/ + +void rv32m1_gpio_irqdisable(uint32_t cfgset) +{ + uint32_t portbase; + unsigned int port; + unsigned int pin; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return ; + } + + /* Get the port base address */ + + portbase = g_ctrlbase[port].portbase; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + rv32m1_modifyreg32(portbase + (pin << 2), PORT_PCR_IRQC_MASK, 0); +} + +/**************************************************************************** + * Name: rv32m1_gpio_irqattach + ****************************************************************************/ + +int rv32m1_gpio_irqattach(uint32_t cfgset, xcpt_t isr, FAR void *arg) +{ + unsigned int port; + unsigned int pin; + uint32_t irq; + + int ret; + + irqstate_t flags; + + FAR sq_queue_t *isrchain; + FAR sq_entry_t *e; + + FAR struct rv32m1_isr_s *priv; + + if (!isr) + { + return -EINVAL; + } + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return -EINVAL; + } + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + isrchain = g_ctrlbase[port].isrchain; + irq = g_ctrlbase[port].irq; + + flags = enter_critical_section(); + + e = sq_peek(isrchain); + while (e) + { + priv = container_of(e, struct rv32m1_isr_s, link); + if (priv->isr == isr && priv->pin == pin && priv->arg == arg) + { + /* The isr has been one 'link' of Chain */ + + ret = 0; + goto done; + } + + e = sq_next(e); + } + + priv = (FAR struct rv32m1_isr_s *)kmm_malloc(sizeof(*priv)); + if (priv) + { + /* If it is the first time to attach an isr, the generic gpio + * isr has to be attached. + */ + + if (!sq_peek(isrchain)) + { + irq_attach(irq, rv32m1_gpio_interrupt, &g_ctrlbase[port]); + } + + priv->isr = isr; + priv->arg = arg; + priv->pin = pin; + + /* Append the new isr to Chain */ + + sq_addlast(&priv->link, isrchain); + + ret = 0; + } + else + { + ret = -ENOMEM; + } + +done: + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: rv32m1_gpio_irqdetach + ****************************************************************************/ + +int rv32m1_gpio_irqdetach(uint32_t cfgset, xcpt_t isr, FAR void *arg) +{ + uint32_t port; + uint32_t pin; + + int ret = -1; + + irqstate_t flags; + + FAR sq_queue_t *isrchain; + FAR sq_entry_t *cur; + FAR sq_entry_t *pre; + + FAR struct rv32m1_isr_s *priv; + + if (!isr) + { + return -EINVAL; + } + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return -EINVAL; + } + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Get the isr chain */ + + isrchain = g_ctrlbase[port].isrchain; + + flags = enter_critical_section(); + + pre = NULL; + cur = sq_peek(isrchain); + while (cur) + { + priv = container_of(cur, struct rv32m1_isr_s, link); + if (priv->isr == isr && priv->pin == pin && priv->arg == arg) + { + if (pre) + { + sq_remafter(pre, isrchain); + cur = pre; + } + else + { + sq_remfirst(isrchain); + cur = NULL; + } + + /* Return back resources */ + + kmm_free(priv); + + ret = 0; + } + + pre = cur; + cur = cur ? sq_next(cur) : sq_peek(isrchain); + } + + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: rv32m1_gpio_clearpending + ****************************************************************************/ + +void rv32m1_gpio_clearpending(uint32_t cfgset) +{ + uint32_t portbase; + unsigned int port; + unsigned int pin; + + /* Verify that this hardware supports the selected GPIO port */ + + port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (port >= RV32M1_NGPIO_PORTS) + { + return; + } + + /* Get the port base address */ + + portbase = g_ctrlbase[port].portbase; + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Write '1' to clear corresponding Interrupt Status bit Flag */ + + putreg32(1 << pin, portbase + RV32M1_PORT_ISFR_OFFSET); +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_gpio.h b/arch/risc-v/src/rv32m1/rv32m1_gpio.h new file mode 100644 index 00000000000..905eceda971 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_gpio.h @@ -0,0 +1,304 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_gpio.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_GPIO_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_GPIO_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "riscv_internal.h" +#include "chip.h" +#include "hardware/rv32m1_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Each port bit of the general-purpose I/O (GPIO) ports can be + * individually configured by software in several modes: + * + * - Input floating + * - Input pull-up + * - Input-pull-down + * - Output open-drain with pull-up or pull-down capability + * - Output push-pull with pull-up or pull-down capability + * - Alternate function push-pull with pull-up or pull-down capability + * - Alternate function open-drain with pull-up or pull-down capability + * - Analog + * + * 20-bit Encoding: 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * Inputs: MMUU IIII FS.. PPPB BBBB + * Outputs: MMUU .... FSOV PPPB BBBB + * Alternate Functions: MMUU AAAA FSO. PPPB BBBB + * Analog: MM.. .... FS.. PPPB BBBB + */ + +/* Mode: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * MM.. .... .... .... .... + */ + +#define GPIO_MODE_SHIFT (18) /* Bits 18-19: GPIO port mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode */ +# define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* General purpose output mode */ +# define GPIO_ALT (2 << GPIO_MODE_SHIFT) /* Alternate function mode */ + +/* Input/output pull-ups/downs (not used with analog): + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * ..UU .... .... .... .... + */ + +#define GPIO_PUPD_SHIFT (16) /* Bits 16-17: Pull-up/pull down */ +#define GPIO_PUPD_MASK (3 << GPIO_PUPD_SHIFT) +# define GPIO_FLOAT (0 << GPIO_PUPD_SHIFT) /* No pull-up, pull-down */ +# define GPIO_PULLUP (1 << GPIO_PUPD_SHIFT) /* Pull-up */ +# define GPIO_PULLDOWN (2 << GPIO_PUPD_SHIFT) /* Pull-down */ + +/* Alternate Functions: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... AAAA .... .... .... + */ + +#define GPIO_AF_SHIFT (12) /* Bits 12-15: Alternate function */ +#define GPIO_AF_MASK (7 << GPIO_AF_SHIFT) +# define GPIO_AF(n) ((n) << GPIO_AF_SHIFT) +# define GPIO_AF0 (0 << GPIO_AF_SHIFT) /* Analog */ +# define GPIO_AF1 (1 << GPIO_AF_SHIFT) /* GPIO */ +# define GPIO_AF2 (2 << GPIO_AF_SHIFT) +# define GPIO_AF3 (3 << GPIO_AF_SHIFT) +# define GPIO_AF4 (4 << GPIO_AF_SHIFT) +# define GPIO_AF5 (5 << GPIO_AF_SHIFT) +# define GPIO_AF6 (6 << GPIO_AF_SHIFT) +# define GPIO_AF7 (7 << GPIO_AF_SHIFT) + +/* Interrupt for Input pins only: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... IIII .... .... .... + */ + +#define GPIO_INT_SHIFT (12) +#define GPIO_INT_MASK (0xf << GPIO_INT_SHIFT) +#define GPIO_INT_NONE (0 << GPIO_INT_SHIFT) +#define GPIO_INT_LOW (8 << GPIO_INT_SHIFT) +#define GPIO_INT_RISE (9 << GPIO_INT_SHIFT) +#define GPIO_INT_FALL (10 << GPIO_INT_SHIFT) +#define GPIO_INT_EDGE (11 << GPIO_INT_SHIFT) +#define GPIO_INT_HIGH (12 << GPIO_INT_SHIFT) + +/* Passive Filter Enable: + * + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... F... .... .... + */ + +#define GPIO_FILTER (1 << 11) /* Bit11: 1=Passive Filter Enable */ + +/* Slow Slew Rate Enable (Default Fast Slew Rate): + * + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .S.. .... .... + */ + +#define GPIO_SSR (1 << 10) /* Bit10: 1=Slow Slew rate, 0=Fast Slew Rate */ + +/* Output/Alt function type selection: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ..O. .... .... + */ + +#define GPIO_OPENDRAIN (1 << 9) /* Bit9: 1=Open-drain output */ + +/* If the pin is a GPIO digital output, then this identifies the initial + * output value. If the pin is an input, this bit is overloaded to + * provide the qualifier to distinguish input pull-up and -down: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... ...V .... .... + */ + +#define GPIO_OUTPUT_SET (1 << 8) /* Bit 8: If output, initial value of output */ +#define GPIO_OUTPUT_CLEAR (0) + +/* This identifies the GPIO port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... PPP. .... + */ + +#define GPIO_PORT_SHIFT (5) /* Bit 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) /* GPIOA */ +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) /* GPIOB */ +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) /* GPIOC */ +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ + +/* This identifies the bit in the port: + * + * 1111 1111 1100 0000 0000 + * 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- + * .... .... .... ...B BBBB + */ + +#define GPIO_PIN_SHIFT (0) /* Bits 0-4: GPIO number: 0-31 */ +#define GPIO_PIN_MASK (31 << GPIO_PIN_SHIFT) +# define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +# define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +# define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +# define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +# define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +# define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +# define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +# define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +# define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +# define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +# define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +# define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +# define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +# define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +# define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +# define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) +# define GPIO_PIN16 (16 << GPIO_PIN_SHIFT) +# define GPIO_PIN17 (17 << GPIO_PIN_SHIFT) +# define GPIO_PIN18 (18 << GPIO_PIN_SHIFT) +# define GPIO_PIN19 (19 << GPIO_PIN_SHIFT) +# define GPIO_PIN20 (20 << GPIO_PIN_SHIFT) +# define GPIO_PIN21 (21 << GPIO_PIN_SHIFT) +# define GPIO_PIN22 (22 << GPIO_PIN_SHIFT) +# define GPIO_PIN23 (23 << GPIO_PIN_SHIFT) +# define GPIO_PIN24 (24 << GPIO_PIN_SHIFT) +# define GPIO_PIN25 (25 << GPIO_PIN_SHIFT) +# define GPIO_PIN26 (26 << GPIO_PIN_SHIFT) +# define GPIO_PIN27 (27 << GPIO_PIN_SHIFT) +# define GPIO_PIN28 (28 << GPIO_PIN_SHIFT) +# define GPIO_PIN29 (29 << GPIO_PIN_SHIFT) +# define GPIO_PIN30 (30 << GPIO_PIN_SHIFT) +# define GPIO_PIN31 (31 << GPIO_PIN_SHIFT) + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: rv32m1_gpio_config + ****************************************************************************/ + +EXTERN int rv32m1_gpio_config(uint32_t cfgset); + +/**************************************************************************** + * Name: rv32m1_gpio_write + ****************************************************************************/ + +EXTERN void rv32m1_gpio_write(uint32_t cfgset, bool value); + +/**************************************************************************** + * Name: rv32m1_gpio_toggle + ****************************************************************************/ + +EXTERN void rv32m1_gpio_toggle(uint32_t cfgset); + +/**************************************************************************** + * Name: rv32m1_gpio_read + ****************************************************************************/ + +EXTERN bool rv32m1_gpio_read(uint32_t cfgset); + +/**************************************************************************** + * Name: rv32m1_gpio_irqenable + ****************************************************************************/ + +EXTERN void rv32m1_gpio_irqenable(uint32_t cfgset); + +/**************************************************************************** + * Name: rv32m1_gpio_irqdisable + ****************************************************************************/ + +EXTERN void rv32m1_gpio_irqdisable(uint32_t cfgset); + +/**************************************************************************** + * Name: rv32m1_gpio_irqattach + ****************************************************************************/ + +EXTERN int rv32m1_gpio_irqattach(uint32_t cfgset, xcpt_t isr, FAR void *arg); + +/**************************************************************************** + * Name: rv32m1_gpio_irqdetach + ****************************************************************************/ + +EXTERN int rv32m1_gpio_irqdetach(uint32_t cfgset, xcpt_t isr, FAR void *arg); + +/**************************************************************************** + * Name: rv32m1_gpio_clearpending + ****************************************************************************/ + +EXTERN void rv32m1_gpio_clearpending(uint32_t cfgset); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_GPIO_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_head.S b/arch/risc-v/src/rv32m1/rv32m1_head.S new file mode 100644 index 00000000000..9663b398eac --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_head.S @@ -0,0 +1,237 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_head.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + /* Exported Symbols */ + + .global exception_common + .global __start + + .section .text + +__start: + + /* Set stack pointer to the idle thread stack */ + + lui sp, %hi(RV32M1_IDLESTACK_TOP) + addi sp, sp, %lo(RV32M1_IDLESTACK_TOP) + + /* Disable all interrupts (i.e. timer, external) in mie */ + + csrci mstatus, 0x8 + csrw mie, zero + + /* Initialize the Machine Trap Vector */ + + lui t0, %hi(_svector) + addi t0, t0, %lo(_svector) + csrw mtvec, t0 + + /* Jump to __rv32m1_start */ + + jal x1, __rv32m1_start + + /* We shouldn't return from __rv32m1_start */ + + .global _init + .global _fini + +_init: +_fini: + + /* These don't have to do anything since we use init_array/fini_array. */ + + ret + +/**************************************************************************** + * Name: exception_common + ****************************************************************************/ + +#ifdef CONFIG_RV32M1_ITCM + .section SECTION_ITCM +#endif + +exception_common: + + addi sp, sp, -XCPTCONTEXT_SIZE + + sw x1, 1*4(sp) /* ra */ + sw x3, 3*4(sp) /* gp */ + sw x4, 4*4(sp) /* tp */ + sw x5, 5*4(sp) /* t0 */ + sw x6, 6*4(sp) /* t1 */ + sw x7, 7*4(sp) /* t2 */ + sw x8, 8*4(sp) /* s0 */ + sw x9, 9*4(sp) /* s1 */ + sw x10, 10*4(sp) /* a0 */ + sw x11, 11*4(sp) /* a1 */ + sw x12, 12*4(sp) /* a2 */ + sw x13, 13*4(sp) /* a3 */ + sw x14, 14*4(sp) /* a4 */ + sw x15, 15*4(sp) /* a5 */ + sw x16, 16*4(sp) /* a6 */ + sw x17, 17*4(sp) /* a7 */ + sw x18, 18*4(sp) /* s2 */ + sw x19, 19*4(sp) /* s3 */ + sw x20, 20*4(sp) /* s4 */ + sw x21, 21*4(sp) /* s5 */ + sw x22, 22*4(sp) /* s6 */ + sw x23, 23*4(sp) /* s7 */ + sw x24, 24*4(sp) /* s8 */ + sw x25, 25*4(sp) /* s9 */ + sw x26, 26*4(sp) /* s10 */ + sw x27, 27*4(sp) /* s11 */ + sw x28, 28*4(sp) /* t3 */ + sw x29, 29*4(sp) /* t4 */ + sw x30, 30*4(sp) /* t5 */ + sw x31, 31*4(sp) /* t6 */ + +#if defined(INT_XCPT_REGS) && INT_XCPT_REGS >= 39 + csrr x28, 0x7b0 + csrr x29, 0x7b1 + csrr x30, 0x7b2 + sw x28, 33*4(sp) + sw x29, 34*4(sp) + sw x30, 35*4(sp) + csrr x28, 0x7b4 + csrr x29, 0x7b5 + csrr x30, 0x7b6 + sw x28, 36*4(sp) + sw x29, 37*4(sp) + sw x30, 38*4(sp) +#endif + + csrr s0, mstatus + sw s0, 32*4(sp) /* mstatus */ + + addi s0, sp, XCPTCONTEXT_SIZE + sw s0, 2*4(sp) /* original SP */ + + /* Setup arg0(exception cause), arg1(context) */ + + csrr a0, mcause /* exception cause */ + csrr s0, mepc + sw s0, 0(sp) /* exception PC */ + + mv a1, sp /* context = sp */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 15 + /* Switch to interrupt stack */ + + lui sp, %hi(g_intstacktop) + addi sp, sp, %lo(g_intstacktop) +#endif + + /* Call interrupt handler in C */ + + jal x1, rv32m1_dispatch_irq + + /* If context switch is needed, return a new sp */ + + mv sp, a0 + lw s0, 0(sp) /* restore mepc */ + csrw mepc, s0 + + lw s0, 32*4(sp) /* restore mstatus */ + csrw mstatus, s0 + +#if defined(INT_XCPT_REGS) && INT_XCPT_REGS >= 39 + lw x28, 36*4(sp) + lw x29, 37*4(sp) + lw x30, 38*4(sp) + csrrw x0, 0x7b4, x28 + csrrw x0, 0x7b5, x29 + csrrw x0, 0x7b6, x30 + lw x28, 33*4(sp) + lw x29, 34*4(sp) + lw x30, 35*4(sp) + csrrw x0, 0x7b0, x28 + csrrw x0, 0x7b1, x29 + csrrw x0, 0x7b2, x30 +#endif + + lw x3, 3*4(sp) /* gp */ + lw x4, 4*4(sp) /* tp */ + lw x5, 5*4(sp) /* t0 */ + lw x6, 6*4(sp) /* t1 */ + lw x7, 7*4(sp) /* t2 */ + lw x8, 8*4(sp) /* s0 */ + lw x9, 9*4(sp) /* s1 */ + lw x10, 10*4(sp) /* a0 */ + lw x11, 11*4(sp) /* a1 */ + lw x12, 12*4(sp) /* a2 */ + lw x13, 13*4(sp) /* a3 */ + lw x14, 14*4(sp) /* a4 */ + lw x15, 15*4(sp) /* a5 */ + lw x16, 16*4(sp) /* a6 */ + lw x17, 17*4(sp) /* a7 */ + lw x18, 18*4(sp) /* s2 */ + lw x19, 19*4(sp) /* s3 */ + lw x20, 20*4(sp) /* s4 */ + lw x21, 21*4(sp) /* s5 */ + lw x22, 22*4(sp) /* s6 */ + lw x23, 23*4(sp) /* s7 */ + lw x24, 24*4(sp) /* s8 */ + lw x25, 25*4(sp) /* s9 */ + lw x26, 26*4(sp) /* s10 */ + lw x27, 27*4(sp) /* s11 */ + lw x28, 28*4(sp) /* t3 */ + lw x29, 29*4(sp) /* t4 */ + lw x30, 30*4(sp) /* t5 */ + lw x31, 31*4(sp) /* t6 */ + + lw x1, 1*4(sp) /* ra */ + + lw sp, 2*4(sp) /* restore original sp */ + + /* Return from Machine Interrupt */ + + mret + +/******************************************************************************* + * Name: g_intstackalloc and g_intstacktop +*******************************************************************************/ + +#if CONFIG_ARCH_INTERRUPTSTACK > 15 + .bss + .balign 16 + .global g_intstackalloc + .global g_intstacktop + .type g_intstackalloc, object + .type g_intstacktop, object +g_intstackalloc: + .skip ((CONFIG_ARCH_INTERRUPTSTACK + 8) & ~15) +g_intstacktop: + .skip 4 + .size g_intstacktop, 4 + .size g_intstackalloc, (CONFIG_ARCH_INTERRUPTSTACK & ~15) +#endif diff --git a/arch/risc-v/src/rv32m1/rv32m1_idle.c b/arch/risc-v/src/rv32m1/rv32m1_idle.c new file mode 100644 index 00000000000..cb298865182 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_idle.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_idle.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "riscv_internal.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when there is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + nxsched_process_timer(); +#else + + board_autoled_off(LED_CPU); + + /* This would be an appropriate place to put some MCU-specific logic to + * sleep in a reduced power mode until an interrupt occurs to save power + */ + + asm("WFI"); + +#endif +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_irq.c b/arch/risc-v/src/rv32m1/rv32m1_irq.c new file mode 100644 index 00000000000..7d71b56fcaa --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_irq.c @@ -0,0 +1,306 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_irq.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "riscv_internal.h" +#include "riscv_arch.h" + +#include "rv32m1.h" +#include "hardware/rv32m1_eu.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_intmuxisr + ****************************************************************************/ + +LOCATE_ITCM +static int rv32m1_intmuxisr(int irq, void *context, FAR void *arg) +{ + UNUSED(irq); + UNUSED(context); + UNUSED(arg); + + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int i; + uint32_t base; + uint32_t regval; + uint32_t regaddr; + + /* Disable Machine interrupts */ + + up_irq_save(); + + rv32m1_pcc_clock_enable(RV32M1_PCC_INTMUX0); + + /* reset all the intmux channels */ + + for (i = 0; i < 8; ++i) + { + base = RV32M1_INTMUX_CH_BASE(i); + regaddr = base + INTMUX_CH_CSR_OFFSET; + regval = getreg32(regaddr); + regval |= INTMUX_CSR_RST; + putreg32(regval, regaddr); + } + + /* Disable all global interrupts */ + + putreg32(0, RV32M1_EU_INTPTEN); + + /* Colorize the interrupt stack for debug purposes */ + +#if defined(CONFIG_STACK_COLORATION) && CONFIG_ARCH_INTERRUPTSTACK > 15 + size_t intstack_size = (CONFIG_ARCH_INTERRUPTSTACK & ~15); + riscv_stack_color((FAR void *)((uintptr_t)&g_intstacktop - intstack_size), + intstack_size); +#endif + + /* Clear all pending flags */ + + putreg32(0xffffffff, RV32M1_EU_INTPTPENDCLR); + putreg32(0xffffffff, RV32M1_EU_EVTPENDCLR); + putreg32(0xffffffff, RV32M1_EU_INTPTSECURE); + + /* Attach INTMUX ISR */ + + irq_attach(RV32M1_IRQ_INTMUX0, rv32m1_intmuxisr, NULL); + + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Attach the ecall interrupt handler */ + + irq_attach(RV32M1_IRQ_ECALL_M, riscv_swint, NULL); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +LOCATE_ITCM +void up_disable_irq(int irq) +{ + int extirq; + uint32_t regval; + + if (irq >= RV32M1_IRQ_MEXT) + { + if (irq >= RV32M1_IRQ_INTMUX) + { + int const subirq = irq - RV32M1_IRQ_INTMUX; + int const chn = 0; + uint32_t regaddr = RV32M1_INTMUX_CH_BASE(chn) + + INTMUX_CH_IER_OFFSET; + + regval = getreg32(regaddr); + regval &= ~(1 << subirq); + putreg32(regval, regaddr); + } + else + { + extirq = irq - RV32M1_IRQ_MEXT; + + /* Clear enable bit for the irq */ + + regval = getreg32(RV32M1_EU_INTPTEN); + regval &= ~(1 << extirq); + putreg32(regval, RV32M1_EU_INTPTEN); + } + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +LOCATE_ITCM +void up_enable_irq(int irq) +{ + int extirq; + uint32_t regval; + + if (irq >= RV32M1_IRQ_MEXT) + { + if (irq >= RV32M1_IRQ_INTMUX) + { + int const subirq = irq - RV32M1_IRQ_INTMUX; + int const chn = 0; + uint32_t regaddr = RV32M1_INTMUX_CH_BASE(chn) + + INTMUX_CH_IER_OFFSET; + + regval = getreg32(regaddr); + regval |= 1 << subirq; + putreg32(regval, regaddr); + + extirq = RV32M1_IRQ_INTMUX0 - RV32M1_IRQ_MEXT; + } + else + { + extirq = irq - RV32M1_IRQ_MEXT; + } + + regval = getreg32(RV32M1_EU_INTPTEN); + + /* Set enable bit for the irq */ + + regval |= 1 << extirq; + putreg32(regval, RV32M1_EU_INTPTEN); + + /* Read INTPTEN back to make it sure */ + + (void)getreg32(RV32M1_EU_INTPTEN); + } +} + +/**************************************************************************** + * Name: riscv_get_newintctx + * + * Description: + * Return initial mstatus when a task is created. + * + ****************************************************************************/ + +uint32_t riscv_get_newintctx(void) +{ + /* Set machine previous privilege mode to machine mode. + * Also set machine previous interrupt enable + */ + + return (MSTATUS_MPPM | MSTATUS_MPIE); +} + +/**************************************************************************** + * Name: riscv_ack_irq + * + * Description: + * Acknowledge the IRQ + * + ****************************************************************************/ + +void riscv_ack_irq(int irq) +{ + board_autoled_on(LED_CPU); +} + +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * Return the current interrupt state and disable interrupts + * + ****************************************************************************/ + +LOCATE_ITCM +irqstate_t up_irq_save(void) +{ + uint32_t oldstat; + + /* Read mstatus & clear machine interrupt enable (MIE) in mstatus */ + + asm volatile ("csrrc %0, mstatus, %1": "=r" (oldstat) : "r"(MSTATUS_MIE)); + return oldstat; +} + +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * Restore previous IRQ mask state + * + ****************************************************************************/ + +LOCATE_ITCM +void up_irq_restore(irqstate_t flags) +{ + /* Write flags to mstatus */ + + asm volatile("csrw mstatus, %0" : /* no output */ : "r" (flags)); +} + +/**************************************************************************** + * Name: up_irq_enable + * + * Description: + * Return the current interrupt state and enable interrupts + * + ****************************************************************************/ + +irqstate_t up_irq_enable(void) +{ + uint32_t oldstat; + +#if 1 + /* Enable MEIE (machine external interrupt enable) */ + + /* TODO: should move to up_enable_irq() */ + + asm volatile ("csrrs %0, mie, %1": "=r" (oldstat) : "r"(MIE_MEIE)); +#endif + + /* Read mstatus & set machine interrupt enable (MIE) in mstatus */ + + asm volatile ("csrrs %0, mstatus, %1": "=r" (oldstat) : "r"(MSTATUS_MIE)); + return oldstat; +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_irq_dispatch.c b/arch/risc-v/src/rv32m1/rv32m1_irq_dispatch.c new file mode 100644 index 00000000000..aba75551a48 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_irq_dispatch.c @@ -0,0 +1,145 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_irq_dispatch.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "riscv_arch.h" +#include "riscv_internal.h" + +#include "rv32m1.h" +#include "hardware/rv32m1_eu.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t * g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * rv32m1_dispatch_irq + ****************************************************************************/ + +LOCATE_ITCM +void *rv32m1_dispatch_irq(uint32_t vector, uint32_t *regs) +{ + int vec = vector & 0x1f; + int irq = (vector >> 27) + vec; + uint32_t *mepc = regs; + + int irqofs = 0; + + /* NOTE: In case of ecall, we need to adjust mepc in the context */ + + if (RV32M1_IRQ_ECALL_M == irq) + { + *mepc += 4; + } + + if (RV32M1_IRQ_INTMUX0 <= irq) + { + uint32_t const chn = irq - RV32M1_IRQ_INTMUX0; + uint32_t regaddr = RV32M1_INTMUX_CH_BASE(chn) + INTMUX_CH_VEC_OFFSET; + uint32_t regval = getreg32(regaddr); + + /* CH_VEC coudle be 0 while INTMUX doesn't latch pending source + * interrupts. In that case a spurious interrupt is being serviced, + * and irq Number shouldn't be compensated. + * + * CH_VEC must be checked to account for spurious interrupts. + */ + + if (regval > 0) + { + /* Register VECN[13:2] = 48 x (CPU Vectors + NVIC Vectors) + + * H(The Highest Interrupt of INTMUX), + * + * 1 CPU Vectors for RV32M1 RISCV Cores. + * No NVIC Vectors for RV32M1 RISCV Cores, + * + * H can be obtained easily: + * H = VECN[13:2] - 48 + * + * H has to be offset by 8 to skip INTMUX0~7. + * + */ + + irqofs = (regval >> 2) - 48 + 8; + irq += irqofs; + } + } + + /* Acknowledge the interrupt */ + + riscv_ack_irq(irq); + +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + + if (RV32M1_IRQ_MEXT <= irq) + { + irq -= irqofs; + + /* Clear the pending flag */ + + putreg32(1 << vec, RV32M1_EU_INTPTPENDCLR); + } + +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)g_current_regs; + g_current_regs = NULL; + + return regs; +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_linker.h b/arch/risc-v/src/rv32m1/rv32m1_linker.h new file mode 100644 index 00000000000..e92b5664de1 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_linker.h @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_linker.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_LINKER_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_LINKER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_RV32M1_ITCM +# define SECTION_ITCM ".itcm" /* System ITCM */ +# define SECTION_UITCM ".uitcm" /* User ITCM */ +#endif + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* LOCATE_ITCM is a recommendation rather than a forced command + * to place codes in Section ITCM. It is effective when RV32M1 + * has ITCM. + */ + +#ifdef CONFIG_RV32M1_ITCM +# define LOCATE_ITCM locate_code(SECTION_ITCM) /* System ITCM */ +# define LOCATE_UITCM locate_code(SECTION_UITCM) /* User ITCM */ +#else +# define LOCATE_ITCM +# define LOCATE_UITCM +#endif + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#ifdef CONFIG_RV32M1_ITCM + EXTERN uint32_t _slitcm; /* Start of ITCM LMA */ + EXTERN uint32_t _svitcm; /* Start of ITCM VMA */ + EXTERN uint32_t _evitcm; /* End+1 of ITCM VMA */ + EXTERN uint32_t _suvitcm; /* Start of User ITCM VMA */ + EXTERN uint32_t _euvitcm; /* End+1 of User ITCM VMA */ +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_LINKER_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_lowputc.c b/arch/risc-v/src/rv32m1/rv32m1_lowputc.c new file mode 100644 index 00000000000..72ef51683a6 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_lowputc.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_lowputc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "rv32m1.h" +#include "rv32m1_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: riscv_lowputc + * + * Description: + * Output one byte on the serial console + * + ****************************************************************************/ + +void riscv_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + rv32m1_console_uart_putc(ch); +#endif /* HAVE_CONSOLE */ +} + +/**************************************************************************** + * Name: rv32m1_lowsetup + * + * Description: + * This performs basic initialization of the UART used for the serial + * console. Its purpose is to get the console output available as soon + * as possible. + * + ****************************************************************************/ + +void rv32m1_lowsetup(void) +{ +#if defined(HAVE_UART) + + /* Enable and configure the selected console device */ + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONFIG_SUPPRESS_UART_CONFIG) + rv32m1_console_uart_setup(); +#endif /* HAVE_SERIAL_CONSOLE && !CONFIG_SUPPRESS_UART_CONFIG */ +#endif /* HAVE_UART */ +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_lowputc.h b/arch/risc-v/src/rv32m1/rv32m1_lowputc.h new file mode 100644 index 00000000000..4f027c50263 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_lowputc.h @@ -0,0 +1,59 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_lowputc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_LOWPUTC_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_LOWPUTC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: rv32m1_lowsetup + ****************************************************************************/ + +EXTERN void rv32m1_lowsetup(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_LOWPUTC_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_memorymap.h b/arch/risc-v/src/rv32m1/rv32m1_memorymap.h new file mode 100644 index 00000000000..efdc818fc6b --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_memorymap.h @@ -0,0 +1,45 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_memorymap.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_MEMORYMAP_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_MEMORYMAP_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hardware/rv32m1_memorymap.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Idle thread stack starts from _ebss */ + +#ifndef __ASSEMBLY__ +#define RV32M1_IDLESTACK_BASE (uint32_t)&_ebss +#else +#define RV32M1_IDLESTACK_BASE _ebss +#endif + +#define RV32M1_IDLESTACK_SIZE (CONFIG_IDLETHREAD_STACKSIZE & ~3) +#define RV32M1_IDLESTACK_TOP (RV32M1_IDLESTACK_BASE + RV32M1_IDLESTACK_SIZE) + +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_MEMORYMAP_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_pcc.c b/arch/risc-v/src/rv32m1/rv32m1_pcc.c new file mode 100644 index 00000000000..3eafb17a72d --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_pcc.c @@ -0,0 +1,69 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_pcc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "riscv_arch.h" +#include "rv32m1_pcc.h" + +/**************************************************************************** + * Pre-Processor Declarations + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_pcc_clock_enable + ****************************************************************************/ + +void rv32m1_pcc_clock_enable(uint32_t regaddr) +{ + uint32_t regval = getreg32(regaddr); + regval |= PCC_CLKCFG_CGC; + putreg32(regval, regaddr); +} + +/**************************************************************************** + * Name: rv32m1_pcc_clock_disable + ****************************************************************************/ + +void rv32m1_pcc_clock_disable(uint32_t regaddr) +{ + uint32_t regval = getreg32(regaddr); + regval &= ~PCC_CLKCFG_CGC; + putreg32(regval, regaddr); +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_pcc.h b/arch/risc-v/src/rv32m1/rv32m1_pcc.h new file mode 100644 index 00000000000..fb5999ac54b --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_pcc.h @@ -0,0 +1,71 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_pcc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_PCC_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_PCC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "chip.h" +#include "hardware/rv32m1_pcc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: rv32m1_pcc_clock_enable + ****************************************************************************/ + +EXTERN void rv32m1_pcc_clock_enable(uint32_t regaddr); + +/**************************************************************************** + * Name: rv32m1_pcc_clock_disable + ****************************************************************************/ + +EXTERN void rv32m1_pcc_clock_disable(uint32_t regaddr); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_GPIO_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_serial.c b/arch/risc-v/src/rv32m1/rv32m1_serial.c new file mode 100644 index 00000000000..0df7ea5e3a4 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_serial.c @@ -0,0 +1,1184 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_serial.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include + +#include "riscv_arch.h" +#include "riscv_internal.h" + +#include "chip.h" +#include "rv32m1.h" +#include "rv32m1_uart.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct rv32m1_tty_s +{ + uart_dev_t * dev; /* TTY Device Reference */ + const int idx; /* TTY Index */ +}; + +#ifdef USE_SERIALDRIVER + +#ifdef HAVE_UART + +#if defined(CONFIG_RV32M1_LPUART0) +# define RV32M1_LPUART0_DEV g_uart0dev +#endif + +#if defined(CONFIG_RV32M1_LPUART1) +# define RV32M1_LPUART1_DEV g_uart1dev +#endif + +#if defined(CONFIG_RV32M1_LPUART2) +# define RV32M1_LPUART2_DEV g_uart2dev +#endif + +#if defined(CONFIG_RV32M1_LPUART3) +# define RV32M1_LPUART3_DEV g_uart3dev +#endif + +/* Which UART with be tty0/console and which tty1? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +#if defined(CONFIG_LPUART0_SERIAL_CONSOLE) +# define CONSOLE_DEV RV32M1_LPUART0_DEV +# define SERIAL_CONSOLE 0 +#elif defined(CONFIG_LPUART1_SERIAL_CONSOLE) +# define CONSOLE_DEV RV32M1_LPUART1_DEV +# define SERIAL_CONSOLE 1 +#elif defined(CONFIG_LPUART2_SERIAL_CONSOLE) +# define CONSOLE_DEV RV32M1_LPUART2_DEV +# define SERIAL_CONSOLE 2 +#elif defined(CONFIG_LPUART3_SERIAL_CONSOLE) +# define CONSOLE_DEV RV32M1_LPUART3_DEV +# define SERIAL_CONSOLE 3 +#elif defined(HAVE_SERIAL_CONSOLE) +# error "No Serial Consoles for RV32M1" +#endif + +#if defined(HAVE_SERIAL_CONSOLE) && !defined(CONSOLE_DEV) +# error "Serial Console Undefined for RV32M1" +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + const uintptr_t uartbase; /* Base address of UART registers */ + const uintptr_t pcc; /* Address of UART PCC clock gate */ + const uint32_t tx_gpio; /* LPUART TX GPIO pin configuration */ + const uint32_t rx_gpio; /* LPUART RX GPIO pin configuration */ + uint32_t baud; /* Configured baud */ + uint16_t irq; /* IRQ associated with this UART */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers */ + +static uint32_t up_getreg(struct up_dev_s *priv, int offset); +static void up_putreg(struct up_dev_s *priv, int offset, uint32_t value); +static void up_restoreuartint(struct up_dev_s *priv, uint32_t im); +static void up_disableuartint(struct up_dev_s *priv, uint32_t *im); +static void up_clkconfig(struct up_dev_s * priv); +static uint32_t up_clkfreq(struct up_dev_s * priv); + +/* Serial driver methods */ + +static void up_set_format(struct uart_dev_s * dev); +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context, FAR void *arg); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* LPUART Instances */ + +#ifdef CONFIG_RV32M1_LPUART0 +static char g_uart0rxbuffer[CONFIG_LPUART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_LPUART0_TXBUFSIZE]; + +static struct up_dev_s g_uart0priv = +{ + .uartbase = RV32M1_LPUART0_BASE, + .pcc = RV32M1_PCC_LPUART0, + .tx_gpio = GPIO_LPUART0_TX, + .rx_gpio = GPIO_LPUART0_RX, + .baud = CONFIG_LPUART0_BAUD, + .irq = RV32M1_IRQ_LPUART0, +}; + +static uart_dev_t g_uart0dev = +{ +#ifdef SERIAL_CONSOLE + .isconsole = SERIAL_CONSOLE == 0, +#endif + + .recv = + { + .size = CONFIG_LPUART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_LPUART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +#ifdef CONFIG_RV32M1_LPUART1 +static char g_uart1rxbuffer[CONFIG_LPUART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_LPUART1_TXBUFSIZE]; + +static struct up_dev_s g_uart1priv = +{ + .uartbase = RV32M1_LPUART1_BASE, + .pcc = RV32M1_PCC_LPUART1, + .tx_gpio = GPIO_LPUART1_TX, + .rx_gpio = GPIO_LPUART1_RX, + .baud = CONFIG_LPUART1_BAUD, + .irq = RV32M1_IRQ_LPUART1, +}; + +static uart_dev_t g_uart1dev = +{ +#ifdef SERIAL_CONSOLE + .isconsole = SERIAL_CONSOLE == 1, +#endif + + .recv = + { + .size = CONFIG_LPUART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_LPUART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +#ifdef CONFIG_RV32M1_LPUART2 +static char g_uart2rxbuffer[CONFIG_LPUART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_LPUART2_TXBUFSIZE]; + +static struct up_dev_s g_uart2priv = +{ + .uartbase = RV32M1_LPUART2_BASE, + .pcc = RV32M1_PCC_LPUART2, + .tx_gpio = GPIO_LPUART2_TX, + .rx_gpio = GPIO_LPUART2_RX, + .baud = CONFIG_LPUART2_BAUD, + .irq = RV32M1_IRQ_LPUART2, +}; + +static uart_dev_t g_uart2dev = +{ +#ifdef SERIAL_CONSOLE + .isconsole = SERIAL_CONSOLE == 2, +#endif + + .recv = + { + .size = CONFIG_LPUART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_LPUART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; +#endif + +#ifdef CONFIG_RV32M1_LPUART3 +static char g_uart3rxbuffer[CONFIG_LPUART3_RXBUFSIZE]; +static char g_uart3txbuffer[CONFIG_LPUART3_TXBUFSIZE]; + +static struct up_dev_s g_uart3priv = +{ + .uartbase = RV32M1_LPUART3_BASE, + .pcc = RV32M1_PCC_LPUART3, + .tx_gpio = GPIO_LPUART3_TX, + .rx_gpio = GPIO_LPUART3_RX, + .baud = CONFIG_LPUART3_BAUD, + .irq = RV32M1_IRQ_LPUART3, +}; + +static uart_dev_t g_uart3dev = +{ +#ifdef SERIAL_CONSOLE + .isconsole = SERIAL_CONSOLE == 3, +#endif + + .recv = + { + .size = CONFIG_LPUART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_LPUART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getreg + ****************************************************************************/ + +static uint32_t up_getreg(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_putreg + ****************************************************************************/ + +static void up_putreg(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct up_dev_s *priv, uint32_t im) +{ + irqstate_t flags = enter_critical_section(); + + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, im); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct up_dev_s *priv, uint32_t *im) +{ + irqstate_t flags = enter_critical_section(); + uint32_t regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + + /* Return the current interrupt mask value */ + + if (im) + { + *im = regval; + } + + /* Disable all interrupts */ + + regval &= ~(LPUART_CTRL_TCIE | LPUART_CTRL_TIE | LPUART_CTRL_RIE); + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_clkconfig + ****************************************************************************/ + +static void up_clkconfig(struct up_dev_s * priv) +{ + uint32_t regval; + + rv32m1_pcc_clock_disable(priv->pcc); + + regval = getreg32(priv->pcc); + regval &= ~PCC_CLKCFG_PCS_MASK; + regval |= PCC_CLKCFG_PCS_FIRC; + putreg32(regval, priv->pcc); + + /* Open the uart pcc clock gate */ + + rv32m1_pcc_clock_enable(priv->pcc); +} + +/**************************************************************************** + * Name: up_clkfreq + ****************************************************************************/ + +static uint32_t up_clkfreq(struct up_dev_s * priv) +{ + uint32_t regval; + uint32_t pcs; + + regval = getreg32(priv->pcc); + pcs = regval & PCC_CLKCFG_PCS_MASK; + + switch (pcs) + { + case PCC_CLKCFG_PCS_SOSC: + return rv32m1_clockfreq(CLK_SOSCDIV2); + + case PCC_CLKCFG_PCS_SIRC: + return rv32m1_clockfreq(CLK_SIRCDIV2); + + case PCC_CLKCFG_PCS_FIRC: + return rv32m1_clockfreq(CLK_FIRCDIV2); + + case PCC_CLKCFG_PCS_LPFLL: + return rv32m1_clockfreq(CLK_LPFLLDIV2); + + default: + return 0u; + } + + return 0u; +} + +/**************************************************************************** + * Name: up_setup_format + * + * Description: + * Configure the UART baud, bits, parity, etc. + * + ****************************************************************************/ + +static void up_set_format(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + uint32_t const freq = up_clkfreq(priv); + + uint32_t diff; + uint16_t sbr; + uint16_t osr; + uint16_t tosr; + + uint32_t ctrl; + uint32_t regval; + + /* 'This LPUART instantiation uses a slightly different baud rate + * calculation. The idea is to use the best OSR (over-sampling rate) + * possible. Note, OSR is typically hard-set to 16 in other LPUART + * instantiations loop to find the best OSR value possible, one that + * generates minimum baudDiff iterate through the rest of the supported + * values of OSR.' + * from rv32m1sdk. + */ + + diff = priv->baud; + + osr = 0; + sbr = 0; + + for (tosr = 4; tosr <= 32; ++tosr) + { + uint32_t baud; + uint32_t tdiff; + + /* Calculate the temporary sbr value */ + + uint32_t tsbr = freq / (priv->baud * tosr); + if (tsbr == 0) + { + tsbr = 1; + } + + baud = freq / (tosr * tsbr); + tdiff = baud - priv->baud; + + /* Select the better value between sbr and (sbr + 1) */ + + baud = freq / (tosr * (tsbr + 1)); + + if (tdiff > (priv->baud - baud)) + { + /* Get the closer one. i.e. the minimum difference */ + + tdiff = priv->baud - baud; + tsbr ++; + } + + /* Pick up the best osr and sbr with the minimum diff */ + + if (tdiff <= diff) + { + diff = tdiff; + osr = tosr; + sbr = tsbr; + } + } + + /* We don't check the baud error rate here even it is out of 3% + * which will cause undesired performance. + */ + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + ctrl = regval; + + /* Stop the Receiver and Transmitter before Baud rate update */ + + regval &= ~(LPUART_CTRL_TE | LPUART_CTRL_RE); + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); + + regval = up_getreg(priv, RV32M1_LPUART_BAUD_OFFSET); + + /* BOTHEDGE is required if osr is below 8 */ + + if (osr > 3 && osr < 8) + { + regval |= LPUART_BAUD_BOTHEDGE; + } + + /* Update OSR */ + + regval &= ~LPUART_BAUD_OSR_MASK; + regval |= ((osr - 1) << LPUART_BAUD_OSR_SHIFT) & LPUART_BAUD_OSR_MASK; + + /* Update SBR */ + + regval &= ~LPUART_BAUD_SBR_MASK; + regval |= (sbr << LPUART_BAUD_SBR_SHIFT) & LPUART_BAUD_SBR_MASK; + + /* Disable 10-bit Mode */ + + regval &= ~LPUART_BAUD_M10; + + /* FIXME: Parity, 1-Wire and Stop bits are configuralbe, + * for the initial(started) version, they are fixed + * (hard coded): No Parity, Full-duplex, and 1 Stop bit. + * Fix the missing pieces later. + */ + + /* 1 Stop bit */ + + regval &= ~LPUART_BAUD_SBNS_MASK; + regval |= LPUART_BAUD_SBNS_1; + + /* Set Baud Register */ + + up_putreg(priv, RV32M1_LPUART_BAUD_OFFSET, regval); + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + + /* No parity, 8-Bit mode */ + + regval &= ~(LPUART_CTRL_PE | LPUART_CTRL_PT_MASK | LPUART_CTRL_M_MASK | + LPUART_CTRL_M7 | LPUART_CTRL_IDLECFG_MASK | + LPUART_CTRL_ILT); + + regval |= LPUART_CTRL_M8 | LPUART_CTRL_IDLECFG_1; + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + if (ctrl & LPUART_CTRL_TE) + { + regval |= LPUART_CTRL_TE; + } + else + { + regval &= ~LPUART_CTRL_TE; + } + + if (ctrl & LPUART_CTRL_RE) + { + regval |= LPUART_CTRL_RE; + } + else + { + regval &= ~LPUART_CTRL_RE; + } + + /* Restore the Control Register */ + + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + /* Configure GPIO */ + + rv32m1_gpio_config(priv->tx_gpio); + rv32m1_gpio_config(priv->rx_gpio); + + /* Configure the clock source and open the clock gate */ + + up_clkconfig(priv); + + /* Reset the Uart */ + + regval = up_getreg(priv, RV32M1_LPUART_GLOBAL_OFFSET); + regval |= LPUART_GLOBAL_RST; + up_putreg(priv, RV32M1_LPUART_GLOBAL_OFFSET, regval); + regval &= ~LPUART_GLOBAL_RST; + up_putreg(priv, RV32M1_LPUART_GLOBAL_OFFSET, regval); + + /* Setup the Baudrate, Line */ + + up_set_format(dev); + + /* Set Watermark Zero Level for this version */ + + regval = up_getreg(priv, RV32M1_LPUART_WATER_OFFSET); + regval &= ~(LPUART_WATER_RXWATER_MASK | LPUART_WATER_TXWATER_MASK); + up_putreg(priv, RV32M1_LPUART_WATER_OFFSET, regval); + + regval = up_getreg(priv, RV32M1_LPUART_FIFO_OFFSET); + + /* Enable RX and TX FIFO */ + + regval |= LPUART_FIFO_TXFE | LPUART_FIFO_RXFE; + up_putreg(priv, RV32M1_LPUART_FIFO_OFFSET, regval); + + /* Flush FIFO */ + + regval |= LPUART_FIFO_TXFLUSH | LPUART_FIFO_RXFLUSH; + up_putreg(priv, RV32M1_LPUART_FIFO_OFFSET, regval); + + /* Write '1' to Clear all Status Flags */ + + regval = up_getreg(priv, RV32M1_LPUART_STAT_OFFSET); + regval |= LPUART_STAT_LBKDIF | LPUART_STAT_RXEDGIF | LPUART_STAT_IDLE | + LPUART_STAT_OR | LPUART_STAT_NF | LPUART_STAT_FE | + LPUART_STAT_PF | LPUART_STAT_MA1F | LPUART_STAT_MA2F ; + + /* LSB First */ + + regval &= ~LPUART_STAT_MSBF; + up_putreg(priv, RV32M1_LPUART_STAT_OFFSET, regval); + + /* Enable Receiver and Transmitter */ + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + regval |= LPUART_CTRL_TE | LPUART_CTRL_RE; + + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + uint32_t regval; + + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(priv, NULL); + + /* Disable Transmitter and Receiver. */ + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + regval &= ~(LPUART_CTRL_TE | LPUART_CTRL_RE); + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); + + /* Close the uart PCC clock gate */ + + rv32m1_pcc_clock_disable(priv->pcc); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + uint32_t regval; + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + regval |= LPUART_CTRL_TCIE | LPUART_CTRL_TIE | LPUART_CTRL_RIE ; + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); + + ret = irq_attach(priv->irq, up_interrupt, dev); + + if (ret == OK) + { + /* Enable the interrupt */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disable_irq(priv->irq); + + /* Detach from the interrupt */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * appropriate uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +LOCATE_ITCM +static int up_interrupt(int irq, void *context, FAR void *arg) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)arg; + struct up_dev_s *priv; + uint32_t status; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct up_dev_s *)dev->priv; + + /* Retrieve interrupt pending status */ + + status = up_getreg(priv, RV32M1_LPUART_STAT_OFFSET); + + if (status & LPUART_STAT_RDRF) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + } + + if (status & (LPUART_STAT_TDRE | LPUART_STAT_TC)) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return status information */ + + if (status) + { + *status = 0; /* We are not yet tracking serial errors */ + } + + /* Return cached data */ + + return up_getreg(priv, RV32M1_LPUART_DATA_OFFSET) & 0xff; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + uint32_t regval; + + irqstate_t flags = enter_critical_section(); + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + regval |= LPUART_CTRL_RIE; +#endif + } + else + { + regval &= ~LPUART_CTRL_RIE; + } + + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true is data is available in the receive data buffer */ + + uint32_t fifo = up_getreg(priv, RV32M1_LPUART_FIFO_OFFSET); + return (fifo & LPUART_FIFO_RXEMPT) == 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_putreg(priv, RV32M1_LPUART_DATA_OFFSET, (uint32_t)ch & 0x0ff); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags = enter_critical_section(); + + uint32_t regval; + + regval = up_getreg(priv, RV32M1_LPUART_CTRL_OFFSET); + + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + regval |= LPUART_CTRL_TCIE | LPUART_CTRL_TIE; +#endif + } + else + { + /* Disable the TX interrupt */ + + regval &= ~(LPUART_CTRL_TCIE | LPUART_CTRL_TIE); + } + + up_putreg(priv, RV32M1_LPUART_CTRL_OFFSET, regval); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + uint32_t txvol = (up_getreg(priv, RV32M1_LPUART_FIFO_OFFSET) & + LPUART_FIFO_TXFIFOSIZE_MASK) >> + LPUART_FIFO_TXFIFOSIZE_SHIFT ; + + uint32_t txcnt = (up_getreg(priv, RV32M1_LPUART_WATER_OFFSET) & + LPUART_WATER_TXCOUNT_MASK) >> + LPUART_WATER_TXCOUNT_SHIFT ; + + /* Return TRUE if the TX FIFO is not full */ + + return txcnt < txvol; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the TX wartermak is pending */ + + return (up_getreg(priv, RV32M1_LPUART_FIFO_OFFSET) & LPUART_FIFO_TXEMPT) + != 0; +} +#endif /* HAVE_UART */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT + +/**************************************************************************** + * Name: riscv_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before riscv_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock + * initialization performed in up_clkinitialize(). + * + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ + /* Do nothing, we've set up the serial console. + * The function must be provided to get rid of + * linking problem when USE_EARLYSERIALINIT is + * defined. + */ +} +#endif + +/**************************************************************************** + * Name: riscv_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that riscv_earlyserialinit was called previously. + * + ****************************************************************************/ + +void riscv_serialinit(void) +{ + int i; + int nuart; + + char devpath[16] = "/dev/ttyS"; + + /* Device NO. */ + + int devno = 1; + + const struct rv32m1_tty_s ttydevs[] = + { +#ifdef RV32M1_LPUART0_DEV + { + .dev = &RV32M1_LPUART0_DEV, + .idx = RV32M1_LPUART0_DEV.isconsole ? 0 : devno ++, + }, +#endif +#ifdef RV32M1_LPUART1_DEV + { + .dev = &RV32M1_LPUART1_DEV, + .idx = RV32M1_LPUART1_DEV.isconsole ? 0 : devno ++, + }, +#endif +#ifdef RV32M1_LPUART2_DEV + { + .dev = &RV32M1_LPUART2_DEV, + .idx = RV32M1_LPUART2_DEV.isconsole ? 0 : devno ++, + }, +#endif +#ifdef RV32M1_LPUART3_DEV + { + .dev = &RV32M1_LPUART3_DEV, + .idx = RV32M1_LPUART3_DEV.isconsole ? 0 : devno ++, + }, +#endif + + /* Place a dummy One as a Place holder to avoid uartdevs + * to be empty when All above uart devices are undefined, + * in which case a complier error will raise. + */ + + { + .dev = NULL, + .idx = -1, + }, + }; + + nuart = (int)(sizeof(ttydevs) / sizeof(ttydevs[0])); + + /* Register the console */ + +#ifdef CONSOLE_DEV + uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register All Uarts */ + + for (i = 0; i < nuart; ++i) + { + const struct rv32m1_tty_s * tty = &ttydevs[i]; + + if (!tty->dev) + { + continue; + } + + /* OS(Nuttx) is primordial and so many resources are uninitialized + * while we are in 'riscv_serialinit'. The high level C lib functions + * may not work well. Codes such as the following + * 'snprintf(devpath, "/dev/ttyS%d\n", devno)...' + * would not work as expected. + * + * It is ok to complete the device path manually. + */ + + devno = tty->idx; + + if (devno < 10) + { + devpath[9] = devno + '0'; + + /* Terminate the String */ + + devpath[10] = '\0'; + } + else + { + /* There is one pre-condition that devno doesn't exceed 100 */ + + int d = devno / 10; + devpath[9] = d + '0'; + + d = devno - d * 10; + devpath[10] = d + '0'; + + /* Terminate the String */ + + devpath[11] = '\0'; + } + + uart_register(devpath, tty->dev); + } +} + +#endif /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef CONSOLE_DEV + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint32_t im; + + up_disableuartint(priv, &im); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); + up_restoreuartint(priv, im); +#endif + return ch; +} + +#ifdef HAVE_SERIAL_CONSOLE +/**************************************************************************** + * Name: rv32m1_console_uart_setup + ****************************************************************************/ + +void rv32m1_console_uart_setup(void) +{ +#ifdef CONSOLE_DEV + up_setup(&CONSOLE_DEV); +#endif +} + +/**************************************************************************** + * Name: rv32m1_console_uart_putc + ****************************************************************************/ + +void rv32m1_console_uart_putc(char ch) +{ +#ifdef CONSOLE_DEV + while (!up_txready(&CONSOLE_DEV)) ; + up_send(&CONSOLE_DEV, ch); +#endif +} +#endif /* HAVE_SERIAL_CONSOLE */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_start.c b/arch/risc-v/src/rv32m1/rv32m1_start.c new file mode 100644 index 00000000000..997bf57678f --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_start.c @@ -0,0 +1,156 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_start.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "riscv_arch.h" +#include "rv32m1_clockconfig.h" +#include "rv32m1.h" +#include "rv32m1_gpio.h" +#include "rv32m1_lowputc.h" +#include "hardware/rv32m1_wdog.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_FEATURES +# define showprogress(c) riscv_lowputc(c) +#else +# define showprogress(c) +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* g_idle_topstack: _sbss is the start of the BSS region as defined by the + * linker script. _ebss lies at the end of the BSS region. The idle task + * stack starts at the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE. + * The IDLE thread is the thread that the system boots on and, eventually, + * becomes the IDLE, do nothing task that runs only when there is nothing + * else to run. The heap continues from there until the end of memory. + * g_idle_topstack is a read-only variable the provides this computed + * address. + */ + +uint32_t g_idle_topstack = RV32M1_IDLESTACK_TOP; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: __rv32m1_start + ****************************************************************************/ + +void __rv32m1_start(void) +{ + const uint32_t *src; + uint32_t *dest; + + uint32_t regval; + + /* Watch dog starts automatically after System resets. Stop it */ + + putreg32(WDOG_CNT_UNLOCK, RV32M1_WDOG_CNT); + putreg32(0xffff, RV32M1_WDOG_TOVAL); + + regval = getreg32(RV32M1_WDOG_CS); + regval &= ~WDOG_CS_EN; + regval |= WDOG_CS_UPDATE; + putreg32(regval, RV32M1_WDOG_CS); + +#ifdef CONFIG_RV32M1_ITCM + + src = &_slitcm; + dest = &_svitcm; + + if (src != dest) + { + /* Copy codes from Flash LMA Region to ITCM VMA Region */ + + for (; dest < &_evitcm; ) + { + *dest++ = *src++; + } + } + +#endif + + /* Clear .bss. We'll do this inline (vs. calling memset) just to be + * certain that there are no issues with the state of global variables. + */ + + for (dest = &_sbss; dest < &_ebss; ) + { + *dest++ = 0; + } + + /* Move the initialized data section from his temporary holding spot in + * FLASH into the correct place in SRAM. The correct place in SRAM is + * give by _sdata and _edata. The temporary location is in FLASH at the + * end of all of the other read-only data (.text, .rodata) at _eronly. + */ + + for (src = &_eronly, dest = &_sdata; dest < &_edata; ) + { + *dest++ = *src++; + } + + /* Setup clock */ + + rv32m1_clockconfig(); + + /* Configure the UART so we can get debug output */ + + rv32m1_lowsetup(); + + showprogress('A'); + +#ifdef USE_EARLYSERIALINIT + riscv_earlyserialinit(); +#endif + + showprogress('B'); + + /* Do board initialization */ + + rv32m1_boardinitialize(); + + showprogress('C'); + + /* Call nx_start() */ + + nx_start(); + + /* Shouldn't get here */ + + for (; ; ); +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_timerisr.c b/arch/risc-v/src/rv32m1/rv32m1_timerisr.c new file mode 100644 index 00000000000..91127d5438b --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_timerisr.c @@ -0,0 +1,142 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_timerisr.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "riscv_arch.h" + +#include "rv32m1.h" +#include "hardware/rv32m1_lptmr.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Data Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_timerisr + ****************************************************************************/ + +LOCATE_ITCM +static int rv32m1_timerisr(int irq, void *context, FAR void *arg) +{ + /* Write '1' to clear the pending flag */ + + uint32_t regval = getreg32(RV32M1_LPTMR_CSR); + regval |= LPTMR_CSR_TCF; + putreg32(regval, RV32M1_LPTMR_CSR); + + /* Process timer interrupt */ + + nxsched_process_timer(); + + return 0; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void up_timer_initialize(void) +{ + uint32_t regaddr; + uint32_t regval; + + /* Stop the timer and clear the pending flag */ + + regaddr = RV32M1_LPTMR_CSR; + regval = getreg32(regaddr); + regval &= ~LPTMR_CSR_TEN; + putreg32(regval, regaddr); + + /* Counter mode, + * Reset counter when the compare value is matched, + * No DMA request + */ + + regval &= ~(LPTMR_CSR_TMS | LPTMR_CSR_TFC | + LPTMR_CSR_TDRE | LPTMR_CSR_TPS_MASK); + regval |= LPTMR_CSR_TPS0; + + putreg32(regval, regaddr); + + regaddr = RV32M1_LPTMR_PSR; + regval = LPTMR_PSR_PCS_SIRCDIV3 | LPTMR_PSR_PBYP; + putreg32(regval, regaddr); + + /* Attach timer interrupt handler */ + + irq_attach(RV32M1_IRQ_LPTMR, rv32m1_timerisr, NULL); + + /* Open the timer interrupt gate */ + + up_enable_irq(RV32M1_IRQ_LPTMR); + + /* Set ticks to compare */ + + regval = rv32m1_clockfreq(CLK_SIRCDIV3) / TICK_PER_SEC; + if (regval > 0) + { + /* Fine tune the ticks */ + + --regval; + } + + putreg32(regval, RV32M1_LPTMR_CMR); + + /* Start the timer with interrupt enabled */ + + regval = getreg32(RV32M1_LPTMR_CSR); + regval &= ~LPTMR_CSR_TCF; + regval |= LPTMR_CSR_TEN | LPTMR_CSR_TIE; + putreg32(regval, RV32M1_LPTMR_CSR); +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_timersvc.c b/arch/risc-v/src/rv32m1/rv32m1_timersvc.c new file mode 100644 index 00000000000..4f90e60876b --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_timersvc.c @@ -0,0 +1,98 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_timersvc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include "riscv_arch.h" + +#include "rv32m1.h" +#include "hardware/rv32m1_tstmr.h" +#include "rv32m1_timersvc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Data Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_timersvc_up + ****************************************************************************/ + +bool rv32m1_timersvc_up(void) +{ +#ifdef CONFIG_RV32M1_TSTMR + /* TSTMR starts up when System Reset and TSTMR is Enabled by Option Byte. + * Query the Option Byte to check whether TSTMR is enabled. + */ + + return (getreg8(RV32M1_FTFE_BASE + 0x10) & 0x01) != 0; +#else + return false; +#endif +} + +/**************************************************************************** + * Name: rv32m1_timersvc_freq + ****************************************************************************/ + +uint32_t rv32m1_timersvc_freq(void) +{ + /* TSTMR runs off 1MHz */ + + return 1000000u; +} + +/**************************************************************************** + * Name: rv32m1_timersvc_period + ****************************************************************************/ + +uint32_t rv32m1_timersvc_period(void) +{ + return 0xffffffffu; +} + +/**************************************************************************** + * Name: rv32m1_timersvc_value + ****************************************************************************/ + +uint32_t rv32m1_timersvc_value(void) +{ + /* Read High and Low Registers completely for the Right Result */ + + uint64_t value = *(volatile uint64_t *)(RV32M1_TSTMR_BASE); + + /* It is ok to return the ONLY low valud caused the it is accumulated + * outside. + */ + + return (uint32_t)value; +} diff --git a/arch/risc-v/src/rv32m1/rv32m1_timersvc.h b/arch/risc-v/src/rv32m1/rv32m1_timersvc.h new file mode 100644 index 00000000000..6b49929c9bd --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_timersvc.h @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_timersvc.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_RV32M1_RV32M1_TIMERSVC_H +#define __ARCH_RISCV_SRC_RV32M1_RV32M1_TIMERSVC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Public Functions Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: rv32m1_timersvc_up + ****************************************************************************/ + +EXTERN bool rv32m1_timersvc_up(void); + +/**************************************************************************** + * Name: rv32m1_timersvc_freq + ****************************************************************************/ + +EXTERN uint32_t rv32m1_timersvc_freq(void); + +/**************************************************************************** + * Name: rv32m1_timersvc_period + ****************************************************************************/ + +EXTERN uint32_t rv32m1_timersvc_period(void); + +/**************************************************************************** + * Name: rv32m1_timersvc_value + ****************************************************************************/ + +EXTERN uint32_t rv32m1_timersvc_value(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_RV32M1_RV32M1_TIMERSVC_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_uart.h b/arch/risc-v/src/rv32m1/rv32m1_uart.h new file mode 100644 index 00000000000..f82e2189571 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_uart.h @@ -0,0 +1,105 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_uart.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef _ARCH_RISCV_SRC_RV32M1_RV32M1_UART_H +#define _ARCH_RISCV_SRC_RV32M1_RV32M1_UART_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip.h" + +#include "hardware/rv32m1_lpuart.h" + +#undef HAVE_UART +#if defined(CONFIG_RV32M1_LPUART0) || \ + defined(CONFIG_RV32M1_LPUART1) || \ + defined(CONFIG_RV32M1_LPUART2) || \ + defined(CONFIG_RV32M1_LPUART3) +# define HAVE_UART 1 +#endif + +#if defined(CONFIG_LPUART0_SERIAL_CONSOLE) && defined(CONFIG_RV32M1_LPUART0) +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_LPUART2_SERIAL_CONSOLE +# undef CONFIG_LPUART3_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_LPUART1_SERIAL_CONSOLE) && defined(CONFIG_RV32M1_LPUART1) +# undef CONFIG_LPUART0_SERIAL_CONSOLE +# undef CONFIG_LPUART2_SERIAL_CONSOLE +# undef CONFIG_LPUART3_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_LPUART2_SERIAL_CONSOLE) && defined(CONFIG_RV32M1_LPUART2) +# undef CONFIG_LPUART0_SERIAL_CONSOLE +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_LPUART3_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_LPUART3_SERIAL_CONSOLE) && defined(CONFIG_RV32M1_LPUART3) +# undef CONFIG_LPUART0_SERIAL_CONSOLE +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_LPUART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_LPUART0_SERIAL_CONSOLE +# undef CONFIG_LPUART1_SERIAL_CONSOLE +# undef CONFIG_LPUART2_SERIAL_CONSOLE +# undef CONFIG_LPUART3_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#if defined(HAVE_SERIAL_CONSOLE) +/**************************************************************************** + * Name: rv32m1_console_uart_setup + ****************************************************************************/ + +EXTERN void rv32m1_console_uart_setup(void); + +/**************************************************************************** + * Name: rv32m1_console_uart_putc + ****************************************************************************/ + +EXTERN void rv32m1_console_uart_putc(char); +#endif /* HAVE_SERIAL_CONSOLE */ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* _ARCH_RISCV_SRC_RV32M1_RV32M1_UART_H */ diff --git a/arch/risc-v/src/rv32m1/rv32m1_vectors.S b/arch/risc-v/src/rv32m1/rv32m1_vectors.S new file mode 100644 index 00000000000..41611317533 --- /dev/null +++ b/arch/risc-v/src/rv32m1/rv32m1_vectors.S @@ -0,0 +1,86 @@ +/**************************************************************************** + * arch/risc-v/src/rv32m1/rv32m1_vectors.S + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "chip.h" + + /* Imported Symbols */ + + .extern __start + .extern exception_common + +#ifdef CONFIG_RV32M1_ITCM + .section .boot, "ax" + .option norvc + .org 0x80 + j __start + + .section SECTION_ITCM +__reset: + lui t0, %hi(__start) + addi t0, t0, %lo(__start) + jalr x0, 0(t0) +#endif + + .section .vectors, "ax" + .option norvc + j exception_common /* 0 */ + j exception_common /* 1 */ + j exception_common /* 2 */ + j exception_common /* 3 */ + j exception_common /* 4 */ + j exception_common /* 5 */ + j exception_common /* 6 */ + j exception_common /* 7 */ + j exception_common /* 8 */ + j exception_common /* 9 */ + j exception_common /* 10 */ + j exception_common /* 11 */ + j exception_common /* 12 */ + j exception_common /* 13 */ + j exception_common /* 14 */ + j exception_common /* 15 */ + j exception_common /* 16 */ + j exception_common /* 17 */ + j exception_common /* 18 */ + j exception_common /* 19 */ + j exception_common /* 20 */ + j exception_common /* 21 */ + j exception_common /* 22 */ + j exception_common /* 23 */ + j exception_common /* 24 */ + j exception_common /* 25 */ + j exception_common /* 26 */ + j exception_common /* 27 */ + j exception_common /* 28 */ + j exception_common /* 29 */ + j exception_common /* 30 */ + j exception_common /* 31 */ +#ifdef CONFIG_RV32M1_ITCM + j __reset +#else + j __start +#endif + j exception_common /* Illegal instruction */ + j exception_common /* Ecall */ + j exception_common /* LSU error */ diff --git a/boards/Kconfig b/boards/Kconfig index ee15c5e961e..94580d7eea0 100644 --- a/boards/Kconfig +++ b/boards/Kconfig @@ -1394,6 +1394,16 @@ config ARCH_BOARD_RX65N_GRROSE This is a port of the renesas RX65N on the Renesas RX65N board. STATUS: Work has just began on this port. +config ARCH_BOARD_RV32M1_VEGA + bool "RV32M1 VEGA board" + depends on ARCH_CHIP_RV32M1 + select ARCH_HAVE_LEDS + select ARCH_HAVE_BUTTONS + select ARCH_HAVE_IRQBUTTONS + ---help--- + This is the board configuration for the port of NuttX to the + RV32M1 VEGA board. This board features the RV32M1 RISC-V Core(s). + config ARCH_BOARD_S32K118EVB bool "NXP S32K118EVB" depends on ARCH_CHIP_S32K118 @@ -2425,6 +2435,7 @@ config ARCH_BOARD default "s32k144evb" if ARCH_BOARD_S32K144EVB default "rddrone-uavcan144" if ARCH_BOARD_RDDRONE_UAVCAN144 default "rddrone-uavcan146" if ARCH_BOARD_RDDRONE_UAVCAN146 + default "rv32m1-vega" if ARCH_BOARD_RV32M1_VEGA default "s32k146evb" if ARCH_BOARD_S32K146EVB default "s32k148evb" if ARCH_BOARD_S32K148EVB default "sabre-6quad" if ARCH_BOARD_SABRE_6QUAD @@ -3150,6 +3161,9 @@ endif if ARCH_BOARD_ICICLE_MPFS source "boards/risc-v/mpfs/icicle/Kconfig" endif +if ARCH_BOARD_RV32M1_VEGA +source "boards/risc-v/rv32m1/rv32m1-vega/Kconfig" +endif if ARCH_BOARD_ESP32C3_DEVKIT source "boards/risc-v/esp32c3/esp32c3-devkit/Kconfig" endif diff --git a/boards/risc-v/rv32m1/rv32m1-vega/Kconfig b/boards/risc-v/rv32m1/rv32m1-vega/Kconfig new file mode 100644 index 00000000000..6f86982c469 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/Kconfig @@ -0,0 +1,15 @@ +# +# For a description of the syntax of this configuration file, +# see misc/tools/kconfig-language.txt. +# + +if ARCH_BOARD_RV32M1_VEGA + +config RV32M1_OPENISA_TOOLCHAIN + bool "Utilize OPEN ISA Toolchain" + default n + select ARCH_RISCV_INTXCPT_EXTENSIONS + ---help--- + With OPEN ISA Toolchain, RV32M1 RISC-V Core Capability can be exploited. + +endif diff --git a/boards/risc-v/rv32m1/rv32m1-vega/README.txt b/boards/risc-v/rv32m1/rv32m1-vega/README.txt new file mode 100644 index 00000000000..d697075aa3d --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/README.txt @@ -0,0 +1,242 @@ +README +====== + +This README discusses issues unique to NuttX configurations for the +OPEN ISA RV32M1-VEGA development board featuring the RV32M1 MCU. The +RV32M1 is a heterogeneous soc including an ARM Cortex-M4 CPU, an ARM +Cortex-M0+ CPU, a RISC-V RI5CY CPU, and a RISC-V ZERO_RISCY CPU. the +SOC integrates 1.25 MB flash, 384 KB SRAM, and varieties of peripherals. +The RV32M1-VEGA board features: + + - On-board OpenSDA Debug Adapter, + - USB Device Port, + - FXOS8700CQ Digital Combo Sensor: 3D Accelerometer + 3D Magnetometer, + - Wirless Abilities: BLE, Generic FSK, and IEEE Std.802.15.4(Thread), + - ONE user RGB LED, + - Four user push-buttons, + - 4 MB external SPI Flash, + - Micro-SD Card Slot on the backside, + - Arduino R3 Compatible IO Header. + +Refer to https://open-isa.org for further information about this board. + +Currently Nuttx is ported to RV32M1 RI5CY only. RI5CY is RV32IMC RISC-V CPU +with PULP extensions features: + - Post-Incrementing load and stores, + - Multiply-Accumulate extenstions, + - ALU extensions, + - Hardware Loops. + +Contents +======== + + - LEDs + - UARTs + - Buttons + - ITCM + - TSTMR + +LEDs +==== + +The RV32M1-VEGA board has ONE user RGB LED; Only the red part led is used to +indicate an interrupt request is being serviced. + + SYMBOL Meaning RED* GREEN BLUE + ------------------- ----------------------- ------- ------- ----- + LED_STARTED NuttX has been started OFF OFF OFF + LED_HEAPALLOCATE Heap has been allocated OFF OFF OFF + LED_IRQSENABLED Interrupts enabled OFF OFF OFF + LED_STACKCREATED Idle stack created OFF OFF OFF + LED_INIRQ In an interrupt** OFF OFF OFF + LED_SIGNAL In a signal handler*** OFF OFF OFF + LED_ASSERTION An assertion failed OFF OFF OFF + LED_PANIC The system has crashed OFF OFF OFF + LED_CPU Interrupt service ON OFF OFF + +UARTs +==== + +LPUART PINS +--------------- + +LPUART0 + RX PC7, PB25, PA2 + TX PC8, PB26, PA3 +LPUART1 + RX PB2, PC29, PA2, PA25 + TX PB3, PC30, PA3, PA26 +LPUART2 + RX PB11, PB18, PB1 + TX PB12, PB19, PB0 +LPUART3 + RX PB28, PE8, PE29 + TX PB29, PE9, PE30 + +Default LPUART Configuration +-------------------------------- + +LPUART0 is enabled in most configurations (see */defconfig). RX and TX are +configured on pins PC7 and PC8, respectively (see include/board.h). These +two above pins are connected to onboard Debug Adpater which provides a USB- +TTL serial channel. + +Buttons +==== + +Four tactile buttons are populated on RV32M1-VEGA Board. + +Buttons PINS Assignment +--------------- +NAME PIN EXTERNAL-PULLUP +SW2 PA0 YES +SW3 PE8 NO +SW4 PE9 NO +SW5 PE12 NO + +All these buttons can be used as interrupt and wake up sources while SW2 can +be an alternative NMI Source. + +ITCM +==== + +A 64KB ITCM is coupled with M4 Cores, RI5CY CPU or ARM Cortex-M4 CPU. If the +ITCM is selected, Critical Codes including but not limited to Exception Vectors, +Interrupt Service Routines will be placed in ITCM. + +TSTMR +==== + +TSTMR Module is embedded in RV32M1 to provide system time stamp. It runs off 1MHz +with a 56-bit counter, and can be adopted to get more accurate delay counting. If +the Module is selected, a hardware delay method will replace mdealy and udelay, +the built-in software delay methods. + +TOOLCHAIN +======== + +It is preferable to use OPEN ISA gcc Toolchain to exploit RV32M1 RI5CY capabi- +lities, though the generic GNU RVG Toolchain can generate binary codes running +on RV32M1 RI5CY without any problems. To switch generic GNU RVG Toolchain to +OPEN ISA Toolchain, the following option must be selected: + +Board Selection ---> + [*] Utilize OPEN ISA Toolchain + +Make sure OPEN ISA Toolchain have been installed and be found in PATH. + +ARCHCPUFLAGS +==== + +RI5CY Core supports hardware loop with 6 hardware loop registers assistance, +these registers could be overwritten when contexts switch. If codes are generated +by OPEN ISA Toolchain and CONFIG_ARCH_RISCV_INTXCPT_EXTREGS is not less than 6, +the RI5CY specific architecture flag will be passed to gcc compiler. In that case, +the 6 hardware loop registers must be saved and restored in interrupt routines with +the general purpose registers. + +You will see the following lines in Make.defs file: + + ARCHCPURV32IM = -march=rv32imc -mabi=ilp32 + + ifeq ($(CONFIG_RV32M1_OPENISA_TOOLCHAIN),y) + ifdef CONFIG_ARCH_RISCV_INTXCPT_EXTREGS + ifeq ($(filter 0 1 2 3 4 5 , $(CONFIG_ARCH_RISCV_INTXCPT_EXTREGS)),) + ARCHCPURV32IM = -march=rv32imcxpulpv2 + endif + endif + endif + + ARCHCPUFLAGS = $(ARCHCPURV32IM) + + + +CONFIG_ARCH_RISV_INTXCPT_EXTREGS could be configured in the following menu: + +System Type ---> + [*] RISC-V Integer Context Extensions + (6) Number of Extral RISC-V Integer Context Registers + + +Program & Debug +======== + +Program +==== + +To program RV32M1, openocd from OPEN ISA and an external jtag adapter are pre- +requisite. There are 2 tested jtag adapters: Segger Jlink EDU mini and SiPEED +USB Jtag Adapter. The Segger Jlink EDU mini can connect J55 header on RV32M1-VEGA +board directly while SiPEED USB Jtag Adpater has to co-operate with an Adapter +board to setup wires connection. +Compared to Segger Jlink EDU Mini Adapter, SiPEED USB Jtag Adpater is cheaper but +not inferior. + +With SiPEED USB Jtag Adapter, some patches must be applied to rv32m1_ri5cy.cfg: + +--- a/rv32m1_ri5cy.cfg ++++ b/rv32m1_ri5cy.cfg +@@ -2,7 +2,11 @@ set _WORKAREASIZE 0x2000 + + adapter_khz 1000 + +-interface jlink ++interface ftdi ++ftdi_vid_pid 0x0403 0x6010 ++ftdi_layout_init 0x0508 0x0f1b ++ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 ++ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 + transport select jtag + + set _WORKAREASIZE 0x1000 + +------------------------------ +Make sure that RV32M1 boots RI5CY, and you do this ONLY ONCE. Refer to RV32M1-VEGA +quick start guide for more details. + +Note: + +OPEN ISA Toolchain, rv32m1_ri5cy.cfg contained in RV32M1 SDK, and RV32M1-VEGA +quick start guide could be found in the following link: +https://open-isa.org/downloads/ + +Debug +==== + +riscv64-unknonw-elf-gdb can not debug RV32M1 RISC-V Cores currently. GDB from +OPEN ISA Toolchain seems the only option and even can debug elf files generated +by risc64-unknown-elf-* tools. + +Configuration Sub-directories +======== + +Nuttx of All configurations in rv32m1-vega/configs can be compiled by +the generic GNU RVG Toolchain and OPEN ISA Toolchain. + +buttons +==== + This configuration is a variant of the NSH configuration used for + demonstrating the four buttons on RV32M1-VEGA board. + Example usage of buttons: + + a. Start the buttons daemon: + nsh> buttons + + b. Press and release SW2, SW3, SW4, SW5 freely, the button pressed + and released messages will display correspondingly. + +nsh +==== + This configuration is basic. getprime is included in this configuration to + determine performance of RV32M1 RI5CY Core. + +nsh-itcm +==== + This configuration is a variant of the NSH configuration used for + demonstrating ITCM. When ITCM is selected, RI5CY Exception Vectors and + Interrupt Service Routines are placed in ITCM. Performance can be calculated + by getprime, and you might find it deteriorated a litte ironically. The drawback + may be caused by long jump frequently between ITCM and flash. Besides, an instr- + uction cache is enabled always after RI5CY resets, and amelioration could not be + achieved with even ITCM enabled. + What if codes fullfill the 64KB ITCM ? diff --git a/boards/risc-v/rv32m1/rv32m1-vega/configs/buttons/defconfig b/boards/risc-v/rv32m1/rv32m1-vega/configs/buttons/defconfig new file mode 100644 index 00000000000..9b510b21c70 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/configs/buttons/defconfig @@ -0,0 +1,79 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="rv32m1-vega" +CONFIG_ARCH_BOARD_RV32M1_VEGA=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP="rv32m1" +CONFIG_ARCH_CHIP_RV32M1=y +CONFIG_ARCH_CHIP_RV32M1_RI5CY=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_IRQBUTTONS=y +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=6366 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_ZERO=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_EXAMPLES_BUTTONS=y +CONFIG_EXAMPLES_BUTTONS_NAME0="SW2" +CONFIG_EXAMPLES_BUTTONS_NAME1="SW3" +CONFIG_EXAMPLES_BUTTONS_NAME2="SW4" +CONFIG_EXAMPLES_BUTTONS_NAME3="SW5" +CONFIG_EXAMPLES_BUTTONS_NAMES=y +CONFIG_EXAMPLES_BUTTONS_QTD=4 +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INPUT=y +CONFIG_INPUT_BUTTONS=y +CONFIG_INPUT_BUTTONS_LOWER=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_LPUART0_SERIAL_CONSOLE=y +CONFIG_MAX_TASKS=8 +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_CD=y +CONFIG_NSH_DISABLE_CP=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_FILEIOSIZE=64 +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RAM_SIZE=196608 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RV32IM_HW_MULDIV=y +CONFIG_RV32M1_LPUART0=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=12 +CONFIG_TESTING_GETPRIME=y +CONFIG_USEC_PER_TICK=1000 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/risc-v/rv32m1/rv32m1-vega/configs/nsh-itcm/defconfig b/boards/risc-v/rv32m1/rv32m1-vega/configs/nsh-itcm/defconfig new file mode 100644 index 00000000000..30efc1268f7 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/configs/nsh-itcm/defconfig @@ -0,0 +1,68 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="rv32m1-vega" +CONFIG_ARCH_BOARD_RV32M1_VEGA=y +CONFIG_ARCH_CHIP="rv32m1" +CONFIG_ARCH_CHIP_RV32M1=y +CONFIG_ARCH_CHIP_RV32M1_RI5CY=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=6366 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_ZERO=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_LPUART0_SERIAL_CONSOLE=y +CONFIG_MAX_TASKS=8 +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_CD=y +CONFIG_NSH_DISABLE_CP=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_FILEIOSIZE=64 +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RAM_SIZE=196608 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RV32IM_HW_MULDIV=y +CONFIG_RV32M1_ITCM=y +CONFIG_RV32M1_LPUART0=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=12 +CONFIG_TESTING_GETPRIME=y +CONFIG_USEC_PER_TICK=1000 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/risc-v/rv32m1/rv32m1-vega/configs/nsh/defconfig b/boards/risc-v/rv32m1/rv32m1-vega/configs/nsh/defconfig new file mode 100644 index 00000000000..af2a8bb7249 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/configs/nsh/defconfig @@ -0,0 +1,67 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_NSH_DISABLEBG is not set +# CONFIG_NSH_DISABLE_LOSMART is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_STANDARD_SERIAL is not set +CONFIG_ARCH="risc-v" +CONFIG_ARCH_BOARD="rv32m1-vega" +CONFIG_ARCH_BOARD_RV32M1_VEGA=y +CONFIG_ARCH_CHIP="rv32m1" +CONFIG_ARCH_CHIP_RV32M1=y +CONFIG_ARCH_CHIP_RV32M1_RI5CY=y +CONFIG_ARCH_INTERRUPTSTACK=2048 +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BINFMT_DISABLE=y +CONFIG_BOARD_LOOPSPERMSEC=6366 +CONFIG_BUILTIN=y +CONFIG_CLOCK_MONOTONIC=y +CONFIG_DEBUG_FULLOPT=y +CONFIG_DEBUG_SYMBOLS=y +CONFIG_DEFAULT_SMALL=y +CONFIG_DEV_ZERO=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_FS_PROCFS=y +CONFIG_IDLETHREAD_STACKSIZE=2048 +CONFIG_INTELHEX_BINARY=y +CONFIG_LIBC_FLOATINGPOINT=y +CONFIG_LIBC_PERROR_STDOUT=y +CONFIG_LIBC_STRERROR=y +CONFIG_LPUART0_SERIAL_CONSOLE=y +CONFIG_MAX_TASKS=8 +CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6 +CONFIG_NSH_ARCHINIT=y +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_DISABLE_CD=y +CONFIG_NSH_DISABLE_CP=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +CONFIG_NSH_DISABLE_MKDIR=y +CONFIG_NSH_DISABLE_RM=y +CONFIG_NSH_DISABLE_RMDIR=y +CONFIG_NSH_DISABLE_UMOUNT=y +CONFIG_NSH_FILEIOSIZE=64 +CONFIG_NSH_STRERROR=y +CONFIG_PREALLOC_TIMERS=0 +CONFIG_RAM_SIZE=196608 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_RV32IM_HW_MULDIV=y +CONFIG_RV32M1_LPUART0=y +CONFIG_SCHED_WAITPID=y +CONFIG_STACK_COLORATION=y +CONFIG_START_DAY=29 +CONFIG_START_MONTH=11 +CONFIG_START_YEAR=2019 +CONFIG_STDIO_DISABLE_BUFFERING=y +CONFIG_SYSTEM_NSH=y +CONFIG_TASK_NAME_SIZE=12 +CONFIG_TESTING_GETPRIME=y +CONFIG_USEC_PER_TICK=1000 +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/boards/risc-v/rv32m1/rv32m1-vega/include/board.h b/boards/risc-v/rv32m1/rv32m1-vega/include/board.h new file mode 100644 index 00000000000..7e3fdff8d36 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/include/board.h @@ -0,0 +1,90 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/include/board.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_RISCV_RV32M1_RV32M1_VEGA_INCLUDE_BOARD_H +#define __BOARDS_RISCV_RV32M1_RV32M1_VEGA_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define LED_STARTED 0 /* N/A */ +#define LED_HEAPALLOCATE 1 /* N/A */ +#define LED_IRQSENABLED 2 /* N/A */ +#define LED_STACKCREATED 3 /* N/A */ +#define LED_INIRQ 4 /* N/A */ +#define LED_SIGNAL 5 /* N/A */ +#define LED_ASSERTION 6 /* N/A */ +#define LED_PANIC 7 /* N/A */ +#define LED_CPU 8 /* LED */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#define GPIO_LPUART0_RX GPIO_LPUART0_RX_1 /* PC7 */ +#define GPIO_LPUART0_TX GPIO_LPUART0_TX_1 /* PC8 */ + +#define GPIO_LPUART1_RX GPIO_LPUART1_RX_4 /* PA25 */ +#define GPIO_LPUART1_TX GPIO_LPUART1_TX_4 /* PA26 */ + +#define GPIO_LPUART2_RX GPIO_LPUART2_RX_1 /* PB11 */ +#define GPIO_LPUART2_TX GPIO_LPUART2_TX_1 /* PB12 */ + +#define GPIO_LPUART3_RX GPIO_LPUART3_RX_2 /* PE8 */ +#define GPIO_LPUART3_TX GPIO_LPUART3_TX_3 /* PE30 */ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_boardinitialize + ****************************************************************************/ + +void rv32m1_boardinitialize(void); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISC-V_RV32M1_RV32M1_VEGA_INCLUDE_BOARD_H */ diff --git a/boards/risc-v/rv32m1/rv32m1-vega/scripts/Make.defs b/boards/risc-v/rv32m1/rv32m1-vega/scripts/Make.defs new file mode 100644 index 00000000000..9c211dd7679 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/scripts/Make.defs @@ -0,0 +1,80 @@ +############################################################################ +# boards/risc-v/rv32m1/rv32m1-vega/scripts/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/.config +include $(TOPDIR)/tools/Config.mk +include $(TOPDIR)/arch/risc-v/src/rv32im/Toolchain.defs + +ifeq ($(CONFIG_RV32M1_OPENISA_TOOLCHAIN),y) + CROSSDEV = riscv32-unknown-elf- +endif + +ifeq ($(CONFIG_RV32M1_ITCM),y) + LDSCRIPT = ld-itcm.script +else + LDSCRIPT = ld.script +endif + +ifeq ($(CONFIG_CYGWIN_WINTOOL),y) + ARCHSCRIPT = -T "${shell cygpath -w $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)}" +else + ARCHSCRIPT = -T$(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT) +endif + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g + ASARCHCPUFLAGS += -Wa,-g +endif + +MAXOPTIMIZATION = -Os + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer +endif + +ARCHCPURV32IM = -march=rv32imc -mabi=ilp32 + +ifeq ($(CONFIG_RV32M1_OPENISA_TOOLCHAIN),y) + ifdef CONFIG_ARCH_RISCV_INTXCPT_EXTREGS + ifeq ($(filter 0 1 2 3 4 5 , $(CONFIG_ARCH_RISCV_INTXCPT_EXTREGS)),) + ARCHCPURV32IM = -march=rv32imcxpulpv2 + endif + endif +endif + +ARCHCPUFLAGS = $(ARCHCPURV32IM) +ARCHCFLAGS = -fno-builtin -ffunction-sections -fdata-sections +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +CFLAGS := $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) +AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS) + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +LDFLAGS += --gc-sections -melf32lriscv diff --git a/boards/risc-v/rv32m1/rv32m1-vega/scripts/ld-itcm.script b/boards/risc-v/rv32m1/rv32m1-vega/scripts/ld-itcm.script new file mode 100644 index 00000000000..34b6bf0fff5 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/scripts/ld-itcm.script @@ -0,0 +1,124 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/scripts/ld-itcm.script + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +MEMORY +{ + flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x000FFF00 + vector(rx) : ORIGIN = 0x000FFF00, LENGTH = 256 + itcm (rx) : ORIGIN = 0x08000000, LENGTH = 64K + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +OUTPUT_ARCH("riscv") + +ENTRY(_stext) +EXTERN(_vectors) +SECTIONS +{ + .boot : { + _sboot = ABSOLUTE(.); + KEEP(*(.boot)) + _eboot = ABSOLUTE(.); + } > vector + + .text : { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + .init_section : ALIGN(4) { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + .ialign : { + . = ALIGN(4); + _slitcm = ABSOLUTE(.); + } > flash + + .itcm : { + . = ALIGN(4); + _sitcm = ABSOLUTE(.); + _svitcm = ABSOLUTE(.); + _svector = .; + KEEP(*(.vectors)) + _evector = .; + *(.itcm .itcm.*) + . = ALIGN(4); + _evitcm = ABSOLUTE(.); + _suvitcm = ABSOLUTE(.); + *(.uitcm .uitcm.*) + _euvitcm = ABSOLUTE(.); + _eitcm = ORIGIN(itcm) + LENGTH(itcm); + } > itcm AT > flash + + .dalign : { + . = ALIGN(4); + _eronly = ABSOLUTE(.); + } > flash + + .data : ALIGN(4) { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/rv32m1/rv32m1-vega/scripts/ld.script b/boards/risc-v/rv32m1/rv32m1-vega/scripts/ld.script new file mode 100644 index 00000000000..8298410d28e --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/scripts/ld.script @@ -0,0 +1,99 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/scripts/ld.script + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +MEMORY +{ + flash (rx) : ORIGIN = 0x00000000, LENGTH = 0x000FFF00 + vector(rx) : ORIGIN = 0x000FFF00, LENGTH = 256 + sram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00030000 +} + +OUTPUT_ARCH("riscv") + +ENTRY(_stext) +EXTERN(_vectors) +SECTIONS +{ + .vectors : ALIGN(4) { + _svector = .; + KEEP(*(.vectors)) + _evector = .; + } > vector + + .text : { + _stext = ABSOLUTE(.); + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > flash + + .init_section : ALIGN(4) { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > flash + + _eronly = ABSOLUTE(.); + + .data : ALIGN(4) { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.sdata .sdata.* .sdata2.*) + *(.gnu.linkonce.d.*) + *(.gnu.linkonce.s.*) + CONSTRUCTORS + . = ALIGN(4); + _edata = ABSOLUTE(.); + } > sram AT > flash + + .bss : ALIGN(4) { + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + *(.gnu.linkonce.b.*) + *(.gnu.linkonce.sb.*) + *(COMMON) + . = ALIGN(4); + _ebss = ABSOLUTE(.); + } > sram + + /* Stabs debugging sections. */ + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} diff --git a/boards/risc-v/rv32m1/rv32m1-vega/src/Makefile b/boards/risc-v/rv32m1/rv32m1-vega/src/Makefile new file mode 100644 index 00000000000..426d902ed59 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/src/Makefile @@ -0,0 +1,37 @@ +############################################################################ +# boards/risc-v/rv32m1/rv32m1-vega/src/Makefile +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +include $(TOPDIR)/Make.defs + +CSRCS = rv32m1_bringup.c rv32m1_boot.c + +ifeq ($(CONFIG_LIB_BOARDCTL),y) +CSRCS += rv32m1_appinit.c +endif + +ifeq ($(CONFIG_ARCH_LEDS),y) +CSRCS += rv32m1_autoleds.c +endif + +ifeq ($(CONFIG_ARCH_BUTTONS),y) +CSRCS += rv32m1_buttons.c +endif + +include $(TOPDIR)/boards/Board.mk diff --git a/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1-vega.h b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1-vega.h new file mode 100644 index 00000000000..c74d582c300 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1-vega.h @@ -0,0 +1,63 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1-vega.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __BOARDS_RISCV_RV32M1_RV32M1_VEGA_SRC_RV32M1_VEGA_H +#define __BOARDS_RISCV_RV32M1_RV32M1_VEGA_SRC_RV32M1_VEGA_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* BUTTONs */ + +#define BOARD_NBUTTON 4 + +#define BUTTON_SW2 (GPIO_INPUT|GPIO_INT_EDGE|GPIO_FLOAT |\ + GPIO_PORTA|GPIO_PIN0) + +#define BUTTON_SW3 (GPIO_INPUT|GPIO_INT_EDGE|GPIO_PULLUP|\ + GPIO_PORTE|GPIO_PIN8) + +#define BUTTON_SW4 (GPIO_INPUT|GPIO_INT_EDGE|GPIO_PULLUP|\ + GPIO_PORTE|GPIO_PIN9) + +#define BUTTON_SW5 (GPIO_INPUT|GPIO_INT_EDGE|GPIO_PULLUP|\ + GPIO_PORTE|GPIO_PIN12) + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: stm32_bringup + * + * Description: + * Perform architecture specific initialization + * + ****************************************************************************/ + +int rv32m1_bringup(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __BOARDS_RISCV_RV32M1_RV32M1_VEGA_SRC_RV32M1_VEGA_H */ diff --git a/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_appinit.c b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_appinit.c new file mode 100644 index 00000000000..21e41299dd9 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_appinit.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_appinit.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include + +#include "rv32m1.h" +#include "rv32m1-vega.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_app_initialize + * + * Description: + * Perform architecture specific initialization + * + * Input Parameters: + * arg - The boardctl() argument is passed to the board_app_initialize() + * implementation without modification. The argument has no + * meaning to NuttX; the meaning of the argument is a contract + * between the board-specific initialization logic and the + * matching application logic. The value could be such things as a + * mode enumeration value, a set of DIP switch switch settings, a + * pointer to configuration data read from a file or serial FLASH, + * or whatever you would like to do with it. Every implementation + * should accept zero/NULL as a default configuration. + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned on + * any failure to indicate the nature of the failure. + * + ****************************************************************************/ + +int board_app_initialize(uintptr_t arg) +{ +#ifdef CONFIG_BOARD_LATE_INITIALIZE + /* Board initialization already performed by board_late_initialize() */ + + return OK; +#else + /* Perform board-specific initialization */ + + return rv32m1_bringup(); +#endif +} diff --git a/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_autoleds.c b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_autoleds.c new file mode 100644 index 00000000000..d5048817aaf --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_autoleds.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_autoleds.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include "rv32m1_gpio.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define GPIO_LED (GPIO_OUTPUT|GPIO_OUTPUT_SET|GPIO_PORTA|GPIO_PIN24) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_autoled_initialize + ****************************************************************************/ + +void board_autoled_initialize(void) +{ + rv32m1_gpio_config(GPIO_LED); +} + +/**************************************************************************** + * Name: board_autoled_on + ****************************************************************************/ + +void board_autoled_on(int led) +{ + if (LED_CPU == led) + { + rv32m1_gpio_write(GPIO_LED, true); + } +} + +/**************************************************************************** + * Name: board_autoled_off + ****************************************************************************/ + +void board_autoled_off(int led) +{ + if (LED_CPU == led) + { + rv32m1_gpio_write(GPIO_LED, false); + } +} diff --git a/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_boot.c b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_boot.c new file mode 100644 index 00000000000..52e8a944319 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_boot.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_boot.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_boardinitialize + * + * Description: + * All RV32M1 architectures must provide the following entry point. + * This entry point is called early in the initialization -- after all + * memory has been configured and mapped but before any devices have been + * initialized. + * + ****************************************************************************/ + +void rv32m1_boardinitialize(void) +{ +#ifdef CONFIG_ARCH_LEDS + /* Configure on-board LEDs if LED support has been selected. */ + + board_autoled_initialize(); +#endif +} diff --git a/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_bringup.c b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_bringup.c new file mode 100644 index 00000000000..6af10072c07 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_bringup.c @@ -0,0 +1,72 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_bringup.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "rv32m1.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: rv32m1_bringup + ****************************************************************************/ + +int rv32m1_bringup(void) +{ + int ret = OK; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, "/proc", "procfs", 0, NULL); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: Failed to mount procfs at %s: %d\n", + "/proc", ret); + } +#endif + +#ifdef CONFIG_INPUT_BUTTONS + /* Register the BUTTON driver */ + + ret = btn_lower_initialize("/dev/buttons"); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", + ret); + } +#endif + + return ret; +} diff --git a/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_buttons.c b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_buttons.c new file mode 100644 index 00000000000..542b3ea1973 --- /dev/null +++ b/boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_buttons.c @@ -0,0 +1,150 @@ +/**************************************************************************** + * boards/risc-v/rv32m1/rv32m1-vega/src/rv32m1_buttons.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include +#include +#include + +#include "rv32m1_gpio.h" +#include "rv32m1.h" +#include "rv32m1-vega.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint32_t g_buttons[BOARD_NBUTTON] = +{ + BUTTON_SW2, + BUTTON_SW3, + BUTTON_SW4, + BUTTON_SW5 +}; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_button_initialize + * + * Description: + * board_button_initialize() must be called to initialize button resources. + * After that, board_buttons() may be called to collect the current state + * of all buttons or board_button_irq() may be called to register button + * interrupt handlers. + * + ****************************************************************************/ + +uint32_t board_button_initialize(void) +{ + int i; + + for (i = 0; i < BOARD_NBUTTON; ++i) + { + rv32m1_gpio_config(g_buttons[i]); + } + + return BOARD_NBUTTON; +} + +/**************************************************************************** + * Name: board_buttons + * + * Description: + * After board_button_initialize() has been called, board_buttons() may be + * called to collect the state of all buttons. board_buttons() returns an + * 32-bit bit set with each bit associated with a button. See the + * BUTTON_*_BIT definitions in board.h for the meaning of each bit. + * + ****************************************************************************/ + +uint32_t board_buttons(void) +{ + uint32_t ret = 0; + int i = 0; + + for (i = 0; i < BOARD_NBUTTON; ++i) + { + /* Low value means that the button is pressed */ + + if (!rv32m1_gpio_read(g_buttons[i])) + { + ret |= 1 << i; + } + } + + return ret; +} + +/**************************************************************************** + * Name: board_button_irq + * + * Description: + * board_button_irq() may be called to register an interrupt handler that + * will be called when a button is depressed or released. The ID value is + * a button enumeration value that uniquely identifies a button resource. + * See the BUTTON_* definitions in board.h for the meaning of enumeration + * value. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQBUTTONS +int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg) +{ + int ret = -EINVAL; + + if (id < 0 || id >= BOARD_NBUTTON) + { + return -EINVAL; + } + + if (NULL != irqhandler) + { + /* Attach the new button handler. */ + + ret = rv32m1_gpio_irqattach(g_buttons[id], irqhandler, arg); + + /* Then make sure that interrupts are enabled on the pin */ + + rv32m1_gpio_irqenable(g_buttons[id]); + } + else + { + rv32m1_gpio_irqdisable(g_buttons[id]); + ret = 0; + } + + return ret; +} +#endif