add gap8 board of riscv for xiuos

This commit is contained in:
Wang_Weigen
2021-08-30 14:05:12 +08:00
parent fde280b6a0
commit 198d61918b
42 changed files with 6303 additions and 1 deletions
+69
View File
@@ -0,0 +1,69 @@
mainmenu "XiUOS Project Configuration"
config BSP_DIR
string
option env="BSP_ROOT"
default "."
config KERNEL_DIR
string
option env="KERNEL_ROOT"
default "../.."
config BOARD_GAPUINO
bool
select ARCH_RISCV
default y
source "$KERNEL_DIR/arch/Kconfig"
menu "gapuino feature"
source "$BSP_DIR/third_party_driver/Kconfig"
menu "config default board resources"
menu "config board app name"
config BOARD_APP_NAME
string "config board app name"
default "/XiUOS_gapuino_app.bin"
endmenu
menu "config board service table"
config SERVICE_TABLE_ADDRESS
hex "board service table address"
default 0x80100000
endmenu
menu "config hardware resources for connection"
if CONNECTION_COMMUNICATION_ETHERNET
config ETHERNET_UART_NAME
string "ethernet uart name"
default "/dev/uart3_dev3"
endif
if CONNECTION_COMMUNICATION_WIFI
config WIFI_UART_NAME
string "wifi uart name"
default "/dev/uart3_dev3"
endif
endmenu
endmenu
config __STACKSIZE__
int "stack size for interrupt"
default 4096
endmenu
menu "Hardware feature"
source "$KERNEL_DIR/resources/Kconfig"
endmenu
source "$KERNEL_DIR/Kconfig"
+6
View File
@@ -0,0 +1,6 @@
SRC_FILES := board.c
SRC_DIR := third_party_driver
include $(KERNEL_ROOT)/compiler.mk
+89
View File
@@ -0,0 +1,89 @@
README
======
gapuino is an evaluation board for GAP8, a 1+8-core DSP-like RISC-V
MCU. GAP8 features a RI5CY core called Fabric Controller(FC), and a
cluster of 8 RI5CY cores that runs at a bit slower speed. GAP8 is an
implementation of the opensource PULP platform, a Parallel-Ultra-Low-
Power design.
The port is currently very minimal, though additional support may be
added in the future to address more of the board peripherals.
Supported:
- USB UART (console port)
- uDMA on SOC domain
- FLL clock scaling
Not supported:
- SPI, I2C, I2S, CPI, LVDS, Hyper-bus on the uDMA subsystem
- the sensor board
- the 8-core cluster
- the Hardware convolution engine
See also:
gapuino board and the sensor board:
https://gwt-website-files.s3.amazonaws.com/gapuino_um.pdf
https://gwt-website-files.s3.amazonaws.com/gapuino_multisensor_um.pdf
GAP8 datasheet:
https://gwt-website-files.s3.amazonaws.com/gap8_datasheet.pdf
Contents
========
- Environment Setup
- Configurations
- Execute
Environment Setup
=================
First, setup the gap_sdk from GreenwavesTechnologies' github repo.
Follow the README to setup the toolchain and environment.
https://github.com/GreenWaves-Technologies/gap_sdk/
Configurations
==============
Each gapuino configuration is maintained in a sub-directory and can
be selected as follow:
tools/configure.sh gapuino:<subdir>
Where <subdir> is one of the following:
nsh
---
This is an NSH example that uses the UART connected to FT2232 as
the console. Default UART settings are 115200, 8N1.
Execute
=======
You may download the ELF to the board by `plpbridge` in gap_sdk.
Remember to first `cd` to the gap_sdk/ and `source sourceme.sh`, so
that you have the $GAP_SDK_HOME environment variable.
Use the following command to download and run the ELF through JTAG:
$GAP_SDK_HOME/install/workstation/bin/plpbridge \
--cable=ftdi@digilent --boot-mode=jtag --chip=gap \
--binary=nuttx \
load ioloop reqloop start wait
As for debugging, the following command download the ELF and opens
a gdbserver on port 1234:
$GAP_SDK_HOME/install/workstation/bin/plpbridge \
--cable=ftdi@digilent --boot-mode=jtag --chip=gap \
--binary=nuttx \
load ioloop gdb wait
And then launch the gdb on another terminal:
riscv32-unknown-elf-gdb nuttx
...
(gdb) target remote :1234
Remote debugging using :1234
IRQ_U_Vector_Base () at chip/startup_gap8.S:293
293 j reset_handler /* 32 */
(gdb)
And then enjoy yourself debugging with the CLI gdb :-)
+69
View File
@@ -0,0 +1,69 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file board.c
* @brief support hifive1-rev-B-board init configure and start-up
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#include <board.h>
#include <arch_interrupt.h>
#include <xiuos.h>
#include <device.h>
extern void entry(void);
extern int InitHwUart(void);
extern void irqinitialize(void);
extern void timer_initialize(void);
extern void up_serialinit(void);
extern unsigned int __bss_end__;
extern void test_dma_txstart(char c, uint32_t size);
extern void test_gap8_uartinit();
extern void gapuino_sysinit(void);
void GapuinoStart(uint32_t mhartid)
{
gapuino_sysinit();
entry();
}
void InitBoardHardware(void)
{
x_base newstat;
x_base oldstat;
irqinitialize();
InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS);
InitHwUart();
InstallConsole("uart0", "uart0_drv", "uart0_dev0");
// asm volatile("nop");
// asm volatile ("csrr %0, 0x300": "=r" (oldstat));
// newstat = oldstat | (0x8);
// asm volatile("csrw mstatus, %0" : /* no output */ : "r" (newstat));
KPrintf("console init completed.\n");
KPrintf("board initialization......\n");
timer_initialize();
KPrintf("memory address range: [0x%08x - 0x%08x], size: %d\n", (x_ubase) MEMORY_START_ADDRESS, (x_ubase) MEMORY_END_ADDRESS, GAP8_SRAM_SIZE);
/* initialize memory system */
KPrintf("board init done.\n");
KPrintf("start kernel...\n");
return;
}
+85
View File
@@ -0,0 +1,85 @@
/****************************************************************************
* boards/risc-v/gap8/gapuino/include/board.h
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef BOARD_H__
#define BOARD_H__
/****************************************************************************
* Included Files
****************************************************************************/
#include <xsconfig.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Public Data
****************************************************************************/
#ifndef __ASSEMBLY__
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
extern unsigned int __bss_start__;
extern unsigned int __bss_end__;
extern unsigned int _end;
extern unsigned int __stack_end__;
extern unsigned int g_service_table_start;
extern unsigned int g_service_table_end;
// #define MEMORY_START_ADDRESS (void*)(&__bss_end__)
#define MEMORY_START_ADDRESS (void*)(&_end)
#define GAP8_SRAM_SIZE 512
#define MEMORY_END_ADDRESS (void*)(0x1C000000 + GAP8_SRAM_SIZE * 1024)
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif
#endif
+38
View File
@@ -0,0 +1,38 @@
# ARCHCFLAGS = -fno-builtin
# ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
# ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
# ARCHOPTIMIZATION = -g
# ASARCHCPUFLAGS += -Wa,-g
# ARCHCPUFLAGS = -march=rv32imcxgap8 -mPE=8 -mFC=1 -D__riscv__ -D__pulp__ -D__GAP8__ -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields
# export CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) -O0 -g3 -gdwarf-2
# export AFLAGS := $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS)
# export LFLAGS := -march=rv32imcxgap8 -mPE=8 -mFC=1 -nostartfiles -Wl,--gc-sections,-Map=XiUOS_gap8.map,-cref,-u,reset_handler -T $(BSP_ROOT)/link.lds
# export APPLFLAGS := -march=rv32imcxgap8 -mPE=8 -mFC=1 -nostartfiles -Wl,--gc-sections,-Map=XiUOS_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
# export CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS)
# export CROSS_COMPILE ?=/opt/gap_riscv_toolchain/bin/riscv32-unknown-elf-
export CFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb -fgnu89-inline -Werror
export AFLAGS := -c -mcmodel=medany -march=rv32imac -mabi=ilp32 -x assembler-with-cpp -ggdb
export LFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiUOS_gap8.map,-cref,-u,_start -T $(BSP_ROOT)/link.lds
export APPLFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -nostartfiles -Wl,--gc-sections,-Map=XiUOS_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
export CXXFLAGS := -mcmodel=medany -march=rv32imac -mabi=ilp32 -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb -Werror
export CROSS_COMPILE ?=/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed-
export DEFINES := -DHAVE_CCONFIG_H -DHAVE_SIGINFO
export ARCH = risc-v
export MCU = GAP8
+175
View File
@@ -0,0 +1,175 @@
/****************************************************************************
* boards/risc-v/gap8/gapuino/scripts/ld.script
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/* Not needed, but we need separate linker scripts anyway */
OUTPUT_ARCH( riscv )
SEARCH_DIR(.)
__DYNAMIC = 0;
MEMORY
{
L2 (wxa!ri) : ORIGIN = 0x1C000000, LENGTH = 0x80000
FC_tcdm : ORIGIN = 0x1B000004, LENGTH = 0x3ffc
FC_tcdm_aliased : ORIGIN = 0x00000004, LENGTH = 0x3ffc
}
__L1_STACK_SIZE = 0x400;
__FC_STACK_SIZE = 4096;
/* We have to align each sector to word boundaries as our current s19->slm
* conversion scripts are not able to handle non-word aligned sections.
*/
ENTRY( reset_handler )
SECTIONS
{
.vectors_M :
{
. = ALIGN(4);
IRQ_U_Vector_Base = .;
KEEP(*(.vectors_M))
} > L2
.dbg_struct :
{
. = ALIGN(4);
IRQ_M_Vector_Base = .;
KEEP(*(.dbg_struct))
} > L2
. = ALIGN(4);
.text : {
PROVIDE( _text = ABSOLUTE(.) );
/* _stext = .; */
*(.text .text.*)
/* *(.rodata .rodata*) */
/* _etext = .; */
/* section information for shell */
. = ALIGN(4);
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
PROVIDE(__ctors_start__ = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE(__ctors_end__ = .);
. = ALIGN(4);
__isrtbl_idx_start = .;
KEEP(*(.isrtbl.idx))
__isrtbl_start = .;
KEEP(*(.isrtbl))
__isrtbl_end = .;
. = ALIGN(4);
PROVIDE(g_service_table_start = ABSOLUTE(.));
KEEP(*(.g_service_table))
PROVIDE(g_service_table_end = ABSOLUTE(.));
/* _endtext = .; */
PROVIDE( _etext = ABSOLUTE(.) );
} > L2
.rodata : {
/* Due to limitations on FPGA loader, loadable sections must have
* base and size aligned on 4 bytes
*/
. = ALIGN(4);
*(.rodata);
*(.rodata.*)
. = ALIGN(4);
} > L2
. = ALIGN(4);
.data : {
__data_start__ = .; /* create a global symbol at data start */
*(.data .data.*)
. = ALIGN(4);
PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800 );
*(.sdata .sdata.*)
__data_end__ = .; /* define a global symbol at data end */
} > L2
. = ALIGN(4);
.bss :
{
/* . = ALIGN(4);
_sbss = .;
__bss_start__ = .;
_fbss = .;
*(.bss)
*(.bss.*)
*(.sbss)
*(.sbss.*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
_ebss = .; */
__bss_start = ABSOLUTE(.);
_fbss = .;
/* Writable uninitialized small data segment (.sbss segment)*/
*(.sbss .sbss.*)
*(.scommon)
/* Uninitialized writeable data section (.bss segment)*/
*(.bss .bss.*)
*(COMMON)
. = ALIGN(4);
__bss_end = ABSOLUTE(.);
} > L2
.stack :
{
. = ALIGN(4);
PROVIDE(_idle_stack_start = ABSOLUTE(.));
. = . + __FC_STACK_SIZE;
PROVIDE( _idle_stack_end = ABSOLUTE(.) );
} > L2
_end = ABSOLUTE(.);
}
+33
View File
@@ -0,0 +1,33 @@
menuconfig BSP_USING_GPIO
bool "Using GPIO device"
default y
select RESOURCES_PIN
if BSP_USING_GPIO
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
endif
menuconfig BSP_USING_SYSCLOCK
bool "Using SYSCLOCK device"
default y
if BSP_USING_SYSCLOCK
source "$BSP_DIR/third_party_driver/sys_clock/Kconfig"
endif
menuconfig BSP_USING_HWTIMER
bool "Using HWTIMER device"
default n
select RESOURCES_HWTIMER
if BSP_USING_HWTIMER
source "$BSP_DIR/third_party_driver/timer/Kconfig"
endif
menuconfig BSP_USING_UART
bool "Using UART device"
default y
select RESOURCES_SERIAL
if BSP_USING_UART
source "$BSP_DIR/third_party_driver/uart/Kconfig"
endif
+28
View File
@@ -0,0 +1,28 @@
SRC_FILES :=
ifeq ($(CONFIG_BSP_USING_DMA),y)
SRC_DIR += udma
endif
ifeq ($(CONFIG_BSP_USING_GPIO),y)
SRC_DIR += gpio
endif
ifeq ($(CONFIG_BSP_USING_PLIC),y)
SRC_DIR += plic
endif
ifeq ($(CONFIG_BSP_USING_SYSCLOCK),y)
SRC_DIR += sys_clock
endif
ifeq ($(CONFIG_BSP_USING_HWTIMER),y)
SRC_DIR += timer
endif
ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_DIR += uart
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,11 @@
config PIN_BUS_NAME
string "pin bus name"
default "pin"
config PIN_DRIVER_NAME
string "pin driver name"
default "pin_drv"
config PIN_DEVICE_NAME
string "pin device name"
default "pin_dev"
@@ -0,0 +1,3 @@
SRC_FILES := hardware_gpio.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,218 @@
/****************************************************************************
* arch/risc-v/src/gap8/gap8_gpio.c
* GAP8 FLL clock generator
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* GAP8 has only 1 port. Each pin could be configured to GPIO or alternative
* functions.
****************************************************************************/
/**
* @file hardware_gpio.c
* @brief add from Gap8 riscv SDK
* https://greenwavesdev2.wpengine.com/sdk-manuals/
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-07-27
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include "hardware_gpio.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: gap8_configpin
*
* Description:
* Configure a pin based on bit-encoded description of the pin.
*
* GPIO software abstraction: bitmap configuration of pins
*
* |31 18| 17 | 16 | 15 |14 10|9 8|7 0|
* | --- | drive | pull-up/OD | I/O | GPIOn | alt | pinnum |
* | --- | 1-bit | 1-bit | 1-b | 5-bit | 2-bit | 8-bit |
*
* Returned Value:
* OK on success
* ERROR on invalid pin.
*
****************************************************************************/
int gap8_configpin(uint32_t cfgset)
{
uint32_t pinnum = cfgset & 0xff;
uint32_t altfunc = (cfgset >> 8) & 0x3;
uint32_t pin_dr_pu = (cfgset >> 16) & 0x3;
uint32_t port_cfg_reg;
uint32_t pin_alt_reg;
int shiftcnt;
if (pinnum > MAX_PIN_NUM)
{
return -1;
}
/* Set pin drive strength (or pin speed in other words) and pulling
* If it's a GPIO, set input or output.
*
* Note that GPIO and non-GPIO uses different register sets...
* And all the GPIO functions are mapped to ALT-1, and ALT-1 contains
* only GPIO functions...
*/
port_cfg_reg = PORTA->PADCFG[pinnum >> 2];
shiftcnt = (pinnum & 0x3) << 3;
port_cfg_reg &= ~(0x3 << shiftcnt);
port_cfg_reg |= pin_dr_pu << shiftcnt;
PORTA->PADCFG[pinnum >> 2] = port_cfg_reg;
if (altfunc == 1)
{
uint32_t gpio_n = (cfgset >> 10) & 0x1f;
uint32_t gpio_dir = (cfgset >> 15) & 0x1;
uint32_t tmp;
/* It must be a GPIO */
GPIOA->EN |= (1L << gpio_n);
tmp = GPIOA->PADCFG[gpio_n >> 2];
shiftcnt = (gpio_n & 0x3) << 3;
tmp &= ~(0x3 << shiftcnt);
tmp |= pin_dr_pu << shiftcnt;
GPIOA->PADCFG[gpio_n >> 2] = tmp;
tmp = GPIOA->DIR;
tmp &= ~(1L << gpio_n);
tmp |= gpio_dir << gpio_n;
GPIOA->DIR = tmp;
}
/* Set pin alternative function */
pin_alt_reg = PORTA->PADFUN[pinnum >> 4];
shiftcnt = (pinnum & 0xf) << 1;
pin_alt_reg &= ~(0x3 << shiftcnt);
pin_alt_reg |= altfunc << shiftcnt;
PORTA->PADFUN[pinnum >> 4] = pin_alt_reg;
return 0;
}
/****************************************************************************
* Name: gap8_gpiowrite
*
* Description:
* Write one or zero to the selected GPIO pin
*
* Bit encoded pinset:
*
* |31 15|14 10|9 0|
* | --- | GPIOn | --- |
* | --- | 5-bit | --- |
*
****************************************************************************/
void gap8_gpiowrite(uint32_t pinset, bool value)
{
uint32_t gpio_n = (pinset >> 10) & 0x1f;
if (value)
{
GPIOA->OUT |= (1L << gpio_n);
}
else
{
GPIOA->OUT &= ~(1L << gpio_n);
}
}
/****************************************************************************
* Name: gap8_gpioread
*
* Description:
* Read one or zero from the selected GPIO pin
*
* Bit encoded pinset:
*
* |31 15|14 10|9 0|
* | --- | GPIOn | --- |
* | --- | 5-bit | --- |
*
****************************************************************************/
bool gap8_gpioread(uint32_t pinset)
{
uint32_t gpio_n = (pinset >> 10) & 0x1f;
return (GPIOA->IN >> gpio_n) & 0x1;
}
/****************************************************************************
* Name: gap8_gpioirqset
*
* Description:
* Enable or disable interrupt on GPIO
*
* Bit encoded pinset:
*
* |31 20|19 18|17 15|14 10|9 0|
* | --- | int-typ | --- | GPIOn | --- |
* | --- | 2-bit | --- | 5-bit | --- |
*
****************************************************************************/
void gap8_gpioirqset(uint32_t pinset, bool enable)
{
uint32_t gpio_n = (pinset >> 10) & 0x1f;
uint32_t int_type = (pinset >> 18) * 0x3;
uint32_t tmp;
uint32_t shitfcnt;
if (enable)
{
shitfcnt = (gpio_n & 0xf) << 1;
tmp = GPIOA->INTCFG[gpio_n >> 4];
tmp &= ~(0x3 << shitfcnt);
tmp |= int_type << shitfcnt;
GPIOA->INTCFG[gpio_n >> 4] = tmp;
GPIOA->INTEN |= (1L << gpio_n);
}
}
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_uart.h
* @brief define gap8-board uart function and struct
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-07-27
*/
#ifndef CONNECT_UART_H
#define CONNECT_UART_H
#include <device.h>
#ifdef __cplusplus
extern "C" {
#endif
int InitHwUart(void);
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,75 @@
/****************************************************************************
* arch/risc-v/src/gap8/gap8_fll.h
* GAP8 FLL clock generator
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* FC can run up to 250MHz@1.2V, and 150MHz@1.0V. While the default voltage
* of PMU is 1.2V, it's okay to boost up without considering PMU.
****************************************************************************/
#ifndef __ARCH_RISC_V_SRC_GAP8_FLL_H
#define __ARCH_RISC_V_SRC_GAP8_FLL_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "gap8.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: gap8_setfreq
*
* Description:
* Set frequency up to 250MHz. Input frequency in Hz.
*
****************************************************************************/
void gap8_setfreq(uint32_t frequency);
/****************************************************************************
* Name: gap8_getfreq
*
* Description:
* Get current system clock frequency in Hz.
*
****************************************************************************/
uint32_t gap8_getfreq(void);
#endif /* __ARCH_RISC_V_SRC_GAP8_FLL_H */
@@ -0,0 +1,87 @@
/****************************************************************************
* arch/risc-v/src/gap8/gap8_tim.h
* PIN driver for GAP8
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* GAP8 features a 64-bit basic timer, able to split into 2 32-bit timers,
* with identicle memory map and 2 IRQ channels, for both FC core and
* cluster. We would use it as system timer.
****************************************************************************/
#ifndef __ARCH_RISC_V_SRC_GAP8_TIM_H
#define __ARCH_RISC_V_SRC_GAP8_TIM_H
/****************************************************************************
* Included Files
****************************************************************************/
#include "gap8.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: gap8_timer_initialize
*
* Description:
* Initialize the timer based on the frequency of source clock and ticks
* per second.
*
****************************************************************************/
void gap8_timer_initialize(uint32_t source_clock, uint32_t tick_per_second);
/****************************************************************************
* Name: gap8_register_timercallback
*
* Description:
* Register a callback function called on timer IRQ
*
****************************************************************************/
void gap8_register_timercallback(void (*on_timer)(void*arg), void *arg);
/****************************************************************************
* Name: gap8_timer_isr
*
* Description:
* ISR for timer
*
****************************************************************************/
void gap8_timer_isr(void);
#endif /* __ARCH_RISC_V_SRC_GAP8_TIM_H */
@@ -0,0 +1,70 @@
/************************************************************************************
* arch/risc-v/src/gap8/gap8_uart.h
* UART driver on uDMA subsystem for GAP8
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* This UART IP has no flow control. So ioctl is limited.
************************************************************************************/
#ifndef _ARCH_RISCV_SRC_GAP8_UART_H
#define _ARCH_RISCV_SRC_GAP8_UART_H
/************************************************************************************
* Included Files
************************************************************************************/
#include "gap8.h"
#include "gap8_udma.h"
#include "gap8_gpio.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
#define GAP8_NR_UART 1
/************************************************************************************
* Public Types
************************************************************************************/
/************************************************************************************
* Public Function Prototypes
************************************************************************************/
void up_earlyserialinit(void);
void up_serialinit(void);
int up_putc(int ch);
#endif /* _ARCH_RISCV_SRC_GAP8_UART_H */
@@ -0,0 +1,305 @@
/************************************************************************************
* arch/risc-v/src/gap8/gap8_gpio.h
* PIN driver for GAP8
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* GAP8 has only 1 port. Each pin could be configured to GPIO or alternative
* functions.
************************************************************************************/
#ifndef __HARDWARE_GPIO_H__
#define __HARDWARE_GPIO_H__
/************************************************************************************
* Included Files
************************************************************************************/
#include <sys/types.h>
#include <stdint.h>
#include <stdbool.h>
#include "gap8.h"
/************************************************************************************
* Pre-Processor Definitions
************************************************************************************/
#define MAX_PIN_NUM 47
/* GPIO software abstraction: bitmap configuration of pins
*
* |31 20|19 18| 17 | 16 | 15 |14 10|9 8|7 0|
* | --- | int-typ | drive | pull-up/OD | I/O | GPIOn | alt | pinnum |
* | --- | 2-bit | 1-bit | 1-bit | 1-b | 5-bit | 2-bit | 8-bit |
*/
#define GAP8_GPIO_INT_FALLING (0L << 18)
#define GAP8_GPIO_INT_RISING (1L << 18)
#define GAP8_GPIO_INT_RISING_AND_FALLING (2L << 18)
#define GAP8_PIN_SPEED_HIGH (1L << 17)
#define GAP8_PIN_SPEED_LOW (0L << 17)
#define GAP8_PIN_PULL_UP (1L << 16)
#define GAP8_PIN_PULL_NONE (0L << 16)
#define GAP8_GPIO_INPUT (0L << 15)
#define GAP8_GPIO_OUTPUT (1L << 15)
#define GAP8_PIN_A4_SPIM1_MISO ((0L << 8) | 0)
#define GAP8_PIN_A4_GPIOA0 ((1L << 8) | (0L << 10) | 0)
#define GAP8_PIN_B3_SPIM1_MOSI ((0L << 8) | 1)
#define GAP8_PIN_B3_GPIOA1 ((1L << 8) | (1L << 10) | 1)
#define GAP8_PIN_A5_SPIM1_CS0 ((0L << 8) | 2)
#define GAP8_PIN_A5_GPIOA2 ((1L << 8) | (2L << 10) | 2)
#define GAP8_PIN_A5_I2C1_SDA ((2L << 8) | 2)
#define GAP8_PIN_B4_SPIM1_SCK ((0L << 8) | 3)
#define GAP8_PIN_B4_GPIOA3 ((1L << 8) | (3L << 10) | 3)
#define GAP8_PIN_B4_I2C1_SCL ((2L << 8) | 3)
#define GAP8_PIN_A3_ORCA_TXSYNC ((0L << 8) | 4)
#define GAP8_PIN_A3_GPIOA0 ((1L << 8) | (0L << 10) | 4)
#define GAP8_PIN_A3_SPIM1_CS0 ((2L << 8) | 4)
#define GAP8_PIN_B2_ORCA_RXSYNC ((0L << 8) | 5)
#define GAP8_PIN_B2_GPIOA1 ((1L << 8) | (1L << 10) | 5)
#define GAP8_PIN_B2_SPIM1_CS1 ((2L << 8) | 5)
#define GAP8_PIN_A2_ORCA_TX1 ((0L << 8) | 6)
#define GAP8_PIN_A2_GPIOA2 ((1L << 8) | (2L << 10) | 6)
#define GAP8_PIN_B1_ORCA_TXQ ((0L << 8) | 7)
#define GAP8_PIN_B1_GPIOA3 ((1L << 8) | (3L << 10) | 7)
#define GAP8_PIN_A44_ORCA_RXI ((0L << 8) | 8)
#define GAP8_PIN_A44_GPIOA4 ((1L << 8) | (4L << 10) | 8)
#define GAP8_PIN_A44_SPIS0_D0 ((2L << 8) | 8)
#define GAP8_PIN_A44_SPIS0_D2 ((3L << 8) | 8)
#define GAP8_PIN_B40_ORCA_RXQ ((0L << 8) | 9)
#define GAP8_PIN_B40_GPIOA5 ((1L << 8) | (5L << 10) | 9)
#define GAP8_PIN_B40_SPIS0_D1 ((2L << 8) | 9)
#define GAP8_PIN_B40_SPIS0_D3 ((3L << 8) | 9)
#define GAP8_PIN_A43_CAM_PCLK ((0L << 8) | 10)
#define GAP8_PIN_A43_GPIOA4 ((1L << 8) | (4L << 10) | 10)
#define GAP8_PIN_A43_TIM1_CH0 ((2L << 8) | 10)
#define GAP8_PIN_A37_CAM_HSYNC ((0L << 8) | 11)
#define GAP8_PIN_A37_GPIOA5 ((1L << 8) | (5L << 10) | 11)
#define GAP8_PIN_A37_TIM1_CH1 ((2L << 8) | 11)
#define GAP8_PIN_B39_CAM_D0 ((0L << 8) | 12)
#define GAP8_PIN_B39_GPIOA6 ((1L << 8) | (6L << 10) | 12)
#define GAP8_PIN_B39_TIM1_CH2 ((2L << 8) | 12)
#define GAP8_PIN_A42_CAM_D1 ((0L << 8) | 13)
#define GAP8_PIN_A42_GPIOA7 ((1L << 8) | (7L << 10) | 13)
#define GAP8_PIN_A42_TIM1_CH3 ((2L << 8) | 13)
#define GAP8_PIN_B38_CAM_D2 ((0L << 8) | 14)
#define GAP8_PIN_B38_GPIOA8 ((1L << 8) | (8L << 10) | 14)
#define GAP8_PIN_B38_TIM2_CH0 ((2L << 8) | 14)
#define GAP8_PIN_A41_CAM_D3 ((0L << 8) | 15)
#define GAP8_PIN_A41_GPIOA9 ((1L << 8) | (9L << 10) | 15)
#define GAP8_PIN_A41_TIM2_CH1 ((2L << 8) | 15)
#define GAP8_PIN_B37_CAM_D4 ((0L << 8) | 16)
#define GAP8_PIN_B37_GPIOA10 ((1L << 8) | (10L << 10) | 16)
#define GAP8_PIN_B37_TIM2_CH2 ((2L << 8) | 16)
#define GAP8_PIN_A40_CAM_D5 ((0L << 8) | 17)
#define GAP8_PIN_A40_GPIOA11 ((1L << 8) | (11L << 10) | 17)
#define GAP8_PIN_A40_TIM2_CH3 ((2L << 8) | 17)
#define GAP8_PIN_B36_CAM_D6 ((0L << 8) | 18)
#define GAP8_PIN_B36_GPIOA12 ((1L << 8) | (12L << 10) | 18)
#define GAP8_PIN_B36_TIM3_CH0 ((2L << 8) | 18)
#define GAP8_PIN_A38_CAM_D7 ((0L << 8) | 19)
#define GAP8_PIN_A38_GPIOA13 ((1L << 8) | (13L << 10) | 19)
#define GAP8_PIN_A38_TIM3_CH1 ((2L << 8) | 19)
#define GAP8_PIN_A36_CAM_VSYNC ((0L << 8) | 20)
#define GAP8_PIN_A36_GPIOA14 ((1L << 8) | (14L << 10) | 20)
#define GAP8_PIN_A36_TIM3_CH2 ((2L << 8) | 20)
#define GAP8_PIN_B34_I2C1_SDA ((0L << 8) | 21)
#define GAP8_PIN_B34_GPIOA15 ((1L << 8) | (15L << 10) | 21)
#define GAP8_PIN_B34_TIM3_CH3 ((2L << 8) | 21)
#define GAP8_PIN_D1_I2C1_SCL ((0L << 8) | 22)
#define GAP8_PIN_D1_GPIOA16 ((1L << 8) | (16L << 10) | 22)
#define GAP8_PIN_D1_ORCA_CLK ((2L << 8) | 22)
#define GAP8_PIN_B11_TIM0_CH0 ((0L << 8) | 23)
#define GAP8_PIN_B11_GPIOA17 ((1L << 8) | (17L << 10) | 23)
#define GAP8_PIN_A13_TIM0_CH1 ((0L << 8) | 24)
#define GAP8_PIN_A13_GPIOA18 ((1L << 8) | (18L << 10) | 24)
#define GAP8_PIN_A13_TIM1_CH0 ((2L << 8) | 24)
#define GAP8_PIN_B12_TIM0_CH2 ((0L << 8) | 25)
#define GAP8_PIN_B12_GPIOA19 ((1L << 8) | (19L << 10) | 25)
#define GAP8_PIN_B12_TIM2_CH0 ((2L << 8) | 25)
#define GAP8_PIN_A14_TIM0_CH3 ((0L << 8) | 26)
#define GAP8_PIN_A14_GPIOA20 ((1L << 8) | (20L << 10) | 26)
#define GAP8_PIN_A14_TIM3_CH0 ((2L << 8) | 26)
#define GAP8_PIN_B13_I2S1_SCK ((0L << 8) | 27)
#define GAP8_PIN_B13_GPIOA21 ((1L << 8) | (21L << 10) | 27)
#define GAP8_PIN_B13_SPIS0_SCK ((2L << 8) | 27)
#define GAP8_PIN_B13_I2S1_SDI ((3L << 8) | 27)
#define GAP8_PIN_A15_I2S1_WS ((0L << 8) | 28)
#define GAP8_PIN_A15_GPIOA22 ((1L << 8) | (22L << 10) | 28)
#define GAP8_PIN_A15_SPIS0_CS ((2L << 8) | 28)
#define GAP8_PIN_A15_HYPER_CKN ((3L << 8) | 28)
#define GAP8_PIN_B14_I2S1_SDI ((0L << 8) | 29)
#define GAP8_PIN_B14_GPIOA23 ((1L << 8) | (23L << 10) | 29)
#define GAP8_PIN_B14_SPIS0_D2 ((2L << 8) | 29)
#define GAP8_PIN_B14_HYPER_CK ((3L << 8) | 29)
#define GAP8_PIN_B6_UART_RX ((0L << 8) | 30)
#define GAP8_PIN_B6_GPIOA24 ((1L << 8) | (24L << 10) | 30)
#define GAP8_PIN_A7_UART_TX ((0L << 8) | 31)
#define GAP8_PIN_A7_GPIOA25 ((1L << 8) | (25L << 10) | 31)
#define GAP8_PIN_D2_SPIM0_D0 ((0L << 8) | 32)
#define GAP8_PIN_D2_HYPER_D0 ((3L << 8) | 32)
#define GAP8_PIN_A11_SPIM0_D1 ((0L << 8) | 33)
#define GAP8_PIN_A11_HYPER_D1 ((3L << 8) | 33)
#define GAP8_PIN_B10_SPIM0_D2 ((0L << 8) | 34)
#define GAP8_PIN_B10_GPIOA26 ((1L << 8) | (26L << 10) | 34)
#define GAP8_PIN_B10_I2C1_SDA ((2L << 8) | 34)
#define GAP8_PIN_B10_HYPER_D2 ((3L << 8) | 34)
#define GAP8_PIN_A10_SPIM0_D3 ((0L << 8) | 35)
#define GAP8_PIN_A10_GPIOA27 ((1L << 8) | (27L << 10) | 35)
#define GAP8_PIN_A10_I2C1_SCL ((2L << 8) | 35)
#define GAP8_PIN_A10_HYPER_D3 ((3L << 8) | 35)
#define GAP8_PIN_B8_SPIM0_CS0 ((0L << 8) | 36)
#define GAP8_PIN_B8_HYPER_D4 ((3L << 8) | 36)
#define GAP8_PIN_A8_SPIM0_CS1 ((0L << 8) | 37)
#define GAP8_PIN_A8_GPIOA28 ((1L << 8) | (28L << 10) | 37)
#define GAP8_PIN_A8_SPIS0_D3 ((2L << 8) | 37)
#define GAP8_PIN_A8_HYPER_D5 ((3L << 8) | 37)
#define GAP8_PIN_B7_SPIM0_SCK ((0L << 8) | 38)
#define GAP8_PIN_B7_HYPER_D6 ((3L << 8) | 38)
#define GAP8_PIN_A9_SPIS0_CS ((0L << 8) | 39)
#define GAP8_PIN_A9_GPIOA29 ((1L << 8) | (29L << 10) | 39)
#define GAP8_PIN_A9_SPIM1_CS0 ((2L << 8) | 39)
#define GAP8_PIN_A9_HYPER_D7 ((3L << 8) | 39)
#define GAP8_PIN_B15_SPIS0_D0 ((0L << 8) | 40)
#define GAP8_PIN_B15_GPIOA30 ((1L << 8) | (30L << 10) | 40)
#define GAP8_PIN_B15_SPIM1_CS1 ((2L << 8) | 40)
#define GAP8_PIN_B15_HYPER_CS0 ((3L << 8) | 40)
#define GAP8_PIN_A16_SPIS0_D1 ((0L << 8) | 41)
#define GAP8_PIN_A16_GPIOA31 ((1L << 8) | (31L << 10) | 41)
#define GAP8_PIN_A16_HYPER_CS1 ((3L << 8) | 41)
#define GAP8_PIN_B9_SPIS0_SCK ((0L << 8) | 42)
#define GAP8_PIN_B9_HYPER_RWDS ((3L << 8) | 42)
#define GAP8_PIN_B22_I2C0_SDA ((0L << 8) | 43)
#define GAP8_PIN_A25_I2C0_SCL ((0L << 8) | 44)
#define GAP8_PIN_A24_I2S0_SCK ((0L << 8) | 45)
#define GAP8_PIN_A26_I2S0_WS ((0L << 8) | 46)
#define GAP8_PIN_B23_I2S0_SDI ((0L << 8) | 47)
/************************************************************************************
* Public Function Prototypes
************************************************************************************/
/************************************************************************************
* Name: gap8_configpin
*
* Description:
* Configure a pin based on bit-encoded description of the pin.
*
* Returned Value:
* OK on success
* ERROR on invalid port, or when pin is locked as ALT function.
*
************************************************************************************/
int gap8_configpin(uint32_t cfgset);
/************************************************************************************
* Name: gap8_gpiowrite
*
* Description:
* Write one or zero to the selected GPIO pin
*
************************************************************************************/
void gap8_gpiowrite(uint32_t pinset, bool value);
/************************************************************************************
* Name: gap8_gpioread
*
* Description:
* Read one or zero from the selected GPIO pin
*
************************************************************************************/
bool gap8_gpioread(uint32_t pinset);
/************************************************************************************
* Name: gap8_gpioirqset
*
* Description:
* Enable or disable interrupt on GPIO
*
************************************************************************************/
void gap8_gpioirqset(uint32_t pinset, bool enable);
#endif /* _ARCH_RISCV_SRC_GAP8_GPIO_H */
@@ -0,0 +1,234 @@
/************************************************************************************
* arch/risc-v/src/gap8/gap8_udma.h
* uDMA driver for GAP8
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************************/
/************************************************************************************
* GAP8 features a simple uDMA subsystem. Peripherals including UART, SPI, I2C, I2S,
* CPI, LVDS, Hyperbus, have config registers memory-mapped, but not data registers.
* The only way to send or receive data is using the uDMA. These peripherals share
* the same uDMA ISR.
*
* uDMA subsystem drivers are object oriented to some extend. Peripherals inherit
* the udma class, which handles all the data exchange stuff.
************************************************************************************/
/**
* @file hardware_udma.h
* @brief add from Gap8 riscv SDK
* https://greenwavesdev2.wpengine.com/sdk-manuals/
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-07-27
*/
#ifndef __HARDWARE_UDMA_H__
#define __HARDWARE_UDMA_H__
/************************************************************************************
* Included Files
************************************************************************************/
#include <stdbool.h>
#include "gap8.h"
/************************************************************************************
* Pre-processor Definitions
************************************************************************************/
/* uDMA channel ID */
#define GAP8_UDMA_ID_LVDS 0
#define GAP8_UDMA_ID_SPIM0 1
#define GAP8_UDMA_ID_SPIM1 2
#define GAP8_UDMA_ID_HYPER 3
#define GAP8_UDMA_ID_UART 4
#define GAP8_UDMA_ID_I2C0 5
#define GAP8_UDMA_ID_I2C1 6
#define GAP8_UDMA_ID_TCDM 7 /* l2 to fc-l1 */
#define GAP8_UDMA_ID_I2S 8
#define GAP8_UDMA_ID_CPI 9
/* Total udma channels */
#define GAP8_UDMA_NR_CHANNELS 10
/************************************************************************************
* Public Types
************************************************************************************/
/* Software abstraction for uDMA */
/* One round of data exchange on one channel gathered into linked list because
* threads would request for data exchange simultaneously.
* Private for udma driver.
*/
struct __udma_queue
{
uint8_t *buff; /* Memory address. either TX or RX */
uint32_t block_size; /* Size of a data block in bytes */
int block_count; /* Number of blocks to send or recv */
};
/* This is the base class of uDMA subsystem. Peripherals connected to uDMA
* should inherited this class.
*/
struct gap8_udma_peripheral
{
/* Public */
udma_reg_t *regs; /* Hardware config regs */
uint32_t id; /* GAP8_UDMA_ID_x */
void (*on_tx)(void *arg); /* tx callback */
void (*on_rx)(void *arg); /* rx callback */
void *tx_arg; /* tx argument */
void *rx_arg; /* rx argument */
uint16_t is_tx_continous;
uint16_t is_rx_continous;
/* Private */
struct __udma_queue tx; /* TX queue */
struct __udma_queue rx; /* RX queue */
};
/************************************************************************************
* Public Function Prototypes
************************************************************************************/
/************************************************************************************
* Name: gap8_udma_init
*
* Description:
* Initialize (and enable) a udma peripheral.
*
* Input:
* instance: pointer to a peripheral instance connected to uDMA
*
************************************************************************************/
int gap8_udma_init(struct gap8_udma_peripheral *instance);
/************************************************************************************
* Name: gap8_udma_deinit
*
* Description:
* Deinit a udma peripheral
*
************************************************************************************/
int gap8_udma_deinit(struct gap8_udma_peripheral *instance);
/************************************************************************************
* Name: gap8_udma_tx_setirq
*
* Description:
* Enable or disable the tx interrupt.
*
************************************************************************************/
int gap8_udma_tx_setirq(struct gap8_udma_peripheral *instance, bool enable);
/************************************************************************************
* Name: gap8_udma_rx_setirq
*
* Description:
* Enable or disable the rx interrupt.
*
************************************************************************************/
int gap8_udma_rx_setirq(struct gap8_udma_peripheral *instance, bool enable);
/************************************************************************************
* Name: gap8_udma_tx_start
*
* Description:
* Send size * count bytes non-blocking.
*
* Return ERROR if unable to send. The caller should poll on execution, or register
* a on_tx to get the signal.
*
************************************************************************************/
int gap8_udma_tx_start(struct gap8_udma_peripheral *instance,
uint8_t *buff, uint32_t size, int count);
/************************************************************************************
* Name: gap8_udma_rx_start
*
* Description:
* Receive size * count bytes
*
* Return ERROR if unable to send. The caller should poll on execution, or register
* a on_rx to get the signal.
*
************************************************************************************/
int gap8_udma_rx_start(struct gap8_udma_peripheral *instance,
uint8_t *buff, uint32_t size, int count);
/************************************************************************************
* Name: gap8_udma_tx_poll
*
* Description:
* Return OK if tx finished.
*
************************************************************************************/
int gap8_udma_tx_poll(struct gap8_udma_peripheral *instance);
/************************************************************************************
* Name: gap8_udma_rx_poll
*
* Description:
* Return OK if rx finished.
*
************************************************************************************/
int gap8_udma_rx_poll(struct gap8_udma_peripheral *instance);
/************************************************************************************
* Name: gap8_udma_doirq
*
* Description:
* uDMA ISR
*
************************************************************************************/
int gap8_udma_doirq(int irq, void *context, void *arg);
#endif /* _ARCH_RISCV_SRC_GAP8_UDMA_H */
@@ -0,0 +1 @@
@@ -0,0 +1,3 @@
SRC_FILES := gapuino_sysinit.c gap8_fll.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,128 @@
/****************************************************************************
* arch/risc-v/src/gap8/gap8_fll.c
* GAP8 FLL clock generator
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* FC can run up to 250MHz@1.2V, and 150MHz@1.0V. While the default voltage
* of PMU is 1.2V, it's okay to boost up without considering PMU.
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include "gap8_fll.h"
/****************************************************************************
* Pre-Processor Declarations
****************************************************************************/
/* Log2(FLL_REF_CLK=32768) */
#define LOG2_REFCLK 15
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: gap8_setfreq
*
* Description:
* Set frequency up to 250MHz. Input frequency counted by Hz.
*
****************************************************************************/
void gap8_setfreq(uint32_t frequency)
{
uint32_t mult;
uint32_t mult_factor_diff;
/* FreqOut = Fref * mult/2^(div-1)
* With 16-bit mult and 4-bit div
* div = 1
*/
mult = frequency >> LOG2_REFCLK;
/* Gain : 2-1 - 2-10 (0x2-0xB)
* Return to close loop mode and give gain to feedback loop
*/
FLL_CTRL->SOC_CONF2 = FLL_CTRL_CONF2_LOOPGAIN(0x7) |
FLL_CTRL_CONF2_DEASSERT_CYCLES(0x10) |
FLL_CTRL_CONF2_ASSERT_CYCLES(0x10) |
FLL_CTRL_CONF2_LOCK_TOLERANCE(0x100) |
FLL_CTRL_CONF2_CONF_CLK_SEL(0x0) |
FLL_CTRL_CONF2_OPEN_LOOP(0x0) |
FLL_CTRL_CONF2_DITHERING(0x1);
/* Configure mult and div */
FLL_CTRL->SOC_CONF1 = FLL_CTRL_CONF1_MODE(1) |
FLL_CTRL_CONF1_MULTI_FACTOR(mult) |
FLL_CTRL_CONF1_CLK_OUT_DIV(1);
/* Check FLL converge by compare status register with multiply factor */
do
{
mult_factor_diff = (FLL_CTRL->SOC_FLL_STATUS - mult);
}
while (mult_factor_diff > 0x10);
FLL_CTRL->SOC_CONF2 = FLL_CTRL_CONF2_LOOPGAIN(0xb) |
FLL_CTRL_CONF2_DEASSERT_CYCLES(0x10) |
FLL_CTRL_CONF2_ASSERT_CYCLES(0x10) |
FLL_CTRL_CONF2_LOCK_TOLERANCE(0x100) |
FLL_CTRL_CONF2_CONF_CLK_SEL(0x0) |
FLL_CTRL_CONF2_OPEN_LOOP(0x0) |
FLL_CTRL_CONF2_DITHERING(0x1);
}
/****************************************************************************
* Name: gap8_getfreq
*
* Description:
* Get current system clock frequency in Hz.
*
****************************************************************************/
uint32_t gap8_getfreq(void)
{
/* FreqOut = Fref * mult/2^(div-1), where div = 1 */
return FLL_REF_CLK * (FLL_CTRL->SOC_FLL_STATUS & 0xffff);
}
@@ -0,0 +1,119 @@
/****************************************************************************
* boards/risc-v/gap8/gapuino/src/gapuino_sysinit.c
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdbool.h>
#include <stdio.h>
#include <errno.h>
#include "gap8.h"
#include "gap8_fll.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
/* Used to communicate with plpbridge */
struct _debug_struct
{
/* Used by external debug bridge to get exit status when using the board */
uint32_t exitStatus;
/* Printf */
uint32_t useInternalPrintf;
uint32_t putcharPending;
uint32_t putcharCurrent;
uint8_t putcharBuffer[128];
/* Debug step, used for showing progress to host loader */
uint32_t debugStep;
uint32_t debugStepPending;
/* Requests */
uint32_t firstReq;
uint32_t lastReq;
uint32_t firstBridgeReq;
uint32_t notifReqAddr;
uint32_t notifReqValue;
uint32_t bridgeConnected;
};
/****************************************************************************
* Private Data
****************************************************************************/
/* Place a dummy debug struct */
struct _debug_struct Debug_Struct =
{
.useInternalPrintf = 1,
};
uint32_t g_current_freq = 0;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: gapuino_sysinit
*
* Description:
* Initialize cache, clock, etc.
*
****************************************************************************/
void gapuino_sysinit(void)
{
SCBC->ICACHE_ENABLE = 0xffffffff;
gap8_setfreq(CONFIG_CORE_CLOCK_FREQ);
/* For debug usage */
g_current_freq = gap8_getfreq();
}
@@ -0,0 +1,19 @@
if BSP_USING_HWTIMER
config HWTIMER_BUS_NAME_1
string "hwtimer bus name"
default "hwtim1"
menuconfig ENABLE_TIM1
bool "enable TIM1"
default y
if ENABLE_TIM1
config HWTIMER_1_DEVICE_NAME_1
string "TIM1 dev name"
default "hwtim1_dev1"
config HWTIMER_DRIVER_NAME_1
string "TIM1 drv name"
default "hwtim1_drv"
endif
endif
@@ -0,0 +1,3 @@
SRC_FILES := hardware_hwtimer.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,116 @@
/****************************************************************************
* arch/risc-v/src/gap8/gap8_tim.c
* GAP8 basic timer
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* FC core has a 64-bit basic timer, able to split into 2 32-bit timers,
* with identicle memory map and 2 IRQ channels, for both FC core and
* cluster. We would use it as system timer.
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <xs_isr.h>
#include <gap8_tim.h>
/****************************************************************************
* Private Types
****************************************************************************/
struct gap8_tim_instance
{
basic_tim_reg_t *reg;
uint32_t core_clock;
};
/****************************************************************************
* Private Data
****************************************************************************/
static struct gap8_tim_instance fc_basic_timer =
{
.reg = BASIC_TIM,
.core_clock = 200000000,
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: gap8_timisr
*
* Description:
* Timer ISR to perform RR context switch
*
****************************************************************************/
extern int TickIsr(void);
void gap8_timisr(int irq, void *arg)
{
TickIsr();
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_timer_initialize
*
* Description:
* Initialize the timer based on the frequency of source clock and ticks
* per second.
*
****************************************************************************/
void timer_initialize(void)
{
/* Set input clock to 1MHz. FC won't exceed 250MHz */
uint32_t prescaler = (fc_basic_timer.core_clock / 1000000) & 0xff;
uint32_t cmpval = TICK_PER_SECOND;
/* Initialize timer registers */
fc_basic_timer.reg->CMP_LO = cmpval;
fc_basic_timer.reg->CFG_REG_LO = (prescaler << 8) |
BASIC_TIM_CLKSRC_FLL | BASIC_TIM_PRESC_ENABLE | BASIC_TIM_MODE_CYCL |
BASIC_TIM_IRQ_ENABLE | BASIC_TIM_RESET | BASIC_TIM_ENABLE;
fc_basic_timer.reg->VALUE_LO = 0;
isrManager.done->registerIrq(GAP8_IRQ_FC_TIMER_LO, gap8_timisr, NONE);
isrManager.done->enableIrq(GAP8_IRQ_FC_TIMER_LO);
}
@@ -0,0 +1,14 @@
menuconfig BSP_USING_UART0
bool "Enable UART0"
default y
if BSP_USING_UART0
config SERIAL_BUS_NAME_0
string "serial bus name"
default "uart0"
config SERIAL_DRV_NAME_0
string "serial bus driver name"
default "uart0_drv"
config SERIAL_0_DEVICE_NAME_0
string "serial bus device name"
default "uart0_dev0"
endif
@@ -0,0 +1,4 @@
SRC_FILES := connect_uart.c hardware_udma.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,326 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_usart.c
* @brief support gap8-board uart function and register to bus framework
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-07-23
*/
#include <xiuos.h>
#include <device.h>
#include "connect_uart.h"
#include "hardware_udma.h"
#include "hardware_gpio.h"
#include <board.h>
static void SerialCfgParamCheck(struct SerialCfgParam *serial_cfg_default, struct SerialCfgParam *serial_cfg_new)
{
struct SerialDataCfg *data_cfg_default = &serial_cfg_default->data_cfg;
struct SerialDataCfg *data_cfg_new = &serial_cfg_new->data_cfg;
if ((data_cfg_default->serial_baud_rate != data_cfg_new->serial_baud_rate) && (data_cfg_new->serial_baud_rate)) {
data_cfg_default->serial_baud_rate = data_cfg_new->serial_baud_rate;
}
if ((data_cfg_default->serial_bit_order != data_cfg_new->serial_bit_order) && (data_cfg_new->serial_bit_order)) {
data_cfg_default->serial_bit_order = data_cfg_new->serial_bit_order;
}
if ((data_cfg_default->serial_buffer_size != data_cfg_new->serial_buffer_size) && (data_cfg_new->serial_buffer_size)) {
data_cfg_default->serial_buffer_size = data_cfg_new->serial_buffer_size;
}
if ((data_cfg_default->serial_data_bits != data_cfg_new->serial_data_bits) && (data_cfg_new->serial_data_bits)) {
data_cfg_default->serial_data_bits = data_cfg_new->serial_data_bits;
}
if ((data_cfg_default->serial_invert_mode != data_cfg_new->serial_invert_mode) && (data_cfg_new->serial_invert_mode)) {
data_cfg_default->serial_invert_mode = data_cfg_new->serial_invert_mode;
}
if ((data_cfg_default->serial_parity_mode != data_cfg_new->serial_parity_mode) && (data_cfg_new->serial_parity_mode)) {
data_cfg_default->serial_parity_mode = data_cfg_new->serial_parity_mode;
}
if ((data_cfg_default->serial_stop_bits != data_cfg_new->serial_stop_bits) && (data_cfg_new->serial_stop_bits)) {
data_cfg_default->serial_stop_bits = data_cfg_new->serial_stop_bits;
}
}
static void UartRxIsr(void *arg)
{
struct SerialBus *serial_bus = (struct SerialBus *)arg;
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_bus->bus.owner_haldev;
SerialSetIsr(serial_dev, SERIAL_EVENT_RX_IND);
}
static uint32 SerialInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info)
{
asm volatile("nop");
NULL_PARAM_CHECK(serial_drv);
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
if (configure_info->private_data) {
struct SerialCfgParam *serial_cfg_new = (struct SerialCfgParam *)configure_info->private_data;
SerialCfgParamCheck(serial_cfg, serial_cfg_new);
}
struct gap8_udma_peripheral *uart_udma = (struct gap8_udma_peripheral *)serial_cfg->hw_cfg.private_data;
uart_reg_t *uart_reg = (uart_reg_t *)uart_udma->regs;
uint32_t cfg_reg = 0;
uint16_t div = CONFIG_CORE_CLOCK_FREQ / serial_cfg->data_cfg.serial_baud_rate;
gap8_udma_init(uart_udma);
/* Setup baudrate etc. */
cfg_reg = UART_SETUP_BIT_LENGTH(serial_cfg->data_cfg.serial_data_bits - 5) |
UART_SETUP_PARITY_ENA(serial_cfg->data_cfg.serial_parity_mode - 1) |
UART_SETUP_STOP_BITS(serial_cfg->data_cfg.serial_stop_bits - 1) |
UART_SETUP_TX_ENA(1) |
UART_SETUP_RX_ENA(1) |
UART_SETUP_CLKDIV(div);
uart_reg->SETUP = cfg_reg;
gap8_configpin(GAP8_PIN_A7_UART_TX | GAP8_PIN_PULL_UP | GAP8_PIN_SPEED_HIGH);
gap8_configpin(GAP8_PIN_B6_UART_RX | GAP8_PIN_PULL_UP | GAP8_PIN_SPEED_HIGH);
return EOK;
}
static uint32 SerialConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd)
{
NULL_PARAM_CHECK(serial_drv);
struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data;
struct gap8_udma_peripheral *uart_udma = (struct gap8_udma_peripheral *)serial_cfg->hw_cfg.private_data;
if (OPER_SET_INT == serial_operation_cmd) {
x_base lock = 0;
lock = DISABLE_INTERRUPT();
gap8_udma_rx_setirq(uart_udma, 1);
gap8_udma_rx_start(uart_udma, serial_dev->serial_fifo.serial_rx->serial_rx_buffer, 1, 1);
ENABLE_INTERRUPT(lock);
} else if (OPER_CLR_INT == serial_operation_cmd) {
gap8_udma_rx_setirq(uart_udma, 0);
gap8_udma_deinit(uart_udma);
}
return EOK;
}
static uint32 SerialDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
int serial_operation_cmd;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = SerialInit(serial_drv, configure_info);
break;
case OPE_CFG:
serial_operation_cmd = *(int *)configure_info->private_data;
ret = SerialConfigure(serial_drv, serial_operation_cmd);
break;
default:
break;
}
return ret;
}
static int SerialPutChar(struct SerialHardwareDevice *serial_dev, char c)
{
struct Driver *drv = serial_dev->haldev.owner_bus->owner_driver;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
struct gap8_udma_peripheral *uart_udma = (struct gap8_udma_peripheral *)serial_cfg->hw_cfg.private_data;
gap8_udma_tx_setirq(uart_udma,1);
gap8_udma_tx_start(uart_udma, &c, 1, 1);
for(int i = 999 ; i> 0 ; i--);
return 0;
}
static int SerialGetChar(struct SerialHardwareDevice *serial_dev)
{
struct Driver *drv = serial_dev->haldev.owner_bus->owner_driver;
struct SerialDriver *serial_drv = (struct SerialDriver *)drv;
struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data;
struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data;
struct gap8_udma_peripheral *uart_udma = (struct gap8_udma_peripheral *)serial_cfg->hw_cfg.private_data;
uint8_t rx_buf[4] = {0};
uint8_t ch = rx_buf[0];
/* Then trigger another reception */
gap8_udma_rx_start(uart_udma, rx_buf, 1, 1);
if (ch == 0)
return -ERROR;
return ch;
}
static const struct SerialDataCfg data_cfg_init =
{
.serial_baud_rate = BAUD_RATE_115200,
.serial_data_bits = DATA_BITS_8,
.serial_stop_bits = STOP_BITS_1,
.serial_parity_mode = PARITY_NONE,
.serial_bit_order = BIT_ORDER_LSB,
.serial_invert_mode = NRZ_NORMAL,
.serial_buffer_size = SERIAL_RB_BUFSZ,
};
static struct gap8_udma_peripheral gap8_udma =
{
.regs = (udma_reg_t *)UART,
.id = GAP8_UDMA_ID_UART,
.on_tx = NONE,//UartRxIsr??
// .on_tx = UartTxIsr,//UartRxIsr??
.tx_arg = NONE,
.on_rx = UartRxIsr,
.rx_arg = NONE,
.is_tx_continous = 0,
.is_rx_continous = 1,
};
/*manage the serial device operations*/
static const struct SerialDrvDone drv_done =
{
.init = SerialInit,
.configure = SerialConfigure,
};
/*manage the serial device hal operations*/
static struct SerialHwDevDone hwdev_done =
{
.put_char = SerialPutChar,
.get_char = SerialGetChar,
};
static int BoardSerialBusInit(struct SerialBus *serial_bus, struct SerialDriver *serial_driver, const char *bus_name, const char *drv_name)
{
x_err_t ret = EOK;
/*Init the serial bus */
ret = SerialBusInit(serial_bus, bus_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialBusInit error %d\n", ret);
return ERROR;
}
/*Init the serial driver*/
ret = SerialDriverInit(serial_driver, drv_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the serial driver to the serial bus*/
ret = SerialDriverAttachToBus(drv_name, bus_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the serial device to the serial bus*/
static int BoardSerialDevBend(struct SerialHardwareDevice *serial_device, void *serial_param, const char *bus_name, const char *dev_name)
{
x_err_t ret = EOK;
ret = SerialDeviceRegister(serial_device, serial_param, dev_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDeviceInit device %s error %d\n", dev_name, ret);
return ERROR;
}
ret = SerialDeviceAttachToBus(dev_name, bus_name);
if (EOK != ret) {
KPrintf("InitHwUart SerialDeviceAttachToBus device %s error %d\n", dev_name, ret);
return ERROR;
}
return ret;
}
int InitHwUart(void)
{
x_err_t ret = EOK;
static struct SerialBus serial_bus;
memset(&serial_bus, 0, sizeof(struct SerialBus));
static struct SerialDriver serial_driver;
memset(&serial_driver, 0, sizeof(struct SerialDriver));
static struct SerialHardwareDevice serial_device;
memset(&serial_device, 0, sizeof(struct SerialHardwareDevice));
static struct SerialCfgParam serial_cfg;
memset(&serial_cfg, 0, sizeof(struct SerialCfgParam));
static struct SerialDevParam serial_dev_param;
memset(&serial_dev_param, 0, sizeof(struct SerialDevParam));
serial_driver.drv_done = &drv_done;
serial_driver.configure = &SerialDrvConfigure;
serial_device.hwdev_done = &hwdev_done;
serial_cfg.data_cfg = data_cfg_init;
serial_cfg.hw_cfg.private_data = (void *)&gap8_udma;
serial_driver.private_data = (void *)&serial_cfg;
serial_dev_param.serial_work_mode = SIGN_OPER_INT_RX;
serial_device.haldev.private_data = (void *)&serial_dev_param;
ret = BoardSerialBusInit(&serial_bus, &serial_driver, SERIAL_BUS_NAME_0, SERIAL_DRV_NAME_0);
if (EOK != ret) {
KPrintf("InitHwUart uarths error ret %u\n", ret);
return ERROR;
}
ret = BoardSerialDevBend(&serial_device, (void *)&serial_cfg, SERIAL_BUS_NAME_0, SERIAL_0_DEVICE_NAME_0);
if (EOK != ret) {
KPrintf("InitHwUart uarths error ret %u\n", ret);
return ERROR;
}
gap8_udma.rx_arg = (void *)&serial_bus;
return ret;
}
@@ -0,0 +1,387 @@
/****************************************************************************
* arch/risc-v/src/gap8/gap8_udma.c
* uDMA driver for GAP8
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: hhuysqt <1020988872@qq.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* GAP8 features a simple uDMA subsystem. Peripherals including UART, SPI,
* I2C, I2S, CPI, LVDS, Hyperbus, have config registers memory-mapped, but
* not data registers. The only way to send or receive data is using the
* uDMA. Those peripherals share the same uDMA ISR.
*
* Note that uDMA can only recognize L2 RAM. So data must not be stored at
* L1, which means that if you link the stack at L1, you cannot use local
* buffers as data src or destination.
*
* As for the UART driver, the SOC_EU may fire a redundant IRQ even if the
* uDMA hasn't finished its job. So I spin on TX channel and bypass on RX
* channel, if the IRQ is redundant.
****************************************************************************/
/**
* @file hardware_udma.c
* @brief add from Gap8 riscv SDK
* https://greenwavesdev2.wpengine.com/sdk-manuals/
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-07-27
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include "hardware_udma.h"
#include <stddef.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define CHECK_CHANNEL_ID(INSTANCE) \
if ((INSTANCE) == NULL || \
(INSTANCE)->id >= GAP8_UDMA_NR_CHANNELS) \
{ \
return -1; \
}
/****************************************************************************
* Private Data
****************************************************************************/
/* uDMA peripheral instances
* The peripheral driver instantiate it and register through _init()
*/
static struct gap8_udma_peripheral *_peripherals[GAP8_UDMA_NR_CHANNELS] =
{
0
};
/****************************************************************************
* Private Functions
****************************************************************************/
static void _dma_txstart(struct gap8_udma_peripheral *the_peri)
{
the_peri->regs->TX_SADDR = (uint32_t)the_peri->tx.buff;
the_peri->regs->TX_SIZE = (uint32_t)the_peri->tx.block_size;
the_peri->regs->TX_CFG = UDMA_CFG_EN(1);
}
static void _dma_rxstart(struct gap8_udma_peripheral *the_peri)
{
the_peri->regs->RX_SADDR = (uint32_t)the_peri->rx.buff;
the_peri->regs->RX_SIZE = (uint32_t)the_peri->rx.block_size;
the_peri->regs->RX_CFG = UDMA_CFG_EN(1);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: gap8_udma_init
*
* Description:
* Initialize (and enable) a udma peripheral.
*
* Input:
* instance: pointer to a peripheral instance connected to uDMA
*
****************************************************************************/
int gap8_udma_init(struct gap8_udma_peripheral *instance)
{
uint32_t id;
asm volatile("nop");
CHECK_CHANNEL_ID(instance)
id = instance->id;
_peripherals[id] = instance;
/* Enable clock gating */
UDMA_GC->CG |= (1L << id);
return 0;
}
/****************************************************************************
* Name: gap8_udma_deinit
*
* Description:
* Deinit a udma peripheral
*
****************************************************************************/
int gap8_udma_deinit(struct gap8_udma_peripheral *instance)
{
uint32_t id;
CHECK_CHANNEL_ID(instance)
id = instance->id;
_peripherals[id] = NULL;
/* Disable clock gating */
UDMA_GC->CG &= ~(1L << id);
return 0;
}
/****************************************************************************
* Name: gap8_udma_tx_setirq
*
* Description:
* Enable or disable the tx interrupt.
*
****************************************************************************/
int gap8_udma_tx_setirq(struct gap8_udma_peripheral *instance, bool enable)
{
CHECK_CHANNEL_ID(instance)
/* The irq enable bit happened to be 2*id + 1 */
if (enable)
{
up_enable_event(1 + (instance->id << 1));
}
else
{
up_disable_event(1 + (instance->id << 1));
#if 0
instance->regs->TX_CFG = UDMA_CFG_CLR(1);
#endif
}
return 0;
}
/****************************************************************************
* Name: gap8_udma_rx_setirq
*
* Description:
* Enable or disable the rx interrupt.
*
****************************************************************************/
int gap8_udma_rx_setirq(struct gap8_udma_peripheral *instance, bool enable)
{
CHECK_CHANNEL_ID(instance)
/* The irq enable bit happened to be 2*id */
if (enable)
{
up_enable_event(instance->id << 1);
}
else
{
up_disable_event(instance->id << 1);
#if 0
instance->regs->RX_CFG = UDMA_CFG_CLR(1);
#endif
}
return 0;
}
/****************************************************************************
* Name: gap8_udma_tx_start
*
* Description:
* Send size * count bytes non-blocking.
*
* This function may be called from ISR, so it cannot be blocked. The
* caller should manage the muxing.
*
****************************************************************************/
int gap8_udma_tx_start(struct gap8_udma_peripheral *instance,
uint8_t *buff, uint32_t size, int count)
{
CHECK_CHANNEL_ID(instance)
instance->tx.buff = buff;
instance->tx.block_size = size;
instance->tx.block_count = count;
_dma_txstart(instance);
return 0;
}
/****************************************************************************
* Name: gap8_udma_rx_start
*
* Description:
* Receive size * count bytes
*
* This function may be called from ISR, so it cannot be blocked. The
* caller should manage the muxing.
*
****************************************************************************/
int gap8_udma_rx_start(struct gap8_udma_peripheral *instance,
uint8_t *buff, uint32_t size, int count)
{
CHECK_CHANNEL_ID(instance)
instance->rx.buff = buff;
instance->rx.block_size = size;
instance->rx.block_count = count;
_dma_rxstart(instance);
return 0;
}
/****************************************************************************
* Name: gap8_udma_tx_poll
*
* Description:
* Return 0 if the buffer is not in the tx pending list.
*
****************************************************************************/
int gap8_udma_tx_poll(struct gap8_udma_peripheral *instance)
{
CHECK_CHANNEL_ID(instance)
return instance->tx.block_count <= 0 ? 0 : -1;
}
/****************************************************************************
* Name: gap8_udma_rx_poll
*
* Description:
* Return 0 if the buffer is not in the rx pending list.
*
****************************************************************************/
int gap8_udma_rx_poll(struct gap8_udma_peripheral *instance)
{
CHECK_CHANNEL_ID(instance)
return instance->rx.block_count <= 0 ? 0 : -1;
}
/****************************************************************************
* Name: gap8_udma_doirq
*
* Description:
* uDMA ISR
*
****************************************************************************/
int gap8_udma_doirq(int irq, void *context, void *arg)
{
struct gap8_udma_peripheral *the_peripheral;
uint32_t event = SOC_EVENTS->CURRENT_EVENT & 0xff;
if (event > GAP8_UDMA_MAX_EVENT)
{
/* Bypass */
return 0;
}
/* Peripheral id happened to be half of event... */
the_peripheral = _peripherals[event >> 1];
if (the_peripheral == NULL)
{
return 0;
}
if (event & 0x1)
{
/* Tx channel */
if (the_peripheral->tx.block_count > 1)
{
the_peripheral->tx.block_count--;
the_peripheral->tx.buff += the_peripheral->tx.block_size;
_dma_txstart(the_peripheral);
}
else
{
/* The buffer is exhausted. Forward to peripheral's driver */
while (the_peripheral->regs->TX_SIZE != 0)
{
/* I don't know why but I have to spin here. SOC_EU would
* fire the IRQ even if uDMA hasn't finished the job.
* If I bypassed it, I would lose the finish event...
*/
}
the_peripheral->tx.block_count = 0;
if (the_peripheral->on_tx)
{
the_peripheral->on_tx(the_peripheral->tx_arg);
}
}
}
else
{
/* Rx channel */
asm volatile("nop");
if (the_peripheral->rx.block_count > 1)
{
the_peripheral->rx.block_count--;
the_peripheral->rx.buff += the_peripheral->rx.block_size;
_dma_rxstart(the_peripheral);
}
else if (!(the_peripheral->regs->RX_CFG & UDMA_CFG_CLR(1)))
{
/* The buffer is exhausted. Forward to peripheral's driver
*
* Again I don't know why but I have to test the PENDING bit of
* the uDMA, so as to avoid the redundant IRQ...
*/
the_peripheral->rx.block_count = 0;
if (the_peripheral->on_rx)
{
the_peripheral->on_rx(the_peripheral->rx_arg);
}
}
}
return 0;
}