From 92cf55e8394678b98d46e2bc964c7793f190909f Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 25 Feb 2013 18:36:25 +0000 Subject: More Cortex-M0/NUC120 fixes git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5670 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/arm/src/armv6-m/exc_return.h | 26 ++++--------------- nuttx/arch/arm/src/armv6-m/up_exception.S | 15 +++++------ nuttx/arch/arm/src/armv6-m/up_initialstate.c | 24 +++++++++-------- nuttx/arch/arm/src/armv7-m/up_initialstate.c | 2 +- nuttx/arch/arm/src/nuc1xx/nuc_lowputc.c | 39 ++++++++++++++++++++++++++-- nuttx/arch/arm/src/nuc1xx/nuc_serial.c | 6 ++--- 6 files changed, 66 insertions(+), 46 deletions(-) (limited to 'nuttx/arch/arm') diff --git a/nuttx/arch/arm/src/armv6-m/exc_return.h b/nuttx/arch/arm/src/armv6-m/exc_return.h index e779df505..4a7829428 100644 --- a/nuttx/arch/arm/src/armv6-m/exc_return.h +++ b/nuttx/arch/arm/src/armv6-m/exc_return.h @@ -50,18 +50,18 @@ * exception mechanism relies on this value to detect when the processor has * completed an exception handler. * - * Bits [31:28] of an EXC_RETURN value are always 1. When the processor loads a + * Bits [31:4] of an EXC_RETURN value are always 1. When the processor loads a * value matching this pattern to the PC it detects that the operation is a not * a normal branch operation and instead, that the exception is complete. * Therefore, it starts the exception return sequence. * - * Bits[4:0] of the EXC_RETURN value indicate the required return stack and eventual + * Bits[3:0] of the EXC_RETURN value indicate the required return stack and eventual * processor mode. The remaining bits of the EXC_RETURN value should be set to 1. */ /* EXC_RETURN_BASE: Bits that are always set in an EXC_RETURN value. */ -#define EXC_RETURN_BASE 0xffffffe1 +#define EXC_RETURN_BASE 0xfffffff1 /* EXC_RETURN_PROCESS_STACK: The exception saved (and will restore) the hardware * context using the process stack pointer (if not set, the context was saved @@ -72,20 +72,12 @@ #define EXC_RETURN_PROCESS_STACK (1 << EXC_RETURN_PROCESS_BITNO) /* EXC_RETURN_THREAD_MODE: The exception will return to thread mode (if not set, - * return stays in handler mode) + * return stays in handler mode). */ #define EXC_RETURN_THREAD_BITNO (3) #define EXC_RETURN_THREAD_MODE (1 << EXC_RETURN_THREAD_BITNO) -/* EXC_RETURN_STD_CONTEXT: The state saved on the stack does not include the - * volatile FP registers and FPSCR. If this bit is clear, the state does include - * these registers. - */ - -#define EXC_RETURN_STD_BITNO (4) -#define EXC_RETURN_STD_CONTEXT (1 << EXC_RETURN_STD_BITNO) - /* EXC_RETURN_HANDLER: Return to handler mode. Exception return gets state from * the main stack. Execution uses MSP after return. */ @@ -104,15 +96,7 @@ #define EXC_RETURN_UNPRIVTHR 0xfffffffd -/* In the kernel build is not selected, then all threads run in privileged thread - * mode. - */ - -#ifdef CONFIG_NUTTX_KERNEL -# define EXC_RETURN 0xfffffff9 -#endif - -/************************Th************************************************************ +/************************************************************************************ * Inline Functions ************************************************************************************/ diff --git a/nuttx/arch/arm/src/armv6-m/up_exception.S b/nuttx/arch/arm/src/armv6-m/up_exception.S index 33f89b3b1..6a74d4dd6 100644 --- a/nuttx/arch/arm/src/armv6-m/up_exception.S +++ b/nuttx/arch/arm/src/armv6-m/up_exception.S @@ -93,7 +93,7 @@ exception_common: */ mov r0, r14 /* Copy high register to low register */ - lsl r1, r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */ + lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */ bmi 1f /* Test bit 31 */ mrs r1, msp /* R1=The main stack pointer */ b 2f @@ -191,7 +191,7 @@ exception_common: /* Recover R8-R11 and EXEC_RETURN (5 registers) */ mov r2, #(4*REG_R8) /* R2=Offset to R8 storage */ - sub r0, r1, r2 /* R0=Address of R8 storage */ + add r0, r1, r2 /* R0=Address of R8 storage */ ldmia r0!, {r2-r6} /* Recover R8-R11 and R14 (5 registers)*/ mov r8, r2 /* Move to position in high registers */ mov r9, r3 @@ -199,21 +199,20 @@ exception_common: mov r11, r5 mov r14, r6 /* EXEC_RETURN */ - /* Recover SP (R2), BASEPRI (R3), and R4-R7. The size of the sofware saved - * portion is 11 words. 5 were recovered above; 6 are recovered by the - * ldmia below. So adding (4*5) to r1 accounts for all of the software - * saved registers. + /* Recover SP (R2), BASEPRI (R3), and R4-R7. Determine the value of + * the stack pointer as it was on entry to the exception handler. */ ldmia r1!, {r2-r7} /* Recover R4-R7 + 2 temp values */ - add r1, #(4*5) /* R1=Value of MSP/PSP on exception entry */ + mov r1, #HW_XCPT_SIZE /* R1=Size of hardware-saved portion of the context array */ + sub r1, r2, r1 /* R1=Value of MSP/PSP on exception entry */ /* Restore the stack pointer. The EXC_RETURN value tells us whether the * context is on the MSP or PSP. */ mov r0, r14 /* Copy high register to low register */ - lsl r1, r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */ + lsl r0, #(31 - EXC_RETURN_PROCESS_BITNO) /* Move to bit 31 */ bmi 5f /* Test bit 31 */ msr msp, r1 /* R1=The main stack pointer */ b 6f diff --git a/nuttx/arch/arm/src/armv6-m/up_initialstate.c b/nuttx/arch/arm/src/armv6-m/up_initialstate.c index 8e5c37e40..ccb924ebe 100644 --- a/nuttx/arch/arm/src/armv6-m/up_initialstate.c +++ b/nuttx/arch/arm/src/armv6-m/up_initialstate.c @@ -115,10 +115,10 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_PIC] = (uint32_t)tcb->dspace->region; } - /* Make certain that bit 0 is set in the main entry address. This - * is only an issue when NXFLAT is enabled. NXFLAT doesn't know - * anything about thumb; the addresses that NXFLAT sets are based - * on file header info and won't have bit 0 set. + /* Make certain that bit 0 is set in the main entry address. This is + * only an issue when NXFLAT is enabled. NXFLAT doesn't know anything + * about thumb; the addresses that NXFLAT sets are based on file header + * info and won't have bit 0 set. */ #ifdef CONFIG_NXFLAT @@ -128,22 +128,24 @@ void up_initial_state(struct tcb_s *tcb) /* Set privileged- or unprivileged-mode, depending on how NuttX is * configured and what kind of thread is being started. - * - * If the kernel build is not selected, then all threads run in - * privileged thread mode. */ - xcp->regs[REG_EXC_RETURN] = EXC_RETURN_BASE | EXC_RETURN_THREAD_MODE; - xcp->regs[REG_EXC_RETURN] |= EXC_RETURN_STD_CONTEXT; - #ifdef CONFIG_NUTTX_KERNEL if ((tcb->flags & TCB_FLAG_TTYPE_MASK) != TCB_FLAG_TTYPE_KERNEL) { /* It is a normal task or a pthread. Set user mode */ - xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PROCESS_STACK; + xcp->regs[REG_EXC_RETURN] = EXC_RETURN_UNPRIVTHR; } + else #endif /* CONFIG_NUTTX_KERNEL */ + { + /* If the kernel build is not selected -OR- if this is a kernel + * thread, then start it in privileged thread mode. + */ + + xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PRIVTHR; + } /* Enable or disable interrupts, based on user configuration */ diff --git a/nuttx/arch/arm/src/armv7-m/up_initialstate.c b/nuttx/arch/arm/src/armv7-m/up_initialstate.c index ee523a016..6f9abcd31 100644 --- a/nuttx/arch/arm/src/armv7-m/up_initialstate.c +++ b/nuttx/arch/arm/src/armv7-m/up_initialstate.c @@ -155,7 +155,7 @@ void up_initial_state(struct tcb_s *tcb) { /* It is a normal task or a pthread. Set user mode */ - xcp->regs[REG_EXC_RETURN] = EXC_RETURN_PROCESS_STACK; + xcp->regs[REG_EXC_RETURN] |= EXC_RETURN_PROCESS_STACK; } #endif /* CONFIG_NUTTX_KERNEL */ diff --git a/nuttx/arch/arm/src/nuc1xx/nuc_lowputc.c b/nuttx/arch/arm/src/nuc1xx/nuc_lowputc.c index ec0c192d2..0855594fe 100644 --- a/nuttx/arch/arm/src/nuc1xx/nuc_lowputc.c +++ b/nuttx/arch/arm/src/nuc1xx/nuc_lowputc.c @@ -63,18 +63,21 @@ #ifdef HAVE_SERIAL_CONSOLE # if defined(CONFIG_UART0_SERIAL_CONSOLE) # define NUC_CONSOLE_BASE NUC_UART0_BASE +# define NUC_CONSOLE_DEPTH UART0_FIFO_DEPTH # define NUC_CONSOLE_BAUD CONFIG_UART0_BAUD # define NUC_CONSOLE_BITS CONFIG_UART0_BITS # define NUC_CONSOLE_PARITY CONFIG_UART0_PARITY # define NUC_CONSOLE_2STOP CONFIG_UART0_2STOP # elif defined(CONFIG_UART1_SERIAL_CONSOLE) # define NUC_CONSOLE_BASE NUC_UART1_BASE +# define NUC_CONSOLE_DEPTH UART1_FIFO_DEPTH # define NUC_CONSOLE_BAUD CONFIG_UART1_BAUD # define NUC_CONSOLE_BITS CONFIG_UART1_BITS # define NUC_CONSOLE_PARITY CONFIG_UART1_PARITY # define NUC_CONSOLE_2STOP CONFIG_UART1_2STOP # elif defined(CONFIG_UART2_SERIAL_CONSOLE) # define NUC_CONSOLE_BASE NUC_UART2_BASE +# define NUC_CONSOLE_DEPTH UART2_FIFO_DEPTH # define NUC_CONSOLE_BAUD CONFIG_UART2_BAUD # define NUC_CONSOLE_BITS CONFIG_UART2_BITS # define NUC_CONSOLE_PARITY CONFIG_UART2_PARITY @@ -97,6 +100,38 @@ /**************************************************************************** * Private Functions ****************************************************************************/ + +/**************************************************************************** + * Name: nuc_console_ready + * + * Description: + * Wait until the console is ready to add another character to the TX + * FIFO. + * + *****************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +static inline void nuc_console_ready(void) +{ +#if 1 + /* Wait for the TX FIFO to be empty (excessive!) */ + + while ((getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET) & UART_FSR_TX_EMPTY) == 0); +#else + uint32_t depth; + + /* Wait until there is space in the TX FIFO */ + + do + { + register uint32_t regval = getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET); + depth = (regval & UART_FSR_TX_POINTER_MASK) >> UART_FSR_TX_POINTER_SHIFT; + } + while (depth >= (NUC_CONSOLE_DEPTH-1)); +#endif +} +#endif /* HAVE_SERIAL_CONSOLE */ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -293,9 +328,9 @@ void nuc_lowsetup(void) void nuc_lowputc(uint32_t ch) { #ifdef HAVE_SERIAL_CONSOLE - /* Wait for the TX FIFO to be empty (excessive!) */ + /* Wait for the TX FIFO to become available */ - while ((getreg32(NUC_CONSOLE_BASE + NUC_UART_FSR_OFFSET) & UART_FSR_TX_EMPTY) == 0); + nuc_console_ready(); /* Then write the character to to the TX FIFO */ diff --git a/nuttx/arch/arm/src/nuc1xx/nuc_serial.c b/nuttx/arch/arm/src/nuc1xx/nuc_serial.c index 060d274ef..6f095826c 100644 --- a/nuttx/arch/arm/src/nuc1xx/nuc_serial.c +++ b/nuttx/arch/arm/src/nuc1xx/nuc_serial.c @@ -159,7 +159,7 @@ static struct nuc_dev_s g_uart0priv = .irq = NUC_IRQ_UART0, .parity = CONFIG_UART0_PARITY, .bits = CONFIG_UART0_BITS, - .depth = UART0_FIFO_DEPTH, + .depth = (UART0_FIFO_DEPTH-1), .stopbits2 = CONFIG_UART0_2STOP, }; @@ -190,7 +190,7 @@ static struct nuc_dev_s g_uart1priv = .irq = NUC_IRQ_UART1, .parity = CONFIG_UART1_PARITY, .bits = CONFIG_UART1_BITS, - .depth = UART1_FIFO_DEPTH, + .depth = (UART1_FIFO_DEPTH-1), .stopbits2 = CONFIG_UART1_2STOP, }; @@ -221,7 +221,7 @@ static struct nuc_dev_s g_uart2priv = .irq = NUC_IRQ_UART2, .parity = CONFIG_UART2_PARITY, .bits = CONFIG_UART2_BITS, - .depth = UART2_FIFO_DEPTH, + .depth = (UART2_FIFO_DEPTH-1), .stopbits2 = CONFIG_UART2_2STOP, }; -- cgit v1.2.3