diff --git a/arch/mips/src/pic32mz/Make.defs b/arch/mips/src/pic32mz/Make.defs index b893fdfd2f..f15b7b0627 100644 --- a/arch/mips/src/pic32mz/Make.defs +++ b/arch/mips/src/pic32mz/Make.defs @@ -65,6 +65,6 @@ endif CHIP_ASRCS = CHIP_CSRCS = pic32mz-lowinit.c pic32mz-exception.c pic32mz-decodeirq.c -CHIP_CSRCS += pic32mz-irq.c pic32mz-timerisr.c +CHIP_CSRCS += pic32mz-irq.c pic32mz-timerisr.c pic32mz-lowconsole.c # Configuration-dependent PIC32MZ files diff --git a/arch/mips/src/pic32mz/chip/pic32mz-timer.h b/arch/mips/src/pic32mz/chip/pic32mz-timer.h index 9545e17fbf..4cc12eacf0 100644 --- a/arch/mips/src/pic32mz/chip/pic32mz-timer.h +++ b/arch/mips/src/pic32mz/chip/pic32mz-timer.h @@ -52,7 +52,7 @@ ************************************************************************************/ /* Timer Peripheral Offsets *********************************************************/ -#define PIC32MZ_TIMER_OFFSET(n) ((n) << 9) +#define PIC32MZ_TIMERn_OFFSET(n) ((n) << 9) # define PIC32MZ_TIMER1_OFFSET 0x0000 # define PIC32MZ_TIMER2_OFFSET 0x0200 # define PIC32MZ_TIMER3_OFFSET 0x0400 @@ -82,16 +82,16 @@ /* Timer Peripheral Addresses *******************************************************/ -#define PIC32MZ_TIMERn_K1BASE(n) (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER_OFFSET(n)) -#define PIC32MZ_TIMER1_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER1_OFFSET) -#define PIC32MZ_TIMER2_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER2_OFFSET) -#define PIC32MZ_TIMER3_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER3_OFFSET) -#define PIC32MZ_TIMER4_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER4_OFFSET) -#define PIC32MZ_TIMER5_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER5_OFFSET) -#define PIC32MZ_TIMER6_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER6_OFFSET) -#define PIC32MZ_TIMER7_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER7_OFFSET) -#define PIC32MZ_TIMER8_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER8_OFFSET) -#define PIC32MZ_TIMER9_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER9_OFFSET) +#define PIC32MZ_TIMERn_K1BASE(n) (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMERn_OFFSET(n)) +# define PIC32MZ_TIMER1_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER1_OFFSET) +# define PIC32MZ_TIMER2_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER2_OFFSET) +# define PIC32MZ_TIMER3_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER3_OFFSET) +# define PIC32MZ_TIMER4_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER4_OFFSET) +# define PIC32MZ_TIMER5_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER5_OFFSET) +# define PIC32MZ_TIMER6_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER6_OFFSET) +# define PIC32MZ_TIMER7_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER7_OFFSET) +# define PIC32MZ_TIMER8_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER8_OFFSET) +# define PIC32MZ_TIMER9_K1BASE (PIC32MZ_TIMER_K1BASE+PIC32MZ_TIMER9_OFFSET) /* Register Addresses ***************************************************************/ diff --git a/arch/mips/src/pic32mz/chip/pic32mz-uart.h b/arch/mips/src/pic32mz/chip/pic32mz-uart.h index 9b3dc3286b..37affc2b89 100644 --- a/arch/mips/src/pic32mz/chip/pic32mz-uart.h +++ b/arch/mips/src/pic32mz/chip/pic32mz-uart.h @@ -1,5 +1,5 @@ /************************************************************************************ - * arch/mips/src/pic32mx/pic32mx-uart.h + * arch/mips/src/pic42mz/pic42mz-uart.h * * Copyright (C) 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -43,11 +43,21 @@ #include #include -#include "pic32mx-memorymap.h" +#include "chip/pic32mz-memorymap.h" /************************************************************************************ * Pre-processor Definitions ************************************************************************************/ +/* UART Peripheral Offsets **********************************************************/ + +#define PIC32MZ_UARTn_OFFSET(n) ((n) << 9) +# define PIC32MZ_UART1_OFFSET 0x0000 +# define PIC32MZ_UART2_OFFSET 0x0200 +# define PIC32MZ_UART3_OFFSET 0x0400 +# define PIC32MZ_UART4_OFFSET 0x0600 +# define PIC32MZ_UART5_OFFSET 0x0800 +# define PIC32MZ_UART6_OFFSET 0x0a00 + /* Register Offsets *****************************************************************/ #define PIC32MZ_UART_MODE_OFFSET 0x0000 /* UARTx mode register */ @@ -68,6 +78,19 @@ #define PIC32MZ_UART_BRGSET_OFFSET 0x0048 /* UARTx baud rate set register */ #define PIC32MZ_UART_BRGINV_OFFSET 0x004c /* UARTx baud rate invert register */ +/* Timer Peripheral Addresses *******************************************************/ + +#define PIC32MZ_UARTn_K1BASE(n) (PIC32MZ_UART_K1BASE+PIC32MZ_UARTn_OFFSET(n)) +# define PIC32MZ_UART1_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART1_OFFSET) +# define PIC32MZ_UART2_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART2_OFFSET) +# define PIC32MZ_UART3_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART3_OFFSET) +# define PIC32MZ_UART4_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART4_OFFSET) +# define PIC32MZ_UART5_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART5_OFFSET) +# define PIC32MZ_UART6_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART6_OFFSET) +# define PIC32MZ_UART7_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART7_OFFSET) +# define PIC32MZ_UART8_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART8_OFFSET) +# define PIC32MZ_UART9_K1BASE (PIC32MZ_UART_K1BASE+PIC32MZ_UART9_OFFSET) + /* Register Addresses ****************************************************************/ #if CHIP_NUARTS > 0 @@ -209,9 +232,9 @@ #define UART_STA_ADDEN (1 << 5) /* Bit 5: Address character detect */ #define UART_STA_URXISEL_SHIFT (6) /* Bits: 6-7: Receive interrupt mode selection */ #define UART_STA_URXISEL_MASK (3 << UART_STA_URXISEL_SHIFT) -#define UART_STA_URXISEL_RECVD (0 << UART_STA_URXISEL_SHIFT) /* Character received */ -#define UART_STA_URXISEL_RXB50 (1 << UART_STA_URXISEL_SHIFT) /* RX buffer 1/2 full */ -#define UART_STA_URXISEL_RXB75 (2 << UART_STA_URXISEL_SHIFT) /* RX buffer 3/4 full */ +# define UART_STA_URXISEL_RECVD (0 << UART_STA_URXISEL_SHIFT) /* Character received */ +# define UART_STA_URXISEL_RXB50 (1 << UART_STA_URXISEL_SHIFT) /* RX buffer 1/2 full */ +# define UART_STA_URXISEL_RXB75 (2 << UART_STA_URXISEL_SHIFT) /* RX buffer 3/4 full */ #define UART_STA_UTRMT (1 << 8) /* Bit 8: Transmit shift register is empty */ #define UART_STA_UTXBF (1 << 9) /* Bit 9: Transmit buffer full status */ #define UART_STA_UTXEN (1 << 10) /* Bit 10: Transmit enable */ diff --git a/arch/mips/src/pic32mz/pic32mz-lowconsole.c b/arch/mips/src/pic32mz/pic32mz-lowconsole.c new file mode 100644 index 0000000000..2cd91de6ba --- /dev/null +++ b/arch/mips/src/pic32mz/pic32mz-lowconsole.c @@ -0,0 +1,352 @@ +/****************************************************************************** + * arch/mips/src/pic32mz/pic32mz-lowconsole.c + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * 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 + +#include +#include + +#include +#include + +#include "up_arch.h" +#include "up_internal.h" + +#include "pic32mz-config.h" +#include "chip/pic32mz-uart.h" + +/****************************************************************************** + * Pre-processor Definitions + ******************************************************************************/ + +/* Select UART parameters for the selected console */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART1_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART1_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART1_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART1_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART1_2STOP +# elif defined(CONFIG_UART2_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART2_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART2_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART2_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART2_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART2_2STOP +# elif defined(CONFIG_UART3_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART3_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART3_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART3_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART3_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART3_2STOP +# elif defined(CONFIG_UART4_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART4_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART4_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART4_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART4_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART4_2STOP +# elif defined(CONFIG_UART5_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART5_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART5_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART5_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART5_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART5_2STOP +# elif defined(CONFIG_UART6_SERIAL_CONSOLE) +# define PIC32MZ_CONSOLE_BASE PIC32MZ_UART6_K1BASE +# define PIC32MZ_CONSOLE_BAUD CONFIG_UART6_BAUD +# define PIC32MZ_CONSOLE_BITS CONFIG_UART6_BITS +# define PIC32MZ_CONSOLE_PARITY CONFIG_UART6_PARITY +# define PIC32MZ_CONSOLE_2STOP CONFIG_UART6_2STOP +# else +# error "No CONFIG_UARTn_SERIAL_CONSOLE Setting" +# endif +#endif + +/****************************************************************************** + * Private Types + ******************************************************************************/ + +/****************************************************************************** + * Private Function Prototypes + ******************************************************************************/ + +/****************************************************************************** + * Global Variables + ******************************************************************************/ + +/****************************************************************************** + * Private Variables + ******************************************************************************/ + +/****************************************************************************** + * Private Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: pic32mz_putreg + * + * Description: + * Write a value to a UART register + * + ******************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static inline void pic32mz_putreg(uintptr_t uart_base, unsigned int offset, + uint32_t value) +{ + putreg32(value, uart_base + offset); +} +#endif + +/****************************************************************************** + * Name: pic32mz_getreg + * + * Description: + * Get a value from a UART register + * + ******************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static inline uint32_t pic32mz_getreg(uintptr_t uart_base, + unsigned int offset) +{ + return getreg32(uart_base + offset); +} +#endif + +/****************************************************************************** + * Name: pic32mz_uartsetbaud + * + * Description: + * Configure the UART baud rate. + * + * With BRGH=0 + * BAUD = PBCLK2 / 16 / (BRG+1) + * BRG = PBCLK2 / 16 / BAUD - 1 + * With BRGH=1 + * BAUD = PBCLK2 / 4 / (BRG+1) + * BRG = PBCLK2 / 4 / BAUD - 1 + * + * + ******************************************************************************/ + +#ifdef HAVE_UART_DEVICE +static void pic32mz_uartsetbaud(uintptr_t uart_base, uint32_t baudrate) +{ + uint32_t tmp; + uint32_t brg; + unsigned int mode; + + /* We want the largest value of BRG divisor possible (for the best accuracy). + * Subject to BRG <= 65536. + */ + + tmp = BOARD_PBCLK2 / baudrate; + + /* Try BRGH=1 first. This will select the 4x divisor and will produce the + * larger BRG divisor, given all other things equal. + */ + + brg = (tmp + 2) >> 2; + mode = PIC32MZ_UART_MODESET_OFFSET; + + if (brg > 65536) + { + /* Nope, too big.. try BRGH=0 */ + + brg = (tmp + 8) >> 4; + mode = PIC32MZ_UART_MODECLR_OFFSET; + } + DEBUGASSERT(brg <= 65536); + + /* Set the BRG divisor */ + + pic32mz_putreg(uart_base, mode, UART_MODE_BRGH); + pic32mz_putreg(uart_base, PIC32MZ_UART_BRG_OFFSET, brg); +} +#endif + +/****************************************************************************** + * Public Functions + ******************************************************************************/ + +/****************************************************************************** + * Name: pic32mz_uartreset + * + * Description: + * Reset hardware and disable Rx and Tx. + * + ******************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mz_uartreset(uintptr_t uart_base) +{ + /* Doesn't reset the hardware... just shuts it down */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STACLR_OFFSET, + UART_STA_UTXEN | UART_STA_URXEN); + pic32mz_putreg(uart_base, PIC32MZ_UART_MODECLR_OFFSET, UART_MODE_ON); +} +#endif + +/****************************************************************************** + * Name: pic32mz_uartconfigure + * + * Description: + * Configure a UART as a RS-232 UART. + * + ******************************************************************************/ + +#ifdef HAVE_UART_DEVICE +void pic32mz_uartconfigure(uintptr_t uart_base, uint32_t baudrate, + unsigned int parity, unsigned int nbits, bool stop2) +{ + /* Clear mode and sta bits */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_MODECLR_OFFSET, + UART_MODE_STSEL | UART_MODE_PDSEL_MASK | UART_MODE_BRGH | + UART_MODE_RXINV | UART_MODE_WAKE | UART_MODE_LPBACK | + UART_MODE_UEN_MASK | UART_MODE_RTSMD | UART_MODE_IREN | + UART_MODE_SIDL | UART_MODE_ON); + + /* Configure the FIFOs: + * + * RX: Interrupt at 75% FIFO full (6 of 8 for 8-deep FIFO) + * TX: Interrupt on FIFO empty + * Invert transmit polarity. + * + * NOTE that there are not many options on trigger TX interrupts. The FIFO not + * full might generate better through-put but with a higher interrupt rate. FIFO + * empty should lower the interrupt rate but result in a burstier output. If + * you change this, please read the comment for acknowledging the interrupt in + * pic32mz-serial.c + */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STACLR_OFFSET, + UART_STA_UTXINV | UART_STA_UTXISEL_TXBE | UART_STA_URXISEL_RXB75); + + /* Configure the FIFO interrupts */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STASET_OFFSET, + UART_STA_UTXISEL_TXBNF | UART_STA_URXISEL_RECVD); + + /* Configure word size and parity */ + + if (nbits == 9) + { + DEBUGASSERT(parity == 0); + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_PDSEL_9NONE); + } + else + { + DEBUGASSERT(nbits == 8); + if (parity == 1) + { + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_PDSEL_8ODD); + } + else if (parity == 2) + { + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_PDSEL_8EVEN); + } + } + + /* Configure 1 or 2 stop bits */ + + if (stop2) + { + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_STSEL); + } + + /* Set the BRG divisor */ + + pic32mz_uartsetbaud(uart_base, baudrate); + + /* Enable the UART */ + + pic32mz_putreg(uart_base, PIC32MZ_UART_STASET_OFFSET, + UART_STA_UTXEN | UART_STA_URXEN); + pic32mz_putreg(uart_base, PIC32MZ_UART_MODESET_OFFSET, + UART_MODE_ON); +} +#endif + +/****************************************************************************** + * Name: pic32mz_consoleinit + * + * Description: + * Initialize a low-level console for debug output. This function is called + * very early in the initialization sequence to configure the serial console + * UART (only). + * + ******************************************************************************/ + +#ifdef HAVE_SERIAL_CONSOLE +void pic32mz_consoleinit(void) +{ + pic32mz_uartconfigure(PIC32MZ_CONSOLE_BASE, PIC32MZ_CONSOLE_BAUD, + PIC32MZ_CONSOLE_PARITY, PIC32MZ_CONSOLE_BITS, + PIC32MZ_CONSOLE_2STOP); +} +#endif + +/****************************************************************************** + * Name: up_lowputc + * + * Description: + * Output one byte on the serial console. + * + ******************************************************************************/ + +void up_lowputc(char ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Wait for the transmit buffer not full */ + + while ((pic32mz_getreg(PIC32MZ_CONSOLE_BASE, PIC32MZ_UART_STA_OFFSET) & UART_STA_UTXBF) != 0); + + /* Then write the character to the TX data register */ + + pic32mz_putreg(PIC32MZ_CONSOLE_BASE, PIC32MZ_UART_TXREG_OFFSET, (uint32_t)ch); +#endif +}