mirror of
https://github.com/apache/nuttx.git
synced 2026-08-01 20:28:58 +00:00
arch/risc-v/rp23xx-rv: Add SMP support for dual Hazard3
Add SMP support to rp23xx risc-v port Signed-off-by: Serg Podtynnyi <serg@podtynnyi.com>
This commit is contained in:
parent
704815b233
commit
1282b94792
26 changed files with 487 additions and 264 deletions
|
|
@ -13,7 +13,7 @@ This is RISC-V version of the chip configuration.
|
|||
|
||||
This port is experimental and still a work in progress. Use with caution.
|
||||
|
||||
SMP (dual core configuration not supported yet)
|
||||
SMP is supported, two cores available.
|
||||
|
||||
Peripheral Support
|
||||
==================
|
||||
|
|
|
|||
|
|
@ -448,13 +448,15 @@ config ARCH_CHIP_RP23XX_RV
|
|||
select ARCH_RV_ISA_C
|
||||
select ARCH_HAVE_RESET
|
||||
select ARCH_HAVE_MULTICPU
|
||||
select ARCH_HAVE_MISALIGN_EXCEPTION
|
||||
select ARCH_HAVE_I2CRESET
|
||||
select ARCH_HAVE_TICKLESS
|
||||
select ARCH_HAVE_DEBUG
|
||||
select RISCV_STRING_FUNCTION
|
||||
select ONESHOT
|
||||
select ONESHOT_COUNT
|
||||
select ONESHOT_FAST_DIVISION
|
||||
select ALARM_ARCH
|
||||
select ARCH_HAVE_I2CRESET
|
||||
select ARCH_BOARD_COMMON
|
||||
---help---
|
||||
Raspberry Pi RP23XX architectures (RISC-V dual Hazard3).
|
||||
|
|
|
|||
|
|
@ -46,6 +46,12 @@ ssize_t up_show_cpuinfo(char *buf, size_t buf_size, off_t file_off)
|
|||
{
|
||||
procfs_sprintf(buf, buf_size, &file_off, "processor\t: %d\n", i);
|
||||
procfs_sprintf(buf, buf_size, &file_off, "hart\t\t: %d\n", i);
|
||||
procfs_sprintf(buf, buf_size, &file_off, "BogoMIPS\t: %u.%02u\n",
|
||||
(CONFIG_BOARD_LOOPSPERMSEC / 1000),
|
||||
(CONFIG_BOARD_LOOPSPERMSEC / 10) % 100);
|
||||
procfs_sprintf(buf, buf_size, &file_off, "cpu MHz\t\t: %u.%03u\n",
|
||||
CONFIG_ARCH_CPUINFO_FREQ_KHZ / 1000,
|
||||
CONFIG_ARCH_CPUINFO_FREQ_KHZ % 1000);
|
||||
|
||||
/* ISA */
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ list(
|
|||
rp23xx_pll.c)
|
||||
|
||||
if(CONFIG_SMP)
|
||||
list(APPEND SRCS rp23xx_cpustart.c rp23xx_smpcall.c rp23xx_cpuidlestack.c)
|
||||
list(REMOVE_ITEM SRCS riscv_smpcall.c riscv_cpustart.c)
|
||||
list(APPEND SRCS rp23xx_cpustart.c rp23xx_smpcall.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_RP23XX_RV_DMAC)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@
|
|||
|
||||
comment "RP23XX Configuration Options"
|
||||
|
||||
config ARCH_RV_ISA_VENDOR_EXTENSIONS
|
||||
default "zba_zbb_zbs_zbkb_zcb_zcmp"
|
||||
|
||||
config RP23XX_RV_RP2350B
|
||||
bool "Use RP2350B variant (QFN-80)"
|
||||
default n
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ CHIP_CSRCS += rp23xx_xosc.c
|
|||
CHIP_CSRCS += rp23xx_pll.c
|
||||
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
CMN_CSRCS := $(filter-out riscv_smpcall.c riscv_cpustart.c, $(CMN_CSRCS))
|
||||
CHIP_CSRCS += rp23xx_cpustart.c
|
||||
CHIP_CSRCS += rp23xx_smpcall.c
|
||||
CHIP_CSRCS += rp23xx_cpuidlestack.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_RP23XX_RV_DMAC),y)
|
||||
|
|
|
|||
|
|
@ -37,11 +37,23 @@
|
|||
|
||||
#include <arch/rp23xx-rv/chip.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Macro Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#if defined(CONFIG_SMP) && CONFIG_ARCH_INTERRUPTSTACK > 15
|
||||
.macro setintstack tmp0, tmp1
|
||||
up_cpu_index \tmp0
|
||||
li \tmp1, STACKFRAME_ALIGN_DOWN(CONFIG_ARCH_INTERRUPTSTACK)
|
||||
mul \tmp1, \tmp0, \tmp1
|
||||
la \tmp0, g_intstacktop
|
||||
sub sp, \tmp0, \tmp1
|
||||
.endm
|
||||
#endif /* CONFIG_SMP && CONFIG_ARCH_INTERRUPTSTACK > 15 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* __ARCH_RISCV_SRC_RP23XX_RV_CHIP_H */
|
||||
|
|
|
|||
|
|
@ -27,11 +27,13 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "rp23xx_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
#define hazard3_block() __asm__ volatile ("slt x0, x0, x0" ::: "memory")
|
||||
#define hazard3_unblock() __asm__ volatile ("slt x0, x0, x1" ::: "memory")
|
||||
|
||||
#define hazard3_irqarray_read(csr, index) (READ_AND_SET_CSR(csr, (index)) >> 16)
|
||||
#define hazard3_irqarray_write(csr, index, data) (WRITE_CSR(csr, (index) | ((uint32_t)(data) << 16)))
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "rp23xx_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "rp23xx_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "rp23xx_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "rp23xx_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "rp23xx_memorymap.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
|
|
|
|||
|
|
@ -1,93 +0,0 @@
|
|||
/****************************************************************************
|
||||
* arch/risc-v/src/rp23xx-rv/rp23xx_cpuidlestack.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* 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 <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/sched.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_cpu_idlestack
|
||||
*
|
||||
* Description:
|
||||
* Allocate a stack for the CPU[n] IDLE task (n > 0) if appropriate and
|
||||
* setup up stack-related information in the IDLE task's TCB. This
|
||||
* function is always called before up_cpu_start(). This function is
|
||||
* only called for the CPU's initial IDLE task; up_create_task is used for
|
||||
* all normal tasks, pthreads, and kernel threads for all CPUs.
|
||||
*
|
||||
* The initial IDLE task is a special case because the CPUs can be started
|
||||
* in different wans in different environments:
|
||||
*
|
||||
* 1. The CPU may already have been started and waiting in a low power
|
||||
* state for up_cpu_start(). In this case, the IDLE thread's stack
|
||||
* has already been allocated and is already in use. Here
|
||||
* up_cpu_idlestack() only has to provide information about the
|
||||
* already allocated stack.
|
||||
*
|
||||
* 2. The CPU may be disabled but started when up_cpu_start() is called.
|
||||
* In this case, a new stack will need to be created for the IDLE
|
||||
* thread and this function is then equivalent to:
|
||||
*
|
||||
* return up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL);
|
||||
*
|
||||
* The following TCB fields must be initialized by this function:
|
||||
*
|
||||
* - adj_stack_size: Stack size after adjustment for hardware, processor,
|
||||
* etc. This value is retained only for debug purposes.
|
||||
* - stack_alloc_ptr: Pointer to allocated stack
|
||||
* - stack_base_ptr: Adjusted stack base pointer after the TLS Data and
|
||||
* Arguments has been removed from the stack allocation.
|
||||
*
|
||||
* Input Parameters:
|
||||
* - cpu: CPU index that indicates which CPU the IDLE task is
|
||||
* being created for.
|
||||
* - tcb: The TCB of new CPU IDLE task
|
||||
* - stack_size: The requested stack size for the IDLE task. At least
|
||||
* this much must be allocated. This should be
|
||||
* CONFIG_SMP_STACK_SIZE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int up_cpu_idlestack(int cpu, struct tcb_s *tcb, size_t stack_size)
|
||||
{
|
||||
#if CONFIG_SMP_NCPUS > 1
|
||||
up_create_stack(tcb, stack_size, TCB_FLAG_TTYPE_KERNEL);
|
||||
#endif
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_SMP */
|
||||
|
|
@ -26,21 +26,15 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <nuttx/debug.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/init.h>
|
||||
#include <nuttx/sched_note.h>
|
||||
|
||||
#include "nvic.h"
|
||||
#include "sched/sched.h"
|
||||
#include "init/init.h"
|
||||
#include "riscv_internal.h"
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "hardware/rp23xx_hazard3.h"
|
||||
#include "hardware/rp23xx_sio.h"
|
||||
#include "hardware/rp23xx_psm.h"
|
||||
|
||||
|
|
@ -62,14 +56,14 @@
|
|||
# define showprogress(c)
|
||||
#endif
|
||||
|
||||
#define CORE1_BOOT_MSG_LEN 6
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
static volatile bool g_core1_boot;
|
||||
|
||||
extern int rp23xx_smp_call_handler(int irq, void *c, void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -90,7 +84,7 @@ static void fifo_drain(void)
|
|||
getreg32(RP23XX_SIO_FIFO_RD);
|
||||
}
|
||||
|
||||
__asm__ volatile ("sev");
|
||||
hazard3_unblock();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -114,14 +108,14 @@ static int fifo_comm(uint32_t msg)
|
|||
while (!(getreg32(RP23XX_SIO_FIFO_ST) & RP23XX_SIO_FIFO_ST_RDY))
|
||||
;
|
||||
putreg32(msg, RP23XX_SIO_FIFO_WR);
|
||||
__asm__ volatile ("sev");
|
||||
hazard3_unblock();
|
||||
|
||||
while (!(getreg32(RP23XX_SIO_FIFO_ST) & RP23XX_SIO_FIFO_ST_VLD))
|
||||
__asm__ volatile ("wfe");
|
||||
hazard3_block();
|
||||
|
||||
rcv = getreg32(RP23XX_SIO_FIFO_RD);
|
||||
|
||||
return msg == rcv;
|
||||
return (msg == rcv);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -138,25 +132,23 @@ static int fifo_comm(uint32_t msg)
|
|||
|
||||
static void core1_boot(void)
|
||||
{
|
||||
#if CONFIG_ARCH_INTERRUPTSTACK > 3
|
||||
/* Initializes the stack pointer */
|
||||
|
||||
riscv_initialize_stack();
|
||||
#endif
|
||||
|
||||
fifo_drain();
|
||||
|
||||
/* Setup NVIC */
|
||||
|
||||
up_irqinitialize();
|
||||
|
||||
/* Per-core timer: enable MTIMER interrupt */
|
||||
|
||||
up_timer_initialize();
|
||||
|
||||
/* Enable inter-processor FIFO interrupt */
|
||||
|
||||
irq_attach(RP23XX_SIO_IRQ_FIFO, rp23xx_smp_call_handler, NULL);
|
||||
irq_attach(RP23XX_SIO_IRQ_FIFO, riscv_smp_call_handler, NULL);
|
||||
up_enable_irq(RP23XX_SIO_IRQ_FIFO);
|
||||
|
||||
g_core1_boot = true;
|
||||
|
||||
UP_DMB();
|
||||
|
||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||
/* Notify that this CPU has started */
|
||||
|
||||
|
|
@ -203,7 +195,7 @@ int up_cpu_start(int cpu)
|
|||
{
|
||||
int i;
|
||||
struct tcb_s *tcb = current_task(cpu);
|
||||
uint32_t core1_boot_msg[5];
|
||||
uint32_t core1_boot_msg[CORE1_BOOT_MSG_LEN];
|
||||
|
||||
DPRINTF("cpu=%d\n", cpu);
|
||||
|
||||
|
|
@ -220,19 +212,18 @@ int up_cpu_start(int cpu)
|
|||
;
|
||||
clrbits_reg32(RP23XX_PSM_PROC1, RP23XX_PSM_FRCE_OFF);
|
||||
|
||||
/* Send initial VTOR, MSP, PC for Core 1 boot */
|
||||
|
||||
core1_boot_msg[0] = 0;
|
||||
core1_boot_msg[1] = 1;
|
||||
core1_boot_msg[2] = getreg32(NVIC_VECTAB);
|
||||
core1_boot_msg[3] = (uint32_t)tcb->stack_base_ptr +
|
||||
core1_boot_msg[1] = 0;
|
||||
core1_boot_msg[2] = 1;
|
||||
core1_boot_msg[3] = READ_CSR(CSR_MTVEC);
|
||||
core1_boot_msg[4] = (uint32_t)tcb->stack_base_ptr +
|
||||
tcb->adj_stack_size;
|
||||
core1_boot_msg[4] = (uint32_t)core1_boot;
|
||||
core1_boot_msg[5] = (uint32_t)core1_boot;
|
||||
|
||||
do
|
||||
{
|
||||
fifo_drain();
|
||||
for (i = 0; i < 5; i++)
|
||||
for (i = 0; i < CORE1_BOOT_MSG_LEN; i++)
|
||||
{
|
||||
if (!fifo_comm(core1_boot_msg[i]))
|
||||
{
|
||||
|
|
@ -240,15 +231,17 @@ int up_cpu_start(int cpu)
|
|||
}
|
||||
}
|
||||
}
|
||||
while (i < 5);
|
||||
while (i < CORE1_BOOT_MSG_LEN);
|
||||
|
||||
fifo_drain();
|
||||
|
||||
/* Enable inter-processor FIFO interrupt */
|
||||
|
||||
irq_attach(RP23XX_SIO_IRQ_FIFO, rp23xx_smp_call_handler, NULL);
|
||||
irq_attach(RP23XX_SIO_IRQ_FIFO, riscv_smp_call_handler, NULL);
|
||||
up_enable_irq(RP23XX_SIO_IRQ_FIFO);
|
||||
|
||||
/* Spin until Core 1 signals that it has finished its initialisation */
|
||||
|
||||
while (!g_core1_boot);
|
||||
|
||||
/* CPU Core 1 boot done */
|
||||
|
|
|
|||
|
|
@ -30,14 +30,13 @@
|
|||
#include "chip.h"
|
||||
#include "hardware/rp23xx_memorymap.h"
|
||||
#include "riscv_internal.h"
|
||||
#include "riscv_macros.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Symbols
|
||||
****************************************************************************/
|
||||
|
||||
/* Imported symbols */
|
||||
|
||||
.extern __trap_vec
|
||||
/* Exported Symbols */
|
||||
|
||||
.section .text
|
||||
.global __start
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
extern void rp23xx_send_irqreq(int irqreq);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
|
@ -91,6 +95,17 @@ void up_irqinitialize(void)
|
|||
|
||||
void up_enable_irq(int irq)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (irq >= RP23XX_IRQ_EXTINT && irq != RP23XX_SIO_IRQ_FIFO &&
|
||||
this_cpu() != 0)
|
||||
{
|
||||
/* Must be handled by Core 0 */
|
||||
|
||||
rp23xx_send_irqreq(irq);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (irq == RISCV_IRQ_MSOFT)
|
||||
{
|
||||
/* Read mstatus & set machine software interrupt enable in mie */
|
||||
|
|
@ -114,6 +129,8 @@ void up_enable_irq(int irq)
|
|||
hazard3_irqarray_set(RVCSR_MEIEA_OFFSET, 2 * n, mask & 0xffffu);
|
||||
hazard3_irqarray_set(RVCSR_MEIEA_OFFSET, 2 * n + 1, mask >> 16);
|
||||
}
|
||||
|
||||
UP_DMB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -126,6 +143,17 @@ void up_enable_irq(int irq)
|
|||
|
||||
void up_disable_irq(int irq)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (irq >= RP23XX_IRQ_EXTINT && irq != RP23XX_SIO_IRQ_FIFO &&
|
||||
this_cpu() != 0)
|
||||
{
|
||||
/* Must be handled by Core 0 */
|
||||
|
||||
rp23xx_send_irqreq(-irq);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (irq == RISCV_IRQ_MSOFT)
|
||||
{
|
||||
/* Read mstatus & clear machine software interrupt enable in mie */
|
||||
|
|
@ -147,6 +175,8 @@ void up_disable_irq(int irq)
|
|||
hazard3_irqarray_clear(RVCSR_MEIEA_OFFSET, 2 * n, mask & 0xffffu);
|
||||
hazard3_irqarray_clear(RVCSR_MEIEA_OFFSET, 2 * n + 1, mask >> 16);
|
||||
}
|
||||
|
||||
UP_DMB();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ static void rp23xx_handle_irqreq(int irqreq)
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rp23xx_smp_call_handler
|
||||
* Name: riscv_smp_call_handler
|
||||
*
|
||||
* Description:
|
||||
* This is the handler for SMP_CALL.
|
||||
|
|
@ -93,7 +93,7 @@ static void rp23xx_handle_irqreq(int irqreq)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
int rp23xx_smp_call_handler(int irq, void *c, void *arg)
|
||||
int riscv_smp_call_handler(int irq, void *c, void *arg)
|
||||
{
|
||||
int cpu = this_cpu();
|
||||
int irqreq;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
#include <nuttx/init.h>
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
#include "rp23xx_config.h"
|
||||
#include "rp23xx_clock.h"
|
||||
#include "rp23xx_uart.h"
|
||||
|
|
|
|||
|
|
@ -64,9 +64,26 @@
|
|||
|
||||
void up_timer_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (this_cpu() != 0)
|
||||
{
|
||||
up_enable_irq(RISCV_IRQ_MTIMER);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Core 0: full timer initialisation */
|
||||
|
||||
/* Stop the timer and reset the counter while we configure it */
|
||||
|
||||
putreg32(0, RP23XX_SIO_BASE + RP23XX_SIO_MTIME_CTRL_OFFSET);
|
||||
putreg32(0, RP23XX_SIO_BASE + RP23XX_SIO_MTIME_OFFSET);
|
||||
putreg32(0, RP23XX_SIO_BASE + RP23XX_SIO_MTIMEH_OFFSET);
|
||||
|
||||
/* Initialise compare registers to maximum so no interrupts fire
|
||||
* before the alarm subsystem sets the first real deadline.
|
||||
*/
|
||||
|
||||
putreg32(RP23XX_SIO_MTIMECMP_MASK,
|
||||
RP23XX_SIO_BASE + RP23XX_SIO_MTIMECMP_OFFSET);
|
||||
putreg32(RP23XX_SIO_MTIMECMPH_MASK,
|
||||
|
|
@ -81,6 +98,8 @@ void up_timer_initialize(void)
|
|||
|
||||
up_alarm_set_lowerhalf(lower);
|
||||
|
||||
/* Start the counter at full system-clock rate */
|
||||
|
||||
putreg32(RP23XX_SIO_MTIME_CTRL_EN | RP23XX_SIO_MTIME_CTRL_FULLSPEED,
|
||||
RP23XX_SIO_BASE + RP23XX_SIO_MTIME_CTRL_OFFSET);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@
|
|||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include <nuttx/debug.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include <nuttx/usb/usb.h>
|
||||
#include <nuttx/usb/usbdev.h>
|
||||
#include <nuttx/usb/usbdev_trace.h>
|
||||
|
|
@ -45,6 +47,7 @@
|
|||
#include "chip.h"
|
||||
#include "riscv_internal.h"
|
||||
#include "rp23xx_usbdev.h"
|
||||
#include "hardware/rp23xx_hazard3.h"
|
||||
|
||||
#include "hardware/rp23xx_resets.h"
|
||||
|
||||
|
|
@ -320,7 +323,10 @@ static int rp23xx_epread(struct rp23xx_ep_s *privep, uint16_t nbytes);
|
|||
static void rp23xx_abortrequest(struct rp23xx_ep_s *privep,
|
||||
struct rp23xx_req_s *privreq,
|
||||
int16_t result);
|
||||
static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result);
|
||||
static struct rp23xx_req_s *
|
||||
rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result);
|
||||
static void rp23xx_callback(struct rp23xx_ep_s *privep,
|
||||
struct rp23xx_req_s *callback_req);
|
||||
static void rp23xx_txcomplete(struct rp23xx_ep_s *privep);
|
||||
static int rp23xx_wrrequest(struct rp23xx_ep_s *privep);
|
||||
static void rp23xx_rxcomplete(struct rp23xx_ep_s *privep);
|
||||
|
|
@ -471,19 +477,15 @@ static void rp23xx_update_buffer_control(struct rp23xx_ep_s *privep,
|
|||
uint32_t and_mask,
|
||||
uint32_t or_mask)
|
||||
{
|
||||
uint32_t value = 0;
|
||||
|
||||
if (and_mask)
|
||||
if (and_mask == 0)
|
||||
{
|
||||
value = getreg32(privep->buf_ctrl) & and_mask;
|
||||
putreg32(or_mask, privep->buf_ctrl);
|
||||
}
|
||||
|
||||
if (or_mask)
|
||||
else
|
||||
{
|
||||
value |= or_mask;
|
||||
uint32_t value = getreg32(privep->buf_ctrl);
|
||||
putreg32((value & and_mask) | or_mask, privep->buf_ctrl);
|
||||
}
|
||||
|
||||
putreg32(value, privep->buf_ctrl);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -498,11 +500,15 @@ static int rp23xx_epwrite(struct rp23xx_ep_s *privep, uint8_t *buf,
|
|||
uint16_t nbytes)
|
||||
{
|
||||
uint32_t val;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Copy the transmit data into DPSRAM */
|
||||
|
||||
memcpy(privep->data_buf, buf, nbytes);
|
||||
if (nbytes > 0)
|
||||
{
|
||||
memcpy(privep->data_buf, buf, nbytes);
|
||||
}
|
||||
|
||||
UP_DMB();
|
||||
|
||||
val = nbytes |
|
||||
RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_AVAIL |
|
||||
|
|
@ -510,13 +516,11 @@ static int rp23xx_epwrite(struct rp23xx_ep_s *privep, uint8_t *buf,
|
|||
(privep->next_pid ?
|
||||
RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_DATA1_PID : 0);
|
||||
|
||||
privep->next_pid = 1 - privep->next_pid; /* Invert DATA0 <-> DATA1 */
|
||||
|
||||
/* Start the transfer */
|
||||
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
privep->next_pid = 1 - privep->next_pid;
|
||||
|
||||
rp23xx_update_buffer_control(privep, 0, val);
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
|
@ -532,20 +536,17 @@ static int rp23xx_epwrite(struct rp23xx_ep_s *privep, uint8_t *buf,
|
|||
static int rp23xx_epread(struct rp23xx_ep_s *privep, uint16_t nbytes)
|
||||
{
|
||||
uint32_t val;
|
||||
irqstate_t flags;
|
||||
|
||||
val = nbytes |
|
||||
RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_AVAIL |
|
||||
(privep->next_pid ?
|
||||
RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_DATA1_PID : 0);
|
||||
|
||||
privep->next_pid = 1 - privep->next_pid; /* Invert DATA0 <-> DATA1 */
|
||||
|
||||
/* Start the transfer */
|
||||
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
privep->next_pid = 1 - privep->next_pid;
|
||||
|
||||
rp23xx_update_buffer_control(privep, 0, val);
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -582,29 +583,17 @@ static void rp23xx_abortrequest(struct rp23xx_ep_s *privep,
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result)
|
||||
static struct rp23xx_req_s *
|
||||
rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result)
|
||||
{
|
||||
struct rp23xx_req_s *privreq;
|
||||
int stalled = privep->stalled;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Remove the completed request at the head of the endpoint request list */
|
||||
|
||||
flags = enter_critical_section();
|
||||
privreq = rp23xx_rqdequeue(privep);
|
||||
leave_critical_section(flags);
|
||||
|
||||
if (privreq)
|
||||
{
|
||||
/* If endpoint 0, temporarily reflect the state of protocol stalled
|
||||
* in the callback.
|
||||
*/
|
||||
|
||||
if (privep->epphy == 0)
|
||||
{
|
||||
privep->stalled = privep->dev->stalled;
|
||||
}
|
||||
|
||||
/* Save the result in the request structure */
|
||||
|
||||
privreq->req.result = result;
|
||||
|
|
@ -612,12 +601,9 @@ static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result)
|
|||
/* Callback to the request completion handler */
|
||||
|
||||
privreq->flink = NULL;
|
||||
privreq->req.callback(&privep->ep, &privreq->req);
|
||||
|
||||
/* Restore the stalled indication */
|
||||
|
||||
privep->stalled = stalled;
|
||||
}
|
||||
|
||||
return privreq;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -631,8 +617,14 @@ static void rp23xx_reqcomplete(struct rp23xx_ep_s *privep, int16_t result)
|
|||
static void rp23xx_txcomplete(struct rp23xx_ep_s *privep)
|
||||
{
|
||||
struct rp23xx_req_s *privreq;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
|
||||
privreq = rp23xx_rqpeek(privep);
|
||||
|
||||
struct rp23xx_req_s *callback_req = NULL;
|
||||
|
||||
if (!privreq)
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_TXREQLOST), privep->epphy);
|
||||
|
|
@ -646,11 +638,42 @@ static void rp23xx_txcomplete(struct rp23xx_ep_s *privep)
|
|||
{
|
||||
usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
|
||||
privep->txnullpkt = 0;
|
||||
rp23xx_reqcomplete(privep, OK);
|
||||
callback_req = rp23xx_reqcomplete(privep, OK);
|
||||
}
|
||||
}
|
||||
|
||||
rp23xx_wrrequest(privep);
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
|
||||
rp23xx_callback(privep, callback_req);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rp23xx_callback
|
||||
*
|
||||
* Description:
|
||||
* Call req callback
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void rp23xx_callback(struct rp23xx_ep_s *privep,
|
||||
struct rp23xx_req_s *callback_req)
|
||||
{
|
||||
irqstate_t flags;
|
||||
|
||||
if (callback_req && callback_req->req.callback)
|
||||
{
|
||||
/* Pass protocol stall state to EP0 callbacks */
|
||||
|
||||
if (privep->epphy == 0)
|
||||
{
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
privep->stalled = privep->dev->stalled;
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
}
|
||||
|
||||
callback_req->req.callback(&privep->ep, &callback_req->req);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -677,22 +700,6 @@ static int rp23xx_wrrequest(struct rp23xx_ep_s *privep)
|
|||
return OK;
|
||||
}
|
||||
|
||||
/* Ignore any attempt to send a zero length packet on anything but EP0IN */
|
||||
|
||||
if (privreq->req.len == 0)
|
||||
{
|
||||
if (privep->epphy == 0)
|
||||
{
|
||||
rp23xx_epwrite(privep, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_NULLPACKET), 0);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* Get the number of bytes left to be sent in the packet */
|
||||
|
||||
bytesleft = privreq->req.len - privreq->req.xfrd;
|
||||
|
|
@ -702,7 +709,7 @@ static int rp23xx_wrrequest(struct rp23xx_ep_s *privep)
|
|||
*/
|
||||
|
||||
usbtrace(TRACE_WRITE(privep->epphy), (uint16_t)bytesleft);
|
||||
if (bytesleft > 0 || privep->txnullpkt)
|
||||
if (bytesleft > 0 || privep->txnullpkt || privreq->req.len == 0)
|
||||
{
|
||||
/* Try to send maxpacketsize -- unless we don't have that many
|
||||
* bytes to send.
|
||||
|
|
@ -743,29 +750,48 @@ static void rp23xx_rxcomplete(struct rp23xx_ep_s *privep)
|
|||
{
|
||||
struct rp23xx_req_s *privreq;
|
||||
uint16_t nrxbytes;
|
||||
uint16_t available;
|
||||
uint16_t copy_len;
|
||||
irqstate_t flags;
|
||||
struct rp23xx_req_s *callback_req = NULL;
|
||||
|
||||
nrxbytes = getreg32(privep->buf_ctrl)
|
||||
& RP23XX_USBCTRL_DPSRAM_EP_BUFF_CTRL_LEN_MASK;
|
||||
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
|
||||
privreq = rp23xx_rqpeek(privep);
|
||||
if (!privreq)
|
||||
{
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_RXREQLOST), privep->epphy);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(privreq->req.buf + privreq->req.xfrd, privep->data_buf, nrxbytes);
|
||||
available = privreq->req.len - privreq->req.xfrd;
|
||||
copy_len = MIN(nrxbytes, available);
|
||||
|
||||
privreq->req.xfrd += nrxbytes;
|
||||
memcpy(privreq->req.buf + privreq->req.xfrd, privep->data_buf, copy_len);
|
||||
privreq->req.xfrd += copy_len;
|
||||
|
||||
if (nrxbytes > available)
|
||||
{
|
||||
usbtrace(TRACE_DEVERROR(RP23XX_TRACEERR_EPREAD), privep->epphy);
|
||||
privreq->req.result = -EIO;
|
||||
}
|
||||
|
||||
if (privreq->req.xfrd >= privreq->req.len ||
|
||||
nrxbytes < privep->ep.maxpacket)
|
||||
{
|
||||
usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd);
|
||||
rp23xx_reqcomplete(privep, OK);
|
||||
callback_req =
|
||||
rp23xx_reqcomplete(privep, privreq->req.result == -EIO ? -EIO : OK);
|
||||
}
|
||||
|
||||
rp23xx_rdrequest(privep);
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
|
||||
rp23xx_callback(privep, callback_req);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -846,6 +872,35 @@ static void rp23xx_handle_zlp(struct rp23xx_usbdev_s *priv)
|
|||
priv->zlp_stat = RP23XX_ZLP_NONE;
|
||||
}
|
||||
|
||||
static void rp23xx_drain_queue(struct rp23xx_ep_s *privep,
|
||||
struct rp23xx_req_s **list_head)
|
||||
{
|
||||
struct rp23xx_req_s *privreq;
|
||||
struct rp23xx_req_s *tail = NULL;
|
||||
|
||||
while (!rp23xx_rqempty(privep))
|
||||
{
|
||||
usbtrace(TRACE_COMPLETE(privep->epphy),
|
||||
(rp23xx_rqpeek(privep))->req.xfrd);
|
||||
privreq = rp23xx_rqdequeue(privep);
|
||||
if (privreq)
|
||||
{
|
||||
privreq->req.result = -ESHUTDOWN;
|
||||
privreq->flink = NULL;
|
||||
if (!*list_head)
|
||||
{
|
||||
*list_head = privreq;
|
||||
}
|
||||
else
|
||||
{
|
||||
tail->flink = privreq;
|
||||
}
|
||||
|
||||
tail = privreq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: rp23xx_cancelrequests
|
||||
*
|
||||
|
|
@ -856,11 +911,23 @@ static void rp23xx_handle_zlp(struct rp23xx_usbdev_s *priv)
|
|||
|
||||
static void rp23xx_cancelrequests(struct rp23xx_ep_s *privep)
|
||||
{
|
||||
while (!rp23xx_rqempty(privep))
|
||||
struct rp23xx_req_s *local_list = NULL;
|
||||
struct rp23xx_req_s *next;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
rp23xx_drain_queue(privep, &local_list);
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
|
||||
while (local_list)
|
||||
{
|
||||
usbtrace(TRACE_COMPLETE(privep->epphy),
|
||||
(rp23xx_rqpeek(privep))->req.xfrd);
|
||||
rp23xx_reqcomplete(privep, -ESHUTDOWN);
|
||||
next = local_list->flink;
|
||||
if (local_list->req.callback)
|
||||
{
|
||||
local_list->req.callback(&privep->ep, &local_list->req);
|
||||
}
|
||||
|
||||
local_list = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1209,16 +1276,17 @@ static void rp23xx_usbintr_setup(struct rp23xx_usbdev_s *priv)
|
|||
|
||||
/* Read USB control request data */
|
||||
|
||||
UP_DMB();
|
||||
memcpy(&priv->ctrl, (void *)RP23XX_USBCTRL_DPSRAM_SETUP_PACKET,
|
||||
USB_SIZEOF_CTRLREQ);
|
||||
len = GETUINT16(priv->ctrl.len);
|
||||
|
||||
/* Reset PID and stall status in setup stage */
|
||||
|
||||
rp23xx_epstall(&priv->eplist[0].ep, true);
|
||||
rp23xx_epstall(&priv->eplist[1].ep, true);
|
||||
priv->eplist[0].next_pid = 1;
|
||||
priv->eplist[1].next_pid = 1;
|
||||
priv->eplist[0].stalled = false;
|
||||
priv->eplist[1].stalled = false;
|
||||
|
||||
/* ZLP type in status stage */
|
||||
|
||||
|
|
@ -1264,6 +1332,7 @@ static void rp23xx_usbintr_ep0out(struct rp23xx_usbdev_s *priv,
|
|||
return;
|
||||
}
|
||||
|
||||
UP_DMB();
|
||||
memcpy(priv->ep0data + priv->ep0datlen, privep->data_buf, len);
|
||||
priv->ep0datlen += len;
|
||||
|
||||
|
|
@ -1307,7 +1376,7 @@ static bool rp23xx_usbintr_buffstat(struct rp23xx_usbdev_s *priv)
|
|||
{
|
||||
if (stat & bit)
|
||||
{
|
||||
clrbits_reg32(bit, RP23XX_USBCTRL_REGS_BUFF_STATUS);
|
||||
putreg32(bit, RP23XX_USBCTRL_REGS_BUFF_STATUS);
|
||||
privep = &priv->eplist[RP23XX_DPTOEP(i)];
|
||||
|
||||
if (i == 1)
|
||||
|
|
@ -1382,7 +1451,7 @@ static void rp23xx_usbintr_busreset(struct rp23xx_usbdev_s *priv)
|
|||
CLASS_DISCONNECT(priv->driver, &priv->usbdev);
|
||||
}
|
||||
|
||||
clrbits_reg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
|
||||
putreg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
|
||||
RP23XX_USBCTRL_REGS_SIE_STATUS);
|
||||
}
|
||||
|
||||
|
|
@ -1411,7 +1480,7 @@ static int rp23xx_usbinterrupt(int irq, void *context, void *arg)
|
|||
|
||||
if (stat & RP23XX_USBCTRL_REGS_INTR_SETUP_REQ)
|
||||
{
|
||||
clrbits_reg32(RP23XX_USBCTRL_REGS_SIE_STATUS_SETUP_REC,
|
||||
putreg32(RP23XX_USBCTRL_REGS_SIE_STATUS_SETUP_REC,
|
||||
RP23XX_USBCTRL_REGS_SIE_STATUS);
|
||||
|
||||
rp23xx_usbintr_setup(priv);
|
||||
|
|
@ -1419,7 +1488,7 @@ static int rp23xx_usbinterrupt(int irq, void *context, void *arg)
|
|||
|
||||
if (stat & RP23XX_USBCTRL_REGS_INTR_BUS_RESET)
|
||||
{
|
||||
clrbits_reg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
|
||||
putreg32(RP23XX_USBCTRL_REGS_SIE_STATUS_BUS_RESET,
|
||||
RP23XX_USBCTRL_REGS_SIE_STATUS);
|
||||
|
||||
rp23xx_usbintr_busreset(priv);
|
||||
|
|
@ -1466,10 +1535,7 @@ static int rp23xx_epconfigure(struct usbdev_ep_s *ep,
|
|||
uinfo("config: EP%d %s %d maxpacket=%d\n", privep->epphy,
|
||||
privep->in ? "IN" : "OUT", eptype, maxpacket);
|
||||
|
||||
if (desc)
|
||||
{
|
||||
privep->ep.maxpacket = GETUINT16(desc->mxpacketsize);
|
||||
}
|
||||
privep->ep.maxpacket = GETUINT16(desc->mxpacketsize);
|
||||
|
||||
if (privep->epphy != 0)
|
||||
{
|
||||
|
|
@ -1477,10 +1543,14 @@ static int rp23xx_epconfigure(struct usbdev_ep_s *ep,
|
|||
* (No need for EP0 because it has the dedicated buffer)
|
||||
*/
|
||||
|
||||
privep->data_buf = (uint8_t *)(RP23XX_USBCTRL_DPSRAM_BASE +
|
||||
priv->next_offset);
|
||||
priv->next_offset =
|
||||
(priv->next_offset + privep->ep.maxpacket + 63) & ~63;
|
||||
if (privep->data_buf == NULL)
|
||||
{
|
||||
privep->data_buf = (uint8_t *)(RP23XX_USBCTRL_DPSRAM_BASE +
|
||||
priv->next_offset);
|
||||
priv->next_offset =
|
||||
(priv->next_offset +
|
||||
privep->ep.maxpacket + 63) & ~63;
|
||||
}
|
||||
|
||||
/* Enable EP */
|
||||
|
||||
|
|
@ -1506,6 +1576,8 @@ static int rp23xx_epconfigure(struct usbdev_ep_s *ep,
|
|||
static int rp23xx_epdisable(struct usbdev_ep_s *ep)
|
||||
{
|
||||
struct rp23xx_ep_s *privep = (struct rp23xx_ep_s *)ep;
|
||||
struct rp23xx_req_s *local_list = NULL;
|
||||
struct rp23xx_req_s *next;
|
||||
irqstate_t flags;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
|
|
@ -1519,18 +1591,28 @@ static int rp23xx_epdisable(struct usbdev_ep_s *ep)
|
|||
usbtrace(TRACE_EPDISABLE, privep->epphy);
|
||||
uinfo("EP%d\n", privep->epphy);
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
|
||||
privep->ep.maxpacket = 64;
|
||||
privep->ep.maxpacket = RP23XX_EP0MAXPACKET;
|
||||
privep->stalled = false;
|
||||
privep->next_pid = 0;
|
||||
putreg32(0, privep->buf_ctrl);
|
||||
|
||||
/* Cancel all queued requests */
|
||||
|
||||
rp23xx_cancelrequests(privep);
|
||||
rp23xx_drain_queue(privep, &local_list);
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
|
||||
leave_critical_section(flags);
|
||||
while (local_list)
|
||||
{
|
||||
next = local_list->flink;
|
||||
if (local_list->req.callback)
|
||||
{
|
||||
local_list->req.callback(&privep->ep, &local_list->req);
|
||||
}
|
||||
|
||||
local_list = next;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
|
@ -1623,12 +1705,13 @@ static int rp23xx_epsubmit(struct usbdev_ep_s *ep,
|
|||
req->result = -EINPROGRESS;
|
||||
req->xfrd = 0;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
|
||||
if (privep->stalled && privep->in)
|
||||
{
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
rp23xx_abortrequest(privep, privreq, -EBUSY);
|
||||
ret = -EBUSY;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* Handle IN (device-to-host) requests */
|
||||
|
|
@ -1668,7 +1751,7 @@ static int rp23xx_epsubmit(struct usbdev_ep_s *ep,
|
|||
}
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -1676,14 +1759,18 @@ static int rp23xx_epsubmit(struct usbdev_ep_s *ep,
|
|||
* Name: rp23xx_epcancel
|
||||
*
|
||||
* Description:
|
||||
* Cancel an I/O request previously sent to an endpoint
|
||||
* Cancel an I/O request previously sent to an endpoint
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int rp23xx_epcancel(struct usbdev_ep_s *ep,
|
||||
struct usbdev_req_s *req)
|
||||
static int rp23xx_epcancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
|
||||
{
|
||||
struct rp23xx_ep_s *privep = (struct rp23xx_ep_s *)ep;
|
||||
struct rp23xx_req_s *privreq = (struct rp23xx_req_s *)req;
|
||||
struct rp23xx_req_s *curr;
|
||||
struct rp23xx_req_s *prev = NULL;
|
||||
bool found = false;
|
||||
bool is_head = false;
|
||||
irqstate_t flags;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FEATURES
|
||||
|
|
@ -1696,12 +1783,64 @@ static int rp23xx_epcancel(struct usbdev_ep_s *ep,
|
|||
|
||||
usbtrace(TRACE_EPCANCEL, privep->epphy);
|
||||
|
||||
/* Remove request from req_queue */
|
||||
flags = spin_lock_irqsave(&g_usbdev.lock);
|
||||
|
||||
flags = enter_critical_section();
|
||||
rp23xx_cancelrequests(privep);
|
||||
leave_critical_section(flags);
|
||||
return OK;
|
||||
for (curr = privep->head; curr != NULL; prev = curr, curr = curr->flink)
|
||||
{
|
||||
if (curr == privreq)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (curr == privep->head)
|
||||
{
|
||||
is_head = true;
|
||||
|
||||
putreg32(0, privep->buf_ctrl);
|
||||
|
||||
privep->head = curr->flink;
|
||||
if (!privep->head)
|
||||
{
|
||||
privep->tail = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
prev->flink = curr->flink;
|
||||
if (privep->tail == curr)
|
||||
{
|
||||
privep->tail = prev;
|
||||
}
|
||||
}
|
||||
|
||||
curr->flink = NULL;
|
||||
curr->req.result = -ECANCELED;
|
||||
|
||||
if (is_head && privep->head != NULL)
|
||||
{
|
||||
if (privep->in)
|
||||
{
|
||||
rp23xx_wrrequest(privep);
|
||||
}
|
||||
else
|
||||
{
|
||||
rp23xx_rdrequest(privep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&g_usbdev.lock, flags);
|
||||
|
||||
if (found && privreq->req.callback)
|
||||
{
|
||||
privreq->req.callback(&privep->ep, &privreq->req);
|
||||
}
|
||||
|
||||
return found ? OK : -ENOENT;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
@ -1985,7 +2124,7 @@ static int rp23xx_pullup(struct usbdev_s *dev, bool enable)
|
|||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: riscv_usbinitialize
|
||||
* Name: rp23xx_usbinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the USB driver
|
||||
|
|
@ -2020,7 +2159,7 @@ void rp23xx_usbinitialize(void)
|
|||
for (i = 0; i < RP23XX_NENDPOINTS; i++)
|
||||
{
|
||||
g_usbdev.eplist[i].ep.ops = &g_epops;
|
||||
g_usbdev.eplist[i].ep.maxpacket = 64;
|
||||
g_usbdev.eplist[i].ep.maxpacket = RP23XX_EP0MAXPACKET;
|
||||
g_usbdev.eplist[i].dev = &g_usbdev;
|
||||
g_usbdev.eplist[i].epphy = 0;
|
||||
g_usbdev.eplist[i].head = NULL;
|
||||
|
|
@ -2075,13 +2214,29 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
|
|||
|
||||
memset((void *)RP23XX_USBCTRL_DPSRAM_BASE, 0, 0x1000);
|
||||
|
||||
putreg32(RP23XX_USBCTRL_REGS_USB_MUXING_SOFTCON |
|
||||
/* Enable interrupt */
|
||||
|
||||
up_enable_irq(RP23XX_USBCTRL_IRQ);
|
||||
|
||||
setbits_reg32(RP23XX_USBCTRL_REGS_USB_MUXING_SOFTCON |
|
||||
RP23XX_USBCTRL_REGS_USB_MUXING_TO_PHY,
|
||||
RP23XX_USBCTRL_REGS_USB_MUXING);
|
||||
putreg32(RP23XX_USBCTRL_REGS_USB_PWR_VBUS_DETECT |
|
||||
|
||||
setbits_reg32(RP23XX_USBCTRL_REGS_USB_PWR_VBUS_DETECT |
|
||||
RP23XX_USBCTRL_REGS_USB_PWR_VBUS_DETECT_OVERRIDE_EN,
|
||||
RP23XX_USBCTRL_REGS_USB_PWR);
|
||||
|
||||
setbits_reg32(RP23XX_USBCTRL_REGS_MAIN_CTRL_CONTROLLER_EN,
|
||||
RP23XX_USBCTRL_REGS_MAIN_CTRL);
|
||||
|
||||
setbits_reg32(RP23XX_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
|
||||
RP23XX_USBCTRL_REGS_SIE_CTRL);
|
||||
|
||||
setbits_reg32(RP23XX_USBCTRL_REGS_INTR_BUFF_STATUS |
|
||||
RP23XX_USBCTRL_REGS_INTR_BUS_RESET |
|
||||
RP23XX_USBCTRL_REGS_INTR_SETUP_REQ,
|
||||
RP23XX_USBCTRL_REGS_INTE);
|
||||
|
||||
rp23xx_allocep(&g_usbdev.usbdev, 0x00, 0, USB_EP_ATTR_XFER_CONTROL);
|
||||
rp23xx_allocep(&g_usbdev.usbdev, 0x80, 1, USB_EP_ATTR_XFER_CONTROL);
|
||||
|
||||
|
|
@ -2100,20 +2255,6 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
|
|||
modifyreg32(RP23XX_USBCTRL_REGS_MAIN_CTRL,
|
||||
RP23XX_USBCTRL_REGS_MAIN_CTRL_PHY_ISO, 0);
|
||||
|
||||
putreg32(RP23XX_USBCTRL_REGS_MAIN_CTRL_CONTROLLER_EN,
|
||||
RP23XX_USBCTRL_REGS_MAIN_CTRL);
|
||||
|
||||
/* Enable interrupt */
|
||||
|
||||
putreg32(RP23XX_USBCTRL_REGS_SIE_CTRL_EP0_INT_1BUF,
|
||||
RP23XX_USBCTRL_REGS_SIE_CTRL);
|
||||
putreg32(RP23XX_USBCTRL_REGS_INTR_BUFF_STATUS |
|
||||
RP23XX_USBCTRL_REGS_INTR_BUS_RESET |
|
||||
RP23XX_USBCTRL_REGS_INTR_SETUP_REQ,
|
||||
RP23XX_USBCTRL_REGS_INTE);
|
||||
|
||||
up_enable_irq(RP23XX_USBCTRL_IRQ);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
#
|
||||
# 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_ARGCAT is not set
|
||||
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
|
||||
# CONFIG_NSH_DISABLE_DATE is not set
|
||||
# CONFIG_NSH_DISABLE_LOSMART is not set
|
||||
# CONFIG_STANDARD_SERIAL is not set
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_BOARD="raspberrypi-pico-2-rv"
|
||||
CONFIG_ARCH_BOARD_COMMON=y
|
||||
CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
|
||||
CONFIG_ARCH_CHIP="rp23xx-rv"
|
||||
CONFIG_ARCH_CHIP_RP23XX_RV=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=4096
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=15000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE=4096
|
||||
CONFIG_DISABLE_POSIX_TIMERS=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=4096
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_RAM_SIZE=532480
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_RISCV_TOOLCHAIN_GNU_RV32=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SMP_NCPUS=2
|
||||
CONFIG_START_DAY=9
|
||||
CONFIG_START_MONTH=2
|
||||
CONFIG_START_YEAR=2021
|
||||
CONFIG_SYSLOG_CONSOLE=y
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_UART0_SERIAL_CONSOLE=y
|
||||
|
|
@ -17,20 +17,19 @@ CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
|
|||
CONFIG_ARCH_CHIP="rp23xx-rv"
|
||||
CONFIG_ARCH_CHIP_RP23XX_RV=y
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb"
|
||||
CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=15000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE=4096
|
||||
CONFIG_DISABLE_POSIX_TIMERS=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_IDLETHREAD_STACKSIZE=4096
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INIT_STACKSIZE=4096
|
||||
CONFIG_IRQ_WORK_STACKSIZE=4096
|
||||
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
#
|
||||
# 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_DEV_CONSOLE is not set
|
||||
# CONFIG_NSH_ARGCAT is not set
|
||||
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
|
||||
# CONFIG_NSH_DISABLE_DATE is not set
|
||||
# CONFIG_NSH_DISABLE_LOSMART is not set
|
||||
# CONFIG_RP23XX_RV_UART0 is not set
|
||||
CONFIG_ARCH="risc-v"
|
||||
CONFIG_ARCH_BOARD="raspberrypi-pico-2-rv"
|
||||
CONFIG_ARCH_BOARD_COMMON=y
|
||||
CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
|
||||
CONFIG_ARCH_CHIP="rp23xx-rv"
|
||||
CONFIG_ARCH_CHIP_RP23XX_RV=y
|
||||
CONFIG_ARCH_INTERRUPTSTACK=4096
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=15000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_CDCACM=y
|
||||
CONFIG_CDCACM_CONSOLE=y
|
||||
CONFIG_CDCACM_DISABLE_RXBUF=y
|
||||
CONFIG_CDCACM_DISABLE_TXBUF=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE=4096
|
||||
CONFIG_DISABLE_POSIX_TIMERS=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=4096
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_NSH_USBCONSOLE=y
|
||||
CONFIG_RAM_SIZE=532480
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_READLINE_CMD_HISTORY=y
|
||||
CONFIG_RISCV_TOOLCHAIN_GNU_RV32=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_SMP=y
|
||||
CONFIG_SMP_NCPUS=2
|
||||
CONFIG_START_DAY=9
|
||||
CONFIG_START_MONTH=2
|
||||
CONFIG_START_YEAR=2021
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_TESTING_GETPRIME=y
|
||||
CONFIG_TESTING_OSTEST=y
|
||||
CONFIG_USBDEV=y
|
||||
CONFIG_USBDEV_BUSPOWERED=y
|
||||
|
|
@ -18,21 +18,23 @@ CONFIG_ARCH_BOARD_RASPBERRYPI_PICO_2_RV=y
|
|||
CONFIG_ARCH_CHIP="rp23xx-rv"
|
||||
CONFIG_ARCH_CHIP_RP23XX_RV=y
|
||||
CONFIG_ARCH_RISCV=y
|
||||
CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb"
|
||||
CONFIG_ARCH_RV_ISA_VENDOR_EXTENSIONS="zba_zbb_zbs_zbkb_zcb_zcmp"
|
||||
CONFIG_BOARDCTL_RESET=y
|
||||
CONFIG_BOARD_LOOPSPERMSEC=15000
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_CDCACM=y
|
||||
CONFIG_CDCACM_CONSOLE=y
|
||||
CONFIG_CDCACM_DISABLE_RXBUF=y
|
||||
CONFIG_CDCACM_DISABLE_TXBUF=y
|
||||
CONFIG_DEBUG_FULLOPT=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEFAULT_TASK_STACKSIZE=4096
|
||||
CONFIG_DISABLE_POSIX_TIMERS=y
|
||||
CONFIG_EXAMPLES_HELLO=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_IDLETHREAD_STACKSIZE=2048
|
||||
CONFIG_IDLETHREAD_STACKSIZE=4096
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INIT_STACKSIZE=4096
|
||||
CONFIG_IRQ_WORK_STACKSIZE=4096
|
||||
CONFIG_NFILE_DESCRIPTORS_PER_BLOCK=6
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_READLINE=y
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue