From 8708cddde16863c86d15b8781db40739d64ff4bb Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Thu, 16 Jun 2016 13:44:14 +0200 Subject: [PATCH 001/155] mmc1 copy + dcache --- arch/arm/src/stm32f7/Make.defs | 4 + arch/arm/src/stm32f7/chip/stm32_sdmmc.h | 52 + .../src/stm32f7/chip/stm32f74xx75xx_sdmmc.h | 268 ++ arch/arm/src/stm32f7/stm32_sdmmc.c | 2977 +++++++++++++++++ arch/arm/src/stm32f7/stm32_sdmmc.h | 129 + configs/stm32f746-ws/include/board.h | 42 + configs/stm32f746-ws/nsh/defconfig | 41 +- configs/stm32f746-ws/src/stm32_spi.c | 12 +- 8 files changed, 3507 insertions(+), 18 deletions(-) create mode 100644 arch/arm/src/stm32f7/chip/stm32_sdmmc.h create mode 100644 arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h create mode 100644 arch/arm/src/stm32f7/stm32_sdmmc.c create mode 100644 arch/arm/src/stm32f7/stm32_sdmmc.h diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs index 07aa380ebd..123c70ffc2 100644 --- a/arch/arm/src/stm32f7/Make.defs +++ b/arch/arm/src/stm32f7/Make.defs @@ -147,6 +147,10 @@ ifeq ($(CONFIG_STM32F7_SPI),y) CHIP_CSRCS += stm32_spi.c endif +ifeq ($(CONFIG_STM32F7_SDMMC1),y) +CHIP_CSRCS += stm32_sdmmc.c +endif + ifeq ($(CONFIG_STM32F7_TIM),y) CHIP_CSRCS += stm32_tim.c endif diff --git a/arch/arm/src/stm32f7/chip/stm32_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h new file mode 100644 index 0000000000..e04bdddc1e --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h @@ -0,0 +1,52 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/chip/stm32_i2c.h + * + * 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SDMMC_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SDMMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "chip.h" + +#if defined(CONFIG_STM32F7_STM32F74XX) || defined(CONFIG_STM32F7_STM32F75XX) +# include "stm32f74xx75xx_sdmmc.h" +#else +# error "Unsupported STM32 F7 part" +#endif + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_SDMMC_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h new file mode 100644 index 0000000000..e40990ec16 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h @@ -0,0 +1,268 @@ +/************************************************************************************ + * arch/arm/src/stm32/chip/stm32_sdio.h + * + * Copyright (C) 2009, 2011-2013 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +/* Register Offsets *****************************************************************/ + +#define STM32_SDMMC1_POWER_OFFSET 0x0000 /* SDIO power control register */ +#define STM32_SDMMC1_CLKCR_OFFSET 0x0004 /* SDI clock control register */ +#define STM32_SDMMC1_ARG_OFFSET 0x0008 /* SDIO argument register */ +#define STM32_SDMMC1_CMD_OFFSET 0x000c /* SDIO command register */ +#define STM32_SDMMC1_RESPCMD_OFFSET 0x0010 /* SDIO command response register */ +#define STM32_SDMMC1_RESP_OFFSET(n) (0x0010+4*(n)) +#define STM32_SDMMC1_RESP1_OFFSET 0x0014 /* SDIO response 1 register */ +#define STM32_SDMMC1_RESP2_OFFSET 0x0018 /* SDIO response 2 register */ +#define STM32_SDMMC1_RESP3_OFFSET 0x001c /* SDIO response 3 register */ +#define STM32_SDMMC1_RESP4_OFFSET 0x0020 /* SDIO response 4 register */ +#define STM32_SDMMC1_DTIMER_OFFSET 0x0024 /* SDIO data timer register */ +#define STM32_SDMMC1_DLEN_OFFSET 0x0028 /* SDIO data length register */ +#define STM32_SDMMC1_DCTRL_OFFSET 0x002c /* SDIO data control register */ +#define STM32_SDMMC1_DCOUNT_OFFSET 0x0030 /* SDIO data counter register */ +#define STM32_SDMMC1_STA_OFFSET 0x0034 /* SDIO status register */ +#define STM32_SDMMC1_ICR_OFFSET 0x0038 /* SDIO interrupt clear register */ +#define STM32_SDMMC1_MASK_OFFSET 0x003c /* SDIO mask register */ +#define STM32_SDMMC1_FIFOCNT_OFFSET 0x0048 /* SDIO FIFO counter register */ +#define STM32_SDMMC1_FIFO_OFFSET 0x0080 /* SDIO data FIFO register */ + +/* Register Addresses ***************************************************************/ + +#define STM32_SDMMC1_POWER (STM32_SDMMC1_BASE+STM32_SDMMC1_POWER_OFFSET) +#define STM32_SDMMC1_CLKCR (STM32_SDMMC1_BASE+STM32_SDMMC1_CLKCR_OFFSET) +#define STM32_SDMMC1_ARG (STM32_SDMMC1_BASE+STM32_SDMMC1_ARG_OFFSET) +#define STM32_SDMMC1_CMD (STM32_SDMMC1_BASE+STM32_SDMMC1_CMD_OFFSET) +#define STM32_SDMMC1_RESPCMD (STM32_SDMMC1_BASE+STM32_SDMMC1_RESPCMD_OFFSET) +#define STM32_SDMMC1_RESP(n) (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP_OFFSET(n)) +#define STM32_SDMMC1_RESP1 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP1_OFFSET) +#define STM32_SDMMC1_RESP2 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP2_OFFSET) +#define STM32_SDMMC1_RESP3 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP3_OFFSET) +#define STM32_SDMMC1_RESP4 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP4_OFFSET) +#define STM32_SDMMC1_DTIMER (STM32_SDMMC1_BASE+STM32_SDMMC1_DTIMER_OFFSET) +#define STM32_SDMMC1_DLEN (STM32_SDMMC1_BASE+STM32_SDMMC1_DLEN_OFFSET) +#define STM32_SDMMC1_DCTRL (STM32_SDMMC1_BASE+STM32_SDMMC1_DCTRL_OFFSET) +#define STM32_SDMMC1_DCOUNT (STM32_SDMMC1_BASE+STM32_SDMMC1_DCOUNT_OFFSET) +#define STM32_SDMMC1_STA (STM32_SDMMC1_BASE+STM32_SDMMC1_STA_OFFSET) +#define STM32_SDMMC1_ICR (STM32_SDMMC1_BASE+STM32_SDMMC1_ICR_OFFSET) +#define STM32_SDMMC1_MASK (STM32_SDMMC1_BASE+STM32_SDMMC1_MASK_OFFSET) +#define STM32_SDMMC1_FIFOCNT (STM32_SDMMC1_BASE+STM32_SDMMC1_FIFOCNT_OFFSET) +#define STM32_SDMMC1_FIFO (STM32_SDMMC1_BASE+STM32_SDMMC1_FIFO_OFFSET) + + +/* Register Bitfield Definitions ****************************************************/ + +#define SDIO_POWER_PWRCTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */ +#define SDIO_POWER_PWRCTRL_MASK (3 << SDIO_POWER_PWRCTRL_SHIFT) +# define SDIO_POWER_PWRCTRL_OFF (0 << SDIO_POWER_PWRCTRL_SHIFT) /* 00: Power-off: card clock stopped */ +# define SDIO_POWER_PWRCTRL_PWRUP (2 << SDIO_POWER_PWRCTRL_SHIFT) /* 10: Reserved power-up */ +# define SDIO_POWER_PWRCTRL_ON (3 << SDIO_POWER_PWRCTRL_SHIFT) /* 11: Power-on: card is clocked */ + +#define SDIO_POWER_RESET (0) /* Reset value */ + +#define SDIO_CLKCR_CLKDIV_SHIFT (0) /* Bits 7-0: Clock divide factor */ +#define SDIO_CLKCR_CLKDIV_MASK (0xff << SDIO_CLKCR_CLKDIV_SHIFT) +#define SDIO_CLKCR_CLKEN (1 << 8) /* Bit 8: Clock enable bit */ +#define SDIO_CLKCR_PWRSAV (1 << 9) /* Bit 9: Power saving configuration bit */ +#define SDIO_CLKCR_BYPASS (1 << 10) /* Bit 10: Clock divider bypass enable bit */ +#define SDIO_CLKCR_WIDBUS_SHIFT (11) /* Bits 12-11: Wide bus mode enable bits */ +#define SDIO_CLKCR_WIDBUS_MASK (3 << SDIO_CLKCR_WIDBUS_SHIFT) +# define SDIO_CLKCR_WIDBUS_D1 (0 << SDIO_CLKCR_WIDBUS_SHIFT) /* 00: Default (SDIO_D0) */ +# define SDIO_CLKCR_WIDBUS_D4 (1 << SDIO_CLKCR_WIDBUS_SHIFT) /* 01: 4-wide (SDIO_D[3:0]) */ +# define SDIO_CLKCR_WIDBUS_D8 (2 << SDIO_CLKCR_WIDBUS_SHIFT) /* 10: 8-wide (SDIO_D[7:0]) */ +#define SDIO_CLKCR_NEGEDGE (1 << 13) /* Bit 13: SDIO_CK dephasing selection bit */ +#define SDIO_CLKCR_HWFC_EN (1 << 14) /* Bit 14: HW Flow Control enable */ + +#define SDIO_CLKCR_RESET (0) /* Reset value */ +#define SDIO_ARG_RESET (0) /* Reset value */ + +#define SDIO_CLKCR_CLKEN_BB (STM32_SDMMC1_CLKCR_BB + (8 * 4)) +#define SDIO_CLKCR_PWRSAV_BB (STM32_SDMMC1_CLKCR_BB + (9 * 4)) +#define SDIO_CLKCR_BYPASS_BB (STM32_SDMMC1_CLKCR_BB + (10 * 4)) +#define SDIO_CLKCR_NEGEDGE_BB (STM32_SDMMC1_CLKCR_BB + (13 * 4)) +#define SDIO_CLKCR_HWFC_EN_BB (STM32_SDMMC1_CLKCR_BB + (14 * 4)) + +#define SDIO_CMD_CMDINDEX_SHIFT (0) +#define SDIO_CMD_CMDINDEX_MASK (0x3f << SDIO_CMD_CMDINDEX_SHIFT) +#define SDIO_CMD_WAITRESP_SHIFT (6) /* Bits 7-6: Wait for response bits */ +#define SDIO_CMD_WAITRESP_MASK (3 << SDIO_CMD_WAITRESP_SHIFT) +# define SDIO_CMD_NORESPONSE (0 << SDIO_CMD_WAITRESP_SHIFT) /* 00/10: No response */ +# define SDIO_CMD_SHORTRESPONSE (1 << SDIO_CMD_WAITRESP_SHIFT) /* 01: Short response */ +# define SDIO_CMD_LONGRESPONSE (3 << SDIO_CMD_WAITRESP_SHIFT) /* 11: Long response */ +#define SDIO_CMD_WAITINT (1 << 8) /* Bit 8: CPSM waits for interrupt request */ +#define SDIO_CMD_WAITPEND (1 << 9) /* Bit 9: CPSM Waits for ends of data transfer */ +#define SDIO_CMD_CPSMEN (1 << 10) /* Bit 10: Command path state machine enable */ +#define SDIO_CMD_SUSPEND (1 << 11) /* Bit 11: SD I/O suspend command */ +#define SDIO_CMD_ENDCMD (1 << 12) /* Bit 12: Enable CMD completion */ +#define SDIO_CMD_NIEN (1 << 13) /* Bit 13: not Interrupt Enable */ +#define SDIO_CMD_ATACMD (1 << 14) /* Bit 14: CE-ATA command */ + +#define SDIO_CMD_RESET (0) /* Reset value */ + +#define SDIO_CMD_WAITINT_BB (STM32_SDMMC1_CMD_BB + (8 * 4)) +#define SDIO_CMD_WAITPEND_BB (STM32_SDMMC1_CMD_BB + (9 * 4)) +#define SDIO_CMD_CPSMEN_BB (STM32_SDMMC1_CMD_BB + (10 * 4)) +#define SDIO_CMD_SUSPEND_BB (STM32_SDMMC1_CMD_BB + (11 * 4)) +#define SDIO_CMD_ENCMD_BB (STM32_SDMMC1_CMD_BB + (12 * 4)) +#define SDIO_CMD_NIEN_BB (STM32_SDMMC1_CMD_BB + (13 * 4)) +#define SDIO_CMD_ATACMD_BB (STM32_SDMMC1_CMD_BB + (14 * 4)) + +#define SDIO_RESPCMD_SHIFT (0) +#define SDIO_RESPCMD_MASK (0x3f << SDIO_RESPCMD_SHIFT) + +#define SDIO_DTIMER_RESET (0) /* Reset value */ + +#define SDIO_DLEN_SHIFT (0) +#define SDIO_DLEN_MASK (0x01ffffff << SDIO_DLEN_SHIFT) + +#define SDIO_DLEN_RESET (0) /* Reset value */ + +#define SDIO_DCTRL_DTEN (1 << 0) /* Bit 0: Data transfer enabled bit */ +#define SDIO_DCTRL_DTDIR (1 << 1) /* Bit 1: Data transfer direction */ +#define SDIO_DCTRL_DTMODE (1 << 2) /* Bit 2: Data transfer mode */ +#define SDIO_DCTRL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */ +#define SDIO_DCTRL_DBLOCKSIZE_SHIFT (4) /* Bits 7-4: Data block size */ +#define SDIO_DCTRL_DBLOCKSIZE_MASK (15 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_1BYTE (0 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_2BYTES (1 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_4BYTES (2 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_8BYTES (3 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_16BYTES (4 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_32BYTES (5 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_64BYTES (6 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_128BYTES (7 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_256BYTES (8 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_512BYTES (9 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_1KBYTE (10 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_2KBYTES (11 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_4KBYTES (12 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_8KBYTES (13 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +# define SDIO_DCTRL_16KBYTES (14 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) +#define SDIO_DCTRL_RWSTART (1 << 8) /* Bit 8: Read wait start */ +#define SDIO_DCTRL_RWSTOP (1 << 9) /* Bit 9: Read wait stop */ +#define SDIO_DCTRL_RWMOD (1 << 10) /* Bit 10: Read wait mode */ +#define SDIO_DCTRL_SDIOEN (1 << 11) /* Bit 11: SD I/O enable functions */ + +#define SDIO_DCTRL_RESET (0) /* Reset value */ + +#define SDIO_DCTRL_DTEN_BB (STM32_SDMMC1_DCTRL_BB + (0 * 4)) +#define SDIO_DCTRL_DTDIR_BB (STM32_SDMMC1_DCTRL_BB + (1 * 4)) +#define SDIO_DCTRL_DTMODE_BB (STM32_SDMMC1_DCTRL_BB + (2 * 4)) +#define SDIO_DCTRL_DMAEN_BB (STM32_SDMMC1_DCTRL_BB + (3 * 4)) +#define SDIO_DCTRL_RWSTART_BB (STM32_SDMMC1_DCTRL_BB + (8 * 4)) +#define SDIO_DCTRL_RWSTOP_BB (STM32_SDMMC1_DCTRL_BB + (9 * 4)) +#define SDIO_DCTRL_RWMOD_BB (STM32_SDMMC1_DCTRL_BB + (10 * 4)) +#define SDIO_DCTRL_SDIOEN_BB (STM32_SDMMC1_DCTRL_BB + (11 * 4)) + +#define SDIO_DATACOUNT_SHIFT (0) +#define SDIO_DATACOUNT_MASK (0x01ffffff << SDIO_DATACOUNT_SHIFT) + +#define SDIO_STA_CCRCFAIL (1 << 0) /* Bit 0: Command response CRC fail */ +#define SDIO_STA_DCRCFAIL (1 << 1) /* Bit 1: Data block CRC fail */ +#define SDIO_STA_CTIMEOUT (1 << 2) /* Bit 2: Command response timeout */ +#define SDIO_STA_DTIMEOUT (1 << 3) /* Bit 3: Data timeout */ +#define SDIO_STA_TXUNDERR (1 << 4) /* Bit 4: Transmit FIFO underrun error */ +#define SDIO_STA_RXOVERR (1 << 5) /* Bit 5: Received FIFO overrun error */ +#define SDIO_STA_CMDREND (1 << 6) /* Bit 6: Command response received */ +#define SDIO_STA_CMDSENT (1 << 7) /* Bit 7: Command sent */ +#define SDIO_STA_DATAEND (1 << 8) /* Bit 8: Data end */ +#define SDIO_STA_STBITERR (1 << 9) /* Bit 9: Start bit not detected */ +#define SDIO_STA_DBCKEND (1 << 10) /* Bit 10: Data block sent/received */ +#define SDIO_STA_CMDACT (1 << 11) /* Bit 11: Command transfer in progress */ +#define SDIO_STA_TXACT (1 << 12) /* Bit 12: Data transmit in progress */ +#define SDIO_STA_RXACT (1 << 13) /* Bit 13: Data receive in progress */ +#define SDIO_STA_TXFIFOHE (1 << 14) /* Bit 14: Transmit FIFO half empty */ +#define SDIO_STA_RXFIFOHF (1 << 15) /* Bit 15: Receive FIFO half full */ +#define SDIO_STA_TXFIFOF (1 << 16) /* Bit 16: Transmit FIFO full */ +#define SDIO_STA_RXFIFOF (1 << 17) /* Bit 17: Receive FIFO full */ +#define SDIO_STA_TXFIFOE (1 << 18) /* Bit 18: Transmit FIFO empty */ +#define SDIO_STA_RXFIFOE (1 << 19) /* Bit 19: Receive FIFO empty */ +#define SDIO_STA_TXDAVL (1 << 20) /* Bit 20: Data available in transmit FIFO */ +#define SDIO_STA_RXDAVL (1 << 21) /* Bit 21: Data available in receive FIFO */ +#define SDIO_STA_SDIOIT (1 << 22) /* Bit 22: SDIO interrupt received */ +#define SDIO_STA_CEATAEND (1 << 23) /* Bit 23: CMD6 CE-ATA command completion */ + +#define SDIO_ICR_CCRCFAILC (1 << 0) /* Bit 0: CCRCFAIL flag clear bit */ +#define SDIO_ICR_DCRCFAILC (1 << 1) /* Bit 1: DCRCFAIL flag clear bit */ +#define SDIO_ICR_CTIMEOUTC (1 << 2) /* Bit 2: CTIMEOUT flag clear bit */ +#define SDIO_ICR_DTIMEOUTC (1 << 3) /* Bit 3: DTIMEOUT flag clear bit */ +#define SDIO_ICR_TXUNDERRC (1 << 4) /* Bit 4: TXUNDERR flag clear bit */ +#define SDIO_ICR_RXOVERRC (1 << 5) /* Bit 5: RXOVERR flag clear bit */ +#define SDIO_ICR_CMDRENDC (1 << 6) /* Bit 6: CMDREND flag clear bit */ +#define SDIO_ICR_CMDSENTC (1 << 7) /* Bit 7: CMDSENT flag clear bit */ +#define SDIO_ICR_DATAENDC (1 << 8) /* Bit 8: DATAEND flag clear bit */ +#define SDIO_ICR_STBITERRC (1 << 9) /* Bit 9: STBITERR flag clear bit */ +#define SDIO_ICR_DBCKENDC (1 << 10) /* Bit 10: DBCKEND flag clear bit */ +#define SDIO_ICR_SDIOITC (1 << 22) /* Bit 22: SDIOIT flag clear bit */ +#define SDIO_ICR_CEATAENDC (1 << 23) /* Bit 23: CEATAEND flag clear bit */ + +#define SDIO_ICR_RESET 0x00c007ff +#define SDIO_ICR_STATICFLAGS 0x000005ff + +#define SDIO_MASK_CCRCFAILIE (1 << 0) /* Bit 0: Command CRC fail interrupt enable */ +#define SDIO_MASK_DCRCFAILIE (1 << 1) /* Bit 1: Data CRC fail interrupt enable */ +#define SDIO_MASK_CTIMEOUTIE (1 << 2) /* Bit 2: Command timeout interrupt enable */ +#define SDIO_MASK_DTIMEOUTIE (1 << 3) /* Bit 3: Data timeout interrupt enable */ +#define SDIO_MASK_TXUNDERRIE (1 << 4) /* Bit 4: Tx FIFO underrun error interrupt enable */ +#define SDIO_MASK_RXOVERRIE (1 << 5) /* Bit 5: Rx FIFO overrun error interrupt enable */ +#define SDIO_MASK_CMDRENDIE (1 << 6) /* Bit 6: Command response received interrupt enable */ +#define SDIO_MASK_CMDSENTIE (1 << 7) /* Bit 7: Command sent interrupt enable */ +#define SDIO_MASK_DATAENDIE (1 << 8) /* Bit 8: Data end interrupt enable */ +#define SDIO_MASK_STBITERRIE (1 << 9) /* Bit 9: Start bit error interrupt enable */ +#define SDIO_MASK_DBCKENDIE (1 << 10) /* Bit 10: Data block end interrupt enable */ +#define SDIO_MASK_CMDACTIE (1 << 11) /* Bit 11: Command acting interrupt enable */ +#define SDIO_MASK_TXACTIE (1 << 12) /* Bit 12: Data transmit acting interrupt enable */ +#define SDIO_MASK_RXACTIE (1 << 13) /* Bit 13: Data receive acting interrupt enable */ +#define SDIO_MASK_TXFIFOHEIE (1 << 14) /* Bit 14: Tx FIFO half empty interrupt enable */ +#define SDIO_MASK_RXFIFOHFIE (1 << 15) /* Bit 15: Rx FIFO half full interrupt enable */ +#define SDIO_MASK_TXFIFOFIE (1 << 16) /* Bit 16: Tx FIFO full interrupt enable */ +#define SDIO_MASK_RXFIFOFIE (1 << 17) /* Bit 17: Rx FIFO full interrupt enable */ +#define SDIO_MASK_TXFIFOEIE (1 << 18) /* Bit 18: Tx FIFO empty interrupt enable */ +#define SDIO_MASK_RXFIFOEIE (1 << 19) /* Bit 19: Rx FIFO empty interrupt enable */ +#define SDIO_MASK_TXDAVLIE (1 << 20) /* Bit 20: Data available in Tx FIFO interrupt enable */ +#define SDIO_MASK_RXDAVLIE (1 << 21) /* Bit 21: Data available in Rx FIFO interrupt enable */ +#define SDIO_MASK_SDIOITIE (1 << 22) /* Bit 22: SDIO mode interrupt received interrupt enable */ +#define SDIO_MASK_CEATAENDIE (1 << 23) /* Bit 23: CE-ATA command completion interrupt enable */ + +#define SDIO_MASK_RESET (0) + +#define SDIO_FIFOCNT_SHIFT (0) +#define SDIO_FIFOCNT_MASK (0x01ffffff << SDIO_FIFOCNT_SHIFT) + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H */ + diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c new file mode 100644 index 0000000000..58f7b7318d --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -0,0 +1,2977 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_sdio.c + * + * Copyright (C) 2009, 2011-2016 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 "stm32_sdmmc.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "cache.h" +#include "chip.h" +#include "up_arch.h" + +#include "stm32_dma.h" +#include "stm32_gpio.h" + + +/* TODO STM32F7_SDMMC2 + */ + +#ifdef CONFIG_STM32F7_SDMMC1 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ +/* Required system configuration options: + * + * CONFIG_ARCH_DMA - Enable architecture-specific DMA subsystem + * initialization. Required if CONFIG_SDIO_DMA is enabled. + * CONFIG_STM32F7_DMA2 - Enable STM32 DMA2 support. Required if + * CONFIG_SDIO_DMA is enabled + * CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support. + * + * Driver-specific configuration options: + * + * CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking + * APIs to manage concurrent accesses on the SDIO bus. This is not + * needed for the simple case of a single SD card, for example. + * CONFIG_SDIO_DMA - Enable SDIO. This is a marginally optional. For + * most usages, SDIO will cause data overruns if used without DMA. + * NOTE the above system DMA configuration options. + * CONFIG_SDIO_WIDTH_D1_ONLY - This may be selected to force the driver + * operate with only a single data line (the default is to use all + * 4 SD data lines). + * CONFIG_SDIO_PRI - SDIO interrupt priority. This setting is not very + * important since interrupt nesting is not currently supported. + * CONFIG_SDM_DMAPRIO - SDIO DMA priority. This can be selecte if + * CONFIG_SDIO_DMA is enabled. + * CONFIG_SDIO_XFRDEBUG - Enables some very low-level debug output + * This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_INFO + */ + +#if defined(CONFIG_SDIO_DMA) && !defined(CONFIG_STM32F7_DMA2) +# warning "CONFIG_SDIO_DMA support requires CONFIG_STM32F7_DMA2" +#endif + +#ifndef CONFIG_SDIO_DMA +# warning "Large Non-DMA transfer may result in RX overrun failures" +#endif + +#ifndef CONFIG_SCHED_WORKQUEUE +# error "Callback support requires CONFIG_SCHED_WORKQUEUE" +#endif + +#ifndef CONFIG_SDIO_PRI +# define CONFIG_SDIO_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +#ifdef CONFIG_SDIO_DMA +# ifndef CONFIG_SDIO_DMAPRIO +# define CONFIG_SDIO_DMAPRIO DMA_SCR_PRIVERYHI +# endif +# if (CONFIG_SDIO_DMAPRIO & ~DMA_SCR_PL_MASK) != 0 +# error "Illegal value for CONFIG_SDIO_DMAPRIO" +# endif +#else +# undef CONFIG_SDIO_DMAPRIO +#endif + +#if !defined(CONFIG_DEBUG_FS) || !defined(CONFIG_DEBUG_FEATURES) +# undef CONFIG_SDIO_XFRDEBUG +#endif + +/* Friendly CLKCR bit re-definitions ****************************************/ + +#define SDIO_CLKCR_RISINGEDGE (0) +#define SDIO_CLKCR_FALLINGEDGE SDIO_CLKCR_NEGEDGE + +/* Mode dependent settings. These depend on clock devisor settings that must + * be defined in the board-specific board.h header file: SDIO_INIT_CLKDIV, + * SDIO_MMCXFR_CLKDIV, and SDIO_SDXFR_CLKDIV. + */ + +#define STM32_CLCKCR_INIT (SDMMC1_INIT_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D1) +#define SDIO_CLKCR_MMCXFR (SDMMC1_MMCXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D1) +#define SDIO_CLCKR_SDXFR (SDMMC1_SDXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D1) +#define SDIO_CLCKR_SDWIDEXFR (SDMMC1_SDXFR_CLKDIV | SDIO_CLKCR_RISINGEDGE | \ + SDIO_CLKCR_WIDBUS_D4) + +/* Timing */ + +#define SDIO_CMDTIMEOUT (100000) +#define SDIO_LONGTIMEOUT (0x7fffffff) + +/* Big DTIMER setting */ + +#define SDIO_DTIMER_DATATIMEOUT (0x000fffff) + +/* DMA channel/stream configuration register settings. The following + * must be selected. The DMA driver will select the remaining fields. + * + * - 32-bit DMA + * - Memory increment + * - Direction (memory-to-peripheral, peripheral-to-memory) + * - Memory burst size (F4 only) + */ + + +/* STM32 stream configuration register (SCR) settings. */ + +#define SDIO_RXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_P2M|DMA_SCR_MINC | \ + DMA_SCR_PSIZE_32BITS | DMA_SCR_MSIZE_32BITS | \ + CONFIG_SDIO_DMAPRIO | DMA_SCR_PBURST_INCR4 | \ + DMA_SCR_MBURST_INCR4) +#define SDIO_TXDMA32_CONFIG (DMA_SCR_PFCTRL | DMA_SCR_DIR_M2P | DMA_SCR_MINC | \ + DMA_SCR_PSIZE_32BITS | DMA_SCR_MSIZE_32BITS | \ + CONFIG_SDIO_DMAPRIO | DMA_SCR_PBURST_INCR4 | \ + DMA_SCR_MBURST_INCR4) + +/* SDIO DMA Channel/Stream selection. There + * are multiple DMA stream options that must be dis-ambiguated in the board.h + * file. + */ + +#define SDIO_DMACHAN DMAMAP_SDMMC1 + +/* FIFO sizes */ + +#define SDIO_HALFFIFO_WORDS (8) +#define SDIO_HALFFIFO_BYTES (8*4) + +/* Data transfer interrupt mask bits */ + +#define SDIO_RECV_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_RXOVERRIE | \ + SDIO_MASK_RXFIFOHFIE | SDIO_MASK_STBITERRIE) +#define SDIO_SEND_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | \ + SDIO_MASK_TXFIFOHEIE | SDIO_MASK_STBITERRIE) +#define SDIO_DMARECV_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_RXOVERRIE | \ + SDIO_MASK_STBITERRIE) +#define SDIO_DMASEND_MASK (SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE | \ + SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE | \ + SDIO_MASK_STBITERRIE) + +/* Event waiting interrupt mask bits */ + +#define SDIO_CMDDONE_STA (SDIO_STA_CMDSENT) +#define SDIO_RESPDONE_STA (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL | \ + SDIO_STA_CMDREND) +#define SDIO_XFRDONE_STA (0) + +#define SDIO_CMDDONE_MASK (SDIO_MASK_CMDSENTIE) +#define SDIO_RESPDONE_MASK (SDIO_MASK_CCRCFAILIE | SDIO_MASK_CTIMEOUTIE | \ + SDIO_MASK_CMDRENDIE) +#define SDIO_XFRDONE_MASK (0) + +#define SDIO_CMDDONE_ICR (SDIO_ICR_CMDSENTC | SDIO_ICR_DBCKENDC) +#define SDIO_RESPDONE_ICR (SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC | \ + SDIO_ICR_CMDRENDC | SDIO_ICR_DBCKENDC) +#define SDIO_XFRDONE_ICR (SDIO_ICR_DATAENDC | SDIO_ICR_DCRCFAILC | \ + SDIO_ICR_DTIMEOUTC | SDIO_ICR_RXOVERRC | \ + SDIO_ICR_TXUNDERRC | SDIO_ICR_STBITERRC | \ + SDIO_ICR_DBCKENDC) + +#define SDIO_WAITALL_ICR (SDIO_CMDDONE_ICR | SDIO_RESPDONE_ICR | \ + SDIO_XFRDONE_ICR | SDIO_ICR_DBCKENDC) + +/* Let's wait until we have both SDIO transfer complete and DMA complete. */ + +#define SDIO_XFRDONE_FLAG (1) +#define SDIO_DMADONE_FLAG (2) +#define SDIO_ALLDONE (3) + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +# ifdef CONFIG_SDIO_DMA +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_BEFORE_ENABLE 1 +# define SAMPLENDX_AFTER_SETUP 2 +# define SAMPLENDX_END_TRANSFER 3 +# define SAMPLENDX_DMA_CALLBACK 4 +# define DEBUG_NSAMPLES 5 +# else +# define SAMPLENDX_BEFORE_SETUP 0 +# define SAMPLENDX_AFTER_SETUP 1 +# define SAMPLENDX_END_TRANSFER 2 +# define DEBUG_NSAMPLES 3 +# endif +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* This structure defines the state of the STM32 SDIO interface */ + +struct stm32_dev_s +{ + struct sdio_dev_s dev; /* Standard, base SDIO interface */ + + /* STM32-specific extensions */ + /* Event support */ + + sem_t waitsem; /* Implements event waiting */ + sdio_eventset_t waitevents; /* Set of events to be waited for */ + uint32_t waitmask; /* Interrupt enables for event waiting */ + volatile sdio_eventset_t wkupevent; /* The event that caused the wakeup */ + WDOG_ID waitwdog; /* Watchdog that handles event timeouts */ + + /* Callback support */ + + uint8_t cdstatus; /* Card status */ + sdio_eventset_t cbevents; /* Set of events to be cause callbacks */ + worker_t callback; /* Registered callback function */ + void *cbarg; /* Registered callback argument */ + struct work_s cbwork; /* Callback work queue structure */ + + /* Interrupt mode data transfer support */ + + uint32_t *buffer; /* Address of current R/W buffer */ + size_t remaining; /* Number of bytes remaining in the transfer */ + uint32_t xfrmask; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + bool widebus; /* Required for DMA support */ +#ifdef CONFIG_SDIO_DMA + volatile uint8_t xfrflags; /* Used to synchronize SDIO and DMA completion events */ + bool dmamode; /* true: DMA mode transfer */ + DMA_HANDLE dma; /* Handle for DMA channel */ +#endif +}; + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +struct stm32_sdioregs_s +{ + uint8_t power; + uint16_t clkcr; + uint16_t dctrl; + uint32_t dtimer; + uint32_t dlen; + uint32_t dcount; + uint32_t sta; + uint32_t mask; + uint32_t fifocnt; +}; + +struct stm32_sampleregs_s +{ + struct stm32_sdioregs_s sdio; +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) + struct stm32_dmaregs_s dma; +#endif +}; +#endif + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers ********************************************************/ + +static void stm32_takesem(struct stm32_dev_s *priv); +#define stm32_givesem(priv) (sem_post(&priv->waitsem)) +static inline void stm32_setclkcr(uint32_t clkcr); +static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents, sdio_eventset_t wkupevents); +static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask); +static void stm32_setpwrctrl(uint32_t pwrctrl); +static inline uint32_t stm32_getpwrctrl(void); + +/* DMA Helpers **************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sampleinit(void); +static void stm32_sdiosample(struct stm32_sdioregs_s *regs); +static void stm32_sample(struct stm32_dev_s *priv, int index); +static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg); +static void stm32_dumpsample(struct stm32_dev_s *priv, + struct stm32_sampleregs_s *regs, const char *msg); +static void stm32_dumpsamples(struct stm32_dev_s *priv); +#else +# define stm32_sampleinit() +# define stm32_sample(priv,index) +# define stm32_dumpsamples(priv) +#endif + +#ifdef CONFIG_SDIO_DMA +static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg); +#endif + +/* Data Transfer Helpers ****************************************************/ + +static uint8_t stm32_log2(uint16_t value); +static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl); +static void stm32_datadisable(void); +static void stm32_sendfifo(struct stm32_dev_s *priv); +static void stm32_recvfifo(struct stm32_dev_s *priv); +static void stm32_eventtimeout(int argc, uint32_t arg); +static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent); +static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupevent); + +/* Interrupt Handling *******************************************************/ + +static int stm32_interrupt(int irq, void *context); +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE +static int stm32_rdyinterrupt(int irq, void *context); +#endif + +/* SDIO interface methods ***************************************************/ + +/* Mutual exclusion */ + +#ifdef CONFIG_SDIO_MUXBUS +static int stm32_lock(FAR struct sdio_dev_s *dev, bool lock); +#endif + +/* Initialization/setup */ + +static void stm32_reset(FAR struct sdio_dev_s *dev); +static uint8_t stm32_status(FAR struct sdio_dev_s *dev); +static void stm32_widebus(FAR struct sdio_dev_s *dev, bool enable); +static void stm32_clock(FAR struct sdio_dev_s *dev, + enum sdio_clock_e rate); +static int stm32_attach(FAR struct sdio_dev_s *dev); + +/* Command/Status/Data Transfer */ + +static int stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t arg); +static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes); +static int stm32_sendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, uint32_t nbytes); +static int stm32_cancel(FAR struct sdio_dev_s *dev); + +static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd); +static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t rlong[4]); +static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rshort); +static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, + uint32_t *rnotimpl); + +/* EVENT handler */ + +static void stm32_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static sdio_eventset_t + stm32_eventwait(FAR struct sdio_dev_s *dev, uint32_t timeout); +static void stm32_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset); +static int stm32_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg); + +/* DMA */ + +#ifdef CONFIG_SDIO_DMA +static bool stm32_dmasupported(FAR struct sdio_dev_s *dev); +#ifdef CONFIG_SDIO_PREFLIGHT +static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif +static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, + FAR uint8_t *buffer, size_t buflen); +static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen); +#endif + +/* Initialization/uninitialization/reset ************************************/ + +static void stm32_callback(void *arg); +static void stm32_default(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct stm32_dev_s g_sdiodev = +{ + .dev = + { +#ifdef CONFIG_SDIO_MUXBUS + .lock = stm32_lock, +#endif + .reset = stm32_reset, + .status = stm32_status, + .widebus = stm32_widebus, + .clock = stm32_clock, + .attach = stm32_attach, + .sendcmd = stm32_sendcmd, +#ifdef CONFIG_SDIO_BLOCKSETUP + .blocksetup = stm32_blocksetup, /* Not implemented yet */ +#endif + .recvsetup = stm32_recvsetup, + .sendsetup = stm32_sendsetup, + .cancel = stm32_cancel, + .waitresponse = stm32_waitresponse, + .recvR1 = stm32_recvshortcrc, + .recvR2 = stm32_recvlong, + .recvR3 = stm32_recvshort, + .recvR4 = stm32_recvnotimpl, + .recvR5 = stm32_recvnotimpl, + .recvR6 = stm32_recvshortcrc, + .recvR7 = stm32_recvshort, + .waitenable = stm32_waitenable, + .eventwait = stm32_eventwait, + .callbackenable = stm32_callbackenable, + .registercallback = stm32_registercallback, +#ifdef CONFIG_SDIO_DMA + .dmasupported = stm32_dmasupported, +#ifdef CONFIG_SDIO_PREFLIGHT + .dmapreflight = stm32_dmapreflight, +#endif + .dmarecvsetup = stm32_dmarecvsetup, + .dmasendsetup = stm32_dmasendsetup, +#endif + }, +}; + +/* Register logging support */ + +#ifdef CONFIG_SDIO_XFRDEBUG +static struct stm32_sampleregs_s g_sampleregs[DEBUG_NSAMPLES]; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Low-level Helpers + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_takesem + * + * Description: + * Take the wait semaphore (handling false alarm wakeups due to the receipt + * of signals). + * + * Input Parameters: + * dev - Instance of the SDIO device driver state structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_takesem(struct stm32_dev_s *priv) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(&priv->waitsem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: stm32_setclkcr + * + * Description: + * Modify oft-changed bits in the CLKCR register. Only the following bit- + * fields are changed: + * + * CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, and HWFC_EN + * + * Input Parameters: + * clkcr - A new CLKCR setting for the above mentions bits (other bits + * are ignored. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_setclkcr(uint32_t clkcr) +{ + uint32_t regval = getreg32(STM32_SDMMC1_CLKCR); + + /* Clear CLKDIV, PWRSAV, BYPASS, WIDBUS, NEGEDGE, HWFC_EN bits */ + + regval &= ~(SDIO_CLKCR_CLKDIV_MASK | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_BYPASS | + SDIO_CLKCR_WIDBUS_MASK | SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN | + SDIO_CLKCR_CLKEN); + + /* Replace with user provided settings */ + + clkcr &= (SDIO_CLKCR_CLKDIV_MASK | SDIO_CLKCR_PWRSAV | SDIO_CLKCR_BYPASS | + SDIO_CLKCR_WIDBUS_MASK | SDIO_CLKCR_NEGEDGE | SDIO_CLKCR_HWFC_EN | + SDIO_CLKCR_CLKEN); + + regval |= clkcr; + putreg32(regval, STM32_SDMMC1_CLKCR); + + finfo("CLKCR: %08x PWR: %08x\n", + getreg32(STM32_SDMMC1_CLKCR), getreg32(STM32_SDMMC1_POWER)); +} + +/**************************************************************************** + * Name: stm32_configwaitints + * + * Description: + * Enable/disable SDIO interrupts needed to suport the wait function + * + * Input Parameters: + * priv - A reference to the SDIO device state structure + * waitmask - The set of bits in the SDIO MASK register to set + * waitevents - Waited for events + * wkupevent - Wake-up events + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, + sdio_eventset_t waitevents, + sdio_eventset_t wkupevent) +{ + irqstate_t flags; +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + int pinset; +#endif + + /* Save all of the data and set the new interrupt mask in one, atomic + * operation. + */ + flags = enter_critical_section(); + +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE + if ((waitmask & SDIOWAIT_WRCOMPLETE) != 0) + { + /* Do not use this in STM32_SDMMC1_MASK register */ + + waitmask &= !SDIOWAIT_WRCOMPLETE; + + pinset = GPIO_SDMMC1_D0 & (GPIO_PORT_MASK | GPIO_PIN_MASK); + pinset |= (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI); + + /* Arm the SDIO_D Ready and install Isr */ + + stm32_gpiosetevent(pinset, true, false, false, stm32_rdyinterrupt); + } + + /* Disarm SDIO_D ready */ + + if ((wkupevent & SDIOWAIT_WRCOMPLETE) != 0) + { + stm32_gpiosetevent(GPIO_SDMMC1_D0, false, false, false , NULL); + stm32_configgpio(GPIO_SDMMC1_D0); + } +#endif + + priv->waitevents = waitevents; + priv->wkupevent = wkupevent; + priv->waitmask = waitmask; +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + putreg32(priv->xfrmask | priv->waitmask, STM32_SDMMC1_MASK); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_configxfrints + * + * Description: + * Enable SDIO interrupts needed to support the data transfer event + * + * Input Parameters: + * priv - A reference to the SDIO device state structure + * xfrmask - The set of bits in the SDIO MASK register to set + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_configxfrints(struct stm32_dev_s *priv, uint32_t xfrmask) +{ + irqstate_t flags; + flags = enter_critical_section(); + priv->xfrmask = xfrmask; + putreg32(priv->xfrmask | priv->waitmask, STM32_SDMMC1_MASK); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_setpwrctrl + * + * Description: + * Change the PWRCTRL field of the SDIO POWER register to turn the SDIO + * ON or OFF + * + * Input Parameters: + * clkcr - A new PWRCTRL setting + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_setpwrctrl(uint32_t pwrctrl) +{ + uint32_t regval; + + regval = getreg32(STM32_SDMMC1_POWER); + regval &= ~SDIO_POWER_PWRCTRL_MASK; + regval |= pwrctrl; + putreg32(regval, STM32_SDMMC1_POWER); +} + +/**************************************************************************** + * Name: stm32_getpwrctrl + * + * Description: + * Return the current value of the the PWRCTRL field of the SDIO POWER + * register. This function can be used to see if the SDIO is powered ON + * or OFF + * + * Input Parameters: + * None + * + * Returned Value: + * The current value of the the PWRCTRL field of the SDIO POWER register. + * + ****************************************************************************/ + +static inline uint32_t stm32_getpwrctrl(void) +{ + return getreg32(STM32_SDMMC1_POWER) & SDIO_POWER_PWRCTRL_MASK; +} + +/**************************************************************************** + * DMA Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sampleinit + * + * Description: + * Setup prior to collecting DMA samples + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sampleinit(void) +{ + memset(g_sampleregs, 0xff, DEBUG_NSAMPLES * sizeof(struct stm32_sampleregs_s)); +} +#endif + +/**************************************************************************** + * Name: stm32_sdiosample + * + * Description: + * Sample SDIO registers + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sdiosample(struct stm32_sdioregs_s *regs) +{ + regs->power = (uint8_t)getreg32(STM32_SDMMC1_POWER); + regs->clkcr = (uint16_t)getreg32(STM32_SDMMC1_CLKCR); + regs->dctrl = (uint16_t)getreg32(STM32_SDMMC1_DCTRL); + regs->dtimer = getreg32(STM32_SDMMC1_DTIMER); + regs->dlen = getreg32(STM32_SDMMC1_DLEN); + regs->dcount = getreg32(STM32_SDMMC1_DCOUNT); + regs->sta = getreg32(STM32_SDMMC1_STA); + regs->mask = getreg32(STM32_SDMMC1_MASK); + regs->fifocnt = getreg32(STM32_SDMMC1_FIFOCNT); +} +#endif + +/**************************************************************************** + * Name: stm32_sample + * + * Description: + * Sample SDIO/DMA registers + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sample(struct stm32_dev_s *priv, int index) +{ + struct stm32_sampleregs_s *regs = &g_sampleregs[index]; + +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dmasample(priv->dma, ®s->dma); + } +#endif + + stm32_sdiosample(®s->sdio); +} +#endif + +/**************************************************************************** + * Name: stm32_sdiodump + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg) +{ + ferr("SDIO Registers: %s\n", msg); + ferr(" POWER[%08x]: %08x\n", STM32_SDMMC1_POWER, regs->power); + ferr(" CLKCR[%08x]: %08x\n", STM32_SDMMC1_CLKCR, regs->clkcr); + ferr(" DCTRL[%08x]: %08x\n", STM32_SDMMC1_DCTRL, regs->dctrl); + ferr(" DTIMER[%08x]: %08x\n", STM32_SDMMC1_DTIMER, regs->dtimer); + ferr(" DLEN[%08x]: %08x\n", STM32_SDMMC1_DLEN, regs->dlen); + ferr(" DCOUNT[%08x]: %08x\n", STM32_SDMMC1_DCOUNT, regs->dcount); + ferr(" STA[%08x]: %08x\n", STM32_SDMMC1_STA, regs->sta); + ferr(" MASK[%08x]: %08x\n", STM32_SDMMC1_MASK, regs->mask); + ferr("FIFOCNT[%08x]: %08x\n", STM32_SDMMC1_FIFOCNT, regs->fifocnt); +} +#endif + +/**************************************************************************** + * Name: stm32_dumpsample + * + * Description: + * Dump one register sample + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_dumpsample(struct stm32_dev_s *priv, + struct stm32_sampleregs_s *regs, const char *msg) +{ +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dmadump(priv->dma, ®s->dma, msg); + } +#endif + + stm32_sdiodump(®s->sdio, msg); +} +#endif + +/**************************************************************************** + * Name: stm32_dumpsamples + * + * Description: + * Dump all sampled register data + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_XFRDEBUG +static void stm32_dumpsamples(struct stm32_dev_s *priv) +{ + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup"); + +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_ENABLE], "Before DMA enable"); + } +#endif + + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP], "After setup"); + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_END_TRANSFER], "End of transfer"); + +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) + if (priv->dmamode) + { + stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_DMA_CALLBACK], "DMA Callback"); + } +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_dmacallback + * + * Description: + * Called when SDIO DMA completes + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)arg; + DEBUGASSERT(priv->dmamode); + sdio_eventset_t result; + + /* In the normal case, SDIO appears to handle the End-Of-Transfer interrupt + * first with the End-Of-DMA event occurring significantly later. On + * transfer errors, however, the DMA error will occur before the End-of- + * Transfer. + */ + + stm32_sample((struct stm32_dev_s *)arg, SAMPLENDX_DMA_CALLBACK); + + /* Get the result of the DMA transfer */ + + if ((status & DMA_STATUS_ERROR) != 0) + { + fllerr("DMA error %02x, remaining: %d\n", status, priv->remaining); + result = SDIOWAIT_ERROR; + } + else + { + result = SDIOWAIT_TRANSFERDONE; + } + + /* Then terminate the transfer if this completes all of the steps in the + * transfer OR if a DMA error occurred. In the non-error case, we should + * already have the SDIO transfer done interrupt. If not, the transfer + * will appropriately time out. + */ + + priv->xfrflags |= SDIO_DMADONE_FLAG; + if (priv->xfrflags == SDIO_ALLDONE || result == SDIOWAIT_ERROR) + { + stm32_endtransfer(priv, result); + } +} +#endif + +/**************************************************************************** + * Data Transfer Helpers + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_log2 + * + * Description: + * Take (approximate) log base 2 of the provided number (Only works if the + * provided number is a power of 2). + * + ****************************************************************************/ + +static uint8_t stm32_log2(uint16_t value) +{ + uint8_t log2 = 0; + + /* 0000 0000 0000 0001 -> return 0, + * 0000 0000 0000 001x -> return 1, + * 0000 0000 0000 01xx -> return 2, + * 0000 0000 0000 1xxx -> return 3, + * ... + * 1xxx xxxx xxxx xxxx -> return 15, + */ + + DEBUGASSERT(value > 0); + while (value != 1) + { + value >>= 1; + log2++; + } + + return log2; +} + +/**************************************************************************** + * Name: stm32_dataconfig + * + * Description: + * Configure the SDIO data path for the next data transfer + * + ****************************************************************************/ + +static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl) +{ + uint32_t regval = 0; + + /* Enable data path */ + + putreg32(timeout, STM32_SDMMC1_DTIMER); /* Set DTIMER */ + putreg32(dlen, STM32_SDMMC1_DLEN); /* Set DLEN */ + + /* Configure DCTRL DTDIR, DTMODE, and DBLOCKSIZE fields and set the DTEN + * field + */ + + regval = getreg32(STM32_SDMMC1_DCTRL); + regval &= ~(SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); + dctrl &= (SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); + regval |= (dctrl | SDIO_DCTRL_DTEN); + putreg32(regval, STM32_SDMMC1_DCTRL); +} + +/**************************************************************************** + * Name: stm32_datadisable + * + * Description: + * Disable the SDIO data path setup by stm32_dataconfig() and + * disable DMA. + * + ****************************************************************************/ + +static void stm32_datadisable(void) +{ + uint32_t regval; + + /* Disable the data path */ + + putreg32(SDIO_DTIMER_DATATIMEOUT, STM32_SDMMC1_DTIMER); /* Reset DTIMER */ + putreg32(0, STM32_SDMMC1_DLEN); /* Reset DLEN */ + + /* Reset DCTRL DTEN, DTDIR, DTMODE, DMAEN, and DBLOCKSIZE fields */ + + regval = getreg32(STM32_SDMMC1_DCTRL); + regval &= ~(SDIO_DCTRL_DTEN | SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | + SDIO_DCTRL_DMAEN | SDIO_DCTRL_DBLOCKSIZE_MASK); + putreg32(regval, STM32_SDMMC1_DCTRL); +} + +/**************************************************************************** + * Name: stm32_sendfifo + * + * Description: + * Send SDIO data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_sendfifo(struct stm32_dev_s *priv) +{ + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Loop while there is more data to be sent and the RX FIFO is not full */ + + while (priv->remaining > 0 && + (getreg32(STM32_SDMMC1_STA) & SDIO_STA_TXFIFOF) == 0) + { + /* Is there a full word remaining in the user buffer? */ + + if (priv->remaining >= sizeof(uint32_t)) + { + /* Yes, transfer the word to the TX FIFO */ + + data.w = *priv->buffer++; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* No.. transfer just the bytes remaining in the user buffer, + * padding with zero as necessary to extend to a full word. + */ + + uint8_t *ptr = (uint8_t *)priv->remaining; + int i; + + data.w = 0; + for (i = 0; i < (int)priv->remaining; i++) + { + data.b[i] = *ptr++; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + + /* Put the word in the FIFO */ + + putreg32(data.w, STM32_SDMMC1_FIFO); + } +} + +/**************************************************************************** + * Name: stm32_recvfifo + * + * Description: + * Receive SDIO data in interrupt mode + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_recvfifo(struct stm32_dev_s *priv) +{ + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Loop while there is space to store the data and there is more + * data available in the RX FIFO. + */ + + while (priv->remaining > 0 && + (getreg32(STM32_SDMMC1_STA) & SDIO_STA_RXDAVL) != 0) + { + /* Read the next word from the RX FIFO */ + + data.w = getreg32(STM32_SDMMC1_FIFO); + if (priv->remaining >= sizeof(uint32_t)) + { + /* Transfer the whole word to the user buffer */ + + *priv->buffer++ = data.w; + priv->remaining -= sizeof(uint32_t); + } + else + { + /* Transfer any trailing fractional word */ + + uint8_t *ptr = (uint8_t *)priv->buffer; + int i; + + for (i = 0; i < (int)priv->remaining; i++) + { + *ptr++ = data.b[i]; + } + + /* Now the transfer is finished */ + + priv->remaining = 0; + } + } +} + +/**************************************************************************** + * Name: stm32_eventtimeout + * + * Description: + * The watchdog timeout setup when the event wait start has expired without + * any other waited-for event occurring. + * + * Input Parameters: + * argc - The number of arguments (should be 1) + * arg - The argument (state structure reference cast to uint32_t) + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void stm32_eventtimeout(int argc, uint32_t arg) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)arg; + + /* There is always race conditions with timer expirations. */ + + DEBUGASSERT((priv->waitevents & SDIOWAIT_TIMEOUT) != 0 || priv->wkupevent != 0); + + /* Is a data transfer complete event expected? */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + /* Yes.. wake up any waiting threads */ + + stm32_endwait(priv, SDIOWAIT_TIMEOUT); + fllerr("Timeout: remaining: %d\n", priv->remaining); + } +} + +/**************************************************************************** + * Name: stm32_endwait + * + * Description: + * Wake up a waiting thread if the waited-for event has occurred. + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * wkupevent - The event that caused the wait to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void stm32_endwait(struct stm32_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Cancel the watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* Disable event-related interrupts */ + + stm32_configwaitints(priv, 0, 0, wkupevent); + + /* Wake up the waiting thread */ + + stm32_givesem(priv); +} + +/**************************************************************************** + * Name: stm32_endtransfer + * + * Description: + * Terminate a transfer with the provided status. This function is called + * only from the SDIO interrupt handler when end-of-transfer conditions + * are detected. + * + * Input Parameters: + * priv - An instance of the SDIO device interface + * wkupevent - The event that caused the transfer to end + * + * Returned Value: + * None + * + * Assumptions: + * Always called from the interrupt level with interrupts disabled. + * + ****************************************************************************/ + +static void stm32_endtransfer(struct stm32_dev_s *priv, sdio_eventset_t wkupevent) +{ + /* Disable all transfer related interrupts */ + + stm32_configxfrints(priv, 0); + + /* Clearing pending interrupt status on all transfer related interrupts */ + + putreg32(SDIO_XFRDONE_ICR, STM32_SDMMC1_ICR); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* DMA debug instrumentation */ + + stm32_sample(priv, SAMPLENDX_END_TRANSFER); + + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition). + */ + + stm32_dmastop(priv->dma); + } +#endif + + /* Mark the transfer finished */ + + priv->remaining = 0; + + /* Is a thread wait for these data transfer complete events? */ + + if ((priv->waitevents & wkupevent) != 0) + { + /* Yes.. wake up any waiting threads */ + + stm32_endwait(priv, wkupevent); + } +} + +/**************************************************************************** + * Interrupt Handling + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_rdyinterrupt + * + * Description: + * SDIO ready interrupt handler + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE +static int stm32_rdyinterrupt(int irq, void *context) +{ + struct stm32_dev_s *priv = &g_sdiodev; + stm32_endwait(priv, SDIOWAIT_WRCOMPLETE); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_interrupt + * + * Description: + * SDIO interrupt handler + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int stm32_interrupt(int irq, void *context) +{ + struct stm32_dev_s *priv = &g_sdiodev; + uint32_t enabled; + uint32_t pending; + + /* Loop while there are pending interrupts. Check the SDIO status + * register. Mask out all bits that don't correspond to enabled + * interrupts. (This depends on the fact that bits are ordered + * the same in both the STA and MASK register). If there are non-zero + * bits remaining, then we have work to do here. + */ + + while ((enabled = getreg32(STM32_SDMMC1_STA) & getreg32(STM32_SDMMC1_MASK)) != 0) + { + /* Handle in progress, interrupt driven data transfers ****************/ + + pending = enabled & priv->xfrmask; + if (pending != 0) + { +#ifdef CONFIG_SDIO_DMA + if (!priv->dmamode) +#endif + { + /* Is the RX FIFO half full or more? Is so then we must be + * processing a receive transaction. + */ + + if ((pending & SDIO_STA_RXFIFOHF) != 0) + { + /* Receive data from the RX FIFO */ + + stm32_recvfifo(priv); + } + + /* Otherwise, Is the transmit FIFO half empty or less? If so we must + * be processing a send transaction. NOTE: We can't be processing + * both! + */ + + else if ((pending & SDIO_STA_TXFIFOHE) != 0) + { + /* Send data via the TX FIFO */ + + stm32_sendfifo(priv); + } + } + + /* Handle data end events */ + + if ((pending & SDIO_STA_DATAEND) != 0) + { + /* Handle any data remaining the RX FIFO. If the RX FIFO is + * less than half full at the end of the transfer, then no + * half-full interrupt will be received. + */ + + /* Was this transfer performed in DMA mode? */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* Yes.. Terminate the transfers only if the DMA has also + * finished. + */ + + priv->xfrflags |= SDIO_XFRDONE_FLAG; + if (priv->xfrflags == SDIO_ALLDONE) + { + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + + /* Otherwise, just disable futher transfer interrupts and + * wait for the DMA complete event. + */ + + else + { + stm32_configxfrints(priv, 0); + } + } + else +#endif + { + /* Receive data from the RX FIFO */ + + stm32_recvfifo(priv); + + /* Then terminate the transfer */ + + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE); + } + } + + /* Handle data block send/receive CRC failure */ + + else if ((pending & SDIO_STA_DCRCFAIL) != 0) + { + /* Terminate the transfer with an error */ + + fllerr("ERROR: Data block CRC failure, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle data timeout error */ + + else if ((pending & SDIO_STA_DTIMEOUT) != 0) + { + /* Terminate the transfer with an error */ + + fllerr("ERROR: Data timeout, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_TIMEOUT); + } + + /* Handle RX FIFO overrun error */ + + else if ((pending & SDIO_STA_RXOVERR) != 0) + { + /* Terminate the transfer with an error */ + + fllerr("ERROR: RX FIFO overrun, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle TX FIFO underrun error */ + + else if ((pending & SDIO_STA_TXUNDERR) != 0) + { + /* Terminate the transfer with an error */ + + fllerr("ERROR: TX FIFO underrun, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + + /* Handle start bit error */ + + else if ((pending & SDIO_STA_STBITERR) != 0) + { + /* Terminate the transfer with an error */ + + fllerr("ERROR: Start bit, remaining: %d\n", priv->remaining); + stm32_endtransfer(priv, SDIOWAIT_TRANSFERDONE | SDIOWAIT_ERROR); + } + } + + /* Handle wait events *************************************************/ + + pending = enabled & priv->waitmask; + if (pending != 0) + { + /* Is this a response completion event? */ + + if ((pending & SDIO_RESPDONE_STA) != 0) + { + /* Yes.. Is their a thread waiting for response done? */ + + if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0) + { + /* Yes.. wake the thread up */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + stm32_endwait(priv, SDIOWAIT_RESPONSEDONE); + } + } + + /* Is this a command completion event? */ + + if ((pending & SDIO_CMDDONE_STA) != 0) + { + /* Yes.. Is their a thread waiting for command done? */ + + if ((priv->waitevents & SDIOWAIT_RESPONSEDONE) != 0) + { + /* Yes.. wake the thread up */ + + putreg32(SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + stm32_endwait(priv, SDIOWAIT_CMDDONE); + } + } + } + } + + return OK; +} + +/**************************************************************************** + * SDIO Interface Methods + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_lock + * + * Description: + * Locks the bus. Function calls low-level multiplexed bus routines to + * resolve bus requests and acknowledgment issues. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * lock - TRUE to lock, FALSE to unlock. + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_MUXBUS +static int stm32_lock(FAR struct sdio_dev_s *dev, bool lock) +{ + /* Single SDIO instance so there is only one possibility. The multiplex + * bus is part of board support package. + */ + + stm32_muxbus_sdio_lock(lock); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_reset + * + * Description: + * Reset the SDIO controller. Undo all setup and initialization. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_reset(FAR struct sdio_dev_s *dev) +{ + FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev; + irqstate_t flags; + + /* Disable clocking */ + + flags = enter_critical_section(); + stm32_setpwrctrl(SDIO_POWER_PWRCTRL_OFF); + + /* Put SDIO registers in their default, reset state */ + + stm32_default(); + + /* Reset data */ + + priv->waitevents = 0; /* Set of events to be waited for */ + priv->waitmask = 0; /* Interrupt enables for event waiting */ + priv->wkupevent = 0; /* The event that caused the wakeup */ +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; /* Used to synchronize SDIO and DMA completion events */ +#endif + + wd_cancel(priv->waitwdog); /* Cancel any timeouts */ + + /* Interrupt mode data transfer support */ + + priv->buffer = 0; /* Address of current R/W buffer */ + priv->remaining = 0; /* Number of bytes remaining in the transfer */ + priv->xfrmask = 0; /* Interrupt enables for data transfer */ + + /* DMA data transfer support */ + + priv->widebus = false; /* Required for DMA support */ +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; /* true: DMA mode transfer */ +#endif + + /* Configure the SDIO peripheral */ + + stm32_setclkcr(STM32_CLCKCR_INIT | SDIO_CLKCR_CLKEN); + stm32_setpwrctrl(SDIO_POWER_PWRCTRL_ON); + leave_critical_section(flags); + + finfo("CLCKR: %08x POWER: %08x\n", + getreg32(STM32_SDMMC1_CLKCR), getreg32(STM32_SDMMC1_POWER)); +} + +/**************************************************************************** + * Name: stm32_status + * + * Description: + * Get SDIO status. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Returns a bitset of status values (see stm32_status_* defines) + * + ****************************************************************************/ + +static uint8_t stm32_status(FAR struct sdio_dev_s *dev) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + return priv->cdstatus; +} + +/**************************************************************************** + * Name: stm32_widebus + * + * Description: + * Called after change in Bus width has been selected (via ACMD6). Most + * controllers will need to perform some special operations to work + * correctly in the new bus mode. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * wide - true: wide bus (4-bit) bus mode enabled + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_widebus(FAR struct sdio_dev_s *dev, bool wide) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + priv->widebus = wide; +} + +/**************************************************************************** + * Name: stm32_clock + * + * Description: + * Enable/disable SDIO clocking + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * rate - Specifies the clocking to use (see enum sdio_clock_e) + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate) +{ + uint32_t clckr; + + switch (rate) + { + /* Disable clocking (with default ID mode divisor) */ + + default: + case CLOCK_SDIO_DISABLED: + clckr = STM32_CLCKCR_INIT; + return; + + /* Enable in initial ID mode clocking (<400KHz) */ + + case CLOCK_IDMODE: + clckr = (STM32_CLCKCR_INIT | SDIO_CLKCR_CLKEN); + break; + + /* Enable in MMC normal operation clocking */ + + case CLOCK_MMC_TRANSFER: + clckr = (SDIO_CLKCR_MMCXFR | SDIO_CLKCR_CLKEN); + break; + + /* SD normal operation clocking (wide 4-bit mode) */ + + case CLOCK_SD_TRANSFER_4BIT: +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + clckr = (SDIO_CLCKR_SDWIDEXFR | SDIO_CLKCR_CLKEN); + break; +#endif + + /* SD normal operation clocking (narrow 1-bit mode) */ + + case CLOCK_SD_TRANSFER_1BIT: + clckr = (SDIO_CLCKR_SDXFR | SDIO_CLKCR_CLKEN); + break; + } + + /* Set the new clock frequency along with the clock enable/disable bit */ + + stm32_setclkcr(clckr); +} + +/**************************************************************************** + * Name: stm32_attach + * + * Description: + * Attach and prepare interrupts + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK on success; A negated errno on failure. + * + ****************************************************************************/ + +static int stm32_attach(FAR struct sdio_dev_s *dev) +{ + int ret; + + /* Attach the SDIO interrupt handler */ + + ret = irq_attach(STM32_IRQ_SDMMC1, stm32_interrupt); + if (ret == OK) + { + + /* Disable all interrupts at the SDIO controller and clear static + * interrupt flags + */ + + putreg32(SDIO_MASK_RESET, STM32_SDMMC1_MASK); + putreg32(SDIO_ICR_STATICFLAGS, STM32_SDMMC1_ICR); + + /* Enable SDIO interrupts at the NVIC. They can now be enabled at + * the SDIO controller as needed. + */ + + up_enable_irq(STM32_IRQ_SDMMC1); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(STM32_IRQ_SDIO, CONFIG_SDIO_PRI); +#endif + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_sendcmd + * + * Description: + * Send the SDIO command + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command to send (32-bits, encoded) + * arg - 32-bit argument required with some commands + * + * Returned Value: + * None + * + ****************************************************************************/ + +static int stm32_sendcmd(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t arg) +{ + uint32_t regval; + uint32_t cmdidx; + + /* Set the SDIO Argument value */ + + putreg32(arg, STM32_SDMMC1_ARG); + + /* Clear CMDINDEX, WAITRESP, WAITINT, WAITPEND, and CPSMEN bits */ + + regval = getreg32(STM32_SDMMC1_CMD); + regval &= ~(SDIO_CMD_CMDINDEX_MASK | SDIO_CMD_WAITRESP_MASK | + SDIO_CMD_WAITINT | SDIO_CMD_WAITPEND | SDIO_CMD_CPSMEN); + + /* Set WAITRESP bits */ + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + regval |= SDIO_CMD_NORESPONSE; + break; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R3_RESPONSE: + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + case MMCSD_R6_RESPONSE: + case MMCSD_R7_RESPONSE: + regval |= SDIO_CMD_SHORTRESPONSE; + break; + + case MMCSD_R2_RESPONSE: + regval |= SDIO_CMD_LONGRESPONSE; + break; + } + + /* Set CPSMEN and the command index */ + + cmdidx = (cmd & MMCSD_CMDIDX_MASK) >> MMCSD_CMDIDX_SHIFT; + regval |= cmdidx | SDIO_CMD_CPSMEN; + + finfo("cmd: %08x arg: %08x regval: %08x\n", cmd, arg, regval); + + /* Write the SDIO CMD */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + putreg32(regval, STM32_SDMMC1_CMD); + return OK; +} + +/**************************************************************************** + * Name: stm32_recvsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card in non-DMA + * (interrupt driven mode). This method will do whatever controller setup + * is necessary. This would be called for SD memory just BEFORE sending + * CMD13 (SEND_STATUS), CMD17 (READ_SINGLE_BLOCK), CMD18 + * (READ_MULTIPLE_BLOCKS), ACMD51 (SEND_SCR), etc. Normally, SDIO_WAITEVENT + * will be called to receive the indication that the transfer is complete. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer in which to receive the data + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t nbytes) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; +#endif + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes, dblocksize | SDIO_DCTRL_DTDIR); + + /* And enable interrupts */ + + stm32_configxfrints(priv, SDIO_RECV_MASK); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: stm32_sendsetup + * + * Description: + * Setup hardware in preparation for data transfer from the card. This method + * will do whatever controller setup is necessary. This would be called + * for SD memory just AFTER sending CMD24 (WRITE_BLOCK), CMD25 + * (WRITE_MULTIPLE_BLOCK), ... and before SDIO_SENDDATA is called. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - Address of the buffer containing the data to send + * nbytes - The number of bytes in the transfer + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, + size_t nbytes) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && nbytes > 0); + DEBUGASSERT(((uint32_t)buffer & 3) == 0); + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = nbytes; +#ifdef CONFIG_SDIO_DMA + priv->dmamode = false; +#endif + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(nbytes) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, nbytes, dblocksize); + + /* Enable TX interrupts */ + + stm32_configxfrints(priv, SDIO_SEND_MASK); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + return OK; +} + +/**************************************************************************** + * Name: stm32_cancel + * + * Description: + * Cancel the data transfer setup of SDIO_RECVSETUP, SDIO_SENDSETUP, + * SDIO_DMARECVSETUP or SDIO_DMASENDSETUP. This must be called to cancel + * the data transfer setup if, for some reason, you cannot perform the + * transfer. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_cancel(FAR struct sdio_dev_s *dev) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + /* Disable all transfer- and event- related interrupts */ + + stm32_configxfrints(priv, 0); + stm32_configwaitints(priv, 0, 0, 0); + + /* Clearing pending interrupt status on all transfer- and event- related + * interrupts + */ + + putreg32(SDIO_WAITALL_ICR, STM32_SDMMC1_ICR); + + /* Cancel any watchdog timeout */ + + (void)wd_cancel(priv->waitwdog); + + /* If this was a DMA transfer, make sure that DMA is stopped */ + +#ifdef CONFIG_SDIO_DMA + if (priv->dmamode) + { + /* Make sure that the DMA is stopped (it will be stopped automatically + * on normal transfers, but not necessarily when the transfer terminates + * on an error condition. + */ + + stm32_dmastop(priv->dma); + } +#endif + + /* Mark no transfer in progress */ + + priv->remaining = 0; + return OK; +} + +/**************************************************************************** + * Name: stm32_waitresponse + * + * Description: + * Poll-wait for the response to the last command to be ready. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * cmd - The command that was sent. See 32-bit command definitions above. + * + * Returned Value: + * OK is success; a negated errno on failure + * + ****************************************************************************/ + +static int stm32_waitresponse(FAR struct sdio_dev_s *dev, uint32_t cmd) +{ + int32_t timeout; + uint32_t events; + + switch (cmd & MMCSD_RESPONSE_MASK) + { + case MMCSD_NO_RESPONSE: + events = SDIO_CMDDONE_STA; + timeout = SDIO_CMDTIMEOUT; + break; + + case MMCSD_R1_RESPONSE: + case MMCSD_R1B_RESPONSE: + case MMCSD_R2_RESPONSE: + case MMCSD_R6_RESPONSE: + events = SDIO_RESPDONE_STA; + timeout = SDIO_LONGTIMEOUT; + break; + + case MMCSD_R4_RESPONSE: + case MMCSD_R5_RESPONSE: + return -ENOSYS; + + case MMCSD_R3_RESPONSE: + case MMCSD_R7_RESPONSE: + events = SDIO_RESPDONE_STA; + timeout = SDIO_CMDTIMEOUT; + break; + + default: + return -EINVAL; + } + + /* Then wait for the response (or timeout) */ + + while ((getreg32(STM32_SDMMC1_STA) & events) == 0) + { + if (--timeout <= 0) + { + ferr("ERROR: Timeout cmd: %08x events: %08x STA: %08x\n", + cmd, events, getreg32(STM32_SDMMC1_STA)); + + return -ETIMEDOUT; + } + } + + putreg32(SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + return OK; +} + +/**************************************************************************** + * Name: stm32_recvRx + * + * Description: + * Receive response to SDIO command. Only the critical payload is + * returned -- that is 32 bits for 48 bit status and 128 bits for 136 bit + * status. The driver implementation should verify the correctness of + * the remaining, non-returned bits (CRCs, CMD index, etc.). + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * Rx - Buffer in which to receive the response + * + * Returned Value: + * Number of bytes sent on success; a negated errno on failure. Here a + * failure means only a faiure to obtain the requested reponse (due to + * transport problem -- timeout, CRC, etc.). The implementation only + * assures that the response is returned intacta and does not check errors + * within the response itself. + * + ****************************************************************************/ + +static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +{ +#ifdef CONFIG_DEBUG_FEATURES + uint32_t respcmd; +#endif + uint32_t regval; + int ret = OK; + + /* R1 Command response (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit card status + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + * + * R1b Identical to R1 with the additional busy signaling via the data + * line. + * + * R6 Published RCA Response (48-bit, SD card only) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Command index (0-63) + * 39:8 bit31 - bit0 32-bit Argument Field, consisting of: + * [31:16] New published RCA of card + * [15:0] Card status bits {23,22,19,12:0} + * 7:1 bit6 - bit0 CRC7 + * 0 1 End bit + */ + + +#ifdef CONFIG_DEBUG_FEATURES + if (!rshort) + { + ferr("ERROR: rshort=NULL\n"); + ret = -EINVAL; + } + + /* Check that this is the correct response to this command */ + + else if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R1B_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R6_RESPONSE) + { + ferr("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(STM32_SDMMC1_STA); + if ((regval & SDIO_STA_CTIMEOUT) != 0) + { + ferr("ERROR: Command timeout: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if ((regval & SDIO_STA_CCRCFAIL) != 0) + { + ferr("ERROR: CRC failure: %08x\n", regval); + ret = -EIO; + } +#ifdef CONFIG_DEBUG_FEATURES + else + { + /* Check response received is of desired command */ + + respcmd = getreg32(STM32_SDMMC1_RESPCMD); + if ((uint8_t)(respcmd & SDIO_RESPCMD_MASK) != (cmd & MMCSD_CMDIDX_MASK)) + { + ferr("ERROR: RESCMD=%02x CMD=%08x\n", respcmd, cmd); + ret = -EINVAL; + } + } +#endif + } + + /* Clear all pending message completion events and return the R1/R6 response */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + *rshort = getreg32(STM32_SDMMC1_RESP1); + return ret; +} + +static int stm32_recvlong(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t rlong[4]) +{ + uint32_t regval; + int ret = OK; + + /* R2 CID, CSD register (136-bit) + * 135 0 Start bit + * 134 0 Transmission bit (0=from card) + * 133:128 bit5 - bit0 Reserved + * 127:1 bit127 - bit1 127-bit CID or CSD register + * (including internal CRC) + * 0 1 End bit + */ + +#ifdef CONFIG_DEBUG_FEATURES + /* Check that R1 is the correct response to this command */ + + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R2_RESPONSE) + { + ferr("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout or CRC error occurred */ + + regval = getreg32(STM32_SDMMC1_STA); + if (regval & SDIO_STA_CTIMEOUT) + { + ferr("ERROR: Timeout STA: %08x\n", regval); + ret = -ETIMEDOUT; + } + else if (regval & SDIO_STA_CCRCFAIL) + { + ferr("ERROR: CRC fail STA: %08x\n", regval); + ret = -EIO; + } + } + + /* Return the long response */ + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + if (rlong) + { + rlong[0] = getreg32(STM32_SDMMC1_RESP1); + rlong[1] = getreg32(STM32_SDMMC1_RESP2); + rlong[2] = getreg32(STM32_SDMMC1_RESP3); + rlong[3] = getreg32(STM32_SDMMC1_RESP4); + } + return ret; +} + +static int stm32_recvshort(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rshort) +{ + uint32_t regval; + int ret = OK; + + /* R3 OCR (48-bit) + * 47 0 Start bit + * 46 0 Transmission bit (0=from card) + * 45:40 bit5 - bit0 Reserved + * 39:8 bit31 - bit0 32-bit OCR register + * 7:1 bit6 - bit0 Reserved + * 0 1 End bit + */ + + /* Check that this is the correct response to this command */ + +#ifdef CONFIG_DEBUG_FEATURES + if ((cmd & MMCSD_RESPONSE_MASK) != MMCSD_R3_RESPONSE && + (cmd & MMCSD_RESPONSE_MASK) != MMCSD_R7_RESPONSE) + { + ferr("ERROR: Wrong response CMD=%08x\n", cmd); + ret = -EINVAL; + } + else +#endif + { + /* Check if a timeout occurred (Apparently a CRC error can terminate + * a good response) + */ + + regval = getreg32(STM32_SDMMC1_STA); + if (regval & SDIO_STA_CTIMEOUT) + { + ferr("ERROR: Timeout STA: %08x\n", regval); + ret = -ETIMEDOUT; + } + } + + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + if (rshort) + { + *rshort = getreg32(STM32_SDMMC1_RESP1); + } + return ret; +} + +/* MMC responses not supported */ + +static int stm32_recvnotimpl(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t *rnotimpl) +{ + putreg32(SDIO_RESPDONE_ICR | SDIO_CMDDONE_ICR, STM32_SDMMC1_ICR); + return -ENOSYS; +} + +/**************************************************************************** + * Name: stm32_waitenable + * + * Description: + * Enable/disable of a set of SDIO wait events. This is part of the + * the SDIO_WAITEVENT sequence. The set of to-be-waited-for events is + * configured before calling stm32_eventwait. This is done in this way + * to help the driver to eliminate race conditions between the command + * setup and the subsequent events. + * + * The enabled events persist until either (1) SDIO_WAITENABLE is called + * again specifying a different set of wait events, or (2) SDIO_EVENTWAIT + * returns. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOWAIT_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_waitenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t waitmask; + + DEBUGASSERT(priv != NULL); + + /* Disable event-related interrupts */ + + stm32_configwaitints(priv, 0, 0, 0); + + /* Select the interrupt mask that will give us the appropriate wakeup + * interrupts. + */ + +#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) + if ((eventset & SDIOWAIT_WRCOMPLETE) != 0) + { + waitmask = SDIOWAIT_WRCOMPLETE; + } + else +#endif + { + waitmask = 0; + if ((eventset & SDIOWAIT_CMDDONE) != 0) + { + waitmask |= SDIO_CMDDONE_MASK; + } + + if ((eventset & SDIOWAIT_RESPONSEDONE) != 0) + { + waitmask |= SDIO_RESPDONE_MASK; + } + + if ((eventset & SDIOWAIT_TRANSFERDONE) != 0) + { + waitmask |= SDIO_XFRDONE_MASK; + } + + /* Enable event-related interrupts */ + + putreg32(SDIO_WAITALL_ICR, STM32_SDMMC1_ICR); + } + + stm32_configwaitints(priv, waitmask, eventset, 0); +} + +/**************************************************************************** + * Name: stm32_eventwait + * + * Description: + * Wait for one of the enabled events to occur (or a timeout). Note that + * all events enabled by SDIO_WAITEVENTS are disabled when stm32_eventwait + * returns. SDIO_WAITEVENTS must be called again before stm32_eventwait + * can be used again. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * timeout - Maximum time in milliseconds to wait. Zero means immediate + * timeout with no wait. The timeout value is ignored if + * SDIOWAIT_TIMEOUT is not included in the waited-for eventset. + * + * Returned Value: + * Event set containing the event(s) that ended the wait. Should always + * be non-zero. All events are disabled after the wait concludes. + * + ****************************************************************************/ + +static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, + uint32_t timeout) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + sdio_eventset_t wkupevent = 0; + irqstate_t flags; + int ret; + + /* There is a race condition here... the event may have completed before + * we get here. In this case waitevents will be zero, but wkupevents will + * be non-zero (and, hopefully, the semaphore count will also be non-zero. + */ + + flags = enter_critical_section(); + DEBUGASSERT(priv->waitevents != 0 || priv->wkupevent != 0); + + /* Check if the timeout event is specified in the event set */ + + if ((priv->waitevents & SDIOWAIT_TIMEOUT) != 0) + { + int delay; + + /* Yes.. Handle a cornercase: The user request a timeout event but + * with timeout == 0? + */ + + if (!timeout) + { + /* Then just tell the caller that we already timed out */ + + wkupevent = SDIOWAIT_TIMEOUT; + goto errout; + } + + /* Start the watchdog timer */ + + delay = MSEC2TICK(timeout); + ret = wd_start(priv->waitwdog, delay, (wdentry_t)stm32_eventtimeout, + 1, (uint32_t)priv); + if (ret != OK) + { + ferr("ERROR: wd_start failed: %d\n", ret); + } + } + +#if defined(CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE) + if ((priv->waitevents & SDIOWAIT_WRCOMPLETE) != 0) + { + /* Atomically read pin to see if ready (true) and determine if ISR fired + * If Pin is ready and if ISR did NOT fire end the wait here + */ + + if (stm32_gpioread(GPIO_SDMMC1_D0) && + (priv->wkupevent & SDIOWAIT_WRCOMPLETE) == 0) + { + stm32_endwait(priv, SDIOWAIT_WRCOMPLETE); + } + } +#endif + + /* Loop until the event (or the timeout occurs). Race conditions are avoided + * by calling stm32_waitenable prior to triggering the logic that will cause + * the wait to terminate. Under certain race conditions, the waited-for + * may have already occurred before this function was called! + */ + + for (; ; ) + { + /* Wait for an event in event set to occur. If this the event has already + * occurred, then the semaphore will already have been incremented and + * there will be no wait. + */ + + stm32_takesem(priv); + wkupevent = priv->wkupevent; + + /* Check if the event has occurred. When the event has occurred, then + * evenset will be set to 0 and wkupevent will be set to a nonzero value. + */ + + if (wkupevent != 0) + { + /* Yes... break out of the loop with wkupevent non-zero */ + + break; + } + } + + /* Disable event-related interrupts */ + + stm32_configwaitints(priv, 0, 0, 0); +#ifdef CONFIG_SDIO_DMA + priv->xfrflags = 0; +#endif + +errout: + leave_critical_section(flags); + stm32_dumpsamples(priv); + return wkupevent; +} + +/**************************************************************************** + * Name: stm32_callbackenable + * + * Description: + * Enable/disable of a set of SDIO callback events. This is part of the + * the SDIO callback sequence. The set of events is configured to enabled + * callbacks to the function provided in stm32_registercallback. + * + * Events are automatically disabled once the callback is performed and no + * further callback events will occur until they are again enabled by + * calling this methos. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * eventset - A bitset of events to enable or disable (see SDIOMEDIA_* + * definitions). 0=disable; 1=enable. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_callbackenable(FAR struct sdio_dev_s *dev, + sdio_eventset_t eventset) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + finfo("eventset: %02x\n", eventset); + DEBUGASSERT(priv != NULL); + + priv->cbevents = eventset; + stm32_callback(priv); +} + +/**************************************************************************** + * Name: stm32_registercallback + * + * Description: + * Register a callback that that will be invoked on any media status + * change. Callbacks should not be made from interrupt handlers, rather + * interrupt level events should be handled by calling back on the work + * thread. + * + * When this method is called, all callbacks should be disabled until they + * are enabled via a call to SDIO_CALLBACKENABLE + * + * Input Parameters: + * dev - Device-specific state data + * callback - The funtion to call on the media change + * arg - A caller provided value to return with the callback + * + * Returned Value: + * 0 on success; negated errno on failure. + * + ****************************************************************************/ + +static int stm32_registercallback(FAR struct sdio_dev_s *dev, + worker_t callback, void *arg) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + /* Disable callbacks and register this callback and is argument */ + + finfo("Register %p(%p)\n", callback, arg); + DEBUGASSERT(priv != NULL); + + priv->cbevents = 0; + priv->cbarg = arg; + priv->callback = callback; + return OK; +} + +/**************************************************************************** + * Name: stm32_dmasupported + * + * Description: + * Return true if the hardware can support DMA + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * + * Returned Value: + * true if DMA is supported. + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static bool stm32_dmasupported(FAR struct sdio_dev_s *dev) +{ + return true; +} +#endif + +/**************************************************************************** + * Name: stm32_dmapreflight + * + * Description: + * Preflight an SDIO DMA operation. If the buffer is not well-formed for + * SDIO DMA transfer (alignment, size, etc.) returns an error. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA to/from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + ****************************************************************************/ + +#if defined(CONFIG_SDIO_DMA) && defined(CONFIG_SDIO_PREFLIGHT) +static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); + + /* Wide bus operation is required for DMA */ + + if (!priv->widebus) + { + return -EINVAL; + } + + /* DMA must be possible to the buffer */ + + if (!stm32_dmacapable((uintptr_t)buffer, (buflen + 3) >> 2, SDIO_RXDMA32_CONFIG)) + { + return -EFAULT; + } + + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32_dmarecvsetup + * + * Description: + * Setup to perform a read DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For read transfers this may mean + * invalidating the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA from + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, + size_t buflen) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); +#ifdef CONFIG_SDIO_PREFLIGHT + DEBUGASSERT(stm32_dmapreflight(dev, buffer, buflen) == 0); +#endif + +#ifdef CONFIG_ARMV7M_DCACHE + /* buffer alignment is required for DMA transfers with dcache */ + + if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) + { + return -EFAULT; + } +#endif + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + + /* Initialize register sampling */ + + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the destination buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->dmamode = true; + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen, dblocksize | SDIO_DCTRL_DTDIR); + + /* Configure the RX DMA */ + + stm32_configxfrints(priv, SDIO_DMARECV_MASK); + + stm32_dmasetup(priv->dma, STM32_SDMMC1_FIFO, (uint32_t)buffer, + (buflen + 3) >> 2, SDIO_RXDMA32_CONFIG); + + /* Force RAM reread */ + + arch_invalidate_dcache((uintptr_t)buffer,(uintptr_t)buffer + buflen); + + /* Start the DMA */ + + stm32_sample(priv, SAMPLENDX_BEFORE_ENABLE); + stm32_dmastart(priv->dma, stm32_dmacallback, priv, false); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_dmasendsetup + * + * Description: + * Setup to perform a write DMA. If the processor supports a data cache, + * then this method will also make sure that the contents of the DMA memory + * and the data cache are coherent. For write transfers, this may mean + * flushing the data cache. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * buffer - The memory to DMA into + * buflen - The size of the DMA transfer in bytes + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_DMA +static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, + FAR const uint8_t *buffer, size_t buflen) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint32_t dblocksize; + + DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0); +#ifdef CONFIG_SDIO_PREFLIGHT + DEBUGASSERT(stm32_dmapreflight(dev, buffer, buflen) == 0); +#endif + +#ifdef CONFIG_ARMV7M_DCACHE + /* buffer alignment is required for DMA transfers with dcache */ + + if (((uintptr_t)buffer & (ARMV7M_DCACHE_LINESIZE-1)) != 0 || (buflen & (ARMV7M_DCACHE_LINESIZE-1)) != 0) + { + return -EFAULT; + } +#endif + + /* Reset the DPSM configuration */ + + stm32_datadisable(); + + /* Initialize register sampling */ + + stm32_sampleinit(); + stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + + /* Save the source buffer information for use by the interrupt handler */ + + priv->buffer = (uint32_t *)buffer; + priv->remaining = buflen; + priv->dmamode = true; + + /* Then set up the SDIO data path */ + + dblocksize = stm32_log2(buflen) << SDIO_DCTRL_DBLOCKSIZE_SHIFT; + stm32_dataconfig(SDIO_DTIMER_DATATIMEOUT, buflen, dblocksize); + + /* Configure the TX DMA */ + + stm32_dmasetup(priv->dma, STM32_SDMMC1_FIFO, (uint32_t)buffer, + (buflen + 3) >> 2, SDIO_TXDMA32_CONFIG); + + stm32_sample(priv, SAMPLENDX_BEFORE_ENABLE); + + /* Flush cache to physical memory */ + + arch_flush_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + + /* Start the DMA */ + + stm32_dmastart(priv->dma, stm32_dmacallback, priv, false); + stm32_sample(priv, SAMPLENDX_AFTER_SETUP); + + /* Enable TX interrupts */ + + stm32_configxfrints(priv, SDIO_DMASEND_MASK); + + return OK; +} +#endif + +/**************************************************************************** + * Initialization/uninitialization/reset + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_callback + * + * Description: + * Perform callback. + * + * Assumptions: + * This function does not execute in the context of an interrupt handler. + * It may be invoked on any user thread or scheduled on the work thread + * from an interrupt handler. + * + ****************************************************************************/ + +static void stm32_callback(void *arg) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)arg; + + /* Is a callback registered? */ + + DEBUGASSERT(priv != NULL); + finfo("Callback %p(%p) cbevents: %02x cdstatus: %02x\n", + priv->callback, priv->cbarg, priv->cbevents, priv->cdstatus); + + if (priv->callback) + { + /* Yes.. Check for enabled callback events */ + + if ((priv->cdstatus & SDIO_STATUS_PRESENT) != 0) + { + /* Media is present. Is the media inserted event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_INSERTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + else + { + /* Media is not present. Is the media eject event enabled? */ + + if ((priv->cbevents & SDIOMEDIA_EJECTED) == 0) + { + /* No... return without performing the callback */ + + return; + } + } + + /* Perform the callback, disabling further callbacks. Of course, the + * the callback can (and probably should) re-enable callbacks. + */ + + priv->cbevents = 0; + + /* Callbacks cannot be performed in the context of an interrupt handler. + * If we are in an interrupt handler, then queue the callback to be + * performed later on the work thread. + */ + + if (up_interrupt_context()) + { + /* Yes.. queue it */ + + finfo("Queuing callback to %p(%p)\n", priv->callback, priv->cbarg); + (void)work_queue(HPWORK, &priv->cbwork, (worker_t)priv->callback, priv->cbarg, 0); + } + else + { + /* No.. then just call the callback here */ + + finfo("Callback to %p(%p)\n", priv->callback, priv->cbarg); + priv->callback(priv->cbarg); + } + } +} + +/**************************************************************************** + * Name: stm32_default + * + * Description: + * Restore SDIO registers to their default, reset values + * + ****************************************************************************/ + +static void stm32_default(void) +{ + putreg32(SDIO_POWER_RESET, STM32_SDMMC1_POWER); + putreg32(SDIO_CLKCR_RESET, STM32_SDMMC1_CLKCR); + putreg32(SDIO_ARG_RESET, STM32_SDMMC1_ARG); + putreg32(SDIO_CMD_RESET, STM32_SDMMC1_CMD); + putreg32(SDIO_DTIMER_RESET, STM32_SDMMC1_DTIMER); + putreg32(SDIO_DLEN_RESET, STM32_SDMMC1_DLEN); + putreg32(SDIO_DCTRL_RESET, STM32_SDMMC1_DCTRL); + putreg32(SDIO_ICR_RESET, STM32_SDMMC1_ICR); + putreg32(SDIO_MASK_RESET, STM32_SDMMC1_MASK); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +FAR struct sdio_dev_s *sdio_initialize(int slotno) +{ + /* There is only one slot */ + + struct stm32_dev_s *priv = &g_sdiodev; + + /* Initialize the SDIO slot structure */ + + sem_init(&priv->waitsem, 0, 0); + priv->waitwdog = wd_create(); + DEBUGASSERT(priv->waitwdog); + + /* Allocate a DMA channel */ + +#ifdef CONFIG_SDIO_DMA + priv->dma = stm32_dmachannel(SDIO_DMACHAN); + DEBUGASSERT(priv->dma); +#endif + + /* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of + * 8-bit wide bus operation but D4-D7 are not configured). + * + * If bus is multiplexed then there is a custom bus configuration utility + * in the scope of the board support package. + */ + +#ifndef CONFIG_SDIO_MUXBUS + stm32_configgpio(GPIO_SDMMC1_D0); +#ifndef CONFIG_SDIO_WIDTH_D1_ONLY + stm32_configgpio(GPIO_SDMMC1_D1); + stm32_configgpio(GPIO_SDMMC1_D2); + stm32_configgpio(GPIO_SDMMC1_D3); +#endif + stm32_configgpio(GPIO_SDMMC1_CK); + stm32_configgpio(GPIO_SDMMC1_CMD); +#endif + + /* Reset the card and assure that it is in the initial, unconfigured + * state. + */ + + stm32_reset(&priv->dev); + return &g_sdiodev.dev; +} + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + uint8_t cdstatus; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + cdstatus = priv->cdstatus; + if (cardinslot) + { + priv->cdstatus |= SDIO_STATUS_PRESENT; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_PRESENT; + } + + leave_critical_section(flags); + + finfo("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus); + + /* Perform any requested callback if the status has changed */ + + if (cdstatus != priv->cdstatus) + { + stm32_callback(priv); + } +} + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect) +{ + struct stm32_dev_s *priv = (struct stm32_dev_s *)dev; + irqstate_t flags; + + /* Update card status */ + + flags = enter_critical_section(); + if (wrprotect) + { + priv->cdstatus |= SDIO_STATUS_WRPROTECTED; + } + else + { + priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED; + } + finfo("cdstatus: %02x\n", priv->cdstatus); + leave_critical_section(flags); +} +#endif /* CONFIG_STM32F7_SDMMC1 */ diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.h b/arch/arm/src/stm32f7/stm32_sdmmc.h new file mode 100644 index 0000000000..29e14683ce --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_sdmmc.h @@ -0,0 +1,129 @@ +/************************************************************************************ + * arch/arm/src/stm32/stm32_sdio.h + * + * Copyright (C) 2009, 2011, 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_SDMMC_H +#define __ARCH_ARM_SRC_STM32F7_STM32_SDMMC_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include "chip/stm32_sdmmc.h" + +#include +#include +#include + +#include "chip.h" + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: sdio_initialize + * + * Description: + * Initialize SDIO for operation. + * + * Input Parameters: + * slotno - Not used. + * + * Returned Values: + * A reference to an SDIO interface structure. NULL is returned on failures. + * + ****************************************************************************/ + +struct sdio_dev_s; /* See include/nuttx/sdio.h */ +FAR struct sdio_dev_s *sdio_initialize(int slotno); + +/**************************************************************************** + * Name: sdio_mediachange + * + * Description: + * Called by board-specific logic -- posssible from an interrupt handler -- + * in order to signal to the driver that a card has been inserted or + * removed from the slot + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * cardinslot - true is a card has been detected in the slot; false if a + * card has been removed from the slot. Only transitions + * (inserted->removed or removed->inserted should be reported) + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_mediachange(FAR struct sdio_dev_s *dev, bool cardinslot); + +/**************************************************************************** + * Name: sdio_wrprotect + * + * Description: + * Called by board-specific logic to report if the card in the slot is + * mechanically write protected. + * + * Input Parameters: + * dev - An instance of the SDIO driver device state structure. + * wrprotect - true is a card is writeprotected. + * + * Returned Values: + * None + * + ****************************************************************************/ + +void sdio_wrprotect(FAR struct sdio_dev_s *dev, bool wrprotect); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_SDMMC_H */ + diff --git a/configs/stm32f746-ws/include/board.h b/configs/stm32f746-ws/include/board.h index 1f5e3f030c..df3474497a 100644 --- a/configs/stm32f746-ws/include/board.h +++ b/configs/stm32f746-ws/include/board.h @@ -213,6 +213,48 @@ #define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 #define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 +/* SDMMC */ + +/* Stream selections are arbitrary for now but might become important in the future + * if we set aside more DMA channels/streams. + * + * SDIO DMA + * DMAMAP_SDMMC1_1 = Channel 4, Stream 3 + * DMAMAP_SDMMC1_2 = Channel 4, Stream 6 + */ + +#define DMAMAP_SDMMC1 DMAMAP_SDMMC1_1 + +/* SDIO dividers. Note that slower clocking is required when DMA is disabled + * in order to avoid RX overrun/TX underrun errors due to delayed responses + * to service FIFOs in interrupt driven mode. These values have not been + * tuned!!! + * + * SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(118+2)=400 KHz + */ + +#define SDMMC1_INIT_CLKDIV (118 << SDIO_CLKCR_CLKDIV_SHIFT) + +/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz + * DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz + */ + +#ifdef CONFIG_SDIO_DMA +# define SDMMC1_MMCXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT) +#else +# define SDMMC1_MMCXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT) +#endif + +/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz + * DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz + */ + +#ifdef CONFIG_SDIO_DMA +# define SDMMC1_SDXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT) +#else +# define SDMMC1_SDXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT) +#endif + /************************************************************************************ * Public Data ************************************************************************************/ diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index df3654343f..c282d9ee49 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -170,7 +170,7 @@ CONFIG_STM32F7_HAVE_LTDC=y # CONFIG_STM32F7_ADC is not set # CONFIG_STM32F7_CAN is not set # CONFIG_STM32F7_DAC is not set -# CONFIG_STM32F7_DMA is not set +CONFIG_STM32F7_DMA=y CONFIG_STM32F7_I2C=y # CONFIG_STM32F7_SAI is not set CONFIG_STM32F7_SPI=y @@ -185,7 +185,7 @@ CONFIG_STM32F7_ADC1=y # CONFIG_STM32F7_CRC is not set # CONFIG_STM32F7_CRYP is not set # CONFIG_STM32F7_DMA1 is not set -# CONFIG_STM32F7_DMA2 is not set +CONFIG_STM32F7_DMA2=y # CONFIG_STM32F7_DAC1 is not set # CONFIG_STM32F7_DAC2 is not set # CONFIG_STM32F7_DCMI is not set @@ -203,7 +203,7 @@ CONFIG_STM32F7_I2C1=y # CONFIG_STM32F7_SAI1 is not set # CONFIG_STM32F7_RNG is not set # CONFIG_STM32F7_SAI2 is not set -# CONFIG_STM32F7_SDMMC1 is not set +CONFIG_STM32F7_SDMMC1=y # CONFIG_STM32F7_SPDIFRX is not set CONFIG_STM32F7_SPI1=y # CONFIG_STM32F7_SPI2 is not set @@ -243,7 +243,7 @@ CONFIG_STM32F7_USART6=y # # CONFIG_ARCH_NOINTC is not set # CONFIG_ARCH_VECNOTIRQ is not set -# CONFIG_ARCH_DMA is not set +CONFIG_ARCH_DMA=y CONFIG_ARCH_HAVE_IRQPRIO=y # CONFIG_ARCH_L2CACHE is not set # CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set @@ -464,6 +464,7 @@ CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CRCGENERATION is not set # CONFIG_I2S is not set CONFIG_ADC=y +CONFIG_SDIO_DMA=y # # Timer Driver Support @@ -485,7 +486,15 @@ CONFIG_WATCHDOG_DEVPATH="/dev/watchdog0" # CONFIG_USERLED is not set # CONFIG_RGBLED is not set # CONFIG_PCA9635PW is not set -# CONFIG_MMCSD is not set + +CONFIG_MMCSD=y +CONFIG_MMCSD_NSLOTS=1 +CONFIG_MMCSD_MULTIBLOCK_DISABLE=y +CONFIG_ARCH_HAVE_SDIO=y +CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE=y +CONFIG_MMCSD_SDIO=y +CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE=y + # CONFIG_MODEM is not set # CONFIG_MTD is not set # CONFIG_EEPROM is not set @@ -578,19 +587,27 @@ CONFIG_USART6_2STOP=0 # CONFIG_DISABLE_MOUNTPOINT is not set # CONFIG_FS_AUTOMOUNTER is not set # CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set -# CONFIG_FS_READABLE is not set -# CONFIG_FS_WRITABLE is not set +CONFIG_FS_READABLE=y +CONFIG_FS_WRITABLE=y # CONFIG_FS_NAMED_SEMAPHORES is not set CONFIG_FS_MQUEUE_MPATH="/var/mqueue" # CONFIG_FS_RAMMAP is not set -# CONFIG_FS_FAT is not set +CONFIG_FS_FAT=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_MAXFNAME=32 # CONFIG_FS_NXFFS is not set -# CONFIG_FS_ROMFS is not set -# CONFIG_FS_TMPFS is not set +CONFIG_FS_ROMFS=y +CONFIG_FS_TMPFS=y +CONFIG_FS_TMPFS_BLOCKSIZE=512 +CONFIG_FS_TMPFS_DIRECTORY_ALLOCGUARD=64 +CONFIG_FS_TMPFS_DIRECTORY_FREEGUARD=128 +CONFIG_FS_TMPFS_FILE_ALLOCGUARD=512 +CONFIG_FS_TMPFS_FILE_FREEGUARD=1024 # CONFIG_FS_SMARTFS is not set # CONFIG_FS_BINFS is not set -# CONFIG_FS_PROCFS is not set -# CONFIG_FS_UNIONFS is not set +CONFIG_FS_PROCFS=y +CONFIG_FS_PROCFS_REGISTER=y # # System Logging diff --git a/configs/stm32f746-ws/src/stm32_spi.c b/configs/stm32f746-ws/src/stm32_spi.c index e973ca9b82..517ea3761b 100644 --- a/configs/stm32f746-ws/src/stm32_spi.c +++ b/configs/stm32f746-ws/src/stm32_spi.c @@ -101,7 +101,7 @@ void weak_function stm32_spidev_initialize(void) #ifdef CONFIG_STM32F7_SPI1 void stm32_spi1select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { - spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); } uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) @@ -113,7 +113,7 @@ uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) #ifdef CONFIG_STM32F7_SPI2 void stm32_spi2select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { - spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); } uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) @@ -125,7 +125,7 @@ uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) #ifdef CONFIG_STM32F7_SPI3 void stm32_spi3select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { - spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); } uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) @@ -137,7 +137,7 @@ uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) #ifdef CONFIG_STM32F7_SPI4 void stm32_spi4select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { - spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); } uint8_t stm32_spi4status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) @@ -149,7 +149,7 @@ uint8_t stm32_spi4status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) #ifdef CONFIG_STM32F7_SPI5 void stm32_spi5select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { - spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); } uint8_t stm32_spi5status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) @@ -161,7 +161,7 @@ uint8_t stm32_spi5status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) #ifdef CONFIG_STM32F7_SPI6 void stm32_spi6select(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool selected) { - spidbg("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); + spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert"); } uint8_t stm32_spi6status(FAR struct spi_dev_s *dev, enum spi_dev_e devid) From 98e7e5c402aa79ca07a6a8f8766e6aed3ff9eb04 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 17 Jun 2016 17:47:23 +0200 Subject: [PATCH 002/155] usb copy --- arch/arm/src/stm32f7/Make.defs | 8 + arch/arm/src/stm32f7/chip/stm32_otg.h | 1022 +++ .../src/stm32f7/chip/stm32f74xx75xx_sdmmc.h | 2 +- arch/arm/src/stm32f7/stm32_i2c.c | 2 +- arch/arm/src/stm32f7/stm32_otg.h | 139 + arch/arm/src/stm32f7/stm32_otgdev.c | 5666 +++++++++++++++++ arch/arm/src/stm32f7/stm32_otghost.c | 5306 +++++++++++++++ arch/arm/src/stm32f7/stm32_sdmmc.h | 2 +- 8 files changed, 12144 insertions(+), 3 deletions(-) create mode 100644 arch/arm/src/stm32f7/chip/stm32_otg.h create mode 100644 arch/arm/src/stm32f7/stm32_otg.h create mode 100644 arch/arm/src/stm32f7/stm32_otgdev.c create mode 100644 arch/arm/src/stm32f7/stm32_otghost.c diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs index 123c70ffc2..1474c0b57d 100644 --- a/arch/arm/src/stm32f7/Make.defs +++ b/arch/arm/src/stm32f7/Make.defs @@ -151,6 +151,14 @@ ifeq ($(CONFIG_STM32F7_SDMMC1),y) CHIP_CSRCS += stm32_sdmmc.c endif +ifeq ($(CONFIG_USBDEV),y) +CHIP_CSRCS += stm32_otgdev.c +endif + +ifeq ($(CONFIG_USBHOST),y) +CHIP_CSRCS += stm32_otghost.c +endif + ifeq ($(CONFIG_STM32F7_TIM),y) CHIP_CSRCS += stm32_tim.c endif diff --git a/arch/arm/src/stm32f7/chip/stm32_otg.h b/arch/arm/src/stm32f7/chip/stm32_otg.h new file mode 100644 index 0000000000..ee06497102 --- /dev/null +++ b/arch/arm/src/stm32f7/chip/stm32_otg.h @@ -0,0 +1,1022 @@ +/**************************************************************************************************** + * arch/arm/src/stm32f7/chip/stm32f_otgfs.h + * + * Copyright (C) 2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Gregory Nutt + * Paul Alexander Patience + * + * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32_OTG_H +#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_OTG_H + +/**************************************************************************************************** + * Included Files + ****************************************************************************************************/ +/**************************************************************************************************** + * Pre-processor Definitions + ****************************************************************************************************/ +/* General definitions */ + +#define OTG_EPTYPE_CTRL (0) /* Control */ +#define OTG_EPTYPE_ISOC (1) /* Isochronous */ +#define OTG_EPTYPE_BULK (2) /* Bulk */ +#define OTG_EPTYPE_INTR (3) /* Interrupt */ + +#define OTG_PID_DATA0 (0) +#define OTG_PID_DATA2 (1) +#define OTG_PID_DATA1 (2) +#define OTG_PID_MDATA (3) /* Non-control */ +#define OTG_PID_SETUP (3) /* Control */ + +/* Register Offsets *********************************************************************************/ +/* Core global control and status registers */ + +#define STM32_OTG_GOTGCTL_OFFSET 0x0000 /* Control and status register */ +#define STM32_OTG_GOTGINT_OFFSET 0x0004 /* Interrupt register */ +#define STM32_OTG_GAHBCFG_OFFSET 0x0008 /* AHB configuration register */ +#define STM32_OTG_GUSBCFG_OFFSET 0x000c /* USB configuration register */ +#define STM32_OTG_GRSTCTL_OFFSET 0x0010 /* Reset register */ +#define STM32_OTG_GINTSTS_OFFSET 0x0014 /* Core interrupt register */ +#define STM32_OTG_GINTMSK_OFFSET 0x0018 /* Interrupt mask register */ +#define STM32_OTG_GRXSTSR_OFFSET 0x001c /* Receive status debug read/OTG status read register */ +#define STM32_OTG_GRXSTSP_OFFSET 0x0020 /* Receive status debug read/OTG status pop register */ +#define STM32_OTG_GRXFSIZ_OFFSET 0x0024 /* Receive FIFO size register */ +#define STM32_OTG_HNPTXFSIZ_OFFSET 0x0028 /* Host non-periodic transmit FIFO size register */ +#define STM32_OTG_DIEPTXF0_OFFSET 0x0028 /* Endpoint 0 Transmit FIFO size */ +#define STM32_OTG_HNPTXSTS_OFFSET 0x002c /* Non-periodic transmit FIFO/queue status register */ +#define STM32_OTG_GCCFG_OFFSET 0x0038 /* General core configuration register */ +#define STM32_OTG_CID_OFFSET 0x003c /* Core ID register */ +#define STM32_OTG_HPTXFSIZ_OFFSET 0x0100 /* Host periodic transmit FIFO size register */ + +#define STM32_OTG_DIEPTXF_OFFSET(n) (104+(((n)-1) << 2)) +#define STM32_OTG_DIEPTXF1_OFFSET 0x0104 /* Device IN endpoint transmit FIFO1 size register */ +#define STM32_OTG_DIEPTXF2_OFFSET 0x0108 /* Device IN endpoint transmit FIFO2 size register */ +#define STM32_OTG_DIEPTXF3_OFFSET 0x010c /* Device IN endpoint transmit FIFO3 size register */ + +/* Host-mode control and status registers */ + +#define STM32_OTG_HCFG_OFFSET 0x0400 /* Host configuration register */ +#define STM32_OTG_HFIR_OFFSET 0x0404 /* Host frame interval register */ +#define STM32_OTG_HFNUM_OFFSET 0x0408 /* Host frame number/frame time remaining register */ +#define STM32_OTG_HPTXSTS_OFFSET 0x0410 /* Host periodic transmit FIFO/queue status register */ +#define STM32_OTG_HAINT_OFFSET 0x0414 /* Host all channels interrupt register */ +#define STM32_OTG_HAINTMSK_OFFSET 0x0418 /* Host all channels interrupt mask register */ +#define STM32_OTG_HPRT_OFFSET 0x0440 /* Host port control and status register */ + +#define STM32_OTG_CHAN_OFFSET(n) (0x500 + ((n) << 5) +#define STM32_OTG_HCCHAR_CHOFFSET 0x0000 /* Host channel characteristics register */ +#define STM32_OTG_HCINT_CHOFFSET 0x0008 /* Host channel interrupt register */ +#define STM32_OTG_HCINTMSK_CHOFFSET 0x000c /* Host channel interrupt mask register */ +#define STM32_OTG_HCTSIZ_CHOFFSET 0x0010 /* Host channel interrupt register */ + +#define STM32_OTG_HCCHAR_OFFSET(n) (0x500 + ((n) << 5)) +#define STM32_OTG_HCCHAR0_OFFSET 0x0500 /* Host channel-0 characteristics register */ +#define STM32_OTG_HCCHAR1_OFFSET 0x0520 /* Host channel-1 characteristics register */ +#define STM32_OTG_HCCHAR2_OFFSET 0x0540 /* Host channel-2 characteristics register */ +#define STM32_OTG_HCCHAR3_OFFSET 0x0560 /* Host channel-3 characteristics register */ +#define STM32_OTG_HCCHAR4_OFFSET 0x0580 /* Host channel-4 characteristics register */ +#define STM32_OTG_HCCHAR5_OFFSET 0x05a0 /* Host channel-5 characteristics register */ +#define STM32_OTG_HCCHAR6_OFFSET 0x05c0 /* Host channel-6 characteristics register */ +#define STM32_OTG_HCCHAR7_OFFSET 0x05e0 /* Host channel-7 characteristics register */ + +#define STM32_OTG_HCINT_OFFSET(n) (0x508 + ((n) << 5)) +#define STM32_OTG_HCINT0_OFFSET 0x0508 /* Host channel-0 interrupt register */ +#define STM32_OTG_HCINT1_OFFSET 0x0528 /* Host channel-1 interrupt register */ +#define STM32_OTG_HCINT2_OFFSET 0x0548 /* Host channel-2 interrupt register */ +#define STM32_OTG_HCINT3_OFFSET 0x0568 /* Host channel-3 interrupt register */ +#define STM32_OTG_HCINT4_OFFSET 0x0588 /* Host channel-4 interrupt register */ +#define STM32_OTG_HCINT5_OFFSET 0x05a8 /* Host channel-5 interrupt register */ +#define STM32_OTG_HCINT6_OFFSET 0x05c8 /* Host channel-6 interrupt register */ +#define STM32_OTG_HCINT7_OFFSET 0x05e8 /* Host channel-7 interrupt register */ + +#define STM32_OTG_HCINTMSK_OFFSET(n) (0x50c + ((n) << 5)) +#define STM32_OTG_HCINTMSK0_OFFSET 0x050c /* Host channel-0 interrupt mask register */ +#define STM32_OTG_HCINTMSK1_OFFSET 0x052c /* Host channel-1 interrupt mask register */ +#define STM32_OTG_HCINTMSK2_OFFSET 0x054c /* Host channel-2 interrupt mask register */ +#define STM32_OTG_HCINTMSK3_OFFSET 0x056c /* Host channel-3 interrupt mask register */ +#define STM32_OTG_HCINTMSK4_OFFSET 0x058c /* Host channel-4 interrupt mask register */ +#define STM32_OTG_HCINTMSK5_OFFSET 0x05ac /* Host channel-5 interrupt mask register */ +#define STM32_OTG_HCINTMSK6_OFFSET 0x05cc /* Host channel-6 interrupt mask register */ +#define STM32_OTG_HCINTMSK7_OFFSET 0x05ec /* Host channel-7 interrupt mask register */ + +#define STM32_OTG_HCTSIZ_OFFSET(n) (0x510 + ((n) << 5)) +#define STM32_OTG_HCTSIZ0_OFFSET 0x0510 /* Host channel-0 interrupt register */ +#define STM32_OTG_HCTSIZ1_OFFSET 0x0530 /* Host channel-1 interrupt register */ +#define STM32_OTG_HCTSIZ2_OFFSET 0x0550 /* Host channel-2 interrupt register */ +#define STM32_OTG_HCTSIZ3_OFFSET 0x0570 /* Host channel-3 interrupt register */ +#define STM32_OTG_HCTSIZ4_OFFSET 0x0590 /* Host channel-4 interrupt register */ +#define STM32_OTG_HCTSIZ5_OFFSET 0x05b0 /* Host channel-5 interrupt register */ +#define STM32_OTG_HCTSIZ6_OFFSET 0x05d0 /* Host channel-6 interrupt register */ +#define STM32_OTG_HCTSIZ7_OFFSET 0x05f0 /* Host channel-7 interrupt register */ + +/* Device-mode control and status registers */ + +#define STM32_OTG_DCFG_OFFSET 0x0800 /* Device configuration register */ +#define STM32_OTG_DCTL_OFFSET 0x0804 /* Device control register */ +#define STM32_OTG_DSTS_OFFSET 0x0808 /* Device status register */ +#define STM32_OTG_DIEPMSK_OFFSET 0x0810 /* Device IN endpoint common interrupt mask register */ +#define STM32_OTG_DOEPMSK_OFFSET 0x0814 /* Device OUT endpoint common interrupt mask register */ +#define STM32_OTG_DAINT_OFFSET 0x0818 /* Device all endpoints interrupt register */ +#define STM32_OTG_DAINTMSK_OFFSET 0x081c /* All endpoints interrupt mask register */ +#define STM32_OTG_DVBUSDIS_OFFSET 0x0828 /* Device VBUS discharge time register */ +#define STM32_OTG_DVBUSPULSE_OFFSET 0x082c /* Device VBUS pulsing time register */ +#define STM32_OTG_DIEPEMPMSK_OFFSET 0x0834 /* Device IN endpoint FIFO empty interrupt mask register */ + +#define STM32_OTG_DIEP_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTG_DIEPCTL_EPOFFSET 0x0000 /* Device endpoint control register */ +#define STM32_OTG_DIEPINT_EPOFFSET 0x0008 /* Device endpoint interrupt register */ +#define STM32_OTG_DIEPTSIZ_EPOFFSET 0x0010 /* Device IN endpoint transfer size register */ +#define STM32_OTG_DTXFSTS_EPOFFSET 0x0018 /* Device IN endpoint transmit FIFO status register */ + +#define STM32_OTG_DIEPCTL_OFFSET(n) (0x0900 + ((n) << 5)) +#define STM32_OTG_DIEPCTL0_OFFSET 0x0900 /* Device control IN endpoint 0 control register */ +#define STM32_OTG_DIEPCTL1_OFFSET 0x0920 /* Device control IN endpoint 2 control register */ +#define STM32_OTG_DIEPCTL2_OFFSET 0x0940 /* Device control IN endpoint 3 control register */ +#define STM32_OTG_DIEPCTL3_OFFSET 0x0960 /* Device control IN endpoint 4 control register */ + +#define STM32_OTG_DIEPINT_OFFSET(n) (0x0908 + ((n) << 5)) +#define STM32_OTG_DIEPINT0_OFFSET 0x0908 /* Device endpoint-0 interrupt register */ +#define STM32_OTG_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 interrupt register */ +#define STM32_OTG_DIEPINT2_OFFSET 0x0948 /* Device endpoint-2 interrupt register */ +#define STM32_OTG_DIEPINT3_OFFSET 0x0968 /* Device endpoint-3 interrupt register */ + +#define STM32_OTG_DIEPTSIZ_OFFSET(n) (0x910 + ((n) << 5)) +#define STM32_OTG_DIEPTSIZ0_OFFSET 0x0910 /* Device IN endpoint 0 transfer size register */ +#define STM32_OTG_DIEPTSIZ1_OFFSET 0x0930 /* Device IN endpoint 1 transfer size register */ +#define STM32_OTG_DIEPTSIZ2_OFFSET 0x0950 /* Device IN endpoint 2 transfer size register */ +#define STM32_OTG_DIEPTSIZ3_OFFSET 0x0970 /* Device IN endpoint 3 transfer size register */ + +#define STM32_OTG_DTXFSTS_OFFSET(n) (0x0918 + ((n) << 5)) +#define STM32_OTG_DTXFSTS0_OFFSET 0x0918 /* Device OUT endpoint-0 TxFIFO status register */ +#define STM32_OTG_DTXFSTS1_OFFSET 0x0938 /* Device OUT endpoint-1 TxFIFO status register */ +#define STM32_OTG_DTXFSTS2_OFFSET 0x0958 /* Device OUT endpoint-2 TxFIFO status register */ +#define STM32_OTG_DTXFSTS3_OFFSET 0x0978 /* Device OUT endpoint-3 TxFIFO status register */ + +#define STM32_OTG_DOEP_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTG_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */ +#define STM32_OTG_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */ + +#define STM32_OTG_DOEPCTL_OFFSET(n) (0x0b00 + ((n) << 5)) +#define STM32_OTG_DOEPCTL0_OFFSET 0x00b00 /* Device OUT endpoint 0 control register */ +#define STM32_OTG_DOEPCTL1_OFFSET 0x00b20 /* Device OUT endpoint 1 control register */ +#define STM32_OTG_DOEPCTL2_OFFSET 0x00b40 /* Device OUT endpoint 2 control register */ +#define STM32_OTG_DOEPCTL3_OFFSET 0x00b60 /* Device OUT endpoint 3 control register */ + +#define STM32_OTG_DOEPINT_OFFSET(n) (0x0b08 + ((n) << 5)) +#define STM32_OTG_DOEPINT0_OFFSET 0x00b08 /* Device endpoint-0 interrupt register */ +#define STM32_OTG_DOEPINT1_OFFSET 0x00b28 /* Device endpoint-1 interrupt register */ +#define STM32_OTG_DOEPINT2_OFFSET 0x00b48 /* Device endpoint-2 interrupt register */ +#define STM32_OTG_DOEPINT3_OFFSET 0x00b68 /* Device endpoint-3 interrupt register */ + +#define STM32_OTG_DOEPTSIZ_OFFSET(n) (0x0b10 + ((n) << 5)) +#define STM32_OTG_DOEPTSIZ0_OFFSET 0x00b10 /* Device OUT endpoint-0 transfer size register */ +#define STM32_OTG_DOEPTSIZ1_OFFSET 0x00b30 /* Device OUT endpoint-1 transfer size register */ +#define STM32_OTG_DOEPTSIZ2_OFFSET 0x00b50 /* Device OUT endpoint-2 transfer size register */ +#define STM32_OTG_DOEPTSIZ3_OFFSET 0x00b70 /* Device OUT endpoint-3 transfer size register */ + +/* Power and clock gating registers */ + +#define STM32_OTG_PCGCCTL_OFFSET 0x0e00 /* Power and clock gating control register */ + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTG_DFIFO_DEP_OFFSET(n) (0x1000 + ((n) << 12)) +#define STM32_OTG_DFIFO_HCH_OFFSET(n) (0x1000 + ((n) << 12)) + +#define STM32_OTG_DFIFO_DEP0_OFFSET 0x1000 /* 0x1000-0x1ffc Device IN/OUT Endpoint 0 DFIFO Write/Read Access */ +#define STM32_OTG_DFIFO_HCH0_OFFSET 0x1000 /* 0x1000-0x1ffc Host OUT/IN Channel 0 DFIFO Read/Write Access */ + +#define STM32_OTG_DFIFO_DEP1_OFFSET 0x2000 /* 0x2000-0x2ffc Device IN/OUT Endpoint 1 DFIFO Write/Read Access */ +#define STM32_OTG_DFIFO_HCH1_OFFSET 0x2000 /* 0x2000-0x2ffc Host OUT/IN Channel 1 DFIFO Read/Write Access */ + +#define STM32_OTG_DFIFO_DEP2_OFFSET 0x3000 /* 0x3000-0x3ffc Device IN/OUT Endpoint 2 DFIFO Write/Read Access */ +#define STM32_OTG_DFIFO_HCH2_OFFSET 0x3000 /* 0x3000-0x3ffc Host OUT/IN Channel 2 DFIFO Read/Write Access */ + +#define STM32_OTG_DFIFO_DEP3_OFFSET 0x4000 /* 0x4000-0x4ffc Device IN/OUT Endpoint 3 DFIFO Write/Read Access */ +#define STM32_OTG_DFIFO_HCH3_OFFSET 0x4000 /* 0x4000-0x4ffc Host OUT/IN Channel 3 DFIFO Read/Write Access */ + +/* Register Addresses *******************************************************************************/ + +#define STM32_OTG_GOTGCTL (STM32_OTG_BASE+STM32_OTG_GOTGCTL_OFFSET) +#define STM32_OTG_GOTGINT (STM32_OTG_BASE+STM32_OTG_GOTGINT_OFFSET) +#define STM32_OTG_GAHBCFG (STM32_OTG_BASE+STM32_OTG_GAHBCFG_OFFSET) +#define STM32_OTG_GUSBCFG (STM32_OTG_BASE+STM32_OTG_GUSBCFG_OFFSET) +#define STM32_OTG_GRSTCTL (STM32_OTG_BASE+STM32_OTG_GRSTCTL_OFFSET) +#define STM32_OTG_GINTSTS (STM32_OTG_BASE+STM32_OTG_GINTSTS_OFFSET) +#define STM32_OTG_GINTMSK (STM32_OTG_BASE+STM32_OTG_GINTMSK_OFFSET) +#define STM32_OTG_GRXSTSR (STM32_OTG_BASE+STM32_OTG_GRXSTSR_OFFSET) +#define STM32_OTG_GRXSTSP (STM32_OTG_BASE+STM32_OTG_GRXSTSP_OFFSET) +#define STM32_OTG_GRXFSIZ (STM32_OTG_BASE+STM32_OTG_GRXFSIZ_OFFSET) +#define STM32_OTG_HNPTXFSIZ (STM32_OTG_BASE+STM32_OTG_HNPTXFSIZ_OFFSET) +#define STM32_OTG_DIEPTXF0 (STM32_OTG_BASE+STM32_OTG_DIEPTXF0_OFFSET) +#define STM32_OTG_HNPTXSTS (STM32_OTG_BASE+STM32_OTG_HNPTXSTS_OFFSET) +#define STM32_OTG_GCCFG (STM32_OTG_BASE+STM32_OTG_GCCFG_OFFSET) +#define STM32_OTG_CID (STM32_OTG_BASE+STM32_OTG_CID_OFFSET) +#define STM32_OTG_HPTXFSIZ (STM32_OTG_BASE+STM32_OTG_HPTXFSIZ_OFFSET) + +#define STM32_OTG_DIEPTXF(n) (STM32_OTG_BASE+STM32_OTG_DIEPTXF_OFFSET(n)) +#define STM32_OTG_DIEPTXF1 (STM32_OTG_BASE+STM32_OTG_DIEPTXF1_OFFSET) +#define STM32_OTG_DIEPTXF2 (STM32_OTG_BASE+STM32_OTG_DIEPTXF2_OFFSET) +#define STM32_OTG_DIEPTXF3 (STM32_OTG_BASE+STM32_OTG_DIEPTXF3_OFFSET) + +/* Host-mode control and status registers */ + +#define STM32_OTG_HCFG (STM32_OTG_BASE+STM32_OTG_HCFG_OFFSET) +#define STM32_OTG_HFIR (STM32_OTG_BASE+STM32_OTG_HFIR_OFFSET) +#define STM32_OTG_HFNUM (STM32_OTG_BASE+STM32_OTG_HFNUM_OFFSET) +#define STM32_OTG_HPTXSTS (STM32_OTG_BASE+STM32_OTG_HPTXSTS_OFFSET) +#define STM32_OTG_HAINT (STM32_OTG_BASE+STM32_OTG_HAINT_OFFSET) +#define STM32_OTG_HAINTMSK (STM32_OTG_BASE+STM32_OTG_HAINTMSK_OFFSET) +#define STM32_OTG_HPRT (STM32_OTG_BASE+STM32_OTG_HPRT_OFFSET) + +#define STM32_OTG_CHAN(n) (STM32_OTG_BASE+STM32_OTG_CHAN_OFFSET(n)) + +#define STM32_OTG_HCCHAR(n) (STM32_OTG_BASE+STM32_OTG_HCCHAR_OFFSET(n)) +#define STM32_OTG_HCCHAR0 (STM32_OTG_BASE+STM32_OTG_HCCHAR0_OFFSET) +#define STM32_OTG_HCCHAR1 (STM32_OTG_BASE+STM32_OTG_HCCHAR1_OFFSET) +#define STM32_OTG_HCCHAR2 (STM32_OTG_BASE+STM32_OTG_HCCHAR2_OFFSET) +#define STM32_OTG_HCCHAR3 (STM32_OTG_BASE+STM32_OTG_HCCHAR3_OFFSET) +#define STM32_OTG_HCCHAR4 (STM32_OTG_BASE+STM32_OTG_HCCHAR4_OFFSET) +#define STM32_OTG_HCCHAR5 (STM32_OTG_BASE+STM32_OTG_HCCHAR5_OFFSET) +#define STM32_OTG_HCCHAR6 (STM32_OTG_BASE+STM32_OTG_HCCHAR6_OFFSET) +#define STM32_OTG_HCCHAR7 (STM32_OTG_BASE+STM32_OTG_HCCHAR7_OFFSET) + +#define STM32_OTG_HCINT(n) (STM32_OTG_BASE+STM32_OTG_HCINT_OFFSET(n)) +#define STM32_OTG_HCINT0 (STM32_OTG_BASE+STM32_OTG_HCINT0_OFFSET) +#define STM32_OTG_HCINT1 (STM32_OTG_BASE+STM32_OTG_HCINT1_OFFSET) +#define STM32_OTG_HCINT2 (STM32_OTG_BASE+STM32_OTG_HCINT2_OFFSET) +#define STM32_OTG_HCINT3 (STM32_OTG_BASE+STM32_OTG_HCINT3_OFFSET) +#define STM32_OTG_HCINT4 (STM32_OTG_BASE+STM32_OTG_HCINT4_OFFSET) +#define STM32_OTG_HCINT5 (STM32_OTG_BASE+STM32_OTG_HCINT5_OFFSET) +#define STM32_OTG_HCINT6 (STM32_OTG_BASE+STM32_OTG_HCINT6_OFFSET) +#define STM32_OTG_HCINT7 (STM32_OTG_BASE+STM32_OTG_HCINT7_OFFSET) + +#define STM32_OTG_HCINTMSK(n) (STM32_OTG_BASE+STM32_OTG_HCINTMSK_OFFSET(n)) +#define STM32_OTG_HCINTMSK0 (STM32_OTG_BASE+STM32_OTG_HCINTMSK0_OFFSET) +#define STM32_OTG_HCINTMSK1 (STM32_OTG_BASE+STM32_OTG_HCINTMSK1_OFFSET) +#define STM32_OTG_HCINTMSK2 (STM32_OTG_BASE+STM32_OTG_HCINTMSK2_OFFSET) +#define STM32_OTG_HCINTMSK3 (STM32_OTG_BASE+STM32_OTG_HCINTMSK3_OFFSET) +#define STM32_OTG_HCINTMSK4 (STM32_OTG_BASE+STM32_OTG_HCINTMSK4_OFFSET) +#define STM32_OTG_HCINTMSK5 (STM32_OTG_BASE+STM32_OTG_HCINTMSK5_OFFSET) +#define STM32_OTG_HCINTMSK6 (STM32_OTG_BASE+STM32_OTG_HCINTMSK6_OFFSET) +#define STM32_OTG_HCINTMSK7 (STM32_OTG_BASE+STM32_OTG_HCINTMSK7_OFFSET)_ + +#define STM32_OTG_HCTSIZ(n) (STM32_OTG_BASE+STM32_OTG_HCTSIZ_OFFSET(n)) +#define STM32_OTG_HCTSIZ0 (STM32_OTG_BASE+STM32_OTG_HCTSIZ0_OFFSET) +#define STM32_OTG_HCTSIZ1 (STM32_OTG_BASE+STM32_OTG_HCTSIZ1_OFFSET) +#define STM32_OTG_HCTSIZ2 (STM32_OTG_BASE+STM32_OTG_HCTSIZ2_OFFSET) +#define STM32_OTG_HCTSIZ3 (STM32_OTG_BASE+STM32_OTG_HCTSIZ3_OFFSET) +#define STM32_OTG_HCTSIZ4 (STM32_OTG_BASE+STM32_OTG_HCTSIZ4_OFFSET) +#define STM32_OTG_HCTSIZ5 (STM32_OTG_BASE+STM32_OTG_HCTSIZ5_OFFSET) +#define STM32_OTG_HCTSIZ6 (STM32_OTG_BASE+STM32_OTG_HCTSIZ6_OFFSET) +#define STM32_OTG_HCTSIZ7 (STM32_OTG_BASE+STM32_OTG_HCTSIZ7_OFFSET) + +/* Device-mode control and status registers */ + +#define STM32_OTG_DCFG (STM32_OTG_BASE+STM32_OTG_DCFG_OFFSET) +#define STM32_OTG_DCTL (STM32_OTG_BASE+STM32_OTG_DCTL_OFFSET) +#define STM32_OTG_DSTS (STM32_OTG_BASE+STM32_OTG_DSTS_OFFSET) +#define STM32_OTG_DIEPMSK (STM32_OTG_BASE+STM32_OTG_DIEPMSK_OFFSET) +#define STM32_OTG_DOEPMSK (STM32_OTG_BASE+STM32_OTG_DOEPMSK_OFFSET) +#define STM32_OTG_DAINT (STM32_OTG_BASE+STM32_OTG_DAINT_OFFSET) +#define STM32_OTG_DAINTMSK (STM32_OTG_BASE+STM32_OTG_DAINTMSK_OFFSET) +#define STM32_OTG_DVBUSDIS (STM32_OTG_BASE+STM32_OTG_DVBUSDIS_OFFSET) +#define STM32_OTG_DVBUSPULSE (STM32_OTG_BASE+STM32_OTG_DVBUSPULSE_OFFSET) +#define STM32_OTG_DIEPEMPMSK (STM32_OTG_BASE+STM32_OTG_DIEPEMPMSK_OFFSET) + +#define STM32_OTG_DIEP(n) (STM32_OTG_BASE+STM32_OTG_DIEP_OFFSET(n)) + +#define STM32_OTG_DIEPCTL(n) (STM32_OTG_BASE+STM32_OTG_DIEPCTL_OFFSET(n)) +#define STM32_OTG_DIEPCTL0 (STM32_OTG_BASE+STM32_OTG_DIEPCTL0_OFFSET) +#define STM32_OTG_DIEPCTL1 (STM32_OTG_BASE+STM32_OTG_DIEPCTL1_OFFSET) +#define STM32_OTG_DIEPCTL2 (STM32_OTG_BASE+STM32_OTG_DIEPCTL2_OFFSET) +#define STM32_OTG_DIEPCTL3 (STM32_OTG_BASE+STM32_OTG_DIEPCTL3_OFFSET) + +#define STM32_OTG_DIEPINT(n) (STM32_OTG_BASE+STM32_OTG_DIEPINT_OFFSET(n)) +#define STM32_OTG_DIEPINT0 (STM32_OTG_BASE+STM32_OTG_DIEPINT0_OFFSET) +#define STM32_OTG_DIEPINT1 (STM32_OTG_BASE+STM32_OTG_DIEPINT1_OFFSET) +#define STM32_OTG_DIEPINT2 (STM32_OTG_BASE+STM32_OTG_DIEPINT2_OFFSET) +#define STM32_OTG_DIEPINT3 (STM32_OTG_BASE+STM32_OTG_DIEPINT3_OFFSET) + +#define STM32_OTG_DIEPTSIZ(n) (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ_OFFSET(n)) +#define STM32_OTG_DIEPTSIZ0 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ0_OFFSET) +#define STM32_OTG_DIEPTSIZ1 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ1_OFFSET) +#define STM32_OTG_DIEPTSIZ2 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ2_OFFSET) +#define STM32_OTG_DIEPTSIZ3 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ3_OFFSET) + +#define STM32_OTG_DTXFSTS(n) (STM32_OTG_BASE+STM32_OTG_DTXFSTS_OFFSET(n)) +#define STM32_OTG_DTXFSTS0 (STM32_OTG_BASE+STM32_OTG_DTXFSTS0_OFFSET) +#define STM32_OTG_DTXFSTS1 (STM32_OTG_BASE+STM32_OTG_DTXFSTS1_OFFSET) +#define STM32_OTG_DTXFSTS2 (STM32_OTG_BASE+STM32_OTG_DTXFSTS2_OFFSET) +#define STM32_OTG_DTXFSTS3 (STM32_OTG_BASE+STM32_OTG_DTXFSTS3_OFFSET) + +#define STM32_OTG_DOEP(n) (STM32_OTG_BASE+STM32_OTG_DOEP_OFFSET(n)) + +#define STM32_OTG_DOEPCTL(n) (STM32_OTG_BASE+STM32_OTG_DOEPCTL_OFFSET(n)) +#define STM32_OTG_DOEPCTL0 (STM32_OTG_BASE+STM32_OTG_DOEPCTL0_OFFSET) +#define STM32_OTG_DOEPCTL1 (STM32_OTG_BASE+STM32_OTG_DOEPCTL1_OFFSET) +#define STM32_OTG_DOEPCTL2 (STM32_OTG_BASE+STM32_OTG_DOEPCTL2_OFFSET) +#define STM32_OTG_DOEPCTL3 (STM32_OTG_BASE+STM32_OTG_DOEPCTL3_OFFSET) + +#define STM32_OTG_DOEPINT(n) (STM32_OTG_BASE+STM32_OTG_DOEPINT_OFFSET(n)) +#define STM32_OTG_DOEPINT0 (STM32_OTG_BASE+STM32_OTG_DOEPINT0_OFFSET) +#define STM32_OTG_DOEPINT1 (STM32_OTG_BASE+STM32_OTG_DOEPINT1_OFFSET) +#define STM32_OTG_DOEPINT2 (STM32_OTG_BASE+STM32_OTG_DOEPINT2_OFFSET) +#define STM32_OTG_DOEPINT3 (STM32_OTG_BASE+STM32_OTG_DOEPINT3_OFFSET) + +#define STM32_OTG_DOEPTSIZ(n) (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ_OFFSET(n)) +#define STM32_OTG_DOEPTSIZ0 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ0_OFFSET) +#define STM32_OTG_DOEPTSIZ1 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ1_OFFSET) +#define STM32_OTG_DOEPTSIZ2 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ2_OFFSET) +#define STM32_OTG_DOEPTSIZ3 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ3_OFFSET) + +/* Power and clock gating registers */ + +#define STM32_OTG_PCGCCTL (STM32_OTG_BASE+STM32_OTG_PCGCCTL_OFFSET) + +/* Data FIFO (DFIFO) access registers */ + +#define STM32_OTG_DFIFO_DEP(n) (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP_OFFSET(n)) +#define STM32_OTG_DFIFO_HCH(n) (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH_OFFSET(n)) + +#define STM32_OTG_DFIFO_DEP0 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP0_OFFSET) +#define STM32_OTG_DFIFO_HCH0 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH0_OFFSET) + +#define STM32_OTG_DFIFO_DEP1 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP1_OFFSET) +#define STM32_OTG_DFIFO_HCH1 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH1_OFFSET) + +#define STM32_OTG_DFIFO_DEP2 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP2_OFFSET) +#define STM32_OTG_DFIFO_HCH2 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH2_OFFSET) + +#define STM32_OTG_DFIFO_DEP3 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP3_OFFSET) +#define STM32_OTG_DFIFO_HCH3 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH3_OFFSET) + +/* Register Bitfield Definitions ********************************************************************/ +/* Core global control and status registers */ + +/* Control and status register */ + +#define OTG_GOTGCTL_SRQSCS (1 << 0) /* Bit 0: Session request success */ +#define OTG_GOTGCTL_SRQ (1 << 1) /* Bit 1: Session request */ +#define OTG_GOTGCTL_VBVALOEN (1 << 2) /* Bit 2: VBUS valid override enable */ +#define OTG_GOTGCTL_VBVALOVAL (1 << 3) /* Bit 3: VBUS valid override value */ +#define OTG_GOTGCTL_AVALOEN (1 << 4) /* Bit 4: A-peripheral session valid override enable */ +#define OTG_GOTGCTL_AVALOVAL (1 << 5) /* Bit 5: A-peripheral session valid override value */ +#define OTG_GOTGCTL_BVALOEN (1 << 6) /* Bit 6: B-peripheral session valid override enable */ +#define OTG_GOTGCTL_BVALOVAL (1 << 7) /* Bit 7: B-peripheral session valid override value */ +#define OTG_GOTGCTL_HNGSCS (1 << 8) /* Bit 8: Host negotiation success */ +#define OTG_GOTGCTL_HNPRQ (1 << 9) /* Bit 9: HNP request */ +#define OTG_GOTGCTL_HSHNPEN (1 << 10) /* Bit 10: host set HNP enable */ +#define OTG_GOTGCTL_DHNPEN (1 << 11) /* Bit 11: Device HNP enabled */ +#define OTG_GOTGCTL_EHEN (1 << 12) /* Bit 12: Embedded host enable */ + /* Bits 13-15: Reserved, must be kept at reset value */ +#define OTG_GOTGCTL_CIDSTS (1 << 16) /* Bit 16: Connector ID status */ +#define OTG_GOTGCTL_DBCT (1 << 17) /* Bit 17: Long/short debounce time */ +#define OTG_GOTGCTL_ASVLD (1 << 18) /* Bit 18: A-session valid */ +#define OTG_GOTGCTL_BSVLD (1 << 19) /* Bit 19: B-session valid */ +#define OTG_GOTGCTL_OTGVER (1 << 20) /* Bit 20: OTG version */ + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Interrupt register */ + /* Bits 1:0 Reserved, must be kept at reset value */ +#define OTG_GOTGINT_SEDET (1 << 2) /* Bit 2: Session end detected */ + /* Bits 3-7: Reserved, must be kept at reset value */ +#define OTG_GOTGINT_SRSSCHG (1 << 8) /* Bit 8: Session request success status change */ +#define OTG_GOTGINT_HNSSCHG (1 << 9) /* Bit 9: Host negotiation success status change */ + /* Bits 16:10 Reserved, must be kept at reset value */ +#define OTG_GOTGINT_HNGDET (1 << 17) /* Bit 17: Host negotiation detected */ +#define OTG_GOTGINT_ADTOCHG (1 << 18) /* Bit 18: A-device timeout change */ +#define OTG_GOTGINT_DBCDNE (1 << 19) /* Bit 19: Debounce done */ +#define OTG_GOTGINT_IDCHNG (1 << 20) /* Bit 20: Change in ID pin input value */ + /* Bits 21-31: Reserved, must be kept at reset value */ + +/* AHB configuration register */ + +#define OTG_GAHBCFG_GINTMSK (1 << 0) /* Bit 0: Global interrupt mask */ + /* Bits 1-6: Reserved, must be kept at reset value */ +#define OTG_GAHBCFG_TXFELVL (1 << 7) /* Bit 7: TxFIFO empty level */ +#define OTG_GAHBCFG_PTXFELVL (1 << 8) /* Bit 8: Periodic TxFIFO empty level */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* USB configuration register */ + +#define OTG_GUSBCFG_TOCAL_SHIFT (0) /* Bits 0-2: FS timeout calibration */ +#define OTG_GUSBCFG_TOCAL_MASK (7 << OTG_GUSBCFG_TOCAL_SHIFT) + /* Bits 3-5: Reserved, must be kept at reset value */ +#define OTG_GUSBCFG_PHYSEL (1 << 6) /* Bit 6: Full Speed serial transceiver select */ + /* Bit 7: Reserved, must be kept at reset value */ +#define OTG_GUSBCFG_SRPCAP (1 << 8) /* Bit 8: SRP-capable */ +#define OTG_GUSBCFG_HNPCAP (1 << 9) /* Bit 9: HNP-capable */ +#define OTG_GUSBCFG_TRDT_SHIFT (10) /* Bits 10-13: USB turnaround time */ +#define OTG_GUSBCFG_TRDT_MASK (15 << OTG_GUSBCFG_TRDT_SHIFT) +# define OTG_GUSBCFG_TRDT(n) ((n) << OTG_GUSBCFG_TRDT_SHIFT) + /* Bits 14-28: Reserved, must be kept at reset value */ +#define OTG_GUSBCFG_FHMOD (1 << 29) /* Bit 29: Force host mode */ +#define OTG_GUSBCFG_FDMOD (1 << 30) /* Bit 30: Force device mode */ +#define OTG_GUSBCFG_CTXPKT (1 << 31) /* Bit 31: Corrupt Tx packet */ + /* Bits 20-31: Reserved, must be kept at reset value */ +/* Reset register */ + +#define OTG_GRSTCTL_CSRST (1 << 0) /* Bit 0: Core soft reset */ +#define OTG_GRSTCTL_HSRST (1 << 1) /* Bit 1: HCLK soft reset */ +#define OTG_GRSTCTL_FCRST (1 << 2) /* Bit 2: Host frame counter reset */ + /* Bit 3 Reserved, must be kept at reset value */ +#define OTG_GRSTCTL_RXFFLSH (1 << 4) /* Bit 4: RxFIFO flush */ +#define OTG_GRSTCTL_TXFFLSH (1 << 5) /* Bit 5: TxFIFO flush */ +#define OTG_GRSTCTL_TXFNUM_SHIFT (6) /* Bits 6-10: TxFIFO number */ +#define OTG_GRSTCTL_TXFNUM_MASK (31 << OTG_GRSTCTL_TXFNUM_SHIFT) +# define OTG_GRSTCTL_TXFNUM_HNONPER (0 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Non-periodic TxFIFO flush in host mode */ +# define OTG_GRSTCTL_TXFNUM_HPER (1 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Periodic TxFIFO flush in host mode */ +# define OTG_GRSTCTL_TXFNUM_HALL (16 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in host mode.*/ +# define OTG_GRSTCTL_TXFNUM_D(n) ((n) << OTG_GRSTCTL_TXFNUM_SHIFT) /* TXFIFO n flush in device mode, n=0-15 */ +# define OTG_GRSTCTL_TXFNUM_DALL (16 << OTG_GRSTCTL_TXFNUM_SHIFT) /* Flush all the transmit FIFOs in device mode.*/ + /* Bits 11-31: Reserved, must be kept at reset value */ +#define OTG_GRSTCTL_AHBIDL (1 << 31) /* Bit 31: AHB master idle */ + +/* Core interrupt and Interrupt mask registers */ + +#define OTG_GINTSTS_CMOD (1 << 0) /* Bit 0: Current mode of operation */ +# define OTG_GINTSTS_DEVMODE (0) +# define OTG_GINTSTS_HOSTMODE (OTG_GINTSTS_CMOD) +#define OTG_GINT_MMIS (1 << 1) /* Bit 1: Mode mismatch interrupt */ +#define OTG_GINT_OTG (1 << 2) /* Bit 2: OTG interrupt */ +#define OTG_GINT_SOF (1 << 3) /* Bit 3: Start of frame */ +#define OTG_GINT_RXFLVL (1 << 4) /* Bit 4: RxFIFO non-empty */ +#define OTG_GINT_NPTXFE (1 << 5) /* Bit 5: Non-periodic TxFIFO empty */ +#define OTG_GINT_GINAKEFF (1 << 6) /* Bit 6: Global IN non-periodic NAK effective */ +#define OTG_GINT_GONAKEFF (1 << 7) /* Bit 7: Global OUT NAK effective */ + /* Bits 8-9: Reserved, must be kept at reset value */ +#define OTG_GINT_ESUSP (1 << 10) /* Bit 10: Early suspend */ +#define OTG_GINT_USBSUSP (1 << 11) /* Bit 11: USB suspend */ +#define OTG_GINT_USBRST (1 << 12) /* Bit 12: USB reset */ +#define OTG_GINT_ENUMDNE (1 << 13) /* Bit 13: Enumeration done */ +#define OTG_GINT_ISOODRP (1 << 14) /* Bit 14: Isochronous OUT packet dropped interrupt */ +#define OTG_GINT_EOPF (1 << 15) /* Bit 15: End of periodic frame interrupt */ + /* Bits 16 Reserved, must be kept at reset value */ +#define OTG_GINTMSK_EPMISM (1 << 17) /* Bit 17: Endpoint mismatch interrupt mask */ +#define OTG_GINT_IEP (1 << 18) /* Bit 18: IN endpoint interrupt */ +#define OTG_GINT_OEP (1 << 19) /* Bit 19: OUT endpoint interrupt */ +#define OTG_GINT_IISOIXFR (1 << 20) /* Bit 20: Incomplete isochronous IN transfer */ +#define OTG_GINT_IISOOXFR (1 << 21) /* Bit 21: Incomplete isochronous OUT transfer (device) */ +#define OTG_GINT_IPXFR (1 << 21) /* Bit 21: Incomplete periodic transfer (host) */ + /* Bit 22: Reserved, must be kept at reset value */ +#define OTG_GINT_RSTDET (1 << 23) /* Bit 23: Reset detected interrupt */ +#define OTG_GINT_HPRT (1 << 24) /* Bit 24: Host port interrupt */ +#define OTG_GINT_HC (1 << 25) /* Bit 25: Host channels interrupt */ +#define OTG_GINT_PTXFE (1 << 26) /* Bit 26: Periodic TxFIFO empty */ +#define OTG_GINT_LPMINT (1 << 27) /* Bit 27: LPM interrupt */ +#define OTG_GINT_CIDSCHG (1 << 28) /* Bit 28: Connector ID status change */ +#define OTG_GINT_DISC (1 << 29) /* Bit 29: Disconnect detected interrupt */ +#define OTG_GINT_SRQ (1 << 30) /* Bit 30: Session request/new session detected interrupt */ +#define OTG_GINT_WKUP (1 << 31) /* Bit 31: Resume/remote wakeup detected interrupt */ + +/* Receive status debug read/OTG status read and pop registers (host mode) */ + +#define OTG_GRXSTSH_CHNUM_SHIFT (0) /* Bits 0-3: Channel number */ +#define OTG_GRXSTSH_CHNUM_MASK (15 << OTG_GRXSTSH_CHNUM_SHIFT) +#define OTG_GRXSTSH_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTG_GRXSTSH_BCNT_MASK (0x7ff << OTG_GRXSTSH_BCNT_SHIFT) +#define OTG_GRXSTSH_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTG_GRXSTSH_DPID_MASK (3 << OTG_GRXSTSH_DPID_SHIFT) +# define OTG_GRXSTSH_DPID_DATA0 (0 << OTG_GRXSTSH_DPID_SHIFT) +# define OTG_GRXSTSH_DPID_DATA2 (1 << OTG_GRXSTSH_DPID_SHIFT) +# define OTG_GRXSTSH_DPID_DATA1 (2 << OTG_GRXSTSH_DPID_SHIFT) +# define OTG_GRXSTSH_DPID_MDATA (3 << OTG_GRXSTSH_DPID_SHIFT) +#define OTG_GRXSTSH_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTG_GRXSTSH_PKTSTS_MASK (15 << OTG_GRXSTSH_PKTSTS_SHIFT) +# define OTG_GRXSTSH_PKTSTS_INRECVD (2 << OTG_GRXSTSH_PKTSTS_SHIFT) /* IN data packet received */ +# define OTG_GRXSTSH_PKTSTS_INDONE (3 << OTG_GRXSTSH_PKTSTS_SHIFT) /* IN transfer completed */ +# define OTG_GRXSTSH_PKTSTS_DTOGERR (5 << OTG_GRXSTSH_PKTSTS_SHIFT) /* Data toggle error */ +# define OTG_GRXSTSH_PKTSTS_HALTED (7 << OTG_GRXSTSH_PKTSTS_SHIFT) /* Channel halted */ + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Receive status debug read/OTG status read and pop registers (device mode) */ + +#define OTG_GRXSTSD_EPNUM_SHIFT (0) /* Bits 0-3: Endpoint number */ +#define OTG_GRXSTSD_EPNUM_MASK (15 << OTG_GRXSTSD_EPNUM_SHIFT) +#define OTG_GRXSTSD_BCNT_SHIFT (4) /* Bits 4-14: Byte count */ +#define OTG_GRXSTSD_BCNT_MASK (0x7ff << OTG_GRXSTSD_BCNT_SHIFT) +#define OTG_GRXSTSD_DPID_SHIFT (15) /* Bits 15-16: Data PID */ +#define OTG_GRXSTSD_DPID_MASK (3 << OTG_GRXSTSD_DPID_SHIFT) +# define OTG_GRXSTSD_DPID_DATA0 (0 << OTG_GRXSTSD_DPID_SHIFT) +# define OTG_GRXSTSD_DPID_DATA2 (1 << OTG_GRXSTSD_DPID_SHIFT) +# define OTG_GRXSTSD_DPID_DATA1 (2 << OTG_GRXSTSD_DPID_SHIFT) +# define OTG_GRXSTSD_DPID_MDATA (3 << OTG_GRXSTSD_DPID_SHIFT) +#define OTG_GRXSTSD_PKTSTS_SHIFT (17) /* Bits 17-20: Packet status */ +#define OTG_GRXSTSD_PKTSTS_MASK (15 << OTG_GRXSTSD_PKTSTS_SHIFT) +# define OTG_GRXSTSD_PKTSTS_OUTNAK (1 << OTG_GRXSTSD_PKTSTS_SHIFT) /* Global OUT NAK */ +# define OTG_GRXSTSD_PKTSTS_OUTRECVD (2 << OTG_GRXSTSD_PKTSTS_SHIFT) /* OUT data packet received */ +# define OTG_GRXSTSD_PKTSTS_OUTDONE (3 << OTG_GRXSTSD_PKTSTS_SHIFT) /* OUT transfer completed */ +# define OTG_GRXSTSD_PKTSTS_SETUPDONE (4 << OTG_GRXSTSD_PKTSTS_SHIFT) /* SETUP transaction completed */ +# define OTG_GRXSTSD_PKTSTS_SETUPRECVD (6 << OTG_GRXSTSD_PKTSTS_SHIFT) /* SETUP data packet received */ +#define OTG_GRXSTSD_FRMNUM_SHIFT (21) /* Bits 21-24: Frame number */ +#define OTG_GRXSTSD_FRMNUM_MASK (15 << OTG_GRXSTSD_FRMNUM_SHIFT) + /* Bits 25-31: Reserved, must be kept at reset value */ +/* Receive FIFO size register */ + +#define OTG_GRXFSIZ_MASK (0xffff) + +/* Host non-periodic transmit FIFO size register */ + +#define OTG_HNPTXFSIZ_NPTXFSA_SHIFT (0) /* Bits 0-15: Non-periodic transmit RAM start address */ +#define OTG_HNPTXFSIZ_NPTXFSA_MASK (0xffff << OTG_HNPTXFSIZ_NPTXFSA_SHIFT) +#define OTG_HNPTXFSIZ_NPTXFD_SHIFT (16) /* Bits 16-31: Non-periodic TxFIFO depth */ +#define OTG_HNPTXFSIZ_NPTXFD_MASK (0xffff << OTG_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTG_HNPTXFSIZ_NPTXFD_MIN (16 << OTG_HNPTXFSIZ_NPTXFD_SHIFT) +# define OTG_HNPTXFSIZ_NPTXFD_MAX (256 << OTG_HNPTXFSIZ_NPTXFD_SHIFT) + +/* Endpoint 0 Transmit FIFO size */ + +#define OTG_DIEPTXF0_TX0FD_SHIFT (0) /* Bits 0-15: Endpoint 0 transmit RAM start address */ +#define OTG_DIEPTXF0_TX0FD_MASK (0xffff << OTG_DIEPTXF0_TX0FD_SHIFT) +#define OTG_DIEPTXF0_TX0FSA_SHIFT (16) /* Bits 16-31: Endpoint 0 TxFIFO depth */ +#define OTG_DIEPTXF0_TX0FSA_MASK (0xffff << OTG_DIEPTXF0_TX0FSA_SHIFT) +# define OTG_DIEPTXF0_TX0FSA_MIN (16 << OTG_DIEPTXF0_TX0FSA_SHIFT) +# define OTG_DIEPTXF0_TX0FSA_MAX (256 << OTG_DIEPTXF0_TX0FSA_SHIFT) + +/* Non-periodic transmit FIFO/queue status register */ + +#define OTG_HNPTXSTS_NPTXFSAV_SHIFT (0) /* Bits 0-15: Non-periodic TxFIFO space available */ +#define OTG_HNPTXSTS_NPTXFSAV_MASK (0xffff << OTG_HNPTXSTS_NPTXFSAV_SHIFT) +# define OTG_HNPTXSTS_NPTXFSAV_FULL (0 << OTG_HNPTXSTS_NPTXFSAV_SHIFT) +#define OTG_HNPTXSTS_NPTQXSAV_SHIFT (16) /* Bits 16-23: Non-periodic transmit request queue space available */ +#define OTG_HNPTXSTS_NPTQXSAV_MASK (0xff << OTG_HNPTXSTS_NPTQXSAV_SHIFT) +# define OTG_HNPTXSTS_NPTQXSAV_FULL (0 << OTG_HNPTXSTS_NPTQXSAV_SHIFT) +#define OTG_HNPTXSTS_NPTXQTOP_SHIFT (24) /* Bits 24-30: Top of the non-periodic transmit request queue */ +#define OTG_HNPTXSTS_NPTXQTOP_MASK (0x7f << OTG_HNPTXSTS_NPTXQTOP_SHIFT) +# define OTG_HNPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTG_HNPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Status */ +# define OTG_HNPTXSTS_TYPE_MASK (3 << OTG_HNPTXSTS_TYPE_SHIFT) +# define OTG_HNPTXSTS_TYPE_INOUT (0 << OTG_HNPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTG_HNPTXSTS_TYPE_ZLP (1 << OTG_HNPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet (device IN/host OUT) */ +# define OTG_HNPTXSTS_TYPE_HALT (3 << OTG_HNPTXSTS_TYPE_SHIFT) /* Channel halt command */ +# define OTG_HNPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTG_HNPTXSTS_CHNUM_MASK (15 << OTG_HNPTXSTS_CHNUM_SHIFT) +# define OTG_HNPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTG_HNPTXSTS_EPNUM_MASK (15 << OTG_HNPTXSTS_EPNUM_SHIFT) + /* Bit 31 Reserved, must be kept at reset value */ +/* General core configuration register */ + /* Bits 0-15: Reserved, must be kept at reset value */ +#define OTG_GCCFG_PWRDWN (1 << 16) /* Bit 16: Power down */ + /* Bit 17 Reserved, must be kept at reset value */ +#define OTG_GCCFG_VBDEN (1 << 21) /* Bit 21: USB VBUS detection enable */ + /* Bits 22-31: Reserved, must be kept at reset value */ +/* Core ID register (32-bit product ID) */ + +/* Host periodic transmit FIFO size register */ + +#define OTG_HPTXFSIZ_PTXSA_SHIFT (0) /* Bits 0-15: Host periodic TxFIFO start address */ +#define OTG_HPTXFSIZ_PTXSA_MASK (0xffff << OTG_HPTXFSIZ_PTXSA_SHIFT) +#define OTG_HPTXFSIZ_PTXFD_SHIFT (16) /* Bits 16-31: Host periodic TxFIFO depth */ +#define OTG_HPTXFSIZ_PTXFD_MASK (0xffff << OTG_HPTXFSIZ_PTXFD_SHIFT) + +/* Device IN endpoint transmit FIFOn size register */ + +#define OTG_DIEPTXF_INEPTXSA_SHIFT (0) /* Bits 0-15: IN endpoint FIFOx transmit RAM start address */ +#define OTG_DIEPTXF_INEPTXSA_MASK (0xffff << OTG_DIEPTXF_INEPTXSA_SHIFT) +#define OTG_DIEPTXF_INEPTXFD_SHIFT (16) /* Bits 16-31: IN endpoint TxFIFO depth */ +#define OTG_DIEPTXF_INEPTXFD_MASK (0xffff << OTG_DIEPTXF_INEPTXFD_SHIFT) +# define OTG_DIEPTXF_INEPTXFD_MIN (16 << OTG_DIEPTXF_INEPTXFD_MASK) + +/* Host-mode control and status registers */ + +/* Host configuration register */ + +#define OTG_HCFG_FSLSPCS_SHIFT (0) /* Bits 0-1: FS/LS PHY clock select */ +#define OTG_HCFG_FSLSPCS_MASK (3 << OTG_HCFG_FSLSPCS_SHIFT) +# define OTG_HCFG_FSLSPCS_FS48MHz (1 << OTG_HCFG_FSLSPCS_SHIFT) /* FS host mode, PHY clock is running at 48 MHz */ +# define OTG_HCFG_FSLSPCS_LS48MHz (1 << OTG_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 48 MHz PHY clock frequency */ +# define OTG_HCFG_FSLSPCS_LS6MHz (2 << OTG_HCFG_FSLSPCS_SHIFT) /* LS host mode, Select 6 MHz PHY clock frequency */ +#define OTG_HCFG_FSLSS (1 << 2) /* Bit 2: FS- and LS-only support */ + /* Bits 31:3 Reserved, must be kept at reset value */ +/* Host frame interval register */ + +#define OTG_HFIR_MASK (0xffff) + +/* Host frame number/frame time remaining register */ + +#define OTG_HFNUM_FRNUM_SHIFT (0) /* Bits 0-15: Frame number */ +#define OTG_HFNUM_FRNUM_MASK (0xffff << OTG_HFNUM_FRNUM_SHIFT) +#define OTG_HFNUM_FTREM_SHIFT (16) /* Bits 16-31: Frame time remaining */ +#define OTG_HFNUM_FTREM_MASK (0xffff << OTG_HFNUM_FTREM_SHIFT) + +/* Host periodic transmit FIFO/queue status register */ + +#define OTG_HPTXSTS_PTXFSAVL_SHIFT (0) /* Bits 0-15: Periodic transmit data FIFO space available */ +#define OTG_HPTXSTS_PTXFSAVL_MASK (0xffff << OTG_HPTXSTS_PTXFSAVL_SHIFT) +# define OTG_HPTXSTS_PTXFSAVL_FULL (0 << OTG_HPTXSTS_PTXFSAVL_SHIFT) +#define OTG_HPTXSTS_PTXQSAV_SHIFT (16) /* Bits 16-23: Periodic transmit request queue space available */ +#define OTG_HPTXSTS_PTXQSAV_MASK (0xff << OTG_HPTXSTS_PTXQSAV_SHIFT) +# define OTG_HPTXSTS_PTXQSAV_FULL (0 << OTG_HPTXSTS_PTXQSAV_SHIFT) +#define OTG_HPTXSTS_PTXQTOP_SHIFT (24) /* Bits 24-31: Top of the periodic transmit request queue */ +#define OTG_HPTXSTS_PTXQTOP_MASK (0x7f << OTG_HPTXSTS_PTXQTOP_SHIFT) +# define OTG_HPTXSTS_TERMINATE (1 << 24) /* Bit 24: Terminate (last entry for selected channel/endpoint) */ +# define OTG_HPTXSTS_TYPE_SHIFT (25) /* Bits 25-26: Type */ +# define OTG_HPTXSTS_TYPE_MASK (3 << OTG_HPTXSTS_TYPE_SHIFT) +# define OTG_HPTXSTS_TYPE_INOUT (0 << OTG_HPTXSTS_TYPE_SHIFT) /* IN/OUT token */ +# define OTG_HPTXSTS_TYPE_ZLP (1 << OTG_HPTXSTS_TYPE_SHIFT) /* Zero-length transmit packet */ +# define OTG_HPTXSTS_TYPE_HALT (3 << OTG_HPTXSTS_TYPE_SHIFT) /* Disable channel command */ +# define OTG_HPTXSTS_EPNUM_SHIFT (27) /* Bits 27-30: Endpoint number */ +# define OTG_HPTXSTS_EPNUM_MASK (15 << OTG_HPTXSTS_EPNUM_SHIFT) +# define OTG_HPTXSTS_CHNUM_SHIFT (27) /* Bits 27-30: Channel number */ +# define OTG_HPTXSTS_CHNUM_MASK (15 << OTG_HPTXSTS_CHNUM_SHIFT) +# define OTG_HPTXSTS_ODD (1 << 24) /* Bit 31: Send in odd (vs even) frame */ + +/* Host all channels interrupt and all channels interrupt mask registers */ + +#define OTG_HAINT(n) (1 << (n)) /* Bits 15:0 HAINTM: Channel interrupt */ + +/* Host port control and status register */ + +#define OTG_HPRT_PCSTS (1 << 0) /* Bit 0: Port connect status */ +#define OTG_HPRT_PCDET (1 << 1) /* Bit 1: Port connect detected */ +#define OTG_HPRT_PENA (1 << 2) /* Bit 2: Port enable */ +#define OTG_HPRT_PENCHNG (1 << 3) /* Bit 3: Port enable/disable change */ +#define OTG_HPRT_POCA (1 << 4) /* Bit 4: Port overcurrent active */ +#define OTG_HPRT_POCCHNG (1 << 5) /* Bit 5: Port overcurrent change */ +#define OTG_HPRT_PRES (1 << 6) /* Bit 6: Port resume */ +#define OTG_HPRT_PSUSP (1 << 7) /* Bit 7: Port suspend */ +#define OTG_HPRT_PRST (1 << 8) /* Bit 8: Port reset */ + /* Bit 9: Reserved, must be kept at reset value */ +#define OTG_HPRT_PLSTS_SHIFT (10) /* Bits 10-11: Port line status */ +#define OTG_HPRT_PLSTS_MASK (3 << OTG_HPRT_PLSTS_SHIFT) +# define OTG_HPRT_PLSTS_DP (1 << 10) /* Bit 10: Logic level of OTG_FS_FS_DP */ +# define OTG_HPRT_PLSTS_DM (1 << 11) /* Bit 11: Logic level of OTG_FS_FS_DM */ +#define OTG_HPRT_PPWR (1 << 12) /* Bit 12: Port power */ +#define OTG_HPRT_PTCTL_SHIFT (13) /* Bits 13-16: Port test control */ +#define OTG_HPRT_PTCTL_MASK (15 << OTG_HPRT_PTCTL_SHIFT) +# define OTG_HPRT_PTCTL_DISABLED (0 << OTG_HPRT_PTCTL_SHIFT) /* Test mode disabled */ +# define OTG_HPRT_PTCTL_J (1 << OTG_HPRT_PTCTL_SHIFT) /* Test_J mode */ +# define OTG_HPRT_PTCTL_L (2 << OTG_HPRT_PTCTL_SHIFT) /* Test_K mode */ +# define OTG_HPRT_PTCTL_SE0_NAK (3 << OTG_HPRT_PTCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTG_HPRT_PTCTL_PACKET (4 << OTG_HPRT_PTCTL_SHIFT) /* Test_Packet mode */ +# define OTG_HPRT_PTCTL_FORCE (5 << OTG_HPRT_PTCTL_SHIFT) /* Test_Force_Enable */ +#define OTG_HPRT_PSPD_SHIFT (17) /* Bits 17-18: Port speed */ +#define OTG_HPRT_PSPD_MASK (3 << OTG_HPRT_PSPD_SHIFT) +# define OTG_HPRT_PSPD_FS (1 << OTG_HPRT_PSPD_SHIFT) /* Full speed */ +# define OTG_HPRT_PSPD_LS (2 << OTG_HPRT_PSPD_SHIFT) /* Low speed */ + /* Bits 19-31: Reserved, must be kept at reset value */ + +/* Host channel-n characteristics register */ + +#define OTG_HCCHAR_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTG_HCCHAR_MPSIZ_MASK (0x7ff << OTG_HCCHAR_MPSIZ_SHIFT) +#define OTG_HCCHAR_EPNUM_SHIFT (11) /* Bits 11-14: Endpoint number */ +#define OTG_HCCHAR_EPNUM_MASK (15 << OTG_HCCHAR_EPNUM_SHIFT) +#define OTG_HCCHAR_EPDIR (1 << 15) /* Bit 15: Endpoint direction */ +# define OTG_HCCHAR_EPDIR_OUT (0) +# define OTG_HCCHAR_EPDIR_IN OTG_HCCHAR_EPDIR + /* Bit 16 Reserved, must be kept at reset value */ +#define OTG_HCCHAR_LSDEV (1 << 17) /* Bit 17: Low-speed device */ +#define OTG_HCCHAR_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTG_HCCHAR_EPTYP_MASK (3 << OTG_HCCHAR_EPTYP_SHIFT) +# define OTG_HCCHAR_EPTYP_CTRL (0 << OTG_HCCHAR_EPTYP_SHIFT) /* Control */ +# define OTG_HCCHAR_EPTYP_ISOC (1 << OTG_HCCHAR_EPTYP_SHIFT) /* Isochronous */ +# define OTG_HCCHAR_EPTYP_BULK (2 << OTG_HCCHAR_EPTYP_SHIFT) /* Bulk */ +# define OTG_HCCHAR_EPTYP_INTR (3 << OTG_HCCHAR_EPTYP_SHIFT) /* Interrupt */ +#define OTG_HCCHAR_MCNT_SHIFT (20) /* Bits 20-21: Multicount */ +#define OTG_HCCHAR_MCNT_MASK (3 << OTG_HCCHAR_MCNT_SHIFT) +#define OTG_HCCHAR_DAD_SHIFT (22) /* Bits 22-28: Device address */ +#define OTG_HCCHAR_DAD_MASK (0x7f << OTG_HCCHAR_DAD_SHIFT) +#define OTG_HCCHAR_ODDFRM (1 << 29) /* Bit 29: Odd frame */ +#define OTG_HCCHAR_CHDIS (1 << 30) /* Bit 30: Channel disable */ +#define OTG_HCCHAR_CHENA (1 << 31) /* Bit 31: Channel enable */ + +/* Host channel-n interrupt and Host channel-0 interrupt mask registers */ + +#define OTG_HCINT_XFRC (1 << 0) /* Bit 0: Transfer completed */ +#define OTG_HCINT_CHH (1 << 1) /* Bit 1: Channel halted */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTG_HCINT_STALL (1 << 3) /* Bit 3: STALL response received interrupt */ +#define OTG_HCINT_NAK (1 << 4) /* Bit 4: NAK response received interrupt */ +#define OTG_HCINT_ACK (1 << 5) /* Bit 5: ACK response received/transmitted interrupt */ +#define OTG_HCINT_NYET (1 << 6) /* Bit 6: Response received interrupt */ +#define OTG_HCINT_TXERR (1 << 7) /* Bit 7: Transaction error */ +#define OTG_HCINT_BBERR (1 << 8) /* Bit 8: Babble error */ +#define OTG_HCINT_FRMOR (1 << 9) /* Bit 9: Frame overrun */ +#define OTG_HCINT_DTERR (1 << 10) /* Bit 10: Data toggle error */ + /* Bits 11-31 Reserved, must be kept at reset value */ +/* Host channel-n interrupt register */ + +#define OTG_HCTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTG_HCTSIZ_XFRSIZ_MASK (0x7ffff << OTG_HCTSIZ_XFRSIZ_SHIFT) +#define OTG_HCTSIZ_PKTCNT_SHIFT (19) /* Bits 19-28: Packet count */ +#define OTG_HCTSIZ_PKTCNT_MASK (0x3ff << OTG_HCTSIZ_PKTCNT_SHIFT) +#define OTG_HCTSIZ_DPID_SHIFT (29) /* Bits 29-30: Data PID */ +#define OTG_HCTSIZ_DPID_MASK (3 << OTG_HCTSIZ_DPID_SHIFT) +# define OTG_HCTSIZ_DPID_DATA0 (0 << OTG_HCTSIZ_DPID_SHIFT) +# define OTG_HCTSIZ_DPID_DATA2 (1 << OTG_HCTSIZ_DPID_SHIFT) +# define OTG_HCTSIZ_DPID_DATA1 (2 << OTG_HCTSIZ_DPID_SHIFT) +# define OTG_HCTSIZ_DPID_MDATA (3 << OTG_HCTSIZ_DPID_SHIFT) /* Non-control */ +# define OTG_HCTSIZ_PID_SETUP (3 << OTG_HCTSIZ_DPID_SHIFT) /* Control */ + /* Bit 31 Reserved, must be kept at reset value */ +/* Device-mode control and status registers */ + +/* Device configuration register */ + +#define OTG_DCFG_DSPD_SHIFT (0) /* Bits 0-1: Device speed */ +#define OTG_DCFG_DSPD_MASK (3 << OTG_DCFG_DSPD_SHIFT) +# define OTG_DCFG_DSPD_FS (3 << OTG_DCFG_DSPD_SHIFT) /* Full speed */ +#define OTG_DCFG_NZLSOHSK (1 << 2) /* Bit 2: Non-zero-length status OUT handshake */ + /* Bit 3: Reserved, must be kept at reset value */ +#define OTG_DCFG_DAD_SHIFT (4) /* Bits 4-10: Device address */ +#define OTG_DCFG_DAD_MASK (0x7f << OTG_DCFG_DAD_SHIFT) +#define OTG_DCFG_PFIVL_SHIFT (11) /* Bits 11-12: Periodic frame interval */ +#define OTG_DCFG_PFIVL_MASK (3 << OTG_DCFG_PFIVL_SHIFT) +# define OTG_DCFG_PFIVL_80PCT (0 << OTG_DCFG_PFIVL_SHIFT) /* 80% of the frame interval */ +# define OTG_DCFG_PFIVL_85PCT (1 << OTG_DCFG_PFIVL_SHIFT) /* 85% of the frame interval */ +# define OTG_DCFG_PFIVL_90PCT (2 << OTG_DCFG_PFIVL_SHIFT) /* 90% of the frame interval */ +# define OTG_DCFG_PFIVL_95PCT (3 << OTG_DCFG_PFIVL_SHIFT) /* 95% of the frame interval */ + /* Bits 13-31 Reserved, must be kept at reset value */ +/* Device control register */ + +#define OTG_TESTMODE_DISABLED (0) /* Test mode disabled */ +#define OTG_TESTMODE_J (1) /* Test_J mode */ +#define OTG_TESTMODE_K (2) /* Test_K mode */ +#define OTG_TESTMODE_SE0_NAK (3) /* Test_SE0_NAK mode */ +#define OTG_TESTMODE_PACKET (4) /* Test_Packet mode */ +#define OTG_TESTMODE_FORCE (5) /* Test_Force_Enable */ + +#define OTG_DCTL_RWUSIG (1 << 0) /* Bit 0: Remote wakeup signaling */ +#define OTG_DCTL_SDIS (1 << 1) /* Bit 1: Soft disconnect */ +#define OTG_DCTL_GINSTS (1 << 2) /* Bit 2: Global IN NAK status */ +#define OTG_DCTL_GONSTS (1 << 3) /* Bit 3: Global OUT NAK status */ +#define OTG_DCTL_TCTL_SHIFT (4) /* Bits 4-6: Test control */ +#define OTG_DCTL_TCTL_MASK (7 << OTG_DCTL_TCTL_SHIFT) +# define OTG_DCTL_TCTL_DISABLED (0 << OTG_DCTL_TCTL_SHIFT) /* Test mode disabled */ +# define OTG_DCTL_TCTL_J (1 << OTG_DCTL_TCTL_SHIFT) /* Test_J mode */ +# define OTG_DCTL_TCTL_K (2 << OTG_DCTL_TCTL_SHIFT) /* Test_K mode */ +# define OTG_DCTL_TCTL_SE0_NAK (3 << OTG_DCTL_TCTL_SHIFT) /* Test_SE0_NAK mode */ +# define OTG_DCTL_TCTL_PACKET (4 << OTG_DCTL_TCTL_SHIFT) /* Test_Packet mode */ +# define OTG_DCTL_TCTL_FORCE (5 << OTG_DCTL_TCTL_SHIFT) /* Test_Force_Enable */ +#define OTG_DCTL_SGINAK (1 << 7) /* Bit 7: Set global IN NAK */ +#define OTG_DCTL_CGINAK (1 << 8) /* Bit 8: Clear global IN NAK */ +#define OTG_DCTL_SGONAK (1 << 9) /* Bit 9: Set global OUT NAK */ +#define OTG_DCTL_CGONAK (1 << 10) /* Bit 10: Clear global OUT NAK */ +#define OTG_DCTL_POPRGDNE (1 << 11) /* Bit 11: Power-on programming done */ + /* Bits 12-31: Reserved, must be kept at reset value */ +/* Device status register */ + +#define OTG_DSTS_SUSPSTS (1 << 0) /* Bit 0: Suspend status */ +#define OTG_DSTS_ENUMSPD_SHIFT (1) /* Bits 1-2: Enumerated speed */ +#define OTG_DSTS_ENUMSPD_MASK (3 << OTG_DSTS_ENUMSPD_SHIFT) +# define OTG_DSTS_ENUMSPD_FS (3 << OTG_DSTS_ENUMSPD_MASK) /* Full speed */ + /* Bits 4-7: Reserved, must be kept at reset value */ +#define OTG_DSTS_EERR (1 << 3) /* Bit 3: Erratic error */ +#define OTG_DSTS_SOFFN_SHIFT (8) /* Bits 8-21: Frame number of the received SOF */ +#define OTG_DSTS_SOFFN_MASK (0x3fff << OTG_DSTS_SOFFN_SHIFT) +#define OTG_DSTS_SOFFN0 (1 << 8) /* Bits 8: Frame number even/odd bit */ +#define OTG_DSTS_SOFFN_EVEN 0 +#define OTG_DSTS_SOFFN_ODD OTG_DSTS_SOFFN0 + /* Bits 22-31: Reserved, must be kept at reset value */ +/* Device IN endpoint common interrupt mask register */ + +#define OTG_DIEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTG_DIEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTG_DIEPMSK_TOM (1 << 3) /* Bit 3: Timeout condition mask (Non-isochronous endpoints) */ +#define OTG_DIEPMSK_ITTXFEMSK (1 << 4) /* Bit 4: IN token received when TxFIFO empty mask */ +#define OTG_DIEPMSK_INEPNMM (1 << 5) /* Bit 5: IN token received with EP mismatch mask */ +#define OTG_DIEPMSK_INEPNEM (1 << 6) /* Bit 6: IN endpoint NAK effective mask */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint common interrupt mask register */ + +#define OTG_DOEPMSK_XFRCM (1 << 0) /* Bit 0: Transfer completed interrupt mask */ +#define OTG_DOEPMSK_EPDM (1 << 1) /* Bit 1: Endpoint disabled interrupt mask */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTG_DOEPMSK_STUPM (1 << 3) /* Bit 3: SETUP phase done mask */ +#define OTG_DOEPMSK_OTEPDM (1 << 4) /* Bit 4: OUT token received when endpoint disabled mask */ + /* Bits 5-31: Reserved, must be kept at reset value */ +/* Device all endpoints interrupt and All endpoints interrupt mask registers */ + +#define OTG_DAINT_IEP_SHIFT (0) /* Bits 0-15: IN endpoint interrupt bits */ +#define OTG_DAINT_IEP_MASK (0xffff << OTG_DAINT_IEP_SHIFT) +# define OTG_DAINT_IEP(n) (1 << (n)) +#define OTG_DAINT_OEP_SHIFT (16) /* Bits 16-31: OUT endpoint interrupt bits */ +#define OTG_DAINT_OEP_MASK (0xffff << OTG_DAINT_OEP_SHIFT) +# define OTG_DAINT_OEP(n) (1 << ((n)+16)) + +/* Device VBUS discharge time register */ + +#define OTG_DVBUSDIS_MASK (0xffff) + +/* Device VBUS pulsing time register */ + +#define OTG_DVBUSPULSE_MASK (0xfff) + +/* Device IN endpoint FIFO empty interrupt mask register */ + +#define OTG_DIEPEMPMSK(n) (1 << (n)) + +/* Device control IN endpoint 0 control register */ + +#define OTG_DIEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTG_DIEPCTL0_MPSIZ_MASK (3 << OTG_DIEPCTL0_MPSIZ_SHIFT) +# define OTG_DIEPCTL0_MPSIZ_64 (0 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTG_DIEPCTL0_MPSIZ_32 (1 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTG_DIEPCTL0_MPSIZ_16 (2 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTG_DIEPCTL0_MPSIZ_8 (3 << OTG_DIEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTG_DIEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTG_DIEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTG_DIEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTG_DIEPCTL0_EPTYP_MASK (3 << OTG_DIEPCTL0_EPTYP_SHIFT) +# define OTG_DIEPCTL0_EPTYP_CTRL (0 << OTG_DIEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTG_DIEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTG_DIEPCTL0_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTG_DIEPCTL0_TXFNUM_MASK (15 << OTG_DIEPCTL0_TXFNUM_SHIFT) +#define OTG_DIEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTG_DIEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTG_DIEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTG_DIEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device control IN endpoint n control register */ + +#define OTG_DIEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTG_DIEPCTL_MPSIZ_MASK (0x7ff << OTG_DIEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTG_DIEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTG_DIEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame */ +# define OTG_DIEPCTL_EVEN (0) +# define OTG_DIEPCTL_ODD OTG_DIEPCTL_EONUM +# define OTG_DIEPCTL_DATA0 (0) +# define OTG_DIEPCTL_DATA1 OTG_DIEPCTL_EONUM +#define OTG_DIEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTG_DIEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTG_DIEPCTL_EPTYP_MASK (3 << OTG_DIEPCTL_EPTYP_SHIFT) +# define OTG_DIEPCTL_EPTYP_CTRL (0 << OTG_DIEPCTL_EPTYP_SHIFT) /* Control */ +# define OTG_DIEPCTL_EPTYP_ISOC (1 << OTG_DIEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTG_DIEPCTL_EPTYP_BULK (2 << OTG_DIEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTG_DIEPCTL_EPTYP_INTR (3 << OTG_DIEPCTL_EPTYP_SHIFT) /* Interrupt */ + /* Bit 20: Reserved, must be kept at reset value */ +#define OTG_DIEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ +#define OTG_DIEPCTL_TXFNUM_SHIFT (22) /* Bits 22-25: TxFIFO number */ +#define OTG_DIEPCTL_TXFNUM_MASK (15 << OTG_DIEPCTL_TXFNUM_SHIFT) +#define OTG_DIEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTG_DIEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTG_DIEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTG_DIEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous)) */ +#define OTG_DIEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous) */ +#define OTG_DIEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTG_DIEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTG_DIEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTG_DIEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTG_DIEPINT_TOC (1 << 3) /* Bit 3: Timeout condition */ +#define OTG_DIEPINT_ITTXFE (1 << 4) /* Bit 4: IN token received when TxFIFO is empty */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTG_DIEPINT_INEPNE (1 << 6) /* Bit 6: IN endpoint NAK effective */ +#define OTG_DIEPINT_TXFE (1 << 7) /* Bit 7: Transmit FIFO empty */ + /* Bits 8-31: Reserved, must be kept at reset value */ +/* Device IN endpoint 0 transfer size register */ + +#define OTG_DIEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTG_DIEPTSIZ0_XFRSIZ_MASK (0x7f << OTG_DIEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTG_DIEPTSIZ0_PKTCNT_SHIFT (19) /* Bits 19-20: Packet count */ +#define OTG_DIEPTSIZ0_PKTCNT_MASK (3 << OTG_DIEPTSIZ0_PKTCNT_SHIFT) + /* Bits 21-31: Reserved, must be kept at reset value */ +/* Device IN endpoint n transfer size register */ + +#define OTG_DIEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTG_DIEPTSIZ_XFRSIZ_MASK (0x7ffff << OTG_DIEPTSIZ_XFRSIZ_SHIFT) +#define OTG_DIEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTG_DIEPTSIZ_PKTCNT_MASK (0x3ff << OTG_DIEPTSIZ_PKTCNT_SHIFT) +#define OTG_DIEPTSIZ_MCNT_SHIFT (29) /* Bits 29-30: Multi count */ +#define OTG_DIEPTSIZ_MCNT_MASK (3 << OTG_DIEPTSIZ_MCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint TxFIFO status register */ + +#define OTG_DTXFSTS_MASK (0xffff) + +/* Device OUT endpoint 0 control register */ + +#define OTG_DOEPCTL0_MPSIZ_SHIFT (0) /* Bits 0-1: Maximum packet size */ +#define OTG_DOEPCTL0_MPSIZ_MASK (3 << OTG_DOEPCTL0_MPSIZ_SHIFT) +# define OTG_DOEPCTL0_MPSIZ_64 (0 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 64 bytes */ +# define OTG_DOEPCTL0_MPSIZ_32 (1 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 32 bytes */ +# define OTG_DOEPCTL0_MPSIZ_16 (2 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 16 bytes */ +# define OTG_DOEPCTL0_MPSIZ_8 (3 << OTG_DOEPCTL0_MPSIZ_SHIFT) /* 8 bytes */ + /* Bits 2-14: Reserved, must be kept at reset value */ +#define OTG_DOEPCTL0_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ + /* Bit 16: Reserved, must be kept at reset value */ +#define OTG_DOEPCTL0_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTG_DOEPCTL0_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTG_DOEPCTL0_EPTYP_MASK (3 << OTG_DOEPCTL0_EPTYP_SHIFT) +# define OTG_DOEPCTL0_EPTYP_CTRL (0 << OTG_DOEPCTL0_EPTYP_SHIFT) /* Control (hard-coded) */ +#define OTG_DOEPCTL0_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTG_DOEPCTL0_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTG_DOEPCTL0_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTG_DOEPCTL0_SNAK (1 << 27) /* Bit 27: Set NAK */ + /* Bits 28-29: Reserved, must be kept at reset value */ +#define OTG_DOEPCTL0_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTG_DOEPCTL0_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device OUT endpoint n control register */ + +#define OTG_DOEPCTL_MPSIZ_SHIFT (0) /* Bits 0-10: Maximum packet size */ +#define OTG_DOEPCTL_MPSIZ_MASK (0x7ff << OTG_DOEPCTL_MPSIZ_SHIFT) + /* Bits 11-14: Reserved, must be kept at reset value */ +#define OTG_DOEPCTL_USBAEP (1 << 15) /* Bit 15: USB active endpoint */ +#define OTG_DOEPCTL_DPID (1 << 16) /* Bit 16: Endpoint data PID (interrupt/buld) */ +# define OTG_DOEPCTL_DATA0 (0) +# define OTG_DOEPCTL_DATA1 OTG_DOEPCTL_DPID +#define OTG_DOEPCTL_EONUM (1 << 16) /* Bit 16: Even/odd frame (isochronous) */ +# define OTG_DOEPCTL_EVEN (0) +# define OTG_DOEPCTL_ODD OTG_DOEPCTL_EONUM +#define OTG_DOEPCTL_NAKSTS (1 << 17) /* Bit 17: NAK status */ +#define OTG_DOEPCTL_EPTYP_SHIFT (18) /* Bits 18-19: Endpoint type */ +#define OTG_DOEPCTL_EPTYP_MASK (3 << OTG_DOEPCTL_EPTYP_SHIFT) +# define OTG_DOEPCTL_EPTYP_CTRL (0 << OTG_DOEPCTL_EPTYP_SHIFT) /* Control */ +# define OTG_DOEPCTL_EPTYP_ISOC (1 << OTG_DOEPCTL_EPTYP_SHIFT) /* Isochronous */ +# define OTG_DOEPCTL_EPTYP_BULK (2 << OTG_DOEPCTL_EPTYP_SHIFT) /* Bulk */ +# define OTG_DOEPCTL_EPTYP_INTR (3 << OTG_DOEPCTL_EPTYP_SHIFT) /* Interrupt */ +#define OTG_DOEPCTL_SNPM (1 << 20) /* Bit 20: Snoop mode */ +#define OTG_DOEPCTL_STALL (1 << 21) /* Bit 21: STALL handshake */ + /* Bits 22-25: Reserved, must be kept at reset value */ +#define OTG_DOEPCTL_CNAK (1 << 26) /* Bit 26: Clear NAK */ +#define OTG_DOEPCTL_SNAK (1 << 27) /* Bit 27: Set NAK */ +#define OTG_DOEPCTL_SD0PID (1 << 28) /* Bit 28: Set DATA0 PID (interrupt/bulk) */ +#define OTG_DOEPCTL_SEVNFRM (1 << 28) /* Bit 28: Set even frame (isochronous) */ +#define OTG_DOEPCTL_SD1PID (1 << 29) /* Bit 29: Set DATA1 PID (interrupt/bulk) */ +#define OTG_DOEPCTL_SODDFRM (1 << 29) /* Bit 29: Set odd frame (isochronous */ +#define OTG_DOEPCTL_EPDIS (1 << 30) /* Bit 30: Endpoint disable */ +#define OTG_DOEPCTL_EPENA (1 << 31) /* Bit 31: Endpoint enable */ + +/* Device endpoint-n interrupt register */ + +#define OTG_DOEPINT_XFRC (1 << 0) /* Bit 0: Transfer completed interrupt */ +#define OTG_DOEPINT_EPDISD (1 << 1) /* Bit 1: Endpoint disabled interrupt */ + /* Bit 2: Reserved, must be kept at reset value */ +#define OTG_DOEPINT_SETUP (1 << 3) /* Bit 3: SETUP phase done */ +#define OTG_DOEPINT_OTEPDIS (1 << 4) /* Bit 4: OUT token received when endpoint disabled */ + /* Bit 5: Reserved, must be kept at reset value */ +#define OTG_DOEPINT_B2BSTUP (1 << 6) /* Bit 6: Back-to-back SETUP packets received */ + /* Bits 7-31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-0 transfer size register */ + +#define OTG_DOEPTSIZ0_XFRSIZ_SHIFT (0) /* Bits 0-6: Transfer size */ +#define OTG_DOEPTSIZ0_XFRSIZ_MASK (0x7f << OTG_DOEPTSIZ0_XFRSIZ_SHIFT) + /* Bits 7-18: Reserved, must be kept at reset value */ +#define OTG_DOEPTSIZ0_PKTCNT (1 << 19) /* Bit 19 PKTCNT: Packet count */ + /* Bits 20-28: Reserved, must be kept at reset value */ +#define OTG_DOEPTSIZ0_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTG_DOEPTSIZ0_STUPCNT_MASK (3 << OTG_DOEPTSIZ0_STUPCNT_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Device OUT endpoint-n transfer size register */ + +#define OTG_DOEPTSIZ_XFRSIZ_SHIFT (0) /* Bits 0-18: Transfer size */ +#define OTG_DOEPTSIZ_XFRSIZ_MASK (0x7ffff << OTG_DOEPTSIZ_XFRSIZ_SHIFT) +#define OTG_DOEPTSIZ_PKTCNT_SHIFT (19) /* Bit 19-28: Packet count */ +#define OTG_DOEPTSIZ_PKTCNT_MASK (0x3ff << OTG_DOEPTSIZ_PKTCNT_SHIFT) +#define OTG_DOEPTSIZ_STUPCNT_SHIFT (29) /* Bits 29-30: SETUP packet count */ +#define OTG_DOEPTSIZ_STUPCNT_MASK (3 << OTG_DOEPTSIZ_STUPCNT_SHIFT) +#define OTG_DOEPTSIZ_RXDPID_SHIFT (29) /* Bits 29-30: Received data PID */ +#define OTG_DOEPTSIZ_RXDPID_MASK (3 << OTG_DOEPTSIZ_RXDPID_SHIFT) +# define OTG_DOEPTSIZ_RXDPID_DATA0 (0 << OTG_DOEPTSIZ_RXDPID_SHIFT) +# define OTG_DOEPTSIZ_RXDPID_DATA2 (1 << OTG_DOEPTSIZ_RXDPID_SHIFT) +# define OTG_DOEPTSIZ_RXDPID_DATA1 (2 << OTG_DOEPTSIZ_RXDPID_SHIFT) +# define OTG_DOEPTSIZ_RXDPID_MDATA (3 << OTG_DOEPTSIZ_RXDPID_SHIFT) + /* Bit 31: Reserved, must be kept at reset value */ +/* Power and clock gating control register */ + +#define OTG_PCGCCTL_STPPCLK (1 << 0) /* Bit 0: Stop PHY clock */ +#define OTG_PCGCCTL_GATEHCLK (1 << 1) /* Bit 1: Gate HCLK */ + /* Bits 2-3: Reserved, must be kept at reset value */ +#define OTG_PCGCCTL_PHYSUSP (1 << 4) /* Bit 4: PHY Suspended */ + /* Bits 5-31: Reserved, must be kept at reset value */ + +#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_OTG_H */ diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h index e40990ec16..f710aed6d1 100644 --- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h @@ -1,5 +1,5 @@ /************************************************************************************ - * arch/arm/src/stm32/chip/stm32_sdio.h + * arch/arm/src/stm32f7/chip/stm32_sdio.h * * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/arm/src/stm32f7/stm32_i2c.c b/arch/arm/src/stm32f7/stm32_i2c.c index bc34aa25aa..6bd842263d 100644 --- a/arch/arm/src/stm32f7/stm32_i2c.c +++ b/arch/arm/src/stm32f7/stm32_i2c.c @@ -1,5 +1,5 @@ /************************************************************************************ - * arch/arm/src/stm32/stm32f3xx_i2c.c + * arch/arm/src/stm32f7/stm32f3xx_i2c.c * STM32 F3 I2C Hardware Layer - Device Driver * * Copyright (C) 2011 Uros Platise. All rights reserved. diff --git a/arch/arm/src/stm32f7/stm32_otg.h b/arch/arm/src/stm32f7/stm32_otg.h new file mode 100644 index 0000000000..69def14608 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_otg.h @@ -0,0 +1,139 @@ +/************************************************************************************ + * arch/arm/src/stm32f7/stm32_otg.h + * + * Copyright (C) 2012-2013 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. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_STM32F7_STM32_OTG_H +#define __ARCH_ARM_SRC_STM32F7_STM32_OTG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include + + +#include "chip/stm32_otg.h" + +#if defined(CONFIG_STM32_OTGFS) || defined(CONFIG_STM32_OTGHS) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* Configuration ********************************************************************/ + +#ifndef CONFIG_OTG_PRI +# define CONFIG_OTG_PRI NVIC_SYSH_PRIORITY_DEFAULT +#endif + +#if defined(CONFIG_STM32_OTGFS) +# define STM32_IRQ_OTG STM32_IRQ_OTGFS +# define STM32_OTG_BASE STM32_USBOTGFS_BASE +# define STM32_NENDPOINTS (6) /* ep0-5 x 2 for IN and OUT */ +#endif + +#if defined(CONFIG_STM32_OTGHS) +# define STM32_IRQ_OTG STM32_IRQ_OTGHS +# define STM32_OTG_BASE STM32_USBOTGHS_BASE +# define STM32_NENDPOINTS (8) /* ep0-7 x 2 for IN and OUT */ +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: stm32_otghost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initializeed. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST +struct usbhost_connection_s; +FAR struct usbhost_connection_s *stm32_otghost_initialize(int controller); +#endif + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the OTG FS device driver + * is used. This function is called whenever the USB enters or leaves suspend + * mode. This is an opportunity for the board logic to shutdown clocks, power, + * etc. while the USB is suspended. + * + ************************************************************************************/ + +void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume); + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_STM32_OTGFS */ +#endif /* __ARCH_ARM_SRC_STM32F7_STM32_OTG_H */ + diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c new file mode 100644 index 0000000000..e362ef2b45 --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -0,0 +1,5666 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_otgdev.c + * + * Copyright (C) 2012-2014 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 +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "chip.h" +#include "stm32_otg.h" +#include "up_arch.h" +#include "up_internal.h" + + +#if defined(CONFIG_USBDEV) && (defined(CONFIG_STM32_OTGFS) || defined(CONFIG_STM32_OTGHS)) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ + +#ifndef CONFIG_USBDEV_EP0_MAXSIZE +# define CONFIG_USBDEV_EP0_MAXSIZE 64 +#endif + +#ifndef CONFIG_USBDEV_SETUP_MAXDATASIZE +# define CONFIG_USBDEV_SETUP_MAXDATASIZE CONFIG_USBDEV_EP0_MAXSIZE +#endif + +#ifndef CONFIG_USBDEV_MAXPOWER +# define CONFIG_USBDEV_MAXPOWER 100 /* mA */ +#endif + +/* There is 1.25Kb of FIFO memory. The default partitions this memory + * so that there is a TxFIFO allocated for each endpoint and with more + * memory provided for the common RxFIFO. A more knowledge-able + * configuration would not allocate any TxFIFO space to OUT endpoints. + */ + +#ifndef CONFIG_USBDEV_RXFIFO_SIZE +# define CONFIG_USBDEV_RXFIFO_SIZE 512 +#endif + +#ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 192 +#endif + +#ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 192 +#endif + +#if (CONFIG_USBDEV_RXFIFO_SIZE + CONFIG_USBDEV_EP0_TXFIFO_SIZE + \ + CONFIG_USBDEV_EP2_TXFIFO_SIZE + CONFIG_USBDEV_EP3_TXFIFO_SIZE) > 1280 +# error "FIFO allocations exceed FIFO memory size" +#endif + +/* The actual FIFO addresses that we use must be aligned to 4-byte boundaries; + * FIFO sizes must be provided in units of 32-bit words. + */ + +#define STM32_RXFIFO_BYTES ((CONFIG_USBDEV_RXFIFO_SIZE + 3) & ~3) +#define STM32_RXFIFO_WORDS ((CONFIG_USBDEV_RXFIFO_SIZE + 3) >> 2) + +#define STM32_EP0_TXFIFO_BYTES ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP0_TXFIFO_WORDS ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP0_TXFIFO_WORDS < 16 || STM32_EP0_TXFIFO_WORDS > 256 +# error "CONFIG_USBDEV_EP0_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP1_TXFIFO_BYTES ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP1_TXFIFO_WORDS ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP1_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP1_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP2_TXFIFO_BYTES ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP2_TXFIFO_WORDS ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP2_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP2_TXFIFO_SIZE is out of range" +#endif + +#define STM32_EP3_TXFIFO_BYTES ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP3_TXFIFO_WORDS ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) >> 2) + +#if STM32_EP3_TXFIFO_WORDS < 16 +# error "CONFIG_USBDEV_EP3_TXFIFO_SIZE is out of range" +#endif + +/* Debug ***********************************************************************/ +/* Trace error codes */ + +#define STM32_TRACEERR_ALLOCFAIL 0x01 +#define STM32_TRACEERR_BADCLEARFEATURE 0x02 +#define STM32_TRACEERR_BADDEVGETSTATUS 0x03 +#define STM32_TRACEERR_BADEPNO 0x04 +#define STM32_TRACEERR_BADEPGETSTATUS 0x05 +#define STM32_TRACEERR_BADGETCONFIG 0x06 +#define STM32_TRACEERR_BADGETSETDESC 0x07 +#define STM32_TRACEERR_BADGETSTATUS 0x08 +#define STM32_TRACEERR_BADSETADDRESS 0x09 +#define STM32_TRACEERR_BADSETCONFIG 0x0a +#define STM32_TRACEERR_BADSETFEATURE 0x0b +#define STM32_TRACEERR_BADTESTMODE 0x0c +#define STM32_TRACEERR_BINDFAILED 0x0d +#define STM32_TRACEERR_DISPATCHSTALL 0x0e +#define STM32_TRACEERR_DRIVER 0x0f +#define STM32_TRACEERR_DRIVERREGISTERED 0x10 +#define STM32_TRACEERR_EP0NOSETUP 0x11 +#define STM32_TRACEERR_EP0SETUPSTALLED 0x12 +#define STM32_TRACEERR_EPINNULLPACKET 0x13 +#define STM32_TRACEERR_EPINUNEXPECTED 0x14 +#define STM32_TRACEERR_EPOUTNULLPACKET 0x15 +#define STM32_TRACEERR_EPOUTUNEXPECTED 0x16 +#define STM32_TRACEERR_INVALIDCTRLREQ 0x17 +#define STM32_TRACEERR_INVALIDPARMS 0x18 +#define STM32_TRACEERR_IRQREGISTRATION 0x19 +#define STM32_TRACEERR_NOEP 0x1a +#define STM32_TRACEERR_NOTCONFIGURED 0x1b +#define STM32_TRACEERR_EPOUTQEMPTY 0x1c +#define STM32_TRACEERR_EPINREQEMPTY 0x1d +#define STM32_TRACEERR_NOOUTSETUP 0x1e +#define STM32_TRACEERR_POLLTIMEOUT 0x1f + +/* Trace interrupt codes */ + +#define STM32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */ +#define STM32_TRACEINTID_INTPENDING 2 /* On each pass through the loop */ + +#define STM32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */ +#define STM32_TRACEINTID_EPIN (10 + 1) +#define STM32_TRACEINTID_MISMATCH (10 + 2) +#define STM32_TRACEINTID_WAKEUP (10 + 3) +#define STM32_TRACEINTID_SUSPEND (10 + 4) +#define STM32_TRACEINTID_SOF (10 + 5) +#define STM32_TRACEINTID_RXFIFO (10 + 6) +#define STM32_TRACEINTID_DEVRESET (10 + 7) +#define STM32_TRACEINTID_ENUMDNE (10 + 8) +#define STM32_TRACEINTID_IISOIXFR (10 + 9) +#define STM32_TRACEINTID_IISOOXFR (10 + 10) +#define STM32_TRACEINTID_SRQ (10 + 11) +#define STM32_TRACEINTID_OTG (10 + 12) + +#define STM32_TRACEINTID_EPOUT_XFRC (40 + 0) /* EPOUT second level decode */ +#define STM32_TRACEINTID_EPOUT_EPDISD (40 + 1) +#define STM32_TRACEINTID_EPOUT_SETUP (40 + 2) +#define STM32_TRACEINTID_DISPATCH (40 + 3) + +#define STM32_TRACEINTID_GETSTATUS (50 + 0) /* EPOUT third level decode */ +#define STM32_TRACEINTID_EPGETSTATUS (50 + 1) +#define STM32_TRACEINTID_DEVGETSTATUS (50 + 2) +#define STM32_TRACEINTID_IFGETSTATUS (50 + 3) +#define STM32_TRACEINTID_CLEARFEATURE (50 + 4) +#define STM32_TRACEINTID_SETFEATURE (50 + 5) +#define STM32_TRACEINTID_SETADDRESS (50 + 6) +#define STM32_TRACEINTID_GETSETDESC (50 + 7) +#define STM32_TRACEINTID_GETCONFIG (50 + 8) +#define STM32_TRACEINTID_SETCONFIG (50 + 9) +#define STM32_TRACEINTID_GETSETIF (50 + 10) +#define STM32_TRACEINTID_SYNCHFRAME (50 + 11) + +#define STM32_TRACEINTID_EPIN_XFRC (70 + 0) /* EPIN second level decode */ +#define STM32_TRACEINTID_EPIN_TOC (70 + 1) +#define STM32_TRACEINTID_EPIN_ITTXFE (70 + 2) +#define STM32_TRACEINTID_EPIN_EPDISD (70 + 3) +#define STM32_TRACEINTID_EPIN_TXFE (70 + 4) + +#define STM32_TRACEINTID_EPIN_EMPWAIT (80 + 0) /* EPIN second level decode */ + +#define STM32_TRACEINTID_OUTNAK (90 + 0) /* RXFLVL second level decode */ +#define STM32_TRACEINTID_OUTRECVD (90 + 1) +#define STM32_TRACEINTID_OUTDONE (90 + 2) +#define STM32_TRACEINTID_SETUPDONE (90 + 3) +#define STM32_TRACEINTID_SETUPRECVD (90 + 4) + +/* Endpoints ******************************************************************/ + + +/* Odd physical endpoint numbers are IN; even are OUT */ + +#define STM32_EPPHYIN2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_IN) +#define STM32_EPPHYOUT2LOG(epphy) ((uint8_t)(epphy)|USB_DIR_OUT) + +/* Endpoint 0 */ + +#define EP0 (0) + +/* The set of all enpoints available to the class implementation (1-3) */ + +#define STM32_EP_AVAILABLE (0x0e) /* All available endpoints */ + +/* Maximum packet sizes for full speed endpoints */ + +#define STM32_MAXPACKET (64) /* Max packet size (1-64) */ + +/* Delays **********************************************************************/ + +#define STM32_READY_DELAY 200000 +#define STM32_FLUSH_DELAY 200000 + +/* Request queue operations ****************************************************/ + +#define stm32_rqempty(ep) ((ep)->head == NULL) +#define stm32_rqpeek(ep) ((ep)->head) + +/* Standard stuff **************************************************************/ + +#ifndef MIN +# define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* Overall device state */ + +enum stm32_devstate_e +{ + DEVSTATE_DEFAULT = 0, /* Power-up, unconfigured state. This state simply + * means that the device is not yet been given an + * address. + * SET: At initialization, uninitialization, + * reset, and whenever the device address + * is set to zero + * TESTED: Never + */ + DEVSTATE_ADDRESSED, /* Device address has been assigned, not no + * configuration has yet been selected. + * SET: When either a non-zero device address + * is first assigned or when the device + * is unconfigured (with configuration == 0) + * TESTED: never + */ + DEVSTATE_CONFIGURED, /* Address assigned and configured: + * SET: When the device has been addressed and + * an non-zero configuration has been selected. + * TESTED: In many places to assure that the USB device + * has been properly configured by the host. + */ +}; + +/* Endpoint 0 states */ + +enum stm32_ep0state_e +{ + EP0STATE_IDLE = 0, /* Idle State, leave on receiving a SETUP packet or + * epsubmit: + * SET: In stm32_epin() and stm32_epout() when + * we revert from request processing to + * SETUP processing. + * TESTED: Never + */ + EP0STATE_SETUP_OUT, /* OUT SETUP packet received. Waiting for the DATA + * OUT phase of SETUP Packet to complete before + * processing a SETUP command (without a USB request): + * SET: Set in stm32_rxinterrupt() when SETUP OUT + * packet is received. + * TESTED: In stm32_ep0out_receive() + */ + EP0STATE_SETUP_READY, /* IN SETUP packet received -OR- OUT SETUP packet and + * accompanying data have been received. Processing + * of SETUP command will happen soon. + * SET: (1) stm32_ep0out_receive() when the OUT + * SETUP data phase completes, or (2) + * stm32_rxinterrupt() when an IN SETUP is + * packet received. + * TESTED: Tested in stm32_epout_interrupt() when + * SETUP phase is done to see if the SETUP + * command is ready to be processed. Also + * tested in stm32_ep0out_setup() just to + * double-check that we have a SETUP request + * and any accompanying data. + */ + EP0STATE_SETUP_PROCESS, /* SETUP Packet is being processed by stm32_ep0out_setup(): + * SET: When SETUP packet received in EP0 OUT + * TESTED: Never + */ + EP0STATE_SETUPRESPONSE, /* Short SETUP response write (without a USB request): + * SET: When SETUP response is sent by + * stm32_ep0in_setupresponse() + * TESTED: Never + */ + EP0STATE_DATA_IN, /* Waiting for data out stage (with a USB request): + * SET: In stm32_epin_request() when a write + * request is processed on EP0. + * TESTED: In stm32_epin() to see if we should + * revert to SETUP processing. + */ + EP0STATE_DATA_OUT /* Waiting for data in phase to complete ( with a + * USB request) + * SET: In stm32_epout_request() when a read + * request is processed on EP0. + * TESTED: In stm32_epout() to see if we should + * revert to SETUP processing + */ +}; + +/* Parsed control request */ + +struct stm32_ctrlreq_s +{ + uint8_t type; + uint8_t req; + uint16_t value; + uint16_t index; + uint16_t len; +}; + +/* A container for a request so that the request may be retained in a list */ + +struct stm32_req_s +{ + struct usbdev_req_s req; /* Standard USB request */ + struct stm32_req_s *flink; /* Supports a singly linked list */ +}; + +/* This is the internal representation of an endpoint */ + +struct stm32_ep_s +{ + /* Common endpoint fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_ep_s + * to struct stm32_ep_s. + */ + + struct usbdev_ep_s ep; /* Standard endpoint structure */ + + /* STM32-specific fields */ + + struct stm32_usbdev_s *dev; /* Reference to private driver data */ + struct stm32_req_s *head; /* Request list for this endpoint */ + struct stm32_req_s *tail; + uint8_t epphy; /* Physical EP address */ + uint8_t eptype:2; /* Endpoint type */ + uint8_t active:1; /* 1: A request is being processed */ + uint8_t stalled:1; /* 1: Endpoint is stalled */ + uint8_t isin:1; /* 1: IN Endpoint */ + uint8_t odd:1; /* 1: Odd frame */ + uint8_t zlp:1; /* 1: Transmit a zero-length-packet (IN EPs only) */ +}; + +/* This structure retains the state of the USB device controller */ + +struct stm32_usbdev_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbdev_s + * to struct stm32_usbdev_s. + */ + + struct usbdev_s usbdev; + + /* The bound device class driver */ + + struct usbdevclass_driver_s *driver; + + /* STM32-specific fields */ + + uint8_t stalled:1; /* 1: Protocol stalled */ + uint8_t selfpowered:1; /* 1: Device is self powered */ + uint8_t addressed:1; /* 1: Peripheral address has been set */ + uint8_t configured:1; /* 1: Class driver has been configured */ + uint8_t wakeup:1; /* 1: Device remote wake-up */ + uint8_t dotest:1; /* 1: Test mode selected */ + + uint8_t devstate:4; /* See enum stm32_devstate_e */ + uint8_t ep0state:4; /* See enum stm32_ep0state_e */ + uint8_t testmode:4; /* Selected test mode */ + uint8_t epavail[2]; /* Bitset of available OUT/IN endpoints */ + + /* E0 SETUP data buffering. + * + * ctrlreq: + * The 8-byte SETUP request is received on the EP0 OUT endpoint and is + * saved. + * + * ep0data + * For OUT SETUP requests, the SETUP data phase must also complete before + * the SETUP command can be processed. The pack receipt logic will save + * the accompanying EP0 IN data in ep0data[] before the SETUP command is + * processed. + * + * For IN SETUP requests, the DATA phase will occur AFTER the SETUP + * control request is processed. In that case, ep0data[] may be used as + * the response buffer. + * + * ep0datlen + * Length of OUT DATA received in ep0data[] (Not used with OUT data) + */ + + struct usb_ctrlreq_s ctrlreq; + uint8_t ep0data[CONFIG_USBDEV_SETUP_MAXDATASIZE]; + uint16_t ep0datlen; + + /* The endpoint lists */ + + struct stm32_ep_s epin[STM32_NENDPOINTS]; + struct stm32_ep_s epout[STM32_NENDPOINTS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t val, uint32_t addr); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(val,addr) putreg32(val,addr) +#endif + +/* Request queue operations ****************************************************/ + +static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep); +static bool stm32_req_addlast(FAR struct stm32_ep_s *privep, + FAR struct stm32_req_s *req); + +/* Low level data transfers and request operations *****************************/ +/* Special endpoint 0 data transfer logic */ + +static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv, + FAR uint8_t *data, uint32_t nbytes); +static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv); +static void stm32_ep0in_activate(void); + +static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv); + +/* IN request and TxFIFO handling */ + +static void stm32_txfifo_write(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void stm32_epin_transfer(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes); +static void stm32_epin_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); + +/* OUT request and RxFIFO handling */ + +static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len); +static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len); +static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); +static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt); +static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt); +static void stm32_epout_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep); + +/* General request handling */ + +static void stm32_ep_flush(FAR struct stm32_ep_s *privep); +static void stm32_req_complete(FAR struct stm32_ep_s *privep, + int16_t result); +static void stm32_req_cancel(FAR struct stm32_ep_s *privep, + int16_t status); + +/* Interrupt handling **********************************************************/ + +static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv, + uint16_t eplog); +static int stm32_req_dispatch(FAR struct stm32_usbdev_s *priv, + FAR const struct usb_ctrlreq_s *ctrl); +static void stm32_usbreset(FAR struct stm32_usbdev_s *priv); + +/* Second level OUT endpoint interrupt processing */ + +static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv, + uint16_t index); +static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, + FAR struct stm32_ctrlreq_s *ctrlreq); +static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv); +static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, + uint8_t epno); +static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv); + +/* Second level IN endpoint interrupt processing */ + +static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv); +static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno); +static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int epno); +static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv); + +/* Other second level interrupt processing */ + +static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv); +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv); +#endif +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv); +static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv); +#endif + +/* First level interrupt processing */ + +static int stm32_usbinterrupt(int irq, FAR void *context); + +/* Endpoint operations *********************************************************/ +/* Global OUT NAK controls */ + +static void stm32_enablegonak(FAR struct stm32_ep_s *privep); +static void stm32_disablegonak(FAR struct stm32_ep_s *privep); + +/* Endpoint configuration */ + +static int stm32_epout_configure(FAR struct stm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int stm32_epin_configure(FAR struct stm32_ep_s *privep, + uint8_t eptype, uint16_t maxpacket); +static int stm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, bool last); +static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv); + +/* Endpoint disable */ + +static void stm32_epout_disable(FAR struct stm32_ep_s *privep); +static void stm32_epin_disable(FAR struct stm32_ep_s *privep); +static int stm32_ep_disable(FAR struct usbdev_ep_s *ep); + +/* Endpoint request management */ + +static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep); +static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep, + FAR struct usbdev_req_s *); + +/* Endpoint buffer management */ + +#ifdef CONFIG_USBDEV_DMA +static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes); +static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf); +#endif + +/* Endpoint request submission */ + +static int stm32_ep_submit(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Endpoint request cancellation */ + +static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, + struct usbdev_req_s *req); + +/* Stall handling */ + +static int stm32_epout_setstall(FAR struct stm32_ep_s *privep); +static int stm32_epin_setstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_setstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep); +static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume); +static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv); + +/* Endpoint allocation */ + +static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t epno, bool in, uint8_t eptype); +static void stm32_ep_free(FAR struct usbdev_s *dev, + FAR struct usbdev_ep_s *ep); + +/* USB device controller operations ********************************************/ + +static int stm32_getframe(struct usbdev_s *dev); +static int stm32_wakeup(struct usbdev_s *dev); +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered); +static int stm32_pullup(struct usbdev_s *dev, bool enable); +static void stm32_setaddress(struct stm32_usbdev_s *priv, + uint16_t address); +static int stm32_txfifo_flush(uint32_t txfnum); +static int stm32_rxfifo_flush(void); + +/* Initialization **************************************************************/ + +static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv); +static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Since there is only a single USB interface, all status information can be + * be simply retained in a single global instance. + */ + +static struct stm32_usbdev_s g_otghsdev; + +static const struct usbdev_epops_s g_epops = +{ + .configure = stm32_ep_configure, + .disable = stm32_ep_disable, + .allocreq = stm32_ep_allocreq, + .freereq = stm32_ep_freereq, +#ifdef CONFIG_USBDEV_DMA + .allocbuffer = stm32_ep_allocbuffer, + .freebuffer = stm32_ep_freebuffer, +#endif + .submit = stm32_ep_submit, + .cancel = stm32_ep_cancel, + .stall = stm32_ep_stall, +}; + +static const struct usbdev_ops_s g_devops = +{ + .allocep = stm32_ep_alloc, + .freeep = stm32_ep_free, + .getframe = stm32_getframe, + .wakeup = stm32_wakeup, + .selfpowered = stm32_selfpowered, + .pullup = stm32_pullup, +}; + +/* Device error strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_deverror[] = +{ + TRACE_STR(STM32_TRACEERR_ALLOCFAIL ), + TRACE_STR(STM32_TRACEERR_BADCLEARFEATURE ), + TRACE_STR(STM32_TRACEERR_BADDEVGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADEPNO ), + TRACE_STR(STM32_TRACEERR_BADEPGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADGETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADGETSETDESC ), + TRACE_STR(STM32_TRACEERR_BADGETSTATUS ), + TRACE_STR(STM32_TRACEERR_BADSETADDRESS ), + TRACE_STR(STM32_TRACEERR_BADSETCONFIG ), + TRACE_STR(STM32_TRACEERR_BADSETFEATURE ), + TRACE_STR(STM32_TRACEERR_BADTESTMODE ), + TRACE_STR(STM32_TRACEERR_BINDFAILED ), + TRACE_STR(STM32_TRACEERR_DISPATCHSTALL ), + TRACE_STR(STM32_TRACEERR_DRIVER ), + TRACE_STR(STM32_TRACEERR_DRIVERREGISTERED), + TRACE_STR(STM32_TRACEERR_EP0NOSETUP ), + TRACE_STR(STM32_TRACEERR_EP0SETUPSTALLED ), + TRACE_STR(STM32_TRACEERR_EPINNULLPACKET ), + TRACE_STR(STM32_TRACEERR_EPINUNEXPECTED ), + TRACE_STR(STM32_TRACEERR_EPOUTNULLPACKET ), + TRACE_STR(STM32_TRACEERR_EPOUTUNEXPECTED ), + TRACE_STR(STM32_TRACEERR_INVALIDCTRLREQ ), + TRACE_STR(STM32_TRACEERR_INVALIDPARMS ), + TRACE_STR(STM32_TRACEERR_IRQREGISTRATION ), + TRACE_STR(STM32_TRACEERR_NOEP ), + TRACE_STR(STM32_TRACEERR_NOTCONFIGURED ), + TRACE_STR(STM32_TRACEERR_EPOUTQEMPTY ), + TRACE_STR(STM32_TRACEERR_EPINREQEMPTY ), + TRACE_STR(STM32_TRACEERR_NOOUTSETUP ), + TRACE_STR(STM32_TRACEERR_POLLTIMEOUT ), + TRACE_STR_END +}; +#endif + +/* Interrupt event strings that may be enabled for more descriptive USB trace + * output. + */ + +#ifdef CONFIG_USBDEV_TRACE_STRINGS +const struct trace_msg_t g_usb_trace_strings_intdecode[] = +{ + TRACE_STR(STM32_TRACEINTID_USB ), + TRACE_STR(STM32_TRACEINTID_INTPENDING ), + TRACE_STR(STM32_TRACEINTID_EPOUT ), + TRACE_STR(STM32_TRACEINTID_EPIN ), + TRACE_STR(STM32_TRACEINTID_MISMATCH ), + TRACE_STR(STM32_TRACEINTID_WAKEUP ), + TRACE_STR(STM32_TRACEINTID_SUSPEND ), + TRACE_STR(STM32_TRACEINTID_SOF ), + TRACE_STR(STM32_TRACEINTID_RXFIFO ), + TRACE_STR(STM32_TRACEINTID_DEVRESET ), + TRACE_STR(STM32_TRACEINTID_ENUMDNE ), + TRACE_STR(STM32_TRACEINTID_IISOIXFR ), + TRACE_STR(STM32_TRACEINTID_IISOOXFR ), + TRACE_STR(STM32_TRACEINTID_SRQ ), + TRACE_STR(STM32_TRACEINTID_OTG ), + TRACE_STR(STM32_TRACEINTID_EPOUT_XFRC ), + TRACE_STR(STM32_TRACEINTID_EPOUT_EPDISD), + TRACE_STR(STM32_TRACEINTID_EPOUT_SETUP ), + TRACE_STR(STM32_TRACEINTID_DISPATCH ), + TRACE_STR(STM32_TRACEINTID_GETSTATUS ), + TRACE_STR(STM32_TRACEINTID_EPGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_DEVGETSTATUS), + TRACE_STR(STM32_TRACEINTID_IFGETSTATUS ), + TRACE_STR(STM32_TRACEINTID_CLEARFEATURE), + TRACE_STR(STM32_TRACEINTID_SETFEATURE ), + TRACE_STR(STM32_TRACEINTID_SETADDRESS ), + TRACE_STR(STM32_TRACEINTID_GETSETDESC ), + TRACE_STR(STM32_TRACEINTID_GETCONFIG ), + TRACE_STR(STM32_TRACEINTID_SETCONFIG ), + TRACE_STR(STM32_TRACEINTID_GETSETIF ), + TRACE_STR(STM32_TRACEINTID_SYNCHFRAME ), + TRACE_STR(STM32_TRACEINTID_EPIN_XFRC ), + TRACE_STR(STM32_TRACEINTID_EPIN_TOC ), + TRACE_STR(STM32_TRACEINTID_EPIN_ITTXFE ), + TRACE_STR(STM32_TRACEINTID_EPIN_EPDISD ), + TRACE_STR(STM32_TRACEINTID_EPIN_TXFE ), + TRACE_STR(STM32_TRACEINTID_EPIN_EMPWAIT), + TRACE_STR(STM32_TRACEINTID_OUTNAK ), + TRACE_STR(STM32_TRACEINTID_OUTRECVD ), + TRACE_STR(STM32_TRACEINTID_OUTDONE ), + TRACE_STR(STM32_TRACEINTID_SETUPDONE ), + TRACE_STR(STM32_TRACEINTID_SETUPRECVD ), + TRACE_STR_END +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +static uint32_t stm32_getreg(uint32_t addr) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Is this the same value that we read from the same register last time? Are + * we polling the register? If so, suppress some of the output. + */ + + if (addr == prevaddr && val == preval) + { + if (count == 0xffffffff || ++count > 3) + { + if (count == 4) + { + llerr("...\n"); + } + + return val; + } + } + + /* No this is a new address or value */ + + else + { + /* Did we print "..." for the previous value? */ + + if (count > 3) + { + /* Yes.. then show how many times the value repeated */ + + llerr("[repeats %d more times]\n", count-3); + } + + /* Save the new address, value, and count */ + + prevaddr = addr; + preval = val; + count = 1; + } + + /* Show the register value read */ + + llerr("%08x->%08x\n", addr, val); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +static void stm32_putreg(uint32_t val, uint32_t addr) +{ + /* Show the register value being written */ + + llerr("%08x<-%08x\n", addr, val); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_req_remfirst + * + * Description: + * Remove a request from the head of an endpoint request queue + * + ****************************************************************************/ + +static FAR struct stm32_req_s *stm32_req_remfirst(FAR struct stm32_ep_s *privep) +{ + FAR struct stm32_req_s *ret = privep->head; + + if (ret) + { + privep->head = ret->flink; + if (!privep->head) + { + privep->tail = NULL; + } + + ret->flink = NULL; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_req_addlast + * + * Description: + * Add a request to the end of an endpoint request queue + * + ****************************************************************************/ + +static bool stm32_req_addlast(FAR struct stm32_ep_s *privep, + FAR struct stm32_req_s *req) +{ + bool is_empty = !privep->head; + + req->flink = NULL; + if (is_empty) + { + privep->head = req; + privep->tail = req; + } + else + { + privep->tail->flink = req; + privep->tail = req; + } + return is_empty; +} + +/**************************************************************************** + * Name: stm32_ep0in_setupresponse + * + * Description: + * Schedule a short transfer on Endpoint 0 (IN or OUT) + * + ****************************************************************************/ + +static void stm32_ep0in_setupresponse(FAR struct stm32_usbdev_s *priv, + FAR uint8_t *buf, uint32_t nbytes) +{ + stm32_epin_transfer(&priv->epin[EP0], buf, nbytes); + priv->ep0state = EP0STATE_SETUPRESPONSE; + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: stm32_ep0in_transmitzlp + * + * Description: + * Send a zero length packet (ZLP) on endpoint 0 IN + * + ****************************************************************************/ + +static inline void stm32_ep0in_transmitzlp(FAR struct stm32_usbdev_s *priv) +{ + stm32_ep0in_setupresponse(priv, NULL, 0); +} + +/**************************************************************************** + * Name: stm32_ep0in_activate + * + * Description: + * Activate the endpoint 0 IN endpoint. + * + ****************************************************************************/ + +static void stm32_ep0in_activate(void) +{ + uint32_t regval; + + /* Set the max packet size of the IN EP. */ + + regval = stm32_getreg(STM32_OTG_DIEPCTL0); + regval &= ~OTG_DIEPCTL0_MPSIZ_MASK; + +#if CONFIG_USBDEV_EP0_MAXSIZE == 8 + regval |= OTG_DIEPCTL0_MPSIZ_8; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 16 + regval |= OTG_DIEPCTL0_MPSIZ_16; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 32 + regval |= OTG_DIEPCTL0_MPSIZ_32; +#elif CONFIG_USBDEV_EP0_MAXSIZE == 64 + regval |= OTG_DIEPCTL0_MPSIZ_64; +#else +# error "Unsupported value of CONFIG_USBDEV_EP0_MAXSIZE" +#endif + + stm32_putreg(regval, STM32_OTG_DIEPCTL0); + + /* Clear global IN NAK */ + + regval = stm32_getreg(STM32_OTG_DCTL); + regval |= OTG_DCTL_CGINAK; + stm32_putreg(regval, STM32_OTG_DCTL); +} + +/**************************************************************************** + * Name: stm32_ep0out_ctrlsetup + * + * Description: + * Setup to receive a SETUP packet. + * + ****************************************************************************/ + +static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Setup the hardware to perform the SETUP transfer */ + + regval = (USB_SIZEOF_CTRLREQ * 3 << OTG_DOEPTSIZ0_XFRSIZ_SHIFT) | + (OTG_DOEPTSIZ0_PKTCNT) | + (3 << OTG_DOEPTSIZ0_STUPCNT_SHIFT); + stm32_putreg(regval, STM32_OTG_DOEPTSIZ0); + + /* Then clear NAKing and enable the transfer */ + + regval = stm32_getreg(STM32_OTG_DOEPCTL0); + regval |= (OTG_DOEPCTL0_CNAK | OTG_DOEPCTL0_EPENA); + stm32_putreg(regval, STM32_OTG_DOEPCTL0); +} + +/**************************************************************************** + * Name: stm32_txfifo_write + * + * Description: + * Send data to the endpoint's TxFIFO. + * + ****************************************************************************/ + +static void stm32_txfifo_write(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t regaddr; + uint32_t regval; + int nwords; + int i; + + /* Convert the number of bytes to words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the TxFIFO for this endpoint (same as the endpoint number) */ + + regaddr = STM32_OTG_DFIFO_DEP(privep->epphy); + + /* Then transfer each word to the TxFIFO */ + + for (i = 0; i < nwords; i++) + { + /* Read four bytes from the source buffer (to avoid unaligned accesses) + * and pack these into one 32-bit word (little endian). + */ + + regval = (uint32_t)*buf++; + regval |= ((uint32_t)*buf++) << 8; + regval |= ((uint32_t)*buf++) << 16; + regval |= ((uint32_t)*buf++) << 24; + + /* Then write the packet data to the TxFIFO */ + + stm32_putreg(regval, regaddr); + } +} + +/**************************************************************************** + * Name: stm32_epin_transfer + * + * Description: + * Start the Tx data transfer + * + ****************************************************************************/ + +static void stm32_epin_transfer(FAR struct stm32_ep_s *privep, + FAR uint8_t *buf, int nbytes) +{ + uint32_t pktcnt; + uint32_t regval; + + /* Read the DIEPSIZx register */ + + regval = stm32_getreg(STM32_OTG_DIEPTSIZ(privep->epphy)); + + /* Clear the XFRSIZ, PKTCNT, and MCNT field of the DIEPSIZx register */ + + regval &= ~(OTG_DIEPTSIZ_XFRSIZ_MASK | OTG_DIEPTSIZ_PKTCNT_MASK | + OTG_DIEPTSIZ_MCNT_MASK); + + /* Are we sending a zero length packet (ZLP) */ + + if (nbytes == 0) + { + /* Yes.. leave the transfer size at zero and set the packet count to 1 */ + + pktcnt = 1; + } + else + { + /* No.. Program the transfer size and packet count . First calculate: + * + * xfrsize = The total number of bytes to be sent. + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + */ + + pktcnt = ((uint32_t)nbytes + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + } + + /* Set the XFRSIZ and PKTCNT */ + + regval |= (pktcnt << OTG_DIEPTSIZ_PKTCNT_SHIFT); + regval |= ((uint32_t)nbytes << OTG_DIEPTSIZ_XFRSIZ_SHIFT); + + /* If this is an isochronous endpoint, then set the multi-count field to + * the PKTCNT as well. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + regval |= (pktcnt << OTG_DIEPTSIZ_MCNT_SHIFT); + } + + /* Save DIEPSIZx register value */ + + stm32_putreg(regval, STM32_OTG_DIEPTSIZ(privep->epphy)); + + /* Read the DIEPCTLx register */ + + regval = stm32_getreg(STM32_OTG_DIEPCTL(privep->epphy)); + + /* If this is an isochronous endpoint, then set the even/odd frame bit + * the DIEPCTLx register. + */ + + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + /* Check bit 0 of the frame number of the received SOF and set the + * even/odd frame to match. + */ + + uint32_t status = stm32_getreg(STM32_OTG_DSTS); + if ((status & OTG_DSTS_SOFFN0) == OTG_DSTS_SOFFN_EVEN) + { + regval |= OTG_DIEPCTL_SEVNFRM; + } + else + { + regval |= OTG_DIEPCTL_SODDFRM; + } + } + + /* EP enable, IN data in FIFO */ + + regval &= ~OTG_DIEPCTL_EPDIS; + regval |= (OTG_DIEPCTL_CNAK | OTG_DIEPCTL_EPENA); + stm32_putreg(regval, STM32_OTG_DIEPCTL(privep->epphy)); + + /* Transfer the data to the TxFIFO. At this point, the caller has already + * assured that there is sufficient space in the TxFIFO to hold the transfer + * we can just blindly continue. + */ + + stm32_txfifo_write(privep, buf, nbytes); +} + +/**************************************************************************** + * Name: stm32_epin_request + * + * Description: + * Begin or continue write request processing. + * + ****************************************************************************/ + +static void stm32_epin_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint8_t *buf; + int nbytes; + int nwords; + int bytesleft; + + /* We get here in one of four possible ways. From three interrupting + * events: + * + * 1. From stm32_epin as part of the transfer complete interrupt processing + * This interrupt indicates that the last transfer has completed. + * 2. As part of the ITTXFE interrupt processing. That interrupt indicates + * that an IN token was received when the associated TxFIFO was empty. + * 3. From stm32_epin_txfifoempty as part of the TXFE interrupt processing. + * The TXFE interrupt is only enabled when the TxFIFO is full and the + * software must wait for space to become available in the TxFIFO. + * + * And this function may be called immediately when the write request is + * queue to start up the next transaction. + * + * 4. From stm32_ep_submit when a new write request is received WHILE the + * endpoint is not active (privep->active == false). + */ + + /* Check the request from the head of the endpoint request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINREQEMPTY), privep->epphy); + + /* There is no TX transfer in progress and no new pending TX + * requests to send. To stop transmitting any data on a particular + * IN endpoint, the application must set the IN NAK bit. To set this + * bit, the following field must be programmed. + */ + + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTG_DIEPCTL_SNAK; + stm32_putreg(regval, regaddr); + + /* The endpoint is no longer active */ + + privep->active = false; + return; + } + + ullinfo("EP%d req=%p: len=%d xfrd=%d zlp=%d\n", + privep->epphy, privreq, privreq->req.len, + privreq->req.xfrd, privep->zlp); + + /* Check for a special case: If we are just starting a request (xfrd==0) and + * the class driver is trying to send a zero-length packet (len==0). Then set + * the ZLP flag so that the packet will be sent. + */ + + if (privreq->req.len == 0) + { + /* The ZLP flag is set TRUE whenever we want to force the driver to + * send a zero-length-packet on the next pass through the loop (below). + * The flag is cleared whenever a packet is sent in the loop below. + */ + + privep->zlp = true; + } + + /* Add one more packet to the TxFIFO. We will wait for the transfer + * complete event before we add the next packet (or part of a packet + * to the TxFIFO). + * + * The documentation says that we can can multiple packets to the TxFIFO, + * but it seems that we need to get the transfer complete event before + * we can add the next (or maybe I have got something wrong?) + */ + +#if 0 + while (privreq->req.xfrd < privreq->req.len || privep->zlp) +#else + if (privreq->req.xfrd < privreq->req.len || privep->zlp) +#endif + { + /* Get the number of bytes left to be sent in the request */ + + bytesleft = privreq->req.len - privreq->req.xfrd; + nbytes = bytesleft; + + /* Assume no zero-length-packet on the next pass through this loop */ + + privep->zlp = false; + + /* Limit the size of the transfer to one full packet and handle + * zero-length packets (ZLPs). + */ + + if (nbytes > 0) + { + /* Either send the maxpacketsize or all of the remaining data in + * the request. + */ + + if (nbytes >= privep->ep.maxpacket) + { + nbytes = privep->ep.maxpacket; + + /* Handle the case where this packet is exactly the + * maxpacketsize. Do we need to send a zero-length packet + * in this case? + */ + + if (bytesleft == privep->ep.maxpacket && + (privreq->req.flags & USBDEV_REQFLAGS_NULLPKT) != 0) + { + /* The ZLP flag is set TRUE whenever we want to force + * the driver to send a zero-length-packet on the next + * pass through this loop. The flag is cleared (above) + * whenever we are committed to sending any packet and + * set here when we want to force one more pass through + * the loop. + */ + + privep->zlp = true; + } + } + } + + /* Get the transfer size in 32-bit words */ + + nwords = (nbytes + 3) >> 2; + + /* Get the number of 32-bit words available in the TxFIFO. The + * DXTFSTS indicates the amount of free space available in the + * endpoint TxFIFO. Values are in terms of 32-bit words: + * + * 0: Endpoint TxFIFO is full + * 1: 1 word available + * 2: 2 words available + * n: n words available + */ + + regaddr = STM32_OTG_DTXFSTS(privep->epphy); + + /* Check for space in the TxFIFO. If space in the TxFIFO is not + * available, then set up an interrupt to resume the transfer when + * the TxFIFO is empty. + */ + + regval = stm32_getreg(regaddr); + if ((int)(regval & OTG_DTXFSTS_MASK) < nwords) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EMPWAIT), (uint16_t)regval); + + /* There is insufficient space in the TxFIFO. Wait for a TxFIFO + * empty interrupt and try again. + */ + + uint32_t empmsk = stm32_getreg(STM32_OTG_DIEPEMPMSK); + empmsk |= OTG_DIEPEMPMSK(privep->epphy); + stm32_putreg(empmsk, STM32_OTG_DIEPEMPMSK); + + /* Terminate the transfer. We will try again when the TxFIFO empty + * interrupt is received. + */ + + return; + } + + /* Transfer data to the TxFIFO */ + + buf = privreq->req.buf + privreq->req.xfrd; + stm32_epin_transfer(privep, buf, nbytes); + + /* If it was not before, the OUT endpoint is now actively transferring + * data. + */ + + privep->active = true; + + /* EP0 is a special case */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_IN; + } + + /* Update for the next time through the loop */ + + privreq->req.xfrd += nbytes; + } + + /* Note that the ZLP, if any, must be sent as a separate transfer. The need + * for a ZLP is indicated by privep->zlp. If all of the bytes were sent + * (including any final null packet) then we are finished with the transfer + */ + + if (privreq->req.xfrd >= privreq->req.len && !privep->zlp) + { + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + + /* We are finished with the request (although the transfer has not + * yet completed). + */ + + stm32_req_complete(privep, OK); + } +} + +/**************************************************************************** + * Name: stm32_rxfifo_read + * + * Description: + * Read packet from the RxFIFO into a read request. + * + ****************************************************************************/ + +static void stm32_rxfifo_read(FAR struct stm32_ep_s *privep, + FAR uint8_t *dest, uint16_t len) +{ + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO. Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = STM32_OTG_DFIFO_DEP(EP0); + + /* Read 32-bits and write 4 x 8-bits at time (to avoid unaligned accesses) */ + + for (i = 0; i < len; i += 4) + { + union + { + uint32_t w; + uint8_t b[4]; + } data; + + /* Read 1 x 32-bits of EP0 packet data */ + + data.w = stm32_getreg(regaddr); + + /* Write 4 x 8-bits of EP0 packet data */ + + *dest++ = data.b[0]; + *dest++ = data.b[1]; + *dest++ = data.b[2]; + *dest++ = data.b[3]; + } +} + +/**************************************************************************** + * Name: stm32_rxfifo_discard + * + * Description: + * Discard packet data from the RxFIFO. + * + ****************************************************************************/ + +static void stm32_rxfifo_discard(FAR struct stm32_ep_s *privep, int len) +{ + if (len > 0) + { + uint32_t regaddr; + int i; + + /* Get the address of the RxFIFO Note: there is only one RxFIFO so + * we might as well use the address associated with EP0. + */ + + regaddr = STM32_OTG_DFIFO_DEP(EP0); + + /* Read 32-bits at time */ + + for (i = 0; i < len; i += 4) + { + volatile uint32_t data = stm32_getreg(regaddr); + (void)data; + } + } +} + +/**************************************************************************** + * Name: stm32_epout_complete + * + * Description: + * This function is called when an OUT transfer complete interrupt is + * received. It completes the read request at the head of the endpoint's + * request queue. + * + ****************************************************************************/ + +static void stm32_epout_complete(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + + /* Since a transfer just completed, there must be a read request at the head of + * the endpoint request queue. + */ + + privreq = stm32_rqpeek(privep); + DEBUGASSERT(privreq); + + if (!privreq) + { + /* An OUT transfer completed, but no packet to receive the data. This + * should not happen. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + privep->active = false; + return; + } + + ullinfo("EP%d: len=%d xfrd=%d\n", + privep->epphy, privreq->req.len, privreq->req.xfrd); + + /* Return the completed read request to the class driver and mark the state + * IDLE. + */ + + usbtrace(TRACE_COMPLETE(privep->epphy), privreq->req.xfrd); + stm32_req_complete(privep, OK); + privep->active = false; + + /* Now set up the next read request (if any) */ + + stm32_epout_request(priv, privep); +} + +/**************************************************************************** + * Name: stm32_ep0out_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void stm32_ep0out_receive(FAR struct stm32_ep_s *privep, int bcnt) +{ + FAR struct stm32_usbdev_s *priv; + + /* Sanity Checking */ + + DEBUGASSERT(privep && privep->ep.priv); + priv = (FAR struct stm32_usbdev_s *)privep->ep.priv; + + ullinfo("EP0: bcnt=%d\n", bcnt); + usbtrace(TRACE_READ(EP0), bcnt); + + /* Verify that an OUT SETUP request as received before this data was + * received in the RxFIFO. + */ + + if (priv->ep0state == EP0STATE_SETUP_OUT) + { + /* Read the data into our special buffer for SETUP data */ + + int readlen = MIN(CONFIG_USBDEV_SETUP_MAXDATASIZE, bcnt); + stm32_rxfifo_read(privep, priv->ep0data, readlen); + + /* Do we have to discard any excess bytes? */ + + stm32_rxfifo_discard(privep, bcnt - readlen); + + /* Now we can process the setup command */ + + privep->active = false; + priv->ep0state = EP0STATE_SETUP_READY; + priv->ep0datlen = readlen; + + stm32_ep0out_setup(priv); + } + else + { + /* This is an error. We don't have any idea what to do with the EP0 + * data in this case. Just read and discard it so that the RxFIFO + * does not become constipated. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOOUTSETUP), priv->ep0state); + stm32_rxfifo_discard(privep, bcnt); + privep->active = false; + } +} + +/**************************************************************************** + * Name: stm32_epout_receive + * + * Description: + * This function is called from the RXFLVL interrupt handler when new incoming + * data is available in the endpoint's RxFIFO. This function will simply + * copy the incoming data into pending request's data buffer. + * + ****************************************************************************/ + +static inline void stm32_epout_receive(FAR struct stm32_ep_s *privep, int bcnt) +{ + struct stm32_req_s *privreq; + uint8_t *dest; + int buflen; + int readlen; + + /* Get a reference to the request at the head of the endpoint's request + * queue. + */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + /* Incoming data is available in the RxFIFO, but there is no read setup + * to receive the receive the data. This should not happen for data + * endpoints; those endpoints should have been NAKing any OUT data tokens. + * + * We should get here normally on OUT data phase following an OUT + * SETUP command. EP0 data will still receive data in this case and it + * should not be NAKing. + */ + + if (privep->epphy == 0) + { + stm32_ep0out_receive(privep, bcnt); + } + else + { + /* Otherwise, the data is lost. This really should not happen if + * NAKing is working as expected. + */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* Discard the data in the RxFIFO */ + + stm32_rxfifo_discard(privep, bcnt); + } + + privep->active = false; + return; + } + + ullinfo("EP%d: len=%d xfrd=%d\n", privep->epphy, privreq->req.len, privreq->req.xfrd); + usbtrace(TRACE_READ(privep->epphy), bcnt); + + /* Get the number of bytes to transfer from the RxFIFO */ + + buflen = privreq->req.len - privreq->req.xfrd; + DEBUGASSERT(buflen > 0 && buflen >= bcnt); + readlen = MIN(buflen, bcnt); + + /* Get the destination of the data transfer */ + + dest = privreq->req.buf + privreq->req.xfrd; + + /* Transfer the data from the RxFIFO to the request's data buffer */ + + stm32_rxfifo_read(privep, dest, readlen); + + /* If there were more bytes in the RxFIFO than could be held in the read + * request, then we will have to discard those. + */ + + stm32_rxfifo_discard(privep, bcnt - readlen); + + /* Update the number of bytes transferred */ + + privreq->req.xfrd += readlen; +} + +/**************************************************************************** + * Name: stm32_epout_request + * + * Description: + * This function is called when either (1) new read request is received, or + * (2) a pending receive request completes. If there is no read in pending, + * then this function will initiate the next OUT (read) operation. + * + ****************************************************************************/ + +static void stm32_epout_request(FAR struct stm32_usbdev_s *priv, + FAR struct stm32_ep_s *privep) +{ + struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t regval; + uint32_t xfrsize; + uint32_t pktcnt; + + /* Make sure that there is not already a pending request request. If there is, + * just return, leaving the newly received request in the request queue. + */ + + if (!privep->active) + { + /* Loop until a valid request is found (or the request queue is empty). + * The loop is only need to look at the request queue again is an invalid + * read request is encountered. + */ + + for (; ; ) + { + /* Get a reference to the request at the head of the endpoint's request queue */ + + privreq = stm32_rqpeek(privep); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTQEMPTY), privep->epphy); + + /* There are no read requests to be setup. Configure the hardware to + * NAK any incoming packets. (This should already be the case. I + * think that the hardware will automatically NAK after a transfer is + * completed until SNAK is cleared). + */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTG_DOEPCTL_SNAK; + stm32_putreg(regval, regaddr); + + /* This endpoint is no longer actively transferring */ + + privep->active = false; + return; + } + + ullinfo("EP%d: len=%d\n", privep->epphy, privreq->req.len); + + /* Ignore any attempt to receive a zero length packet (this really + * should not happen. + */ + + if (privreq->req.len <= 0) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTNULLPACKET), 0); + stm32_req_complete(privep, OK); + } + + /* Otherwise, we have a usable read request... break out of the loop */ + + else + { + break; + } + } + + /* Setup the pending read into the request buffer. First calculate: + * + * pktcnt = the number of packets (of maxpacket bytes) required to + * perform the transfer. + * xfrsize = The total number of bytes required (in units of + * maxpacket bytes). + */ + + pktcnt = (privreq->req.len + (privep->ep.maxpacket - 1)) / privep->ep.maxpacket; + xfrsize = pktcnt * privep->ep.maxpacket; + + /* Then setup the hardware to perform this transfer */ + + regaddr = STM32_OTG_DOEPTSIZ(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~(OTG_DOEPTSIZ_XFRSIZ_MASK | OTG_DOEPTSIZ_PKTCNT_MASK); + regval |= (xfrsize << OTG_DOEPTSIZ_XFRSIZ_SHIFT); + regval |= (pktcnt << OTG_DOEPTSIZ_PKTCNT_SHIFT); + stm32_putreg(regval, regaddr); + + /* Then enable the transfer */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + + /* When an isochronous transfer is enabled the Even/Odd frame bit must + * also be set appropriately. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if (privep->eptype == USB_EP_ATTR_XFER_ISOC) + { + if (privep->odd) + { + regval |= OTG_DOEPCTL_SODDFRM; + } + else + { + regval |= OTG_DOEPCTL_SEVNFRM; + } + } +#endif + + /* Clearing NAKing and enable the transfer. */ + + regval |= (OTG_DOEPCTL_CNAK | OTG_DOEPCTL_EPENA); + stm32_putreg(regval, regaddr); + + /* A transfer is now active on this endpoint */ + + privep->active = true; + + /* EP0 is a special case. We need to know when to switch back to + * normal SETUP processing. + */ + + if (privep->epphy == EP0) + { + priv->ep0state = EP0STATE_DATA_OUT; + } + } +} + +/**************************************************************************** + * Name: stm32_ep_flush + * + * Description: + * Flush any primed descriptors from this ep + * + ****************************************************************************/ + +static void stm32_ep_flush(struct stm32_ep_s *privep) +{ + if (privep->isin) + { + stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_D(privep->epphy)); + } + else + { + stm32_rxfifo_flush(); + } +} + +/**************************************************************************** + * Name: stm32_req_complete + * + * Description: + * Handle termination of the request at the head of the endpoint request queue. + * + ****************************************************************************/ + +static void stm32_req_complete(struct stm32_ep_s *privep, int16_t result) +{ + FAR struct stm32_req_s *privreq; + + /* Remove the request at the head of the request list */ + + privreq = stm32_req_remfirst(privep); + DEBUGASSERT(privreq != NULL); + + /* If endpoint 0, temporarily reflect the state of protocol stalled + * in the callback. + */ + + bool stalled = privep->stalled; + if (privep->epphy == EP0) + { + privep->stalled = privep->dev->stalled; + } + + /* Save the result in the request structure */ + + privreq->req.result = result; + + /* Callback to the request completion handler */ + + privreq->req.callback(&privep->ep, &privreq->req); + + /* Restore the stalled indication */ + + privep->stalled = stalled; +} + +/**************************************************************************** + * Name: stm32_req_cancel + * + * Description: + * Cancel all pending requests for an endpoint + * + ****************************************************************************/ + +static void stm32_req_cancel(struct stm32_ep_s *privep, int16_t status) +{ + if (!stm32_rqempty(privep)) + { + stm32_ep_flush(privep); + } + + while (!stm32_rqempty(privep)) + { + usbtrace(TRACE_COMPLETE(privep->epphy), + (stm32_rqpeek(privep))->req.xfrd); + stm32_req_complete(privep, status); + } +} + +/**************************************************************************** + * Name: stm32_ep_findbyaddr + * + * Description: + * Find the physical endpoint structure corresponding to a logic endpoint + * address + * + ****************************************************************************/ + +static struct stm32_ep_s *stm32_ep_findbyaddr(struct stm32_usbdev_s *priv, + uint16_t eplog) +{ + struct stm32_ep_s *privep; + uint8_t epphy = USB_EPNO(eplog); + + if (epphy >= STM32_NENDPOINTS) + { + return NULL; + } + + /* Is this an IN or an OUT endpoint? */ + + if (USB_ISEPIN(eplog)) + { + privep = &priv->epin[epphy]; + } + else + { + privep = &priv->epout[epphy]; + } + + /* Return endpoint reference */ + + DEBUGASSERT(privep->epphy == epphy); + return privep; +} + +/**************************************************************************** + * Name: stm32_req_dispatch + * + * Description: + * Provide unhandled setup actions to the class driver. This is logically part + * of the USB interrupt handler. + * + ****************************************************************************/ + +static int stm32_req_dispatch(struct stm32_usbdev_s *priv, + const struct usb_ctrlreq_s *ctrl) +{ + int ret = -EIO; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DISPATCH), 0); + if (priv->driver) + { + /* Forward to the control request to the class driver implementation */ + + ret = CLASS_SETUP(priv->driver, &priv->usbdev, ctrl, + priv->ep0data, priv->ep0datlen); + } + + if (ret < 0) + { + /* Stall on failure */ + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DISPATCHSTALL), 0); + priv->stalled = true; + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_usbreset + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void stm32_usbreset(struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + uint32_t regval; + int i; + + /* Clear the Remote Wake-up Signaling */ + + regval = stm32_getreg(STM32_OTG_DCTL); + regval &= ~OTG_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTG_DCTL); + + /* Flush the EP0 Tx FIFO */ + + stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_D(EP0)); + + /* Tell the class driver that we are disconnected. The class + * driver should then accept any new configurations. + */ + + if (priv->driver) + { + CLASS_DISCONNECT(priv->driver, &priv->usbdev); + } + + /* Mark all endpoints as available */ + + priv->epavail[0] = STM32_EP_AVAILABLE; + priv->epavail[1] = STM32_EP_AVAILABLE; + + /* Disable all end point interrupts */ + + for (i = 0; i < STM32_NENDPOINTS ; i++) + { + /* Disable endpoint interrupts */ + + stm32_putreg(0xff, STM32_OTG_DIEPINT(i)); + stm32_putreg(0xff, STM32_OTG_DOEPINT(i)); + + /* Return write requests to the class implementation */ + + privep = &priv->epin[i]; + stm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset IN endpoint status */ + + privep->stalled = false; + + /* Return read requests to the class implementation */ + + privep = &priv->epout[i]; + stm32_req_cancel(privep, -ESHUTDOWN); + + /* Reset endpoint status */ + + privep->stalled = false; + } + + stm32_putreg(0xffffffff, STM32_OTG_DAINT); + + /* Mask all device endpoint interrupts except EP0 */ + + regval = (OTG_DAINT_IEP(EP0) | OTG_DAINT_OEP(EP0)); + stm32_putreg(regval, STM32_OTG_DAINTMSK); + + /* Unmask OUT interrupts */ + + regval = (OTG_DOEPMSK_XFRCM | OTG_DOEPMSK_STUPM | OTG_DOEPMSK_EPDM); + stm32_putreg(regval, STM32_OTG_DOEPMSK); + + /* Unmask IN interrupts */ + + regval = (OTG_DIEPMSK_XFRCM | OTG_DIEPMSK_EPDM | OTG_DIEPMSK_TOM); + stm32_putreg(regval, STM32_OTG_DIEPMSK); + + /* Reset device address to 0 */ + + stm32_setaddress(priv, 0); + priv->devstate = DEVSTATE_DEFAULT; + priv->usbdev.speed = USB_SPEED_FULL; + + /* Re-configure EP0 */ + + stm32_ep0_configure(priv); + + /* Setup EP0 to receive SETUP packets */ + + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Name: stm32_ep0out_testmode + * + * Description: + * Select test mode + * + ****************************************************************************/ + +static inline void stm32_ep0out_testmode(FAR struct stm32_usbdev_s *priv, + uint16_t index) +{ + uint8_t testmode; + + testmode = index >> 8; + switch (testmode) + { + case 1: + priv->testmode = OTG_TESTMODE_J; + break; + + case 2: + priv->testmode = OTG_TESTMODE_K; + break; + + case 3: + priv->testmode = OTG_TESTMODE_SE0_NAK; + break; + + case 4: + priv->testmode = OTG_TESTMODE_PACKET; + break; + + case 5: + priv->testmode = OTG_TESTMODE_FORCE; + break; + + default: + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADTESTMODE), testmode); + priv->dotest = false; + priv->testmode = OTG_TESTMODE_DISABLED; + priv->stalled = true; + } + + priv->dotest = true; + stm32_ep0in_transmitzlp(priv); +} + +/**************************************************************************** + * Name: stm32_ep0out_stdrequest + * + * Description: + * Handle a stanard request on EP0. Pick off the things of interest to the + * USB device controller driver; pass what is left to the class driver. + * + ****************************************************************************/ + +static inline void stm32_ep0out_stdrequest(struct stm32_usbdev_s *priv, + FAR struct stm32_ctrlreq_s *ctrlreq) +{ + FAR struct stm32_ep_s *privep; + + /* Handle standard request */ + + switch (ctrlreq->req) + { + case USB_REQ_GETSTATUS: + { + /* type: device-to-host; recipient = device, interface, endpoint + * value: 0 + * index: zero interface endpoint + * len: 2; data = status + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSTATUS), 0); + if (!priv->addressed || + ctrlreq->len != 2 || + USB_REQ_ISOUT(ctrlreq->type) || + ctrlreq->value != 0) + { + priv->stalled = true; + } + else + { + switch (ctrlreq->type & USB_REQ_RECIPIENT_MASK) + { + case USB_REQ_RECIPIENT_ENDPOINT: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPGETSTATUS), 0); + privep = stm32_ep_findbyaddr(priv, ctrlreq->index); + if (!privep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPGETSTATUS), 0); + priv->stalled = true; + } + else + { + if (privep->stalled) + { + priv->ep0data[0] = (1 << USB_FEATURE_ENDPOINTHALT); + } + else + { + priv->ep0data[0] = 0; /* Not stalled */ + } + + priv->ep0data[1] = 0; + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + } + break; + + case USB_REQ_RECIPIENT_DEVICE: + { + if (ctrlreq->index == 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVGETSTATUS), 0); + + /* Features: Remote Wakeup and self-powered */ + + priv->ep0data[0] = (priv->selfpowered << USB_FEATURE_SELFPOWERED); + priv->ep0data[0] |= (priv->wakeup << USB_FEATURE_REMOTEWAKEUP); + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADDEVGETSTATUS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_RECIPIENT_INTERFACE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IFGETSTATUS), 0); + priv->ep0data[0] = 0; + priv->ep0data[1] = 0; + + stm32_ep0in_setupresponse(priv, priv->ep0data, 2); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSTATUS), 0); + priv->stalled = true; + } + break; + } + } + } + break; + + case USB_REQ_CLEARFEATURE: + { + /* type: host-to-device; recipient = device, interface or endpoint + * value: feature selector + * index: zero interface endpoint; + * len: zero, data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_CLEARFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + stm32_ep_clrstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 0; + stm32_ep0in_transmitzlp(priv); + } + else + { + /* Actually, I think we could just stall here. */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADCLEARFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETFEATURE: + { + /* type: host-to-device; recipient = device, interface, endpoint + * value: feature selector + * index: zero interface endpoint; + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETFEATURE), 0); + if (priv->addressed != 0 && ctrlreq->len == 0) + { + uint8_t recipient = ctrlreq->type & USB_REQ_RECIPIENT_MASK; + if (recipient == USB_REQ_RECIPIENT_ENDPOINT && + ctrlreq->value == USB_FEATURE_ENDPOINTHALT && + (privep = stm32_ep_findbyaddr(priv, ctrlreq->index)) != NULL) + { + stm32_ep_setstall(privep); + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_REMOTEWAKEUP) + { + priv->wakeup = 1; + stm32_ep0in_transmitzlp(priv); + } + else if (recipient == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == USB_FEATURE_TESTMODE && + ((ctrlreq->index & 0xff) == 0)) + { + stm32_ep0out_testmode(priv, ctrlreq->index); + } + else if (priv->configured) + { + /* Actually, I think we could just stall here. */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETFEATURE), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETADDRESS: + { + /* type: host-to-device; recipient = device + * value: device address + * index: 0 + * len: 0; data = none + */ + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETADDRESS), ctrlreq->value); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0 && + ctrlreq->value < 128 && + priv->devstate != DEVSTATE_CONFIGURED) + { + /* Save the address. We cannot actually change to the next address until + * the completion of the status phase. + */ + + stm32_setaddress(priv, (uint16_t)priv->ctrlreq.value[0]); + stm32_ep0in_transmitzlp(priv); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETADDRESS), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETDESCRIPTOR: + /* type: device-to-host; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + case USB_REQ_SETDESCRIPTOR: + /* type: host-to-device; recipient = device + * value: descriptor type and index + * index: 0 or language ID; + * len: descriptor len; data = descriptor + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETDESC), 0); + if ((ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE) + { + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETSETDESC), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETCONFIGURATION: + /* type: device-to-host; recipient = device + * value: 0; + * index: 0; + * len: 1; data = configuration value + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->value == 0 && + ctrlreq->index == 0 && + ctrlreq->len == 1) + { + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADGETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_SETCONFIGURATION: + /* type: host-to-device; recipient = device + * value: configuration value + * index: 0; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETCONFIG), 0); + if (priv->addressed && + (ctrlreq->type & USB_REQ_RECIPIENT_MASK) == USB_REQ_RECIPIENT_DEVICE && + ctrlreq->index == 0 && + ctrlreq->len == 0) + { + /* Give the configuration to the class driver */ + + int ret = stm32_req_dispatch(priv, &priv->ctrlreq); + + /* If the class driver accepted the configuration, then mark the + * device state as configured (or not, depending on the + * configuration). + */ + + if (ret == OK) + { + uint8_t cfg = (uint8_t)ctrlreq->value; + if (cfg != 0) + { + priv->devstate = DEVSTATE_CONFIGURED; + priv->configured = true; + } + else + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->configured = false; + } + } + } + else + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADSETCONFIG), 0); + priv->stalled = true; + } + } + break; + + case USB_REQ_GETINTERFACE: + /* type: device-to-host; recipient = interface + * value: 0 + * index: interface; + * len: 1; data = alt interface + */ + + case USB_REQ_SETINTERFACE: + /* type: host-to-device; recipient = interface + * value: alternate setting + * index: interface; + * len: 0; data = none + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_GETSETIF), 0); + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + break; + + case USB_REQ_SYNCHFRAME: + /* type: device-to-host; recipient = endpoint + * value: 0 + * index: endpoint; + * len: 2; data = frame number + */ + + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SYNCHFRAME), 0); + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDCTRLREQ), 0); + priv->stalled = true; + } + break; + } +} + +/**************************************************************************** + * Name: stm32_ep0out_setup + * + * Description: + * USB Ctrl EP Setup Event. This is logically part of the USB interrupt + * handler. This event occurs when a setup packet is receive on EP0 OUT. + * + ****************************************************************************/ + +static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv) +{ + struct stm32_ctrlreq_s ctrlreq; + + /* Verify that a SETUP was received */ + + if (priv->ep0state != EP0STATE_SETUP_READY) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0NOSETUP), priv->ep0state); + return; + } + + /* Terminate any pending requests */ + + stm32_req_cancel(&priv->epout[EP0], -EPROTO); + stm32_req_cancel(&priv->epin[EP0], -EPROTO); + + /* Assume NOT stalled */ + + priv->epout[EP0].stalled = false; + priv->epin[EP0].stalled = false; + priv->stalled = false; + + /* Starting to process a control request - update state */ + + priv->ep0state = EP0STATE_SETUP_PROCESS; + + /* And extract the little-endian 16-bit values to host order */ + + ctrlreq.type = priv->ctrlreq.type; + ctrlreq.req = priv->ctrlreq.req; + ctrlreq.value = GETUINT16(priv->ctrlreq.value); + ctrlreq.index = GETUINT16(priv->ctrlreq.index); + ctrlreq.len = GETUINT16(priv->ctrlreq.len); + + ullinfo("type=%02x req=%02x value=%04x index=%04x len=%04x\n", + ctrlreq.type, ctrlreq.req, ctrlreq.value, ctrlreq.index, ctrlreq.len); + + /* Check for a standard request */ + + if ((ctrlreq.type & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) + { + /* Dispatch any non-standard requests */ + + (void)stm32_req_dispatch(priv, &priv->ctrlreq); + } + else + { + /* Handle standard requests. */ + + stm32_ep0out_stdrequest(priv, &ctrlreq); + } + + /* Check if the setup processing resulted in a STALL */ + + if (priv->stalled) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EP0SETUPSTALLED), priv->ep0state); + stm32_ep0_stall(priv); + } + + /* Reset state/data associated with thie SETUP request */ + + priv->ep0datlen = 0; +} + +/**************************************************************************** + * Name: stm32_epout + * + * Description: + * This is part of the OUT endpoint interrupt processing. This function + * handles the OUT event for a single endpoint. + * + ****************************************************************************/ + +static inline void stm32_epout(FAR struct stm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct stm32_ep_s *privep; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + privep = &priv->epout[EP0]; + + /* In the EP0STATE_DATA_OUT state, we are receiving data into the + * request buffer. In that case, we must continue the request + * processing. + */ + + if (priv->ep0state == EP0STATE_DATA_OUT) + { + /* Continue processing data from the EP0 OUT request queue */ + + stm32_epout_complete(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + stm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an OUT request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + stm32_epout_complete(priv, &priv->epout[epno]); + } +} + +/**************************************************************************** + * Name: stm32_epout_interrupt + * + * Description: + * USB OUT endpoint interrupt handler. The core generates this interrupt when + * there is an interrupt is pending on one of the OUT endpoints of the core. + * The driver must read the OTG DAINT register to determine the exact number + * of the OUT endpoint on which the interrupt occurred, and then read the + * corresponding OTG DOEPINTx register to determine the exact cause of the + * interrupt. + * + ****************************************************************************/ + +static inline void stm32_epout_interrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t daint; + uint32_t regval; + uint32_t doepint; + int epno; + + /* Get the pending, enabled interrupts for the OUT endpoint from the endpoint + * interrupt status register. + */ + + regval = stm32_getreg(STM32_OTG_DAINT); + regval &= stm32_getreg(STM32_OTG_DAINTMSK); + daint = (regval & OTG_DAINT_OEP_MASK) >> OTG_DAINT_OEP_SHIFT; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + regval = stm32_getreg(STM32_OTG_DAINT); + daint = (regval & OTG_DAINT_OEP_MASK) >> OTG_DAINT_OEP_SHIFT; + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPOUTUNEXPECTED), + (uint16_t)regval); + + epno = 0; + while (daint) + { + if ((daint & 1) != 0) + { + regval = stm32_getreg(STM32_OTG_DOEPINT(epno)); + ullerr("DOEPINT(%d) = %08x\n", epno, regval); + stm32_putreg(0xFF, STM32_OTG_DOEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an OUT interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Yes.. get the OUT endpoint interrupt status */ + + doepint = stm32_getreg(STM32_OTG_DOEPINT(epno)); + doepint &= stm32_getreg(STM32_OTG_DOEPMSK); + + /* Transfer completed interrupt. This interrupt is trigged when + * stm32_rxinterrupt() removes the last packet data from the RxFIFO. + * In this case, core internally sets the NAK bit for this endpoint to + * prevent it from receiving any more packets. + */ + + if ((doepint & OTG_DOEPINT_XFRC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_XFRC), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + stm32_putreg(OTG_DOEPINT_XFRC, STM32_OTG_DOEPINT(epno)); + + /* Handle the RX transfer data ready event */ + + stm32_epout(priv, epno); + } + + /* Endpoint disabled interrupt (ignored because this interrupt is + * used in polled mode by the endpoint disable logic). + */ +#if 1 + /* REVISIT: */ + if ((doepint & OTG_DOEPINT_EPDISD) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_EPDISD), (uint16_t)doepint); + + /* Clear the bit in DOEPINTn for this interrupt */ + + stm32_putreg(OTG_DOEPINT_EPDISD, STM32_OTG_DOEPINT(epno)); + } +#endif + /* Setup Phase Done (control EPs) */ + + if ((doepint & OTG_DOEPINT_SETUP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT_SETUP), priv->ep0state); + + /* Handle the receipt of the IN SETUP packets now (OUT setup + * packet processing may be delayed until the accompanying + * OUT DATA is received) + */ + + if (priv->ep0state == EP0STATE_SETUP_READY) + { + stm32_ep0out_setup(priv); + } + stm32_putreg(OTG_DOEPINT_SETUP, STM32_OTG_DOEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: stm32_epin_runtestmode + * + * Description: + * Execute the test mode setup by the SET FEATURE request + * + ****************************************************************************/ + +static inline void stm32_epin_runtestmode(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval = stm32_getreg(STM32_OTG_DCTL); + regval &= OTG_DCTL_TCTL_MASK; + regval |= (uint32_t)priv->testmode << OTG_DCTL_TCTL_SHIFT; + stm32_putreg(regval , STM32_OTG_DCTL); + + priv->dotest = 0; + priv->testmode = OTG_TESTMODE_DISABLED; +} + +/**************************************************************************** + * Name: stm32_epin + * + * Description: + * This is part of the IN endpoint interrupt processing. This function + * handles the IN event for a single endpoint. + * + ****************************************************************************/ + +static inline void stm32_epin(FAR struct stm32_usbdev_s *priv, uint8_t epno) +{ + FAR struct stm32_ep_s *privep = &priv->epin[epno]; + + /* Endpoint 0 is a special case. */ + + if (epno == 0) + { + /* In the EP0STATE_DATA_IN state, we are sending data from request + * buffer. In that case, we must continue the request processing. + */ + + if (priv->ep0state == EP0STATE_DATA_IN) + { + /* Continue processing data from the EP0 OUT request queue */ + + stm32_epin_request(priv, privep); + + /* If we are not actively processing an OUT request, then we + * need to setup to receive the next control request. + */ + + if (!privep->active) + { + stm32_ep0out_ctrlsetup(priv); + priv->ep0state = EP0STATE_IDLE; + } + } + + /* Test mode is another special case */ + + if (priv->dotest) + { + stm32_epin_runtestmode(priv); + } + } + + /* For other endpoints, the only possibility is that we are continuing + * or finishing an IN request. + */ + + else if (priv->devstate == DEVSTATE_CONFIGURED) + { + /* Continue processing data from the endpoint write request queue */ + + stm32_epin_request(priv, privep); + } +} + +/**************************************************************************** + * Name: stm32_epin_txfifoempty + * + * Description: + * TxFIFO empty interrupt handling + * + ****************************************************************************/ + +static inline void stm32_epin_txfifoempty(FAR struct stm32_usbdev_s *priv, int epno) +{ + FAR struct stm32_ep_s *privep = &priv->epin[epno]; + + /* Continue processing the write request queue. This may mean sending + * more data from the existing request or terminating the current requests + * and (perhaps) starting the IN transfer from the next write request. + */ + + stm32_epin_request(priv, privep); +} + +/**************************************************************************** + * Name: stm32_epin_interrupt + * + * Description: + * USB IN endpoint interrupt handler. The core generates this interrupt when + * an interrupt is pending on one of the IN endpoints of the core. The driver + * must read the OTG DAINT register to determine the exact number of the IN + * endpoint on which the interrupt occurred, and then read the corresponding + * OTG DIEPINTx register to determine the exact cause of the interrupt. + * + ****************************************************************************/ + +static inline void stm32_epin_interrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t diepint; + uint32_t daint; + uint32_t mask; + uint32_t empty; + int epno; + + /* Get the pending, enabled interrupts for the IN endpoint from the endpoint + * interrupt status register. + */ + + daint = stm32_getreg(STM32_OTG_DAINT); + daint &= stm32_getreg(STM32_OTG_DAINTMSK); + daint &= OTG_DAINT_IEP_MASK; + + if (daint == 0) + { + /* We got an interrupt, but there is no unmasked endpoint that caused + * it ?! When this happens, the interrupt flag never gets cleared and + * we are stuck in infinite interrupt loop. + * + * This shouldn't happen if we are diligent about handling timing + * issues when masking endpoint interrupts. However, this workaround + * avoids infinite loop and allows operation to continue normally. It + * works by clearing each endpoint flags, masked or not. + */ + + daint = stm32_getreg(STM32_OTG_DAINT); + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_EPINUNEXPECTED), + (uint16_t)daint); + + daint &= OTG_DAINT_IEP_MASK; + epno = 0; + + while (daint) + { + if ((daint & 1) != 0) + { + ullerr("DIEPINT(%d) = %08x\n", + epno, stm32_getreg(STM32_OTG_DIEPINT(epno))); + stm32_putreg(0xFF, STM32_OTG_DIEPINT(epno)); + } + + epno++; + daint >>= 1; + } + + return; + } + + /* Process each pending IN endpoint interrupt */ + + epno = 0; + while (daint) + { + /* Is an IN interrupt pending for this endpoint? */ + + if ((daint & 1) != 0) + { + /* Get IN interrupt mask register. Bits 0-6 correspond to enabled + * interrupts as will be found in the DIEPINT interrupt status + * register. + */ + + mask = stm32_getreg(STM32_OTG_DIEPMSK); + + /* Check if the TxFIFO not empty interrupt is enabled for this + * endpoint in the DIEPMSK register. Bits n corresponds to + * endpoint n in the register. That condition corresponds to + * bit 7 of the DIEPINT interrupt status register. There is + * no TXFE bit in the mask register, so we fake one here. + */ + + empty = stm32_getreg(STM32_OTG_DIEPEMPMSK); + if ((empty & OTG_DIEPEMPMSK(epno)) != 0) + { + mask |= OTG_DIEPINT_TXFE; + } + + /* Now, read the interrupt status and mask out all disabled + * interrupts. + */ + + diepint = stm32_getreg(STM32_OTG_DIEPINT(epno)) & mask; + + /* Decode and process the enabled, pending interrupts */ + /* Transfer completed interrupt */ + + if ((diepint & OTG_DIEPINT_XFRC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_XFRC), + (uint16_t)diepint); + + /* It is possible that logic may be waiting for a the + * TxFIFO to become empty. We disable the TxFIFO empty + * interrupt here; it will be re-enabled if there is still + * insufficient space in the TxFIFO. + */ + + empty &= ~OTG_DIEPEMPMSK(epno); + stm32_putreg(empty, STM32_OTG_DIEPEMPMSK); + stm32_putreg(OTG_DIEPINT_XFRC, STM32_OTG_DIEPINT(epno)); + + /* IN transfer complete */ + + stm32_epin(priv, epno); + } + + /* Timeout condition */ + + if ((diepint & OTG_DIEPINT_TOC) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TOC), (uint16_t)diepint); + stm32_putreg(OTG_DIEPINT_TOC, STM32_OTG_DIEPINT(epno)); + } + + /* IN token received when TxFIFO is empty. Applies to non-periodic IN + * endpoints only. This interrupt indicates that an IN token was received + * when the associated TxFIFO (periodic/non-periodic) was empty. This + * interrupt is asserted on the endpoint for which the IN token was + * received. + */ + + if ((diepint & OTG_DIEPINT_ITTXFE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_ITTXFE), (uint16_t)diepint); + stm32_epin_request(priv, &priv->epin[epno]); + stm32_putreg(OTG_DIEPINT_ITTXFE, STM32_OTG_DIEPINT(epno)); + } + + /* IN endpoint NAK effective (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & OTG_DIEPINT_INEPNE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_INEPNE), (uint16_t)diepint); + stm32_putreg(OTG_DIEPINT_INEPNE, STM32_OTG_DIEPINT(epno)); + } +#endif + /* Endpoint disabled interrupt (ignored as this used only in polled + * mode) + */ +#if 0 + if ((diepint & OTG_DIEPINT_EPDISD) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_EPDISD), (uint16_t)diepint); + stm32_putreg(OTG_DIEPINT_EPDISD, STM32_OTG_DIEPINT(epno)); + } +#endif + /* Transmit FIFO empty */ + + if ((diepint & OTG_DIEPINT_TXFE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN_TXFE), (uint16_t)diepint); + + /* If we were waiting for TxFIFO to become empty, the we might have both + * XFRC and TXFE interrupts pending. Since we do the same thing for both + * cases, ignore the TXFE if we have already processed the XFRC. + */ + + if ((diepint & OTG_DIEPINT_XFRC) == 0) + { + /* Mask further FIFO empty interrupts. This will be re-enabled + * whenever we need to wait for a FIFO event. + */ + + empty &= ~OTG_DIEPEMPMSK(epno); + stm32_putreg(empty, STM32_OTG_DIEPEMPMSK); + + /* Handle TxFIFO empty */ + + stm32_epin_txfifoempty(priv, epno); + } + + /* Clear the pending TxFIFO empty interrupt */ + + stm32_putreg(OTG_DIEPINT_TXFE, STM32_OTG_DIEPINT(epno)); + } + } + + epno++; + daint >>= 1; + } +} + +/**************************************************************************** + * Name: stm32_resumeinterrupt + * + * Description: + * Resume/remote wakeup detected interrupt + * + ****************************************************************************/ + +static inline void stm32_resumeinterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Restart the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = stm32_getreg(STM32_OTG_PCGCCTL); + regval &= ~(OTG_PCGCCTL_STPPCLK | OTG_PCGCCTL_GATEHCLK); + stm32_putreg(regval, STM32_OTG_PCGCCTL); +#endif + + /* Clear remote wake-up signaling */ + + regval = stm32_getreg(STM32_OTG_DCTL); + regval &= ~OTG_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTG_DCTL); + + /* Restore full power -- whatever that means for this particular board */ + + stm32_usbsuspend((struct usbdev_s *)priv, true); + + /* Notify the class driver of the resume event */ + + if (priv->driver) + { + CLASS_RESUME(priv->driver, &priv->usbdev); + } +} + +/**************************************************************************** + * Name: stm32_suspendinterrupt + * + * Description: + * USB suspend interrupt + * + ****************************************************************************/ + +static inline void stm32_suspendinterrupt(FAR struct stm32_usbdev_s *priv) +{ +#ifdef CONFIG_USBDEV_LOWPOWER + uint32_t regval; +#endif + + /* Notify the class driver of the suspend event */ + + if (priv->driver) + { + CLASS_SUSPEND(priv->driver, &priv->usbdev); + } + +#ifdef CONFIG_USBDEV_LOWPOWER + /* OTG_DSTS_SUSPSTS is set as long as the suspend condition is detected + * on USB. Check if we are still have the suspend condition, that we are + * connected to the host, and that we have been configured. + */ + + regval = stm32_getreg(STM32_OTG_DSTS); + + if ((regval & OTG_DSTS_SUSPSTS) != 0 && devstate == DEVSTATE_CONFIGURED) + { + /* Switch off OTG clocking. Setting OTG_PCGCCTL_STPPCLK stops the + * PHY clock. + */ + + regval = stm32_getreg(STM32_OTG_PCGCCTL); + regval |= OTG_PCGCCTL_STPPCLK; + stm32_putreg(regval, STM32_OTG_PCGCCTL); + + /* Setting OTG_PCGCCTL_GATEHCLK gate HCLK to modules other than + * the AHB Slave and Master and wakeup logic. + */ + + regval |= OTG_PCGCCTL_GATEHCLK; + stm32_putreg(regval, STM32_OTG_PCGCCTL); + } +#endif + + /* Let the board-specific logic know that we have entered the suspend + * state + */ + + stm32_usbsuspend((FAR struct usbdev_s *)priv, false); +} + +/**************************************************************************** + * Name: stm32_rxinterrupt + * + * Description: + * RxFIFO non-empty interrupt. This interrupt indicates that there is at + * least one packet pending to be read from the RxFIFO. + * + ****************************************************************************/ + +static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + uint32_t regval; + int bcnt; + int epphy; + + /* Disable the Rx status queue level interrupt */ + + regval = stm32_getreg(STM32_OTG_GINTMSK); + regval &= ~OTG_GINT_RXFLVL; + stm32_putreg(regval, STM32_OTG_GINTMSK); + + /* Get the status from the top of the FIFO */ + + regval = stm32_getreg(STM32_OTG_GRXSTSP); + + /* Decode status fields */ + + epphy = (regval & OTG_GRXSTSD_EPNUM_MASK) >> OTG_GRXSTSD_EPNUM_SHIFT; + + if (epphy < STM32_NENDPOINTS) + { + privep = &priv->epout[epphy]; + + /* Handle the RX event according to the packet status field */ + + switch (regval & OTG_GRXSTSD_PKTSTS_MASK) + { + /* Global OUT NAK. This indicate that the global OUT NAK bit has taken + * effect. + * + * PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't + * Care. + */ + + case OTG_GRXSTSD_PKTSTS_OUTNAK: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTNAK), 0); + } + break; + + /* OUT data packet received. + * + * PKTSTS = DataOUT, BCNT = size of the received data OUT packet, + * EPNUM = EPNUM on which the packet was received, DPID = Actual Data PID. + */ + + case OTG_GRXSTSD_PKTSTS_OUTRECVD: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTRECVD), epphy); + bcnt = (regval & OTG_GRXSTSD_BCNT_MASK) >> OTG_GRXSTSD_BCNT_SHIFT; + if (bcnt > 0) + { + stm32_epout_receive(privep, bcnt); + } + } + break; + + /* OUT transfer completed. This indicates that an OUT data transfer for + * the specified OUT endpoint has completed. After this entry is popped + * from the receive FIFO, the core asserts a Transfer Completed interrupt + * on the specified OUT endpoint. + * + * PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on + * which the data transfer is complete, DPID = Don't Care. + */ + + case OTG_GRXSTSD_PKTSTS_OUTDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OUTDONE), epphy); + } + break; + + /* SETUP transaction completed. This indicates that the Setup stage for + * the specified endpoint has completed and the Data stage has started. + * After this entry is popped from the receive FIFO, the core asserts a + * Setup interrupt on the specified control OUT endpoint (triggers an + * interrupt). + * + * PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num, + * DPID = Don't Care. + */ + + case OTG_GRXSTSD_PKTSTS_SETUPDONE: + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPDONE), epphy); + } + break; + + /* SETUP data packet received. This indicates that a SETUP packet for the + * specified endpoint is now available for reading from the receive FIFO. + * + * PKTSTS = SETUP, BCNT = 8, EPNUM = Control EP Num, DPID = D0. + */ + + case OTG_GRXSTSD_PKTSTS_SETUPRECVD: + { + uint16_t datlen; + + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SETUPRECVD), epphy); + + /* Read EP0 setup data. NOTE: If multiple SETUP packets are received, + * the last one overwrites the previous setup packets and only that + * last SETUP packet will be processed. + */ + + stm32_rxfifo_read(&priv->epout[EP0], (FAR uint8_t *)&priv->ctrlreq, + USB_SIZEOF_CTRLREQ); + + /* Was this an IN or an OUT SETUP packet. If it is an OUT SETUP, + * then we need to wait for the completion of the data phase to + * process the setup command. If it is an IN SETUP packet, then + * we must processing the command BEFORE we enter the DATA phase. + * + * If the data associated with the OUT SETUP packet is zero length, + * then, of course, we don't need to wait. + */ + + datlen = GETUINT16(priv->ctrlreq.len); + if (USB_REQ_ISOUT(priv->ctrlreq.type) && datlen > 0) + { + /* Clear NAKSTS so that we can receive the data */ + + regval = stm32_getreg(STM32_OTG_DOEPCTL0); + regval |= OTG_DOEPCTL0_CNAK; + stm32_putreg(regval, STM32_OTG_DOEPCTL0); + + /* Wait for the data phase. */ + + priv->ep0state = EP0STATE_SETUP_OUT; + } + else + { + /* We can process the setup data as soon as SETUP done word is + * popped of the RxFIFO. + */ + + priv->ep0state = EP0STATE_SETUP_READY; + } + } + break; + + default: + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), + (regval & OTG_GRXSTSD_PKTSTS_MASK) >> OTG_GRXSTSD_PKTSTS_SHIFT); + } + break; + } + } + + /* Enable the Rx Status Queue Level interrupt */ + + regval = stm32_getreg(STM32_OTG_GINTMSK); + regval |= OTG_GINT_RXFLVL; + stm32_putreg(regval, STM32_OTG_GINTMSK); +} + +/**************************************************************************** + * Name: stm32_enuminterrupt + * + * Description: + * Enumeration done interrupt + * + ****************************************************************************/ + +static inline void stm32_enuminterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Activate EP0 */ + + stm32_ep0in_activate(); + + /* Set USB turn-around time for the full speed device with internal PHY interface. */ + + regval = stm32_getreg(STM32_OTG_GUSBCFG); + regval &= ~OTG_GUSBCFG_TRDT_MASK; + regval |= OTG_GUSBCFG_TRDT(5); + stm32_putreg(regval, STM32_OTG_GUSBCFG); +} + +/**************************************************************************** + * Name: stm32_isocininterrupt + * + * Description: + * Incomplete isochronous IN transfer interrupt. Assertion of the incomplete + * isochronous IN transfer interrupt indicates an incomplete isochronous IN + * transfer on at least one of the isochronous IN endpoints. + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocininterrupt(FAR struct stm32_usbdev_s *priv) +{ + int i; + + /* The application must read the endpoint control register for all isochronous + * IN endpoints to detect endpoints with incomplete IN data transfers. + */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Is this an isochronous IN endpoint? */ + + privep = &priv->epin[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + doepctl = stm32_getreg(regaddr); + dsts = stm32_getreg(STM32_OTG_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & OTG_DIEPCTL_EONUM) != 0); + soffn = ((dsts & OTG_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous IN endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + stm32_req_complete(privep, -EIO); +#warning "Will clear OTG_DIEPCTL_USBAEP too" + stm32_epin_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: stm32_isocoutinterrupt + * + * Description: + * Incomplete periodic transfer interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS +static inline void stm32_isocoutinterrupt(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + FAR struct stm32_req_s *privreq; + uint32_t regaddr; + uint32_t doepctl; + uint32_t dsts; + bool eonum; + bool soffn; + + /* When it receives an IISOOXFR interrupt, the application must read the + * control registers of all isochronous OUT endpoints to determine which + * endpoints had an incomplete transfer in the current microframe. An + * endpoint transfer is incomplete if both the following conditions are true: + * + * DOEPCTLx:EONUM = DSTS:SOFFN[0], and + * DOEPCTLx:EPENA = 1 + */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Is this an isochronous OUT endpoint? */ + + privep = &priv->epout[i]; + if (privep->eptype != USB_EP_ATTR_XFER_ISOC) + { + /* No... keep looking */ + + continue; + } + + /* Is there an active read request on the isochronous OUT endpoint? */ + + if (!privep->active) + { + /* No.. the endpoint is not actively transmitting data */ + + continue; + } + + /* Check if this is the endpoint that had the incomplete transfer */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + doepctl = stm32_getreg(regaddr); + dsts = stm32_getreg(STM32_OTG_DSTS); + + /* EONUM = 0:even frame, 1:odd frame + * SOFFN = Frame number of the received SOF + */ + + eonum = ((doepctl & OTG_DOEPCTL_EONUM) != 0); + soffn = ((dsts & OTG_DSTS_SOFFN0) != 0); + + if (eonum != soffn) + { + /* Not this endpoint */ + + continue; + } + + /* For isochronous OUT endpoints with incomplete transfers, + * the application must discard the data in the memory and + * disable the endpoint. + */ + + stm32_req_complete(privep, -EIO); +#warning "Will clear OTG_DOEPCTL_USBAEP too" + stm32_epout_disable(privep); + break; + } +} +#endif + +/**************************************************************************** + * Name: stm32_sessioninterrupt + * + * Description: + * Session request/new session detected interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_sessioninterrupt(FAR struct stm32_usbdev_s *priv) +{ +#warning "Missing logic" +} +#endif + +/**************************************************************************** + * Name: stm32_otginterrupt + * + * Description: + * OTG interrupt + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_VBUSSENSING +static inline void stm32_otginterrupt(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + + /* Check for session end detected */ + + regval = stm32_getreg(STM32_OTG_GOTGINT); + if ((regval & OTG_GOTGINT_SEDET) != 0) + { +#warning "Missing logic" + } + + /* Clear OTG interrupt */ + + stm32_putreg(retval, STM32_OTG_GOTGINT); +} +#endif + +/**************************************************************************** + * Name: stm32_usbinterrupt + * + * Description: + * USB interrupt handler + * + ****************************************************************************/ + +static int stm32_usbinterrupt(int irq, FAR void *context) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + uint32_t regval; + + usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), 0); + + /* Assure that we are in device mode */ + + DEBUGASSERT((stm32_getreg(STM32_OTG_GINTSTS) & OTG_GINTSTS_CMOD) == OTG_GINTSTS_DEVMODE); + + /* Get the state of all enabled interrupts. We will do this repeatedly + * some interrupts (like RXFLVL) will generate additional interrupting + * events. + */ + + for (; ; ) + { + /* Get the set of pending, un-masked interrupts */ + + regval = stm32_getreg(STM32_OTG_GINTSTS); + regval &= stm32_getreg(STM32_OTG_GINTMSK); + + /* Break out of the loop when there are no further pending (and + * unmasked) interrupts to be processes. + */ + + if (regval == 0) + { + break; + } + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_INTPENDING), (uint16_t)regval); + + /* OUT endpoint interrupt. The core sets this bit to indicate that an + * interrupt is pending on one of the OUT endpoints of the core. + */ + + if ((regval & OTG_GINT_OEP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPOUT), (uint16_t)regval); + stm32_epout_interrupt(priv); + stm32_putreg(OTG_GINT_OEP, STM32_OTG_GINTSTS); + } + + /* IN endpoint interrupt. The core sets this bit to indicate that + * an interrupt is pending on one of the IN endpoints of the core. + */ + + if ((regval & OTG_GINT_IEP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_EPIN), (uint16_t)regval); + stm32_epin_interrupt(priv); + stm32_putreg(OTG_GINT_IEP, STM32_OTG_GINTSTS); + } + + /* Host/device mode mismatch error interrupt */ + +#ifdef CONFIG_DEBUG_USB + if ((regval & OTG_GINT_MMIS) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_MISMATCH), (uint16_t)regval); + stm32_putreg(OTG_GINT_MMIS, STM32_OTG_GINTSTS); + } +#endif + + /* Resume/remote wakeup detected interrupt */ + + if ((regval & OTG_GINT_WKUP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_WAKEUP), (uint16_t)regval); + stm32_resumeinterrupt(priv); + stm32_putreg(OTG_GINT_WKUP, STM32_OTG_GINTSTS); + } + + /* USB suspend interrupt */ + + if ((regval & OTG_GINT_USBSUSP) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SUSPEND), (uint16_t)regval); + stm32_suspendinterrupt(priv); + stm32_putreg(OTG_GINT_USBSUSP, STM32_OTG_GINTSTS); + } + + /* Start of frame interrupt */ + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + if ((regval & OTG_GINT_SOF) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SOF), (uint16_t)regval); + stm32_putreg(OTG_GINT_SOF, STM32_OTG_GINTSTS); + } +#endif + + /* RxFIFO non-empty interrupt. Indicates that there is at least one + * packet pending to be read from the RxFIFO. + */ + + if ((regval & OTG_GINT_RXFLVL) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_RXFIFO), (uint16_t)regval); + stm32_rxinterrupt(priv); + stm32_putreg(OTG_GINT_RXFLVL, STM32_OTG_GINTSTS); + } + + /* USB reset interrupt */ + + if ((regval & OTG_GINT_USBRST) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_DEVRESET), (uint16_t)regval); + + /* Perform the device reset */ + + stm32_usbreset(priv); + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0); + stm32_putreg(OTG_GINT_USBRST, STM32_OTG_GINTSTS); + return OK; + } + + /* Enumeration done interrupt */ + + if ((regval & OTG_GINT_ENUMDNE) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_ENUMDNE), (uint16_t)regval); + stm32_enuminterrupt(priv); + stm32_putreg(OTG_GINT_ENUMDNE, STM32_OTG_GINTSTS); + } + + /* Incomplete isochronous IN transfer interrupt. When the core finds + * non-empty any of the isochronous IN endpoint FIFOs scheduled for + * the current frame non-empty, the core generates an IISOIXFR + * interrupt. + */ + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + if ((regval & OTG_GINT_IISOIXFR) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOIXFR), (uint16_t)regval); + stm32_isocininterrupt(priv); + stm32_putreg(OTG_GINT_IISOIXFR, STM32_OTG_GINTSTS); + } + + /* Incomplete isochronous OUT transfer. For isochronous OUT + * endpoints, the XFRC interrupt may not always be asserted. If the + * core drops isochronous OUT data packets, the application could fail + * to detect the XFRC interrupt. The incomplete Isochronous OUT data + * interrupt indicates that an XFRC interrupt was not asserted on at + * least one of the isochronous OUT endpoints. At this point, the + * endpoint with the incomplete transfer remains enabled, but no active + * transfers remain in progress on this endpoint on the USB. + */ + + if ((regval & OTG_GINT_IISOOXFR) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_IISOOXFR), (uint16_t)regval); + stm32_isocoutinterrupt(priv); + stm32_putreg(OTG_GINT_IISOOXFR, STM32_OTG_GINTSTS); + } +#endif + + /* Session request/new session detected interrupt */ + +#ifdef CONFIG_USBDEV_VBUSSENSING + if ((regval & OTG_GINT_SRQ) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_SRQ), (uint16_t)regval); + stm32_sessioninterrupt(priv); + stm32_putreg(OTG_GINT_SRQ, STM32_OTG_GINTSTS); + } + + /* OTG interrupt */ + + if ((regval & OTG_GINT_OTG) != 0) + { + usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_OTG), (uint16_t)regval); + stm32_otginterrupt(priv); + stm32_putreg(OTG_GINT_OTG, STM32_OTG_GINTSTS); + } +#endif + } + + usbtrace(TRACE_INTEXIT(STM32_TRACEINTID_USB), 0); + return OK; +} + +/**************************************************************************** + * Endpoint operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_enablegonak + * + * Description: + * Enable global OUT NAK mode + * + ****************************************************************************/ + +static void stm32_enablegonak(FAR struct stm32_ep_s *privep) +{ + uint32_t regval; + + /* First, make sure that there is no GNOAKEFF interrupt pending. */ + +#if 0 + stm32_putreg(OTG_GINT_GONAKEFF, STM32_OTG_GINTSTS); +#endif + + /* Enable Global OUT NAK mode in the core. */ + + regval = stm32_getreg(STM32_OTG_DCTL); + regval |= OTG_DCTL_SGONAK; + stm32_putreg(regval, STM32_OTG_DCTL); + +#if 0 + /* Wait for the GONAKEFF interrupt that indicates that the OUT NAK + * mode is in effect. When the interrupt handler pops the OUTNAK word + * from the RxFIFO, the core sets the GONAKEFF interrupt. + */ + + while ((stm32_getreg(STM32_OTG_GINTSTS) & OTG_GINT_GONAKEFF) == 0); + stm32_putreg(OTG_GINT_GONAKEFF, STM32_OTG_GINTSTS); + +#else + /* Since we are in the interrupt handler, we cannot wait inline for the + * GONAKEFF because it cannot occur until service the RXFLVL global interrupt + * and pop the OUTNAK word from the RxFIFO. + * + * Perhaps it is sufficient to wait for Global OUT NAK status to be reported + * in OTG DCTL register? + */ + + while ((stm32_getreg(STM32_OTG_DCTL) & OTG_DCTL_GONSTS) == 0); +#endif +} + +/**************************************************************************** + * Name: stm32_disablegonak + * + * Description: + * Disable global OUT NAK mode + * + ****************************************************************************/ + +static void stm32_disablegonak(FAR struct stm32_ep_s *privep) +{ + uint32_t regval; + + /* Set the "Clear the Global OUT NAK bit" to disable global OUT NAK mode */ + + regval = stm32_getreg(STM32_OTG_DCTL); + regval |= OTG_DCTL_CGONAK; + stm32_putreg(regval, STM32_OTG_DCTL); +} + +/**************************************************************************** + * Name: stm32_epout_configure + * + * Description: + * Configure an OUT endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int stm32_epout_configure(FAR struct stm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = OTG_DOEPCTL0_MPSIZ_8; + break; + + case 16: + mpsiz = OTG_DOEPCTL0_MPSIZ_16; + break; + + case 32: + mpsiz = OTG_DOEPCTL0_MPSIZ_32; + break; + + case 64: + mpsiz = OTG_DOEPCTL0_MPSIZ_64; + break; + + default: + uerr("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << OTG_DOEPCTL_MPSIZ_SHIFT); + } + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTG_DOEPCTL_USBAEP) == 0) + { + if (regval & OTG_DOEPCTL_NAKSTS) + { + regval |= OTG_DOEPCTL_CNAK; + } + + regval &= ~(OTG_DOEPCTL_MPSIZ_MASK | OTG_DOEPCTL_EPTYP_MASK); + regval |= mpsiz; + regval |= (eptype << OTG_DOEPCTL_EPTYP_SHIFT); + regval |= (OTG_DOEPCTL_SD0PID | OTG_DOEPCTL_USBAEP); + stm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = stm32_getreg(STM32_OTG_DAINTMSK); + regval |= OTG_DAINT_OEP(privep->epphy); + stm32_putreg(regval, STM32_OTG_DAINTMSK); + return OK; +} + +/**************************************************************************** + * Name: stm32_epin_configure + * + * Description: + * Configure an IN endpoint, making it usable + * + * Input Parameters: + * privep - a pointer to an internal endpoint structure + * eptype - The type of the endpoint + * maxpacket - The max packet size of the endpoint + * + ****************************************************************************/ + +static int stm32_epin_configure(FAR struct stm32_ep_s *privep, uint8_t eptype, + uint16_t maxpacket) +{ + uint32_t mpsiz; + uint32_t regaddr; + uint32_t regval; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + + /* For EP0, the packet size is encoded */ + + if (privep->epphy == EP0) + { + DEBUGASSERT(eptype == USB_EP_ATTR_XFER_CONTROL); + + /* Map the size in bytes to the encoded value in the register */ + + switch (maxpacket) + { + case 8: + mpsiz = OTG_DIEPCTL0_MPSIZ_8; + break; + + case 16: + mpsiz = OTG_DIEPCTL0_MPSIZ_16; + break; + + case 32: + mpsiz = OTG_DIEPCTL0_MPSIZ_32; + break; + + case 64: + mpsiz = OTG_DIEPCTL0_MPSIZ_64; + break; + + default: + uerr("Unsupported maxpacket: %d\n", maxpacket); + return -EINVAL; + } + } + + /* For other endpoints, the packet size is in bytes */ + + else + { + mpsiz = (maxpacket << OTG_DIEPCTL_MPSIZ_SHIFT); + } + + + /* If the endpoint is already active don't change the endpoint control + * register. + */ + + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTG_DIEPCTL_USBAEP) == 0) + { + if (regval & OTG_DIEPCTL_NAKSTS) + { + regval |= OTG_DIEPCTL_CNAK; + } + + regval &= ~(OTG_DIEPCTL_MPSIZ_MASK | OTG_DIEPCTL_EPTYP_MASK | OTG_DIEPCTL_TXFNUM_MASK); + regval |= mpsiz; + regval |= (eptype << OTG_DIEPCTL_EPTYP_SHIFT); + regval |= (eptype << OTG_DIEPCTL_TXFNUM_SHIFT); + regval |= (OTG_DIEPCTL_SD0PID | OTG_DIEPCTL_USBAEP); + stm32_putreg(regval, regaddr); + + /* Save the endpoint configuration */ + + privep->ep.maxpacket = maxpacket; + privep->eptype = eptype; + privep->stalled = false; + } + + /* Enable the interrupt for this endpoint */ + + regval = stm32_getreg(STM32_OTG_DAINTMSK); + regval |= OTG_DAINT_IEP(privep->epphy); + stm32_putreg(regval, STM32_OTG_DAINTMSK); + + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_configure + * + * Description: + * Configure endpoint, making it usable + * + * Input Parameters: + * ep - the struct usbdev_ep_s instance obtained from allocep() + * desc - A struct usb_epdesc_s instance describing the endpoint + * last - true if this this last endpoint to be configured. Some hardware + * needs to take special action when all of the endpoints have been + * configured. + * + ****************************************************************************/ + +static int stm32_ep_configure(FAR struct usbdev_ep_s *ep, + FAR const struct usb_epdesc_s *desc, + bool last) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + uint16_t maxpacket; + uint8_t eptype; + int ret; + + usbtrace(TRACE_EPCONFIGURE, privep->epphy); + DEBUGASSERT(desc->addr == ep->eplog); + + /* Initialize EP capabilities */ + + maxpacket = GETUINT16(desc->mxpacketsize); + eptype = desc->attr & USB_EP_ATTR_XFERTYPE_MASK; + + /* Setup Endpoint Control Register */ + + if (privep->isin) + { + ret = stm32_epin_configure(privep, eptype, maxpacket); + } + else + { + ret = stm32_epout_configure(privep, eptype, maxpacket); + } + + return ret; +} + +/**************************************************************************** + * Name: stm32_ep0_configure + * + * Description: + * Reset Usb engine + * + ****************************************************************************/ + +static void stm32_ep0_configure(FAR struct stm32_usbdev_s *priv) +{ + /* Enable EP0 IN and OUT */ + + (void)stm32_epin_configure(&priv->epin[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); + (void)stm32_epout_configure(&priv->epout[EP0], USB_EP_ATTR_XFER_CONTROL, + CONFIG_USBDEV_EP0_MAXSIZE); +} + +/**************************************************************************** + * Name: stm32_epout_disable + * + * Description: + * Diable an OUT endpoint will no longer be used + * + ****************************************************************************/ + +static void stm32_epout_disable(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + /* Before disabling any OUT endpoint, the application must enable + * Global OUT NAK mode in the core. + */ + + flags = enter_critical_section(); + stm32_enablegonak(privep); + + /* Disable the required OUT endpoint by setting the EPDIS and SNAK bits + * int DOECPTL register. + */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTG_DOEPCTL_USBAEP; + regval |= (OTG_DOEPCTL_EPDIS | OTG_DOEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = STM32_OTG_DOEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTG_DOEPINT_EPDISD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Clear the EPDISD interrupt indication */ + + stm32_putreg(OTG_DOEPINT_EPDISD, STM32_OTG_DOEPINT(privep->epphy)); + + /* Then disable the Global OUT NAK mode to continue receiving data + * from other non-disabled OUT endpoints. + */ + + stm32_disablegonak(privep); + + /* Disable endpoint interrupts */ + + regval = stm32_getreg(STM32_OTG_DAINTMSK); + regval &= ~OTG_DAINT_OEP(privep->epphy); + stm32_putreg(regval, STM32_OTG_DAINTMSK); + + /* Cancel any queued read requests */ + + stm32_req_cancel(privep, -ESHUTDOWN); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_epin_disable + * + * Description: + * Disable an IN endpoint when it will no longer be used + * + ****************************************************************************/ + +static void stm32_epin_disable(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* After USB reset, the endpoint will already be deactivated by the + * hardware. Trying to disable again will just hang in the wait. + */ + + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + if ((regval & OTG_DIEPCTL_USBAEP) == 0) + { + return; + } + + /* This INEPNE wait logic is suggested by reference manual, but seems + * to get stuck to infinite loop. + */ + +#if 0 + /* Make sure that there is no pending IPEPNE interrupt (because we are + * to poll this bit below). + */ + + stm32_putreg(OTG_DIEPINT_INEPNE, STM32_OTG_DIEPINT(privep->epphy)); + + /* Set the endpoint in NAK mode */ + + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTG_DIEPCTL_USBAEP; + regval |= (OTG_DIEPCTL_EPDIS | OTG_DIEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the INEPNE interrupt that indicates that we are now in NAK mode */ + + regaddr = STM32_OTG_DIEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTG_DIEPINT_INEPNE) == 0); + + /* Clear the INEPNE interrupt indication */ + + stm32_putreg(OTG_DIEPINT_INEPNE, regaddr); +#endif + + /* Deactivate and disable the endpoint by setting the EPDIS and SNAK bits + * the DIEPCTLx register. + */ + + flags = enter_critical_section(); + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval &= ~OTG_DIEPCTL_USBAEP; + regval |= (OTG_DIEPCTL_EPDIS | OTG_DIEPCTL_SNAK); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the IN + * endpoint is completely disabled. + */ + + regaddr = STM32_OTG_DIEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTG_DIEPINT_EPDISD) == 0); + + /* Clear the EPDISD interrupt indication */ + + stm32_putreg(OTG_DIEPINT_EPDISD, stm32_getreg(regaddr)); + + /* Flush any data remaining in the TxFIFO */ + + stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_D(privep->epphy)); + + /* Disable endpoint interrupts */ + + regval = stm32_getreg(STM32_OTG_DAINTMSK); + regval &= ~OTG_DAINT_IEP(privep->epphy); + stm32_putreg(regval, STM32_OTG_DAINTMSK); + + /* Cancel any queued write requests */ + + stm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: stm32_ep_disable + * + * Description: + * The endpoint will no longer be used + * + ****************************************************************************/ + +static int stm32_ep_disable(FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPDISABLE, privep->epphy); + + /* Is this an IN or an OUT endpoint */ + + if (privep->isin) + { + /* Disable the IN endpoint */ + + stm32_epin_disable(privep); + } + else + { + /* Disable the OUT endpoint */ + + stm32_epout_disable(privep); + } + + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_allocreq + * + * Description: + * Allocate an I/O request + * + ****************************************************************************/ + +static FAR struct usbdev_req_s *stm32_ep_allocreq(FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_req_s *privreq; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return NULL; + } +#endif + + usbtrace(TRACE_EPALLOCREQ, ((FAR struct stm32_ep_s *)ep)->epphy); + + privreq = (FAR struct stm32_req_s *)kmm_malloc(sizeof(struct stm32_req_s)); + if (!privreq) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_ALLOCFAIL), 0); + return NULL; + } + + memset(privreq, 0, sizeof(struct stm32_req_s)); + return &privreq->req; +} + +/**************************************************************************** + * Name: stm32_ep_freereq + * + * Description: + * Free an I/O request + * + ****************************************************************************/ + +static void stm32_ep_freereq(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return; + } +#endif + + usbtrace(TRACE_EPFREEREQ, ((FAR struct stm32_ep_s *)ep)->epphy); + kmm_free(privreq); +} + +/**************************************************************************** + * Name: stm32_ep_allocbuffer + * + * Description: + * Allocate an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void *stm32_ep_allocbuffer(FAR struct usbdev_ep_s *ep, unsigned bytes) +{ + usbtrace(TRACE_EPALLOCBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + return usbdev_dma_alloc(bytes); +#else + return kmm_malloc(bytes); +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_ep_freebuffer + * + * Description: + * Free an I/O buffer + * + ****************************************************************************/ + +#ifdef CONFIG_USBDEV_DMA +static void stm32_ep_freebuffer(FAR struct usbdev_ep_s *ep, FAR void *buf) +{ + usbtrace(TRACE_EPFREEBUFFER, privep->epphy); + +#ifdef CONFIG_USBDEV_DMAMEMORY + usbdev_dma_free(buf); +#else + kmm_free(buf); +#endif +} +#endif + +/**************************************************************************** + * Name: stm32_ep_submit + * + * Description: + * Submit an I/O request to the endpoint + * + ****************************************************************************/ + +static int stm32_ep_submit(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_req_s *privreq = (FAR struct stm32_req_s *)req; + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + FAR struct stm32_usbdev_s *priv; + irqstate_t flags; + int ret = OK; + + /* Some sanity checking */ + +#ifdef CONFIG_DEBUG_FEATURES + if (!req || !req->callback || !req->buf || !ep) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + ullinfo("req=%p callback=%p buf=%p ep=%p\n", req, req->callback, req->buf, ep); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPSUBMIT, privep->epphy); + priv = privep->dev; + +#ifdef CONFIG_DEBUG_FEATURES + if (!priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOTCONFIGURED), priv->usbdev.speed); + return -ESHUTDOWN; + } +#endif + + /* Handle the request from the class driver */ + + req->result = -EINPROGRESS; + req->xfrd = 0; + + /* Disable Interrupts */ + + flags = enter_critical_section(); + + /* If we are stalled, then drop all requests on the floor */ + + if (privep->stalled) + { + ret = -EBUSY; + } + else + { + /* Add the new request to the request queue for the endpoint. */ + + if (stm32_req_addlast(privep, privreq) && !privep->active) + { + /* If a request was added to an IN endpoint, then attempt to send + * the request data buffer now. + */ + + if (privep->isin) + { + usbtrace(TRACE_INREQQUEUED(privep->epphy), privreq->req.len); + + /* If the endpoint is not busy with another write request, + * then process the newly received write request now. + */ + + if (!privep->active) + { + stm32_epin_request(priv, privep); + } + } + + /* If the request was added to an OUT endpoint, then attempt to + * setup a read into the request data buffer now (this will, of + * course, fail if there is already a read in place). + */ + + else + { + usbtrace(TRACE_OUTREQQUEUED(privep->epphy), privreq->req.len); + stm32_epout_request(priv, privep); + } + } + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_ep_cancel + * + * Description: + * Cancel an I/O request previously sent to an endpoint + * + ****************************************************************************/ + +static int stm32_ep_cancel(FAR struct usbdev_ep_s *ep, FAR struct usbdev_req_s *req) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + +#ifdef CONFIG_DEBUG_FEATURES + if (!ep || !req) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + usbtrace(TRACE_EPCANCEL, privep->epphy); + + flags = enter_critical_section(); + + /* FIXME: if the request is the first, then we need to flush the EP + * otherwise just remove it from the list + * + * but ... all other implementations cancel all requests ... + */ + + stm32_req_cancel(privep, -ESHUTDOWN); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_epout_setstall + * + * Description: + * Stall an OUT endpoint + * + ****************************************************************************/ + +static int stm32_epout_setstall(FAR struct stm32_ep_s *privep) +{ +#if 1 + /* This implementation follows the requirements from the STM32 F4 reference + * manual. + */ + + uint32_t regaddr; + uint32_t regval; + + /* Put the core in the Global OUT NAK mode */ + + stm32_enablegonak(privep); + + /* Disable and STALL the OUT endpoint by setting the EPDIS and STALL bits + * in the DOECPTL register. + */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= (OTG_DOEPCTL_EPDIS | OTG_DOEPCTL_STALL); + stm32_putreg(regval, regaddr); + + /* Wait for the EPDISD interrupt which indicates that the OUT + * endpoint is completely disabled. + */ + +#if 0 /* Doesn't happen */ + regaddr = STM32_OTG_DOEPINT(privep->epphy); + while ((stm32_getreg(regaddr) & OTG_DOEPINT_EPDISD) == 0); +#else + /* REVISIT: */ + up_udelay(10); +#endif + + /* Disable Global OUT NAK mode */ + + stm32_disablegonak(privep); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#else + /* This implementation follows the STMicro code example. */ + /* REVISIT: */ + + uint32_t regaddr; + uint32_t regval; + + /* Stall the OUT endpoint by setting the STALL bit in the DOECPTL register. */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + regval |= OTG_DOEPCTL_STALL; + stm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +#endif +} + +/**************************************************************************** + * Name: stm32_epin_setstall + * + * Description: + * Stall an IN endpoint + * + ****************************************************************************/ + +static int stm32_epin_setstall(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + + /* Get the IN endpoint device control register */ + + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + regval = stm32_getreg(regaddr); + + /* Then stall the endpoint */ + + regval |= OTG_DIEPCTL_STALL; + stm32_putreg(regval, regaddr); + + /* The endpoint is now stalled */ + + privep->stalled = true; + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_setstall + * + * Description: + * Stall an endpoint + * + ****************************************************************************/ + +static int stm32_ep_setstall(FAR struct stm32_ep_s *privep) +{ + usbtrace(TRACE_EPSTALL, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + return stm32_epin_setstall(privep); + } + else + { + return stm32_epout_setstall(privep); + } +} + +/**************************************************************************** + * Name: stm32_ep_clrstall + * + * Description: + * Resume a stalled endpoint + * + ****************************************************************************/ + +static int stm32_ep_clrstall(FAR struct stm32_ep_s *privep) +{ + uint32_t regaddr; + uint32_t regval; + uint32_t stallbit; + uint32_t data0bit; + + usbtrace(TRACE_EPRESUME, privep->epphy); + + /* Is this an IN endpoint? */ + + if (privep->isin == 1) + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = STM32_OTG_DIEPCTL(privep->epphy); + stallbit = OTG_DIEPCTL_STALL; + data0bit = OTG_DIEPCTL_SD0PID; + } + else + { + /* Clear the stall bit in the IN endpoint device control register */ + + regaddr = STM32_OTG_DOEPCTL(privep->epphy); + stallbit = OTG_DOEPCTL_STALL; + data0bit = OTG_DOEPCTL_SD0PID; + } + + /* Clear the stall bit */ + + regval = stm32_getreg(regaddr); + regval &= ~stallbit; + + /* Set the DATA0 pid for interrupt and bulk endpoints */ + + if (privep->eptype == USB_EP_ATTR_XFER_INT || + privep->eptype == USB_EP_ATTR_XFER_BULK) + { + /* Writing this bit sets the DATA0 PID */ + + regval |= data0bit; + } + + stm32_putreg(regval, regaddr); + + /* The endpoint is no longer stalled */ + + privep->stalled = false; + return OK; +} + +/**************************************************************************** + * Name: stm32_ep_stall + * + * Description: + * Stall or resume an endpoint + * + ****************************************************************************/ + +static int stm32_ep_stall(FAR struct usbdev_ep_s *ep, bool resume) +{ + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + int ret; + + /* Set or clear the stall condition as requested */ + + flags = enter_critical_section(); + if (resume) + { + ret = stm32_ep_clrstall(privep); + } + else + { + ret = stm32_ep_setstall(privep); + } + leave_critical_section(flags); + + return ret; +} + +/**************************************************************************** + * Name: stm32_ep0_stall + * + * Description: + * Stall endpoint 0 + * + ****************************************************************************/ + +static void stm32_ep0_stall(FAR struct stm32_usbdev_s *priv) +{ + stm32_epin_setstall(&priv->epin[EP0]); + stm32_epout_setstall(&priv->epout[EP0]); + priv->stalled = true; + stm32_ep0out_ctrlsetup(priv); +} + +/**************************************************************************** + * Device operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ep_alloc + * + * Description: + * Allocate an endpoint matching the parameters. + * + * Input Parameters: + * eplog - 7-bit logical endpoint number (direction bit ignored). Zero means + * that any endpoint matching the other requirements will suffice. The + * assigned endpoint can be found in the eplog field. + * in - true: IN (device-to-host) endpoint requested + * eptype - Endpoint type. One of {USB_EP_ATTR_XFER_ISOC, USB_EP_ATTR_XFER_BULK, + * USB_EP_ATTR_XFER_INT} + * + ****************************************************************************/ + +static FAR struct usbdev_ep_s *stm32_ep_alloc(FAR struct usbdev_s *dev, + uint8_t eplog, bool in, + uint8_t eptype) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + uint8_t epavail; + irqstate_t flags; + int epphy; + int epno = 0; + + usbtrace(TRACE_DEVALLOCEP, (uint16_t)eplog); + + /* Ignore any direction bits in the logical address */ + + epphy = USB_EPNO(eplog); + + /* Get the set of available endpoints depending on the direction */ + + flags = enter_critical_section(); + epavail = priv->epavail[in]; + + /* A physical address of 0 means that any endpoint will do */ + + if (epphy > 0) + { + /* Otherwise, we will return the endpoint structure only for the requested + * 'logical' endpoint. All of the other checks will still be performed. + * + * First, verify that the logical endpoint is in the range supported by + * by the hardware. + */ + + if (epphy >= STM32_NENDPOINTS) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BADEPNO), (uint16_t)epphy); + return NULL; + } + + /* Remove all of the candidate endpoints from the bitset except for the + * this physical endpoint number. + */ + + epavail &= (1 << epphy); + } + + /* Is there an available endpoint? */ + + if (epavail) + { + /* Yes.. Select the lowest numbered endpoint in the set of available + * endpoints. + */ + + for (epno = 1; epno < STM32_NENDPOINTS; epno++) + { + uint8_t bit = 1 << epno; + if ((epavail & bit) != 0) + { + /* Mark the endpoint no longer available */ + + priv->epavail[in] &= ~(1 << epno); + + /* And return the pointer to the standard endpoint structure */ + + leave_critical_section(flags); + return in ? &priv->epin[epno].ep : &priv->epout[epno].ep; + } + } + + /* We should not get here */ + } + + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_NOEP), (uint16_t)eplog); + leave_critical_section(flags); + return NULL; +} + +/**************************************************************************** + * Name: stm32_ep_free + * + * Description: + * Free the previously allocated endpoint + * + ****************************************************************************/ + +static void stm32_ep_free(FAR struct usbdev_s *dev, FAR struct usbdev_ep_s *ep) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + FAR struct stm32_ep_s *privep = (FAR struct stm32_ep_s *)ep; + irqstate_t flags; + + usbtrace(TRACE_DEVFREEEP, (uint16_t)privep->epphy); + + if (priv && privep) + { + /* Mark the endpoint as available */ + + flags = enter_critical_section(); + priv->epavail[privep->isin] |= (1 << privep->epphy); + leave_critical_section(flags); + } +} + +/**************************************************************************** + * Name: stm32_getframe + * + * Description: + * Returns the current frame number + * + ****************************************************************************/ + +static int stm32_getframe(struct usbdev_s *dev) +{ + uint32_t regval; + + usbtrace(TRACE_DEVGETFRAME, 0); + + /* Return the last frame number of the last SOF detected by the hardware */ + + regval = stm32_getreg(STM32_OTG_DSTS); + return (int)((regval & OTG_DSTS_SOFFN_MASK) >> OTG_DSTS_SOFFN_SHIFT); +} + +/**************************************************************************** + * Name: stm32_wakeup + * + * Description: + * Exit suspend mode. + * + ****************************************************************************/ + +static int stm32_wakeup(struct usbdev_s *dev) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + uint32_t regval; + irqstate_t flags; + + usbtrace(TRACE_DEVWAKEUP, 0); + + /* Is wakeup enabled? */ + + flags = enter_critical_section(); + if (priv->wakeup) + { + /* Yes... is the core suspended? */ + + regval = stm32_getreg(STM32_OTG_DSTS); + if ((regval & OTG_DSTS_SUSPSTS) != 0) + { + /* Re-start the PHY clock and un-gate USB core clock (HCLK) */ + +#ifdef CONFIG_USBDEV_LOWPOWER + regval = stm32_getreg(STM32_OTG_PCGCCTL); + regval &= ~(OTG_PCGCCTL_STPPCLK | OTG_PCGCCTL_GATEHCLK); + stm32_putreg(regval, STM32_OTG_PCGCCTL); +#endif + /* Activate Remote wakeup signaling */ + + regval = stm32_getreg(STM32_OTG_DCTL); + regval |= OTG_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTG_DCTL); + up_mdelay(5); + regval &= ~OTG_DCTL_RWUSIG; + stm32_putreg(regval, STM32_OTG_DCTL); + } + } + + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_selfpowered + * + * Description: + * Sets/clears the device self-powered feature + * + ****************************************************************************/ + +static int stm32_selfpowered(struct usbdev_s *dev, bool selfpowered) +{ + FAR struct stm32_usbdev_s *priv = (FAR struct stm32_usbdev_s *)dev; + + usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered); + +#ifdef CONFIG_DEBUG_FEATURES + if (!dev) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -ENODEV; + } +#endif + + priv->selfpowered = selfpowered; + return OK; +} + +/**************************************************************************** + * Name: stm32_pullup + * + * Description: + * Software-controlled connect to/disconnect from USB host + * + ****************************************************************************/ + +static int stm32_pullup(struct usbdev_s *dev, bool enable) +{ + uint32_t regval; + + usbtrace(TRACE_DEVPULLUP, (uint16_t)enable); + + irqstate_t flags = enter_critical_section(); + regval = stm32_getreg(STM32_OTG_DCTL); + if (enable) + { + /* Connect the device by clearing the soft disconnect bit in the DCTL + * register + */ + + regval &= ~OTG_DCTL_SDIS; + } + else + { + /* Connect the device by setting the soft disconnect bit in the DCTL + * register + */ + + regval |= OTG_DCTL_SDIS; + } + + stm32_putreg(regval, STM32_OTG_DCTL); + leave_critical_section(flags); + return OK; +} + +/**************************************************************************** + * Name: stm32_setaddress + * + * Description: + * Set the devices USB address + * + ****************************************************************************/ + +static void stm32_setaddress(struct stm32_usbdev_s *priv, uint16_t address) +{ + uint32_t regval; + + /* Set the device address in the DCFG register */ + + regval = stm32_getreg(STM32_OTG_DCFG); + regval &= ~OTG_DCFG_DAD_MASK; + regval |= ((uint32_t)address << OTG_DCFG_DAD_SHIFT); + stm32_putreg(regval, STM32_OTG_DCFG); + + /* Are we now addressed? (i.e., do we have a non-NULL device + * address?) + */ + + if (address != 0) + { + priv->devstate = DEVSTATE_ADDRESSED; + priv->addressed = true; + } + else + { + priv->devstate = DEVSTATE_DEFAULT; + priv->addressed = false; + } +} + +/**************************************************************************** + * Name: stm32_txfifo_flush + * + * Description: + * Flush the specific TX fifo. + * + ****************************************************************************/ + +static int stm32_txfifo_flush(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = OTG_GRSTCTL_TXFFLSH | txfnum; + stm32_putreg(regval, STM32_OTG_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: stm32_rxfifo_flush + * + * Description: + * Flush the RX fifo. + * + ****************************************************************************/ + +static int stm32_rxfifo_flush(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + stm32_putreg(OTG_GRSTCTL_RXFFLSH, STM32_OTG_GRSTCTL); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + return OK; +} + +/**************************************************************************** + * Name: stm32_swinitialize + * + * Description: + * Initialize all driver data structures. + * + ****************************************************************************/ + +static void stm32_swinitialize(FAR struct stm32_usbdev_s *priv) +{ + FAR struct stm32_ep_s *privep; + int i; + + /* Initialize the device state structure */ + + memset(priv, 0, sizeof(struct stm32_usbdev_s)); + + priv->usbdev.ops = &g_devops; + priv->usbdev.ep0 = &priv->epin[EP0].ep; + + priv->epavail[0] = STM32_EP_AVAILABLE; + priv->epavail[1] = STM32_EP_AVAILABLE; + + priv->epin[EP0].ep.priv = priv; + priv->epout[EP0].ep.priv = priv; + + /* Initialize the endpoint lists */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epin[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + privep->isin = 1; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = STM32_EPPHYIN2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } + + /* Initialize the endpoint lists */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + /* Set endpoint operations, reference to driver structure (not + * really necessary because there is only one controller), and + * the physical endpoint number (which is just the index to the + * endpoint). + */ + + privep = &priv->epout[i]; + privep->ep.ops = &g_epops; + privep->dev = priv; + + /* The index, i, is the physical endpoint address; Map this + * to a logical endpoint address usable by the class driver. + */ + + privep->epphy = i; + privep->ep.eplog = STM32_EPPHYOUT2LOG(i); + + /* Control until endpoint is activated */ + + privep->eptype = USB_EP_ATTR_XFER_CONTROL; + privep->ep.maxpacket = CONFIG_USBDEV_EP0_MAXSIZE; + } +} + +/**************************************************************************** + * Name: stm32_hwinitialize + * + * Description: + * Configure the OTG core for operation. + * + ****************************************************************************/ + +static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv) +{ + uint32_t regval; + uint32_t timeout; + uint32_t address; + int i; + + /* At start-up the core is in FS/HS mode. */ + + /* Disable global interrupts by clearing the GINTMASK bit in the GAHBCFG + * register; Set the TXFELVL bit in the GAHBCFG register so that TxFIFO + * interrupts will occur when the TxFIFO is truly empty (not just half full). + */ + + stm32_putreg(OTG_GAHBCFG_TXFELVL, STM32_OTG_GAHBCFG); + +#if defined(CONFIG_STM32_OTGHS) + /* Set the PHYSEL bit in the GUSBCFG register to select the OTG HS serial + * transceiver: "This bit is always 1 with write-only access" + */ + + regval = stm32_getreg(STM32_OTG_GUSBCFG); + regval |= OTG_GUSBCFG_PHYSEL; + stm32_putreg(regval, STM32_OTG_GUSBCFG); +#endif + + /* Common USB OTG core initialization */ + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_AHBIDL) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + stm32_putreg(OTG_GRSTCTL_CSRST, STM32_OTG_GRSTCTL); + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_CSRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Deactivate the power down */ + + + /* Detection Enable when set + */ + + regval = OTG_GCCFG_PWRDWN; + +# ifdef CONFIG_USBDEV_VBUSSENSING + regval |= OTG_GCCFG_VBDEN; +# endif + + + stm32_putreg(regval, STM32_OTG_GCCFG); + up_mdelay(20); + + /* When VBUS sensing is not used we + * need to force the B session valid + */ + + +# ifndef CONFIG_USBDEV_VBUSSENSING + regval = stm32_getreg(STM32_OTG_GOTGCTL); + regval |= (OTG_GOTGCTL_BVALOEN | OTG_GOTGCTL_BVALOVAL); + stm32_putreg(regval, STM32_OTG_GOTGCTL); +# endif + + + /* Force Device Mode */ + + regval = stm32_getreg(STM32_OTG_GUSBCFG); + regval &= ~OTG_GUSBCFG_FHMOD; + regval |= OTG_GUSBCFG_FDMOD; + stm32_putreg(regval, STM32_OTG_GUSBCFG); + up_mdelay(50); + + /* Initialize device mode */ + /* Restart the PHY Clock */ + + stm32_putreg(0, STM32_OTG_PCGCCTL); + + /* Device configuration register */ + + regval = stm32_getreg(STM32_OTG_DCFG); + regval &= ~OTG_DCFG_PFIVL_MASK; + regval |= OTG_DCFG_PFIVL_80PCT; + stm32_putreg(regval, STM32_OTG_DCFG); + + /* Set full speed PHY */ + + regval = stm32_getreg(STM32_OTG_DCFG); + regval &= ~OTG_DCFG_DSPD_MASK; + regval |= OTG_DCFG_DSPD_FS; + stm32_putreg(regval, STM32_OTG_DCFG); + + /* Set Rx FIFO size */ + + stm32_putreg(STM32_RXFIFO_WORDS, STM32_OTG_GRXFSIZ); + + /* EP0 TX */ + + address = STM32_RXFIFO_WORDS; + regval = (address << OTG_DIEPTXF0_TX0FD_SHIFT) | + (STM32_EP0_TXFIFO_WORDS << OTG_DIEPTXF0_TX0FSA_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF0); + + /* EP1 TX */ + + address += STM32_EP0_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP1_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF1); + + /* EP2 TX */ + + address += STM32_EP1_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP2_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF2); + + /* EP3 TX */ + + address += STM32_EP2_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP3_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF3); + + /* Flush the FIFOs */ + + stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_DALL); + stm32_rxfifo_flush(); + + /* Clear all pending Device Interrupts */ + + stm32_putreg(0, STM32_OTG_DIEPMSK); + stm32_putreg(0, STM32_OTG_DOEPMSK); + stm32_putreg(0, STM32_OTG_DIEPEMPMSK); + stm32_putreg(0xffffffff, STM32_OTG_DAINT); + stm32_putreg(0, STM32_OTG_DAINTMSK); + + /* Configure all IN endpoints */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + regval = stm32_getreg(STM32_OTG_DIEPCTL(i)); + if ((regval & OTG_DIEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = OTG_DIEPCTL_EPENA | OTG_DIEPCTL_SNAK; + } + else + { + regval = 0; + } + + stm32_putreg(regval, STM32_OTG_DIEPCTL(i)); + stm32_putreg(0, STM32_OTG_DIEPTSIZ(i)); + stm32_putreg(0xff, STM32_OTG_DIEPINT(i)); + } + + /* Configure all OUT endpoints */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + regval = stm32_getreg(STM32_OTG_DOEPCTL(i)); + if ((regval & OTG_DOEPCTL_EPENA) != 0) + { + /* The endpoint is already enabled */ + + regval = OTG_DOEPCTL_EPENA | OTG_DOEPCTL_SNAK; + } + else + { + regval = 0; + } + + stm32_putreg(regval, STM32_OTG_DOEPCTL(i)); + stm32_putreg(0, STM32_OTG_DOEPTSIZ(i)); + stm32_putreg(0xff, STM32_OTG_DOEPINT(i)); + } + + /* Disable all interrupts. */ + + stm32_putreg(0, STM32_OTG_GINTMSK); + + /* Clear any pending USB_OTG Interrupts */ + + stm32_putreg(0xffffffff, STM32_OTG_GOTGINT); + + /* Clear any pending interrupts */ + + stm32_putreg(0xbfffffff, STM32_OTG_GINTSTS); + +#ifdef defined(CONFIG_STM32_OTGHS) + /* Disable the ULPI Clock enable in RCC AHB1 Register. This must + * be done because if both the ULPI and the FS PHY clock enable bits + * are set at the same time, the ARM never awakens from WFI due to + * some bug / errata in the chip. + */ + + regval = stm32_getreg(STM32_RCC_AHB1LPENR); + regval &= ~RCC_AHB1ENR_OTGULPIEN; + stm32_putreg(regval, STM32_RCC_AHB1LPENR); +#endif + + /* Enable the interrupts in the INTMSK */ + + regval = (OTG_GINT_RXFLVL | OTG_GINT_USBSUSP | OTG_GINT_ENUMDNE | + OTG_GINT_IEP | OTG_GINT_OEP | OTG_GINT_USBRST); + +#ifdef CONFIG_USBDEV_ISOCHRONOUS + regval |= (OTG_GINT_IISOIXFR | OTG_GINT_IISOOXFR); +#endif + +#ifdef CONFIG_USBDEV_SOFINTERRUPT + regval |= OTG_GINT_SOF; +#endif + +#ifdef CONFIG_USBDEV_VBUSSENSING + regval |= (OTG_GINT_OTG | OTG_GINT_SRQ); +#endif + +#ifdef CONFIG_DEBUG_USB + regval |= OTG_GINT_MMIS; +#endif + + stm32_putreg(regval, STM32_OTG_GINTMSK); + + /* Enable the USB global interrupt by setting GINTMSK in the global OTG + * AHB configuration register; Set the TXFELVL bit in the GAHBCFG + * register so that TxFIFO interrupts will occur when the TxFIFO is truly + * empty (not just half full). + */ + + stm32_putreg(OTG_GAHBCFG_GINTMSK | OTG_GAHBCFG_TXFELVL, + STM32_OTG_GAHBCFG); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_usbinitialize + * + * Description: + * Initialize USB hardware. + * + * Assumptions: + * - This function is called very early in the initialization sequence + * - PLL and GIO pin initialization is not performed here but should been in + * the low-level boot logic: PLL1 must be configured for operation at 48MHz + * and P0.23 and PO.31 in PINSEL1 must be configured for Vbus and USB connect + * LED. + * + ****************************************************************************/ + +void up_usbinitialize(void) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + int ret; + + usbtrace(TRACE_DEVINIT, 0); + + /* Here we assume that: + * + * 1. GPIOA and OTG peripheral clocking has already been enabled as part + * of the boot sequence. + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* Configure OTG alternate function pins + */ + + stm32_configgpio(GPIO_OTG_DM); + stm32_configgpio(GPIO_OTG_DP); + stm32_configgpio(GPIO_OTG_ID); /* Only needed for OTG */ + + /* SOF output pin configuration is configurable. */ + +#ifdef CONFIG_STM32_OTG_SOFOUTPUT + stm32_configgpio(GPIO_OTG_SOF); +#endif + + /* Uninitialize the hardware so that we know that we are starting from a + * known state. */ + + up_usbuninitialize(); + + /* Initialie the driver data structure */ + + stm32_swinitialize(priv); + + /* Attach the OTG interrupt handler */ + + ret = irq_attach(STM32_IRQ_OTG, stm32_usbinterrupt); + if (ret < 0) + { + uerr("irq_attach failed\n", ret); + goto errout; + } + + /* Initialize the USB OTG core */ + + stm32_hwinitialize(priv); + + /* Disconnect device */ + + stm32_pullup(&priv->usbdev, false); + + /* Reset/Re-initialize the USB hardware */ + + stm32_usbreset(priv); + + /* Enable USB controller interrupts at the NVIC */ + + up_enable_irq(STM32_IRQ_OTG); + +#ifdef CONFIG_ARCH_IRQPRIO + /* Set the interrupt priority */ + + up_prioritize_irq(STM32_IRQ_OTG, CONFIG_OTG_PRI); +#endif + return; + +errout: + up_usbuninitialize(); +} + +/**************************************************************************** + * Name: up_usbuninitialize + ****************************************************************************/ + +void up_usbuninitialize(void) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + irqstate_t flags; + int i; + + usbtrace(TRACE_DEVUNINIT, 0); + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVERREGISTERED), 0); + usbdev_unregister(priv->driver); + } + + /* Disconnect device */ + + flags = enter_critical_section(); + stm32_pullup(&priv->usbdev, false); + priv->usbdev.speed = USB_SPEED_UNKNOWN; + + /* Disable and detach IRQs */ + + up_disable_irq(STM32_IRQ_OTG); + irq_detach(STM32_IRQ_OTG); + + /* Disable all endpoint interrupts */ + + for (i = 0; i < STM32_NENDPOINTS; i++) + { + stm32_putreg(0xff, STM32_OTG_DIEPINT(i)); + stm32_putreg(0xff, STM32_OTG_DOEPINT(i)); + } + + stm32_putreg(0, STM32_OTG_DIEPMSK); + stm32_putreg(0, STM32_OTG_DOEPMSK); + stm32_putreg(0, STM32_OTG_DIEPEMPMSK); + stm32_putreg(0, STM32_OTG_DAINTMSK); + stm32_putreg(0xffffffff, STM32_OTG_DAINT); + + /* Flush the FIFOs */ + + stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_DALL); + stm32_rxfifo_flush(); + + /* TODO: Turn off USB power and clocking */ + + priv->devstate = DEVSTATE_DEFAULT; + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: usbdev_register + * + * Description: + * Register a USB device class driver. The class driver's bind() method will be + * called to bind it to a USB device driver. + * + ****************************************************************************/ + +int usbdev_register(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + int ret; + + usbtrace(TRACE_DEVREGISTER, 0); + +#ifdef CONFIG_DEBUG_FEATURES + if (!driver || !driver->ops->bind || !driver->ops->unbind || + !driver->ops->disconnect || !driver->ops->setup) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } + + if (priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_DRIVER), 0); + return -EBUSY; + } +#endif + + /* First hook up the driver */ + + priv->driver = driver; + + /* Then bind the class driver */ + + ret = CLASS_BIND(driver, &priv->usbdev); + if (ret) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_BINDFAILED), (uint16_t)-ret); + priv->driver = NULL; + } + else + { + /* Enable USB controller interrupts */ + + up_enable_irq(STM32_IRQ_OTG); + + /* FIXME: nothing seems to call DEV_CONNECT(), but we need to set + * the RS bit to enable the controller. It kind of makes sense + * to do this after the class has bound to us... + * GEN: This bug is really in the class driver. It should make the + * soft connect when it is ready to be enumerated. I have added + * that logic to the class drivers but left this logic here. + */ + + stm32_pullup(&priv->usbdev, true); + priv->usbdev.speed = USB_SPEED_FULL; + } + + return ret; +} + +/**************************************************************************** + * Name: usbdev_unregister + * + * Description: + * Un-register usbdev class driver.If the USB device is connected to a USB host, + * it will first disconnect(). The driver is also requested to unbind() and clean + * up any device state, before this procedure finally returns. + * + ****************************************************************************/ + +int usbdev_unregister(struct usbdevclass_driver_s *driver) +{ + /* At present, there is only a single OTG device support. Hence it is + * pre-allocated as g_otghsdev. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbdev_s *priv = &g_otghsdev; + irqstate_t flags; + + usbtrace(TRACE_DEVUNREGISTER, 0); + +#ifdef CONFIG_DEBUG_FEATURES + if (driver != priv->driver) + { + usbtrace(TRACE_DEVERROR(STM32_TRACEERR_INVALIDPARMS), 0); + return -EINVAL; + } +#endif + + /* Reset the hardware and cancel all requests. All requests must be + * canceled while the class driver is still bound. + */ + + flags = enter_critical_section(); + stm32_usbreset(priv); + leave_critical_section(flags); + + /* Unbind the class driver */ + + CLASS_UNBIND(driver, &priv->usbdev); + + /* Disable USB controller interrupts */ + + flags = enter_critical_section(); + up_disable_irq(STM32_IRQ_OTG); + + /* Disconnect device */ + + stm32_pullup(&priv->usbdev, false); + + /* Unhook the driver */ + + priv->driver = NULL; + leave_critical_section(flags); + + return OK; +} + +#endif /* CONFIG_USBDEV && CONFIG_STM32_OTGDEV */ diff --git a/arch/arm/src/stm32f7/stm32_otghost.c b/arch/arm/src/stm32f7/stm32_otghost.c new file mode 100644 index 0000000000..cc00b1336f --- /dev/null +++ b/arch/arm/src/stm32f7/stm32_otghost.c @@ -0,0 +1,5306 @@ +/**************************************************************************** + * arch/arm/src/stm32f7/stm32_otghost.c + * + * Copyright (C) 2012-2016 Gregory Nutt. All rights reserved. + * Authors: 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "chip.h" /* Includes default GPIO settings */ +#include /* May redefine GPIO settings */ + +#include "up_arch.h" +#include "up_internal.h" + +#include "stm32_otg.h" + +#if defined(CONFIG_USBHOST) && defined(CONFIG_STM32_OTGFS) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ***************************************************************/ +/* STM32 USB OTG FS Host Driver Support + * + * Pre-requisites + * + * CONFIG_USBHOST - Enable general USB host support + * CONFIG_STM32_OTGFS - Enable the STM32 USB OTG FS block + * CONFIG_STM32_SYSCFG - Needed + * + * Options: + * + * CONFIG_STM32_OTG_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * Default 128 (512 bytes) + * CONFIG_STM32_OTG_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * in 32-bit words. Default 96 (384 bytes) + * CONFIG_STM32_OTG_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * words. Default 96 (384 bytes) + * CONFIG_STM32_OTG_DESCSIZE - Maximum size of a descriptor. Default: 128 + * CONFIG_STM32_OTG_SOFINTR - Enable SOF interrupts. Why would you ever + * want to do that? + * CONFIG_STM32_USBHOST_REGDEBUG - Enable very low-level register access + * debug. Depends on CONFIG_DEBUG_FEATURES. + * CONFIG_STM32_USBHOST_PKTDUMP - Dump all incoming and outgoing USB + * packets. Depends on CONFIG_DEBUG_FEATURES. + */ + +/* Pre-requisites (partial) */ + +#ifndef CONFIG_STM32_SYSCFG +# error "CONFIG_STM32_SYSCFG is required" +#endif + +/* Default RxFIFO size */ + +#ifndef CONFIG_STM32_OTG_RXFIFO_SIZE +# define CONFIG_STM32_OTG_RXFIFO_SIZE 128 +#endif + +/* Default host non-periodic Tx FIFO size */ + +#ifndef CONFIG_STM32_OTG_NPTXFIFO_SIZE +# define CONFIG_STM32_OTG_NPTXFIFO_SIZE 96 +#endif + +/* Default host periodic Tx fifo size register */ + +#ifndef CONFIG_STM32_OTG_PTXFIFO_SIZE +# define CONFIG_STM32_OTG_PTXFIFO_SIZE 96 +#endif + +/* Maximum size of a descriptor */ + +#ifndef CONFIG_STM32_OTG_DESCSIZE +# define CONFIG_STM32_OTG_DESCSIZE 128 +#endif + +/* Register/packet debug depends on CONFIG_DEBUG_FEATURES */ + +#ifndef CONFIG_DEBUG_FEATURES +# undef CONFIG_STM32_USBHOST_REGDEBUG +# undef CONFIG_STM32_USBHOST_PKTDUMP +#endif + +/* HCD Setup *******************************************************************/ +/* Hardware capabilities */ + +#define STM32_NHOST_CHANNELS 8 /* Number of host channels */ +#define STM32_MAX_PACKET_SIZE 64 /* Full speed max packet size */ +#define STM32_EP0_DEF_PACKET_SIZE 8 /* EP0 default packet size */ +#define STM32_EP0_MAX_PACKET_SIZE 64 /* EP0 FS max packet size */ +#define STM32_MAX_TX_FIFOS 15 /* Max number of TX FIFOs */ +#define STM32_MAX_PKTCOUNT 256 /* Max packet count */ +#define STM32_RETRY_COUNT 3 /* Number of ctrl transfer retries */ + +/* Delays **********************************************************************/ + +#define STM32_READY_DELAY 200000 /* In loop counts */ +#define STM32_FLUSH_DELAY 200000 /* In loop counts */ +#define STM32_SETUP_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ +#define STM32_DATANAK_DELAY SEC2TICK(5) /* 5 seconds in system ticks */ + +/* Ever-present MIN/MAX macros */ + +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The following enumeration represents the various states of the USB host + * state machine (for debug purposes only) + */ + +enum stm32_smstate_e +{ + SMSTATE_DETACHED = 0, /* Not attached to a device */ + SMSTATE_ATTACHED, /* Attached to a device */ + SMSTATE_ENUM, /* Attached, enumerating */ + SMSTATE_CLASS_BOUND, /* Enumeration complete, class bound */ +}; + +/* This enumeration provides the reason for the channel halt. */ + +enum stm32_chreason_e +{ + CHREASON_IDLE = 0, /* Inactive (initial state) */ + CHREASON_FREED, /* Channel is no longer in use */ + CHREASON_XFRC, /* Transfer complete */ + CHREASON_NAK, /* NAK received */ + CHREASON_NYET, /* NotYet received */ + CHREASON_STALL, /* Endpoint stalled */ + CHREASON_TXERR, /* Transfer error received */ + CHREASON_DTERR, /* Data toggle error received */ + CHREASON_FRMOR, /* Frame overrun */ + CHREASON_CANCELLED /* Transfer cancelled */ +}; + +/* This structure retains the state of one host channel. NOTE: Since there + * is only one channel operation active at a time, some of the fields in + * in the structure could be moved in struct stm32_ubhost_s to achieve + * some memory savings. + */ + +struct stm32_chan_s +{ + sem_t waitsem; /* Channel wait semaphore */ + volatile uint8_t result; /* The result of the transfer */ + volatile uint8_t chreason; /* Channel halt reason. See enum stm32_chreason_e */ + uint8_t chidx; /* Channel index */ + uint8_t epno; /* Device endpoint number (0-127) */ + uint8_t eptype; /* See OTG_EPTYPE_* definitions */ + uint8_t funcaddr; /* Device function address */ + uint8_t speed; /* Device speed */ + uint8_t pid; /* Data PID */ + uint8_t npackets; /* Number of packets (for data toggle) */ + bool inuse; /* True: This channel is "in use" */ + volatile bool indata1; /* IN data toggle. True: DATA01 (Bulk and INTR only) */ + volatile bool outdata1; /* OUT data toggle. True: DATA01 */ + bool in; /* True: IN endpoint */ + volatile bool waiter; /* True: Thread is waiting for a channel event */ + uint16_t maxpacket; /* Max packet size */ + uint16_t buflen; /* Buffer length (at start of transfer) */ + volatile uint16_t xfrd; /* Bytes transferred (at end of transfer) */ + volatile uint16_t inflight; /* Number of Tx bytes "in-flight" */ + FAR uint8_t *buffer; /* Transfer buffer pointer */ +#ifdef CONFIG_USBHOST_ASYNCH + usbhost_asynch_t callback; /* Transfer complete callback */ + FAR void *arg; /* Argument that accompanies the callback */ +#endif +}; + +/* A channel represents on uni-directional endpoint. So, in the case of the + * bi-directional, control endpoint, there must be two channels to represent + * the endpoint. + */ + +struct stm32_ctrlinfo_s +{ + uint8_t inndx; /* EP0 IN control channel index */ + uint8_t outndx; /* EP0 OUT control channel index */ +}; + +/* This structure retains the state of the USB host controller */ + +struct stm32_usbhost_s +{ + /* Common device fields. This must be the first thing defined in the + * structure so that it is possible to simply cast from struct usbhost_s + * to structstm32_usbhost_s. + */ + + struct usbhost_driver_s drvr; + + /* This is the hub port description understood by class drivers */ + + struct usbhost_roothubport_s rhport; + + /* Overall driver status */ + + volatile uint8_t smstate; /* The state of the USB host state machine */ + uint8_t chidx; /* ID of channel waiting for space in Tx FIFO */ + volatile bool connected; /* Connected to device */ + volatile bool change; /* Connection change */ + volatile bool pscwait; /* True: Thread is waiting for a port event */ + sem_t exclsem; /* Support mutually exclusive access */ + sem_t pscsem; /* Semaphore to wait for a port event */ + struct stm32_ctrlinfo_s ep0; /* Root hub port EP0 description */ + +#ifdef CONFIG_USBHOST_HUB + /* Used to pass external hub port events */ + + volatile struct usbhost_hubport_s *hport; +#endif + + /* The state of each host channel */ + + struct stm32_chan_s chan[STM32_MAX_TX_FIFOS]; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Register operations ********************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite); +static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite); +static uint32_t stm32_getreg(uint32_t addr); +static void stm32_putreg(uint32_t addr, uint32_t value); +#else +# define stm32_getreg(addr) getreg32(addr) +# define stm32_putreg(addr,val) putreg32(val,addr) +#endif + +static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits, + uint32_t setbits); + +#ifdef CONFIG_STM32_USBHOST_PKTDUMP +# define stm32_pktdump(m,b,n) lib_dumpbuffer(m,b,n) +#else +# define stm32_pktdump(m,b,n) +#endif + +/* Semaphores ******************************************************************/ + +static void stm32_takesem(sem_t *sem); +#define stm32_givesem(s) sem_post(s); + +/* Byte stream access helper functions *****************************************/ + +static inline uint16_t stm32_getle16(const uint8_t *val); + +/* Channel management **********************************************************/ + +static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv); +static inline void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx); +static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv); +static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx); +static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx, + enum stm32_chreason_e chreason); +static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct stm32_ctrlinfo_s *ctrlep); +static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); + +/* Control/data transfer logic *************************************************/ + +static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx); +#if 0 /* Not used */ +static inline uint16_t stm32_getframe(void); +#endif +static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req); +static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen); +static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx); +static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_in_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx); +static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_out_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan); +static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif + +/* Interrupt handling **********************************************************/ +/* Lower level interrupt handlers */ + +static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen); +static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv, + int chidx); +static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv, + int chidx); +static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv); +static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv); + +/* Second level interrupt handlers */ + +#ifdef CONFIG_STM32_OTG_SOFINTR +static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv); +#endif +static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv); +static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv); + +/* First level, global interrupt handler */ + +static int stm32_gint_isr(int irq, FAR void *context); + +/* Interrupt controls */ + +static void stm32_gint_enable(void); +static void stm32_gint_disable(void); +static inline void stm32_hostinit_enable(void); +static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx); + +/* USB host controller operations **********************************************/ + +static int stm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport); +static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); +static int stm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport); + +static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, + usbhost_ep_t ep0, uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize); +static int stm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const FAR struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep); +static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +static int stm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen); +static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen); +static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer); +static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer); +static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer); +static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen); +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg); +#endif +static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep); +#ifdef CONFIG_USBHOST_HUB +static int stm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected); +#endif +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport); + +/* Initialization **************************************************************/ + +static void stm32_portreset(FAR struct stm32_usbhost_s *priv); +static void stm32_flush_txfifos(uint32_t txfnum); +static void stm32_flush_rxfifo(void); +static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state); +static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv); + +static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv); +static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* In this driver implementation, support is provided for only a single a single + * USB device. All status information can be simply retained in a single global + * instance. + */ + +static struct stm32_usbhost_s g_usbhost; + +/* This is the connection/enumeration interface */ + +static struct usbhost_connection_s g_usbconn = +{ + .wait = stm32_wait, + .enumerate = stm32_enumerate, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_printreg + * + * Description: + * Print the contents of an STM32xx register operation + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite) +{ + llerr("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); +} +#endif + +/**************************************************************************** + * Name: stm32_checkreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) +{ + static uint32_t prevaddr = 0; + static uint32_t preval = 0; + static uint32_t count = 0; + static bool prevwrite = false; + + /* Is this the same value that we read from/wrote to the same register last time? + * Are we polling the register? If so, suppress the output. + */ + + if (addr == prevaddr && val == preval && prevwrite == iswrite) + { + /* Yes.. Just increment the count */ + + count++; + } + else + { + /* No this is a new address or value or operation. Were there any + * duplicate accesses before this one? + */ + + if (count > 0) + { + /* Yes.. Just one? */ + + if (count == 1) + { + /* Yes.. Just one */ + + stm32_printreg(prevaddr, preval, prevwrite); + } + else + { + /* No.. More than one. */ + + llerr("[repeats %d more times]\n", count); + } + } + + /* Save the new address, value, count, and operation for next time */ + + prevaddr = addr; + preval = val; + count = 0; + prevwrite = iswrite; + + /* Show the new regisgter access */ + + stm32_printreg(addr, val, iswrite); + } +} +#endif + +/**************************************************************************** + * Name: stm32_getreg + * + * Description: + * Get the contents of an STM32 register + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static uint32_t stm32_getreg(uint32_t addr) +{ + /* Read the value from the register */ + + uint32_t val = getreg32(addr); + + /* Check if we need to print this value */ + + stm32_checkreg(addr, val, false); + return val; +} +#endif + +/**************************************************************************** + * Name: stm32_putreg + * + * Description: + * Set the contents of an STM32 register to a value + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_USBHOST_REGDEBUG +static void stm32_putreg(uint32_t addr, uint32_t val) +{ + /* Check if we need to print this value */ + + stm32_checkreg(addr, val, true); + + /* Write the value */ + + putreg32(val, addr); +} +#endif + +/**************************************************************************** + * Name: stm32_modifyreg + * + * Description: + * Modify selected bits of an STM32 register. + * + ****************************************************************************/ + +static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits, uint32_t setbits) +{ + stm32_putreg(addr, (((stm32_getreg(addr)) & ~clrbits) | setbits)); +} + +/**************************************************************************** + * Name: stm32_takesem + * + * Description: + * This is just a wrapper to handle the annoying behavior of semaphore + * waits that return due to the receipt of a signal. + * + ****************************************************************************/ + +static void stm32_takesem(sem_t *sem) +{ + /* Take the semaphore (perhaps waiting) */ + + while (sem_wait(sem) != 0) + { + /* The only case that an error should occr here is if the wait was + * awakened by a signal. + */ + + ASSERT(errno == EINTR); + } +} + +/**************************************************************************** + * Name: stm32_getle16 + * + * Description: + * Get a (possibly unaligned) 16-bit little endian value. + * + ****************************************************************************/ + +static inline uint16_t stm32_getle16(const uint8_t *val) +{ + return (uint16_t)val[1] << 8 | (uint16_t)val[0]; +} + +/**************************************************************************** + * Name: stm32_chan_alloc + * + * Description: + * Allocate a channel. + * + ****************************************************************************/ + +static int stm32_chan_alloc(FAR struct stm32_usbhost_s *priv) +{ + int chidx; + + /* Search the table of channels */ + + for (chidx = 0; chidx < STM32_NHOST_CHANNELS; chidx++) + { + /* Is this channel available? */ + + if (!priv->chan[chidx].inuse) + { + /* Yes... make it "in use" and return the index */ + + priv->chan[chidx].inuse = true; + return chidx; + } + } + + /* All of the channels are "in-use" */ + + return -EBUSY; +} + +/**************************************************************************** + * Name: stm32_chan_free + * + * Description: + * Free a previoiusly allocated channel. + * + ****************************************************************************/ + +static void stm32_chan_free(FAR struct stm32_usbhost_s *priv, int chidx) +{ + DEBUGASSERT((unsigned)chidx < STM32_NHOST_CHANNELS); + + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_FREED); + + /* Mark the channel available */ + + priv->chan[chidx].inuse = false; +} + +/**************************************************************************** + * Name: stm32_chan_freeall + * + * Description: + * Free all channels. + * + ****************************************************************************/ + +static inline void stm32_chan_freeall(FAR struct stm32_usbhost_s *priv) +{ + uint8_t chidx; + + /* Free all host channels */ + + for (chidx = 2; chidx < STM32_NHOST_CHANNELS; chidx ++) + { + stm32_chan_free(priv, chidx); + } +} + +/**************************************************************************** + * Name: stm32_chan_configure + * + * Description: + * Configure or re-configure a host channel. Host channels are configured + * when endpoint is allocated and EP0 (only) is re-configured with the + * max packet size or device address changes. + * + ****************************************************************************/ + +static void stm32_chan_configure(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + + /* Clear any old pending interrupts for this host channel. */ + + stm32_putreg(STM32_OTG_HCINT(chidx), 0xffffffff); + + /* Enable channel interrupts required for transfers on this channel. */ + + regval = 0; + + switch (chan->eptype) + { + case OTG_EPTYPE_CTRL: + case OTG_EPTYPE_BULK: + { +#ifdef HAVE_USBHOST_TRACE_VERBOSE + uint16_t intrace; + uint16_t outtrace; + + /* Determine the definitive trace ID to use below */ + + if (chan->eptype == OTG_EPTYPE_CTRL) + { + intrace = OTG_VTRACE2_CHANCONF_CTRL_IN; + outtrace = OTG_VTRACE2_CHANCONF_CTRL_OUT; + } + else + { + intrace = OTG_VTRACE2_CHANCONF_BULK_IN; + outtrace = OTG_VTRACE2_CHANCONF_BULK_OUT; + } +#endif + + /* Interrupts required for CTRL and BULK endpoints */ + + regval |= (OTG_HCINT_XFRC | OTG_HCINT_STALL | OTG_HCINT_NAK | + OTG_HCINT_TXERR | OTG_HCINT_DTERR); + + /* Additional setting for IN/OUT endpoints */ + + if (chan->in) + { + usbhost_vtrace2(intrace, chidx, chan->epno); + regval |= OTG_HCINT_BBERR; + } + else + { + usbhost_vtrace2(outtrace, chidx, chan->epno); + regval |= OTG_HCINT_NYET; + } + } + break; + + case OTG_EPTYPE_INTR: + { + /* Interrupts required for INTR endpoints */ + + regval |= (OTG_HCINT_XFRC | OTG_HCINT_STALL | OTG_HCINT_NAK | + OTG_HCINT_TXERR | OTG_HCINT_FRMOR | OTG_HCINT_DTERR); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(OTG_VTRACE2_CHANCONF_INTR_IN, chidx, + chan->epno); + regval |= OTG_HCINT_BBERR; + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(OTG_VTRACE2_CHANCONF_INTR_OUT, chidx, + chan->epno); + } +#endif + } + break; + + case OTG_EPTYPE_ISOC: + { + /* Interrupts required for ISOC endpoints */ + + regval |= (OTG_HCINT_XFRC | OTG_HCINT_ACK | OTG_HCINT_FRMOR); + + /* Additional setting for IN endpoints */ + + if (chan->in) + { + usbhost_vtrace2(OTG_VTRACE2_CHANCONF_ISOC_IN, chidx, + chan->epno); + regval |= (OTG_HCINT_TXERR | OTG_HCINT_BBERR); + } +#ifdef HAVE_USBHOST_TRACE_VERBOSE + else + { + usbhost_vtrace2(OTG_VTRACE2_CHANCONF_ISOC_OUT, chidx, + chan->epno); + } +#endif + } + break; + } + + stm32_putreg(STM32_OTG_HCINTMSK(chidx), regval); + + /* Enable the top level host channel interrupt. */ + + stm32_modifyreg(STM32_OTG_HAINTMSK, 0, OTG_HAINT(chidx)); + + /* Make sure host channel interrupts are enabled. */ + + stm32_modifyreg(STM32_OTG_GINTMSK, 0, OTG_GINT_HC); + + /* Program the HCCHAR register */ + + regval = ((uint32_t)chan->maxpacket << OTG_HCCHAR_MPSIZ_SHIFT) | + ((uint32_t)chan->epno << OTG_HCCHAR_EPNUM_SHIFT) | + ((uint32_t)chan->eptype << OTG_HCCHAR_EPTYP_SHIFT) | + ((uint32_t)chan->funcaddr << OTG_HCCHAR_DAD_SHIFT); + + /* Special case settings for low speed devices */ + + if (chan->speed == USB_SPEED_LOW) + { + regval |= OTG_HCCHAR_LSDEV; + } + + /* Special case settings for IN endpoints */ + + if (chan->in) + { + regval |= OTG_HCCHAR_EPDIR_IN; + } + + /* Special case settings for INTR endpoints */ + + if (chan->eptype == OTG_EPTYPE_INTR) + { + regval |= OTG_HCCHAR_ODDFRM; + } + + /* Write the channel configuration */ + + stm32_putreg(STM32_OTG_HCCHAR(chidx), regval); +} + +/**************************************************************************** + * Name: stm32_chan_halt + * + * Description: + * Halt the channel associated with 'chidx' by setting the CHannel DISable + * (CHDIS) bit in in the HCCHAR register. + * + ****************************************************************************/ + +static void stm32_chan_halt(FAR struct stm32_usbhost_s *priv, int chidx, + enum stm32_chreason_e chreason) +{ + uint32_t hcchar; + uint32_t intmsk; + uint32_t eptype; + unsigned int avail; + + /* Save the reason for the halt. We need this in the channel halt interrupt + * handling logic to know what to do next. + */ + + usbhost_vtrace2(OTG_VTRACE2_CHANHALT, chidx, chreason); + + priv->chan[chidx].chreason = (uint8_t)chreason; + + /* "The application can disable any channel by programming the OTG_FS_HCCHARx + * register with the CHDIS and CHENA bits set to 1. This enables the OTG_FS + * host to flush the posted requests (if any) and generates a channel halted + * interrupt. The application must wait for the CHH interrupt in OTG_FS_HCINTx + * before reallocating the channel for other transactions. The OTG_FS host + * does not interrupt the transaction that has already been started on the + * USB." + */ + + hcchar = stm32_getreg(STM32_OTG_HCCHAR(chidx)); + hcchar |= (OTG_HCCHAR_CHDIS | OTG_HCCHAR_CHENA); + + /* Get the endpoint type from the HCCHAR register */ + + eptype = hcchar & OTG_HCCHAR_EPTYP_MASK; + + /* Check for space in the Tx FIFO to issue the halt. + * + * "Before disabling a channel, the application must ensure that there is at + * least one free space available in the non-periodic request queue (when + * disabling a non-periodic channel) or the periodic request queue (when + * disabling a periodic channel). The application can simply flush the + * posted requests when the Request queue is full (before disabling the + * channel), by programming the OTG_FS_HCCHARx register with the CHDIS bit + * set to 1, and the CHENA bit cleared to 0. + */ + + if (eptype == OTG_HCCHAR_EPTYP_CTRL || eptype == OTG_HCCHAR_EPTYP_BULK) + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = stm32_getreg(STM32_OTG_HNPTXSTS) & OTG_HNPTXSTS_NPTXFSAV_MASK; + } + else /* if (eptype == OTG_HCCHAR_EPTYP_ISOC || eptype == OTG_HCCHAR_EPTYP_INTR) */ + { + /* Get the number of words available in the non-periodic Tx FIFO. */ + + avail = stm32_getreg(STM32_OTG_HPTXSTS) & OTG_HPTXSTS_PTXFSAVL_MASK; + } + + /* Check if there is any space available in the Tx FIFO. */ + + if (avail == 0) + { + /* The Tx FIFO is full... disable the channel to flush the requests */ + + hcchar &= ~OTG_HCCHAR_CHENA; + } + + /* Unmask the CHannel Halted (CHH) interrupt */ + + intmsk = stm32_getreg(STM32_OTG_HCINTMSK(chidx)); + intmsk |= OTG_HCINT_CHH; + stm32_putreg(STM32_OTG_HCINTMSK(chidx), intmsk); + + /* Halt the channel by setting CHDIS (and maybe CHENA) in the HCCHAR */ + + stm32_putreg(STM32_OTG_HCCHAR(chidx), hcchar); +} + +/**************************************************************************** + * Name: stm32_chan_waitsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Called from a normal thread context BEFORE the transfer has been started. + * + ****************************************************************************/ + +static int stm32_chan_waitsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = true; +#ifdef CONFIG_USBHOST_ASYNCH + chan->callback = NULL; + chan->arg = NULL; +#endif + ret = OK; + } + + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_chan_asynchsetup + * + * Description: + * Set the request for the transfer complete event well BEFORE enabling the + * transfer (as soon as we are absolutely committed to the to avoid transfer). + * We do this to minimize race conditions. This logic would have to be expanded + * if we want to have more than one packet in flight at a time! + * + * Assumptions: + * Might be called from the level of an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_chan_asynchsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan, + usbhost_asynch_t callback, FAR void *arg) +{ + irqstate_t flags = enter_critical_section(); + int ret = -ENODEV; + + /* Is the device still connected? */ + + if (priv->connected) + { + /* Yes.. then set waiter to indicate that we expect to be informed when + * either (1) the device is disconnected, or (2) the transfer completed. + */ + + chan->waiter = false; + chan->callback = callback; + chan->arg = arg; + ret = OK; + } + + leave_critical_section(flags); + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_chan_wait + * + * Description: + * Wait for a transfer on a channel to complete. + * + * Assumptions: + * Called from a normal thread context + * + ****************************************************************************/ + +static int stm32_chan_wait(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + irqstate_t flags; + int ret; + + /* Disable interrupts so that the following operations will be atomic. On + * the OTG FS global interrupt needs to be disabled. However, here we disable + * all interrupts to exploit that fact that interrupts will be re-enabled + * while we wait. + */ + + flags = enter_critical_section(); + + /* Loop, testing for an end of transfer condition. The channel 'result' + * was set to EBUSY and 'waiter' was set to true before the transfer; 'waiter' + * will be set to false and 'result' will be set appropriately when the + * transfer is completed. + */ + + do + { + /* Wait for the transfer to complete. NOTE the transfer may already + * completed before we get here or the transfer may complete while we + * wait here. + */ + + ret = sem_wait(&chan->waitsem); + + /* sem_wait should succeed. But it is possible that we could be + * awakened by a signal too. + */ + + DEBUGASSERT(ret == OK || get_errno() == EINTR); + } + while (chan->waiter); + + /* The transfer is complete re-enable interrupts and return the result */ + + ret = -(int)chan->result; + leave_critical_section(flags); + return ret; +} + +/**************************************************************************** + * Name: stm32_chan_wakeup + * + * Description: + * A channel transfer has completed... wakeup any threads waiting for the + * transfer to complete. + * + * Assumptions: + * This function is called from the transfer complete interrupt handler for + * the channel. Interrupts are disabled. + * + ****************************************************************************/ + +static void stm32_chan_wakeup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + /* Is the transfer complete? */ + + if (chan->result != EBUSY) + { + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + /* Wake'em up! */ + + usbhost_vtrace2(chan->in ? OTG_VTRACE2_CHANWAKEUP_IN : + OTG_VTRACE2_CHANWAKEUP_OUT, + chan->epno, chan->result); + + stm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + /* Handle continuation of IN/OUT pipes */ + + if (chan->in) + { + stm32_in_next(priv, chan); + } + else + { + stm32_out_next(priv, chan); + } + } +#endif + } +} + +/**************************************************************************** + * Name: stm32_ctrlchan_alloc + * + * Description: + * Allocate and configured channels for a control pipe. + * + ****************************************************************************/ + +static int stm32_ctrlchan_alloc(FAR struct stm32_usbhost_s *priv, + uint8_t epno, uint8_t funcaddr, uint8_t speed, + FAR struct stm32_ctrlinfo_s *ctrlep) +{ + FAR struct stm32_chan_s *chan; + int inndx; + int outndx; + + outndx = stm32_chan_alloc(priv); + if (outndx < 0) + { + return -ENOMEM; + } + + ctrlep->outndx = outndx; + chan = &priv->chan[outndx]; + chan->epno = epno; + chan->in = false; + chan->eptype = OTG_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control OUT channels */ + + stm32_chan_configure(priv, outndx); + + /* Allocate and initialize the control IN channel */ + + inndx = stm32_chan_alloc(priv); + if (inndx < 0) + { + stm32_chan_free(priv, outndx); + return -ENOMEM; + } + + ctrlep->inndx = inndx; + chan = &priv->chan[inndx]; + chan->epno = epno; + chan->in = true; + chan->eptype = OTG_EPTYPE_CTRL; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = STM32_EP0_DEF_PACKET_SIZE; + chan->indata1 = false; + chan->outdata1 = false; + + /* Configure control IN channels */ + + stm32_chan_configure(priv, inndx); + return OK; +} + +/**************************************************************************** + * Name: stm32_ctrlep_alloc + * + * Description: + * Allocate a container and channels for control pipe. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_ctrlep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + FAR struct usbhost_hubport_s *hport; + FAR struct stm32_ctrlinfo_s *ctrlep; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a container for the control endpoint */ + + ctrlep = (FAR struct stm32_ctrlinfo_s *)kmm_malloc(sizeof(struct stm32_ctrlinfo_s)); + if (ctrlep == NULL) + { + uerr("ERROR: Failed to allocate control endpoint container\n"); + return -ENOMEM; + } + + /* Then allocate and configure the IN/OUT channnels */ + + ret = stm32_ctrlchan_alloc(priv, epdesc->addr & USB_EPNO_MASK, + hport->funcaddr, hport->speed, ctrlep); + if (ret < 0) + { + uerr("ERROR: stm32_ctrlchan_alloc failed: %d\n", ret); + kmm_free(ctrlep); + return ret; + } + + /* Return a pointer to the control pipe container as the pipe "handle" */ + + *ep = (usbhost_ep_t)ctrlep; + return OK; +} + +/************************************************************************************ + * Name: stm32_xfrep_alloc + * + * Description: + * Allocate and configure one unidirectional endpoint. + * + * Input Parameters: + * priv - The private USB host driver state. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_xfrep_alloc(FAR struct stm32_usbhost_s *priv, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + struct usbhost_hubport_s *hport; + FAR struct stm32_chan_s *chan; + int chidx; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(epdesc->hport != NULL); + hport = epdesc->hport; + + /* Allocate a host channel for the endpoint */ + + chidx = stm32_chan_alloc(priv); + if (chidx < 0) + { + uerr("ERROR: Failed to allocate a host channel\n"); + return -ENOMEM; + } + + /* Decode the endpoint descriptor to initialize the channel data structures. + * Note: Here we depend on the fact that the endpoint point type is + * encoded in the same way in the endpoint descriptor as it is in the OTG + * HS hardware. + */ + + chan = &priv->chan[chidx]; + chan->epno = epdesc->addr & USB_EPNO_MASK; + chan->in = epdesc->in; + chan->eptype = epdesc->xfrtype; + chan->funcaddr = hport->funcaddr; + chan->speed = hport->speed; + chan->maxpacket = epdesc->mxpacketsize; + chan->indata1 = false; + chan->outdata1 = false; + + /* Then configure the endpoint */ + + stm32_chan_configure(priv, chidx); + + /* Return the index to the allocated channel as the endpoint "handle" */ + + *ep = (usbhost_ep_t)chidx; + return OK; +} + +/**************************************************************************** + * Name: stm32_transfer_start + * + * Description: + * Start at transfer on the select IN or OUT channel. + * + ****************************************************************************/ + +static void stm32_transfer_start(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int npackets; + unsigned int maxpacket; + unsigned int avail; + unsigned int wrsize; + unsigned int minsize; + + /* Set up the initial state of the transfer */ + + chan = &priv->chan[chidx]; + + usbhost_vtrace2(OTG_VTRACE2_STARTTRANSFER, chidx, chan->buflen); + + chan->result = EBUSY; + chan->inflight = 0; + chan->xfrd = 0; + priv->chidx = chidx; + + /* Compute the expected number of packets associated to the transfer. + * If the transfer length is zero (or less than the size of one maximum + * size packet), then one packet is expected. + */ + + /* If the transfer size is greater than one packet, then calculate the + * number of packets that will be received/sent, including any partial + * final packet. + */ + + maxpacket = chan->maxpacket; + + if (chan->buflen > maxpacket) + { + npackets = (chan->buflen + maxpacket - 1) / maxpacket; + + /* Clip if the buffer length if it exceeds the maximum number of + * packets that can be transferred (this should not happen). + */ + + if (npackets > STM32_MAX_PKTCOUNT) + { + npackets = STM32_MAX_PKTCOUNT; + chan->buflen = STM32_MAX_PKTCOUNT * maxpacket; + usbhost_trace2(OTG_TRACE2_CLIP, chidx, chan->buflen); + } + } + else + { + /* One packet will be sent/received (might be a zero length packet) */ + + npackets = 1; + } + + /* If it is an IN transfer, then adjust the size of the buffer UP to + * a full number of packets. Hmmm... couldn't this cause an overrun + * into unallocated memory? + */ + +#if 0 /* Think about this */ + if (chan->in) + { + /* Force the buffer length to an even multiple of maxpacket */ + + chan->buflen = npackets * maxpacket; + } +#endif + + /* Save the number of packets in the transfer. We will need this in + * order to set the next data toggle correctly when the transfer + * completes. + */ + + chan->npackets = (uint8_t)npackets; + + /* Setup the HCTSIZn register */ + + regval = ((uint32_t)chan->buflen << OTG_HCTSIZ_XFRSIZ_SHIFT) | + ((uint32_t)npackets << OTG_HCTSIZ_PKTCNT_SHIFT) | + ((uint32_t)chan->pid << OTG_HCTSIZ_DPID_SHIFT); + stm32_putreg(STM32_OTG_HCTSIZ(chidx), regval); + + /* Setup the HCCHAR register: Frame oddness and host channel enable */ + + regval = stm32_getreg(STM32_OTG_HCCHAR(chidx)); + + /* Set/clear the Odd Frame bit. Check for an even frame; if so set Odd + * Frame. This field is applicable for only periodic (isochronous and + * interrupt) channels. + */ + + if ((stm32_getreg(STM32_OTG_HFNUM) & 1) == 0) + { + regval |= OTG_HCCHAR_ODDFRM; + } + else + { + regval &= ~OTG_HCCHAR_ODDFRM; + } + + regval &= ~OTG_HCCHAR_CHDIS; + regval |= OTG_HCCHAR_CHENA; + stm32_putreg(STM32_OTG_HCCHAR(chidx), regval); + + /* If this is an out transfer, then we need to do more.. we need to copy + * the outgoing data into the correct TxFIFO. + */ + + if (!chan->in && chan->buflen > 0) + { + /* Handle non-periodic (CTRL and BULK) OUT transfers differently than + * periodic (INTR and ISOC) OUT transfers. + */ + + minsize = MIN(chan->buflen, chan->maxpacket); + + switch (chan->eptype) + { + case OTG_EPTYPE_CTRL: /* Non periodic transfer */ + case OTG_EPTYPE_BULK: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = stm32_getreg(STM32_OTG_HNPTXSTS); + avail = ((regval & OTG_HNPTXSTS_NPTXFSAV_MASK) >> OTG_HNPTXSTS_NPTXFSAV_SHIFT) << 2; + } + break; + + /* Periodic transfer */ + + case OTG_EPTYPE_INTR: + case OTG_EPTYPE_ISOC: + { + /* Read the Non-periodic Tx FIFO status register */ + + regval = stm32_getreg(STM32_OTG_HPTXSTS); + avail = ((regval & OTG_HPTXSTS_PTXFSAVL_MASK) >> OTG_HPTXSTS_PTXFSAVL_SHIFT) << 2; + } + break; + + default: + DEBUGASSERT(false); + return; + } + + /* Is there space in the TxFIFO to hold the minimum size packet? */ + + if (minsize <= avail) + { + /* Yes.. Get the size of the biggest thing that we can put in the Tx FIFO now */ + + wrsize = chan->buflen; + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Write packet into the Tx FIFO. */ + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); + } + + /* Did we put the entire buffer into the Tx FIFO? */ + + if (chan->buflen > avail) + { + /* No, there was insufficient space to hold the entire transfer ... + * Enable the Tx FIFO interrupt to handle the transfer when the Tx + * FIFO becomes empty. + */ + + stm32_txfe_enable(priv, chidx); + } + } +} + +/**************************************************************************** + * Name: stm32_getframe + * + * Description: + * Get the current frame number. The frame number (FRNUM) field increments + * when a new SOF is transmitted on the USB, and is cleared to 0 when it + * reaches 0x3fff. + * + ****************************************************************************/ + +#if 0 /* Not used */ +static inline uint16_t stm32_getframe(void) +{ + return (uint16_t)(stm32_getreg(STM32_OTG_HFNUM) & OTG_HFNUM_FRNUM_MASK); +} +#endif + +/**************************************************************************** + * Name: stm32_ctrl_sendsetup + * + * Description: + * Send an IN/OUT SETUP packet. + * + ****************************************************************************/ + +static int stm32_ctrl_sendsetup(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR const struct usb_ctrlreq_s *req) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop while the device reports NAK (and a timeout is not exceeded */ + + chan = &priv->chan[ep0->outndx]; + start = clock_systimer(); + + do + { + /* Send the SETUP packet */ + + chan->pid = OTG_PID_SETUP; + chan->buffer = (FAR uint8_t *)req; + chan->buflen = USB_SIZEOF_CTRLREQ; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete */ + + ret = stm32_chan_wait(priv, chan); + + /* Return on success and for all failures other than EAGAIN. EAGAIN + * means that the device NAKed the SETUP command and that we should + * try a few more times. + */ + + if (ret != -EAGAIN) + { + /* Output some debug information if the transfer failed */ + + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_TRNSFRFAILED, ret); + } + + /* Return the result in any event */ + + return ret; + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_SETUP_DELAY); + + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: stm32_ctrl_senddata + * + * Description: + * Send data in the data phase of an OUT control transfer. Or send status + * in the status phase of an IN control transfer + * + ****************************************************************************/ + +static int stm32_ctrl_senddata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct stm32_chan_s *chan = &priv->chan[ep0->outndx]; + int ret; + + /* Save buffer information */ + + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set the DATA PID */ + + if (buflen == 0) + { + /* For status OUT stage with buflen == 0, set PID DATA1 */ + + chan->outdata1 = true; + } + + /* Set the Data PID as per the outdata1 boolean */ + + chan->pid = chan->outdata1 ? OTG_PID_DATA1 : OTG_PID_DATA0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->outndx); + + /* Wait for the transfer to complete and return the result */ + + return stm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: stm32_ctrl_recvdata + * + * Description: + * Receive data in the data phase of an IN control transfer. Or receive status + * in the status phase of an OUT control transfer + * + ****************************************************************************/ + +static int stm32_ctrl_recvdata(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_ctrlinfo_s *ep0, + FAR uint8_t *buffer, unsigned int buflen) +{ + FAR struct stm32_chan_s *chan = &priv->chan[ep0->inndx]; + int ret; + + /* Save buffer information */ + + chan->pid = OTG_PID_DATA1; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0); + return ret; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, ep0->inndx); + + /* Wait for the transfer to complete and return the result */ + + return stm32_chan_wait(priv, chan); +} + +/**************************************************************************** + * Name: stm32_in_setup + * + * Description: + * Initiate an IN transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int stm32_in_setup(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case OTG_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case OTG_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the IN data PID */ + + usbhost_vtrace2(OTG_VTRACE2_ISOCIN, chidx, chan->buflen); + chan->pid = OTG_PID_DATA0; + } + break; + + case OTG_EPTYPE_BULK: /* Bulk */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(OTG_VTRACE2_BULKIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? OTG_PID_DATA1 : OTG_PID_DATA0; + } + break; + + case OTG_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the IN data PID */ + + usbhost_vtrace2(OTG_VTRACE2_INTRIN, chidx, chan->buflen); + chan->pid = chan->indata1 ? OTG_PID_DATA1 : OTG_PID_DATA0; + } + break; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: stm32_in_transfer + * + * Description: + * Transfer 'buflen' bytes into 'buffer' from an IN channel. + * + ****************************************************************************/ + +static ssize_t stm32_in_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + start = clock_systimer(); + while (chan->xfrd < chan->buflen) + { + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_in_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: stm32_in_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = stm32_chan_wait(priv, chan); + + /* EAGAIN indicates that the device NAKed the transfer and we need + * do try again. Anything else (success or other errors) will + * cause use to return + */ + + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + uerr("ERROR: stm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + } + } + + return (ssize_t)chan->xfrd; +} + +/**************************************************************************** + * Name: stm32_in_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_in_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = stm32_in_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + uerr("ERROR: stm32_in_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uinfo("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: stm32_in_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_in_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = stm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + uerr("ERROR: stm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_in_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: stm32_in_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_out_setup + * + * Description: + * Initiate an OUT transfer on an bulk, interrupt, or isochronous pipe. + * + ****************************************************************************/ + +static int stm32_out_setup(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan; + + /* Set up for the transfer based on the direction and the endpoint type */ + + chan = &priv->chan[chidx]; + switch (chan->eptype) + { + default: + case OTG_EPTYPE_CTRL: /* Control */ + { + /* This kind of transfer on control endpoints other than EP0 are not + * currently supported + */ + + return -ENOSYS; + } + + case OTG_EPTYPE_ISOC: /* Isochronous */ + { + /* Set up the OUT data PID */ + + usbhost_vtrace2(OTG_VTRACE2_ISOCOUT, chidx, chan->buflen); + chan->pid = OTG_PID_DATA0; + } + break; + + case OTG_EPTYPE_BULK: /* Bulk */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(OTG_VTRACE2_BULKOUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? OTG_PID_DATA1 : OTG_PID_DATA0; + } + break; + + case OTG_EPTYPE_INTR: /* Interrupt */ + { + /* Setup the OUT data PID */ + + usbhost_vtrace2(OTG_VTRACE2_INTROUT, chidx, chan->buflen); + chan->pid = chan->outdata1 ? OTG_PID_DATA1 : OTG_PID_DATA0; + + /* Toggle the OUT data PID for the next transfer */ + + chan->outdata1 ^= true; + } + break; + } + + /* Start the transfer */ + + stm32_transfer_start(priv, chidx); + return OK; +} + +/**************************************************************************** + * Name: stm32_out_transfer + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' through an OUT channel. + * + ****************************************************************************/ + +static ssize_t stm32_out_transfer(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_chan_s *chan; + systime_t start; + systime_t elapsed; + size_t xfrlen; + ssize_t xfrd; + int ret; + + /* Loop until the transfer completes (i.e., buflen is decremented to zero) + * or a fatal error occurs (any error other than a simple NAK) + */ + + chan = &priv->chan[chidx]; + start = clock_systimer(); + xfrd = 0; + + while (buflen > 0) + { + /* Transfer one packet at a time. The hardware is capable of queueing + * multiple OUT packets, but I just haven't figured out how to handle + * the case where a single OUT packet in the group is NAKed. + */ + + xfrlen = MIN(chan->maxpacket, buflen); + chan->buffer = buffer; + chan->buflen = xfrlen; + chan->xfrd = 0; + + /* Set up for the wait BEFORE starting the transfer */ + + ret = stm32_chan_waitsetup(priv, chan); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0); + return (ssize_t)ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_out_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: stm32_out_setup failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Wait for the transfer to complete and get the result */ + + ret = stm32_chan_wait(priv, chan); + + /* Handle transfer failures */ + + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_TRNSFRFAILED, ret); + + /* Check for a special case: If (1) the transfer was NAKed and (2) + * no Tx FIFO empty or Rx FIFO not-empty event occurred, then we + * should be able to just flush the Rx and Tx FIFOs and try again. + * We can detect this latter case because the then the transfer + * buffer pointer and buffer size will be unaltered. + */ + + elapsed = clock_systimer() - start; + if (ret != -EAGAIN || /* Not a NAK condition OR */ + elapsed >= STM32_DATANAK_DELAY || /* Timeout has elapsed OR */ + chan->xfrd > 0) /* Data has been partially transferred */ + { + /* Break out and return the error */ + + uerr("ERROR: stm32_chan_wait failed: %d\n", ret); + return (ssize_t)ret; + } + + /* Is this flush really necessary? What does the hardware do with the + * data in the FIFO when the NAK occurs? Does it discard it? + */ + + stm32_flush_txfifos(OTG_GRSTCTL_TXFNUM_HALL); + + /* Get the device a little time to catch up. Then retry the transfer + * using the same buffer pointer and length. + */ + + usleep(20*1000); + } + else + { + /* Successfully transferred. Update the buffer pointer and length */ + + buffer += xfrlen; + buflen -= xfrlen; + xfrd += chan->xfrd; + } + } + + return xfrd; +} + +/**************************************************************************** + * Name: stm32_out_next + * + * Description: + * Initiate the next of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is always called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static void stm32_out_next(FAR struct stm32_usbhost_s *priv, + FAR struct stm32_chan_s *chan) +{ + usbhost_asynch_t callback; + FAR void *arg; + ssize_t nbytes; + int result; + int ret; + + /* Is the full transfer complete? Did the last chunk transfer complete OK? */ + + result = -(int)chan->result; + if (chan->xfrd < chan->buflen && result == OK) + { + /* Yes.. Set up for the next transfer based on the direction and the + * endpoint type + */ + + ret = stm32_out_setup(priv, chan->chidx); + if (ret >= 0) + { + return; + } + + uerr("ERROR: stm32_out_setup failed: %d\n", ret); + result = ret; + } + + /* The transfer is complete, with or without an error */ + + uinfo("Transfer complete: %d\n", result); + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + nbytes = chan->xfrd; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + if (result < 0) + { + nbytes = (ssize_t)result; + } + + callback(arg, nbytes); +} +#endif + +/**************************************************************************** + * Name: stm32_out_asynch + * + * Description: + * Initiate the first of a sequence of asynchronous transfers. + * + * Assumptions: + * This function is never called from an interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_out_asynch(FAR struct stm32_usbhost_s *priv, int chidx, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_chan_s *chan; + int ret; + + /* Set up for the transfer data and callback BEFORE starting the first transfer */ + + chan = &priv->chan[chidx]; + chan->buffer = buffer; + chan->buflen = buflen; + chan->xfrd = 0; + + ret = stm32_chan_asynchsetup(priv, chan, callback, arg); + if (ret < 0) + { + uerr("ERROR: stm32_chan_asynchsetup failed: %d\n", ret); + return ret; + } + + /* Set up for the transfer based on the direction and the endpoint type */ + + ret = stm32_out_setup(priv, chidx); + if (ret < 0) + { + uerr("ERROR: stm32_out_setup failed: %d\n", ret); + } + + /* And return with the transfer pending */ + + return ret; +} +#endif + +/**************************************************************************** + * Name: stm32_gint_wrpacket + * + * Description: + * Transfer the 'buflen' bytes in 'buffer' to the Tx FIFO associated with + * 'chidx' (non-DMA). + * + ****************************************************************************/ + +static void stm32_gint_wrpacket(FAR struct stm32_usbhost_s *priv, + FAR uint8_t *buffer, int chidx, int buflen) +{ + FAR uint32_t *src; + uint32_t fifo; + int buflen32; + + stm32_pktdump("Sending", buffer, buflen); + + /* Get the number of 32-byte words associated with this byte size */ + + buflen32 = (buflen + 3) >> 2; + + /* Get the address of the Tx FIFO associated with this channel */ + + fifo = STM32_OTG_DFIFO_HCH(chidx); + + /* Transfer all of the data into the Tx FIFO */ + + src = (FAR uint32_t *)buffer; + for (; buflen32 > 0; buflen32--) + { + uint32_t data = *src++; + stm32_putreg(fifo, data); + } + + /* Increment the count of bytes "in-flight" in the Tx FIFO */ + + priv->chan[chidx].inflight += buflen; +} + +/**************************************************************************** + * Name: stm32_gint_hcinisr + * + * Description: + * USB OTG FS host IN channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void stm32_gint_hcinisr(FAR struct stm32_usbhost_s *priv, + int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = stm32_getreg(STM32_OTG_HCINT(chidx)); + regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullinfo("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & OTG_HCINT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_ACK); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & OTG_HCINT_STALL) != 0) + { + /* Clear the NAK and STALL Conditions. */ + + stm32_putreg(STM32_OTG_HCINT(chidx), (OTG_HCINT_NAK | OTG_HCINT_STALL)); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_STALL); + + /* When there is a STALL, clear any pending NAK so that it is not + * processed below. + */ + + pending &= ~OTG_HCINT_NAK; + } + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if ((pending & OTG_HCINT_DTERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the NAK and data toggle error conditions */ + + stm32_putreg(STM32_OTG_HCINT(chidx), (OTG_HCINT_NAK | OTG_HCINT_DTERR)); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + if ((pending & OTG_HCINT_FRMOR) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the FRaMe OverRun (FRMOR) condition */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_FRMOR); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & OTG_HCINT_XFRC) != 0) + { + /* Clear the TransFeR Completed (XFRC) condition */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_XFRC); + + /* Then handle the transfer completion event based on the endpoint type */ + + if (chan->eptype == OTG_EPTYPE_CTRL || chan->eptype == OTG_EPTYPE_BULK) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear any pending NAK condition. The 'indata1' data toggle + * should have been appropriately updated by the RxFIFO + * logic as each packet was received. + */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NAK); + } + else if (chan->eptype == OTG_EPTYPE_INTR) + { + /* Force the next transfer on an ODD frame */ + + regval = stm32_getreg(STM32_OTG_HCCHAR(chidx)); + regval |= OTG_HCCHAR_ODDFRM; + stm32_putreg(STM32_OTG_HCCHAR(chidx), regval); + + /* Set the request done state */ + + chan->result = OK; + } + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & OTG_HCINT_CHH) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx)); + regval &= ~OTG_HCINT_CHH; + stm32_putreg(STM32_OTG_HCINTMSK(chidx), regval); + + /* Update the request state based on the host state machine state */ + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the request I/O error result */ + + chan->result = EIO; + } + else if (chan->chreason == CHREASON_NAK) + { + /* Halt on NAK only happens on an INTR channel. Fetch the HCCHAR register + * and check for an interrupt endpoint. + */ + + regval = stm32_getreg(STM32_OTG_HCCHAR(chidx)); + if ((regval & OTG_HCCHAR_EPTYP_MASK) == OTG_HCCHAR_EPTYP_INTR) + { + /* Toggle the IN data toggle (Used by Bulk and INTR only) */ + + chan->indata1 ^= true; + } + + /* Set the NAK error result */ + + chan->result = EAGAIN; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame overrun error result */ + + chan->result = EPIPE; + } + + /* Clear the CHannel Halted (CHH) condition */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_CHH); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & OTG_HCINT_TXERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the Transaction ERror (TXERR) condition */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_TXERR); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & OTG_HCINT_NAK) != 0) + { + /* For a BULK transfer, the hardware is capable of retrying + * automatically on a NAK. However, this is not always + * what we need to do. So we always halt the transfer and + * return control to high level logic in the event of a NAK. + */ + +#if 1 + /* Halt the interrupt channel */ + + if (chan->eptype == OTG_EPTYPE_INTR) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); + } + + /* Re-activate CTRL and BULK channels. + * REVISIT: This can cause a lot of interrupts! + */ + + else if (chan->eptype == OTG_EPTYPE_CTRL || + chan->eptype == OTG_EPTYPE_BULK) + { + /* Re-activate the channel by clearing CHDIS and assuring that + * CHENA is set + */ + + regval = stm32_getreg(STM32_OTG_HCCHAR(chidx)); + regval |= OTG_HCCHAR_CHENA; + regval &= ~OTG_HCCHAR_CHDIS; + stm32_putreg(STM32_OTG_HCCHAR(chidx), regval); + } +#else + /* Halt all transfers on the NAK -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); +#endif + + /* Clear the NAK condition */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NAK); + } + + /* Check for a transfer complete event */ + + stm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: stm32_gint_hcoutisr + * + * Description: + * USB OTG FS host OUT channels interrupt handler + * + * One the completion of the transfer, the channel result byte may be set as + * follows: + * + * OK - Transfer completed successfully + * EAGAIN - If devices NAKs the transfer or NYET occurs + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Frame overrun + * + * EBUSY in the result field indicates that the transfer has not completed. + * + ****************************************************************************/ + +static inline void stm32_gint_hcoutisr(FAR struct stm32_usbhost_s *priv, + int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + uint32_t regval; + uint32_t pending; + + /* Read the HCINT register to get the pending HC interrupts. Read the + * HCINTMSK register to get the set of enabled HC interrupts. + */ + + pending = stm32_getreg(STM32_OTG_HCINT(chidx)); + regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx)); + + /* AND the two to get the set of enabled, pending HC interrupts */ + + pending &= regval; + ullinfo("HCINTMSK%d: %08x pending: %08x\n", chidx, regval, pending); + + /* Check for a pending ACK response received/transmitted (ACK) interrupt */ + + if ((pending & OTG_HCINT_ACK) != 0) + { + /* Clear the pending the ACK response received/transmitted (ACK) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_ACK); + } + + /* Check for a pending FRaMe OverRun (FRMOR) interrupt */ + + else if ((pending & OTG_HCINT_FRMOR) != 0) + { + /* Halt the channel (probably not necessary for FRMOR) */ + + stm32_chan_halt(priv, chidx, CHREASON_FRMOR); + + /* Clear the pending the FRaMe OverRun (FRMOR) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_FRMOR); + } + + /* Check for a pending TransFeR Completed (XFRC) interrupt */ + + else if ((pending & OTG_HCINT_XFRC) != 0) + { + /* Decrement the number of bytes remaining by the number of + * bytes that were "in-flight". + */ + + priv->chan[chidx].buffer += priv->chan[chidx].inflight; + priv->chan[chidx].xfrd += priv->chan[chidx].inflight; + priv->chan[chidx].inflight = 0; + + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_XFRC); + + /* Clear the pending the TransFeR Completed (XFRC) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_XFRC); + } + + /* Check for a pending STALL response receive (STALL) interrupt */ + + else if ((pending & OTG_HCINT_STALL) != 0) + { + /* Clear the pending the STALL response receiv (STALL) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_STALL); + + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_STALL); + } + + /* Check for a pending NAK response received (NAK) interrupt */ + + else if ((pending & OTG_HCINT_NAK) != 0) + { + /* Halt the channel -- the CHH interrupt is expected next */ + + stm32_chan_halt(priv, chidx, CHREASON_NAK); + + /* Clear the pending the NAK response received (NAK) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NAK); + } + + /* Check for a pending Transaction ERror (TXERR) interrupt */ + + else if ((pending & OTG_HCINT_TXERR) != 0) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_TXERR); + + /* Clear the pending the Transaction ERror (TXERR) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_TXERR); + } + + /* Check for a NYET interrupt */ + +#if 0 /* NYET is a reserved bit in the HCINT register */ + else if ((pending & OTG_HCINT_NYET) != 0) + { + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_NYET); + + /* Clear the pending the NYET interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_NYET); + } +#endif + + /* Check for a pending Data Toggle ERRor (DTERR) interrupt */ + + else if (pending & OTG_HCINT_DTERR) + { + /* Halt the channel when a STALL, TXERR, BBERR or DTERR interrupt is + * received on the channel. + */ + + stm32_chan_halt(priv, chidx, CHREASON_DTERR); + + /* Clear the pending the Data Toggle ERRor (DTERR) and NAK interrupts */ + + stm32_putreg(STM32_OTG_HCINT(chidx), (OTG_HCINT_DTERR | OTG_HCINT_NAK)); + } + + /* Check for a pending CHannel Halted (CHH) interrupt */ + + else if ((pending & OTG_HCINT_CHH) != 0) + { + /* Mask the CHannel Halted (CHH) interrupt */ + + regval = stm32_getreg(STM32_OTG_HCINTMSK(chidx)); + regval &= ~OTG_HCINT_CHH; + stm32_putreg(STM32_OTG_HCINTMSK(chidx), regval); + + if (chan->chreason == CHREASON_XFRC) + { + /* Set the request done result */ + + chan->result = OK; + + /* Read the HCCHAR register to get the HCCHAR register to get + * the endpoint type. + */ + + regval = stm32_getreg(STM32_OTG_HCCHAR(chidx)); + + /* Is it a bulk endpoint? Were an odd number of packets + * transferred? + */ + + if ((regval & OTG_HCCHAR_EPTYP_MASK) == OTG_HCCHAR_EPTYP_BULK && + (chan->npackets & 1) != 0) + { + /* Yes to both... toggle the data out PID */ + + chan->outdata1 ^= true; + } + } + else if (chan->chreason == CHREASON_NAK || + chan->chreason == CHREASON_NYET) + { + /* Set the try again later result */ + + chan->result = EAGAIN; + } + else if (chan->chreason == CHREASON_STALL) + { + /* Set the request stall result */ + + chan->result = EPERM; + } + else if ((chan->chreason == CHREASON_TXERR) || + (chan->chreason == CHREASON_DTERR)) + { + /* Set the I/O failure result */ + + chan->result = EIO; + } + else /* if (chan->chreason == CHREASON_FRMOR) */ + { + /* Set the frame error result */ + + chan->result = EPIPE; + } + + /* Clear the pending the CHannel Halted (CHH) interrupt */ + + stm32_putreg(STM32_OTG_HCINT(chidx), OTG_HCINT_CHH); + } + + /* Check for a transfer complete event */ + + stm32_chan_wakeup(priv, chan); +} + +/**************************************************************************** + * Name: stm32_gint_connected + * + * Description: + * Handle a connection event. + * + ****************************************************************************/ + +static void stm32_gint_connected(FAR struct stm32_usbhost_s *priv) +{ + /* We we previously disconnected? */ + + if (!priv->connected) + { + /* Yes.. then now we are connected */ + + usbhost_vtrace1(OTG_VTRACE1_CONNECTED, 0); + priv->connected = true; + priv->change = true; + DEBUGASSERT(priv->smstate == SMSTATE_DETACHED); + + /* Notify any waiters */ + + priv->smstate = SMSTATE_ATTACHED; + if (priv->pscwait) + { + stm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: stm32_gint_disconnected + * + * Description: + * Handle a disconnection event. + * + ****************************************************************************/ + +static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv) +{ + /* Were we previously connected? */ + + if (priv->connected) + { + /* Yes.. then we no longer connected */ + + usbhost_vtrace1(OTG_VTRACE1_DISCONNECTED, 0); + + /* Are we bound to a class driver? */ + + if (priv->rhport.hport.devclass) + { + /* Yes.. Disconnect the class driver */ + + CLASS_DISCONNECTED(priv->rhport.hport.devclass); + priv->rhport.hport.devclass = NULL; + } + + /* Re-Initialize Host for new Enumeration */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = true; + stm32_chan_freeall(priv); + + priv->rhport.hport.speed = USB_SPEED_FULL; + + /* Notify any waiters that there is a change in the connection state */ + + if (priv->pscwait) + { + stm32_givesem(&priv->pscsem); + priv->pscwait = false; + } + } +} + +/**************************************************************************** + * Name: stm32_gint_sofisr + * + * Description: + * USB OTG FS start-of-frame interrupt handler + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_OTG_SOFINTR +static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv) +{ + /* Handle SOF interrupt */ +#warning "Do what?" + + /* Clear pending SOF interrupt */ + + stm32_putreg(STM32_OTG_GINTSTS, OTG_GINT_SOF); +} +#endif + +/**************************************************************************** + * Name: stm32_gint_rxflvlisr + * + * Description: + * USB OTG FS RxFIFO non-empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv) +{ + FAR uint32_t *dest; + uint32_t grxsts; + uint32_t intmsk; + uint32_t hcchar; + uint32_t hctsiz; + uint32_t fifo; + int bcnt; + int bcnt32; + int chidx; + int i; + + /* Disable the RxFIFO non-empty interrupt */ + + intmsk = stm32_getreg(STM32_OTG_GINTMSK); + intmsk &= ~OTG_GINT_RXFLVL; + stm32_putreg(STM32_OTG_GINTMSK, intmsk); + + /* Read and pop the next status from the Rx FIFO */ + + grxsts = stm32_getreg(STM32_OTG_GRXSTSP); + ullinfo("GRXSTS: %08x\n", grxsts); + + /* Isolate the channel number/index in the status word */ + + chidx = (grxsts & OTG_GRXSTSH_CHNUM_MASK) >> OTG_GRXSTSH_CHNUM_SHIFT; + + /* Get the host channel characteristics register (HCCHAR) for this channel */ + + hcchar = stm32_getreg(STM32_OTG_HCCHAR(chidx)); + + /* Then process the interrupt according to the packet status */ + + switch (grxsts & OTG_GRXSTSH_PKTSTS_MASK) + { + case OTG_GRXSTSH_PKTSTS_INRECVD: /* IN data packet received */ + { + /* Read the data into the host buffer. */ + + bcnt = (grxsts & OTG_GRXSTSH_BCNT_MASK) >> OTG_GRXSTSH_BCNT_SHIFT; + if (bcnt > 0 && priv->chan[chidx].buffer != NULL) + { + /* Transfer the packet from the Rx FIFO into the user buffer */ + + dest = (FAR uint32_t *)priv->chan[chidx].buffer; + fifo = STM32_OTG_DFIFO_HCH(0); + bcnt32 = (bcnt + 3) >> 2; + + for (i = 0; i < bcnt32; i++) + { + *dest++ = stm32_getreg(fifo); + } + + stm32_pktdump("Received", priv->chan[chidx].buffer, bcnt); + + /* Toggle the IN data pid (Used by Bulk and INTR only) */ + + priv->chan[chidx].indata1 ^= true; + + /* Manage multiple packet transfers */ + + priv->chan[chidx].buffer += bcnt; + priv->chan[chidx].xfrd += bcnt; + + /* Check if more packets are expected */ + + hctsiz = stm32_getreg(STM32_OTG_HCTSIZ(chidx)); + if ((hctsiz & OTG_HCTSIZ_PKTCNT_MASK) != 0) + { + /* Re-activate the channel when more packets are expected */ + + hcchar |= OTG_HCCHAR_CHENA; + hcchar &= ~OTG_HCCHAR_CHDIS; + stm32_putreg(STM32_OTG_HCCHAR(chidx), hcchar); + } + } + } + break; + + case OTG_GRXSTSH_PKTSTS_INDONE: /* IN transfer completed */ + case OTG_GRXSTSH_PKTSTS_DTOGERR: /* Data toggle error */ + case OTG_GRXSTSH_PKTSTS_HALTED: /* Channel halted */ + default: + break; + } + + /* Re-enable the RxFIFO non-empty interrupt */ + + intmsk |= OTG_GINT_RXFLVL; + stm32_putreg(STM32_OTG_GINTMSK, intmsk); +} + +/**************************************************************************** + * Name: stm32_gint_nptxfeisr + * + * Description: + * USB OTG FS non-periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_nptxfeisr(FAR struct stm32_usbhost_s *priv) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transferred the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the NPTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_NPTXFE, 0); + return; + } + + /* Read the status from the top of the non-periodic TxFIFO */ + + regval = stm32_getreg(STM32_OTG_HNPTXSTS); + + /* Extract the number of bytes available in the non-periodic Tx FIFO. */ + + avail = ((regval & OTG_HNPTXSTS_NPTXFSAV_MASK) >> OTG_HNPTXSTS_NPTXFSAV_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize > 0 && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further NPTXFE interrupts. + */ + + else + { + stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_NPTXFE, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullinfo("HNPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: stm32_gint_ptxfeisr + * + * Description: + * USB OTG FS periodic TxFIFO empty interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_ptxfeisr(FAR struct stm32_usbhost_s *priv) +{ + FAR struct stm32_chan_s *chan; + uint32_t regval; + unsigned int wrsize; + unsigned int avail; + unsigned int chidx; + + /* Recover the index of the channel that is waiting for space in the Tx + * FIFO. + */ + + chidx = priv->chidx; + chan = &priv->chan[chidx]; + + /* Reduce the buffer size by the number of bytes that were previously placed + * in the Tx FIFO. + */ + + chan->buffer += chan->inflight; + chan->xfrd += chan->inflight; + chan->inflight = 0; + + /* If we have now transfered the entire buffer, then this transfer is + * complete (this case really should never happen because we disable + * the PTXFE interrupt on the final packet). + */ + + if (chan->xfrd >= chan->buflen) + { + /* Disable further Tx FIFO empty interrupts and bail. */ + + stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_PTXFE, 0); + return; + } + + /* Read the status from the top of the periodic TxFIFO */ + + regval = stm32_getreg(STM32_OTG_HPTXSTS); + + /* Extract the number of bytes available in the periodic Tx FIFO. */ + + avail = ((regval & OTG_HPTXSTS_PTXFSAVL_MASK) >> OTG_HPTXSTS_PTXFSAVL_SHIFT) << 2; + + /* Get the size to put in the Tx FIFO now */ + + wrsize = chan->buflen - chan->xfrd; + + /* Get minimal size packet that can be sent. Something is seriously + * configured wrong if one packet will not fit into the empty Tx FIFO. + */ + + DEBUGASSERT(wrsize && avail >= MIN(wrsize, chan->maxpacket)); + if (wrsize > avail) + { + /* Clip the write size to the number of full, max sized packets + * that will fit in the Tx FIFO. + */ + + unsigned int wrpackets = avail / chan->maxpacket; + wrsize = wrpackets * chan->maxpacket; + } + + /* Otherwise, this will be the last packet to be sent in this transaction. + * We now need to disable further PTXFE interrupts. + */ + + else + { + stm32_modifyreg(STM32_OTG_GINTMSK, OTG_GINT_PTXFE, 0); + } + + /* Write the next group of packets into the Tx FIFO */ + + ullinfo("HPTXSTS: %08x chidx: %d avail: %d buflen: %d xfrd: %d wrsize: %d\n", + regval, chidx, avail, chan->buflen, chan->xfrd, wrsize); + + stm32_gint_wrpacket(priv, chan->buffer, chidx, wrsize); +} + +/**************************************************************************** + * Name: stm32_gint_hcisr + * + * Description: + * USB OTG FS host channels interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_hcisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t haint; + uint32_t hcchar; + int i = 0; + + /* Read the Host all channels interrupt register and test each bit in the + * register. Each bit i, i=0...(STM32_NHOST_CHANNELS-1), corresponds to + * a pending interrupt on channel i. + */ + + haint = stm32_getreg(STM32_OTG_HAINT); + for (i = 0; i < STM32_NHOST_CHANNELS; i++) + { + /* Is an interrupt pending on this channel? */ + + if ((haint & OTG_HAINT(i)) != 0) + { + /* Yes... read the HCCHAR register to get the direction bit */ + + hcchar = stm32_getreg(STM32_OTG_HCCHAR(i)); + + /* Was this an interrupt on an IN or an OUT channel? */ + + if ((hcchar & OTG_HCCHAR_EPDIR) != 0) + { + /* Handle the HC IN channel interrupt */ + + stm32_gint_hcinisr(priv, i); + } + else + { + /* Handle the HC OUT channel interrupt */ + + stm32_gint_hcoutisr(priv, i); + } + } + } +} + +/**************************************************************************** + * Name: stm32_gint_hprtisr + * + * Description: + * USB OTG FS host port interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_hprtisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t hprt; + uint32_t newhprt; + uint32_t hcfg; + + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT, 0); + /* Read the port status and control register (HPRT) */ + + hprt = stm32_getreg(STM32_OTG_HPRT); + + /* Setup to clear the interrupt bits in GINTSTS by setting the corresponding + * bits in the HPRT. The HCINT interrupt bit is cleared when the appropriate + * status bits in the HPRT register are cleared. + */ + + newhprt = hprt & ~(OTG_HPRT_PENA | OTG_HPRT_PCDET | + OTG_HPRT_PENCHNG | OTG_HPRT_POCCHNG); + + /* Check for Port Overcurrent CHaNGe (POCCHNG) */ + + if ((hprt & OTG_HPRT_POCCHNG) != 0) + { + /* Set up to clear the POCCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_POCCHNG, 0); + newhprt |= OTG_HPRT_POCCHNG; + } + + /* Check for Port Connect DETected (PCDET). The core sets this bit when a + * device connection is detected. + */ + + if ((hprt & OTG_HPRT_PCDET) != 0) + { + /* Set up to clear the PCDET status in the new HPRT contents. Then + * process the new connection event. + */ + + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_PCDET, 0); + newhprt |= OTG_HPRT_PCDET; + stm32_portreset(priv); + stm32_gint_connected(priv); + } + + /* Check for Port Enable CHaNGed (PENCHNG) */ + + if ((hprt & OTG_HPRT_PENCHNG) != 0) + { + /* Set up to clear the PENCHNG status in the new HPRT contents. */ + + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_PENCHNG, 0); + newhprt |= OTG_HPRT_PENCHNG; + + /* Was the port enabled? */ + + if ((hprt & OTG_HPRT_PENA) != 0) + { + /* Yes.. handle the new connection event */ + + stm32_gint_connected(priv); + + /* Check the Host ConFiGuration register (HCFG) */ + + hcfg = stm32_getreg(STM32_OTG_HCFG); + + /* Is this a low speed or full speed connection (OTG FS does not + * support high speed) + */ + + if ((hprt & OTG_HPRT_PSPD_MASK) == OTG_HPRT_PSPD_LS) + { + /* Set the Host Frame Interval Register for the 6KHz speed */ + + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_LSDEV, 0); + stm32_putreg(STM32_OTG_HFIR, 6000); + + /* Are we switching from FS to LS? */ + + if ((hcfg & OTG_HCFG_FSLSPCS_MASK) != OTG_HCFG_FSLSPCS_LS6MHz) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_FSLSSW, 0); + + /* Yes... configure for LS */ + + hcfg &= ~OTG_HCFG_FSLSPCS_MASK; + hcfg |= OTG_HCFG_FSLSPCS_LS6MHz; + stm32_putreg(STM32_OTG_HCFG, hcfg); + + /* And reset the port */ + + stm32_portreset(priv); + } + } + else /* if ((hprt & OTG_HPRT_PSPD_MASK) == OTG_HPRT_PSPD_FS) */ + { + + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_FSDEV, 0); + stm32_putreg(STM32_OTG_HFIR, 48000); + + /* Are we switching from LS to FS? */ + + if ((hcfg & OTG_HCFG_FSLSPCS_MASK) != OTG_HCFG_FSLSPCS_FS48MHz) + { + + usbhost_vtrace1(OTG_VTRACE1_GINT_HPRT_LSFSSW, 0); + /* Yes... configure for FS */ + + hcfg &= ~OTG_HCFG_FSLSPCS_MASK; + hcfg |= OTG_HCFG_FSLSPCS_FS48MHz; + stm32_putreg(STM32_OTG_HCFG, hcfg); + + /* And reset the port */ + + stm32_portreset(priv); + } + } + } + } + + /* Clear port interrupts by setting bits in the HPRT */ + + stm32_putreg(STM32_OTG_HPRT, newhprt); +} + +/**************************************************************************** + * Name: stm32_gint_discisr + * + * Description: + * USB OTG FS disconnect detected interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_discisr(FAR struct stm32_usbhost_s *priv) +{ + /* Handle the disconnection event */ + + stm32_gint_disconnected(priv); + + /* Clear the dicsonnect interrupt */ + + stm32_putreg(STM32_OTG_GINTSTS, OTG_GINT_DISC); +} + +/**************************************************************************** + * Name: stm32_gint_ipxfrisr + * + * Description: + * USB OTG FS incomplete periodic interrupt handler + * + ****************************************************************************/ + +static inline void stm32_gint_ipxfrisr(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + + /* CHENA : Set to enable the channel + * CHDIS : Set to stop transmitting/receiving data on a channel + */ + + regval = stm32_getreg(STM32_OTG_HCCHAR(0)); + regval |= (OTG_HCCHAR_CHDIS | OTG_HCCHAR_CHENA); + stm32_putreg(STM32_OTG_HCCHAR(0), regval); + + /* Clear the incomplete isochronous OUT interrupt */ + + stm32_putreg(STM32_OTG_GINTSTS, OTG_GINT_IPXFR); +} + +/**************************************************************************** + * Name: stm32_gint_isr + * + * Description: + * USB OTG FS global interrupt handler + * + ****************************************************************************/ + +static int stm32_gint_isr(int irq, FAR void *context) +{ + /* At present, there is only support for a single OTG FS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbhost_s *priv = &g_usbhost; + uint32_t pending; + + /* If OTG were supported, we would need to check if we are in host or + * device mode when the global interrupt occurs. Here we support only + * host mode + */ + + /* Loop while there are pending interrupts to process. This loop may save a + * little interrupt handling overhead. + */ + + for (; ; ) + { + /* Get the unmasked bits in the GINT status */ + + pending = stm32_getreg(STM32_OTG_GINTSTS); + pending &= stm32_getreg(STM32_OTG_GINTMSK); + + /* Return from the interrupt when there are no further pending + * interrupts. + */ + + if (pending == 0) + { + return OK; + } + + /* Otherwise, process each pending, unmasked GINT interrupts */ + + /* Handle the start of frame interrupt */ + +#ifdef CONFIG_STM32_OTG_SOFINTR + if ((pending & OTG_GINT_SOF) != 0) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_SOF, 0); + stm32_gint_sofisr(priv); + } +#endif + + /* Handle the RxFIFO non-empty interrupt */ + + if ((pending & OTG_GINT_RXFLVL) != 0) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_RXFLVL, 0); + stm32_gint_rxflvlisr(priv); + } + + /* Handle the non-periodic TxFIFO empty interrupt */ + + if ((pending & OTG_GINT_NPTXFE) != 0) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_NPTXFE, 0); + stm32_gint_nptxfeisr(priv); + } + + /* Handle the periodic TxFIFO empty interrupt */ + + if ((pending & OTG_GINT_PTXFE) != 0) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_PTXFE, 0); + stm32_gint_ptxfeisr(priv); + } + + /* Handle the host channels interrupt */ + + if ((pending & OTG_GINT_HC) != 0) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_HC, 0); + stm32_gint_hcisr(priv); + } + + /* Handle the host port interrupt */ + + if ((pending & OTG_GINT_HPRT) != 0) + { + stm32_gint_hprtisr(priv); + } + + /* Handle the disconnect detected interrupt */ + + if ((pending & OTG_GINT_DISC) != 0) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_DISC, 0); + stm32_gint_discisr(priv); + } + + /* Handle the incomplete periodic transfer */ + + if ((pending & OTG_GINT_IPXFR) != 0) + { + usbhost_vtrace1(OTG_VTRACE1_GINT_IPXFR, 0); + stm32_gint_ipxfrisr(priv); + } + } + + /* We won't get here */ + + return OK; +} + +/**************************************************************************** + * Name: stm32_gint_enable and stm32_gint_disable + * + * Description: + * Respectively enable or disable the global OTG FS interrupt. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_gint_enable(void) +{ + uint32_t regval; + + /* Set the GINTMSK bit to unmask the interrupt */ + + regval = stm32_getreg(STM32_OTG_GAHBCFG); + regval |= OTG_GAHBCFG_GINTMSK; + stm32_putreg(STM32_OTG_GAHBCFG, regval); +} + +static void stm32_gint_disable(void) +{ + uint32_t regval; + + /* Clear the GINTMSK bit to mask the interrupt */ + + regval = stm32_getreg(STM32_OTG_GAHBCFG); + regval &= ~OTG_GAHBCFG_GINTMSK; + stm32_putreg(STM32_OTG_GAHBCFG, regval); +} + +/**************************************************************************** + * Name: stm32_hostinit_enable + * + * Description: + * Enable host interrupts. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void stm32_hostinit_enable(void) +{ + uint32_t regval; + + /* Disable all interrupts. */ + + stm32_putreg(STM32_OTG_GINTMSK, 0); + + /* Clear any pending interrupts. */ + + stm32_putreg(STM32_OTG_GINTSTS, 0xffffffff); + + /* Clear any pending USB OTG Interrupts (should be done elsewhere if OTG is supported) */ + + stm32_putreg(STM32_OTG_GOTGINT, 0xffffffff); + + /* Clear any pending USB OTG interrupts */ + + stm32_putreg(STM32_OTG_GINTSTS, 0xbfffffff); + + /* Enable the host interrupts */ + /* Common interrupts: + * + * OTG_GINT_WKUP : Resume/remote wakeup detected interrupt + * OTG_GINT_USBSUSP : USB suspend + */ + + regval = (OTG_GINT_WKUP | OTG_GINT_USBSUSP); + + /* If OTG were supported, we would need to enable the following as well: + * + * OTG_GINT_OTG : OTG interrupt + * OTG_GINT_SRQ : Session request/new session detected interrupt + * OTG_GINT_CIDSCHG : Connector ID status change + */ + + /* Host-specific interrupts + * + * OTG_GINT_SOF : Start of frame + * OTG_GINT_RXFLVL : RxFIFO non-empty + * OTG_GINT_IISOOXFR : Incomplete isochronous OUT transfer + * OTG_GINT_HPRT : Host port interrupt + * OTG_GINT_HC : Host channels interrupt + * OTG_GINT_DISC : Disconnect detected interrupt + */ + +#ifdef CONFIG_STM32_OTG_SOFINTR + regval |= (OTG_GINT_SOF | OTG_GINT_RXFLVL | OTG_GINT_IISOOXFR | + OTG_GINT_HPRT | OTG_GINT_HC | OTG_GINT_DISC); +#else + regval |= (OTG_GINT_RXFLVL | OTG_GINT_IPXFR | OTG_GINT_HPRT | + OTG_GINT_HC | OTG_GINT_DISC); +#endif + stm32_putreg(STM32_OTG_GINTMSK, regval); +} + +/**************************************************************************** + * Name: stm32_txfe_enable + * + * Description: + * Enable Tx FIFO empty interrupts. This is necessary when the entire + * transfer will not fit into Tx FIFO. The transfer will then be completed + * when the Tx FIFO is empty. NOTE: The Tx FIFO interrupt is disabled + * the fifo empty interrupt handler when the transfer is complete. + * + * Input Parameters: + * priv - Driver state structure reference + * chidx - The channel that requires the Tx FIFO empty interrupt + * + * Returned Value: + * None + * + * Assumptions: + * Called from user task context. Interrupts must be disabled to assure + * exclusive access to the GINTMSK register. + * + ****************************************************************************/ + +static void stm32_txfe_enable(FAR struct stm32_usbhost_s *priv, int chidx) +{ + FAR struct stm32_chan_s *chan = &priv->chan[chidx]; + irqstate_t flags; + uint32_t regval; + + /* Disable all interrupts so that we have exclusive access to the GINTMSK + * (it would be sufficent just to disable the GINT interrupt). + */ + + flags = enter_critical_section(); + + /* Should we enable the periodic or non-peridic Tx FIFO empty interrupts */ + + regval = stm32_getreg(STM32_OTG_GINTMSK); + switch (chan->eptype) + { + default: + case OTG_EPTYPE_CTRL: /* Non periodic transfer */ + case OTG_EPTYPE_BULK: + regval |= OTG_GINT_NPTXFE; + break; + + case OTG_EPTYPE_INTR: /* Periodic transfer */ + case OTG_EPTYPE_ISOC: + regval |= OTG_GINT_PTXFE; + break; + } + + /* Enable interrupts */ + + stm32_putreg(STM32_OTG_GINTMSK, regval); + leave_critical_section(flags); +} + +/**************************************************************************** + * USB Host Controller Operations + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_wait + * + * Description: + * Wait for a device to be connected or disconnected to/from a hub port. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from the call to + * the USB driver initialization logic. + * hport - The location to return the hub port descriptor that detected the + * connection related event. + * + * Returned Values: + * Zero (OK) is returned on success when a device in connected or + * disconnected. This function will not return until either (1) a device is + * connected or disconnect to/from any hub port or until (2) some failure + * occurs. On a failure, a negated errno value is returned indicating the + * nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_wait(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s **hport) +{ + FAR struct stm32_usbhost_s *priv = &g_usbhost; + struct usbhost_hubport_s *connport; + irqstate_t flags; + + /* Loop until a change in connection state is detected */ + + flags = enter_critical_section(); + for (; ; ) + { + /* Is there a change in the connection state of the single root hub + * port? + */ + + if (priv->change) + { + connport = &priv->rhport.hport; + + /* Yes. Remember the new state */ + + connport->connected = priv->connected; + priv->change = false; + + /* And return the root hub port */ + + *hport = connport; + leave_critical_section(flags); + + uinfo("RHport Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } + +#ifdef CONFIG_USBHOST_HUB + /* Is a device connected to an external hub? */ + + if (priv->hport) + { + /* Yes.. return the external hub port */ + + connport = (struct usbhost_hubport_s *)priv->hport; + priv->hport = NULL; + + *hport = connport; + leave_critical_section(flags); + + uinfo("Hub port Connected: %s\n", connport->connected ? "YES" : "NO"); + return OK; + } +#endif + + /* Wait for the next connection event */ + + priv->pscwait = true; + stm32_takesem(&priv->pscsem); + } +} + +/**************************************************************************** + * Name: stm32_enumerate + * + * Description: + * Enumerate the connected device. As part of this enumeration process, + * the driver will (1) get the device's configuration descriptor, (2) + * extract the class ID info from the configuration descriptor, (3) call + * usbhost_findclass() to find the class that supports this device, (4) + * call the create() method on the struct usbhost_registry_s interface + * to get a class instance, and finally (5) call the connect() method + * of the struct usbhost_class_s interface. After that, the class is in + * charge of the sequence of operations. + * + * Input Parameters: + * conn - The USB host connection instance obtained as a parameter from + * the call to the USB driver initialization logic. + * hport - The descriptor of the hub port that has the newly connected + * device. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_rh_enumerate(FAR struct stm32_usbhost_s *priv, + FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + uint32_t regval; + int ret; + + DEBUGASSERT(conn != NULL && hport != NULL && hport->port == 0); + + /* Are we connected to a device? The caller should have called the wait() + * method first to be assured that a device is connected. + */ + + while (!priv->connected) + { + /* No, return an error */ + + usbhost_trace1(OTG_TRACE1_DEVDISCONN, 0); + return -ENODEV; + } + + DEBUGASSERT(priv->smstate == SMSTATE_ATTACHED); + + /* USB 2.0 spec says at least 50ms delay before port reset. We wait 100ms. */ + + usleep(100*1000); + + /* Reset the host port */ + + stm32_portreset(priv); + + /* Get the current device speed */ + + regval = stm32_getreg(STM32_OTG_HPRT); + if ((regval & OTG_HPRT_PSPD_MASK) == OTG_HPRT_PSPD_LS) + { + priv->rhport.hport.speed = USB_SPEED_LOW; + } + else + { + priv->rhport.hport.speed = USB_SPEED_FULL; + } + + /* Allocate and initialize the root hub port EP0 channels */ + + ret = stm32_ctrlchan_alloc(priv, 0, 0, priv->rhport.hport.speed, &priv->ep0); + if (ret < 0) + { + uerr("ERROR: Failed to allocate a control endpoint: %d\n", ret); + } + + return ret; +} + +static int stm32_enumerate(FAR struct usbhost_connection_s *conn, + FAR struct usbhost_hubport_s *hport) +{ + FAR struct stm32_usbhost_s *priv = &g_usbhost; + int ret; + + DEBUGASSERT(hport); + + /* If this is a connection on the root hub, then we need to go to + * little more effort to get the device speed. If it is a connection + * on an external hub, then we already have that information. + */ + +#ifdef CONFIG_USBHOST_HUB + if (ROOTHUB(hport)) +#endif + { + ret = stm32_rh_enumerate(priv, conn, hport); + if (ret < 0) + { + return ret; + } + } + + /* Then let the common usbhost_enumerate do the real enumeration. */ + + uinfo("Enumerate the device\n"); + priv->smstate = SMSTATE_ENUM; + ret = usbhost_enumerate(hport, &hport->devclass); + + /* The enumeration may fail either because of some HCD interfaces failure + * or because the device class is not supported. In either case, we just + * need to perform the disconnection operation and make ready for a new + * enumeration. + */ + + if (ret < 0) + { + /* Return to the disconnected state */ + + uerr("ERROR: Enumeration failed: %d\n", ret); + stm32_gint_disconnected(priv); + } + + return ret; +} + +/************************************************************************************ + * Name: stm32_ep0configure + * + * Description: + * Configure endpoint 0. This method is normally used internally by the + * enumerate() method but is made available at the interface to support an + * external implementation of the enumeration logic. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The (opaque) EP0 endpoint instance + * funcaddr - The USB address of the function containing the endpoint that EP0 + * controls + * speed - The speed of the port USB_SPEED_LOW, _FULL, or _HIGH + * maxpacketsize - The maximum number of bytes that can be sent to or + * received from the endpoint in a single data packet + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_ep0configure(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + uint8_t funcaddr, uint8_t speed, + uint16_t maxpacketsize) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + FAR struct stm32_chan_s *chan; + + DEBUGASSERT(drvr != NULL && ep0info != NULL && funcaddr < 128 && + maxpacketsize <= 64); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Configure the EP0 OUT channel */ + + chan = &priv->chan[ep0info->outndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + stm32_chan_configure(priv, ep0info->outndx); + + /* Configure the EP0 IN channel */ + + chan = &priv->chan[ep0info->inndx]; + chan->funcaddr = funcaddr; + chan->speed = speed; + chan->maxpacket = maxpacketsize; + + stm32_chan_configure(priv, ep0info->inndx); + + stm32_givesem(&priv->exclsem); + return OK; +} + +/************************************************************************************ + * Name: stm32_epalloc + * + * Description: + * Allocate and configure one endpoint. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * epdesc - Describes the endpoint to be allocated. + * ep - A memory location provided by the caller in which to receive the + * allocated endpoint descriptor. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_epalloc(FAR struct usbhost_driver_s *drvr, + FAR const struct usbhost_epdesc_s *epdesc, + FAR usbhost_ep_t *ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + int ret; + + /* Sanity check. NOTE that this method should only be called if a device is + * connected (because we need a valid low speed indication). + */ + + DEBUGASSERT(drvr != 0 && epdesc != NULL && ep != NULL); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handler control pipes differently from other endpoint types. This is + * because the normal, "transfer" endpoints are unidirectional an require + * only a single channel. Control endpoints, however, are bi-diretional + * and require two channels, one for the IN and one for the OUT direction. + */ + + if (epdesc->xfrtype == OTG_EPTYPE_CTRL) + { + ret = stm32_ctrlep_alloc(priv, epdesc, ep); + } + else + { + ret = stm32_xfrep_alloc(priv, epdesc, ep); + } + + stm32_givesem(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: stm32_epfree + * + * Description: + * Free and endpoint previously allocated by DRVR_EPALLOC. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The endpoint to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_epfree(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + + DEBUGASSERT(priv); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* A single channel is represent by an index in the range of 0 to STM32_MAX_TX_FIFOS. + * Otherwise, the ep must be a pointer to an allocated control endpoint structure. + */ + + if ((uintptr_t)ep < STM32_MAX_TX_FIFOS) + { + /* Halt the channel and mark the channel available */ + + stm32_chan_free(priv, (int)ep); + } + else + { + /* Halt both control channel and mark the channels available */ + + FAR struct stm32_ctrlinfo_s *ctrlep = (FAR struct stm32_ctrlinfo_s *)ep; + stm32_chan_free(priv, ctrlep->inndx); + stm32_chan_free(priv, ctrlep->outndx); + + /* And free the control endpoint container */ + + kmm_free(ctrlep); + } + + stm32_givesem(&priv->exclsem); + return OK; +} + +/**************************************************************************** + * Name: stm32_alloc + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface was optimized under a particular assumption. It was assumed + * that the driver maintains a pool of small, pre-allocated buffers for descriptor + * traffic. NOTE that size is not an input, but an output: The size of the + * pre-allocated buffer is returned. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * maxlen - The address of a memory location provided by the caller in which to + * return the maximum size of the allocated buffer memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_alloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, FAR size_t *maxlen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && maxlen); + + /* There is no special memory requirement for the STM32. */ + + alloc = (FAR uint8_t *)kmm_malloc(CONFIG_STM32_OTG_DESCSIZE); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated address and size of the descriptor buffer */ + + *buffer = alloc; + *maxlen = CONFIG_STM32_OTG_DESCSIZE; + return OK; +} + +/**************************************************************************** + * Name: stm32_free + * + * Description: + * Some hardware supports special memory in which request and descriptor data can + * be accessed more efficiently. This method provides a mechanism to free that + * request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_free(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/************************************************************************************ + * Name: stm32_ioalloc + * + * Description: + * Some hardware supports special memory in which larger IO buffers can + * be accessed more efficiently. This method provides a mechanism to allocate + * the request/descriptor memory. If the underlying hardware does not support + * such "special" memory, this functions may simply map to kmm_malloc. + * + * This interface differs from DRVR_ALLOC in that the buffers are variable-sized. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of a memory location provided by the caller in which to + * return the allocated buffer memory address. + * buflen - The size of the buffer required. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_ioalloc(FAR struct usbhost_driver_s *drvr, + FAR uint8_t **buffer, size_t buflen) +{ + FAR uint8_t *alloc; + + DEBUGASSERT(drvr && buffer && buflen > 0); + + /* There is no special memory requirement */ + + alloc = (FAR uint8_t *)kmm_malloc(buflen); + if (!alloc) + { + return -ENOMEM; + } + + /* Return the allocated buffer */ + + *buffer = alloc; + return OK; +} + +/************************************************************************************ + * Name: stm32_iofree + * + * Description: + * Some hardware supports special memory in which IO data can be accessed more + * efficiently. This method provides a mechanism to free that IO buffer + * memory. If the underlying hardware does not support such "special" memory, + * this functions may simply map to kmm_free(). + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * buffer - The address of the allocated buffer memory to be freed. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * This function will *not* be called from an interrupt handler. + * + ************************************************************************************/ + +static int stm32_iofree(FAR struct usbhost_driver_s *drvr, FAR uint8_t *buffer) +{ + /* There is no special memory requirement */ + + DEBUGASSERT(drvr && buffer); + kmm_free(buffer); + return OK; +} + +/**************************************************************************** + * Name: stm32_ctrlin and stm32_ctrlout + * + * Description: + * Process a IN or OUT request on the control endpoint. These methods + * will enqueue the request and wait for it to complete. Only one transfer may be + * queued; Neither these methods nor the transfer() method can be called again + * until the control transfer functions returns. + * + * These are blocking methods; these functions will not return until the + * control transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep0 - The control endpoint to send/receive the control request. + * req - Describes the request to be sent. This request must lie in memory + * created by DRVR_ALLOC. + * buffer - A buffer used for sending the request and for returning any + * responses. This buffer must be large enough to hold the length value + * in the request description. buffer must have been allocated using DRVR_ALLOC. + * + * NOTE: On an IN transaction, req and buffer may refer to the same allocated + * memory. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static int stm32_ctrlin(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR uint8_t *buffer) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(OTG_VTRACE2_CTRLIN, req->type, req->req); + uinfo("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = stm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < STM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = stm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the IN data phase (if any) */ + + if (buflen > 0) + { + ret = stm32_ctrl_recvdata(priv, ep0info, buffer, buflen); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_RECVDATA, -ret); + } + } + + /* Handle the status OUT phase */ + + if (ret == OK) + { + priv->chan[ep0info->outndx].outdata1 ^= true; + ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactions exit here */ + + stm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(OTG_TRACE1_SENDDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + stm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +static int stm32_ctrlout(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep0, + FAR const struct usb_ctrlreq_s *req, + FAR const uint8_t *buffer) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_ctrlinfo_s *ep0info = (FAR struct stm32_ctrlinfo_s *)ep0; + uint16_t buflen; + systime_t start; + systime_t elapsed; + int retries; + int ret; + + DEBUGASSERT(priv != NULL && ep0info != NULL && req != NULL); + usbhost_vtrace2(OTG_VTRACE2_CTRLOUT, req->type, req->req); + uinfo("type:%02x req:%02x value:%02x%02x index:%02x%02x len:%02x%02x\n", + req->type, req->req, req->value[1], req->value[0], + req->index[1], req->index[0], req->len[1], req->len[0]); + + /* Extract values from the request */ + + buflen = stm32_getle16(req->len); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Loop, retrying until the retry time expires */ + + for (retries = 0; retries < STM32_RETRY_COUNT; retries++) + { + /* Send the SETUP request */ + + ret = stm32_ctrl_sendsetup(priv, ep0info, req); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_SENDSETUP, -ret); + continue; + } + + /* Get the start time. Loop again until the timeout expires */ + + start = clock_systimer(); + do + { + /* Handle the data OUT phase (if any) */ + + if (buflen > 0) + { + /* Start DATA out transfer (only one DATA packet) */ + + priv->chan[ep0info->outndx].outdata1 = true; + ret = stm32_ctrl_senddata(priv, ep0info, NULL, 0); + if (ret < 0) + { + usbhost_trace1(OTG_TRACE1_SENDDATA, -ret); + } + } + + /* Handle the status IN phase */ + + if (ret == OK) + { + ret = stm32_ctrl_recvdata(priv, ep0info, NULL, 0); + if (ret == OK) + { + /* All success transactins exit here */ + + stm32_givesem(&priv->exclsem); + return OK; + } + + usbhost_trace1(OTG_TRACE1_RECVDATA, ret < 0 ? -ret : ret); + } + + /* Get the elapsed time (in frames) */ + + elapsed = clock_systimer() - start; + } + while (elapsed < STM32_DATANAK_DELAY); + } + + /* All failures exit here after all retries and timeouts have been exhausted */ + + stm32_givesem(&priv->exclsem); + return -ETIMEDOUT; +} + +/**************************************************************************** + * Name: stm32_transfer + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request, blocking until the transfer completes. Only + * one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until this function returns. + * + * This is a blocking method; this functions will not return until the + * transfer has completed. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * + * Returned Values: + * On success, a non-negative value is returned that indicates the number + * of bytes successfully transferred. On a failure, a negated errno value is + * returned that indicates the nature of the failure: + * + * EAGAIN - If devices NAKs the transfer (or NYET or other error where + * it may be appropriate to restart the entire transaction). + * EPERM - If the endpoint stalls + * EIO - On a TX or data toggle error + * EPIPE - Overrun errors + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static ssize_t stm32_transfer(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + ssize_t nbytes; + + uinfo("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + nbytes = stm32_in_transfer(priv, chidx, buffer, buflen); + } + else + { + nbytes = stm32_out_transfer(priv, chidx, buffer, buflen); + } + + stm32_givesem(&priv->exclsem); + return nbytes; +} + +/**************************************************************************** + * Name: stm32_asynch + * + * Description: + * Process a request to handle a transfer descriptor. This method will + * enqueue the transfer request and return immediately. When the transfer + * completes, the the callback will be invoked with the provided transfer. + * This method is useful for receiving interrupt transfers which may come + * infrequently. + * + * Only one transfer may be queued; Neither this method nor the ctrlin or + * ctrlout methods can be called again until the transfer completes. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which to + * perform the transfer. + * buffer - A buffer containing the data to be sent (OUT endpoint) or received + * (IN endpoint). buffer must have been allocated using DRVR_ALLOC + * buflen - The length of the data to be sent or received. + * callback - This function will be called when the transfer completes. + * arg - The arbitrary parameter that will be passed to the callback function + * when the transfer completes. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure + * + * Assumptions: + * - Called from a single thread so no mutual exclusion is required. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +#ifdef CONFIG_USBHOST_ASYNCH +static int stm32_asynch(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep, + FAR uint8_t *buffer, size_t buflen, + usbhost_asynch_t callback, FAR void *arg) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + unsigned int chidx = (unsigned int)ep; + int ret; + + uinfo("chidx: %d buflen: %d\n", (unsigned int)ep, buflen); + + DEBUGASSERT(priv && buffer && chidx < STM32_MAX_TX_FIFOS && buflen > 0); + + /* We must have exclusive access to the USB host hardware and state structures */ + + stm32_takesem(&priv->exclsem); + + /* Handle IN and OUT transfer slightly differently */ + + if (priv->chan[chidx].in) + { + ret = stm32_in_asynch(priv, chidx, buffer, buflen, callback, arg); + } + else + { + ret = stm32_out_asynch(priv, chidx, buffer, buflen, callback, arg); + } + + stm32_givesem(&priv->exclsem); + return ret; +} +#endif /* CONFIG_USBHOST_ASYNCH */ + +/************************************************************************************ + * Name: stm32_cancel + * + * Description: + * Cancel a pending transfer on an endpoint. Cancelled synchronous or + * asynchronous transfer will complete normally with the error -ESHUTDOWN. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * ep - The IN or OUT endpoint descriptor for the device endpoint on which an + * asynchronous transfer should be transferred. + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +static int stm32_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + FAR struct stm32_chan_s *chan; + unsigned int chidx = (unsigned int)ep; + irqstate_t flags; + + uinfo("chidx: %u: %d\n", chidx); + + DEBUGASSERT(priv && chidx < STM32_MAX_TX_FIFOS); + chan = &priv->chan[chidx]; + + /* We need to disable interrupts to avoid race conditions with the asynchronous + * completion of the transfer being cancelled. + */ + + flags = enter_critical_section(); + + /* Halt the channel */ + + stm32_chan_halt(priv, chidx, CHREASON_CANCELLED); + chan->result = -ESHUTDOWN; + + /* Is there a thread waiting for this transfer to complete? */ + + if (chan->waiter) + { +#ifdef CONFIG_USBHOST_ASYNCH + /* Yes.. there should not also be a callback scheduled */ + + DEBUGASSERT(chan->callback == NULL); +#endif + + /* Wake'em up! */ + + stm32_givesem(&chan->waitsem); + chan->waiter = false; + } + +#ifdef CONFIG_USBHOST_ASYNCH + /* No.. is an asynchronous callback expected when the transfer + * completes? + */ + + else if (chan->callback) + { + usbhost_asynch_t callback; + FAR void *arg; + + /* Extract the callback information */ + + callback = chan->callback; + arg = chan->arg; + + chan->callback = NULL; + chan->arg = NULL; + chan->xfrd = 0; + + /* Then perform the callback */ + + callback(arg, -ESHUTDOWN); + } +#endif + + leave_critical_section(flags); + return OK; +} + +/************************************************************************************ + * Name: stm32_connect + * + * Description: + * New connections may be detected by an attached hub. This method is the + * mechanism that is used by the hub class to introduce a new connection + * and port description to the system. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The descriptor of the hub port that detected the connection + * related event + * connected - True: device connected; false: device disconnected + * + * Returned Values: + * On success, zero (OK) is returned. On a failure, a negated errno value is + * returned indicating the nature of the failure. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST_HUB +static int stm32_connect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport, + bool connected) +{ + FAR struct stm32_usbhost_s *priv = (FAR struct stm32_usbhost_s *)drvr; + irqstate_t flags; + + DEBUGASSERT(priv != NULL && hport != NULL); + + /* Set the connected/disconnected flag */ + + hport->connected = connected; + ullinfo("Hub port %d connected: %s\n", hport->port, connected ? "YES" : "NO"); + + /* Report the connection event */ + + flags = enter_critical_section(); + priv->hport = hport; + if (priv->pscwait) + { + priv->pscwait = false; + stm32_givesem(&priv->pscsem); + } + + leave_critical_section(flags); + return OK; +} +#endif + +/**************************************************************************** + * Name: stm32_disconnect + * + * Description: + * Called by the class when an error occurs and driver has been disconnected. + * The USB host driver should discard the handle to the class instance (it is + * stale) and not attempt any further interaction with the class driver instance + * (until a new instance is received from the create() method). The driver + * should not called the class' disconnected() method. + * + * Input Parameters: + * drvr - The USB host driver instance obtained as a parameter from the call to + * the class create() method. + * hport - The port from which the device is being disconnected. Might be a port + * on a hub. + * + * Returned Values: + * None + * + * Assumptions: + * - Only a single class bound to a single device is supported. + * - Never called from an interrupt handler. + * + ****************************************************************************/ + +static void stm32_disconnect(FAR struct usbhost_driver_s *drvr, + FAR struct usbhost_hubport_s *hport) +{ + DEBUGASSERT(hport != NULL); + hport->devclass = NULL; +} + +/**************************************************************************** + * Initialization + ****************************************************************************/ +/**************************************************************************** + * Name: stm32_portreset + * + * Description: + * Reset the USB host port. + * + * NOTE: "Before starting to drive a USB reset, the application waits for the + * OTG interrupt triggered by the debounce done bit (DBCDNE bit in + * OTG_FS_GOTGINT), which indicates that the bus is stable again after the + * electrical debounce caused by the attachment of a pull-up resistor on DP + * (FS) or DM (LS). + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void stm32_portreset(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + + regval = stm32_getreg(STM32_OTG_HPRT); + regval &= ~(OTG_HPRT_PENA | OTG_HPRT_PCDET | OTG_HPRT_PENCHNG | + OTG_HPRT_POCCHNG); + regval |= OTG_HPRT_PRST; + stm32_putreg(STM32_OTG_HPRT, regval); + + up_mdelay(20); + + regval &= ~OTG_HPRT_PRST; + stm32_putreg(STM32_OTG_HPRT, regval); + + up_mdelay(20); +} + +/**************************************************************************** + * Name: stm32_flush_txfifos + * + * Description: + * Flush the selected Tx FIFO. + * + * Input Parameters: + * txfnum -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_flush_txfifos(uint32_t txfnum) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the TX FIFO flush operation */ + + regval = OTG_GRSTCTL_TXFFLSH | txfnum; + stm32_putreg(STM32_OTG_GRSTCTL, regval); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_TXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: stm32_flush_rxfifo + * + * Description: + * Flush the Rx FIFO. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_flush_rxfifo(void) +{ + uint32_t regval; + uint32_t timeout; + + /* Initiate the RX FIFO flush operation */ + + stm32_putreg(STM32_OTG_GRSTCTL, OTG_GRSTCTL_RXFFLSH); + + /* Wait for the FLUSH to complete */ + + for (timeout = 0; timeout < STM32_FLUSH_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_RXFFLSH) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); +} + +/**************************************************************************** + * Name: stm32_vbusdrive + * + * Description: + * Drive the Vbus +5V. + * + * Input Parameters: + * priv - USB host driver private data structure. + * state - True: Drive, False: Don't drive + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_vbusdrive(FAR struct stm32_usbhost_s *priv, bool state) +{ + uint32_t regval; + + /* Enable/disable the external charge pump */ + + stm32_usbhost_vbusdrive(0, state); + + /* Turn on the Host port power. */ + + regval = stm32_getreg(STM32_OTG_HPRT); + regval &= ~(OTG_HPRT_PENA | OTG_HPRT_PCDET | OTG_HPRT_PENCHNG | + OTG_HPRT_POCCHNG); + + if (((regval & OTG_HPRT_PPWR) == 0) && state) + { + regval |= OTG_HPRT_PPWR; + stm32_putreg(STM32_OTG_HPRT, regval); + } + + if (((regval & OTG_HPRT_PPWR) != 0) && !state) + { + regval &= ~OTG_HPRT_PPWR; + stm32_putreg(STM32_OTG_HPRT, regval); + } + + up_mdelay(200); +} + +/**************************************************************************** + * Name: stm32_host_initialize + * + * Description: + * Initialize/re-initialize hardware for host mode operation. At present, + * this function is called only from stm32_hw_initialize(). But if OTG mode + * were supported, this function would also be called to swtich between + * host and device modes on a connector ID change interrupt. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + uint32_t offset; + int i; + + /* Restart the PHY Clock */ + + stm32_putreg(STM32_OTG_PCGCCTL, 0); + + /* Initialize Host Configuration (HCFG) register */ + + regval = stm32_getreg(STM32_OTG_HCFG); + regval &= ~OTG_HCFG_FSLSPCS_MASK; + regval |= OTG_HCFG_FSLSPCS_FS48MHz; + stm32_putreg(STM32_OTG_HCFG, regval); + + /* Reset the host port */ + + stm32_portreset(priv); + + /* Clear the FS-/LS-only support bit in the HCFG register */ + + regval = stm32_getreg(STM32_OTG_HCFG); + regval &= ~OTG_HCFG_FSLSS; + stm32_putreg(STM32_OTG_HCFG, regval); + + /* Carve up FIFO memory for the Rx FIFO and the periodic and non-periodic Tx FIFOs */ + /* Configure Rx FIFO size (GRXFSIZ) */ + + stm32_putreg(STM32_OTG_GRXFSIZ, CONFIG_STM32_OTG_RXFIFO_SIZE); + offset = CONFIG_STM32_OTG_RXFIFO_SIZE; + + /* Setup the host non-periodic Tx FIFO size (HNPTXFSIZ) */ + + regval = (offset | (CONFIG_STM32_OTG_NPTXFIFO_SIZE << OTG_HNPTXFSIZ_NPTXFD_SHIFT)); + stm32_putreg(STM32_OTG_HNPTXFSIZ, regval); + offset += CONFIG_STM32_OTG_NPTXFIFO_SIZE; + + /* Set up the host periodic Tx fifo size register (HPTXFSIZ) */ + + regval = (offset | (CONFIG_STM32_OTG_PTXFIFO_SIZE << OTG_HPTXFSIZ_PTXFD_SHIFT)); + stm32_putreg(STM32_OTG_HPTXFSIZ, regval); + + /* If OTG were supported, we sould need to clear HNP enable bit in the + * USB_OTG control register about here. + */ + + /* Flush all FIFOs */ + + stm32_flush_txfifos(OTG_GRSTCTL_TXFNUM_HALL); + stm32_flush_rxfifo(); + + /* Clear all pending HC Interrupts */ + + for (i = 0; i < STM32_NHOST_CHANNELS; i++) + { + stm32_putreg(STM32_OTG_HCINT(i), 0xffffffff); + stm32_putreg(STM32_OTG_HCINTMSK(i), 0); + } + + /* Driver Vbus +5V (the smoke test). Should be done elsewhere in OTG + * mode. + */ + + stm32_vbusdrive(priv, true); + + /* Enable host interrupts */ + + stm32_hostinit_enable(); +} + +/**************************************************************************** + * Name: stm32_sw_initialize + * + * Description: + * One-time setup of the host driver state structure. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) +{ + FAR struct usbhost_driver_s *drvr; + FAR struct usbhost_hubport_s *hport; + int i; + + /* Initialize the device operations */ + + drvr = &priv->drvr; + drvr->ep0configure = stm32_ep0configure; + drvr->epalloc = stm32_epalloc; + drvr->epfree = stm32_epfree; + drvr->alloc = stm32_alloc; + drvr->free = stm32_free; + drvr->ioalloc = stm32_ioalloc; + drvr->iofree = stm32_iofree; + drvr->ctrlin = stm32_ctrlin; + drvr->ctrlout = stm32_ctrlout; + drvr->transfer = stm32_transfer; +#ifdef CONFIG_USBHOST_ASYNCH + drvr->asynch = stm32_asynch; +#endif + drvr->cancel = stm32_cancel; +#ifdef CONFIG_USBHOST_HUB + drvr->connect = stm32_connect; +#endif + drvr->disconnect = stm32_disconnect; + + /* Initialize the public port representation */ + + hport = &priv->rhport.hport; + hport->drvr = drvr; +#ifdef CONFIG_USBHOST_HUB + hport->parent = NULL; +#endif + hport->ep0 = (usbhost_ep_t)&priv->ep0; + hport->speed = USB_SPEED_FULL; + + /* Initialize function address generation logic */ + + usbhost_devaddr_initialize(&priv->rhport); + + /* Initialize semaphores */ + + sem_init(&priv->pscsem, 0, 0); + sem_init(&priv->exclsem, 0, 1); + + /* Initialize the driver state data */ + + priv->smstate = SMSTATE_DETACHED; + priv->connected = false; + priv->change = false; + + /* Put all of the channels back in their initial, allocated state */ + + memset(priv->chan, 0, STM32_MAX_TX_FIFOS * sizeof(struct stm32_chan_s)); + + /* Initialize each channel */ + + for (i = 0; i < STM32_MAX_TX_FIFOS; i++) + { + FAR struct stm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + sem_init(&chan->waitsem, 0, 0); + } +} + +/**************************************************************************** + * Name: stm32_hw_initialize + * + * Description: + * One-time setup of the host controller harware for normal operations. + * + * Input Parameters: + * priv -- USB host driver private data structure. + * + * Returned Value: + * Zero on success; a negated errno value on failure. + * + ****************************************************************************/ + +static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv) +{ + uint32_t regval; + unsigned long timeout; + + /* Set the PHYSEL bit in the GUSBCFG register to select the OTG FS serial + * transceiver: "This bit is always 1 with write-only access" + */ + + regval = stm32_getreg(STM32_OTG_GUSBCFG); + regval |= OTG_GUSBCFG_PHYSEL; + stm32_putreg(STM32_OTG_GUSBCFG, regval); + + /* Reset after a PHY select and set Host mode. First, wait for AHB master + * IDLE state. + */ + + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + up_udelay(3); + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_AHBIDL) != 0) + { + break; + } + } + + /* Then perform the core soft reset. */ + + stm32_putreg(STM32_OTG_GRSTCTL, OTG_GRSTCTL_CSRST); + for (timeout = 0; timeout < STM32_READY_DELAY; timeout++) + { + regval = stm32_getreg(STM32_OTG_GRSTCTL); + if ((regval & OTG_GRSTCTL_CSRST) == 0) + { + break; + } + } + + /* Wait for 3 PHY Clocks */ + + up_udelay(3); + + /* Deactivate the power down */ + + regval = (OTG_GCCFG_PWRDWN | OTG_GCCFG_VBUSASEN | OTG_GCCFG_VBUSBSEN); +#ifndef CONFIG_USBDEV_VBUSSENSING + regval |= OTG_GCCFG_NOVBUSSENS; +#endif +#ifdef CONFIG_STM32_OTG_SOFOUTPUT + regval |= OTG_GCCFG_SOFOUTEN; +#endif + stm32_putreg(STM32_OTG_GCCFG, regval); + up_mdelay(20); + + /* Initialize OTG features: In order to support OTP, the HNPCAP and SRPCAP + * bits would need to be set in the GUSBCFG register about here. + */ + + /* Force Host Mode */ + + regval = stm32_getreg(STM32_OTG_GUSBCFG); + regval &= ~OTG_GUSBCFG_FDMOD; + regval |= OTG_GUSBCFG_FHMOD; + stm32_putreg(STM32_OTG_GUSBCFG, regval); + up_mdelay(50); + + /* Initialize host mode and return success */ + + stm32_host_initialize(priv); + return OK; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_otgfshost_initialize + * + * Description: + * Initialize USB host device controller hardware. + * + * Input Parameters: + * controller -- If the device supports more than USB host controller, then + * this identifies which controller is being initialized. Normally, this + * is just zero. + * + * Returned Value: + * And instance of the USB host interface. The controlling task should + * use this interface to (1) call the wait() method to wait for a device + * to be connected, and (2) call the enumerate() method to bind the device + * to a class driver. + * + * Assumptions: + * - This function should called in the initialization sequence in order + * to initialize the USB device functionality. + * - Class drivers should be initialized prior to calling this function. + * Otherwise, there is a race condition if the device is already connected. + * + ****************************************************************************/ + +FAR struct usbhost_connection_s *stm32_otgfshost_initialize(int controller) +{ + /* At present, there is only support for a single OTG FS host. Hence it is + * pre-allocated as g_usbhost. However, in most code, the private data + * structure will be referenced using the 'priv' pointer (rather than the + * global data) in order to simplify any future support for multiple devices. + */ + + FAR struct stm32_usbhost_s *priv = &g_usbhost; + + /* Sanity checks */ + + DEBUGASSERT(controller == 0); + + /* Make sure that interrupts from the OTG FS core are disabled */ + + stm32_gint_disable(); + + /* Reset the state of the host driver */ + + stm32_sw_initialize(priv); + + /* Alternate function pin configuration. Here we assume that: + * + * 1. GPIOA, SYSCFG, and OTG FS peripheral clocking have already been\ + * enabled as part of the boot sequence. + * 2. Board-specific logic has already enabled other board specific GPIOs + * for things like soft pull-up, VBUS sensing, power controls, and over- + * current detection. + */ + + /* Configure OTG FS alternate function pins for DM, DP, ID, and SOF. + * + * PIN* SIGNAL DIRECTION + * ---- ----------- ---------- + * PA8 OTG_FS_SOF SOF clock output + * PA9 OTG_FS_VBUS VBUS input for device, Driven by external regulator by + * host (not an alternate function) + * PA10 OTG_FS_ID OTG ID pin (only needed in Dual mode) + * PA11 OTG_FS_DM D- I/O + * PA12 OTG_FS_DP D+ I/O + * + * *Pins may vary from device-to-device. + */ + + stm32_configgpio(GPIO_OTG_DM); + stm32_configgpio(GPIO_OTG_DP); + stm32_configgpio(GPIO_OTG_ID); /* Only needed for OTG */ + + /* SOF output pin configuration is configurable */ + +#ifdef CONFIG_STM32_OTG_SOFOUTPUT + stm32_configgpio(GPIO_OTG_SOF); +#endif + + /* Initialize the USB OTG FS core */ + + stm32_hw_initialize(priv); + + /* Attach USB host controller interrupt handler */ + + if (irq_attach(STM32_IRQ_OTGFS, stm32_gint_isr) != 0) + { + usbhost_trace1(OTG_TRACE1_IRQATTACH, 0); + return NULL; + } + + /* Enable USB OTG FS global interrupts */ + + stm32_gint_enable(); + + /* Enable interrupts at the interrupt controller */ + + up_enable_irq(STM32_IRQ_OTGFS); + return &g_usbconn; +} + +#endif /* CONFIG_USBHOST && CONFIG_STM32_OTGFS */ diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.h b/arch/arm/src/stm32f7/stm32_sdmmc.h index 29e14683ce..18e6c44601 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.h +++ b/arch/arm/src/stm32f7/stm32_sdmmc.h @@ -1,5 +1,5 @@ /************************************************************************************ - * arch/arm/src/stm32/stm32_sdio.h + * arch/arm/src/stm32f7/stm32_sdio.h * * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt From 6f2e37e3adb3da2bcb3a7fe0bacfc23b7dd9707d Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Sun, 19 Jun 2016 23:06:21 +0200 Subject: [PATCH 003/155] mmc + usb --- arch/arm/src/stm32f7/stm32_otg.h | 32 +- arch/arm/src/stm32f7/stm32_otgdev.c | 17 +- arch/arm/src/stm32f7/stm32_otghost.c | 84 ++--- arch/arm/src/stm32f7/stm32_sdmmc.c | 5 + configs/stm32f746-ws/nsh/defconfig | 86 ++++- configs/stm32f746-ws/src/Makefile | 10 +- .../stm32f746-ws/src/stm32_appinitialize.c | 18 + configs/stm32f746-ws/src/stm32_dma_alloc.c | 117 ++++++ configs/stm32f746-ws/src/stm32_sdmmc.c | 171 +++++++++ configs/stm32f746-ws/src/stm32_usb.c | 340 ++++++++++++++++++ configs/stm32f746-ws/src/stm32f746-ws.h | 33 ++ 11 files changed, 842 insertions(+), 71 deletions(-) create mode 100644 configs/stm32f746-ws/src/stm32_dma_alloc.c create mode 100644 configs/stm32f746-ws/src/stm32_sdmmc.c create mode 100644 configs/stm32f746-ws/src/stm32_usb.c diff --git a/arch/arm/src/stm32f7/stm32_otg.h b/arch/arm/src/stm32f7/stm32_otg.h index 69def14608..0bb6b9b393 100644 --- a/arch/arm/src/stm32f7/stm32_otg.h +++ b/arch/arm/src/stm32f7/stm32_otg.h @@ -44,10 +44,10 @@ #include - +#include "chip.h" #include "chip/stm32_otg.h" -#if defined(CONFIG_STM32_OTGFS) || defined(CONFIG_STM32_OTGHS) +#if defined(CONFIG_STM32F7_OTGFS) || defined(CONFIG_STM32F7_OTGHS) /************************************************************************************ * Pre-processor Definitions @@ -58,16 +58,26 @@ # define CONFIG_OTG_PRI NVIC_SYSH_PRIORITY_DEFAULT #endif -#if defined(CONFIG_STM32_OTGFS) -# define STM32_IRQ_OTG STM32_IRQ_OTGFS -# define STM32_OTG_BASE STM32_USBOTGFS_BASE -# define STM32_NENDPOINTS (6) /* ep0-5 x 2 for IN and OUT */ +#if defined(CONFIG_STM32F7_OTGFS) +# define STM32_IRQ_OTG STM32_IRQ_OTGFS +# define STM32_OTG_BASE STM32_USBOTGFS_BASE +# define STM32_NENDPOINTS (6) /* ep0-5 x 2 for IN and OUT */ +# define GPIO_OTG_DM GPIO_OTGFS_DM +# define GPIO_OTG_DP GPIO_OTGFS_DP +# define GPIO_OTG_ID GPIO_OTGFS_ID +# define GPIO_OTG_SOF GPIO_OTGFS_SOF + #endif -#if defined(CONFIG_STM32_OTGHS) -# define STM32_IRQ_OTG STM32_IRQ_OTGHS -# define STM32_OTG_BASE STM32_USBOTGHS_BASE -# define STM32_NENDPOINTS (8) /* ep0-7 x 2 for IN and OUT */ +#if defined(CONFIG_STM32F7_OTGHS) +# define STM32_IRQ_OTG STM32_IRQ_OTGHS +# define STM32_OTG_BASE STM32_USBOTGHS_BASE +# define STM32_NENDPOINTS (8) /* ep0-7 x 2 for IN and OUT */ +# define GPIO_OTG_DM GPIO_OTGHS_DM +# define GPIO_OTG_DP GPIO_OTGHS_DP +# define GPIO_OTG_ID GPIO_OTGHS_ID +# define GPIO_OTG_SOF GPIO_OTGHS_SOF + #endif /************************************************************************************ @@ -134,6 +144,6 @@ void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume); #endif #endif /* __ASSEMBLY__ */ -#endif /* CONFIG_STM32_OTGFS */ +#endif /* CONFIG_STM32F7_OTGFS */ #endif /* __ARCH_ARM_SRC_STM32F7_STM32_OTG_H */ diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c index e362ef2b45..d4d46c4efb 100644 --- a/arch/arm/src/stm32f7/stm32_otgdev.c +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -57,12 +57,13 @@ #include #include "chip.h" +#include "stm32_gpio.h" #include "stm32_otg.h" #include "up_arch.h" #include "up_internal.h" -#if defined(CONFIG_USBDEV) && (defined(CONFIG_STM32_OTGFS) || defined(CONFIG_STM32_OTGHS)) +#if defined(CONFIG_USBDEV) && (defined(CONFIG_STM32F7_OTGFS) || defined(CONFIG_STM32F7_OTGHS)) /**************************************************************************** * Pre-processor Definitions @@ -469,7 +470,7 @@ struct stm32_usbdev_s /* Register operations ********************************************************/ -#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +#if defined(CONFIG_STM32F7_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) static uint32_t stm32_getreg(uint32_t addr); static void stm32_putreg(uint32_t val, uint32_t addr); #else @@ -789,7 +790,7 @@ const struct trace_msg_t g_usb_trace_strings_intdecode[] = * ****************************************************************************/ -#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +#if defined(CONFIG_STM32F7_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) static uint32_t stm32_getreg(uint32_t addr) { static uint32_t prevaddr = 0; @@ -852,7 +853,7 @@ static uint32_t stm32_getreg(uint32_t addr) * ****************************************************************************/ -#if defined(CONFIG_STM32_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) +#if defined(CONFIG_STM32F7_USBDEV_REGDEBUG) && defined(CONFIG_DEBUG_FEATURES) static void stm32_putreg(uint32_t val, uint32_t addr) { /* Show the register value being written */ @@ -5134,7 +5135,7 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv) stm32_putreg(OTG_GAHBCFG_TXFELVL, STM32_OTG_GAHBCFG); -#if defined(CONFIG_STM32_OTGHS) +#if defined(CONFIG_STM32F7_OTGHS) /* Set the PHYSEL bit in the GUSBCFG register to select the OTG HS serial * transceiver: "This bit is always 1 with write-only access" */ @@ -5329,7 +5330,7 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv) stm32_putreg(0xbfffffff, STM32_OTG_GINTSTS); -#ifdef defined(CONFIG_STM32_OTGHS) +#if defined(CONFIG_STM32F7_OTGHS) /* Disable the ULPI Clock enable in RCC AHB1 Register. This must * be done because if both the ULPI and the FS PHY clock enable bits * are set at the same time, the ARM never awakens from WFI due to @@ -5424,7 +5425,7 @@ void up_usbinitialize(void) /* SOF output pin configuration is configurable. */ -#ifdef CONFIG_STM32_OTG_SOFOUTPUT +#ifdef CONFIG_STM32F7_OTG_SOFOUTPUT stm32_configgpio(GPIO_OTG_SOF); #endif @@ -5663,4 +5664,4 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver) return OK; } -#endif /* CONFIG_USBDEV && CONFIG_STM32_OTGDEV */ +#endif /* CONFIG_USBDEV && CONFIG_STM32F7_OTGDEV */ diff --git a/arch/arm/src/stm32f7/stm32_otghost.c b/arch/arm/src/stm32f7/stm32_otghost.c index cc00b1336f..0feb6c98da 100644 --- a/arch/arm/src/stm32f7/stm32_otghost.c +++ b/arch/arm/src/stm32f7/stm32_otghost.c @@ -67,7 +67,7 @@ #include "stm32_otg.h" -#if defined(CONFIG_USBHOST) && defined(CONFIG_STM32_OTGFS) +#if defined(CONFIG_USBHOST) && defined(CONFIG_STM32F7_OTGFS) /**************************************************************************** * Pre-processor Definitions @@ -78,61 +78,61 @@ * Pre-requisites * * CONFIG_USBHOST - Enable general USB host support - * CONFIG_STM32_OTGFS - Enable the STM32 USB OTG FS block - * CONFIG_STM32_SYSCFG - Needed + * CONFIG_STM32F7_OTGFS - Enable the STM32 USB OTG FS block + * CONFIG_STM32F7_SYSCFG - Needed * * Options: * - * CONFIG_STM32_OTG_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. + * CONFIG_STM32F7_OTG_RXFIFO_SIZE - Size of the RX FIFO in 32-bit words. * Default 128 (512 bytes) - * CONFIG_STM32_OTG_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO + * CONFIG_STM32F7_OTG_NPTXFIFO_SIZE - Size of the non-periodic Tx FIFO * in 32-bit words. Default 96 (384 bytes) - * CONFIG_STM32_OTG_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit + * CONFIG_STM32F7_OTG_PTXFIFO_SIZE - Size of the periodic Tx FIFO in 32-bit * words. Default 96 (384 bytes) - * CONFIG_STM32_OTG_DESCSIZE - Maximum size of a descriptor. Default: 128 - * CONFIG_STM32_OTG_SOFINTR - Enable SOF interrupts. Why would you ever + * CONFIG_STM32F7_OTG_DESCSIZE - Maximum size of a descriptor. Default: 128 + * CONFIG_STM32F7_OTG_SOFINTR - Enable SOF interrupts. Why would you ever * want to do that? - * CONFIG_STM32_USBHOST_REGDEBUG - Enable very low-level register access + * CONFIG_STM32F7_USBHOST_REGDEBUG - Enable very low-level register access * debug. Depends on CONFIG_DEBUG_FEATURES. - * CONFIG_STM32_USBHOST_PKTDUMP - Dump all incoming and outgoing USB + * CONFIG_STM32F7_USBHOST_PKTDUMP - Dump all incoming and outgoing USB * packets. Depends on CONFIG_DEBUG_FEATURES. */ /* Pre-requisites (partial) */ -#ifndef CONFIG_STM32_SYSCFG -# error "CONFIG_STM32_SYSCFG is required" +#ifndef CONFIG_STM32F7_SYSCFG +# error "CONFIG_STM32F7_SYSCFG is required" #endif /* Default RxFIFO size */ -#ifndef CONFIG_STM32_OTG_RXFIFO_SIZE -# define CONFIG_STM32_OTG_RXFIFO_SIZE 128 +#ifndef CONFIG_STM32F7_OTG_RXFIFO_SIZE +# define CONFIG_STM32F7_OTG_RXFIFO_SIZE 128 #endif /* Default host non-periodic Tx FIFO size */ -#ifndef CONFIG_STM32_OTG_NPTXFIFO_SIZE -# define CONFIG_STM32_OTG_NPTXFIFO_SIZE 96 +#ifndef CONFIG_STM32F7_OTG_NPTXFIFO_SIZE +# define CONFIG_STM32F7_OTG_NPTXFIFO_SIZE 96 #endif /* Default host periodic Tx fifo size register */ -#ifndef CONFIG_STM32_OTG_PTXFIFO_SIZE -# define CONFIG_STM32_OTG_PTXFIFO_SIZE 96 +#ifndef CONFIG_STM32F7_OTG_PTXFIFO_SIZE +# define CONFIG_STM32F7_OTG_PTXFIFO_SIZE 96 #endif /* Maximum size of a descriptor */ -#ifndef CONFIG_STM32_OTG_DESCSIZE -# define CONFIG_STM32_OTG_DESCSIZE 128 +#ifndef CONFIG_STM32F7_OTG_DESCSIZE +# define CONFIG_STM32F7_OTG_DESCSIZE 128 #endif /* Register/packet debug depends on CONFIG_DEBUG_FEATURES */ #ifndef CONFIG_DEBUG_FEATURES -# undef CONFIG_STM32_USBHOST_REGDEBUG -# undef CONFIG_STM32_USBHOST_PKTDUMP +# undef CONFIG_STM32F7_USBHOST_REGDEBUG +# undef CONFIG_STM32F7_USBHOST_PKTDUMP #endif /* HCD Setup *******************************************************************/ @@ -283,7 +283,7 @@ struct stm32_usbhost_s /* Register operations ********************************************************/ -#ifdef CONFIG_STM32_USBHOST_REGDEBUG +#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite); static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite); static uint32_t stm32_getreg(uint32_t addr); @@ -296,7 +296,7 @@ static void stm32_putreg(uint32_t addr, uint32_t value); static inline void stm32_modifyreg(uint32_t addr, uint32_t clrbits, uint32_t setbits); -#ifdef CONFIG_STM32_USBHOST_PKTDUMP +#ifdef CONFIG_STM32F7_USBHOST_PKTDUMP # define stm32_pktdump(m,b,n) lib_dumpbuffer(m,b,n) #else # define stm32_pktdump(m,b,n) @@ -390,7 +390,7 @@ static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv); /* Second level interrupt handlers */ -#ifdef CONFIG_STM32_OTG_SOFINTR +#ifdef CONFIG_STM32F7_OTG_SOFINTR static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv); #endif static inline void stm32_gint_rxflvlisr(FAR struct stm32_usbhost_s *priv); @@ -503,7 +503,7 @@ static struct usbhost_connection_s g_usbconn = * ****************************************************************************/ -#ifdef CONFIG_STM32_USBHOST_REGDEBUG +#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite) { llerr("%08x%s%08x\n", addr, iswrite ? "<-" : "->", val); @@ -518,7 +518,7 @@ static void stm32_printreg(uint32_t addr, uint32_t val, bool iswrite) * ****************************************************************************/ -#ifdef CONFIG_STM32_USBHOST_REGDEBUG +#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) { static uint32_t prevaddr = 0; @@ -582,7 +582,7 @@ static void stm32_checkreg(uint32_t addr, uint32_t val, bool iswrite) * ****************************************************************************/ -#ifdef CONFIG_STM32_USBHOST_REGDEBUG +#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG static uint32_t stm32_getreg(uint32_t addr) { /* Read the value from the register */ @@ -604,7 +604,7 @@ static uint32_t stm32_getreg(uint32_t addr) * ****************************************************************************/ -#ifdef CONFIG_STM32_USBHOST_REGDEBUG +#ifdef CONFIG_STM32F7_USBHOST_REGDEBUG static void stm32_putreg(uint32_t addr, uint32_t val) { /* Check if we need to print this value */ @@ -2907,7 +2907,7 @@ static void stm32_gint_disconnected(FAR struct stm32_usbhost_s *priv) * ****************************************************************************/ -#ifdef CONFIG_STM32_OTG_SOFINTR +#ifdef CONFIG_STM32F7_OTG_SOFINTR static inline void stm32_gint_sofisr(FAR struct stm32_usbhost_s *priv) { /* Handle SOF interrupt */ @@ -3469,7 +3469,7 @@ static int stm32_gint_isr(int irq, FAR void *context) /* Handle the start of frame interrupt */ -#ifdef CONFIG_STM32_OTG_SOFINTR +#ifdef CONFIG_STM32F7_OTG_SOFINTR if ((pending & OTG_GINT_SOF) != 0) { usbhost_vtrace1(OTG_VTRACE1_GINT_SOF, 0); @@ -3634,7 +3634,7 @@ static inline void stm32_hostinit_enable(void) * OTG_GINT_DISC : Disconnect detected interrupt */ -#ifdef CONFIG_STM32_OTG_SOFINTR +#ifdef CONFIG_STM32F7_OTG_SOFINTR regval |= (OTG_GINT_SOF | OTG_GINT_RXFLVL | OTG_GINT_IISOOXFR | OTG_GINT_HPRT | OTG_GINT_HC | OTG_GINT_DISC); #else @@ -4138,7 +4138,7 @@ static int stm32_alloc(FAR struct usbhost_driver_s *drvr, /* There is no special memory requirement for the STM32. */ - alloc = (FAR uint8_t *)kmm_malloc(CONFIG_STM32_OTG_DESCSIZE); + alloc = (FAR uint8_t *)kmm_malloc(CONFIG_STM32F7_OTG_DESCSIZE); if (!alloc) { return -ENOMEM; @@ -4147,7 +4147,7 @@ static int stm32_alloc(FAR struct usbhost_driver_s *drvr, /* Return the allocated address and size of the descriptor buffer */ *buffer = alloc; - *maxlen = CONFIG_STM32_OTG_DESCSIZE; + *maxlen = CONFIG_STM32F7_OTG_DESCSIZE; return OK; } @@ -4987,18 +4987,18 @@ static void stm32_host_initialize(FAR struct stm32_usbhost_s *priv) /* Carve up FIFO memory for the Rx FIFO and the periodic and non-periodic Tx FIFOs */ /* Configure Rx FIFO size (GRXFSIZ) */ - stm32_putreg(STM32_OTG_GRXFSIZ, CONFIG_STM32_OTG_RXFIFO_SIZE); - offset = CONFIG_STM32_OTG_RXFIFO_SIZE; + stm32_putreg(STM32_OTG_GRXFSIZ, CONFIG_STM32F7_OTG_RXFIFO_SIZE); + offset = CONFIG_STM32F7_OTG_RXFIFO_SIZE; /* Setup the host non-periodic Tx FIFO size (HNPTXFSIZ) */ - regval = (offset | (CONFIG_STM32_OTG_NPTXFIFO_SIZE << OTG_HNPTXFSIZ_NPTXFD_SHIFT)); + regval = (offset | (CONFIG_STM32F7_OTG_NPTXFIFO_SIZE << OTG_HNPTXFSIZ_NPTXFD_SHIFT)); stm32_putreg(STM32_OTG_HNPTXFSIZ, regval); - offset += CONFIG_STM32_OTG_NPTXFIFO_SIZE; + offset += CONFIG_STM32F7_OTG_NPTXFIFO_SIZE; /* Set up the host periodic Tx fifo size register (HPTXFSIZ) */ - regval = (offset | (CONFIG_STM32_OTG_PTXFIFO_SIZE << OTG_HPTXFSIZ_PTXFD_SHIFT)); + regval = (offset | (CONFIG_STM32F7_OTG_PTXFIFO_SIZE << OTG_HPTXFSIZ_PTXFD_SHIFT)); stm32_putreg(STM32_OTG_HPTXFSIZ, regval); /* If OTG were supported, we sould need to clear HNP enable bit in the @@ -5173,7 +5173,7 @@ static inline int stm32_hw_initialize(FAR struct stm32_usbhost_s *priv) #ifndef CONFIG_USBDEV_VBUSSENSING regval |= OTG_GCCFG_NOVBUSSENS; #endif -#ifdef CONFIG_STM32_OTG_SOFOUTPUT +#ifdef CONFIG_STM32F7_OTG_SOFOUTPUT regval |= OTG_GCCFG_SOFOUTEN; #endif stm32_putreg(STM32_OTG_GCCFG, regval); @@ -5277,7 +5277,7 @@ FAR struct usbhost_connection_s *stm32_otgfshost_initialize(int controller) /* SOF output pin configuration is configurable */ -#ifdef CONFIG_STM32_OTG_SOFOUTPUT +#ifdef CONFIG_STM32F7_OTG_SOFOUTPUT stm32_configgpio(GPIO_OTG_SOF); #endif @@ -5303,4 +5303,4 @@ FAR struct usbhost_connection_s *stm32_otgfshost_initialize(int controller) return &g_usbconn; } -#endif /* CONFIG_USBHOST && CONFIG_STM32_OTGFS */ +#endif /* CONFIG_USBHOST && CONFIG_STM32F7_OTGFS */ diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 58f7b7318d..4f2b7a8d01 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -964,6 +964,11 @@ static void stm32_dataconfig(uint32_t timeout, uint32_t dlen, uint32_t dctrl) regval &= ~(SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); dctrl &= (SDIO_DCTRL_DTDIR | SDIO_DCTRL_DTMODE | SDIO_DCTRL_DBLOCKSIZE_MASK); regval |= (dctrl | SDIO_DCTRL_DTEN); + +#ifdef CONFIG_SDIO_DMA + regval |= SDIO_DCTRL_DMAEN; +#endif + putreg32(regval, STM32_SDMMC1_DCTRL); } diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index 97b867c160..44a25aec95 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -52,6 +52,12 @@ CONFIG_ARCH_HAVE_CUSTOMOPT=y CONFIG_DEBUG_NOOPT=y # CONFIG_DEBUG_CUSTOMOPT is not set # CONFIG_DEBUG_FULLOPT is not set +CONFIG_DEBUG_ERROR=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_WARN=y +CONFIG_DEBUG_FS_INFO=y +CONFIG_DEBUG_FS_ERROR=y +CONFIG_DEBUG_FS_WARN=y # # System Type @@ -267,7 +273,7 @@ CONFIG_STM32F7_HAVE_DMA2D=y CONFIG_STM32F7_ADC=y # CONFIG_STM32F7_CAN is not set # CONFIG_STM32F7_DAC is not set -# CONFIG_STM32F7_DMA is not set +CONFIG_STM32F7_DMA=y CONFIG_STM32F7_I2C=y # CONFIG_STM32F7_SAI is not set CONFIG_STM32F7_SPI=y @@ -282,7 +288,7 @@ CONFIG_STM32F7_ADC1=y # CONFIG_STM32F7_CEC is not set # CONFIG_STM32F7_CRC is not set # CONFIG_STM32F7_DMA1 is not set -# CONFIG_STM32F7_DMA2 is not set +CONFIG_STM32F7_DMA2=y # CONFIG_STM32F7_DAC1 is not set # CONFIG_STM32F7_DAC2 is not set # CONFIG_STM32F7_DCMI is not set @@ -294,13 +300,13 @@ CONFIG_STM32F7_I2C1=y # CONFIG_STM32F7_I2C3 is not set # CONFIG_STM32F7_LPTIM1 is not set # CONFIG_STM32F7_LTDC is not set -# CONFIG_STM32F7_OTGFS is not set +##CONFIG_STM32F7_OTGFS=y # CONFIG_STM32F7_OTGHS is not set # CONFIG_STM32F7_QUADSPI is not set # CONFIG_STM32F7_RNG is not set # CONFIG_STM32F7_SAI1 is not set # CONFIG_STM32F7_SAI2 is not set -# CONFIG_STM32F7_SDMMC1 is not set +CONFIG_STM32F7_SDMMC1=y # CONFIG_STM32F7_SPDIFRX is not set CONFIG_STM32F7_SPI1=y # CONFIG_STM32F7_SPI2 is not set @@ -352,7 +358,7 @@ CONFIG_STM32F7_USART6=y # # CONFIG_ARCH_NOINTC is not set # CONFIG_ARCH_VECNOTIRQ is not set -# CONFIG_ARCH_DMA is not set +CONFIG_ARCH_DMA=y CONFIG_ARCH_HAVE_IRQPRIO=y # CONFIG_ARCH_L2CACHE is not set # CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set @@ -416,6 +422,7 @@ CONFIG_ARCH_BOARD="stm32f746-ws" # Common Board Options # CONFIG_NSH_MMCSDMINOR=0 +CONFIG_NSH_MMCSDSLOTNO=0 # # Board-Specific Options @@ -427,6 +434,7 @@ CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_PWMTEST is not set # CONFIG_BOARDCTL_GRAPHICS is not set # CONFIG_BOARDCTL_IOCTL is not set +##CONFIG_BOARDCTL_USBDEVCTRL=y # # RTOS Features @@ -550,6 +558,17 @@ CONFIG_DEV_NULL=y # CONFIG_DEV_ZERO is not set # CONFIG_DEV_LOOP is not set +CONFIG_MMCSD=y +CONFIG_MMCSD_NSLOTS=1 +# CONFIG_MMCSD_READONLY is not set +CONFIG_MMCSD_MULTIBLOCK_DISABLE=y +# CONFIG_MMCSD_MMCSUPPORT is not set +CONFIG_MMCSD_HAVECARDDETECT=y +# CONFIG_MMCSD_SPI is not set +CONFIG_ARCH_HAVE_SDIO=y +CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE=y +CONFIG_MMCSD_SDIO=y + # # Buffering # @@ -579,6 +598,8 @@ CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_I2S is not set +CONFIG_SDIO_DMA=y + # # Timer Driver Support # @@ -669,7 +690,50 @@ CONFIG_USART6_2STOP=0 # CONFIG_USART6_IFLOWCONTROL is not set # CONFIG_USART6_OFLOWCONTROL is not set # CONFIG_USART6_DMA is not set -# CONFIG_USBDEV is not set +##CONFIG_USBDEV=y +# CONFIG_USBHOST is not set +# CONFIG_DRIVERS_WIRELESS is not set + + +# +# USB Device Controller Driver Options +# +# CONFIG_USBDEV_ISOCHRONOUS is not set +# CONFIG_USBDEV_DUALSPEED is not set +##CONFIG_USBDEV_SELFPOWERED=y +# CONFIG_USBDEV_BUSPOWERED is not set +##CONFIG_USBDEV_MAXPOWER=100 +# CONFIG_USBDEV_DMA is not set +# CONFIG_ARCH_USBDEV_STALLQUEUE is not set +# CONFIG_USBDEV_TRACE is not set + +# +# USB Device Class Driver Options +# +# CONFIG_USBDEV_COMPOSITE is not set +# CONFIG_PL2303 is not set +##CONFIG_CDCACM=y +##CONFIG_CDCACM_CONSOLE=y +##CONFIG_CDCACM_EP0MAXPACKET=64 +##CONFIG_CDCACM_EPINTIN=1 +##CONFIG_CDCACM_EPINTIN_FSSIZE=64 +##CONFIG_CDCACM_EPINTIN_HSSIZE=64 +##CONFIG_CDCACM_EPBULKOUT=3 +##CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 +##CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 +##CONFIG_CDCACM_EPBULKIN=2 +##CONFIG_CDCACM_EPBULKIN_FSSIZE=64 +##CONFIG_CDCACM_EPBULKIN_HSSIZE=512 +##CONFIG_CDCACM_NRDREQS=4 +##CONFIG_CDCACM_NWRREQS=4 +##CONFIG_CDCACM_BULKIN_REQLEN=96 +##CONFIG_CDCACM_RXBUFSIZE=256 +##CONFIG_CDCACM_TXBUFSIZE=256 +##CONFIG_CDCACM_VENDORID=0x0525 +##CONFIG_CDCACM_PRODUCTID=0xa4a7 +##CONFIG_CDCACM_VENDORSTR="NuttX" +##CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" +# CONFIG_USBMSC is not set # CONFIG_USBHOST is not set # CONFIG_DRIVERS_WIRELESS is not set @@ -706,13 +770,17 @@ CONFIG_USART6_2STOP=0 # CONFIG_DISABLE_MOUNTPOINT is not set # CONFIG_FS_AUTOMOUNTER is not set # CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set -# CONFIG_FS_READABLE is not set -# CONFIG_FS_WRITABLE is not set +CONFIG_FS_READABLE=y +CONFIG_FS_WRITABLE=y # CONFIG_FS_AIO is not set # CONFIG_FS_NAMED_SEMAPHORES is not set CONFIG_FS_MQUEUE_MPATH="/var/mqueue" # CONFIG_FS_RAMMAP is not set -# CONFIG_FS_FAT is not set +CONFIG_FS_FAT=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_MAXFNAME=32 +CONFIG_FAT_DMAMEMORY=y # CONFIG_FS_NXFFS is not set # CONFIG_FS_ROMFS is not set # CONFIG_FS_TMPFS is not set diff --git a/configs/stm32f746-ws/src/Makefile b/configs/stm32f746-ws/src/Makefile index b20f916b7e..4096729548 100644 --- a/configs/stm32f746-ws/src/Makefile +++ b/configs/stm32f746-ws/src/Makefile @@ -36,10 +36,18 @@ -include $(TOPDIR)/Make.defs ASRCS = -CSRCS = stm32_boot.c stm32_spi.c +CSRCS = stm32_boot.c stm32_spi.c stm32_dma_alloc.c ifeq ($(CONFIG_LIB_BOARDCTL),y) CSRCS += stm32_appinitialize.c endif +ifeq ($(CONFIG_STM32F7_OTGFS),y) +CSRCS += stm32_usb.c +endif + +ifeq ($(CONFIG_STM32F7_SDMMC1),y) +CSRCS += stm32_sdmmc.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/stm32f746-ws/src/stm32_appinitialize.c b/configs/stm32f746-ws/src/stm32_appinitialize.c index 734e35957a..689bea75fe 100644 --- a/configs/stm32f746-ws/src/stm32_appinitialize.c +++ b/configs/stm32f746-ws/src/stm32_appinitialize.c @@ -93,5 +93,23 @@ int board_app_initialize(void) stm32_i2ctool(); +#if defined(CONFIG_FAT_DMAMEMORY) + if (stm32_dma_alloc_init() < 0) + { + syslog(LOG_ERR, "DMA alloc FAILED"); + } +#endif + + /* Initialize the SDIO block driver */ + + int ret = OK; + + ret = stm32_sdio_initialize(); + if (ret != OK) + { + ferr("ERROR: Failed to initialize MMC/SD driver: %d\n", ret); + return ret; + } + return OK; } diff --git a/configs/stm32f746-ws/src/stm32_dma_alloc.c b/configs/stm32f746-ws/src/stm32_dma_alloc.c new file mode 100644 index 0000000000..e6d2744529 --- /dev/null +++ b/configs/stm32f746-ws/src/stm32_dma_alloc.c @@ -0,0 +1,117 @@ +/**************************************************************************** + * configs/nucleo-144/stc/stm32_dma_alloc.c + * + * Copyright (C) 2016 PX4 Development Team. All rights reserved. + * + * 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 PX4 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 "stm32f746-ws.h" + +#if defined(CONFIG_FAT_DMAMEMORY) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if !defined(CONFIG_GRAN) +# error microSD DMA support requires CONFIG_GRAN +#endif + +#define BOARD_DMA_ALLOC_POOL_SIZE (8*512) + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +static GRAN_HANDLE dma_allocator; + +/* The DMA heap size constrains the total number of things that can be + * ready to do DMA at a time. + * + * For example, FAT DMA depends on one sector-sized buffer per filesystem plus + * one sector-sized buffer per file. + * + * We use a fundamental alignment / granule size of 64B; this is sufficient + * to guarantee alignment for the largest STM32 DMA burst (16 beats x 32bits). + */ + +static uint8_t g_dma_heap[BOARD_DMA_ALLOC_POOL_SIZE] __attribute__((aligned(64))); + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_dma_alloc_init + * + * Description: + * All boards may optionally provide this API to instantiate a pool of + * memory for uses with FAST FS DMA operations. + * + ************************************************************************************/ + +int stm32_dma_alloc_init(void) +{ + dma_allocator = gran_initialize(g_dma_heap, + sizeof(g_dma_heap), + 7, /* 128B granule - must be > alignment (XXX bug?) */ + 6); /* 64B alignment */ + + if (dma_allocator == NULL) + { + return -ENOMEM; + } + + return OK; +} + +/* DMA-aware allocator stubs for the FAT filesystem. */ + +void *fat_dma_alloc(size_t size) +{ + return gran_alloc(dma_allocator, size); +} + +void fat_dma_free(FAR void *memory, size_t size) +{ + gran_free(dma_allocator, memory, size); +} + +#endif /* CONFIG_FAT_DMAMEMORY */ diff --git a/configs/stm32f746-ws/src/stm32_sdmmc.c b/configs/stm32f746-ws/src/stm32_sdmmc.c new file mode 100644 index 0000000000..bdbe7a7f65 --- /dev/null +++ b/configs/stm32f746-ws/src/stm32_sdmmc.c @@ -0,0 +1,171 @@ +/**************************************************************************** + * config/stm32f746-ws/src/stm32_sdio.c + * + * Copyright (C) 2014 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 +#include + +#include "stm32_sdmmc.h" +#include "stm32f746-ws.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Configuration ************************************************************/ + +/* Card detections requires card support and a card detection GPIO */ + +#define HAVE_NCD 1 +#if !defined(HAVE_SDIO) || !defined(GPIO_SDIO_NCD) +# undef HAVE_NCD +#endif + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static FAR struct sdio_dev_s *g_sdio_dev; +#ifdef HAVE_NCD +static bool g_sd_inserted = 0xff; /* Impossible value */ +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_ncd_interrupt + * + * Description: + * Card detect interrupt handler. + * + ****************************************************************************/ + +#ifdef HAVE_NCD +static int stm32_ncd_interrupt(int irq, FAR void *context) +{ + bool present; + + present = !stm32_gpioread(GPIO_SDIO_NCD); + if (present != g_sd_inserted) + { + sdio_mediachange(g_sdio_dev, present); + g_sd_inserted = present; + } + + return OK; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + +int stm32_sdio_initialize(void) +{ + int ret; + +#ifdef HAVE_NCD + /* Card detect */ + + bool cd_status; + + /* Configure the card detect GPIO */ + + stm32_configgpio(GPIO_SDIO_NCD); + + /* Register an interrupt handler for the card detect pin */ + + stm32_gpiosetevent(GPIO_SDIO_NCD, true, true, true, stm32_ncd_interrupt); +#endif + + /* Mount the SDIO-based MMC/SD block driver */ + /* First, get an instance of the SDIO interface */ + + finfo("Initializing SDIO slot %d\n", SDIO_SLOTNO); + + g_sdio_dev = sdio_initialize(SDIO_SLOTNO); + if (!g_sdio_dev) + { + ferr("ERROR: Failed to initialize SDIO slot %d\n", SDIO_SLOTNO); + return -ENODEV; + } + + /* Now bind the SDIO interface to the MMC/SD driver */ + + finfo("Bind SDIO to the MMC/SD driver, minor=%d\n", SDIO_MINOR); + + ret = mmcsd_slotinitialize(SDIO_MINOR, g_sdio_dev); + if (ret != OK) + { + ferr("ERROR: Failed to bind SDIO to the MMC/SD driver: %d\n", ret); + return ret; + } + + finfo("Successfully bound SDIO to the MMC/SD driver\n"); + +#ifdef HAVE_NCD + /* Use SD card detect pin to check if a card is g_sd_inserted */ + + cd_status = !stm32_gpioread(GPIO_SDIO_NCD); + finfo("Card detect : %d\n", cd_status); + + sdio_mediachange(g_sdio_dev, cd_status); +#else + /* Assume that the SD card is inserted. What choice do we have? */ + + sdio_mediachange(g_sdio_dev, true); +#endif + + return OK; +} diff --git a/configs/stm32f746-ws/src/stm32_usb.c b/configs/stm32f746-ws/src/stm32_usb.c new file mode 100644 index 0000000000..b81aacd6ca --- /dev/null +++ b/configs/stm32f746-ws/src/stm32_usb.c @@ -0,0 +1,340 @@ +/************************************************************************************ + * configs/stm32f4discovery/src/stm32_usb.c + * + * Copyright (C) 2012-2013, 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 +#include +#include + +#include +#include +#include + +#include "up_arch.h" +#include "stm32_otg.h" +#include "stm32_gpio.h" +#include "stm32f746-ws.h" + +#ifdef CONFIG_STM32F7_OTGFS + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#if defined(CONFIG_USBDEV) || defined(CONFIG_USBHOST) +# define HAVE_USB 1 +#else +# warning "CONFIG_STM32F7_OTGFS is enabled but neither CONFIG_USBDEV nor CONFIG_USBHOST" +# undef HAVE_USB +#endif + +#ifndef CONFIG_STM32F7F4DISCO_USBHOST_PRIO +# define CONFIG_STM32F7F4DISCO_USBHOST_PRIO 100 +#endif + +#ifndef CONFIG_STM32F7F4DISCO_USBHOST_STACKSIZE +# define CONFIG_STM32F7F4DISCO_USBHOST_STACKSIZE 1024 +#endif + +/************************************************************************************ + * Private Data + ************************************************************************************/ + +#ifdef CONFIG_USBHOST +static struct usbhost_connection_s *g_usbconn; +#endif + +/************************************************************************************ + * Private Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: usbhost_waiter + * + * Description: + * Wait for USB devices to be connected. + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST +static int usbhost_waiter(int argc, char *argv[]) +{ + struct usbhost_hubport_s *hport; + + uinfo("Running\n"); + for (;;) + { + /* Wait for the device to change state */ + + DEBUGVERIFY(CONN_WAIT(g_usbconn, &hport)); + uinfo("%s\n", hport->connected ? "connected" : "disconnected"); + + /* Did we just become connected? */ + + if (hport->connected) + { + /* Yes.. enumerate the newly connected device */ + + (void)CONN_ENUMERATE(g_usbconn, hport); + } + } + + /* Keep the compiler from complaining */ + + return 0; +} +#endif + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_usbinitialize + * + * Description: + * Called from stm32_usbinitialize very early in inialization to setup USB-related + * GPIO pins for the STM32F4Discovery board. + * + ************************************************************************************/ + +void stm32_usbinitialize(void) +{ + /* The OTG FS has an internal soft pull-up. No GPIO configuration is required */ + + /* Configure the OTG FS VBUS sensing GPIO, Power On, and Overcurrent GPIOs */ + +#ifdef CONFIG_STM32F7_OTGFS + stm32_configgpio(GPIO_OTGFS_VBUS); + +#ifdef CONFIG_USBHOST + stm32_configgpio(GPIO_OTGFS_PWRON); + stm32_configgpio(GPIO_OTGFS_OVER); +#endif + +#endif +} + +/*********************************************************************************** + * Name: stm32_usbhost_initialize + * + * Description: + * Called at application startup time to initialize the USB host functionality. + * This function will start a thread that will monitor for device + * connection/disconnection events. + * + ***********************************************************************************/ + +#ifdef CONFIG_USBHOST +int stm32_usbhost_initialize(void) +{ + int pid; +#if defined(CONFIG_USBHOST_HUB) || defined(CONFIG_USBHOST_MSC) || \ + defined(CONFIG_USBHOST_HIDKBD) || defined(CONFIG_USBHOST_HIDMOUSE) + int ret; +#endif + + /* First, register all of the class drivers needed to support the drivers + * that we care about: + */ + + uinfo("Register class drivers\n"); + +#ifdef CONFIG_USBHOST_HUB + /* Initialize USB hub class support */ + + ret = usbhost_hub_initialize(); + if (ret < 0) + { + uerr("ERROR: usbhost_hub_initialize failed: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_MSC + /* Register the USB mass storage class class */ + + ret = usbhost_msc_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the mass storage class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_CDCACM + /* Register the CDC/ACM serial class */ + + ret = usbhost_cdcacm_initialize(); + if (ret != OK) + { + uerr("ERROR: Failed to register the CDC/ACM serial class: %d\n", ret); + } +#endif + +#ifdef CONFIG_USBHOST_HIDKBD + /* Initialize the HID keyboard class */ + + ret = usbhost_kbdinit(); + if (ret != OK) + { + uerr("ERROR: Failed to register the HID keyboard class\n"); + } +#endif + +#ifdef CONFIG_USBHOST_HIDMOUSE + /* Initialize the HID mouse class */ + + ret = usbhost_mouse_init(); + if (ret != OK) + { + uerr("ERROR: Failed to register the HID mouse class\n"); + } +#endif + + /* Then get an instance of the USB host interface */ + + uinfo("Initialize USB host\n"); + g_usbconn = stm32_otgfshost_initialize(0); + if (g_usbconn) + { + /* Start a thread to handle device connection. */ + + uinfo("Start usbhost_waiter\n"); + + pid = task_create("usbhost", CONFIG_STM32F7F4DISCO_USBHOST_PRIO, + CONFIG_STM32F7F4DISCO_USBHOST_STACKSIZE, + (main_t)usbhost_waiter, (FAR char * const *)NULL); + return pid < 0 ? -ENOEXEC : OK; + } + + return -ENODEV; +} +#endif + +/*********************************************************************************** + * Name: stm32_usbhost_vbusdrive + * + * Description: + * Enable/disable driving of VBUS 5V output. This function must be provided be + * each platform that implements the STM32 OTG FS host interface + * + * "On-chip 5 V VBUS generation is not supported. For this reason, a charge pump + * or, if 5 V are available on the application board, a basic power switch, must + * be added externally to drive the 5 V VBUS line. The external charge pump can + * be driven by any GPIO output. When the application decides to power on VBUS + * using the chosen GPIO, it must also set the port power bit in the host port + * control and status register (PPWR bit in OTG_FS_HPRT). + * + * "The application uses this field to control power to this port, and the core + * clears this bit on an overcurrent condition." + * + * Input Parameters: + * iface - For future growth to handle multiple USB host interface. Should be zero. + * enable - true: enable VBUS power; false: disable VBUS power + * + * Returned Value: + * None + * + ***********************************************************************************/ + +#ifdef CONFIG_USBHOST +void stm32_usbhost_vbusdrive(int iface, bool enable) +{ + DEBUGASSERT(iface == 0); + + if (enable) + { + /* Enable the Power Switch by driving the enable pin low */ + + stm32_gpiowrite(GPIO_OTGFS_PWRON, false); + } + else + { + /* Disable the Power Switch by driving the enable pin high */ + + stm32_gpiowrite(GPIO_OTGFS_PWRON, true); + } +} +#endif + +/************************************************************************************ + * Name: stm32_setup_overcurrent + * + * Description: + * Setup to receive an interrupt-level callback if an overcurrent condition is + * detected. + * + * Input Parameter: + * handler - New overcurrent interrupt handler + * + * Returned value: + * Old overcurrent interrupt handler + * + ************************************************************************************/ + +#ifdef CONFIG_USBHOST +xcpt_t stm32_setup_overcurrent(xcpt_t handler) +{ + return stm32_gpiosetevent(GPIO_OTGFS_OVER, true, true, true, handler); +} +#endif + +/************************************************************************************ + * Name: stm32_usbsuspend + * + * Description: + * Board logic must provide the stm32_usbsuspend logic if the USBDEV driver is + * used. This function is called whenever the USB enters or leaves suspend mode. + * This is an opportunity for the board logic to shutdown clocks, power, etc. + * while the USB is suspended. + * + ************************************************************************************/ + +#ifdef CONFIG_USBDEV +void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) +{ + ullinfo("resume: %d\n", resume); +} +#endif + +#endif /* CONFIG_STM32F7_OTGFS */ diff --git a/configs/stm32f746-ws/src/stm32f746-ws.h b/configs/stm32f746-ws/src/stm32f746-ws.h index 07d2c6c11f..0a61a7b162 100644 --- a/configs/stm32f746-ws/src/stm32f746-ws.h +++ b/configs/stm32f746-ws/src/stm32f746-ws.h @@ -82,6 +82,12 @@ #define GPIO_BTN_USER (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | GPIO_PORTC | GPIO_PIN13) +#define GPIO_OTGFS_VBUS (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|\ + GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9) + +#define SDIO_SLOTNO 0 +#define SDIO_MINOR 0 + /**************************************************************************************************** * Public data ****************************************************************************************************/ @@ -102,5 +108,32 @@ void weak_function stm32_spidev_initialize(void); + /**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ + + #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_STM32F7_SDMMC1) + int stm32_sdio_initialize(void); + #endif + + /************************************************************************************ + * Name: stm32_dma_alloc_init + * + * Description: + * Called to create a FAT DMA allocator + * + * Returned Value: + * 0 on success or -ENOMEM + * + ************************************************************************************/ + + #if defined (CONFIG_FAT_DMAMEMORY) + int stm32_dma_alloc_init(void); + #endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_STM32F746_WS_SRC_STM32F746_WS_H */ From 495e475357d8cf0e2219b116ee5fc935d108b216 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Mon, 20 Jun 2016 10:55:38 +0200 Subject: [PATCH 004/155] ignore CRC for SD_CMD55 --- arch/arm/src/stm32f7/stm32_sdmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 4f2b7a8d01..c1eb3542d7 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -2093,7 +2093,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t else #endif { - /* Check if a timeout or CRC error occurred */ + /* Check if a timeout or CRC error occurred (not for SD_CMD55 - see ERRATA) */ regval = getreg32(STM32_SDMMC1_STA); if ((regval & SDIO_STA_CTIMEOUT) != 0) @@ -2101,7 +2101,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t ferr("ERROR: Command timeout: %08x\n", regval); ret = -ETIMEDOUT; } - else if ((regval & SDIO_STA_CCRCFAIL) != 0) + else if (cmd != SD_CMD55 && (regval & SDIO_STA_CCRCFAIL) != 0) { ferr("ERROR: CRC failure: %08x\n", regval); ret = -EIO; From e70ac97cef06b86b54af3e2c199b40695b8874b3 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Tue, 21 Jun 2016 13:17:50 +0200 Subject: [PATCH 005/155] should be cmd5 not cmd55 --- arch/arm/src/stm32f7/stm32_sdmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index c1eb3542d7..4f2b7a8d01 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -2093,7 +2093,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t else #endif { - /* Check if a timeout or CRC error occurred (not for SD_CMD55 - see ERRATA) */ + /* Check if a timeout or CRC error occurred */ regval = getreg32(STM32_SDMMC1_STA); if ((regval & SDIO_STA_CTIMEOUT) != 0) @@ -2101,7 +2101,7 @@ static int stm32_recvshortcrc(FAR struct sdio_dev_s *dev, uint32_t cmd, uint32_t ferr("ERROR: Command timeout: %08x\n", regval); ret = -ETIMEDOUT; } - else if (cmd != SD_CMD55 && (regval & SDIO_STA_CCRCFAIL) != 0) + else if ((regval & SDIO_STA_CCRCFAIL) != 0) { ferr("ERROR: CRC failure: %08x\n", regval); ret = -EIO; From bdfd3e824834b1faf47ffcb5b32a8a2bed202617 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Tue, 21 Jun 2016 14:02:53 +0200 Subject: [PATCH 006/155] flush cache before setup --- arch/arm/src/stm32f7/stm32_sdmmc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 4f2b7a8d01..dbeb880f93 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -2694,6 +2694,10 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, stm32_sampleinit(); stm32_sample(priv, SAMPLENDX_BEFORE_SETUP); + /* Flush cache to physical memory */ + + arch_flush_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); + /* Save the source buffer information for use by the interrupt handler */ priv->buffer = (uint32_t *)buffer; @@ -2712,10 +2716,6 @@ static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, stm32_sample(priv, SAMPLENDX_BEFORE_ENABLE); - /* Flush cache to physical memory */ - - arch_flush_dcache((uintptr_t)buffer, (uintptr_t)buffer + buflen); - /* Start the DMA */ stm32_dmastart(priv->dma, stm32_dmacallback, priv, false); From 0369bbff508bf93fad3413e839f7c7e33ecb9a9d Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Wed, 22 Jun 2016 10:54:06 +0200 Subject: [PATCH 007/155] styling --- arch/arm/src/stm32f7/chip/stm32_sdmmc.h | 4 ++-- arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h | 4 ++-- arch/arm/src/stm32f7/stm32_sdmmc.c | 2 +- arch/arm/src/stm32f7/stm32_sdmmc.h | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/src/stm32f7/chip/stm32_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h index e04bdddc1e..10ed29f238 100644 --- a/arch/arm/src/stm32f7/chip/stm32_sdmmc.h +++ b/arch/arm/src/stm32f7/chip/stm32_sdmmc.h @@ -1,7 +1,7 @@ /************************************************************************************ - * arch/arm/src/stm32f7/chip/stm32_i2c.h + * arch/arm/src/stm32f7/chip/stm32_sdmmc.h * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h index f710aed6d1..117c4da2fa 100644 --- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h @@ -1,7 +1,7 @@ /************************************************************************************ - * arch/arm/src/stm32f7/chip/stm32_sdio.h + * arch/arm/src/stm32f7/chip/stm32_sdmmc.h * - * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index dbeb880f93..16473094b5 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/stm32f7/stm32_sdio.c + * arch/arm/src/stm32f7/stm32_sdmmc.c * * Copyright (C) 2009, 2011-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.h b/arch/arm/src/stm32f7/stm32_sdmmc.h index 18e6c44601..12b6348559 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.h +++ b/arch/arm/src/stm32f7/stm32_sdmmc.h @@ -1,7 +1,7 @@ /************************************************************************************ - * arch/arm/src/stm32f7/stm32_sdio.h + * arch/arm/src/stm32f7/stm32_sdmmc.h * - * Copyright (C) 2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without From 47a5f81a63bb408f691550283c844bd6f86c0c83 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Sat, 25 Jun 2016 17:55:33 +0200 Subject: [PATCH 008/155] mmc1 --- configs/stm32f746-ws/src/stm32_appinitialize.c | 2 ++ configs/stm32f746-ws/src/stm32_sdmmc.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/configs/stm32f746-ws/src/stm32_appinitialize.c b/configs/stm32f746-ws/src/stm32_appinitialize.c index 689bea75fe..0a58e61e36 100644 --- a/configs/stm32f746-ws/src/stm32_appinitialize.c +++ b/configs/stm32f746-ws/src/stm32_appinitialize.c @@ -100,6 +100,7 @@ int board_app_initialize(void) } #endif +#ifdef CONFIG_STM32F7_SDMMC1 /* Initialize the SDIO block driver */ int ret = OK; @@ -110,6 +111,7 @@ int board_app_initialize(void) ferr("ERROR: Failed to initialize MMC/SD driver: %d\n", ret); return ret; } +#endif return OK; } diff --git a/configs/stm32f746-ws/src/stm32_sdmmc.c b/configs/stm32f746-ws/src/stm32_sdmmc.c index bdbe7a7f65..4169d511a2 100644 --- a/configs/stm32f746-ws/src/stm32_sdmmc.c +++ b/configs/stm32f746-ws/src/stm32_sdmmc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * config/stm32f746-ws/src/stm32_sdio.c + * config/stm32f746-ws/src/stm32_sdmmc.c * * Copyright (C) 2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt From 2723de9a09a1a16d1135afef193308dd27a11cff Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Sat, 25 Jun 2016 18:31:37 +0200 Subject: [PATCH 009/155] usb ep 0-8 --- arch/arm/src/stm32f7/chip/stm32_otg.h | 148 --------------------- arch/arm/src/stm32f7/stm32_otg.h | 6 +- arch/arm/src/stm32f7/stm32_otgdev.c | 182 +++++++++++++++++++------- configs/stm32f746-ws/nsh/defconfig | 56 ++++---- 4 files changed, 170 insertions(+), 222 deletions(-) diff --git a/arch/arm/src/stm32f7/chip/stm32_otg.h b/arch/arm/src/stm32f7/chip/stm32_otg.h index ee06497102..474d063026 100644 --- a/arch/arm/src/stm32f7/chip/stm32_otg.h +++ b/arch/arm/src/stm32f7/chip/stm32_otg.h @@ -78,9 +78,6 @@ #define STM32_OTG_HPTXFSIZ_OFFSET 0x0100 /* Host periodic transmit FIFO size register */ #define STM32_OTG_DIEPTXF_OFFSET(n) (104+(((n)-1) << 2)) -#define STM32_OTG_DIEPTXF1_OFFSET 0x0104 /* Device IN endpoint transmit FIFO1 size register */ -#define STM32_OTG_DIEPTXF2_OFFSET 0x0108 /* Device IN endpoint transmit FIFO2 size register */ -#define STM32_OTG_DIEPTXF3_OFFSET 0x010c /* Device IN endpoint transmit FIFO3 size register */ /* Host-mode control and status registers */ @@ -99,44 +96,12 @@ #define STM32_OTG_HCTSIZ_CHOFFSET 0x0010 /* Host channel interrupt register */ #define STM32_OTG_HCCHAR_OFFSET(n) (0x500 + ((n) << 5)) -#define STM32_OTG_HCCHAR0_OFFSET 0x0500 /* Host channel-0 characteristics register */ -#define STM32_OTG_HCCHAR1_OFFSET 0x0520 /* Host channel-1 characteristics register */ -#define STM32_OTG_HCCHAR2_OFFSET 0x0540 /* Host channel-2 characteristics register */ -#define STM32_OTG_HCCHAR3_OFFSET 0x0560 /* Host channel-3 characteristics register */ -#define STM32_OTG_HCCHAR4_OFFSET 0x0580 /* Host channel-4 characteristics register */ -#define STM32_OTG_HCCHAR5_OFFSET 0x05a0 /* Host channel-5 characteristics register */ -#define STM32_OTG_HCCHAR6_OFFSET 0x05c0 /* Host channel-6 characteristics register */ -#define STM32_OTG_HCCHAR7_OFFSET 0x05e0 /* Host channel-7 characteristics register */ #define STM32_OTG_HCINT_OFFSET(n) (0x508 + ((n) << 5)) -#define STM32_OTG_HCINT0_OFFSET 0x0508 /* Host channel-0 interrupt register */ -#define STM32_OTG_HCINT1_OFFSET 0x0528 /* Host channel-1 interrupt register */ -#define STM32_OTG_HCINT2_OFFSET 0x0548 /* Host channel-2 interrupt register */ -#define STM32_OTG_HCINT3_OFFSET 0x0568 /* Host channel-3 interrupt register */ -#define STM32_OTG_HCINT4_OFFSET 0x0588 /* Host channel-4 interrupt register */ -#define STM32_OTG_HCINT5_OFFSET 0x05a8 /* Host channel-5 interrupt register */ -#define STM32_OTG_HCINT6_OFFSET 0x05c8 /* Host channel-6 interrupt register */ -#define STM32_OTG_HCINT7_OFFSET 0x05e8 /* Host channel-7 interrupt register */ #define STM32_OTG_HCINTMSK_OFFSET(n) (0x50c + ((n) << 5)) -#define STM32_OTG_HCINTMSK0_OFFSET 0x050c /* Host channel-0 interrupt mask register */ -#define STM32_OTG_HCINTMSK1_OFFSET 0x052c /* Host channel-1 interrupt mask register */ -#define STM32_OTG_HCINTMSK2_OFFSET 0x054c /* Host channel-2 interrupt mask register */ -#define STM32_OTG_HCINTMSK3_OFFSET 0x056c /* Host channel-3 interrupt mask register */ -#define STM32_OTG_HCINTMSK4_OFFSET 0x058c /* Host channel-4 interrupt mask register */ -#define STM32_OTG_HCINTMSK5_OFFSET 0x05ac /* Host channel-5 interrupt mask register */ -#define STM32_OTG_HCINTMSK6_OFFSET 0x05cc /* Host channel-6 interrupt mask register */ -#define STM32_OTG_HCINTMSK7_OFFSET 0x05ec /* Host channel-7 interrupt mask register */ #define STM32_OTG_HCTSIZ_OFFSET(n) (0x510 + ((n) << 5)) -#define STM32_OTG_HCTSIZ0_OFFSET 0x0510 /* Host channel-0 interrupt register */ -#define STM32_OTG_HCTSIZ1_OFFSET 0x0530 /* Host channel-1 interrupt register */ -#define STM32_OTG_HCTSIZ2_OFFSET 0x0550 /* Host channel-2 interrupt register */ -#define STM32_OTG_HCTSIZ3_OFFSET 0x0570 /* Host channel-3 interrupt register */ -#define STM32_OTG_HCTSIZ4_OFFSET 0x0590 /* Host channel-4 interrupt register */ -#define STM32_OTG_HCTSIZ5_OFFSET 0x05b0 /* Host channel-5 interrupt register */ -#define STM32_OTG_HCTSIZ6_OFFSET 0x05d0 /* Host channel-6 interrupt register */ -#define STM32_OTG_HCTSIZ7_OFFSET 0x05f0 /* Host channel-7 interrupt register */ /* Device-mode control and status registers */ @@ -158,50 +123,22 @@ #define STM32_OTG_DTXFSTS_EPOFFSET 0x0018 /* Device IN endpoint transmit FIFO status register */ #define STM32_OTG_DIEPCTL_OFFSET(n) (0x0900 + ((n) << 5)) -#define STM32_OTG_DIEPCTL0_OFFSET 0x0900 /* Device control IN endpoint 0 control register */ -#define STM32_OTG_DIEPCTL1_OFFSET 0x0920 /* Device control IN endpoint 2 control register */ -#define STM32_OTG_DIEPCTL2_OFFSET 0x0940 /* Device control IN endpoint 3 control register */ -#define STM32_OTG_DIEPCTL3_OFFSET 0x0960 /* Device control IN endpoint 4 control register */ #define STM32_OTG_DIEPINT_OFFSET(n) (0x0908 + ((n) << 5)) -#define STM32_OTG_DIEPINT0_OFFSET 0x0908 /* Device endpoint-0 interrupt register */ -#define STM32_OTG_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 interrupt register */ -#define STM32_OTG_DIEPINT2_OFFSET 0x0948 /* Device endpoint-2 interrupt register */ -#define STM32_OTG_DIEPINT3_OFFSET 0x0968 /* Device endpoint-3 interrupt register */ #define STM32_OTG_DIEPTSIZ_OFFSET(n) (0x910 + ((n) << 5)) -#define STM32_OTG_DIEPTSIZ0_OFFSET 0x0910 /* Device IN endpoint 0 transfer size register */ -#define STM32_OTG_DIEPTSIZ1_OFFSET 0x0930 /* Device IN endpoint 1 transfer size register */ -#define STM32_OTG_DIEPTSIZ2_OFFSET 0x0950 /* Device IN endpoint 2 transfer size register */ -#define STM32_OTG_DIEPTSIZ3_OFFSET 0x0970 /* Device IN endpoint 3 transfer size register */ #define STM32_OTG_DTXFSTS_OFFSET(n) (0x0918 + ((n) << 5)) -#define STM32_OTG_DTXFSTS0_OFFSET 0x0918 /* Device OUT endpoint-0 TxFIFO status register */ -#define STM32_OTG_DTXFSTS1_OFFSET 0x0938 /* Device OUT endpoint-1 TxFIFO status register */ -#define STM32_OTG_DTXFSTS2_OFFSET 0x0958 /* Device OUT endpoint-2 TxFIFO status register */ -#define STM32_OTG_DTXFSTS3_OFFSET 0x0978 /* Device OUT endpoint-3 TxFIFO status register */ #define STM32_OTG_DOEP_OFFSET(n) (0x0b00 + ((n) << 5)) #define STM32_OTG_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */ #define STM32_OTG_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */ #define STM32_OTG_DOEPCTL_OFFSET(n) (0x0b00 + ((n) << 5)) -#define STM32_OTG_DOEPCTL0_OFFSET 0x00b00 /* Device OUT endpoint 0 control register */ -#define STM32_OTG_DOEPCTL1_OFFSET 0x00b20 /* Device OUT endpoint 1 control register */ -#define STM32_OTG_DOEPCTL2_OFFSET 0x00b40 /* Device OUT endpoint 2 control register */ -#define STM32_OTG_DOEPCTL3_OFFSET 0x00b60 /* Device OUT endpoint 3 control register */ #define STM32_OTG_DOEPINT_OFFSET(n) (0x0b08 + ((n) << 5)) -#define STM32_OTG_DOEPINT0_OFFSET 0x00b08 /* Device endpoint-0 interrupt register */ -#define STM32_OTG_DOEPINT1_OFFSET 0x00b28 /* Device endpoint-1 interrupt register */ -#define STM32_OTG_DOEPINT2_OFFSET 0x00b48 /* Device endpoint-2 interrupt register */ -#define STM32_OTG_DOEPINT3_OFFSET 0x00b68 /* Device endpoint-3 interrupt register */ #define STM32_OTG_DOEPTSIZ_OFFSET(n) (0x0b10 + ((n) << 5)) -#define STM32_OTG_DOEPTSIZ0_OFFSET 0x00b10 /* Device OUT endpoint-0 transfer size register */ -#define STM32_OTG_DOEPTSIZ1_OFFSET 0x00b30 /* Device OUT endpoint-1 transfer size register */ -#define STM32_OTG_DOEPTSIZ2_OFFSET 0x00b50 /* Device OUT endpoint-2 transfer size register */ -#define STM32_OTG_DOEPTSIZ3_OFFSET 0x00b70 /* Device OUT endpoint-3 transfer size register */ /* Power and clock gating registers */ @@ -212,17 +149,6 @@ #define STM32_OTG_DFIFO_DEP_OFFSET(n) (0x1000 + ((n) << 12)) #define STM32_OTG_DFIFO_HCH_OFFSET(n) (0x1000 + ((n) << 12)) -#define STM32_OTG_DFIFO_DEP0_OFFSET 0x1000 /* 0x1000-0x1ffc Device IN/OUT Endpoint 0 DFIFO Write/Read Access */ -#define STM32_OTG_DFIFO_HCH0_OFFSET 0x1000 /* 0x1000-0x1ffc Host OUT/IN Channel 0 DFIFO Read/Write Access */ - -#define STM32_OTG_DFIFO_DEP1_OFFSET 0x2000 /* 0x2000-0x2ffc Device IN/OUT Endpoint 1 DFIFO Write/Read Access */ -#define STM32_OTG_DFIFO_HCH1_OFFSET 0x2000 /* 0x2000-0x2ffc Host OUT/IN Channel 1 DFIFO Read/Write Access */ - -#define STM32_OTG_DFIFO_DEP2_OFFSET 0x3000 /* 0x3000-0x3ffc Device IN/OUT Endpoint 2 DFIFO Write/Read Access */ -#define STM32_OTG_DFIFO_HCH2_OFFSET 0x3000 /* 0x3000-0x3ffc Host OUT/IN Channel 2 DFIFO Read/Write Access */ - -#define STM32_OTG_DFIFO_DEP3_OFFSET 0x4000 /* 0x4000-0x4ffc Device IN/OUT Endpoint 3 DFIFO Write/Read Access */ -#define STM32_OTG_DFIFO_HCH3_OFFSET 0x4000 /* 0x4000-0x4ffc Host OUT/IN Channel 3 DFIFO Read/Write Access */ /* Register Addresses *******************************************************************************/ @@ -244,9 +170,6 @@ #define STM32_OTG_HPTXFSIZ (STM32_OTG_BASE+STM32_OTG_HPTXFSIZ_OFFSET) #define STM32_OTG_DIEPTXF(n) (STM32_OTG_BASE+STM32_OTG_DIEPTXF_OFFSET(n)) -#define STM32_OTG_DIEPTXF1 (STM32_OTG_BASE+STM32_OTG_DIEPTXF1_OFFSET) -#define STM32_OTG_DIEPTXF2 (STM32_OTG_BASE+STM32_OTG_DIEPTXF2_OFFSET) -#define STM32_OTG_DIEPTXF3 (STM32_OTG_BASE+STM32_OTG_DIEPTXF3_OFFSET) /* Host-mode control and status registers */ @@ -261,44 +184,12 @@ #define STM32_OTG_CHAN(n) (STM32_OTG_BASE+STM32_OTG_CHAN_OFFSET(n)) #define STM32_OTG_HCCHAR(n) (STM32_OTG_BASE+STM32_OTG_HCCHAR_OFFSET(n)) -#define STM32_OTG_HCCHAR0 (STM32_OTG_BASE+STM32_OTG_HCCHAR0_OFFSET) -#define STM32_OTG_HCCHAR1 (STM32_OTG_BASE+STM32_OTG_HCCHAR1_OFFSET) -#define STM32_OTG_HCCHAR2 (STM32_OTG_BASE+STM32_OTG_HCCHAR2_OFFSET) -#define STM32_OTG_HCCHAR3 (STM32_OTG_BASE+STM32_OTG_HCCHAR3_OFFSET) -#define STM32_OTG_HCCHAR4 (STM32_OTG_BASE+STM32_OTG_HCCHAR4_OFFSET) -#define STM32_OTG_HCCHAR5 (STM32_OTG_BASE+STM32_OTG_HCCHAR5_OFFSET) -#define STM32_OTG_HCCHAR6 (STM32_OTG_BASE+STM32_OTG_HCCHAR6_OFFSET) -#define STM32_OTG_HCCHAR7 (STM32_OTG_BASE+STM32_OTG_HCCHAR7_OFFSET) #define STM32_OTG_HCINT(n) (STM32_OTG_BASE+STM32_OTG_HCINT_OFFSET(n)) -#define STM32_OTG_HCINT0 (STM32_OTG_BASE+STM32_OTG_HCINT0_OFFSET) -#define STM32_OTG_HCINT1 (STM32_OTG_BASE+STM32_OTG_HCINT1_OFFSET) -#define STM32_OTG_HCINT2 (STM32_OTG_BASE+STM32_OTG_HCINT2_OFFSET) -#define STM32_OTG_HCINT3 (STM32_OTG_BASE+STM32_OTG_HCINT3_OFFSET) -#define STM32_OTG_HCINT4 (STM32_OTG_BASE+STM32_OTG_HCINT4_OFFSET) -#define STM32_OTG_HCINT5 (STM32_OTG_BASE+STM32_OTG_HCINT5_OFFSET) -#define STM32_OTG_HCINT6 (STM32_OTG_BASE+STM32_OTG_HCINT6_OFFSET) -#define STM32_OTG_HCINT7 (STM32_OTG_BASE+STM32_OTG_HCINT7_OFFSET) #define STM32_OTG_HCINTMSK(n) (STM32_OTG_BASE+STM32_OTG_HCINTMSK_OFFSET(n)) -#define STM32_OTG_HCINTMSK0 (STM32_OTG_BASE+STM32_OTG_HCINTMSK0_OFFSET) -#define STM32_OTG_HCINTMSK1 (STM32_OTG_BASE+STM32_OTG_HCINTMSK1_OFFSET) -#define STM32_OTG_HCINTMSK2 (STM32_OTG_BASE+STM32_OTG_HCINTMSK2_OFFSET) -#define STM32_OTG_HCINTMSK3 (STM32_OTG_BASE+STM32_OTG_HCINTMSK3_OFFSET) -#define STM32_OTG_HCINTMSK4 (STM32_OTG_BASE+STM32_OTG_HCINTMSK4_OFFSET) -#define STM32_OTG_HCINTMSK5 (STM32_OTG_BASE+STM32_OTG_HCINTMSK5_OFFSET) -#define STM32_OTG_HCINTMSK6 (STM32_OTG_BASE+STM32_OTG_HCINTMSK6_OFFSET) -#define STM32_OTG_HCINTMSK7 (STM32_OTG_BASE+STM32_OTG_HCINTMSK7_OFFSET)_ #define STM32_OTG_HCTSIZ(n) (STM32_OTG_BASE+STM32_OTG_HCTSIZ_OFFSET(n)) -#define STM32_OTG_HCTSIZ0 (STM32_OTG_BASE+STM32_OTG_HCTSIZ0_OFFSET) -#define STM32_OTG_HCTSIZ1 (STM32_OTG_BASE+STM32_OTG_HCTSIZ1_OFFSET) -#define STM32_OTG_HCTSIZ2 (STM32_OTG_BASE+STM32_OTG_HCTSIZ2_OFFSET) -#define STM32_OTG_HCTSIZ3 (STM32_OTG_BASE+STM32_OTG_HCTSIZ3_OFFSET) -#define STM32_OTG_HCTSIZ4 (STM32_OTG_BASE+STM32_OTG_HCTSIZ4_OFFSET) -#define STM32_OTG_HCTSIZ5 (STM32_OTG_BASE+STM32_OTG_HCTSIZ5_OFFSET) -#define STM32_OTG_HCTSIZ6 (STM32_OTG_BASE+STM32_OTG_HCTSIZ6_OFFSET) -#define STM32_OTG_HCTSIZ7 (STM32_OTG_BASE+STM32_OTG_HCTSIZ7_OFFSET) /* Device-mode control and status registers */ @@ -316,48 +207,20 @@ #define STM32_OTG_DIEP(n) (STM32_OTG_BASE+STM32_OTG_DIEP_OFFSET(n)) #define STM32_OTG_DIEPCTL(n) (STM32_OTG_BASE+STM32_OTG_DIEPCTL_OFFSET(n)) -#define STM32_OTG_DIEPCTL0 (STM32_OTG_BASE+STM32_OTG_DIEPCTL0_OFFSET) -#define STM32_OTG_DIEPCTL1 (STM32_OTG_BASE+STM32_OTG_DIEPCTL1_OFFSET) -#define STM32_OTG_DIEPCTL2 (STM32_OTG_BASE+STM32_OTG_DIEPCTL2_OFFSET) -#define STM32_OTG_DIEPCTL3 (STM32_OTG_BASE+STM32_OTG_DIEPCTL3_OFFSET) #define STM32_OTG_DIEPINT(n) (STM32_OTG_BASE+STM32_OTG_DIEPINT_OFFSET(n)) -#define STM32_OTG_DIEPINT0 (STM32_OTG_BASE+STM32_OTG_DIEPINT0_OFFSET) -#define STM32_OTG_DIEPINT1 (STM32_OTG_BASE+STM32_OTG_DIEPINT1_OFFSET) -#define STM32_OTG_DIEPINT2 (STM32_OTG_BASE+STM32_OTG_DIEPINT2_OFFSET) -#define STM32_OTG_DIEPINT3 (STM32_OTG_BASE+STM32_OTG_DIEPINT3_OFFSET) #define STM32_OTG_DIEPTSIZ(n) (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ_OFFSET(n)) -#define STM32_OTG_DIEPTSIZ0 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ0_OFFSET) -#define STM32_OTG_DIEPTSIZ1 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ1_OFFSET) -#define STM32_OTG_DIEPTSIZ2 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ2_OFFSET) -#define STM32_OTG_DIEPTSIZ3 (STM32_OTG_BASE+STM32_OTG_DIEPTSIZ3_OFFSET) #define STM32_OTG_DTXFSTS(n) (STM32_OTG_BASE+STM32_OTG_DTXFSTS_OFFSET(n)) -#define STM32_OTG_DTXFSTS0 (STM32_OTG_BASE+STM32_OTG_DTXFSTS0_OFFSET) -#define STM32_OTG_DTXFSTS1 (STM32_OTG_BASE+STM32_OTG_DTXFSTS1_OFFSET) -#define STM32_OTG_DTXFSTS2 (STM32_OTG_BASE+STM32_OTG_DTXFSTS2_OFFSET) -#define STM32_OTG_DTXFSTS3 (STM32_OTG_BASE+STM32_OTG_DTXFSTS3_OFFSET) #define STM32_OTG_DOEP(n) (STM32_OTG_BASE+STM32_OTG_DOEP_OFFSET(n)) #define STM32_OTG_DOEPCTL(n) (STM32_OTG_BASE+STM32_OTG_DOEPCTL_OFFSET(n)) -#define STM32_OTG_DOEPCTL0 (STM32_OTG_BASE+STM32_OTG_DOEPCTL0_OFFSET) -#define STM32_OTG_DOEPCTL1 (STM32_OTG_BASE+STM32_OTG_DOEPCTL1_OFFSET) -#define STM32_OTG_DOEPCTL2 (STM32_OTG_BASE+STM32_OTG_DOEPCTL2_OFFSET) -#define STM32_OTG_DOEPCTL3 (STM32_OTG_BASE+STM32_OTG_DOEPCTL3_OFFSET) #define STM32_OTG_DOEPINT(n) (STM32_OTG_BASE+STM32_OTG_DOEPINT_OFFSET(n)) -#define STM32_OTG_DOEPINT0 (STM32_OTG_BASE+STM32_OTG_DOEPINT0_OFFSET) -#define STM32_OTG_DOEPINT1 (STM32_OTG_BASE+STM32_OTG_DOEPINT1_OFFSET) -#define STM32_OTG_DOEPINT2 (STM32_OTG_BASE+STM32_OTG_DOEPINT2_OFFSET) -#define STM32_OTG_DOEPINT3 (STM32_OTG_BASE+STM32_OTG_DOEPINT3_OFFSET) #define STM32_OTG_DOEPTSIZ(n) (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ_OFFSET(n)) -#define STM32_OTG_DOEPTSIZ0 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ0_OFFSET) -#define STM32_OTG_DOEPTSIZ1 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ1_OFFSET) -#define STM32_OTG_DOEPTSIZ2 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ2_OFFSET) -#define STM32_OTG_DOEPTSIZ3 (STM32_OTG_BASE+STM32_OTG_DOEPTSIZ3_OFFSET) /* Power and clock gating registers */ @@ -368,17 +231,6 @@ #define STM32_OTG_DFIFO_DEP(n) (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP_OFFSET(n)) #define STM32_OTG_DFIFO_HCH(n) (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH_OFFSET(n)) -#define STM32_OTG_DFIFO_DEP0 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP0_OFFSET) -#define STM32_OTG_DFIFO_HCH0 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH0_OFFSET) - -#define STM32_OTG_DFIFO_DEP1 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP1_OFFSET) -#define STM32_OTG_DFIFO_HCH1 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH1_OFFSET) - -#define STM32_OTG_DFIFO_DEP2 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP2_OFFSET) -#define STM32_OTG_DFIFO_HCH2 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH2_OFFSET) - -#define STM32_OTG_DFIFO_DEP3 (STM32_OTG_BASE+STM32_OTG_DFIFO_DEP3_OFFSET) -#define STM32_OTG_DFIFO_HCH3 (STM32_OTG_BASE+STM32_OTG_DFIFO_HCH3_OFFSET) /* Register Bitfield Definitions ********************************************************************/ /* Core global control and status registers */ diff --git a/arch/arm/src/stm32f7/stm32_otg.h b/arch/arm/src/stm32f7/stm32_otg.h index 0bb6b9b393..3c60683ea3 100644 --- a/arch/arm/src/stm32f7/stm32_otg.h +++ b/arch/arm/src/stm32f7/stm32_otg.h @@ -66,18 +66,18 @@ # define GPIO_OTG_DP GPIO_OTGFS_DP # define GPIO_OTG_ID GPIO_OTGFS_ID # define GPIO_OTG_SOF GPIO_OTGFS_SOF - +# define STM32_OTG_FIFO_SIZE 1280 #endif #if defined(CONFIG_STM32F7_OTGHS) # define STM32_IRQ_OTG STM32_IRQ_OTGHS # define STM32_OTG_BASE STM32_USBOTGHS_BASE -# define STM32_NENDPOINTS (8) /* ep0-7 x 2 for IN and OUT */ +# define STM32_NENDPOINTS (7) /* ep0-8 x 2 for IN and OUT but driver internals use byte to map + one bit for direction */ # define GPIO_OTG_DM GPIO_OTGHS_DM # define GPIO_OTG_DP GPIO_OTGHS_DP # define GPIO_OTG_ID GPIO_OTGHS_ID # define GPIO_OTG_SOF GPIO_OTGHS_SOF - +# define STM32_OTG_FIFO_SIZE 4096 #endif /************************************************************************************ diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c index d4d46c4efb..7b9db010ad 100644 --- a/arch/arm/src/stm32f7/stm32_otgdev.c +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -89,30 +89,82 @@ */ #ifndef CONFIG_USBDEV_RXFIFO_SIZE -# define CONFIG_USBDEV_RXFIFO_SIZE 512 +# define CONFIG_USBDEV_RXFIFO_SIZE (STM32_OTG_FIFO_SIZE - STM32_OTG_FIFO_SIZE/4/2/STM32_NENDPOINTS*4*STM32_NENDPOINTS) #endif -#ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE -# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 192 +#if STM32_NENDPOINTS > 0 +# ifndef CONFIG_USBDEV_EP0_TXFIFO_SIZE +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP0_TXFIFO_SIZE 0 #endif -#ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE -# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 192 +#if STM32_NENDPOINTS > 1 +# ifndef CONFIG_USBDEV_EP1_TXFIFO_SIZE +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP1_TXFIFO_SIZE 0 #endif -#ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE -# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 192 +#if STM32_NENDPOINTS > 2 +# ifndef CONFIG_USBDEV_EP2_TXFIFO_SIZE +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP2_TXFIFO_SIZE 0 #endif -#ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE -# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 192 +#if STM32_NENDPOINTS > 3 +# ifndef CONFIG_USBDEV_EP3_TXFIFO_SIZE +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP3_TXFIFO_SIZE 0 #endif -#if (CONFIG_USBDEV_RXFIFO_SIZE + CONFIG_USBDEV_EP0_TXFIFO_SIZE + \ - CONFIG_USBDEV_EP2_TXFIFO_SIZE + CONFIG_USBDEV_EP3_TXFIFO_SIZE) > 1280 -# error "FIFO allocations exceed FIFO memory size" +#if STM32_NENDPOINTS > 4 +# ifndef CONFIG_USBDEV_EP4_TXFIFO_SIZE +# define CONFIG_USBDEV_EP4_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP4_TXFIFO_SIZE 0 #endif +#if STM32_NENDPOINTS > 5 +# ifndef CONFIG_USBDEV_EP5_TXFIFO_SIZE +# define CONFIG_USBDEV_EP5_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP5_TXFIFO_SIZE 0 +#endif + +#if STM32_NENDPOINTS > 6 +# ifndef CONFIG_USBDEV_EP6_TXFIFO_SIZE +# define CONFIG_USBDEV_EP6_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP6_TXFIFO_SIZE 0 +#endif + +#if STM32_NENDPOINTS > 7 +# ifndef CONFIG_USBDEV_EP7_TXFIFO_SIZE +# define CONFIG_USBDEV_EP7_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP7_TXFIFO_SIZE 0 +#endif + +#if STM32_NENDPOINTS > 8 +# ifndef CONFIG_USBDEV_EP8_TXFIFO_SIZE +# define CONFIG_USBDEV_EP8_TXFIFO_SIZE ((STM32_OTG_FIFO_SIZE - CONFIG_USBDEV_RXFIFO_SIZE)/STM32_NENDPOINTS) +# endif +#else +# define CONFIG_USBDEV_EP8_TXFIFO_SIZE 0 +#endif + + /* The actual FIFO addresses that we use must be aligned to 4-byte boundaries; * FIFO sizes must be provided in units of 32-bit words. */ @@ -123,29 +175,36 @@ #define STM32_EP0_TXFIFO_BYTES ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) & ~3) #define STM32_EP0_TXFIFO_WORDS ((CONFIG_USBDEV_EP0_TXFIFO_SIZE + 3) >> 2) -#if STM32_EP0_TXFIFO_WORDS < 16 || STM32_EP0_TXFIFO_WORDS > 256 -# error "CONFIG_USBDEV_EP0_TXFIFO_SIZE is out of range" -#endif - #define STM32_EP1_TXFIFO_BYTES ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) & ~3) #define STM32_EP1_TXFIFO_WORDS ((CONFIG_USBDEV_EP1_TXFIFO_SIZE + 3) >> 2) -#if STM32_EP1_TXFIFO_WORDS < 16 -# error "CONFIG_USBDEV_EP1_TXFIFO_SIZE is out of range" -#endif - #define STM32_EP2_TXFIFO_BYTES ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) & ~3) #define STM32_EP2_TXFIFO_WORDS ((CONFIG_USBDEV_EP2_TXFIFO_SIZE + 3) >> 2) -#if STM32_EP2_TXFIFO_WORDS < 16 -# error "CONFIG_USBDEV_EP2_TXFIFO_SIZE is out of range" -#endif - #define STM32_EP3_TXFIFO_BYTES ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) & ~3) #define STM32_EP3_TXFIFO_WORDS ((CONFIG_USBDEV_EP3_TXFIFO_SIZE + 3) >> 2) -#if STM32_EP3_TXFIFO_WORDS < 16 -# error "CONFIG_USBDEV_EP3_TXFIFO_SIZE is out of range" +#define STM32_EP4_TXFIFO_BYTES ((CONFIG_USBDEV_EP4_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP4_TXFIFO_WORDS ((CONFIG_USBDEV_EP4_TXFIFO_SIZE + 3) >> 2) + +#define STM32_EP5_TXFIFO_BYTES ((CONFIG_USBDEV_EP5_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP5_TXFIFO_WORDS ((CONFIG_USBDEV_EP5_TXFIFO_SIZE + 3) >> 2) + +#define STM32_EP6_TXFIFO_BYTES ((CONFIG_USBDEV_EP6_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP6_TXFIFO_WORDS ((CONFIG_USBDEV_EP6_TXFIFO_SIZE + 3) >> 2) + +#define STM32_EP7_TXFIFO_BYTES ((CONFIG_USBDEV_EP7_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP7_TXFIFO_WORDS ((CONFIG_USBDEV_EP7_TXFIFO_SIZE + 3) >> 2) + +#define STM32_EP8_TXFIFO_BYTES ((CONFIG_USBDEV_EP8_TXFIFO_SIZE + 3) & ~3) +#define STM32_EP8_TXFIFO_WORDS ((CONFIG_USBDEV_EP8_TXFIFO_SIZE + 3) >> 2) + + +#if (STM32_RXFIFO_BYTES + \ + STM32_EP0_TXFIFO_BYTES + STM32_EP1_TXFIFO_BYTES + STM32_EP2_TXFIFO_BYTES + STM32_EP3_TXFIFO_BYTES + \ + STM32_EP4_TXFIFO_BYTES + STM32_EP5_TXFIFO_BYTES + STM32_EP6_TXFIFO_BYTES + STM32_EP7_TXFIFO_BYTES + CONFIG_USBDEV_EP8_TXFIFO_SIZE \ + ) > STM32_OTG_FIFO_SIZE +# error "FIFO allocations exceed FIFO memory size" #endif /* Debug ***********************************************************************/ @@ -962,7 +1021,7 @@ static void stm32_ep0in_activate(void) /* Set the max packet size of the IN EP. */ - regval = stm32_getreg(STM32_OTG_DIEPCTL0); + regval = stm32_getreg(STM32_OTG_DIEPCTL(0)); regval &= ~OTG_DIEPCTL0_MPSIZ_MASK; #if CONFIG_USBDEV_EP0_MAXSIZE == 8 @@ -977,7 +1036,7 @@ static void stm32_ep0in_activate(void) # error "Unsupported value of CONFIG_USBDEV_EP0_MAXSIZE" #endif - stm32_putreg(regval, STM32_OTG_DIEPCTL0); + stm32_putreg(regval, STM32_OTG_DIEPCTL(0)); /* Clear global IN NAK */ @@ -1003,13 +1062,13 @@ static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv) regval = (USB_SIZEOF_CTRLREQ * 3 << OTG_DOEPTSIZ0_XFRSIZ_SHIFT) | (OTG_DOEPTSIZ0_PKTCNT) | (3 << OTG_DOEPTSIZ0_STUPCNT_SHIFT); - stm32_putreg(regval, STM32_OTG_DOEPTSIZ0); + stm32_putreg(regval, STM32_OTG_DOEPTSIZ(0)); /* Then clear NAKing and enable the transfer */ - regval = stm32_getreg(STM32_OTG_DOEPCTL0); + regval = stm32_getreg(STM32_OTG_DOEPCTL(0)); regval |= (OTG_DOEPCTL0_CNAK | OTG_DOEPCTL0_EPENA); - stm32_putreg(regval, STM32_OTG_DOEPCTL0); + stm32_putreg(regval, STM32_OTG_DOEPCTL(0)); } /**************************************************************************** @@ -3227,9 +3286,9 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv) { /* Clear NAKSTS so that we can receive the data */ - regval = stm32_getreg(STM32_OTG_DOEPCTL0); + regval = stm32_getreg(STM32_OTG_DOEPCTL(0)); regval |= OTG_DOEPCTL0_CNAK; - stm32_putreg(regval, STM32_OTG_DOEPCTL0); + stm32_putreg(regval, STM32_OTG_DOEPCTL(0)); /* Wait for the data phase. */ @@ -5235,33 +5294,68 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv) stm32_putreg(STM32_RXFIFO_WORDS, STM32_OTG_GRXFSIZ); - /* EP0 TX */ - +#if STM32_NENDPOINTS > 0 address = STM32_RXFIFO_WORDS; regval = (address << OTG_DIEPTXF0_TX0FD_SHIFT) | (STM32_EP0_TXFIFO_WORDS << OTG_DIEPTXF0_TX0FSA_SHIFT); stm32_putreg(regval, STM32_OTG_DIEPTXF0); +#endif - /* EP1 TX */ - +#if STM32_NENDPOINTS > 1 address += STM32_EP0_TXFIFO_WORDS; regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | (STM32_EP1_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); - stm32_putreg(regval, STM32_OTG_DIEPTXF1); - - /* EP2 TX */ + stm32_putreg(regval, STM32_OTG_DIEPTXF(1)); +#endif +#if STM32_NENDPOINTS > 2 address += STM32_EP1_TXFIFO_WORDS; regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | (STM32_EP2_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); - stm32_putreg(regval, STM32_OTG_DIEPTXF2); - - /* EP3 TX */ + stm32_putreg(regval, STM32_OTG_DIEPTXF(2)); +#endif +#if STM32_NENDPOINTS > 3 address += STM32_EP2_TXFIFO_WORDS; regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | (STM32_EP3_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); - stm32_putreg(regval, STM32_OTG_DIEPTXF3); + stm32_putreg(regval, STM32_OTG_DIEPTXF(3)); +#endif + +#if STM32_NENDPOINTS > 4 + address += STM32_EP3_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP4_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF(4)); +#endif + +#if STM32_NENDPOINTS > 5 + address += STM32_EP4_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP5_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF(5)); +#endif + +#if STM32_NENDPOINTS > 6 + address += STM32_EP5_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP6_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF(6)); +#endif + +#if STM32_NENDPOINTS > 7 + address += STM32_EP6_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP7_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF(7)); +#endif + +#if STM32_NENDPOINTS > 8 + address += STM32_EP7_TXFIFO_WORDS; + regval = (address << OTG_DIEPTXF_INEPTXSA_SHIFT) | + (STM32_EP8_TXFIFO_WORDS << OTG_DIEPTXF_INEPTXFD_SHIFT); + stm32_putreg(regval, STM32_OTG_DIEPTXF(8)); +#endif /* Flush the FIFOs */ diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index 44a25aec95..653cccf1e6 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -300,13 +300,13 @@ CONFIG_STM32F7_I2C1=y # CONFIG_STM32F7_I2C3 is not set # CONFIG_STM32F7_LPTIM1 is not set # CONFIG_STM32F7_LTDC is not set -##CONFIG_STM32F7_OTGFS=y +CONFIG_STM32F7_OTGFS=y # CONFIG_STM32F7_OTGHS is not set # CONFIG_STM32F7_QUADSPI is not set # CONFIG_STM32F7_RNG is not set # CONFIG_STM32F7_SAI1 is not set # CONFIG_STM32F7_SAI2 is not set -CONFIG_STM32F7_SDMMC1=y +##CONFIG_STM32F7_SDMMC1=y # CONFIG_STM32F7_SPDIFRX is not set CONFIG_STM32F7_SPI1=y # CONFIG_STM32F7_SPI2 is not set @@ -434,7 +434,7 @@ CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_PWMTEST is not set # CONFIG_BOARDCTL_GRAPHICS is not set # CONFIG_BOARDCTL_IOCTL is not set -##CONFIG_BOARDCTL_USBDEVCTRL=y +CONFIG_BOARDCTL_USBDEVCTRL=y # # RTOS Features @@ -690,7 +690,7 @@ CONFIG_USART6_2STOP=0 # CONFIG_USART6_IFLOWCONTROL is not set # CONFIG_USART6_OFLOWCONTROL is not set # CONFIG_USART6_DMA is not set -##CONFIG_USBDEV=y +CONFIG_USBDEV=y # CONFIG_USBHOST is not set # CONFIG_DRIVERS_WIRELESS is not set @@ -700,9 +700,9 @@ CONFIG_USART6_2STOP=0 # # CONFIG_USBDEV_ISOCHRONOUS is not set # CONFIG_USBDEV_DUALSPEED is not set -##CONFIG_USBDEV_SELFPOWERED=y +CONFIG_USBDEV_SELFPOWERED=y # CONFIG_USBDEV_BUSPOWERED is not set -##CONFIG_USBDEV_MAXPOWER=100 +CONFIG_USBDEV_MAXPOWER=100 # CONFIG_USBDEV_DMA is not set # CONFIG_ARCH_USBDEV_STALLQUEUE is not set # CONFIG_USBDEV_TRACE is not set @@ -712,27 +712,26 @@ CONFIG_USART6_2STOP=0 # # CONFIG_USBDEV_COMPOSITE is not set # CONFIG_PL2303 is not set -##CONFIG_CDCACM=y -##CONFIG_CDCACM_CONSOLE=y -##CONFIG_CDCACM_EP0MAXPACKET=64 -##CONFIG_CDCACM_EPINTIN=1 -##CONFIG_CDCACM_EPINTIN_FSSIZE=64 -##CONFIG_CDCACM_EPINTIN_HSSIZE=64 -##CONFIG_CDCACM_EPBULKOUT=3 -##CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 -##CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 -##CONFIG_CDCACM_EPBULKIN=2 -##CONFIG_CDCACM_EPBULKIN_FSSIZE=64 -##CONFIG_CDCACM_EPBULKIN_HSSIZE=512 -##CONFIG_CDCACM_NRDREQS=4 -##CONFIG_CDCACM_NWRREQS=4 -##CONFIG_CDCACM_BULKIN_REQLEN=96 -##CONFIG_CDCACM_RXBUFSIZE=256 -##CONFIG_CDCACM_TXBUFSIZE=256 -##CONFIG_CDCACM_VENDORID=0x0525 -##CONFIG_CDCACM_PRODUCTID=0xa4a7 -##CONFIG_CDCACM_VENDORSTR="NuttX" -##CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" +CONFIG_CDCACM=y +CONFIG_CDCACM_EP0MAXPACKET=64 +CONFIG_CDCACM_EPINTIN=1 +CONFIG_CDCACM_EPINTIN_FSSIZE=64 +CONFIG_CDCACM_EPINTIN_HSSIZE=64 +CONFIG_CDCACM_EPBULKOUT=2 +CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 +CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 +CONFIG_CDCACM_EPBULKIN=2 +CONFIG_CDCACM_EPBULKIN_FSSIZE=64 +CONFIG_CDCACM_EPBULKIN_HSSIZE=512 +CONFIG_CDCACM_NRDREQS=4 +CONFIG_CDCACM_NWRREQS=4 +CONFIG_CDCACM_BULKIN_REQLEN=96 +CONFIG_CDCACM_RXBUFSIZE=256 +CONFIG_CDCACM_TXBUFSIZE=256 +CONFIG_CDCACM_VENDORID=0x03EB +CONFIG_CDCACM_PRODUCTID=0x2044 +CONFIG_CDCACM_VENDORSTR="NuttX" +CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" # CONFIG_USBMSC is not set # CONFIG_USBHOST is not set # CONFIG_DRIVERS_WIRELESS is not set @@ -1128,3 +1127,6 @@ CONFIG_READLINE_ECHO=y # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set + +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_CDCACM_DEVMINOR=0 From 1905cb94a09d9f1d7cb8e247691382f817277c00 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Tue, 27 Sep 2016 16:43:41 +0200 Subject: [PATCH 010/155] to uinfo --- configs/stm32f746-ws/src/stm32_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/stm32f746-ws/src/stm32_usb.c b/configs/stm32f746-ws/src/stm32_usb.c index b81aacd6ca..d0c118af89 100644 --- a/configs/stm32f746-ws/src/stm32_usb.c +++ b/configs/stm32f746-ws/src/stm32_usb.c @@ -333,7 +333,7 @@ xcpt_t stm32_setup_overcurrent(xcpt_t handler) #ifdef CONFIG_USBDEV void stm32_usbsuspend(FAR struct usbdev_s *dev, bool resume) { - ullinfo("resume: %d\n", resume); + uinfo("resume: %d\n", resume); } #endif From 9b7341b670194815d09713025c85cb2113b7d878 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Tue, 27 Sep 2016 16:47:49 +0200 Subject: [PATCH 011/155] ignore eclipse .project --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3ec700458d..839c74cb5e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ cscope.out /*.hex /pcode /tags +.cproject +.project \ No newline at end of file From 1cbd7a0e5972ee6bf4d5fb04613de0278a494fd2 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 30 Sep 2016 16:00:18 +0200 Subject: [PATCH 012/155] CONFIG_ARCH_IRQPRIO check --- arch/arm/src/stm32f7/stm32_sdmmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 3e6aff9620..9fa8d00b07 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -113,7 +113,7 @@ #endif #ifdef CONFIG_STM32F7_SDMMC1 -# ifndef CONFIG_SDMMC1_PRI +# if defined(CONFIG_ARCH_IRQPRIO) && !defined(CONFIG_SDMMC1_PRI) # define CONFIG_SDMMC1_PRI NVIC_SYSH_PRIORITY_DEFAULT # endif @@ -130,7 +130,7 @@ #endif #ifdef CONFIG_STM32F7_SDMMC2 -# ifndef CONFIG_SDMMC2_PRI +# if defined(CONFIG_ARCH_IRQPRIO) && !defined(CONFIG_SDMMC2_PRI) # define CONFIG_SDMMC2_PRI NVIC_SYSH_PRIORITY_DEFAULT # endif From 4cb1ba493b64eb567e7b33261e4df18c15d55cfb Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 30 Sep 2016 16:00:28 +0200 Subject: [PATCH 013/155] mmc renames --- configs/stm32f746-ws/include/board.h | 10 +++++----- configs/stm32f746-ws/nsh/defconfig | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/configs/stm32f746-ws/include/board.h b/configs/stm32f746-ws/include/board.h index ea5072ce20..17ca38417e 100644 --- a/configs/stm32f746-ws/include/board.h +++ b/configs/stm32f746-ws/include/board.h @@ -274,16 +274,16 @@ * SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(118+2)=400 KHz */ -#define SDMMC1_INIT_CLKDIV (118 << SDIO_CLKCR_CLKDIV_SHIFT) +#define STM32_SDMMC_INIT_CLKDIV (118 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) /* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz * DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz */ #ifdef CONFIG_SDIO_DMA -# define SDMMC1_MMCXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_MMCXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else -# define SDMMC1_MMCXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_MMCXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif /* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz @@ -291,9 +291,9 @@ */ #ifdef CONFIG_SDIO_DMA -# define SDMMC1_SDXFR_CLKDIV (1 << SDIO_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_SDXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else -# define SDMMC1_SDXFR_CLKDIV (2 << SDIO_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_SDXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif /************************************************************************************ diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index c9598479e3..6fafd45558 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -312,7 +312,7 @@ CONFIG_STM32F7_OTGFS=y # CONFIG_STM32F7_RNG is not set # CONFIG_STM32F7_SAI1 is not set # CONFIG_STM32F7_SAI2 is not set -##CONFIG_STM32F7_SDMMC1=y +CONFIG_STM32F7_SDMMC1=y # CONFIG_STM32F7_SPDIFRX is not set CONFIG_STM32F7_SPI1=y # CONFIG_STM32F7_SPI2 is not set From 33cea5038f516d1b2bf57fe3badbafb6b3069d29 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Sat, 1 Oct 2016 19:38:43 +0200 Subject: [PATCH 014/155] memory corruption, typo addr-value --- arch/arm/src/stm32f7/stm32_otgdev.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c index f06175cb5b..54a0232cdf 100644 --- a/arch/arm/src/stm32f7/stm32_otgdev.c +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -4230,7 +4230,10 @@ static void stm32_epin_disable(FAR struct stm32_ep_s *privep) /* Clear the EPDISD interrupt indication */ - stm32_putreg(OTG_DIEPINT_EPDISD, stm32_getreg(regaddr)); + regval = stm32_getreg(regaddr); + regval |= OTG_DIEPINT_EPDISD; + stm32_putreg(OTG_DIEPINT_EPDISD, regaddr); + /* Flush any data remaining in the TxFIFO */ From a196f2968c9fe8697ca58717bb1ee56008055108 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Sat, 1 Oct 2016 19:39:33 +0200 Subject: [PATCH 015/155] more stack size for Idle thread --- configs/stm32f746-ws/nsh/defconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index 6fafd45558..5c0a529820 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -312,7 +312,7 @@ CONFIG_STM32F7_OTGFS=y # CONFIG_STM32F7_RNG is not set # CONFIG_STM32F7_SAI1 is not set # CONFIG_STM32F7_SAI2 is not set -CONFIG_STM32F7_SDMMC1=y +##CONFIG_STM32F7_SDMMC1=y # CONFIG_STM32F7_SPDIFRX is not set CONFIG_STM32F7_SPI1=y # CONFIG_STM32F7_SPI2 is not set @@ -416,7 +416,7 @@ CONFIG_BOARD_LOOPSPERMSEC=43103 # Interrupt options # CONFIG_ARCH_HAVE_INTERRUPTSTACK=y -CONFIG_ARCH_INTERRUPTSTACK=600 +CONFIG_ARCH_INTERRUPTSTACK=2600 CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y # CONFIG_ARCH_HIPRI_INTERRUPT is not set @@ -571,7 +571,7 @@ CONFIG_SCHED_LPWORKSTACKSIZE=1800 # # Stack and heap information # -CONFIG_IDLETHREAD_STACKSIZE=500 +CONFIG_IDLETHREAD_STACKSIZE=2500 CONFIG_USERMAIN_STACKSIZE=2500 CONFIG_PTHREAD_STACK_MIN=512 CONFIG_PTHREAD_STACK_DEFAULT=2048 From a2e4c0e898734ea78a9f22975aeea7eee0e38362 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 7 Oct 2016 15:12:34 +0200 Subject: [PATCH 016/155] i2s rcc typo fix --- arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c b/arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c index aac857b9c3..10e4fe2bb5 100644 --- a/arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c +++ b/arch/arm/src/stm32f7/stm32f74xx75xx_rcc.c @@ -882,10 +882,10 @@ static void stm32_stdclockconfig(void) | RCC_PLLI2SCFGR_PLLI2SP_MASK | RCC_PLLI2SCFGR_PLLI2SQ_MASK | RCC_PLLI2SCFGR_PLLI2SR_MASK); - regval |= (STM32_RCC_PLLSAICFGR_PLLSAIN - | STM32_RCC_PLLSAICFGR_PLLSAIP - | STM32_RCC_PLLSAICFGR_PLLSAIQ - | STM32_RCC_PLLSAICFGR_PLLSAIR); + regval |= (STM32_RCC_PLLI2SCFGR_PLLI2SN + | STM32_RCC_PLLI2SCFGR_PLLI2SP + | STM32_RCC_PLLI2SCFGR_PLLI2SQ + | STM32_RCC_PLLI2SCFGR_PLLI2SR); putreg32(regval, STM32_RCC_PLLI2SCFGR); regval = getreg32(STM32_RCC_DCKCFGR2); From fd92f01f556fbe5cf24365aa153af104469441e1 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 7 Oct 2016 15:12:46 +0200 Subject: [PATCH 017/155] exact values for i2c clock --- arch/arm/src/stm32f7/stm32_i2c.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_i2c.c b/arch/arm/src/stm32f7/stm32_i2c.c index 3786e7d52c..8d5e4db7c0 100644 --- a/arch/arm/src/stm32f7/stm32_i2c.c +++ b/arch/arm/src/stm32f7/stm32_i2c.c @@ -1306,17 +1306,17 @@ static void stm32_i2c_setclock(FAR struct stm32_i2c_priv_s *priv, uint32_t frequ if (frequency == 100000) { presc = 0; - scl_delay = 3; + scl_delay = 5; sda_delay = 0; - scl_h_period = 30; - scl_l_period = 120; + scl_h_period = 61; + scl_l_period = 89; } else if (frequency == 400000) { presc = 0; scl_delay = 3; - sda_delay = 9; + sda_delay = 0; scl_h_period = 6; scl_l_period = 24; } From 74284aec14ab5824f2a76497fe72aae40cac9b81 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 7 Oct 2016 15:13:07 +0200 Subject: [PATCH 018/155] enable i2c clock config --- configs/stm32f746-ws/include/board.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/stm32f746-ws/include/board.h b/configs/stm32f746-ws/include/board.h index 17ca38417e..8cbd85bc92 100644 --- a/configs/stm32f746-ws/include/board.h +++ b/configs/stm32f746-ws/include/board.h @@ -144,7 +144,7 @@ /* Configure factors for PLLI2S clock */ - +#define CONFIG_STM32F7_PLLI2S 1 #define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192) #define STM32_RCC_PLLI2SCFGR_PLLI2SP RCC_PLLI2SCFGR_PLLI2SP(2) #define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2) From bd08646768ab324fd220cdcf59ea7e385089c824 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 7 Oct 2016 15:18:20 +0200 Subject: [PATCH 019/155] enable PLLSAI --- configs/stm32f746-ws/include/board.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/stm32f746-ws/include/board.h b/configs/stm32f746-ws/include/board.h index 8cbd85bc92..65a27fc6b7 100644 --- a/configs/stm32f746-ws/include/board.h +++ b/configs/stm32f746-ws/include/board.h @@ -124,7 +124,7 @@ /* Configure factors for PLLSAI clock */ - +#define CONFIG_STM32F7_PLLSAI 1 #define STM32_RCC_PLLSAICFGR_PLLSAIN RCC_PLLSAICFGR_PLLSAIN(192) #define STM32_RCC_PLLSAICFGR_PLLSAIP RCC_PLLSAICFGR_PLLSAIP(2) #define STM32_RCC_PLLSAICFGR_PLLSAIQ RCC_PLLSAICFGR_PLLSAIQ(2) From 9e3479555db056bb8c2c2f6868d9a6b4e5ae4b5b Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 7 Oct 2016 15:47:30 +0200 Subject: [PATCH 020/155] usb set value typo --- arch/arm/src/stm32f7/stm32_otgdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c index 54a0232cdf..694cf713a8 100644 --- a/arch/arm/src/stm32f7/stm32_otgdev.c +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -4232,7 +4232,7 @@ static void stm32_epin_disable(FAR struct stm32_ep_s *privep) regval = stm32_getreg(regaddr); regval |= OTG_DIEPINT_EPDISD; - stm32_putreg(OTG_DIEPINT_EPDISD, regaddr); + stm32_putreg(regval, regaddr); /* Flush any data remaining in the TxFIFO */ From 6ff1c96017f0abc891d9a700c744dfc5b0718d4d Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Mon, 31 Oct 2016 18:41:36 -0600 Subject: [PATCH 021/155] LM32: First commit adds only reviewed architecture header files --- arch/Kconfig | 9 ++ arch/misoc/include/arch.h | 0 arch/misoc/include/irq.h | 80 ++++++++++++ arch/misoc/include/limits.h | 88 +++++++++++++ arch/misoc/include/lm32/irq.h | 193 ++++++++++++++++++++++++++++ arch/misoc/include/lm32/syscall.h | 207 ++++++++++++++++++++++++++++++ arch/misoc/include/lm32/types.h | 94 ++++++++++++++ arch/misoc/include/syscall.h | 88 +++++++++++++ arch/misoc/include/types.h | 94 ++++++++++++++ 9 files changed, 853 insertions(+) create mode 100644 arch/misoc/include/arch.h create mode 100644 arch/misoc/include/irq.h create mode 100644 arch/misoc/include/limits.h create mode 100644 arch/misoc/include/lm32/irq.h create mode 100644 arch/misoc/include/lm32/syscall.h create mode 100644 arch/misoc/include/lm32/types.h create mode 100644 arch/misoc/include/syscall.h create mode 100644 arch/misoc/include/types.h diff --git a/arch/Kconfig b/arch/Kconfig index 32ecb06410..0125994830 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -39,6 +39,13 @@ config ARCH_MIPS ---help--- MIPS architectures (PIC32) +config ARCH_MISOC + bool "MISOC" + select ARCH_HAVE_INTERRUPTSTACK + select ARCH_HAVE_CUSTOMOPT + ---help--- + MISOC + config ARCH_RGMP bool "RGMP" ---help--- @@ -99,6 +106,7 @@ config ARCH default "avr" if ARCH_AVR default "hc" if ARCH_HC default "mips" if ARCH_MIPS + default "misoc" if ARCH_MISOC default "rgmp" if ARCH_RGMP default "renesas" if ARCH_RENESAS default "risc-v" if ARCH_RISCV @@ -112,6 +120,7 @@ source arch/arm/Kconfig source arch/avr/Kconfig source arch/hc/Kconfig source arch/mips/Kconfig +source arch/misoc/Kconfig source arch/rgmp/Kconfig source arch/renesas/Kconfig source arch/risc-v/Kconfig diff --git a/arch/misoc/include/arch.h b/arch/misoc/include/arch.h new file mode 100644 index 0000000000..e69de29bb2 diff --git a/arch/misoc/include/irq.h b/arch/misoc/include/irq.h new file mode 100644 index 0000000000..1fbf884fc3 --- /dev/null +++ b/arch/misoc/include/irq.h @@ -0,0 +1,80 @@ +/**************************************************************************** + * arch/misoc/include/irq.h + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through nuttx/irq.h + */ + +#ifndef __ARCH_MISOC_INCLUDE_IRQ_H +#define __ARCH_MISOC_INCLUDE_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define NR_IRQS 32 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +irqstate_t up_irq_save(void); +void up_irq_restore(irqstate_t flags); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_MISOC_INCLUDE_IRQ_H */ diff --git a/arch/misoc/include/limits.h b/arch/misoc/include/limits.h new file mode 100644 index 0000000000..12dd86efb2 --- /dev/null +++ b/arch/misoc/include/limits.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/misoc/include/limits.h + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +#ifndef __ARCH_MISOC_INCLUDE_LIMITS_H +#define __ARCH_MISOC_INCLUDE_LIMITS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CHAR_BIT 8 +#define SCHAR_MIN (-SCHAR_MAX - 1) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +/* These could be different on machines where char is unsigned */ + +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-SHRT_MAX - 1) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535U + +/* Integer is four bytes */ + +#define INT_MIN (-INT_MAX - 1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +/* These change on 32-bit and 64-bit platforms */ + +#define LONG_MIN (-LONG_MAX - 1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#define LLONG_MIN (-LLONG_MAX - 1) +#define LLONG_MAX 9223372036854775807LL +#define ULLONG_MAX 18446744073709551615ULL + +/* A pointer is four bytes */ + +#define PTR_MIN (-PTR_MAX - 1) +#define PTR_MAX 2147483647 +#define UPTR_MAX 4294967295U + +#endif /* __ARCH_MISOC_INCLUDE_LIMITS_H */ diff --git a/arch/misoc/include/lm32/irq.h b/arch/misoc/include/lm32/irq.h new file mode 100644 index 0000000000..a98bcab8e3 --- /dev/null +++ b/arch/misoc/include/lm32/irq.h @@ -0,0 +1,193 @@ +/**************************************************************************** + * arch/misoc/include/lm32/syscall.h + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +#ifndef __ARCH_MISOC_INCLUDE_LM32_IRQ_H +#define __ARCH_MISOC_INCLUDE_LM32_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Registers */ + +#define REG_X0_NDX 0 /* Holds the value zero */ +#define REG_X1_NDX 1 /* General-purpose/argument 0/return value 0 */ +#define REG_X2_NDX 2 /* General-purpose/argument 1/return value 1 */ +#define REG_X3_NDX 3 /* General-purpose/argument 2 */ +#define REG_X4_NDX 4 /* General-purpose/argument 3 */ +#define REG_X5_NDX 5 /* General-purpose/argument 4 */ +#define REG_X6_NDX 6 /* General-purpose/argument 5 */ +#define REG_X7_NDX 7 /* General-purpose/argument 6 */ +#define REG_X8_NDX 8 /* General-purpose/argument 7 */ +#define REG_X9_NDX 9 /* General-purpose */ +#define REG_X10_NDX 10 /* General-purpose */ +#define REG_X11_NDX 11 /* General-purpose */ +#define REG_X12_NDX 12 /* General-purpose */ +#define REG_X13_NDX 13 /* General-purpose */ +#define REG_X14_NDX 14 /* General-purpose */ +#define REG_X15_NDX 15 /* General-purpose */ +#define REG_X16_NDX 16 /* General-purpose */ +#define REG_X17_NDX 17 /* General-purpose */ +#define REG_X18_NDX 18 /* General-purpose */ +#define REG_X19_NDX 19 /* General-purpose */ +#define REG_X20_NDX 20 /* General-purpose */ +#define REG_X21_NDX 21 /* General-purpose */ +#define REG_X22_NDX 22 /* General-purpose */ +#define REG_X23_NDX 23 /* General-purpose */ +#define REG_X24_NDX 24 /* General-purpose */ +#define REG_X25_NDX 25 /* General-purpose */ +#define REG_X26_NDX 26 /* General-purpose/global pointer */ +#define REG_X27_NDX 27 /* General-purpose/frame pointer */ +#define REG_X28_NDX 28 /* Stack pointer */ +#define REG_X29_NDX 29 /* General-purpose/return address */ +#define REG_X30_NDX 30 /* Exception address */ +#define REG_X31_NDX 31 /* Breakpoint address */ + +/* Interrupt Context register */ + +#define XCPTCONTEXT_REGS 32 +#define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) + +#ifdef __ASSEMBLY__ +# define REG_X0 (4*REG_X0_NDX) +# define REG_X1 (4*REG_X1_NDX) +# define REG_X2 (4*REG_X2_NDX) +# define REG_X3 (4*REG_X3_NDX) +# define REG_X4 (4*REG_X4_NDX) +# define REG_X5 (4*REG_X5_NDX) +# define REG_X6 (4*REG_X6_NDX) +# define REG_X7 (4*REG_X7_NDX) +# define REG_X8 (4*REG_X8_NDX) +# define REG_X9 (4*REG_X9_NDX) +# define REG_X10 (4*REG_X10_NDX) +# define REG_X11 (4*REG_X11_NDX) +# define REG_X12 (4*REG_X12_NDX) +# define REG_X13 (4*REG_X13_NDX) +# define REG_X14 (4*REG_X14_NDX) +# define REG_X15 (4*REG_X15_NDX) +# define REG_X16 (4*REG_X16_NDX) +# define REG_X17 (4*REG_X17_NDX) +# define REG_X18 (4*REG_X18_NDX) +# define REG_X19 (4*REG_X19_NDX) +# define REG_X20 (4*REG_X20_NDX) +# define REG_X21 (4*REG_X21_NDX) +# define REG_X22 (4*REG_X22_NDX) +# define REG_X23 (4*REG_X23_NDX) +# define REG_X24 (4*REG_X24_NDX) +# define REG_X25 (4*REG_X25_NDX) +# define REG_X26 (4*REG_X26_NDX) +# define REG_X27 (4*REG_X27_NDX) +# define REG_X28 (4*REG_X28_NDX) +# define REG_X29 (4*REG_X29_NDX) +# define REG_X30 (4*REG_X30_NDX) +# define REG_X31 (4*REG_X31_NDX) +#else +# define REG_X0 REG_X0_NDX +# define REG_X1 REG_X1_NDX +# define REG_X2 REG_X2_NDX +# define REG_X3 REG_X3_NDX +# define REG_X4 REG_X4_NDX +# define REG_X5 REG_X5_NDX +# define REG_X6 REG_X6_NDX +# define REG_X7 REG_X7_NDX +# define REG_X8 REG_X8_NDX +# define REG_X9 REG_X9_NDX +# define REG_X10 REG_X10_NDX +# define REG_X11 REG_X11_NDX +# define REG_X12 REG_X12_NDX +# define REG_X13 REG_X13_NDX +# define REG_X14 REG_X14_NDX +# define REG_X15 REG_X15_NDX +# define REG_X16 REG_X16_NDX +# define REG_X17 REG_X17_NDX +# define REG_X18 REG_X18_NDX +# define REG_X19 REG_X19_NDX +# define REG_X20 REG_X20_NDX +# define REG_X21 REG_X21_NDX +# define REG_X22 REG_X22_NDX +# define REG_X23 REG_X23_NDX +# define REG_X24 REG_X24_NDX +# define REG_X25 REG_X25_NDX +# define REG_X26 REG_X26_NDX +# define REG_X27 REG_X27_NDX +# define REG_X28 REG_X28_NDX +# define REG_X29 REG_X29_NDX +# define REG_X30 REG_X30_NDX +# define REG_X31 REG_X31_NDX +#endif + +/* Register aliases */ + +#define REG_GP REG_X26 +#define REG_FP REG_X27 +#define REG_SP REG_X28 +#define REG_RA REG_X29 +#define REG_EA REG_X30 +#define REG_BA REG_X31 + +#define REG_EPC REG_X30 + +#define REG_A0 REG_X1 +#define REG_A1 REG_X2 +#define REG_A2 REG_X3 +#define REG_A3 REG_X4 +#define REG_A4 REG_X5 +#define REG_A5 REG_X6 +#define REG_A6 REG_X7 +#define REG_A7 REG_X8 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +struct xcptcontext +{ + /* Register save area */ + + uint32_t regs[XCPTCONTEXT_REGS]; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_MISOC_INCLUDE_LM32_IRQ_H */ diff --git a/arch/misoc/include/lm32/syscall.h b/arch/misoc/include/lm32/syscall.h new file mode 100644 index 0000000000..7c0c2b1066 --- /dev/null +++ b/arch/misoc/include/lm32/syscall.h @@ -0,0 +1,207 @@ +/**************************************************************************** + * arch/misoc/include/lm32/syscall.h + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_MISOC_INCLUDE_LM32_SYSCALL_H +#define __ARCH_MISOC_INCLUDE_LM32_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define SYS_syscall 0x00 + +/* Configuration ********************************************************************/ +/* SYS call 1 and 2 are defined for internal use by the RISC-V port (see + * arch/riscv/include/mips32/syscall.h). In addition, SYS call 3 is the return from + * a SYS call in kernel mode. The first four syscall values must, therefore, be + * reserved (0 is not used). + */ + +#ifdef CONFIG_BUILD_KERNEL +# ifndef CONFIG_SYS_RESERVED +# error "CONFIG_SYS_RESERVED must be defined to the value 4" +# elif CONFIG_SYS_RESERVED != 4 +# error "CONFIG_SYS_RESERVED must have the value 4" +# endif +#endif + +/* sys_call macros ******************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Context switching system calls ***************************************************/ + +/* SYS call 0: (not used) */ + +/* SYS call 1: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + */ + +#define SYS_restore_context (1) +#define up_fullcontextrestore(restoreregs) \ + (void)sys_call1(SYS_restore_context, (uintptr_t)restoreregs) + +/* SYS call 2: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + */ + +#define SYS_switch_context (2) +#define up_switchcontext(saveregs, restoreregs) \ + (void)sys_call2(SYS_switch_context, (uintptr_t)saveregs, (uintptr_t)restoreregs) + +#ifdef CONFIG_BUILD_KERNEL +/* SYS call 3: + * + * void up_syscall_return(void); + */ + +#define SYS_syscall_return (3) +#define up_syscall_return() (void)sys_call0(SYS_syscall_return) + +#endif +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: up_syscall0 + * + * Description: + * System call SYS_ argument and no additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call0(unsigned int nbr); + +/**************************************************************************** + * Name: up_syscall1 + * + * Description: + * System call SYS_ argument and one additional parameter. + * + ****************************************************************************/ + +uintptr_t sys_call1(unsigned int nbr, uintptr_t parm1); + +/**************************************************************************** + * Name: up_syscall2 + * + * Description: + * System call SYS_ argument and two additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call2(unsigned int nbr, uintptr_t parm1, uintptr_t parm2); + +/**************************************************************************** + * Name: up_syscall3 + * + * Description: + * System call SYS_ argument and three additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call3(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3); + +/**************************************************************************** + * Name: up_syscall4 + * + * Description: + * System call SYS_ argument and four additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call4(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3, uintptr_t parm4); + +/**************************************************************************** + * Name: up_syscall5 + * + * Description: + * System call SYS_ argument and five additional parameters. + * + ****************************************************************************/ + +uintptr_t sys_call5(unsigned int nbr, uintptr_t parm1, uintptr_t parm2, + uintptr_t parm3, uintptr_t parm4, uintptr_t parm5); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MISOC_INCLUDE_LM32_SYSCALL_H */ diff --git a/arch/misoc/include/lm32/types.h b/arch/misoc/include/lm32/types.h new file mode 100644 index 0000000000..dbaaff28d2 --- /dev/null +++ b/arch/misoc/include/lm32/types.h @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/misoc/include/lm32/types.h + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through stdint.h + */ + +#ifndef __ARCH_MISOC_INCLUDE_LM32_TYPES_H +#define __ARCH_MISOC_INCLUDE_LM32_TYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save(). */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_MISOC_INCLUDE_LM32_TYPES_H */ diff --git a/arch/misoc/include/syscall.h b/arch/misoc/include/syscall.h new file mode 100644 index 0000000000..3a8f2e9df0 --- /dev/null +++ b/arch/misoc/include/syscall.h @@ -0,0 +1,88 @@ +/**************************************************************************** + * arch/misoc/include/syscall.h + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through include/syscall.h or include/sys/sycall.h + */ + +#ifndef __ARCH_MISOC_INCLUDE_SYSCALL_H +#define __ARCH_MISOC_INCLUDE_SYSCALL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/* Include RISC-V architecture-specific syscall macros */ + +#ifdef CONFIG_ARCH_MISOC +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Inline functions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifndef __ASSEMBLY__ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif + +#endif /* __ARCH_MISOC_INCLUDE_SYSCALL_H */ diff --git a/arch/misoc/include/types.h b/arch/misoc/include/types.h new file mode 100644 index 0000000000..f63ab15f19 --- /dev/null +++ b/arch/misoc/include/types.h @@ -0,0 +1,94 @@ +/**************************************************************************** + * arch/misoc/include/types.h + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +/* This file should never be included directed but, rather, only indirectly + * through stdint.h + */ + +#ifndef __ARCH_MISOC_INCLUDE_TYPESL_H +#define __ARCH_MISOC_INCLUDE_TYPESL_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Type Declarations + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* These are the sizes of the standard integer types. NOTE that these type + * names have a leading underscore character. This file will be included + * (indirectly) by include/stdint.h and typedef'ed to the final name without + * the underscore character. This roundabout way of doings things allows + * the stdint.h to be removed from the include/ directory in the event that + * the user prefers to use the definitions provided by their toolchain header + * files + */ + +typedef signed char _int8_t; +typedef unsigned char _uint8_t; + +typedef signed short _int16_t; +typedef unsigned short _uint16_t; + +typedef signed int _int32_t; +typedef unsigned int _uint32_t; + +typedef signed long long _int64_t; +typedef unsigned long long _uint64_t; +#define __INT64_DEFINED + +/* A pointer is 4 bytes */ + +typedef signed int _intptr_t; +typedef unsigned int _uintptr_t; + +/* This is the size of the interrupt state save returned by up_irq_save(). */ + +typedef unsigned int irqstate_t; + +#endif /* __ASSEMBLY__ */ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#endif /* __ARCH_MISOC_INCLUDE_TYPESL_H */ From 6662c75679a7e5b03b9076c24cdfe5c8267f8e70 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 31 Oct 2016 19:29:30 -0600 Subject: [PATCH 022/155] LM32: Add arch/misoc/Kconfig file --- arch/misoc/Kconfig | 64 +++++++++++++++++++++++++++++++++++ arch/misoc/include/lm32/irq.h | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 arch/misoc/Kconfig diff --git a/arch/misoc/Kconfig b/arch/misoc/Kconfig new file mode 100644 index 0000000000..7f3ae0dab4 --- /dev/null +++ b/arch/misoc/Kconfig @@ -0,0 +1,64 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_MISOC + +choice + prompt "Misoc Chip Selection" + default ARCH_CHIP_LM32 + +config ARCH_CHIP_LM32 + bool "LM32" + select MISOC_HAVE_UART0 + ---help--- + LM32 Chip Selected + +config ARCH_CHIP_MOR1K + bool "MOR1K" + ---help--- + MOR1K Chip Selected + +endchoice # Misoc Chip Selection + +config ARCH_CHIP + string + default "lm32" if ARCH_CHIP_LM32 + +menu "MISOC Peripheral Support" + +# These "hidden" settings determine is a peripheral option is available for the +# selection MCU + +config MISOC_HAVE_UART0 + bool + default n + select UART0_SERIALDRIVER + +config MISOC_UART0 + bool "UART0" + default n + select ARCH_HAVE_UART0 + select MISOC_UART + +endmenu # MISOC Peripheral Support + +config MISOC_UART + bool + +config MISOC_UART_RX_BUF_SIZE + int "UART RX Bufer size" + default 64 + depends on MISOC_UART + ---help--- + Size of RX buffers for MISOC UARTs + +config MISOC_UART_TX_BUF_SIZE + int "UART TX Bufer size" + default 64 + depends on MISOC_UART + ---help--- + Size of TX buffers for MISOC UARTs + +endif # ARCH_MISOC diff --git a/arch/misoc/include/lm32/irq.h b/arch/misoc/include/lm32/irq.h index a98bcab8e3..f12fcb7db6 100644 --- a/arch/misoc/include/lm32/irq.h +++ b/arch/misoc/include/lm32/irq.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/misoc/include/lm32/syscall.h + * arch/misoc/include/lm32/irq.h * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt From 6a78c0f1130a9c314aa00d7a5c2531ffe8d00ab0 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Tue, 1 Nov 2016 07:20:44 -0600 Subject: [PATCH 023/155] LM32: Add Kconfig files --- arch/misoc/Kconfig | 9 ++ arch/misoc/include/lm32/irq.h | 1 + arch/misoc/include/lm32/syscall.h | 1 + arch/misoc/include/lm32/types.h | 1 + arch/misoc/src/Makefile | 189 ++++++++++++++++++++++++++++++ arch/misoc/src/common/Kconfig | 8 ++ arch/misoc/src/lm32/Kconfig | 8 ++ 7 files changed, 217 insertions(+) create mode 100644 arch/misoc/src/Makefile create mode 100644 arch/misoc/src/common/Kconfig create mode 100644 arch/misoc/src/lm32/Kconfig diff --git a/arch/misoc/Kconfig b/arch/misoc/Kconfig index 7f3ae0dab4..74a2a7649b 100644 --- a/arch/misoc/Kconfig +++ b/arch/misoc/Kconfig @@ -25,6 +25,7 @@ endchoice # Misoc Chip Selection config ARCH_CHIP string default "lm32" if ARCH_CHIP_LM32 + default "mor1k" if ARCH_CHIP_MOR1K menu "MISOC Peripheral Support" @@ -61,4 +62,12 @@ config MISOC_UART_TX_BUF_SIZE ---help--- Size of TX buffers for MISOC UARTs +source arch/misoc/src/common/Kconfig +ifdef ARCH_CHIP_LM32 +source arch/misoc/src/lm32/Kconfig +endif +ifdef ARCH_CHIP_MOR1K +source arch/misoc/src/mor1k/Kconfig +endif + endif # ARCH_MISOC diff --git a/arch/misoc/include/lm32/irq.h b/arch/misoc/include/lm32/irq.h index f12fcb7db6..e73d3815d5 100644 --- a/arch/misoc/include/lm32/irq.h +++ b/arch/misoc/include/lm32/irq.h @@ -3,6 +3,7 @@ * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt + * Ramtin Amin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/arch/misoc/include/lm32/syscall.h b/arch/misoc/include/lm32/syscall.h index 7c0c2b1066..9e4b0d9ee0 100644 --- a/arch/misoc/include/lm32/syscall.h +++ b/arch/misoc/include/lm32/syscall.h @@ -3,6 +3,7 @@ * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt + * Ramtin Amin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/arch/misoc/include/lm32/types.h b/arch/misoc/include/lm32/types.h index dbaaff28d2..0e113100f9 100644 --- a/arch/misoc/include/lm32/types.h +++ b/arch/misoc/include/lm32/types.h @@ -3,6 +3,7 @@ * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt + * Ramtin Amin * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/arch/misoc/src/Makefile b/arch/misoc/src/Makefile new file mode 100644 index 0000000000..6a92f22910 --- /dev/null +++ b/arch/misoc/src/Makefile @@ -0,0 +1,189 @@ +############################################################################ +# arch/misoc/src/Makefile +# +# Copyright (C) 2016 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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include chip/Make.defs + +ARCH_SUBDIR = lm32 + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + ARCH_SRCDIR = $(TOPDIR)\arch\$(CONFIG_ARCH)\src + NUTTX = "$(TOPDIR)\nuttx$(EXEEXT)" + INCLUDES += -I "$(ARCH_SRCDIR)\chip" + INCLUDES += -I "$(ARCH_SRCDIR)\common" + INCLUDES += -I "$(ARCH_SRCDIR)\generated" + INCLUDES += -I "$(ARCH_SRCDIR)\$(ARCH_SUBDIR)" + INCLUDES += -I "$(TOPDIR)\sched" +else + ARCH_SRCDIR = $(TOPDIR)/arch/$(CONFIG_ARCH)/src +ifeq ($(WINTOOL),y) + NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" + INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" + INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" + INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/generated}" + INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" + INCLUDES += -I "${shell cygpath -w $(TOPDIR)/sched}" +else + NUTTX = "$(TOPDIR)/nuttx$(EXEEXT)" + INCLUDES += -I "$(ARCH_SRCDIR)/chip" + INCLUDES += -I "$(ARCH_SRCDIR)/common" + INCLUDES += -I "$(ARCH_SRCDIR)/generated" + INCLUDES += -I "$(ARCH_SRCDIR)/$(ARCH_SUBDIR)" + INCLUDES += -I "$(TOPDIR)/sched" +endif +endif + +CPPFLAGS += $(INCLUDES) $(EXTRADEFINES) +CFLAGS += $(INCLUDES) $(EXTRADEFINES) +CXXFLAGS += $(INCLUDES) $(EXTRADEFINES) +AFLAGS += $(INCLUDES) $(EXTRADEFINES) + +HEAD_OBJ = $(HEAD_ASRC:.S=$(OBJEXT)) +STARTUP_OBJS ?= $(HEAD_OBJ) + +ASRCS = $(CHIP_ASRCS) $(CMN_ASRCS) +AOBJS = $(ASRCS:.S=$(OBJEXT)) + +CSRCS = $(CHIP_CSRCS) $(CMN_CSRCS) +COBJS = $(CSRCS:.c=$(OBJEXT)) + +SRCS = $(ASRCS) $(CSRCS) +OBJS = $(AOBJS) $(COBJS) + +# Override in Make.defs if linker is not 'ld' + +LDSTARTGROUP ?= --start-group +LDENDGROUP ?= --end-group + +LDFLAGS += $(ARCHSCRIPT) +EXTRA_LIBS ?= +LINKLIBS ?= + +ifeq ($(CONFIG_WINDOWS_NATIVE),y) + BOARDMAKE = $(if $(wildcard .\board\Makefile),y,) + LIBPATHS += -L"$(TOPDIR)\lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)\arch\$(CONFIG_ARCH)\src\board" +endif + +else + BOARDMAKE = $(if $(wildcard ./board/Makefile),y,) + +ifeq ($(WINTOOL),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/lib"}" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"${shell cygpath -w "$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board"}" +endif + +else + LIBPATHS += -L"$(TOPDIR)/lib" +ifeq ($(BOARDMAKE),y) + LIBPATHS += -L"$(TOPDIR)/arch/$(CONFIG_ARCH)/src/board" +endif +endif +endif + +LDLIBS = $(patsubst %.a,%,$(patsubst lib%,-l%,$(LINKLIBS))) +ifeq ($(BOARDMAKE),y) + LDLIBS += -lboard +endif + +LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" + +VPATH = chip:common:$(ARCH_SUBDIR) + +all: $(HEAD_OBJ) libarch$(LIBEXT) + +.PHONY: board/libboard$(LIBEXT) + +$(AOBJS) $(HEAD_OBJ): %$(OBJEXT): %.S + $(call ASSEMBLE, $<, $@) + +$(COBJS): %$(OBJEXT): %.c + $(call COMPILE, $<, $@) + +libarch$(LIBEXT): $(OBJS) + $(call ARCHIVE, $@, $(OBJS)) + +board/libboard$(LIBEXT): + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) + +nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) + @echo "LD: nuttx toto $(LIBGCC)" + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \ + $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LDENDGROUP) +ifneq ($(CONFIG_WINDOWS_NATIVE),y) + $(Q) $(NM) $(NUTTX) | \ + grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ + sort > $(TOPDIR)/System.map +endif + +# This is part of the top-level export target + +export_startup: board/libboard$(LIBEXT) $(STARTUP_OBJS) + $(Q) if [ -d "$(EXPORT_DIR)/startup" ]; then \ + cp -f $(STARTUP_OBJS) "$(EXPORT_DIR)/startup"; \ + else \ + echo "$(EXPORT_DIR)/startup does not exist"; \ + exit 1; \ + fi + +# Dependencies + +.depend: Makefile chip/Make.defs $(SRCS) +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" depend +endif + $(Q) $(MKDEP) --dep-path chip --dep-path common --dep-path $(ARCH_SUBDIR) \ + "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep + $(Q) touch $@ + +depend: .depend + +clean: +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" clean +endif + $(call DELFILE, libarch$(LIBEXT)) + $(call CLEAN) + +distclean: clean +ifeq ($(BOARDMAKE),y) + $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" distclean +endif + $(call DELFILE, Make.dep) + $(call DELFILE, .depend) + +-include Make.dep diff --git a/arch/misoc/src/common/Kconfig b/arch/misoc/src/common/Kconfig new file mode 100644 index 0000000000..6cd8cd8175 --- /dev/null +++ b/arch/misoc/src/common/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_MISOC + +endif # ARCH_MISOC diff --git a/arch/misoc/src/lm32/Kconfig b/arch/misoc/src/lm32/Kconfig new file mode 100644 index 0000000000..75814271c6 --- /dev/null +++ b/arch/misoc/src/lm32/Kconfig @@ -0,0 +1,8 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +if ARCH_CHIP_LM32 + +endif # ARCH_CHIP_LM32 From 62b394d06fc01cc211a9c2963b4a1fd389350104 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Tue, 1 Nov 2016 08:10:14 -0600 Subject: [PATCH 024/155] LM32: First of many LM32 source files --- arch/misoc/src/lm32/lm32.h | 173 ++++++++++++++++++++++++ arch/misoc/src/lm32/lm32_allocateheap.c | 104 ++++++++++++++ 2 files changed, 277 insertions(+) create mode 100644 arch/misoc/src/lm32/lm32.h create mode 100644 arch/misoc/src/lm32/lm32_allocateheap.c diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h new file mode 100644 index 0000000000..8335c6917d --- /dev/null +++ b/arch/misoc/src/lm32/lm32.h @@ -0,0 +1,173 @@ +/**************************************************************************** + * arch/misoc/src/common/lm32.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_COMMON_LM32_H +#define __ARCH_MISOC_SRC_COMMON_LM32_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifndef __ASSEMBLY__ +# include +# include +# include +#endif + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This is the value used to mark the stack for subsequent stack monitoring + * logic. + */ + +#define STACK_COLOR 0xdeadbeef +#define INTSTACK_COLOR 0xdeadbeef +#define HEAP_COLOR 'h' + +/* In the RISC_V model, the state is copied from the stack to the TCB, but + * only a referenced is passed to get the state from the TCB. + */ + +#define up_savestate(regs) lm32_copystate(regs, (uint32_t*)g_current_regs) +#define up_restorestate(regs) (g_current_regs = regs) + +/* Determine which (if any) console driver to use. If a console is enabled + * and no other console device is specified, then a serial console is + * assumed. + */ + +#if !defined(CONFIG_DEV_CONSOLE) || CONFIG_NFILE_DESCRIPTORS <= 0 +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# undef CONFIG_RAMLOG_CONSOLE +#else +# if defined(CONFIG_RAMLOG_CONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# undef CONFIG_DEV_LOWCONSOLE +# elif defined(CONFIG_DEV_LOWCONSOLE) +# undef USE_SERIALDRIVER +# undef USE_EARLYSERIALINIT +# else +# define USE_SERIALDRIVER 1 +# define USE_EARLYSERIALINIT 1 +# endif +#endif + +/* Low-level register access */ + +#define getreg8(a) (*(volatile uint8_t *)(a)) +#define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +#define getreg16(a) (*(volatile uint16_t *)(a)) +#define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +#define getreg32(a) (*(volatile uint32_t *)(a)) +#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern volatile uint32_t *g_current_regs; + +extern uint32_t g_idle_topstack; + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/* Low level initialization provided by board-level logic ******************/ + +void lm32_board_initialize(void); + +/* Memory allocation ********************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void lm32_add_region(void); +#endif + +/* Context switching ********************************************************/ + +void lm32_copystate(uint32_t *dest, uint32_t *src); + +/* IRQ initialization *******************************************************/ + +void lm32_irq_initialize(void); + +/* System timer *************************************************************/ + +void lm32_timer_initialize(void); +int lm32_timerisr(int irq, void *context); + +/* Software interrupts ******************************************************/ + +uint32_t lm32_swint(int irq, FAR void *context); + +/* Signal handling **********************************************************/ + +void lm32_sigdeliver(void); + +/* Atomic modification of registers *****************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); + +/* Debug ********************************************************************/ + +void lm32_dumpstate(void); + +#undef EXTERN +#ifdef __cplusplus +} +#endif +#endif /* __ASSEMBLY__ */ + +#endif /* __ARCH_MISOC_SRC_COMMON_LM32_H */ diff --git a/arch/misoc/src/lm32/lm32_allocateheap.c b/arch/misoc/src/lm32/lm32_allocateheap.c new file mode 100644 index 0000000000..4df88cecaf --- /dev/null +++ b/arch/misoc/src/lm32/lm32_allocateheap.c @@ -0,0 +1,104 @@ +/**************************************************************************** + * arch/misoc/src/common/lm32_allocateheap.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 + +#include "lm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_allocate_heap + * + * Description: + * This function will be called to dynamically set aside the heap region. + * + * For the kernel build (CONFIG_BUILD_KERNEL=y) with both kernel- and + * user-space heaps (CONFIG_MM_KERNEL_HEAP=y), this function provides the + * size of the unprotected, user-space heap. + * + * If a protected kernel-space heap is provided, the kernel heap must be + * allocated (and protected) by an analogous up_allocate_kheap(). + * + ****************************************************************************/ + +void up_allocate_heap(FAR void **heap_start, size_t *heap_size) +{ + board_autoled_on(LED_HEAPALLOCATE); + *heap_start = (FAR void *)g_idle_topstack; + *heap_size = CONFIG_RAM_END - g_idle_topstack; +} + +/**************************************************************************** + * Name: lm32_add_region + * + * Description: + * Memory may be added in non-contiguous chunks. Additional chunks are + * added by calling this function. + * + ****************************************************************************/ + +#if CONFIG_MM_REGIONS > 1 +void lm32_add_region(void) +{ +#warning Missing logic +} +#endif From 000e10470c79ba5393a437ef4aa48af3b9466940 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Tue, 1 Nov 2016 11:35:27 -0600 Subject: [PATCH 025/155] MISOC LM32: Add arch/src/lm32 directory --- arch/misoc/src/Makefile | 4 +- arch/misoc/src/common/misoc_isr.c | 20 ++ arch/misoc/src/common/misoc_uart.c | 141 +++++++++ arch/misoc/src/lm32/Make.defs | 49 +++ arch/misoc/src/lm32/lm32.h | 3 +- arch/misoc/src/lm32/lm32_allocateheap.c | 2 +- arch/misoc/src/lm32/lm32_assert.c | 162 ++++++++++ arch/misoc/src/lm32/lm32_blocktask.c | 180 +++++++++++ arch/misoc/src/lm32/lm32_copystate.c | 87 ++++++ arch/misoc/src/lm32/lm32_createstack.c | 214 +++++++++++++ arch/misoc/src/lm32/lm32_doirq.c | 147 +++++++++ arch/misoc/src/lm32/lm32_dumpstate.c | 228 ++++++++++++++ arch/misoc/src/lm32/lm32_exit.c | 82 +++++ arch/misoc/src/lm32/lm32_idle.c | 96 ++++++ arch/misoc/src/lm32/lm32_initialize.c | 77 +++++ arch/misoc/src/lm32/lm32_initialstate.c | 120 +++++++ arch/misoc/src/lm32/lm32_interruptcontext.c | 62 ++++ arch/misoc/src/lm32/lm32_irq.c | 121 +++++++ arch/misoc/src/lm32/lm32_releasepending.c | 149 +++++++++ arch/misoc/src/lm32/lm32_releasestack.c | 115 +++++++ arch/misoc/src/lm32/lm32_stackframe.c | 136 ++++++++ arch/misoc/src/lm32/lm32_swint.c | 330 ++++++++++++++++++++ arch/misoc/src/lm32/lm32_syscall.S | 103 ++++++ arch/misoc/src/lm32/lm32_unblocktask.c | 164 ++++++++++ arch/misoc/src/lm32/lm32_vectors.S | 251 +++++++++++++++ 25 files changed, 3037 insertions(+), 6 deletions(-) create mode 100644 arch/misoc/src/common/misoc_isr.c create mode 100644 arch/misoc/src/common/misoc_uart.c create mode 100644 arch/misoc/src/lm32/Make.defs create mode 100644 arch/misoc/src/lm32/lm32_assert.c create mode 100644 arch/misoc/src/lm32/lm32_blocktask.c create mode 100644 arch/misoc/src/lm32/lm32_copystate.c create mode 100644 arch/misoc/src/lm32/lm32_createstack.c create mode 100644 arch/misoc/src/lm32/lm32_doirq.c create mode 100644 arch/misoc/src/lm32/lm32_dumpstate.c create mode 100644 arch/misoc/src/lm32/lm32_exit.c create mode 100644 arch/misoc/src/lm32/lm32_idle.c create mode 100644 arch/misoc/src/lm32/lm32_initialize.c create mode 100644 arch/misoc/src/lm32/lm32_initialstate.c create mode 100644 arch/misoc/src/lm32/lm32_interruptcontext.c create mode 100644 arch/misoc/src/lm32/lm32_irq.c create mode 100644 arch/misoc/src/lm32/lm32_releasepending.c create mode 100644 arch/misoc/src/lm32/lm32_releasestack.c create mode 100644 arch/misoc/src/lm32/lm32_stackframe.c create mode 100644 arch/misoc/src/lm32/lm32_swint.c create mode 100644 arch/misoc/src/lm32/lm32_syscall.S create mode 100644 arch/misoc/src/lm32/lm32_unblocktask.c create mode 100644 arch/misoc/src/lm32/lm32_vectors.S diff --git a/arch/misoc/src/Makefile b/arch/misoc/src/Makefile index 6a92f22910..6a0285810b 100644 --- a/arch/misoc/src/Makefile +++ b/arch/misoc/src/Makefile @@ -3,6 +3,7 @@ # # Copyright (C) 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt +# Ramtin Amin # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -43,7 +44,6 @@ ifeq ($(CONFIG_WINDOWS_NATIVE),y) NUTTX = "$(TOPDIR)\nuttx$(EXEEXT)" INCLUDES += -I "$(ARCH_SRCDIR)\chip" INCLUDES += -I "$(ARCH_SRCDIR)\common" - INCLUDES += -I "$(ARCH_SRCDIR)\generated" INCLUDES += -I "$(ARCH_SRCDIR)\$(ARCH_SUBDIR)" INCLUDES += -I "$(TOPDIR)\sched" else @@ -52,14 +52,12 @@ ifeq ($(WINTOOL),y) NUTTX = "${shell cygpath -w $(TOPDIR)/nuttx$(EXEEXT)}" INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/chip}" INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/common}" - INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/generated}" INCLUDES += -I "${shell cygpath -w $(ARCH_SRCDIR)/$(ARCH_SUBDIR)}" INCLUDES += -I "${shell cygpath -w $(TOPDIR)/sched}" else NUTTX = "$(TOPDIR)/nuttx$(EXEEXT)" INCLUDES += -I "$(ARCH_SRCDIR)/chip" INCLUDES += -I "$(ARCH_SRCDIR)/common" - INCLUDES += -I "$(ARCH_SRCDIR)/generated" INCLUDES += -I "$(ARCH_SRCDIR)/$(ARCH_SUBDIR)" INCLUDES += -I "$(TOPDIR)/sched" endif diff --git a/arch/misoc/src/common/misoc_isr.c b/arch/misoc/src/common/misoc_isr.c new file mode 100644 index 0000000000..96c726b17c --- /dev/null +++ b/arch/misoc/src/common/misoc_isr.c @@ -0,0 +1,20 @@ +#include + +void uart_isr(); +void uart_isr() +{ + +} + +void isr(void); +void isr(void) +{ + unsigned int irqs; + + irqs = irq_pending() & irq_getmask(); + + if (irqs & (1 << UART_INTERRUPT)) + { + uart_isr(); + } +} diff --git a/arch/misoc/src/common/misoc_uart.c b/arch/misoc/src/common/misoc_uart.c new file mode 100644 index 0000000000..7a36e78199 --- /dev/null +++ b/arch/misoc/src/common/misoc_uart.c @@ -0,0 +1,141 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include +#include + +#include +#include + +#include "hw/flags.h" +#include "misoc_irqasm.h" +#include "misoc_uart.h" + +#include "lm32.h" + +/* Buffer sizes must be a power of 2 so that modulos can be computed + * with logical AND. + */ + +#define UART_RINGBUFFER_SIZE_RX 128 +#define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1) + +static char rx_buf[UART_RINGBUFFER_SIZE_RX]; +static volatile unsigned int rx_produce; +static unsigned int rx_consume; + +#define UART_RINGBUFFER_SIZE_TX 128 +#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) + +static char tx_buf[UART_RINGBUFFER_SIZE_TX]; +static unsigned int tx_produce; +static volatile unsigned int tx_consume; + +static int uart_interrupt(int irq, void *context); + +static int uart_interrupt(int irq, void *context) +{ + unsigned int stat, rx_produce_next; + + stat = uart_ev_pending_read(); + + if(stat & UART_EV_RX) { + while(!uart_rxempty_read()) { + rx_produce_next = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX; + if(rx_produce_next != rx_consume) { + rx_buf[rx_produce] = uart_rxtx_read(); + rx_produce = rx_produce_next; + } + uart_ev_pending_write(UART_EV_RX); + } + } + + if(stat & UART_EV_TX) { + uart_ev_pending_write(UART_EV_TX); + while((tx_consume != tx_produce) && !uart_txfull_read()) { + uart_rxtx_write(tx_buf[tx_consume]); + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } + } + + return OK; +} + +/* Do not use in interrupt handlers! */ +char uart_read(void) +{ + char c; + + if(irq_getie()) { + while(rx_consume == rx_produce); + } else if (rx_consume == rx_produce) { + return 0; + } + + c = rx_buf[rx_consume]; + rx_consume = (rx_consume + 1) & UART_RINGBUFFER_MASK_RX; + return c; +} + +int uart_read_nonblock(void) +{ + return (rx_consume != rx_produce); +} + +int up_putc(int ch) +{ + unsigned int oldmask; + unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; + + if(irq_getie()) { + while(tx_produce_next == tx_consume); + } else if(tx_produce_next == tx_consume) { + return ch; + } + + oldmask = irq_getmask(); + irq_setmask(oldmask & ~(1 << UART_INTERRUPT)); + if((tx_consume != tx_produce) || uart_txfull_read()) { + tx_buf[tx_produce] = ch; + tx_produce = tx_produce_next; + } else { + uart_rxtx_write(ch); + } + irq_setmask(oldmask); + return ch; +} + +void uart_init(void) +{ + rx_produce = 0; + rx_consume = 0; + + tx_produce = 0; + tx_consume = 0; + + uart_ev_pending_write(uart_ev_pending_read()); + uart_ev_enable_write(UART_EV_TX | UART_EV_RX); + irq_setmask(irq_getmask() | (1 << UART_INTERRUPT)); + + irq_attach(1 << UART_INTERRUPT, uart_interrupt); +} + +void uart_sync(void) +{ + while(tx_consume != tx_produce); +} + + + diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs new file mode 100644 index 0000000000..1c12e0c527 --- /dev/null +++ b/arch/misoc/src/lm32/Make.defs @@ -0,0 +1,49 @@ +############################################################################ +# arch/misoc/src/Makefile +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Ramtin Amin +# +# 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. +# +############################################################################ + +HEAD_ASRC = lm32_vectors.S + +CMN_ASRCS = +CMN_CSRCS = misoc_uart.c + +CHIP_ASRCS = lm32_start.S lm32_syscall.S + +CHIP_CSRCS = lm32_allocateheap.c lm32_assert.c lm32_blocktask.c +CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_doirq.c lm32_dumpstate.c +CHIP_CSRCS += lm32_dumpstate.c lm32_exit.c lm32_idle.c lm32_initialize.c +CHIP_CSRCS += lm32_initialstate.c lm32_interruptcontext.c lm32_irq.c +CHIP_CSRCS += lm32_releasepending.c lm32_releasestack.c lm32_stackframe.c +CHIP_CSRCS += lm32_swint.c lm32_unblocktask.c diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index 8335c6917d..fe18969c75 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/misoc/src/common/lm32.h + * arch/misoc/src/lm32/lm32.h * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -144,7 +144,6 @@ void lm32_irq_initialize(void); /* System timer *************************************************************/ void lm32_timer_initialize(void); -int lm32_timerisr(int irq, void *context); /* Software interrupts ******************************************************/ diff --git a/arch/misoc/src/lm32/lm32_allocateheap.c b/arch/misoc/src/lm32/lm32_allocateheap.c index 4df88cecaf..882bed891a 100644 --- a/arch/misoc/src/lm32/lm32_allocateheap.c +++ b/arch/misoc/src/lm32/lm32_allocateheap.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/misoc/src/common/lm32_allocateheap.c + * arch/misoc/src/lm32/lm32_allocateheap.c * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/arch/misoc/src/lm32/lm32_assert.c b/arch/misoc/src/lm32/lm32_assert.c new file mode 100644 index 0000000000..78e7d2b668 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_assert.c @@ -0,0 +1,162 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_assert.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 +#include +#include +#include + +#include + +#include "sched/sched.h" +#include "lm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* USB trace dumping */ + +#ifndef CONFIG_USBDEV_TRACE +# undef CONFIG_ARCH_USBDUMP +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _up_assert + ****************************************************************************/ + +static void _up_assert(int errorcode) noreturn_function; +static void _up_assert(int errorcode) +{ + /* Are we in an interrupt handler or the idle task? */ + + if (g_current_regs || this_task()->pid == 0) + { + (void)up_irq_save(); + for (; ; ) + { +#ifdef CONFIG_ARCH_LEDS + board_autoled_on(LED_PANIC); + up_mdelay(250); + board_autoled_off(LED_PANIC); + up_mdelay(250); +#endif + } + } + else + { + exit(errorcode); + } +} + +/**************************************************************************** + * Name: assert_tracecallback + ****************************************************************************/ + +#ifdef CONFIG_ARCH_USBDUMP +static int usbtrace_syslog(FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + /* Let vsyslog do the real work */ + + va_start(ap, fmt); + ret = vsyslog(LOG_EMERG, fmt, ap); + va_end(ap); + return ret; +} + +static int assert_tracecallback(FAR struct usbtrace_s *trace, FAR void *arg) +{ + usbtrace_trprintf(usbtrace_syslog, trace->event, trace->value); + return 0; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_assert + ****************************************************************************/ + +void up_assert(const uint8_t *filename, int lineno) +{ +#if CONFIG_TASK_NAME_SIZE > 0 && defined(CONFIG_DEBUG_ALERT) + struct tcb_s *rtcb = this_task(); +#endif + + board_autoled_on(LED_ASSERTION); + +#if CONFIG_TASK_NAME_SIZE > 0 + _alert("Assertion failed at file:%s line: %d task: %s\n", + filename, lineno, rtcb->name); +#else + _alert("Assertion failed at file:%s line: %d\n", + filename, lineno); +#endif + + lm32_dumpstate(); + +#ifdef CONFIG_ARCH_USBDUMP + /* Dump USB trace data */ + + (void)usbtrace_enumerate(assert_tracecallback, NULL); +#endif + +#ifdef CONFIG_BOARD_CRASHDUMP + board_crashdump(up_getsp(), this_task(), filename, lineno); +#endif + + _up_assert(EXIT_FAILURE); +} diff --git a/arch/misoc/src/lm32/lm32_blocktask.c b/arch/misoc/src/lm32/lm32_blocktask.c new file mode 100644 index 0000000000..f313da11cc --- /dev/null +++ b/arch/misoc/src/lm32/lm32_blocktask.c @@ -0,0 +1,180 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_blocktask.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_block_task + * + * Description: + * The currently executing task at the head of + * the ready to run list must be stopped. Save its context + * and move it to the inactive list specified by task_state. + * + * Inputs: + * tcb: Refers to a task in the ready-to-run list (normally + * the task at the head of the list). It most be + * stopped, its context saved and moved into one of the + * waiting task lists. It it was the task at the head + * of the ready-to-run list, then a context to the new + * ready to run task must be performed. + * task_state: Specifies which waiting task list should be + * hold the blocked task TCB. + * + ****************************************************************************/ + +void up_block_task(struct tcb_s *tcb, tstate_t task_state) +{ + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_READY_TO_RUN_STATE) && + (tcb->task_state <= LAST_READY_TO_RUN_STATE)); + + /* Remove the tcb task from the ready-to-run list. If we + * are blocking the task at the head of the task list (the + * most likely case), then a context switch to the next + * ready-to-run task is needed. In this case, it should + * also be true that rtcb == tcb. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Add the task to the specified blocked task list */ + + sched_addblocked(tcb, (tstate_t)task_state); + + /* If there are any pending tasks, then add them to the ready-to-run + * task list now + */ + + if (g_pendingtasks.head) + { + switch_needed |= sched_mergepending(); + } + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Reset scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Get the context of the task at the head of the ready to + * run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Reset scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/misoc/src/lm32/lm32_copystate.c b/arch/misoc/src/lm32/lm32_copystate.c new file mode 100644 index 0000000000..b3afa387b8 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_copystate.c @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_copystate.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 "lm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lm32_copystate + ****************************************************************************/ + +/* A little faster than most memcpy's */ + +void lm32_copystate(uint32_t *dest, uint32_t *src) +{ + int i; + + /* In the LM32 model, the state is copied from the stack to the TCB, + * but only a reference is passed to get the state from the TCB. So the + * following check avoids copying the TCB save area onto itself: + */ + + if (src != dest) + { + for (i = 0; i < XCPTCONTEXT_REGS; i++) + { + *dest++ = *src++; + } + } +} + diff --git a/arch/misoc/src/lm32/lm32_createstack.c b/arch/misoc/src/lm32/lm32_createstack.c new file mode 100644 index 0000000000..31c7f24226 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_createstack.c @@ -0,0 +1,214 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_createstack.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 +#include +#include +#include + +#include "lm32.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* LM32 requires at least a 4-byte stack alignment. For floating point use, + * however, the stack must be aligned to 8-byte addresses. + */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# define STACK_ALIGNMENT 8 +#else +# define STACK_ALIGNMENT 4 +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_create_stack + * + * Description: + * Allocate a stack for a new thread and setup up stack-related information + * in the TCB. + * + * 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 + * - adj_stack_ptr: Adjusted stack_alloc_ptr for HW. The initial value of + * the stack pointer. + * + * Inputs: + * - tcb: The TCB of new task + * - stack_size: The requested stack size. At least this much + * must be allocated. + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain contexts where the TCB may not be fully + * initialized when up_create_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is allocated. For example, kernel thread stacks should + * be allocated from protected kernel memory. Stacks for user tasks and + * threads must come from memory that is accessible to user code. + * + ****************************************************************************/ + +int up_create_stack(FAR struct tcb_s *tcb, size_t stack_size, uint8_t ttype) +{ + /* Is there already a stack allocated of a different size? Because of + * alignment issues, stack_size might erroneously appear to be of a + * different size. Fortunately, this is not a critical operation. + */ + + if (tcb->stack_alloc_ptr && tcb->adj_stack_size != stack_size) + { + /* Yes.. Release the old stack */ + + up_release_stack(tcb, ttype); + } + + /* Do we need to allocate a new stack? */ + + if (!tcb->stack_alloc_ptr) + { + /* Allocate the stack. If DEBUG is enabled (but not stack debug), + * then create a zeroed stack to make stack dumps easier to trace. + */ + +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + tcb->stack_alloc_ptr = (uint32_t *)kmm_malloc(stack_size); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + tcb->stack_alloc_ptr = (uint32_t *)kumm_malloc(stack_size); + } + +#ifdef CONFIG_DEBUG_FEATURES + /* Was the allocation successful? */ + + if (!tcb->stack_alloc_ptr) + { + serr("ERROR: Failed to allocate stack, size %d\n", stack_size); + } +#endif + } + + /* Did we successfully allocate a stack? */ + + if (tcb->stack_alloc_ptr) + { + size_t top_of_stack; + size_t size_of_stack; + + /* Yes.. If stack debug is enabled, then fill the stack with a + * recognizable value that we can use later to test for high + * water marks. + */ + +#ifdef CONFIG_STACK_COLORATION + memset(tcb->stack_alloc_ptr, 0xaa, stack_size); +#endif + + /* LM32 uses a push-down stack: the stack grows toward lower + * addresses in memory. The stack pointer register points to the + * lowest, valid working address (the "top" of the stack). Items on + * the stack are referenced as positive word offsets from sp. + */ + + top_of_stack = (uint32_t)tcb->stack_alloc_ptr + stack_size - 4; + + /* The LM32 stack must be aligned at word (4 byte) boundaries; for + * floating point use, the stack must be aligned to 8-byte addresses. + * If necessary top_of_stack must be rounded down to the next + * boundary to meet these alignment requirements. + */ + + top_of_stack = STACK_ALIGN_DOWN(top_of_stack); + size_of_stack = top_of_stack - (uint32_t)tcb->stack_alloc_ptr + 4; + + /* Save the adjusted stack values in the struct tcb_s */ + + tcb->adj_stack_ptr = (FAR uint32_t *)top_of_stack; + tcb->adj_stack_size = size_of_stack; + + board_autoled_on(LED_STACKCREATED); + return OK; + } + + return ERROR; +} diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c new file mode 100644 index 0000000000..50b2e745fc --- /dev/null +++ b/arch/misoc/src/lm32/lm32_doirq.c @@ -0,0 +1,147 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_doirq.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 +#include + +#include "group/group.h" +#include "lm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +uint32_t *up_doirq(int irq, uint32_t *regs) +{ + board_autoled_on(LED_INIRQ); +#ifdef CONFIG_SUPPRESS_INTERRUPTS + PANIC(); +#else + /* Current regs non-zero indicates that we are processing an interrupt; + * g_current_regs is also used to manage interrupt level context switches. + * + * Nested interrupts are not supported + */ + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Disable further occurrences of this interrupt (until the interrupt sources + * have been clear by the driver). + */ + + up_disable_irq(irq); + + /* Deliver the IRQ */ + + irq_dispatch(irq, regs); + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + g_current_regs = NULL; + + /* Unmask the last interrupt (global interrupts are still disabled) */ + + up_enable_irq(irq); +#endif + board_autoled_off(LED_INIRQ); + return regs; +} diff --git a/arch/misoc/src/lm32/lm32_dumpstate.c b/arch/misoc/src/lm32/lm32_dumpstate.c new file mode 100644 index 0000000000..e847bec40c --- /dev/null +++ b/arch/misoc/src/lm32/lm32_dumpstate.c @@ -0,0 +1,228 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_dumpstate.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 +#include +#include + +#include "sched/sched.h" +#include "lm32.h" + +#ifdef CONFIG_ARCH_STACKDUMP + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_getsp + ****************************************************************************/ + +static inline uint32_t up_getsp(void) +{ + register uint32_t sp; + + __asm__ __volatile__("addi %0, sp, 0" : "=r" (sp)); + + return sp; +} + +/**************************************************************************** + * Name: up_stackdump + ****************************************************************************/ + +static void up_stackdump(uint32_t sp, uint32_t stack_base) +{ +# if 0 + uint32_t stack ; + + for (stack = sp & ~0x1f; stack < stack_base; stack += 32) + { + uint32_t *ptr = (uint32_t *)stack; + _alert("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n", + stack, ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7]); + } +#endif +} + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +static inline void up_registerdump(void) +{ +#if 0 + /* Are user registers available from interrupt processing? */ + + if (g_current_regs) + { + _alert("EPC:%08x \n", + g_current_regs[REG_EPC]); + _alert("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x A7:%08x\n", + g_current_regs[REG_A0], g_current_regs[REG_A1], g_current_regs[REG_A2], + g_current_regs[REG_A3], g_current_regs[REG_A4], g_current_regs[REG_A5], + g_current_regs[REG_A6], g_current_regs[REG_A7]); + _alert("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n", + g_current_regs[REG_T0], g_current_regs[REG_T1], g_current_regs[REG_T2], + g_current_regs[REG_T3], g_current_regs[REG_T4], g_current_regs[REG_T5], + g_current_regs[REG_T6]); + _alert("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", + g_current_regs[REG_S0], g_current_regs[REG_S1], g_current_regs[REG_S2], + g_current_regs[REG_S3], g_current_regs[REG_S4], g_current_regs[REG_S5], + g_current_regs[REG_S6], g_current_regs[REG_S7]); + _alert("S8:%08x S9:%08x S10:%08x S11:%08x\n", + g_current_regs[REG_S8], g_current_regs[REG_S9], g_current_regs[REG_S10], + g_current_regs[REG_S11]); +#ifdef RISCV_SAVE_GP + _alert("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n", + g_current_regs[REG_GP], g_current_regs[REG_SP], g_current_regs[REG_FP], + g_current_regs[REG_TP], g_current_regs[REG_RA]); +#else + _alert("SP:%08x FP:%08x TP:%08x RA:%08x\n", + g_current_regs[REG_SP], g_current_regs[REG_FP], g_current_regs[REG_TP], + g_current_regs[REG_RA]); +#endif + } +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lm32_dumpstate + ****************************************************************************/ + +void lm32_dumpstate(void) +{ + struct tcb_s *rtcb = this_task(); + uint32_t sp = up_getsp(); + uint32_t ustackbase; + uint32_t ustacksize; +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + uint32_t istackbase; + uint32_t istacksize; +#endif + + /* Get the limits on the user stack memory */ + + if (rtcb->pid == 0) + { + ustackbase = g_idle_topstack - 4; + ustacksize = CONFIG_IDLETHREAD_STACKSIZE; + } + else + { + ustackbase = (uint32_t)rtcb->adj_stack_ptr; + ustacksize = (uint32_t)rtcb->adj_stack_size; + } + + /* Get the limits on the interrupt stack memory */ + +#if CONFIG_ARCH_INTERRUPTSTACK > 3 + istackbase = (uint32_t)&g_intstackbase; + istacksize = (CONFIG_ARCH_INTERRUPTSTACK & ~3) - 4; + + /* Show interrupt stack info */ + + _alert("sp: %08x\n", sp); + _alert("IRQ stack:\n"); + _alert(" base: %08x\n", istackbase); + _alert(" size: %08x\n", istacksize); + + /* Does the current stack pointer lie within the interrupt + * stack? + */ + + if (sp <= istackbase && sp > istackbase - istacksize) + { + /* Yes.. dump the interrupt stack */ + + up_stackdump(sp, istackbase); + + /* Extract the user stack pointer which should lie + * at the base of the interrupt stack. + */ + + sp = g_intstackbase; + _alert("sp: %08x\n", sp); + } + + /* Show user stack info */ + + _alert("User stack:\n"); + _alert(" base: %08x\n", ustackbase); + _alert(" size: %08x\n", ustacksize); +#else + _alert("sp: %08x\n", sp); + _alert("stack base: %08x\n", ustackbase); + _alert("stack size: %08x\n", ustacksize); +#endif + + /* Dump the user stack if the stack pointer lies within the allocated user + * stack memory. + */ + + if (sp > ustackbase || sp <= ustackbase - ustacksize) + { +#if !defined(CONFIG_ARCH_INTERRUPTSTACK) || CONFIG_ARCH_INTERRUPTSTACK < 4 + _alert("ERROR: Stack pointer is not within allocated stack\n"); +#endif + } + else + { + up_stackdump(sp, ustackbase); + } + + /* Then dump the registers (if available) */ + + up_registerdump(); +} + +#endif /* CONFIG_ARCH_STACKDUMP */ diff --git a/arch/misoc/src/lm32/lm32_exit.c b/arch/misoc/src/lm32/lm32_exit.c new file mode 100644 index 0000000000..688f085426 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_exit.c @@ -0,0 +1,82 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_exit.c + * + * Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 + +#ifdef CONFIG_DUMP_ON_EXIT +# include +#endif + +#include "task/task.h" +#include "sched/sched.h" +#include "group/group.h" +#include "lm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: _exit + * + * Description: + * This function causes the currently executing task to cease + * to exist. This is a special case of task_delete() where the task to + * be deleted is the currently executing task. It is more complex because + * a context switch must be perform to the next ready to run task. + * + ****************************************************************************/ + +void _exit(int status) +{ +#warning Missing logic +} diff --git a/arch/misoc/src/lm32/lm32_idle.c b/arch/misoc/src/lm32/lm32_idle.c new file mode 100644 index 0000000000..5b85bcc0c0 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_idle.c @@ -0,0 +1,96 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_idle.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_idle + * + * Description: + * up_idle() is the logic that will be executed when their is no other + * ready-to-run task. This is processor idle time and will continue until + * some interrupt occurs to cause a context switch from the idle task. + * + * Processing in this state may be processor-specific. e.g., this is where + * power management operations might be performed. + * + ****************************************************************************/ + +void up_idle(void) +{ +#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) + /* If the system is idle and there are no timer interrupts, then process + * "fake" timer interrupts. Hopefully, something will wake up. + */ + + sched_process_timer(); +#else + + /* This would be an appropriate place to put some MCU-specific logic to + * sleep in a reduced power mode until an interrupt occurs to save power + */ + + /* This is a kludge that I still don't understand. The call to kmm_trysemaphore() + * in the os_start.c IDLE loop seems necessary for the good health of the IDLE + * loop. When the work queue is enabled, this logic is removed from the IDLE + * loop and it appears that we are somehow left idling with interrupts non- + * functional. The following should be no-op, it just disables then re-enables + * interrupts. But it fixes the problem and will stay here until I understand + * the problem/fix better. + * + * And no, the contents of the CP0 status register are not incorrect. But for + * some reason the status register needs to be re-written again on this thread + * for it to take effect. This might be a PIC32-only issue? + */ + +#ifdef CONFIG_SCHED_WORKQUEUE + irqstate_t flags = enter_critical_section(); + leave_critical_section(flags); +#endif +#endif +} diff --git a/arch/misoc/src/lm32/lm32_initialize.c b/arch/misoc/src/lm32/lm32_initialize.c new file mode 100644 index 0000000000..4efa2ecbf0 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_initialize.c @@ -0,0 +1,77 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_initialize.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "lm32.h" + +/**************************************************************************** + * Public Functionis + ****************************************************************************/ + +void up_initialize(void) +{ + /* Initialize the System Timer */ + + lm32_irq_initialize(); + + /* Initialize the serial driver */ + +#warning REVISIT: Here you should all lm32_serial_initialize(). That initializes the entire serial driver, a part of the operation is the uart initialization. + + uart_init(); +} diff --git a/arch/misoc/src/lm32/lm32_initialstate.c b/arch/misoc/src/lm32/lm32_initialstate.c new file mode 100644 index 0000000000..e42107e145 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_initialstate.c @@ -0,0 +1,120 @@ +/**************************************************************************** + * arch/misoc/src/lm32/up_initialstate.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 + +#include "lm32.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_initial_state + * + * Description: + * A new thread is being started and a new TCB + * has been created. This function is called to initialize + * the processor specific portions of the new TCB. + * + * This function must setup the intial architecture registers + * and/or stack so that execution will begin at tcb->start + * on the next context switch. + * + ****************************************************************************/ + +void up_initial_state(struct tcb_s *tcb) +{ + struct xcptcontext *xcp = &tcb->xcp; + + /* Initialize the initial exception register context structure */ + + memset(xcp, 0, sizeof(struct xcptcontext)); + + /* Save the initial stack pointer. Hmmm.. the stack is set to the very + * beginning of the stack region. Some functions may want to store data on + * the caller's stack and it might be good to reserve some space. However, + * only the start function would do that and we have control over that one + */ + + xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* Save the task entry point */ + + xcp->regs[REG_EPC] = (uint32_t)tcb->start; + + /* If this task is running PIC, then set the PIC base register to the + * address of the allocated D-Space region. + */ + +#ifdef CONFIG_PIC +# warning "Missing logic" +#endif + + /* 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. + */ + +#ifdef CONFIG_BUILD_KERNEL +# warning "Missing logic" +#endif +} diff --git a/arch/misoc/src/lm32/lm32_interruptcontext.c b/arch/misoc/src/lm32/lm32_interruptcontext.c new file mode 100644 index 0000000000..8edd553853 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_interruptcontext.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/misoc/src/lm32/up_interruptcontext.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_interrupt_context + * + * Description: Return true is we are currently executing in + * the interrupt handler context. + ****************************************************************************/ + +bool up_interrupt_context(void) +{ + return g_current_regs != NULL; +} diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c new file mode 100644 index 0000000000..b99bb443b4 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -0,0 +1,121 @@ +/**************************************************************************** + * arch/misoc/src/lm32/_irq.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 +#include + +#include "misoc_irqasm.h" +#include "lm32.h" + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lm32_irq_initialize + ****************************************************************************/ + +void lm32_irq_initialize(void) +{ + /* currents_regs is non-NULL only while processing an interrupt */ + + g_current_regs = NULL; + + /* Enable interrupt */ + + irq_setie(1); +} + +irqstate_t up_irq_save(void) +{ + irqstate_t flags; + irq_setie(0); + +#warning Return value MUST be the previous IE value. Returning 1 will not work. + return 1; +} + +void up_irq_restore(irqstate_t flags) +{ + irq_setie(1); +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + irqstate_t flags; + flags = irq_getmask(); + flags &= ~(1 < + * Ramtin Amin + * + * 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 + +#include "sched/sched.h" +#include "group/group.h" +#include "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_pending + * + * Description: + * Release and ready-to-run tasks that have + * collected in the pending task list. This can call a + * context switch if a new task is placed at the head of + * the ready to run list. + * + ****************************************************************************/ + +void up_release_pending(void) +{ + struct tcb_s *rtcb = this_task(); + + sinfo("From TCB=%p\n", rtcb); + + /* Merge the g_pendingtasks list into the ready-to-run task list */ + + /* sched_lock(); */ + if (sched_mergepending()) + { + /* The currently active task has changed! We will need to switch + * contexts. + * + * Update scheduler parameters. + */ + + sched_suspend_scheduler(rtcb); + + /* Are we operating in interrupt context? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/misoc/src/lm32/lm32_releasestack.c b/arch/misoc/src/lm32/lm32_releasestack.c new file mode 100644 index 0000000000..fa88500bf9 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_releasestack.c @@ -0,0 +1,115 @@ +/**************************************************************************** + * arch/misoc/src/lm32/up_releasestack.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_release_stack + * + * Description: + * A task has been stopped. Free all stack related resources retained in + * the defunct TCB. + * + * Input Parmeters + * - dtcb: The TCB containing information about the stack to be released + * - ttype: The thread type. This may be one of following (defined in + * include/nuttx/sched.h): + * + * TCB_FLAG_TTYPE_TASK Normal user task + * TCB_FLAG_TTYPE_PTHREAD User pthread + * TCB_FLAG_TTYPE_KERNEL Kernel thread + * + * This thread type is normally available in the flags field of the TCB, + * however, there are certain error recovery contexts where the TCB may + * not be fully initialized when up_release_stack is called. + * + * If CONFIG_BUILD_KERNEL is defined, then this thread type may affect + * how the stack is freed. For example, kernel thread stacks may have + * been allocated from protected kernel memory. Stacks for user tasks + * and threads must have come from memory that is accessible to user + * code. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void up_release_stack(FAR struct tcb_s *dtcb, uint8_t ttype) +{ + /* Is there a stack allocated? */ + + if (dtcb->stack_alloc_ptr) + { +#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_MM_KERNEL_HEAP) + /* Use the kernel allocator if this is a kernel thread */ + + if (ttype == TCB_FLAG_TTYPE_KERNEL) + { + sched_kfree(dtcb->stack_alloc_ptr); + } + else +#endif + { + /* Use the user-space allocator if this is a task or pthread */ + + sched_ufree(dtcb->stack_alloc_ptr); + } + + /* Mark the stack freed */ + + dtcb->stack_alloc_ptr = NULL; + } + + /* The size of the allocated stack is now zero */ + + dtcb->adj_stack_size = 0; +} diff --git a/arch/misoc/src/lm32/lm32_stackframe.c b/arch/misoc/src/lm32/lm32_stackframe.c new file mode 100644 index 0000000000..981c655f81 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_stackframe.c @@ -0,0 +1,136 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_stackframe.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 + +#include "lm32.h" + +/**************************************************************************** + * Pre-processor Macros + ****************************************************************************/ + +/* LM32 requires at least a 4-byte stack alignment. For floating point use, + * however, the stack must be aligned to 8-byte addresses. + */ + +#ifdef CONFIG_LIBC_FLOATINGPOINT +# define STACK_ALIGNMENT 8 +#else +# define STACK_ALIGNMENT 4 +#endif + +/* Stack alignment macros */ + +#define STACK_ALIGN_MASK (STACK_ALIGNMENT-1) +#define STACK_ALIGN_DOWN(a) ((a) & ~STACK_ALIGN_MASK) +#define STACK_ALIGN_UP(a) (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_stack_frame + * + * Description: + * Allocate a stack frame in the TCB's stack to hold thread-specific data. + * This function may be called anytime after up_create_stack() or + * up_use_stack() have been called but before the task has been started. + * + * Thread data may be kept in the stack (instead of in the TCB) if it is + * accessed by the user code directly. This includes such things as + * argv[]. The stack memory is guaranteed to be in the same protection + * domain as the thread. + * + * The following TCB fields will be re-initialized: + * + * - adj_stack_size: Stack size after removal of the stack frame from + * the stack + * - adj_stack_ptr: Adjusted initial stack pointer after the frame has + * been removed from the stack. This will still be the initial value + * of the stack pointer when the task is started. + * + * Inputs: + * - tcb: The TCB of new task + * - frame_size: The size of the stack frame to allocate. + * + * Returned Value: + * - A pointer to bottom of the allocated stack frame. NULL will be + * returned on any failures. The alignment of the returned value is + * the same as the alignment of the stack itself. + * + ****************************************************************************/ + +FAR void *up_stack_frame(FAR struct tcb_s *tcb, size_t frame_size) +{ + uintptr_t topaddr; + + /* Align the frame_size */ + + frame_size = STACK_ALIGN_UP(frame_size); + + /* Is there already a stack allocated? Is it big enough? */ + + if (!tcb->stack_alloc_ptr || tcb->adj_stack_size <= frame_size) + { + return NULL; + } + + /* Save the adjusted stack values in the struct tcb_s */ + + topaddr = (uintptr_t)tcb->adj_stack_ptr - frame_size; + tcb->adj_stack_ptr = (FAR void *)topaddr; + tcb->adj_stack_size -= frame_size; + + /* Reset the initial stack pointer */ + + tcb->xcp.regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; + + /* And return the pointer to the allocated region */ + + return (FAR void *)(topaddr + sizeof(uint32_t)); +} diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c new file mode 100644 index 0000000000..c8148812cc --- /dev/null +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -0,0 +1,330 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_swint.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 + +#include +#include + +#include "lm32.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_registerdump + ****************************************************************************/ + +#ifdef CONFIG_DEBUG_SYSCALL_INFO +static void up_registerdump(const uint32_t *regs) +{ +#if 0 + svcinfo("EPC:%08x\n", + regs[REG_EPC]); + svcinfo("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x A7:%08x\n", + regs[REG_A0], regs[REG_A1], regs[REG_A2], regs[REG_A3], + regs[REG_A4], regs[REG_A5], regs[REG_A6], regs[REG_A7]); + svcinfo("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n", + regs[REG_T0], regs[REG_T1], regs[REG_T2], regs[REG_T3], + regs[REG_T4], regs[REG_T5], regs[REG_T6]); + svcinfo("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", + regs[REG_S0], regs[REG_S1], regs[REG_S2], regs[REG_S3], + regs[REG_S4], regs[REG_S5], regs[REG_S6], regs[REG_S7]); + svcinfo("S8:%08x S9:%08x S10:%08x S11:%08x\n", + regs[REG_S8], regs[REG_S9], regs[REG_S10], regs[REG_S11]); +#ifdef LM3232_SAVE_GP + svcinfo("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n", + regs[REG_GP], regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); +#else + svcinfo("SP:%08x FP:%08x TP:%08x RA:%08x\n", + regs[REG_SP], regs[REG_FP], regs[REG_TP], regs[REG_RA]); +#endif +#endif +} +#else +# define up_registerdump(regs) +#endif + +/**************************************************************************** + * Name: dispatch_syscall + * + * Description: + * Call the stub function corresponding to the system call. + * + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +static void dispatch_syscall(void) naked_function; +static void dispatch_syscall(void) +{ +# error "Missing logic" + +/* Refer to arch/arm/src/armv7-m/up_svcall.h for how this is done for ARM */ +/* __asm__ __volatile__ */ +/* ( */ +/* Save registers */ +/* Get the base of the stub lookup table */ +/* Get the offset of the stub for this syscall */ +/* Load the entry of the stub for this syscall */ +/* Call the stub */ +/* Restore regsisters */ +/* Return from the syscall */ +/* ); */ +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lm32_swint + * + * Description: + * This is software interrupt exception handler that performs context + * switching and manages system calls + * + ****************************************************************************/ + +uint32_t lm32_swint(int irq, FAR void *context) +{ + uint32_t *regs = (uint32_t *)context; + + DEBUGASSERT(g_current_regs == NULL); + g_current_regs = regs; + + /* Software interrupt 0 is invoked with REG_A0 (REG_X10) = system call + * command and REG_A1-6 = variable number of + * arguments depending on the system call. + */ + +#ifdef CONFIG_DEBUG_SYSCALL_INFO + svcinfo("Entry: regs: %p cmd: %d\n", regs, regs[REG_A0]); + up_registerdump(regs); +#endif + + /* Handle the SWInt according to the command in $a0 */ + + switch (regs[REG_A0]) + { + /* A0=SYS_restore_context: This a restore context command: + * + * void up_fullcontextrestore(uint32_t *restoreregs) noreturn_function; + * + * At this point, the following values are saved in context: + * + * A0 = SYS_restore_context + * A1 = restoreregs + * + * In this case, we simply need to set g_current_regs to restore register + * area referenced in the saved R1. context == g_current_regs is the normal + * exception return. By setting g_current_regs = context[R1], we force + * the return to the saved context referenced in $a1. + */ + + case SYS_restore_context: + { + DEBUGASSERT(regs[REG_A1] != 0); + g_current_regs = (uint32_t *)regs[REG_A1]; + } + break; + + /* A0=SYS_switch_context: This a switch context command: + * + * void up_switchcontext(uint32_t *saveregs, uint32_t *restoreregs); + * + * At this point, the following values are saved in context: + * + * A0 = SYS_switch_context + * A1 = saveregs + * A2 = restoreregs + * + * In this case, we save the context registers to the save register + * area reference by the saved contents of R5 and then set + * g_current_regs to to the save register area referenced by the saved + * contents of R6. + */ + + case SYS_switch_context: + { + DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0); + lm32_copystate((uint32_t *)regs[REG_A1], regs); + g_current_regs = (uint32_t *)regs[REG_A2]; + } + break; + + /* A0=SYS_syscall_return: This a switch context command: + * + * void up_sycall_return(void); + * + * At this point, the following values are saved in context: + * + * A0 = SYS_syscall_return + * + * We need to restore the saved return address and return in + * unprivileged thread mode. + */ + +#ifdef CONFIG_BUILD_KERNEL + case SYS_syscall_return: + { + struct tcb_s *rtcb = sched_self(); + int index = (int)rtcb->xcp.nsyscalls - 1; + + /* Make sure that there is a saved syscall return address. */ + + DEBUGASSERT(index >= 0); + + /* Setup to return to the saved syscall return address in + * the original mode. + */ + + g_current_regs[REG_EPC] = rtcb->xcp.syscall[index].sysreturn; +#error "Missing logic -- need to restore the original mode" + rtcb->xcp.nsyscalls = index; + } + break; +#endif + + /* This is not an architecture-specify system call. If NuttX is built + * as a standalone kernel with a system call interface, then all of the + * additional system calls must be handled as in the default case. + */ + + default: + { +#ifdef CONFIG_BUILD_KERNEL + FAR struct tcb_s *rtcb = sched_self(); + int index = rtcb->xcp.nsyscalls; + + /* Verify that the SYS call number is within range */ + + DEBUGASSERT(g_current_regs[REG_A0] < SYS_maxsyscall); + + /* Make sure that we got here that there is a no saved syscall + * return address. We cannot yet handle nested system calls. + */ + + DEBUGASSERT(index < CONFIG_SYS_NNEST); + + /* Setup to return to dispatch_syscall in privileged mode. */ + + rtcb->xcpsyscall[index].sysreturn = regs[REG_EPC]; +#error "Missing logic -- Need to save mode" + rtcb->xcp.nsyscalls = index + 1; + + regs[REG_EPC] = (uint32_t)dispatch_syscall; +#error "Missing logic -- Need to set privileged mode" + + /* Offset R0 to account for the reserved values */ + + g_current_regs[REG_A0] -= CONFIG_SYS_RESERVED; +#else + svcerr("ERROR: Bad SYS call: %d\n", regs[REG_A0]); +#endif + } + break; + } + + /* Report what happened. That might difficult in the case of a context switch */ + +#ifdef CONFIG_DEBUG_SYSCALL_INFO + if (regs != g_current_regs) + { + svcinfo("SWInt Return: Context switch!\n"); + up_registerdump((const uint32_t *)g_current_regs); + } + else + { + svcinfo("SWInt Return: %d\n", regs[REG_A0]); + } +#endif + + +#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV) + /* Check for a context switch. If a context switch occurred, then + * g_current_regs will have a different value than it did on entry. If an + * interrupt level context switch has occurred, then restore the floating + * point state and the establish the correct address environment before + * returning from the interrupt. + */ + + if (regs != g_current_regs) + { +#ifdef CONFIG_ARCH_FPU + /* Restore floating point registers */ + + up_restorefpu((uint32_t *)g_current_regs); +#endif + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(NULL); +#endif + } +#endif + + /* If a context switch occurred while processing the interrupt then + * g_current_regs may have change value. If we return any value different + * from the input regs, then the lower level will know that a context + * switch occurred during interrupt processing. + */ + + regs = (uint32_t *)g_current_regs; + + /* Set g_current_regs to NULL to indicate that we are no longer in an + * interrupt handler. + */ + + g_current_regs = NULL; + return regs; +} diff --git a/arch/misoc/src/lm32/lm32_syscall.S b/arch/misoc/src/lm32/lm32_syscall.S new file mode 100644 index 0000000000..61b0b6ca7c --- /dev/null +++ b/arch/misoc/src/lm32/lm32_syscall.S @@ -0,0 +1,103 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_syscall.S + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * Derives from RISC-V version: + * + * Copyright (C) 2016 Ken Pettit. All rights reserved. + * Author: Ken Pettit + * + * 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 + +/**************************************************************************** + * Public Symbols + ****************************************************************************/ + + .file "up_syscall.S" + .global sys_call0 + .global sys_call1 + .global sys_call2 + .global sys_call3 + .global sys_call4 + .global sys_call5 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_syscall0, up_syscall1, up_syscall2, up_syscall3 + * + * Description: + * up_syscall0 - System call SYS_ argument and no additional parameters. + * up_syscall1 - System call SYS_ argument and one additional parameter. + * up_syscall2 - System call SYS_ argument and two additional parameters. + * up_syscall3 - System call SYS_ argument and three additional parameters. + * up_syscall4 - System call SYS_ argument and four additional parameters. + * up_syscall5 - System call SYS_ argument and five additional parameters. + * + * Assumption: + * All interrupts are disabled except for the software interrupts. + * + ****************************************************************************/ + + .text + +sys_call0: /* a0 holds the syscall number */ +sys_call1: /* a0 holds the syscall number, argument in a1 */ +sys_call2: /* a0 holds the syscall number, arguments in a1 and a2 */ +sys_call3: /* a0 holds the syscall number, arguments in a1, a2, and a3 */ +sys_call4: /* a0 holds the syscall number, arguments in a1, a2, a3 and a4 */ +sys_call5: /* a0 holds the syscall number, arguments in a1, a2, a3, a4 and a5 */ + + /* Issue the ECALL opcode to perform a SW interrupt to the OS */ + + scall + + /* The actual interrupt may not a occur for a few more cycles. Let's + * put a few nop's here in hope that the SW interrupt occurs during + * the sequence of nops. + */ + + nop + nop + + /* Then return with the result of the software interrupt in v0 */ + + ret + nop diff --git a/arch/misoc/src/lm32/lm32_unblocktask.c b/arch/misoc/src/lm32/lm32_unblocktask.c new file mode 100644 index 0000000000..74b1d92472 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_unblocktask.c @@ -0,0 +1,164 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_unblocktask.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 + +#include "sched/sched.h" +#include "group/group.h" +#include "clock/clock.h" +#include "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_unblock_task + * + * Description: + * A task is currently in an inactive task list + * but has been prepped to execute. Move the TCB to the + * ready-to-run list, restore its context, and start execution. + * + * Inputs: + * tcb: Refers to the tcb to be unblocked. This tcb is + * in one of the waiting tasks lists. It must be moved to + * the ready-to-run list and, if it is the highest priority + * ready to run task, executed. + * + ****************************************************************************/ + +void up_unblock_task(struct tcb_s *tcb) +{ + struct tcb_s *rtcb = this_task(); + + /* Verify that the context switch can be performed */ + + ASSERT((tcb->task_state >= FIRST_BLOCKED_STATE) && + (tcb->task_state <= LAST_BLOCKED_STATE)); + + /* Remove the task from the blocked task list */ + + sched_removeblocked(tcb); + + /* Add the task in the correct location in the prioritized + * ready-to-run task list + */ + + if (sched_addreadytorun(tcb)) + { + /* The currently active task has changed! We need to do + * a context switch to the new task. + */ + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Restore the exception context of the new task that is ready to + * run (probably tcb). This is the new rtcb at the head of the + * ready-to-run task list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } +} diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S new file mode 100644 index 0000000000..a5ca7a550d --- /dev/null +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -0,0 +1,251 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_allocateheap.c + * LM32 C startup code. + * + * Adapted for NuttX: + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * Derives from LatticeMico32 C startup code. + * + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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 + +/**************************************************************************** + * Exception handlers - Must be 32 bytes long. + ****************************************************************************/ + + .section .text, "ax", @progbits + .global __start + +__start: +_reset_handler: + xor r0, r0, r0 + wcsr IE, r0 + mvhi r1, hi(_reset_handler) + ori r1, r1, lo(_reset_handler) + wcsr EBA, r1 + bi _do_reset + nop + nop + +_breakpoint_handler: + bi _breakpoint_handler + nop + nop + nop + nop + nop + nop + nop + +_instruction_bus_error_handler: + bi _instruction_bus_error_handler + nop + nop + nop + nop + nop + nop + nop + +_watchpoint_hander: + bi _watchpoint_hander + nop + nop + nop + nop + nop + nop + nop + +_data_bus_error_handler: + bi _data_bus_error_handler + nop + nop + nop + nop + nop + nop + nop + +_divide_by_zero_handler: + bi _divide_by_zero_handler + nop + nop + nop + nop + nop + nop + nop + +_interrupt_handler: + sw (sp+0), ra + calli .save_all + rcsr r1, IP + calli up_doirq + bi .restore_all_and_eret + nop + nop + nop + +_syscall_handler: + sw (sp+0), ra + calli .save_all + rcsr r1, IP + calli lm32_swint + bi .restore_all_and_eret + nop + nop + nop + +_do_reset: + /* Setup stack and global pointer */ + + mvhi sp, hi(_fstack) + ori sp, sp, lo(_fstack) + + /* Clear BSS */ + + mvhi r1, hi(_sbss) + ori r1, r1, lo(_sbss) + mvhi r3, hi(_ebss) + ori r3, r3, lo(_ebss) + +.clearBSS: + be r1, r3, .callMain + sw (r1+0), r0 + addi r1, r1, 4 + bi .clearBSS + +.callMain: + bi os_start + +.save_all: + addi sp, sp, -132 + sw (sp+REG_X0), r0 + sw (sp+REG_X1), r1 + sw (sp+REG_X2), r2 + sw (sp+REG_X3), r3 + sw (sp+REG_X4), r4 + sw (sp+REG_X5), r5 + sw (sp+REG_X6), r6 + sw (sp+REG_X7), r7 + sw (sp+REG_X8), r8 + sw (sp+REG_X9), r9 + sw (sp+REG_X10), r10 + sw (sp+REG_X11), r11 + sw (sp+REG_X12), r12 + sw (sp+REG_X13), r13 + sw (sp+REG_X14), r14 + sw (sp+REG_X15), r15 + sw (sp+REG_X16), r16 + sw (sp+REG_X17), r17 + sw (sp+REG_X18), r18 + sw (sp+REG_X19), r19 + sw (sp+REG_X20), r20 + sw (sp+REG_X21), r21 + sw (sp+REG_X22), r22 + sw (sp+REG_X23), r23 + sw (sp+REG_X24), r24 + sw (sp+REG_X25), r25 + + sw (sp+REG_GP), r26 + sw (sp+REG_FP), r27 + sw (sp+REG_SP), r28 + + /* reg RA done later */ + + sw (sp+REG_EA), r30 + sw (sp+REG_BA), r31 + + /* ra needs to be moved from initial stack location */ + + lw r1, (sp+ 132) + sw (sp+REG_RA), r1 + + /* the 2nd argument is the regs pointer */ + + addi r2, sp, 0 + ret + +.restore_all_and_eret: + /* r1 should have the place where we restore ! */ + + lw r2, (r1+REG_X2) + lw r3, (r1+REG_X3) + lw r4, (r1+REG_X4) + lw r5, (r1+REG_X5) + lw r6, (r1+REG_X6) + lw r7, (r1+REG_X7) + lw r8, (r1+REG_X8) + lw r9, (r1+REG_X9) + lw r10, (r1+REG_X10) + lw r11, (r1+REG_X11) + lw r12, (r1+REG_X12) + lw r13, (r1+REG_X13) + lw r14, (r1+REG_X14) + lw r15, (r1+REG_X15) + lw r16, (r1+REG_X16) + lw r17, (r1+REG_X17) + lw r18, (r1+REG_X18) + lw r19, (r1+REG_X19) + lw r20, (r1+REG_X20) + lw r21, (r1+REG_X21) + lw r22, (r1+REG_X22) + lw r23, (r1+REG_X23) + lw r24, (r1+REG_X24) + lw r25, (r1+REG_X25) + lw r26, (r1+REG_GP) + lw r27, (r1+REG_FP) + lw r28, (r1+REG_SP) + lw r29, (r1+REG_RA) + lw r30, (r1+REG_EA) + lw r31, (r1+REG_BA) + lw r1, (r1+REG_X1) + addi sp, sp, 132 + eret + + /* This global variable is unsigned long g_idle_topstack and is + * exported from here only because of its coupling to other + * uses of _ebss in this file + */ + + .data + .align 4 + .globl g_idle_topstack + .type g_idle_topstack, object + +g_idle_topstack: + .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .size g_idle_topstack, .-g_idle_topstack + .end From 0088f24603a5e73d503e0ea779712e1ff124f270 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Tue, 1 Nov 2016 12:47:35 -0600 Subject: [PATCH 026/155] MISOC LM32: Add arch/src/common directory --- arch/misoc/Kconfig | 1 - arch/misoc/src/common/Kconfig | 8 -- arch/misoc/src/common/hw/common.h | 49 +++++++ arch/misoc/src/common/hw/ethmac_mem.h | 54 ++++++++ arch/misoc/src/common/hw/flags.h | 79 ++++++++++++ arch/misoc/src/common/misoc_isr.c | 20 --- arch/misoc/src/common/misoc_uart.c | 179 +++++++++++++++++++------- arch/misoc/src/common/misoc_uart.h | 60 +++++++++ arch/misoc/src/lm32/Make.defs | 4 +- arch/misoc/src/lm32/chip.h | 92 +++++++++++++ arch/misoc/src/lm32/lm32_irq.c | 2 +- arch/misoc/src/lm32/lm32_isr.c | 61 +++++++++ 12 files changed, 534 insertions(+), 75 deletions(-) delete mode 100644 arch/misoc/src/common/Kconfig create mode 100644 arch/misoc/src/common/hw/common.h create mode 100644 arch/misoc/src/common/hw/ethmac_mem.h create mode 100644 arch/misoc/src/common/hw/flags.h delete mode 100644 arch/misoc/src/common/misoc_isr.c create mode 100644 arch/misoc/src/common/misoc_uart.h create mode 100644 arch/misoc/src/lm32/chip.h create mode 100644 arch/misoc/src/lm32/lm32_isr.c diff --git a/arch/misoc/Kconfig b/arch/misoc/Kconfig index 74a2a7649b..5cfbf0268c 100644 --- a/arch/misoc/Kconfig +++ b/arch/misoc/Kconfig @@ -62,7 +62,6 @@ config MISOC_UART_TX_BUF_SIZE ---help--- Size of TX buffers for MISOC UARTs -source arch/misoc/src/common/Kconfig ifdef ARCH_CHIP_LM32 source arch/misoc/src/lm32/Kconfig endif diff --git a/arch/misoc/src/common/Kconfig b/arch/misoc/src/common/Kconfig deleted file mode 100644 index 6cd8cd8175..0000000000 --- a/arch/misoc/src/common/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -if ARCH_MISOC - -endif # ARCH_MISOC diff --git a/arch/misoc/src/common/hw/common.h b/arch/misoc/src/common/hw/common.h new file mode 100644 index 0000000000..a6a7a92159 --- /dev/null +++ b/arch/misoc/src/common/hw/common.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/misoc/src/common/hw/common.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_COMMON_HW_COMMON_H +#define __ARCH_MISOC_SRC_COMMON_HW_COMMON_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef __ASSEMBLER__ +# define MMPTR(x) x +#else +# define MMPTR(x) (*((volatile unsigned int *)(x))) +#endif + +#endif /* __ARCH_MISOC_SRC_COMMON_HW_COMMON_H */ diff --git a/arch/misoc/src/common/hw/ethmac_mem.h b/arch/misoc/src/common/hw/ethmac_mem.h new file mode 100644 index 0000000000..6196480912 --- /dev/null +++ b/arch/misoc/src/common/hw/ethmac_mem.h @@ -0,0 +1,54 @@ +/**************************************************************************** + * arch/misoc/src/common/hw/emac_mem.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_COMMON_HW_EMAC_MEM_H +#define __ARCH_MISOC_SRC_COMMON_HW_EMAC_MEM_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ETHMAC_RX0_BASE ETHMAC_BASE +#define ETHMAC_RX1_BASE (ETHMAC_BASE+0x0800) +#define ETHMAC_TX0_BASE (ETHMAC_BASE+0x1000) +#define ETHMAC_TX1_BASE (ETHMAC_BASE+0x1800) + +#endif /* __ARCH_MISOC_SRC_COMMON_HW_EMAC_MEM_H */ diff --git a/arch/misoc/src/common/hw/flags.h b/arch/misoc/src/common/hw/flags.h new file mode 100644 index 0000000000..7ed2f4bf42 --- /dev/null +++ b/arch/misoc/src/common/hw/flags.h @@ -0,0 +1,79 @@ +/**************************************************************************** + * arch/misoc/src/common/hw/emac_mem.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_COMMON_HW_FLAGS_H +#define __ARCH_MISOC_SRC_COMMON_HW_FLAGS_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define UART_EV_TX 0x1 +#define UART_EV_RX 0x2 + +#define DFII_CONTROL_SEL 0x01 +#define DFII_CONTROL_CKE 0x02 +#define DFII_CONTROL_ODT 0x04 +#define DFII_CONTROL_RESET_N 0x08 + +#define DFII_COMMAND_CS 0x01 +#define DFII_COMMAND_WE 0x02 +#define DFII_COMMAND_CAS 0x04 +#define DFII_COMMAND_RAS 0x08 +#define DFII_COMMAND_WRDATA 0x10 +#define DFII_COMMAND_RDDATA 0x20 + +#define ETHMAC_EV_SRAM_WRITER 0x1 +#define ETHMAC_EV_SRAM_READER 0x1 + +#define CLKGEN_STATUS_BUSY 0x1 +#define CLKGEN_STATUS_PROGDONE 0x2 +#define CLKGEN_STATUS_LOCKED 0x4 + +#define DVISAMPLER_TOO_LATE 0x1 +#define DVISAMPLER_TOO_EARLY 0x2 + +#define DVISAMPLER_DELAY_MASTER_CAL 0x01 +#define DVISAMPLER_DELAY_MASTER_RST 0x02 +#define DVISAMPLER_DELAY_SLAVE_CAL 0x04 +#define DVISAMPLER_DELAY_SLAVE_RST 0x08 +#define DVISAMPLER_DELAY_INC 0x10 +#define DVISAMPLER_DELAY_DEC 0x20 + +#define DVISAMPLER_SLOT_EMPTY 0 +#define DVISAMPLER_SLOT_LOADED 1 +#define DVISAMPLER_SLOT_PENDING 2 + +#endif /* __ARCH_MISOC_SRC_COMMON_HW_FLAGS_H */ diff --git a/arch/misoc/src/common/misoc_isr.c b/arch/misoc/src/common/misoc_isr.c deleted file mode 100644 index 96c726b17c..0000000000 --- a/arch/misoc/src/common/misoc_isr.c +++ /dev/null @@ -1,20 +0,0 @@ -#include - -void uart_isr(); -void uart_isr() -{ - -} - -void isr(void); -void isr(void) -{ - unsigned int irqs; - - irqs = irq_pending() & irq_getmask(); - - if (irqs & (1 << UART_INTERRUPT)) - { - uart_isr(); - } -} diff --git a/arch/misoc/src/common/misoc_uart.c b/arch/misoc/src/common/misoc_uart.c index 7a36e78199..77410f5071 100644 --- a/arch/misoc/src/common/misoc_uart.c +++ b/arch/misoc/src/common/misoc_uart.c @@ -1,3 +1,42 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_uart.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 @@ -20,11 +59,15 @@ #include #include "hw/flags.h" -#include "misoc_irqasm.h" +#include "chip.h" #include "misoc_uart.h" #include "lm32.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + /* Buffer sizes must be a power of 2 so that modulos can be computed * with logical AND. */ @@ -32,91 +75,140 @@ #define UART_RINGBUFFER_SIZE_RX 128 #define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1) +#define UART_RINGBUFFER_SIZE_TX 128 +#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + static char rx_buf[UART_RINGBUFFER_SIZE_RX]; static volatile unsigned int rx_produce; static unsigned int rx_consume; -#define UART_RINGBUFFER_SIZE_TX 128 -#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) - static char tx_buf[UART_RINGBUFFER_SIZE_TX]; static unsigned int tx_produce; static volatile unsigned int tx_consume; -static int uart_interrupt(int irq, void *context); - +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: uart_interrupt + ****************************************************************************/ + static int uart_interrupt(int irq, void *context) { unsigned int stat, rx_produce_next; stat = uart_ev_pending_read(); - if(stat & UART_EV_RX) { - while(!uart_rxempty_read()) { - rx_produce_next = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX; - if(rx_produce_next != rx_consume) { - rx_buf[rx_produce] = uart_rxtx_read(); - rx_produce = rx_produce_next; - } - uart_ev_pending_write(UART_EV_RX); - } - } + if ((stat & UART_EV_RX) != 0) + { + while (!uart_rxempty_read()) + { + rx_produce_next = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX; + if (rx_produce_next != rx_consume) + { + rx_buf[rx_produce] = uart_rxtx_read(); + rx_produce = rx_produce_next; + } - if(stat & UART_EV_TX) { - uart_ev_pending_write(UART_EV_TX); - while((tx_consume != tx_produce) && !uart_txfull_read()) { - uart_rxtx_write(tx_buf[tx_consume]); - tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + uart_ev_pending_write(UART_EV_RX); + } + } + + if ((stat & UART_EV_TX) != 0) + { + uart_ev_pending_write(UART_EV_TX); + while ((tx_consume != tx_produce) && !uart_txfull_read()) + { + uart_rxtx_write(tx_buf[tx_consume]); + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } } - } return OK; } -/* Do not use in interrupt handlers! */ +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: uart_read + * + * Do not use in interrupt handlers! + * + ****************************************************************************/ + char uart_read(void) { char c; - if(irq_getie()) { - while(rx_consume == rx_produce); - } else if (rx_consume == rx_produce) { - return 0; - } + if (irq_getie()) + { + while (rx_consume == rx_produce); + } + else if (rx_consume == rx_produce) + { + return 0; + } c = rx_buf[rx_consume]; rx_consume = (rx_consume + 1) & UART_RINGBUFFER_MASK_RX; return c; } +/**************************************************************************** + * Name: uart_read_nonblock + ****************************************************************************/ + int uart_read_nonblock(void) { return (rx_consume != rx_produce); } +/**************************************************************************** + * Name: up_putc + ****************************************************************************/ + int up_putc(int ch) { unsigned int oldmask; unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; - if(irq_getie()) { - while(tx_produce_next == tx_consume); - } else if(tx_produce_next == tx_consume) { - return ch; - } + if (irq_getie()) + { + while (tx_produce_next == tx_consume); + } + else if (tx_produce_next == tx_consume) + { + return ch; + } oldmask = irq_getmask(); irq_setmask(oldmask & ~(1 << UART_INTERRUPT)); - if((tx_consume != tx_produce) || uart_txfull_read()) { - tx_buf[tx_produce] = ch; - tx_produce = tx_produce_next; - } else { - uart_rxtx_write(ch); - } + + if ((tx_consume != tx_produce) || uart_txfull_read()) + { + tx_buf[tx_produce] = ch; + tx_produce = tx_produce_next; + } + else + { + uart_rxtx_write(ch); + } + irq_setmask(oldmask); return ch; } +/**************************************************************************** + * Name: uart_init + ****************************************************************************/ + void uart_init(void) { rx_produce = 0; @@ -132,10 +224,11 @@ void uart_init(void) irq_attach(1 << UART_INTERRUPT, uart_interrupt); } +/**************************************************************************** + * Name: uart_sync + ****************************************************************************/ + void uart_sync(void) { - while(tx_consume != tx_produce); + while (tx_consume != tx_produce); } - - - diff --git a/arch/misoc/src/common/misoc_uart.h b/arch/misoc/src/common/misoc_uart.h new file mode 100644 index 0000000000..74fcc7c0ac --- /dev/null +++ b/arch/misoc/src/common/misoc_uart.h @@ -0,0 +1,60 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_uart.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_COMMON_MISOC_UART_H +#define __ARCH_MISOC_SRC_COMMON_MISOC_UART_H 1 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +void uart_init(void); +void uart_isr(void); +void uart_sync(void); + +void uart_write(char c); +char uart_read(void); +int uart_read_nonblock(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __ARCH_MISOC_SRC_COMMON_MISOC_UART_H */ diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index 1c12e0c527..1a0ce75de2 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -45,5 +45,5 @@ CHIP_CSRCS = lm32_allocateheap.c lm32_assert.c lm32_blocktask.c CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_doirq.c lm32_dumpstate.c CHIP_CSRCS += lm32_dumpstate.c lm32_exit.c lm32_idle.c lm32_initialize.c CHIP_CSRCS += lm32_initialstate.c lm32_interruptcontext.c lm32_irq.c -CHIP_CSRCS += lm32_releasepending.c lm32_releasestack.c lm32_stackframe.c -CHIP_CSRCS += lm32_swint.c lm32_unblocktask.c +CHIP_CSRCS += lm32_isr.c lm32_releasepending.c lm32_releasestack.c +CHIP_CSRCS += lm32_stackframe.c lm32_swint.c lm32_unblocktask.c diff --git a/arch/misoc/src/lm32/chip.h b/arch/misoc/src/lm32/chip.h new file mode 100644 index 0000000000..0683bd5a28 --- /dev/null +++ b/arch/misoc/src/lm32/chip.h @@ -0,0 +1,92 @@ +/**************************************************************************** + * arch/misoc/src/lm32/chip.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_LM32_CHIP_H +#define __ARCH_MISOC_SRC_LM32_CHIP_H 1 + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#ifdef __cplusplus +extern "C" +{ +#endif + +static inline unsigned int irq_getie(void) +{ + unsigned int ie; + __asm__ __volatile__("rcsr %0, IE" : "=r" (ie)); + return ie; +} + +static inline void irq_setie(unsigned int ie) +{ + __asm__ __volatile__("wcsr IE, %0" : : "r" (ie)); +} + +static inline unsigned int irq_getmask(void) +{ + + unsigned int mask; + __asm__ __volatile__("rcsr %0, IM" : "=r" (mask)); + return mask; +} + +static inline void irq_setmask(unsigned int mask) +{ + __asm__ __volatile__("wcsr IM, %0" : : "r" (mask)); +} + +static inline unsigned int irq_pending(void) +{ + + unsigned int pending; + __asm__ __volatile__("rcsr %0, IP" : "=r" (pending)); + return pending; +} + +#ifdef __cplusplus +} +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +void uart_isr(void); +void isr(void); + +#endif /* __ARCH_MISOC_SRC_LM32_CHIP_H */ diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index b99bb443b4..2e01b511fd 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -46,7 +46,7 @@ #include #include -#include "misoc_irqasm.h" +#include "chip_irqasm.h" #include "lm32.h" /**************************************************************************** diff --git a/arch/misoc/src/lm32/lm32_isr.c b/arch/misoc/src/lm32/lm32_isr.c new file mode 100644 index 0000000000..539614d317 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_isr.c @@ -0,0 +1,61 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_isr.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 "chip_irqasm.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void uart_isr() +{ +} + +void isr(void) +{ + unsigned int irqs; + + irqs = irq_pending() & irq_getmask(); + + if (irqs & (1 << UART_INTERRUPT)) + { + uart_isr(); + } +} From 1787a8143ee405ca0b64b7e6f9466893d388036e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 1 Nov 2016 14:18:21 -0600 Subject: [PATCH 027/155] Misoc: Logic on common directory should not include ANY lm32 specific header file. The generic header file chip.h can be exported by all architectures and that is what should be included instead of lm32.h which is an inappropriate dependency. --- arch/misoc/src/common/misoc_uart.c | 3 +-- arch/misoc/src/lm32/chip.h | 6 ++++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/misoc/src/common/misoc_uart.c b/arch/misoc/src/common/misoc_uart.c index 77410f5071..76cdd48703 100644 --- a/arch/misoc/src/common/misoc_uart.c +++ b/arch/misoc/src/common/misoc_uart.c @@ -59,10 +59,9 @@ #include #include "hw/flags.h" -#include "chip.h" #include "misoc_uart.h" -#include "lm32.h" +#include "chip.h" /**************************************************************************** * Pre-processor Definitions diff --git a/arch/misoc/src/lm32/chip.h b/arch/misoc/src/lm32/chip.h index 0683bd5a28..bdb8823c5a 100644 --- a/arch/misoc/src/lm32/chip.h +++ b/arch/misoc/src/lm32/chip.h @@ -36,6 +36,12 @@ #ifndef __ARCH_MISOC_SRC_LM32_CHIP_H #define __ARCH_MISOC_SRC_LM32_CHIP_H 1 +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +#include "lm32.h" + /**************************************************************************** * Inline Functions ****************************************************************************/ From 19f5a5f49de34dd62f22e5114d2b783d2ef9837b Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Tue, 1 Nov 2016 16:14:18 -0600 Subject: [PATCH 028/155] MISOC LM32: configs/misoc board support for testing --- configs/misoc/Kconfig | 4 + configs/misoc/hello/Make.defs | 101 +++ configs/misoc/hello/defconfig | 609 ++++++++++++++++++ configs/misoc/hello/setenv.sh | 64 ++ configs/misoc/include/board.h | 100 +++ configs/misoc/include/generated/common.h | 49 ++ configs/misoc/include/generated/csr.h | 397 ++++++++++++ configs/misoc/include/generated/mem.h | 52 ++ .../misoc/include/generated/output_format.ld | 1 + configs/misoc/include/generated/regions.ld | 6 + configs/misoc/include/generated/sdram_phy.h | 144 +++++ configs/misoc/include/generated/variables.mak | 11 + configs/misoc/scripts/ld.script | 106 +++ configs/misoc/src/.gitignore | 2 + configs/misoc/src/Makefile | 42 ++ configs/misoc/src/lm32_boot.c | 68 ++ configs/misoc/src/misoc.h | 102 +++ 17 files changed, 1858 insertions(+) create mode 100644 configs/misoc/Kconfig create mode 100644 configs/misoc/hello/Make.defs create mode 100644 configs/misoc/hello/defconfig create mode 100644 configs/misoc/hello/setenv.sh create mode 100644 configs/misoc/include/board.h create mode 100644 configs/misoc/include/generated/common.h create mode 100644 configs/misoc/include/generated/csr.h create mode 100644 configs/misoc/include/generated/mem.h create mode 100644 configs/misoc/include/generated/output_format.ld create mode 100644 configs/misoc/include/generated/regions.ld create mode 100644 configs/misoc/include/generated/sdram_phy.h create mode 100644 configs/misoc/include/generated/variables.mak create mode 100644 configs/misoc/scripts/ld.script create mode 100644 configs/misoc/src/.gitignore create mode 100644 configs/misoc/src/Makefile create mode 100644 configs/misoc/src/lm32_boot.c create mode 100644 configs/misoc/src/misoc.h diff --git a/configs/misoc/Kconfig b/configs/misoc/Kconfig new file mode 100644 index 0000000000..f72f3c094c --- /dev/null +++ b/configs/misoc/Kconfig @@ -0,0 +1,4 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# diff --git a/configs/misoc/hello/Make.defs b/configs/misoc/hello/Make.defs new file mode 100644 index 0000000000..b6124b7759 --- /dev/null +++ b/configs/misoc/hello/Make.defs @@ -0,0 +1,101 @@ +############################################################################ +# configs/misoc/hello/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Ramtin Amin +# +# 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. +# +############################################################################ + +include ${TOPDIR}/.config +include ${TOPDIR}/tools/Config.mk +CROSSDEV = lm32-elf- + +LDSCRIPT = ld.script + +ifeq ($(WINTOOL),y) + # Windows-native toolchains + DIRLINK = $(TOPDIR)/tools/copydir.sh + DIRUNLINK = $(TOPDIR)/tools/unlink.sh + MKDEP = $(TOPDIR)/tools/mkwindeps.sh + ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" + ARCHXXINCLUDES = $(ARCHINCLUDES) "${shell cygpath -w $(TOPDIR)/include/cxx}" + ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}" +else + # Linux/Cygwin-native toolchain + MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT) + ARCHINCLUDES = -I. -isystem "$(TOPDIR)/include" + ARCHXXINCLUDES = $(ARCHINCLUDES) -isystem "$(TOPDIR)/include/cxx" + ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD_CUSTOM_NAME)/scripts/$(LDSCRIPT) +endif + +CC = $(CROSSDEV)gcc +CXX = $(CROSSDEV)g++ +CPP = $(CROSSDEV)gcc -E +LD = $(CROSSDEV)ld +AR = $(CROSSDEV)ar rcs +NM = $(CROSSDEV)nm +OBJCOPY = $(CROSSDEV)objcopy +OBJDUMP = $(CROSSDEV)objdump + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer +endif + +ARCHCFLAGS = -fno-builtin +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef +ARCHDEFINES = + +CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +AFLAGS = $(CFLAGS) -D__ASSEMBLY__ + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-gotoff.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +ASMEXT = .S +OBJEXT = .o +LIBEXT = .a +EXEEXT = + + +HOSTCC = gcc +HOSTINCLUDES = -I. +HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe +HOSTLDFLAGS = diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig new file mode 100644 index 0000000000..99c0c9ef2c --- /dev/null +++ b/configs/misoc/hello/defconfig @@ -0,0 +1,609 @@ +# +# Automatically generated file; DO NOT EDIT. +# Nuttx/ Configuration +# + +# +# Build Setup +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_DEFAULT_SMALL=y +CONFIG_HOST_LINUX=y +# CONFIG_HOST_OSX is not set +# CONFIG_HOST_WINDOWS is not set +# CONFIG_HOST_OTHER is not set + +# +# Build Configuration +# +# CONFIG_APPS_DIR="../apps" +CONFIG_BUILD_FLAT=y +# CONFIG_BUILD_2PASS is not set + +# +# Binary Output Formats +# +# CONFIG_RRLOAD_BINARY is not set +# CONFIG_INTELHEX_BINARY is not set +# CONFIG_MOTOROLA_SREC is not set +CONFIG_RAW_BINARY=y +# CONFIG_UBOOT_UIMAGE is not set + +# +# Customize Header Files +# +# CONFIG_ARCH_STDINT_H is not set +# CONFIG_ARCH_STDBOOL_H is not set +# CONFIG_ARCH_MATH_H is not set +# CONFIG_ARCH_FLOAT_H is not set +# CONFIG_ARCH_STDARG_H is not set +# CONFIG_ARCH_DEBUG_H is not set + +# +# Debug Options +# +CONFIG_DEBUG_ALERT=y +CONFIG_DEBUG_FEATURES=y + +# +# Debug SYSLOG Output Controls +# +# CONFIG_DEBUG_ERROR is not set +# CONFIG_DEBUG_ASSERTIONS is not set + +# +# Subsystem Debug Options +# +# CONFIG_DEBUG_BINFMT is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_GRAPHICS is not set +# CONFIG_DEBUG_LIB is not set +# CONFIG_DEBUG_MM is not set +# CONFIG_DEBUG_SCHED is not set + +# +# OS Function Debug Options +# +# CONFIG_DEBUG_IRQ is not set + +# +# Driver Debug Options +# +# CONFIG_DEBUG_GPIO is not set +# CONFIG_DEBUG_TIMER is not set +# CONFIG_ARCH_HAVE_STACKCHECK is not set +# CONFIG_ARCH_HAVE_HEAPCHECK is not set +CONFIG_DEBUG_SYMBOLS=y +# CONFIG_ARCH_HAVE_CUSTOMOPT is not set +CONFIG_DEBUG_NOOPT=y +# CONFIG_DEBUG_FULLOPT is not set + +# +# System Type +# +# CONFIG_ARCH_ARM is not set +# CONFIG_ARCH_AVR is not set +# CONFIG_ARCH_HC is not set +# CONFIG_ARCH_MIPS is not set +CONFIG_ARCH_MISOC=y +# CONFIG_ARCH_RGMP is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_SIM is not set +# CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_Z16 is not set +# CONFIG_ARCH_Z80 is not set +CONFIG_ARCH="misoc" +CONFIG_ARCH_CHIP="lm32" +CONFIG_ARCH_CHIP_LM32=y +# CONFIG_ARCH_CHIP_MOR1K is not set + +# +# Architecture Options +# +# CONFIG_ARCH_NOINTC is not set +# CONFIG_ARCH_VECNOTIRQ is not set +# CONFIG_ARCH_DMA is not set +# CONFIG_ARCH_HAVE_IRQPRIO is not set +# CONFIG_ARCH_L2CACHE is not set +# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set +# CONFIG_ARCH_HAVE_ADDRENV is not set +# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set +# CONFIG_ARCH_HAVE_MULTICPU is not set +# CONFIG_ARCH_HAVE_VFORK is not set +# CONFIG_ARCH_HAVE_MMU is not set +# CONFIG_ARCH_HAVE_MPU is not set +# CONFIG_ARCH_NAND_HWECC is not set +# CONFIG_ARCH_HAVE_EXTCLK is not set +# CONFIG_ARCH_HAVE_POWEROFF is not set +# CONFIG_ARCH_HAVE_RESET is not set +CONFIG_ARCH_STACKDUMP=y +# CONFIG_ENDIAN_BIG is not set +# CONFIG_ARCH_IDLE_CUSTOM is not set +# CONFIG_ARCH_HAVE_RAMFUNCS is not set +# CONFIG_ARCH_HAVE_RAMVECTORS is not set + +# +# Board Settings +# +CONFIG_BOARD_LOOPSPERMSEC=800 +# CONFIG_ARCH_CALIBRATION is not set + +# +# Interrupt options +# +# CONFIG_ARCH_HAVE_INTERRUPTSTACK is not set +# CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set + +# +# Boot options +# +# CONFIG_BOOT_RUNFROMEXTSRAM is not set +CONFIG_BOOT_RUNFROMFLASH=y +# CONFIG_BOOT_RUNFROMISRAM is not set +# CONFIG_BOOT_RUNFROMSDRAM is not set +# CONFIG_BOOT_COPYTORAM is not set + +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x40000000 +CONFIG_RAM_SIZE=524288 +# CONFIG_ARCH_HAVE_SDRAM is not set + +# +# Board Selection +# +CONFIG_ARCH_BOARD_CUSTOM=y + +# +# Custom Board Configuration +# +CONFIG_ARCH_BOARD_CUSTOM_NAME="misoc" +CONFIG_ARCH_BOARD_CUSTOM_DIR="/configs/misoc/" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +# CONFIG_BOARD_CUSTOM_LEDS is not set +# CONFIG_BOARD_CUSTOM_BUTTONS is not set + +# +# Common Board Options +# + +# +# Board-Specific Options +# +# CONFIG_BOARD_CRASHDUMP is not set +# CONFIG_LIB_BOARDCTL is not set + +# +# RTOS Features +# +CONFIG_DISABLE_OS_API=y +CONFIG_DISABLE_POSIX_TIMERS=y +CONFIG_DISABLE_PTHREAD=y +CONFIG_DISABLE_SIGNALS=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_DISABLE_ENVIRON=y + +# +# Clocks and Timers +# +CONFIG_USEC_PER_TICK=10000 +# CONFIG_SYSTEM_TIME64 is not set +# CONFIG_CLOCK_MONOTONIC is not set +# CONFIG_ARCH_HAVE_TIMEKEEPING is not set +# CONFIG_JULIAN_TIME is not set +CONFIG_START_YEAR=2011 +CONFIG_START_MONTH=6 +CONFIG_START_DAY=16 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_PREALLOC_WDOGS=4 +CONFIG_WDOG_INTRESERVE=0 +CONFIG_PREALLOC_TIMERS=0 + +# +# Tasks and Scheduling +# +# CONFIG_INIT_NONE is not set +CONFIG_INIT_ENTRYPOINT=y +# CONFIG_INIT_FILEPATH is not set +CONFIG_USER_ENTRYPOINT="hello_main" +CONFIG_RR_INTERVAL=0 +# CONFIG_SCHED_SPORADIC is not set +CONFIG_TASK_NAME_SIZE=0 +CONFIG_MAX_TASKS=4 +# CONFIG_SCHED_HAVE_PARENT is not set +# CONFIG_SCHED_WAITPID is not set + +# +# Performance Monitoring +# +# CONFIG_SCHED_CPULOAD is not set +# CONFIG_SCHED_INSTRUMENTATION is not set + +# +# Files and I/O +# +CONFIG_DEV_CONSOLE=y +# CONFIG_FDCLONE_DISABLE is not set +# CONFIG_FDCLONE_STDIO is not set +CONFIG_SDCLONE_DISABLE=y +CONFIG_NFILE_DESCRIPTORS=4 +CONFIG_NFILE_STREAMS=4 +CONFIG_NAME_MAX=32 +# CONFIG_PRIORITY_INHERITANCE is not set + +# +# RTOS hooks +# +# CONFIG_BOARD_INITIALIZE is not set +# CONFIG_SCHED_STARTHOOK is not set +# CONFIG_SCHED_ATEXIT is not set +# CONFIG_SCHED_ONEXIT is not set +# CONFIG_MODULE is not set + +# +# Work queue support +# + +# +# Stack and heap information +# +CONFIG_IDLETHREAD_STACKSIZE=512 +CONFIG_USERMAIN_STACKSIZE=512 +CONFIG_PTHREAD_STACK_MIN=256 +CONFIG_PTHREAD_STACK_DEFAULT=1024 +# CONFIG_LIB_SYSCALL is not set + +# +# Device Drivers +# +CONFIG_DISABLE_POLL=y +CONFIG_DEV_NULL=y +# CONFIG_DEV_ZERO is not set +# CONFIG_DEV_URANDOM is not set +# CONFIG_DEV_LOOP is not set + +# +# Buffering +# +# CONFIG_DRVR_WRITEBUFFER is not set +# CONFIG_DRVR_READAHEAD is not set +# CONFIG_RAMDISK is not set +# CONFIG_CAN is not set +# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set +# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set +# CONFIG_PWM is not set +# CONFIG_ARCH_HAVE_I2CRESET is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_I2S is not set + +# +# Timer Driver Support +# +# CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set +# CONFIG_RTC is not set +# CONFIG_WATCHDOG is not set +# CONFIG_ANALOG is not set +# CONFIG_AUDIO_DEVICES is not set +# CONFIG_VIDEO_DEVICES is not set +# CONFIG_BCH is not set +# CONFIG_INPUT is not set + +# +# IO Expander/GPIO Support +# +# CONFIG_IOEXPANDER is not set +# CONFIG_DEV_GPIO is not set + +# +# LCD Driver Support +# +# CONFIG_LCD is not set +# CONFIG_SLCD is not set + +# +# LED Support +# +# CONFIG_RGBLED is not set +# CONFIG_PCA9635PW is not set +# CONFIG_NCP5623C is not set +# CONFIG_MMCSD is not set +# CONFIG_MODEM is not set +# CONFIG_MTD is not set +# CONFIG_EEPROM is not set +# CONFIG_PIPES is not set +# CONFIG_PM is not set +# CONFIG_POWER is not set +# CONFIG_SENSORS is not set +# CONFIG_SERCOMM_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_DEV_LOWCONSOLE=y +# CONFIG_SERIAL_REMOVABLE is not set +# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_16550_UART is not set +# CONFIG_UART_SERIALDRIVER is not set +# CONFIG_UART0_SERIALDRIVER is not set +# CONFIG_UART1_SERIALDRIVER is not set +# CONFIG_UART2_SERIALDRIVER is not set +# CONFIG_UART3_SERIALDRIVER is not set +# CONFIG_UART4_SERIALDRIVER is not set +# CONFIG_UART5_SERIALDRIVER is not set +# CONFIG_UART6_SERIALDRIVER is not set +# CONFIG_UART7_SERIALDRIVER is not set +# CONFIG_UART8_SERIALDRIVER is not set +# CONFIG_SCI0_SERIALDRIVER is not set +# CONFIG_SCI1_SERIALDRIVER is not set +# CONFIG_USART0_SERIALDRIVER is not set +# CONFIG_USART1_SERIALDRIVER is not set +# CONFIG_USART2_SERIALDRIVER is not set +# CONFIG_USART3_SERIALDRIVER is not set +# CONFIG_USART4_SERIALDRIVER is not set +# CONFIG_USART5_SERIALDRIVER is not set +# CONFIG_USART6_SERIALDRIVER is not set +# CONFIG_USART7_SERIALDRIVER is not set +# CONFIG_USART8_SERIALDRIVER is not set +# CONFIG_OTHER_UART_SERIALDRIVER is not set +# CONFIG_MCU_SERIAL is not set +# CONFIG_SERIAL_IFLOWCONTROL is not set +# CONFIG_SERIAL_OFLOWCONTROL is not set +# CONFIG_SERIAL_DMA is not set +# CONFIG_ARCH_HAVE_SERIAL_TERMIOS is not set +# CONFIG_PSEUDOTERM is not set +# CONFIG_USBDEV is not set +# CONFIG_USBHOST is not set +# CONFIG_HAVE_USBTRACE is not set +# CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set + +# +# System Logging +# +# CONFIG_ARCH_SYSLOG is not set +# CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_INTBUFFER is not set +# CONFIG_SYSLOG_TIMESTAMP is not set +# CONFIG_SYSLOG_SERIAL_CONSOLE is not set +# CONFIG_SYSLOG_CHAR is not set +CONFIG_SYSLOG_CONSOLE=y +# CONFIG_SYSLOG_NONE is not set +# CONFIG_SYSLOG_FILE is not set +# CONFIG_SYSLOG_CHARDEV is not set + +# +# Networking Support +# +# CONFIG_ARCH_HAVE_NET is not set +# CONFIG_ARCH_HAVE_PHY is not set +# CONFIG_NET is not set + +# +# Crypto API +# +# CONFIG_CRYPTO is not set + +# +# File Systems +# + +# +# File system configuration +# +CONFIG_DISABLE_MOUNTPOINT=y +CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y +# CONFIG_FS_READABLE is not set +# CONFIG_FS_WRITABLE is not set +# CONFIG_FS_NAMED_SEMAPHORES is not set +# CONFIG_FS_RAMMAP is not set +# CONFIG_FS_PROCFS is not set +# CONFIG_FS_UNIONFS is not set + +# +# Graphics Support +# +# CONFIG_NX is not set + +# +# Memory Management +# +CONFIG_MM_SMALL=y +CONFIG_MM_REGIONS=1 +# CONFIG_ARCH_HAVE_HEAP2 is not set +# CONFIG_GRAN is not set + +# +# Audio Support +# +# CONFIG_AUDIO is not set + +# +# Wireless Support +# + +# +# Binary Loader +# +# CONFIG_BINFMT_DISABLE is not set +# CONFIG_NXFLAT is not set +# CONFIG_ELF is not set +# CONFIG_BUILTIN is not set +# CONFIG_PIC is not set +# CONFIG_SYMTAB_ORDEREDBYNAME is not set + +# +# Library Routines +# + +# +# Standard C Library Options +# +CONFIG_STDIO_BUFFER_SIZE=0 +CONFIG_STDIO_LINEBUFFER=y +CONFIG_NUNGET_CHARS=0 +# CONFIG_LIBM is not set +# CONFIG_NOPRINTF_FIELDWIDTH is not set +# CONFIG_LIBC_FLOATINGPOINT is not set +# CONFIG_LIBC_LONG_LONG is not set +# CONFIG_LIBC_IOCTL_VARIADIC is not set +CONFIG_LIB_RAND_ORDER=1 +# CONFIG_EOL_IS_CR is not set +# CONFIG_EOL_IS_LF is not set +# CONFIG_EOL_IS_BOTH_CRLF is not set +CONFIG_EOL_IS_EITHER_CRLF=y +# CONFIG_LIBC_EXECFUNCS is not set +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 +# CONFIG_LIBC_STRERROR is not set +# CONFIG_LIBC_PERROR_STDOUT is not set +CONFIG_ARCH_LOWPUTC=y +# CONFIG_TIME_EXTENDED is not set +CONFIG_LIB_SENDFILE_BUFSIZE=512 +# CONFIG_ARCH_ROMGETC is not set +# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set +# CONFIG_ARCH_HAVE_TLS is not set +# CONFIG_LIBC_NETDB is not set + +# +# Non-standard Library Support +# +# CONFIG_LIB_CRC64_FAST is not set +# CONFIG_LIB_KBDCODEC is not set +# CONFIG_LIB_SLCDCODEC is not set +# CONFIG_LIB_HEX2BIN is not set + +# +# Basic CXX Support +# +# CONFIG_C99_BOOL8 is not set +# CONFIG_HAVE_CXX is not set + +# +# Application Configuration +# + +# +# CAN Utilities +# + +# +# Examples +# +# CONFIG_EXAMPLES_CHAT is not set +# CONFIG_EXAMPLES_CONFIGDATA is not set +# CONFIG_EXAMPLES_DHCPD is not set +# CONFIG_EXAMPLES_ELF is not set +# CONFIG_EXAMPLES_FTPC is not set +# CONFIG_EXAMPLES_FTPD is not set +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_HELLO_PRIORITY=100 +CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 +# CONFIG_EXAMPLES_HIDKBD is not set +# CONFIG_EXAMPLES_IGMP is not set +# CONFIG_EXAMPLES_JSON is not set +# CONFIG_EXAMPLES_KEYPADTEST is not set +# CONFIG_EXAMPLES_MEDIA is not set +# CONFIG_EXAMPLES_MM is not set +# CONFIG_EXAMPLES_MODBUS is not set +# CONFIG_EXAMPLES_MOUNT is not set +# CONFIG_EXAMPLES_NRF24L01TERM is not set +# CONFIG_EXAMPLES_NSH is not set +# CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NXFFS is not set +# CONFIG_EXAMPLES_NXHELLO is not set +# CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set +# CONFIG_EXAMPLES_NXLINES is not set +# CONFIG_EXAMPLES_NXTERM is not set +# CONFIG_EXAMPLES_NXTEXT is not set +# CONFIG_EXAMPLES_OSTEST is not set +# CONFIG_EXAMPLES_PCA9635 is not set +# CONFIG_EXAMPLES_POSIXSPAWN is not set +# CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set +# CONFIG_EXAMPLES_RGBLED is not set +# CONFIG_EXAMPLES_RGMP is not set +# CONFIG_EXAMPLES_SENDMAIL is not set +# CONFIG_EXAMPLES_SERIALBLASTER is not set +# CONFIG_EXAMPLES_SERIALRX is not set +# CONFIG_EXAMPLES_SERLOOP is not set +# CONFIG_EXAMPLES_SLCD is not set +# CONFIG_EXAMPLES_SMART is not set +# CONFIG_EXAMPLES_SMP is not set +# CONFIG_EXAMPLES_TCPECHO is not set +# CONFIG_EXAMPLES_TELNETD is not set +# CONFIG_EXAMPLES_TIFF is not set +# CONFIG_EXAMPLES_TOUCHSCREEN is not set +# CONFIG_EXAMPLES_USBTERM is not set +# CONFIG_EXAMPLES_WATCHDOG is not set +# CONFIG_EXAMPLES_WEBSERVER is not set + +# +# File System Utilities +# +# CONFIG_FSUTILS_INIFILE is not set + +# +# GPS Utilities +# +# CONFIG_GPSUTILS_MINMEA_LIB is not set + +# +# Graphics Support +# +# CONFIG_TIFF is not set +# CONFIG_GRAPHICS_TRAVELER is not set + +# +# Interpreters +# +# CONFIG_INTERPRETERS_FICL is not set +# CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set +# CONFIG_INTERPRETERS_PCODE is not set + +# +# FreeModBus +# +# CONFIG_MODBUS is not set + +# +# Network Utilities +# +# CONFIG_NETUTILS_CODECS is not set +# CONFIG_NETUTILS_ESP8266 is not set +# CONFIG_NETUTILS_FTPC is not set +# CONFIG_NETUTILS_JSON is not set +# CONFIG_NETUTILS_SMTP is not set + +# +# NSH Library +# +# CONFIG_NSH_LIBRARY is not set + +# +# NxWidgets/NxWM +# + +# +# Platform-specific Support +# +# CONFIG_PLATFORM_CONFIGDATA is not set + +# +# System Libraries and NSH Add-Ons +# +# CONFIG_SYSTEM_CLE is not set +# CONFIG_SYSTEM_CUTERM is not set +# CONFIG_SYSTEM_FREE is not set +# CONFIG_SYSTEM_HEX2BIN is not set +# CONFIG_SYSTEM_HEXED is not set +# CONFIG_SYSTEM_INSTALL is not set +# CONFIG_SYSTEM_RAMTEST is not set +# CONFIG_READLINE_HAVE_EXTMATCH is not set +# CONFIG_SYSTEM_READLINE is not set +# CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_TEE is not set +# CONFIG_SYSTEM_UBLOXMODEM is not set +# CONFIG_SYSTEM_VI is not set +# CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/misoc/hello/setenv.sh b/configs/misoc/hello/setenv.sh new file mode 100644 index 0000000000..c66c878239 --- /dev/null +++ b/configs/misoc/hello/setenv.sh @@ -0,0 +1,64 @@ +#!/bin/bash +# configs/amber/hello/setenv.sh +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Ramtin Amin +# +# 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. +# + +if [ "$_" = "$0" ] ; then + echo "You must source this script, not run it!" 1>&2 + exit 1 +fi + +WD=`pwd` +if [ ! -x "setenv.sh" ]; then + echo "This script must be executed from the top-level NuttX build directory" + exit 1 +fi + +if [ -z "${PATH_ORIG}" ]; then + export PATH_ORIG="${PATH}" +fi + +# This is the Cygwin path to the location where I installed the WinAVR +# toolchain under windows. This is *not* the default install +# location so you will probably have to edit this. You will also have +# to edit this if you install the Linux AVR toolchain as well +#export TOOLCHAIN_BIN="/cygdrive/c/WinAVR/bin" + +# This is the Cygwin path to the location where I build the buildroot +# toolchain. +#export TOOLCHAIN_BIN="${WD}/../buildroot/build_avr/staging_dir/bin" + +# Add the path to the toolchain to the PATH varialble +#export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" + +echo "PATH : ${PATH}" diff --git a/configs/misoc/include/board.h b/configs/misoc/include/board.h new file mode 100644 index 0000000000..8db2fcc7cf --- /dev/null +++ b/configs/misoc/include/board.h @@ -0,0 +1,100 @@ +/**************************************************************************** + * configs/misoc/include/board.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 __CONFIGS_AMBER_INCLUDE_BOARD_H +#define __CONFIGS_AMBER_INCLUDE_BOARD_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Clocking *****************************************************************/ +/* Assume default CLKDIV8 fuse setting is overridden to CLKDIV1 */ + +#define BOARD_XTAL_FREQ 14745600 /* 14.7456MHz crystal */ +#define BOARD_CPU_CLOCK BOARD_XTAL_FREQ /* F_CPU = 14.7456MHz */ +#define BOARD_TOSCK_CLOCK 32768 /* TOSC = 32.768KHz */ + +/* LED definitions **********************************************************/ +/* The Amber Web Server has a reset switch and four LEDs. The LEDs indicate + * the status of power, programming state, Ethernet link status and reset + * status (Active). None are available for software use. + */ + +#define LED_STARTED 0 +#define LED_HEAPALLOCATE 1 +#define LED_IRQSENABLED 2 +#define LED_STACKCREATED 3 +#define LED_INIRQ 4 +#define LED_SIGNAL 5 +#define LED_ASSERTION 6 +#define LED_PANIC 7 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __CONFIGS_AMBER_INCLUDE_BOARD_H */ diff --git a/configs/misoc/include/generated/common.h b/configs/misoc/include/generated/common.h new file mode 100644 index 0000000000..38859deefa --- /dev/null +++ b/configs/misoc/include/generated/common.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * configs/misoc/include/generated/common.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __CONFIGS_MISOC_INCLUDE_GENERATED_COMMON_H +#define __CONFIGS_MISOC_INCLUDE_GENERATED_COMMON_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifdef __ASSEMBLER__ +# define MMPTR(x) x +#else +# define MMPTR(x) (*((volatile unsigned int *)(x))) +#endif + +#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_COMMON_H */ diff --git a/configs/misoc/include/generated/csr.h b/configs/misoc/include/generated/csr.h new file mode 100644 index 0000000000..64bd1915a1 --- /dev/null +++ b/configs/misoc/include/generated/csr.h @@ -0,0 +1,397 @@ +/**************************************************************************** + * configs/misoc/include/generated/csr.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __CONFIGS_MISOC_INCLUDE_GENERATED_CSR_H +#define __CONFIGS_MISOC_INCLUDE_GENERATED_CSR_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include "hw/common.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* SDRAM */ + +#define CSR_SDRAM_BASE 0xe0004000 +#define CSR_SDRAM_DFII_CONTROL_ADDR 0xe0004000 +#define CSR_SDRAM_DFII_CONTROL_SIZE 1 + +#define CSR_SDRAM_DFII_PI0_COMMAND_ADDR 0xe0004004 +#define CSR_SDRAM_DFII_PI0_COMMAND_SIZE 1 + +#define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_ADDR 0xe0004008 +#define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_SIZE 1 + +#define CSR_SDRAM_DFII_PI0_ADDRESS_ADDR 0xe000400c +#define CSR_SDRAM_DFII_PI0_ADDRESS_SIZE 2 + +#define CSR_SDRAM_DFII_PI0_BADDRESS_ADDR 0xe0004014 +#define CSR_SDRAM_DFII_PI0_BADDRESS_SIZE 1 + +#define CSR_SDRAM_DFII_PI0_WRDATA_ADDR 0xe0004018 +#define CSR_SDRAM_DFII_PI0_WRDATA_SIZE 2 + +#define CSR_SDRAM_DFII_PI0_RDDATA_ADDR 0xe0004020 +#define CSR_SDRAM_DFII_PI0_RDDATA_SIZE 2 + +#define CSR_TIMER0_BASE 0xe0002000 +#define CSR_TIMER0_LOAD_ADDR 0xe0002000 +#define CSR_TIMER0_LOAD_SIZE 4 + +#define CSR_TIMER0_RELOAD_ADDR 0xe0002010 +#define CSR_TIMER0_RELOAD_SIZE 4 + +#define CSR_TIMER0_EN_ADDR 0xe0002020 +#define CSR_TIMER0_EN_SIZE 1 + +#define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002024 +#define CSR_TIMER0_UPDATE_VALUE_SIZE 1 + +#define CSR_TIMER0_VALUE_ADDR 0xe0002028 +#define CSR_TIMER0_VALUE_SIZE 4 + +#define CSR_TIMER0_EV_STATUS_ADDR 0xe0002038 +#define CSR_TIMER0_EV_STATUS_SIZE 1 + +#define CSR_TIMER0_EV_PENDING_ADDR 0xe000203c +#define CSR_TIMER0_EV_PENDING_SIZE 1 + +#define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002040 +#define CSR_TIMER0_EV_ENABLE_SIZE 1 + +#define CSR_UART_TXFULL_ADDR 0xe0001004 +#define CSR_UART_TXFULL_SIZE 1 + +#define CSR_UART_RXEMPTY_ADDR 0xe0001008 +#define CSR_UART_RXEMPTY_SIZE 1 + +#define CSR_UART_EV_STATUS_ADDR 0xe000100c +#define CSR_UART_EV_STATUS_SIZE 1 + +#define CSR_UART_EV_PENDING_ADDR 0xe0001010 +#define CSR_UART_EV_PENDING_SIZE 1 + +#define CSR_UART_EV_ENABLE_ADDR 0xe0001014 +#define CSR_UART_EV_ENABLE_SIZE 1 + +#define CSR_UART_PHY_BASE 0xe0000800 +#define CSR_UART_PHY_TUNING_WORD_ADDR 0xe0000800 +#define CSR_UART_PHY_TUNING_WORD_SIZE 4 + +/* Constants */ + +#define UART_INTERRUPT 0 +#define TIMER0_INTERRUPT 1 +#define SYSTEM_CLOCK_FREQUENCY 80000000 +#define L2_SIZE 8192 + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +static inline unsigned char sdram_dfii_control_read(void) +{ + unsigned char r = MMPTR(0xe0004000); + return r; +} + +static inline void sdram_dfii_control_write(unsigned char value) +{ + MMPTR(0xe0004000) = value; +} + +static inline unsigned char sdram_dfii_pi0_command_read(void) +{ + unsigned char r = MMPTR(0xe0004004); + return r; +} + +static inline void sdram_dfii_pi0_command_write(unsigned char value) +{ + MMPTR(0xe0004004) = value; +} + +static inline unsigned char sdram_dfii_pi0_command_issue_read(void) +{ + unsigned char r = MMPTR(0xe0004008); + return r; +} + +static inline void sdram_dfii_pi0_command_issue_write(unsigned char value) +{ + MMPTR(0xe0004008) = value; +} + +static inline unsigned short int sdram_dfii_pi0_address_read(void) +{ + unsigned short int r = MMPTR(0xe000400c); + r <<= 8; + r |= MMPTR(0xe0004010); + return r; +} + +static inline void sdram_dfii_pi0_address_write(unsigned short int value) +{ + MMPTR(0xe000400c) = value >> 8; + MMPTR(0xe0004010) = value; +} + +static inline unsigned char sdram_dfii_pi0_baddress_read(void) +{ + unsigned char r = MMPTR(0xe0004014); + return r; +} + +static inline void sdram_dfii_pi0_baddress_write(unsigned char value) +{ + MMPTR(0xe0004014) = value; +} + +static inline unsigned short int sdram_dfii_pi0_wrdata_read(void) +{ + unsigned short int r = MMPTR(0xe0004018); + r <<= 8; + r |= MMPTR(0xe000401c); + return r; +} + +static inline void sdram_dfii_pi0_wrdata_write(unsigned short int value) +{ + MMPTR(0xe0004018) = value >> 8; + MMPTR(0xe000401c) = value; +} + +static inline unsigned short int sdram_dfii_pi0_rddata_read(void) +{ + unsigned short int r = MMPTR(0xe0004020); + r <<= 8; + r |= MMPTR(0xe0004024); + return r; +} + +/* Timer0 */ + +static inline unsigned int timer0_load_read(void) +{ + unsigned int r = MMPTR(0xe0002000); + r <<= 8; + r |= MMPTR(0xe0002004); + r <<= 8; + r |= MMPTR(0xe0002008); + r <<= 8; + r |= MMPTR(0xe000200c); + return r; +} + +static inline void timer0_load_write(unsigned int value) +{ + MMPTR(0xe0002000) = value >> 24; + MMPTR(0xe0002004) = value >> 16; + MMPTR(0xe0002008) = value >> 8; + MMPTR(0xe000200c) = value; +} + +static inline unsigned int timer0_reload_read(void) +{ + unsigned int r = MMPTR(0xe0002010); + r <<= 8; + r |= MMPTR(0xe0002014); + r <<= 8; + r |= MMPTR(0xe0002018); + r <<= 8; + r |= MMPTR(0xe000201c); + return r; +} + +static inline void timer0_reload_write(unsigned int value) +{ + MMPTR(0xe0002010) = value >> 24; + MMPTR(0xe0002014) = value >> 16; + MMPTR(0xe0002018) = value >> 8; + MMPTR(0xe000201c) = value; +} + +static inline unsigned char timer0_en_read(void) +{ + unsigned char r = MMPTR(0xe0002020); + return r; +} + +static inline void timer0_en_write(unsigned char value) +{ + MMPTR(0xe0002020) = value; +} + +static inline unsigned char timer0_update_value_read(void) +{ + unsigned char r = MMPTR(0xe0002024); + return r; +} + +static inline void timer0_update_value_write(unsigned char value) +{ + MMPTR(0xe0002024) = value; +} + +static inline unsigned int timer0_value_read(void) +{ + unsigned int r = MMPTR(0xe0002028); + r <<= 8; + r |= MMPTR(0xe000202c); + r <<= 8; + r |= MMPTR(0xe0002030); + r <<= 8; + r |= MMPTR(0xe0002034); + return r; +} + +static inline unsigned char timer0_ev_status_read(void) +{ + unsigned char r = MMPTR(0xe0002038); + return r; +} + +static inline void timer0_ev_status_write(unsigned char value) +{ + MMPTR(0xe0002038) = value; +} + +static inline unsigned char timer0_ev_pending_read(void) +{ + unsigned char r = MMPTR(0xe000203c); + return r; +} + +static inline void timer0_ev_pending_write(unsigned char value) +{ + MMPTR(0xe000203c) = value; +} + +static inline unsigned char timer0_ev_enable_read(void) +{ + unsigned char r = MMPTR(0xe0002040); + return r; +} + +static inline void timer0_ev_enable_write(unsigned char value) +{ + MMPTR(0xe0002040) = value; +} + +/* UART */ + +static inline unsigned char uart_rxtx_read(void) +{ + unsigned char r = MMPTR(0xe0001000); + return r; +} + +static inline void uart_rxtx_write(unsigned char value) +{ + MMPTR(0xe0001000) = value; +} + +static inline unsigned char uart_txfull_read(void) +{ + unsigned char r = MMPTR(0xe0001004); + return r; +} + +static inline unsigned char uart_rxempty_read(void) +{ + unsigned char r = MMPTR(0xe0001008); + return r; +} + +static inline unsigned char uart_ev_status_read(void) +{ + unsigned char r = MMPTR(0xe000100c); + return r; +} + +static inline void uart_ev_status_write(unsigned char value) +{ + MMPTR(0xe000100c) = value; +} + +static inline unsigned char uart_ev_pending_read(void) +{ + unsigned char r = MMPTR(0xe0001010); + return r; +} + +static inline void uart_ev_pending_write(unsigned char value) +{ + MMPTR(0xe0001010) = value; +} + +static inline unsigned char uart_ev_enable_read(void) +{ + unsigned char r = MMPTR(0xe0001014); + return r; +} + +static inline void uart_ev_enable_write(unsigned char value) +{ + MMPTR(0xe0001014) = value; +} + +/* uart_phy */ + +static inline unsigned int uart_phy_tuning_word_read(void) +{ + unsigned int r = MMPTR(0xe0000800); + r <<= 8; + r |= MMPTR(0xe0000804); + r <<= 8; + r |= MMPTR(0xe0000808); + r <<= 8; + r |= MMPTR(0xe000080c); + return r; +} + +static inline void uart_phy_tuning_word_write(unsigned int value) +{ + MMPTR(0xe0000800) = value >> 24; + MMPTR(0xe0000804) = value >> 16; + MMPTR(0xe0000808) = value >> 8; + MMPTR(0xe000080c) = value; +} + +#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_CSR_H */ diff --git a/configs/misoc/include/generated/mem.h b/configs/misoc/include/generated/mem.h new file mode 100644 index 0000000000..dd6b512e91 --- /dev/null +++ b/configs/misoc/include/generated/mem.h @@ -0,0 +1,52 @@ +/**************************************************************************** + * configs/misoc/include/generated/mem.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __CONFIGS_MISOC_INCLUDE_GENERATED_MEM_H +#define __CONFIGS_MISOC_INCLUDE_GENERATED_MEM_H + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ROM_BASE 0x00000000 +#define ROM_SIZE 0x00008000 + +#define SRAM_BASE 0x10000000 +#define SRAM_SIZE 0x00001000 + +#define MAIN_RAM_BASE 0x40000000 +#define MAIN_RAM_SIZE 0x00800000 + +#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_MEM_H / diff --git a/configs/misoc/include/generated/output_format.ld b/configs/misoc/include/generated/output_format.ld new file mode 100644 index 0000000000..72acc74d0f --- /dev/null +++ b/configs/misoc/include/generated/output_format.ld @@ -0,0 +1 @@ +OUTPUT_FORMAT("elf32-lm32") diff --git a/configs/misoc/include/generated/regions.ld b/configs/misoc/include/generated/regions.ld new file mode 100644 index 0000000000..bd7502729b --- /dev/null +++ b/configs/misoc/include/generated/regions.ld @@ -0,0 +1,6 @@ +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 + sram : ORIGIN = 0x10000000, LENGTH = 0x00001000 + main_ram : ORIGIN = 0x40000000, LENGTH = 0x00800000 +} diff --git a/configs/misoc/include/generated/sdram_phy.h b/configs/misoc/include/generated/sdram_phy.h new file mode 100644 index 0000000000..2161b7d5b9 --- /dev/null +++ b/configs/misoc/include/generated/sdram_phy.h @@ -0,0 +1,144 @@ +/**************************************************************************** + * configs/misoc/include/generated/common.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 __CONFIGS_MISOC_INCLUDE_GENERATED_SDRAM_PHY_H +#define __CONFIGS_MISOC_INCLUDE_GENERATED_SDRAM_PHY_H + +/**************************************************************************** + * Included Filese + ****************************************************************************/ + +#include "hw/common.h" +#include "hw/flags.h" + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DFII_NPHASES 1 + +#define sdram_dfii_pird_address_write(X) sdram_dfii_pi0_address_write(X) +#define sdram_dfii_piwr_address_write(X) sdram_dfii_pi0_address_write(X) + +#define sdram_dfii_pird_baddress_write(X) sdram_dfii_pi0_baddress_write(X) +#define sdram_dfii_piwr_baddress_write(X) sdram_dfii_pi0_baddress_write(X) + +#define command_prd(X) command_p0(X) +#define command_pwr(X) command_p0(X) + +#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +const unsigned int sdram_dfii_pix_wrdata_addr[1] = +{ + CSR_SDRAM_DFII_PI0_WRDATA_ADDR +}; + +const unsigned int sdram_dfii_pix_rddata_addr[1] = +{ + CSR_SDRAM_DFII_PI0_RDDATA_ADDR +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void cdelay(int i); + +static void command_p0(int cmd) +{ + sdram_dfii_pi0_command_write(cmd); + sdram_dfii_pi0_command_issue_write(1); +} + +static void init_sequence(void) +{ + /* Bring CKE high */ + + sdram_dfii_pi0_address_write(0x0); + sdram_dfii_pi0_baddress_write(0); + sdram_dfii_control_write(DFII_CONTROL_CKE | DFII_CONTROL_ODT | + DFII_CONTROL_RESET_N); + cdelay(20000); + + /* Precharge All */ + + sdram_dfii_pi0_address_write(0x400); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS | DFII_COMMAND_WE | DFII_COMMAND_CS); + + /* Load Mode Register / Reset DLL, CL=2, BL=1 */ + + sdram_dfii_pi0_address_write(0x120); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_WE | + DFII_COMMAND_CS); + cdelay(200); + + /* Precharge All */ + + sdram_dfii_pi0_address_write(0x400); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS | DFII_COMMAND_WE | DFII_COMMAND_CS); + + /* Auto Refresh */ + + sdram_dfii_pi0_address_write(0x0); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_CS); + cdelay(4); + + /* Auto Refresh */ + + sdram_dfii_pi0_address_write(0x0); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_CS); + cdelay(4); + + /* Load Mode Register / CL=2, BL=1 */ + + sdram_dfii_pi0_address_write(0x20); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_WE | + DFII_COMMAND_CS); + cdelay(200); +} + +#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_SDRAM_PHY_H diff --git a/configs/misoc/include/generated/variables.mak b/configs/misoc/include/generated/variables.mak new file mode 100644 index 0000000000..a5e6478ad4 --- /dev/null +++ b/configs/misoc/include/generated/variables.mak @@ -0,0 +1,11 @@ +TRIPLE=lm32-elf +CPU=lm32 +CPUFLAGS=-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled +CPUENDIANNESS=big +CLANG=0 +SOC_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc +BUILDINC_DIRECTORY=/home/lenovo/fpga/litex/litex/boards/targets/soc_basesoc_papilio_pro/software/include +LIBBASE_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/libbase +LIBCOMPILER_RT_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/libcompiler_rt +LIBNET_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/libnet +BIOS_DIRECTORY=/usr/local/lib/python3.5/dist-packages/litex-0.1-py3.5.egg/litex/soc/software/bios diff --git a/configs/misoc/scripts/ld.script b/configs/misoc/scripts/ld.script new file mode 100644 index 0000000000..806aa57928 --- /dev/null +++ b/configs/misoc/scripts/ld.script @@ -0,0 +1,106 @@ +/**************************************************************************** + * configs/misoc/hello/script/ld.script + * + * Copyright (C) 2016 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. + * + ****************************************************************************/ + +OUTPUT_FORMAT("elf32-lm32") +ENTRY(_stext) + +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 + sram : ORIGIN = 0x10000000, LENGTH = 0x00004000 + main_ram : ORIGIN = 0x40000000, LENGTH = 0x00080000 +} + +/* +MEMORY +{ + flash (rxai!w) : ORIGIN = 0x80002000, LENGTH = 256K - 8K + intram (wxa!ri) : ORIGIN = 0x00000004, LENGTH = 32K + userpage : ORIGIN = 0x80800000, LENGTH = 512 + factorypage : ORIGIN = 0x80800200, LENGTH = 512 +} +*/ + +SECTIONS +{ + .text : { + _stext = ABSOLUTE(.); + *(.vectors) + *(.text .text.*) + *(.fixup) + *(.gnu.warning) + *(.rodata .rodata.*) + *(.gnu.linkonce.t.*) + *(.glue_7) + *(.glue_7t) + *(.got) + *(.gcc_except_table) + *(.gnu.linkonce.r.*) + _etext = ABSOLUTE(.); + } > main_ram + + _eronly = ABSOLUTE(.); /* See below */ + + .data : { + _sdata = ABSOLUTE(.); + *(.data .data.*) + *(.gnu.linkonce.d.*) + CONSTRUCTORS + _edata = ABSOLUTE(.); + } > main_ram + + .bss : { /* BSS */ + _sbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + _ebss = ABSOLUTE(.); + } > main_ram + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_info 0 : { *(.debug_info) } + .debug_line 0 : { *(.debug_line) } + .debug_pubnames 0 : { *(.debug_pubnames) } + .debug_aranges 0 : { *(.debug_aranges) } +} + +PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 4); diff --git a/configs/misoc/src/.gitignore b/configs/misoc/src/.gitignore new file mode 100644 index 0000000000..726d936e1e --- /dev/null +++ b/configs/misoc/src/.gitignore @@ -0,0 +1,2 @@ +/.depend +/Make.dep diff --git a/configs/misoc/src/Makefile b/configs/misoc/src/Makefile new file mode 100644 index 0000000000..b52ee91e5c --- /dev/null +++ b/configs/misoc/src/Makefile @@ -0,0 +1,42 @@ +############################################################################ +# configs/misoc/src/Makefile +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Ramtin Amin +# +# 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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +ASRCS = +CSRCS = atmega_boot.c + +include $(TOPDIR)/configs/Board.mk diff --git a/configs/misoc/src/lm32_boot.c b/configs/misoc/src/lm32_boot.c new file mode 100644 index 0000000000..8d23d5dc63 --- /dev/null +++ b/configs/misoc/src/lm32_boot.c @@ -0,0 +1,68 @@ +/************************************************************************************ + * configs/misoc/src/lm32_boot.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: lm32_board_initialize + * + * Description: + * All LM32 architectures must provide the following entry point. This entry + * point is called early in the initialization -- after all memory has been + * configured and mapped but before any devices have been initialized. + * + ************************************************************************************/ + +void lm32_board_initialize(void) +{ + /* Configure SSP chip selects if 1) at least one SSP is enabled, and 2) the weak + * function atmega_spidev_initialize() has been brought into the link. + */ + + /* Configure on-board LEDs if LED support has been selected. */ +} diff --git a/configs/misoc/src/misoc.h b/configs/misoc/src/misoc.h new file mode 100644 index 0000000000..24fe09a452 --- /dev/null +++ b/configs/misoc/src/misoc.h @@ -0,0 +1,102 @@ +/**************************************************************************** + * configs/misoc/src/misoc.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 __CONFIGS_MISOC_SRC_MISOC_H +#define __CONFIGS_MISOC_SRC_MISOC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Inline Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Name: lm32_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the Amber Web Server. + * + ************************************************************************************/ + +#if defined(CONFIG_AVR_SPI1) || defined(CONFIG_AVR_SPI2) +void weak_function lm32_spidev_initialize(void); +#endif + +/************************************************************************************ + * Name: lm32_led_initialize + * + * Description: + * Configure on-board LEDs if LED support has been selected. + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_LEDS +void lm32_led_initialize(void); +#endif + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __CONFIGS_MISOC_SRC_MISOC_H */ From 14e06a3ce3316379b52bb0a8f20e3137a3af4536 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 07:37:56 -0600 Subject: [PATCH 029/155] libc/pthread: Rename long files so that they are more readable --- libc/pthread/Make.defs | 24 +++++++++---------- ...d_attrdestroy.c => pthread_attr_destroy.c} | 2 +- ...taffinity.c => pthread_attr_getaffinity.c} | 2 +- ...sched.c => pthread_attr_getinheritsched.c} | 2 +- ...edparam.c => pthread_attr_getschedparam.c} | 2 +- ...policy.c => pthread_attr_getschedpolicy.c} | 2 +- ...tacksize.c => pthread_attr_getstacksize.c} | 2 +- ...pthread_attrinit.c => pthread_attr_init.c} | 2 +- ...taffinity.c => pthread_attr_setaffinity.c} | 2 +- ...sched.c => pthread_attr_setinheritsched.c} | 2 +- ...edparam.c => pthread_attr_setschedparam.c} | 2 +- ...policy.c => pthread_attr_setschedpolicy.c} | 2 +- ...tacksize.c => pthread_attr_setstacksize.c} | 2 +- ...estroy.c => pthread_barrierattr_destroy.c} | 2 +- ...red.c => pthread_barrierattr_getpshared.c} | 2 +- ...rattrinit.c => pthread_barrierattr_init.c} | 2 +- ...red.c => pthread_barrierattr_setpshared.c} | 2 +- ...trdestroy.c => pthread_condattr_destroy.c} | 2 +- ...condattrinit.c => pthread_condattr_init.c} | 2 +- ...rdestroy.c => pthread_mutexattr_destroy.c} | 2 +- ...hared.c => pthread_mutexattr_getpshared.c} | 2 +- ...rgettype.c => pthread_mutexattr_gettype.c} | 3 ++- ...texattrinit.c => pthread_mutexattr_init.c} | 2 +- ...hared.c => pthread_mutexattr_setpshared.c} | 2 +- ...rsettype.c => pthread_mutexattr_settype.c} | 2 +- 25 files changed, 37 insertions(+), 36 deletions(-) rename libc/pthread/{pthread_attrdestroy.c => pthread_attr_destroy.c} (98%) rename libc/pthread/{pthread_attrgetaffinity.c => pthread_attr_getaffinity.c} (98%) rename libc/pthread/{pthread_attrgetinheritsched.c => pthread_attr_getinheritsched.c} (98%) rename libc/pthread/{pthread_attrgetschedparam.c => pthread_attr_getschedparam.c} (98%) rename libc/pthread/{pthread_attrgetschedpolicy.c => pthread_attr_getschedpolicy.c} (98%) rename libc/pthread/{pthread_attrgetstacksize.c => pthread_attr_getstacksize.c} (98%) rename libc/pthread/{pthread_attrinit.c => pthread_attr_init.c} (99%) rename libc/pthread/{pthread_attrsetaffinity.c => pthread_attr_setaffinity.c} (98%) rename libc/pthread/{pthread_attrsetinheritsched.c => pthread_attr_setinheritsched.c} (98%) rename libc/pthread/{pthread_attrsetschedparam.c => pthread_attr_setschedparam.c} (98%) rename libc/pthread/{pthread_attrsetschedpolicy.c => pthread_attr_setschedpolicy.c} (98%) rename libc/pthread/{pthread_attrsetstacksize.c => pthread_attr_setstacksize.c} (98%) rename libc/pthread/{pthread_barrierattrdestroy.c => pthread_barrierattr_destroy.c} (98%) rename libc/pthread/{pthread_barrierattrgetpshared.c => pthread_barrierattr_getpshared.c} (98%) rename libc/pthread/{pthread_barrierattrinit.c => pthread_barrierattr_init.c} (98%) rename libc/pthread/{pthread_barrierattrsetpshared.c => pthread_barrierattr_setpshared.c} (98%) rename libc/pthread/{pthread_condattrdestroy.c => pthread_condattr_destroy.c} (98%) rename libc/pthread/{pthread_condattrinit.c => pthread_condattr_init.c} (98%) rename libc/pthread/{pthread_mutexattrdestroy.c => pthread_mutexattr_destroy.c} (98%) rename libc/pthread/{pthread_mutexattrgetpshared.c => pthread_mutexattr_getpshared.c} (98%) rename libc/pthread/{pthread_mutexattrgettype.c => pthread_mutexattr_gettype.c} (98%) rename libc/pthread/{pthread_mutexattrinit.c => pthread_mutexattr_init.c} (98%) rename libc/pthread/{pthread_mutexattrsetpshared.c => pthread_mutexattr_setpshared.c} (98%) rename libc/pthread/{pthread_mutexattrsettype.c => pthread_mutexattr_settype.c} (98%) diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index 44a2d8b2d6..0d783c07fd 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -35,23 +35,23 @@ # Add the pthread C files to the build -CSRCS += pthread_attrinit.c pthread_attrdestroy.c \ - pthread_attrsetschedpolicy.c pthread_attrgetschedpolicy.c \ - pthread_attrsetinheritsched.c pthread_attrgetinheritsched.c \ - pthread_attrsetstacksize.c pthread_attrgetstacksize.c \ - pthread_attrsetschedparam.c pthread_attrgetschedparam.c \ - pthread_barrierattrinit.c pthread_barrierattrdestroy.c \ - pthread_barrierattrgetpshared.c pthread_barrierattrsetpshared.c \ - pthread_condattrinit.c pthread_condattrdestroy.c \ - pthread_mutexattrinit.c pthread_mutexattrdestroy.c \ - pthread_mutexattrgetpshared.c pthread_mutexattrsetpshared.c +CSRCS += pthread_attr_init.c pthread_attr_destroy.c \ + pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c \ + pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c \ + pthread_attr_setstacksize.c pthread_attr_getstacksize.c \ + pthread_attr_setschedparam.c pthread_attr_getschedparam.c \ + pthread_barrierattr_init.c pthread_barrierattr_destroy.c \ + pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c \ + pthread_condattr_init.c pthread_condattr_destroy.c \ + pthread_mutexattr_init.c pthread_mutexattr_destroy.c \ + pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c ifeq ($(CONFIG_SMP),y) -CSRCS += pthread_attrgetaffinity.c pthread_attrsetaffinity.c +CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c endif ifeq ($(CONFIG_MUTEX_TYPES),y) -CSRCS += pthread_mutexattrsettype.c pthread_mutexattrgettype.c +CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c endif ifeq ($(CONFIG_BUILD_PROTECTED),y) diff --git a/libc/pthread/pthread_attrdestroy.c b/libc/pthread/pthread_attr_destroy.c similarity index 98% rename from libc/pthread/pthread_attrdestroy.c rename to libc/pthread/pthread_attr_destroy.c index 7dc431f808..084946cf72 100644 --- a/libc/pthread/pthread_attrdestroy.c +++ b/libc/pthread/pthread_attr_destroy.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrdestroy.c + * libc/pthread/pthread_attr_destroy.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrgetaffinity.c b/libc/pthread/pthread_attr_getaffinity.c similarity index 98% rename from libc/pthread/pthread_attrgetaffinity.c rename to libc/pthread/pthread_attr_getaffinity.c index a08f18cb00..706f059ec5 100644 --- a/libc/pthread/pthread_attrgetaffinity.c +++ b/libc/pthread/pthread_attr_getaffinity.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrgetaffinity.c + * libc/pthread/pthread_attr_getaffinity.c * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrgetinheritsched.c b/libc/pthread/pthread_attr_getinheritsched.c similarity index 98% rename from libc/pthread/pthread_attrgetinheritsched.c rename to libc/pthread/pthread_attr_getinheritsched.c index 0f6b42a879..0760c5e265 100644 --- a/libc/pthread/pthread_attrgetinheritsched.c +++ b/libc/pthread/pthread_attr_getinheritsched.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrgetinheritsched.c + * libc/pthread/pthread_attr_getinheritsched.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrgetschedparam.c b/libc/pthread/pthread_attr_getschedparam.c similarity index 98% rename from libc/pthread/pthread_attrgetschedparam.c rename to libc/pthread/pthread_attr_getschedparam.c index beea2a595b..d3280ffde3 100644 --- a/libc/pthread/pthread_attrgetschedparam.c +++ b/libc/pthread/pthread_attr_getschedparam.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrgetschedparam.c + * libc/pthread/pthread_attr_getschedparam.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrgetschedpolicy.c b/libc/pthread/pthread_attr_getschedpolicy.c similarity index 98% rename from libc/pthread/pthread_attrgetschedpolicy.c rename to libc/pthread/pthread_attr_getschedpolicy.c index 601b3cebea..f4f624f4f0 100644 --- a/libc/pthread/pthread_attrgetschedpolicy.c +++ b/libc/pthread/pthread_attr_getschedpolicy.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrgetschedpolicy.c + * libc/pthread/pthread_attr_getschedpolicy.c * * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrgetstacksize.c b/libc/pthread/pthread_attr_getstacksize.c similarity index 98% rename from libc/pthread/pthread_attrgetstacksize.c rename to libc/pthread/pthread_attr_getstacksize.c index 130bed7fb6..15de1b38f9 100644 --- a/libc/pthread/pthread_attrgetstacksize.c +++ b/libc/pthread/pthread_attr_getstacksize.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrgetstacksize.c + * libc/pthread/pthread_attr_getstacksize.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrinit.c b/libc/pthread/pthread_attr_init.c similarity index 99% rename from libc/pthread/pthread_attrinit.c rename to libc/pthread/pthread_attr_init.c index 1d303a05f0..b6c7c39ed6 100644 --- a/libc/pthread/pthread_attrinit.c +++ b/libc/pthread/pthread_attr_init.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrinit.c + * libc/pthread/pthread_attr_init.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrsetaffinity.c b/libc/pthread/pthread_attr_setaffinity.c similarity index 98% rename from libc/pthread/pthread_attrsetaffinity.c rename to libc/pthread/pthread_attr_setaffinity.c index c8e7c3607d..6705e87aa0 100644 --- a/libc/pthread/pthread_attrsetaffinity.c +++ b/libc/pthread/pthread_attr_setaffinity.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrsetaffinity.c + * libc/pthread/pthread_attr_setaffinity.c * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrsetinheritsched.c b/libc/pthread/pthread_attr_setinheritsched.c similarity index 98% rename from libc/pthread/pthread_attrsetinheritsched.c rename to libc/pthread/pthread_attr_setinheritsched.c index 89d29d07bb..c61be6f4f6 100644 --- a/libc/pthread/pthread_attrsetinheritsched.c +++ b/libc/pthread/pthread_attr_setinheritsched.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrsetinheritsched.c + * libc/pthread/pthread_attr_setinheritsched.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrsetschedparam.c b/libc/pthread/pthread_attr_setschedparam.c similarity index 98% rename from libc/pthread/pthread_attrsetschedparam.c rename to libc/pthread/pthread_attr_setschedparam.c index 602f76eafa..b37d3aad27 100644 --- a/libc/pthread/pthread_attrsetschedparam.c +++ b/libc/pthread/pthread_attr_setschedparam.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrsetschedparam.c + * libc/pthread/pthread_attr_setschedparam.c * * Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrsetschedpolicy.c b/libc/pthread/pthread_attr_setschedpolicy.c similarity index 98% rename from libc/pthread/pthread_attrsetschedpolicy.c rename to libc/pthread/pthread_attr_setschedpolicy.c index 2aa2686157..75a58e105b 100644 --- a/libc/pthread/pthread_attrsetschedpolicy.c +++ b/libc/pthread/pthread_attr_setschedpolicy.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrsetschedpolicy.c + * libc/pthread/pthread_attr_setschedpolicy.c * * Copyright (C) 2007-2009, 2011, 2015 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_attrsetstacksize.c b/libc/pthread/pthread_attr_setstacksize.c similarity index 98% rename from libc/pthread/pthread_attrsetstacksize.c rename to libc/pthread/pthread_attr_setstacksize.c index 3ed309981c..0501f76aa6 100644 --- a/libc/pthread/pthread_attrsetstacksize.c +++ b/libc/pthread/pthread_attr_setstacksize.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_attrsetstacksize.c + * libc/pthread/pthread_attr_setstacksize.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_barrierattrdestroy.c b/libc/pthread/pthread_barrierattr_destroy.c similarity index 98% rename from libc/pthread/pthread_barrierattrdestroy.c rename to libc/pthread/pthread_barrierattr_destroy.c index 98342e28c1..7ab23b7b84 100644 --- a/libc/pthread/pthread_barrierattrdestroy.c +++ b/libc/pthread/pthread_barrierattr_destroy.c @@ -1,5 +1,5 @@ /******************************************************************************** - * libc/pthread/pthread_barrierattrdestroy.c + * libc/pthread/pthread_barrierattr_destroy.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_barrierattrgetpshared.c b/libc/pthread/pthread_barrierattr_getpshared.c similarity index 98% rename from libc/pthread/pthread_barrierattrgetpshared.c rename to libc/pthread/pthread_barrierattr_getpshared.c index ce186f230a..d74d54dcbf 100644 --- a/libc/pthread/pthread_barrierattrgetpshared.c +++ b/libc/pthread/pthread_barrierattr_getpshared.c @@ -1,5 +1,5 @@ /******************************************************************************** - * libc/pthread/pthread_barrierattrgetpshared.c + * libc/pthread/pthread_barrierattr_getpshared.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_barrierattrinit.c b/libc/pthread/pthread_barrierattr_init.c similarity index 98% rename from libc/pthread/pthread_barrierattrinit.c rename to libc/pthread/pthread_barrierattr_init.c index 16c31922d7..9b3f577552 100644 --- a/libc/pthread/pthread_barrierattrinit.c +++ b/libc/pthread/pthread_barrierattr_init.c @@ -1,5 +1,5 @@ /******************************************************************************** - * libc/pthread/pthread_barrierattrinit.c + * libc/pthread/pthread_barrierattr_init.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_barrierattrsetpshared.c b/libc/pthread/pthread_barrierattr_setpshared.c similarity index 98% rename from libc/pthread/pthread_barrierattrsetpshared.c rename to libc/pthread/pthread_barrierattr_setpshared.c index 6839511df5..1736a4e430 100644 --- a/libc/pthread/pthread_barrierattrsetpshared.c +++ b/libc/pthread/pthread_barrierattr_setpshared.c @@ -1,5 +1,5 @@ /******************************************************************************** - * libc/pthread/pthread_barrierattrsetpshared.c + * libc/pthread/pthread_barrierattr_setpshared.c * * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_condattrdestroy.c b/libc/pthread/pthread_condattr_destroy.c similarity index 98% rename from libc/pthread/pthread_condattrdestroy.c rename to libc/pthread/pthread_condattr_destroy.c index d538891f82..5833de44cf 100644 --- a/libc/pthread/pthread_condattrdestroy.c +++ b/libc/pthread/pthread_condattr_destroy.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_condattrdestroy.c + * libc/pthread/pthread_condattr_destroy.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_condattrinit.c b/libc/pthread/pthread_condattr_init.c similarity index 98% rename from libc/pthread/pthread_condattrinit.c rename to libc/pthread/pthread_condattr_init.c index 64d2d0ac25..7f5602ce76 100644 --- a/libc/pthread/pthread_condattrinit.c +++ b/libc/pthread/pthread_condattr_init.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_condattrinit.c + * libc/pthread/pthread_condattr_init.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_mutexattrdestroy.c b/libc/pthread/pthread_mutexattr_destroy.c similarity index 98% rename from libc/pthread/pthread_mutexattrdestroy.c rename to libc/pthread/pthread_mutexattr_destroy.c index c20a67bdf7..a5ada87790 100644 --- a/libc/pthread/pthread_mutexattrdestroy.c +++ b/libc/pthread/pthread_mutexattr_destroy.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_mutexattrdestroy.c + * libc/pthread/pthread_mutexattr_destroy.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_mutexattrgetpshared.c b/libc/pthread/pthread_mutexattr_getpshared.c similarity index 98% rename from libc/pthread/pthread_mutexattrgetpshared.c rename to libc/pthread/pthread_mutexattr_getpshared.c index b8f0b77ec4..51e515cbbb 100644 --- a/libc/pthread/pthread_mutexattrgetpshared.c +++ b/libc/pthread/pthread_mutexattr_getpshared.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_mutexattrgetpshared.c + * libc/pthread/pthread_mutexattr_getpshared.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_mutexattrgettype.c b/libc/pthread/pthread_mutexattr_gettype.c similarity index 98% rename from libc/pthread/pthread_mutexattrgettype.c rename to libc/pthread/pthread_mutexattr_gettype.c index cc553c8350..c9703f5c01 100644 --- a/libc/pthread/pthread_mutexattrgettype.c +++ b/libc/pthread/pthread_mutexattr_gettype.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_mutexattrgettype.c + * libc/pthread/pthread_mutexattr_gettype.c * * Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -72,6 +72,7 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) *type = attr->type; return 0; } + return EINVAL; } diff --git a/libc/pthread/pthread_mutexattrinit.c b/libc/pthread/pthread_mutexattr_init.c similarity index 98% rename from libc/pthread/pthread_mutexattrinit.c rename to libc/pthread/pthread_mutexattr_init.c index 95f5ba8ab8..01c3bb867d 100644 --- a/libc/pthread/pthread_mutexattrinit.c +++ b/libc/pthread/pthread_mutexattr_init.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_mutexattrinit.c + * libc/pthread/pthread_mutexattr_init.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_mutexattrsetpshared.c b/libc/pthread/pthread_mutexattr_setpshared.c similarity index 98% rename from libc/pthread/pthread_mutexattrsetpshared.c rename to libc/pthread/pthread_mutexattr_setpshared.c index 3418521ee8..22b915c4f0 100644 --- a/libc/pthread/pthread_mutexattrsetpshared.c +++ b/libc/pthread/pthread_mutexattr_setpshared.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_mutexattrsetpshared.c + * libc/pthread/pthread_mutexattr_setpshared.c * * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt diff --git a/libc/pthread/pthread_mutexattrsettype.c b/libc/pthread/pthread_mutexattr_settype.c similarity index 98% rename from libc/pthread/pthread_mutexattrsettype.c rename to libc/pthread/pthread_mutexattr_settype.c index ef8b263686..9922a34355 100644 --- a/libc/pthread/pthread_mutexattrsettype.c +++ b/libc/pthread/pthread_mutexattr_settype.c @@ -1,5 +1,5 @@ /**************************************************************************** - * libc/pthread/pthread_mutexattrsettype.c + * libc/pthread/pthread_mutexattr_settype.c * * Copyright (C) 2008, 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt From 92d3022411f363fce0f925a5b0a66d773e0560f9 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 09:05:18 -0600 Subject: [PATCH 030/155] Add pthread_mutexattr_get/set_protocol and non-standard sem_get/set_protocol. These may use to enable or disable priority inheritance on a single semaphore. --- include/nuttx/semaphore.h | 3 +- include/pthread.h | 26 ++++- include/semaphore.h | 23 +++- include/sys/syscall.h | 18 ++- libc/pthread/Make.defs | 4 + libc/pthread/pthread_attr_destroy.c | 3 +- libc/pthread/pthread_mutexattr_destroy.c | 1 - libc/pthread/pthread_mutexattr_getprotocol.c | 73 ++++++++++++ libc/pthread/pthread_mutexattr_setprotocol.c | 79 +++++++++++++ libc/semaphore/sem_init.c | 23 +--- sched/pthread/pthread_mutexinit.c | 27 ++++- sched/semaphore/Make.defs | 3 + sched/semaphore/sem_getprotocol.c | 85 ++++++++++++++ sched/semaphore/sem_holder.c | 26 +++-- sched/semaphore/sem_setprotocol.c | 110 +++++++++++++++++++ syscall/syscall.csv | 2 + syscall/syscall_lookup.h | 7 +- syscall/syscall_stublookup.c | 3 + 18 files changed, 465 insertions(+), 51 deletions(-) create mode 100644 libc/pthread/pthread_mutexattr_getprotocol.c create mode 100644 libc/pthread/pthread_mutexattr_setprotocol.c create mode 100644 sched/semaphore/sem_getprotocol.c create mode 100644 sched/semaphore/sem_setprotocol.c diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 4a5bb32d32..1d0afca38e 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -61,12 +61,13 @@ struct inode; struct nsem_inode_s { + sem_t ns_sem; /* The contained semaphore */ + /* Inode payload unique to named semaphores. ns_inode must appear first * in this structure in order to support casting between type sem_t and * types of struct nsem_inode_s. */ FAR struct inode *ns_inode; /* Containing inode */ - sem_t ns_sem; /* The semaphore */ }; #endif diff --git a/include/pthread.h b/include/pthread.h index 64228154f7..e25e63d41f 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -135,6 +135,12 @@ #define PTHREAD_BARRIER_SERIAL_THREAD 0x1000 +/* Values for protocol attribute */ + +#define PTHREAD_PRIO_NONE SEM_PRIO_NONE +#define PTHREAD_PRIO_INHERIT SEM_PRIO_INHERIT +#define PTHREAD_PRIO_PROTECT SEM_PRIO_PROTECT + /* Definitions to map some non-standard, BSD thread management interfaces to * the non-standard Linux-like prctl() interface. Since these are simple * mappings to prctl, they will return 0 on success and -1 on failure with the @@ -212,6 +218,9 @@ typedef struct pthread_cond_s pthread_cond_t; struct pthread_mutexattr_s { uint8_t pshared; /* PTHREAD_PROCESS_PRIVATE or PTHREAD_PROCESS_SHARED */ +#ifdef CONFIG_PRIORITY_INHERITANCE + uint8_t proto; /* See PTHREAD_PRIO_* definitions */ +#endif #ifdef CONFIG_MUTEX_TYPES uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ #endif @@ -222,11 +231,11 @@ typedef struct pthread_mutexattr_s pthread_mutexattr_t; struct pthread_mutex_s { - int pid; /* ID of the holder of the mutex */ - sem_t sem; /* Semaphore underlying the implementation of the mutex */ + int pid; /* ID of the holder of the mutex */ + sem_t sem; /* Semaphore underlying the implementation of the mutex */ #ifdef CONFIG_MUTEX_TYPES - uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ - int nlocks; /* The number of recursive locks held */ + uint8_t type; /* Type of the mutex. See PTHREAD_MUTEX_* definitions */ + int nlocks; /* The number of recursive locks held */ #endif }; @@ -395,6 +404,15 @@ int pthread_mutex_lock(FAR pthread_mutex_t *mutex); int pthread_mutex_trylock(FAR pthread_mutex_t *mutex); int pthread_mutex_unlock(FAR pthread_mutex_t *mutex); +#ifdef CONFIG_PRIORITY_INHERITANCE +/* Manage priority inheritance */ + +int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, + FAR int *protocol); +int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, + int protocol); +#endif + /* Operations on condition variables */ int pthread_condattr_init(FAR pthread_condattr_t *attr); diff --git a/include/semaphore.h b/include/semaphore.h index 142ef51ada..41db9caa8b 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -57,6 +57,17 @@ extern "C" * Pre-processor Definitions ****************************************************************************/ +/* Values for protocol attribute */ + +#define SEM_PRIO_NONE 0 +#define SEM_PRIO_INHERIT 1 +#define SEM_PRIO_PROTECT 2 + +/* Bit definitions for the struct sem_s flags field */ + +#define PRIOINHERIT_FLAGS_DISABLE (1 << 0) /* Bit 0: Priority inheritance + * is disabled for this semaphore. */ + /**************************************************************************** * Public Type Declarations ****************************************************************************/ @@ -92,6 +103,7 @@ struct sem_s */ #ifdef CONFIG_PRIORITY_INHERITANCE + uint8_t flags; /* See PRIOINHERIT_FLAGS_* definitions */ # if CONFIG_SEM_PREALLOCHOLDERS > 0 FAR struct semholder_s *hhead; /* List of holders of semaphore counts */ # else @@ -106,9 +118,9 @@ typedef struct sem_s sem_t; #ifdef CONFIG_PRIORITY_INHERITANCE # if CONFIG_SEM_PREALLOCHOLDERS > 0 -# define SEM_INITIALIZER(c) {(c), NULL} /* semcount, hhead */ +# define SEM_INITIALIZER(c) {(c), 0, NULL} /* semcount, flags, hhead */ # else -# define SEM_INITIALIZER(c) {(c), SEMHOLDER_INITIALIZER} /* semcount, holder */ +# define SEM_INITIALIZER(c) {(c), 0, SEMHOLDER_INITIALIZER} /* semcount, flags, holder */ # endif #else # define SEM_INITIALIZER(c) {(c)} /* semcount */ @@ -141,6 +153,13 @@ int sem_close(FAR sem_t *sem); int sem_unlink(FAR const char *name); #endif +#ifdef CONFIG_PRIORITY_INHERITANCE +/* Non-standard interfaces to manage priority inheritance */ + +int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); +int sem_setprotocol(FAR sem_t *sem, int protocol); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/sys/syscall.h b/include/sys/syscall.h index 2fba44de34..134b2cb27d 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -91,15 +91,23 @@ #define SYS_sem_trywait (CONFIG_SYS_RESERVED+18) #define SYS_sem_wait (CONFIG_SYS_RESERVED+19) +#ifdef CONFIG_PRIORITY_INHERITANCE +# define SYS_sem_getprotocol (CONFIG_SYS_RESERVED+20) +# define SYS_sem_setprotocol (CONFIG_SYS_RESERVED+21) +# define __SYS_named_sem (CONFIG_SYS_RESERVED+22) +#else +# define __SYS_named_sem (CONFIG_SYS_RESERVED+20) +#endif + /* Named semaphores */ #ifdef CONFIG_FS_NAMED_SEMAPHORES -# define SYS_sem_open (CONFIG_SYS_RESERVED+20) -# define SYS_sem_close (CONFIG_SYS_RESERVED+21) -# define SYS_sem_unlink (CONFIG_SYS_RESERVED+22) -# define __SYS_task_create (CONFIG_SYS_RESERVED+23) +# define SYS_sem_open __SYS_named_sem +# define SYS_sem_close (__SYS_named_sem+1) +# define SYS_sem_unlink (__SYS_named_sem+2) +# define __SYS_task_create (__SYS_named_sem+3) #else -# define __SYS_task_create (CONFIG_SYS_RESERVED+20) +# define __SYS_task_create __SYS_named_sem #endif /* Task creation APIs based on global entry points cannot be use with diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index 0d783c07fd..9d343f6052 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -54,6 +54,10 @@ ifeq ($(CONFIG_MUTEX_TYPES),y) CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c endif +ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) +CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c +endif + ifeq ($(CONFIG_BUILD_PROTECTED),y) CSRCS += pthread_startup.c endif diff --git a/libc/pthread/pthread_attr_destroy.c b/libc/pthread/pthread_attr_destroy.c index 084946cf72..7d39a19278 100644 --- a/libc/pthread/pthread_attr_destroy.c +++ b/libc/pthread/pthread_attr_destroy.c @@ -52,8 +52,7 @@ * Function: pthread_attr_destroy * * Description: - * An attributes object can be deleted when it is no longer - * needed. + * An attributes object can be deleted when it is no longer needed. * * Parameters: * attr diff --git a/libc/pthread/pthread_mutexattr_destroy.c b/libc/pthread/pthread_mutexattr_destroy.c index a5ada87790..62d5de4a92 100644 --- a/libc/pthread/pthread_mutexattr_destroy.c +++ b/libc/pthread/pthread_mutexattr_destroy.c @@ -55,7 +55,6 @@ * * Parameters: * attr - * pshared * * Return Value: * 0 if successful. Otherwise, an error code. diff --git a/libc/pthread/pthread_mutexattr_getprotocol.c b/libc/pthread/pthread_mutexattr_getprotocol.c new file mode 100644 index 0000000000..f7851855ac --- /dev/null +++ b/libc/pthread/pthread_mutexattr_getprotocol.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * libc/pthread/pthread_mutexattr_getprotocol.c + * + * Copyright (C) 2016 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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pthread_mutexattr_getprotocol + * + * Description: + * Return the value of the mutex protocol attribute. + * + * Parameters: + * attr - A pointer to the mutex attributes to be queried. + * protocol - The user provided location in which to store the protocol + * value. + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + ****************************************************************************/ + +int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, + FAR int *protocol) +{ + DEBUGASSERT(attr != NULL && protocol != NULL); + + linfo("Returning %d\n", attr->proto); + return attr->proto; +} diff --git a/libc/pthread/pthread_mutexattr_setprotocol.c b/libc/pthread/pthread_mutexattr_setprotocol.c new file mode 100644 index 0000000000..621a94d1c1 --- /dev/null +++ b/libc/pthread/pthread_mutexattr_setprotocol.c @@ -0,0 +1,79 @@ +/**************************************************************************** + * libc/pthread/pthread_mutexattr_setprotocol.c + * + * Copyright (C) 2016 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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: pthread_mutexattr_setprotocol + * + * Description: + * Set mutex protocol attribute. + * + * Parameters: + * attr - A pointer to the mutex attributes to be modified + * protocol - The new protocol to use + * + * Return Value: + * 0 if successful. Otherwise, an error code. + * + ****************************************************************************/ + +int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, + int protocol) +{ + linfo("attr=0x%p protocol=%d\n", attr, protocol); + DEBUGASSERT(attr != NULL); + + if (protocol >= PTHREAD_PRIO_NONE && protocol <= PTHREAD_PRIO_PROTECT) + { + attr->proto = protocol; + return OK; + } + + return EINVAL; +} diff --git a/libc/semaphore/sem_init.c b/libc/semaphore/sem_init.c index 861acb6cde..f4037d342c 100644 --- a/libc/semaphore/sem_init.c +++ b/libc/semaphore/sem_init.c @@ -1,7 +1,7 @@ /**************************************************************************** * libc/sem/sem_init.c * - * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011-2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -44,26 +44,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Declarations - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -108,6 +88,7 @@ int sem_init(FAR sem_t *sem, int pshared, unsigned int value) /* Initialize to support priority inheritance */ #ifdef CONFIG_PRIORITY_INHERITANCE + sem->flags = 0; # if CONFIG_SEM_PREALLOCHOLDERS > 0 sem->hhead = NULL; # else diff --git a/sched/pthread/pthread_mutexinit.c b/sched/pthread/pthread_mutexinit.c index 31d18e2f46..0c65fbc7ed 100644 --- a/sched/pthread/pthread_mutexinit.c +++ b/sched/pthread/pthread_mutexinit.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_mutexinit.c * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -66,13 +66,17 @@ * ****************************************************************************/ -int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t *attr) +int pthread_mutex_init(FAR pthread_mutex_t *mutex, + FAR const pthread_mutexattr_t *attr) { int pshared = 0; #ifdef CONFIG_MUTEX_TYPES - uint8_t type = PTHREAD_MUTEX_DEFAULT; + uint8_t type = PTHREAD_MUTEX_DEFAULT; #endif - int ret = OK; +#ifdef CONFIG_PRIORITY_INHERITANCE + uint8_t proto = PTHREAD_PRIO_INHERIT; +#endif + int ret = OK; int status; sinfo("mutex=0x%p attr=0x%p\n", mutex, attr); @@ -88,6 +92,9 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t if (attr) { pshared = attr->pshared; +#ifdef CONFIG_PRIORITY_INHERITANCE + proto = attr->proto; +#endif #ifdef CONFIG_MUTEX_TYPES type = attr->type; #endif @@ -102,9 +109,19 @@ int pthread_mutex_init(FAR pthread_mutex_t *mutex, FAR const pthread_mutexattr_t status = sem_init((FAR sem_t *)&mutex->sem, pshared, 1); if (status != OK) { - ret = EINVAL; + ret = get_errno(); } +#ifdef CONFIG_PRIORITY_INHERITANCE + /* Initialize the semaphore protocol */ + + status = sem_setprotocol((FAR sem_t *)&mutex->sem, proto); + if (status != OK) + { + ret = get_errno(); + } +#endif + /* Set up attributes unique to the mutex type */ #ifdef CONFIG_MUTEX_TYPES diff --git a/sched/semaphore/Make.defs b/sched/semaphore/Make.defs index 39ba7cd2dc..70b9e356bd 100644 --- a/sched/semaphore/Make.defs +++ b/sched/semaphore/Make.defs @@ -33,12 +33,15 @@ # ############################################################################ +# Add semaphore-related files to the build + CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_tickwait.c CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c CSRCS += sem_reset.c sem_waitirq.c ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) CSRCS += sem_initialize.c sem_holder.c +CSRCS += sem_setprotocol.c sem_getprotocol.c endif ifeq ($(CONFIG_SPINLOCK),y) diff --git a/sched/semaphore/sem_getprotocol.c b/sched/semaphore/sem_getprotocol.c new file mode 100644 index 0000000000..f3dc169e6e --- /dev/null +++ b/sched/semaphore/sem_getprotocol.c @@ -0,0 +1,85 @@ +/**************************************************************************** + * sched/semaphore/sem_getprotocol.c + * + * Copyright (C) 2016 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 "semaphore/semaphore.h" + +#ifdef CONFIG_PRIORITY_INHERITANCE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sem_getprotocol + * + * Description: + * Return the value of the semaphore protocol attribute. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * queried. + * protocol - The user provided location in which to store the protocol + * value. + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +int sem_getprotocol(FAR sem_t *sem, FAR int *protocol) +{ + DEBUGASSERT(sem != NULL); + + if ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) != 0) + { + return SEM_PRIO_NONE; + } + else + { + return SEM_PRIO_INHERIT; + } +} + +#endif /* CONFIG_PRIORITY_INHERITANCE */ diff --git a/sched/semaphore/sem_holder.c b/sched/semaphore/sem_holder.c index 769444fd99..6b9f05af3e 100644 --- a/sched/semaphore/sem_holder.c +++ b/sched/semaphore/sem_holder.c @@ -790,7 +790,7 @@ void sem_initholders(void) * Name: sem_destroyholder * * Description: - * Called from sem_destroy() to handle any holders of a semaphore when + * Called from sem_destroyholder() to handle any holders of a semaphore when * it is destroyed. * * Parameters: @@ -855,17 +855,25 @@ void sem_addholder_tcb(FAR struct tcb_s *htcb, FAR sem_t *sem) { FAR struct semholder_s *pholder; - /* Find or allocate a container for this new holder */ + /* If priority inheritance is disabled for this thread, then do not add + * the holder. If there are never holders of the semaphore, the priority + * inheritance is effectively disabled. + */ - pholder = sem_findorallocateholder(sem, htcb); - if (pholder != NULL) + if ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) == 0) { - /* Then set the holder and increment the number of counts held by this - * holder - */ + /* Find or allocate a container for this new holder */ - pholder->htcb = htcb; - pholder->counts++; + pholder = sem_findorallocateholder(sem, htcb); + if (pholder != NULL) + { + /* Then set the holder and increment the number of counts held by this + * holder + */ + + pholder->htcb = htcb; + pholder->counts++; + } } } diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c new file mode 100644 index 0000000000..c5609fdcd5 --- /dev/null +++ b/sched/semaphore/sem_setprotocol.c @@ -0,0 +1,110 @@ +/**************************************************************************** + * sched/semaphore/sem_setprotocol.c + * + * Copyright (C) 2016 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 "semaphore/semaphore.h" + +#ifdef CONFIG_PRIORITY_INHERITANCE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sem_setprotocol + * + * Description: + * Set semaphore protocol attribute. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * modified + * protocol - The new protocol to use + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +int sem_setprotocol(FAR sem_t *sem, int protocol) +{ + int errcode; + + DEBUGASSERT(sem != NULL); + + switch (protocol) + { + case SEM_PRIO_NONE: + /* Disable priority inheritance */ + + sem->flags |= PRIOINHERIT_FLAGS_DISABLE; + + /* Remove any current holders */ + + sem_destroyholder(sem); + return OK; + + case SEM_PRIO_INHERIT: + /* Enable priority inheritance (dangerous) */ + + sem->flags &= ~PRIOINHERIT_FLAGS_DISABLE; + return OK; + + case SEM_PRIO_PROTECT: + /* Not yet supported */ + + errcode = ENOSYS; + break; + + default: + errcode = EINVAL; + break; + } + + set_errno(errcode); + return ERROR; +} + +#endif /* CONFIG_PRIORITY_INHERITANCE */ diff --git a/syscall/syscall.csv b/syscall/syscall.csv index c1fdd2e291..b745998c4b 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -117,7 +117,9 @@ "sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t*" "sem_destroy","semaphore.h","","int","FAR sem_t*" "sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","..." +"sem_getprotocol","semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","FAR int*" "sem_post","semaphore.h","","int","FAR sem_t*" +"sem_setprotocol","semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" "sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *" "sem_trywait","semaphore.h","","int","FAR sem_t*" "sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char*" diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index d0f304fbad..e3506707d8 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -61,12 +61,17 @@ SYSCALL_LOOKUP(uname, 1, STUB_uname) /* Semaphores */ -SYSCALL_LOOKUP(sem_destroy, 2, STUB_sem_destroy) +SYSCALL_LOOKUP(sem_destroy, 1, STUB_sem_destroy) SYSCALL_LOOKUP(sem_post, 1, STUB_sem_post) SYSCALL_LOOKUP(sem_timedwait, 2, STUB_sem_timedwait) SYSCALL_LOOKUP(sem_trywait, 1, STUB_sem_trywait) SYSCALL_LOOKUP(sem_wait, 1, STUB_sem_wait) +#ifdef CONFIG_PRIORITY_INHERITANCE +SYSCALL_LOOKUP(sem_getprotocol, 2, STUB_sem_getprotocol) +SYSCALL_LOOKUP(sem_setprotocol, 2, STUB_sem_setprotocol) +#endif + /* Named semaphores */ #ifdef CONFIG_FS_NAMED_SEMAPHORES diff --git a/syscall/syscall_stublookup.c b/syscall/syscall_stublookup.c index 868eca6f13..996763daea 100644 --- a/syscall/syscall_stublookup.c +++ b/syscall/syscall_stublookup.c @@ -82,13 +82,16 @@ uintptr_t STUB_uname(int nbr, uintptr_t parm1); uintptr_t STUB_sem_close(int nbr, uintptr_t parm1); uintptr_t STUB_sem_destroy(int nbr, uintptr_t parm1); +uintptr_t STUB_sem_getprotocol(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_open(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm6); uintptr_t STUB_sem_post(int nbr, uintptr_t parm1); +uintptr_t STUB_sem_setprotocol(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_timedwait(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_trywait(int nbr, uintptr_t parm1); uintptr_t STUB_sem_unlink(int nbr, uintptr_t parm1); uintptr_t STUB_sem_wait(int nbr, uintptr_t parm1); + uintptr_t STUB_pgalloc(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_task_create(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4, uintptr_t parm5); From b738a646adb577c0e6514e128131bc24030eb9b3 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 09:29:16 -0600 Subject: [PATCH 031/155] sem_getprotocol() can be in C library --- include/sys/syscall.h | 5 ++--- libc/semaphore/Make.defs | 6 +++++- {sched => libc}/semaphore/sem_getprotocol.c | 6 ++---- sched/semaphore/Make.defs | 3 +-- syscall/syscall.csv | 1 - syscall/syscall_lookup.h | 1 - syscall/syscall_stublookup.c | 1 - 7 files changed, 10 insertions(+), 13 deletions(-) rename {sched => libc}/semaphore/sem_getprotocol.c (96%) diff --git a/include/sys/syscall.h b/include/sys/syscall.h index 134b2cb27d..d0bfcd9597 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -92,9 +92,8 @@ #define SYS_sem_wait (CONFIG_SYS_RESERVED+19) #ifdef CONFIG_PRIORITY_INHERITANCE -# define SYS_sem_getprotocol (CONFIG_SYS_RESERVED+20) -# define SYS_sem_setprotocol (CONFIG_SYS_RESERVED+21) -# define __SYS_named_sem (CONFIG_SYS_RESERVED+22) +# define SYS_sem_setprotocol (CONFIG_SYS_RESERVED+20) +# define __SYS_named_sem (CONFIG_SYS_RESERVED+21) #else # define __SYS_named_sem (CONFIG_SYS_RESERVED+20) #endif diff --git a/libc/semaphore/Make.defs b/libc/semaphore/Make.defs index b6551ff96a..d456f07520 100644 --- a/libc/semaphore/Make.defs +++ b/libc/semaphore/Make.defs @@ -1,7 +1,7 @@ ############################################################################ # libc/semaphore/Make.defs # -# Copyright (C) 2011-2012 Gregory Nutt. All rights reserved. +# Copyright (C) 2011-2012, 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -37,6 +37,10 @@ CSRCS += sem_init.c sem_getvalue.c +ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) +CSRCS += sem_getprotocol.c +endif + # Add the semaphore directory to the build DEPPATH += --dep-path semaphore diff --git a/sched/semaphore/sem_getprotocol.c b/libc/semaphore/sem_getprotocol.c similarity index 96% rename from sched/semaphore/sem_getprotocol.c rename to libc/semaphore/sem_getprotocol.c index f3dc169e6e..abbc4c02db 100644 --- a/sched/semaphore/sem_getprotocol.c +++ b/libc/semaphore/sem_getprotocol.c @@ -1,5 +1,5 @@ /**************************************************************************** - * sched/semaphore/sem_getprotocol.c + * libc/semaphore/sem_getprotocol.c * * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -42,8 +42,6 @@ #include #include -#include "semaphore/semaphore.h" - #ifdef CONFIG_PRIORITY_INHERITANCE /**************************************************************************** @@ -70,7 +68,7 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol) { - DEBUGASSERT(sem != NULL); + DEBUGASSERT(sem != NULL && protocol != NULL); if ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) != 0) { diff --git a/sched/semaphore/Make.defs b/sched/semaphore/Make.defs index 70b9e356bd..7eb1740424 100644 --- a/sched/semaphore/Make.defs +++ b/sched/semaphore/Make.defs @@ -40,8 +40,7 @@ CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c CSRCS += sem_reset.c sem_waitirq.c ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -CSRCS += sem_initialize.c sem_holder.c -CSRCS += sem_setprotocol.c sem_getprotocol.c +CSRCS += sem_initialize.c sem_holder.c sem_setprotocol.c endif ifeq ($(CONFIG_SPINLOCK),y) diff --git a/syscall/syscall.csv b/syscall/syscall.csv index b745998c4b..8d8307f42a 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -117,7 +117,6 @@ "sem_close","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR sem_t*" "sem_destroy","semaphore.h","","int","FAR sem_t*" "sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","..." -"sem_getprotocol","semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","FAR int*" "sem_post","semaphore.h","","int","FAR sem_t*" "sem_setprotocol","semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" "sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *" diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index e3506707d8..0c16b8ce1e 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -68,7 +68,6 @@ SYSCALL_LOOKUP(sem_trywait, 1, STUB_sem_trywait) SYSCALL_LOOKUP(sem_wait, 1, STUB_sem_wait) #ifdef CONFIG_PRIORITY_INHERITANCE -SYSCALL_LOOKUP(sem_getprotocol, 2, STUB_sem_getprotocol) SYSCALL_LOOKUP(sem_setprotocol, 2, STUB_sem_setprotocol) #endif diff --git a/syscall/syscall_stublookup.c b/syscall/syscall_stublookup.c index 996763daea..f655e0800d 100644 --- a/syscall/syscall_stublookup.c +++ b/syscall/syscall_stublookup.c @@ -82,7 +82,6 @@ uintptr_t STUB_uname(int nbr, uintptr_t parm1); uintptr_t STUB_sem_close(int nbr, uintptr_t parm1); uintptr_t STUB_sem_destroy(int nbr, uintptr_t parm1); -uintptr_t STUB_sem_getprotocol(int nbr, uintptr_t parm1, uintptr_t parm2); uintptr_t STUB_sem_open(int nbr, uintptr_t parm1, uintptr_t parm2, uintptr_t parm3, uintptr_t parm4, uintptr_t parm5, uintptr_t parm6); uintptr_t STUB_sem_post(int nbr, uintptr_t parm1); From 93e938768985b851dae1d7e4b7a21fa0258ff476 Mon Sep 17 00:00:00 2001 From: "Paul A. Patience" Date: Wed, 2 Nov 2016 12:46:04 -0400 Subject: [PATCH 032/155] STM32 ADC: Fix compilation error when DMA isn't enabled --- arch/arm/src/stm32/stm32_adc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index acbb707d34..83939499c8 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -2203,6 +2203,7 @@ static void adc_shutdown(FAR struct adc_dev_s *dev) static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) { FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)dev->ad_priv; + uint32_t regval; ainfo("intf: %d enable: %d\n", priv->intf, enable ? 1 : 0); @@ -2212,8 +2213,15 @@ static void adc_rxint(FAR struct adc_dev_s *dev, bool enable) * end-of-conversion ADC. */ - adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, - priv->hasdma ? ADC_IER_AWD | ADC_ISR_OVR : ADC_IER_ALLINTS); + regval = ADC_IER_ALLINTS; +#ifdef ADC_HAVE_DMA + if (priv->hasdma) + { + regval &= ~(ADC_IER_EOC | ADC_IER_JEOC); + } +#endif + + adc_modifyreg(priv, STM32_ADC_IER_OFFSET, 0, regval); } else { @@ -2803,7 +2811,7 @@ static int adc_interrupt(FAR struct adc_dev_s *dev) /* by MR regval &= ~pending; */ /* by MR adc_putreg(priv, STM32_ADC_ISR_OFFSET, regval); - + adc_putreg(priv, STM32_ADC_ISR_OFFSET, pending); */ return OK; } From d89765e1d05527ec8121708c0c6f31fdd5b97dcd Mon Sep 17 00:00:00 2001 From: "Paul A. Patience" Date: Wed, 2 Nov 2016 12:58:29 -0400 Subject: [PATCH 033/155] spi: Fix Kconfig warning This commit moves the ARCH_HAVE_SPI options outside the check for SPI. Those options don't depend on SPI, and Kconfig files in arch/ enable them even if SPI isn't enabled. Sourcing the driver's Kconfig in drivers/Kconfig only if support for the driver is enabled prevents us from defining these ARCH_HAVE options in the driver's Kconfig. We should probably remove the other checks in drivers/Kconfig and check if the drivers are enabled only in their Kconfig. --- drivers/Kconfig | 2 -- drivers/spi/Kconfig | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/Kconfig b/drivers/Kconfig index 9b508fdd7f..4ac8a9d0c6 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -345,9 +345,7 @@ menuconfig SPI should be enabled by all platforms that support SPI interfaces. See include/nuttx/spi/spi.h for further SPI driver information. -if SPI source drivers/spi/Kconfig -endif menuconfig I2S bool "I2S Driver Support" diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index ea8b8ac9ab..177d863ee2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -3,6 +3,18 @@ # see the file kconfig-language.txt in the NuttX tools repository. # +config ARCH_HAVE_SPI_CRCGENERATION + bool + default n + +config ARCH_HAVE_SPI_CS_CONTROL + bool + default n + +config ARCH_HAVE_SPI_BITORDER + bool + default n + if SPI config SPI_SLAVE @@ -55,10 +67,6 @@ config SPI_HWFEATURES basically the OR of any specific hardware feature and eanbles the SPI hwfeatures() interface method. -config ARCH_HAVE_SPI_CRCGENERATION - bool - default n - config SPI_CRCGENERATION bool default n @@ -69,10 +77,6 @@ config SPI_CRCGENERATION generation of SPI CRCs. Enables the HWFEAT_CRCGENERATION option as well as the hwfeartures() interface method. -config ARCH_HAVE_SPI_CS_CONTROL - bool - default n - config SPI_CS_CONTROL bool "SPI CS Behavior Control" default n @@ -82,10 +86,6 @@ config SPI_CS_CONTROL Enables possibilities to define the behavior of CS. Also enables the hwfeatures() interface method. -config ARCH_HAVE_SPI_BITORDER - bool - default n - config SPI_BITORDER bool "SPI Bit Order Control" default n From b5a94e255aaa4410b59b2e950fa1834af21fabbf Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Wed, 2 Nov 2016 12:07:52 -0600 Subject: [PATCH 034/155] Misoc/LM32: Changes to get a clean compilation after initial review and commit --- arch/misoc/Kconfig | 6 +- arch/misoc/include/inttypes.h | 245 +++++++++++++++++++++++++++++++ arch/misoc/src/Makefile | 4 +- arch/misoc/src/lm32/Make.defs | 4 +- arch/misoc/src/lm32/chip.h | 3 - arch/misoc/src/lm32/lm32.h | 2 +- arch/misoc/src/lm32/lm32_irq.c | 2 +- arch/misoc/src/lm32/lm32_isr.c | 61 -------- arch/misoc/src/lm32/lm32_swint.c | 2 +- configs/misoc/scripts/ld.script | 17 +-- configs/misoc/src/Makefile | 2 +- 11 files changed, 259 insertions(+), 89 deletions(-) create mode 100644 arch/misoc/include/inttypes.h delete mode 100644 arch/misoc/src/lm32/lm32_isr.c diff --git a/arch/misoc/Kconfig b/arch/misoc/Kconfig index 5cfbf0268c..f0acc68046 100644 --- a/arch/misoc/Kconfig +++ b/arch/misoc/Kconfig @@ -62,11 +62,11 @@ config MISOC_UART_TX_BUF_SIZE ---help--- Size of TX buffers for MISOC UARTs -ifdef ARCH_CHIP_LM32 +if ARCH_CHIP_LM32 source arch/misoc/src/lm32/Kconfig endif -ifdef ARCH_CHIP_MOR1K -source arch/misoc/src/mor1k/Kconfig +if ARCH_CHIP_MOR1K +#source arch/misoc/src/mor1k/Kconfig endif endif # ARCH_MISOC diff --git a/arch/misoc/include/inttypes.h b/arch/misoc/include/inttypes.h new file mode 100644 index 0000000000..16c4046f7a --- /dev/null +++ b/arch/misoc/include/inttypes.h @@ -0,0 +1,245 @@ +/**************************************************************************** + * arch/misoc/include/inttypes.h + * + * Copyright (C) 2016 Omni Hoverboards Inc. All rights reserved. + * Author: Paul Alexander Patience + * + * 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 __ARCH_MISOC_INCLUDE_INTTYPES_H +#define __ARCH_MISOC_INCLUDE_INTTYPES_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "d" +#define PRId64 "lld" + +#define PRIdLEAST8 "d" +#define PRIdLEAST16 "d" +#define PRIdLEAST32 "d" +#define PRIdLEAST64 "lld" + +#define PRIdFAST8 "d" +#define PRIdFAST16 "d" +#define PRIdFAST32 "d" +#define PRIdFAST64 "lld" + +#define PRIdMAX "lld" +#define PRIdPTR "d" + +#define PRIi8 "i" +#define PRIi16 "i" +#define PRIi32 "i" +#define PRIi64 "lli" + +#define PRIiLEAST8 "i" +#define PRIiLEAST16 "i" +#define PRIiLEAST32 "i" +#define PRIiLEAST64 "lli" + +#define PRIiFAST8 "i" +#define PRIiFAST16 "i" +#define PRIiFAST32 "i" +#define PRIiFAST64 "lli" + +#define PRIiMAX "lli" +#define PRIiPTR "i" + +#define PRIo8 "o" +#define PRIo16 "o" +#define PRIo32 "o" +#define PRIo64 "llo" + +#define PRIoLEAST8 "o" +#define PRIoLEAST16 "o" +#define PRIoLEAST32 "o" +#define PRIoLEAST64 "llo" + +#define PRIoFAST8 "o" +#define PRIoFAST16 "o" +#define PRIoFAST32 "o" +#define PRIoFAST64 "llo" + +#define PRIoMAX "llo" +#define PRIoPTR "o" + +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "u" +#define PRIu64 "llu" + +#define PRIuLEAST8 "u" +#define PRIuLEAST16 "u" +#define PRIuLEAST32 "u" +#define PRIuLEAST64 "llu" + +#define PRIuFAST8 "u" +#define PRIuFAST16 "u" +#define PRIuFAST32 "u" +#define PRIuFAST64 "llu" + +#define PRIuMAX "llu" +#define PRIuPTR "u" + +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "x" +#define PRIx64 "llx" + +#define PRIxLEAST8 "x" +#define PRIxLEAST16 "x" +#define PRIxLEAST32 "x" +#define PRIxLEAST64 "llx" + +#define PRIxFAST8 "x" +#define PRIxFAST16 "x" +#define PRIxFAST32 "x" +#define PRIxFAST64 "llx" + +#define PRIxMAX "llx" +#define PRIxPTR "x" + +#define PRIX8 "X" +#define PRIX16 "X" +#define PRIX32 "X" +#define PRIX64 "llX" + +#define PRIXLEAST8 "X" +#define PRIXLEAST16 "X" +#define PRIXLEAST32 "X" +#define PRIXLEAST64 "llX" + +#define PRIXFAST8 "X" +#define PRIXFAST16 "X" +#define PRIXFAST32 "X" +#define PRIXFAST64 "llX" + +#define PRIXMAX "llX" +#define PRIXPTR "X" + +#define SCNd8 "hhd" +#define SCNd16 "hd" +#define SCNd32 "d" +#define SCNd64 "lld" + +#define SCNdLEAST8 "hhd" +#define SCNdLEAST16 "hd" +#define SCNdLEAST32 "d" +#define SCNdLEAST64 "lld" + +#define SCNdFAST8 "hhd" +#define SCNdFAST16 "hd" +#define SCNdFAST32 "d" +#define SCNdFAST64 "lld" + +#define SCNdMAX "lld" +#define SCNdPTR "d" + +#define SCNi8 "hhi" +#define SCNi16 "hi" +#define SCNi32 "i" +#define SCNi64 "lli" + +#define SCNiLEAST8 "hhi" +#define SCNiLEAST16 "hi" +#define SCNiLEAST32 "i" +#define SCNiLEAST64 "lli" + +#define SCNiFAST8 "hhi" +#define SCNiFAST16 "hi" +#define SCNiFAST32 "i" +#define SCNiFAST64 "lli" + +#define SCNiMAX "lli" +#define SCNiPTR "i" + +#define SCNo8 "hho" +#define SCNo16 "ho" +#define SCNo32 "o" +#define SCNo64 "llo" + +#define SCNoLEAST8 "hho" +#define SCNoLEAST16 "ho" +#define SCNoLEAST32 "o" +#define SCNoLEAST64 "llo" + +#define SCNoFAST8 "hho" +#define SCNoFAST16 "ho" +#define SCNoFAST32 "o" +#define SCNoFAST64 "llo" + +#define SCNoMAX "llo" +#define SCNoPTR "o" + +#define SCNu8 "hhu" +#define SCNu16 "hu" +#define SCNu32 "u" +#define SCNu64 "llu" + +#define SCNuLEAST8 "hhu" +#define SCNuLEAST16 "hu" +#define SCNuLEAST32 "u" +#define SCNuLEAST64 "llu" + +#define SCNuFAST8 "hhu" +#define SCNuFAST16 "hu" +#define SCNuFAST32 "u" +#define SCNuFAST64 "llu" + +#define SCNuMAX "llu" +#define SCNuPTR "u" + +#define SCNx8 "hhx" +#define SCNx16 "hx" +#define SCNx32 "x" +#define SCNx64 "llx" + +#define SCNxLEAST8 "hhx" +#define SCNxLEAST16 "hx" +#define SCNxLEAST32 "x" +#define SCNxLEAST64 "llx" + +#define SCNxFAST8 "hhx" +#define SCNxFAST16 "hx" +#define SCNxFAST32 "x" +#define SCNxFAST64 "llx" + +#define SCNxMAX "llx" +#define SCNxPTR "x" + +#endif /* __ARCH_MISOC_INCLUDE_INTTYPES_H */ diff --git a/arch/misoc/src/Makefile b/arch/misoc/src/Makefile index 6a0285810b..19bd124422 100644 --- a/arch/misoc/src/Makefile +++ b/arch/misoc/src/Makefile @@ -3,7 +3,6 @@ # # Copyright (C) 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt -# Ramtin Amin # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -139,9 +138,8 @@ board/libboard$(LIBEXT): $(Q) $(MAKE) -C board TOPDIR="$(TOPDIR)" libboard$(LIBEXT) EXTRADEFINES=$(EXTRADEFINES) nuttx$(EXEEXT): $(HEAD_OBJ) board/libboard$(LIBEXT) - @echo "LD: nuttx toto $(LIBGCC)" $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \ - $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LDENDGROUP) + $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) $(LDENDGROUP) ifneq ($(CONFIG_WINDOWS_NATIVE),y) $(Q) $(NM) $(NUTTX) | \ grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index 1a0ce75de2..8338154388 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -39,11 +39,11 @@ HEAD_ASRC = lm32_vectors.S CMN_ASRCS = CMN_CSRCS = misoc_uart.c -CHIP_ASRCS = lm32_start.S lm32_syscall.S +CHIP_ASRCS = lm32_syscall.S CHIP_CSRCS = lm32_allocateheap.c lm32_assert.c lm32_blocktask.c CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_doirq.c lm32_dumpstate.c CHIP_CSRCS += lm32_dumpstate.c lm32_exit.c lm32_idle.c lm32_initialize.c CHIP_CSRCS += lm32_initialstate.c lm32_interruptcontext.c lm32_irq.c -CHIP_CSRCS += lm32_isr.c lm32_releasepending.c lm32_releasestack.c +CHIP_CSRCS += lm32_releasepending.c lm32_releasestack.c CHIP_CSRCS += lm32_stackframe.c lm32_swint.c lm32_unblocktask.c diff --git a/arch/misoc/src/lm32/chip.h b/arch/misoc/src/lm32/chip.h index bdb8823c5a..78d671f7f9 100644 --- a/arch/misoc/src/lm32/chip.h +++ b/arch/misoc/src/lm32/chip.h @@ -92,7 +92,4 @@ static inline unsigned int irq_pending(void) * Public Function Prototypes ****************************************************************************/ -void uart_isr(void); -void isr(void); - #endif /* __ARCH_MISOC_SRC_LM32_CHIP_H */ diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index fe18969c75..8098da7492 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -147,7 +147,7 @@ void lm32_timer_initialize(void); /* Software interrupts ******************************************************/ -uint32_t lm32_swint(int irq, FAR void *context); +uint32_t *lm32_swint(int irq, FAR void *context); /* Signal handling **********************************************************/ diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index 2e01b511fd..726d60c297 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -46,7 +46,7 @@ #include #include -#include "chip_irqasm.h" +#include "chip.h" #include "lm32.h" /**************************************************************************** diff --git a/arch/misoc/src/lm32/lm32_isr.c b/arch/misoc/src/lm32/lm32_isr.c deleted file mode 100644 index 539614d317..0000000000 --- a/arch/misoc/src/lm32/lm32_isr.c +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** - * arch/misoc/src/lm32/lm32_isr.c - * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Ramtin Amin - * - * 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 "chip_irqasm.h" - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -void uart_isr() -{ -} - -void isr(void) -{ - unsigned int irqs; - - irqs = irq_pending() & irq_getmask(); - - if (irqs & (1 << UART_INTERRUPT)) - { - uart_isr(); - } -} diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c index c8148812cc..f8c7b280ee 100644 --- a/arch/misoc/src/lm32/lm32_swint.c +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -130,7 +130,7 @@ static void dispatch_syscall(void) * ****************************************************************************/ -uint32_t lm32_swint(int irq, FAR void *context) +uint32_t *lm32_swint(int irq, FAR void *context) { uint32_t *regs = (uint32_t *)context; diff --git a/configs/misoc/scripts/ld.script b/configs/misoc/scripts/ld.script index 806aa57928..0a3aa7e3d0 100644 --- a/configs/misoc/scripts/ld.script +++ b/configs/misoc/scripts/ld.script @@ -36,23 +36,14 @@ OUTPUT_FORMAT("elf32-lm32") ENTRY(_stext) +/*INCLUDE configs/misoc/include/generated/regions.ld*/ MEMORY { - rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 - sram : ORIGIN = 0x10000000, LENGTH = 0x00004000 - main_ram : ORIGIN = 0x40000000, LENGTH = 0x00080000 + rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 + sram : ORIGIN = 0x10000000, LENGTH = 0x00004000 + main_ram : ORIGIN = 0x40000000, LENGTH = 0x00080000 } -/* -MEMORY -{ - flash (rxai!w) : ORIGIN = 0x80002000, LENGTH = 256K - 8K - intram (wxa!ri) : ORIGIN = 0x00000004, LENGTH = 32K - userpage : ORIGIN = 0x80800000, LENGTH = 512 - factorypage : ORIGIN = 0x80800200, LENGTH = 512 -} -*/ - SECTIONS { .text : { diff --git a/configs/misoc/src/Makefile b/configs/misoc/src/Makefile index b52ee91e5c..0607a11ed3 100644 --- a/configs/misoc/src/Makefile +++ b/configs/misoc/src/Makefile @@ -37,6 +37,6 @@ -include $(TOPDIR)/Make.defs ASRCS = -CSRCS = atmega_boot.c +CSRCS = lm32_boot.c include $(TOPDIR)/configs/Board.mk From 6c51544e56cf4d568d176d0ae5ffa268f07717af Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 14:24:16 -0600 Subject: [PATCH 035/155] Update some comments --- include/nuttx/semaphore.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 1d0afca38e..a4bec12cd2 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -61,6 +61,10 @@ struct inode; struct nsem_inode_s { + /* This must be the first element of the structure. In sem_close() this + * structure must be cast compatible with sem_t. + */ + sem_t ns_sem; /* The contained semaphore */ /* Inode payload unique to named semaphores. ns_inode must appear first From d5b4d848d3ed481b1d74ff8117af4c859a1dfb3b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 14:43:03 -0600 Subject: [PATCH 036/155] Move protoypes for the non-standard include/semaphore.h file to the non-standard include/nuttx/semaphore.h with the other non-standard semaphore interfaces. --- include/nuttx/semaphore.h | 43 +++++++++++++++++++++++++++++++ include/semaphore.h | 7 ----- libc/semaphore/sem_getprotocol.c | 3 ++- sched/pthread/pthread_mutexinit.c | 2 ++ sched/semaphore/sem_setprotocol.c | 3 ++- syscall/syscall.csv | 2 +- 6 files changed, 50 insertions(+), 10 deletions(-) diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index a4bec12cd2..7fef2a91c5 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -138,6 +138,49 @@ int sem_tickwait(FAR sem_t *sem, systime_t start, uint32_t delay); int sem_reset(FAR sem_t *sem, int16_t count); +/**************************************************************************** + * Function: sem_getprotocol + * + * Description: + * Return the value of the semaphore protocol attribute. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * queried. + * protocol - The user provided location in which to store the protocol + * value. + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +#ifdef CONFIG_PRIORITY_INHERITANCE +int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); +#endif + +/**************************************************************************** + * Function: sem_setprotocol + * + * Description: + * Set semaphore protocol attribute. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * modified + * protocol - The new protocol to use + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +#ifdef CONFIG_PRIORITY_INHERITANCE +int sem_setprotocol(FAR sem_t *sem, int protocol); +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/include/semaphore.h b/include/semaphore.h index 41db9caa8b..964d753bd9 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -153,13 +153,6 @@ int sem_close(FAR sem_t *sem); int sem_unlink(FAR const char *name); #endif -#ifdef CONFIG_PRIORITY_INHERITANCE -/* Non-standard interfaces to manage priority inheritance */ - -int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); -int sem_setprotocol(FAR sem_t *sem, int protocol); -#endif - #undef EXTERN #ifdef __cplusplus } diff --git a/libc/semaphore/sem_getprotocol.c b/libc/semaphore/sem_getprotocol.c index abbc4c02db..4ae1606ff7 100644 --- a/libc/semaphore/sem_getprotocol.c +++ b/libc/semaphore/sem_getprotocol.c @@ -39,9 +39,10 @@ #include -#include #include +#include + #ifdef CONFIG_PRIORITY_INHERITANCE /**************************************************************************** diff --git a/sched/pthread/pthread_mutexinit.c b/sched/pthread/pthread_mutexinit.c index 0c65fbc7ed..fe9620da0b 100644 --- a/sched/pthread/pthread_mutexinit.c +++ b/sched/pthread/pthread_mutexinit.c @@ -44,6 +44,8 @@ #include #include +#include + #include "pthread/pthread.h" /**************************************************************************** diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c index c5609fdcd5..daacca9f30 100644 --- a/sched/semaphore/sem_setprotocol.c +++ b/sched/semaphore/sem_setprotocol.c @@ -39,10 +39,11 @@ #include -#include #include #include +#include + #include "semaphore/semaphore.h" #ifdef CONFIG_PRIORITY_INHERITANCE diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 8d8307f42a..8ecf52854f 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -118,7 +118,7 @@ "sem_destroy","semaphore.h","","int","FAR sem_t*" "sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","..." "sem_post","semaphore.h","","int","FAR sem_t*" -"sem_setprotocol","semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" +"sem_setprotocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" "sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *" "sem_trywait","semaphore.h","","int","FAR sem_t*" "sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char*" From 9a49ab8260435da6ba3cf26d7a7f0fcc5c2b8efa Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 16:32:59 -0600 Subject: [PATCH 037/155] Correct a wrong comment --- include/nuttx/semaphore.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 7fef2a91c5..d9df434fef 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -67,9 +67,7 @@ struct nsem_inode_s sem_t ns_sem; /* The contained semaphore */ - /* Inode payload unique to named semaphores. ns_inode must appear first - * in this structure in order to support casting between type sem_t and - * types of struct nsem_inode_s. */ + /* Inode payload unique to named semaphores. */ FAR struct inode *ns_inode; /* Containing inode */ }; From 97bf82ee05036a26a15c1df6f27574ca60888df6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 18:21:46 -0600 Subject: [PATCH 038/155] Semaphores: Provide macros for sem_setprotobol() and sem_getprotocol() if priority inheritance is not enabled. More SEM_PRIO_* definitions to include/nuttx/semaphore.h --- TODO | 51 ++++++++++++++++++++++++++++++- include/nuttx/semaphore.h | 33 ++++++++++++++++++-- include/pthread.h | 27 ++++++++-------- include/semaphore.h | 22 +++++-------- sched/semaphore/sem_setprotocol.c | 19 ++++++++++++ 5 files changed, 120 insertions(+), 32 deletions(-) diff --git a/TODO b/TODO index 3c187e017e..97d9f00719 100644 --- a/TODO +++ b/TODO @@ -9,7 +9,7 @@ issues related to each board port. nuttx/: - (13) Task/Scheduler (sched/) + (14) Task/Scheduler (sched/) (1) Memory Management (mm/) (1) Power Management (drivers/pm) (3) Signals (sched/signal, arch/) @@ -216,6 +216,55 @@ o Task/Scheduler (sched/) Status: Open Priority: Medium-ish + Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE USED AS IPC + Description: The semaphores have multiple uses. The typical usage is where + the semaphore is used as lock on one or more resources. In + this typical case, priority inheritance works perfectly: The + holder of a semaphore count must be remembered so that its + priority can be boosted if a higher priority task requires a + count from the semaphore. It remains the holder until is + calls sem_post() to release the count on the semaphore. + + But a different usage model for semaphores is for signalling + events. In this case, the semaphore count is initialized to + zero and the receiving task calls sem_wait() to wait for the + next event of interest. When an event of interest is + detected by another task (or even an interrupt handler), + sem_post() is called which increments the count to 1 and + wakes up the receiving task. + + For example, in the following TASK A waits for events and + TASK B (or perhaps an interrupt handler) signals task A of + the occurence of the events by posting the semaphore: + + TASK A TASK B + sem_init(sem, 0, 0); + sem_wait(sem); + sem_post(sem); + Awakens as holder + + These two usage models are really very different and priority + inheritance simply does not apply when the semaphore is used for + signalling rather than locking. In this signalling case + priority inheritance can interfere with the operation of the + semaphore. The problem is that when TASK A is awakened it is + a holder of the semaphore. Normally, a task is removed from + the holder list when it finally release the + + However, TASK A never calls sem_post(sem) so it becomes + *permanently* a holder of the semaphore and may have its + priority boosted when any other task tries to acquire the + semaphore. + + The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately + after the sem_init() call so that there will be no priority + inheritance operations on this semaphore used for signalling. + Status: Open + Priority: High. If you have priority inheritance enabled and you use + semaphores for signalling events, then you *must* call + sem_setprotocol(SEM_PRIO_NONE) immediately after initializing + the semaphore. + Title: SCALABILITY Description: Task control information is retained in simple lists. This is completely appropriate for small embedded systems where diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 7fef2a91c5..04fde1bacb 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -51,6 +51,12 @@ * Pre-processor Definitions ****************************************************************************/ +/* Values for protocol attribute */ + +#define SEM_PRIO_NONE 0 +#define SEM_PRIO_INHERIT 1 +#define SEM_PRIO_PROTECT 2 + /**************************************************************************** * Public Type Definitions ****************************************************************************/ @@ -67,9 +73,7 @@ struct nsem_inode_s sem_t ns_sem; /* The contained semaphore */ - /* Inode payload unique to named semaphores. ns_inode must appear first - * in this structure in order to support casting between type sem_t and - * types of struct nsem_inode_s. */ + /* Inode payload unique to named semaphores. */ FAR struct inode *ns_inode; /* Containing inode */ }; @@ -158,6 +162,8 @@ int sem_reset(FAR sem_t *sem, int16_t count); #ifdef CONFIG_PRIORITY_INHERITANCE int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); +#else +# define sem_getprotocol(s,p) do { *(p) == SEM_PRIO_NONE); } while (0) #endif /**************************************************************************** @@ -166,6 +172,25 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); * Description: * Set semaphore protocol attribute. * + * One particularly important use of this function is when a semaphore + * is used for inter-task communication like: + * + * TASK A TASK B + * sem_init(sem, 0, 0); + * sem_wait(sem); + * sem_post(sem); + * Awakens as holder + * + * In this case priority inheritance can interfere with the operation of + * the semaphore. The problem is that when TASK A is restarted it is a + * holder of the semaphore. However, it never calls sem_post(sem) so it + * becomes *permanently* a holder of the semaphore and may have its + * priority boosted when any other task tries to acquire the semaphore. + * + * The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after + * the sem_init() call so that there will be no priority inheritance + * operations on this semaphore. + * * Parameters: * sem - A pointer to the semaphore whose attributes are to be * modified @@ -179,6 +204,8 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); #ifdef CONFIG_PRIORITY_INHERITANCE int sem_setprotocol(FAR sem_t *sem, int protocol); +#else +# define sem_setprotocol(s,p) DEBUGASSERT((p) == SEM_PRIO_NONE); #endif #undef EXTERN diff --git a/include/pthread.h b/include/pthread.h index e25e63d41f..1c368d737b 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -40,18 +40,19 @@ * Included Files ********************************************************************************/ -#include /* Default settings */ -#include /* Compiler settings, noreturn_function */ +#include /* Default settings */ +#include /* Compiler settings, noreturn_function */ -#include /* Needed for general types */ -#include /* Needed by pthread_[set|get]name_np */ +#include /* Needed for general types */ +#include /* Needed by pthread_[set|get]name_np */ -#include /* C99 fixed width integer types */ -#include /* C99 boolean types */ -#include /* For getpid */ -#include /* Needed for sem_t */ -#include /* Needed for sigset_t, includes this file */ -#include /* Needed for struct timespec */ +#include /* C99 fixed width integer types */ +#include /* C99 boolean types */ +#include /* For getpid */ +#include /* Needed for sigset_t, includes this file */ +#include /* Needed for struct timespec */ + +#include /* For sem_t and SEM_PRIO_* defines */ /******************************************************************************** * Pre-processor Definitions @@ -112,9 +113,7 @@ #define PTHREAD_INHERIT_SCHED 0 #define PTHREAD_EXPLICIT_SCHED 1 -#define PTHREAD_PRIO_NONE 0 -#define PTHREAD_PRIO_INHERIT 1 -#define PTHREAD_PRIO_PROTECT 2 +/* Default priority */ #define PTHREAD_DEFAULT_PRIORITY 100 @@ -135,7 +134,7 @@ #define PTHREAD_BARRIER_SERIAL_THREAD 0x1000 -/* Values for protocol attribute */ +/* Values for protocol mutex attribute */ #define PTHREAD_PRIO_NONE SEM_PRIO_NONE #define PTHREAD_PRIO_INHERIT SEM_PRIO_INHERIT diff --git a/include/semaphore.h b/include/semaphore.h index 964d753bd9..8821b129d0 100644 --- a/include/semaphore.h +++ b/include/semaphore.h @@ -45,24 +45,10 @@ #include #include -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* Values for protocol attribute */ - -#define SEM_PRIO_NONE 0 -#define SEM_PRIO_INHERIT 1 -#define SEM_PRIO_PROTECT 2 - /* Bit definitions for the struct sem_s flags field */ #define PRIOINHERIT_FLAGS_DISABLE (1 << 0) /* Bit 0: Priority inheritance @@ -130,6 +116,14 @@ typedef struct sem_s sem_t; * Public Data ****************************************************************************/ +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c index daacca9f30..1350206941 100644 --- a/sched/semaphore/sem_setprotocol.c +++ b/sched/semaphore/sem_setprotocol.c @@ -58,6 +58,25 @@ * Description: * Set semaphore protocol attribute. * + * One particularly important use of this furnction is when a semaphore + * is used for inter-task communication like: + * + * TASK A TASK B + * sem_init(sem, 0, 0); + * sem_wait(sem); + * sem_post(sem); + * Awakens as holder + * + * In this case priority inheritance can interfere with the operation of + * the semaphore. The problem is that when TASK A is restarted it is a + * holder of the semaphore. However, it never calls sem_post(sem) so it + * becomes *permanently* a holder of the semaphore and may have its + * priority boosted when any other task tries to acquire the semaphore. + * + * The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after + * the sem_init() call so that there will be no priority inheritance + * operations on this semaphore. + * * Parameters: * sem - A pointer to the semaphore whose attributes are to be * modified From 470c692dbf79098b5fdf18169bbf87c7ad9a2138 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Wed, 2 Nov 2016 18:31:22 -0600 Subject: [PATCH 039/155] Update TODO list --- TODO | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 97d9f00719..62d2e562ce 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -NuttX TODO List (Last updated October 9, 2016) +NuttX TODO List (Last updated November 2, 2016) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This file summarizes known NuttX bugs, limitations, inconsistencies with @@ -217,13 +217,14 @@ o Task/Scheduler (sched/) Priority: Medium-ish Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE USED AS IPC - Description: The semaphores have multiple uses. The typical usage is where + Description: Semaphores have multiple uses. The typical usage is where the semaphore is used as lock on one or more resources. In this typical case, priority inheritance works perfectly: The holder of a semaphore count must be remembered so that its priority can be boosted if a higher priority task requires a - count from the semaphore. It remains the holder until is - calls sem_post() to release the count on the semaphore. + count from the semaphore. It remains the holder until the + same task calls sem_post() to release the count on the + semaphore. But a different usage model for semaphores is for signalling events. In this case, the semaphore count is initialized to @@ -237,11 +238,14 @@ o Task/Scheduler (sched/) TASK B (or perhaps an interrupt handler) signals task A of the occurence of the events by posting the semaphore: + ---------------------- --------------- TASK A TASK B + ---------------------- --------------- sem_init(sem, 0, 0); sem_wait(sem); sem_post(sem); Awakens as holder + ---------------------- --------------- These two usage models are really very different and priority inheritance simply does not apply when the semaphore is used for @@ -249,12 +253,13 @@ o Task/Scheduler (sched/) priority inheritance can interfere with the operation of the semaphore. The problem is that when TASK A is awakened it is a holder of the semaphore. Normally, a task is removed from - the holder list when it finally release the + the holder list when it finally releases the semaphore via + sem_post(). However, TASK A never calls sem_post(sem) so it becomes *permanently* a holder of the semaphore and may have its - priority boosted when any other task tries to acquire the - semaphore. + priority boosted at any time when any other task tries to + acquire the semaphore. The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after the sem_init() call so that there will be no priority From 54d7656f18375215e30bcfda74ded9c408ef4f37 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 07:04:03 -0600 Subject: [PATCH 040/155] Update some comments --- arch/xtensa/src/esp32/esp32_cpuhead.S | 4 +--- arch/xtensa/src/esp32/esp32_cpuidlestack.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/arch/xtensa/src/esp32/esp32_cpuhead.S b/arch/xtensa/src/esp32/esp32_cpuhead.S index 9fb05f66ea..40cbf2e85d 100644 --- a/arch/xtensa/src/esp32/esp32_cpuhead.S +++ b/arch/xtensa/src/esp32/esp32_cpuhead.S @@ -110,9 +110,7 @@ __cpu1_start: l32r sp, .Lcpu1_bottomofstack - /* Does it make since to have co-processors enabled on the IDLE thread? */ - -//#warning REVISIT: Must set aside co-processor save ares + /* REVIST: Does it make since to have co-processors enabled on the IDLE thread? */ #ifdef CONFIG_STACK_COLORATION /* Write a known value to the IDLE thread stack to support stack diff --git a/arch/xtensa/src/esp32/esp32_cpuidlestack.c b/arch/xtensa/src/esp32/esp32_cpuidlestack.c index e1f0941ce9..7b2e90364e 100644 --- a/arch/xtensa/src/esp32/esp32_cpuidlestack.c +++ b/arch/xtensa/src/esp32/esp32_cpuidlestack.c @@ -102,9 +102,7 @@ int up_cpu_idlestack(int cpu, FAR struct tcb_s *tcb, size_t stack_size) tcb->adj_stack_ptr = (uint32_t *)topofstack; #if XCHAL_CP_NUM > 0 - /* Does it make since to have co-processors enabled on the IDLE thread? */ - -//#warning REVISIT: Need to set co-processor save are in TCB + /* REVISIT: Does it make since to have co-processors enabled on the IDLE thread? */ #endif return OK; From cb96e632faf84ccaa98d401160b41f78ed3cdf1b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 07:21:25 -0600 Subject: [PATCH 041/155] LM32: Add toolchain configuration; Add Toolchain.defs. --- arch/arm/src/armv7-r/Kconfig | 2 +- arch/misoc/src/lm32/Kconfig | 24 +++++++ arch/misoc/src/lm32/Toolchain.defs | 104 +++++++++++++++++++++++++++++ configs/misoc/hello/Make.defs | 2 +- 4 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 arch/misoc/src/lm32/Toolchain.defs diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig index 0582a4fee3..810e80601d 100644 --- a/arch/arm/src/armv7-r/Kconfig +++ b/arch/arm/src/armv7-r/Kconfig @@ -162,7 +162,7 @@ config ARMV7R_TOOLCHAIN_GNU_OABI ---help--- This option should work for any GNU toolchain configured for arm-elf-. -endchoice # ARMV7R_HAVE_L2CC +endchoice # Toolchain Selection config ARMV7R_OABI_TOOLCHAIN bool "OABI (vs EABI)" diff --git a/arch/misoc/src/lm32/Kconfig b/arch/misoc/src/lm32/Kconfig index 75814271c6..b9178978e7 100644 --- a/arch/misoc/src/lm32/Kconfig +++ b/arch/misoc/src/lm32/Kconfig @@ -5,4 +5,28 @@ if ARCH_CHIP_LM32 +choice + prompt "Toolchain Selection" + default LM32_TOOLCHAIN_GNUW if HOST_WINDOWS + default LM32_TOOLCHAIN_GNUL if !HOST_WINDOWS + +config LM32_TOOLCHAIN_BUILDROOT + bool "Buildroot (Cygwin or Linux)" + depends on !WINDOWS_NATIVE + +config LM32_TOOLCHAIN_GNUL + bool "Generic GNU toolchain under Linux (or other POSIX environment)" + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for lm32-elf-. + +config LM32_TOOLCHAIN_GNUW + bool "Generic GNU toolchain under Windows" + depends on HOST_WINDOWS + ---help--- + This option should work for any modern GNU toolchain (GCC 4.5 or newer) + configured for lm32-elf-. + +endchoice # Toolchain Selection + endif # ARCH_CHIP_LM32 diff --git a/arch/misoc/src/lm32/Toolchain.defs b/arch/misoc/src/lm32/Toolchain.defs new file mode 100644 index 0000000000..e0227e2e16 --- /dev/null +++ b/arch/misoc/src/lm32/Toolchain.defs @@ -0,0 +1,104 @@ +############################################################################ +# arch/misco/src/lm32/Toolchain.defs +# +# Copyright (C) 2016 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. +# +############################################################################ + +# Setup for the selected toolchain + +# +# Select and allow the selected toolchain to be overridden by a command-line +#selection. +# + +ifeq ($(filter y, \ + $(CONFIG_LM32_TOOLCHAIN_BUILDROOT) \ + ),y) + CONFIG_LM32_TOOLCHAIN ?= BUILDROOT +endif + +ifeq ($(filter y, \ + $(CONFIG_LM32_TOOLCHAIN_GNUL) \ + ),y) + CONFIG_LM32_TOOLCHAIN ?= GNUL +endif + +ifeq ($(filter y, \ + $(CONFIG_LM32_TOOLCHAIN_GNUW) \ + ),y) + CONFIG_LM32_TOOLCHAIN ?= GNUW +endif + +# +# Supported toolchains +# +# Each toolchain definition should set: +# +# CROSSDEV The GNU toolchain triple (command prefix) +# ARCROSSDEV If required, an alternative prefix used when +# invoking ar and nm. +# ARCHCPUFLAGS CPU-specific flags selecting the instruction set +# FPU options, etc. +# MAXOPTIMIZATION The maximum optimization level that results in +# reliable code generation. +# + +ifeq ($(CONFIG_DEBUG_CUSTOMOPT),y) + MAXOPTIMIZATION := $(CONFIG_DEBUG_OPTLEVEL) +endif + +# NuttX buildroot under Linux or Cygwin + +ifeq ($(CONFIG_LM32_TOOLCHAIN),BUILDROOT) + CROSSDEV ?= lm32-nuttx-elf- + ARCROSSDEV ?= lm32-nuttx-elf- + MAXOPTIMIZATION ?= -Os +endif + +# Generic GNU toolchain on OS X, Linux or any typical Posix system + +ifeq ($(CONFIG_LM32_TOOLCHAIN),GNUL) + CROSSDEV ?= lm32-elf-- + ARCROSSDEV ?= lm32-elf-- + MAXOPTIMIZATION ?= -Os +endif + +# Generic GNU toolchain under Windows (native) + +ifeq ($(CONFIG_LM32_TOOLCHAIN),GNUW) + CROSSDEV ?= lm32-elf-- + ARCROSSDEV ?= lm32-elf-- + MAXOPTIMIZATION ?= -Os + ifeq ($(CONFIG_WINDOWS_CYGWIN),y) + WINTOOL = y + endif +endif diff --git a/configs/misoc/hello/Make.defs b/configs/misoc/hello/Make.defs index b6124b7759..f82c1cb223 100644 --- a/configs/misoc/hello/Make.defs +++ b/configs/misoc/hello/Make.defs @@ -36,7 +36,7 @@ include ${TOPDIR}/.config include ${TOPDIR}/tools/Config.mk -CROSSDEV = lm32-elf- +include ${TOPDIR}/arch/misoc/src/lm32/Toolchain.defs LDSCRIPT = ld.script From 47b043df1eff60b4ed6368dd34dc69a6d48240b0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 08:16:59 -0600 Subject: [PATCH 042/155] drivers/serial.c: Make sure that priority inheritance is not enabled for the signaling semaphores used in the serial driver. --- drivers/serial/serial.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 2b6d7ec8e5..64354e2a76 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -52,6 +51,7 @@ #include #include +#include #include #include #include @@ -112,16 +112,6 @@ static const struct file_operations g_serialops = * Private Functions ************************************************************************************/ -/************************************************************************************ - * Name: sem_reinit - ************************************************************************************/ - -static int sem_reinit(FAR sem_t *sem, int pshared, unsigned int value) -{ - sem_destroy(sem); - return sem_init(sem, pshared, value); -} - /************************************************************************************ * Name: uart_takesem ************************************************************************************/ @@ -1253,19 +1243,14 @@ static int uart_close(FAR struct file *filep) /* We need to re-initialize the semaphores if this is the last close * of the device, as the close might be caused by pthread_cancel() of * a thread currently blocking on any of them. - * - * REVISIT: This logic *only* works in the case where the cancelled - * thread had the only reference to the serial driver. If there other - * references, then the this logic will not be executed and the - * semaphore count will still be incorrect. */ - sem_reinit(&dev->xmitsem, 0, 0); - sem_reinit(&dev->recvsem, 0, 0); - sem_reinit(&dev->xmit.sem, 0, 1); - sem_reinit(&dev->recv.sem, 0, 1); + sem_reset(&dev->xmitsem, 0); + sem_reset(&dev->recvsem, 0); + sem_reset(&dev->xmit.sem, 1); + sem_reset(&dev->recv.sem, 1); #ifndef CONFIG_DISABLE_POLL - sem_reinit(&dev->pollsem, 0, 1); + sem_reset(&dev->pollsem, 1); #endif uart_givesem(&dev->closesem); @@ -1416,6 +1401,8 @@ errout_with_sem: int uart_register(FAR const char *path, FAR uart_dev_t *dev) { + /* Initialize semaphores */ + sem_init(&dev->xmit.sem, 0, 1); sem_init(&dev->recv.sem, 0, 1); sem_init(&dev->closesem, 0, 1); @@ -1425,6 +1412,15 @@ int uart_register(FAR const char *path, FAR uart_dev_t *dev) sem_init(&dev->pollsem, 0, 1); #endif + /* The recvsem and xmitsem are used for signaling and, hence, should not have + * priroity inheritance enabled. + */ + + sem_setprotocol(&dev->xmitsem, SEM_PRIO_NONE); + sem_setprotocol(&dev->recvsem, SEM_PRIO_NONE); + + /* Register the serial driver */ + _info("Registering %s\n", path); return register_driver(path, &g_serialops, 0666, dev); } From 1e754402b86e10c28ada5949d33c8b759ab463fb Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Thu, 3 Nov 2016 08:50:58 -0600 Subject: [PATCH 043/155] Add C++ support linking with GNU toolchain newlib/stdlibc++ --- arch/arm/src/Makefile | 12 +- configs/bambino-200e/gnutoolcpp/Make.defs | 141 +++ configs/bambino-200e/gnutoolcpp/defconfig | 1004 +++++++++++++++++++++ configs/bambino-200e/gnutoolcpp/setenv.sh | 92 ++ configs/samv71-xult/nsh/defconfig | 8 +- include/cxx/cwchar | 2 +- libxx/Kconfig | 8 + 7 files changed, 1261 insertions(+), 6 deletions(-) create mode 100644 configs/bambino-200e/gnutoolcpp/Make.defs create mode 100644 configs/bambino-200e/gnutoolcpp/defconfig create mode 100644 configs/bambino-200e/gnutoolcpp/setenv.sh diff --git a/arch/arm/src/Makefile b/arch/arm/src/Makefile index e505b956da..b182a97e7e 100644 --- a/arch/arm/src/Makefile +++ b/arch/arm/src/Makefile @@ -168,6 +168,14 @@ endif LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" GCC_LIBDIR := ${shell dirname $(LIBGCC)} +ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) + LIBGXX = "${shell "$(CXX)" $(ARCHCPUFLAGS) -print-file-name=$(LIBSTDCXX)}" + GXX_LIBDIR := ${shell dirname $(LIBGXX)} + LIBCXXPATH = -L"$(GXX_LIBDIR)" +else + LIBCXXPATH ?= +endif + VPATH += chip VPATH += common VPATH += $(ARCH_SUBDIR) @@ -201,9 +209,9 @@ board$(DELIM)libboard$(LIBEXT): nuttx$(EXEEXT): $(HEAD_OBJ) board$(DELIM)libboard$(LIBEXT) $(Q) echo "LD: nuttx" - $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \ + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(LIBCXXPATH) $(EXTRA_LIBPATHS) \ -o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \ - $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) $(LDENDGROUP) + $(LDSTARTGROUP) $(LDLIBS) $(LDLIBSCXX) $(EXTRA_LIBS) $(LIBGCC) $(LDENDGROUP) ifneq ($(CONFIG_WINDOWS_NATIVE),y) $(Q) $(NM) $(NUTTX) | \ grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ diff --git a/configs/bambino-200e/gnutoolcpp/Make.defs b/configs/bambino-200e/gnutoolcpp/Make.defs new file mode 100644 index 0000000000..a7d6e8d274 --- /dev/null +++ b/configs/bambino-200e/gnutoolcpp/Make.defs @@ -0,0 +1,141 @@ +############################################################################ +# configs/bambino-200e/nsh/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Alan Carvalho de Assis +# +# 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. +# +############################################################################ + +include ${TOPDIR}/.config +include ${TOPDIR}/tools/Config.mk +include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs + +# Setup for the kind of memory that we are executing from + +ifeq ($(CONFIG_LPC43_BOOT_SRAM),y) + LDSCRIPT = ramconfig.ld +endif +ifeq ($(CONFIG_LPC43_BOOT_SPIFI),y) + LDSCRIPT = spificonfig.ld +endif +ifeq ($(CONFIG_LPC43_BOOT_FLASHA),y) + LDSCRIPT = flashaconfig.ld +endif +ifeq ($(CONFIG_LPC43_BOOT_FLASHB),y) + LDSCRIPT = flashaconfig.ld +endif +ifeq ($(CONFIG_LPC43_BOOT_CS0FLASH),y) + LDSCRIPT = cs0flash.ld +endif + +# Setup for Windows vs Linux/Cygwin/OSX environments + +ifeq ($(WINTOOL),y) + # Windows-native toolchains + DIRLINK = $(TOPDIR)/tools/copydir.sh + DIRUNLINK = $(TOPDIR)/tools/unlink.sh + MKDEP = $(TOPDIR)/tools/mkwindeps.sh + ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" + ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" + ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}" +else + # Linux/Cygwin-native toolchain + MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT) + ARCHINCLUDES = -I. -isystem $(TOPDIR)/include + ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx + ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT) +endif + +CC = $(CROSSDEV)gcc +CXX = $(CROSSDEV)g++ +CPP = $(CROSSDEV)gcc -E +LD = $(CROSSDEV)ld +AR = $(ARCROSSDEV)ar rcs +NM = $(ARCROSSDEV)nm +OBJCOPY = $(CROSSDEV)objcopy +OBJDUMP = $(CROSSDEV)objdump + +ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'} +ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1} + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer +endif + +ARCHCFLAGS = -fno-builtin +ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) +ARCHCXXFLAGS = -fno-builtin -fno-use-cxa-atexit -fcheck-new -specs=nano.specs -lstdc++ -lsupc++ -lm -lgcc -lc -lnosys -std=gnu++11 +else +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti +endif +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef +ARCHDEFINES = +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +AFLAGS = $(CFLAGS) -D__ASSEMBLY__ + +ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) +LDLIBSCXX = -lstdc++_nano -lsupc++_nano -lnosys -lm +LIBSTDCXX = libstdc++_nano.a +endif + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +ASMEXT = .S +OBJEXT = .o +LIBEXT = .a +EXEEXT = + +ifneq ($(CROSSDEV),arm-nuttx-elf-) + LDFLAGS += -nostartfiles -nodefaultlibs --no-wchar-size-warning +endif +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + LDFLAGS += -g +endif + + +HOSTCC = gcc +HOSTINCLUDES = -I. +HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe +HOSTLDFLAGS = + diff --git a/configs/bambino-200e/gnutoolcpp/defconfig b/configs/bambino-200e/gnutoolcpp/defconfig new file mode 100644 index 0000000000..1c7bbf0c87 --- /dev/null +++ b/configs/bambino-200e/gnutoolcpp/defconfig @@ -0,0 +1,1004 @@ +# +# Automatically generated file; DO NOT EDIT. +# Nuttx/ Configuration +# + +# +# Build Setup +# +# CONFIG_EXPERIMENTAL is not set +# CONFIG_DEFAULT_SMALL is not set +CONFIG_HOST_LINUX=y +# CONFIG_HOST_OSX is not set +# CONFIG_HOST_WINDOWS is not set +# CONFIG_HOST_OTHER is not set + +# +# Build Configuration +# +# CONFIG_APPS_DIR="../apps" +CONFIG_BUILD_FLAT=y +# CONFIG_BUILD_2PASS is not set + +# +# Binary Output Formats +# +# CONFIG_RRLOAD_BINARY is not set +# CONFIG_INTELHEX_BINARY is not set +# CONFIG_MOTOROLA_SREC is not set +CONFIG_RAW_BINARY=y +# CONFIG_UBOOT_UIMAGE is not set + +# +# Customize Header Files +# +# CONFIG_ARCH_STDINT_H is not set +# CONFIG_ARCH_STDBOOL_H is not set +# CONFIG_ARCH_MATH_H is not set +# CONFIG_ARCH_FLOAT_H is not set +CONFIG_ARCH_STDARG_H=y +# CONFIG_ARCH_DEBUG_H is not set + +# +# Debug Options +# +CONFIG_DEBUG_ALERT=y +# CONFIG_DEBUG_FEATURES is not set +CONFIG_ARCH_HAVE_STACKCHECK=y +# CONFIG_STACK_COLORATION is not set +# CONFIG_ARCH_HAVE_HEAPCHECK is not set +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ARCH_HAVE_CUSTOMOPT=y +CONFIG_DEBUG_NOOPT=y +# CONFIG_DEBUG_CUSTOMOPT is not set +# CONFIG_DEBUG_FULLOPT is not set + +# +# System Type +# +CONFIG_ARCH_ARM=y +# CONFIG_ARCH_AVR is not set +# CONFIG_ARCH_HC is not set +# CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_RGMP is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_SIM is not set +# CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set +# CONFIG_ARCH_Z16 is not set +# CONFIG_ARCH_Z80 is not set +CONFIG_ARCH="arm" + +# +# ARM Options +# +# CONFIG_ARCH_CHIP_A1X is not set +# CONFIG_ARCH_CHIP_C5471 is not set +# CONFIG_ARCH_CHIP_CALYPSO is not set +# CONFIG_ARCH_CHIP_DM320 is not set +# CONFIG_ARCH_CHIP_EFM32 is not set +# CONFIG_ARCH_CHIP_IMX1 is not set +# CONFIG_ARCH_CHIP_IMX6 is not set +# CONFIG_ARCH_CHIP_KINETIS is not set +# CONFIG_ARCH_CHIP_KL is not set +# CONFIG_ARCH_CHIP_LM is not set +# CONFIG_ARCH_CHIP_TIVA is not set +# CONFIG_ARCH_CHIP_LPC11XX is not set +# CONFIG_ARCH_CHIP_LPC17XX is not set +# CONFIG_ARCH_CHIP_LPC214X is not set +# CONFIG_ARCH_CHIP_LPC2378 is not set +# CONFIG_ARCH_CHIP_LPC31XX is not set +CONFIG_ARCH_CHIP_LPC43XX=y +# CONFIG_ARCH_CHIP_NUC1XX is not set +# CONFIG_ARCH_CHIP_SAMA5 is not set +# CONFIG_ARCH_CHIP_SAMD is not set +# CONFIG_ARCH_CHIP_SAML is not set +# CONFIG_ARCH_CHIP_SAM34 is not set +# CONFIG_ARCH_CHIP_SAMV7 is not set +# CONFIG_ARCH_CHIP_STM32 is not set +# CONFIG_ARCH_CHIP_STM32F7 is not set +# CONFIG_ARCH_CHIP_STM32L4 is not set +# CONFIG_ARCH_CHIP_STR71X is not set +# CONFIG_ARCH_CHIP_TMS570 is not set +# CONFIG_ARCH_CHIP_MOXART is not set +# CONFIG_ARCH_ARM7TDMI is not set +# CONFIG_ARCH_ARM926EJS is not set +# CONFIG_ARCH_ARM920T is not set +# CONFIG_ARCH_CORTEXM0 is not set +# CONFIG_ARCH_CORTEXM3 is not set +CONFIG_ARCH_CORTEXM4=y +# CONFIG_ARCH_CORTEXM7 is not set +# CONFIG_ARCH_CORTEXA5 is not set +# CONFIG_ARCH_CORTEXA8 is not set +# CONFIG_ARCH_CORTEXA9 is not set +# CONFIG_ARCH_CORTEXR4 is not set +# CONFIG_ARCH_CORTEXR4F is not set +# CONFIG_ARCH_CORTEXR5 is not set +# CONFIG_ARCH_CORTEX5F is not set +# CONFIG_ARCH_CORTEXR7 is not set +# CONFIG_ARCH_CORTEXR7F is not set +CONFIG_ARCH_FAMILY="armv7-m" +CONFIG_ARCH_CHIP="lpc43xx" +# CONFIG_ARM_TOOLCHAIN_IAR is not set +CONFIG_ARM_TOOLCHAIN_GNU=y +# CONFIG_ARMV7M_USEBASEPRI is not set +CONFIG_ARCH_HAVE_CMNVECTOR=y +CONFIG_ARMV7M_CMNVECTOR=y +# CONFIG_ARMV7M_LAZYFPU is not set +CONFIG_ARCH_HAVE_FPU=y +# CONFIG_ARCH_HAVE_DPFPU is not set +# CONFIG_ARCH_FPU is not set +# CONFIG_ARCH_HAVE_TRUSTZONE is not set +CONFIG_ARM_HAVE_MPU_UNIFIED=y +# CONFIG_ARM_MPU is not set + +# +# ARMV7M Configuration Options +# +# CONFIG_ARMV7M_HAVE_ICACHE is not set +# CONFIG_ARMV7M_HAVE_DCACHE is not set +# CONFIG_ARMV7M_HAVE_ITCM is not set +# CONFIG_ARMV7M_HAVE_DTCM is not set +# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set +# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set +CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y +# CONFIG_ARMV7M_HAVE_STACKCHECK is not set +# CONFIG_ARMV7M_ITMSYSLOG is not set +# CONFIG_SERIAL_TERMIOS is not set + +# +# LPC43xx Configuration Options +# +# CONFIG_ARCH_CHIP_LPC4310FBD144 is not set +# CONFIG_ARCH_CHIP_LPC4310FET100 is not set +# CONFIG_ARCH_CHIP_LPC4320FBD144 is not set +# CONFIG_ARCH_CHIP_LPC4320FET100 is not set +CONFIG_ARCH_CHIP_LPC4330FBD144=y +# CONFIG_ARCH_CHIP_LPC4330FET100 is not set +# CONFIG_ARCH_CHIP_LPC4330FET180 is not set +# CONFIG_ARCH_CHIP_LPC4330FET256 is not set +# CONFIG_ARCH_CHIP_LPC4337JBD144 is not set +# CONFIG_ARCH_CHIP_LPC4337JET100 is not set +# CONFIG_ARCH_CHIP_LPC4350FBD208 is not set +# CONFIG_ARCH_CHIP_LPC4350FET180 is not set +# CONFIG_ARCH_CHIP_LPC4350FET256 is not set +# CONFIG_ARCH_CHIP_LPC4353FBD208 is not set +# CONFIG_ARCH_CHIP_LPC4353FET180 is not set +# CONFIG_ARCH_CHIP_LPC4353FET256 is not set +# CONFIG_ARCH_CHIP_LPC4357FET180 is not set +# CONFIG_ARCH_CHIP_LPC4357FBD208 is not set +# CONFIG_ARCH_CHIP_LPC4357FET256 is not set +# CONFIG_ARCH_CHIP_LPC4370FET100 is not set +CONFIG_ARCH_FAMILY_LPC4330=y +# CONFIG_LPC43_BOOT_SRAM is not set +CONFIG_LPC43_BOOT_SPIFI=y +# CONFIG_LPC43_BOOT_FLASHA is not set +# CONFIG_LPC43_BOOT_FLASHB is not set +# CONFIG_LPC43_BOOT_CS0FLASH is not set +# CONFIG_LPC43_BOOT_CS1FLASH is not set +# CONFIG_LPC43_BOOT_CS2FLASH is not set +# CONFIG_LPC43_BOOT_CS3FLASH is not set + +# +# LPC43xx Peripheral Support +# +# CONFIG_LPC43_ADC0 is not set +# CONFIG_LPC43_ADC1 is not set +# CONFIG_LPC43_ATIMER is not set +# CONFIG_LPC43_CAN1 is not set +# CONFIG_LPC43_CAN2 is not set +# CONFIG_LPC43_DAC is not set +# CONFIG_LPC43_EMC is not set +# CONFIG_LPC43_ETHERNET is not set +# CONFIG_LPC43_EVNTMNTR is not set +# CONFIG_LPC43_GPDMA is not set +# CONFIG_LPC43_I2C0 is not set +# CONFIG_LPC43_I2C1 is not set +# CONFIG_LPC43_I2S0 is not set +# CONFIG_LPC43_I2S1 is not set +# CONFIG_LPC43_LCD is not set +# CONFIG_LPC43_MCPWM is not set +# CONFIG_LPC43_QEI is not set +# CONFIG_LPC43_RIT is not set +# CONFIG_LPC43_RTC is not set +# CONFIG_LPC43_SCT is not set +# CONFIG_LPC43_SDMMC is not set +# CONFIG_LPC43_SPI is not set +# CONFIG_LPC43_SPIFI is not set +# CONFIG_LPC43_SSP0 is not set +# CONFIG_LPC43_SSP1 is not set +# CONFIG_LPC43_TMR0 is not set +# CONFIG_LPC43_TMR1 is not set +# CONFIG_LPC43_TMR2 is not set +# CONFIG_LPC43_TMR3 is not set +# CONFIG_LPC43_USART0 is not set +CONFIG_LPC43_UART1=y +# CONFIG_LPC43_USART2 is not set +# CONFIG_LPC43_USART3 is not set +# CONFIG_LPC43_USBOTG is not set +CONFIG_LPC43_USB0=y +# CONFIG_LPC43_USB1 is not set +# CONFIG_LPC43_WWDT is not set +# CONFIG_LPC43_GPIO_IRQ is not set + +# +# Internal Memory Configuration +# +CONFIG_ARCH_HAVE_AHB_SRAM_BANK1=y +# CONFIG_LPC43_USE_LOCSRAM_BANK1 is not set +# CONFIG_LPC43_USE_AHBSRAM_BANK0 is not set +# CONFIG_LPC43_USE_AHBSRAM_BANK1 is not set +# CONFIG_LPC43_HEAP_AHBSRAM_BANK2 is not set + +# +# External Memory Configuration +# + +# +# RS-485 Configuration +# +# CONFIG_UART1_RS485MODE is not set +# CONFIG_UART1_RS485_DTRDIR is not set + +# +# USB device controller driver (DCD) options +# +# CONFIG_LPC43_USB0DEV_NOVBUS is not set + +# +# Architecture Options +# +# CONFIG_ARCH_NOINTC is not set +# CONFIG_ARCH_VECNOTIRQ is not set +# CONFIG_ARCH_DMA is not set +CONFIG_ARCH_HAVE_IRQPRIO=y +# CONFIG_ARCH_L2CACHE is not set +# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set +# CONFIG_ARCH_HAVE_ADDRENV is not set +# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set +# CONFIG_ARCH_HAVE_MULTICPU is not set +CONFIG_ARCH_HAVE_VFORK=y +# CONFIG_ARCH_HAVE_MMU is not set +CONFIG_ARCH_HAVE_MPU=y +# CONFIG_ARCH_NAND_HWECC is not set +# CONFIG_ARCH_HAVE_EXTCLK is not set +# CONFIG_ARCH_HAVE_POWEROFF is not set +CONFIG_ARCH_HAVE_RESET=y +# CONFIG_ARCH_USE_MPU is not set +# CONFIG_ARCH_IRQPRIO is not set +CONFIG_ARCH_STACKDUMP=y +# CONFIG_ENDIAN_BIG is not set +# CONFIG_ARCH_IDLE_CUSTOM is not set +# CONFIG_ARCH_HAVE_RAMFUNCS is not set +CONFIG_ARCH_HAVE_RAMVECTORS=y +# CONFIG_ARCH_RAMVECTORS is not set + +# +# Board Settings +# +CONFIG_BOARD_LOOPSPERMSEC=18535 +# CONFIG_ARCH_CALIBRATION is not set + +# +# Interrupt options +# +CONFIG_ARCH_HAVE_INTERRUPTSTACK=y +CONFIG_ARCH_INTERRUPTSTACK=0 +CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y +# CONFIG_ARCH_HIPRI_INTERRUPT is not set + +# +# Boot options +# +# CONFIG_BOOT_RUNFROMEXTSRAM is not set +CONFIG_BOOT_RUNFROMFLASH=y +# CONFIG_BOOT_RUNFROMISRAM is not set +# CONFIG_BOOT_RUNFROMSDRAM is not set +# CONFIG_BOOT_COPYTORAM is not set + +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x10000000 +CONFIG_RAM_SIZE=131072 +# CONFIG_ARCH_HAVE_SDRAM is not set + +# +# Board Selection +# +CONFIG_ARCH_BOARD_BAMBINO_200E=y +# CONFIG_ARCH_BOARD_CUSTOM is not set +CONFIG_ARCH_BOARD="bambino-200e" + +# +# Common Board Options +# +CONFIG_ARCH_HAVE_LEDS=y +CONFIG_ARCH_LEDS=y +CONFIG_ARCH_HAVE_BUTTONS=y +# CONFIG_ARCH_BUTTONS is not set +CONFIG_ARCH_HAVE_IRQBUTTONS=y + +# +# Board-Specific Options +# +# CONFIG_BOARD_CRASHDUMP is not set +CONFIG_LIB_BOARDCTL=y +# CONFIG_BOARDCTL_RESET is not set +# CONFIG_BOARDCTL_UNIQUEID is not set +CONFIG_BOARDCTL_USBDEVCTRL=y +# CONFIG_BOARDCTL_TSCTEST is not set +# CONFIG_BOARDCTL_ADCTEST is not set +# CONFIG_BOARDCTL_PWMTEST is not set +# CONFIG_BOARDCTL_GRAPHICS is not set +# CONFIG_BOARDCTL_IOCTL is not set + +# +# RTOS Features +# +CONFIG_DISABLE_OS_API=y +# CONFIG_DISABLE_POSIX_TIMERS is not set +# CONFIG_DISABLE_PTHREAD is not set +# CONFIG_DISABLE_SIGNALS is not set +# CONFIG_DISABLE_MQUEUE is not set +# CONFIG_DISABLE_ENVIRON is not set + +# +# Clocks and Timers +# +CONFIG_ARCH_HAVE_TICKLESS=y +# CONFIG_SCHED_TICKLESS is not set +CONFIG_USEC_PER_TICK=10000 +# CONFIG_SYSTEM_TIME64 is not set +# CONFIG_CLOCK_MONOTONIC is not set +# CONFIG_ARCH_HAVE_TIMEKEEPING is not set +# CONFIG_JULIAN_TIME is not set +CONFIG_START_YEAR=2012 +CONFIG_START_MONTH=7 +CONFIG_START_DAY=11 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_PREALLOC_WDOGS=4 +CONFIG_WDOG_INTRESERVE=0 +CONFIG_PREALLOC_TIMERS=4 + +# +# Tasks and Scheduling +# +# CONFIG_INIT_NONE is not set +CONFIG_INIT_ENTRYPOINT=y +# CONFIG_INIT_FILEPATH is not set +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_RR_INTERVAL=200 +# CONFIG_SCHED_SPORADIC is not set +CONFIG_TASK_NAME_SIZE=0 +CONFIG_MAX_TASKS=16 +# CONFIG_SCHED_HAVE_PARENT is not set +CONFIG_SCHED_WAITPID=y + +# +# Pthread Options +# +# CONFIG_MUTEX_TYPES is not set +CONFIG_NPTHREAD_KEYS=4 + +# +# Performance Monitoring +# +# CONFIG_SCHED_CPULOAD is not set +# CONFIG_SCHED_INSTRUMENTATION is not set + +# +# Files and I/O +# +CONFIG_DEV_CONSOLE=y +# CONFIG_FDCLONE_DISABLE is not set +# CONFIG_FDCLONE_STDIO is not set +CONFIG_SDCLONE_DISABLE=y +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NAME_MAX=32 +# CONFIG_PRIORITY_INHERITANCE is not set + +# +# RTOS hooks +# +# CONFIG_BOARD_INITIALIZE is not set +# CONFIG_SCHED_STARTHOOK is not set +# CONFIG_SCHED_ATEXIT is not set +# CONFIG_SCHED_ONEXIT is not set + +# +# Signal Numbers +# +CONFIG_SIG_SIGUSR1=1 +CONFIG_SIG_SIGUSR2=2 +CONFIG_SIG_SIGALARM=3 +CONFIG_SIG_SIGCONDTIMEDOUT=16 + +# +# POSIX Message Queue Options +# +CONFIG_PREALLOC_MQ_MSGS=4 +CONFIG_MQ_MAXMSGSIZE=32 +# CONFIG_MODULE is not set + +# +# Work queue support +# +# CONFIG_SCHED_WORKQUEUE is not set +# CONFIG_SCHED_HPWORK is not set +# CONFIG_SCHED_LPWORK is not set + +# +# Stack and heap information +# +CONFIG_IDLETHREAD_STACKSIZE=1024 +CONFIG_USERMAIN_STACKSIZE=2048 +CONFIG_PTHREAD_STACK_MIN=256 +CONFIG_PTHREAD_STACK_DEFAULT=2048 +# CONFIG_LIB_SYSCALL is not set + +# +# Device Drivers +# +# CONFIG_DISABLE_POLL is not set +CONFIG_DEV_NULL=y +# CONFIG_DEV_ZERO is not set +# CONFIG_DEV_URANDOM is not set +# CONFIG_DEV_LOOP is not set + +# +# Buffering +# +# CONFIG_DRVR_WRITEBUFFER is not set +# CONFIG_DRVR_READAHEAD is not set +# CONFIG_RAMDISK is not set +# CONFIG_CAN is not set +# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set +# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set +# CONFIG_PWM is not set +# CONFIG_ARCH_HAVE_I2CRESET is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set +# CONFIG_I2S is not set + +# +# Timer Driver Support +# +# CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set +# CONFIG_RTC is not set +# CONFIG_WATCHDOG is not set +# CONFIG_ANALOG is not set +# CONFIG_AUDIO_DEVICES is not set +# CONFIG_VIDEO_DEVICES is not set +# CONFIG_BCH is not set +# CONFIG_INPUT is not set + +# +# IO Expander/GPIO Support +# +# CONFIG_IOEXPANDER is not set +# CONFIG_DEV_GPIO is not set + +# +# LCD Driver Support +# +# CONFIG_LCD is not set +# CONFIG_SLCD is not set + +# +# LED Support +# +# CONFIG_USERLED is not set +# CONFIG_RGBLED is not set +# CONFIG_PCA9635PW is not set +# CONFIG_NCP5623C is not set +# CONFIG_MMCSD is not set +# CONFIG_MODEM is not set +# CONFIG_MTD is not set +# CONFIG_EEPROM is not set +# CONFIG_PIPES is not set +# CONFIG_PM is not set +# CONFIG_POWER is not set +# CONFIG_SENSORS is not set +# CONFIG_SERCOMM_CONSOLE is not set +CONFIG_SERIAL=y +# CONFIG_DEV_LOWCONSOLE is not set +CONFIG_SERIAL_REMOVABLE=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_16550_UART is not set +# CONFIG_UART_SERIALDRIVER is not set +# CONFIG_UART0_SERIALDRIVER is not set +CONFIG_UART1_SERIALDRIVER=y +# CONFIG_UART2_SERIALDRIVER is not set +# CONFIG_UART3_SERIALDRIVER is not set +# CONFIG_UART4_SERIALDRIVER is not set +# CONFIG_UART5_SERIALDRIVER is not set +# CONFIG_UART6_SERIALDRIVER is not set +# CONFIG_UART7_SERIALDRIVER is not set +# CONFIG_UART8_SERIALDRIVER is not set +# CONFIG_SCI0_SERIALDRIVER is not set +# CONFIG_SCI1_SERIALDRIVER is not set +# CONFIG_USART0_SERIALDRIVER is not set +# CONFIG_USART1_SERIALDRIVER is not set +# CONFIG_USART2_SERIALDRIVER is not set +# CONFIG_USART3_SERIALDRIVER is not set +# CONFIG_USART4_SERIALDRIVER is not set +# CONFIG_USART5_SERIALDRIVER is not set +# CONFIG_USART6_SERIALDRIVER is not set +# CONFIG_USART7_SERIALDRIVER is not set +# CONFIG_USART8_SERIALDRIVER is not set +# CONFIG_OTHER_UART_SERIALDRIVER is not set +CONFIG_MCU_SERIAL=y +CONFIG_STANDARD_SERIAL=y +CONFIG_SERIAL_NPOLLWAITERS=2 +# CONFIG_SERIAL_IFLOWCONTROL is not set +# CONFIG_SERIAL_OFLOWCONTROL is not set +# CONFIG_SERIAL_DMA is not set +CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y +CONFIG_UART1_SERIAL_CONSOLE=y +# CONFIG_OTHER_SERIAL_CONSOLE is not set +# CONFIG_NO_SERIAL_CONSOLE is not set + +# +# UART1 Configuration +# +CONFIG_UART1_RXBUFSIZE=256 +CONFIG_UART1_TXBUFSIZE=256 +CONFIG_UART1_BAUD=115200 +CONFIG_UART1_BITS=8 +CONFIG_UART1_PARITY=0 +CONFIG_UART1_2STOP=0 +# CONFIG_UART1_IFLOWCONTROL is not set +# CONFIG_UART1_OFLOWCONTROL is not set +# CONFIG_UART1_DMA is not set +# CONFIG_PSEUDOTERM is not set +CONFIG_USBDEV=y + +# +# USB Device Controller Driver Options +# +# CONFIG_USBDEV_ISOCHRONOUS is not set +# CONFIG_USBDEV_DUALSPEED is not set +CONFIG_USBDEV_SELFPOWERED=y +# CONFIG_USBDEV_BUSPOWERED is not set +CONFIG_USBDEV_MAXPOWER=100 +# CONFIG_USBDEV_DMA is not set +# CONFIG_ARCH_USBDEV_STALLQUEUE is not set +# CONFIG_USBDEV_TRACE is not set + +# +# USB Device Class Driver Options +# +# CONFIG_USBDEV_COMPOSITE is not set +# CONFIG_PL2303 is not set +CONFIG_CDCACM=y +# CONFIG_CDCACM_CONSOLE is not set +CONFIG_CDCACM_EP0MAXPACKET=64 +CONFIG_CDCACM_EPINTIN=1 +CONFIG_CDCACM_EPINTIN_FSSIZE=64 +CONFIG_CDCACM_EPINTIN_HSSIZE=64 +CONFIG_CDCACM_EPBULKOUT=3 +CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 +CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 +CONFIG_CDCACM_EPBULKIN=2 +CONFIG_CDCACM_EPBULKIN_FSSIZE=64 +CONFIG_CDCACM_EPBULKIN_HSSIZE=512 +CONFIG_CDCACM_NRDREQS=4 +CONFIG_CDCACM_NWRREQS=4 +CONFIG_CDCACM_BULKIN_REQLEN=96 +CONFIG_CDCACM_RXBUFSIZE=257 +CONFIG_CDCACM_TXBUFSIZE=193 +CONFIG_CDCACM_VENDORID=0x0525 +CONFIG_CDCACM_PRODUCTID=0xa4a7 +CONFIG_CDCACM_VENDORSTR="NuttX" +CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" +# CONFIG_USBMSC is not set +# CONFIG_USBHOST is not set +# CONFIG_HAVE_USBTRACE is not set +# CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set + +# +# System Logging +# +# CONFIG_ARCH_SYSLOG is not set +# CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_INTBUFFER is not set +# CONFIG_SYSLOG_TIMESTAMP is not set +CONFIG_SYSLOG_SERIAL_CONSOLE=y +# CONFIG_SYSLOG_CHAR is not set +CONFIG_SYSLOG_CONSOLE=y +# CONFIG_SYSLOG_NONE is not set +# CONFIG_SYSLOG_FILE is not set +# CONFIG_SYSLOG_CHARDEV is not set + +# +# Networking Support +# +# CONFIG_ARCH_HAVE_NET is not set +# CONFIG_ARCH_HAVE_PHY is not set +# CONFIG_NET is not set + +# +# Crypto API +# +# CONFIG_CRYPTO is not set + +# +# File Systems +# + +# +# File system configuration +# +# CONFIG_DISABLE_MOUNTPOINT is not set +# CONFIG_FS_AUTOMOUNTER is not set +# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set +CONFIG_FS_READABLE=y +CONFIG_FS_WRITABLE=y +# CONFIG_FS_NAMED_SEMAPHORES is not set +CONFIG_FS_MQUEUE_MPATH="/var/mqueue" +# CONFIG_FS_RAMMAP is not set +CONFIG_FS_FAT=y +CONFIG_FAT_LCNAMES=y +CONFIG_FAT_LFN=y +CONFIG_FAT_MAXFNAME=32 +# CONFIG_FS_FATTIME is not set +# CONFIG_FAT_FORCE_INDIRECT is not set +# CONFIG_FAT_DMAMEMORY is not set +# CONFIG_FAT_DIRECT_RETRY is not set +# CONFIG_FS_NXFFS is not set +# CONFIG_FS_ROMFS is not set +# CONFIG_FS_TMPFS is not set +# CONFIG_FS_SMARTFS is not set +# CONFIG_FS_BINFS is not set +# CONFIG_FS_PROCFS is not set +# CONFIG_FS_UNIONFS is not set + +# +# Graphics Support +# +# CONFIG_NX is not set + +# +# Memory Management +# +# CONFIG_MM_SMALL is not set +CONFIG_MM_REGIONS=2 +# CONFIG_ARCH_HAVE_HEAP2 is not set +# CONFIG_GRAN is not set + +# +# Audio Support +# +# CONFIG_AUDIO is not set + +# +# Wireless Support +# + +# +# Binary Loader +# +# CONFIG_BINFMT_DISABLE is not set +# CONFIG_BINFMT_EXEPATH is not set +# CONFIG_NXFLAT is not set +# CONFIG_ELF is not set +CONFIG_BUILTIN=y +# CONFIG_PIC is not set +CONFIG_SYMTAB_ORDEREDBYNAME=y + +# +# Library Routines +# + +# +# Standard C Library Options +# +CONFIG_STDIO_BUFFER_SIZE=64 +CONFIG_STDIO_LINEBUFFER=y +CONFIG_NUNGET_CHARS=2 +CONFIG_LIB_HOMEDIR="/" +# CONFIG_LIBM is not set +# CONFIG_NOPRINTF_FIELDWIDTH is not set +# CONFIG_LIBC_FLOATINGPOINT is not set +CONFIG_LIBC_LONG_LONG=y +# CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set +CONFIG_LIB_RAND_ORDER=1 +# CONFIG_EOL_IS_CR is not set +# CONFIG_EOL_IS_LF is not set +# CONFIG_EOL_IS_BOTH_CRLF is not set +CONFIG_EOL_IS_EITHER_CRLF=y +# CONFIG_LIBC_EXECFUNCS is not set +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 +# CONFIG_LIBC_STRERROR is not set +# CONFIG_LIBC_PERROR_STDOUT is not set +CONFIG_LIBC_TMPDIR="/tmp" +CONFIG_LIBC_MAX_TMPFILE=32 +CONFIG_ARCH_LOWPUTC=y +# CONFIG_LIBC_LOCALTIME is not set +# CONFIG_TIME_EXTENDED is not set +CONFIG_LIB_SENDFILE_BUFSIZE=512 +# CONFIG_ARCH_ROMGETC is not set +# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set +CONFIG_ARCH_HAVE_TLS=y +# CONFIG_TLS is not set +# CONFIG_LIBC_NETDB is not set +# CONFIG_NETDB_HOSTFILE is not set + +# +# Non-standard Library Support +# +# CONFIG_LIB_CRC64_FAST is not set +# CONFIG_LIB_KBDCODEC is not set +# CONFIG_LIB_SLCDCODEC is not set +# CONFIG_LIB_HEX2BIN is not set + +# +# Basic CXX Support +# +# CONFIG_C99_BOOL8 is not set +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +# CONFIG_CXX_NEWLONG is not set +CONFIG_CXX_LINK_GNUTOOL_LIB=y + +# +# uClibc++ Standard C++ Library +# +# CONFIG_UCLIBCXX is not set + +# +# Application Configuration +# + +# +# Built-In Applications +# +CONFIG_BUILTIN_PROXY_STACKSIZE=1024 + +# +# CAN Utilities +# + +# +# Examples +# +# CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set +# CONFIG_EXAMPLES_CHAT is not set +# CONFIG_EXAMPLES_CONFIGDATA is not set +# CONFIG_EXAMPLES_CXXTEST is not set +# CONFIG_EXAMPLES_DHCPD is not set +# CONFIG_EXAMPLES_ELF is not set +# CONFIG_EXAMPLES_FSTEST is not set +# CONFIG_EXAMPLES_FTPC is not set +# CONFIG_EXAMPLES_FTPD is not set +# CONFIG_EXAMPLES_HELLO is not set +# CONFIG_EXAMPLES_HELLOXX is not set +# CONFIG_EXAMPLES_HIDKBD is not set +# CONFIG_EXAMPLES_IGMP is not set +# CONFIG_EXAMPLES_JSON is not set +# CONFIG_EXAMPLES_KEYPADTEST is not set +# CONFIG_EXAMPLES_MEDIA is not set +# CONFIG_EXAMPLES_MM is not set +# CONFIG_EXAMPLES_MODBUS is not set +# CONFIG_EXAMPLES_MOUNT is not set +# CONFIG_EXAMPLES_NRF24L01TERM is not set +CONFIG_EXAMPLES_NSH=y +# CONFIG_EXAMPLES_NSH_CXXINITIALIZE is not set +# CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NXFFS is not set +# CONFIG_EXAMPLES_NXHELLO is not set +# CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set +# CONFIG_EXAMPLES_NXLINES is not set +# CONFIG_EXAMPLES_NXTERM is not set +# CONFIG_EXAMPLES_NXTEXT is not set +# CONFIG_EXAMPLES_OSTEST is not set +# CONFIG_EXAMPLES_PCA9635 is not set +# CONFIG_EXAMPLES_POSIXSPAWN is not set +# CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set +# CONFIG_EXAMPLES_RGBLED is not set +# CONFIG_EXAMPLES_RGMP is not set +# CONFIG_EXAMPLES_SENDMAIL is not set +# CONFIG_EXAMPLES_SERIALBLASTER is not set +# CONFIG_EXAMPLES_SERIALRX is not set +# CONFIG_EXAMPLES_SERLOOP is not set +# CONFIG_EXAMPLES_SLCD is not set +# CONFIG_EXAMPLES_SMART is not set +# CONFIG_EXAMPLES_SMART_TEST is not set +# CONFIG_EXAMPLES_SMP is not set +# CONFIG_EXAMPLES_TCPECHO is not set +# CONFIG_EXAMPLES_TELNETD is not set +# CONFIG_EXAMPLES_TIFF is not set +# CONFIG_EXAMPLES_TOUCHSCREEN is not set +# CONFIG_EXAMPLES_USBSERIAL is not set +# CONFIG_EXAMPLES_USBTERM is not set +# CONFIG_EXAMPLES_WATCHDOG is not set +# CONFIG_EXAMPLES_WEBSERVER is not set + +# +# File System Utilities +# +# CONFIG_FSUTILS_INIFILE is not set +# CONFIG_FSUTILS_PASSWD is not set + +# +# GPS Utilities +# +# CONFIG_GPSUTILS_MINMEA_LIB is not set + +# +# Graphics Support +# +# CONFIG_TIFF is not set +# CONFIG_GRAPHICS_TRAVELER is not set + +# +# Interpreters +# +# CONFIG_INTERPRETERS_BAS is not set +# CONFIG_INTERPRETERS_FICL is not set +# CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set +# CONFIG_INTERPRETERS_PCODE is not set + +# +# FreeModBus +# +# CONFIG_MODBUS is not set + +# +# Network Utilities +# +# CONFIG_NETUTILS_CHAT is not set +# CONFIG_NETUTILS_CODECS is not set +# CONFIG_NETUTILS_ESP8266 is not set +# CONFIG_NETUTILS_FTPC is not set +# CONFIG_NETUTILS_JSON is not set +# CONFIG_NETUTILS_SMTP is not set + +# +# NSH Library +# +CONFIG_NSH_LIBRARY=y +# CONFIG_NSH_MOTD is not set + +# +# Command Line Configuration +# +CONFIG_NSH_READLINE=y +# CONFIG_NSH_CLE is not set +CONFIG_NSH_LINELEN=64 +# CONFIG_NSH_DISABLE_SEMICOLON is not set +CONFIG_NSH_CMDPARMS=y +CONFIG_NSH_MAXARGUMENTS=6 +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_NESTDEPTH=3 +# CONFIG_NSH_DISABLEBG is not set +CONFIG_NSH_BUILTIN_APPS=y + +# +# Disable Individual commands +# +# CONFIG_NSH_DISABLE_ADDROUTE is not set +# CONFIG_NSH_DISABLE_BASENAME is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_CMP is not set +CONFIG_NSH_DISABLE_DATE=y +# CONFIG_NSH_DISABLE_DD is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_DELROUTE is not set +# CONFIG_NSH_DISABLE_DIRNAME is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +# CONFIG_NSH_DISABLE_IFCONFIG is not set +CONFIG_NSH_DISABLE_IFUPDOWN=y +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOSETUP is not set +CONFIG_NSH_DISABLE_LOSMART=y +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MB is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set +# CONFIG_NSH_DISABLE_MKRD is not set +# CONFIG_NSH_DISABLE_MH is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PUT is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SH is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_NSH_DISABLE_WGET is not set +# CONFIG_NSH_DISABLE_XD is not set +CONFIG_NSH_MMCSDMINOR=0 + +# +# Configure Command Options +# +CONFIG_NSH_CMDOPT_DF_H=y +CONFIG_NSH_CODECS_BUFSIZE=128 +CONFIG_NSH_CMDOPT_HEXDUMP=y +CONFIG_NSH_FILEIOSIZE=512 + +# +# Scripting Support +# +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_LOOPS is not set + +# +# Console Configuration +# +CONFIG_NSH_CONSOLE=y +# CONFIG_NSH_USBCONSOLE is not set +# CONFIG_NSH_ALTCONDEV is not set +CONFIG_NSH_ARCHINIT=y +# CONFIG_NSH_LOGIN is not set +# CONFIG_NSH_CONSOLE_LOGIN is not set + +# +# NxWidgets/NxWM +# + +# +# Platform-specific Support +# +# CONFIG_PLATFORM_CONFIGDATA is not set + +# +# System Libraries and NSH Add-Ons +# +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_CDCACM_DEVMINOR=1 +# CONFIG_SYSTEM_CLE is not set +# CONFIG_SYSTEM_CUTERM is not set +# CONFIG_SYSTEM_FREE is not set +# CONFIG_SYSTEM_HEX2BIN is not set +# CONFIG_SYSTEM_HEXED is not set +# CONFIG_SYSTEM_INSTALL is not set +# CONFIG_SYSTEM_RAMTEST is not set +CONFIG_READLINE_HAVE_EXTMATCH=y +CONFIG_SYSTEM_READLINE=y +CONFIG_READLINE_ECHO=y +# CONFIG_READLINE_TABCOMPLETION is not set +# CONFIG_READLINE_CMD_HISTORY is not set +# CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_SYSTEM is not set +# CONFIG_SYSTEM_TEE is not set +# CONFIG_SYSTEM_UBLOXMODEM is not set +# CONFIG_SYSTEM_VI is not set +# CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/bambino-200e/gnutoolcpp/setenv.sh b/configs/bambino-200e/gnutoolcpp/setenv.sh new file mode 100644 index 0000000000..600b6c5f72 --- /dev/null +++ b/configs/bambino-200e/gnutoolcpp/setenv.sh @@ -0,0 +1,92 @@ +#!/bin/bash +# configs/bambino-200e/nsh/setenv.sh +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Alan Carvalho de Assis +# +# 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. +# + +if [ "$_" = "$0" ] ; then + echo "You must source this script, not run it!" 1>&2 + exit 1 +fi + +WD=`pwd` +if [ ! -x "setenv.sh" ]; then + echo "This script must be executed from the top-level NuttX build directory" + exit 1 +fi + +if [ -z "${PATH_ORIG}" ]; then + export PATH_ORIG="${PATH}" +fi + +# This is the Cygwin path to the location where I installed the Code Red +# toolchain under windows. You will have to edit this if you install the +# Code Red toolchain in any other location or if you install a different +# version +export TOOLCHAIN_BIN="/cygdrive/c/code_red/RedSuite_4.2.3_379/redsuite/Tools/bin" +#export SCRIPT_BIN="/cygdrive/c/code_red/RedSuite_4.2.3_379/redsuite/bin" +export SCRIPT_BIN="/cygdrive/c/nxp/LPCXpresso_4.2.3_292/lpcxpresso/bin" + +# This is the Cygwin path to the location where I installed the CodeSourcery +# toolchain under windows. You will also have to edit this if you install +# the CodeSourcery toolchain in any other location +#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin" +#export SCRIPT_BIN= + +# These are the Cygwin paths to the locations where I installed the Atollic +# toolchain under windows. You will also have to edit this if you install +# the Atollic toolchain in any other location. /usr/bin is added before +# the Atollic bin path because there is are binaries named gcc.exe and g++.exe +# at those locations as well. +#export TOOLCHAIN_BIN="/usr/bin:/cygdrive/c/Program Files (x86)/Atollic/TrueSTUDIO for ARM Pro 2.3.0/ARMTools/bin" +#export TOOLCHAIN_BIN="/usr/bin:/cygdrive/c/Program Files (x86)/Atollic/TrueSTUDIO for STMicroelectronics STM32 Lite 2.3.0/ARMTools/bin" +#export SCRIPT_BIN= + +# This is the Cygwin path to the location where I build the buildroot +# toolchain. +#export TOOLCHAIN_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin" +#export SCRIPT_BIN= + +# And add the selected toolchain path[s] to the PATH variable + +export PATH="/sbin:/usr/sbin:${PATH_ORIG}" + +if [ ! -z ${SCRIPT_BIN} ]; then + export PATH="${SCRIPT_BIN}:${PATH}" +fi + +export PATH="${TOOLCHAIN_BIN}:${PATH}" +echo "PATH : ${PATH}" + +# Set an alias that can be used to put the LPC43xx in boot mode + +alias lpc43xx='${SCRIPT_BIN}/Scripts/bootLPCXpresso.cmd winusb' diff --git a/configs/samv71-xult/nsh/defconfig b/configs/samv71-xult/nsh/defconfig index b135609f71..a35e82a9b8 100644 --- a/configs/samv71-xult/nsh/defconfig +++ b/configs/samv71-xult/nsh/defconfig @@ -69,6 +69,7 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -528,15 +529,15 @@ CONFIG_I2C_RESET=y # CONFIG_I2C_TRACE is not set CONFIG_I2C_DRIVER=y CONFIG_SPI=y +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +CONFIG_ARCH_HAVE_SPI_CS_CONTROL=y +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_SPI_SLAVE is not set CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CMDDATA is not set # CONFIG_SPI_CALLBACK is not set # CONFIG_SPI_HWFEATURES is not set -# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set -CONFIG_ARCH_HAVE_SPI_CS_CONTROL=y # CONFIG_SPI_CS_CONTROL is not set -# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_SPI_DRIVER is not set # CONFIG_SPI_BITBANG is not set @@ -877,6 +878,7 @@ CONFIG_EXAMPLES_ARCHBUTTONS_NAME5="Button 5" CONFIG_EXAMPLES_ARCHBUTTONS_NAME6="Button 6" CONFIG_EXAMPLES_ARCHBUTTONS_NAME7="Button 7" # CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set diff --git a/include/cxx/cwchar b/include/cxx/cwchar index 67716abbe0..847eb98c47 100755 --- a/include/cxx/cwchar +++ b/include/cxx/cwchar @@ -48,7 +48,7 @@ namespace std { -#if 0 /* Not defined */ +#if __cplusplus >= 201103L using ::mbstate_t; #endif using ::wint_t; diff --git a/libxx/Kconfig b/libxx/Kconfig index 4707bb8715..03871c3f1a 100644 --- a/libxx/Kconfig +++ b/libxx/Kconfig @@ -38,6 +38,14 @@ config CXX_NEWLONG C++ library routines because the NuttX size_t might not have the same underlying type as your toolchain's size_t. +config CXX_LINK_GNUTOOL_LIB + bool "Link to GNU Toolchain Libraries" + default n + depends on ARM_TOOLCHAIN_GNU + ---help--- + This option enable NuttX build system to link with GNU Toolchain + libraries. Mainly stdlib++ and newlib nano. + comment "uClibc++ Standard C++ Library" config UCLIBCXX From 8190e089489cbd6117f5fd0522171ab3fdda4662 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 08:57:55 -0600 Subject: [PATCH 044/155] Back out part of previous commit --- arch/arm/src/Makefile | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/arch/arm/src/Makefile b/arch/arm/src/Makefile index b182a97e7e..e505b956da 100644 --- a/arch/arm/src/Makefile +++ b/arch/arm/src/Makefile @@ -168,14 +168,6 @@ endif LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" GCC_LIBDIR := ${shell dirname $(LIBGCC)} -ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) - LIBGXX = "${shell "$(CXX)" $(ARCHCPUFLAGS) -print-file-name=$(LIBSTDCXX)}" - GXX_LIBDIR := ${shell dirname $(LIBGXX)} - LIBCXXPATH = -L"$(GXX_LIBDIR)" -else - LIBCXXPATH ?= -endif - VPATH += chip VPATH += common VPATH += $(ARCH_SUBDIR) @@ -209,9 +201,9 @@ board$(DELIM)libboard$(LIBEXT): nuttx$(EXEEXT): $(HEAD_OBJ) board$(DELIM)libboard$(LIBEXT) $(Q) echo "LD: nuttx" - $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(LIBCXXPATH) $(EXTRA_LIBPATHS) \ + $(Q) $(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) $(EXTRA_LIBPATHS) \ -o $(NUTTX) $(HEAD_OBJ) $(EXTRA_OBJS) \ - $(LDSTARTGROUP) $(LDLIBS) $(LDLIBSCXX) $(EXTRA_LIBS) $(LIBGCC) $(LDENDGROUP) + $(LDSTARTGROUP) $(LDLIBS) $(EXTRA_LIBS) $(LIBGCC) $(LDENDGROUP) ifneq ($(CONFIG_WINDOWS_NATIVE),y) $(Q) $(NM) $(NUTTX) | \ grep -v '\(compiled\)\|\(\$(OBJEXT)$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ From ea9ac4417188179d9f5f7247f4da40938ac4be7b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 09:06:24 -0600 Subject: [PATCH 045/155] Move CONFIG_CXX_LINK_GNUTOOL_LIB from libxx/Kconfig to configs/bambino-200e/Kconfig --- configs/bambino-200e/Kconfig | 9 +++++++++ libxx/Kconfig | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/configs/bambino-200e/Kconfig b/configs/bambino-200e/Kconfig index 3892c96da7..dba37f0c0f 100644 --- a/configs/bambino-200e/Kconfig +++ b/configs/bambino-200e/Kconfig @@ -4,4 +4,13 @@ # if ARCH_BOARD_BAMBINO_200E + +config CXX_LINK_GNUTOOL_LIB + bool "Link to GNU Toolchain Libraries" + default n + depends on ARM_TOOLCHAIN_GNU + ---help--- + This option enable NuttX build system to link with GNU Toolchain + libraries. Mainly stdlib++ and newlib nano. + endif diff --git a/libxx/Kconfig b/libxx/Kconfig index 03871c3f1a..4707bb8715 100644 --- a/libxx/Kconfig +++ b/libxx/Kconfig @@ -38,14 +38,6 @@ config CXX_NEWLONG C++ library routines because the NuttX size_t might not have the same underlying type as your toolchain's size_t. -config CXX_LINK_GNUTOOL_LIB - bool "Link to GNU Toolchain Libraries" - default n - depends on ARM_TOOLCHAIN_GNU - ---help--- - This option enable NuttX build system to link with GNU Toolchain - libraries. Mainly stdlib++ and newlib nano. - comment "uClibc++ Standard C++ Library" config UCLIBCXX From 96aba62fdac4c05c713c19740a4080afb29a26e8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 09:15:30 -0600 Subject: [PATCH 046/155] bambino-200e: Add EXTRA_LIBS and EXTRA_LIBPATHS to nsh/Make.defs --- configs/bambino-200e/nsh/Make.defs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configs/bambino-200e/nsh/Make.defs b/configs/bambino-200e/nsh/Make.defs index 105969c6b1..ea9aafb4d6 100644 --- a/configs/bambino-200e/nsh/Make.defs +++ b/configs/bambino-200e/nsh/Make.defs @@ -117,6 +117,12 @@ OBJEXT = .o LIBEXT = .a EXEEXT = +ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) + EXTRA_LIBS = "${shell "$(CXX)" $(ARCHCPUFLAGS) -print-file-name=$(LIBSTDCXX)}" + GXX_LIBDIR := ${shell dirname $(LIBGXX)} + EXTRA_LIBPATHS = -L"$(GXX_LIBDIR)" +endif + ifneq ($(CROSSDEV),arm-nuttx-elf-) LDFLAGS += -nostartfiles -nodefaultlibs endif From 77caf4180f8809dbc425ff2c20544333ff29583b Mon Sep 17 00:00:00 2001 From: "Spahlinger, Michael" Date: Thu, 3 Nov 2016 09:22:33 -0600 Subject: [PATCH 047/155] SAMV7: Fix to SPI-Master driver. Without this the chip select decoding feature will not work properly --- arch/arm/src/samv7/sam_spi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/samv7/sam_spi.c b/arch/arm/src/samv7/sam_spi.c index 06c18b70f1..959a3cd290 100644 --- a/arch/arm/src/samv7/sam_spi.c +++ b/arch/arm/src/samv7/sam_spi.c @@ -626,7 +626,7 @@ static inline uint32_t spi_cs2pcs(struct sam_spics_s *spics) #ifndef CONFIG_SAMV7_SPI_CS_DECODING return ((uint32_t)1 << (spics->cs)) - 1; #else - return spics->cs; + return spics->cs - 1; #endif } From de30c2e5ddc78f1a44b85fcddf1339a96f893af3 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 09:41:38 -0600 Subject: [PATCH 048/155] Back out the rest of commit 1e754402b86e10c28ada5949d33c8b759ab463fb. Newlib support will not be accepted into the NuttX repository. --- configs/bambino-200e/Kconfig | 8 - configs/bambino-200e/gnutoolcpp/Make.defs | 141 --- configs/bambino-200e/gnutoolcpp/defconfig | 1004 --------------------- configs/bambino-200e/gnutoolcpp/setenv.sh | 92 -- include/cxx/cwchar | 2 +- 5 files changed, 1 insertion(+), 1246 deletions(-) delete mode 100644 configs/bambino-200e/gnutoolcpp/Make.defs delete mode 100644 configs/bambino-200e/gnutoolcpp/defconfig delete mode 100644 configs/bambino-200e/gnutoolcpp/setenv.sh diff --git a/configs/bambino-200e/Kconfig b/configs/bambino-200e/Kconfig index dba37f0c0f..12ce8d77f5 100644 --- a/configs/bambino-200e/Kconfig +++ b/configs/bambino-200e/Kconfig @@ -5,12 +5,4 @@ if ARCH_BOARD_BAMBINO_200E -config CXX_LINK_GNUTOOL_LIB - bool "Link to GNU Toolchain Libraries" - default n - depends on ARM_TOOLCHAIN_GNU - ---help--- - This option enable NuttX build system to link with GNU Toolchain - libraries. Mainly stdlib++ and newlib nano. - endif diff --git a/configs/bambino-200e/gnutoolcpp/Make.defs b/configs/bambino-200e/gnutoolcpp/Make.defs deleted file mode 100644 index a7d6e8d274..0000000000 --- a/configs/bambino-200e/gnutoolcpp/Make.defs +++ /dev/null @@ -1,141 +0,0 @@ -############################################################################ -# configs/bambino-200e/nsh/Make.defs -# -# Copyright (C) 2016 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt -# Alan Carvalho de Assis -# -# 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. -# -############################################################################ - -include ${TOPDIR}/.config -include ${TOPDIR}/tools/Config.mk -include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs - -# Setup for the kind of memory that we are executing from - -ifeq ($(CONFIG_LPC43_BOOT_SRAM),y) - LDSCRIPT = ramconfig.ld -endif -ifeq ($(CONFIG_LPC43_BOOT_SPIFI),y) - LDSCRIPT = spificonfig.ld -endif -ifeq ($(CONFIG_LPC43_BOOT_FLASHA),y) - LDSCRIPT = flashaconfig.ld -endif -ifeq ($(CONFIG_LPC43_BOOT_FLASHB),y) - LDSCRIPT = flashaconfig.ld -endif -ifeq ($(CONFIG_LPC43_BOOT_CS0FLASH),y) - LDSCRIPT = cs0flash.ld -endif - -# Setup for Windows vs Linux/Cygwin/OSX environments - -ifeq ($(WINTOOL),y) - # Windows-native toolchains - DIRLINK = $(TOPDIR)/tools/copydir.sh - DIRUNLINK = $(TOPDIR)/tools/unlink.sh - MKDEP = $(TOPDIR)/tools/mkwindeps.sh - ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" - ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" - ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}" -else - # Linux/Cygwin-native toolchain - MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT) - ARCHINCLUDES = -I. -isystem $(TOPDIR)/include - ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx - ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT) -endif - -CC = $(CROSSDEV)gcc -CXX = $(CROSSDEV)g++ -CPP = $(CROSSDEV)gcc -E -LD = $(CROSSDEV)ld -AR = $(ARCROSSDEV)ar rcs -NM = $(ARCROSSDEV)nm -OBJCOPY = $(CROSSDEV)objcopy -OBJDUMP = $(CROSSDEV)objdump - -ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'} -ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1} - -ifeq ($(CONFIG_DEBUG_SYMBOLS),y) - ARCHOPTIMIZATION = -g -endif - -ifneq ($(CONFIG_DEBUG_NOOPT),y) - ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer -endif - -ARCHCFLAGS = -fno-builtin -ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) -ARCHCXXFLAGS = -fno-builtin -fno-use-cxa-atexit -fcheck-new -specs=nano.specs -lstdc++ -lsupc++ -lm -lgcc -lc -lnosys -std=gnu++11 -else -ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti -endif -ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -ARCHWARNINGSXX = -Wall -Wshadow -Wundef -ARCHDEFINES = -ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 - -CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe -CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) -CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe -CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) -CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -AFLAGS = $(CFLAGS) -D__ASSEMBLY__ - -ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) -LDLIBSCXX = -lstdc++_nano -lsupc++_nano -lnosys -lm -LIBSTDCXX = libstdc++_nano.a -endif - -NXFLATLDFLAGS1 = -r -d -warn-common -NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections -LDNXFLATFLAGS = -e main -s 2048 - -ASMEXT = .S -OBJEXT = .o -LIBEXT = .a -EXEEXT = - -ifneq ($(CROSSDEV),arm-nuttx-elf-) - LDFLAGS += -nostartfiles -nodefaultlibs --no-wchar-size-warning -endif -ifeq ($(CONFIG_DEBUG_SYMBOLS),y) - LDFLAGS += -g -endif - - -HOSTCC = gcc -HOSTINCLUDES = -I. -HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe -HOSTLDFLAGS = - diff --git a/configs/bambino-200e/gnutoolcpp/defconfig b/configs/bambino-200e/gnutoolcpp/defconfig deleted file mode 100644 index 1c7bbf0c87..0000000000 --- a/configs/bambino-200e/gnutoolcpp/defconfig +++ /dev/null @@ -1,1004 +0,0 @@ -# -# Automatically generated file; DO NOT EDIT. -# Nuttx/ Configuration -# - -# -# Build Setup -# -# CONFIG_EXPERIMENTAL is not set -# CONFIG_DEFAULT_SMALL is not set -CONFIG_HOST_LINUX=y -# CONFIG_HOST_OSX is not set -# CONFIG_HOST_WINDOWS is not set -# CONFIG_HOST_OTHER is not set - -# -# Build Configuration -# -# CONFIG_APPS_DIR="../apps" -CONFIG_BUILD_FLAT=y -# CONFIG_BUILD_2PASS is not set - -# -# Binary Output Formats -# -# CONFIG_RRLOAD_BINARY is not set -# CONFIG_INTELHEX_BINARY is not set -# CONFIG_MOTOROLA_SREC is not set -CONFIG_RAW_BINARY=y -# CONFIG_UBOOT_UIMAGE is not set - -# -# Customize Header Files -# -# CONFIG_ARCH_STDINT_H is not set -# CONFIG_ARCH_STDBOOL_H is not set -# CONFIG_ARCH_MATH_H is not set -# CONFIG_ARCH_FLOAT_H is not set -CONFIG_ARCH_STDARG_H=y -# CONFIG_ARCH_DEBUG_H is not set - -# -# Debug Options -# -CONFIG_DEBUG_ALERT=y -# CONFIG_DEBUG_FEATURES is not set -CONFIG_ARCH_HAVE_STACKCHECK=y -# CONFIG_STACK_COLORATION is not set -# CONFIG_ARCH_HAVE_HEAPCHECK is not set -CONFIG_DEBUG_SYMBOLS=y -CONFIG_ARCH_HAVE_CUSTOMOPT=y -CONFIG_DEBUG_NOOPT=y -# CONFIG_DEBUG_CUSTOMOPT is not set -# CONFIG_DEBUG_FULLOPT is not set - -# -# System Type -# -CONFIG_ARCH_ARM=y -# CONFIG_ARCH_AVR is not set -# CONFIG_ARCH_HC is not set -# CONFIG_ARCH_MIPS is not set -# CONFIG_ARCH_RGMP is not set -# CONFIG_ARCH_RENESAS is not set -# CONFIG_ARCH_RISCV is not set -# CONFIG_ARCH_SIM is not set -# CONFIG_ARCH_X86 is not set -# CONFIG_ARCH_XTENSA is not set -# CONFIG_ARCH_Z16 is not set -# CONFIG_ARCH_Z80 is not set -CONFIG_ARCH="arm" - -# -# ARM Options -# -# CONFIG_ARCH_CHIP_A1X is not set -# CONFIG_ARCH_CHIP_C5471 is not set -# CONFIG_ARCH_CHIP_CALYPSO is not set -# CONFIG_ARCH_CHIP_DM320 is not set -# CONFIG_ARCH_CHIP_EFM32 is not set -# CONFIG_ARCH_CHIP_IMX1 is not set -# CONFIG_ARCH_CHIP_IMX6 is not set -# CONFIG_ARCH_CHIP_KINETIS is not set -# CONFIG_ARCH_CHIP_KL is not set -# CONFIG_ARCH_CHIP_LM is not set -# CONFIG_ARCH_CHIP_TIVA is not set -# CONFIG_ARCH_CHIP_LPC11XX is not set -# CONFIG_ARCH_CHIP_LPC17XX is not set -# CONFIG_ARCH_CHIP_LPC214X is not set -# CONFIG_ARCH_CHIP_LPC2378 is not set -# CONFIG_ARCH_CHIP_LPC31XX is not set -CONFIG_ARCH_CHIP_LPC43XX=y -# CONFIG_ARCH_CHIP_NUC1XX is not set -# CONFIG_ARCH_CHIP_SAMA5 is not set -# CONFIG_ARCH_CHIP_SAMD is not set -# CONFIG_ARCH_CHIP_SAML is not set -# CONFIG_ARCH_CHIP_SAM34 is not set -# CONFIG_ARCH_CHIP_SAMV7 is not set -# CONFIG_ARCH_CHIP_STM32 is not set -# CONFIG_ARCH_CHIP_STM32F7 is not set -# CONFIG_ARCH_CHIP_STM32L4 is not set -# CONFIG_ARCH_CHIP_STR71X is not set -# CONFIG_ARCH_CHIP_TMS570 is not set -# CONFIG_ARCH_CHIP_MOXART is not set -# CONFIG_ARCH_ARM7TDMI is not set -# CONFIG_ARCH_ARM926EJS is not set -# CONFIG_ARCH_ARM920T is not set -# CONFIG_ARCH_CORTEXM0 is not set -# CONFIG_ARCH_CORTEXM3 is not set -CONFIG_ARCH_CORTEXM4=y -# CONFIG_ARCH_CORTEXM7 is not set -# CONFIG_ARCH_CORTEXA5 is not set -# CONFIG_ARCH_CORTEXA8 is not set -# CONFIG_ARCH_CORTEXA9 is not set -# CONFIG_ARCH_CORTEXR4 is not set -# CONFIG_ARCH_CORTEXR4F is not set -# CONFIG_ARCH_CORTEXR5 is not set -# CONFIG_ARCH_CORTEX5F is not set -# CONFIG_ARCH_CORTEXR7 is not set -# CONFIG_ARCH_CORTEXR7F is not set -CONFIG_ARCH_FAMILY="armv7-m" -CONFIG_ARCH_CHIP="lpc43xx" -# CONFIG_ARM_TOOLCHAIN_IAR is not set -CONFIG_ARM_TOOLCHAIN_GNU=y -# CONFIG_ARMV7M_USEBASEPRI is not set -CONFIG_ARCH_HAVE_CMNVECTOR=y -CONFIG_ARMV7M_CMNVECTOR=y -# CONFIG_ARMV7M_LAZYFPU is not set -CONFIG_ARCH_HAVE_FPU=y -# CONFIG_ARCH_HAVE_DPFPU is not set -# CONFIG_ARCH_FPU is not set -# CONFIG_ARCH_HAVE_TRUSTZONE is not set -CONFIG_ARM_HAVE_MPU_UNIFIED=y -# CONFIG_ARM_MPU is not set - -# -# ARMV7M Configuration Options -# -# CONFIG_ARMV7M_HAVE_ICACHE is not set -# CONFIG_ARMV7M_HAVE_DCACHE is not set -# CONFIG_ARMV7M_HAVE_ITCM is not set -# CONFIG_ARMV7M_HAVE_DTCM is not set -# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set -# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set -# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set -# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set -CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y -# CONFIG_ARMV7M_HAVE_STACKCHECK is not set -# CONFIG_ARMV7M_ITMSYSLOG is not set -# CONFIG_SERIAL_TERMIOS is not set - -# -# LPC43xx Configuration Options -# -# CONFIG_ARCH_CHIP_LPC4310FBD144 is not set -# CONFIG_ARCH_CHIP_LPC4310FET100 is not set -# CONFIG_ARCH_CHIP_LPC4320FBD144 is not set -# CONFIG_ARCH_CHIP_LPC4320FET100 is not set -CONFIG_ARCH_CHIP_LPC4330FBD144=y -# CONFIG_ARCH_CHIP_LPC4330FET100 is not set -# CONFIG_ARCH_CHIP_LPC4330FET180 is not set -# CONFIG_ARCH_CHIP_LPC4330FET256 is not set -# CONFIG_ARCH_CHIP_LPC4337JBD144 is not set -# CONFIG_ARCH_CHIP_LPC4337JET100 is not set -# CONFIG_ARCH_CHIP_LPC4350FBD208 is not set -# CONFIG_ARCH_CHIP_LPC4350FET180 is not set -# CONFIG_ARCH_CHIP_LPC4350FET256 is not set -# CONFIG_ARCH_CHIP_LPC4353FBD208 is not set -# CONFIG_ARCH_CHIP_LPC4353FET180 is not set -# CONFIG_ARCH_CHIP_LPC4353FET256 is not set -# CONFIG_ARCH_CHIP_LPC4357FET180 is not set -# CONFIG_ARCH_CHIP_LPC4357FBD208 is not set -# CONFIG_ARCH_CHIP_LPC4357FET256 is not set -# CONFIG_ARCH_CHIP_LPC4370FET100 is not set -CONFIG_ARCH_FAMILY_LPC4330=y -# CONFIG_LPC43_BOOT_SRAM is not set -CONFIG_LPC43_BOOT_SPIFI=y -# CONFIG_LPC43_BOOT_FLASHA is not set -# CONFIG_LPC43_BOOT_FLASHB is not set -# CONFIG_LPC43_BOOT_CS0FLASH is not set -# CONFIG_LPC43_BOOT_CS1FLASH is not set -# CONFIG_LPC43_BOOT_CS2FLASH is not set -# CONFIG_LPC43_BOOT_CS3FLASH is not set - -# -# LPC43xx Peripheral Support -# -# CONFIG_LPC43_ADC0 is not set -# CONFIG_LPC43_ADC1 is not set -# CONFIG_LPC43_ATIMER is not set -# CONFIG_LPC43_CAN1 is not set -# CONFIG_LPC43_CAN2 is not set -# CONFIG_LPC43_DAC is not set -# CONFIG_LPC43_EMC is not set -# CONFIG_LPC43_ETHERNET is not set -# CONFIG_LPC43_EVNTMNTR is not set -# CONFIG_LPC43_GPDMA is not set -# CONFIG_LPC43_I2C0 is not set -# CONFIG_LPC43_I2C1 is not set -# CONFIG_LPC43_I2S0 is not set -# CONFIG_LPC43_I2S1 is not set -# CONFIG_LPC43_LCD is not set -# CONFIG_LPC43_MCPWM is not set -# CONFIG_LPC43_QEI is not set -# CONFIG_LPC43_RIT is not set -# CONFIG_LPC43_RTC is not set -# CONFIG_LPC43_SCT is not set -# CONFIG_LPC43_SDMMC is not set -# CONFIG_LPC43_SPI is not set -# CONFIG_LPC43_SPIFI is not set -# CONFIG_LPC43_SSP0 is not set -# CONFIG_LPC43_SSP1 is not set -# CONFIG_LPC43_TMR0 is not set -# CONFIG_LPC43_TMR1 is not set -# CONFIG_LPC43_TMR2 is not set -# CONFIG_LPC43_TMR3 is not set -# CONFIG_LPC43_USART0 is not set -CONFIG_LPC43_UART1=y -# CONFIG_LPC43_USART2 is not set -# CONFIG_LPC43_USART3 is not set -# CONFIG_LPC43_USBOTG is not set -CONFIG_LPC43_USB0=y -# CONFIG_LPC43_USB1 is not set -# CONFIG_LPC43_WWDT is not set -# CONFIG_LPC43_GPIO_IRQ is not set - -# -# Internal Memory Configuration -# -CONFIG_ARCH_HAVE_AHB_SRAM_BANK1=y -# CONFIG_LPC43_USE_LOCSRAM_BANK1 is not set -# CONFIG_LPC43_USE_AHBSRAM_BANK0 is not set -# CONFIG_LPC43_USE_AHBSRAM_BANK1 is not set -# CONFIG_LPC43_HEAP_AHBSRAM_BANK2 is not set - -# -# External Memory Configuration -# - -# -# RS-485 Configuration -# -# CONFIG_UART1_RS485MODE is not set -# CONFIG_UART1_RS485_DTRDIR is not set - -# -# USB device controller driver (DCD) options -# -# CONFIG_LPC43_USB0DEV_NOVBUS is not set - -# -# Architecture Options -# -# CONFIG_ARCH_NOINTC is not set -# CONFIG_ARCH_VECNOTIRQ is not set -# CONFIG_ARCH_DMA is not set -CONFIG_ARCH_HAVE_IRQPRIO=y -# CONFIG_ARCH_L2CACHE is not set -# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set -# CONFIG_ARCH_HAVE_ADDRENV is not set -# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set -# CONFIG_ARCH_HAVE_MULTICPU is not set -CONFIG_ARCH_HAVE_VFORK=y -# CONFIG_ARCH_HAVE_MMU is not set -CONFIG_ARCH_HAVE_MPU=y -# CONFIG_ARCH_NAND_HWECC is not set -# CONFIG_ARCH_HAVE_EXTCLK is not set -# CONFIG_ARCH_HAVE_POWEROFF is not set -CONFIG_ARCH_HAVE_RESET=y -# CONFIG_ARCH_USE_MPU is not set -# CONFIG_ARCH_IRQPRIO is not set -CONFIG_ARCH_STACKDUMP=y -# CONFIG_ENDIAN_BIG is not set -# CONFIG_ARCH_IDLE_CUSTOM is not set -# CONFIG_ARCH_HAVE_RAMFUNCS is not set -CONFIG_ARCH_HAVE_RAMVECTORS=y -# CONFIG_ARCH_RAMVECTORS is not set - -# -# Board Settings -# -CONFIG_BOARD_LOOPSPERMSEC=18535 -# CONFIG_ARCH_CALIBRATION is not set - -# -# Interrupt options -# -CONFIG_ARCH_HAVE_INTERRUPTSTACK=y -CONFIG_ARCH_INTERRUPTSTACK=0 -CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y -# CONFIG_ARCH_HIPRI_INTERRUPT is not set - -# -# Boot options -# -# CONFIG_BOOT_RUNFROMEXTSRAM is not set -CONFIG_BOOT_RUNFROMFLASH=y -# CONFIG_BOOT_RUNFROMISRAM is not set -# CONFIG_BOOT_RUNFROMSDRAM is not set -# CONFIG_BOOT_COPYTORAM is not set - -# -# Boot Memory Configuration -# -CONFIG_RAM_START=0x10000000 -CONFIG_RAM_SIZE=131072 -# CONFIG_ARCH_HAVE_SDRAM is not set - -# -# Board Selection -# -CONFIG_ARCH_BOARD_BAMBINO_200E=y -# CONFIG_ARCH_BOARD_CUSTOM is not set -CONFIG_ARCH_BOARD="bambino-200e" - -# -# Common Board Options -# -CONFIG_ARCH_HAVE_LEDS=y -CONFIG_ARCH_LEDS=y -CONFIG_ARCH_HAVE_BUTTONS=y -# CONFIG_ARCH_BUTTONS is not set -CONFIG_ARCH_HAVE_IRQBUTTONS=y - -# -# Board-Specific Options -# -# CONFIG_BOARD_CRASHDUMP is not set -CONFIG_LIB_BOARDCTL=y -# CONFIG_BOARDCTL_RESET is not set -# CONFIG_BOARDCTL_UNIQUEID is not set -CONFIG_BOARDCTL_USBDEVCTRL=y -# CONFIG_BOARDCTL_TSCTEST is not set -# CONFIG_BOARDCTL_ADCTEST is not set -# CONFIG_BOARDCTL_PWMTEST is not set -# CONFIG_BOARDCTL_GRAPHICS is not set -# CONFIG_BOARDCTL_IOCTL is not set - -# -# RTOS Features -# -CONFIG_DISABLE_OS_API=y -# CONFIG_DISABLE_POSIX_TIMERS is not set -# CONFIG_DISABLE_PTHREAD is not set -# CONFIG_DISABLE_SIGNALS is not set -# CONFIG_DISABLE_MQUEUE is not set -# CONFIG_DISABLE_ENVIRON is not set - -# -# Clocks and Timers -# -CONFIG_ARCH_HAVE_TICKLESS=y -# CONFIG_SCHED_TICKLESS is not set -CONFIG_USEC_PER_TICK=10000 -# CONFIG_SYSTEM_TIME64 is not set -# CONFIG_CLOCK_MONOTONIC is not set -# CONFIG_ARCH_HAVE_TIMEKEEPING is not set -# CONFIG_JULIAN_TIME is not set -CONFIG_START_YEAR=2012 -CONFIG_START_MONTH=7 -CONFIG_START_DAY=11 -CONFIG_MAX_WDOGPARMS=2 -CONFIG_PREALLOC_WDOGS=4 -CONFIG_WDOG_INTRESERVE=0 -CONFIG_PREALLOC_TIMERS=4 - -# -# Tasks and Scheduling -# -# CONFIG_INIT_NONE is not set -CONFIG_INIT_ENTRYPOINT=y -# CONFIG_INIT_FILEPATH is not set -CONFIG_USER_ENTRYPOINT="nsh_main" -CONFIG_RR_INTERVAL=200 -# CONFIG_SCHED_SPORADIC is not set -CONFIG_TASK_NAME_SIZE=0 -CONFIG_MAX_TASKS=16 -# CONFIG_SCHED_HAVE_PARENT is not set -CONFIG_SCHED_WAITPID=y - -# -# Pthread Options -# -# CONFIG_MUTEX_TYPES is not set -CONFIG_NPTHREAD_KEYS=4 - -# -# Performance Monitoring -# -# CONFIG_SCHED_CPULOAD is not set -# CONFIG_SCHED_INSTRUMENTATION is not set - -# -# Files and I/O -# -CONFIG_DEV_CONSOLE=y -# CONFIG_FDCLONE_DISABLE is not set -# CONFIG_FDCLONE_STDIO is not set -CONFIG_SDCLONE_DISABLE=y -CONFIG_NFILE_DESCRIPTORS=8 -CONFIG_NFILE_STREAMS=8 -CONFIG_NAME_MAX=32 -# CONFIG_PRIORITY_INHERITANCE is not set - -# -# RTOS hooks -# -# CONFIG_BOARD_INITIALIZE is not set -# CONFIG_SCHED_STARTHOOK is not set -# CONFIG_SCHED_ATEXIT is not set -# CONFIG_SCHED_ONEXIT is not set - -# -# Signal Numbers -# -CONFIG_SIG_SIGUSR1=1 -CONFIG_SIG_SIGUSR2=2 -CONFIG_SIG_SIGALARM=3 -CONFIG_SIG_SIGCONDTIMEDOUT=16 - -# -# POSIX Message Queue Options -# -CONFIG_PREALLOC_MQ_MSGS=4 -CONFIG_MQ_MAXMSGSIZE=32 -# CONFIG_MODULE is not set - -# -# Work queue support -# -# CONFIG_SCHED_WORKQUEUE is not set -# CONFIG_SCHED_HPWORK is not set -# CONFIG_SCHED_LPWORK is not set - -# -# Stack and heap information -# -CONFIG_IDLETHREAD_STACKSIZE=1024 -CONFIG_USERMAIN_STACKSIZE=2048 -CONFIG_PTHREAD_STACK_MIN=256 -CONFIG_PTHREAD_STACK_DEFAULT=2048 -# CONFIG_LIB_SYSCALL is not set - -# -# Device Drivers -# -# CONFIG_DISABLE_POLL is not set -CONFIG_DEV_NULL=y -# CONFIG_DEV_ZERO is not set -# CONFIG_DEV_URANDOM is not set -# CONFIG_DEV_LOOP is not set - -# -# Buffering -# -# CONFIG_DRVR_WRITEBUFFER is not set -# CONFIG_DRVR_READAHEAD is not set -# CONFIG_RAMDISK is not set -# CONFIG_CAN is not set -# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set -# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set -# CONFIG_PWM is not set -# CONFIG_ARCH_HAVE_I2CRESET is not set -# CONFIG_I2C is not set -# CONFIG_SPI is not set -# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set -# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set -# CONFIG_ARCH_HAVE_SPI_BITORDER is not set -# CONFIG_I2S is not set - -# -# Timer Driver Support -# -# CONFIG_TIMER is not set -# CONFIG_ONESHOT is not set -# CONFIG_RTC is not set -# CONFIG_WATCHDOG is not set -# CONFIG_ANALOG is not set -# CONFIG_AUDIO_DEVICES is not set -# CONFIG_VIDEO_DEVICES is not set -# CONFIG_BCH is not set -# CONFIG_INPUT is not set - -# -# IO Expander/GPIO Support -# -# CONFIG_IOEXPANDER is not set -# CONFIG_DEV_GPIO is not set - -# -# LCD Driver Support -# -# CONFIG_LCD is not set -# CONFIG_SLCD is not set - -# -# LED Support -# -# CONFIG_USERLED is not set -# CONFIG_RGBLED is not set -# CONFIG_PCA9635PW is not set -# CONFIG_NCP5623C is not set -# CONFIG_MMCSD is not set -# CONFIG_MODEM is not set -# CONFIG_MTD is not set -# CONFIG_EEPROM is not set -# CONFIG_PIPES is not set -# CONFIG_PM is not set -# CONFIG_POWER is not set -# CONFIG_SENSORS is not set -# CONFIG_SERCOMM_CONSOLE is not set -CONFIG_SERIAL=y -# CONFIG_DEV_LOWCONSOLE is not set -CONFIG_SERIAL_REMOVABLE=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_16550_UART is not set -# CONFIG_UART_SERIALDRIVER is not set -# CONFIG_UART0_SERIALDRIVER is not set -CONFIG_UART1_SERIALDRIVER=y -# CONFIG_UART2_SERIALDRIVER is not set -# CONFIG_UART3_SERIALDRIVER is not set -# CONFIG_UART4_SERIALDRIVER is not set -# CONFIG_UART5_SERIALDRIVER is not set -# CONFIG_UART6_SERIALDRIVER is not set -# CONFIG_UART7_SERIALDRIVER is not set -# CONFIG_UART8_SERIALDRIVER is not set -# CONFIG_SCI0_SERIALDRIVER is not set -# CONFIG_SCI1_SERIALDRIVER is not set -# CONFIG_USART0_SERIALDRIVER is not set -# CONFIG_USART1_SERIALDRIVER is not set -# CONFIG_USART2_SERIALDRIVER is not set -# CONFIG_USART3_SERIALDRIVER is not set -# CONFIG_USART4_SERIALDRIVER is not set -# CONFIG_USART5_SERIALDRIVER is not set -# CONFIG_USART6_SERIALDRIVER is not set -# CONFIG_USART7_SERIALDRIVER is not set -# CONFIG_USART8_SERIALDRIVER is not set -# CONFIG_OTHER_UART_SERIALDRIVER is not set -CONFIG_MCU_SERIAL=y -CONFIG_STANDARD_SERIAL=y -CONFIG_SERIAL_NPOLLWAITERS=2 -# CONFIG_SERIAL_IFLOWCONTROL is not set -# CONFIG_SERIAL_OFLOWCONTROL is not set -# CONFIG_SERIAL_DMA is not set -CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y -CONFIG_UART1_SERIAL_CONSOLE=y -# CONFIG_OTHER_SERIAL_CONSOLE is not set -# CONFIG_NO_SERIAL_CONSOLE is not set - -# -# UART1 Configuration -# -CONFIG_UART1_RXBUFSIZE=256 -CONFIG_UART1_TXBUFSIZE=256 -CONFIG_UART1_BAUD=115200 -CONFIG_UART1_BITS=8 -CONFIG_UART1_PARITY=0 -CONFIG_UART1_2STOP=0 -# CONFIG_UART1_IFLOWCONTROL is not set -# CONFIG_UART1_OFLOWCONTROL is not set -# CONFIG_UART1_DMA is not set -# CONFIG_PSEUDOTERM is not set -CONFIG_USBDEV=y - -# -# USB Device Controller Driver Options -# -# CONFIG_USBDEV_ISOCHRONOUS is not set -# CONFIG_USBDEV_DUALSPEED is not set -CONFIG_USBDEV_SELFPOWERED=y -# CONFIG_USBDEV_BUSPOWERED is not set -CONFIG_USBDEV_MAXPOWER=100 -# CONFIG_USBDEV_DMA is not set -# CONFIG_ARCH_USBDEV_STALLQUEUE is not set -# CONFIG_USBDEV_TRACE is not set - -# -# USB Device Class Driver Options -# -# CONFIG_USBDEV_COMPOSITE is not set -# CONFIG_PL2303 is not set -CONFIG_CDCACM=y -# CONFIG_CDCACM_CONSOLE is not set -CONFIG_CDCACM_EP0MAXPACKET=64 -CONFIG_CDCACM_EPINTIN=1 -CONFIG_CDCACM_EPINTIN_FSSIZE=64 -CONFIG_CDCACM_EPINTIN_HSSIZE=64 -CONFIG_CDCACM_EPBULKOUT=3 -CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 -CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 -CONFIG_CDCACM_EPBULKIN=2 -CONFIG_CDCACM_EPBULKIN_FSSIZE=64 -CONFIG_CDCACM_EPBULKIN_HSSIZE=512 -CONFIG_CDCACM_NRDREQS=4 -CONFIG_CDCACM_NWRREQS=4 -CONFIG_CDCACM_BULKIN_REQLEN=96 -CONFIG_CDCACM_RXBUFSIZE=257 -CONFIG_CDCACM_TXBUFSIZE=193 -CONFIG_CDCACM_VENDORID=0x0525 -CONFIG_CDCACM_PRODUCTID=0xa4a7 -CONFIG_CDCACM_VENDORSTR="NuttX" -CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" -# CONFIG_USBMSC is not set -# CONFIG_USBHOST is not set -# CONFIG_HAVE_USBTRACE is not set -# CONFIG_DRIVERS_WIRELESS is not set -# CONFIG_DRIVERS_CONTACTLESS is not set - -# -# System Logging -# -# CONFIG_ARCH_SYSLOG is not set -# CONFIG_RAMLOG is not set -# CONFIG_SYSLOG_INTBUFFER is not set -# CONFIG_SYSLOG_TIMESTAMP is not set -CONFIG_SYSLOG_SERIAL_CONSOLE=y -# CONFIG_SYSLOG_CHAR is not set -CONFIG_SYSLOG_CONSOLE=y -# CONFIG_SYSLOG_NONE is not set -# CONFIG_SYSLOG_FILE is not set -# CONFIG_SYSLOG_CHARDEV is not set - -# -# Networking Support -# -# CONFIG_ARCH_HAVE_NET is not set -# CONFIG_ARCH_HAVE_PHY is not set -# CONFIG_NET is not set - -# -# Crypto API -# -# CONFIG_CRYPTO is not set - -# -# File Systems -# - -# -# File system configuration -# -# CONFIG_DISABLE_MOUNTPOINT is not set -# CONFIG_FS_AUTOMOUNTER is not set -# CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set -CONFIG_FS_READABLE=y -CONFIG_FS_WRITABLE=y -# CONFIG_FS_NAMED_SEMAPHORES is not set -CONFIG_FS_MQUEUE_MPATH="/var/mqueue" -# CONFIG_FS_RAMMAP is not set -CONFIG_FS_FAT=y -CONFIG_FAT_LCNAMES=y -CONFIG_FAT_LFN=y -CONFIG_FAT_MAXFNAME=32 -# CONFIG_FS_FATTIME is not set -# CONFIG_FAT_FORCE_INDIRECT is not set -# CONFIG_FAT_DMAMEMORY is not set -# CONFIG_FAT_DIRECT_RETRY is not set -# CONFIG_FS_NXFFS is not set -# CONFIG_FS_ROMFS is not set -# CONFIG_FS_TMPFS is not set -# CONFIG_FS_SMARTFS is not set -# CONFIG_FS_BINFS is not set -# CONFIG_FS_PROCFS is not set -# CONFIG_FS_UNIONFS is not set - -# -# Graphics Support -# -# CONFIG_NX is not set - -# -# Memory Management -# -# CONFIG_MM_SMALL is not set -CONFIG_MM_REGIONS=2 -# CONFIG_ARCH_HAVE_HEAP2 is not set -# CONFIG_GRAN is not set - -# -# Audio Support -# -# CONFIG_AUDIO is not set - -# -# Wireless Support -# - -# -# Binary Loader -# -# CONFIG_BINFMT_DISABLE is not set -# CONFIG_BINFMT_EXEPATH is not set -# CONFIG_NXFLAT is not set -# CONFIG_ELF is not set -CONFIG_BUILTIN=y -# CONFIG_PIC is not set -CONFIG_SYMTAB_ORDEREDBYNAME=y - -# -# Library Routines -# - -# -# Standard C Library Options -# -CONFIG_STDIO_BUFFER_SIZE=64 -CONFIG_STDIO_LINEBUFFER=y -CONFIG_NUNGET_CHARS=2 -CONFIG_LIB_HOMEDIR="/" -# CONFIG_LIBM is not set -# CONFIG_NOPRINTF_FIELDWIDTH is not set -# CONFIG_LIBC_FLOATINGPOINT is not set -CONFIG_LIBC_LONG_LONG=y -# CONFIG_LIBC_IOCTL_VARIADIC is not set -# CONFIG_LIBC_WCHAR is not set -# CONFIG_LIBC_LOCALE is not set -CONFIG_LIB_RAND_ORDER=1 -# CONFIG_EOL_IS_CR is not set -# CONFIG_EOL_IS_LF is not set -# CONFIG_EOL_IS_BOTH_CRLF is not set -CONFIG_EOL_IS_EITHER_CRLF=y -# CONFIG_LIBC_EXECFUNCS is not set -CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 -CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 -# CONFIG_LIBC_STRERROR is not set -# CONFIG_LIBC_PERROR_STDOUT is not set -CONFIG_LIBC_TMPDIR="/tmp" -CONFIG_LIBC_MAX_TMPFILE=32 -CONFIG_ARCH_LOWPUTC=y -# CONFIG_LIBC_LOCALTIME is not set -# CONFIG_TIME_EXTENDED is not set -CONFIG_LIB_SENDFILE_BUFSIZE=512 -# CONFIG_ARCH_ROMGETC is not set -# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set -CONFIG_ARCH_HAVE_TLS=y -# CONFIG_TLS is not set -# CONFIG_LIBC_NETDB is not set -# CONFIG_NETDB_HOSTFILE is not set - -# -# Non-standard Library Support -# -# CONFIG_LIB_CRC64_FAST is not set -# CONFIG_LIB_KBDCODEC is not set -# CONFIG_LIB_SLCDCODEC is not set -# CONFIG_LIB_HEX2BIN is not set - -# -# Basic CXX Support -# -# CONFIG_C99_BOOL8 is not set -CONFIG_HAVE_CXX=y -CONFIG_HAVE_CXXINITIALIZE=y -# CONFIG_CXX_NEWLONG is not set -CONFIG_CXX_LINK_GNUTOOL_LIB=y - -# -# uClibc++ Standard C++ Library -# -# CONFIG_UCLIBCXX is not set - -# -# Application Configuration -# - -# -# Built-In Applications -# -CONFIG_BUILTIN_PROXY_STACKSIZE=1024 - -# -# CAN Utilities -# - -# -# Examples -# -# CONFIG_EXAMPLES_BUTTONS is not set -# CONFIG_EXAMPLES_CCTYPE is not set -# CONFIG_EXAMPLES_CHAT is not set -# CONFIG_EXAMPLES_CONFIGDATA is not set -# CONFIG_EXAMPLES_CXXTEST is not set -# CONFIG_EXAMPLES_DHCPD is not set -# CONFIG_EXAMPLES_ELF is not set -# CONFIG_EXAMPLES_FSTEST is not set -# CONFIG_EXAMPLES_FTPC is not set -# CONFIG_EXAMPLES_FTPD is not set -# CONFIG_EXAMPLES_HELLO is not set -# CONFIG_EXAMPLES_HELLOXX is not set -# CONFIG_EXAMPLES_HIDKBD is not set -# CONFIG_EXAMPLES_IGMP is not set -# CONFIG_EXAMPLES_JSON is not set -# CONFIG_EXAMPLES_KEYPADTEST is not set -# CONFIG_EXAMPLES_MEDIA is not set -# CONFIG_EXAMPLES_MM is not set -# CONFIG_EXAMPLES_MODBUS is not set -# CONFIG_EXAMPLES_MOUNT is not set -# CONFIG_EXAMPLES_NRF24L01TERM is not set -CONFIG_EXAMPLES_NSH=y -# CONFIG_EXAMPLES_NSH_CXXINITIALIZE is not set -# CONFIG_EXAMPLES_NULL is not set -# CONFIG_EXAMPLES_NXFFS is not set -# CONFIG_EXAMPLES_NXHELLO is not set -# CONFIG_EXAMPLES_NXIMAGE is not set -# CONFIG_EXAMPLES_NX is not set -# CONFIG_EXAMPLES_NXLINES is not set -# CONFIG_EXAMPLES_NXTERM is not set -# CONFIG_EXAMPLES_NXTEXT is not set -# CONFIG_EXAMPLES_OSTEST is not set -# CONFIG_EXAMPLES_PCA9635 is not set -# CONFIG_EXAMPLES_POSIXSPAWN is not set -# CONFIG_EXAMPLES_PPPD is not set -# CONFIG_EXAMPLES_RFID_READUID is not set -# CONFIG_EXAMPLES_RGBLED is not set -# CONFIG_EXAMPLES_RGMP is not set -# CONFIG_EXAMPLES_SENDMAIL is not set -# CONFIG_EXAMPLES_SERIALBLASTER is not set -# CONFIG_EXAMPLES_SERIALRX is not set -# CONFIG_EXAMPLES_SERLOOP is not set -# CONFIG_EXAMPLES_SLCD is not set -# CONFIG_EXAMPLES_SMART is not set -# CONFIG_EXAMPLES_SMART_TEST is not set -# CONFIG_EXAMPLES_SMP is not set -# CONFIG_EXAMPLES_TCPECHO is not set -# CONFIG_EXAMPLES_TELNETD is not set -# CONFIG_EXAMPLES_TIFF is not set -# CONFIG_EXAMPLES_TOUCHSCREEN is not set -# CONFIG_EXAMPLES_USBSERIAL is not set -# CONFIG_EXAMPLES_USBTERM is not set -# CONFIG_EXAMPLES_WATCHDOG is not set -# CONFIG_EXAMPLES_WEBSERVER is not set - -# -# File System Utilities -# -# CONFIG_FSUTILS_INIFILE is not set -# CONFIG_FSUTILS_PASSWD is not set - -# -# GPS Utilities -# -# CONFIG_GPSUTILS_MINMEA_LIB is not set - -# -# Graphics Support -# -# CONFIG_TIFF is not set -# CONFIG_GRAPHICS_TRAVELER is not set - -# -# Interpreters -# -# CONFIG_INTERPRETERS_BAS is not set -# CONFIG_INTERPRETERS_FICL is not set -# CONFIG_INTERPRETERS_MICROPYTHON is not set -# CONFIG_INTERPRETERS_MINIBASIC is not set -# CONFIG_INTERPRETERS_PCODE is not set - -# -# FreeModBus -# -# CONFIG_MODBUS is not set - -# -# Network Utilities -# -# CONFIG_NETUTILS_CHAT is not set -# CONFIG_NETUTILS_CODECS is not set -# CONFIG_NETUTILS_ESP8266 is not set -# CONFIG_NETUTILS_FTPC is not set -# CONFIG_NETUTILS_JSON is not set -# CONFIG_NETUTILS_SMTP is not set - -# -# NSH Library -# -CONFIG_NSH_LIBRARY=y -# CONFIG_NSH_MOTD is not set - -# -# Command Line Configuration -# -CONFIG_NSH_READLINE=y -# CONFIG_NSH_CLE is not set -CONFIG_NSH_LINELEN=64 -# CONFIG_NSH_DISABLE_SEMICOLON is not set -CONFIG_NSH_CMDPARMS=y -CONFIG_NSH_MAXARGUMENTS=6 -CONFIG_NSH_ARGCAT=y -CONFIG_NSH_NESTDEPTH=3 -# CONFIG_NSH_DISABLEBG is not set -CONFIG_NSH_BUILTIN_APPS=y - -# -# Disable Individual commands -# -# CONFIG_NSH_DISABLE_ADDROUTE is not set -# CONFIG_NSH_DISABLE_BASENAME is not set -# CONFIG_NSH_DISABLE_CAT is not set -# CONFIG_NSH_DISABLE_CD is not set -# CONFIG_NSH_DISABLE_CP is not set -# CONFIG_NSH_DISABLE_CMP is not set -CONFIG_NSH_DISABLE_DATE=y -# CONFIG_NSH_DISABLE_DD is not set -# CONFIG_NSH_DISABLE_DF is not set -# CONFIG_NSH_DISABLE_DELROUTE is not set -# CONFIG_NSH_DISABLE_DIRNAME is not set -# CONFIG_NSH_DISABLE_ECHO is not set -# CONFIG_NSH_DISABLE_EXEC is not set -# CONFIG_NSH_DISABLE_EXIT is not set -# CONFIG_NSH_DISABLE_FREE is not set -# CONFIG_NSH_DISABLE_GET is not set -# CONFIG_NSH_DISABLE_HELP is not set -# CONFIG_NSH_DISABLE_HEXDUMP is not set -# CONFIG_NSH_DISABLE_IFCONFIG is not set -CONFIG_NSH_DISABLE_IFUPDOWN=y -# CONFIG_NSH_DISABLE_KILL is not set -# CONFIG_NSH_DISABLE_LOSETUP is not set -CONFIG_NSH_DISABLE_LOSMART=y -# CONFIG_NSH_DISABLE_LS is not set -# CONFIG_NSH_DISABLE_MB is not set -# CONFIG_NSH_DISABLE_MKDIR is not set -# CONFIG_NSH_DISABLE_MKFATFS is not set -# CONFIG_NSH_DISABLE_MKRD is not set -# CONFIG_NSH_DISABLE_MH is not set -# CONFIG_NSH_DISABLE_MOUNT is not set -# CONFIG_NSH_DISABLE_MV is not set -# CONFIG_NSH_DISABLE_MW is not set -CONFIG_NSH_DISABLE_PRINTF=y -# CONFIG_NSH_DISABLE_PS is not set -# CONFIG_NSH_DISABLE_PUT is not set -# CONFIG_NSH_DISABLE_PWD is not set -# CONFIG_NSH_DISABLE_RM is not set -# CONFIG_NSH_DISABLE_RMDIR is not set -# CONFIG_NSH_DISABLE_SET is not set -# CONFIG_NSH_DISABLE_SH is not set -# CONFIG_NSH_DISABLE_SLEEP is not set -# CONFIG_NSH_DISABLE_TIME is not set -# CONFIG_NSH_DISABLE_TEST is not set -# CONFIG_NSH_DISABLE_UMOUNT is not set -# CONFIG_NSH_DISABLE_UNAME is not set -# CONFIG_NSH_DISABLE_UNSET is not set -# CONFIG_NSH_DISABLE_USLEEP is not set -# CONFIG_NSH_DISABLE_WGET is not set -# CONFIG_NSH_DISABLE_XD is not set -CONFIG_NSH_MMCSDMINOR=0 - -# -# Configure Command Options -# -CONFIG_NSH_CMDOPT_DF_H=y -CONFIG_NSH_CODECS_BUFSIZE=128 -CONFIG_NSH_CMDOPT_HEXDUMP=y -CONFIG_NSH_FILEIOSIZE=512 - -# -# Scripting Support -# -# CONFIG_NSH_DISABLESCRIPT is not set -# CONFIG_NSH_DISABLE_ITEF is not set -# CONFIG_NSH_DISABLE_LOOPS is not set - -# -# Console Configuration -# -CONFIG_NSH_CONSOLE=y -# CONFIG_NSH_USBCONSOLE is not set -# CONFIG_NSH_ALTCONDEV is not set -CONFIG_NSH_ARCHINIT=y -# CONFIG_NSH_LOGIN is not set -# CONFIG_NSH_CONSOLE_LOGIN is not set - -# -# NxWidgets/NxWM -# - -# -# Platform-specific Support -# -# CONFIG_PLATFORM_CONFIGDATA is not set - -# -# System Libraries and NSH Add-Ons -# -CONFIG_SYSTEM_CDCACM=y -CONFIG_SYSTEM_CDCACM_DEVMINOR=1 -# CONFIG_SYSTEM_CLE is not set -# CONFIG_SYSTEM_CUTERM is not set -# CONFIG_SYSTEM_FREE is not set -# CONFIG_SYSTEM_HEX2BIN is not set -# CONFIG_SYSTEM_HEXED is not set -# CONFIG_SYSTEM_INSTALL is not set -# CONFIG_SYSTEM_RAMTEST is not set -CONFIG_READLINE_HAVE_EXTMATCH=y -CONFIG_SYSTEM_READLINE=y -CONFIG_READLINE_ECHO=y -# CONFIG_READLINE_TABCOMPLETION is not set -# CONFIG_READLINE_CMD_HISTORY is not set -# CONFIG_SYSTEM_SUDOKU is not set -# CONFIG_SYSTEM_SYSTEM is not set -# CONFIG_SYSTEM_TEE is not set -# CONFIG_SYSTEM_UBLOXMODEM is not set -# CONFIG_SYSTEM_VI is not set -# CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/bambino-200e/gnutoolcpp/setenv.sh b/configs/bambino-200e/gnutoolcpp/setenv.sh deleted file mode 100644 index 600b6c5f72..0000000000 --- a/configs/bambino-200e/gnutoolcpp/setenv.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/bash -# configs/bambino-200e/nsh/setenv.sh -# -# Copyright (C) 2016 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt -# Alan Carvalho de Assis -# -# 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. -# - -if [ "$_" = "$0" ] ; then - echo "You must source this script, not run it!" 1>&2 - exit 1 -fi - -WD=`pwd` -if [ ! -x "setenv.sh" ]; then - echo "This script must be executed from the top-level NuttX build directory" - exit 1 -fi - -if [ -z "${PATH_ORIG}" ]; then - export PATH_ORIG="${PATH}" -fi - -# This is the Cygwin path to the location where I installed the Code Red -# toolchain under windows. You will have to edit this if you install the -# Code Red toolchain in any other location or if you install a different -# version -export TOOLCHAIN_BIN="/cygdrive/c/code_red/RedSuite_4.2.3_379/redsuite/Tools/bin" -#export SCRIPT_BIN="/cygdrive/c/code_red/RedSuite_4.2.3_379/redsuite/bin" -export SCRIPT_BIN="/cygdrive/c/nxp/LPCXpresso_4.2.3_292/lpcxpresso/bin" - -# This is the Cygwin path to the location where I installed the CodeSourcery -# toolchain under windows. You will also have to edit this if you install -# the CodeSourcery toolchain in any other location -#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin" -#export SCRIPT_BIN= - -# These are the Cygwin paths to the locations where I installed the Atollic -# toolchain under windows. You will also have to edit this if you install -# the Atollic toolchain in any other location. /usr/bin is added before -# the Atollic bin path because there is are binaries named gcc.exe and g++.exe -# at those locations as well. -#export TOOLCHAIN_BIN="/usr/bin:/cygdrive/c/Program Files (x86)/Atollic/TrueSTUDIO for ARM Pro 2.3.0/ARMTools/bin" -#export TOOLCHAIN_BIN="/usr/bin:/cygdrive/c/Program Files (x86)/Atollic/TrueSTUDIO for STMicroelectronics STM32 Lite 2.3.0/ARMTools/bin" -#export SCRIPT_BIN= - -# This is the Cygwin path to the location where I build the buildroot -# toolchain. -#export TOOLCHAIN_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin" -#export SCRIPT_BIN= - -# And add the selected toolchain path[s] to the PATH variable - -export PATH="/sbin:/usr/sbin:${PATH_ORIG}" - -if [ ! -z ${SCRIPT_BIN} ]; then - export PATH="${SCRIPT_BIN}:${PATH}" -fi - -export PATH="${TOOLCHAIN_BIN}:${PATH}" -echo "PATH : ${PATH}" - -# Set an alias that can be used to put the LPC43xx in boot mode - -alias lpc43xx='${SCRIPT_BIN}/Scripts/bootLPCXpresso.cmd winusb' diff --git a/include/cxx/cwchar b/include/cxx/cwchar index 847eb98c47..7c29791570 100755 --- a/include/cxx/cwchar +++ b/include/cxx/cwchar @@ -48,7 +48,7 @@ namespace std { -#if __cplusplus >= 201103L +#if 0 // Not defined using ::mbstate_t; #endif using ::wint_t; From bdde5720ca9ee245b6b13bc50baa57582b4f616a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 09:43:27 -0600 Subject: [PATCH 049/155] Back out the rest of commit 1e754402b86e10c28ada5949d33c8b759ab463fb. Newlib support will not be accepted into the NuttX repository. --- configs/bambino-200e/nsh/Make.defs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/configs/bambino-200e/nsh/Make.defs b/configs/bambino-200e/nsh/Make.defs index ea9aafb4d6..105969c6b1 100644 --- a/configs/bambino-200e/nsh/Make.defs +++ b/configs/bambino-200e/nsh/Make.defs @@ -117,12 +117,6 @@ OBJEXT = .o LIBEXT = .a EXEEXT = -ifeq ($(CONFIG_CXX_LINK_GNUTOOL_LIB),y) - EXTRA_LIBS = "${shell "$(CXX)" $(ARCHCPUFLAGS) -print-file-name=$(LIBSTDCXX)}" - GXX_LIBDIR := ${shell dirname $(LIBGXX)} - EXTRA_LIBPATHS = -L"$(GXX_LIBDIR)" -endif - ifneq ($(CROSSDEV),arm-nuttx-elf-) LDFLAGS += -nostartfiles -nodefaultlibs endif From 4fcbe8e4104f5d82e72f31b9ce256cf65f652f6b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 11:00:47 -0600 Subject: [PATCH 050/155] drivers: Disable priority inheritance on all semaphores used for signaling --- drivers/analog/adc.c | 9 +++++++++ drivers/analog/dac.c | 11 ++++++++++- drivers/can.c | 10 +++++++++- drivers/input/ads7843e.c | 9 +++++++++ drivers/input/max11802.c | 9 +++++++++ drivers/input/mxt.c | 9 +++++++++ drivers/net/slip.c | 4 +++- drivers/net/tun.c | 8 +++++++- drivers/pipes/pipe_common.c | 16 ++++++++++++---- drivers/pwm.c | 14 +++++++++++--- drivers/sercomm/console.c | 4 ++++ drivers/serial/pty.c | 10 ++++++++++ drivers/serial/serial.c | 2 +- drivers/syslog/ramlog.c | 15 +++++++++++---- drivers/usbdev/usbmsc.c | 12 +++++++++++- drivers/usbhost/usbhost_hidkbd.c | 13 +++++++++++++ drivers/usbhost/usbhost_hidmouse.c | 13 +++++++++++++ drivers/wireless/cc3000/cc3000.c | 20 +++++++++++++++++++- drivers/wireless/ieee802154/mrf24j40.c | 11 +++++++++++ drivers/wireless/nrf24l01.c | 4 +++- 20 files changed, 184 insertions(+), 19 deletions(-) diff --git a/drivers/analog/adc.c b/drivers/analog/adc.c index 0dac979d60..d81971f101 100644 --- a/drivers/analog/adc.c +++ b/drivers/analog/adc.c @@ -58,6 +58,7 @@ #include #include +#include #include #include @@ -441,9 +442,17 @@ int adc_register(FAR const char *path, FAR struct adc_dev_s *dev) dev->ad_ocount = 0; + /* Initialize semaphores */ + sem_init(&dev->ad_recv.af_sem, 0, 0); sem_init(&dev->ad_closesem, 0, 1); + /* The receive semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&dev->ad_recv.af_sem, SEM_PRIO_NONE); + /* Reset the ADC hardware */ DEBUGASSERT(dev->ad_ops->ao_reset != NULL); diff --git a/drivers/analog/dac.c b/drivers/analog/dac.c index fbbc761833..131b7e800f 100644 --- a/drivers/analog/dac.c +++ b/drivers/analog/dac.c @@ -55,8 +55,9 @@ #include #include -#include #include +#include +#include #include #include @@ -515,9 +516,17 @@ int dac_register(FAR const char *path, FAR struct dac_dev_s *dev) dev->ad_ocount = 0; + /* Initialize semaphores */ + sem_init(&dev->ad_xmit.af_sem, 0, 0); sem_init(&dev->ad_closesem, 0, 1); + /* The transmit semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&dev->ad_xmit.af_sem, SEM_PRIO_NONE); + dev->ad_ops->ao_reset(dev); return register_driver(path, &dac_fops, 0555, dev); diff --git a/drivers/can.c b/drivers/can.c index 483769d7db..e896d492f4 100644 --- a/drivers/can.c +++ b/drivers/can.c @@ -54,8 +54,9 @@ #include #include -#include #include +#include +#include #include #ifdef CONFIG_CAN_TXREADY @@ -1166,6 +1167,8 @@ int can_register(FAR const char *path, FAR struct can_dev_s *dev) dev->cd_error = 0; #endif + /* Initialize semaphores */ + sem_init(&dev->cd_xmit.tx_sem, 0, 1); sem_init(&dev->cd_recv.rx_sem, 0, 1); sem_init(&dev->cd_closesem, 0, 1); @@ -1175,7 +1178,12 @@ int can_register(FAR const char *path, FAR struct can_dev_s *dev) for (i = 0; i < CONFIG_CAN_NPENDINGRTR; i++) { + /* Initialize wait semahores. These semaphores are used for signaling + * and should not have priority inheritance enabled. + */ + sem_init(&dev->cd_rtr[i].cr_sem, 0, 0); + sem_setprotocol(&dev->cd_rtr[i].cr_sem, SEM_PRIO_NONE); dev->cd_rtr[i].cr_msg = NULL; } diff --git a/drivers/input/ads7843e.c b/drivers/input/ads7843e.c index 5f4c159a9f..f7019639de 100644 --- a/drivers/input/ads7843e.c +++ b/drivers/input/ads7843e.c @@ -71,6 +71,7 @@ #include #include +#include #include #include @@ -1184,9 +1185,17 @@ int ads7843e_register(FAR struct spi_dev_s *spi, priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */ priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */ + /* Initialize semaphores */ + sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + /* The pen event semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Make sure that interrupts are disabled */ config->clear(config); diff --git a/drivers/input/max11802.c b/drivers/input/max11802.c index 2394cd2e5e..82ad1f6689 100644 --- a/drivers/input/max11802.c +++ b/drivers/input/max11802.c @@ -65,6 +65,7 @@ #include #include +#include #include #include @@ -1187,9 +1188,17 @@ int max11802_register(FAR struct spi_dev_s *spi, priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */ priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */ + /* Initialize semaphores */ + sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + /* The pen event semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Make sure that interrupts are disabled */ config->clear(config); diff --git a/drivers/input/mxt.c b/drivers/input/mxt.c index 891f781120..5d617ba764 100644 --- a/drivers/input/mxt.c +++ b/drivers/input/mxt.c @@ -65,6 +65,7 @@ #include #include +#include #include #include @@ -1884,9 +1885,17 @@ int mxt_register(FAR struct i2c_master_s *i2c, priv->i2c = i2c; /* Save the SPI device handle */ priv->lower = lower; /* Save the board configuration */ + /* Initialize semaphores */ + sem_init(&priv->devsem, 0, 1); /* Initialize device semaphore */ sem_init(&priv->waitsem, 0, 0); /* Initialize event wait semaphore */ + /* The event wait semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Make sure that interrupts are disabled */ MXT_CLEAR(lower); diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 07fac24fc3..744126971e 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -55,8 +55,9 @@ #include #include -#include #include +#include +#include #include #include #include @@ -965,6 +966,7 @@ int slip_initialize(int intf, FAR const char *devname) /* Initialize the wait semaphore */ sem_init(&priv->waitsem, 0, 0); + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); /* Put the interface in the down state. This usually amounts to resetting * the device and/or calling slip_ifdown(). diff --git a/drivers/net/tun.c b/drivers/net/tun.c index d14fb7ed28..b4938c4e50 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -884,11 +884,17 @@ static int tun_dev_init(FAR struct tun_device_s *priv, FAR struct file *filep, #endif priv->dev.d_private = (FAR void *)priv; /* Used to recover private state from dev */ - /* Initialize the wait semaphore */ + /* Initialize the mutual exlcusion and wait semaphore */ sem_init(&priv->waitsem, 0, 1); sem_init(&priv->read_wait_sem, 0, 0); + /* The wait semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->read_wait_sem, SEM_PRIO_NONE); + /* Create a watchdog for timing polling for and timing of transmisstions */ priv->txpoll = wd_create(); /* Create periodic poll timer */ diff --git a/drivers/pipes/pipe_common.c b/drivers/pipes/pipe_common.c index 730e0228de..6fc0711dcf 100644 --- a/drivers/pipes/pipe_common.c +++ b/drivers/pipes/pipe_common.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/pipes/pipe_common.c * - * Copyright (C) 2008-2009, 2011, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -53,12 +53,13 @@ #include #include -#include -#include -#include #ifdef CONFIG_DEBUG_FEATURES # include #endif +#include +#include +#include +#include #include "pipe_common.h" @@ -172,6 +173,13 @@ FAR struct pipe_dev_s *pipecommon_allocdev(size_t bufsize) sem_init(&dev->d_rdsem, 0, 0); sem_init(&dev->d_wrsem, 0, 0); + /* The read/write wait semaphores are used for signaling and, hence, + * should not have priority inheritance enabled. + */ + + sem_setprotocol(&dev->d_rdsem, SEM_PRIO_NONE); + sem_setprotocol(&dev->d_wrsem, SEM_PRIO_NONE); + dev->d_bufsize = bufsize; } diff --git a/drivers/pwm.c b/drivers/pwm.c index f3de79a387..03958b6778 100644 --- a/drivers/pwm.c +++ b/drivers/pwm.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/pwm.c * - * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -55,9 +55,10 @@ #include #include -#include -#include #include +#include +#include +#include #include #include @@ -601,7 +602,14 @@ int pwm_register(FAR const char *path, FAR struct pwm_lowerhalf_s *dev) sem_init(&upper->exclsem, 0, 1); #ifdef CONFIG_PWM_PULSECOUNT sem_init(&upper->waitsem, 0, 0); + + /* The wait semaphore is used for signaling and, hence, should not have priority + * inheritance enabled. + */ + + sem_setprotocol(&upper->waitsem, SEM_PRIO_NONE); #endif + upper->dev = dev; /* Register the PWM device */ diff --git a/drivers/sercomm/console.c b/drivers/sercomm/console.c index c12c35af5f..efd1174ba3 100644 --- a/drivers/sercomm/console.c +++ b/drivers/sercomm/console.c @@ -47,6 +47,7 @@ #include #include "uart.h" +#include #include /************************************************************************************ @@ -187,6 +188,9 @@ int sercomm_register(FAR const char *path, FAR uart_dev_t *dev) sem_init(&dev->pollsem, 0, 1); #endif + sem_setprotocol(&dev->xmitsem, SEM_PRIO_NONE); + sem_setprotocol(&dev->recvsem, SEM_PRIO_NONE); + _info("Registering %s\n", path); return register_driver(path, &g_sercom_console_ops, 0666, NULL); } diff --git a/drivers/serial/pty.c b/drivers/serial/pty.c index 03c844b5f9..4c27cd89bb 100644 --- a/drivers/serial/pty.c +++ b/drivers/serial/pty.c @@ -97,6 +97,7 @@ #include #include +#include #include #include #include @@ -1016,8 +1017,17 @@ int pty_register(int minor) return -ENOMEM; } + /* Initialize semaphores */ + sem_init(&devpair->pp_slavesem, 0, 0); sem_init(&devpair->pp_exclsem, 0, 1); + + /* The pp_slavesem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + sem_setprotocol(&devpair->pp_slavesem, SEM_PRIO_NONE); + #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS devpair->pp_minor = minor; #endif diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c index 64354e2a76..80c6fa3f1a 100644 --- a/drivers/serial/serial.c +++ b/drivers/serial/serial.c @@ -1413,7 +1413,7 @@ int uart_register(FAR const char *path, FAR uart_dev_t *dev) #endif /* The recvsem and xmitsem are used for signaling and, hence, should not have - * priroity inheritance enabled. + * priority inheritance enabled. */ sem_setprotocol(&dev->xmitsem, SEM_PRIO_NONE); diff --git a/drivers/syslog/ramlog.c b/drivers/syslog/ramlog.c index 6044b7157b..d322710433 100644 --- a/drivers/syslog/ramlog.c +++ b/drivers/syslog/ramlog.c @@ -1,7 +1,7 @@ /**************************************************************************** * drivers/syslog/ramlog.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -53,10 +53,10 @@ #include #include -#include -#include -#include #include +#include +#include +#include #include #include @@ -694,7 +694,14 @@ int ramlog_register(FAR const char *devpath, FAR char *buffer, size_t buflen) sem_init(&priv->rl_exclsem, 0, 1); #ifndef CONFIG_RAMLOG_NONBLOCKING sem_init(&priv->rl_waitsem, 0, 0); + + /* The rl_waitsem semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + sem_setprotocol(&priv->rl_waitsem, SEM_PRIO_NONE); #endif + priv->rl_bufsize = buflen; priv->rl_buffer = buffer; diff --git a/drivers/usbdev/usbmsc.c b/drivers/usbdev/usbmsc.c index 35fc5cf5a3..c83febb011 100644 --- a/drivers/usbdev/usbmsc.c +++ b/drivers/usbdev/usbmsc.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include @@ -1339,11 +1340,20 @@ int usbmsc_configure(unsigned int nluns, void **handle) priv = &alloc->dev; memset(priv, 0, sizeof(struct usbmsc_dev_s)); + /* Initialize semaphores */ + sem_init(&priv->thsynch, 0, 0); sem_init(&priv->thlock, 0, 1); sem_init(&priv->thwaitsem, 0, 0); - sq_init(&priv->wrreqlist); + /* The thsynch and thwaitsem semaphores are used for signaling and, hence, + * should not have priority inheritance enabled. + */ + + sem_setprotocol(&priv->thsynch, SEM_PRIO_NONE); + sem_setprotocol(&priv->thwaitsem, SEM_PRIO_NONE); + + sq_init(&priv->wrreqlist); priv->nluns = nluns; /* Allocate the LUN table */ diff --git a/drivers/usbhost/usbhost_hidkbd.c b/drivers/usbhost/usbhost_hidkbd.c index c8a3c582f7..6a5be0e9ba 100644 --- a/drivers/usbhost/usbhost_hidkbd.c +++ b/drivers/usbhost/usbhost_hidkbd.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include @@ -1864,6 +1865,12 @@ static FAR struct usbhost_class_s * sem_init(&priv->exclsem, 0, 1); sem_init(&priv->waitsem, 0, 0); + /* The waitsem semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Return the instance of the USB keyboard class driver */ return &priv->usbclass; @@ -2423,6 +2430,12 @@ int usbhost_kbdinit(void) sem_init(&g_exclsem, 0, 1); sem_init(&g_syncsem, 0, 0); + /* The g_syncsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + sem_setprotocol(&g_syncsem, SEM_PRIO_NONE); + /* Advertise our availability to support (certain) devices */ return usbhost_registerclass(&g_hidkbd); diff --git a/drivers/usbhost/usbhost_hidmouse.c b/drivers/usbhost/usbhost_hidmouse.c index 922e133c8b..dbd0033920 100644 --- a/drivers/usbhost/usbhost_hidmouse.c +++ b/drivers/usbhost/usbhost_hidmouse.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -1934,6 +1935,12 @@ static FAR struct usbhost_class_s * sem_init(&priv->exclsem, 0, 1); sem_init(&priv->waitsem, 0, 0); + /* The waitsem semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Return the instance of the USB mouse class driver */ return &priv->usbclass; @@ -2553,6 +2560,12 @@ int usbhost_mouse_init(void) sem_init(&g_exclsem, 0, 1); sem_init(&g_syncsem, 0, 0); + /* The g_syncsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + sem_setprotocol(&g_syncsem, SEM_PRIO_NONE); + /* Advertise our availability to support (certain) mouse devices */ return usbhost_registerclass(&g_hidmouse); diff --git a/drivers/wireless/cc3000/cc3000.c b/drivers/wireless/cc3000/cc3000.c index 6c0fb74828..2a651cd19c 100644 --- a/drivers/wireless/cc3000/cc3000.c +++ b/drivers/wireless/cc3000/cc3000.c @@ -63,13 +63,15 @@ #include #include +#include + #include #include #include #include +#include #include #include -#include #include #include @@ -822,19 +824,33 @@ static int cc3000_open(FAR struct file *filep) if (tmp == 1) { + /* Initialize semaphores */ + sem_init(&priv->waitsem, 0, 0); /* Initialize event wait semaphore */ sem_init(&priv->irqsem, 0, 0); /* Initialize IRQ Ready semaphore */ sem_init(&priv->readysem, 0, 0); /* Initialize Device Ready semaphore */ + /* These semaphores are all used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + sem_setprotocol(&priv->irqsem, SEM_PRIO_NONE); + sem_setprotocol(&priv->readysem, SEM_PRIO_NONE); + #ifdef CONFIG_CC3000_MT priv->accepting_socket.acc.sd = FREE_SLOT; sem_init(&priv->accepting_socket.acc.semwait, 0, 0); + sem_setprotocol(&priv->accepting_socket.acc.semwait, SEM_PRIO_NONE); + for (s = 0; s < CONFIG_WL_MAX_SOCKETS; s++) { priv->sockets[s].sd = FREE_SLOT; priv->sockets[s].received_closed_event = false; priv->sockets[s].emptied_and_remotely_closed = false; + sem_init(&priv->sockets[s].semwait, 0, 0); + sem_setprotocol(&priv->sockets[s].semwait, SEM_PRIO_NONE); } #endif @@ -884,6 +900,8 @@ static int cc3000_open(FAR struct file *filep) pthread_attr_setschedparam(&tattr, ¶m); sem_init(&priv->selectsem, 0, 0); + sem_setprotocol(&priv->selectsem, SEM_PRIO_NONE); + ret = pthread_create(&priv->selecttid, &tattr, select_thread_func, (pthread_addr_t)priv); if (ret != 0) diff --git a/drivers/wireless/ieee802154/mrf24j40.c b/drivers/wireless/ieee802154/mrf24j40.c index 77079fe468..9e216acabc 100644 --- a/drivers/wireless/ieee802154/mrf24j40.c +++ b/drivers/wireless/ieee802154/mrf24j40.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include @@ -1370,9 +1371,19 @@ FAR struct ieee802154_dev_s *mrf24j40_init(FAR struct spi_dev_s *spi, } dev->ieee.ops = &mrf24j40_devops; + + /* Initialize semaphores */ + sem_init(&dev->ieee.rxsem, 0, 0); sem_init(&dev->ieee.txsem, 0, 0); + /* These semaphores are all used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + sem_setprotocol(&dev->ieee.rxsem, SEM_PRIO_NONE); + sem_setprotocol(&dev->ieee.txsem, SEM_PRIO_NONE); + dev->lower = lower; dev->spi = spi; diff --git a/drivers/wireless/nrf24l01.c b/drivers/wireless/nrf24l01.c index ff79034ad6..8b088e9857 100644 --- a/drivers/wireless/nrf24l01.c +++ b/drivers/wireless/nrf24l01.c @@ -1224,7 +1224,8 @@ int nrf24l01_register(FAR struct spi_dev_s *spi, FAR struct nrf24l01_config_s *c dev->pfd = NULL; #endif - sem_init(&(dev->sem_tx), 0, 0); + sem_init(&dev->sem_tx, 0, 0); + sem_setprotocol(&dev->sem_tx, SEM_PRIO_NONE); #ifdef CONFIG_WL_NRF24L01_RXSUPPORT if ((rx_fifo = kmm_malloc(CONFIG_WL_NRF24L01_RXFIFO_LEN)) == NULL) @@ -1240,6 +1241,7 @@ int nrf24l01_register(FAR struct spi_dev_s *spi, FAR struct nrf24l01_config_s *c sem_init(&(dev->sem_fifo), 0, 1); sem_init(&(dev->sem_rx), 0, 0); + sem_setprotocol(&dev->sem_rx, SEM_PRIO_NONE); #endif /* Set the global reference */ From 2d057c28c8e33a578b9b2bd82b5a1c9cf795a98f Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 12:17:02 -0600 Subject: [PATCH 051/155] net: Disable priority inheritance on all semaphores used for signaling --- net/arp/arp_notify.c | 11 +++++++++-- net/arp/arp_send.c | 9 ++++++++- net/icmp/icmp_ping.c | 9 ++++++++- net/icmpv6/icmpv6_autoconfig.c | 8 +++++++- net/icmpv6/icmpv6_neighbor.c | 11 +++++++++-- net/icmpv6/icmpv6_notify.c | 11 +++++++++-- net/icmpv6/icmpv6_ping.c | 9 ++++++++- net/icmpv6/icmpv6_rnotify.c | 17 +++++++++++++++-- net/igmp/igmp_group.c | 9 ++++++++- net/local/local_conn.c | 10 +++++++++- net/pkt/pkt_send.c | 11 ++++++++++- net/socket/connect.c | 10 +++++++++- net/socket/net_close.c | 10 +++++++++- net/socket/net_sendfile.c | 11 +++++++++-- net/socket/recvfrom.c | 8 ++++++++ net/tcp/tcp_accept.c | 9 ++++++++- net/tcp/tcp_send_unbuffered.c | 9 +++++++++ net/udp/udp_psock_sendto.c | 8 ++++++++ 18 files changed, 160 insertions(+), 20 deletions(-) diff --git a/net/arp/arp_notify.c b/net/arp/arp_notify.c index 727d765651..7b92bfc25a 100644 --- a/net/arp/arp_notify.c +++ b/net/arp/arp_notify.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/arp/arp_notify.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,8 +47,9 @@ #include -#include #include +#include +#include #include "arp/arp.h" @@ -88,7 +89,13 @@ void arp_wait_setup(in_addr_t ipaddr, FAR struct arp_notify_s *notify) notify->nt_ipaddr = ipaddr; notify->nt_result = -ETIMEDOUT; + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(¬ify->nt_sem, 0, 0); + sem_setprotocol(¬ify->nt_sem, SEM_PRIO_NONE); /* Add the wait structure to the list with interrupts disabled */ diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index faec0a13f4..0a525c7d68 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/arp/arp_send.c * - * Copyright (C) 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -294,7 +295,13 @@ int arp_send(in_addr_t ipaddr) * disabled */ + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ + sem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); + state.snd_retries = 0; /* No retries yet */ state.snd_ipaddr = ipaddr; /* IP address to query */ diff --git a/net/icmp/icmp_ping.c b/net/icmp/icmp_ping.c index a121ddfbbd..0c7f6e1627 100644 --- a/net/icmp/icmp_ping.c +++ b/net/icmp/icmp_ping.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/icmp/icmp_ping.c * - * Copyright (C) 2008-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2012, 2014-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -364,7 +365,13 @@ int icmp_ping(in_addr_t addr, uint16_t id, uint16_t seqno, uint16_t datalen, /* Initialize the state structure */ + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&state.png_sem, 0, 0); + sem_setprotocol(&state.png_sem, SEM_PRIO_NONE); + state.png_ticks = DSEC2TICK(dsecs); /* System ticks to wait */ state.png_result = -ENOMEM; /* Assume allocation failure */ state.png_addr = addr; /* Address of the peer to be ping'ed */ diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c index eb404e7812..0e8fc688cd 100644 --- a/net/icmpv6/icmpv6_autoconfig.c +++ b/net/icmpv6/icmpv6_autoconfig.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/icmpv6/icmpv6_autoconfig.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,6 +47,7 @@ #include +#include #include #include @@ -208,7 +209,12 @@ static int icmpv6_send_message(FAR struct net_driver_s *dev, bool advertise) * disabled */ + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ + sem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); #ifdef CONFIG_NETDEV_MULTINIC /* Remember the routing device name */ diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c index 9bb02f34b4..60f63660bd 100644 --- a/net/icmpv6/icmpv6_neighbor.c +++ b/net/icmpv6/icmpv6_neighbor.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/icmpv6/icmpv6_neighbor.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,7 @@ #include #include +#include #include #include #include @@ -307,8 +308,14 @@ int icmpv6_neighbor(const net_ipv6addr_t ipaddr) * disabled */ + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ - state.snd_retries = 0; /* No retries yet */ + sem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); + + state.snd_retries = 0; /* No retries yet */ net_ipv6addr_copy(state.snd_ipaddr, lookup); /* IP address to query */ #ifdef CONFIG_NETDEV_MULTINIC diff --git a/net/icmpv6/icmpv6_notify.c b/net/icmpv6/icmpv6_notify.c index 4185b5a352..ad0ddbd8c1 100644 --- a/net/icmpv6/icmpv6_notify.c +++ b/net/icmpv6/icmpv6_notify.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/icmpv6/icmpv6_notify.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,8 +47,9 @@ #include -#include #include +#include +#include #include "icmpv6/icmpv6.h" @@ -101,7 +102,13 @@ void icmpv6_wait_setup(const net_ipv6addr_t ipaddr, net_ipv6addr_copy(notify->nt_ipaddr, ipaddr); notify->nt_result = -ETIMEDOUT; + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(¬ify->nt_sem, 0, 0); + sem_setprotocol(¬ify->nt_sem, SEM_PRIO_NONE); /* Add the wait structure to the list with interrupts disabled */ diff --git a/net/icmpv6/icmpv6_ping.c b/net/icmpv6/icmpv6_ping.c index 507d09a266..839ac06e07 100644 --- a/net/icmpv6/icmpv6_ping.c +++ b/net/icmpv6/icmpv6_ping.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/icmpv6/icmpv6_ping.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -50,6 +50,7 @@ #include #include +#include #include #include #include @@ -437,7 +438,13 @@ int icmpv6_ping(net_ipv6addr_t addr, uint16_t id, uint16_t seqno, /* Initialize the state structure */ + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&state.png_sem, 0, 0); + sem_setprotocol(&state.png_sem, SEM_PRIO_NONE); + state.png_ticks = DSEC2TICK(dsecs); /* System ticks to wait */ state.png_result = -ENOMEM; /* Assume allocation failure */ state.png_id = id; /* The ID to use in the ECHO request */ diff --git a/net/icmpv6/icmpv6_rnotify.c b/net/icmpv6/icmpv6_rnotify.c index bf1f1beffd..b43d825702 100644 --- a/net/icmpv6/icmpv6_rnotify.c +++ b/net/icmpv6/icmpv6_rnotify.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/icmpv6/icmpv6_rnotify.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,9 +47,10 @@ #include +#include +#include #include #include -#include #include "netdev/netdev.h" #include "utils/utils.h" @@ -166,7 +167,13 @@ void icmpv6_rwait_setup(FAR struct net_driver_s *dev, memcpy(notify->rn_ifname, dev->d_ifname, IFNAMSIZ); notify->rn_result = -ETIMEDOUT; + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(¬ify->rn_sem, 0, 0); + sem_setprotocol(¬ify->rn_sem, SEM_PRIO_NONE); /* Add the wait structure to the list with interrupts disabled */ @@ -183,7 +190,13 @@ void icmpv6_rwait_setup(FAR struct net_driver_s *dev, /* Initialize and remember wait structure */ notify->rn_result = -ETIMEDOUT; + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(¬ify->rn_sem, 0, 0); + sem_setprotocol(¬ify->rn_sem, SEM_PRIO_NONE); DEBUGASSERT(g_icmpv6_rwaiters == NULL); g_icmpv6_rwaiters = notify; diff --git a/net/igmp/igmp_group.c b/net/igmp/igmp_group.c index 90e8fb6579..e93a502052 100644 --- a/net/igmp/igmp_group.c +++ b/net/igmp/igmp_group.c @@ -2,7 +2,7 @@ * net/igmp/igmp_group.c * IGMP group data structure management logic * - * Copyright (C) 2010, 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2013-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * The NuttX implementation of IGMP was inspired by the IGMP add-on for the @@ -55,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -240,7 +241,13 @@ FAR struct igmp_group_s *igmp_grpalloc(FAR struct net_driver_s *dev, /* Initialize the non-zero elements of the group structure */ net_ipv4addr_copy(group->grpaddr, *addr); + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&group->sem, 0, 0); + sem_setprotocol(&group->sem, SEM_PRIO_NONE); /* Initialize the group timer (but don't start it yet) */ diff --git a/net/local/local_conn.c b/net/local/local_conn.c index a369f04b7c..e70f8df7ab 100644 --- a/net/local/local_conn.c +++ b/net/local/local_conn.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/local/local_conn.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,7 @@ #include #include +#include #include "local/local.h" @@ -92,8 +93,15 @@ FAR struct local_conn_s *local_alloc(void) conn->lc_infd = -1; conn->lc_outfd = -1; + #ifdef CONFIG_NET_LOCAL_STREAM + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&conn->lc_waitsem, 0, 0); + sem_setprotocol(&conn->lc_waitsem, SEM_PRIO_NONE); + #ifdef HAVE_LOCAL_POLL memset(conn->lc_accept_fds, 0, sizeof(conn->lc_accept_fds)); #endif diff --git a/net/pkt/pkt_send.c b/net/pkt/pkt_send.c index a419d69d8f..b4dc0d6d45 100644 --- a/net/pkt/pkt_send.c +++ b/net/pkt/pkt_send.c @@ -1,7 +1,8 @@ /**************************************************************************** * net/pkt/pkt_send.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,6 +53,7 @@ #include #include +#include #include #include #include @@ -245,7 +247,14 @@ ssize_t psock_pkt_send(FAR struct socket *psock, FAR const void *buf, save = net_lock(); memset(&state, 0, sizeof(struct send_s)); + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ + (void)sem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); + state.snd_sock = psock; /* Socket descriptor to use */ state.snd_buflen = len; /* Number of bytes to send */ state.snd_buffer = buf; /* Buffer to send from */ diff --git a/net/socket/connect.c b/net/socket/connect.c index 22c9cbbe31..3e174ae0b3 100644 --- a/net/socket/connect.c +++ b/net/socket/connect.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/socket/connect.c * - * Copyright (C) 2007-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2012, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,8 @@ #include #include + +#include #include #include #include @@ -107,7 +109,13 @@ static inline int psock_setup_callbacks(FAR struct socket *psock, /* Initialize the TCP state structure */ + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(&pstate->tc_sem, 0, 0); /* Doesn't really fail */ + (void)sem_setprotocol(&pstate->tc_sem, SEM_PRIO_NONE); + pstate->tc_conn = conn; pstate->tc_psock = psock; pstate->tc_result = -EAGAIN; diff --git a/net/socket/net_close.c b/net/socket/net_close.c index 261e1d4a88..3ca53d30de 100644 --- a/net/socket/net_close.c +++ b/net/socket/net_close.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/socket/net_close.c * - * Copyright (C) 2007-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,8 @@ #include #include + +#include #include #include #include @@ -388,7 +390,13 @@ static inline int netclose_disconnect(FAR struct socket *psock) state.cl_psock = psock; state.cl_result = -EBUSY; + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&state.cl_sem, 0, 0); + sem_setprotocol(&state.cl_sem, SEM_PRIO_NONE); /* Record the time that we started the wait (in ticks) */ diff --git a/net/socket/net_sendfile.c b/net/socket/net_sendfile.c index 6c70cab18e..1efb22d1c8 100644 --- a/net/socket/net_sendfile.c +++ b/net/socket/net_sendfile.c @@ -57,6 +57,7 @@ #include #include +#include #include #include #include @@ -673,9 +674,15 @@ ssize_t net_sendfile(int outfd, struct file *infile, off_t *offset, */ save = net_lock(); - memset(&state, 0, sizeof(struct sendfile_s)); - sem_init(&state. snd_sem, 0, 0); /* Doesn't really fail */ + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ + sem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); + state.snd_sock = psock; /* Socket descriptor to use */ state.snd_foffset = offset ? *offset : 0; /* Input file offset */ state.snd_flen = count; /* Number of bytes to send */ diff --git a/net/socket/recvfrom.c b/net/socket/recvfrom.c index 8b318bb6df..046860b75f 100644 --- a/net/socket/recvfrom.c +++ b/net/socket/recvfrom.c @@ -56,6 +56,7 @@ #include #include +#include #include #include #include @@ -1217,7 +1218,14 @@ static void recvfrom_init(FAR struct socket *psock, FAR void *buf, /* Initialize the state structure. */ memset(pstate, 0, sizeof(struct recvfrom_s)); + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(&pstate->rf_sem, 0, 0); /* Doesn't really fail */ + (void)sem_setprotocol(&pstate->rf_sem, SEM_PRIO_NONE); + pstate->rf_buflen = len; pstate->rf_buffer = buf; pstate->rf_from = infrom; diff --git a/net/tcp/tcp_accept.c b/net/tcp/tcp_accept.c index d2b7d426ed..95d8bfbf40 100644 --- a/net/tcp/tcp_accept.c +++ b/net/tcp/tcp_accept.c @@ -1,7 +1,7 @@ /**************************************************************************** * net/tcp/tcp_accept.c * - * Copyright (C) 2007-2012, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2012, 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,7 @@ #include #include +#include #include #include "socket/socket.h" @@ -279,7 +280,13 @@ int psock_tcp_accept(FAR struct socket *psock, FAR struct sockaddr *addr, state.acpt_addrlen = addrlen; state.acpt_newconn = NULL; state.acpt_result = OK; + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&state.acpt_sem, 0, 0); + sem_setprotocol(&state.acpt_sem, SEM_PRIO_NONE); /* Set up the callback in the connection */ diff --git a/net/tcp/tcp_send_unbuffered.c b/net/tcp/tcp_send_unbuffered.c index f0f7c60121..4710c41fe7 100644 --- a/net/tcp/tcp_send_unbuffered.c +++ b/net/tcp/tcp_send_unbuffered.c @@ -52,7 +52,9 @@ #include #include + #include +#include #include #include #include @@ -792,7 +794,14 @@ ssize_t psock_tcp_send(FAR struct socket *psock, save = net_lock(); memset(&state, 0, sizeof(struct send_s)); + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + (void)sem_init(&state.snd_sem, 0, 0); /* Doesn't really fail */ + (void)sem_setprotocol(&state.snd_sem, SEM_PRIO_NONE); + state.snd_sock = psock; /* Socket descriptor to use */ state.snd_buflen = len; /* Number of bytes to send */ state.snd_buffer = buf; /* Buffer to send from */ diff --git a/net/udp/udp_psock_sendto.c b/net/udp/udp_psock_sendto.c index 9210a5dcef..7ae830c5b7 100644 --- a/net/udp/udp_psock_sendto.c +++ b/net/udp/udp_psock_sendto.c @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -391,7 +392,14 @@ ssize_t psock_udp_sendto(FAR struct socket *psock, FAR const void *buf, save = net_lock(); memset(&state, 0, sizeof(struct sendto_s)); + + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&state.st_sem, 0, 0); + sem_setprotocol(&state.st_sem, SEM_PRIO_NONE); + state.st_buflen = len; state.st_buffer = buf; From dbbe46a2bce9b88266e7e40ee3717eca188c4f3a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 12:23:31 -0600 Subject: [PATCH 052/155] fs: Disable priority inheritance on all semaphores used for signaling --- fs/vfs/fs_poll.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/vfs/fs_poll.c b/fs/vfs/fs_poll.c index 605147ec7f..e2c66abf7b 100644 --- a/fs/vfs/fs_poll.c +++ b/fs/vfs/fs_poll.c @@ -47,9 +47,9 @@ #include #include +#include #include #include -#include #include @@ -365,7 +365,13 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) int errcode; int ret; + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&sem, 0, 0); + sem_setprotocol(&sem, SEM_PRIO_NONE); + ret = poll_setup(fds, nfds, &sem); if (ret >= 0) { From 1da3a5fa61d8a0f7d0f5047791c2db2a6f3cd735 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 12:42:02 -0600 Subject: [PATCH 053/155] sched: Disable priority inheritance on all semaphores used for signaling --- include/nuttx/semaphore.h | 2 +- sched/group/group_create.c | 8 +++++++- sched/pthread/pthread_create.c | 17 ++++++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 04fde1bacb..1b90a1b6a0 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -205,7 +205,7 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); #ifdef CONFIG_PRIORITY_INHERITANCE int sem_setprotocol(FAR sem_t *sem, int protocol); #else -# define sem_setprotocol(s,p) DEBUGASSERT((p) == SEM_PRIO_NONE); +# define sem_setprotocol(s,p) ((p) == SEM_PRIO_NONE ? 0 : -ENOSYS); #endif #undef EXTERN diff --git a/sched/group/group_create.c b/sched/group/group_create.c index 2aecb9c12b..d5cee38002 100644 --- a/sched/group/group_create.c +++ b/sched/group/group_create.c @@ -46,6 +46,7 @@ #include #include +#include #include "environ/environ.h" #include "group/group.h" @@ -248,9 +249,14 @@ int group_allocate(FAR struct task_tcb_s *tcb, uint8_t ttype) #endif #if defined(CONFIG_SCHED_WAITPID) && !defined(CONFIG_SCHED_HAVE_PARENT) - /* Initialize the exit/wait semaphores */ + /* Initialize the exit/wait semaphores + * + * This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ (void)sem_init(&group->tg_exitsem, 0, 0); + (void)sem_setprotocol(&group->tg_exitsem, SEM_PRIO_NONE); #endif return OK; diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index be81a5f0ff..dccee1b965 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -49,9 +49,10 @@ #include #include +#include +#include #include #include -#include #include "sched/sched.h" #include "group/group.h" @@ -498,6 +499,20 @@ int pthread_create(FAR pthread_t *thread, FAR const pthread_attr_t *attr, ret = sem_init(&pjoin->exit_sem, 0, 0); } + /* Thse semaphores are used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + if (ret == OK) + { + ret = sem_setprotocol(&pjoin->data_sem, SEM_PRIO_NONE); + } + + if (ret == OK) + { + ret = sem_setprotocol(&pjoin->exit_sem, SEM_PRIO_NONE); + } + /* If the priority of the new pthread is lower than the priority of the * parent thread, then starting the pthread could result in both the * parent and the pthread to be blocked. This is a recipe for priority From 4c8ec0d2cae3da81787824642a4166a51416c94b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 12:49:44 -0600 Subject: [PATCH 054/155] include/nuttx/semaphore.h: Fix broken macros --- include/nuttx/semaphore.h | 8 -------- libc/semaphore/Make.defs | 6 +----- libc/semaphore/sem_getprotocol.c | 15 +++++++++------ sched/semaphore/Make.defs | 4 ++-- sched/semaphore/sem_setprotocol.c | 8 ++++---- syscall/syscall.csv | 2 +- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/include/nuttx/semaphore.h b/include/nuttx/semaphore.h index 1b90a1b6a0..579a0c4a10 100644 --- a/include/nuttx/semaphore.h +++ b/include/nuttx/semaphore.h @@ -160,11 +160,7 @@ int sem_reset(FAR sem_t *sem, int16_t count); * ****************************************************************************/ -#ifdef CONFIG_PRIORITY_INHERITANCE int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); -#else -# define sem_getprotocol(s,p) do { *(p) == SEM_PRIO_NONE); } while (0) -#endif /**************************************************************************** * Function: sem_setprotocol @@ -202,11 +198,7 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol); * ****************************************************************************/ -#ifdef CONFIG_PRIORITY_INHERITANCE int sem_setprotocol(FAR sem_t *sem, int protocol); -#else -# define sem_setprotocol(s,p) ((p) == SEM_PRIO_NONE ? 0 : -ENOSYS); -#endif #undef EXTERN #ifdef __cplusplus diff --git a/libc/semaphore/Make.defs b/libc/semaphore/Make.defs index d456f07520..cafa18b65a 100644 --- a/libc/semaphore/Make.defs +++ b/libc/semaphore/Make.defs @@ -35,11 +35,7 @@ # Add the semaphore C files to the build -CSRCS += sem_init.c sem_getvalue.c - -ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -CSRCS += sem_getprotocol.c -endif +CSRCS += sem_init.c sem_getprotocol.c sem_getvalue.c # Add the semaphore directory to the build diff --git a/libc/semaphore/sem_getprotocol.c b/libc/semaphore/sem_getprotocol.c index 4ae1606ff7..614d5da72a 100644 --- a/libc/semaphore/sem_getprotocol.c +++ b/libc/semaphore/sem_getprotocol.c @@ -43,8 +43,6 @@ #include -#ifdef CONFIG_PRIORITY_INHERITANCE - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -71,14 +69,19 @@ int sem_getprotocol(FAR sem_t *sem, FAR int *protocol) { DEBUGASSERT(sem != NULL && protocol != NULL); +#ifdef CONFIG_PRIORITY_INHERITANCE if ((sem->flags & PRIOINHERIT_FLAGS_DISABLE) != 0) { - return SEM_PRIO_NONE; + *protocol = SEM_PRIO_NONE; } else { - return SEM_PRIO_INHERIT; + *protocol = SEM_PRIO_INHERIT; } -} -#endif /* CONFIG_PRIORITY_INHERITANCE */ +#else + *protocol = SEM_PRIO_NONE; +#endif + + return OK; +} diff --git a/sched/semaphore/Make.defs b/sched/semaphore/Make.defs index 7eb1740424..93fd35a0d0 100644 --- a/sched/semaphore/Make.defs +++ b/sched/semaphore/Make.defs @@ -37,10 +37,10 @@ CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_tickwait.c CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c -CSRCS += sem_reset.c sem_waitirq.c +CSRCS += sem_reset.c sem_setprotocol.c sem_waitirq.c ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -CSRCS += sem_initialize.c sem_holder.c sem_setprotocol.c +CSRCS += sem_initialize.c sem_holder.c endif ifeq ($(CONFIG_SPINLOCK),y) diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c index 1350206941..6f4392bcce 100644 --- a/sched/semaphore/sem_setprotocol.c +++ b/sched/semaphore/sem_setprotocol.c @@ -46,8 +46,6 @@ #include "semaphore/semaphore.h" -#ifdef CONFIG_PRIORITY_INHERITANCE - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -97,6 +95,7 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) switch (protocol) { case SEM_PRIO_NONE: +#ifdef CONFIG_PRIORITY_INHERITANCE /* Disable priority inheritance */ sem->flags |= PRIOINHERIT_FLAGS_DISABLE; @@ -104,13 +103,16 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) /* Remove any current holders */ sem_destroyholder(sem); +#endif return OK; case SEM_PRIO_INHERIT: +#ifdef CONFIG_PRIORITY_INHERITANCE /* Enable priority inheritance (dangerous) */ sem->flags &= ~PRIOINHERIT_FLAGS_DISABLE; return OK; +#endif case SEM_PRIO_PROTECT: /* Not yet supported */ @@ -126,5 +128,3 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) set_errno(errcode); return ERROR; } - -#endif /* CONFIG_PRIORITY_INHERITANCE */ diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 8ecf52854f..99071ea27d 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -118,7 +118,7 @@ "sem_destroy","semaphore.h","","int","FAR sem_t*" "sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","..." "sem_post","semaphore.h","","int","FAR sem_t*" -"sem_setprotocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" +"sem_setprotocol","nuttx/semaphore.h","","int","FAR sem_t*","int" "sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *" "sem_trywait","semaphore.h","","int","FAR sem_t*" "sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char*" From 0d5bd30943ede5a5bdc8584a6616936d5811f7ee Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 12:58:02 -0600 Subject: [PATCH 055/155] Fix a type in include file name --- sched/pthread/pthread_create.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index dccee1b965..6efc9aa21a 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -50,7 +50,7 @@ #include #include -#include +#include #include #include From e1cd9febbff41db30475fa8f2fde0270adfccacd Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 14:23:42 -0600 Subject: [PATCH 056/155] arch: Disable priority inheritance on all semaphores used for signaling in all I2C/TWI drivers --- arch/arm/src/efm32/efm32_i2c.c | 9 ++++++++- arch/arm/src/kinetis/kinetis_i2c.c | 9 +++++++++ arch/arm/src/lpc11xx/lpc11_i2c.c | 9 +++++++++ arch/arm/src/lpc17xx/lpc17_i2c.c | 9 +++++++++ arch/arm/src/lpc2378/lpc23xx_i2c.c | 9 +++++++++ arch/arm/src/lpc31xx/lpc31_i2c.c | 9 +++++++++ arch/arm/src/lpc43xx/lpc43_i2c.c | 9 +++++++++ arch/arm/src/sam34/sam_twi.c | 9 +++++++++ arch/arm/src/sama5/sam_twi.c | 9 +++++++++ arch/arm/src/samv7/sam_twihs.c | 9 +++++++++ arch/arm/src/stm32/stm32_i2c.c | 9 ++++++++- arch/arm/src/stm32/stm32_i2c_alt.c | 9 ++++++++- arch/arm/src/stm32/stm32f30xxx_i2c.c | 9 ++++++++- arch/arm/src/stm32/stm32f40xxx_i2c.c | 9 ++++++++- arch/arm/src/stm32f7/stm32_i2c.c | 9 ++++++++- arch/arm/src/stm32l4/stm32l4_i2c.c | 9 ++++++++- arch/arm/src/tiva/tiva_i2c.c | 9 ++++++++- 17 files changed, 145 insertions(+), 8 deletions(-) diff --git a/arch/arm/src/efm32/efm32_i2c.c b/arch/arm/src/efm32/efm32_i2c.c index d05f9ae22a..1c10e5b14c 100644 --- a/arch/arm/src/efm32/efm32_i2c.c +++ b/arch/arm/src/efm32/efm32_i2c.c @@ -71,8 +71,9 @@ #include #include -#include #include +#include +#include #include @@ -681,8 +682,14 @@ static inline void efm32_i2c_sem_post(FAR struct efm32_i2c_priv_s *priv) static inline void efm32_i2c_sem_init(FAR struct efm32_i2c_priv_s *priv) { sem_init(&priv->sem_excl, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->sem_isr, 0, 0); + sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); #endif } diff --git a/arch/arm/src/kinetis/kinetis_i2c.c b/arch/arm/src/kinetis/kinetis_i2c.c index 520534b3a5..337e24b4d3 100644 --- a/arch/arm/src/kinetis/kinetis_i2c.c +++ b/arch/arm/src/kinetis/kinetis_i2c.c @@ -49,6 +49,7 @@ #include #include +#include #include #include @@ -1105,9 +1106,17 @@ struct i2c_master_s *kinetis_i2cbus_initialize(int port) leave_critical_section(flags); + /* Initialize semaphores */ + sem_init(&priv->mutex, 0, 1); sem_init(&priv->wait, 0, 0); + /* The wait semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->wait, SEM_PRIO_NONE); + /* Allocate a watchdog timer */ priv->timeout = wd_create(); diff --git a/arch/arm/src/lpc11xx/lpc11_i2c.c b/arch/arm/src/lpc11xx/lpc11_i2c.c index 184290a602..b8f91daee7 100644 --- a/arch/arm/src/lpc11xx/lpc11_i2c.c +++ b/arch/arm/src/lpc11xx/lpc11_i2c.c @@ -59,6 +59,7 @@ #include #include +#include #include #include @@ -584,9 +585,17 @@ struct i2c_master_s *lpc11_i2cbus_initialize(int port) putreg32(I2C_CONSET_I2EN, priv->base + LPC11_I2C_CONSET_OFFSET); + /* Initialize semaphores */ + sem_init(&priv->mutex, 0, 1); sem_init(&priv->wait, 0, 0); + /* The wait semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->wait, SEM_PRIO_NONE); + /* Allocate a watchdog timer */ priv->timeout = wd_create(); diff --git a/arch/arm/src/lpc17xx/lpc17_i2c.c b/arch/arm/src/lpc17xx/lpc17_i2c.c index 58bb2de898..554659818f 100644 --- a/arch/arm/src/lpc17xx/lpc17_i2c.c +++ b/arch/arm/src/lpc17xx/lpc17_i2c.c @@ -59,6 +59,7 @@ #include #include +#include #include #include @@ -589,9 +590,17 @@ struct i2c_master_s *lpc17_i2cbus_initialize(int port) putreg32(I2C_CONSET_I2EN, priv->base + LPC17_I2C_CONSET_OFFSET); + /* Initialize semaphores */ + sem_init(&priv->mutex, 0, 1); sem_init(&priv->wait, 0, 0); + /* The wait semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->wait, SEM_PRIO_NONE); + /* Allocate a watchdog timer */ priv->timeout = wd_create(); diff --git a/arch/arm/src/lpc2378/lpc23xx_i2c.c b/arch/arm/src/lpc2378/lpc23xx_i2c.c index 1c281e8857..5de046a39f 100644 --- a/arch/arm/src/lpc2378/lpc23xx_i2c.c +++ b/arch/arm/src/lpc2378/lpc23xx_i2c.c @@ -64,6 +64,7 @@ #include #include +#include #include #include @@ -600,9 +601,17 @@ struct i2c_master_s *lpc2378_i2cbus_initialize(int port) putreg32(I2C_CONSET_I2EN, priv->base + I2C_CONSET_OFFSET); + /* Initialize semaphores */ + sem_init(&priv->mutex, 0, 1); sem_init(&priv->wait, 0, 0); + /* The wait semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->wait, SEM_PRIO_NONE); + /* Allocate a watchdog timer */ priv->timeout = wd_create(); diff --git a/arch/arm/src/lpc31xx/lpc31_i2c.c b/arch/arm/src/lpc31xx/lpc31_i2c.c index 79d9667a9d..1f27c4d1ff 100644 --- a/arch/arm/src/lpc31xx/lpc31_i2c.c +++ b/arch/arm/src/lpc31xx/lpc31_i2c.c @@ -51,6 +51,7 @@ #include #include +#include #include #include @@ -554,9 +555,17 @@ struct i2c_master_s *lpc31_i2cbus_initialize(int port) priv->rstid = (port == 0) ? RESETID_I2C0RST : RESETID_I2C1RST; priv->irqid = (port == 0) ? LPC31_IRQ_I2C0 : LPC31_IRQ_I2C1; + /* Initialize semaphores */ + sem_init(&priv->mutex, 0, 1); sem_init(&priv->wait, 0, 0); + /* The wait semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->wait, SEM_PRIO_NONE); + /* Enable I2C system clocks */ lpc31_enableclock(priv->clkid); diff --git a/arch/arm/src/lpc43xx/lpc43_i2c.c b/arch/arm/src/lpc43xx/lpc43_i2c.c index fed79db207..49a77bb8b5 100644 --- a/arch/arm/src/lpc43xx/lpc43_i2c.c +++ b/arch/arm/src/lpc43xx/lpc43_i2c.c @@ -62,6 +62,7 @@ #include #include +#include #include #include @@ -539,9 +540,17 @@ struct i2c_master_s *lpc43_i2cbus_initialize(int port) putreg32(I2C_CONSET_I2EN, priv->base + LPC43_I2C_CONSET_OFFSET); + /* Initialize semaphores */ + sem_init(&priv->mutex, 0, 1); sem_init(&priv->wait, 0, 0); + /* The wait semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->wait, SEM_PRIO_NONE); + /* Allocate a watchdog timer */ priv->timeout = wd_create(); diff --git a/arch/arm/src/sam34/sam_twi.c b/arch/arm/src/sam34/sam_twi.c index 74d0e7d6ed..1ed9c03f64 100644 --- a/arch/arm/src/sam34/sam_twi.c +++ b/arch/arm/src/sam34/sam_twi.c @@ -56,6 +56,7 @@ #include #include +#include #include #include @@ -982,9 +983,17 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus) priv->dev.ops = &g_twiops; + /* Initialize semaphores */ + sem_init(&priv->exclsem, 0, 1); sem_init(&priv->waitsem, 0, 0); + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Allocate a watchdog timer */ priv->timeout = wd_create(); diff --git a/arch/arm/src/sama5/sam_twi.c b/arch/arm/src/sama5/sam_twi.c index 4af5f702b0..52f3e0950d 100644 --- a/arch/arm/src/sama5/sam_twi.c +++ b/arch/arm/src/sama5/sam_twi.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -1306,9 +1307,17 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus) priv->dev.ops = &g_twiops; + /* Initialize semaphores */ + (void)sem_init(&priv->exclsem, 0, 1); (void)sem_init(&priv->waitsem, 0, 0); + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Perform repeatable TWI hardware initialization */ twi_hw_initialize(priv, frequency); diff --git a/arch/arm/src/samv7/sam_twihs.c b/arch/arm/src/samv7/sam_twihs.c index 6800ecbba8..bdb5523ace 100644 --- a/arch/arm/src/samv7/sam_twihs.c +++ b/arch/arm/src/samv7/sam_twihs.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -1454,9 +1455,17 @@ struct i2c_master_s *sam_i2cbus_initialize(int bus) priv->dev.ops = &g_twiops; + /* Initialize semaphores */ + (void)sem_init(&priv->exclsem, 0, 1); (void)sem_init(&priv->waitsem, 0, 0); + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + /* Perform repeatable TWIHS hardware initialization */ twi_hw_initialize(priv, frequency); diff --git a/arch/arm/src/stm32/stm32_i2c.c b/arch/arm/src/stm32/stm32_i2c.c index 9f41597f04..631ba66501 100644 --- a/arch/arm/src/stm32/stm32_i2c.c +++ b/arch/arm/src/stm32/stm32_i2c.c @@ -84,8 +84,9 @@ #include #include -#include #include +#include +#include #include @@ -784,8 +785,14 @@ static inline void stm32_i2c_sem_post(struct stm32_i2c_priv_s *priv) static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv) { sem_init(&priv->sem_excl, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->sem_isr, 0, 0); + sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); #endif } diff --git a/arch/arm/src/stm32/stm32_i2c_alt.c b/arch/arm/src/stm32/stm32_i2c_alt.c index ac2ea5f607..545a647334 100644 --- a/arch/arm/src/stm32/stm32_i2c_alt.c +++ b/arch/arm/src/stm32/stm32_i2c_alt.c @@ -91,8 +91,9 @@ #include #include -#include #include +#include +#include #include @@ -792,8 +793,14 @@ static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv) static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv) { sem_init(&priv->sem_excl, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->sem_isr, 0, 0); + sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); #endif } diff --git a/arch/arm/src/stm32/stm32f30xxx_i2c.c b/arch/arm/src/stm32/stm32f30xxx_i2c.c index 27b1c92488..312e0b4bb8 100644 --- a/arch/arm/src/stm32/stm32f30xxx_i2c.c +++ b/arch/arm/src/stm32/stm32f30xxx_i2c.c @@ -85,8 +85,9 @@ #include #include -#include #include +#include +#include #include @@ -899,8 +900,14 @@ static inline void stm32_i2c_sem_post(FAR struct stm32_i2c_priv_s *priv) static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv) { sem_init(&priv->sem_excl, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->sem_isr, 0, 0); + sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); #endif } diff --git a/arch/arm/src/stm32/stm32f40xxx_i2c.c b/arch/arm/src/stm32/stm32f40xxx_i2c.c index 155add73ae..2bb715c4a8 100644 --- a/arch/arm/src/stm32/stm32f40xxx_i2c.c +++ b/arch/arm/src/stm32/stm32f40xxx_i2c.c @@ -84,8 +84,9 @@ #include #include -#include #include +#include +#include #include @@ -786,8 +787,14 @@ static inline void stm32_i2c_sem_post(struct stm32_i2c_priv_s *priv) static inline void stm32_i2c_sem_init(FAR struct stm32_i2c_priv_s *priv) { sem_init(&priv->sem_excl, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->sem_isr, 0, 0); + sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); #endif } diff --git a/arch/arm/src/stm32f7/stm32_i2c.c b/arch/arm/src/stm32f7/stm32_i2c.c index eda1fba72a..5da613f528 100644 --- a/arch/arm/src/stm32f7/stm32_i2c.c +++ b/arch/arm/src/stm32f7/stm32_i2c.c @@ -231,9 +231,10 @@ #include #include -#include +#include #include #include +#include #include @@ -1089,8 +1090,14 @@ static inline void stm32_i2c_sem_post(FAR struct i2c_master_s *dev) static inline void stm32_i2c_sem_init(FAR struct i2c_master_s *dev) { sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_excl, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, 0, 0); + sem_setprotocol(&((struct stm32_i2c_inst_s *)dev)->priv->sem_isr, SEM_PRIO_NONE); #endif } diff --git a/arch/arm/src/stm32l4/stm32l4_i2c.c b/arch/arm/src/stm32l4/stm32l4_i2c.c index 278885fc58..eed199f86d 100644 --- a/arch/arm/src/stm32l4/stm32l4_i2c.c +++ b/arch/arm/src/stm32l4/stm32l4_i2c.c @@ -81,8 +81,9 @@ #include #include -#include #include +#include +#include #include @@ -843,8 +844,14 @@ static inline void stm32l4_i2c_sem_post(FAR struct stm32l4_i2c_priv_s *priv) static inline void stm32l4_i2c_sem_init(FAR struct stm32l4_i2c_priv_s *priv) { sem_init(&priv->sem_excl, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->sem_isr, 0, 0); + sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); #endif } diff --git a/arch/arm/src/tiva/tiva_i2c.c b/arch/arm/src/tiva/tiva_i2c.c index 1d0127aa04..13b9c7b5ad 100644 --- a/arch/arm/src/tiva/tiva_i2c.c +++ b/arch/arm/src/tiva/tiva_i2c.c @@ -57,8 +57,9 @@ #include #include -#include #include +#include +#include #include @@ -891,8 +892,14 @@ static inline void tiva_i2c_sem_post(struct tiva_i2c_priv_s *priv) static inline void tiva_i2c_sem_init(struct tiva_i2c_priv_s *priv) { sem_init(&priv->exclsem, 0, 1); + #ifndef CONFIG_I2C_POLLED + /* This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->waitsem, 0, 0); + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); #endif } From 8b07aa6f7cf1f37e2c5a690547c8d5bd0c3b79b2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 14:51:44 -0600 Subject: [PATCH 057/155] arch: Disable priority inheritance on all semaphores used for signaling in all SPI drivers --- arch/arm/src/efm32/efm32_spi.c | 8 ++++++++ arch/arm/src/imx1/imx_spi.c | 7 +++++++ arch/arm/src/sam34/sam_spi.c | 5 ++++- arch/arm/src/sama5/sam_spi.c | 5 ++++- arch/arm/src/samv7/sam_qspi.c | 5 ++++- arch/arm/src/samv7/sam_spi.c | 5 ++++- arch/arm/src/stm32/stm32_spi.c | 11 +++++++++-- arch/arm/src/stm32f7/stm32_spi.c | 13 ++++++++++--- arch/arm/src/stm32l4/stm32l4_qspi.c | 12 +++++++++--- arch/arm/src/stm32l4/stm32l4_spi.c | 8 ++++++++ 10 files changed, 67 insertions(+), 12 deletions(-) diff --git a/arch/arm/src/efm32/efm32_spi.c b/arch/arm/src/efm32/efm32_spi.c index 0bf2c31a86..d0ae6d378a 100644 --- a/arch/arm/src/efm32/efm32_spi.c +++ b/arch/arm/src/efm32/efm32_spi.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -1640,6 +1641,13 @@ static int spi_portinitialize(struct efm32_spidev_s *priv) (void)sem_init(&priv->rxdmasem, 0, 0); (void)sem_init(&priv->txdmasem, 0, 0); + + /* These semaphores are used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->rxdmasem, SEM_PRIO_NONE); + sem_setprotocol(&priv->txdmasem, SEM_PRIO_NONE); #endif /* Enable SPI */ diff --git a/arch/arm/src/imx1/imx_spi.c b/arch/arm/src/imx1/imx_spi.c index fb58314386..d63c65ed2e 100644 --- a/arch/arm/src/imx1/imx_spi.c +++ b/arch/arm/src/imx1/imx_spi.c @@ -50,6 +50,7 @@ #include #include +#include #include #include "up_internal.h" @@ -1116,7 +1117,13 @@ FAR struct spi_dev_s *imx_spibus_initialize(int port) /* Initialize the state structure */ #ifndef CONFIG_SPI_POLLWAIT + /* Initialize the semaphore that is used to wake up the waiting + * thread when the DMA transfer completes. This semaphore is used for + * signaling and, hence, should not have priority inheritance enabled. + */ + sem_init(&priv->waitsem, 0, 0); + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); #endif sem_init(&priv->exclsem, 0, 1); diff --git a/arch/arm/src/sam34/sam_spi.c b/arch/arm/src/sam34/sam_spi.c index 4b7f1dba7e..2cbe3614b6 100644 --- a/arch/arm/src/sam34/sam_spi.c +++ b/arch/arm/src/sam34/sam_spi.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include "up_internal.h" @@ -1882,10 +1883,12 @@ struct spi_dev_s *sam_spibus_initialize(int port) #ifdef CONFIG_SAM34_SPI_DMA /* Initialize the SPI semaphore that is used to wake up the waiting - * thread when the DMA transfer completes. + * thread when the DMA transfer completes. This semaphore is used for + * signaling and, hence, should not have priority inheritance enabled. */ sem_init(&spics->dmawait, 0, 0); + sem_setprotocol(&spics->dmawait, SEM_PRIO_NONE); /* Create a watchdog time to catch DMA timeouts */ diff --git a/arch/arm/src/sama5/sam_spi.c b/arch/arm/src/sama5/sam_spi.c index 0386fcc681..459e949cad 100644 --- a/arch/arm/src/sama5/sam_spi.c +++ b/arch/arm/src/sama5/sam_spi.c @@ -60,6 +60,7 @@ #include #include #include +#include #include #include "up_internal.h" @@ -1810,10 +1811,12 @@ struct spi_dev_s *sam_spibus_initialize(int port) #ifdef CONFIG_SAMA5_SPI_DMA /* Initialize the SPI semaphore that is used to wake up the waiting - * thread when the DMA transfer completes. + * thread when the DMA transfer completes. This semaphore is used for + * signaling and, hence, should not have priority inheritance enabled. */ sem_init(&spics->dmawait, 0, 0); + sem_setprotocol(&spics->dmawait, SEM_PRIO_NONE); /* Create a watchdog time to catch DMA timeouts */ diff --git a/arch/arm/src/samv7/sam_qspi.c b/arch/arm/src/samv7/sam_qspi.c index b90a515d8b..a37245c7e6 100644 --- a/arch/arm/src/samv7/sam_qspi.c +++ b/arch/arm/src/samv7/sam_qspi.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "up_internal.h" @@ -1790,10 +1791,12 @@ struct qspi_dev_s *sam_qspi_initialize(int intf) } /* Initialize the QSPI semaphore that is used to wake up the waiting - * thread when the DMA transfer completes. + * thread when the DMA transfer completes. This semaphore is used for + * signaling and, hence, should not have priority inheritance enabled. */ sem_init(&priv->dmawait, 0, 0); + sem_setprotocol(&priv->dmawait, SEM_PRIO_NONE); /* Create a watchdog time to catch DMA timeouts */ diff --git a/arch/arm/src/samv7/sam_spi.c b/arch/arm/src/samv7/sam_spi.c index 959a3cd290..d0b40e8694 100644 --- a/arch/arm/src/samv7/sam_spi.c +++ b/arch/arm/src/samv7/sam_spi.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include "up_internal.h" @@ -2164,10 +2165,12 @@ FAR struct spi_dev_s *sam_spibus_initialize(int port) #ifdef CONFIG_SAMV7_SPI_DMA /* Initialize the SPI semaphore that is used to wake up the waiting - * thread when the DMA transfer completes. + * thread when the DMA transfer completes. This semaphore is used for + * signaling and, hence, should not have priority inheritance enabled. */ sem_init(&spics->dmawait, 0, 0); + sem_setprotocol(&spics->dmawait, SEM_PRIO_NONE); /* Create a watchdog time to catch DMA timeouts */ diff --git a/arch/arm/src/stm32/stm32_spi.c b/arch/arm/src/stm32/stm32_spi.c index c70bf8f6f1..ad6d2fc47c 100644 --- a/arch/arm/src/stm32/stm32_spi.c +++ b/arch/arm/src/stm32/stm32_spi.c @@ -70,6 +70,7 @@ #include #include +#include #include #include @@ -1719,12 +1720,18 @@ static void spi_bus_initialize(FAR struct stm32_spidev_s *priv) sem_init(&priv->exclsem, 0, 1); - /* Initialize the SPI semaphores that is used to wait for DMA completion */ - #ifdef CONFIG_STM32_SPI_DMA + /* Initialize the SPI semaphores that is used to wait for DMA completion. + * This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->rxsem, 0, 0); sem_init(&priv->txsem, 0, 0); + sem_setprotocol(&priv->rxsem, SEM_PRIO_NONE); + sem_setprotocol(&priv->txsem, SEM_PRIO_NONE); + /* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA channel. * if the channel is not available, then stm32_dmachannel() will block and wait * until the channel becomes available. WARNING: If you have another device sharing diff --git a/arch/arm/src/stm32f7/stm32_spi.c b/arch/arm/src/stm32f7/stm32_spi.c index 4b0fceba54..c00e717a09 100644 --- a/arch/arm/src/stm32f7/stm32_spi.c +++ b/arch/arm/src/stm32f7/stm32_spi.c @@ -72,6 +72,7 @@ #include #include +#include #include #include @@ -1665,16 +1666,22 @@ static void spi_bus_initialize(FAR struct stm32_spidev_s *priv) spi_putreg(priv, STM32_SPI_CRCPR_OFFSET, 7); - /* Initialize the SPI semaphore that enforces mutually exclusive access */ + /* Initialize the SPI semaphore that enforces mutually exclusive access. */ sem_init(&priv->exclsem, 0, 1); - /* Initialize the SPI semaphores that is used to wait for DMA completion */ - #ifdef CONFIG_STM32F7_SPI_DMA + /* Initialize the SPI semaphores that is used to wait for DMA completion. + * This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->rxsem, 0, 0); sem_init(&priv->txsem, 0, 0); + sem_setprotocol(&priv->rxsem, SEM_PRIO_NONE); + sem_setprotocol(&priv->txsem, SEM_PRIO_NONE); + /* Get DMA channels. NOTE: stm32_dmachannel() will always assign the DMA channel. * if the channel is not available, then stm32_dmachannel() will block and wait * until the channel becomes available. WARNING: If you have another device sharing diff --git a/arch/arm/src/stm32l4/stm32l4_qspi.c b/arch/arm/src/stm32l4/stm32l4_qspi.c index db01e22bba..95d2da540b 100644 --- a/arch/arm/src/stm32l4/stm32l4_qspi.c +++ b/arch/arm/src/stm32l4/stm32l4_qspi.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include "up_internal.h" @@ -2501,10 +2502,12 @@ struct qspi_dev_s *stm32l4_qspi_initialize(int intf) } /* Initialize the QSPI semaphore that is used to wake up the waiting - * thread when the DMA transfer completes. + * thread when the DMA transfer completes. This semaphore is used for + * signaling and, hence, should not have priority inheritance enabled. */ sem_init(&priv->dmawait, 0, 0); + sem_setprotocol(&priv->dmawait, SEM_PRIO_NONE); /* Create a watchdog time to catch DMA timeouts */ @@ -2526,10 +2529,13 @@ struct qspi_dev_s *stm32l4_qspi_initialize(int intf) goto errout_with_dmadog; } - /* Initialize the semaphore that blocks until the operation completes */ + /* Initialize the semaphore that blocks until the operation completes. + * This semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ sem_init(&priv->op_sem, 0, 0); - + sem_setprotocol(&priv->op_sem, SEM_PRIO_NONE); #endif /* Perform hardware initialization. Puts the QSPI into an active diff --git a/arch/arm/src/stm32l4/stm32l4_spi.c b/arch/arm/src/stm32l4/stm32l4_spi.c index bc61ed7446..9d9db706e0 100644 --- a/arch/arm/src/stm32l4/stm32l4_spi.c +++ b/arch/arm/src/stm32l4/stm32l4_spi.c @@ -76,6 +76,7 @@ #include #include +#include #include #include @@ -1517,6 +1518,13 @@ static void spi_bus_initialize(FAR struct stm32l4_spidev_s *priv) sem_init(&priv->rxsem, 0, 0); sem_init(&priv->txsem, 0, 0); + /* These semaphores are used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->rxsem, SEM_PRIO_NONE); + sem_setprotocol(&priv->txsem, SEM_PRIO_NONE); + /* Get DMA channels. NOTE: stm32l4_dmachannel() will always assign the DMA channel. * if the channel is not available, then stm32l4_dmachannel() will block and wait * until the channel becomes available. WARNING: If you have another device sharing From bb6bfa633eb8e8fcf4155b7ded61d4095284ecad Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 15:13:27 -0600 Subject: [PATCH 058/155] arch: Disable priority inheritance on all semaphores used for signaling in all SD card drivers --- arch/arm/src/kinetis/kinetis_sdhc.c | 11 +++++++++++ arch/arm/src/lpc17xx/lpc17_sdcard.c | 13 ++++++++++++- arch/arm/src/sam34/sam_hsmci.c | 13 ++++++++++++- arch/arm/src/sama5/sam_hsmci.c | 13 ++++++++++++- arch/arm/src/samv7/sam_hsmci.c | 13 ++++++++++++- arch/arm/src/stm32/stm32_sdio.c | 13 ++++++++++++- arch/arm/src/stm32f7/stm32_sdmmc.c | 11 +++++++++++ 7 files changed, 82 insertions(+), 5 deletions(-) diff --git a/arch/arm/src/kinetis/kinetis_sdhc.c b/arch/arm/src/kinetis/kinetis_sdhc.c index 0f1197b6e7..b724bfec91 100644 --- a/arch/arm/src/kinetis/kinetis_sdhc.c +++ b/arch/arm/src/kinetis/kinetis_sdhc.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -2774,8 +2775,18 @@ FAR struct sdio_dev_s *sdhc_initialize(int slotno) DEBUGASSERT(slotno == 0); /* Initialize the SDHC slot structure data structure */ + /* Initialize semaphores */ sem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Create a watchdog timer */ + priv->waitwdog = wd_create(); DEBUGASSERT(priv->waitwdog); diff --git a/arch/arm/src/lpc17xx/lpc17_sdcard.c b/arch/arm/src/lpc17xx/lpc17_sdcard.c index 2ea6c17c45..532c8ed35d 100644 --- a/arch/arm/src/lpc17xx/lpc17_sdcard.c +++ b/arch/arm/src/lpc17xx/lpc17_sdcard.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/lpc17xx/lpc17_sdcard.c * - * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -2699,8 +2700,18 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) putreg32(regval, LPC17_SYSCON_PCONP); /* Initialize the SD card slot structure */ + /* Initialize semaphores */ sem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Create a watchdog timer */ + priv->waitwdog = wd_create(); DEBUGASSERT(priv->waitwdog); diff --git a/arch/arm/src/sam34/sam_hsmci.c b/arch/arm/src/sam34/sam_hsmci.c index fa4073d6a2..2ad23303c4 100644 --- a/arch/arm/src/sam34/sam_hsmci.c +++ b/arch/arm/src/sam34/sam_hsmci.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/sam34/sam_hsmci.c * - * Copyright (C) 2010, 2012-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2010, 2012-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -2668,8 +2669,18 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) mcinfo("slotno: %d\n", slotno); /* Initialize the HSMCI slot structure */ + /* Initialize semaphores */ sem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Create a watchdog timer */ + priv->waitwdog = wd_create(); DEBUGASSERT(priv->waitwdog); diff --git a/arch/arm/src/sama5/sam_hsmci.c b/arch/arm/src/sama5/sam_hsmci.c index 2b4eb8361a..165a8f1a12 100644 --- a/arch/arm/src/sama5/sam_hsmci.c +++ b/arch/arm/src/sama5/sam_hsmci.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/sama5/sam_hsmci.c * - * Copyright (C) 2013-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2013-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -3331,8 +3332,18 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) priv, priv->base, priv->hsmci, dmac, pid); /* Initialize the HSMCI slot structure */ + /* Initialize semaphores */ sem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Create a watchdog timer */ + priv->waitwdog = wd_create(); DEBUGASSERT(priv->waitwdog); diff --git a/arch/arm/src/samv7/sam_hsmci.c b/arch/arm/src/samv7/sam_hsmci.c index cffada9e47..589a8cbf87 100644 --- a/arch/arm/src/samv7/sam_hsmci.c +++ b/arch/arm/src/samv7/sam_hsmci.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/samv7/sam_hsmci.c * - * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -3352,8 +3353,18 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) priv, priv->base, priv->hsmci, pid); /* Initialize the HSMCI slot structure */ + /* Initialize semaphores */ sem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Create a watchdog timer */ + priv->waitwdog = wd_create(); DEBUGASSERT(priv->waitwdog); diff --git a/arch/arm/src/stm32/stm32_sdio.c b/arch/arm/src/stm32/stm32_sdio.c index 6cd372b7fd..be060c7026 100644 --- a/arch/arm/src/stm32/stm32_sdio.c +++ b/arch/arm/src/stm32/stm32_sdio.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/stm32/stm32_sdio.c * - * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011-2014, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ #include #include #include +#include #include #include @@ -2853,8 +2854,18 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) struct stm32_dev_s *priv = &g_sdiodev; /* Initialize the SDIO slot structure */ + /* Initialize semaphores */ sem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Create a watchdog timer */ + priv->waitwdog = wd_create(); DEBUGASSERT(priv->waitwdog); diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 3e6aff9620..47ac3abf39 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -3214,8 +3215,18 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) } /* Initialize the SDIO slot structure */ + /* Initialize semaphores */ sem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Create a watchdog timer */ + priv->waitwdog = wd_create(); DEBUGASSERT(priv->waitwdog); From d28181da1042f8527f57b656c917c840d3a8285e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 17:05:53 -0600 Subject: [PATCH 059/155] arch: Disable priority inheritance on all semaphores used for signaling in all USB host drivers --- arch/arm/src/efm32/efm32_usbhost.c | 14 ++++++++++++++ arch/arm/src/lpc17xx/lpc17_usbhost.c | 19 +++++++++++++++++-- arch/arm/src/lpc31xx/lpc31_ehci.c | 19 +++++++++++++++++++ arch/arm/src/lpc43xx/lpc43_ehci.c | 19 +++++++++++++++++++ arch/arm/src/sama5/sam_ehci.c | 19 +++++++++++++++++++ arch/arm/src/sama5/sam_ohci.c | 15 ++++++++++++++- arch/arm/src/stm32/stm32_otgfshost.c | 14 ++++++++++++++ arch/arm/src/stm32/stm32_otghshost.c | 14 ++++++++++++++ arch/arm/src/stm32f7/stm32_otghost.c | 14 ++++++++++++++ arch/arm/src/stm32l4/stm32l4_otgfshost.c | 14 ++++++++++++++ 10 files changed, 158 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/efm32/efm32_usbhost.c b/arch/arm/src/efm32/efm32_usbhost.c index 19f80bc43d..be9bbccf23 100644 --- a/arch/arm/src/efm32/efm32_usbhost.c +++ b/arch/arm/src/efm32/efm32_usbhost.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -5157,6 +5158,12 @@ static inline void efm32_sw_initialize(FAR struct efm32_usbhost_s *priv) sem_init(&priv->pscsem, 0, 0); sem_init(&priv->exclsem, 0, 1); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->pscsem, SEM_PRIO_NONE); + /* Initialize the driver state data */ priv->smstate = SMSTATE_DETACHED; @@ -5172,8 +5179,15 @@ static inline void efm32_sw_initialize(FAR struct efm32_usbhost_s *priv) for (i = 0; i < EFM32_MAX_TX_FIFOS; i++) { FAR struct efm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&chan->waitsem, 0, 0); + sem_setprotocol(&chan->waitsem, SEM_PRIO_NONE); } } diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index d8d02f629c..59268f94a5 100644 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/lpc17xx/lpc17_usbhost.c * - * Copyright (C) 2010-2012, 2014-2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2010-2012, 2014-2016 Gregory Nutt. All rights reserved. * Authors: Rafael Noronha * Gregory Nutt * @@ -51,6 +51,7 @@ #include #include +#include #include #include #include @@ -2262,10 +2263,12 @@ static int lpc17_epalloc(struct usbhost_driver_s *drvr, uinfo("EP%d CTRL:%08x\n", epdesc->addr, ed->hw.ctrl); /* Initialize the semaphore that is used to wait for the endpoint - * WDH event. + * WDH event. The wdhsem semaphore is used for signaling and, hence, + * should not have priority inheritance enabled. */ sem_init(&ed->wdhsem, 0, 0); + sem_setprotocol(&priv->wdhsem, SEM_PRIO_NONE); /* Link the common tail TD to the ED's TD list */ @@ -3639,6 +3642,12 @@ struct usbhost_connection_s *lpc17_usbhost_initialize(int controller) sem_init(&priv->pscsem, 0, 0); sem_init(&priv->exclsem, 0, 1); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->pscsem, SEM_PRIO_NONE); + #ifndef CONFIG_USBHOST_INT_DISABLE priv->ininterval = MAX_PERINTERVAL; priv->outinterval = MAX_PERINTERVAL; @@ -3719,7 +3728,13 @@ struct usbhost_connection_s *lpc17_usbhost_initialize(int controller) memset((void *)HCCA, 0, sizeof(struct ohci_hcca_s)); memset((void *)TDTAIL, 0, sizeof(struct ohci_gtd_s)); memset((void *)EDCTRL, 0, sizeof(struct lpc17_ed_s)); + + /* The EDCTRL wdhsem semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + sem_init(&EDCTRL->wdhsem, 0, 0); + sem_setprotocol(&EDCTRL->wdhsem, SEM_PRIO_NONE); /* Initialize user-configurable EDs */ diff --git a/arch/arm/src/lpc31xx/lpc31_ehci.c b/arch/arm/src/lpc31xx/lpc31_ehci.c index e37abe4997..345ec24dc6 100644 --- a/arch/arm/src/lpc31xx/lpc31_ehci.c +++ b/arch/arm/src/lpc31xx/lpc31_ehci.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -3931,7 +3932,13 @@ static int lpc31_epalloc(FAR struct usbhost_driver_s *drvr, epinfo->maxpacket = epdesc->mxpacketsize; epinfo->xfrtype = epdesc->xfrtype; epinfo->speed = hport->speed; + + /* The iocsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&epinfo->iocsem, 0, 0); + sem_setprotocol(&epinfo->iocsem, SEM_PRIO_NONE); /* Success.. return an opaque reference to the endpoint information structure * instance @@ -4916,6 +4923,12 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller) sem_init(&g_ehci.exclsem, 0, 1); sem_init(&g_ehci.pscsem, 0, 0); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&g_ehci.pscsem, SEM_PRIO_NONE); + /* Initialize EP0 */ sem_init(&g_ehci.ep0.iocsem, 0, 1); @@ -4952,7 +4965,13 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller) rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL; rhport->ep0.speed = USB_SPEED_FULL; rhport->ep0.maxpacket = 8; + + /* The port iocsem semaphore is used for signaling and, hence, + * should not have priority inheritance enabled. + */ + sem_init(&rhport->ep0.iocsem, 0, 0); + sem_setprotocol(&rhport->iocsem, SEM_PRIO_NONE); /* Initialize the public port representation */ diff --git a/arch/arm/src/lpc43xx/lpc43_ehci.c b/arch/arm/src/lpc43xx/lpc43_ehci.c index ae462f80b4..2893369ced 100644 --- a/arch/arm/src/lpc43xx/lpc43_ehci.c +++ b/arch/arm/src/lpc43xx/lpc43_ehci.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -3768,7 +3769,13 @@ static int lpc43_epalloc(FAR struct usbhost_driver_s *drvr, epinfo->maxpacket = epdesc->mxpacketsize; epinfo->xfrtype = epdesc->xfrtype; epinfo->speed = hport->speed; + + /* The endpoint iocsem semaphore is used for signaling and, hence, + * should not have priority inheritance enabled. + */ + sem_init(&epinfo->iocsem, 0, 0); + sem_setprotocol(&epinfo->iocsem, SEM_PRIO_NONE); /* Success.. return an opaque reference to the endpoint information structure * instance @@ -4747,6 +4754,12 @@ FAR struct usbhost_connection_s *lpc43_ehci_initialize(int controller) sem_init(&g_ehci.exclsem, 0, 1); sem_init(&g_ehci.pscsem, 0, 0); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&g_ehci.pscsem, SEM_PRIO_NONE); + /* Initialize EP0 */ sem_init(&g_ehci.ep0.iocsem, 0, 1); @@ -4783,7 +4796,13 @@ FAR struct usbhost_connection_s *lpc43_ehci_initialize(int controller) rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL; rhport->ep0.speed = USB_SPEED_FULL; rhport->ep0.maxpacket = 8; + + /* The EP0 iocsem semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + sem_init(&rhport->ep0.iocsem, 0, 0); + sem_setprotocol(&rhport->ep0.iocsem, SEM_PRIO_NONE); /* Initialize the public port representation */ diff --git a/arch/arm/src/sama5/sam_ehci.c b/arch/arm/src/sama5/sam_ehci.c index 78135e3e8d..6065a04d50 100644 --- a/arch/arm/src/sama5/sam_ehci.c +++ b/arch/arm/src/sama5/sam_ehci.c @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -3752,7 +3753,13 @@ static int sam_epalloc(FAR struct usbhost_driver_s *drvr, epinfo->maxpacket = epdesc->mxpacketsize; epinfo->xfrtype = epdesc->xfrtype; epinfo->speed = hport->speed; + + /* The endpoint iocsem semaphore is used for signaling and, hence, + * should not have priority inheritance enabled. + */ + sem_init(&epinfo->iocsem, 0, 0); + sem_setprotocol(&epinfo->iocsem, SEM_PRIO_NONE); /* Success.. return an opaque reference to the endpoint information structure * instance @@ -4787,6 +4794,12 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller) sem_init(&g_ehci.exclsem, 0, 1); sem_init(&g_ehci.pscsem, 0, 0); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&g_ehci.pscsem, SEM_PRIO_NONE); + /* Initialize EP0 */ sem_init(&g_ehci.ep0.iocsem, 0, 1); @@ -4823,7 +4836,13 @@ FAR struct usbhost_connection_s *sam_ehci_initialize(int controller) rhport->ep0.xfrtype = USB_EP_ATTR_XFER_CONTROL; rhport->ep0.speed = USB_SPEED_FULL; rhport->ep0.maxpacket = 8; + + /* The endpoint 0 iocsem semaphore is used for signaling and, hence, + * should not have priority inheritance enabled. + */ + sem_init(&rhport->ep0.iocsem, 0, 0); + sem_setprotocol(&rhport->ep0.iocsem, SEM_PRIO_NONE); /* Initialize the public port representation */ diff --git a/arch/arm/src/sama5/sam_ohci.c b/arch/arm/src/sama5/sam_ohci.c index 7d4533dca6..b4a6b03f92 100644 --- a/arch/arm/src/sama5/sam_ohci.c +++ b/arch/arm/src/sama5/sam_ohci.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/sama5/sam_ohci.c * - * Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2015-2016 Gregory Nutt. All rights reserved. * Authors: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -51,6 +51,7 @@ #include #include #include +#include #include #include #include @@ -2664,6 +2665,12 @@ static int sam_epalloc(struct usbhost_driver_s *drvr, sem_init(&eplist->wdhsem, 0, 0); + /* The wdhsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&eplist->wdhsem, SEM_PRIO_NONE); + /* We must have exclusive access to the ED pool, the bulk list, the periodic list * and the interrupt table. */ @@ -3903,6 +3910,12 @@ struct usbhost_connection_s *sam_ohci_initialize(int controller) sem_init(&g_ohci.pscsem, 0, 0); sem_init(&g_ohci.exclsem, 0, 1); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&g_ohci.pscsem, SEM_PRIO_NONE); + #ifndef CONFIG_USBHOST_INT_DISABLE g_ohci.ininterval = MAX_PERINTERVAL; g_ohci.outinterval = MAX_PERINTERVAL; diff --git a/arch/arm/src/stm32/stm32_otgfshost.c b/arch/arm/src/stm32/stm32_otgfshost.c index 9b3c48102d..3feb0924c0 100644 --- a/arch/arm/src/stm32/stm32_otgfshost.c +++ b/arch/arm/src/stm32/stm32_otgfshost.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -5091,6 +5092,12 @@ static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) sem_init(&priv->pscsem, 0, 0); sem_init(&priv->exclsem, 0, 1); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->pscsem, SEM_PRIO_NONE); + /* Initialize the driver state data */ priv->smstate = SMSTATE_DETACHED; @@ -5106,8 +5113,15 @@ static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) for (i = 0; i < STM32_MAX_TX_FIFOS; i++) { FAR struct stm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&chan->waitsem, 0, 0); + sem_setprotocol(&chan->waitsem, SEM_PRIO_NONE); } } diff --git a/arch/arm/src/stm32/stm32_otghshost.c b/arch/arm/src/stm32/stm32_otghshost.c index da0a114aa8..aec4fc37d5 100644 --- a/arch/arm/src/stm32/stm32_otghshost.c +++ b/arch/arm/src/stm32/stm32_otghshost.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -5091,6 +5092,12 @@ static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) sem_init(&priv->pscsem, 0, 0); sem_init(&priv->exclsem, 0, 1); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->pscsem, SEM_PRIO_NONE); + /* Initialize the driver state data */ priv->smstate = SMSTATE_DETACHED; @@ -5106,8 +5113,15 @@ static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) for (i = 0; i < STM32_MAX_TX_FIFOS; i++) { FAR struct stm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&chan->waitsem, 0, 0); + sem_setprotocol(&chan->waitsem, SEM_PRIO_NONE); } } diff --git a/arch/arm/src/stm32f7/stm32_otghost.c b/arch/arm/src/stm32f7/stm32_otghost.c index 37677a614d..12488c262f 100644 --- a/arch/arm/src/stm32f7/stm32_otghost.c +++ b/arch/arm/src/stm32f7/stm32_otghost.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -5089,6 +5090,12 @@ static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) sem_init(&priv->pscsem, 0, 0); sem_init(&priv->exclsem, 0, 1); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->pscsem, SEM_PRIO_NONE); + /* Initialize the driver state data */ priv->smstate = SMSTATE_DETACHED; @@ -5104,8 +5111,15 @@ static inline void stm32_sw_initialize(FAR struct stm32_usbhost_s *priv) for (i = 0; i < STM32_MAX_TX_FIFOS; i++) { FAR struct stm32_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&chan->waitsem, 0, 0); + sem_setprotocol(&chan->waitsem, SEM_PRIO_NONE); } } diff --git a/arch/arm/src/stm32l4/stm32l4_otgfshost.c b/arch/arm/src/stm32l4/stm32l4_otgfshost.c index 428a7f80cf..d47295f429 100644 --- a/arch/arm/src/stm32l4/stm32l4_otgfshost.c +++ b/arch/arm/src/stm32l4/stm32l4_otgfshost.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -5096,6 +5097,12 @@ static inline void stm32l4_sw_initialize(FAR struct stm32l4_usbhost_s *priv) sem_init(&priv->pscsem, 0, 0); sem_init(&priv->exclsem, 0, 1); + /* The pscsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->pscsem, SEM_PRIO_NONE); + /* Initialize the driver state data */ priv->smstate = SMSTATE_DETACHED; @@ -5111,8 +5118,15 @@ static inline void stm32l4_sw_initialize(FAR struct stm32l4_usbhost_s *priv) for (i = 0; i < STM32L4_MAX_TX_FIFOS; i++) { FAR struct stm32l4_chan_s *chan = &priv->chan[i]; + chan->chidx = i; + + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&chan->waitsem, 0, 0); + sem_setprotocol(&chan->waitsem, SEM_PRIO_NONE); } } From 77a0b6c26aa95cb89b7466b9fc534245bfbbf9b8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 17:12:49 -0600 Subject: [PATCH 060/155] graphics/, libnx/: Disable priority inheritance on all semaphores used for signaling --- graphics/nxterm/nxterm_register.c | 20 +++++++------------- libnx/nxmu/nx_bitmap.c | 28 ++++++++-------------------- libnx/nxmu/nx_getrectangle.c | 28 ++++++++-------------------- 3 files changed, 23 insertions(+), 53 deletions(-) diff --git a/graphics/nxterm/nxterm_register.c b/graphics/nxterm/nxterm_register.c index 41cd456789..d1d99d16a4 100644 --- a/graphics/nxterm/nxterm_register.c +++ b/graphics/nxterm/nxterm_register.c @@ -1,7 +1,7 @@ /**************************************************************************** * nuttx/graphics/nxterm/nxterm_register.c * - * Copyright (C) 2012 Gregory Nutt. All rights reserved. + * Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -48,22 +48,11 @@ #include #include +#include #include #include "nxterm.h" -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -104,7 +93,12 @@ FAR struct nxterm_state_s * #endif #ifdef CONFIG_NXTERM_NXKBDIN + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->waitsem, 0, 0); + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); #endif /* Select the font */ diff --git a/libnx/nxmu/nx_bitmap.c b/libnx/nxmu/nx_bitmap.c index 0d8ec93f40..9c69291572 100644 --- a/libnx/nxmu/nx_bitmap.c +++ b/libnx/nxmu/nx_bitmap.c @@ -1,7 +1,7 @@ /**************************************************************************** * libnx/nxmu/nx_bitmap.c * - * Copyright (C) 2008-2009, 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2008-2009, 2011-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -46,25 +46,7 @@ #include #include -/**************************************************************************** - * Pre-Processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ +#include /**************************************************************************** * Public Functions @@ -137,6 +119,12 @@ int nx_bitmap(NXWINDOW hwnd, FAR const struct nxgl_rect_s *dest, return ret; } + /* The sem_done semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + (void)sem_setprotocol(&sem_done, SEM_PRIO_NONE); + /* Forward the fill command to the server */ ret = nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_bitmap_s)); diff --git a/libnx/nxmu/nx_getrectangle.c b/libnx/nxmu/nx_getrectangle.c index 3bac5a3ae9..9420d02df5 100644 --- a/libnx/nxmu/nx_getrectangle.c +++ b/libnx/nxmu/nx_getrectangle.c @@ -1,7 +1,7 @@ /**************************************************************************** * libnx/nxmu/nx_getrectangle.c * - * Copyright (C) 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -47,25 +47,7 @@ #include #include -/**************************************************************************** - * Pre-Processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ +#include /**************************************************************************** * Public Functions @@ -131,6 +113,12 @@ int nx_getrectangle(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, return ret; } + /* The sem_done semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + (void)sem_setprotocol(&sem_done, SEM_PRIO_NONE); + /* Forward the fill command to the server */ ret = nxmu_sendwindow(wnd, &outmsg, sizeof(struct nxsvrmsg_getrectangle_s)); From d8fecba333d166b363184f1252b7dff286085493 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 17:19:51 -0600 Subject: [PATCH 061/155] arch: Disable priority inheritance on all semaphores used for signaling in all RNG drivers --- arch/arm/src/sama5/sam_trng.c | 10 ++++++++++ arch/arm/src/samv7/sam_trng.c | 10 ++++++++++ arch/arm/src/stm32l4/stm32l4_rng.c | 8 ++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/sama5/sam_trng.c b/arch/arm/src/sama5/sam_trng.c index 4c0f5ab1bc..c724612456 100644 --- a/arch/arm/src/sama5/sam_trng.c +++ b/arch/arm/src/sama5/sam_trng.c @@ -52,6 +52,7 @@ #include #include +#include #include #include @@ -352,9 +353,18 @@ static int sam_rng_initialize(void) /* Initialize the device structure */ memset(&g_trngdev, 0, sizeof(struct trng_dev_s)); + + /* Initialize semphores */ + sem_init(&g_trngdev.exclsem, 0, 1); sem_init(&g_trngdev.waitsem, 0, 0); + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&g_trngdev.waitsem, SEM_PRIO_NONE); + /* Enable clocking to the TRNG */ sam_trng_enableclk(); diff --git a/arch/arm/src/samv7/sam_trng.c b/arch/arm/src/samv7/sam_trng.c index d6cc16eb0b..6fee91e850 100644 --- a/arch/arm/src/samv7/sam_trng.c +++ b/arch/arm/src/samv7/sam_trng.c @@ -53,6 +53,7 @@ #include #include +#include #include #include @@ -353,9 +354,18 @@ static int sam_rng_initialize(void) /* Initialize the device structure */ memset(&g_trngdev, 0, sizeof(struct trng_dev_s)); + + /* Initialize semaphores */ + sem_init(&g_trngdev.exclsem, 0, 1); sem_init(&g_trngdev.waitsem, 0, 0); + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&g_trngdev.waitsem, SEM_PRIO_NONE); + /* Enable clocking to the TRNG */ sam_trng_enableclk(); diff --git a/arch/arm/src/stm32l4/stm32l4_rng.c b/arch/arm/src/stm32l4/stm32l4_rng.c index a544847061..abd2851037 100644 --- a/arch/arm/src/stm32l4/stm32l4_rng.c +++ b/arch/arm/src/stm32l4/stm32l4_rng.c @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -259,11 +260,14 @@ static ssize_t stm32l4_rngread(struct file *filep, char *buffer, size_t buflen) { /* We've got the device semaphore, proceed with reading */ - /* Initialize the operation semaphore with 0 for blocking until - * the buffer is filled from interrupts. + /* Initialize the operation semaphore with 0 for blocking until the + * buffer is filled from interrupts. The waitsem semaphore is used + * for signaling and, hence, should not have priority inheritance + * enabled. */ sem_init(&g_rngdev.rd_readsem, 0, 0); + sem_setprotocol(&g_rngdev.rd_readsem, SEM_PRIO_NONE); g_rngdev.rd_buflen = buflen; g_rngdev.rd_buf = buffer; From 0a5b4f684a86a7a4c50cc5f84b52c65e2d868cff Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 17:38:26 -0600 Subject: [PATCH 062/155] arch: Disable priority inheritance on all semaphores used for signaling in the rest of the MCU drivers --- arch/arm/src/calypso/calypso_keypad.c | 7 ++++++- arch/arm/src/sama5/sam_nand.c | 14 +++++++++++++- arch/arm/src/sama5/sam_tsd.c | 8 +++++++- arch/arm/src/stm32/stm32_1wire.c | 7 +++++++ arch/arm/src/stm32/stm32_dma2d.c | 9 +++++++-- arch/arm/src/stm32/stm32_ltdc.c | 9 +++++++-- arch/arm/src/tiva/tiva_ssi.c | 6 ++++++ arch/sim/src/up_touchscreen.c | 10 ++++++++++ arch/sim/src/up_uartwait.c | 7 +++++++ arch/xtensa/src/esp32/esp32_cpustart.c | 7 +++++++ 10 files changed, 77 insertions(+), 7 deletions(-) diff --git a/arch/arm/src/calypso/calypso_keypad.c b/arch/arm/src/calypso/calypso_keypad.c index 2430667ca5..1d9b11b98a 100644 --- a/arch/arm/src/calypso/calypso_keypad.c +++ b/arch/arm/src/calypso/calypso_keypad.c @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -360,9 +361,13 @@ int calypso_kbd_irq(int irq, uint32_t * regs) void up_keypad(void) { - /* Semaphore; helps leaving IRQ ctx as soon as possible */ + /* kbssem semaphore helps leaving IRQ ctx as soon as possible. This + * semaphore is used for signaling and, hence, should not have priority + * inheritance enabled. + */ sem_init(&kbdsem, 0, 0); + sem_setprotocol(&kbdsem, SEM_PRIO_NONE); /* Drive cols low in idle state such that all buttons cause events */ diff --git a/arch/arm/src/sama5/sam_nand.c b/arch/arm/src/sama5/sam_nand.c index 0e6757c073..1ac8e2a9ba 100644 --- a/arch/arm/src/sama5/sam_nand.c +++ b/arch/arm/src/sama5/sam_nand.c @@ -1,7 +1,7 @@ /**************************************************************************** * arch/arm/src/sama5/sam_nand.c * - * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2013, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * References: @@ -58,6 +58,7 @@ #include #include +#include #include #include #include @@ -2944,7 +2945,12 @@ struct mtd_dev_s *sam_nand_initialize(int cs) priv->cs = cs; #ifdef CONFIG_SAMA5_NAND_DMA + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->waitsem, 0, 0); + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); #endif /* Perform one-time, global NFC/PMECC initialization */ @@ -2956,8 +2962,14 @@ struct mtd_dev_s *sam_nand_initialize(int cs) #if NAND_NBANKS > 1 sem_init(&g_nand.exclsem, 0, 1); #endif + #ifdef CONFIG_SAMA5_NAND_HSMCINTERRUPTS + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&g_nand.waitsem, 0, 0); + sem_setprotocol(&g_nand.waitsem, SEM_PRIO_NONE); #endif /* Enable the NAND FLASH Controller (The NFC is always used) */ diff --git a/arch/arm/src/sama5/sam_tsd.c b/arch/arm/src/sama5/sam_tsd.c index edb2199f36..403aa93f75 100644 --- a/arch/arm/src/sama5/sam_tsd.c +++ b/arch/arm/src/sama5/sam_tsd.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -1669,7 +1670,12 @@ int sam_tsd_register(struct sam_adc_s *adc, int minor) priv->threshx = INVALID_THRESHOLD; /* Initialize thresholding logic */ priv->threshy = INVALID_THRESHOLD; /* Initialize thresholding logic */ - sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + /* Initialize pen event wait semaphore. This semaphore is used for + * signaling and, hence, should not have priority inheritance enabled. + */ + + sem_init(&priv->waitsem, 0, 0); + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); /* Register the device as an input device */ diff --git a/arch/arm/src/stm32/stm32_1wire.c b/arch/arm/src/stm32/stm32_1wire.c index 00f24fc019..952f2777ec 100644 --- a/arch/arm/src/stm32/stm32_1wire.c +++ b/arch/arm/src/stm32/stm32_1wire.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -744,6 +745,12 @@ static inline void stm32_1wire_sem_init(FAR struct stm32_1wire_priv_s *priv) { sem_init(&priv->sem_excl, 0, 1); sem_init(&priv->sem_isr, 0, 0); + + /* The sem_isr semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->sem_isr, SEM_PRIO_NONE); } /**************************************************************************** diff --git a/arch/arm/src/stm32/stm32_dma2d.c b/arch/arm/src/stm32/stm32_dma2d.c index db76245708..c4ef73fc2b 100644 --- a/arch/arm/src/stm32/stm32_dma2d.c +++ b/arch/arm/src/stm32/stm32_dma2d.c @@ -49,8 +49,9 @@ #include #include -#include #include +#include +#include #include #include @@ -2167,9 +2168,13 @@ int up_dma2dinitialize(void) sem_init(&g_lock, 0, 1); - /* Initialize the semaphore for interrupt handling */ + /* Initialize the semaphore for interrupt handling. This waitsem + * semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ sem_init(g_interrupt.sem, 0, 0); + sem_setprotocol(g_interrupt.sem, SEM_PRIO_NONE); #ifdef CONFIG_STM32_DMA2D_L8 /* Enable dma2d transfer and clut loading interrupts only */ diff --git a/arch/arm/src/stm32/stm32_ltdc.c b/arch/arm/src/stm32/stm32_ltdc.c index 442af257dd..ebaeff8d47 100644 --- a/arch/arm/src/stm32/stm32_ltdc.c +++ b/arch/arm/src/stm32/stm32_ltdc.c @@ -49,8 +49,9 @@ #include #include -#include #include +#include +#include #include #include @@ -1287,9 +1288,13 @@ static void stm32_global_configure(void) sem_init(&g_lock, 0, 1); - /* Initialize the semaphore for interrupt handling */ + /* Initialize the semaphore for interrupt handling. This waitsem + * semaphore is used for signaling and, hence, should not have priority + * inheritance enabled. + */ sem_init(g_interrupt.sem, 0, 0); + sem_setprotocol(g_interrupt.sem, SEM_PRIO_NONE); /* Attach LTDC interrupt vector */ diff --git a/arch/arm/src/tiva/tiva_ssi.c b/arch/arm/src/tiva/tiva_ssi.c index 882d6460df..6c2a92fbcc 100644 --- a/arch/arm/src/tiva/tiva_ssi.c +++ b/arch/arm/src/tiva/tiva_ssi.c @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -1635,7 +1636,12 @@ FAR struct spi_dev_s *tiva_ssibus_initialize(int port) /* Initialize the state structure */ #ifndef CONFIG_SSI_POLLWAIT + /* The xfrsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + sem_init(&priv->xfrsem, 0, 0); + sem_setprotocol(&priv->xfrsem, SEM_PRIO_NONE); #endif sem_init(&priv->exclsem, 0, 1); diff --git a/arch/sim/src/up_touchscreen.c b/arch/sim/src/up_touchscreen.c index a56870c850..4c327bb683 100644 --- a/arch/sim/src/up_touchscreen.c +++ b/arch/sim/src/up_touchscreen.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -657,9 +658,18 @@ int board_tsc_setup(int minor) /* Initialize the touchscreen device driver instance */ memset(priv, 0, sizeof(struct up_dev_s)); + + /* Initialize semaphores */ + sem_init(&priv->devsem, 0, 1); /* Initialize device structure semaphore */ sem_init(&priv->waitsem, 0, 0); /* Initialize pen event wait semaphore */ + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + sem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + priv->minor = minor; /* Register the device as an input device */ diff --git a/arch/sim/src/up_uartwait.c b/arch/sim/src/up_uartwait.c index 9f69717116..50f6b5f281 100644 --- a/arch/sim/src/up_uartwait.c +++ b/arch/sim/src/up_uartwait.c @@ -39,6 +39,8 @@ #include +#include + #include "up_internal.h" /**************************************************************************** @@ -57,7 +59,12 @@ static sem_t g_uartavail; void simuart_initialize(void) { + /* The g_uartavail semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&g_uartavail, 0, 0); + sem_setprotocol(&g_uartavail, SEM_PRIO_NONE); } /**************************************************************************** diff --git a/arch/xtensa/src/esp32/esp32_cpustart.c b/arch/xtensa/src/esp32/esp32_cpustart.c index 40f9882a5e..3a603579b6 100644 --- a/arch/xtensa/src/esp32/esp32_cpustart.c +++ b/arch/xtensa/src/esp32/esp32_cpustart.c @@ -46,6 +46,7 @@ #include #include +#include #include "sched/sched.h" #include "xtensa.h" @@ -259,7 +260,13 @@ int up_cpu_start(int cpu) /* Start CPU1 */ sinfo("Starting CPU%d\n", cpu); + + /* The waitsem semaphore is used for signaling and, hence, should not + * have priority inheritance enabled. + */ + sem_init(&g_appcpu_interlock, 0, 0); + sem_setprotocol(&g_appcpu_interlock, SEM_PRIO_NONE); regval = getreg32(DPORT_APPCPU_CTRL_B_REG); regval |= DPORT_APPCPU_CLKGATE_EN; From 5cfb83ec81cf87702b15a6b7e3561f2f83f7719b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 17:47:09 -0600 Subject: [PATCH 063/155] ESP32: File repeated in Make.defs --- arch/xtensa/src/esp32/Make.defs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/xtensa/src/esp32/Make.defs b/arch/xtensa/src/esp32/Make.defs index 0e13e3b1db..39a67813c6 100644 --- a/arch/xtensa/src/esp32/Make.defs +++ b/arch/xtensa/src/esp32/Make.defs @@ -84,7 +84,7 @@ endif CHIP_ASRCS = CHIP_CSRCS = esp32_allocateheap.c esp32_clockconfig.c esp32_cpuint.c CHIP_CSRCS += esp32_gpio.c esp32_intdecode.c esp32_irq.c esp32_region.c -CHIP_CSRCS += esp32_start.c esp32_timerisr.c +CHIP_CSRCS += esp32_timerisr.c # Configuration-dependent ESP32 files From 6ff6cca1a03ad2db924a5a9963412c07189cb096 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 17:48:36 -0600 Subject: [PATCH 064/155] Fix some mispellings of semaphore --- drivers/can.c | 2 +- net/icmp/icmp_ping.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/can.c b/drivers/can.c index e896d492f4..dd810ebcd1 100644 --- a/drivers/can.c +++ b/drivers/can.c @@ -1178,7 +1178,7 @@ int can_register(FAR const char *path, FAR struct can_dev_s *dev) for (i = 0; i < CONFIG_CAN_NPENDINGRTR; i++) { - /* Initialize wait semahores. These semaphores are used for signaling + /* Initialize wait semaphores. These semaphores are used for signaling * and should not have priority inheritance enabled. */ diff --git a/net/icmp/icmp_ping.c b/net/icmp/icmp_ping.c index 0c7f6e1627..96dd811cce 100644 --- a/net/icmp/icmp_ping.c +++ b/net/icmp/icmp_ping.c @@ -51,7 +51,7 @@ #include #include -#include +#include #include #include #include From 73fc186beb1ddec498c874da5f4da00ac6ff1cd4 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 18:51:38 -0600 Subject: [PATCH 065/155] sem_setprotocol: Handle a case of missing proxy for sem_setprotocol. Reorder so that (1) this error is avoided, and (2) >No proxy is needed if priority inheritance is not enabled. --- libc/semaphore/Make.defs | 4 ++ libc/semaphore/sem_setprotocol.c | 114 ++++++++++++++++++++++++++++++ sched/semaphore/Make.defs | 4 +- sched/semaphore/sem_setprotocol.c | 8 +-- syscall/syscall.csv | 2 +- 5 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 libc/semaphore/sem_setprotocol.c diff --git a/libc/semaphore/Make.defs b/libc/semaphore/Make.defs index cafa18b65a..6c91f068cd 100644 --- a/libc/semaphore/Make.defs +++ b/libc/semaphore/Make.defs @@ -37,6 +37,10 @@ CSRCS += sem_init.c sem_getprotocol.c sem_getvalue.c +ifneq ($(CONFIG_PRIORITY_INHERITANCE),y) +CSRCS += sem_setprotocol.c +endif + # Add the semaphore directory to the build DEPPATH += --dep-path semaphore diff --git a/libc/semaphore/sem_setprotocol.c b/libc/semaphore/sem_setprotocol.c new file mode 100644 index 0000000000..38336a31a0 --- /dev/null +++ b/libc/semaphore/sem_setprotocol.c @@ -0,0 +1,114 @@ +/**************************************************************************** + * libc/semaphore/sem_setprotocol.c + * + * Copyright (C) 2016 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 + +#ifndef CONFIG_PRIORITY_INHERITANCE + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: sem_setprotocol + * + * Description: + * Set semaphore protocol attribute. + * + * One particularly important use of this furnction is when a semaphore + * is used for inter-task communication like: + * + * TASK A TASK B + * sem_init(sem, 0, 0); + * sem_wait(sem); + * sem_post(sem); + * Awakens as holder + * + * In this case priority inheritance can interfere with the operation of + * the semaphore. The problem is that when TASK A is restarted it is a + * holder of the semaphore. However, it never calls sem_post(sem) so it + * becomes *permanently* a holder of the semaphore and may have its + * priority boosted when any other task tries to acquire the semaphore. + * + * The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after + * the sem_init() call so that there will be no priority inheritance + * operations on this semaphore. + * + * Parameters: + * sem - A pointer to the semaphore whose attributes are to be + * modified + * protocol - The new protocol to use + * + * Return Value: + * 0 if successful. Otherwise, -1 is returned and the errno value is set + * appropriately. + * + ****************************************************************************/ + +int sem_setprotocol(FAR sem_t *sem, int protocol) +{ + int errcode; + + DEBUGASSERT(sem != NULL); + + switch (protocol) + { + case SEM_PRIO_NONE: + return OK; + + case SEM_PRIO_INHERIT: + case SEM_PRIO_PROTECT: + errcode = ENOSYS; + break; + + default: + errcode = EINVAL; + break; + } + + set_errno(errcode); + return ERROR; +} + +#endif /* !CONFIG_PRIORITY_INHERITANCE */ diff --git a/sched/semaphore/Make.defs b/sched/semaphore/Make.defs index 93fd35a0d0..7eb1740424 100644 --- a/sched/semaphore/Make.defs +++ b/sched/semaphore/Make.defs @@ -37,10 +37,10 @@ CSRCS += sem_destroy.c sem_wait.c sem_trywait.c sem_tickwait.c CSRCS += sem_timedwait.c sem_timeout.c sem_post.c sem_recover.c -CSRCS += sem_reset.c sem_setprotocol.c sem_waitirq.c +CSRCS += sem_reset.c sem_waitirq.c ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -CSRCS += sem_initialize.c sem_holder.c +CSRCS += sem_initialize.c sem_holder.c sem_setprotocol.c endif ifeq ($(CONFIG_SPINLOCK),y) diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c index 6f4392bcce..89764f6ad7 100644 --- a/sched/semaphore/sem_setprotocol.c +++ b/sched/semaphore/sem_setprotocol.c @@ -46,6 +46,8 @@ #include "semaphore/semaphore.h" +#ifdef CONFIG_PRIORITY_INHERITANCE + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -95,7 +97,6 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) switch (protocol) { case SEM_PRIO_NONE: -#ifdef CONFIG_PRIORITY_INHERITANCE /* Disable priority inheritance */ sem->flags |= PRIOINHERIT_FLAGS_DISABLE; @@ -103,16 +104,13 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) /* Remove any current holders */ sem_destroyholder(sem); -#endif return OK; case SEM_PRIO_INHERIT: -#ifdef CONFIG_PRIORITY_INHERITANCE /* Enable priority inheritance (dangerous) */ sem->flags &= ~PRIOINHERIT_FLAGS_DISABLE; return OK; -#endif case SEM_PRIO_PROTECT: /* Not yet supported */ @@ -128,3 +126,5 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) set_errno(errcode); return ERROR; } + +endif /* CONFIG_PRIORITY_INHERITANCE */ diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 99071ea27d..8ecf52854f 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -118,7 +118,7 @@ "sem_destroy","semaphore.h","","int","FAR sem_t*" "sem_open","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","FAR sem_t*","FAR const char*","int","..." "sem_post","semaphore.h","","int","FAR sem_t*" -"sem_setprotocol","nuttx/semaphore.h","","int","FAR sem_t*","int" +"sem_setprotocol","nuttx/semaphore.h","defined(CONFIG_PRIORITY_INHERITANCE)","int","FAR sem_t*","int" "sem_timedwait","semaphore.h","","int","FAR sem_t*","FAR const struct timespec *" "sem_trywait","semaphore.h","","int","FAR sem_t*" "sem_unlink","semaphore.h","defined(CONFIG_FS_NAMED_SEMAPHORES)","int","FAR const char*" From b78ee72a0745f832c23f6c993c9a087b352b3d46 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 20:20:25 -0600 Subject: [PATCH 066/155] defconfgs: More fallout from name change of apps/examples/buttons to archbuttons. --- configs/hymini-stm32v/buttons/defconfig | 2 +- configs/stm3210e-eval/buttons/defconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/hymini-stm32v/buttons/defconfig b/configs/hymini-stm32v/buttons/defconfig index 39464dac3d..c314821a14 100644 --- a/configs/hymini-stm32v/buttons/defconfig +++ b/configs/hymini-stm32v/buttons/defconfig @@ -578,7 +578,7 @@ CONFIG_PREALLOC_TIMERS=4 # # CONFIG_INIT_NONE is not set CONFIG_INIT_ENTRYPOINT=y -CONFIG_USER_ENTRYPOINT="buttons_main" +CONFIG_USER_ENTRYPOINT="archbuttons_main" CONFIG_RR_INTERVAL=200 # CONFIG_SCHED_SPORADIC is not set CONFIG_TASK_NAME_SIZE=0 diff --git a/configs/stm3210e-eval/buttons/defconfig b/configs/stm3210e-eval/buttons/defconfig index 5cbbaebc25..202b99f6c8 100644 --- a/configs/stm3210e-eval/buttons/defconfig +++ b/configs/stm3210e-eval/buttons/defconfig @@ -596,7 +596,7 @@ CONFIG_PREALLOC_TIMERS=4 # CONFIG_INIT_NONE is not set CONFIG_INIT_ENTRYPOINT=y # CONFIG_INIT_FILEPATH is not set -CONFIG_USER_ENTRYPOINT="buttons_main" +CONFIG_USER_ENTRYPOINT="archbuttons_main" CONFIG_RR_INTERVAL=200 # CONFIG_SCHED_SPORADIC is not set CONFIG_TASK_NAME_SIZE=0 From 1d0d2fb8e1e06ad32b3ad0e35224edd450006694 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 21:08:17 -0600 Subject: [PATCH 067/155] Fix typo introduced with big set of sem_setprotocol() changes. --- arch/arm/src/lpc17xx/lpc17_usbhost.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/lpc17xx/lpc17_usbhost.c b/arch/arm/src/lpc17xx/lpc17_usbhost.c index 59268f94a5..e81f9f676e 100644 --- a/arch/arm/src/lpc17xx/lpc17_usbhost.c +++ b/arch/arm/src/lpc17xx/lpc17_usbhost.c @@ -2268,7 +2268,7 @@ static int lpc17_epalloc(struct usbhost_driver_s *drvr, */ sem_init(&ed->wdhsem, 0, 0); - sem_setprotocol(&priv->wdhsem, SEM_PRIO_NONE); + sem_setprotocol(&ed->wdhsem, SEM_PRIO_NONE); /* Link the common tail TD to the ED's TD list */ @@ -3308,7 +3308,9 @@ errout_with_sem: static int lpc17_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) { +#ifdef CONFIG_USBHOST_ASYNCH struct lpc17_usbhost_s *priv = (struct lpc17_usbhost_s *)drvr; +#endif struct lpc17_ed_s *ed = (struct lpc17_ed_s *)ep; struct lpc17_gtd_s *td; struct lpc17_gtd_s *next; @@ -3316,7 +3318,7 @@ static int lpc17_cancel(FAR struct usbhost_driver_s *drvr, usbhost_ep_t ep) uint32_t ctrl; irqstate_t flags; - DEBUGASSERT(priv != NULL && ed != NULL); + DEBUGASSERT(drvr != NULL && ed != NULL); /* These first steps must be atomic as possible */ From 4b0372e542e0288171d73623b4613cf4a42734fc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 3 Nov 2016 21:27:52 -0600 Subject: [PATCH 068/155] Missing # on endif --- sched/semaphore/sem_setprotocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sched/semaphore/sem_setprotocol.c b/sched/semaphore/sem_setprotocol.c index 89764f6ad7..1350206941 100644 --- a/sched/semaphore/sem_setprotocol.c +++ b/sched/semaphore/sem_setprotocol.c @@ -127,4 +127,4 @@ int sem_setprotocol(FAR sem_t *sem, int protocol) return ERROR; } -endif /* CONFIG_PRIORITY_INHERITANCE */ +#endif /* CONFIG_PRIORITY_INHERITANCE */ From 8bd8ab1a45238c46a6b7d69a1f4d12d2cc9ce80a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 06:59:28 -0600 Subject: [PATCH 069/155] configs/nucleo_f303re: Various fixes to get the adc configuration building again after PR. Refresh all configurations. --- arch/arm/src/stm32/stm32_adc.c | 2 +- configs/nucleo-f303re/adc/defconfig | 22 ++++++++++++++-- configs/nucleo-f303re/can/defconfig | 20 +++++++++++++- configs/nucleo-f303re/hello/defconfig | 2 ++ configs/nucleo-f303re/nxlines/defconfig | 25 +++++++++++++++--- configs/nucleo-f303re/pwm/defconfig | 22 +++++++++++++++- configs/nucleo-f303re/src/stm32_adc.c | 26 ++++++++++--------- .../nucleo-f303re/src/stm32_appinitialize.c | 17 ++++++++++-- configs/nucleo-f303re/uavcan/defconfig | 20 +++++++++++++- 9 files changed, 132 insertions(+), 24 deletions(-) diff --git a/arch/arm/src/stm32/stm32_adc.c b/arch/arm/src/stm32/stm32_adc.c index 83939499c8..5ede920b24 100644 --- a/arch/arm/src/stm32/stm32_adc.c +++ b/arch/arm/src/stm32/stm32_adc.c @@ -226,7 +226,7 @@ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP8_SHIFT) | \ (ADC_SMPR_DEFAULT << ADC_SMPR2_SMP9_SHIFT)) #elif defined(CONFIG_STM32_STM32F30XX) -# ifdef ADC_HAVE_DMA || (ADC_MAX_SAMPLES == 1) +# if defined(ADC_HAVE_DMA) || (ADC_MAX_SAMPLES == 1) # define ADC_SMPR_DEFAULT ADC_SMPR_61p5 # else /* Slow down sampling frequency */ # define ADC_SMPR_DEFAULT ADC_SMPR_601p5 diff --git a/configs/nucleo-f303re/adc/defconfig b/configs/nucleo-f303re/adc/defconfig index 630f5b8918..4b67445407 100644 --- a/configs/nucleo-f303re/adc/defconfig +++ b/configs/nucleo-f303re/adc/defconfig @@ -63,8 +63,10 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -349,6 +351,12 @@ CONFIG_STM32_HAVE_ADC1_DMA=y # CONFIG_STM32_HAVE_ADC2_DMA is not set # CONFIG_STM32_HAVE_ADC3_DMA is not set # CONFIG_STM32_HAVE_ADC4_DMA is not set +# CONFIG_STM32_HAVE_SDADC1 is not set +# CONFIG_STM32_HAVE_SDADC2 is not set +# CONFIG_STM32_HAVE_SDADC3 is not set +# CONFIG_STM32_HAVE_SDADC1_DMA is not set +# CONFIG_STM32_HAVE_SDADC2_DMA is not set +# CONFIG_STM32_HAVE_SDADC3_DMA is not set CONFIG_STM32_HAVE_CAN1=y # CONFIG_STM32_HAVE_CAN2 is not set CONFIG_STM32_HAVE_DAC1=y @@ -432,7 +440,7 @@ CONFIG_STM32_CCMEXCLUDE=y # # ADC Configuration # -CONFIG_STM32_ADC1_DMA=y +# CONFIG_STM32_ADC1_DMA is not set # CONFIG_STM32_HAVE_RTC_COUNTER is not set # CONFIG_STM32_HAVE_RTC_SUBSECONDS is not set @@ -667,6 +675,8 @@ CONFIG_DEV_NULL=y CONFIG_ARCH_HAVE_I2CRESET=y # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_I2S is not set @@ -674,6 +684,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set CONFIG_ANALOG=y @@ -722,6 +733,7 @@ CONFIG_ADC_FIFOSIZE=8 # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -820,6 +832,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -870,7 +884,9 @@ CONFIG_EXAMPLES_ADC_DEVPATH="/dev/adc0" CONFIG_EXAMPLES_ADC_NSAMPLES=0 CONFIG_EXAMPLES_ADC_GROUPSIZE=4 CONFIG_EXAMPLES_ADC_SWTRIG=y +# CONFIG_EXAMPLES_ARCHBUTTONS is not set # CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set @@ -889,10 +905,10 @@ CONFIG_EXAMPLES_ADC_SWTRIG=y # CONFIG_EXAMPLES_NRF24L01TERM is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set @@ -940,6 +956,7 @@ CONFIG_EXAMPLES_ADC_SWTRIG=y # # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -983,6 +1000,7 @@ CONFIG_EXAMPLES_ADC_SWTRIG=y # CONFIG_READLINE_HAVE_EXTMATCH is not set # CONFIG_SYSTEM_READLINE is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/nucleo-f303re/can/defconfig b/configs/nucleo-f303re/can/defconfig index 47529ba808..3450575cbf 100644 --- a/configs/nucleo-f303re/can/defconfig +++ b/configs/nucleo-f303re/can/defconfig @@ -63,8 +63,10 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -354,6 +356,12 @@ CONFIG_STM32_HAVE_ADC4=y # CONFIG_STM32_HAVE_ADC2_DMA is not set # CONFIG_STM32_HAVE_ADC3_DMA is not set # CONFIG_STM32_HAVE_ADC4_DMA is not set +# CONFIG_STM32_HAVE_SDADC1 is not set +# CONFIG_STM32_HAVE_SDADC2 is not set +# CONFIG_STM32_HAVE_SDADC3 is not set +# CONFIG_STM32_HAVE_SDADC1_DMA is not set +# CONFIG_STM32_HAVE_SDADC2_DMA is not set +# CONFIG_STM32_HAVE_SDADC3_DMA is not set CONFIG_STM32_HAVE_CAN1=y # CONFIG_STM32_HAVE_CAN2 is not set CONFIG_STM32_HAVE_DAC1=y @@ -676,6 +684,8 @@ CONFIG_CAN_NPENDINGRTR=4 CONFIG_ARCH_HAVE_I2CRESET=y # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_I2S is not set @@ -683,6 +693,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set @@ -724,6 +735,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -822,6 +834,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -868,12 +882,14 @@ CONFIG_ARCH_HAVE_TLS=y # # Examples # +# CONFIG_EXAMPLES_ARCHBUTTONS is not set # CONFIG_EXAMPLES_BUTTONS is not set CONFIG_EXAMPLES_CAN=y CONFIG_EXAMPLES_CAN_DEVPATH="/dev/can0" # CONFIG_EXAMPLES_CAN_READ is not set # CONFIG_EXAMPLES_CAN_WRITE is not set CONFIG_EXAMPLES_CAN_READWRITE=y +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set @@ -892,10 +908,10 @@ CONFIG_EXAMPLES_CAN_READWRITE=y # CONFIG_EXAMPLES_NRF24L01TERM is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set @@ -943,6 +959,7 @@ CONFIG_EXAMPLES_CAN_READWRITE=y # # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -986,6 +1003,7 @@ CONFIG_EXAMPLES_CAN_READWRITE=y # CONFIG_READLINE_HAVE_EXTMATCH is not set # CONFIG_SYSTEM_READLINE is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/nucleo-f303re/hello/defconfig b/configs/nucleo-f303re/hello/defconfig index b35c6c70d2..9c434786e3 100644 --- a/configs/nucleo-f303re/hello/defconfig +++ b/configs/nucleo-f303re/hello/defconfig @@ -683,6 +683,8 @@ CONFIG_DEV_NULL=y CONFIG_ARCH_HAVE_I2CRESET=y # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_I2S is not set diff --git a/configs/nucleo-f303re/nxlines/defconfig b/configs/nucleo-f303re/nxlines/defconfig index c77961855f..6eb9debcdb 100644 --- a/configs/nucleo-f303re/nxlines/defconfig +++ b/configs/nucleo-f303re/nxlines/defconfig @@ -63,8 +63,10 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -351,6 +353,12 @@ CONFIG_STM32_HAVE_ADC4=y # CONFIG_STM32_HAVE_ADC2_DMA is not set # CONFIG_STM32_HAVE_ADC3_DMA is not set # CONFIG_STM32_HAVE_ADC4_DMA is not set +# CONFIG_STM32_HAVE_SDADC1 is not set +# CONFIG_STM32_HAVE_SDADC2 is not set +# CONFIG_STM32_HAVE_SDADC3 is not set +# CONFIG_STM32_HAVE_SDADC1_DMA is not set +# CONFIG_STM32_HAVE_SDADC2_DMA is not set +# CONFIG_STM32_HAVE_SDADC3_DMA is not set CONFIG_STM32_HAVE_CAN1=y # CONFIG_STM32_HAVE_CAN2 is not set CONFIG_STM32_HAVE_DAC1=y @@ -675,14 +683,14 @@ CONFIG_CAN_NPENDINGRTR=4 CONFIG_ARCH_HAVE_I2CRESET=y # CONFIG_I2C is not set CONFIG_SPI=y +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_SPI_SLAVE is not set CONFIG_SPI_EXCHANGE=y CONFIG_SPI_CMDDATA=y # CONFIG_SPI_CALLBACK is not set # CONFIG_SPI_HWFEATURES is not set -# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set -# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set -CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_SPI_BITORDER is not set # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_SPI_DRIVER is not set @@ -693,6 +701,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set @@ -728,6 +737,7 @@ CONFIG_LCD_MAXPOWER=1 # CONFIG_LCD_MIO283QT2 is not set # CONFIG_LCD_MIO283QT9A is not set # CONFIG_LCD_UG9664HSWAG01 is not set +# CONFIG_LCD_SH1106_OLED_132 is not set # CONFIG_LCD_UG2864HSWEG01 is not set # CONFIG_LCD_UG2832HSWEG04 is not set CONFIG_LCD_SSD1351=y @@ -789,6 +799,7 @@ CONFIG_LCD_LANDSCAPE=y # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -977,6 +988,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -1023,8 +1036,10 @@ CONFIG_ARCH_HAVE_TLS=y # # Examples # +# CONFIG_EXAMPLES_ARCHBUTTONS is not set # CONFIG_EXAMPLES_BUTTONS is not set # CONFIG_EXAMPLES_CAN is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set @@ -1044,10 +1059,10 @@ CONFIG_ARCH_HAVE_TLS=y # CONFIG_EXAMPLES_NRF24L01TERM is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set CONFIG_EXAMPLES_NXLINES=y CONFIG_EXAMPLES_NXLINES_VPLANE=0 CONFIG_EXAMPLES_NXLINES_DEVNO=0 @@ -1102,6 +1117,7 @@ CONFIG_EXAMPLES_NXLINES_EXTERNINIT=y # # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -1145,6 +1161,7 @@ CONFIG_EXAMPLES_NXLINES_EXTERNINIT=y # CONFIG_READLINE_HAVE_EXTMATCH is not set # CONFIG_SYSTEM_READLINE is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/nucleo-f303re/pwm/defconfig b/configs/nucleo-f303re/pwm/defconfig index c0b27a94ee..0e54eba6eb 100644 --- a/configs/nucleo-f303re/pwm/defconfig +++ b/configs/nucleo-f303re/pwm/defconfig @@ -63,8 +63,10 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -349,6 +351,12 @@ CONFIG_STM32_HAVE_ADC4=y # CONFIG_STM32_HAVE_ADC2_DMA is not set # CONFIG_STM32_HAVE_ADC3_DMA is not set # CONFIG_STM32_HAVE_ADC4_DMA is not set +# CONFIG_STM32_HAVE_SDADC1 is not set +# CONFIG_STM32_HAVE_SDADC2 is not set +# CONFIG_STM32_HAVE_SDADC3 is not set +# CONFIG_STM32_HAVE_SDADC1_DMA is not set +# CONFIG_STM32_HAVE_SDADC2_DMA is not set +# CONFIG_STM32_HAVE_SDADC3_DMA is not set CONFIG_STM32_HAVE_CAN1=y # CONFIG_STM32_HAVE_CAN2 is not set CONFIG_STM32_HAVE_DAC1=y @@ -674,6 +682,8 @@ CONFIG_PWM_NCHANNELS=2 CONFIG_ARCH_HAVE_I2CRESET=y # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_I2S is not set @@ -681,6 +691,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set @@ -722,6 +733,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -825,6 +837,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -875,7 +889,9 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # # Examples # +# CONFIG_EXAMPLES_ARCHBUTTONS is not set # CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set @@ -894,10 +910,10 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # CONFIG_EXAMPLES_NRF24L01TERM is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set @@ -954,6 +970,7 @@ CONFIG_EXAMPLES_PWM_CHANNEL2=2 # # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -1024,6 +1041,7 @@ CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set # CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y # CONFIG_NSH_DISABLE_PS is not set # CONFIG_NSH_DISABLE_PUT is not set # CONFIG_NSH_DISABLE_PWD is not set @@ -1089,6 +1107,8 @@ CONFIG_SYSTEM_CLE_DEBUGLEVEL=0 CONFIG_READLINE_HAVE_EXTMATCH=y # CONFIG_SYSTEM_READLINE is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_SYSTEM is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/nucleo-f303re/src/stm32_adc.c b/configs/nucleo-f303re/src/stm32_adc.c index 2c2e0bed28..10183458ec 100644 --- a/configs/nucleo-f303re/src/stm32_adc.c +++ b/configs/nucleo-f303re/src/stm32_adc.c @@ -58,13 +58,23 @@ * Pre-processor Definitions ****************************************************************************/ +/* Configuration ************************************************************/ + +#if defined(ADC1_HAVE_DMA) && defined(CONFIG_STM32_ADC1) +# warning "ADC1 with DMA support is not fully implemented" +# undef CONFIG_STM32_ADC1 +#endif + +#if defined(ADC2_HAVE_DMA) && defined(CONFIG_STM32_ADC2) +# warning "ADC2 with DMA support is not fully implemented" +# undef CONFIG_STM32_ADC2 +#endif + #if (defined(CONFIG_STM32_ADC1) && defined(CONFIG_STM32_ADC2)) || \ (defined(CONFIG_STM32_ADC3) && defined(CONFIG_STM32_ADC4)) # error "will not work with this combination of ADCs" #endif -/* Configuration ************************************************************/ - /* 1 or 2 ADC devices (DEV1, DEV2) */ #if defined(CONFIG_STM32_ADC1) @@ -106,16 +116,8 @@ /* The number of ADC channels in the conversion list */ /* TODO DMA */ -#if defined(ADC1_HAVE_DMA) -# error "ADC1 with DMA support is not fully implemented" -#else -# define ADC1_NCHANNELS 4 -#endif -#if defined(ADC2_HAVE_DMA) -# error "ADC2 with DMA support is not fully implemented" -#else -# define ADC2_NCHANNELS 3 -#endif +#define ADC1_NCHANNELS 4 +#define ADC2_NCHANNELS 3 #define ADC3_NCHANNELS 3 #define ADC4_NCHANNELS 1 diff --git a/configs/nucleo-f303re/src/stm32_appinitialize.c b/configs/nucleo-f303re/src/stm32_appinitialize.c index 3ce7e293bd..7157606edb 100644 --- a/configs/nucleo-f303re/src/stm32_appinitialize.c +++ b/configs/nucleo-f303re/src/stm32_appinitialize.c @@ -53,6 +53,17 @@ * Pre-processor Definitions ****************************************************************************/ +#undef HAVE_LEDS +#undef HAVE_DAC + +#if !defined(CONFIG_ARCH_LEDS) && defined(CONFIG_USERLED_LOWER) +# define HAVE_LEDS 1 +#endif + +#if defined(CONFIG_DAC) +# define HAVE_DAC 1 +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -84,9 +95,11 @@ int board_app_initialize(uintptr_t arg) { +#if defined(HAVE_LEDS) || defined(HAVE_DAC) int ret; +#endif -#if !defined(CONFIG_ARCH_LEDS) && defined(CONFIG_USERLED_LOWER) +#ifdef HAVE_LEDS /* Register the LED driver */ ret = userled_lower_initialize(LED_DRIVER_PATH); @@ -101,7 +114,7 @@ int board_app_initialize(uintptr_t arg) * faut le faire ici */ -#if defined(CONFIG_DAC) +#ifdef HAVE_DAC ret = board_dac_setup(); if (ret < 0) { diff --git a/configs/nucleo-f303re/uavcan/defconfig b/configs/nucleo-f303re/uavcan/defconfig index 836893eafc..944984f2d5 100644 --- a/configs/nucleo-f303re/uavcan/defconfig +++ b/configs/nucleo-f303re/uavcan/defconfig @@ -63,8 +63,10 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -349,6 +351,12 @@ CONFIG_STM32_HAVE_ADC4=y # CONFIG_STM32_HAVE_ADC2_DMA is not set # CONFIG_STM32_HAVE_ADC3_DMA is not set # CONFIG_STM32_HAVE_ADC4_DMA is not set +# CONFIG_STM32_HAVE_SDADC1 is not set +# CONFIG_STM32_HAVE_SDADC2 is not set +# CONFIG_STM32_HAVE_SDADC3 is not set +# CONFIG_STM32_HAVE_SDADC1_DMA is not set +# CONFIG_STM32_HAVE_SDADC2_DMA is not set +# CONFIG_STM32_HAVE_SDADC3_DMA is not set CONFIG_STM32_HAVE_CAN1=y # CONFIG_STM32_HAVE_CAN2 is not set CONFIG_STM32_HAVE_DAC1=y @@ -653,6 +661,8 @@ CONFIG_DEV_NULL=y CONFIG_ARCH_HAVE_I2CRESET=y # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_I2S is not set @@ -660,6 +670,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set @@ -701,6 +712,7 @@ CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -799,6 +811,8 @@ CONFIG_LIBM=y # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -881,7 +895,9 @@ CONFIG_LIBUAVCAN_INIT_RETRIES=0 # # Examples # +# CONFIG_EXAMPLES_ARCHBUTTONS is not set # CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_CXXTEST is not set @@ -902,10 +918,10 @@ CONFIG_LIBUAVCAN_INIT_RETRIES=0 # CONFIG_EXAMPLES_NRF24L01TERM is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set @@ -956,6 +972,7 @@ CONFIG_EXAMPLES_UAVCAN_NODE_NAME="org.nuttx.apps.examples.uavcan" # # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -1000,6 +1017,7 @@ CONFIG_EXAMPLES_UAVCAN_NODE_NAME="org.nuttx.apps.examples.uavcan" # CONFIG_READLINE_HAVE_EXTMATCH is not set # CONFIG_SYSTEM_READLINE is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set From e6435c28d0f866f8f348e4e4015ed5e2e802323b Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 09:58:27 -0600 Subject: [PATCH 070/155] Fix some name errors in port: RISC-V -> LM32 --- arch/misoc/include/lm32/syscall.h | 4 ++-- arch/misoc/include/syscall.h | 2 +- arch/misoc/src/lm32/lm32.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/misoc/include/lm32/syscall.h b/arch/misoc/include/lm32/syscall.h index 9e4b0d9ee0..d0816c7a21 100644 --- a/arch/misoc/include/lm32/syscall.h +++ b/arch/misoc/include/lm32/syscall.h @@ -58,8 +58,8 @@ #define SYS_syscall 0x00 /* Configuration ********************************************************************/ -/* SYS call 1 and 2 are defined for internal use by the RISC-V port (see - * arch/riscv/include/mips32/syscall.h). In addition, SYS call 3 is the return from +/* SYS call 1 and 2 are defined for internal use by the LM32 port (see + * arch/miscoc/include/lm32/syscall.h). In addition, SYS call 3 is the return from * a SYS call in kernel mode. The first four syscall values must, therefore, be * reserved (0 is not used). */ diff --git a/arch/misoc/include/syscall.h b/arch/misoc/include/syscall.h index 3a8f2e9df0..71b9e85a6c 100644 --- a/arch/misoc/include/syscall.h +++ b/arch/misoc/include/syscall.h @@ -44,7 +44,7 @@ * Included Files ****************************************************************************/ -/* Include RISC-V architecture-specific syscall macros */ +/* Include LM32 architecture-specific syscall macros */ #ifdef CONFIG_ARCH_MISOC # include diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index 8098da7492..280c2ff17f 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -61,7 +61,7 @@ #define INTSTACK_COLOR 0xdeadbeef #define HEAP_COLOR 'h' -/* In the RISC_V model, the state is copied from the stack to the TCB, but +/* In the LM32 model, the state is copied from the stack to the TCB, but * only a referenced is passed to get the state from the TCB. */ From 8f3c59b0d60dc37c6edf6c26ed929c0ddff37fcc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 10:21:55 -0600 Subject: [PATCH 071/155] LM32: Rename up_doirq() to lm32_doirq() --- arch/misoc/src/lm32/lm32_doirq.c | 2 +- arch/misoc/src/lm32/lm32_vectors.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c index 50b2e745fc..50a001ea69 100644 --- a/arch/misoc/src/lm32/lm32_doirq.c +++ b/arch/misoc/src/lm32/lm32_doirq.c @@ -71,7 +71,7 @@ * Public Functions ****************************************************************************/ -uint32_t *up_doirq(int irq, uint32_t *regs) +uint32_t *lm32_doirq(int irq, uint32_t *regs) { board_autoled_on(LED_INIRQ); #ifdef CONFIG_SUPPRESS_INTERRUPTS diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index a5ca7a550d..70187767dd 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -112,7 +112,7 @@ _interrupt_handler: sw (sp+0), ra calli .save_all rcsr r1, IP - calli up_doirq + calli lm32_doirq bi .restore_all_and_eret nop nop From 145ee2e6f157245c3311213d8f6eaa1124a3cde5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 10:39:57 -0600 Subject: [PATCH 072/155] LM32: Add prototype for lm32_decodeirq(). --- arch/misoc/src/lm32/Make.defs | 11 ++-- arch/misoc/src/lm32/lm32_decodeirq.c | 92 ++++++++++++++++++++++++++++ arch/misoc/src/lm32/lm32_vectors.S | 2 +- 3 files changed, 99 insertions(+), 6 deletions(-) create mode 100644 arch/misoc/src/lm32/lm32_decodeirq.c diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index 8338154388..cc4b72da66 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -42,8 +42,9 @@ CMN_CSRCS = misoc_uart.c CHIP_ASRCS = lm32_syscall.S CHIP_CSRCS = lm32_allocateheap.c lm32_assert.c lm32_blocktask.c -CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_doirq.c lm32_dumpstate.c -CHIP_CSRCS += lm32_dumpstate.c lm32_exit.c lm32_idle.c lm32_initialize.c -CHIP_CSRCS += lm32_initialstate.c lm32_interruptcontext.c lm32_irq.c -CHIP_CSRCS += lm32_releasepending.c lm32_releasestack.c -CHIP_CSRCS += lm32_stackframe.c lm32_swint.c lm32_unblocktask.c +CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_decodeirq.c +CHIP_CSRCS += lm32_doirq.c lm32_dumpstate.c lm32_dumpstate.c lm32_exit.c +CHIP_CSRCS += lm32_idle.c lm32_initialize.c lm32_initialstate.c +CHIP_CSRCS += lm32_interruptcontext.c lm32_irq.c lm32_releasepending.c +CHIP_CSRCS += lm32_releasestack.c lm32_stackframe.c lm32_swint.c +CHIP_CSRCS += lm32_unblocktask.c diff --git a/arch/misoc/src/lm32/lm32_decodeirq.c b/arch/misoc/src/lm32/lm32_decodeirq.c new file mode 100644 index 0000000000..a532331ca3 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_decodeirq.c @@ -0,0 +1,92 @@ +/******************************************************************************** + * arch/misoc/src/lm32/lm32_decodeirq.c + * + * Copyright (C) 2016 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 "chip.h" +#include "lm32.h" + +/******************************************************************************** + * Public Functions + ********************************************************************************/ + +/**************************************************************************** + * Name: lm32_decodeirq + * + * Description: + * This function is called from the IRQ vector handler in lm32_vectors.S. + * At this point, the interrupt has been taken and the registers have + * been saved on the stack. This function simply needs to determine the + * the irq number of the interrupt and then to call lm32_doirq to dispatch + * the interrupt. + * + * Input parameters: + * regs - A pointer to the register save area on the stack. + * + ****************************************************************************/ + +uint32_t *lm32_decodeirq(uint32_t *regs) +{ + uint32_t im; + int irq; + + /* Read the interrupt acknowledge register and get the interrupt ID */ + + im = getreg32(GIC_ICCIAR); + irq = (im & GIC_ICCIAR_INTID_MASK) >> GIC_ICCIAR_INTID_SHIFT; + + irqinfo("irq=%d\n", irq); + + /* Ignore spurions IRQs. ICCIAR will report 1023 if there is no pending + * interrupt. + */ + + DEBUGASSERT(irq < NR_IRQS || irq == 1023); + if (irq < NR_IRQS) + { + /* Dispatch the interrupt */ + + regs = lm32_doirq(irq, regs); + } + + /* Write to the end-of-interrupt register */ + + putreg32(im, GIC_ICCEOIR); + return regs; +} diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index 70187767dd..f672fa7fda 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -112,7 +112,7 @@ _interrupt_handler: sw (sp+0), ra calli .save_all rcsr r1, IP - calli lm32_doirq + calli lm32_decodeirq bi .restore_all_and_eret nop nop From ddd871618937104d069fac7687036e3a3171c3c7 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 10:42:05 -0600 Subject: [PATCH 073/155] LM32: Ooops.. last version still in editor --- arch/misoc/src/lm32/lm32_decodeirq.c | 45 +++++++++++++++++++--------- arch/misoc/src/lm32/lm32_doirq.c | 16 ---------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_decodeirq.c b/arch/misoc/src/lm32/lm32_decodeirq.c index a532331ca3..bdf0abe240 100644 --- a/arch/misoc/src/lm32/lm32_decodeirq.c +++ b/arch/misoc/src/lm32/lm32_decodeirq.c @@ -63,30 +63,47 @@ uint32_t *lm32_decodeirq(uint32_t *regs) { - uint32_t im; + uint32_t intstat; int irq; - /* Read the interrupt acknowledge register and get the interrupt ID */ + /* Read the pending interrupts */ + /* REVISIT: How do I get the interupt status */ +#warning Missing logic + intstat = 0; - im = getreg32(GIC_ICCIAR); - irq = (im & GIC_ICCIAR_INTID_MASK) >> GIC_ICCIAR_INTID_SHIFT; + /* REVIST: Do I need to mask the interrupt status with the IM? */ - irqinfo("irq=%d\n", irq); + irqinfo("intstat=%08lx\n", (unsigned long)intstat); - /* Ignore spurions IRQs. ICCIAR will report 1023 if there is no pending - * interrupt. - */ + /* Decode and dispatch interrupts */ - DEBUGASSERT(irq < NR_IRQS || irq == 1023); - if (irq < NR_IRQS) + for (irq = 0; irq < NR_IRQS & instat != 0; i++) { - /* Dispatch the interrupt */ + uint32_t bit = (1 << irq); - regs = lm32_doirq(irq, regs); + /* Is this interrupt pending? */ + + if ((instat & bit) != 0) + { + /* Yes.. Dispatch the interrupt */ + /* REVIST: Do I need to acknowledge the interrupt first? */ + + irqinfo("irq=%d\n", irq); + regs = lm32_doirq(irq, regs); + + /* Clear the bit in the interrupt status copy so that maybe we can + * break out of the loop early. + */ + + instat &= ~bit; + } } - /* Write to the end-of-interrupt register */ + /* Return the final task register save area. This will typically be the + * same as the value of regs on input. In the event of a context switch, + * however, it will differ. It will refere to the register save are in the + * TCB of the new thread. + */ - putreg32(im, GIC_ICCEOIR); return regs; } diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c index 50a001ea69..6d44eeb95c 100644 --- a/arch/misoc/src/lm32/lm32_doirq.c +++ b/arch/misoc/src/lm32/lm32_doirq.c @@ -51,22 +51,6 @@ #include "group/group.h" #include "lm32.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ From b2126738cd2091cf5e079b1f08a8f7ec39720b55 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Fri, 4 Nov 2016 10:54:10 -0600 Subject: [PATCH 074/155] LM32: Fix implementation of up_irq_save() and up_irq_restore() --- arch/misoc/include/lm32/irq.h | 7 +++- arch/misoc/src/lm32/lm32_doirq.c | 4 +- arch/misoc/src/lm32/lm32_initialstate.c | 4 ++ arch/misoc/src/lm32/lm32_irq.c | 32 +++++++++++---- arch/misoc/src/lm32/lm32_swint.c | 1 + arch/misoc/src/lm32/lm32_vectors.S | 13 ++++-- configs/misoc/hello/defconfig | 53 +++++++++++++++++++++---- 7 files changed, 90 insertions(+), 24 deletions(-) diff --git a/arch/misoc/include/lm32/irq.h b/arch/misoc/include/lm32/irq.h index e73d3815d5..782bb06ae9 100644 --- a/arch/misoc/include/lm32/irq.h +++ b/arch/misoc/include/lm32/irq.h @@ -82,10 +82,11 @@ #define REG_X29_NDX 29 /* General-purpose/return address */ #define REG_X30_NDX 30 /* Exception address */ #define REG_X31_NDX 31 /* Breakpoint address */ +#define REG_X32_NDX 32 /* Reg IE */ /* Interrupt Context register */ -#define XCPTCONTEXT_REGS 32 +#define XCPTCONTEXT_REGS 33 #define XCPTCONTEXT_SIZE (4 * XCPTCONTEXT_REGS) #ifdef __ASSEMBLY__ @@ -121,6 +122,7 @@ # define REG_X29 (4*REG_X29_NDX) # define REG_X30 (4*REG_X30_NDX) # define REG_X31 (4*REG_X31_NDX) +# define REG_INT_CTX (4*REG_X32_NDX) #else # define REG_X0 REG_X0_NDX # define REG_X1 REG_X1_NDX @@ -154,6 +156,7 @@ # define REG_X29 REG_X29_NDX # define REG_X30 REG_X30_NDX # define REG_X31 REG_X31_NDX +# define REG_INT_CTX REG_X32_NDX #endif /* Register aliases */ @@ -176,6 +179,8 @@ #define REG_A6 REG_X7 #define REG_A7 REG_X8 +#define REG_IE REG_INT_CTX + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c index 6d44eeb95c..e318a65adf 100644 --- a/arch/misoc/src/lm32/lm32_doirq.c +++ b/arch/misoc/src/lm32/lm32_doirq.c @@ -58,9 +58,7 @@ uint32_t *lm32_doirq(int irq, uint32_t *regs) { board_autoled_on(LED_INIRQ); -#ifdef CONFIG_SUPPRESS_INTERRUPTS - PANIC(); -#else + /* Current regs non-zero indicates that we are processing an interrupt; * g_current_regs is also used to manage interrupt level context switches. * diff --git a/arch/misoc/src/lm32/lm32_initialstate.c b/arch/misoc/src/lm32/lm32_initialstate.c index e42107e145..6064e186c8 100644 --- a/arch/misoc/src/lm32/lm32_initialstate.c +++ b/arch/misoc/src/lm32/lm32_initialstate.c @@ -99,6 +99,10 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_EPC] = (uint32_t)tcb->start; + /* Initial state of IE: Interrupts enabled */ + + xcp->regs[REG_INT_CTX] = 1; + /* If this task is running PIC, then set the PIC base register to the * address of the allocated D-Space region. */ diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index 726d60c297..d64623dfa3 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -69,7 +69,7 @@ void lm32_irq_initialize(void) g_current_regs = NULL; - /* Enable interrupt */ + /* Enable interrupts */ irq_setie(1); } @@ -77,15 +77,22 @@ void lm32_irq_initialize(void) irqstate_t up_irq_save(void) { irqstate_t flags; - irq_setie(0); -#warning Return value MUST be the previous IE value. Returning 1 will not work. - return 1; + /* Get the previous value of IE */ + + flags = irq_getie(); + + /* Disable interrupts and return the previous interrupt state */ + + irq_setie(0); + return flags; } void up_irq_restore(irqstate_t flags) { - irq_setie(1); + /* Restore the interrupt state returned by up_save_irq() */ + + irq_setie(flags); } /**************************************************************************** @@ -99,8 +106,13 @@ void up_irq_restore(irqstate_t flags) void up_disable_irq(int irq) { irqstate_t flags; - flags = irq_getmask(); - flags &= ~(1 <= 0 && irq < NR_IRQS); + + /* Disable interrupts by clearing the bit that corresponds to the irq */ + + flags = irq_getmask(); + flags &= ~(1 << irq); irq_setmask(flags); } @@ -115,7 +127,11 @@ void up_disable_irq(int irq) void up_enable_irq(int irq) { irqstate_t flags; - flags = irq_getmask(); + DEBUGASSERT(irq >= 0 && irq < NR_IRQS); + + /* Enable interrupts by setting the bit that corresponds to the irq */ + + flags = irq_getmask(); flags |= (1 << irq); irq_setmask(flags); } diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c index f8c7b280ee..9e5f932d46 100644 --- a/arch/misoc/src/lm32/lm32_swint.c +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -326,5 +326,6 @@ uint32_t *lm32_swint(int irq, FAR void *context) */ g_current_regs = NULL; + return regs; } diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index f672fa7fda..f501059997 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -151,7 +151,7 @@ _do_reset: bi os_start .save_all: - addi sp, sp, -132 + addi sp, sp, -136 sw (sp+REG_X0), r0 sw (sp+REG_X1), r1 sw (sp+REG_X2), r2 @@ -190,11 +190,14 @@ _do_reset: /* ra needs to be moved from initial stack location */ - lw r1, (sp+ 132) + lw r1, (sp+ 136) sw (sp+REG_RA), r1 - /* the 2nd argument is the regs pointer */ + /* get IE/REG_INT_CTX */ + rcsr r1, IE + sw (sp+REG_INT_CTX), r1 + /* the 2nd argument is the regs pointer */ addi r2, sp, 0 ret @@ -231,8 +234,10 @@ _do_reset: lw r29, (r1+REG_RA) lw r30, (r1+REG_EA) lw r31, (r1+REG_BA) + lw r1, (r1+REG_INT_CTX) + wcsr IE, r1 lw r1, (r1+REG_X1) - addi sp, sp, 132 + addi sp, sp, 136 eret /* This global variable is unsigned long g_idle_topstack and is diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig index 99c0c9ef2c..f7b4a0082d 100644 --- a/configs/misoc/hello/defconfig +++ b/configs/misoc/hello/defconfig @@ -16,7 +16,7 @@ CONFIG_HOST_LINUX=y # # Build Configuration # -# CONFIG_APPS_DIR="../apps" +CONFIG_APPS_DIR="../apps" CONFIG_BUILD_FLAT=y # CONFIG_BUILD_2PASS is not set @@ -74,8 +74,9 @@ CONFIG_DEBUG_FEATURES=y # CONFIG_ARCH_HAVE_STACKCHECK is not set # CONFIG_ARCH_HAVE_HEAPCHECK is not set CONFIG_DEBUG_SYMBOLS=y -# CONFIG_ARCH_HAVE_CUSTOMOPT is not set +CONFIG_ARCH_HAVE_CUSTOMOPT=y CONFIG_DEBUG_NOOPT=y +# CONFIG_DEBUG_CUSTOMOPT is not set # CONFIG_DEBUG_FULLOPT is not set # @@ -88,8 +89,10 @@ CONFIG_DEBUG_NOOPT=y CONFIG_ARCH_MISOC=y # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="misoc" @@ -97,6 +100,15 @@ CONFIG_ARCH_CHIP="lm32" CONFIG_ARCH_CHIP_LM32=y # CONFIG_ARCH_CHIP_MOR1K is not set +# +# MISOC Peripheral Support +# +CONFIG_MISOC_HAVE_UART1=y +CONFIG_MISOC_UART1=y +CONFIG_MISOC_UART=y +CONFIG_MISOC_UART_RX_BUF_SIZE=64 +CONFIG_MISOC_UART_TX_BUF_SIZE=64 + # # Architecture Options # @@ -131,7 +143,8 @@ CONFIG_BOARD_LOOPSPERMSEC=800 # # Interrupt options # -# CONFIG_ARCH_HAVE_INTERRUPTSTACK is not set +CONFIG_ARCH_HAVE_INTERRUPTSTACK=y +CONFIG_ARCH_INTERRUPTSTACK=0 # CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set # @@ -276,6 +289,9 @@ CONFIG_DEV_NULL=y # CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_I2S is not set # @@ -319,13 +335,13 @@ CONFIG_DEV_NULL=y # CONFIG_SENSORS is not set # CONFIG_SERCOMM_CONSOLE is not set CONFIG_SERIAL=y -CONFIG_DEV_LOWCONSOLE=y +# CONFIG_DEV_LOWCONSOLE is not set # CONFIG_SERIAL_REMOVABLE is not set -# CONFIG_SERIAL_CONSOLE is not set +CONFIG_SERIAL_CONSOLE=y # CONFIG_16550_UART is not set # CONFIG_UART_SERIALDRIVER is not set # CONFIG_UART0_SERIALDRIVER is not set -# CONFIG_UART1_SERIALDRIVER is not set +CONFIG_UART1_SERIALDRIVER=y # CONFIG_UART2_SERIALDRIVER is not set # CONFIG_UART3_SERIALDRIVER is not set # CONFIG_UART4_SERIALDRIVER is not set @@ -345,11 +361,29 @@ CONFIG_DEV_LOWCONSOLE=y # CONFIG_USART7_SERIALDRIVER is not set # CONFIG_USART8_SERIALDRIVER is not set # CONFIG_OTHER_UART_SERIALDRIVER is not set -# CONFIG_MCU_SERIAL is not set +CONFIG_MCU_SERIAL=y +# CONFIG_STANDARD_SERIAL is not set # CONFIG_SERIAL_IFLOWCONTROL is not set # CONFIG_SERIAL_OFLOWCONTROL is not set # CONFIG_SERIAL_DMA is not set +# CONFIG_SERIAL_TIOCSERGSTRUCT is not set # CONFIG_ARCH_HAVE_SERIAL_TERMIOS is not set +CONFIG_UART1_SERIAL_CONSOLE=y +# CONFIG_OTHER_SERIAL_CONSOLE is not set +# CONFIG_NO_SERIAL_CONSOLE is not set + +# +# UART1 Configuration +# +CONFIG_UART1_RXBUFSIZE=256 +CONFIG_UART1_TXBUFSIZE=256 +CONFIG_UART1_BAUD=115200 +CONFIG_UART1_BITS=8 +CONFIG_UART1_PARITY=0 +CONFIG_UART1_2STOP=0 +# CONFIG_UART1_IFLOWCONTROL is not set +# CONFIG_UART1_OFLOWCONTROL is not set +# CONFIG_UART1_DMA is not set # CONFIG_PSEUDOTERM is not set # CONFIG_USBDEV is not set # CONFIG_USBHOST is not set @@ -364,7 +398,7 @@ CONFIG_DEV_LOWCONSOLE=y # CONFIG_RAMLOG is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set -# CONFIG_SYSLOG_SERIAL_CONSOLE is not set +CONFIG_SYSLOG_SERIAL_CONSOLE=y # CONFIG_SYSLOG_CHAR is not set CONFIG_SYSLOG_CONSOLE=y # CONFIG_SYSLOG_NONE is not set @@ -446,6 +480,8 @@ CONFIG_NUNGET_CHARS=0 # CONFIG_LIBC_FLOATINGPOINT is not set # CONFIG_LIBC_LONG_LONG is not set # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -489,6 +525,7 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 # # Examples # +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_DHCPD is not set From 50efe4a906f82eda23b9dc9d4ed75e683bcd2bbd Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 11:17:12 -0600 Subject: [PATCH 075/155] LM32: Add a fake IRQ number for a software interrupt. --- arch/misoc/include/irq.h | 6 ++++- arch/misoc/src/lm32/lm32_decodeirq.c | 2 +- arch/misoc/src/lm32/lm32_irq.c | 40 ++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/arch/misoc/include/irq.h b/arch/misoc/include/irq.h index 1fbf884fc3..a21987b00a 100644 --- a/arch/misoc/include/irq.h +++ b/arch/misoc/include/irq.h @@ -53,7 +53,11 @@ * Pre-processor Definitions ****************************************************************************/ -#define NR_IRQS 32 +/* 32 True interrupts plus the sofware interrupt */ + +#define MISOC_NINTERRUPTS 32 +#define MISOC_IRQ_SWINT 32 +#define NR_IRQS 33 /**************************************************************************** * Public Function Prototypes diff --git a/arch/misoc/src/lm32/lm32_decodeirq.c b/arch/misoc/src/lm32/lm32_decodeirq.c index bdf0abe240..0df3f73ed9 100644 --- a/arch/misoc/src/lm32/lm32_decodeirq.c +++ b/arch/misoc/src/lm32/lm32_decodeirq.c @@ -77,7 +77,7 @@ uint32_t *lm32_decodeirq(uint32_t *regs) /* Decode and dispatch interrupts */ - for (irq = 0; irq < NR_IRQS & instat != 0; i++) + for (irq = 0; irq < MISOC_NINTERRUPTS & instat != 0; i++) { uint32_t bit = (1 << irq); diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index d64623dfa3..4218d8872b 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -74,6 +74,13 @@ void lm32_irq_initialize(void) irq_setie(1); } +/**************************************************************************** + * Name: up_irq_save + * + * Description: + * + ****************************************************************************/ + irqstate_t up_irq_save(void) { irqstate_t flags; @@ -88,6 +95,13 @@ irqstate_t up_irq_save(void) return flags; } +/**************************************************************************** + * Name: up_irq_restore + * + * Description: + * + ****************************************************************************/ + void up_irq_restore(irqstate_t flags) { /* Restore the interrupt state returned by up_save_irq() */ @@ -109,11 +123,16 @@ void up_disable_irq(int irq) DEBUGASSERT(irq >= 0 && irq < NR_IRQS); - /* Disable interrupts by clearing the bit that corresponds to the irq */ + /* Ignore any attempt to disable software interrupts */ - flags = irq_getmask(); - flags &= ~(1 << irq); - irq_setmask(flags); + if (irq < MISOC_NINTERRUPTS) + { + /* Disable interrupts by clearing the bit that corresponds to the irq */ + + flags = irq_getmask(); + flags &= ~(1 << irq); + irq_setmask(flags); + } } /**************************************************************************** @@ -129,9 +148,14 @@ void up_enable_irq(int irq) irqstate_t flags; DEBUGASSERT(irq >= 0 && irq < NR_IRQS); - /* Enable interrupts by setting the bit that corresponds to the irq */ + /* Ignore any attempt to enable software interrupts */ - flags = irq_getmask(); - flags |= (1 << irq); - irq_setmask(flags); + if (irq < MISOC_NINTERRUPTS) + { + /* Enable interrupts by setting the bit that corresponds to the irq */ + + flags = irq_getmask(); + flags |= (1 << irq); + irq_setmask(flags); + } } From 8fe916e13384fd9f7a76fde167cea38470e3bf2e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 11:23:33 -0600 Subject: [PATCH 076/155] Attach the software interrupt handler when interrupts are intialized. --- arch/misoc/src/lm32/lm32_irq.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index 4218d8872b..dab24189e6 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -69,6 +69,10 @@ void lm32_irq_initialize(void) g_current_regs = NULL; + /* Attach the software interrupt */ + + (void)irq_attach(MISOC_IRQ_SWINT, lm32_swint); + /* Enable interrupts */ irq_setie(1); From 45caca804a01205cb7cebb1e21dda76419d183a6 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Fri, 4 Nov 2016 14:04:43 -0600 Subject: [PATCH 077/155] LM32: Progress on interrupt and serial driver. --- arch/misoc/Kconfig | 12 +- arch/misoc/src/common/misoc.h | 64 ++ arch/misoc/src/common/misoc_mdelay.c | 70 ++ arch/misoc/src/common/misoc_serial.c | 685 ++++++++++++++++++++ arch/misoc/src/lm32/Make.defs | 2 +- arch/misoc/src/lm32/Toolchain.defs | 4 +- arch/misoc/src/lm32/lm32.h | 21 +- arch/misoc/src/lm32/lm32_config.h | 97 +++ arch/misoc/src/lm32/lm32_decodeirq.c | 10 +- arch/misoc/src/lm32/lm32_doirq.c | 3 + arch/misoc/src/lm32/lm32_initialize.c | 5 +- arch/misoc/src/lm32/lm32_swint.c | 18 +- arch/misoc/src/lm32/lm32_vectors.S | 148 ++--- configs/misoc/include/generated/csr.h | 537 ++++++--------- configs/misoc/include/generated/mem.h | 45 +- configs/misoc/include/generated/regions.ld | 3 +- configs/misoc/include/generated/sdram_phy.h | 168 ++--- 17 files changed, 1270 insertions(+), 622 deletions(-) create mode 100644 arch/misoc/src/common/misoc.h create mode 100644 arch/misoc/src/common/misoc_mdelay.c create mode 100644 arch/misoc/src/common/misoc_serial.c create mode 100644 arch/misoc/src/lm32/lm32_config.h diff --git a/arch/misoc/Kconfig b/arch/misoc/Kconfig index f0acc68046..615b741c52 100644 --- a/arch/misoc/Kconfig +++ b/arch/misoc/Kconfig @@ -11,7 +11,7 @@ choice config ARCH_CHIP_LM32 bool "LM32" - select MISOC_HAVE_UART0 + select MISOC_HAVE_UART1 ---help--- LM32 Chip Selected @@ -32,15 +32,15 @@ menu "MISOC Peripheral Support" # These "hidden" settings determine is a peripheral option is available for the # selection MCU -config MISOC_HAVE_UART0 +config MISOC_HAVE_UART1 bool default n - select UART0_SERIALDRIVER + select UART1_SERIALDRIVER -config MISOC_UART0 - bool "UART0" +config MISOC_UART1 + bool "UART1" default n - select ARCH_HAVE_UART0 + select ARCH_HAVE_UART1 select MISOC_UART endmenu # MISOC Peripheral Support diff --git a/arch/misoc/src/common/misoc.h b/arch/misoc/src/common/misoc.h new file mode 100644 index 0000000000..d487babab2 --- /dev/null +++ b/arch/misoc/src/common/misoc.h @@ -0,0 +1,64 @@ +/**************************************************************************** + * arch/misoc/src/common/serial.h + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_COMMON_MISOC_H +#define __ARCH_MISOC_SRC_COMMON_MISOC_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifndef __ASSEMBLY__ + +/**************************************************************************** + * Name: up_serialinit + * + * Description: + * Register serial console and serial ports. This assumes that + * misoc_earlyserialinit was called previously. + * + ****************************************************************************/ + +void misoc_serial_initialize(void); + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_MISOC_SRC_COMMON_MISOC_H */ diff --git a/arch/misoc/src/common/misoc_mdelay.c b/arch/misoc/src/common/misoc_mdelay.c new file mode 100644 index 0000000000..2a1ccaa1a1 --- /dev/null +++ b/arch/misoc/src/common/misoc_mdelay.c @@ -0,0 +1,70 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_mdelay.c + * + * Copyright (C) 2016 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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_mdelay + * + * Description: + * Delay inline for the requested number of milliseconds. + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_mdelay(unsigned int milliseconds) +{ + volatile int i; + volatile int j; + + for (i = 0; i < milliseconds; i++) + { + for (j = 0; j < CONFIG_BOARD_LOOPSPERMSEC; j++) + { + } + } +} diff --git a/arch/misoc/src/common/misoc_serial.c b/arch/misoc/src/common/misoc_serial.c new file mode 100644 index 0000000000..af05eb1bb1 --- /dev/null +++ b/arch/misoc/src/common/misoc_serial.c @@ -0,0 +1,685 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_blocktask.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Ramtin Amin + * + * 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 +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include "chip.h" +#include "hw/flags.h +#include "misoc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_MISOC_UART1) || defined(CONFIG_MISOC_UART2) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn, n=1,.. CHIP_NUARTS + */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_MISOC_UART1) +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_MISOC_UART2) +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of misoc_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART1_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart1port /* UART1 is console */ +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# error "I'm confused... Do we have a serial console or not?" +# endif +#else +# undef CONSOLE_DEV /* No console */ +# undef CONFIG_UART1_SERIAL_CONSOLE +# if defined(CONFIG_NR5_UART1) +# define TTYS0_DEV g_uart1port /* UART1 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# undef TTYS0_DEV +# undef TTYS1_DEV +# endif +#endif + +/* Common initialization logic will not not know that the all of the UARTs + * have been disabled. So, as a result, we may still have to provide + * stub implementations of misoc_earlyserialinit(), misoc_serial_initialize(), and + * misoc_putc(). + */ + +#ifdef HAVE_UART_DEVICE + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct misoc_dev_s +{ + uintptr_t uartbase; + uintptr_t rxtx_addr; + uintptr_t txfull_addr; + uintptr_t rxempty_addr; + uintptr_t ev_status_addr; + uintptr_t ev_pending_addr; + uintptr_t ev_enable_addr; + uint8_t irq; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers */ + +static inline uint32_t misoc_serialin(struct misoc_dev_s *priv, int offset); +static inline void misoc_serialout(struct misoc_dev_s *priv, int offset, + uint32_t value); +static void misoc_restoreuartint(struct uart_dev_s *dev, uint8_t im); +static void misoc_disableuartint(struct uart_dev_s *dev, uint8_t *im); + +/* Serial driver methods */ + +static int misoc_setup(struct uart_dev_s *dev); +static void misoc_shutdown(struct uart_dev_s *dev); +static int misoc_attach(struct uart_dev_s *dev); +static void misoc_detach(struct uart_dev_s *dev); +static int misoc_uart_interrupt(int irq, void *context); +static int misoc_ioctl(struct file *filep, int cmd, unsigned long arg); +static int misoc_receive(struct uart_dev_s *dev, uint32_t *status); +static void misoc_rxint(struct uart_dev_s *dev, bool enable); +static bool misoc_rxavailable(struct uart_dev_s *dev); +static void misoc_send(struct uart_dev_s *dev, int ch); +static void misoc_txint(struct uart_dev_s *dev, bool enable); +static bool misoc_txready(struct uart_dev_s *dev); +static bool misoc_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = misoc_setup, + .shutdown = misoc_shutdown, + .attach = misoc_attach, + .detach = misoc_detach, + .ioctl = misoc_ioctl, + .receive = misoc_receive, + .rxint = misoc_rxint, + .rxavailable = misoc_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = misoc_send, + .txint = misoc_txint, + .txready = misoc_txready, + .txempty = misoc_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_MISOC_UART1 +static char g_uart1rxbuffer[CONFIG_UART1_RXBUFSIZE]; +static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; +#endif + +/* This describes the state of the NR5 UART1 port. */ + +#ifdef CONFIG_MISOC_UART1 +#ifndef CONFIG_MISOC_UART1PRIO +# define CONFIG_MISOC_UART1PRIO 4 +#endif + +static struct misoc_dev_s g_uart1priv = +{ + .uartbase = CSR_UART_BASE, + .irq = UART_INTERRUPT, + .rxtx_addr = CSR_UART_RXTX_ADDR, + .rxempty_addr = CSR_UART_RXEMPTY_ADDR, + .txfull_addr = CSR_UART_TXFULL_ADDR, + .ev_status_addr = CSR_UART_EV_STATUS_ADDR, + .ev_pending_addr = CSR_UART_EV_PENDING_ADDR, + .ev_enable_addr = CSR_UART_EV_ENABLE_ADDR, +}; + +static uart_dev_t g_uart1port = +{ +#if SERIAL_CONSOLE == 1 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: misoc_restoreuartint + ****************************************************************************/ + +static void misoc_restoreuartint(struct uart_dev_s *dev, uint8_t im) +{ + /* Re-enable/re-disable interrupts corresponding to the state of bits in + * im. + */ + + uart_ev_enable_write(im); +} + +/**************************************************************************** + * Name: misoc_disableuartint + ****************************************************************************/ + +static void misoc_disableuartint(struct uart_dev_s *dev, uint8_t *im) +{ + struct misoc_dev_s *priv = (struct misoc_dev_s *)dev->priv; + + if (im) + { + *im = uart_ev_enable_read(); + } + + misoc_restoreuartint(dev, 0); +} + +/**************************************************************************** + * Name: misoc_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int misoc_setup(struct uart_dev_s *dev) +{ + uart_ev_pending_write(uart_ev_pending_read()); + return OK; +} + +/**************************************************************************** + * Name: misoc_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void misoc_shutdown(struct uart_dev_s *dev) +{ +} + +/**************************************************************************** + * Name: misoc_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() methods are called. + * + ****************************************************************************/ + +static int misoc_attach(struct uart_dev_s *dev) +{ + struct misoc_dev_s *priv = (struct misoc_dev_s *)dev->priv; + uint32_t im; + + irq_attach(priv->irq, misoc_uart_interrupt); + + /* enable interrupt */ + /* TODO: move that somewhere proper ! */ + + im = irq_getmask(); + im |= (1 << UART_INTERRUPT); + irq_setmask(im); + + return OK; +} + +/**************************************************************************** + * Name: misoc_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void misoc_detach(struct uart_dev_s *dev) +{ + struct misoc_dev_s *priv = (struct misoc_dev_s *)dev->priv; + uint32_t im; + + /* TODO: move that somewhere proper */ + + im = irq_getmask(); + im &= ~(1 << UART_INTERRUPT); + irq_setmask(im); + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: misoc_interrupt + * + * Description: + * This is the UART interrupt handler. It will be invoked when an + * interrupt received on the 'irq' It should call uart_transmitchars or + * uart_receivechar to perform the appropriate data transfers. The + * interrupt handling logic must be able to map the 'irq' number into the + * approprite uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int misoc_uart_interrupt(int irq, void *context) +{ + uint32_t stat; + struct uart_dev_s *dev = NULL; + int i; + + dev = &g_uart1port; + + /* Read as much as we can */ + + stat = uart_ev_pending_read(); + if (stat & UART_EV_RX) + { + while (!uart_rxempty_read()) + { + uart_recvchars(dev); + } + } + + /* Try to send all the buffer that were not sent. Does uart_xmitchars + * send only if there is something to send ??? + */ + + if ((stat & UART_EV_TX) != 0) + { + uart_ev_pending_write(UART_EV_TX); + uart_xmitchars(dev); + } + + return OK; +} + +/**************************************************************************** + * Name: misoc_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int misoc_ioctl(struct file *filep, int cmd, unsigned long arg) +{ +#ifdef CONFIG_SERIAL_TERMIOS + return -ENOSYS; +#else + return -ENOTTY; +#endif +} + +/**************************************************************************** + * Name: misoc_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int misoc_receive(struct uart_dev_s *dev, uint32_t *status) +{ + int ret; + + if (status != NULL) + { + *status = 0; + } + + ret = uart_rxtx_read(); + + uart_ev_pending_write(UART_EV_RX); + + return ret; +} + +/**************************************************************************** + * Name: misoc_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void misoc_rxint(struct uart_dev_s *dev, bool enable) +{ + uint8_t im; + + im = uart_ev_enable_read(); + if (enable) + { + im |= UART_EV_RX; + } + else + { + im &= ~UART_EV_RX; + } + + uart_ev_enable_write(im); +} + +/**************************************************************************** + * Name: misoc_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool misoc_rxavailable(struct uart_dev_s *dev) +{ + return !uart_rxempty_read(); +} + +/**************************************************************************** + * Name: misoc_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void misoc_send(struct uart_dev_s *dev, int ch) +{ + uart_rxtx_write(ch); +} + +/**************************************************************************** + * Name: misoc_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void misoc_txint(struct uart_dev_s *dev, bool enable) +{ + uint8_t im; + int i; + + im = uart_ev_enable_read(); + if (enable) + { + im |= UART_EV_TX; + uart_ev_enable_write(im); + + /* Fake an uart INT */ + + uart_xmitchars(dev); + } + else + { + im &= ~UART_EV_TX; + uart_ev_enable_write(im); + } +} + +/**************************************************************************** + * Name: misoc_txready + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool misoc_txready(struct uart_dev_s *dev) +{ + return !uart_txfull_read(); +} + +/**************************************************************************** + * Name: misoc_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool misoc_txempty(struct uart_dev_s *dev) +{ + return !uart_txfull_read(); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: misoc_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before misoc_serial_initialize. + * + ****************************************************************************/ + +void misoc_earlyserialinit(void) +{ +} + +/**************************************************************************** + * Name: misoc_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct uart_dev_s *dev = (struct uart_dev_s *)&CONSOLE_DEV; + uint8_t imr; + + misoc_disableuartint(dev, &imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + misoc_lowputc('\r'); + } + + misoc_lowputc(ch); + misoc_restoreuartint(dev, imr); +#endif + return ch; +} + +/**************************************************************************** + * Name: misoc_earlyserialinit, misoc_serial_initialize, and misoc_putc + * + * Description: + * stubs that may be needed. These stubs would be used if all UARTs are + * disabled. In that case, the logic in common/misoc_initialize() is not + * smart enough to know that there are not UARTs and will still expect + * these interfaces to be provided. + * + ****************************************************************************/ + +#else /* HAVE_UART_DEVICE */ +void misoc_earlyserialinit(void) +{ +} + +void misoc_serial_initialize(void) +{ +} + +int up_putc(int ch) +{ + return ch; +} + +#endif /* HAVE_UART_DEVICE */ +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: misoc_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + misoc_lowputc('\r'); + } + + misoc_lowputc(ch); +#endif + + return ch; +} + +#endif /* USE_SERIALDRIVER */ + +void misoc_lowputc(char ch) +{ + while (uart_txfull_read()); + uart_rxtx_write(ch); + uart_ev_pending_write(UART_EV_TX); +} + +/**************************************************************************** + * Name: misoc_serial_initialize + * + * Description: + * Register serial console and serial ports. This assumes + * that misoc_earlyserialinit was called previously. + * + ****************************************************************************/ + +void misoc_serial_initialize(void) +{ +#ifdef USE_SERIALDRIVER + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + (void)uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + (void)uart_register("/dev/ttyS0", &TTYS0_DEV); +#endif +} diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index cc4b72da66..4548e6fe32 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -37,7 +37,7 @@ HEAD_ASRC = lm32_vectors.S CMN_ASRCS = -CMN_CSRCS = misoc_uart.c +CMN_CSRCS = misoc_serial.c misoc_mdelay.c CHIP_ASRCS = lm32_syscall.S diff --git a/arch/misoc/src/lm32/Toolchain.defs b/arch/misoc/src/lm32/Toolchain.defs index e0227e2e16..f59fa1ab45 100644 --- a/arch/misoc/src/lm32/Toolchain.defs +++ b/arch/misoc/src/lm32/Toolchain.defs @@ -87,8 +87,8 @@ endif # Generic GNU toolchain on OS X, Linux or any typical Posix system ifeq ($(CONFIG_LM32_TOOLCHAIN),GNUL) - CROSSDEV ?= lm32-elf-- - ARCROSSDEV ?= lm32-elf-- + CROSSDEV ?= lm32-elf- + ARCROSSDEV ?= lm32-elf- MAXOPTIMIZATION ?= -Os endif diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index 280c2ff17f..ddfd2320e1 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -34,8 +34,8 @@ * ****************************************************************************/ -#ifndef __ARCH_MISOC_SRC_COMMON_LM32_H -#define __ARCH_MISOC_SRC_COMMON_LM32_H +#ifndef __ARCH_MISOC_SRC_LM32_LM32_H +#define __ARCH_MISOC_SRC_LM32_LM32_H /**************************************************************************** * Included Files @@ -141,13 +141,17 @@ void lm32_copystate(uint32_t *dest, uint32_t *src); void lm32_irq_initialize(void); -/* System timer *************************************************************/ +/* Interrupt decode *********************************************************/ -void lm32_timer_initialize(void); +uint32_t *lm32_decodeirq(uint32_t intstat, uint32_t *regs); /* Software interrupts ******************************************************/ -uint32_t *lm32_swint(int irq, FAR void *context); +int lm32_swint(int irq, FAR void *context); + +/* System timer *************************************************************/ + +void lm32_timer_initialize(void); /* Signal handling **********************************************************/ @@ -163,10 +167,5 @@ void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); void lm32_dumpstate(void); -#undef EXTERN -#ifdef __cplusplus -} -#endif #endif /* __ASSEMBLY__ */ - -#endif /* __ARCH_MISOC_SRC_COMMON_LM32_H */ +#endif /* __ARCH_MISOC_SRC_LM32_LM32_H */ diff --git a/arch/misoc/src/lm32/lm32_config.h b/arch/misoc/src/lm32/lm32_config.h new file mode 100644 index 0000000000..5b0d5d9b03 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_config.h @@ -0,0 +1,97 @@ +/************************************************************************************ + * arch/misoc/src/lm32/lm32_config.h + * + * Copyright (C) 2015 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Modified for LM32: + * + * Copyright (C) 2016 Ramin Amin. All rights reserved. + * Author: Ramtin Amin + * + * 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 __ARCH_MISOC_SRC_LM32_LM32_CONFIG_H +#define __ARCH_MISOC_SRC_LM32_LM32_CONFIG_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ +/* UARTs ****************************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART_DEVICE +#if defined(CONFIG_MISOC_UART1) || defined(CONFIG_MISOC_UART2) +# define HAVE_UART_DEVICE 1 +#endif + +/* Is there a serial console? There should be no more than one defined. It + * could be on any UARTn, n=1,.. CHIP_NUARTS + */ + +#if defined(CONFIG_UART1_SERIAL_CONSOLE) && defined(CONFIG_MISOC_UART1) +# undef CONFIG_UART2_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#elif defined(CONFIG_UART2_SERIAL_CONSOLE) && defined(CONFIG_MISOC_UART2) +# undef CONFIG_UART1_SERIAL_CONSOLE +# define HAVE_SERIAL_CONSOLE 1 +#else +# undef CONFIG_UART1_SERIAL_CONSOLE +# undef CONFIG_UART2_SERIAL_CONSOLE +# undef HAVE_SERIAL_CONSOLE +#endif + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +#endif /* __ARCH_MISOC_SRC_LM32_LM32_CONFIG_H */ diff --git a/arch/misoc/src/lm32/lm32_decodeirq.c b/arch/misoc/src/lm32/lm32_decodeirq.c index 0df3f73ed9..198445deed 100644 --- a/arch/misoc/src/lm32/lm32_decodeirq.c +++ b/arch/misoc/src/lm32/lm32_decodeirq.c @@ -61,18 +61,10 @@ * ****************************************************************************/ -uint32_t *lm32_decodeirq(uint32_t *regs) +uint32_t *lm32_decodeirq(uint32_t intstat, uint32_t *regs) { - uint32_t intstat; int irq; - /* Read the pending interrupts */ - /* REVISIT: How do I get the interupt status */ -#warning Missing logic - intstat = 0; - - /* REVIST: Do I need to mask the interrupt status with the IM? */ - irqinfo("intstat=%08lx\n", (unsigned long)intstat); /* Decode and dispatch interrupts */ diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c index e318a65adf..25cc30e2a0 100644 --- a/arch/misoc/src/lm32/lm32_doirq.c +++ b/arch/misoc/src/lm32/lm32_doirq.c @@ -42,10 +42,13 @@ #include #include +#include #include #include #include + +#include #include #include "group/group.h" diff --git a/arch/misoc/src/lm32/lm32_initialize.c b/arch/misoc/src/lm32/lm32_initialize.c index 4efa2ecbf0..23e6e8fc1f 100644 --- a/arch/misoc/src/lm32/lm32_initialize.c +++ b/arch/misoc/src/lm32/lm32_initialize.c @@ -57,6 +57,7 @@ #include +#include "misoc.h" #include "lm32.h" /**************************************************************************** @@ -71,7 +72,7 @@ void up_initialize(void) /* Initialize the serial driver */ -#warning REVISIT: Here you should all lm32_serial_initialize(). That initializes the entire serial driver, a part of the operation is the uart initialization. +#warning REVISIT: Here you should all misoc_serial_initialize(). That initializes the entire serial driver, a part of the operation is the uart initialization. - uart_init(); + misoc_serial_initialize(); } diff --git a/arch/misoc/src/lm32/lm32_swint.c b/arch/misoc/src/lm32/lm32_swint.c index 9e5f932d46..cdfbeeb389 100644 --- a/arch/misoc/src/lm32/lm32_swint.c +++ b/arch/misoc/src/lm32/lm32_swint.c @@ -130,7 +130,7 @@ static void dispatch_syscall(void) * ****************************************************************************/ -uint32_t *lm32_swint(int irq, FAR void *context) +int lm32_swint(int irq, FAR void *context) { uint32_t *regs = (uint32_t *)context; @@ -313,19 +313,5 @@ uint32_t *lm32_swint(int irq, FAR void *context) } #endif - /* If a context switch occurred while processing the interrupt then - * g_current_regs may have change value. If we return any value different - * from the input regs, then the lower level will know that a context - * switch occurred during interrupt processing. - */ - - regs = (uint32_t *)g_current_regs; - - /* Set g_current_regs to NULL to indicate that we are no longer in an - * interrupt handler. - */ - - g_current_regs = NULL; - - return regs; + return OK; } diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index f501059997..a7d7d9b621 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -143,101 +143,103 @@ _do_reset: .clearBSS: be r1, r3, .callMain - sw (r1+0), r0 - addi r1, r1, 4 + sw (r1+0), r0 + addi r1, r1, 4 bi .clearBSS .callMain: bi os_start .save_all: - addi sp, sp, -136 - sw (sp+REG_X0), r0 - sw (sp+REG_X1), r1 - sw (sp+REG_X2), r2 - sw (sp+REG_X3), r3 - sw (sp+REG_X4), r4 - sw (sp+REG_X5), r5 - sw (sp+REG_X6), r6 - sw (sp+REG_X7), r7 - sw (sp+REG_X8), r8 - sw (sp+REG_X9), r9 - sw (sp+REG_X10), r10 - sw (sp+REG_X11), r11 - sw (sp+REG_X12), r12 - sw (sp+REG_X13), r13 - sw (sp+REG_X14), r14 - sw (sp+REG_X15), r15 - sw (sp+REG_X16), r16 - sw (sp+REG_X17), r17 - sw (sp+REG_X18), r18 - sw (sp+REG_X19), r19 - sw (sp+REG_X20), r20 - sw (sp+REG_X21), r21 - sw (sp+REG_X22), r22 - sw (sp+REG_X23), r23 - sw (sp+REG_X24), r24 - sw (sp+REG_X25), r25 + addi sp, sp, -136 + sw (sp+REG_X0), r0 + sw (sp+REG_X1), r1 + sw (sp+REG_X2), r2 + sw (sp+REG_X3), r3 + sw (sp+REG_X4), r4 + sw (sp+REG_X5), r5 + sw (sp+REG_X6), r6 + sw (sp+REG_X7), r7 + sw (sp+REG_X8), r8 + sw (sp+REG_X9), r9 + sw (sp+REG_X10), r10 + sw (sp+REG_X11), r11 + sw (sp+REG_X12), r12 + sw (sp+REG_X13), r13 + sw (sp+REG_X14), r14 + sw (sp+REG_X15), r15 + sw (sp+REG_X16), r16 + sw (sp+REG_X17), r17 + sw (sp+REG_X18), r18 + sw (sp+REG_X19), r19 + sw (sp+REG_X20), r20 + sw (sp+REG_X21), r21 + sw (sp+REG_X22), r22 + sw (sp+REG_X23), r23 + sw (sp+REG_X24), r24 + sw (sp+REG_X25), r25 - sw (sp+REG_GP), r26 - sw (sp+REG_FP), r27 - sw (sp+REG_SP), r28 + sw (sp+REG_GP), r26 + sw (sp+REG_FP), r27 + sw (sp+REG_SP), r28 /* reg RA done later */ - sw (sp+REG_EA), r30 - sw (sp+REG_BA), r31 + sw (sp+REG_EA), r30 + sw (sp+REG_BA), r31 /* ra needs to be moved from initial stack location */ - lw r1, (sp+ 136) - sw (sp+REG_RA), r1 + w r1, (sp+ 136) + sw (sp+REG_RA), r1 + + /* Get IE/REG_INT_CTX */ - /* get IE/REG_INT_CTX */ rcsr r1, IE - sw (sp+REG_INT_CTX), r1 + sw (sp+REG_INT_CTX), r1 - /* the 2nd argument is the regs pointer */ - addi r2, sp, 0 + /* The 2nd argument is the regs pointer */ + + addi r2, sp, 0 ret .restore_all_and_eret: /* r1 should have the place where we restore ! */ - lw r2, (r1+REG_X2) - lw r3, (r1+REG_X3) - lw r4, (r1+REG_X4) - lw r5, (r1+REG_X5) - lw r6, (r1+REG_X6) - lw r7, (r1+REG_X7) - lw r8, (r1+REG_X8) - lw r9, (r1+REG_X9) - lw r10, (r1+REG_X10) - lw r11, (r1+REG_X11) - lw r12, (r1+REG_X12) - lw r13, (r1+REG_X13) - lw r14, (r1+REG_X14) - lw r15, (r1+REG_X15) - lw r16, (r1+REG_X16) - lw r17, (r1+REG_X17) - lw r18, (r1+REG_X18) - lw r19, (r1+REG_X19) - lw r20, (r1+REG_X20) - lw r21, (r1+REG_X21) - lw r22, (r1+REG_X22) - lw r23, (r1+REG_X23) - lw r24, (r1+REG_X24) - lw r25, (r1+REG_X25) - lw r26, (r1+REG_GP) - lw r27, (r1+REG_FP) - lw r28, (r1+REG_SP) - lw r29, (r1+REG_RA) - lw r30, (r1+REG_EA) - lw r31, (r1+REG_BA) - lw r1, (r1+REG_INT_CTX) + w r2, (r1+REG_X2) + w r3, (r1+REG_X3) + w r4, (r1+REG_X4) + w r5, (r1+REG_X5) + w r6, (r1+REG_X6) + w r7, (r1+REG_X7) + w r8, (r1+REG_X8) + w r9, (r1+REG_X9) + w r10, (r1+REG_X10) + w r11, (r1+REG_X11) + w r12, (r1+REG_X12) + w r13, (r1+REG_X13) + w r14, (r1+REG_X14) + w r15, (r1+REG_X15) + w r16, (r1+REG_X16) + w r17, (r1+REG_X17) + w r18, (r1+REG_X18) + w r19, (r1+REG_X19) + w r20, (r1+REG_X20) + w r21, (r1+REG_X21) + w r22, (r1+REG_X22) + w r23, (r1+REG_X23) + w r24, (r1+REG_X24) + w r25, (r1+REG_X25) + w r26, (r1+REG_GP) + w r27, (r1+REG_FP) + w r28, (r1+REG_SP) + w r29, (r1+REG_RA) + w r30, (r1+REG_EA) + w r31, (r1+REG_BA) + lw r1, (r1+REG_INT_CTX) wcsr IE, r1 - lw r1, (r1+REG_X1) - addi sp, sp, 136 + w r1, (r1+REG_X1) + addi sp, sp, 136 eret /* This global variable is unsigned long g_idle_topstack and is diff --git a/configs/misoc/include/generated/csr.h b/configs/misoc/include/generated/csr.h index 64bd1915a1..abfa8b39cd 100644 --- a/configs/misoc/include/generated/csr.h +++ b/configs/misoc/include/generated/csr.h @@ -1,397 +1,250 @@ -/**************************************************************************** - * configs/misoc/include/generated/csr.h - * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Ramtin Amin - * - * 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 __CONFIGS_MISOC_INCLUDE_GENERATED_CSR_H -#define __CONFIGS_MISOC_INCLUDE_GENERATED_CSR_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include "hw/common.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* SDRAM */ +#ifndef __GENERATED_CSR_H +#define __GENERATED_CSR_H +#include +/* sdram */ #define CSR_SDRAM_BASE 0xe0004000 #define CSR_SDRAM_DFII_CONTROL_ADDR 0xe0004000 #define CSR_SDRAM_DFII_CONTROL_SIZE 1 - +static inline unsigned char sdram_dfii_control_read(void) { + unsigned char r = MMPTR(0xe0004000); + return r; +} +static inline void sdram_dfii_control_write(unsigned char value) { + MMPTR(0xe0004000) = value; +} #define CSR_SDRAM_DFII_PI0_COMMAND_ADDR 0xe0004004 #define CSR_SDRAM_DFII_PI0_COMMAND_SIZE 1 - +static inline unsigned char sdram_dfii_pi0_command_read(void) { + unsigned char r = MMPTR(0xe0004004); + return r; +} +static inline void sdram_dfii_pi0_command_write(unsigned char value) { + MMPTR(0xe0004004) = value; +} #define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_ADDR 0xe0004008 #define CSR_SDRAM_DFII_PI0_COMMAND_ISSUE_SIZE 1 - +static inline unsigned char sdram_dfii_pi0_command_issue_read(void) { + unsigned char r = MMPTR(0xe0004008); + return r; +} +static inline void sdram_dfii_pi0_command_issue_write(unsigned char value) { + MMPTR(0xe0004008) = value; +} #define CSR_SDRAM_DFII_PI0_ADDRESS_ADDR 0xe000400c #define CSR_SDRAM_DFII_PI0_ADDRESS_SIZE 2 - +static inline unsigned short int sdram_dfii_pi0_address_read(void) { + unsigned short int r = MMPTR(0xe000400c); + r <<= 8; + r |= MMPTR(0xe0004010); + return r; +} +static inline void sdram_dfii_pi0_address_write(unsigned short int value) { + MMPTR(0xe000400c) = value >> 8; + MMPTR(0xe0004010) = value; +} #define CSR_SDRAM_DFII_PI0_BADDRESS_ADDR 0xe0004014 #define CSR_SDRAM_DFII_PI0_BADDRESS_SIZE 1 - +static inline unsigned char sdram_dfii_pi0_baddress_read(void) { + unsigned char r = MMPTR(0xe0004014); + return r; +} +static inline void sdram_dfii_pi0_baddress_write(unsigned char value) { + MMPTR(0xe0004014) = value; +} #define CSR_SDRAM_DFII_PI0_WRDATA_ADDR 0xe0004018 #define CSR_SDRAM_DFII_PI0_WRDATA_SIZE 2 - +static inline unsigned short int sdram_dfii_pi0_wrdata_read(void) { + unsigned short int r = MMPTR(0xe0004018); + r <<= 8; + r |= MMPTR(0xe000401c); + return r; +} +static inline void sdram_dfii_pi0_wrdata_write(unsigned short int value) { + MMPTR(0xe0004018) = value >> 8; + MMPTR(0xe000401c) = value; +} #define CSR_SDRAM_DFII_PI0_RDDATA_ADDR 0xe0004020 #define CSR_SDRAM_DFII_PI0_RDDATA_SIZE 2 +static inline unsigned short int sdram_dfii_pi0_rddata_read(void) { + unsigned short int r = MMPTR(0xe0004020); + r <<= 8; + r |= MMPTR(0xe0004024); + return r; +} +/* timer0 */ #define CSR_TIMER0_BASE 0xe0002000 #define CSR_TIMER0_LOAD_ADDR 0xe0002000 #define CSR_TIMER0_LOAD_SIZE 4 - +static inline unsigned int timer0_load_read(void) { + unsigned int r = MMPTR(0xe0002000); + r <<= 8; + r |= MMPTR(0xe0002004); + r <<= 8; + r |= MMPTR(0xe0002008); + r <<= 8; + r |= MMPTR(0xe000200c); + return r; +} +static inline void timer0_load_write(unsigned int value) { + MMPTR(0xe0002000) = value >> 24; + MMPTR(0xe0002004) = value >> 16; + MMPTR(0xe0002008) = value >> 8; + MMPTR(0xe000200c) = value; +} #define CSR_TIMER0_RELOAD_ADDR 0xe0002010 #define CSR_TIMER0_RELOAD_SIZE 4 - +static inline unsigned int timer0_reload_read(void) { + unsigned int r = MMPTR(0xe0002010); + r <<= 8; + r |= MMPTR(0xe0002014); + r <<= 8; + r |= MMPTR(0xe0002018); + r <<= 8; + r |= MMPTR(0xe000201c); + return r; +} +static inline void timer0_reload_write(unsigned int value) { + MMPTR(0xe0002010) = value >> 24; + MMPTR(0xe0002014) = value >> 16; + MMPTR(0xe0002018) = value >> 8; + MMPTR(0xe000201c) = value; +} #define CSR_TIMER0_EN_ADDR 0xe0002020 #define CSR_TIMER0_EN_SIZE 1 - +static inline unsigned char timer0_en_read(void) { + unsigned char r = MMPTR(0xe0002020); + return r; +} +static inline void timer0_en_write(unsigned char value) { + MMPTR(0xe0002020) = value; +} #define CSR_TIMER0_UPDATE_VALUE_ADDR 0xe0002024 #define CSR_TIMER0_UPDATE_VALUE_SIZE 1 - +static inline unsigned char timer0_update_value_read(void) { + unsigned char r = MMPTR(0xe0002024); + return r; +} +static inline void timer0_update_value_write(unsigned char value) { + MMPTR(0xe0002024) = value; +} #define CSR_TIMER0_VALUE_ADDR 0xe0002028 #define CSR_TIMER0_VALUE_SIZE 4 - +static inline unsigned int timer0_value_read(void) { + unsigned int r = MMPTR(0xe0002028); + r <<= 8; + r |= MMPTR(0xe000202c); + r <<= 8; + r |= MMPTR(0xe0002030); + r <<= 8; + r |= MMPTR(0xe0002034); + return r; +} #define CSR_TIMER0_EV_STATUS_ADDR 0xe0002038 #define CSR_TIMER0_EV_STATUS_SIZE 1 - +static inline unsigned char timer0_ev_status_read(void) { + unsigned char r = MMPTR(0xe0002038); + return r; +} +static inline void timer0_ev_status_write(unsigned char value) { + MMPTR(0xe0002038) = value; +} #define CSR_TIMER0_EV_PENDING_ADDR 0xe000203c #define CSR_TIMER0_EV_PENDING_SIZE 1 - +static inline unsigned char timer0_ev_pending_read(void) { + unsigned char r = MMPTR(0xe000203c); + return r; +} +static inline void timer0_ev_pending_write(unsigned char value) { + MMPTR(0xe000203c) = value; +} #define CSR_TIMER0_EV_ENABLE_ADDR 0xe0002040 #define CSR_TIMER0_EV_ENABLE_SIZE 1 +static inline unsigned char timer0_ev_enable_read(void) { + unsigned char r = MMPTR(0xe0002040); + return r; +} +static inline void timer0_ev_enable_write(unsigned char value) { + MMPTR(0xe0002040) = value; +} +/* uart */ +#define CSR_UART_BASE 0xe0001000 +#define CSR_UART_RXTX_ADDR 0xe0001000 +#define CSR_UART_RXTX_SIZE 1 +static inline unsigned char uart_rxtx_read(void) { + unsigned char r = MMPTR(0xe0001000); + return r; +} +static inline void uart_rxtx_write(unsigned char value) { + MMPTR(0xe0001000) = value; +} #define CSR_UART_TXFULL_ADDR 0xe0001004 #define CSR_UART_TXFULL_SIZE 1 - +static inline unsigned char uart_txfull_read(void) { + unsigned char r = MMPTR(0xe0001004); + return r; +} #define CSR_UART_RXEMPTY_ADDR 0xe0001008 #define CSR_UART_RXEMPTY_SIZE 1 - +static inline unsigned char uart_rxempty_read(void) { + unsigned char r = MMPTR(0xe0001008); + return r; +} #define CSR_UART_EV_STATUS_ADDR 0xe000100c #define CSR_UART_EV_STATUS_SIZE 1 - +static inline unsigned char uart_ev_status_read(void) { + unsigned char r = MMPTR(0xe000100c); + return r; +} +static inline void uart_ev_status_write(unsigned char value) { + MMPTR(0xe000100c) = value; +} #define CSR_UART_EV_PENDING_ADDR 0xe0001010 #define CSR_UART_EV_PENDING_SIZE 1 - +static inline unsigned char uart_ev_pending_read(void) { + unsigned char r = MMPTR(0xe0001010); + return r; +} +static inline void uart_ev_pending_write(unsigned char value) { + MMPTR(0xe0001010) = value; +} #define CSR_UART_EV_ENABLE_ADDR 0xe0001014 #define CSR_UART_EV_ENABLE_SIZE 1 +static inline unsigned char uart_ev_enable_read(void) { + unsigned char r = MMPTR(0xe0001014); + return r; +} +static inline void uart_ev_enable_write(unsigned char value) { + MMPTR(0xe0001014) = value; +} +/* uart_phy */ #define CSR_UART_PHY_BASE 0xe0000800 #define CSR_UART_PHY_TUNING_WORD_ADDR 0xe0000800 #define CSR_UART_PHY_TUNING_WORD_SIZE 4 +static inline unsigned int uart_phy_tuning_word_read(void) { + unsigned int r = MMPTR(0xe0000800); + r <<= 8; + r |= MMPTR(0xe0000804); + r <<= 8; + r |= MMPTR(0xe0000808); + r <<= 8; + r |= MMPTR(0xe000080c); + return r; +} +static inline void uart_phy_tuning_word_write(unsigned int value) { + MMPTR(0xe0000800) = value >> 24; + MMPTR(0xe0000804) = value >> 16; + MMPTR(0xe0000808) = value >> 8; + MMPTR(0xe000080c) = value; +} -/* Constants */ - +/* constants */ #define UART_INTERRUPT 0 #define TIMER0_INTERRUPT 1 #define SYSTEM_CLOCK_FREQUENCY 80000000 #define L2_SIZE 8192 -/**************************************************************************** - * Inline Functions - ****************************************************************************/ - -static inline unsigned char sdram_dfii_control_read(void) -{ - unsigned char r = MMPTR(0xe0004000); - return r; -} - -static inline void sdram_dfii_control_write(unsigned char value) -{ - MMPTR(0xe0004000) = value; -} - -static inline unsigned char sdram_dfii_pi0_command_read(void) -{ - unsigned char r = MMPTR(0xe0004004); - return r; -} - -static inline void sdram_dfii_pi0_command_write(unsigned char value) -{ - MMPTR(0xe0004004) = value; -} - -static inline unsigned char sdram_dfii_pi0_command_issue_read(void) -{ - unsigned char r = MMPTR(0xe0004008); - return r; -} - -static inline void sdram_dfii_pi0_command_issue_write(unsigned char value) -{ - MMPTR(0xe0004008) = value; -} - -static inline unsigned short int sdram_dfii_pi0_address_read(void) -{ - unsigned short int r = MMPTR(0xe000400c); - r <<= 8; - r |= MMPTR(0xe0004010); - return r; -} - -static inline void sdram_dfii_pi0_address_write(unsigned short int value) -{ - MMPTR(0xe000400c) = value >> 8; - MMPTR(0xe0004010) = value; -} - -static inline unsigned char sdram_dfii_pi0_baddress_read(void) -{ - unsigned char r = MMPTR(0xe0004014); - return r; -} - -static inline void sdram_dfii_pi0_baddress_write(unsigned char value) -{ - MMPTR(0xe0004014) = value; -} - -static inline unsigned short int sdram_dfii_pi0_wrdata_read(void) -{ - unsigned short int r = MMPTR(0xe0004018); - r <<= 8; - r |= MMPTR(0xe000401c); - return r; -} - -static inline void sdram_dfii_pi0_wrdata_write(unsigned short int value) -{ - MMPTR(0xe0004018) = value >> 8; - MMPTR(0xe000401c) = value; -} - -static inline unsigned short int sdram_dfii_pi0_rddata_read(void) -{ - unsigned short int r = MMPTR(0xe0004020); - r <<= 8; - r |= MMPTR(0xe0004024); - return r; -} - -/* Timer0 */ - -static inline unsigned int timer0_load_read(void) -{ - unsigned int r = MMPTR(0xe0002000); - r <<= 8; - r |= MMPTR(0xe0002004); - r <<= 8; - r |= MMPTR(0xe0002008); - r <<= 8; - r |= MMPTR(0xe000200c); - return r; -} - -static inline void timer0_load_write(unsigned int value) -{ - MMPTR(0xe0002000) = value >> 24; - MMPTR(0xe0002004) = value >> 16; - MMPTR(0xe0002008) = value >> 8; - MMPTR(0xe000200c) = value; -} - -static inline unsigned int timer0_reload_read(void) -{ - unsigned int r = MMPTR(0xe0002010); - r <<= 8; - r |= MMPTR(0xe0002014); - r <<= 8; - r |= MMPTR(0xe0002018); - r <<= 8; - r |= MMPTR(0xe000201c); - return r; -} - -static inline void timer0_reload_write(unsigned int value) -{ - MMPTR(0xe0002010) = value >> 24; - MMPTR(0xe0002014) = value >> 16; - MMPTR(0xe0002018) = value >> 8; - MMPTR(0xe000201c) = value; -} - -static inline unsigned char timer0_en_read(void) -{ - unsigned char r = MMPTR(0xe0002020); - return r; -} - -static inline void timer0_en_write(unsigned char value) -{ - MMPTR(0xe0002020) = value; -} - -static inline unsigned char timer0_update_value_read(void) -{ - unsigned char r = MMPTR(0xe0002024); - return r; -} - -static inline void timer0_update_value_write(unsigned char value) -{ - MMPTR(0xe0002024) = value; -} - -static inline unsigned int timer0_value_read(void) -{ - unsigned int r = MMPTR(0xe0002028); - r <<= 8; - r |= MMPTR(0xe000202c); - r <<= 8; - r |= MMPTR(0xe0002030); - r <<= 8; - r |= MMPTR(0xe0002034); - return r; -} - -static inline unsigned char timer0_ev_status_read(void) -{ - unsigned char r = MMPTR(0xe0002038); - return r; -} - -static inline void timer0_ev_status_write(unsigned char value) -{ - MMPTR(0xe0002038) = value; -} - -static inline unsigned char timer0_ev_pending_read(void) -{ - unsigned char r = MMPTR(0xe000203c); - return r; -} - -static inline void timer0_ev_pending_write(unsigned char value) -{ - MMPTR(0xe000203c) = value; -} - -static inline unsigned char timer0_ev_enable_read(void) -{ - unsigned char r = MMPTR(0xe0002040); - return r; -} - -static inline void timer0_ev_enable_write(unsigned char value) -{ - MMPTR(0xe0002040) = value; -} - -/* UART */ - -static inline unsigned char uart_rxtx_read(void) -{ - unsigned char r = MMPTR(0xe0001000); - return r; -} - -static inline void uart_rxtx_write(unsigned char value) -{ - MMPTR(0xe0001000) = value; -} - -static inline unsigned char uart_txfull_read(void) -{ - unsigned char r = MMPTR(0xe0001004); - return r; -} - -static inline unsigned char uart_rxempty_read(void) -{ - unsigned char r = MMPTR(0xe0001008); - return r; -} - -static inline unsigned char uart_ev_status_read(void) -{ - unsigned char r = MMPTR(0xe000100c); - return r; -} - -static inline void uart_ev_status_write(unsigned char value) -{ - MMPTR(0xe000100c) = value; -} - -static inline unsigned char uart_ev_pending_read(void) -{ - unsigned char r = MMPTR(0xe0001010); - return r; -} - -static inline void uart_ev_pending_write(unsigned char value) -{ - MMPTR(0xe0001010) = value; -} - -static inline unsigned char uart_ev_enable_read(void) -{ - unsigned char r = MMPTR(0xe0001014); - return r; -} - -static inline void uart_ev_enable_write(unsigned char value) -{ - MMPTR(0xe0001014) = value; -} - -/* uart_phy */ - -static inline unsigned int uart_phy_tuning_word_read(void) -{ - unsigned int r = MMPTR(0xe0000800); - r <<= 8; - r |= MMPTR(0xe0000804); - r <<= 8; - r |= MMPTR(0xe0000808); - r <<= 8; - r |= MMPTR(0xe000080c); - return r; -} - -static inline void uart_phy_tuning_word_write(unsigned int value) -{ - MMPTR(0xe0000800) = value >> 24; - MMPTR(0xe0000804) = value >> 16; - MMPTR(0xe0000808) = value >> 8; - MMPTR(0xe000080c) = value; -} - -#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_CSR_H */ +#endif diff --git a/configs/misoc/include/generated/mem.h b/configs/misoc/include/generated/mem.h index dd6b512e91..7b6839d2a9 100644 --- a/configs/misoc/include/generated/mem.h +++ b/configs/misoc/include/generated/mem.h @@ -1,44 +1,5 @@ -/**************************************************************************** - * configs/misoc/include/generated/mem.h - * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Ramtin Amin - * - * 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 __CONFIGS_MISOC_INCLUDE_GENERATED_MEM_H -#define __CONFIGS_MISOC_INCLUDE_GENERATED_MEM_H - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ +#ifndef __GENERATED_MEM_H +#define __GENERATED_MEM_H #define ROM_BASE 0x00000000 #define ROM_SIZE 0x00008000 @@ -49,4 +10,4 @@ #define MAIN_RAM_BASE 0x40000000 #define MAIN_RAM_SIZE 0x00800000 -#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_MEM_H / +#endif diff --git a/configs/misoc/include/generated/regions.ld b/configs/misoc/include/generated/regions.ld index bd7502729b..eb3a45be98 100644 --- a/configs/misoc/include/generated/regions.ld +++ b/configs/misoc/include/generated/regions.ld @@ -1,5 +1,4 @@ -MEMORY -{ +MEMORY { rom : ORIGIN = 0x00000000, LENGTH = 0x00008000 sram : ORIGIN = 0x10000000, LENGTH = 0x00001000 main_ram : ORIGIN = 0x40000000, LENGTH = 0x00800000 diff --git a/configs/misoc/include/generated/sdram_phy.h b/configs/misoc/include/generated/sdram_phy.h index 2161b7d5b9..9fa49eec22 100644 --- a/configs/misoc/include/generated/sdram_phy.h +++ b/configs/misoc/include/generated/sdram_phy.h @@ -1,56 +1,20 @@ -/**************************************************************************** - * configs/misoc/include/generated/common.h - * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Ramtin Amin - * - * 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 __CONFIGS_MISOC_INCLUDE_GENERATED_SDRAM_PHY_H -#define __CONFIGS_MISOC_INCLUDE_GENERATED_SDRAM_PHY_H - -/**************************************************************************** - * Included Filese - ****************************************************************************/ - -#include "hw/common.h" -#include "hw/flags.h" - -#include - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ +#ifndef __GENERATED_SDRAM_PHY_H +#define __GENERATED_SDRAM_PHY_H +#include +#include +#include #define DFII_NPHASES 1 +static void cdelay(int i); + +static void command_p0(int cmd) +{ + sdram_dfii_pi0_command_write(cmd); + sdram_dfii_pi0_command_issue_write(1); +} + + #define sdram_dfii_pird_address_write(X) sdram_dfii_pi0_address_write(X) #define sdram_dfii_piwr_address_write(X) sdram_dfii_pi0_address_write(X) @@ -62,83 +26,55 @@ #define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE -/**************************************************************************** - * Private Data - ****************************************************************************/ - -const unsigned int sdram_dfii_pix_wrdata_addr[1] = -{ - CSR_SDRAM_DFII_PI0_WRDATA_ADDR +const unsigned int sdram_dfii_pix_wrdata_addr[1] = { + CSR_SDRAM_DFII_PI0_WRDATA_ADDR }; -const unsigned int sdram_dfii_pix_rddata_addr[1] = -{ - CSR_SDRAM_DFII_PI0_RDDATA_ADDR +const unsigned int sdram_dfii_pix_rddata_addr[1] = { + CSR_SDRAM_DFII_PI0_RDDATA_ADDR }; -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static void cdelay(int i); - -static void command_p0(int cmd) -{ - sdram_dfii_pi0_command_write(cmd); - sdram_dfii_pi0_command_issue_write(1); -} - static void init_sequence(void) { - /* Bring CKE high */ + /* Bring CKE high */ + sdram_dfii_pi0_address_write(0x0); + sdram_dfii_pi0_baddress_write(0); + sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N); + cdelay(20000); - sdram_dfii_pi0_address_write(0x0); - sdram_dfii_pi0_baddress_write(0); - sdram_dfii_control_write(DFII_CONTROL_CKE | DFII_CONTROL_ODT | - DFII_CONTROL_RESET_N); - cdelay(20000); + /* Precharge All */ + sdram_dfii_pi0_address_write(0x400); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS); - /* Precharge All */ + /* Load Mode Register / Reset DLL, CL=2, BL=1 */ + sdram_dfii_pi0_address_write(0x120); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); + cdelay(200); - sdram_dfii_pi0_address_write(0x400); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS | DFII_COMMAND_WE | DFII_COMMAND_CS); + /* Precharge All */ + sdram_dfii_pi0_address_write(0x400); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS); - /* Load Mode Register / Reset DLL, CL=2, BL=1 */ + /* Auto Refresh */ + sdram_dfii_pi0_address_write(0x0); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS); + cdelay(4); - sdram_dfii_pi0_address_write(0x120); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_WE | - DFII_COMMAND_CS); - cdelay(200); + /* Auto Refresh */ + sdram_dfii_pi0_address_write(0x0); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS); + cdelay(4); - /* Precharge All */ + /* Load Mode Register / CL=2, BL=1 */ + sdram_dfii_pi0_address_write(0x20); + sdram_dfii_pi0_baddress_write(0); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); + cdelay(200); - sdram_dfii_pi0_address_write(0x400); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS | DFII_COMMAND_WE | DFII_COMMAND_CS); - - /* Auto Refresh */ - - sdram_dfii_pi0_address_write(0x0); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_CS); - cdelay(4); - - /* Auto Refresh */ - - sdram_dfii_pi0_address_write(0x0); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_CS); - cdelay(4); - - /* Load Mode Register / CL=2, BL=1 */ - - sdram_dfii_pi0_address_write(0x20); - sdram_dfii_pi0_baddress_write(0); - command_p0(DFII_COMMAND_RAS | DFII_COMMAND_CAS | DFII_COMMAND_WE | - DFII_COMMAND_CS); - cdelay(200); } - -#endif /* __CONFIGS_MISOC_INCLUDE_GENERATED_SDRAM_PHY_H +#endif From af0d7a96fe1fc6969611eecfd0c3dde48caa6af8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 14:42:17 -0600 Subject: [PATCH 078/155] LM32: More standard, common helper functions --- arch/misoc/src/common/misoc.h | 42 ++++++++ arch/misoc/src/common/misoc_lowputs.c | 62 ++++++++++++ arch/misoc/src/common/misoc_modifyreg16.c | 73 ++++++++++++++ arch/misoc/src/common/misoc_modifyreg32.c | 73 ++++++++++++++ arch/misoc/src/common/misoc_modifyreg8.c | 73 ++++++++++++++ arch/misoc/src/common/misoc_puts.c | 63 ++++++++++++ arch/misoc/src/common/misoc_udelay.c | 117 ++++++++++++++++++++++ arch/misoc/src/lm32/Make.defs | 4 +- arch/misoc/src/lm32/lm32.h | 6 -- 9 files changed, 506 insertions(+), 7 deletions(-) create mode 100644 arch/misoc/src/common/misoc_lowputs.c create mode 100644 arch/misoc/src/common/misoc_modifyreg16.c create mode 100644 arch/misoc/src/common/misoc_modifyreg32.c create mode 100644 arch/misoc/src/common/misoc_modifyreg8.c create mode 100644 arch/misoc/src/common/misoc_puts.c create mode 100644 arch/misoc/src/common/misoc_udelay.c diff --git a/arch/misoc/src/common/misoc.h b/arch/misoc/src/common/misoc.h index d487babab2..e95a60e5d7 100644 --- a/arch/misoc/src/common/misoc.h +++ b/arch/misoc/src/common/misoc.h @@ -60,5 +60,47 @@ void misoc_serial_initialize(void); +/**************************************************************************** + * Name: misoc_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void misoc_puts(const char *str); + +/**************************************************************************** + * Name: misoc_lowputc + * + * Description: + * Low-level, blocking character output the the serial console. + * + ****************************************************************************/ + +void misoc_lowputc(char ch); + +/**************************************************************************** + * Name: misoc_lowputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void misoc_lowputs(const char *str); + +/**************************************************************************** + * Name: modifyreg[N] + * + * Description: + * Atomic modification of registers. + * + ****************************************************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); + #endif /* __ASSEMBLY__ */ #endif /* __ARCH_MISOC_SRC_COMMON_MISOC_H */ diff --git a/arch/misoc/src/common/misoc_lowputs.c b/arch/misoc/src/common/misoc_lowputs.c new file mode 100644 index 0000000000..d384883816 --- /dev/null +++ b/arch/misoc/src/common/misoc_lowputs.c @@ -0,0 +1,62 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_lowputs.c + * + * Copyright (C) 2016 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 "misoc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: misoc_lowputs + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void misoc_lowputs(const char *str) +{ + while (*str) + { + up_lowputc(*str++); + } +} diff --git a/arch/misoc/src/common/misoc_modifyreg16.c b/arch/misoc/src/common/misoc_modifyreg16.c new file mode 100644 index 0000000000..a8502dbe54 --- /dev/null +++ b/arch/misoc/src/common/misoc_modifyreg16.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_modifyreg16.c + * + * Copyright (C) 2016 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 "misoc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg16 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits) +{ + irqstate_t flags; + uint16_t regval; + + flags = enter_critical_section(); + regval = getreg16(addr); + regval &= ~clearbits; + regval |= setbits; + putreg16(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/misoc/src/common/misoc_modifyreg32.c b/arch/misoc/src/common/misoc_modifyreg32.c new file mode 100644 index 0000000000..3e7c2d5419 --- /dev/null +++ b/arch/misoc/src/common/misoc_modifyreg32.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_modifyreg32.c + * + * Copyright (C) 2016 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 "misoc_arch.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg32 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits) +{ + irqstate_t flags; + uint32_t regval; + + flags = enter_critical_section(); + regval = getreg32(addr); + regval &= ~clearbits; + regval |= setbits; + putreg32(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/misoc/src/common/misoc_modifyreg8.c b/arch/misoc/src/common/misoc_modifyreg8.c new file mode 100644 index 0000000000..88ba788e7b --- /dev/null +++ b/arch/misoc/src/common/misoc_modifyreg8.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_modifyreg8.c + * + * Copyright (C) 2016 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 "misoc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: modifyreg8 + * + * Description: + * Atomically modify the specified bits in a memory mapped register + * + ****************************************************************************/ + +void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits) +{ + irqstate_t flags; + uint8_t regval; + + flags = enter_critical_section(); + regval = getreg8(addr); + regval &= ~clearbits; + regval |= setbits; + putreg8(regval, addr); + leave_critical_section(flags); +} diff --git a/arch/misoc/src/common/misoc_puts.c b/arch/misoc/src/common/misoc_puts.c new file mode 100644 index 0000000000..556c23f829 --- /dev/null +++ b/arch/misoc/src/common/misoc_puts.c @@ -0,0 +1,63 @@ +/**************************************************************************** + * arch/misoc/src/common/misoc_puts.c + * + * Copyright (C) 2016 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 "misoc.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: misoc_puts + * + * Description: + * This is a low-level helper function used to support debug. + * + ****************************************************************************/ + +void misoc_puts(const char *str) +{ + while (*str) + { + misoc_putc(*str++); + } +} diff --git a/arch/misoc/src/common/misoc_udelay.c b/arch/misoc/src/common/misoc_udelay.c new file mode 100644 index 0000000000..42bbc1f95a --- /dev/null +++ b/arch/misoc/src/common/misoc_udelay.c @@ -0,0 +1,117 @@ +/**************************************************************************** + * arch/misoc/src/common/up_udelay.c + * + * Copyright (C) 2016 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 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10) +#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100) +#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_udelay + * + * Description: + * Delay inline for the requested number of microseconds. NOTE: Because + * of all of the setup, several microseconds will be lost before the actual + * timing looop begins. Thus, the delay will always be a few microseconds + * longer than requested. + * + * *** NOT multi-tasking friendly *** + * + * ASSUMPTIONS: + * The setting CONFIG_BOARD_LOOPSPERMSEC has been calibrated + * + ****************************************************************************/ + +void up_udelay(useconds_t microseconds) +{ + volatile int i; + + /* We'll do this a little at a time because we expect that the + * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in + * the divisions of its calculation. We'll use the largest values that + * we can in order to prevent significant error buildup in the loops. + */ + + while (microseconds > 1000) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++) + { + } + + microseconds -= 1000; + } + + while (microseconds > 100) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++) + { + } + + microseconds -= 100; + } + + while (microseconds > 10) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++) + { + } + + microseconds -= 10; + } + + while (microseconds > 0) + { + for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++) + { + } + + microseconds--; + } +} diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index 4548e6fe32..e31fd7f50f 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -37,7 +37,9 @@ HEAD_ASRC = lm32_vectors.S CMN_ASRCS = -CMN_CSRCS = misoc_serial.c misoc_mdelay.c +CMN_CSRCS = misoc_lowputs.c misoc_serial.c misoc_mdelay.c +CMN_CSRCS += misoc_modifyreg8.cmisoc_modifyreg16.c misoc_modifyreg32.c +CMN_CSRCS += misoc_puts.c misoc_udelay.c CHIP_ASRCS = lm32_syscall.S diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index ddfd2320e1..a04fb5e571 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -157,12 +157,6 @@ void lm32_timer_initialize(void); void lm32_sigdeliver(void); -/* Atomic modification of registers *****************************************/ - -void modifyreg8(unsigned int addr, uint8_t clearbits, uint8_t setbits); -void modifyreg16(unsigned int addr, uint16_t clearbits, uint16_t setbits); -void modifyreg32(unsigned int addr, uint32_t clearbits, uint32_t setbits); - /* Debug ********************************************************************/ void lm32_dumpstate(void); From 82f880227569c70e24cadd57f7ac9be73b3d867a Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 4 Nov 2016 21:58:31 +0100 Subject: [PATCH 079/155] typo, missing ( --- arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h | 2 +- arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h index 70c9a2a5aa..f7bf4d122c 100644 --- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h +++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_rcc.h @@ -580,7 +580,7 @@ # define RCC_PLLI2SCFGR_PLLI2SQ(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) #define RCC_PLLI2SCFGR_PLLI2SR_SHIFT (28) /* Bits 28-30: PLLI2S division factor for I2S clocks */ #define RCC_PLLI2SCFGR_PLLI2SR_MASK (7 << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) -# define RCC_PLLI2SCFGR_PLLI2SR(n) (uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SR(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) /* PLLSAI configuration register */ diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h index a1b9ed4e32..6c8a784068 100644 --- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h +++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h @@ -601,7 +601,7 @@ # define RCC_PLLI2SCFGR_PLLI2SQ(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SQ_SHIFT) #define RCC_PLLI2SCFGR_PLLI2SR_SHIFT (28) /* Bits 28-30: PLLI2S division factor for I2S clocks */ #define RCC_PLLI2SCFGR_PLLI2SR_MASK (7 << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) -# define RCC_PLLI2SCFGR_PLLI2SR(n) (uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) +# define RCC_PLLI2SCFGR_PLLI2SR(n) ((uint32_t)(n) << RCC_PLLI2SCFGR_PLLI2SR_SHIFT) /* PLLSAI configuration register */ From b1b20080372e2ce32be7be1f3a63d0b3ab129b81 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 4 Nov 2016 22:02:15 +0100 Subject: [PATCH 080/155] bad offset --- arch/arm/src/stm32f7/chip/stm32_otg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/stm32f7/chip/stm32_otg.h b/arch/arm/src/stm32f7/chip/stm32_otg.h index aca7365552..b69ef1a9dd 100644 --- a/arch/arm/src/stm32f7/chip/stm32_otg.h +++ b/arch/arm/src/stm32f7/chip/stm32_otg.h @@ -77,7 +77,7 @@ #define STM32_OTG_CID_OFFSET 0x003c /* Core ID register */ #define STM32_OTG_HPTXFSIZ_OFFSET 0x0100 /* Host periodic transmit FIFO size register */ -#define STM32_OTG_DIEPTXF_OFFSET(n) (104+(((n)-1) << 2)) +#define STM32_OTG_DIEPTXF_OFFSET(n) (0x0104+(((n)-1) << 2)) /* Host-mode control and status registers */ From 0fd38c28836b47ba86321a7a673ce07f06451930 Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Fri, 4 Nov 2016 22:02:46 +0100 Subject: [PATCH 081/155] enable mmc --- configs/stm32f746-ws/nsh/defconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index 5c0a529820..3da3bc4b5f 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -127,7 +127,7 @@ CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32f7" # CONFIG_ARM_TOOLCHAIN_IAR is not set CONFIG_ARM_TOOLCHAIN_GNU=y -# CONFIG_ARMV7M_USEBASEPRI is not set +CONFIG_ARMV7M_USEBASEPRI=y CONFIG_ARCH_HAVE_CMNVECTOR=y CONFIG_ARMV7M_CMNVECTOR=y # CONFIG_ARMV7M_LAZYFPU is not set @@ -312,7 +312,7 @@ CONFIG_STM32F7_OTGFS=y # CONFIG_STM32F7_RNG is not set # CONFIG_STM32F7_SAI1 is not set # CONFIG_STM32F7_SAI2 is not set -##CONFIG_STM32F7_SDMMC1=y +CONFIG_STM32F7_SDMMC1=y # CONFIG_STM32F7_SPDIFRX is not set CONFIG_STM32F7_SPI1=y # CONFIG_STM32F7_SPI2 is not set From 5a9d3b20fab4c07b3a1a735b1699281543338ba0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 17:19:42 -0600 Subject: [PATCH 082/155] LM32: Add README. Update hello defconfig and setenv.sh --- Documentation/README.html | 4 ++- README.txt | 2 ++ arch/misoc/src/lm32/lm32.h | 5 ++-- configs/misoc/README.txt | 54 +++++++++++++++++++++++++++++++++++ configs/misoc/hello/defconfig | 6 ++-- configs/misoc/hello/setenv.sh | 10 ++----- 6 files changed, 67 insertions(+), 14 deletions(-) create mode 100644 configs/misoc/README.txt diff --git a/Documentation/README.html b/Documentation/README.html index baf534cf50..8751b6b37c 100644 --- a/Documentation/README.html +++ b/Documentation/README.html @@ -8,7 +8,7 @@

NuttX README Files

-

Last Updated: November 1, 2016

+

Last Updated: November 4, 2016

@@ -150,6 +150,8 @@ nuttx/ | | `- README.txt | |- mirtoo/ | | `- README.txt + | |- misoc/ + | | `- README.txt | |- moteino-mega/ | | `- README.txt | |- mx1ads/ diff --git a/README.txt b/README.txt index 6203ab4cd1..d2a9a7b9fe 100644 --- a/README.txt +++ b/README.txt @@ -1366,6 +1366,8 @@ nuttx/ | | `- README.txt | |- mirtoo/ | | `- README.txt + | |- misoc/ + | | `- README.txt | |- moteino-mega/ | | `- README.txt | |- mx1ads/ diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index a04fb5e571..7b125578f0 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -109,8 +109,9 @@ * Public Data ****************************************************************************/ -extern volatile uint32_t *g_current_regs; +#ifndef __ASSEMBLY__ +extern volatile uint32_t *g_current_regs; extern uint32_t g_idle_topstack; /**************************************************************************** @@ -121,8 +122,6 @@ extern uint32_t g_idle_topstack; * Public Functions ****************************************************************************/ -#ifndef __ASSEMBLY__ - /* Low level initialization provided by board-level logic ******************/ void lm32_board_initialize(void); diff --git a/configs/misoc/README.txt b/configs/misoc/README.txt new file mode 100644 index 0000000000..1c20544513 --- /dev/null +++ b/configs/misoc/README.txt @@ -0,0 +1,54 @@ +Misoc README +============ + +Buildroot Toolchain +=================== + + A GNU GCC-based toolchain is assumed. The files */setenv.sh should + be modified to point to the correct path to the LM32 GCC toolchain (if + different from the default in your PATH variable). + + If you have no LM32 toolchain, one can be cloned from the NuttX + Bitbucket GIT repository (https://bitbucket.org/nuttx/buildroot). + This GNU toolchain builds and executes in the Linux or Cygwin environment. + + 1. You must have already configured Nuttx in /nuttx. + + cd tools + ./configure.sh misoc/ + + 2. Clone the latest buildroot package into + + git clone git@bitbucket.org:nuttx/buildroot.git + + or + + git clone https://patacongo@bitbucket.org/nuttx/buildroot.git + + 3. cd + + 4. cp lm32-elf-defconfig-6.1.0 .config + + 5. make oldconfig + + 6. make + + 7. Edit setenv.h, if necessary, so that the PATH variable includes + the path to the newly built binaries. + + By default, the tools will be at: + + /build_lm32/staging_dir/bin + + That location can be changed by reconfiguring the .config file. + + See the file configs/README.txt in the buildroot source tree. That has more + detailed PLUS some special instructions that you will need to follow if you + are building a LM32 toolchain for Cygwin under Windows. Also included in + that README file is a FAQ of frequent build issues that their work-arounds. + + In order to use the buildroot toolchain, you also must set the following + in your .config file: + + CONFIG_LM3S_TOOLCHAIN_BUILDROOT=y + diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig index f7b4a0082d..b859e4ab2d 100644 --- a/configs/misoc/hello/defconfig +++ b/configs/misoc/hello/defconfig @@ -16,7 +16,7 @@ CONFIG_HOST_LINUX=y # # Build Configuration # -CONFIG_APPS_DIR="../apps" +# CONFIG_APPS_DIR="../apps" CONFIG_BUILD_FLAT=y # CONFIG_BUILD_2PASS is not set @@ -108,6 +108,8 @@ CONFIG_MISOC_UART1=y CONFIG_MISOC_UART=y CONFIG_MISOC_UART_RX_BUF_SIZE=64 CONFIG_MISOC_UART_TX_BUF_SIZE=64 +# CONFIG_LM32_TOOLCHAIN_BUILDROOT is not set +CONFIG_LM32_TOOLCHAIN_GNUL=y # # Architecture Options @@ -546,10 +548,10 @@ CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 # CONFIG_EXAMPLES_NRF24L01TERM is not set # CONFIG_EXAMPLES_NSH is not set # CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set diff --git a/configs/misoc/hello/setenv.sh b/configs/misoc/hello/setenv.sh index c66c878239..7ba5ee60e7 100644 --- a/configs/misoc/hello/setenv.sh +++ b/configs/misoc/hello/setenv.sh @@ -48,17 +48,11 @@ if [ -z "${PATH_ORIG}" ]; then export PATH_ORIG="${PATH}" fi -# This is the Cygwin path to the location where I installed the WinAVR -# toolchain under windows. This is *not* the default install -# location so you will probably have to edit this. You will also have -# to edit this if you install the Linux AVR toolchain as well -#export TOOLCHAIN_BIN="/cygdrive/c/WinAVR/bin" - # This is the Cygwin path to the location where I build the buildroot # toolchain. -#export TOOLCHAIN_BIN="${WD}/../buildroot/build_avr/staging_dir/bin" +export TOOLCHAIN_BIN="${WD}/../buildroot/build_lm32/staging_dir/bin" # Add the path to the toolchain to the PATH varialble -#export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" +export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" echo "PATH : ${PATH}" From 911e5abb2c7a2eb7a6b4c200871b20390dfab380 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 17:37:10 -0600 Subject: [PATCH 083/155] LM32: Fix various compilation errors that I introduced. --- arch/misoc/include/.gitignore | 3 +++ arch/misoc/src/.gitignore | 5 +++++ arch/misoc/src/common/misoc.h | 14 ++++++++++++++ arch/misoc/src/common/misoc_lowputs.c | 2 +- arch/misoc/src/common/misoc_modifyreg32.c | 2 +- arch/misoc/src/common/misoc_puts.c | 2 +- arch/misoc/src/common/misoc_serial.c | 2 +- arch/misoc/src/lm32/Make.defs | 11 +++++------ arch/misoc/src/lm32/lm32.h | 10 +--------- arch/misoc/src/lm32/lm32_decodeirq.c | 11 ++++++++--- arch/misoc/src/lm32/lm32_doirq.c | 1 - 11 files changed, 40 insertions(+), 23 deletions(-) create mode 100644 arch/misoc/include/.gitignore create mode 100644 arch/misoc/src/.gitignore diff --git a/arch/misoc/include/.gitignore b/arch/misoc/include/.gitignore new file mode 100644 index 0000000000..e6460c4a67 --- /dev/null +++ b/arch/misoc/include/.gitignore @@ -0,0 +1,3 @@ +/board +/chip + diff --git a/arch/misoc/src/.gitignore b/arch/misoc/src/.gitignore new file mode 100644 index 0000000000..dfdfc93543 --- /dev/null +++ b/arch/misoc/src/.gitignore @@ -0,0 +1,5 @@ +/.depend +/Make.dep +/locked.r +/board +/chip diff --git a/arch/misoc/src/common/misoc.h b/arch/misoc/src/common/misoc.h index e95a60e5d7..4726759ea5 100644 --- a/arch/misoc/src/common/misoc.h +++ b/arch/misoc/src/common/misoc.h @@ -42,6 +42,20 @@ ****************************************************************************/ #include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Low-level register access */ + +#define getreg8(a) (*(volatile uint8_t *)(a)) +#define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) +#define getreg16(a) (*(volatile uint16_t *)(a)) +#define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) +#define getreg32(a) (*(volatile uint32_t *)(a)) +#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) /**************************************************************************** * Public Functions diff --git a/arch/misoc/src/common/misoc_lowputs.c b/arch/misoc/src/common/misoc_lowputs.c index d384883816..7b8b962678 100644 --- a/arch/misoc/src/common/misoc_lowputs.c +++ b/arch/misoc/src/common/misoc_lowputs.c @@ -57,6 +57,6 @@ void misoc_lowputs(const char *str) { while (*str) { - up_lowputc(*str++); + misoc_lowputc(*str++); } } diff --git a/arch/misoc/src/common/misoc_modifyreg32.c b/arch/misoc/src/common/misoc_modifyreg32.c index 3e7c2d5419..65eda199ab 100644 --- a/arch/misoc/src/common/misoc_modifyreg32.c +++ b/arch/misoc/src/common/misoc_modifyreg32.c @@ -45,7 +45,7 @@ #include #include -#include "misoc_arch.h" +#include "misoc.h" /**************************************************************************** * Public Functions diff --git a/arch/misoc/src/common/misoc_puts.c b/arch/misoc/src/common/misoc_puts.c index 556c23f829..f048b74795 100644 --- a/arch/misoc/src/common/misoc_puts.c +++ b/arch/misoc/src/common/misoc_puts.c @@ -58,6 +58,6 @@ void misoc_puts(const char *str) { while (*str) { - misoc_putc(*str++); + up_putc(*str++); } } diff --git a/arch/misoc/src/common/misoc_serial.c b/arch/misoc/src/common/misoc_serial.c index af05eb1bb1..c46e83775a 100644 --- a/arch/misoc/src/common/misoc_serial.c +++ b/arch/misoc/src/common/misoc_serial.c @@ -57,7 +57,7 @@ #include #include "chip.h" -#include "hw/flags.h +#include "hw/flags.h" #include "misoc.h" /**************************************************************************** diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index e31fd7f50f..9c0768b2a4 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -38,15 +38,14 @@ HEAD_ASRC = lm32_vectors.S CMN_ASRCS = CMN_CSRCS = misoc_lowputs.c misoc_serial.c misoc_mdelay.c -CMN_CSRCS += misoc_modifyreg8.cmisoc_modifyreg16.c misoc_modifyreg32.c +CMN_CSRCS += misoc_modifyreg8.c misoc_modifyreg16.c misoc_modifyreg32.c CMN_CSRCS += misoc_puts.c misoc_udelay.c CHIP_ASRCS = lm32_syscall.S CHIP_CSRCS = lm32_allocateheap.c lm32_assert.c lm32_blocktask.c CHIP_CSRCS += lm32_copystate.c lm32_createstack.c lm32_decodeirq.c -CHIP_CSRCS += lm32_doirq.c lm32_dumpstate.c lm32_dumpstate.c lm32_exit.c -CHIP_CSRCS += lm32_idle.c lm32_initialize.c lm32_initialstate.c -CHIP_CSRCS += lm32_interruptcontext.c lm32_irq.c lm32_releasepending.c -CHIP_CSRCS += lm32_releasestack.c lm32_stackframe.c lm32_swint.c -CHIP_CSRCS += lm32_unblocktask.c +CHIP_CSRCS += lm32_doirq.c lm32_dumpstate.c lm32_exit.c lm32_idle.c +CHIP_CSRCS += lm32_initialize.c lm32_initialstate.c lm32_interruptcontext.c +CHIP_CSRCS += lm32_irq.c lm32_releasepending.c lm32_releasestack.c +CHIP_CSRCS += lm32_stackframe.c lm32_swint.c lm32_unblocktask.c diff --git a/arch/misoc/src/lm32/lm32.h b/arch/misoc/src/lm32/lm32.h index 7b125578f0..eac1fe7651 100644 --- a/arch/misoc/src/lm32/lm32.h +++ b/arch/misoc/src/lm32/lm32.h @@ -92,15 +92,6 @@ # endif #endif -/* Low-level register access */ - -#define getreg8(a) (*(volatile uint8_t *)(a)) -#define putreg8(v,a) (*(volatile uint8_t *)(a) = (v)) -#define getreg16(a) (*(volatile uint16_t *)(a)) -#define putreg16(v,a) (*(volatile uint16_t *)(a) = (v)) -#define getreg32(a) (*(volatile uint32_t *)(a)) -#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) - /**************************************************************************** * Public Types ****************************************************************************/ @@ -143,6 +134,7 @@ void lm32_irq_initialize(void); /* Interrupt decode *********************************************************/ uint32_t *lm32_decodeirq(uint32_t intstat, uint32_t *regs); +uint32_t *lm32_doirq(int irq, uint32_t *regs); /* Software interrupts ******************************************************/ diff --git a/arch/misoc/src/lm32/lm32_decodeirq.c b/arch/misoc/src/lm32/lm32_decodeirq.c index 198445deed..1cb792cedf 100644 --- a/arch/misoc/src/lm32/lm32_decodeirq.c +++ b/arch/misoc/src/lm32/lm32_decodeirq.c @@ -39,6 +39,11 @@ #include +#include +#include + +#include + #include "chip.h" #include "lm32.h" @@ -69,13 +74,13 @@ uint32_t *lm32_decodeirq(uint32_t intstat, uint32_t *regs) /* Decode and dispatch interrupts */ - for (irq = 0; irq < MISOC_NINTERRUPTS & instat != 0; i++) + for (irq = 0; irq < MISOC_NINTERRUPTS && intstat != 0; irq++) { uint32_t bit = (1 << irq); /* Is this interrupt pending? */ - if ((instat & bit) != 0) + if ((intstat & bit) != 0) { /* Yes.. Dispatch the interrupt */ /* REVIST: Do I need to acknowledge the interrupt first? */ @@ -87,7 +92,7 @@ uint32_t *lm32_decodeirq(uint32_t intstat, uint32_t *regs) * break out of the loop early. */ - instat &= ~bit; + intstat &= ~bit; } } diff --git a/arch/misoc/src/lm32/lm32_doirq.c b/arch/misoc/src/lm32/lm32_doirq.c index 25cc30e2a0..cf42f4e699 100644 --- a/arch/misoc/src/lm32/lm32_doirq.c +++ b/arch/misoc/src/lm32/lm32_doirq.c @@ -126,7 +126,6 @@ uint32_t *lm32_doirq(int irq, uint32_t *regs) /* Unmask the last interrupt (global interrupts are still disabled) */ up_enable_irq(irq); -#endif board_autoled_off(LED_INIRQ); return regs; } From 6cc73f04057d737e2fa6079a5733fb9e5f036e00 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 17:42:10 -0600 Subject: [PATCH 084/155] LM32: Fix a copy/paste error in lm32_vectors.S that I introduced. --- arch/misoc/src/lm32/lm32_vectors.S | 64 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index a7d7d9b621..aa66237565 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -190,7 +190,7 @@ _do_reset: /* ra needs to be moved from initial stack location */ - w r1, (sp+ 136) + lw r1, (sp+ 136) sw (sp+REG_RA), r1 /* Get IE/REG_INT_CTX */ @@ -206,39 +206,39 @@ _do_reset: .restore_all_and_eret: /* r1 should have the place where we restore ! */ - w r2, (r1+REG_X2) - w r3, (r1+REG_X3) - w r4, (r1+REG_X4) - w r5, (r1+REG_X5) - w r6, (r1+REG_X6) - w r7, (r1+REG_X7) - w r8, (r1+REG_X8) - w r9, (r1+REG_X9) - w r10, (r1+REG_X10) - w r11, (r1+REG_X11) - w r12, (r1+REG_X12) - w r13, (r1+REG_X13) - w r14, (r1+REG_X14) - w r15, (r1+REG_X15) - w r16, (r1+REG_X16) - w r17, (r1+REG_X17) - w r18, (r1+REG_X18) - w r19, (r1+REG_X19) - w r20, (r1+REG_X20) - w r21, (r1+REG_X21) - w r22, (r1+REG_X22) - w r23, (r1+REG_X23) - w r24, (r1+REG_X24) - w r25, (r1+REG_X25) - w r26, (r1+REG_GP) - w r27, (r1+REG_FP) - w r28, (r1+REG_SP) - w r29, (r1+REG_RA) - w r30, (r1+REG_EA) - w r31, (r1+REG_BA) + lw r2, (r1+REG_X2) + lw r3, (r1+REG_X3) + lw r4, (r1+REG_X4) + lw r5, (r1+REG_X5) + lw r6, (r1+REG_X6) + lw r7, (r1+REG_X7) + lw r8, (r1+REG_X8) + lw r9, (r1+REG_X9) + lw r10, (r1+REG_X10) + lw r11, (r1+REG_X11) + lw r12, (r1+REG_X12) + lw r13, (r1+REG_X13) + lw r14, (r1+REG_X14) + lw r15, (r1+REG_X15) + lw r16, (r1+REG_X16) + lw r17, (r1+REG_X17) + lw r18, (r1+REG_X18) + lw r19, (r1+REG_X19) + lw r20, (r1+REG_X20) + lw r21, (r1+REG_X21) + lw r22, (r1+REG_X22) + lw r23, (r1+REG_X23) + lw r24, (r1+REG_X24) + lw r25, (r1+REG_X25) + lw r26, (r1+REG_GP) + lw r27, (r1+REG_FP) + lw r28, (r1+REG_SP) + lw r29, (r1+REG_RA) + lw r30, (r1+REG_EA) + lw r31, (r1+REG_BA) lw r1, (r1+REG_INT_CTX) wcsr IE, r1 - w r1, (r1+REG_X1) + lw r1, (r1+REG_X1) addi sp, sp, 136 eret From 0b83e8afaa900d89148846ec0c8e0e5a83c8475a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 17:48:24 -0600 Subject: [PATCH 085/155] LM32: Remove some extra spacing --- arch/misoc/src/lm32/lm32_vectors.S | 60 +++++++++++++++--------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index aa66237565..80645f834d 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -206,39 +206,39 @@ _do_reset: .restore_all_and_eret: /* r1 should have the place where we restore ! */ - lw r2, (r1+REG_X2) - lw r3, (r1+REG_X3) - lw r4, (r1+REG_X4) - lw r5, (r1+REG_X5) - lw r6, (r1+REG_X6) - lw r7, (r1+REG_X7) - lw r8, (r1+REG_X8) - lw r9, (r1+REG_X9) + lw r2, (r1+REG_X2) + lw r3, (r1+REG_X3) + lw r4, (r1+REG_X4) + lw r5, (r1+REG_X5) + lw r6, (r1+REG_X6) + lw r7, (r1+REG_X7) + lw r8, (r1+REG_X8) + lw r9, (r1+REG_X9) lw r10, (r1+REG_X10) - lw r11, (r1+REG_X11) - lw r12, (r1+REG_X12) - lw r13, (r1+REG_X13) - lw r14, (r1+REG_X14) - lw r15, (r1+REG_X15) - lw r16, (r1+REG_X16) - lw r17, (r1+REG_X17) - lw r18, (r1+REG_X18) - lw r19, (r1+REG_X19) - lw r20, (r1+REG_X20) - lw r21, (r1+REG_X21) - lw r22, (r1+REG_X22) - lw r23, (r1+REG_X23) - lw r24, (r1+REG_X24) - lw r25, (r1+REG_X25) - lw r26, (r1+REG_GP) - lw r27, (r1+REG_FP) - lw r28, (r1+REG_SP) - lw r29, (r1+REG_RA) - lw r30, (r1+REG_EA) - lw r31, (r1+REG_BA) + lw r11, (r1+REG_X11) + lw r12, (r1+REG_X12) + lw r13, (r1+REG_X13) + lw r14, (r1+REG_X14) + lw r15, (r1+REG_X15) + lw r16, (r1+REG_X16) + lw r17, (r1+REG_X17) + lw r18, (r1+REG_X18) + lw r19, (r1+REG_X19) + lw r20, (r1+REG_X20) + lw r21, (r1+REG_X21) + lw r22, (r1+REG_X22) + lw r23, (r1+REG_X23) + lw r24, (r1+REG_X24) + lw r25, (r1+REG_X25) + lw r26, (r1+REG_GP) + lw r27, (r1+REG_FP) + lw r28, (r1+REG_SP) + lw r29, (r1+REG_RA) + lw r30, (r1+REG_EA) + lw r31, (r1+REG_BA) lw r1, (r1+REG_INT_CTX) wcsr IE, r1 - lw r1, (r1+REG_X1) + lw r1, (r1+REG_X1) addi sp, sp, 136 eret From 1c05eb651c45830ae6f4256883493a4d5e8f6f68 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 19:29:54 -0600 Subject: [PATCH 086/155] LM32: lm32_vectors.S needs to call lm32_doirq(), passing two parameters --- arch/misoc/src/lm32/lm32_vectors.S | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index 80645f834d..f3dd955f86 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -38,7 +38,7 @@ * Included Files ****************************************************************************/ -#include +#include /**************************************************************************** * Exception handlers - Must be 32 bytes long. @@ -121,12 +121,11 @@ _interrupt_handler: _syscall_handler: sw (sp+0), ra calli .save_all - rcsr r1, IP - calli lm32_swint + mvi r1, MISOC_IRQ_SWINT + rcsr r2, IP + calli lm32_doirq bi .restore_all_and_eret nop - nop - nop _do_reset: /* Setup stack and global pointer */ From 3f150daf9657df24b3049ed2844c1a1f104a3fa0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Fri, 4 Nov 2016 19:41:43 -0600 Subject: [PATCH 087/155] LM32: Oops, missed one line of code in the manual application of a patch --- arch/misoc/src/lm32/lm32_vectors.S | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index f3dd955f86..4a0e6cd095 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -120,6 +120,7 @@ _interrupt_handler: _syscall_handler: sw (sp+0), ra + addi ea, ea, 4 calli .save_all mvi r1, MISOC_IRQ_SWINT rcsr r2, IP From b0dffdc2ca9a6d177dcf5114f32a96d934cc92b4 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 5 Nov 2016 07:25:05 -0600 Subject: [PATCH 088/155] Fix a number of header files with mismatched 'extern C {' and '}' --- arch/arm/src/kl/kl_spi.h | 5 +++++ arch/arm/src/lpc43xx/chip/lpc43_ethernet.h | 10 ---------- arch/arm/src/lpc43xx/lpc43_ethernet.h | 3 ++- arch/mips/src/pic32mz/pic32mz-dma.h | 5 +++++ arch/risc-v/src/common/up_internal.h | 16 ++++++++++------ arch/xtensa/src/esp32/esp32_gpio.h | 9 ++------- configs/fire-stm32v2/include/board.h | 8 +++++++- drivers/usbhost/usbhost_composite.h | 9 +++++++++ fs/aio/aio.h | 5 +++++ include/nuttx/arch.h | 3 +-- include/nuttx/binfmt/symtab.h | 5 +++++ libc/aio/aio.h | 5 +++++ net/loopback/loopback.h | 5 +++++ 13 files changed, 61 insertions(+), 27 deletions(-) diff --git a/arch/arm/src/kl/kl_spi.h b/arch/arm/src/kl/kl_spi.h index 466ab832f8..227ab9e6c5 100644 --- a/arch/arm/src/kl/kl_spi.h +++ b/arch/arm/src/kl/kl_spi.h @@ -126,6 +126,11 @@ int kl_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); #endif #endif +#if defined(__cplusplus) +} +#endif +#undef EXTERN + #endif /* __ASSEMBLY__ */ #endif /* CONFIG_KL_SPI0 || CONFIG_KL_SPI1 */ #endif /* __ARCH_ARM_SRC_KL_KL_SPI_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h b/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h index 6da125a6fe..d03ed7123b 100644 --- a/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h +++ b/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h @@ -653,15 +653,5 @@ struct eth_rxdesc_s * Public Functions ****************************************************************************************************/ -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - #endif /* __ASSEMBLY__ */ #endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ETHERNET_H */ - diff --git a/arch/arm/src/lpc43xx/lpc43_ethernet.h b/arch/arm/src/lpc43xx/lpc43_ethernet.h index 55888fc727..7d60a43697 100644 --- a/arch/arm/src/lpc43xx/lpc43_ethernet.h +++ b/arch/arm/src/lpc43xx/lpc43_ethernet.h @@ -55,7 +55,8 @@ #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif diff --git a/arch/mips/src/pic32mz/pic32mz-dma.h b/arch/mips/src/pic32mz/pic32mz-dma.h index 99cc6c47c5..3bea2172ee 100644 --- a/arch/mips/src/pic32mz/pic32mz-dma.h +++ b/arch/mips/src/pic32mz/pic32mz-dma.h @@ -224,5 +224,10 @@ void pic32mx_dmadump(DMA_HANDLE handle, const struct pic32mx_dmaregs_s *regs, #endif #endif +#if defined(__cplusplus) +} +#endif +#undef EXTERN + #endif /* __ASSEMBLY__ */ #endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_DMA_H */ diff --git a/arch/risc-v/src/common/up_internal.h b/arch/risc-v/src/common/up_internal.h index f4481a2269..f18d937150 100644 --- a/arch/risc-v/src/common/up_internal.h +++ b/arch/risc-v/src/common/up_internal.h @@ -104,13 +104,17 @@ * Public Variables ****************************************************************************/ -extern volatile uint32_t *g_current_regs; +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif -extern uint32_t g_idle_topstack; - -/**************************************************************************** - * Inline Functions - ****************************************************************************/ +EXTERN volatile uint32_t *g_current_regs; +EXTERN uint32_t g_idle_topstack; /**************************************************************************** * Public Functions diff --git a/arch/xtensa/src/esp32/esp32_gpio.h b/arch/xtensa/src/esp32/esp32_gpio.h index ea09df2439..e4b647b976 100644 --- a/arch/xtensa/src/esp32/esp32_gpio.h +++ b/arch/xtensa/src/esp32/esp32_gpio.h @@ -199,13 +199,6 @@ void esp32_gpioirqdisable(int irq); # define esp32_gpioirqdisable(irq) #endif -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __ASSEMBLY__ */ - int digitalRead(uint8_t pin); void attachInterrupt(uint8_t pin, void (*)(void), int mode); @@ -214,5 +207,7 @@ void detachInterrupt(uint8_t pin); #ifdef __cplusplus } #endif +#undef EXTERN +#endif /* __ASSEMBLY__ */ #endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_GPIO_H */ diff --git a/configs/fire-stm32v2/include/board.h b/configs/fire-stm32v2/include/board.h index 0f9e7c11aa..4319e397a9 100644 --- a/configs/fire-stm32v2/include/board.h +++ b/configs/fire-stm32v2/include/board.h @@ -371,7 +371,8 @@ #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif @@ -406,5 +407,10 @@ void stm32_boardinitialize(void); void fire_lcdclear(uint16_t color); #endif +#if defined(__cplusplus) +} +#endif +#undef EXTERN + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_FIRE_STM32V2_INCLUDE_BOARD_H */ diff --git a/drivers/usbhost/usbhost_composite.h b/drivers/usbhost/usbhost_composite.h index 4d1e35d0d1..765624da2a 100644 --- a/drivers/usbhost/usbhost_composite.h +++ b/drivers/usbhost/usbhost_composite.h @@ -51,6 +51,15 @@ * Public Function Prototypes ****************************************************************************/ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + /**************************************************************************** * Name: usbhost_composite * diff --git a/fs/aio/aio.h b/fs/aio/aio.h index f74269a19a..73ff7faa79 100644 --- a/fs/aio/aio.h +++ b/fs/aio/aio.h @@ -277,5 +277,10 @@ int aio_queue(FAR struct aio_container_s *aioc, worker_t worker); int aio_signal(pid_t pid, FAR struct aiocb *aiocbp); +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* CONFIG_FS_AIO */ #endif /* __FS_AIO_AIO_H */ diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 1ef8efe4b1..8b83308fc8 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -2294,9 +2294,8 @@ void arch_sporadic_resume(FAR struct tcb_s *tcb); #endif #undef EXTERN -#ifdef __cplusplus +#if defined(__cplusplus) } #endif #endif /* __INCLUDE_NUTTX_ARCH_H */ - diff --git a/include/nuttx/binfmt/symtab.h b/include/nuttx/binfmt/symtab.h index 9e51ca3539..affb7cda17 100644 --- a/include/nuttx/binfmt/symtab.h +++ b/include/nuttx/binfmt/symtab.h @@ -90,4 +90,9 @@ void exec_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols); void exec_setsymtab(FAR const struct symtab_s *symtab, int nsymbols); +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* __INCLUDE_NUTTX_BINFMT_SYMTAB_H */ diff --git a/libc/aio/aio.h b/libc/aio/aio.h index f28340f3c2..f61e6908f5 100644 --- a/libc/aio/aio.h +++ b/libc/aio/aio.h @@ -69,5 +69,10 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* CONFIG_FS_AIO */ #endif /* __LIBC_AIO_AIO_H */ diff --git a/net/loopback/loopback.h b/net/loopback/loopback.h index 8529fdbd1c..a881f46fdb 100644 --- a/net/loopback/loopback.h +++ b/net/loopback/loopback.h @@ -68,5 +68,10 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +#undef EXTERN +#ifdef __cplusplus +} +#endif + #endif /* CONFIG_NET_LOOPBACK */ #endif /* __NET_LOOPBACK_LOOBACK_H */ From 479c9776a78f551dca293df611947f6722503e8c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 5 Nov 2016 08:42:33 -0600 Subject: [PATCH 089/155] configs/misoc: Should not have CONFIG_MM_SMALL set in defconfig. --- configs/misoc/hello/defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig index b859e4ab2d..39eddd2435 100644 --- a/configs/misoc/hello/defconfig +++ b/configs/misoc/hello/defconfig @@ -443,7 +443,7 @@ CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y # # Memory Management # -CONFIG_MM_SMALL=y +# CONFIG_MM_SMALL is not set CONFIG_MM_REGIONS=1 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set From 5dc9d963f64364aee3bcea5d153ce722e1cef569 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 5 Nov 2016 08:49:50 -0600 Subject: [PATCH 090/155] configs/misco: CONFIG_DEFAULT_SMALL should not be set either. It is really too late now, hoever, because all of the small defaults have already been set. --- configs/misoc/hello/defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig index 39eddd2435..dddddfd3ee 100644 --- a/configs/misoc/hello/defconfig +++ b/configs/misoc/hello/defconfig @@ -7,7 +7,7 @@ # Build Setup # # CONFIG_EXPERIMENTAL is not set -CONFIG_DEFAULT_SMALL=y +# CONFIG_DEFAULT_SMALL is not set CONFIG_HOST_LINUX=y # CONFIG_HOST_OSX is not set # CONFIG_HOST_WINDOWS is not set From 6f1c5e7b43b4a9ef3be51d1f8a54fe426ee1e247 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 5 Nov 2016 09:44:29 -0600 Subject: [PATCH 091/155] Add some comments. --- mm/mm_heap/mm_initialize.c | 2 +- sched/semaphore/sem_post.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index cacff9c047..7696676fde 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -79,12 +79,12 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart, # define IDX 0 #endif +#if defined(CONFIG_MM_SMALL) && !defined(CONFIG_SMALL_MEMORY) /* If the MCU handles wide addresses but the memory manager is configured * for a small heap, then verify that the caller is not doing something * crazy. */ -#if defined(CONFIG_MM_SMALL) && !defined(CONFIG_SMALL_MEMORY) DEBUGASSERT(heapsize <= MMSIZE_MAX+1); #endif diff --git a/sched/semaphore/sem_post.c b/sched/semaphore/sem_post.c index 1c90449953..47487db42a 100644 --- a/sched/semaphore/sem_post.c +++ b/sched/semaphore/sem_post.c @@ -98,7 +98,22 @@ int sem_post(FAR sem_t *sem) flags = enter_critical_section(); - /* Perform the semaphore unlock operation. */ + /* Perform the semaphore unlock operation, releasing this task as a + * holder then also incrementing the count on the semaphore. + * + * NOTE: When semaphores are used for signaling purposes, the holder + * of the semaphore may not be this thread! In this case, + * sem_releaseholder() will do nothing. + * + * In the case of a mutex this could be simply resolved since there is + * only one holder but for the case of counting semaphores, there may + * be many holders and if the holder is not this thread, then it is + * not possible to know which thread/holder should be released. + * + * For this reason, it is recommended that priority inheritance be + * disabled via sem_setprotocol(SEM_PRIO_NONE) when the semahore is + * initialixed if the semaphore is to used for signaling purposes. + */ ASSERT(sem->semcount < SEM_VALUE_MAX); sem_releaseholder(sem); From 796969f6b650b9d025c6c77c32b5944dc7cd22d5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 5 Nov 2016 11:06:52 -0600 Subject: [PATCH 092/155] Update TODO. Provide do-nothing stubs for mutex attribute interfaces if features not enabled. pthread_cond includes a signaling semaphore and should call sem_setprotocol. --- TODO | 16 +++++++++++- arch/sim/src/up_uartwait.c | 2 +- include/pthread.h | 25 ++++++------------ libc/pthread/Make.defs | 27 +++++++++----------- libc/pthread/pthread_mutexattr_getprotocol.c | 5 ++++ libc/pthread/pthread_mutexattr_gettype.c | 10 ++++---- libc/pthread/pthread_mutexattr_setprotocol.c | 11 ++++++++ libc/pthread/pthread_mutexattr_settype.c | 13 +++++++--- sched/pthread/pthread_condinit.c | 22 +++++++++++----- 9 files changed, 81 insertions(+), 50 deletions(-) diff --git a/TODO b/TODO index 62d2e562ce..f770f9a2f6 100644 --- a/TODO +++ b/TODO @@ -216,7 +216,7 @@ o Task/Scheduler (sched/) Status: Open Priority: Medium-ish - Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE USED AS IPC + Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE/MUTX IS USED AS IPC Description: Semaphores have multiple uses. The typical usage is where the semaphore is used as lock on one or more resources. In this typical case, priority inheritance works perfectly: The @@ -264,6 +264,20 @@ o Task/Scheduler (sched/) The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after the sem_init() call so that there will be no priority inheritance operations on this semaphore used for signalling. + + NOTE also that in NuttX, pthread mutexes are build on top of + binary semaphores. As a result, the above recommendation also + applies when pthread mutexes are used for inter-thread + signaling. That is, a mutex that is used for signaling should + be initialize like this (simplified, no error checking here): + + pthread_mutexattr_t attr; + pthread_mutex_t mutex; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_PRIO_NONE); + pthread_mutex_init(&mutex, &attr); + Status: Open Priority: High. If you have priority inheritance enabled and you use semaphores for signalling events, then you *must* call diff --git a/arch/sim/src/up_uartwait.c b/arch/sim/src/up_uartwait.c index 50f6b5f281..681e87dcdd 100644 --- a/arch/sim/src/up_uartwait.c +++ b/arch/sim/src/up_uartwait.c @@ -39,7 +39,7 @@ #include -#include +#include #include "up_internal.h" diff --git a/include/pthread.h b/include/pthread.h index 1c368d737b..ac495e44c2 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -96,12 +96,10 @@ * An implementation is allowed to map this mutex to one of the other mutex types. */ -#ifdef CONFIG_MUTEX_TYPES -# define PTHREAD_MUTEX_NORMAL 0 -# define PTHREAD_MUTEX_ERRORCHECK 1 -# define PTHREAD_MUTEX_RECURSIVE 2 -# define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL -#endif +#define PTHREAD_MUTEX_NORMAL 0 +#define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL /* Valid ranges for the pthread stacksize attribute */ @@ -389,10 +387,12 @@ int pthread_mutexattr_getpshared(FAR const pthread_mutexattr_t *attr, FAR int *pshared); int pthread_mutexattr_setpshared(FAR pthread_mutexattr_t *attr, int pshared); -#ifdef CONFIG_MUTEX_TYPES int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type); int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); -#endif +int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, + FAR int *protocol); +int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, + int protocol); /* The following routines create, delete, lock and unlock mutexes. */ @@ -403,15 +403,6 @@ int pthread_mutex_lock(FAR pthread_mutex_t *mutex); int pthread_mutex_trylock(FAR pthread_mutex_t *mutex); int pthread_mutex_unlock(FAR pthread_mutex_t *mutex); -#ifdef CONFIG_PRIORITY_INHERITANCE -/* Manage priority inheritance */ - -int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, - FAR int *protocol); -int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, - int protocol); -#endif - /* Operations on condition variables */ int pthread_condattr_init(FAR pthread_condattr_t *attr); diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index 9d343f6052..bbb3280959 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -35,27 +35,24 @@ # Add the pthread C files to the build -CSRCS += pthread_attr_init.c pthread_attr_destroy.c \ - pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c \ - pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c \ - pthread_attr_setstacksize.c pthread_attr_getstacksize.c \ - pthread_attr_setschedparam.c pthread_attr_getschedparam.c \ - pthread_barrierattr_init.c pthread_barrierattr_destroy.c \ - pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c \ - pthread_condattr_init.c pthread_condattr_destroy.c \ - pthread_mutexattr_init.c pthread_mutexattr_destroy.c \ - pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c +CSRCS += pthread_attr_init.c pthread_attr_destroy.c +CSRCS += pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c +CSRCS += pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c +CSRCS += pthread_attr_setstacksize.c pthread_attr_getstacksize.c +CSRCS += pthread_attr_setschedparam.c pthread_attr_getschedparam.c +CSRCS += pthread_barrierattr_init.c pthread_barrierattr_destroy.c +CSRCS += pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c +CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c +CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c +CSRCS += pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c +CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c +CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c ifeq ($(CONFIG_SMP),y) CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c endif ifeq ($(CONFIG_MUTEX_TYPES),y) -CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c -endif - -ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c endif ifeq ($(CONFIG_BUILD_PROTECTED),y) diff --git a/libc/pthread/pthread_mutexattr_getprotocol.c b/libc/pthread/pthread_mutexattr_getprotocol.c index f7851855ac..f803006bb2 100644 --- a/libc/pthread/pthread_mutexattr_getprotocol.c +++ b/libc/pthread/pthread_mutexattr_getprotocol.c @@ -68,6 +68,11 @@ int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, { DEBUGASSERT(attr != NULL && protocol != NULL); +#ifdef CONFIG_PRIORITY_INHERITANCE linfo("Returning %d\n", attr->proto); return attr->proto; +#else + linfo("Returning %d\n", PTHREAD_PRIO_NONE); + return PTHREAD_PRIO_NONE; +#endif } diff --git a/libc/pthread/pthread_mutexattr_gettype.c b/libc/pthread/pthread_mutexattr_gettype.c index c9703f5c01..9f057ae11d 100644 --- a/libc/pthread/pthread_mutexattr_gettype.c +++ b/libc/pthread/pthread_mutexattr_gettype.c @@ -41,8 +41,6 @@ #include #include -#ifdef CONFIG_MUTEX_TYPES - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -67,13 +65,15 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) { - if (attr && type) + if (attr != NULL && type != NULL) { +#ifdef CONFIG_MUTEX_TYPES *type = attr->type; +#else + *type = PTHREAD_MUTEX_NORMAL; +#endif return 0; } return EINVAL; } - -#endif /* CONFIG_MUTEX_TYPES */ diff --git a/libc/pthread/pthread_mutexattr_setprotocol.c b/libc/pthread/pthread_mutexattr_setprotocol.c index 621a94d1c1..0d128e0480 100644 --- a/libc/pthread/pthread_mutexattr_setprotocol.c +++ b/libc/pthread/pthread_mutexattr_setprotocol.c @@ -69,6 +69,7 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, linfo("attr=0x%p protocol=%d\n", attr, protocol); DEBUGASSERT(attr != NULL); +#ifdef CONFIG_PRIORITY_INHERITANCE if (protocol >= PTHREAD_PRIO_NONE && protocol <= PTHREAD_PRIO_PROTECT) { attr->proto = protocol; @@ -76,4 +77,14 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, } return EINVAL; + +#else + if (protocol == PTHREAD_PRIO_NONE) + { + return OK; + } + + return ENOSYS; +#endif + } diff --git a/libc/pthread/pthread_mutexattr_settype.c b/libc/pthread/pthread_mutexattr_settype.c index 9922a34355..b43e86fc12 100644 --- a/libc/pthread/pthread_mutexattr_settype.c +++ b/libc/pthread/pthread_mutexattr_settype.c @@ -41,8 +41,6 @@ #include #include -#ifdef CONFIG_MUTEX_TYPES - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -69,10 +67,17 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) { if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_RECURSIVE) { +#ifdef CONFIG_MUTEX_TYPES attr->type = type; +#else + if (type != PTHREAD_MUTEX_NORMAL) + { + return ENOSYS; + } +#endif + return OK; } + return EINVAL; } - -#endif /* CONFIG_MUTEX_TYPES */ diff --git a/sched/pthread/pthread_condinit.c b/sched/pthread/pthread_condinit.c index 73a6423c69..7368e0fb5a 100644 --- a/sched/pthread/pthread_condinit.c +++ b/sched/pthread/pthread_condinit.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_condinit.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -40,9 +40,12 @@ #include #include +#include #include #include +#include + #include "pthread/pthread.h" /**************************************************************************** @@ -71,23 +74,28 @@ int pthread_cond_init(FAR pthread_cond_t *cond, FAR const pthread_condattr_t *at sinfo("cond=0x%p attr=0x%p\n", cond, attr); - if (!cond) + if (cond == NULL) { ret = EINVAL; } - /* Initialize the semaphore contained in the condition structure - * with initial count = 0 + /* Initialize the semaphore contained in the condition structure with + * initial count = 0 */ else if (sem_init((FAR sem_t *)&cond->sem, 0, 0) != OK) { ret = EINVAL; } + else + { + /* The contained semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + sem_setprotocol(&cond->sem, SEM_PRIO_NONE); + } sinfo("Returning %d\n", ret); return ret; } - - - From 45f549d2b833fbfebf2439108c805de678646d3a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 5 Nov 2016 17:39:06 -0600 Subject: [PATCH 093/155] LM32: Back out part of last change --- arch/misoc/src/lm32/lm32_vectors.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index 4a0e6cd095..dc62cfe25e 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -123,10 +123,10 @@ _syscall_handler: addi ea, ea, 4 calli .save_all mvi r1, MISOC_IRQ_SWINT - rcsr r2, IP calli lm32_doirq bi .restore_all_and_eret nop + nop _do_reset: /* Setup stack and global pointer */ From 96a200a71cf956019954a475cb3eaf784b4dab3a Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:15:53 +0900 Subject: [PATCH 094/155] ARMv7-R: fix typo fix trivial typo: s/ARMv7-A/ARMv7-R/ Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig index 0582a4fee3..e87315574d 100644 --- a/arch/arm/src/armv7-r/Kconfig +++ b/arch/arm/src/armv7-r/Kconfig @@ -3,7 +3,7 @@ # see the file kconfig-language.txt in the NuttX tools repository. # -comment "ARMv7-A Configuration Options" +comment "ARMv7-R Configuration Options" config ARMV7R_MEMINIT bool From af6e4f59c646017edf5fec9061cf280024705fbe Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:32:03 +0900 Subject: [PATCH 095/155] ARMv7-R: fix compilation error This commit fixes compilation errors on MPU support for ARMv7-R. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index e9e29cf13f..762bd92e7e 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -49,6 +49,8 @@ # include # include "up_arch.h" +# include "cache.h" +# include "sctlr.h" # include "cp15.h" #endif @@ -66,7 +68,7 @@ /* Region Base Address Register Definitions */ -#define MPU_RBAR_MASK 0xfffffffc +#define MPU_RBAR_ADDR_MASK 0xfffffffc /* Region Size and Enable Register */ @@ -201,7 +203,7 @@ static inline unsigned int mpu_get_mpuir(void) unsigned int mpuir; __asm__ __volatile__ ( - "\tmrc " CP15_MPUIR(%0) + "\tmrc p15, 0, %0, c0, c0, 4" : "=r" (mpuir) : : "memory" @@ -222,7 +224,7 @@ static inline void mpu_set_drbar(unsigned int drbar) { __asm__ __volatile__ ( - "\tmcr " CP15_DRBAR(%0) + "\tmcr p15, 0, %0, c6, c1, 0" : : "r" (drbar) : "memory" @@ -241,7 +243,7 @@ static inline void mpu_set_drsr(unsigned int drsr) { __asm__ __volatile__ ( - "\tmcr " CP15_DRSR(%0) + "\tmcr p15, 0, %0, c6, c1, 2" : : "r" (drsr) : "memory" @@ -260,7 +262,7 @@ static inline void mpu_set_dracr(unsigned int dracr) { __asm__ __volatile__ ( - "\tmcr " CP15_DRACR(%0) + "\tmcr p15, 0, %0, c6, c1, 4" : : "r" (dracr) : "memory" @@ -280,7 +282,7 @@ static inline void mpu_set_irbar(unsigned int irbar) { __asm__ __volatile__ ( - "\tmcr " CP15_IRBAR(%0) + "\tmcr p15, 0, %0, c6, c1, 1" : : "r" (irbar) : "memory" @@ -301,7 +303,7 @@ static inline void mpu_set_irsr(unsigned int irsr) { __asm__ __volatile__ ( - "\tmcr " CP15_IRSR(%0) + "\tmcr p15, 0, %0, c6, c1, 3" : : "r" (irsr) : "memory" @@ -322,7 +324,7 @@ static inline void mpu_set_iracr(unsigned int iracr) { __asm__ __volatile__ ( - "\tmcr " CP15_IRACR(%0) + "\tmcr p15, 0, %0, c6, c1, 5" : : "r" (iracr) : "memory" @@ -342,7 +344,7 @@ static inline void mpu_set_rgnr(unsigned int rgnr) { __asm__ __volatile__ ( - "\tmcr " CP15_RGNR(%0) + "\tmcr p15, 0, %0, c6, c2, 0" : : "r" (rgnr) : "memory" @@ -422,7 +424,7 @@ static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar(base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID); + mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID); /* Select the region size and the sub-region map */ From 05d477661b3f81a899597c3216ad5d89a8b81ea8 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Wed, 23 Mar 2016 16:06:49 +0900 Subject: [PATCH 096/155] ARMv7-R: fix invalid drbar handling In ARMv7-R, [31:5] bits of DRBAR is physical base address and other bits are reserved and SBZ. Thus, there is no point in passing other than the base address. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index 762bd92e7e..9d11df1997 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -424,7 +424,7 @@ static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -467,7 +467,7 @@ static inline void mpu_user_flash(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -508,7 +508,7 @@ static inline void mpu_priv_flash(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -548,7 +548,7 @@ static inline void mpu_user_intsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -589,7 +589,7 @@ static inline void mpu_priv_intsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -630,7 +630,7 @@ static inline void mpu_user_extsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -672,7 +672,7 @@ static inline void mpu_priv_extsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -714,7 +714,7 @@ static inline void mpu_peripheral(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ From 2b922fcdbd511da9d970c5a24cb1169420aa9356 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:40:40 +0900 Subject: [PATCH 097/155] ARMv7-R: remove the redundant update on SCTLR mpu_control() is invoking cp15_wrsctlr() around SCTLR update redundantly. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index 9d11df1997..5245375bb0 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -392,7 +392,6 @@ static inline void mpu_control(bool enable) if (enable) { regval |= (SCTLR_M | SCTLR_BR); - cp15_wrsctlr(regval); } else { From 6a1a8460111fae211ce94fefd1318f8017008367 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:21:26 +0900 Subject: [PATCH 098/155] ARMv7-R: add new Kconfig entries for d/i-cache Unlike in ARMv7-A/M, Kconfig entries for data and instruction caches are currently missing in ARMv7-R. This commit adds those missing Kconfig entries. Actual implmenetation for those functions will be added in the subsequent patches. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/Kconfig | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig index e87315574d..e4b50492aa 100644 --- a/arch/arm/src/armv7-r/Kconfig +++ b/arch/arm/src/armv7-r/Kconfig @@ -19,6 +19,29 @@ config ARMV7R_MEMINIT the memory initialization first, then explicitly call arm_data_initialize(). +config ARMV7R_HAVE_ICACHE + bool + default n + +config ARMV7R_HAVE_DCACHE + bool + default n + +config ARMV7R_ICACHE + bool "Use I-Cache" + default n + depends on ARMV7R_HAVE_ICACHE + +config ARMV7R_DCACHE + bool "Use D-Cache" + default n + depends on ARMV7R_HAVE_DCACHE + +config ARMV7R_DCACHE_WRITETHROUGH + bool "D-Cache Write-Through" + default n + depends on ARMV7R_DCACHE + config ARMV7R_HAVE_L2CC bool default n From 003511d198ac1ee68363e6d79c16d9a5ad82762b Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 22 Mar 2016 15:50:12 +0900 Subject: [PATCH 099/155] ARMv7-R: add cache handling functions This commit adds functions for enabling and disabling d/i-caches which were missing for ARMv7-R. Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/cache.h | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/arch/arm/src/armv7-r/cache.h b/arch/arm/src/armv7-r/cache.h index 2c60fe2c3d..a0d25c8941 100644 --- a/arch/arm/src/armv7-r/cache.h +++ b/arch/arm/src/armv7-r/cache.h @@ -43,6 +43,7 @@ #include #include +#include "sctlr.h" #include "cp15_cacheops.h" #include "l2cc.h" @@ -50,6 +51,16 @@ * Pre-processor Definitions ************************************************************************************/ +/* intrinsics are used in these inline functions */ + +#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory") +#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory") +#define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory") + +#define ARM_DSB() arm_dsb(15) +#define ARM_ISB() arm_isb(15) +#define ARM_DMB() arm_dmb(15) + /************************************************************************************ * Inline Functions ************************************************************************************/ @@ -183,6 +194,70 @@ static inline void arch_flush_dcache(uintptr_t start, uintptr_t end) l2cc_flush(start, end); } +/**************************************************************************** + * Name: arch_enable_icache + * + * Description: + * Enable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_enable_icache(void) +{ +#ifdef CONFIG_ARMV7R_ICACHE + uint32_t regval; + + ARM_DSB(); + ARM_ISB(); + + /* Enable the I-Cache */ + + regval = cp15_rdsctlr(); + if ((regval & SCTLR_I) == 0) + { + cp15_wrsctlr(regval | SCTLR_I); + } + + ARM_DSB(); + ARM_ISB(); +#endif +} + +/**************************************************************************** +* Name: arch_enable_dcache +* +* Description: +* Enable the D-Cache +* +* Input Parameters: +* None +* +* Returned Value: +* None +* +****************************************************************************/ + +static inline void arch_enable_dcache(void) +{ +#ifdef CONFIG_ARMV7R_DCACHE + uint32_t regval; + + /* Enable the D-Cache */ + + regval = cp15_rdsctlr(); + if ((regval & SCTLR_C) == 0) + { + cp15_wrsctlr(regval | SCTLR_C); + } +#endif +} + /**************************************************************************** * Public Data ****************************************************************************/ From 6bfc6b4d238d0b561ed31ebaac74dbaeed186ad3 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Tue, 5 Apr 2016 15:09:17 +0900 Subject: [PATCH 100/155] ARMv7-R: fix typo in mpu support s/ARMV7M/ARMV7R/g Reported-by: Eunbong Song Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/mpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index 5245375bb0..7c1a201567 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -409,7 +409,7 @@ static inline void mpu_control(bool enable) * ****************************************************************************/ -#if defined(CONFIG_ARMV7M_HAVE_ICACHE) || defined(CONFIG_ARMV7M_DCACHE) +#if defined(CONFIG_ARMV7R_HAVE_ICACHE) || defined(CONFIG_ARMV7R_DCACHE) static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) { unsigned int region = mpu_allocregion(); From 343243c7c0de3d0696fa19c08d8d81e8d6cf0a1c Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Thu, 7 Apr 2016 15:51:48 +0900 Subject: [PATCH 101/155] ARMv7-R: fix CPSR corruption after exception handling A sporadic hang with consequent crash is observed when booting: arm_prefetchabort: Prefetch abort. PC: 04d34a00 IFAR: 04d34a00 IFSR: 00000008 up_assert: Assertion failed at file:armv7-r/arm_prefetchabort.c line: 87 task: init up_dumpstate: Current sp: 004c3df0 up_dumpstate: Interrupt stack: up_dumpstate: base: 004c05fc up_dumpstate: size: 00000800 up_dumpstate: User stack: up_dumpstate: base: 004c3f58 up_dumpstate: size: 00000fec up_dumpstate: User Stack up_stackdump: 004c3de0: 004a0d14 004c3df0 004c3f58 004a0d20 00000057 004c2c58 09000000 004a42a4 up_stackdump: 004c3e00: 00000003 004c3e10 004a0f1c 004bbcef 33c44b00 004a0f28 04d34a00 00000008 up_stackdump: 004c3e20: 00000008 004a01bc 004bfd38 00000001 00007fff 00000001 34134a00 d83e4c00 up_stackdump: 004c3e40: 09000000 00000000 33c44b00 d83e4c00 0c3f4c00 00000000 00000000 00000003 up_stackdump: 004c3e60: 004c3e70 004a1494 04d34a00 200b0253 004c3ed8 004a5298 004c3ed8 6d00006d up_stackdump: 004c3e80: 0000006d 004bc3f4 00000009 004a4f64 00000009 b9e0784f 333f3ed0 69d4227d up_stackdump: 004c3ea0: d81f09bd 0f867344 5a7e2c12 8acefd34 5d00dc1b 004bc432 004c3f08 004c0e08 up_stackdump: 004c3ec0: 00000000 00000000 00000000 00000000 00000000 004a4210 004a5258 004a5300 up_stackdump: 004c3ee0: 00000000 00000001 ffffffff 004c3f80 000002b0 004a4234 00000007 004c3f08 up_stackdump: 004c3f00: 004a58b4 004bc432 004bc3f4 004c3f80 000002b0 0000029c 00000000 0000029c up_stackdump: 004c3f20: 00000000 004a5900 0000ff01 00000000 00000000 004a61f4 00000000 004a5fa4 up_stackdump: 004c3f40: 00000000 004a5f6c 00000000 004a2668 00000000 00000000 b7509f04 004c3f64 up_registerdump: R0: 00000001 00007fff 00000001 34134a00 d83e4c00 09000000 00000000 33c44b00 up_registerdump: R8: d83e4c00 0c3f4c00 00000000 00000000 00000003 004c3e70 004a1494 04d34a00 up_registerdump: CPSR: 200b0253 It seems to be caused by the corrupted or wrong CPSR restored on return from exception. NuttX restores the context using code like this: msr spsr, r1 GCC translates this to: msr spsr_fc, r1 As a result, not all SPSR fields are updated on exception return. This should be: msr spsr_fsxc, r1 On some evaluation boards, spsr_svc may have totally invalid value at power-on-reset. As it is not initialized at boot, the code above may result in the corruption of cpsr and thus unexpected behavior. Reported-by: Eunbong Song Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/arm_vectors.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/armv7-r/arm_vectors.S b/arch/arm/src/armv7-r/arm_vectors.S index 216633e3a3..0f088b7358 100644 --- a/arch/arm/src/armv7-r/arm_vectors.S +++ b/arch/arm/src/armv7-r/arm_vectors.S @@ -202,7 +202,7 @@ arm_vectorirq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -331,7 +331,7 @@ arm_vectorsvc: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -913,7 +913,7 @@ arm_vectorfiq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the From bda7d9ee4d18a66cbeede91617938223b4f3c7b3 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Sun, 6 Nov 2016 15:45:51 +0900 Subject: [PATCH 102/155] ARMv7-R: fix to restore the Thumb flag in CPSR Thumb flag in CPSR is not restored back when the context switch occurs while executing thumb instruction. Reported-by: Eunbong Song Signed-off-by: Byoungtae Cho Signed-off-by: Heesub Shin --- arch/arm/src/armv7-r/arm_fullcontextrestore.S | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/arch/arm/src/armv7-r/arm_fullcontextrestore.S b/arch/arm/src/armv7-r/arm_fullcontextrestore.S index 9f197063b2..b23f613354 100644 --- a/arch/arm/src/armv7-r/arm_fullcontextrestore.S +++ b/arch/arm/src/armv7-r/arm_fullcontextrestore.S @@ -157,20 +157,10 @@ up_fullcontextrestore: */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */ - msr cpsr, r1 /* Set the CPSR */ - - /* Now recover r0 and r1 */ - - ldr r0, [sp] - ldr r1, [sp, #4] - add sp, sp, #(2*4) - - /* Then return to the address at the stop of the stack, - * destroying the stack frame - */ - - ldr pc, [sp], #4 + msr spsr_cxsf, r1 /* Set the SPSR */ + /* Now recover r0-r1, pc and cpsr, destroying the stack frame */ + ldmia sp!, {r0-r1, pc}^ #endif .size up_fullcontextrestore, . - up_fullcontextrestore From 3c2a00bc4bd4bb93b6217183d8366ebdcd4d9b26 Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Sun, 6 Nov 2016 07:56:38 -0600 Subject: [PATCH 103/155] LP worker: When queuing new work, don't signal any threads if they are all busy --- sched/wqueue/kwork_queue.c | 4 ++-- sched/wqueue/kwork_signal.c | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/sched/wqueue/kwork_queue.c b/sched/wqueue/kwork_queue.c index 3c4acb2d00..0ac27a87b7 100644 --- a/sched/wqueue/kwork_queue.c +++ b/sched/wqueue/kwork_queue.c @@ -152,7 +152,7 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker, #ifdef CONFIG_SCHED_HPWORK if (qid == HPWORK) { - /* Cancel high priority work */ + /* Queue high priority work */ work_qqueue((FAR struct kwork_wqueue_s *)&g_hpwork, work, worker, arg, delay); return work_signal(HPWORK); @@ -162,7 +162,7 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker, #ifdef CONFIG_SCHED_LPWORK if (qid == LPWORK) { - /* Cancel low priority work */ + /* Queue low priority work */ work_qqueue((FAR struct kwork_wqueue_s *)&g_lpwork, work, worker, arg, delay); return work_signal(LPWORK); diff --git a/sched/wqueue/kwork_signal.c b/sched/wqueue/kwork_signal.c index 9359fb2e2a..9c5b9a8e97 100644 --- a/sched/wqueue/kwork_signal.c +++ b/sched/wqueue/kwork_signal.c @@ -85,12 +85,11 @@ int work_signal(int qid) #ifdef CONFIG_SCHED_LPWORK if (qid == LPWORK) { - int wndx; int i; /* Find an IDLE worker thread */ - for (wndx = 0, i = 0; i < CONFIG_SCHED_LPNTHREADS; i++) + for (i = 0; i < CONFIG_SCHED_LPNTHREADS; i++) { /* Is this worker thread busy? */ @@ -98,16 +97,20 @@ int work_signal(int qid) { /* No.. select this thread */ - wndx = i; break; } } - /* Use the process ID of the IDLE worker thread (or the ID of worker - * thread 0 if all of the worker threads are busy). - */ + /* If all of the IDLE threads are busy, then just return successfully */ - pid = g_lpwork.worker[wndx].pid; + if (i >= CONFIG_SCHED_LPNTHREADS) + { + return OK; + } + + /* Otherwise, signal the first IDLE thread found */ + + pid = g_lpwork.worker[i].pid; } else #endif From 8e94d8e7cc31f1ec6afb6c8880dc444a7ff92f8a Mon Sep 17 00:00:00 2001 From: Heesub Shin Date: Sun, 6 Nov 2016 07:56:38 -0600 Subject: [PATCH 104/155] Signal sent from work_signal() may interrupt the low priority worker thread that is already running. For example, the worker thread that is waiting for a semaphore could be woken up by the signal and break any synchronization assumption as a result. It also does not make any sense to send signal if it is already running and busy. This commit fixes it. --- sched/wqueue/kwork_queue.c | 4 ++-- sched/wqueue/kwork_signal.c | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/sched/wqueue/kwork_queue.c b/sched/wqueue/kwork_queue.c index 3c4acb2d00..0ac27a87b7 100644 --- a/sched/wqueue/kwork_queue.c +++ b/sched/wqueue/kwork_queue.c @@ -152,7 +152,7 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker, #ifdef CONFIG_SCHED_HPWORK if (qid == HPWORK) { - /* Cancel high priority work */ + /* Queue high priority work */ work_qqueue((FAR struct kwork_wqueue_s *)&g_hpwork, work, worker, arg, delay); return work_signal(HPWORK); @@ -162,7 +162,7 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker, #ifdef CONFIG_SCHED_LPWORK if (qid == LPWORK) { - /* Cancel low priority work */ + /* Queue low priority work */ work_qqueue((FAR struct kwork_wqueue_s *)&g_lpwork, work, worker, arg, delay); return work_signal(LPWORK); diff --git a/sched/wqueue/kwork_signal.c b/sched/wqueue/kwork_signal.c index 9359fb2e2a..9c5b9a8e97 100644 --- a/sched/wqueue/kwork_signal.c +++ b/sched/wqueue/kwork_signal.c @@ -85,12 +85,11 @@ int work_signal(int qid) #ifdef CONFIG_SCHED_LPWORK if (qid == LPWORK) { - int wndx; int i; /* Find an IDLE worker thread */ - for (wndx = 0, i = 0; i < CONFIG_SCHED_LPNTHREADS; i++) + for (i = 0; i < CONFIG_SCHED_LPNTHREADS; i++) { /* Is this worker thread busy? */ @@ -98,16 +97,20 @@ int work_signal(int qid) { /* No.. select this thread */ - wndx = i; break; } } - /* Use the process ID of the IDLE worker thread (or the ID of worker - * thread 0 if all of the worker threads are busy). - */ + /* If all of the IDLE threads are busy, then just return successfully */ - pid = g_lpwork.worker[wndx].pid; + if (i >= CONFIG_SCHED_LPNTHREADS) + { + return OK; + } + + /* Otherwise, signal the first IDLE thread found */ + + pid = g_lpwork.worker[i].pid; } else #endif From c1a687a4e5c6e0c3938f87bb69eeb1b6a04a20bc Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 6 Nov 2016 08:11:01 -0600 Subject: [PATCH 105/155] Trivial changes from review of last PR --- arch/arm/src/armv7-r/arm_fullcontextrestore.S | 2 +- arch/arm/src/armv7-r/arm_vectors.S | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/src/armv7-r/arm_fullcontextrestore.S b/arch/arm/src/armv7-r/arm_fullcontextrestore.S index b23f613354..06daa22182 100644 --- a/arch/arm/src/armv7-r/arm_fullcontextrestore.S +++ b/arch/arm/src/armv7-r/arm_fullcontextrestore.S @@ -60,7 +60,6 @@ .cpu cortex-r4f #endif .syntax unified - .file "arm_fullcontextrestore.S" /**************************************************************************** * Public Functions @@ -160,6 +159,7 @@ up_fullcontextrestore: msr spsr_cxsf, r1 /* Set the SPSR */ /* Now recover r0-r1, pc and cpsr, destroying the stack frame */ + ldmia sp!, {r0-r1, pc}^ #endif diff --git a/arch/arm/src/armv7-r/arm_vectors.S b/arch/arm/src/armv7-r/arm_vectors.S index 0f088b7358..bea7c927bc 100644 --- a/arch/arm/src/armv7-r/arm_vectors.S +++ b/arch/arm/src/armv7-r/arm_vectors.S @@ -202,7 +202,7 @@ arm_vectorirq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr_cxsf, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -331,7 +331,7 @@ arm_vectorsvc: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr_cxsf, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -913,7 +913,7 @@ arm_vectorfiq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr_cxsf, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the From 175394904528bd1f3c562d2cc56584731480e738 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 6 Nov 2016 08:55:15 -0600 Subject: [PATCH 106/155] Update README --- configs/misoc/README.txt | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/configs/misoc/README.txt b/configs/misoc/README.txt index 1c20544513..b75eaad7e8 100644 --- a/configs/misoc/README.txt +++ b/configs/misoc/README.txt @@ -16,16 +16,17 @@ Buildroot Toolchain cd tools ./configure.sh misoc/ + make oldconfig context - 2. Clone the latest buildroot package into + 2. Clone the latest buildroot package into /buildroot - git clone git@bitbucket.org:nuttx/buildroot.git + git clone git@bitbucket.org:nuttx/buildroot.git /buildroot or - git clone https://patacongo@bitbucket.org/nuttx/buildroot.git + git clone https://patacongo@bitbucket.org/nuttx/buildroot.git /buildroot - 3. cd + 3. cd /buildroot 4. cp lm32-elf-defconfig-6.1.0 .config @@ -33,14 +34,18 @@ Buildroot Toolchain 6. make - 7. Edit setenv.h, if necessary, so that the PATH variable includes - the path to the newly built binaries. + 7. By default, the tools will be at the absolute path: - By default, the tools will be at: + /buildroot/build_lm32/staging_dir/bin - /build_lm32/staging_dir/bin + Or the NuttX relative path: - That location can be changed by reconfiguring the .config file. + ../buildroot/build_lm32/staging_dir/bin + + The setenv.sh files in these sub-directories are already set to use + the relative path. It you choose to install the buildroot package + in some other location, you may need to edit the setenv.h file so + that the PATH variable includes the path to the newly built binaries. See the file configs/README.txt in the buildroot source tree. That has more detailed PLUS some special instructions that you will need to follow if you From 120d29b4804795579565d9ce4e3852f99b206ae2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 6 Nov 2016 09:06:37 -0600 Subject: [PATCH 107/155] Update some Kconfig comments --- sched/Kconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sched/Kconfig b/sched/Kconfig index d06143d7d5..60156e0368 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -803,6 +803,18 @@ menuconfig PRIORITY_INHERITANCE default n ---help--- Set to enable support for priority inheritance on mutexes and semaphores. + When this option is enabled, the initial configuration of all seamphores + and mutexes will be with priority inheritance enabled. That configuration + may not be appropriate in all cases (such as when the semaphore or mutex + is used for signaling). In such cases, priority inheritance be be + disabled for individual semaphores by calling: + + int ret = sem_setprotocol(&sem, SEM_PRIO_NONE); + + And for individual pthread mutexes by setting the protocol attribute + before initializing the mutex: + + int ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_NONE); if PRIORITY_INHERITANCE From 860c0f58734688751f41488b64366ebded85fd27 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 6 Nov 2016 10:15:01 -0600 Subject: [PATCH 108/155] Update TODO list. --- TODO | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index f770f9a2f6..703cfad205 100644 --- a/TODO +++ b/TODO @@ -278,11 +278,11 @@ o Task/Scheduler (sched/) pthread_mutexattr_settype(&attr, PTHREAD_PRIO_NONE); pthread_mutex_init(&mutex, &attr); - Status: Open - Priority: High. If you have priority inheritance enabled and you use + Status: Closed. If you have priority inheritance enabled and you use semaphores for signalling events, then you *must* call sem_setprotocol(SEM_PRIO_NONE) immediately after initializing the semaphore. + Priority: High. Title: SCALABILITY Description: Task control information is retained in simple lists. This @@ -466,7 +466,7 @@ o pthreads (sched/pthreads) Priority: Low, probably not that useful Title: PTHREAD_PRIO_PROTECT - Description: Extended pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT: + Description: Extend pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT: "When a thread owns one or more mutexes initialized with the PTHREAD_PRIO_PROTECT protocol, it shall execute at the higher of its priority or the highest of the priority ceilings of all the mutexes From 5ac9136b21c4bf24e0286f87d6c39940311a287c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 6 Nov 2016 10:46:11 -0600 Subject: [PATCH 109/155] LM32: Implement some commented out logic in lm32_dumpstate --- arch/misoc/src/lm32/lm32_dumpstate.c | 50 ++++++++++++---------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_dumpstate.c b/arch/misoc/src/lm32/lm32_dumpstate.c index e847bec40c..229aee8bfd 100644 --- a/arch/misoc/src/lm32/lm32_dumpstate.c +++ b/arch/misoc/src/lm32/lm32_dumpstate.c @@ -77,7 +77,6 @@ static inline uint32_t up_getsp(void) static void up_stackdump(uint32_t sp, uint32_t stack_base) { -# if 0 uint32_t stack ; for (stack = sp & ~0x1f; stack < stack_base; stack += 32) @@ -87,7 +86,6 @@ static void up_stackdump(uint32_t sp, uint32_t stack_base) stack, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7]); } -#endif } /**************************************************************************** @@ -96,39 +94,35 @@ static void up_stackdump(uint32_t sp, uint32_t stack_base) static inline void up_registerdump(void) { -#if 0 /* Are user registers available from interrupt processing? */ if (g_current_regs) { _alert("EPC:%08x \n", g_current_regs[REG_EPC]); - _alert("A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x A7:%08x\n", - g_current_regs[REG_A0], g_current_regs[REG_A1], g_current_regs[REG_A2], - g_current_regs[REG_A3], g_current_regs[REG_A4], g_current_regs[REG_A5], - g_current_regs[REG_A6], g_current_regs[REG_A7]); - _alert("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x\n", - g_current_regs[REG_T0], g_current_regs[REG_T1], g_current_regs[REG_T2], - g_current_regs[REG_T3], g_current_regs[REG_T4], g_current_regs[REG_T5], - g_current_regs[REG_T6]); - _alert("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", - g_current_regs[REG_S0], g_current_regs[REG_S1], g_current_regs[REG_S2], - g_current_regs[REG_S3], g_current_regs[REG_S4], g_current_regs[REG_S5], - g_current_regs[REG_S6], g_current_regs[REG_S7]); - _alert("S8:%08x S9:%08x S10:%08x S11:%08x\n", - g_current_regs[REG_S8], g_current_regs[REG_S9], g_current_regs[REG_S10], - g_current_regs[REG_S11]); -#ifdef RISCV_SAVE_GP - _alert("GP:%08x SP:%08x FP:%08x TP:%08x RA:%08x\n", - g_current_regs[REG_GP], g_current_regs[REG_SP], g_current_regs[REG_FP], - g_current_regs[REG_TP], g_current_regs[REG_RA]); -#else - _alert("SP:%08x FP:%08x TP:%08x RA:%08x\n", - g_current_regs[REG_SP], g_current_regs[REG_FP], g_current_regs[REG_TP], - g_current_regs[REG_RA]); -#endif + _alert(" X0:%08x A0:%08x A1:%08x A2:%08x A3:%08x A4:%08x A5:%08x A6:%08x\n", + g_current_regs[REG_X0_NDX], g_current_regs[REG_X1_NDX], + g_current_regs[REG_X2_NDX], g_current_regs[REG_X3_NDX], + g_current_regs[REG_X4_NDX], g_current_regs[REG_X5_NDX], + g_current_regs[REG_X6_NDX], g_current_regs[REG_X7_NDX]); + _alert(" A7:%08x X9:%08x X10:%08x X11:%08x X12:%08x X13:%08x X14:%08x X15:%08x\n", + g_current_regs[REG_X8_NDX], g_current_regs[REG_X9_NDX], + g_current_regs[REG_X10_NDX], g_current_regs[REG_X11_NDX], + g_current_regs[REG_X12_NDX], g_current_regs[REG_X13_NDX], + g_current_regs[REG_X14_NDX], g_current_regs[REG_X15_NDX]); + _alert("X16:%08x X17:%08x X18:%08x X19:%08x X20:%08x X21:%08x X22:%08x X23:%08x\n", + g_current_regs[REG_X16_NDX], g_current_regs[REG_X17_NDX], + g_current_regs[REG_X18_NDX], g_current_regs[REG_X19_NDX], + g_current_regs[REG_X20_NDX], g_current_regs[REG_X21_NDX], + g_current_regs[REG_X22_NDX], g_current_regs[REG_X23_NDX]); + _alert("X24:%08x X25:%08x GP:%08x FP:%08x SP:%08x RA:%08x EA:%08x BA:%08x\n", + g_current_regs[REG_X24_NDX], g_current_regs[REG_X25_NDX], + g_current_regs[REG_X26_NDX], g_current_regs[REG_X27_NDX], + g_current_regs[REG_X28_NDX], g_current_regs[REG_X29_NDX], + g_current_regs[REG_X30_NDX], g_current_regs[REG_X31_NDX]); + _alert(" IE:%08x\n", + g_current_regs[REG_X32_NDX]); } -#endif } /**************************************************************************** From d6315a3084c1e7088ba31cc2e3671b7fc38d349a Mon Sep 17 00:00:00 2001 From: Lok Tep Date: Mon, 7 Nov 2016 13:11:59 +0100 Subject: [PATCH 110/155] del stm32f74xx75xx_sdmmc.h --- .../src/stm32f7/chip/stm32f74xx75xx_sdmmc.h | 268 ------------------ 1 file changed, 268 deletions(-) delete mode 100644 arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h deleted file mode 100644 index 117c4da2fa..0000000000 --- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_sdmmc.h +++ /dev/null @@ -1,268 +0,0 @@ -/************************************************************************************ - * arch/arm/src/stm32f7/chip/stm32_sdmmc.h - * - * Copyright (C) 2009, 2011-2016 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. - * - ************************************************************************************/ - -#ifndef __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H -#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H - -/************************************************************************************ - * Pre-processor Definitions - ************************************************************************************/ - -/* Register Offsets *****************************************************************/ - -#define STM32_SDMMC1_POWER_OFFSET 0x0000 /* SDIO power control register */ -#define STM32_SDMMC1_CLKCR_OFFSET 0x0004 /* SDI clock control register */ -#define STM32_SDMMC1_ARG_OFFSET 0x0008 /* SDIO argument register */ -#define STM32_SDMMC1_CMD_OFFSET 0x000c /* SDIO command register */ -#define STM32_SDMMC1_RESPCMD_OFFSET 0x0010 /* SDIO command response register */ -#define STM32_SDMMC1_RESP_OFFSET(n) (0x0010+4*(n)) -#define STM32_SDMMC1_RESP1_OFFSET 0x0014 /* SDIO response 1 register */ -#define STM32_SDMMC1_RESP2_OFFSET 0x0018 /* SDIO response 2 register */ -#define STM32_SDMMC1_RESP3_OFFSET 0x001c /* SDIO response 3 register */ -#define STM32_SDMMC1_RESP4_OFFSET 0x0020 /* SDIO response 4 register */ -#define STM32_SDMMC1_DTIMER_OFFSET 0x0024 /* SDIO data timer register */ -#define STM32_SDMMC1_DLEN_OFFSET 0x0028 /* SDIO data length register */ -#define STM32_SDMMC1_DCTRL_OFFSET 0x002c /* SDIO data control register */ -#define STM32_SDMMC1_DCOUNT_OFFSET 0x0030 /* SDIO data counter register */ -#define STM32_SDMMC1_STA_OFFSET 0x0034 /* SDIO status register */ -#define STM32_SDMMC1_ICR_OFFSET 0x0038 /* SDIO interrupt clear register */ -#define STM32_SDMMC1_MASK_OFFSET 0x003c /* SDIO mask register */ -#define STM32_SDMMC1_FIFOCNT_OFFSET 0x0048 /* SDIO FIFO counter register */ -#define STM32_SDMMC1_FIFO_OFFSET 0x0080 /* SDIO data FIFO register */ - -/* Register Addresses ***************************************************************/ - -#define STM32_SDMMC1_POWER (STM32_SDMMC1_BASE+STM32_SDMMC1_POWER_OFFSET) -#define STM32_SDMMC1_CLKCR (STM32_SDMMC1_BASE+STM32_SDMMC1_CLKCR_OFFSET) -#define STM32_SDMMC1_ARG (STM32_SDMMC1_BASE+STM32_SDMMC1_ARG_OFFSET) -#define STM32_SDMMC1_CMD (STM32_SDMMC1_BASE+STM32_SDMMC1_CMD_OFFSET) -#define STM32_SDMMC1_RESPCMD (STM32_SDMMC1_BASE+STM32_SDMMC1_RESPCMD_OFFSET) -#define STM32_SDMMC1_RESP(n) (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP_OFFSET(n)) -#define STM32_SDMMC1_RESP1 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP1_OFFSET) -#define STM32_SDMMC1_RESP2 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP2_OFFSET) -#define STM32_SDMMC1_RESP3 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP3_OFFSET) -#define STM32_SDMMC1_RESP4 (STM32_SDMMC1_BASE+STM32_SDMMC1_RESP4_OFFSET) -#define STM32_SDMMC1_DTIMER (STM32_SDMMC1_BASE+STM32_SDMMC1_DTIMER_OFFSET) -#define STM32_SDMMC1_DLEN (STM32_SDMMC1_BASE+STM32_SDMMC1_DLEN_OFFSET) -#define STM32_SDMMC1_DCTRL (STM32_SDMMC1_BASE+STM32_SDMMC1_DCTRL_OFFSET) -#define STM32_SDMMC1_DCOUNT (STM32_SDMMC1_BASE+STM32_SDMMC1_DCOUNT_OFFSET) -#define STM32_SDMMC1_STA (STM32_SDMMC1_BASE+STM32_SDMMC1_STA_OFFSET) -#define STM32_SDMMC1_ICR (STM32_SDMMC1_BASE+STM32_SDMMC1_ICR_OFFSET) -#define STM32_SDMMC1_MASK (STM32_SDMMC1_BASE+STM32_SDMMC1_MASK_OFFSET) -#define STM32_SDMMC1_FIFOCNT (STM32_SDMMC1_BASE+STM32_SDMMC1_FIFOCNT_OFFSET) -#define STM32_SDMMC1_FIFO (STM32_SDMMC1_BASE+STM32_SDMMC1_FIFO_OFFSET) - - -/* Register Bitfield Definitions ****************************************************/ - -#define SDIO_POWER_PWRCTRL_SHIFT (0) /* Bits 0-1: Power supply control bits */ -#define SDIO_POWER_PWRCTRL_MASK (3 << SDIO_POWER_PWRCTRL_SHIFT) -# define SDIO_POWER_PWRCTRL_OFF (0 << SDIO_POWER_PWRCTRL_SHIFT) /* 00: Power-off: card clock stopped */ -# define SDIO_POWER_PWRCTRL_PWRUP (2 << SDIO_POWER_PWRCTRL_SHIFT) /* 10: Reserved power-up */ -# define SDIO_POWER_PWRCTRL_ON (3 << SDIO_POWER_PWRCTRL_SHIFT) /* 11: Power-on: card is clocked */ - -#define SDIO_POWER_RESET (0) /* Reset value */ - -#define SDIO_CLKCR_CLKDIV_SHIFT (0) /* Bits 7-0: Clock divide factor */ -#define SDIO_CLKCR_CLKDIV_MASK (0xff << SDIO_CLKCR_CLKDIV_SHIFT) -#define SDIO_CLKCR_CLKEN (1 << 8) /* Bit 8: Clock enable bit */ -#define SDIO_CLKCR_PWRSAV (1 << 9) /* Bit 9: Power saving configuration bit */ -#define SDIO_CLKCR_BYPASS (1 << 10) /* Bit 10: Clock divider bypass enable bit */ -#define SDIO_CLKCR_WIDBUS_SHIFT (11) /* Bits 12-11: Wide bus mode enable bits */ -#define SDIO_CLKCR_WIDBUS_MASK (3 << SDIO_CLKCR_WIDBUS_SHIFT) -# define SDIO_CLKCR_WIDBUS_D1 (0 << SDIO_CLKCR_WIDBUS_SHIFT) /* 00: Default (SDIO_D0) */ -# define SDIO_CLKCR_WIDBUS_D4 (1 << SDIO_CLKCR_WIDBUS_SHIFT) /* 01: 4-wide (SDIO_D[3:0]) */ -# define SDIO_CLKCR_WIDBUS_D8 (2 << SDIO_CLKCR_WIDBUS_SHIFT) /* 10: 8-wide (SDIO_D[7:0]) */ -#define SDIO_CLKCR_NEGEDGE (1 << 13) /* Bit 13: SDIO_CK dephasing selection bit */ -#define SDIO_CLKCR_HWFC_EN (1 << 14) /* Bit 14: HW Flow Control enable */ - -#define SDIO_CLKCR_RESET (0) /* Reset value */ -#define SDIO_ARG_RESET (0) /* Reset value */ - -#define SDIO_CLKCR_CLKEN_BB (STM32_SDMMC1_CLKCR_BB + (8 * 4)) -#define SDIO_CLKCR_PWRSAV_BB (STM32_SDMMC1_CLKCR_BB + (9 * 4)) -#define SDIO_CLKCR_BYPASS_BB (STM32_SDMMC1_CLKCR_BB + (10 * 4)) -#define SDIO_CLKCR_NEGEDGE_BB (STM32_SDMMC1_CLKCR_BB + (13 * 4)) -#define SDIO_CLKCR_HWFC_EN_BB (STM32_SDMMC1_CLKCR_BB + (14 * 4)) - -#define SDIO_CMD_CMDINDEX_SHIFT (0) -#define SDIO_CMD_CMDINDEX_MASK (0x3f << SDIO_CMD_CMDINDEX_SHIFT) -#define SDIO_CMD_WAITRESP_SHIFT (6) /* Bits 7-6: Wait for response bits */ -#define SDIO_CMD_WAITRESP_MASK (3 << SDIO_CMD_WAITRESP_SHIFT) -# define SDIO_CMD_NORESPONSE (0 << SDIO_CMD_WAITRESP_SHIFT) /* 00/10: No response */ -# define SDIO_CMD_SHORTRESPONSE (1 << SDIO_CMD_WAITRESP_SHIFT) /* 01: Short response */ -# define SDIO_CMD_LONGRESPONSE (3 << SDIO_CMD_WAITRESP_SHIFT) /* 11: Long response */ -#define SDIO_CMD_WAITINT (1 << 8) /* Bit 8: CPSM waits for interrupt request */ -#define SDIO_CMD_WAITPEND (1 << 9) /* Bit 9: CPSM Waits for ends of data transfer */ -#define SDIO_CMD_CPSMEN (1 << 10) /* Bit 10: Command path state machine enable */ -#define SDIO_CMD_SUSPEND (1 << 11) /* Bit 11: SD I/O suspend command */ -#define SDIO_CMD_ENDCMD (1 << 12) /* Bit 12: Enable CMD completion */ -#define SDIO_CMD_NIEN (1 << 13) /* Bit 13: not Interrupt Enable */ -#define SDIO_CMD_ATACMD (1 << 14) /* Bit 14: CE-ATA command */ - -#define SDIO_CMD_RESET (0) /* Reset value */ - -#define SDIO_CMD_WAITINT_BB (STM32_SDMMC1_CMD_BB + (8 * 4)) -#define SDIO_CMD_WAITPEND_BB (STM32_SDMMC1_CMD_BB + (9 * 4)) -#define SDIO_CMD_CPSMEN_BB (STM32_SDMMC1_CMD_BB + (10 * 4)) -#define SDIO_CMD_SUSPEND_BB (STM32_SDMMC1_CMD_BB + (11 * 4)) -#define SDIO_CMD_ENCMD_BB (STM32_SDMMC1_CMD_BB + (12 * 4)) -#define SDIO_CMD_NIEN_BB (STM32_SDMMC1_CMD_BB + (13 * 4)) -#define SDIO_CMD_ATACMD_BB (STM32_SDMMC1_CMD_BB + (14 * 4)) - -#define SDIO_RESPCMD_SHIFT (0) -#define SDIO_RESPCMD_MASK (0x3f << SDIO_RESPCMD_SHIFT) - -#define SDIO_DTIMER_RESET (0) /* Reset value */ - -#define SDIO_DLEN_SHIFT (0) -#define SDIO_DLEN_MASK (0x01ffffff << SDIO_DLEN_SHIFT) - -#define SDIO_DLEN_RESET (0) /* Reset value */ - -#define SDIO_DCTRL_DTEN (1 << 0) /* Bit 0: Data transfer enabled bit */ -#define SDIO_DCTRL_DTDIR (1 << 1) /* Bit 1: Data transfer direction */ -#define SDIO_DCTRL_DTMODE (1 << 2) /* Bit 2: Data transfer mode */ -#define SDIO_DCTRL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */ -#define SDIO_DCTRL_DBLOCKSIZE_SHIFT (4) /* Bits 7-4: Data block size */ -#define SDIO_DCTRL_DBLOCKSIZE_MASK (15 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_1BYTE (0 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_2BYTES (1 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_4BYTES (2 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_8BYTES (3 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_16BYTES (4 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_32BYTES (5 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_64BYTES (6 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_128BYTES (7 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_256BYTES (8 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_512BYTES (9 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_1KBYTE (10 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_2KBYTES (11 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_4KBYTES (12 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_8KBYTES (13 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -# define SDIO_DCTRL_16KBYTES (14 << SDIO_DCTRL_DBLOCKSIZE_SHIFT) -#define SDIO_DCTRL_RWSTART (1 << 8) /* Bit 8: Read wait start */ -#define SDIO_DCTRL_RWSTOP (1 << 9) /* Bit 9: Read wait stop */ -#define SDIO_DCTRL_RWMOD (1 << 10) /* Bit 10: Read wait mode */ -#define SDIO_DCTRL_SDIOEN (1 << 11) /* Bit 11: SD I/O enable functions */ - -#define SDIO_DCTRL_RESET (0) /* Reset value */ - -#define SDIO_DCTRL_DTEN_BB (STM32_SDMMC1_DCTRL_BB + (0 * 4)) -#define SDIO_DCTRL_DTDIR_BB (STM32_SDMMC1_DCTRL_BB + (1 * 4)) -#define SDIO_DCTRL_DTMODE_BB (STM32_SDMMC1_DCTRL_BB + (2 * 4)) -#define SDIO_DCTRL_DMAEN_BB (STM32_SDMMC1_DCTRL_BB + (3 * 4)) -#define SDIO_DCTRL_RWSTART_BB (STM32_SDMMC1_DCTRL_BB + (8 * 4)) -#define SDIO_DCTRL_RWSTOP_BB (STM32_SDMMC1_DCTRL_BB + (9 * 4)) -#define SDIO_DCTRL_RWMOD_BB (STM32_SDMMC1_DCTRL_BB + (10 * 4)) -#define SDIO_DCTRL_SDIOEN_BB (STM32_SDMMC1_DCTRL_BB + (11 * 4)) - -#define SDIO_DATACOUNT_SHIFT (0) -#define SDIO_DATACOUNT_MASK (0x01ffffff << SDIO_DATACOUNT_SHIFT) - -#define SDIO_STA_CCRCFAIL (1 << 0) /* Bit 0: Command response CRC fail */ -#define SDIO_STA_DCRCFAIL (1 << 1) /* Bit 1: Data block CRC fail */ -#define SDIO_STA_CTIMEOUT (1 << 2) /* Bit 2: Command response timeout */ -#define SDIO_STA_DTIMEOUT (1 << 3) /* Bit 3: Data timeout */ -#define SDIO_STA_TXUNDERR (1 << 4) /* Bit 4: Transmit FIFO underrun error */ -#define SDIO_STA_RXOVERR (1 << 5) /* Bit 5: Received FIFO overrun error */ -#define SDIO_STA_CMDREND (1 << 6) /* Bit 6: Command response received */ -#define SDIO_STA_CMDSENT (1 << 7) /* Bit 7: Command sent */ -#define SDIO_STA_DATAEND (1 << 8) /* Bit 8: Data end */ -#define SDIO_STA_STBITERR (1 << 9) /* Bit 9: Start bit not detected */ -#define SDIO_STA_DBCKEND (1 << 10) /* Bit 10: Data block sent/received */ -#define SDIO_STA_CMDACT (1 << 11) /* Bit 11: Command transfer in progress */ -#define SDIO_STA_TXACT (1 << 12) /* Bit 12: Data transmit in progress */ -#define SDIO_STA_RXACT (1 << 13) /* Bit 13: Data receive in progress */ -#define SDIO_STA_TXFIFOHE (1 << 14) /* Bit 14: Transmit FIFO half empty */ -#define SDIO_STA_RXFIFOHF (1 << 15) /* Bit 15: Receive FIFO half full */ -#define SDIO_STA_TXFIFOF (1 << 16) /* Bit 16: Transmit FIFO full */ -#define SDIO_STA_RXFIFOF (1 << 17) /* Bit 17: Receive FIFO full */ -#define SDIO_STA_TXFIFOE (1 << 18) /* Bit 18: Transmit FIFO empty */ -#define SDIO_STA_RXFIFOE (1 << 19) /* Bit 19: Receive FIFO empty */ -#define SDIO_STA_TXDAVL (1 << 20) /* Bit 20: Data available in transmit FIFO */ -#define SDIO_STA_RXDAVL (1 << 21) /* Bit 21: Data available in receive FIFO */ -#define SDIO_STA_SDIOIT (1 << 22) /* Bit 22: SDIO interrupt received */ -#define SDIO_STA_CEATAEND (1 << 23) /* Bit 23: CMD6 CE-ATA command completion */ - -#define SDIO_ICR_CCRCFAILC (1 << 0) /* Bit 0: CCRCFAIL flag clear bit */ -#define SDIO_ICR_DCRCFAILC (1 << 1) /* Bit 1: DCRCFAIL flag clear bit */ -#define SDIO_ICR_CTIMEOUTC (1 << 2) /* Bit 2: CTIMEOUT flag clear bit */ -#define SDIO_ICR_DTIMEOUTC (1 << 3) /* Bit 3: DTIMEOUT flag clear bit */ -#define SDIO_ICR_TXUNDERRC (1 << 4) /* Bit 4: TXUNDERR flag clear bit */ -#define SDIO_ICR_RXOVERRC (1 << 5) /* Bit 5: RXOVERR flag clear bit */ -#define SDIO_ICR_CMDRENDC (1 << 6) /* Bit 6: CMDREND flag clear bit */ -#define SDIO_ICR_CMDSENTC (1 << 7) /* Bit 7: CMDSENT flag clear bit */ -#define SDIO_ICR_DATAENDC (1 << 8) /* Bit 8: DATAEND flag clear bit */ -#define SDIO_ICR_STBITERRC (1 << 9) /* Bit 9: STBITERR flag clear bit */ -#define SDIO_ICR_DBCKENDC (1 << 10) /* Bit 10: DBCKEND flag clear bit */ -#define SDIO_ICR_SDIOITC (1 << 22) /* Bit 22: SDIOIT flag clear bit */ -#define SDIO_ICR_CEATAENDC (1 << 23) /* Bit 23: CEATAEND flag clear bit */ - -#define SDIO_ICR_RESET 0x00c007ff -#define SDIO_ICR_STATICFLAGS 0x000005ff - -#define SDIO_MASK_CCRCFAILIE (1 << 0) /* Bit 0: Command CRC fail interrupt enable */ -#define SDIO_MASK_DCRCFAILIE (1 << 1) /* Bit 1: Data CRC fail interrupt enable */ -#define SDIO_MASK_CTIMEOUTIE (1 << 2) /* Bit 2: Command timeout interrupt enable */ -#define SDIO_MASK_DTIMEOUTIE (1 << 3) /* Bit 3: Data timeout interrupt enable */ -#define SDIO_MASK_TXUNDERRIE (1 << 4) /* Bit 4: Tx FIFO underrun error interrupt enable */ -#define SDIO_MASK_RXOVERRIE (1 << 5) /* Bit 5: Rx FIFO overrun error interrupt enable */ -#define SDIO_MASK_CMDRENDIE (1 << 6) /* Bit 6: Command response received interrupt enable */ -#define SDIO_MASK_CMDSENTIE (1 << 7) /* Bit 7: Command sent interrupt enable */ -#define SDIO_MASK_DATAENDIE (1 << 8) /* Bit 8: Data end interrupt enable */ -#define SDIO_MASK_STBITERRIE (1 << 9) /* Bit 9: Start bit error interrupt enable */ -#define SDIO_MASK_DBCKENDIE (1 << 10) /* Bit 10: Data block end interrupt enable */ -#define SDIO_MASK_CMDACTIE (1 << 11) /* Bit 11: Command acting interrupt enable */ -#define SDIO_MASK_TXACTIE (1 << 12) /* Bit 12: Data transmit acting interrupt enable */ -#define SDIO_MASK_RXACTIE (1 << 13) /* Bit 13: Data receive acting interrupt enable */ -#define SDIO_MASK_TXFIFOHEIE (1 << 14) /* Bit 14: Tx FIFO half empty interrupt enable */ -#define SDIO_MASK_RXFIFOHFIE (1 << 15) /* Bit 15: Rx FIFO half full interrupt enable */ -#define SDIO_MASK_TXFIFOFIE (1 << 16) /* Bit 16: Tx FIFO full interrupt enable */ -#define SDIO_MASK_RXFIFOFIE (1 << 17) /* Bit 17: Rx FIFO full interrupt enable */ -#define SDIO_MASK_TXFIFOEIE (1 << 18) /* Bit 18: Tx FIFO empty interrupt enable */ -#define SDIO_MASK_RXFIFOEIE (1 << 19) /* Bit 19: Rx FIFO empty interrupt enable */ -#define SDIO_MASK_TXDAVLIE (1 << 20) /* Bit 20: Data available in Tx FIFO interrupt enable */ -#define SDIO_MASK_RXDAVLIE (1 << 21) /* Bit 21: Data available in Rx FIFO interrupt enable */ -#define SDIO_MASK_SDIOITIE (1 << 22) /* Bit 22: SDIO mode interrupt received interrupt enable */ -#define SDIO_MASK_CEATAENDIE (1 << 23) /* Bit 23: CE-ATA command completion interrupt enable */ - -#define SDIO_MASK_RESET (0) - -#define SDIO_FIFOCNT_SHIFT (0) -#define SDIO_FIFOCNT_MASK (0x01ffffff << SDIO_FIFOCNT_SHIFT) - -#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32F74XX75XX_SDMMC_H */ - From fe2b75579115818be2093cc7608626e6003303df Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Mon, 7 Nov 2016 06:54:57 -0600 Subject: [PATCH 111/155] LM32: Correct some assembly language interrupt handling issues. Now the basic port seems functional. --- arch/misoc/src/lm32/lm32_vectors.S | 59 +++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 13 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index dc62cfe25e..a71cf63b98 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -38,13 +38,43 @@ * Included Files ****************************************************************************/ +#include #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ +/* Linker memory organization ***********************************************/ +/* Data memory is organized as follows: + * + * 1) Initialized data (.data): + * Start: _sdata + * End(+1): _edata + * 2) Uninitialized data (.bss): + * Start: _sbss + * End(+1): _ebss + * + * The following are placed outside of the "normal" memory segments -- mostly + * so that they do not have to be cleared on power up. + * + * 3) Idle thread stack: + * Start: _ebss + * End(+1): _ebss+CONFIG_IDLETHREAD_STACKSIZE + * 4) Heap: + * Start: _ebss+CONFIG_IDLETHREAD_STACKSIZE + * End(+1): to the end of memory + */ + +#define LM32_STACK_BASE _ebss +#define LM32_STACK_TOP _ebss+CONFIG_IDLETHREAD_STACKSIZE +#define LM32_HEAP_BASE LM32_STACK_TOP + /**************************************************************************** * Exception handlers - Must be 32 bytes long. ****************************************************************************/ .section .text, "ax", @progbits + .global g_idle_topstack .global __start __start: @@ -131,24 +161,24 @@ _syscall_handler: _do_reset: /* Setup stack and global pointer */ - mvhi sp, hi(_fstack) - ori sp, sp, lo(_fstack) + mvhi sp, hi(LM32_STACK_TOP) + ori sp, sp, lo(LM32_STACK_TOP) /* Clear BSS */ - mvhi r1, hi(_sbss) - ori r1, r1, lo(_sbss) - mvhi r3, hi(_ebss) - ori r3, r3, lo(_ebss) + mvhi r1, hi(_sbss) + ori r1, r1, lo(_sbss) + mvhi r3, hi(_ebss) + ori r3, r3, lo(_ebss) .clearBSS: - be r1, r3, .callMain + be r1, r3, .callMain sw (r1+0), r0 addi r1, r1, 4 - bi .clearBSS + bi .clearBSS .callMain: - bi os_start + bi os_start .save_all: addi sp, sp, -136 @@ -181,7 +211,11 @@ _do_reset: sw (sp+REG_GP), r26 sw (sp+REG_FP), r27 - sw (sp+REG_SP), r28 + + /* Save SP before we add 136 */ + + addi r1, sp, 136 + sw (sp+REG_SP), r1 /* reg RA done later */ @@ -239,7 +273,7 @@ _do_reset: lw r1, (r1+REG_INT_CTX) wcsr IE, r1 lw r1, (r1+REG_X1) - addi sp, sp, 136 + eret /* This global variable is unsigned long g_idle_topstack and is @@ -249,10 +283,9 @@ _do_reset: .data .align 4 - .globl g_idle_topstack .type g_idle_topstack, object g_idle_topstack: - .long _ebss+CONFIG_IDLETHREAD_STACKSIZE + .long _LM32_STACK_TOP .size g_idle_topstack, .-g_idle_topstack .end From 155f863ca16f9ca8f5d89dda084be7872f2c271a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 07:04:44 -0600 Subject: [PATCH 112/155] Update README --- configs/misoc/README.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/misoc/README.txt b/configs/misoc/README.txt index b75eaad7e8..285b6a4724 100644 --- a/configs/misoc/README.txt +++ b/configs/misoc/README.txt @@ -1,6 +1,9 @@ Misoc README ============ + This README applies to a port to NuttX running on a Qemu LM32 system. You + can find the Qemu setup at https://bitbucket.org/key2/qemu + Buildroot Toolchain =================== From 86ef659ee56f53a49aece6b8fba2f9655e682e05 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 07:16:53 -0600 Subject: [PATCH 113/155] LM32: Fix a typo in my many patching; eliminate some warnings --- arch/misoc/src/common/misoc_serial.c | 7 ------- arch/misoc/src/lm32/lm32_vectors.S | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/misoc/src/common/misoc_serial.c b/arch/misoc/src/common/misoc_serial.c index c46e83775a..9b15ba8e12 100644 --- a/arch/misoc/src/common/misoc_serial.c +++ b/arch/misoc/src/common/misoc_serial.c @@ -147,9 +147,6 @@ struct misoc_dev_s /* Low-level helpers */ -static inline uint32_t misoc_serialin(struct misoc_dev_s *priv, int offset); -static inline void misoc_serialout(struct misoc_dev_s *priv, int offset, - uint32_t value); static void misoc_restoreuartint(struct uart_dev_s *dev, uint8_t im); static void misoc_disableuartint(struct uart_dev_s *dev, uint8_t *im); @@ -261,8 +258,6 @@ static void misoc_restoreuartint(struct uart_dev_s *dev, uint8_t im) static void misoc_disableuartint(struct uart_dev_s *dev, uint8_t *im) { - struct misoc_dev_s *priv = (struct misoc_dev_s *)dev->priv; - if (im) { *im = uart_ev_enable_read(); @@ -371,7 +366,6 @@ static int misoc_uart_interrupt(int irq, void *context) { uint32_t stat; struct uart_dev_s *dev = NULL; - int i; dev = &g_uart1port; @@ -504,7 +498,6 @@ static void misoc_send(struct uart_dev_s *dev, int ch) static void misoc_txint(struct uart_dev_s *dev, bool enable) { uint8_t im; - int i; im = uart_ev_enable_read(); if (enable) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index a71cf63b98..95cfd26001 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -286,6 +286,6 @@ _do_reset: .type g_idle_topstack, object g_idle_topstack: - .long _LM32_STACK_TOP + .long LM32_STACK_TOP .size g_idle_topstack, .-g_idle_topstack .end From 424ffc76dc6706a9222996222e24ebd229658b93 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 07:31:15 -0600 Subject: [PATCH 114/155] LM32: Add missing _exit() logic (untested) --- arch/misoc/include/syscall.h | 37 +------------ arch/misoc/src/lm32/lm32_exit.c | 98 ++++++++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 37 deletions(-) diff --git a/arch/misoc/include/syscall.h b/arch/misoc/include/syscall.h index 71b9e85a6c..709ac8fa07 100644 --- a/arch/misoc/include/syscall.h +++ b/arch/misoc/include/syscall.h @@ -46,43 +46,8 @@ /* Include LM32 architecture-specific syscall macros */ -#ifdef CONFIG_ARCH_MISOC +#ifdef CONFIG_ARCH_CHIP_LM32 # include #endif -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Types - ****************************************************************************/ - -/**************************************************************************** - * Inline functions - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#ifndef __ASSEMBLY__ -#ifdef __cplusplus -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - -#undef EXTERN -#ifdef __cplusplus -} -#endif -#endif - #endif /* __ARCH_MISOC_INCLUDE_SYSCALL_H */ diff --git a/arch/misoc/src/lm32/lm32_exit.c b/arch/misoc/src/lm32/lm32_exit.c index 688f085426..a5f0cd3743 100644 --- a/arch/misoc/src/lm32/lm32_exit.c +++ b/arch/misoc/src/lm32/lm32_exit.c @@ -48,6 +48,8 @@ # include #endif +#include + #include "task/task.h" #include "sched/sched.h" #include "group/group.h" @@ -61,6 +63,63 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: _up_dumponexit + * + * Description: + * Dump the state of all tasks whenever on task exits. This is debug + * instrumentation that was added to check file-related reference counting + * but could be useful again sometime in the future. + * + ****************************************************************************/ + +#ifdef CONFIG_DUMP_ON_EXIT +static void _up_dumponexit(FAR struct tcb_s *tcb, FAR void *arg) +{ +#if CONFIG_NFILE_DESCRIPTORS > 0 + FAR struct filelist *filelist; +#if CONFIG_NFILE_STREAMS > 0 + FAR struct streamlist *streamlist; +#endif + int i; +#endif + + sinfo(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid); + sinfo(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state); + +#if CONFIG_NFILE_DESCRIPTORS > 0 + filelist = tcb->group->tg_filelist; + for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++) + { + struct inode *inode = filelist->fl_files[i].f_inode; + if (inode) + { + sinfo(" fd=%d refcount=%d\n", + i, inode->i_crefssinfo); + } + } +#endif + +#if CONFIG_NFILE_STREAMS > 0 + streamlist = tcb->group->tg_streamlist; + for (i = 0; i < CONFIG_NFILE_STREAMS; i++) + { + struct file_struct *filep = &streamlist->sl_streams[i]; + if (filep->fs_fd >= 0) + { +#if CONFIG_STDIO_BUFFER_SIZE > 0 + sinfo(" fd=%d nbytes=%d\n", + filep->fs_fd, + filep->fs_bufpos - filep->fs_bufstart); +#else + sinfo(" fd=%d\n", filep->fs_fd); +#endif + } + } +#endif +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -78,5 +137,42 @@ void _exit(int status) { -#warning Missing logic + struct tcb_s *tcb; + + /* Disable interrupts. They will be restored when the next + * task is started. + */ + + (void)up_irq_save(); + + sinfo("TCB=%p exiting\n", this_task()); + +#ifdef CONFIG_DUMP_ON_EXIT + sinfo("Other tasks:\n"); + sched_foreach(_up_dumponexit, NULL); +#endif + + /* Destroy the task at the head of the ready to run list. */ + + (void)task_exit(); + + /* Now, perform the context switch to the new ready-to-run task at the + * head of the list. + */ + + tcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously running + * task is closed down gracefully (data caches dump, MMU flushed) and + * set up the address environment for the new thread at the head of + * the ready-to-run list. + */ + + (void)group_addrenv(tcb); +#endif + + /* Then switch contexts */ + + up_fullcontextrestore(tcb->xcp.regs); } From c0af10125780b4ed0aa72d768f5f4924d3191251 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 08:12:33 -0600 Subject: [PATCH 115/155] Remove Eclipse project garbage --- .cproject | 52 ---------------------------------------------------- .gitignore | 2 -- .project | 26 -------------------------- 3 files changed, 80 deletions(-) delete mode 100644 .cproject delete mode 100644 .project diff --git a/.cproject b/.cproject deleted file mode 100644 index 623b3f8a2a..0000000000 --- a/.cproject +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.gitignore b/.gitignore index 839c74cb5e..3ec700458d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,5 +28,3 @@ cscope.out /*.hex /pcode /tags -.cproject -.project \ No newline at end of file diff --git a/.project b/.project deleted file mode 100644 index 2fa85124b0..0000000000 --- a/.project +++ /dev/null @@ -1,26 +0,0 @@ - - - nuttx - - - - - - org.eclipse.cdt.managedbuilder.core.genmakebuilder - clean,full,incremental, - - - - - org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder - full,incremental, - - - - - - org.eclipse.cdt.core.cnature - org.eclipse.cdt.managedbuilder.core.managedBuildNature - org.eclipse.cdt.managedbuilder.core.ScannerConfigNature - - From ac6581acecac998e673e67891754cb836a165994 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 08:28:39 -0600 Subject: [PATCH 116/155] Changes from review of last PR --- arch/arm/src/stm32f7/stm32_otgdev.c | 1 - configs/stm32f746-ws/include/board.h | 20 ++-- configs/stm32f746-ws/nsh/defconfig | 111 ++++++------------ .../stm32f746-ws/src/stm32_appinitialize.c | 6 +- configs/stm32f746-ws/src/stm32_sdmmc.c | 2 +- configs/stm32f746-ws/src/stm32_usb.c | 3 +- configs/stm32f746-ws/src/stm32f746-ws.h | 54 ++++----- 7 files changed, 80 insertions(+), 117 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_otgdev.c b/arch/arm/src/stm32f7/stm32_otgdev.c index 59a0db983d..9bf818182b 100644 --- a/arch/arm/src/stm32f7/stm32_otgdev.c +++ b/arch/arm/src/stm32f7/stm32_otgdev.c @@ -4234,7 +4234,6 @@ static void stm32_epin_disable(FAR struct stm32_ep_s *privep) regval |= OTG_DIEPINT_EPDISD; stm32_putreg(regval, regaddr); - /* Flush any data remaining in the TxFIFO */ stm32_txfifo_flush(OTG_GRSTCTL_TXFNUM_D(privep->epphy)); diff --git a/configs/stm32f746-ws/include/board.h b/configs/stm32f746-ws/include/board.h index 65a27fc6b7..b58542d120 100644 --- a/configs/stm32f746-ws/include/board.h +++ b/configs/stm32f746-ws/include/board.h @@ -124,7 +124,7 @@ /* Configure factors for PLLSAI clock */ -#define CONFIG_STM32F7_PLLSAI 1 +#define CONFIG_STM32F7_PLLSAI 1 #define STM32_RCC_PLLSAICFGR_PLLSAIN RCC_PLLSAICFGR_PLLSAIN(192) #define STM32_RCC_PLLSAICFGR_PLLSAIP RCC_PLLSAICFGR_PLLSAIP(2) #define STM32_RCC_PLLSAICFGR_PLLSAIQ RCC_PLLSAICFGR_PLLSAIQ(2) @@ -141,10 +141,9 @@ #define STM32_RCC_DCKCFGR1_DFSDM1SRC 0 #define STM32_RCC_DCKCFGR1_ADFSDM1SRC 0 - - /* Configure factors for PLLI2S clock */ -#define CONFIG_STM32F7_PLLI2S 1 + +#define CONFIG_STM32F7_PLLI2S 1 #define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192) #define STM32_RCC_PLLI2SCFGR_PLLI2SP RCC_PLLI2SCFGR_PLLI2SP(2) #define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2) @@ -170,7 +169,6 @@ #define STM32_RCC_DCKCFGR2_SDMMC2SRC RCC_DCKCFGR2_SDMMC2SEL_48MHZ #define STM32_RCC_DCKCFGR2_DSISRC RCC_DCKCFGR2_DSISEL_48MHZ - /* Several prescalers allow the configuration of the two AHB buses, the * high-speed APB (APB2) and the low-speed APB (APB1) domains. The maximum * frequency of the two AHB buses is 216 MHz while the maximum frequency of @@ -264,7 +262,7 @@ * DMAMAP_SDMMC1_2 = Channel 4, Stream 6 */ -#define DMAMAP_SDMMC1 DMAMAP_SDMMC1_1 +#define DMAMAP_SDMMC1 DMAMAP_SDMMC1_1 /* SDIO dividers. Note that slower clocking is required when DMA is disabled * in order to avoid RX overrun/TX underrun errors due to delayed responses @@ -274,16 +272,16 @@ * SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(118+2)=400 KHz */ -#define STM32_SDMMC_INIT_CLKDIV (118 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +#define STM32_SDMMC_INIT_CLKDIV (118 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) /* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz * DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz */ #ifdef CONFIG_SDIO_DMA -# define STM32_SDMMC_MMCXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_MMCXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else -# define STM32_SDMMC_MMCXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_MMCXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif /* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz @@ -291,9 +289,9 @@ */ #ifdef CONFIG_SDIO_DMA -# define STM32_SDMMC_SDXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_SDXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #else -# define STM32_SDMMC_SDXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) +# define STM32_SDMMC_SDXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT) #endif /************************************************************************************ diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index 3da3bc4b5f..ae75c897c2 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -53,12 +53,6 @@ CONFIG_ARCH_HAVE_CUSTOMOPT=y CONFIG_DEBUG_NOOPT=y # CONFIG_DEBUG_CUSTOMOPT is not set # CONFIG_DEBUG_FULLOPT is not set -CONFIG_DEBUG_ERROR=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_WARN=y -CONFIG_DEBUG_FS_INFO=y -CONFIG_DEBUG_FS_ERROR=y -CONFIG_DEBUG_FS_WARN=y # # System Type @@ -67,10 +61,13 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -160,6 +157,7 @@ CONFIG_ARMV7M_HAVE_STACKCHECK=y # CONFIG_ARMV7M_ITMSYSLOG is not set # CONFIG_SERIAL_TERMIOS is not set # CONFIG_USART6_RS485 is not set +# CONFIG_USART6_RXDMA is not set # CONFIG_SERIAL_DISABLE_REORDERING is not set # @@ -263,7 +261,7 @@ CONFIG_STM32F7_HAVE_RNG=y CONFIG_STM32F7_HAVE_SPI5=y CONFIG_STM32F7_HAVE_SPI6=y # CONFIG_STM32F7_HAVE_SDMMC2 is not set -# CONFIG_STM32F7_HAVE_ADC1_DMA is not set +CONFIG_STM32F7_HAVE_ADC1_DMA=y # CONFIG_STM32F7_HAVE_ADC2_DMA is not set # CONFIG_STM32F7_HAVE_ADC3_DMA is not set # CONFIG_STM32F7_HAVE_CAN3 is not set @@ -365,10 +363,18 @@ CONFIG_STM32F7_I2CTIMEOSEC=0 CONFIG_STM32F7_I2CTIMEOMS=500 CONFIG_STM32F7_I2CTIMEOTICKS=500 # CONFIG_STM32F7_I2C_DUTY16_9 is not set + +# +# SDMMC1 Configuration +# +CONFIG_SDMMC1_DMA=y +CONFIG_SDMMC1_DMAPRIO=0x00010000 +# CONFIG_SDMMC1_WIDTH_D1_ONLY is not set # CONFIG_STM32F7_HAVE_RTC_COUNTER is not set # CONFIG_STM32F7_HAVE_RTC_SUBSECONDS is not set # CONFIG_STM32F7_CUSTOM_CLOCKCONFIG is not set # CONFIG_STM32F7_DTCMEXCLUDE is not set +CONFIG_STM32F7_DMACAPABLE=y # # Timer Configuration @@ -377,6 +383,7 @@ CONFIG_STM32F7_I2CTIMEOTICKS=500 # # ADC Configuration # +# CONFIG_STM32F7_ADC1_DMA is not set # # Architecture Options @@ -446,8 +453,6 @@ CONFIG_ARCH_BOARD="stm32f746-ws" # # Common Board Options # -CONFIG_NSH_MMCSDMINOR=0 -CONFIG_NSH_MMCSDSLOTNO=0 # # Board-Specific Options @@ -460,7 +465,6 @@ CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_PWMTEST is not set # CONFIG_BOARDCTL_GRAPHICS is not set # CONFIG_BOARDCTL_IOCTL is not set -CONFIG_BOARDCTL_USBDEVCTRL=y # # RTOS Features @@ -586,17 +590,6 @@ CONFIG_DEV_NULL=y # CONFIG_DEV_URANDOM is not set # CONFIG_DEV_LOOP is not set -CONFIG_MMCSD=y -CONFIG_MMCSD_NSLOTS=1 -# CONFIG_MMCSD_READONLY is not set -CONFIG_MMCSD_MULTIBLOCK_DISABLE=y -# CONFIG_MMCSD_MMCSUPPORT is not set -CONFIG_MMCSD_HAVECARDDETECT=y -# CONFIG_MMCSD_SPI is not set -CONFIG_ARCH_HAVE_SDIO=y -CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE=y -CONFIG_MMCSD_SDIO=y - # # Buffering # @@ -615,26 +608,25 @@ CONFIG_I2C_RESET=y # CONFIG_I2C_TRACE is not set CONFIG_I2C_DRIVER=y CONFIG_SPI=y +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_SPI_SLAVE is not set CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CMDDATA is not set # CONFIG_SPI_CALLBACK is not set # CONFIG_SPI_HWFEATURES is not set -# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set -# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set -CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_SPI_BITORDER is not set # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_SPI_DRIVER is not set # CONFIG_SPI_BITBANG is not set # CONFIG_I2S is not set -CONFIG_SDIO_DMA=y - # # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set CONFIG_WATCHDOG=y CONFIG_WATCHDOG_DEVPATH="/dev/watchdog0" @@ -670,6 +662,9 @@ CONFIG_ADC_FIFOSIZE=8 # CONFIG_PCA9635PW is not set # CONFIG_NCP5623C is not set # CONFIG_MMCSD is not set +CONFIG_ARCH_HAVE_SDIO=y +CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE=y +CONFIG_SDIO_PREFLIGHT=y # CONFIG_MODEM is not set # CONFIG_MTD is not set # CONFIG_EEPROM is not set @@ -731,54 +726,12 @@ CONFIG_USART6_2STOP=0 # CONFIG_USART6_IFLOWCONTROL is not set # CONFIG_USART6_OFLOWCONTROL is not set # CONFIG_USART6_DMA is not set -CONFIG_USBDEV=y -# CONFIG_USBHOST is not set -# CONFIG_DRIVERS_WIRELESS is not set - - -# -# USB Device Controller Driver Options -# -# CONFIG_USBDEV_ISOCHRONOUS is not set -# CONFIG_USBDEV_DUALSPEED is not set -CONFIG_USBDEV_SELFPOWERED=y -# CONFIG_USBDEV_BUSPOWERED is not set -CONFIG_USBDEV_MAXPOWER=100 -# CONFIG_USBDEV_DMA is not set -# CONFIG_ARCH_USBDEV_STALLQUEUE is not set -# CONFIG_USBDEV_TRACE is not set - -# -# USB Device Class Driver Options -# -# CONFIG_USBDEV_COMPOSITE is not set -# CONFIG_PL2303 is not set -CONFIG_CDCACM=y -CONFIG_CDCACM_EP0MAXPACKET=64 -CONFIG_CDCACM_EPINTIN=1 -CONFIG_CDCACM_EPINTIN_FSSIZE=64 -CONFIG_CDCACM_EPINTIN_HSSIZE=64 -CONFIG_CDCACM_EPBULKOUT=2 -CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 -CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 -CONFIG_CDCACM_EPBULKIN=2 -CONFIG_CDCACM_EPBULKIN_FSSIZE=64 -CONFIG_CDCACM_EPBULKIN_HSSIZE=512 -CONFIG_CDCACM_NRDREQS=4 -CONFIG_CDCACM_NWRREQS=4 -CONFIG_CDCACM_BULKIN_REQLEN=96 -CONFIG_CDCACM_RXBUFSIZE=256 -CONFIG_CDCACM_TXBUFSIZE=256 -CONFIG_CDCACM_VENDORID=0x03EB -CONFIG_CDCACM_PRODUCTID=0x2044 -CONFIG_CDCACM_VENDORSTR="NuttX" -CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" -# CONFIG_USBMSC is not set # CONFIG_PSEUDOTERM is not set # CONFIG_USBDEV is not set # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -827,7 +780,10 @@ CONFIG_FS_FAT=y CONFIG_FAT_LCNAMES=y CONFIG_FAT_LFN=y CONFIG_FAT_MAXFNAME=32 +# CONFIG_FS_FATTIME is not set +# CONFIG_FAT_FORCE_INDIRECT is not set CONFIG_FAT_DMAMEMORY=y +CONFIG_FAT_DIRECT_RETRY=y # CONFIG_FS_NXFFS is not set # CONFIG_FS_ROMFS is not set # CONFIG_FS_TMPFS is not set @@ -887,6 +843,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -898,6 +856,8 @@ CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 CONFIG_LIBC_STRERROR=y # CONFIG_LIBC_STRERROR_SHORT is not set # CONFIG_LIBC_PERROR_STDOUT is not set +CONFIG_LIBC_TMPDIR="/tmp" +CONFIG_LIBC_MAX_TMPFILE=32 CONFIG_ARCH_LOWPUTC=y # CONFIG_LIBC_LOCALTIME is not set # CONFIG_TIME_EXTENDED is not set @@ -907,6 +867,7 @@ CONFIG_LIB_SENDFILE_BUFSIZE=512 CONFIG_ARCH_HAVE_TLS=y # CONFIG_TLS is not set # CONFIG_LIBC_NETDB is not set +# CONFIG_NETDB_HOSTFILE is not set # # Non-standard Library Support @@ -946,12 +907,14 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # Examples # # CONFIG_EXAMPLES_ADC is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_CPUHOG is not set # CONFIG_EXAMPLES_CXXTEST is not set # CONFIG_EXAMPLES_DHCPD is not set # CONFIG_EXAMPLES_ELF is not set +# CONFIG_EXAMPLES_FSTEST is not set # CONFIG_EXAMPLES_FTPC is not set # CONFIG_EXAMPLES_FTPD is not set # CONFIG_EXAMPLES_HELLO is not set @@ -1004,6 +967,7 @@ CONFIG_EXAMPLES_NSH=y # File System Utilities # # CONFIG_FSUTILS_INIFILE is not set +# CONFIG_FSUTILS_PASSWD is not set # # GPS Utilities @@ -1019,8 +983,10 @@ CONFIG_EXAMPLES_NSH=y # # Interpreters # +# CONFIG_INTERPRETERS_BAS is not set # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -1087,12 +1053,14 @@ CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_LS is not set # CONFIG_NSH_DISABLE_MB is not set # CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKFATFS is not set # CONFIG_NSH_DISABLE_MKFIFO is not set # CONFIG_NSH_DISABLE_MKRD is not set # CONFIG_NSH_DISABLE_MH is not set # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set # CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y # CONFIG_NSH_DISABLE_PS is not set # CONFIG_NSH_DISABLE_PSSTACKUSAGE is not set # CONFIG_NSH_DISABLE_PUT is not set @@ -1170,9 +1138,8 @@ CONFIG_READLINE_ECHO=y # CONFIG_READLINE_CMD_HISTORY is not set # CONFIG_SYSTEM_STACKMONITOR is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_SYSTEM is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set - -CONFIG_SYSTEM_CDCACM=y -CONFIG_SYSTEM_CDCACM_DEVMINOR=0 diff --git a/configs/stm32f746-ws/src/stm32_appinitialize.c b/configs/stm32f746-ws/src/stm32_appinitialize.c index 0a58e61e36..8079b43f69 100644 --- a/configs/stm32f746-ws/src/stm32_appinitialize.c +++ b/configs/stm32f746-ws/src/stm32_appinitialize.c @@ -108,9 +108,9 @@ int board_app_initialize(void) ret = stm32_sdio_initialize(); if (ret != OK) { - ferr("ERROR: Failed to initialize MMC/SD driver: %d\n", ret); - return ret; - } + ferr("ERROR: Failed to initialize MMC/SD driver: %d\n", ret); + return ret; + } #endif return OK; diff --git a/configs/stm32f746-ws/src/stm32_sdmmc.c b/configs/stm32f746-ws/src/stm32_sdmmc.c index 4169d511a2..9dfaaa34a7 100644 --- a/configs/stm32f746-ws/src/stm32_sdmmc.c +++ b/configs/stm32f746-ws/src/stm32_sdmmc.c @@ -1,7 +1,7 @@ /**************************************************************************** * config/stm32f746-ws/src/stm32_sdmmc.c * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without diff --git a/configs/stm32f746-ws/src/stm32_usb.c b/configs/stm32f746-ws/src/stm32_usb.c index d0c118af89..770f950fa0 100644 --- a/configs/stm32f746-ws/src/stm32_usb.c +++ b/configs/stm32f746-ws/src/stm32_usb.c @@ -1,7 +1,7 @@ /************************************************************************************ * configs/stm32f4discovery/src/stm32_usb.c * - * Copyright (C) 2012-2013, 2015 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -152,7 +152,6 @@ void stm32_usbinitialize(void) stm32_configgpio(GPIO_OTGFS_PWRON); stm32_configgpio(GPIO_OTGFS_OVER); #endif - #endif } diff --git a/configs/stm32f746-ws/src/stm32f746-ws.h b/configs/stm32f746-ws/src/stm32f746-ws.h index 0a61a7b162..681ceb3068 100644 --- a/configs/stm32f746-ws/src/stm32f746-ws.h +++ b/configs/stm32f746-ws/src/stm32f746-ws.h @@ -82,11 +82,11 @@ #define GPIO_BTN_USER (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | GPIO_PORTC | GPIO_PIN13) -#define GPIO_OTGFS_VBUS (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|\ - GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9) +#define GPIO_OTGFS_VBUS (GPIO_INPUT|GPIO_FLOAT|GPIO_SPEED_100MHz|\ + GPIO_OPENDRAIN|GPIO_PORTA|GPIO_PIN9) -#define SDIO_SLOTNO 0 -#define SDIO_MINOR 0 +#define SDIO_SLOTNO 0 +#define SDIO_MINOR 0 /**************************************************************************************************** * Public data @@ -108,32 +108,32 @@ void weak_function stm32_spidev_initialize(void); - /**************************************************************************** - * Name: stm32_sdio_initialize - * - * Description: - * Initialize SDIO-based MMC/SD card support - * - ****************************************************************************/ +/**************************************************************************** + * Name: stm32_sdio_initialize + * + * Description: + * Initialize SDIO-based MMC/SD card support + * + ****************************************************************************/ - #if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_STM32F7_SDMMC1) - int stm32_sdio_initialize(void); - #endif +#if !defined(CONFIG_DISABLE_MOUNTPOINT) && defined(CONFIG_STM32F7_SDMMC1) +int stm32_sdio_initialize(void); +#endif - /************************************************************************************ - * Name: stm32_dma_alloc_init - * - * Description: - * Called to create a FAT DMA allocator - * - * Returned Value: - * 0 on success or -ENOMEM - * - ************************************************************************************/ +/************************************************************************************ + * Name: stm32_dma_alloc_init + * + * Description: + * Called to create a FAT DMA allocator + * + * Returned Value: + * 0 on success or -ENOMEM + * + ************************************************************************************/ - #if defined (CONFIG_FAT_DMAMEMORY) - int stm32_dma_alloc_init(void); - #endif +#if defined (CONFIG_FAT_DMAMEMORY) +int stm32_dma_alloc_init(void); +#endif #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_STM32F746_WS_SRC_STM32F746_WS_H */ From dd04d73afebb7de0cc965fadf05f4a94dfae80f4 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 09:16:34 -0600 Subject: [PATCH 117/155] STM32F7 SD/MMC driver depends on CONFIG_SDIO_DMA which is only defined in stm32/Kconfig. Changed to CONFIG_STM32F7_SDMMC_DMA and defined in stm32f7/Kconfig. --- arch/arm/src/stm32f7/Kconfig | 20 +++++++- arch/arm/src/stm32f7/stm32_sdmmc.c | 76 +++++++++++++++--------------- configs/stm32f746-ws/nsh/defconfig | 63 +++++++++++++++++++++++-- 3 files changed, 116 insertions(+), 43 deletions(-) diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index 75dd21454b..c909a1d980 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -992,6 +992,10 @@ config STM32F7_SAI bool default n +config STM32F7_SDMMC + bool + default n + config STM32F7_SPI bool default n @@ -1006,7 +1010,6 @@ config STM32F7_USART # These are the peripheral selections proper - config STM32F7_ADC1 bool "ADC1" default n @@ -1218,6 +1221,7 @@ config STM32F7_SAI2 config STM32F7_SDMMC1 bool "SDMMC1" default n + select STM32F7_SDMMC select ARCH_HAVE_SDIO select ARCH_HAVE_SDIOWAIT_WRCOMPLETE select SDIO_PREFLIGHT @@ -1226,6 +1230,7 @@ config STM32F7_SDMMC2 bool "SDMMC2" default n depends on STM32F7_HAVE_SDMMC2 + select STM32F7_SDMMC select ARCH_HAVE_SDIO select ARCH_HAVE_SDIOWAIT_WRCOMPLETE select SDIO_PREFLIGHT @@ -1718,9 +1723,12 @@ config STM32F7_I2C_DUTY16_9 endmenu # "I2C Configuration" +menu "SD/MMC Configuration" + depends on STM32F7_SDMMC + config STM32F7_SDMMC_XFRDEBUG bool "SDMMC transfer debug" - depends on DEBUG_FS_INFO && (STM32F7_SDMMC1 || STM32F7_SDMMC2) + depends on DEBUG_FS_INFO default n ---help--- Enable special debug instrumentation analyze SDMMC data transfers. @@ -1730,6 +1738,13 @@ config STM32F7_SDMMC_XFRDEBUG enabled, then DMA register will be collected as well. Requires also DEBUG_FS and CONFIG_DEBUG_INFO. +config STM32F7_SDMMC_DMA + bool "Support DMA data transfers" + default n + depends on STM32F7_DMA + ---help--- + Support DMA data transfers. + menu "SDMMC1 Configuration" depends on STM32F7_SDMMC1 @@ -1797,6 +1812,7 @@ config SDMMC2_WIDTH_D1_ONLY Select 1-bit transfer mode. Default: 4-bit transfer mode. endmenu # "SDMMC2 Configuration" +endmenu # "SD/MMC Configuration" if STM32F7_BKPSRAM diff --git a/arch/arm/src/stm32f7/stm32_sdmmc.c b/arch/arm/src/stm32f7/stm32_sdmmc.c index 3a639472f3..52e7ef3878 100644 --- a/arch/arm/src/stm32f7/stm32_sdmmc.c +++ b/arch/arm/src/stm32f7/stm32_sdmmc.c @@ -87,7 +87,7 @@ * CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking * APIs to manage concurrent accesses on the SDMMC bus. This is not * needed for the simple case of a single SD card, for example. - * CONFIG_SDIO_DMA - Enable SDMMC. This is a marginally optional. For + * CONFIG_STM32F7_SDMMC_DMA - Enable SDMMC. This is a marginally optional. For * most usages, SDMMC will cause data overruns if used without DMA. * NOTE the above system DMA configuration options. * CONFIG_SDMMC_WIDTH_D1_ONLY - This may be selected to force the driver @@ -96,16 +96,16 @@ * CONFIG_SDMMC_PRI - SDMMC interrupt priority. This setting is not very * important since interrupt nesting is not currently supported. * CONFIG_SDMMMC_DMAPRIO - SDMMC DMA priority. This can be selecte if - * CONFIG_SDIO_DMA is enabled. + * CONFIG_STM32F7_SDMMC_DMA is enabled. * CONFIG_CONFIG_STM32F7_SDMMC_XFRDEBUG - Enables some very low-level debug output * This also requires CONFIG_DEBUG_FS and CONFIG_DEBUG_INFO */ -#if defined(CONFIG_SDIO_DMA) && !defined(CONFIG_STM32F7_DMA2) -# warning "CONFIG_SDIO_DMA support requires CONFIG_STM32F7_DMA2" +#if defined(CONFIG_STM32F7_SDMMC_DMA) && !defined(CONFIG_STM32F7_DMA2) +# warning "CONFIG_STM32F7_SDMMC_DMA support requires CONFIG_STM32F7_DMA2" #endif -#ifndef CONFIG_SDIO_DMA +#ifndef CONFIG_STM32F7_SDMMC_DMA # warning "Large Non-DMA transfer may result in RX overrun failures" #endif @@ -118,7 +118,7 @@ # define CONFIG_SDMMC1_PRI NVIC_SYSH_PRIORITY_DEFAULT # endif -# ifdef CONFIG_SDIO_DMA +# ifdef CONFIG_STM32F7_SDMMC_DMA # ifndef CONFIG_SDMMC1_DMAPRIO # define CONFIG_SDMMC1_DMAPRIO DMA_SCR_PRIVERYHI # endif @@ -135,7 +135,7 @@ # define CONFIG_SDMMC2_PRI NVIC_SYSH_PRIORITY_DEFAULT # endif -# ifdef CONFIG_SDIO_DMA +# ifdef CONFIG_STM32F7_SDMMC_DMA # ifndef CONFIG_SDMMC2_DMAPRIO # define CONFIG_SDMMC2_DMAPRIO DMA_SCR_PRIVERYHI # endif @@ -307,7 +307,7 @@ /* Register logging support */ #ifdef CONFIG_STM32F7_SDMMC_XFRDEBUG -# ifdef CONFIG_SDIO_DMA +# ifdef CONFIG_STM32F7_SDMMC_DMA # define SAMPLENDX_BEFORE_SETUP 0 # define SAMPLENDX_BEFORE_ENABLE 1 # define SAMPLENDX_AFTER_SETUP 2 @@ -343,7 +343,7 @@ struct stm32_dev_s uint32_t d0_gpio; xcpt_t wrchandler; #endif -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA uint32_t dmapri; #endif @@ -372,7 +372,7 @@ struct stm32_dev_s /* DMA data transfer support */ bool widebus; /* Required for DMA support */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA volatile uint8_t xfrflags; /* Used to synchronize SDMMC and DMA completion events */ bool dmamode; /* true: DMA mode transfer */ DMA_HANDLE dma; /* Handle for DMA channel */ @@ -398,7 +398,7 @@ struct stm32_sdioregs_s struct stm32_sampleregs_s { struct stm32_sdioregs_s sdio; -#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32F7_SDMMC_DMA) struct stm32_dmaregs_s dma; #endif }; @@ -439,7 +439,7 @@ static void stm32_dumpsamples(struct stm32_dev_s *priv); # define stm32_dumpsamples(priv) #endif -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg); #endif @@ -525,7 +525,7 @@ static int stm32_registercallback(FAR struct sdio_dev_s *dev, /* DMA */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA static bool stm32_dmasupported(FAR struct sdio_dev_s *dev); #ifdef CONFIG_SDIO_PREFLIGHT static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, @@ -577,7 +577,7 @@ struct stm32_dev_s g_sdmmcdev1 = .eventwait = stm32_eventwait, .callbackenable = stm32_callbackenable, .registercallback = stm32_registercallback, -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA .dmasupported = stm32_dmasupported, #ifdef CONFIG_SDIO_PREFLIGHT .dmapreflight = stm32_dmapreflight, @@ -633,7 +633,7 @@ struct stm32_dev_s g_sdmmcdev2 = .eventwait = stm32_eventwait, .callbackenable = stm32_callbackenable, .registercallback = stm32_registercallback, -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA .dmasupported = stm32_dmasupported, #ifdef CONFIG_SDIO_PREFLIGHT .dmapreflight = stm32_dmapreflight, @@ -840,7 +840,7 @@ static void stm32_configwaitints(struct stm32_dev_s *priv, uint32_t waitmask, priv->waitevents = waitevents; priv->wkupevent = wkupevent; priv->waitmask = waitmask; -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA priv->xfrflags = 0; #endif sdmmc_putreg32(priv, priv->xfrmask | priv->waitmask, STM32_SDMMC_MASK_OFFSET); @@ -975,7 +975,7 @@ static void stm32_sample(struct stm32_dev_s *priv, int index) { struct stm32_sampleregs_s *regs = &g_sampleregs[index]; -#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32F7_SDMMC_DMA) if (priv->dmamode) { stm32_dmasample(priv->dma, ®s->dma); @@ -1022,7 +1022,7 @@ static void stm32_sdiodump(struct stm32_sdioregs_s *regs, const char *msg) static void stm32_dumpsample(struct stm32_dev_s *priv, struct stm32_sampleregs_s *regs, const char *msg) { -#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32F7_SDMMC_DMA) if (priv->dmamode) { stm32_dmadump(priv->dma, ®s->dma, msg); @@ -1046,7 +1046,7 @@ static void stm32_dumpsamples(struct stm32_dev_s *priv) { stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_SETUP], "Before setup"); -#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32F7_SDMMC_DMA) if (priv->dmamode) { stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_BEFORE_ENABLE], "Before DMA enable"); @@ -1056,7 +1056,7 @@ static void stm32_dumpsamples(struct stm32_dev_s *priv) stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_AFTER_SETUP], "After setup"); stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_END_TRANSFER], "End of transfer"); -#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_SDIO_DMA) +#if defined(CONFIG_DEBUG_DMA_INFO) && defined(CONFIG_STM32F7_SDMMC_DMA) if (priv->dmamode) { stm32_dumpsample(priv, &g_sampleregs[SAMPLENDX_DMA_CALLBACK], "DMA Callback"); @@ -1073,7 +1073,7 @@ static void stm32_dumpsamples(struct stm32_dev_s *priv) * ****************************************************************************/ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA static void stm32_dmacallback(DMA_HANDLE handle, uint8_t status, void *arg) { FAR struct stm32_dev_s *priv = (FAR struct stm32_dev_s *)arg; @@ -1434,7 +1434,7 @@ static void stm32_endtransfer(struct stm32_dev_s *priv, /* If this was a DMA transfer, make sure that DMA is stopped */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA if (priv->dmamode) { /* DMA debug instrumentation */ @@ -1537,7 +1537,7 @@ static int stm32_sdmmc_interrupt(struct stm32_dev_s *priv) pending = enabled & priv->xfrmask; if (pending != 0) { -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA if (!priv->dmamode) #endif { @@ -1576,7 +1576,7 @@ static int stm32_sdmmc_interrupt(struct stm32_dev_s *priv) /* Was this transfer performed in DMA mode? */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA if (priv->dmamode) { /* Yes.. Terminate the transfers only if the DMA has also @@ -1812,7 +1812,7 @@ static void stm32_reset(FAR struct sdio_dev_s *dev) priv->waitevents = 0; /* Set of events to be waited for */ priv->waitmask = 0; /* Interrupt enables for event waiting */ priv->wkupevent = 0; /* The event that caused the wakeup */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA priv->xfrflags = 0; /* Used to synchronize SDIO and DMA * completion events */ #endif @@ -1828,7 +1828,7 @@ static void stm32_reset(FAR struct sdio_dev_s *dev) /* DMA data transfer support */ priv->widebus = false; /* Required for DMA support */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA priv->dmamode = false; /* true: DMA mode transfer */ #endif @@ -2108,7 +2108,7 @@ static int stm32_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, priv->buffer = (uint32_t *)buffer; priv->remaining = nbytes; -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA priv->dmamode = false; #endif @@ -2163,7 +2163,7 @@ static int stm32_sendsetup(FAR struct sdio_dev_s *dev, FAR const priv->buffer = (uint32_t *)buffer; priv->remaining = nbytes; -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA priv->dmamode = false; #endif @@ -2217,7 +2217,7 @@ static int stm32_cancel(FAR struct sdio_dev_s *dev) /* If this was a DMA transfer, make sure that DMA is stopped */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA if (priv->dmamode) { /* Make sure that the DMA is stopped (it will be stopped automatically @@ -2712,7 +2712,7 @@ static sdio_eventset_t stm32_eventwait(FAR struct sdio_dev_s *dev, /* Disable event-related interrupts */ stm32_configwaitints(priv, 0, 0, 0); -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA priv->xfrflags = 0; #endif @@ -2808,7 +2808,7 @@ static int stm32_registercallback(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA static bool stm32_dmasupported(FAR struct sdio_dev_s *dev) { return true; @@ -2831,7 +2831,7 @@ static bool stm32_dmasupported(FAR struct sdio_dev_s *dev) * OK on success; a negated errno on failure ****************************************************************************/ -#if defined(CONFIG_SDIO_DMA) && defined(CONFIG_SDIO_PREFLIGHT) +#if defined(CONFIG_STM32F7_SDMMC_DMA) && defined(CONFIG_SDIO_PREFLIGHT) static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, size_t buflen) { @@ -2877,7 +2877,7 @@ static int stm32_dmapreflight(FAR struct sdio_dev_s *dev, * ****************************************************************************/ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, size_t buflen) { @@ -2962,7 +2962,7 @@ static int stm32_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer, * ****************************************************************************/ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA static int stm32_dmasendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer, size_t buflen) { @@ -3152,7 +3152,7 @@ static void stm32_default(struct stm32_dev_s *priv) FAR struct sdio_dev_s *sdio_initialize(int slotno) { struct stm32_dev_s *priv = NULL; -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA unsigned int dmachan; #endif @@ -3162,7 +3162,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) /* Select SDMMC 1 */ priv = &g_sdmmcdev1; -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA dmachan = SDMMC1_DMACHAN; #endif @@ -3192,7 +3192,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) /* Select SDMMC 2 */ priv = &g_sdmmcdev2; -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA dmachan = SDMMC2_DMACHAN; #endif @@ -3232,7 +3232,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) /* Allocate a DMA channel */ -#ifdef CONFIG_SDIO_DMA +#ifdef CONFIG_STM32F7_SDMMC_DMA priv->dma = stm32_dmachannel(dmachan); DEBUGASSERT(priv->dma); #endif diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index ae75c897c2..94ab01db9f 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -156,6 +156,8 @@ CONFIG_ARMV7M_HAVE_STACKCHECK=y # CONFIG_ARMV7M_STACKCHECK is not set # CONFIG_ARMV7M_ITMSYSLOG is not set # CONFIG_SERIAL_TERMIOS is not set +# CONFIG_SDIO_DMA is not set +# CONFIG_SDIO_WIDTH_D1_ONLY is not set # CONFIG_USART6_RS485 is not set # CONFIG_USART6_RXDMA is not set # CONFIG_SERIAL_DISABLE_REORDERING is not set @@ -460,6 +462,7 @@ CONFIG_ARCH_BOARD="stm32f746-ws" # CONFIG_BOARD_CRASHDUMP is not set CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_UNIQUEID is not set +CONFIG_BOARDCTL_USBDEVCTRL=y # CONFIG_BOARDCTL_TSCTEST is not set # CONFIG_BOARDCTL_ADCTEST is not set # CONFIG_BOARDCTL_PWMTEST is not set @@ -661,10 +664,20 @@ CONFIG_ADC_FIFOSIZE=8 # CONFIG_RGBLED is not set # CONFIG_PCA9635PW is not set # CONFIG_NCP5623C is not set -# CONFIG_MMCSD is not set +CONFIG_MMCSD=y +CONFIG_MMCSD_NSLOTS=1 +# CONFIG_MMCSD_READONLY is not set +CONFIG_MMCSD_MULTIBLOCK_DISABLE=y +# CONFIG_MMCSD_MMCSUPPORT is not set +CONFIG_MMCSD_HAVECARDDETECT=y +# CONFIG_MMCSD_SPI is not set CONFIG_ARCH_HAVE_SDIO=y CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE=y +CONFIG_MMCSD_SDIO=y CONFIG_SDIO_PREFLIGHT=y +# CONFIG_SDIO_MUXBUS is not set +# CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE is not set +# CONFIG_SDIO_BLOCKSETUP is not set # CONFIG_MODEM is not set # CONFIG_MTD is not set # CONFIG_EEPROM is not set @@ -678,7 +691,7 @@ CONFIG_DEV_FIFO_SIZE=1024 # CONFIG_SERCOMM_CONSOLE is not set CONFIG_SERIAL=y # CONFIG_DEV_LOWCONSOLE is not set -# CONFIG_SERIAL_REMOVABLE is not set +CONFIG_SERIAL_REMOVABLE=y CONFIG_SERIAL_CONSOLE=y # CONFIG_16550_UART is not set # CONFIG_UART_SERIALDRIVER is not set @@ -727,7 +740,47 @@ CONFIG_USART6_2STOP=0 # CONFIG_USART6_OFLOWCONTROL is not set # CONFIG_USART6_DMA is not set # CONFIG_PSEUDOTERM is not set -# CONFIG_USBDEV is not set +CONFIG_USBDEV=y + +# +# USB Device Controller Driver Options +# +# CONFIG_USBDEV_ISOCHRONOUS is not set +# CONFIG_USBDEV_DUALSPEED is not set +CONFIG_USBDEV_SELFPOWERED=y +# CONFIG_USBDEV_BUSPOWERED is not set +CONFIG_USBDEV_MAXPOWER=100 +# CONFIG_USBDEV_DMA is not set +# CONFIG_ARCH_USBDEV_STALLQUEUE is not set +# CONFIG_USBDEV_TRACE is not set + +# +# USB Device Class Driver Options +# +# CONFIG_USBDEV_COMPOSITE is not set +# CONFIG_PL2303 is not set +CONFIG_CDCACM=y +# CONFIG_CDCACM_CONSOLE is not set +CONFIG_CDCACM_EP0MAXPACKET=64 +CONFIG_CDCACM_EPINTIN=1 +CONFIG_CDCACM_EPINTIN_FSSIZE=64 +CONFIG_CDCACM_EPINTIN_HSSIZE=512 +CONFIG_CDCACM_EPBULKOUT=3 +CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 +CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 +CONFIG_CDCACM_EPBULKIN=2 +CONFIG_CDCACM_EPBULKIN_FSSIZE=64 +CONFIG_CDCACM_EPBULKIN_HSSIZE=512 +CONFIG_CDCACM_NRDREQS=4 +CONFIG_CDCACM_NWRREQS=4 +CONFIG_CDCACM_BULKIN_REQLEN=96 +CONFIG_CDCACM_RXBUFSIZE=257 +CONFIG_CDCACM_TXBUFSIZE=193 +CONFIG_CDCACM_VENDORID=0x0525 +CONFIG_CDCACM_PRODUCTID=0xa4a7 +CONFIG_CDCACM_VENDORSTR="NuttX" +CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" +# CONFIG_USBMSC is not set # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set @@ -1079,6 +1132,7 @@ CONFIG_NSH_DISABLE_PRINTF=y # CONFIG_NSH_DISABLE_WGET is not set # CONFIG_NSH_DISABLE_XD is not set CONFIG_NSH_MMCSDMINOR=0 +CONFIG_NSH_MMCSDSLOTNO=0 # # Configure Command Options @@ -1100,6 +1154,7 @@ CONFIG_NSH_FILEIOSIZE=512 # Console Configuration # CONFIG_NSH_CONSOLE=y +# CONFIG_NSH_USBCONSOLE is not set # CONFIG_NSH_ALTCONDEV is not set CONFIG_NSH_ARCHINIT=y # CONFIG_NSH_LOGIN is not set @@ -1117,6 +1172,8 @@ CONFIG_NSH_ARCHINIT=y # # System Libraries and NSH Add-Ons # +CONFIG_SYSTEM_CDCACM=y +CONFIG_SYSTEM_CDCACM_DEVMINOR=0 # CONFIG_SYSTEM_CLE is not set # CONFIG_SYSTEM_CUTERM is not set # CONFIG_SYSTEM_FREE is not set From 1344d8b466d0e8d0c5eb8833104680a828caadb6 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 09:20:47 -0600 Subject: [PATCH 118/155] STM32F746-WS: A few repairs to the nsh/defconfig for USB support. --- arch/arm/src/stm32f7/Kconfig | 4 ++-- configs/stm32f746-ws/nsh/defconfig | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig index c909a1d980..ced8f62ca3 100644 --- a/arch/arm/src/stm32f7/Kconfig +++ b/arch/arm/src/stm32f7/Kconfig @@ -1751,7 +1751,7 @@ menu "SDMMC1 Configuration" config SDMMC1_DMA bool "Support DMA data transfers on SDMMC1" default y if STM32F7_DMA2 - depends on STM32F7_DMA2 + depends on STM32F7_SDMMC_DMA && STM32F7_DMA2 ---help--- Support DMA data transfers on SDMMC1. Requires STM32F7_SDMMC1 and config STM32F7_DMA2. @@ -1785,7 +1785,7 @@ menu "SDMMC2 Configuration" config SDMMC2_DMA bool "Support DMA data transfers on SDMMC2" default y if STM32F7_DMA2 - depends on STM32F7_DMA2 + depends on STM32F7_SDMMC_DMA && STM32F7_DMA2 ---help--- Support DMA data transfers on SDMMC2. Requires STM32F7_SDMMC2 and config STM32F7_DMA2. diff --git a/configs/stm32f746-ws/nsh/defconfig b/configs/stm32f746-ws/nsh/defconfig index 94ab01db9f..4ba7dddad4 100644 --- a/configs/stm32f746-ws/nsh/defconfig +++ b/configs/stm32f746-ws/nsh/defconfig @@ -280,6 +280,7 @@ CONFIG_STM32F7_ADC=y CONFIG_STM32F7_DMA=y CONFIG_STM32F7_I2C=y # CONFIG_STM32F7_SAI is not set +CONFIG_STM32F7_SDMMC=y CONFIG_STM32F7_SPI=y # CONFIG_STM32F7_TIM is not set CONFIG_STM32F7_USART=y @@ -366,6 +367,11 @@ CONFIG_STM32F7_I2CTIMEOMS=500 CONFIG_STM32F7_I2CTIMEOTICKS=500 # CONFIG_STM32F7_I2C_DUTY16_9 is not set +# +# SD/MMC Configuration +# +CONFIG_STM32F7_SDMMC_DMA=y + # # SDMMC1 Configuration # From eb9a8ed79098f328e2fc8ed66be85c10fa773c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Recht=C3=A9?= Date: Mon, 7 Nov 2016 09:35:48 -0600 Subject: [PATCH 119/155] STM37xx PWM: Add PWM driver support for STMF37xx. The changes have been tested successfuly for TIM4 and TIM17 (different IPs). --- arch/arm/src/stm32/chip/stm32_tim.h | 8 +- arch/arm/src/stm32/stm32_pwm.c | 539 +++++++++++++++++++--------- 2 files changed, 371 insertions(+), 176 deletions(-) diff --git a/arch/arm/src/stm32/chip/stm32_tim.h b/arch/arm/src/stm32/chip/stm32_tim.h index 56c748a98f..f4113cd6dd 100644 --- a/arch/arm/src/stm32/chip/stm32_tim.h +++ b/arch/arm/src/stm32/chip/stm32_tim.h @@ -31,6 +31,10 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * + * This the lower half driver for PWM and the STM32 F1 to F4 family MCUs + * Athough this driver does make the difference between 16/32-bit timers, + * it does manage all of them as 16-bit. This will have to be improved. + * ****************************************************************************************************/ #ifndef __ARCH_ARM_SRC_STM32_CHIP_STM32_TIM_H @@ -824,7 +828,9 @@ #define ATIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable */ #define ATIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity */ -#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F40XX) || defined(CONFIG_STM32_STM32L15XX) +#if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F40XX) || \ + defined(CONFIG_STM32_STM32L15XX) # define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */ #elif defined(CONFIG_STM32_STM32F30XX) # define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */ diff --git a/arch/arm/src/stm32/stm32_pwm.c b/arch/arm/src/stm32/stm32_pwm.c index 425f256ba0..83a1a4cd7d 100644 --- a/arch/arm/src/stm32/stm32_pwm.c +++ b/arch/arm/src/stm32/stm32_pwm.c @@ -114,6 +114,159 @@ #define TIMTYPE_TIM16 TIMTYPE_COUNTUP16 #define TIMTYPE_TIM17 TIMTYPE_COUNTUP16 +/* Timer clock source, RCC EN offset, enable bit, + * RCC RST offset, reset bit to use + */ + +#if defined(CONFIG_STM32_STM32F37XX) +# define TIMCLK_TIM2 STM32_APB1_TIM2_CLKIN +# define TIMRCCEN_TIM2 STM32_RCC_APB1ENR +# define TIMEN_TIM2 RCC_APB1ENR_TIM2EN +# define TIMRCCRST_TIM2 STM32_RCC_APB1RSTR +# define TIMRST_TIM2 RCC_APB1RSTR_TIM2RST +# define TIMCLK_TIM3 STM32_APB1_TIM3_CLKIN +# define TIMRCCEN_TIM3 STM32_RCC_APB1ENR +# define TIMEN_TIM3 RCC_APB1ENR_TIM3EN +# define TIMRCCRST_TIM3 STM32_RCC_APB1RSTR +# define TIMRST_TIM3 RCC_APB1RSTR_TIM3RST +# define TIMCLK_TIM4 STM32_APB1_TIM4_CLKIN +# define TIMRCCEN_TIM4 STM32_RCC_APB1ENR +# define TIMEN_TIM4 RCC_APB1ENR_TIM4EN +# define TIMRCCRST_TIM4 STM32_RCC_APB1RSTR +# define TIMRST_TIM4 RCC_APB1RSTR_TIM4RST +# define TIMCLK_TIM5 STM32_APB1_TIM5_CLKIN +# define TIMRCCEN_TIM5 STM32_RCC_APB1ENR +# define TIMEN_TIM5 RCC_APB1ENR_TIM5EN +# define TIMRCCRST_TIM5 STM32_RCC_APB1RSTR +# define TIMRST_TIM5 RCC_APB1RSTR_TIM5RST +# define TIMCLK_TIM6 STM32_APB1_TIM6_CLKIN +# define TIMRCCEN_TIM6 STM32_RCC_APB1ENR +# define TIMEN_TIM6 RCC_APB1ENR_TIM6EN +# define TIMRCCRST_TIM6 STM32_RCC_APB1RSTR +# define TIMRST_TIM6 RCC_APB1RSTR_TIM6RST +# define TIMCLK_TIM7 STM32_APB1_TIM7_CLKIN +# define TIMRCCEN_TIM7 STM32_RCC_APB1ENR +# define TIMEN_TIM7 RCC_APB1ENR_TIM7EN +# define TIMRCCRST_TIM7 STM32_RCC_APB1RSTR +# define TIMRST_TIM7 RCC_APB1RSTR_TIM7RST +# define TIMCLK_TIM12 STM32_APB1_TIM12_CLKIN +# define TIMRCCEN_TIM12 STM32_RCC_APB1ENR +# define TIMEN_TIM12 RCC_APB1ENR_TIM12EN +# define TIMRCCRST_TIM12 STM32_RCC_APB1RSTR +# define TIMRST_TIM12 RCC_APB1RSTR_TIM12RST +# define TIMCLK_TIM13 STM32_APB1_TIM13_CLKIN +# define TIMRCCEN_TIM13 STM32_RCC_APB1ENR +# define TIMEN_TIM13 RCC_APB1ENR_TIM13EN +# define TIMRCCRST_TIM13 STM32_RCC_APB1RSTR +# define TIMRST_TIM13 RCC_APB1RSTR_TIM13RST +# define TIMCLK_TIM14 STM32_APB1_TIM14_CLKIN +# define TIMRCCEN_TIM14 STM32_RCC_APB1ENR +# define TIMEN_TIM14 RCC_APB1ENR_TIM14EN +# define TIMRCCRST_TIM14 STM32_RCC_APB1RSTR +# define TIMRST_TIM14 RCC_APB1RSTR_TIM14RST +# define TIMCLK_TIM15 STM32_APB2_TIM15_CLKIN +# define TIMRCCEN_TIM15 STM32_RCC_APB2ENR +# define TIMEN_TIM15 RCC_APB2ENR_TIM15EN +# define TIMRCCRST_TIM15 STM32_RCC_APB2RSTR +# define TIMRST_TIM15 RCC_APB2RSTR_TIM15RST +# define TIMCLK_TIM16 STM32_APB2_TIM16_CLKIN +# define TIMRCCEN_TIM16 STM32_RCC_APB2ENR +# define TIMEN_TIM16 RCC_APB2ENR_TIM16EN +# define TIMRCCRST_TIM16 STM32_RCC_APB2RSTR +# define TIMRST_TIM16 RCC_APB2RSTR_TIM16RST +# define TIMCLK_TIM17 STM32_APB2_TIM17_CLKIN +# define TIMRCCEN_TIM17 STM32_RCC_APB2ENR +# define TIMEN_TIM17 RCC_APB2ENR_TIM17EN +# define TIMRCCRST_TIM17 STM32_RCC_APB2RSTR +# define TIMRST_TIM17 RCC_APB2RSTR_TIM17RST +# define TIMCLK_TIM18 STM32_APB1_TIM18_CLKIN +# define TIMRCCEN_TIM18 STM32_RCC_APB1ENR +# define TIMEN_TIM18 RCC_APB1ENR_TIM18EN +# define TIMRCCRST_TIM18 STM32_RCC_APB1RSTR +# define TIMRST_TIM18 RCC_APB1RSTR_TIM18RST +# define TIMCLK_TIM19 STM32_APB2_TIM19_CLKIN +# define TIMRCCEN_TIM19 STM32_RCC_APB2ENR +# define TIMEN_TIM19 RCC_APB2ENR_TIM19EN +# define TIMRCCRST_TIM19 STM32_RCC_APB2RSTR +# define TIMRST_TIM19 RCC_APB2RSTR_TIM19RST +#else +# define TIMCLK_TIM1 STM32_APB2_TIM1_CLKIN +# define TIMRCCEN_TIM1 STM32_RCC_APB2ENR +# define TIMEN_TIM1 RCC_APB2ENR_TIM1EN +# define TIMRCCRST_TIM1 STM32_RCC_APB2RSTR +# define TIMRST_TIM1 RCC_APB2RSTR_TIM1RST +# define TIMCLK_TIM2 STM32_APB1_TIM2_CLKIN +# define TIMRCCEN_TIM2 STM32_RCC_APB1ENR +# define TIMEN_TIM2 RCC_APB1ENR_TIM2EN +# define TIMRCCRST_TIM2 STM32_RCC_APB1RSTR +# define TIMRST_TIM2 RCC_APB1RSTR_TIM2RST +# define TIMCLK_TIM3 STM32_APB1_TIM3_CLKIN +# define TIMRCCEN_TIM3 STM32_RCC_APB1ENR +# define TIMEN_TIM3 RCC_APB1ENR_TIM3EN +# define TIMRCCRST_TIM3 STM32_RCC_APB1RSTR +# define TIMRST_TIM3 RCC_APB1RSTR_TIM3RST +# define TIMCLK_TIM4 STM32_APB1_TIM4_CLKIN +# define TIMRCCEN_TIM4 STM32_RCC_APB1ENR +# define TIMEN_TIM4 RCC_APB1ENR_TIM4EN +# define TIMRCCRST_TIM4 STM32_RCC_APB1RSTR +# define TIMRST_TIM4 RCC_APB1RSTR_TIM4RST +# define TIMCLK_TIM5 STM32_APB1_TIM5_CLKIN +# define TIMRCCEN_TIM5 STM32_RCC_APB1ENR +# define TIMEN_TIM5 RCC_APB1ENR_TIM5EN +# define TIMRCCRST_TIM5 STM32_RCC_APB1RSTR +# define TIMRST_TIM5 RCC_APB1RSTR_TIM5RST +# define TIMCLK_TIM8 STM32_APB2_TIM8_CLKIN +# define TIMRCCEN_TIM8 STM32_RCC_APB2ENR +# define TIMEN_TIM8 RCC_APB2ENR_TIM8EN +# define TIMRCCRST_TIM8 STM32_RCC_APB2RSTR +# define TIMRST_TIM8 RCC_APB2RSTR_TIM8RST +# define TIMCLK_TIM9 STM32_APB2_TIM9_CLKIN +# define TIMRCCEN_TIM9 STM32_RCC_APB2ENR +# define TIMEN_TIM9 RCC_APB2ENR_TIM9EN +# define TIMRCCRST_TIM9 STM32_RCC_APB2RSTR +# define TIMRST_TIM9 RCC_APB2RSTR_TIM9RST +# define TIMCLK_TIM10 STM32_APB2_TIM10_CLKIN +# define TIMRCCEN_TIM10 STM32_RCC_APB2ENR +# define TIMEN_TIM10 RCC_APB2ENR_TIM10EN +# define TIMRCCRST_TIM10 STM32_RCC_APB2RSTR +# define TIMRST_TIM10 RCC_APB2RSTR_TIM10RST +# define TIMCLK_TIM11 STM32_APB2_TIM11_CLKIN +# define TIMRCCEN_TIM11 STM32_RCC_APB2ENR +# define TIMEN_TIM11 RCC_APB2ENR_TIM11EN +# define TIMRCCRST_TIM11 STM32_RCC_APB2RSTR +# define TIMRST_TIM11 RCC_APB2RSTR_TIM11RST +# define TIMCLK_TIM12 STM32_APB1_TIM12_CLKIN +# define TIMRCCEN_TIM12 STM32_RCC_APB1ENR +# define TIMEN_TIM12 RCC_APB1ENR_TIM12EN +# define TIMRCCRST_TIM12 STM32_RCC_APB1RSTR +# define TIMRST_TIM12 RCC_APB1RSTR_TIM12RST +# define TIMCLK_TIM13 STM32_APB1_TIM13_CLKIN +# define TIMRCCEN_TIM13 STM32_RCC_APB1ENR +# define TIMEN_TIM13 RCC_APB1ENR_TIM13EN +# define TIMRCCRST_TIM13 STM32_RCC_APB1RSTR +# define TIMRST_TIM13 RCC_APB1RSTR_TIM13RST +# define TIMCLK_TIM14 STM32_APB1_TIM14_CLKIN +# define TIMRCCEN_TIM14 STM32_RCC_APB1ENR +# define TIMEN_TIM14 RCC_APB1ENR_TIM14EN +# define TIMRCCRST_TIM14 STM32_RCC_APB1RSTR +# define TIMRST_TIM14 RCC_APB1RSTR_TIM14RST +# define TIMCLK_TIM15 STM32_APB1_TIM15_CLKIN +# define TIMRCCEN_TIM15 STM32_RCC_APB1ENR +# define TIMEN_TIM15 RCC_APB1ENR_TIM15EN +# define TIMRCCRST_TIM15 STM32_RCC_APB1RSTR +# define TIMRST_TIM15 RCC_APB1RSTR_TIM15RST +# define TIMCLK_TIM16 STM32_APB1_TIM16_CLKIN +# define TIMRCCEN_TIM16 STM32_RCC_APB1ENR +# define TIMEN_TIM16 RCC_APB1ENR_TIM16EN +# define TIMRCCRST_TIM16 STM32_RCC_APB1RSTR +# define TIMRST_TIM16 RCC_APB1RSTR_TIM16RST +# define TIMCLK_TIM17 STM32_APB1_TIM17_CLKIN +# define TIMRCCEN_TIM17 STM32_RCC_APB1ENR +# define TIMEN_TIM17 RCC_APB1ENR_TIM71EN +# define TIMRCCRST_TIM17 STM32_RCC_APB1RSTR +# define TIMRST_TIM17 RCC_APB1RSTR_TIM17RST +#endif + /* Debug ********************************************************************/ #ifdef CONFIG_DEBUG_PWM_INFO @@ -281,7 +434,7 @@ static struct stm32_pwmtimer_s g_pwm1dev = .irq = STM32_IRQ_TIM1UP, #endif .base = STM32_TIM1_BASE, - .pclk = STM32_APB2_TIM1_CLKIN, + .pclk = TIMCLK_TIM1, }; #endif @@ -327,7 +480,7 @@ static struct stm32_pwmtimer_s g_pwm2dev = .irq = STM32_IRQ_TIM2, #endif .base = STM32_TIM2_BASE, - .pclk = STM32_APB1_TIM2_CLKIN, + .pclk = TIMCLK_TIM2, }; #endif @@ -373,7 +526,7 @@ static struct stm32_pwmtimer_s g_pwm3dev = .irq = STM32_IRQ_TIM3, #endif .base = STM32_TIM3_BASE, - .pclk = STM32_APB1_TIM3_CLKIN, + .pclk = TIMCLK_TIM3, }; #endif @@ -419,7 +572,7 @@ static struct stm32_pwmtimer_s g_pwm4dev = .irq = STM32_IRQ_TIM4, #endif .base = STM32_TIM4_BASE, - .pclk = STM32_APB1_TIM4_CLKIN, + .pclk = TIMCLK_TIM4, }; #endif @@ -465,7 +618,7 @@ static struct stm32_pwmtimer_s g_pwm5dev = .irq = STM32_IRQ_TIM5, #endif .base = STM32_TIM5_BASE, - .pclk = STM32_APB1_TIM5_CLKIN, + .pclk = TIMCLK_TIM5, }; #endif @@ -511,7 +664,7 @@ static struct stm32_pwmtimer_s g_pwm8dev = .irq = STM32_IRQ_TIM8UP, #endif .base = STM32_TIM8_BASE, - .pclk = STM32_APB2_TIM8_CLKIN, + .pclk = TIMCLK_TIM8, }; #endif @@ -557,7 +710,7 @@ static struct stm32_pwmtimer_s g_pwm9dev = .irq = STM32_IRQ_TIM9, #endif .base = STM32_TIM9_BASE, - .pclk = STM32_APB2_TIM9_CLKIN, + .pclk = TIMCLK_TIM9, }; #endif @@ -603,7 +756,7 @@ static struct stm32_pwmtimer_s g_pwm10dev = .irq = STM32_IRQ_TIM10, #endif .base = STM32_TIM10_BASE, - .pclk = STM32_APB2_TIM10_CLKIN, + .pclk = TIMCLK_TIM10, }; #endif @@ -649,7 +802,7 @@ static struct stm32_pwmtimer_s g_pwm11dev = .irq = STM32_IRQ_TIM11, #endif .base = STM32_TIM11_BASE, - .pclk = STM32_APB2_TIM11_CLKIN, + .pclk = TIMCLK_TIM11, }; #endif @@ -695,7 +848,7 @@ static struct stm32_pwmtimer_s g_pwm12dev = .irq = STM32_IRQ_TIM12, #endif .base = STM32_TIM12_BASE, - .pclk = STM32_APB1_TIM12_CLKIN, + .pclk = TIMCLK_TIM12, }; #endif @@ -741,7 +894,7 @@ static struct stm32_pwmtimer_s g_pwm13dev = .irq = STM32_IRQ_TIM13, #endif .base = STM32_TIM13_BASE, - .pclk = STM32_APB1_TIM13_CLKIN, + .pclk = TIMCLK_TIM13, }; #endif @@ -787,7 +940,7 @@ static struct stm32_pwmtimer_s g_pwm14dev = .irq = STM32_IRQ_TIM14, #endif .base = STM32_TIM14_BASE, - .pclk = STM32_APB1_TIM14_CLKIN, + .pclk = TIMCLK_TIM14, }; #endif @@ -819,7 +972,7 @@ static struct stm32_pwmtimer_s g_pwm15dev = .irq = STM32_IRQ_TIM15, #endif .base = STM32_TIM15_BASE, - .pclk = STM32_APB1_TIM15_CLKIN, + .pclk = TIMCLK_TIM15, }; #endif @@ -844,7 +997,7 @@ static struct stm32_pwmtimer_s g_pwm16dev = .irq = STM32_IRQ_TIM16, #endif .base = STM32_TIM16_BASE, - .pclk = STM32_APB1_TIM16_CLKIN, + .pclk = TIMCLK_TIM16, }; #endif @@ -869,7 +1022,7 @@ static struct stm32_pwmtimer_s g_pwm17dev = .irq = STM32_IRQ_TIM17, #endif .base = STM32_TIM17_BASE, - .pclk = STM32_APB1_TIM17_CLKIN, + .pclk = TIMCLK_TIM17, }; #endif @@ -954,42 +1107,68 @@ static void pwm_putreg(struct stm32_pwmtimer_s *priv, int offset, uint16_t value static void pwm_dumpregs(struct stm32_pwmtimer_s *priv, FAR const char *msg) { pwminfo("%s:\n", msg); - pwminfo(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", - pwm_getreg(priv, STM32_GTIM_CR1_OFFSET), - pwm_getreg(priv, STM32_GTIM_CR2_OFFSET), - pwm_getreg(priv, STM32_GTIM_SMCR_OFFSET), - pwm_getreg(priv, STM32_GTIM_DIER_OFFSET)); - pwminfo(" SR: %04x EGR: %04x CCMR1: %04x CCMR2: %04x\n", - pwm_getreg(priv, STM32_GTIM_SR_OFFSET), - pwm_getreg(priv, STM32_GTIM_EGR_OFFSET), - pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET), - pwm_getreg(priv, STM32_GTIM_CCMR2_OFFSET)); + if (priv->timid == 16 || priv->timid == 17) + { + pwminfo(" CR1: %04x CR2: %04x DIER: %04x\n", + pwm_getreg(priv, STM32_GTIM_CR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CR2_OFFSET), + pwm_getreg(priv, STM32_GTIM_DIER_OFFSET)); + } + else + { + pwminfo(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n", + pwm_getreg(priv, STM32_GTIM_CR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CR2_OFFSET), + pwm_getreg(priv, STM32_GTIM_SMCR_OFFSET), + pwm_getreg(priv, STM32_GTIM_DIER_OFFSET)); + } + + if (priv->timid >= 15 || priv->timid <= 17) + { + pwminfo(" SR: %04x EGR: %04x CCMR1: %04x\n", + pwm_getreg(priv, STM32_GTIM_SR_OFFSET), + pwm_getreg(priv, STM32_GTIM_EGR_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET)); + } + else + { + pwminfo(" SR: %04x EGR: %04x CCMR1: %04x CCMR2: %04x\n", + pwm_getreg(priv, STM32_GTIM_SR_OFFSET), + pwm_getreg(priv, STM32_GTIM_EGR_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCMR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCMR2_OFFSET)); + } + pwminfo(" CCER: %04x CNT: %04x PSC: %04x ARR: %04x\n", pwm_getreg(priv, STM32_GTIM_CCER_OFFSET), pwm_getreg(priv, STM32_GTIM_CNT_OFFSET), pwm_getreg(priv, STM32_GTIM_PSC_OFFSET), pwm_getreg(priv, STM32_GTIM_ARR_OFFSET)); - pwminfo(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", - pwm_getreg(priv, STM32_GTIM_CCR1_OFFSET), - pwm_getreg(priv, STM32_GTIM_CCR2_OFFSET), - pwm_getreg(priv, STM32_GTIM_CCR3_OFFSET), - pwm_getreg(priv, STM32_GTIM_CCR4_OFFSET)); -#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) - if (priv->timtype == TIMTYPE_ADVANCED) + + if (priv->timid >= 15 || priv->timid <= 17) { - pwminfo(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n", + pwminfo(" RCR: %04x BDTR: %04x\n", pwm_getreg(priv, STM32_ATIM_RCR_OFFSET), - pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET), - pwm_getreg(priv, STM32_ATIM_DCR_OFFSET), - pwm_getreg(priv, STM32_ATIM_DMAR_OFFSET)); + pwm_getreg(priv, STM32_ATIM_BDTR_OFFSET)); + } + + if (priv->timid == 16 || priv->timid == 17) + { + pwminfo(" CCR1: %04x\n", + pwm_getreg(priv, STM32_GTIM_CCR1_OFFSET)); } else -#endif { - pwminfo(" DCR: %04x DMAR: %04x\n", - pwm_getreg(priv, STM32_GTIM_DCR_OFFSET), - pwm_getreg(priv, STM32_GTIM_DMAR_OFFSET)); + pwminfo(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n", + pwm_getreg(priv, STM32_GTIM_CCR1_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR2_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR3_OFFSET), + pwm_getreg(priv, STM32_GTIM_CCR4_OFFSET)); } + + pwminfo(" DCR: %04x DMAR: %04x\n", + pwm_getreg(priv, STM32_GTIM_DCR_OFFSET), + pwm_getreg(priv, STM32_GTIM_DMAR_OFFSET)); } #endif @@ -1520,8 +1699,10 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, /* Some special setup for advanced timers */ -#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) - if (priv->timtype == TIMTYPE_ADVANCED) +#if defined(CONFIG_STM32_TIM1_PWM) || defined(CONFIG_STM32_TIM8_PWM) || \ + defined(CONFIG_STM32_TIM15_PWM) || defined(CONFIG_STM32_TIM16_PWM) || \ + defined(CONFIG_STM32_TIM17_PWM) + if (priv->timtype == TIMTYPE_ADVANCED || priv->timtype == TIMTYPE_COUNTUP16) { uint16_t bdtr; @@ -1530,7 +1711,7 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, */ #if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F40XX) + defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F40XX) ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP | ATIM_CCER_CC2NE | ATIM_CCER_CC2NP | ATIM_CCER_CC3NE | ATIM_CCER_CC3NP | ATIM_CCER_CC4NP); #else @@ -1553,14 +1734,16 @@ static int pwm_timer(FAR struct stm32_pwmtimer_s *priv, pwm_putreg(priv, STM32_ATIM_BDTR_OFFSET, bdtr); } #if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F40XX) + defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F40XX) else #endif #endif #if defined(CONFIG_STM32_STM32F20XX) || defined(CONFIG_STM32_STM32F30XX) || \ - defined(CONFIG_STM32_STM32F40XX) + defined(CONFIG_STM32_STM32F37XX) || defined(CONFIG_STM32_STM32F40XX) { - ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP); + /* CCxNP must be cleared in any case */ + + ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP | GTIM_CCER_CC4NP); } #endif @@ -1875,98 +2058,100 @@ static void pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) uint32_t en_bit; uint32_t regaddr; + pwminfo("timer %d clock enable: %d\n", priv->timid, on ? 1 : 0); + /* Determine which timer to configure */ switch (priv->timid) { #ifdef CONFIG_STM32_TIM1_PWM case 1: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM1EN; + regaddr = TIMRCCEN_TIM1; + en_bit = TIMEN_TIM1; break; #endif #ifdef CONFIG_STM32_TIM2_PWM case 2: - regaddr = STM32_RCC_APB1ENR; - en_bit = RCC_APB1ENR_TIM2EN; + regaddr = TIMRCCEN_TIM2; + en_bit = TIMEN_TIM2; break; #endif #ifdef CONFIG_STM32_TIM3_PWM case 3: - regaddr = STM32_RCC_APB1ENR; - en_bit = RCC_APB1ENR_TIM3EN; + regaddr = TIMRCCEN_TIM3; + en_bit = TIMEN_TIM3; break; #endif #ifdef CONFIG_STM32_TIM4_PWM case 4: - regaddr = STM32_RCC_APB1ENR; - en_bit = RCC_APB1ENR_TIM4EN; + regaddr = TIMRCCEN_TIM4; + en_bit = TIMEN_TIM4; break; #endif #ifdef CONFIG_STM32_TIM5_PWM case 5: - regaddr = STM32_RCC_APB1ENR; - en_bit = RCC_APB1ENR_TIM5EN; + regaddr = TIMRCCEN_TIM5; + en_bit = TIMEN_TIM5; break; #endif #ifdef CONFIG_STM32_TIM8_PWM case 8: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM8EN; + regaddr = TIMRCCEN_TIM8; + en_bit = TIMEN_TIM8; break; #endif #ifdef CONFIG_STM32_TIM9_PWM case 9: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM9EN; + regaddr = TIMRCCEN_TIM9; + en_bit = TIMEN_TIM9; break; #endif #ifdef CONFIG_STM32_TIM10_PWM case 10: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM10EN; + regaddr = TIMRCCEN_TIM10; + en_bit = TIMEN_TIM10; break; #endif #ifdef CONFIG_STM32_TIM11_PWM case 11: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM11EN; + regaddr = TIMRCCEN_TIM11; + en_bit = TIMEN_TIM11; break; #endif #ifdef CONFIG_STM32_TIM12_PWM case 12: - regaddr = STM32_RCC_APB1ENR; - en_bit = RCC_APB1ENR_TIM12EN; + regaddr = TIMRCCEN_TIM12; + en_bit = TIMEN_TIM12; break; #endif #ifdef CONFIG_STM32_TIM13_PWM case 13: - regaddr = STM32_RCC_APB1ENR; - en_bit = RCC_APB1ENR_TIM13EN; + regaddr = TIMRCCEN_TIM13; + en_bit = TIMEN_TIM13; break; #endif #ifdef CONFIG_STM32_TIM14_PWM case 14: - regaddr = STM32_RCC_APB1ENR; - en_bit = RCC_APB1ENR_TIM14EN; + regaddr = TIMRCCEN_TIM14; + en_bit = TIMEN_TIM14; break; #endif #ifdef CONFIG_STM32_TIM15_PWM case 15: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM15EN; + regaddr = TIMRCCEN_TIM15; + en_bit = TIMEN_TIM15; break; #endif #ifdef CONFIG_STM32_TIM16_PWM case 16: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM16EN; + regaddr = TIMRCCEN_TIM16; + en_bit = TIMEN_TIM16; break; #endif #ifdef CONFIG_STM32_TIM17_PWM case 17: - regaddr = STM32_RCC_APB2ENR; - en_bit = RCC_APB2ENR_TIM17EN; + regaddr = TIMRCCEN_TIM17; + en_bit = TIMEN_TIM17; break; #endif default: @@ -1975,6 +2160,8 @@ static void pwm_set_apb_clock(FAR struct stm32_pwmtimer_s *priv, bool on) /* Enable/disable APB 1/2 clock for timer */ + pwminfo("RCC_APBxENR base: %08x bits: %04x\n", regaddr, en_bit); + if (on) { modifyreg32(regaddr, 0, en_bit); @@ -2012,12 +2199,13 @@ static int pwm_setup(FAR struct pwm_lowerhalf_s *dev) int i; pwminfo("TIM%u\n", priv->timid); - pwm_dumpregs(priv, "Initially"); /* Enable APB1/2 clocking for timer. */ pwm_set_apb_clock(priv, true); + pwm_dumpregs(priv, "Initially"); + /* Configure the PWM output pins, but do not start the timer yet */ for (i = 0; i < PWM_NCHANNELS; i++) @@ -2087,6 +2275,7 @@ static int pwm_shutdown(FAR struct pwm_lowerhalf_s *dev) pincfg |= GPIO_INPUT | GPIO_CNF_INFLOAT | GPIO_MODE_INPUT; #elif defined(CONFIG_STM32_STM32F20XX) || \ defined(CONFIG_STM32_STM32F30XX) || \ + defined(CONFIG_STM32_STM32F37XX) || \ defined(CONFIG_STM32_STM32F40XX) || \ defined(CONFIG_STM32_STM32L15XX) pincfg |= GPIO_INPUT | GPIO_FLOAT; @@ -2216,6 +2405,104 @@ static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) pwminfo("TIM%u\n", priv->timid); + /* Determine which timer to reset */ + + switch (priv->timid) + { +#ifdef CONFIG_STM32_TIM1_PWM + case 1: + regaddr = TIMRCCRST_TIM1; + resetbit = TIMRST_TIM1; + break; +#endif +#ifdef CONFIG_STM32_TIM2_PWM + case 2: + regaddr = TIMRCCRST_TIM2; + resetbit = TIMRST_TIM2; + break; +#endif +#ifdef CONFIG_STM32_TIM3_PWM + case 3: + regaddr = TIMRCCRST_TIM3; + resetbit = TIMRST_TIM3; + break; +#endif +#ifdef CONFIG_STM32_TIM4_PWM + case 4: + regaddr = TIMRCCRST_TIM4; + resetbit = TIMRST_TIM4; + break; +#endif +#ifdef CONFIG_STM32_TIM5_PWM + case 5: + regaddr = TIMRCCRST_TIM5; + resetbit = TIMRST_TIM5; + break; +#endif +#ifdef CONFIG_STM32_TIM8_PWM + case 8: + regaddr = TIMRCCRST_TIM8; + resetbit = TIMRST_TIM8; + break; +#endif +#ifdef CONFIG_STM32_TIM9_PWM + case 9: + regaddr = TIMRCCRST_TIM9; + resetbit = TIMRST_TIM9; + break; +#endif +#ifdef CONFIG_STM32_TIM10_PWM + case 10: + regaddr = TIMRCCRST_TIM10; + resetbit = TIMRST_TIM10; + break; +#endif +#ifdef CONFIG_STM32_TIM11_PWM + case 11: + regaddr = TIMRCCRST_TIM11; + resetbit = TIMRST_TIM11; + break; +#endif +#ifdef CONFIG_STM32_TIM12_PWM + case 12: + regaddr = TIMRCCRST_TIM12; + resetbit = TIMRST_TIM12; + break; +#endif +#ifdef CONFIG_STM32_TIM13_PWM + case 13: + regaddr = TIMRCCRST_TIM13; + resetbit = TIMRST_TIM13; + break; +#endif +#ifdef CONFIG_STM32_TIM14_PWM + case 14: + regaddr = TIMRCCRST_TIM14; + resetbit = TIMRST_TIM14; + break; +#endif +#ifdef CONFIG_STM32_TIM15_PWM + case 15: + regaddr = TIMRCCRST_TIM15; + resetbit = TIMRST_TIM15; + break; +#endif +#ifdef CONFIG_STM32_TIM16_PWM + case 16: + regaddr = TIMRCCRST_TIM16; + resetbit = TIMRST_TIM16; + break; +#endif +#ifdef CONFIG_STM32_TIM17_PWM + case 17: + regaddr = TIMRCCRST_TIM17; + resetbit = TIMRST_TIM17; + break; +#endif + default: + return -EINVAL; + } + /* Disable interrupts momentary to stop any ongoing timer processing and * to prevent any concurrent access to the reset register. */ @@ -2231,104 +2518,6 @@ static int pwm_stop(FAR struct pwm_lowerhalf_s *dev) pwm_putreg(priv, STM32_GTIM_DIER_OFFSET, 0); pwm_putreg(priv, STM32_GTIM_SR_OFFSET, 0); - /* Determine which timer to reset */ - - switch (priv->timid) - { -#ifdef CONFIG_STM32_TIM1_PWM - case 1: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM1RST; - break; -#endif -#ifdef CONFIG_STM32_TIM2_PWM - case 2: - regaddr = STM32_RCC_APB1RSTR; - resetbit = RCC_APB1RSTR_TIM2RST; - break; -#endif -#ifdef CONFIG_STM32_TIM3_PWM - case 3: - regaddr = STM32_RCC_APB1RSTR; - resetbit = RCC_APB1RSTR_TIM3RST; - break; -#endif -#ifdef CONFIG_STM32_TIM4_PWM - case 4: - regaddr = STM32_RCC_APB1RSTR; - resetbit = RCC_APB1RSTR_TIM4RST; - break; -#endif -#ifdef CONFIG_STM32_TIM5_PWM - case 5: - regaddr = STM32_RCC_APB1RSTR; - resetbit = RCC_APB1RSTR_TIM5RST; - break; -#endif -#ifdef CONFIG_STM32_TIM8_PWM - case 8: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM8RST; - break; -#endif -#ifdef CONFIG_STM32_TIM9_PWM - case 9: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM9RST; - break; -#endif -#ifdef CONFIG_STM32_TIM10_PWM - case 10: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM10RST; - break; -#endif -#ifdef CONFIG_STM32_TIM11_PWM - case 11: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM11RST; - break; -#endif -#ifdef CONFIG_STM32_TIM12_PWM - case 12: - regaddr = STM32_RCC_APB1RSTR; - resetbit = RCC_APB1RSTR_TIM12RST; - break; -#endif -#ifdef CONFIG_STM32_TIM13_PWM - case 13: - regaddr = STM32_RCC_APB1RSTR; - resetbit = RCC_APB1RSTR_TIM13RST; - break; -#endif -#ifdef CONFIG_STM32_TIM14_PWM - case 14: - regaddr = STM32_RCC_APB1RSTR; - resetbit = RCC_APB1RSTR_TIM14RST; - break; -#endif -#ifdef CONFIG_STM32_TIM15_PWM - case 15: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM15RST; - break; -#endif -#ifdef CONFIG_STM32_TIM16_PWM - case 16: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM16RST; - break; -#endif -#ifdef CONFIG_STM32_TIM17_PWM - case 17: - regaddr = STM32_RCC_APB2RSTR; - resetbit = RCC_APB2RSTR_TIM17RST; - break; -#endif - default: - return -EINVAL; - } - /* Reset the timer - stopping the output and putting the timer back * into a state where pwm_start() can be called. */ From 3cb1e0e67fb93767668b891bab389273113842a5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 09:37:22 -0600 Subject: [PATCH 120/155] STM32F7: Fix Make.defs. Would not work if only SDMMC2 were enabled. --- arch/arm/src/stm32f7/Make.defs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs index ee6b3e0687..5f5344d9eb 100644 --- a/arch/arm/src/stm32f7/Make.defs +++ b/arch/arm/src/stm32f7/Make.defs @@ -161,7 +161,7 @@ ifeq ($(CONFIG_STM32F7_SPI),y) CHIP_CSRCS += stm32_spi.c endif -ifeq ($(CONFIG_STM32F7_SDMMC1),y) +ifeq ($(CONFIG_STM32F7_SDMMC),y) CHIP_CSRCS += stm32_sdmmc.c endif From 2964779985fb97249eca57f9a3ec512f6acd327c Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Mon, 7 Nov 2016 10:10:44 -0600 Subject: [PATCH 121/155] configs/misoc: Add an NSH configuration --- configs/misoc/hello/setenv.sh | 2 +- configs/misoc/nsh/Make.defs | 101 +++++ configs/misoc/nsh/defconfig | 747 ++++++++++++++++++++++++++++++++++ configs/misoc/nsh/setenv.sh | 58 +++ 4 files changed, 907 insertions(+), 1 deletion(-) create mode 100644 configs/misoc/nsh/Make.defs create mode 100644 configs/misoc/nsh/defconfig create mode 100644 configs/misoc/nsh/setenv.sh diff --git a/configs/misoc/hello/setenv.sh b/configs/misoc/hello/setenv.sh index 7ba5ee60e7..9b84648e5c 100644 --- a/configs/misoc/hello/setenv.sh +++ b/configs/misoc/hello/setenv.sh @@ -1,5 +1,5 @@ #!/bin/bash -# configs/amber/hello/setenv.sh +# configs/misoc/hello/setenv.sh # # Copyright (C) 2016 Gregory Nutt. All rights reserved. # Author: Gregory Nutt diff --git a/configs/misoc/nsh/Make.defs b/configs/misoc/nsh/Make.defs new file mode 100644 index 0000000000..bf0aa6ba19 --- /dev/null +++ b/configs/misoc/nsh/Make.defs @@ -0,0 +1,101 @@ +############################################################################ +# configs/misoc/nsh/Make.defs +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Ramtin Amin +# +# 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. +# +############################################################################ + +include ${TOPDIR}/.config +include ${TOPDIR}/tools/Config.mk +include ${TOPDIR}/arch/misoc/src/lm32/Toolchain.defs + +LDSCRIPT = ld.script + +ifeq ($(WINTOOL),y) + # Windows-native toolchains + DIRLINK = $(TOPDIR)/tools/copydir.sh + DIRUNLINK = $(TOPDIR)/tools/unlink.sh + MKDEP = $(TOPDIR)/tools/mkwindeps.sh + ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" + ARCHXXINCLUDES = $(ARCHINCLUDES) "${shell cygpath -w $(TOPDIR)/include/cxx}" + ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}" +else + # Linux/Cygwin-native toolchain + MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT) + ARCHINCLUDES = -I. -isystem "$(TOPDIR)/include" + ARCHXXINCLUDES = $(ARCHINCLUDES) -isystem "$(TOPDIR)/include/cxx" + ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD_CUSTOM_NAME)/scripts/$(LDSCRIPT) +endif + +CC = $(CROSSDEV)gcc +CXX = $(CROSSDEV)g++ +CPP = $(CROSSDEV)gcc -E +LD = $(CROSSDEV)ld +AR = $(CROSSDEV)ar rcs +NM = $(CROSSDEV)nm +OBJCOPY = $(CROSSDEV)objcopy +OBJDUMP = $(CROSSDEV)objdump + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer +endif + +ARCHCFLAGS = -fno-builtin +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef +ARCHDEFINES = + +CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +AFLAGS = $(CFLAGS) -D__ASSEMBLY__ + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-gotoff.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +ASMEXT = .S +OBJEXT = .o +LIBEXT = .a +EXEEXT = + + +HOSTCC = gcc +HOSTINCLUDES = -I. +HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe +HOSTLDFLAGS = diff --git a/configs/misoc/nsh/defconfig b/configs/misoc/nsh/defconfig new file mode 100644 index 0000000000..71aea364a7 --- /dev/null +++ b/configs/misoc/nsh/defconfig @@ -0,0 +1,747 @@ +# +# Automatically generated file; DO NOT EDIT. +# Nuttx/ Configuration +# + +# +# Build Setup +# +# CONFIG_EXPERIMENTAL is not set +# CONFIG_DEFAULT_SMALL is not set +CONFIG_HOST_LINUX=y +# CONFIG_HOST_OSX is not set +# CONFIG_HOST_WINDOWS is not set +# CONFIG_HOST_OTHER is not set + +# +# Build Configuration +# +# CONFIG_APPS_DIR="../apps" +CONFIG_BUILD_FLAT=y +# CONFIG_BUILD_2PASS is not set + +# +# Binary Output Formats +# +# CONFIG_RRLOAD_BINARY is not set +# CONFIG_INTELHEX_BINARY is not set +# CONFIG_MOTOROLA_SREC is not set +CONFIG_RAW_BINARY=y +# CONFIG_UBOOT_UIMAGE is not set + +# +# Customize Header Files +# +# CONFIG_ARCH_STDINT_H is not set +# CONFIG_ARCH_STDBOOL_H is not set +# CONFIG_ARCH_MATH_H is not set +# CONFIG_ARCH_FLOAT_H is not set +# CONFIG_ARCH_STDARG_H is not set +# CONFIG_ARCH_DEBUG_H is not set + +# +# Debug Options +# +CONFIG_DEBUG_ALERT=y +CONFIG_DEBUG_FEATURES=y + +# +# Debug SYSLOG Output Controls +# +# CONFIG_DEBUG_ERROR is not set +# CONFIG_DEBUG_ASSERTIONS is not set + +# +# Subsystem Debug Options +# +# CONFIG_DEBUG_BINFMT is not set +# CONFIG_DEBUG_FS is not set +# CONFIG_DEBUG_GRAPHICS is not set +# CONFIG_DEBUG_LIB is not set +# CONFIG_DEBUG_MM is not set +# CONFIG_DEBUG_SCHED is not set + +# +# OS Function Debug Options +# +# CONFIG_DEBUG_IRQ is not set + +# +# Driver Debug Options +# +# CONFIG_DEBUG_GPIO is not set +# CONFIG_DEBUG_TIMER is not set +# CONFIG_ARCH_HAVE_STACKCHECK is not set +# CONFIG_ARCH_HAVE_HEAPCHECK is not set +CONFIG_DEBUG_SYMBOLS=y +CONFIG_ARCH_HAVE_CUSTOMOPT=y +CONFIG_DEBUG_NOOPT=y +# CONFIG_DEBUG_CUSTOMOPT is not set +# CONFIG_DEBUG_FULLOPT is not set + +# +# System Type +# +# CONFIG_ARCH_ARM is not set +# CONFIG_ARCH_AVR is not set +# CONFIG_ARCH_HC is not set +# CONFIG_ARCH_MIPS is not set +CONFIG_ARCH_MISOC=y +# CONFIG_ARCH_RGMP is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_SIM is not set +# CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set +# CONFIG_ARCH_Z16 is not set +# CONFIG_ARCH_Z80 is not set +CONFIG_ARCH="misoc" +CONFIG_ARCH_CHIP="lm32" +CONFIG_ARCH_CHIP_LM32=y +# CONFIG_ARCH_CHIP_MOR1K is not set + +# +# MISOC Peripheral Support +# +CONFIG_MISOC_HAVE_UART1=y +CONFIG_MISOC_UART1=y +CONFIG_MISOC_UART=y +CONFIG_MISOC_UART_RX_BUF_SIZE=64 +CONFIG_MISOC_UART_TX_BUF_SIZE=64 +# CONFIG_LM32_TOOLCHAIN_BUILDROOT is not set +CONFIG_LM32_TOOLCHAIN_GNUL=y + +# +# Architecture Options +# +# CONFIG_ARCH_NOINTC is not set +# CONFIG_ARCH_VECNOTIRQ is not set +# CONFIG_ARCH_DMA is not set +# CONFIG_ARCH_HAVE_IRQPRIO is not set +# CONFIG_ARCH_L2CACHE is not set +# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set +# CONFIG_ARCH_HAVE_ADDRENV is not set +# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set +# CONFIG_ARCH_HAVE_MULTICPU is not set +# CONFIG_ARCH_HAVE_VFORK is not set +# CONFIG_ARCH_HAVE_MMU is not set +# CONFIG_ARCH_HAVE_MPU is not set +# CONFIG_ARCH_NAND_HWECC is not set +# CONFIG_ARCH_HAVE_EXTCLK is not set +# CONFIG_ARCH_HAVE_POWEROFF is not set +# CONFIG_ARCH_HAVE_RESET is not set +CONFIG_ARCH_STACKDUMP=y +# CONFIG_ENDIAN_BIG is not set +# CONFIG_ARCH_IDLE_CUSTOM is not set +# CONFIG_ARCH_HAVE_RAMFUNCS is not set +# CONFIG_ARCH_HAVE_RAMVECTORS is not set + +# +# Board Settings +# +CONFIG_BOARD_LOOPSPERMSEC=800 +# CONFIG_ARCH_CALIBRATION is not set + +# +# Interrupt options +# +CONFIG_ARCH_HAVE_INTERRUPTSTACK=y +CONFIG_ARCH_INTERRUPTSTACK=0 +# CONFIG_ARCH_HAVE_HIPRI_INTERRUPT is not set + +# +# Boot options +# +# CONFIG_BOOT_RUNFROMEXTSRAM is not set +CONFIG_BOOT_RUNFROMFLASH=y +# CONFIG_BOOT_RUNFROMISRAM is not set +# CONFIG_BOOT_RUNFROMSDRAM is not set +# CONFIG_BOOT_COPYTORAM is not set + +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x40000000 +CONFIG_RAM_SIZE=524288 +# CONFIG_ARCH_HAVE_SDRAM is not set + +# +# Board Selection +# +CONFIG_ARCH_BOARD_CUSTOM=y + +# +# Custom Board Configuration +# +CONFIG_ARCH_BOARD_CUSTOM_NAME="misoc" +CONFIG_ARCH_BOARD_CUSTOM_DIR="/configs/misoc/" +CONFIG_ARCH_BOARD_CUSTOM_DIR_RELPATH=y +# CONFIG_BOARD_CUSTOM_LEDS is not set +# CONFIG_BOARD_CUSTOM_BUTTONS is not set + +# +# Common Board Options +# + +# +# Board-Specific Options +# +# CONFIG_BOARD_CRASHDUMP is not set +# CONFIG_LIB_BOARDCTL is not set + +# +# RTOS Features +# +CONFIG_DISABLE_OS_API=y +CONFIG_DISABLE_POSIX_TIMERS=y +CONFIG_DISABLE_PTHREAD=y +CONFIG_DISABLE_SIGNALS=y +CONFIG_DISABLE_MQUEUE=y +CONFIG_DISABLE_ENVIRON=y + +# +# Clocks and Timers +# +CONFIG_USEC_PER_TICK=10000 +# CONFIG_SYSTEM_TIME64 is not set +# CONFIG_CLOCK_MONOTONIC is not set +# CONFIG_ARCH_HAVE_TIMEKEEPING is not set +# CONFIG_JULIAN_TIME is not set +CONFIG_START_YEAR=2011 +CONFIG_START_MONTH=6 +CONFIG_START_DAY=16 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_PREALLOC_WDOGS=4 +CONFIG_WDOG_INTRESERVE=0 +CONFIG_PREALLOC_TIMERS=0 + +# +# Tasks and Scheduling +# +# CONFIG_INIT_NONE is not set +CONFIG_INIT_ENTRYPOINT=y +# CONFIG_INIT_FILEPATH is not set +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_RR_INTERVAL=0 +# CONFIG_SCHED_SPORADIC is not set +CONFIG_TASK_NAME_SIZE=0 +CONFIG_MAX_TASKS=4 +# CONFIG_SCHED_HAVE_PARENT is not set +# CONFIG_SCHED_WAITPID is not set + +# +# Performance Monitoring +# +# CONFIG_SCHED_CPULOAD is not set +# CONFIG_SCHED_INSTRUMENTATION is not set + +# +# Files and I/O +# +CONFIG_DEV_CONSOLE=y +# CONFIG_FDCLONE_DISABLE is not set +# CONFIG_FDCLONE_STDIO is not set +CONFIG_SDCLONE_DISABLE=y +CONFIG_NFILE_DESCRIPTORS=4 +CONFIG_NFILE_STREAMS=4 +CONFIG_NAME_MAX=32 +# CONFIG_PRIORITY_INHERITANCE is not set + +# +# RTOS hooks +# +# CONFIG_BOARD_INITIALIZE is not set +# CONFIG_SCHED_STARTHOOK is not set +# CONFIG_SCHED_ATEXIT is not set +# CONFIG_SCHED_ONEXIT is not set +# CONFIG_MODULE is not set + +# +# Work queue support +# + +# +# Stack and heap information +# +CONFIG_IDLETHREAD_STACKSIZE=1024 +CONFIG_USERMAIN_STACKSIZE=1024 +CONFIG_PTHREAD_STACK_MIN=512 +CONFIG_PTHREAD_STACK_DEFAULT=1024 +# CONFIG_LIB_SYSCALL is not set + +# +# Device Drivers +# +CONFIG_DISABLE_POLL=y +CONFIG_DEV_NULL=y +# CONFIG_DEV_ZERO is not set +# CONFIG_DEV_URANDOM is not set +# CONFIG_DEV_LOOP is not set + +# +# Buffering +# +# CONFIG_DRVR_WRITEBUFFER is not set +# CONFIG_DRVR_READAHEAD is not set +# CONFIG_RAMDISK is not set +# CONFIG_CAN is not set +# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set +# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set +# CONFIG_PWM is not set +# CONFIG_ARCH_HAVE_I2CRESET is not set +# CONFIG_I2C is not set +# CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set +# CONFIG_I2S is not set + +# +# Timer Driver Support +# +# CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set +# CONFIG_RTC is not set +# CONFIG_WATCHDOG is not set +# CONFIG_ANALOG is not set +# CONFIG_AUDIO_DEVICES is not set +# CONFIG_VIDEO_DEVICES is not set +# CONFIG_BCH is not set +# CONFIG_INPUT is not set + +# +# IO Expander/GPIO Support +# +# CONFIG_IOEXPANDER is not set +# CONFIG_DEV_GPIO is not set + +# +# LCD Driver Support +# +# CONFIG_LCD is not set +# CONFIG_SLCD is not set + +# +# LED Support +# +# CONFIG_RGBLED is not set +# CONFIG_PCA9635PW is not set +# CONFIG_NCP5623C is not set +# CONFIG_MMCSD is not set +# CONFIG_MODEM is not set +# CONFIG_MTD is not set +# CONFIG_EEPROM is not set +# CONFIG_PIPES is not set +# CONFIG_PM is not set +# CONFIG_POWER is not set +# CONFIG_SENSORS is not set +# CONFIG_SERCOMM_CONSOLE is not set +CONFIG_SERIAL=y +# CONFIG_DEV_LOWCONSOLE is not set +# CONFIG_SERIAL_REMOVABLE is not set +CONFIG_SERIAL_CONSOLE=y +# CONFIG_16550_UART is not set +# CONFIG_UART_SERIALDRIVER is not set +# CONFIG_UART0_SERIALDRIVER is not set +CONFIG_UART1_SERIALDRIVER=y +# CONFIG_UART2_SERIALDRIVER is not set +# CONFIG_UART3_SERIALDRIVER is not set +# CONFIG_UART4_SERIALDRIVER is not set +# CONFIG_UART5_SERIALDRIVER is not set +# CONFIG_UART6_SERIALDRIVER is not set +# CONFIG_UART7_SERIALDRIVER is not set +# CONFIG_UART8_SERIALDRIVER is not set +# CONFIG_SCI0_SERIALDRIVER is not set +# CONFIG_SCI1_SERIALDRIVER is not set +# CONFIG_USART0_SERIALDRIVER is not set +# CONFIG_USART1_SERIALDRIVER is not set +# CONFIG_USART2_SERIALDRIVER is not set +# CONFIG_USART3_SERIALDRIVER is not set +# CONFIG_USART4_SERIALDRIVER is not set +# CONFIG_USART5_SERIALDRIVER is not set +# CONFIG_USART6_SERIALDRIVER is not set +# CONFIG_USART7_SERIALDRIVER is not set +# CONFIG_USART8_SERIALDRIVER is not set +# CONFIG_OTHER_UART_SERIALDRIVER is not set +CONFIG_MCU_SERIAL=y +# CONFIG_STANDARD_SERIAL is not set +# CONFIG_SERIAL_IFLOWCONTROL is not set +# CONFIG_SERIAL_OFLOWCONTROL is not set +# CONFIG_SERIAL_DMA is not set +# CONFIG_SERIAL_TIOCSERGSTRUCT is not set +# CONFIG_ARCH_HAVE_SERIAL_TERMIOS is not set +CONFIG_UART1_SERIAL_CONSOLE=y +# CONFIG_OTHER_SERIAL_CONSOLE is not set +# CONFIG_NO_SERIAL_CONSOLE is not set + +# +# UART1 Configuration +# +CONFIG_UART1_RXBUFSIZE=256 +CONFIG_UART1_TXBUFSIZE=256 +CONFIG_UART1_BAUD=115200 +CONFIG_UART1_BITS=8 +CONFIG_UART1_PARITY=0 +CONFIG_UART1_2STOP=0 +# CONFIG_UART1_IFLOWCONTROL is not set +# CONFIG_UART1_OFLOWCONTROL is not set +# CONFIG_UART1_DMA is not set +# CONFIG_PSEUDOTERM is not set +# CONFIG_USBDEV is not set +# CONFIG_USBHOST is not set +# CONFIG_HAVE_USBTRACE is not set +# CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set + +# +# System Logging +# +# CONFIG_ARCH_SYSLOG is not set +# CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_INTBUFFER is not set +# CONFIG_SYSLOG_TIMESTAMP is not set +CONFIG_SYSLOG_SERIAL_CONSOLE=y +# CONFIG_SYSLOG_CHAR is not set +CONFIG_SYSLOG_CONSOLE=y +# CONFIG_SYSLOG_NONE is not set +# CONFIG_SYSLOG_FILE is not set +# CONFIG_SYSLOG_CHARDEV is not set + +# +# Networking Support +# +# CONFIG_ARCH_HAVE_NET is not set +# CONFIG_ARCH_HAVE_PHY is not set +# CONFIG_NET is not set + +# +# Crypto API +# +# CONFIG_CRYPTO is not set + +# +# File Systems +# + +# +# File system configuration +# +CONFIG_DISABLE_MOUNTPOINT=y +CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y +# CONFIG_FS_READABLE is not set +# CONFIG_FS_WRITABLE is not set +# CONFIG_FS_NAMED_SEMAPHORES is not set +# CONFIG_FS_RAMMAP is not set +# CONFIG_FS_PROCFS is not set +# CONFIG_FS_UNIONFS is not set + +# +# Graphics Support +# +# CONFIG_NX is not set + +# +# Memory Management +# +# CONFIG_MM_SMALL is not set +CONFIG_MM_REGIONS=1 +# CONFIG_ARCH_HAVE_HEAP2 is not set +# CONFIG_GRAN is not set + +# +# Audio Support +# +# CONFIG_AUDIO is not set + +# +# Wireless Support +# + +# +# Binary Loader +# +# CONFIG_BINFMT_DISABLE is not set +# CONFIG_NXFLAT is not set +# CONFIG_ELF is not set +# CONFIG_BUILTIN is not set +# CONFIG_PIC is not set +# CONFIG_SYMTAB_ORDEREDBYNAME is not set + +# +# Library Routines +# + +# +# Standard C Library Options +# +CONFIG_STDIO_BUFFER_SIZE=0 +CONFIG_STDIO_LINEBUFFER=y +CONFIG_NUNGET_CHARS=0 +# CONFIG_LIBM is not set +# CONFIG_NOPRINTF_FIELDWIDTH is not set +# CONFIG_LIBC_FLOATINGPOINT is not set +# CONFIG_LIBC_LONG_LONG is not set +# CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set +CONFIG_LIB_RAND_ORDER=1 +# CONFIG_EOL_IS_CR is not set +# CONFIG_EOL_IS_LF is not set +# CONFIG_EOL_IS_BOTH_CRLF is not set +CONFIG_EOL_IS_EITHER_CRLF=y +# CONFIG_LIBC_EXECFUNCS is not set +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 +# CONFIG_LIBC_STRERROR is not set +# CONFIG_LIBC_PERROR_STDOUT is not set +CONFIG_ARCH_LOWPUTC=y +# CONFIG_TIME_EXTENDED is not set +CONFIG_LIB_SENDFILE_BUFSIZE=512 +# CONFIG_ARCH_ROMGETC is not set +# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set +# CONFIG_ARCH_HAVE_TLS is not set +# CONFIG_LIBC_NETDB is not set + +# +# Non-standard Library Support +# +# CONFIG_LIB_CRC64_FAST is not set +# CONFIG_LIB_KBDCODEC is not set +# CONFIG_LIB_SLCDCODEC is not set +# CONFIG_LIB_HEX2BIN is not set + +# +# Basic CXX Support +# +# CONFIG_C99_BOOL8 is not set +# CONFIG_HAVE_CXX is not set + +# +# Application Configuration +# + +# +# CAN Utilities +# + +# +# Examples +# +# CONFIG_EXAMPLES_CCTYPE is not set +# CONFIG_EXAMPLES_CHAT is not set +# CONFIG_EXAMPLES_CONFIGDATA is not set +# CONFIG_EXAMPLES_DHCPD is not set +# CONFIG_EXAMPLES_ELF is not set +# CONFIG_EXAMPLES_FTPC is not set +# CONFIG_EXAMPLES_FTPD is not set +CONFIG_EXAMPLES_HELLO=y +CONFIG_EXAMPLES_HELLO_PRIORITY=100 +CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 +# CONFIG_EXAMPLES_HIDKBD is not set +# CONFIG_EXAMPLES_IGMP is not set +# CONFIG_EXAMPLES_JSON is not set +# CONFIG_EXAMPLES_KEYPADTEST is not set +# CONFIG_EXAMPLES_MEDIA is not set +# CONFIG_EXAMPLES_MM is not set +# CONFIG_EXAMPLES_MODBUS is not set +# CONFIG_EXAMPLES_MOUNT is not set +# CONFIG_EXAMPLES_NRF24L01TERM is not set +CONFIG_EXAMPLES_NSH=y +# CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NX is not set +# CONFIG_EXAMPLES_NXFFS is not set +# CONFIG_EXAMPLES_NXHELLO is not set +# CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NXLINES is not set +# CONFIG_EXAMPLES_NXTERM is not set +# CONFIG_EXAMPLES_NXTEXT is not set +CONFIG_EXAMPLES_OSTEST=y +CONFIG_EXAMPLES_OSTEST_LOOPS=1 +CONFIG_EXAMPLES_OSTEST_STACKSIZE=8192 +CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS=8 +CONFIG_EXAMPLES_OSTEST_RR_RANGE=10000 +CONFIG_EXAMPLES_OSTEST_RR_RUNS=10 +# CONFIG_EXAMPLES_PCA9635 is not set +# CONFIG_EXAMPLES_POSIXSPAWN is not set +# CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set +# CONFIG_EXAMPLES_RGBLED is not set +# CONFIG_EXAMPLES_RGMP is not set +# CONFIG_EXAMPLES_SENDMAIL is not set +# CONFIG_EXAMPLES_SERIALBLASTER is not set +# CONFIG_EXAMPLES_SERIALRX is not set +# CONFIG_EXAMPLES_SERLOOP is not set +# CONFIG_EXAMPLES_SLCD is not set +# CONFIG_EXAMPLES_SMART is not set +# CONFIG_EXAMPLES_SMP is not set +# CONFIG_EXAMPLES_TCPECHO is not set +# CONFIG_EXAMPLES_TELNETD is not set +# CONFIG_EXAMPLES_TIFF is not set +# CONFIG_EXAMPLES_TOUCHSCREEN is not set +# CONFIG_EXAMPLES_USBTERM is not set +# CONFIG_EXAMPLES_WATCHDOG is not set +# CONFIG_EXAMPLES_WEBSERVER is not set + +# +# File System Utilities +# +# CONFIG_FSUTILS_INIFILE is not set + +# +# GPS Utilities +# +# CONFIG_GPSUTILS_MINMEA_LIB is not set + +# +# Graphics Support +# +# CONFIG_TIFF is not set +# CONFIG_GRAPHICS_TRAVELER is not set + +# +# Interpreters +# +# CONFIG_INTERPRETERS_FICL is not set +# CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set +# CONFIG_INTERPRETERS_PCODE is not set + +# +# FreeModBus +# +# CONFIG_MODBUS is not set + +# +# Network Utilities +# +# CONFIG_NETUTILS_CODECS is not set +# CONFIG_NETUTILS_ESP8266 is not set +# CONFIG_NETUTILS_FTPC is not set +# CONFIG_NETUTILS_JSON is not set +# CONFIG_NETUTILS_SMTP is not set + +# +# NSH Library +# +CONFIG_NSH_LIBRARY=y +# CONFIG_NSH_MOTD is not set + +# +# Command Line Configuration +# +# CONFIG_NSH_READLINE is not set +CONFIG_NSH_CLE=y +CONFIG_NSH_LINELEN=80 +# CONFIG_NSH_DISABLE_SEMICOLON is not set +CONFIG_NSH_MAXARGUMENTS=6 +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_NESTDEPTH=3 +# CONFIG_NSH_DISABLEBG is not set + +# +# Disable Individual commands +# +# CONFIG_NSH_DISABLE_ADDROUTE is not set +# CONFIG_NSH_DISABLE_BASENAME is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_CMP is not set +CONFIG_NSH_DISABLE_DATE=y +# CONFIG_NSH_DISABLE_DD is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_DELROUTE is not set +# CONFIG_NSH_DISABLE_DIRNAME is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +CONFIG_NSH_DISABLE_IFCONFIG=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOSETUP is not set +CONFIG_NSH_DISABLE_LOSMART=y +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MB is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKRD is not set +# CONFIG_NSH_DISABLE_MH is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y +CONFIG_NSH_DISABLE_PS=y +# CONFIG_NSH_DISABLE_PUT is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SH is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_NSH_DISABLE_WGET is not set +# CONFIG_NSH_DISABLE_XD is not set +CONFIG_NSH_MMCSDMINOR=0 + +# +# Configure Command Options +# +CONFIG_NSH_CMDOPT_DF_H=y +CONFIG_NSH_CODECS_BUFSIZE=128 +CONFIG_NSH_CMDOPT_HEXDUMP=y +CONFIG_NSH_FILEIOSIZE=1024 + +# +# Scripting Support +# +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_LOOPS is not set + +# +# Console Configuration +# +CONFIG_NSH_CONSOLE=y +# CONFIG_NSH_ALTCONDEV is not set +# CONFIG_NSH_ARCHINIT is not set +# CONFIG_NSH_LOGIN is not set +# CONFIG_NSH_CONSOLE_LOGIN is not set + +# +# NxWidgets/NxWM +# + +# +# Platform-specific Support +# +# CONFIG_PLATFORM_CONFIGDATA is not set + +# +# System Libraries and NSH Add-Ons +# +CONFIG_SYSTEM_CLE=y +CONFIG_SYSTEM_CLE_DEBUGLEVEL=0 +# CONFIG_SYSTEM_CUTERM is not set +# CONFIG_SYSTEM_FREE is not set +# CONFIG_SYSTEM_HEX2BIN is not set +# CONFIG_SYSTEM_HEXED is not set +# CONFIG_SYSTEM_INSTALL is not set +# CONFIG_SYSTEM_RAMTEST is not set +CONFIG_READLINE_HAVE_EXTMATCH=y +CONFIG_SYSTEM_READLINE=y +CONFIG_READLINE_ECHO=y +# CONFIG_READLINE_TABCOMPLETION is not set +# CONFIG_READLINE_CMD_HISTORY is not set +# CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_TEE is not set +# CONFIG_SYSTEM_UBLOXMODEM is not set +# CONFIG_SYSTEM_VI is not set +# CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/misoc/nsh/setenv.sh b/configs/misoc/nsh/setenv.sh new file mode 100644 index 0000000000..851cd9727d --- /dev/null +++ b/configs/misoc/nsh/setenv.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# configs/misoc/nsh/setenv.sh +# +# Copyright (C) 2016 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# Ramtin Amin +# +# 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. +# + +if [ "$_" = "$0" ] ; then + echo "You must source this script, not run it!" 1>&2 + exit 1 +fi + +WD=`pwd` +if [ ! -x "setenv.sh" ]; then + echo "This script must be executed from the top-level NuttX build directory" + exit 1 +fi + +if [ -z "${PATH_ORIG}" ]; then + export PATH_ORIG="${PATH}" +fi + +# This is the Cygwin path to the location where I build the buildroot +# toolchain. +export TOOLCHAIN_BIN="${WD}/../buildroot/build_lm32/staging_dir/bin" + +# Add the path to the toolchain to the PATH varialble +export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" + +echo "PATH : ${PATH}" From 693f8d743d218082a9f3b906ea25e27fc5fd78d3 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Mon, 7 Nov 2016 10:13:53 -0600 Subject: [PATCH 122/155] LM32: Move interrupt definitions from common irq.h to lm32/irq.h. Remove unused misoc_uart.c and .h --- arch/misoc/include/irq.h | 4 - arch/misoc/include/lm32/irq.h | 6 + arch/misoc/src/common/misoc_uart.c | 233 --------------------------- arch/misoc/src/common/misoc_uart.h | 60 ------- arch/misoc/src/lm32/lm32_decodeirq.c | 2 +- arch/misoc/src/lm32/lm32_irq.c | 6 +- arch/misoc/src/lm32/lm32_vectors.S | 2 +- 7 files changed, 11 insertions(+), 302 deletions(-) delete mode 100644 arch/misoc/src/common/misoc_uart.c delete mode 100644 arch/misoc/src/common/misoc_uart.h diff --git a/arch/misoc/include/irq.h b/arch/misoc/include/irq.h index a21987b00a..882c37a0fb 100644 --- a/arch/misoc/include/irq.h +++ b/arch/misoc/include/irq.h @@ -53,11 +53,7 @@ * Pre-processor Definitions ****************************************************************************/ -/* 32 True interrupts plus the sofware interrupt */ -#define MISOC_NINTERRUPTS 32 -#define MISOC_IRQ_SWINT 32 -#define NR_IRQS 33 /**************************************************************************** * Public Function Prototypes diff --git a/arch/misoc/include/lm32/irq.h b/arch/misoc/include/lm32/irq.h index 782bb06ae9..2e5e51e83a 100644 --- a/arch/misoc/include/lm32/irq.h +++ b/arch/misoc/include/lm32/irq.h @@ -48,6 +48,12 @@ * Pre-processor Definitions ****************************************************************************/ +/* 32 True interrupts plus the sofware interrupt */ + +#define LM32_NINTERRUPTS 32 +#define LM32_IRQ_SWINT 32 +#define NR_IRQS 33 + /* Registers */ #define REG_X0_NDX 0 /* Holds the value zero */ diff --git a/arch/misoc/src/common/misoc_uart.c b/arch/misoc/src/common/misoc_uart.c deleted file mode 100644 index 76cdd48703..0000000000 --- a/arch/misoc/src/common/misoc_uart.c +++ /dev/null @@ -1,233 +0,0 @@ -/**************************************************************************** - * arch/misoc/src/common/misoc_uart.c - * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Ramtin Amin - * - * 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 -#include -#include -#include - -#ifdef CONFIG_SERIAL_TERMIOS -# include -#endif - -#include -#include -#include - -#include -#include - -#include "hw/flags.h" -#include "misoc_uart.h" - -#include "chip.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/* Buffer sizes must be a power of 2 so that modulos can be computed - * with logical AND. - */ - -#define UART_RINGBUFFER_SIZE_RX 128 -#define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1) - -#define UART_RINGBUFFER_SIZE_TX 128 -#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static char rx_buf[UART_RINGBUFFER_SIZE_RX]; -static volatile unsigned int rx_produce; -static unsigned int rx_consume; - -static char tx_buf[UART_RINGBUFFER_SIZE_TX]; -static unsigned int tx_produce; -static volatile unsigned int tx_consume; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: uart_interrupt - ****************************************************************************/ - -static int uart_interrupt(int irq, void *context) -{ - unsigned int stat, rx_produce_next; - - stat = uart_ev_pending_read(); - - if ((stat & UART_EV_RX) != 0) - { - while (!uart_rxempty_read()) - { - rx_produce_next = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX; - if (rx_produce_next != rx_consume) - { - rx_buf[rx_produce] = uart_rxtx_read(); - rx_produce = rx_produce_next; - } - - uart_ev_pending_write(UART_EV_RX); - } - } - - if ((stat & UART_EV_TX) != 0) - { - uart_ev_pending_write(UART_EV_TX); - while ((tx_consume != tx_produce) && !uart_txfull_read()) - { - uart_rxtx_write(tx_buf[tx_consume]); - tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; - } - } - - return OK; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: uart_read - * - * Do not use in interrupt handlers! - * - ****************************************************************************/ - -char uart_read(void) -{ - char c; - - if (irq_getie()) - { - while (rx_consume == rx_produce); - } - else if (rx_consume == rx_produce) - { - return 0; - } - - c = rx_buf[rx_consume]; - rx_consume = (rx_consume + 1) & UART_RINGBUFFER_MASK_RX; - return c; -} - -/**************************************************************************** - * Name: uart_read_nonblock - ****************************************************************************/ - -int uart_read_nonblock(void) -{ - return (rx_consume != rx_produce); -} - -/**************************************************************************** - * Name: up_putc - ****************************************************************************/ - -int up_putc(int ch) -{ - unsigned int oldmask; - unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; - - if (irq_getie()) - { - while (tx_produce_next == tx_consume); - } - else if (tx_produce_next == tx_consume) - { - return ch; - } - - oldmask = irq_getmask(); - irq_setmask(oldmask & ~(1 << UART_INTERRUPT)); - - if ((tx_consume != tx_produce) || uart_txfull_read()) - { - tx_buf[tx_produce] = ch; - tx_produce = tx_produce_next; - } - else - { - uart_rxtx_write(ch); - } - - irq_setmask(oldmask); - return ch; -} - -/**************************************************************************** - * Name: uart_init - ****************************************************************************/ - -void uart_init(void) -{ - rx_produce = 0; - rx_consume = 0; - - tx_produce = 0; - tx_consume = 0; - - uart_ev_pending_write(uart_ev_pending_read()); - uart_ev_enable_write(UART_EV_TX | UART_EV_RX); - irq_setmask(irq_getmask() | (1 << UART_INTERRUPT)); - - irq_attach(1 << UART_INTERRUPT, uart_interrupt); -} - -/**************************************************************************** - * Name: uart_sync - ****************************************************************************/ - -void uart_sync(void) -{ - while (tx_consume != tx_produce); -} diff --git a/arch/misoc/src/common/misoc_uart.h b/arch/misoc/src/common/misoc_uart.h deleted file mode 100644 index 74fcc7c0ac..0000000000 --- a/arch/misoc/src/common/misoc_uart.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** - * arch/misoc/src/common/misoc_uart.c - * - * Copyright (C) 2016 Gregory Nutt. All rights reserved. - * Author: Ramtin Amin - * - * 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 __ARCH_MISOC_SRC_COMMON_MISOC_UART_H -#define __ARCH_MISOC_SRC_COMMON_MISOC_UART_H 1 - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - -#ifdef __cplusplus -extern "C" -{ -#endif - -void uart_init(void); -void uart_isr(void); -void uart_sync(void); - -void uart_write(char c); -char uart_read(void); -int uart_read_nonblock(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __ARCH_MISOC_SRC_COMMON_MISOC_UART_H */ diff --git a/arch/misoc/src/lm32/lm32_decodeirq.c b/arch/misoc/src/lm32/lm32_decodeirq.c index 1cb792cedf..ea55e3a0b7 100644 --- a/arch/misoc/src/lm32/lm32_decodeirq.c +++ b/arch/misoc/src/lm32/lm32_decodeirq.c @@ -74,7 +74,7 @@ uint32_t *lm32_decodeirq(uint32_t intstat, uint32_t *regs) /* Decode and dispatch interrupts */ - for (irq = 0; irq < MISOC_NINTERRUPTS && intstat != 0; irq++) + for (irq = 0; irq < LM32_NINTERRUPTS && intstat != 0; irq++) { uint32_t bit = (1 << irq); diff --git a/arch/misoc/src/lm32/lm32_irq.c b/arch/misoc/src/lm32/lm32_irq.c index dab24189e6..eb5313810d 100644 --- a/arch/misoc/src/lm32/lm32_irq.c +++ b/arch/misoc/src/lm32/lm32_irq.c @@ -71,7 +71,7 @@ void lm32_irq_initialize(void) /* Attach the software interrupt */ - (void)irq_attach(MISOC_IRQ_SWINT, lm32_swint); + (void)irq_attach(LM32_IRQ_SWINT, lm32_swint); /* Enable interrupts */ @@ -129,7 +129,7 @@ void up_disable_irq(int irq) /* Ignore any attempt to disable software interrupts */ - if (irq < MISOC_NINTERRUPTS) + if (irq < LM32_NINTERRUPTS) { /* Disable interrupts by clearing the bit that corresponds to the irq */ @@ -154,7 +154,7 @@ void up_enable_irq(int irq) /* Ignore any attempt to enable software interrupts */ - if (irq < MISOC_NINTERRUPTS) + if (irq < LM32_NINTERRUPTS) { /* Enable interrupts by setting the bit that corresponds to the irq */ diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index 95cfd26001..94521a3a69 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -152,7 +152,7 @@ _syscall_handler: sw (sp+0), ra addi ea, ea, 4 calli .save_all - mvi r1, MISOC_IRQ_SWINT + mvi r1, LM32_IRQ_SWINT calli lm32_doirq bi .restore_all_and_eret nop From d6759019136ebae7d05d4dcb5aaf0cbff605e575 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 7 Nov 2016 11:03:01 -0600 Subject: [PATCH 123/155] ESP32: Update README. --- configs/esp32-core/README.txt | 73 ++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 933420fc00..b1fd04a83d 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -22,6 +22,7 @@ Contents o Serial Console o Buttons and LEDs o SMP + o Debug Issues o Configurations o Things to Do @@ -135,6 +136,51 @@ SMP 3. Assertions. On a fatal assertions, other CPUs need to be stopped. +Debug Issues +============ + + I basically need the debug environment and a step-by-step procedure. + + - First in need some debug environment which would be a JTAG emulator + and software. + + - I don't see any way to connect JTAG to the ESP32 Core V2 board. There + is a USB/Serial converter chip, but that does not look it supports JTAG. + + - I need to understand how to use the secondary bootloader. My + understanding is that it will configure hardware, read a partition + table at address 0x5000, and then load code into memory. I do need to + download and build the bootloader? + + - Do I need to create a partition table at 0x5000? Should this be part + of the NuttX build? + + I see https://github.com/espressif/esp-idf/tree/master/components/bootloader + and https://github.com/espressif/esp-idf/tree/master/components/partition_table. + I suppose some of what I need is in there, but I am not sure what I am + looking at right now. + + There is an OpenOCD port here: https://github.com/espressif/openocd-esp32 + and I see some additional OpenOCD documentation in + https://github.com/espressif/esp-idf/tree/master/docs. This documentation + raises some more questions. It says I need to use and external JTAG like + the TIAO USB Multi-protocol Adapter and the Flyswatter2. I don't have + either of those. I am not sure if I have any USB serial JTAG. I have some + older ones that might work, however. + + My understanding when I started this was that I could use my trusty Segger + J-Link. But that won't work with OpenOCD. Is the J-Link that also a + possibility? + + I also see that I can now get an ESP32 board from Sparkfun: + https://www.sparkfun.com/products/13907 But I don't see JTAG there either: + https://cdn.sparkfun.com/assets/learn_tutorials/5/0/7/esp32-thing-schematic.pdf + + Right now, the NuttX port depends on the bootloader to initialize hardware, + including basic (slow) clocking. If I had the clock configuration logic, + would I be able to run directly out of IRAM without a bootloader? That + might be a simpler bring-up. + Configurations ============== @@ -202,14 +248,29 @@ Things to Do ============ 1. There is no support for an interrupt stack yet. - 2. I did not implement the lazy co-processor save logic supported by Xtensa. That logic works like this: + 2. There is no clock intialization logic in place. This depends on logic in + Expressif libriaries. The board comes up using that basic 40 Mhz crystal + for clocking. Getting to 80 MHz will require clocking initialization in + esp32_clockconfig.c. + 3. I did not implement the lazy co-processor save logic supported by Xtensa. + That logic works like this: - a. CPENABLE is set to zero on each context switch, disabling all co-processors. - b. If/when the task attempts to use the disabled co-processor, an exception occurs + a. CPENABLE is set to zero on each context switch, disabling all co- + processors. + b. If/when the task attempts to use the disabled co-processor, an + exception occurs c. The co-processor exception handler re-enables the co-processor. - Instead, the NuttX logic saves and restores CPENABLE on each context switch. + Instead, the NuttX logic saves and restores CPENABLE on each context + switch. - 3. Currently the Xtensa port copies register state save information from the stack into the TCB. A more efficient alternative would be to just save a pointer to a register state save area in the TCB. This would add some complexity to signal handling and also also the the up_initialstate(). But the performance improvement might be worth the effort. + 4. Currently the Xtensa port copies register state save information from + the stack into the TCB. A more efficient alternative would be to just + save a pointer to a register state save area in the TCB. This would + add some complexity to signal handling and also also the the + up_initialstate(). But the performance improvement might be worth + the effort. - 4. See SMP-related issues above \ No newline at end of file + 5. See SMP-related issues above + + 6. See Debug Issues above From 9045959aa694e73c2927cac1211a1c4e786319b9 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 8 Nov 2016 07:45:21 -0600 Subject: [PATCH 124/155] Update TODO and README --- TODO | 56 ++++++++++++++++++----------------- configs/esp32-core/README.txt | 7 ++++- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/TODO b/TODO index 703cfad205..aa048fde33 100644 --- a/TODO +++ b/TODO @@ -467,21 +467,23 @@ o pthreads (sched/pthreads) Title: PTHREAD_PRIO_PROTECT Description: Extend pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT: + "When a thread owns one or more mutexes initialized with the PTHREAD_PRIO_PROTECT protocol, it shall execute at the higher of its priority or the highest of the priority ceilings of all the mutexes owned by this thread and initialized with this attribute, regardless of whether other threads are blocked on any of these mutexes or not. - "While a thread is holding a mutex which has been initialized with + "While a thread is holding a mutex which has been initialized with the PTHREAD_PRIO_INHERIT or PTHREAD_PRIO_PROTECT protocol attributes, it shall not be subject to being moved to the tail of the scheduling queue at its priority in the event that its original priority is changed, such as by a call to sched_setparam(). Likewise, when a thread unlocks a mutex that has been initialized with the PTHREAD_PRIO_INHERIT or PTHREAD_PRIO_PROTECT protocol attributes, it shall not be subject to - being moved to the tail of the scheduling queue at its priority in the + being moved to the tail of the scheduling queue at its priority in the event that its original priority is changed." + Status: Open. No changes planned. Priority: Low -- about zero, probably not that useful. Priority inheritance is already supported and is a much better solution. And it turns out @@ -489,39 +491,39 @@ o pthreads (sched/pthreads) Excerpted from my post in a Linked-In discussion: "I started to implement this HLS/"PCP" semaphore in an RTOS that I - work with (http://www.nuttx.org) and I discovered after doing the - analysis and basic code framework that a complete solution for the - case of a counting semaphore is still quite complex -- essentially - as complex as is priority inheritance. + work with (http://www.nuttx.org) and I discovered after doing the + analysis and basic code framework that a complete solution for the + case of a counting semaphore is still quite complex -- essentially + as complex as is priority inheritance. "For example, suppose that a thread takes 3 different HLS semaphores - A, B, and C. Suppose that they are prioritized in that order with - A the lowest and C the highest. Suppose the thread takes 5 counts - from A, 3 counts from B, and 2 counts from C. What priority should - it run at? It would have to run at the priority of the highest - priority semaphore C. This means that the RTOS must maintain - internal information of the priority of every semaphore held by - the thread. + A, B, and C. Suppose that they are prioritized in that order with + A the lowest and C the highest. Suppose the thread takes 5 counts + from A, 3 counts from B, and 2 counts from C. What priority should + it run at? It would have to run at the priority of the highest + priority semaphore C. This means that the RTOS must maintain + internal information of the priority of every semaphore held by + the thread. "Now suppose it releases one count on semaphore B. How does the - RTOS know that it still holds 2 counts on B? With some complex - internal data structure. The RTOS would have to maintain internal - information about how many counts from each semaphore are held - by each thread. + RTOS know that it still holds 2 counts on B? With some complex + internal data structure. The RTOS would have to maintain internal + information about how many counts from each semaphore are held + by each thread. "How does the RTOS know that it should not decrement the priority - from the priority of C? Again, only with internal complexity. It - would have to know the priority of every semaphore held by - every thread. + from the priority of C? Again, only with internal complexity. It + would have to know the priority of every semaphore held by + every thread. "Providing the HLS capability on a simple pthread mutex would not - be such quite such a complex job if you allow only one mutex per - thread. However, the more general case seems almost as complex - as priority inheritance. I decided that the implementation does - not have value to me. I only wanted it for its reduced - complexity; in all other ways I believe that it is the inferior - solution. So I discarded a few hours of programming. Not a - big loss from the experience I gained." + be such quite such a complex job if you allow only one mutex per + thread. However, the more general case seems almost as complex + as priority inheritance. I decided that the implementation does + not have value to me. I only wanted it for its reduced + complexity; in all other ways I believe that it is the inferior + solution. So I discarded a few hours of programming. Not a + big loss from the experience I gained." o Message Queues (sched/mqueue) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index b1fd04a83d..12fdbc4581 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -145,7 +145,12 @@ Debug Issues and software. - I don't see any way to connect JTAG to the ESP32 Core V2 board. There - is a USB/Serial converter chip, but that does not look it supports JTAG. + is a USB/Serial converter chip, but that does not look like it + supports JTAG. + + It may be necessary to make cable. Refer to + http://www.esp32.com/viewtopic.php?t=381 "How to debug ESP32 with + JTAG / OpenOCD / GDB 1st part connect the hardware." - I need to understand how to use the secondary bootloader. My understanding is that it will configure hardware, read a partition From 58c2cd2843f02612a9e186574603328b9dd74ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Recht=C3=A9?= Date: Tue, 8 Nov 2016 07:46:25 -0600 Subject: [PATCH 125/155] drivers/ioexpander: Add some debug output. --- drivers/ioexpander/gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/ioexpander/gpio.c b/drivers/ioexpander/gpio.c index bf256e8a0a..072687f1f8 100644 --- a/drivers/ioexpander/gpio.c +++ b/drivers/ioexpander/gpio.c @@ -372,6 +372,8 @@ int gpio_pin_register(FAR struct gpio_dev_s *dev, int minor) } snprintf(devname, 16, fmt, (unsigned int)minor); + gpioinfo("Registering %s\n", devname); + return register_driver(devname, &g_gpio_drvrops, 0666, dev); } From 6d2a10571f808561ca7109a6ec165d5781a302c8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 8 Nov 2016 08:22:07 -0600 Subject: [PATCH 126/155] Update README --- configs/misoc/README.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/misoc/README.txt b/configs/misoc/README.txt index 285b6a4724..2bb07dc699 100644 --- a/configs/misoc/README.txt +++ b/configs/misoc/README.txt @@ -4,6 +4,9 @@ Misoc README This README applies to a port to NuttX running on a Qemu LM32 system. You can find the Qemu setup at https://bitbucket.org/key2/qemu + This initial release supports two UARTs, but does not have a system timer + or other peripherals. More to come. + Buildroot Toolchain =================== From b6d6b774e9c78a6e9597b87a8b4658b33db66606 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 8 Nov 2016 08:23:52 -0600 Subject: [PATCH 127/155] Xtensa: In this model, co-processor state restore must enable co-processors in CPENABLE. --- arch/xtensa/src/common/xtensa_coproc.S | 50 ++++++++++++++------------ 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/arch/xtensa/src/common/xtensa_coproc.S b/arch/xtensa/src/common/xtensa_coproc.S index c29e23a33b..371959b2de 100644 --- a/arch/xtensa/src/common/xtensa_coproc.S +++ b/arch/xtensa/src/common/xtensa_coproc.S @@ -113,29 +113,29 @@ _xtensa_coproc_savestate: /* Move the address of the thread state save area to R15 */ - mov a15, a2 /* A15 is now the address of the save area */ + mov a15, a2 /* A15 is now the address of the save area */ /* CPENABLE should show which CPs are enabled. */ - rsr a2, CPENABLE /* a2 = which CPs are enabled */ - beqz a2, .Ldone1 /* Quick exit if none */ + rsr a2, CPENABLE /* a2 = which CPs are enabled */ + beqz a2, .Ldone1 /* Quick exit if none */ - s16i a2, a15, XTENSA_CPSTORED /* Save mask of CPs being stored */ + s16i a2, a15, XTENSA_CPSTORED /* Save mask of CPs being stored */ movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */ - l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */ + l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */ #if XCHAL_CP0_SA_SIZE > 0 - bbci.l a2, 0, 2f /* CP 0 not enabled */ - l32i a14, a13, 0 /* a14 = _xtensa_coproc_saoffsets[0] */ - add a3, a14, a15 /* a3 = save area for CP 0 */ + bbci.l a2, 0, 2f /* CP 0 not enabled */ + l32i a14, a13, 0 /* a14 = _xtensa_coproc_saoffsets[0] */ + add a3, a14, a15 /* a3 = save area for CP 0 */ xchal_cp0_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL 2: #endif #if XCHAL_CP1_SA_SIZE > 0 - bbci.l a2, 1, 2f /* CP 1 not enabled */ - l32i a14, a13, 4 /* a14 = _xtensa_coproc_saoffsets[1] */ - add a3, a14, a15 /* a3 = save area for CP 1 */ + bbci.l a2, 1, 2f /* CP 1 not enabled */ + l32i a14, a13, 4 /* a14 = _xtensa_coproc_saoffsets[1] */ + add a3, a14, a15 /* a3 = save area for CP 1 */ xchal_cp1_store a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL 2: #endif @@ -283,11 +283,10 @@ xtensa_coproc_savestate: * Entry Conditions: * - A2 holds the address of the co-processor state save area * - The incoming thread is set as the current thread. - * - CPENABLE is set up correctly for all required coprocessors. * * Exit conditions: * - All necessary CP callee-saved state has been restored. - * - CPENABLE - unchanged. + * - CPENABLE - Set up correctly for the current thread. * - Registers a2-a7, a13-a15 have been trashed. * * Must be called from assembly code only, using CALL0. @@ -305,26 +304,29 @@ _xtensa_coproc_restorestate: /* Move the address of the thread state save area to R15 */ - mov a15, a2 /* A15 is now the address of the save area */ - l16ui a2, a15, XTENSA_CPSTORED /* a2 = which CPs have been saved */ - movi a3, 0 /* Clear the ones being restored (all of them) */ + mov a15, a2 /* A15 is now the address of the save area */ + + l16ui a2, a15, XTENSA_CPENABLE /* a2 = Which CPs have been enable for this thread? */ + wsr a2, CPENABLE /* Set CPENABLE correctly for this thread */ + l16ui a2, a15, XTENSA_CPSTORED /* a2 = Which CPs have been saved for this thread? */ + movi a3, 0 /* Clear the ones being restored (all of them) */ s16i a3, a15, XTENSA_CPSTORED /* Clear saved CP mask */ movi a13, _xtensa_coproc_saoffsets /* Array of CP save offsets */ - l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */ + l32i a15, a15, XTENSA_CPASA /* a15 = base of aligned save area */ #if XCHAL_CP0_SA_SIZE - bbci.l a2, 0, 2f /* CP 0 not enabled */ - l32i a14, a13, 0 /* a14 = _xtensa_coproc_saoffsets[0] */ - add a3, a14, a15 /* a3 = save area for CP 0 */ + bbci.l a2, 0, 2f /* CP 0 not enabled */ + l32i a14, a13, 0 /* a14 = _xtensa_coproc_saoffsets[0] */ + add a3, a14, a15 /* a3 = save area for CP 0 */ xchal_cp0_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL 2: #endif #if XCHAL_CP1_SA_SIZE - bbci.l a2, 1, 2f /* CP 1 not enabled */ - l32i a14, a13, 4 /* a14 = _xtensa_coproc_saoffsets[1] */ - add a3, a14, a15 /* a3 = save area for CP 1 */ + bbci.l a2, 1, 2f /* CP 1 not enabled */ + l32i a14, a13, 4 /* a14 = _xtensa_coproc_saoffsets[1] */ + add a3, a14, a15 /* a3 = save area for CP 1 */ xchal_cp1_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL 2: #endif @@ -376,7 +378,9 @@ _xtensa_coproc_restorestate: xchal_cp7_load a3, a4, a5, a6, a7 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL 2: #endif + /* Ensure wsr.CPENABLE has completed. */ + rsync ret .size _xtensa_coproc_restorestate, . - _xtensa_coproc_restorestate From ac1bb127b6e169aca86af8b0715ee622aeba1c18 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 8 Nov 2016 08:51:03 -0600 Subject: [PATCH 128/155] Correct some C++ style comments. --- arch/xtensa/src/esp32/esp32_clockconfig.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/src/esp32/esp32_clockconfig.c b/arch/xtensa/src/esp32/esp32_clockconfig.c index f2f7df08ea..cabcb1197b 100644 --- a/arch/xtensa/src/esp32/esp32_clockconfig.c +++ b/arch/xtensa/src/esp32/esp32_clockconfig.c @@ -84,7 +84,7 @@ void esp32_clockconfig(void) phy_get_romfunc_addr(); - // freq will be changed to 40MHz in rtc_init_lite + /* Frequency will be changed to 40MHz in rtc_init_lite */ rtc_init_lite(); @@ -105,7 +105,7 @@ void esp32_clockconfig(void) break; } - // freq will be changed to freq in rtc_set_cpu_freq, + /* Frequency will be changed to freq in rtc_set_cpu_freq */ rtc_set_cpu_freq(XTAL_AUTO, freq); ets_update_cpu_frequency(freq_mhz); From 484a1b61049ca9927979216503d4a08abf9600b3 Mon Sep 17 00:00:00 2001 From: Freddie Chopin Date: Wed, 9 Nov 2016 07:01:49 -0600 Subject: [PATCH 129/155] sem_wait() and sem_trywait() no longer modify the errno value UNLESS an error occurs. This allows these functions to be used internallly without clobbering the errno value. --- sched/semaphore/sem_trywait.c | 24 ++++++++++++------------ sched/semaphore/sem_wait.c | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sched/semaphore/sem_trywait.c b/sched/semaphore/sem_trywait.c index 37ba0d66e2..c55116a2b7 100644 --- a/sched/semaphore/sem_trywait.c +++ b/sched/semaphore/sem_trywait.c @@ -84,13 +84,9 @@ int sem_trywait(FAR sem_t *sem) /* This API should not be called from interrupt handlers */ - DEBUGASSERT(up_interrupt_context() == false); + DEBUGASSERT(sem != NULL && up_interrupt_context() == false); - /* Assume any errors reported are due to invalid arguments. */ - - set_errno(EINVAL); - - if (sem) + if (sem != NULL) { /* The following operations must be performed with interrupts disabled * because sem_post() may be called from an interrupt handler. @@ -98,12 +94,6 @@ int sem_trywait(FAR sem_t *sem) flags = enter_critical_section(); - /* Any further errors could only occurr because the semaphore is not - * available. - */ - - set_errno(EAGAIN); - /* If the semaphore is available, give it to the requesting task */ if (sem->semcount > 0) @@ -114,11 +104,21 @@ int sem_trywait(FAR sem_t *sem) rtcb->waitsem = NULL; ret = OK; } + else + { + /* Semaphore is not available */ + + set_errno(EAGAIN); + } /* Interrupts may now be enabled. */ leave_critical_section(flags); } + else + { + set_errno(EINVAL); + } return ret; } diff --git a/sched/semaphore/sem_wait.c b/sched/semaphore/sem_wait.c index 9c19d406d7..da855bc70c 100644 --- a/sched/semaphore/sem_wait.c +++ b/sched/semaphore/sem_wait.c @@ -84,11 +84,11 @@ int sem_wait(FAR sem_t *sem) /* This API should not be called from interrupt handlers */ - DEBUGASSERT(up_interrupt_context() == false); + DEBUGASSERT(sem != NULL && up_interrupt_context() == false); /* Make sure we were supplied with a valid semaphore. */ - if (sem) + if (sem != NULL) { /* The following operations must be performed with interrupts * disabled because sem_post() may be called from an interrupt From a9c66683f285494f5182ad19c1b3e0790aa22f7a Mon Sep 17 00:00:00 2001 From: Sebastien Lorquet Date: Wed, 9 Nov 2016 19:16:44 +0100 Subject: [PATCH 130/155] Change the way to configure quadrature encoder prescalers. --- arch/arm/src/stm32l4/Kconfig | 54 +++++++++++---------- arch/arm/src/stm32l4/stm32l4_qencoder.c | 62 +++++++++++-------------- 2 files changed, 56 insertions(+), 60 deletions(-) diff --git a/arch/arm/src/stm32l4/Kconfig b/arch/arm/src/stm32l4/Kconfig index a365dd4783..6995a51421 100644 --- a/arch/arm/src/stm32l4/Kconfig +++ b/arch/arm/src/stm32l4/Kconfig @@ -2807,11 +2807,12 @@ config STM32L4_TIM1_QE if STM32L4_TIM1_QE -config STM32L4_TIM1_QECLKOUT - int "TIM1 output clock" - default 2800000 +config STM32L4_TIM1_QEPSC + int "TIM1 pulse prescaler" + default 1 ---help--- - The output clock of TIM1. + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM1." (CONFIG_TIM1_QECLKOUT). endif @@ -2824,11 +2825,12 @@ config STM32L4_TIM2_QE if STM32L4_TIM2_QE -config STM32L4_TIM2_QECLKOUT - int "TIM2 output clock" - default 2800000 +config STM32L4_TIM2_QEPSC + int "TIM2 pulse prescaler" + default 1 ---help--- - The output clock of TIM2. + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM2." (CONFIG_TIM2_QECLKOUT). endif @@ -2841,11 +2843,12 @@ config STM32L4_TIM3_QE if STM32L4_TIM3_QE -config STM32L4_TIM3_QECLKOUT - int "TIM3 output clock" - default 2800000 +config STM32L4_TIM3_QEPSC + int "TIM3 pulse prescaler" + default 1 ---help--- - The output clock of TIM3. + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM3." (CONFIG_TIM3_QECLKOUT). endif @@ -2858,11 +2861,12 @@ config STM32L4_TIM4_QE if STM32L4_TIM4_QE -config STM32L4_TIM4_QECLKOUT - int "TIM4 output clock" - default 2800000 +config STM32L4_TIM4_QEPSC + int "TIM4 pulse prescaler" + default 1 ---help--- - The output clock of TIM4. + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM4." (CONFIG_TIM4_QECLKOUT). endif @@ -2875,11 +2879,12 @@ config STM32L4_TIM5_QE if STM32L4_TIM5_QE -config STM32L4_TIM5_QECLKOUT - int "TIM5 output clock" - default 2800000 +config STM32L4_TIM5_QEPSC + int "TIM5 pulse prescaler" + default 1 ---help--- - The output clock of TIM5. + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM5." (CONFIG_TIM5_QECLKOUT). endif @@ -2892,11 +2897,12 @@ config STM32L4_TIM8_QE if STM32L4_TIM8_QE -config STM32L4_TIM8_QECLKOUT - int "TIM8 output clock" - default 2800000 +config STM32L4_TIM8_QEPSC + int "TIM8 pulse prescaler" + default 1 ---help--- - The output clock of TIM8. + This prescaler divides the number of recorded encoder pulses, limiting the count rate at the expense of resolution. + Replaces the obscure "output clock of TIM8." (CONFIG_TIM8_QECLKOUT). endif diff --git a/arch/arm/src/stm32l4/stm32l4_qencoder.c b/arch/arm/src/stm32l4/stm32l4_qencoder.c index 19436b2e18..647d151fb3 100644 --- a/arch/arm/src/stm32l4/stm32l4_qencoder.c +++ b/arch/arm/src/stm32l4/stm32l4_qencoder.c @@ -66,31 +66,6 @@ * Pre-processor Definitions ************************************************************************************/ /* Clocking *************************************************************************/ -/* The CLKOUT value should not exceed the CLKIN value */ - -#if defined(CONFIG_STM32L4_TIM1_QE) && CONFIG_STM32L4_TIM1_QECLKOUT > STM32L4_APB2_TIM1_CLKIN -# warning "CONFIG_STM32L4_TIM1_QECLKOUT exceeds STM32L4_APB2_TIM1_CLKIN" -#endif - -#if defined(CONFIG_STM32L4_TIM2_QE) && CONFIG_STM32L4_TIM2_QECLKOUT > STM32L4_APB1_TIM2_CLKIN -# warning "CONFIG_STM32L4_TIM2_QECLKOUT exceeds STM32L4_APB2_TIM2_CLKIN" -#endif - -#if defined(CONFIG_STM32L4_TIM3_QE) && CONFIG_STM32L4_TIM3_QECLKOUT > STM32L4_APB1_TIM3_CLKIN -# warning "CONFIG_STM32L4_TIM3_QECLKOUT exceeds STM32L4_APB2_TIM3_CLKIN" -#endif - -#if defined(CONFIG_STM32L4_TIM4_QE) && CONFIG_STM32L4_TIM4_QECLKOUT > STM32L4_APB1_TIM4_CLKIN -# warning "CONFIG_STM32L4_TIM4_QECLKOUT exceeds STM32L4_APB2_TIM4_CLKIN" -#endif - -#if defined(CONFIG_STM32L4_TIM5_QE) && CONFIG_STM32L4_TIM5_QECLKOUT > STM32L4_APB1_TIM5_CLKIN -# warning "CONFIG_STM32L4_TIM5_QECLKOUT exceeds STM32L4_APB2_TIM5_CLKIN" -#endif - -#if defined(CONFIG_STM32L4_TIM8_QE) && CONFIG_STM32L4_TIM8_QECLKOUT > STM32L4_APB2_TIM8_CLKIN -# warning "CONFIG_STM32L4_TIM8_QECLKOUT exceeds STM32L4_APB2_TIM8_CLKIN" -#endif /* Timers ***************************************************************************/ @@ -223,7 +198,7 @@ struct stm32l4_qeconfig_s uint32_t ti1cfg; /* TI1 input pin configuration (20-bit encoding) */ uint32_t ti2cfg; /* TI2 input pin configuration (20-bit encoding) */ uint32_t base; /* Register base address */ - uint32_t psc; /* Timer input clock prescaler */ + uint32_t psc; /* Encoder pulses prescaler */ xcpt_t handler; /* Interrupt handler for this IRQ */ }; @@ -323,7 +298,7 @@ static const struct stm32l4_qeconfig_s g_tim1config = .width = TIM1_BITWIDTH, #endif .base = STM32L4_TIM1_BASE, - .psc = (STM32L4_APB2_TIM1_CLKIN / CONFIG_STM32L4_TIM1_QECLKOUT) - 1, + .psc = CONFIG_STM32L4_TIM1_QEPSC, .ti1cfg = GPIO_TIM1_CH1IN, .ti2cfg = GPIO_TIM1_CH2IN, #if TIM1_BITWIDTH == 16 @@ -349,7 +324,7 @@ static const struct stm32l4_qeconfig_s g_tim2config = .width = TIM2_BITWIDTH, #endif .base = STM32L4_TIM2_BASE, - .psc = (STM32L4_APB1_TIM2_CLKIN / CONFIG_STM32L4_TIM2_QECLKOUT) - 1, + .psc = CONFIG_STM32L4_TIM2_QEPSC, .ti1cfg = GPIO_TIM2_CH1IN, .ti2cfg = GPIO_TIM2_CH2IN, #if TIM2_BITWIDTH == 16 @@ -375,7 +350,7 @@ static const struct stm32l4_qeconfig_s g_tim3config = .width = TIM3_BITWIDTH, #endif .base = STM32L4_TIM3_BASE, - .psc = (STM32L4_APB1_TIM3_CLKIN / CONFIG_STM32L4_TIM3_QECLKOUT) - 1, + .psc = CONFIG_STM32L4_TIM3_QEPSC, .ti1cfg = GPIO_TIM3_CH1IN, .ti2cfg = GPIO_TIM3_CH2IN, #if TIM3_BITWIDTH == 16 @@ -401,7 +376,7 @@ static const struct stm32l4_qeconfig_s g_tim4config = .width = TIM4_BITWIDTH, #endif .base = STM32L4_TIM4_BASE, - .psc = (STM32L4_APB1_TIM4_CLKIN / CONFIG_STM32L4_TIM4_QECLKOUT) - 1, + .psc = CONFIG_STM32L4_TIM4_QEPSC, .ti1cfg = GPIO_TIM4_CH1IN, .ti2cfg = GPIO_TIM4_CH2IN, #if TIM4_BITWIDTH == 16 @@ -427,7 +402,7 @@ static const struct stm32l4_qeconfig_s g_tim5config = .width = TIM5_BITWIDTH, #endif .base = STM32L4_TIM5_BASE, - .psc = (STM32L4_APB1_TIM5_CLKIN / CONFIG_STM32L4_TIM5_QECLKOUT) - 1, + .psc = CONFIG_STM32L4_TI55_QEPSC, .ti1cfg = GPIO_TIM5_CH1IN, .ti2cfg = GPIO_TIM5_CH2IN, #if TIM5_BITWIDTH == 16 @@ -453,7 +428,7 @@ static const struct stm32l4_qeconfig_s g_tim8config = .width = TIM8_BITWIDTH, #endif .base = STM32L4_TIM8_BASE, - .psc = (STM32L4_APB2_TIM8_CLKIN / CONFIG_STM32L4_TIM8_QECLKOUT) - 1, + .psc = CONFIG_STM32L4_TIM8_QEPSC, .ti1cfg = GPIO_TIM8_CH1IN, .ti2cfg = GPIO_TIM8_CH2IN, #if TIM8_BITWIDTH == 16 @@ -804,10 +779,23 @@ static int stm32l4_setup(FAR struct qe_lowerhalf_s *lower) stm32l4_putreg16(priv, STM32L4_GTIM_ARR_OFFSET, 0xffff); #endif - /* Set the timer prescaler value. The clock input value (CLKIN) is based on the - * peripheral clock (PCLK) and a multiplier. These CLKIN values are provided in - * the board.h file. The prescaler value is then that CLKIN value divided by the - * configured CLKOUT value (minus one) + /* Set the timer prescaler value. + * + * Previously, and still in the stm32fx driver, the clock input value (CLKIN) + * was based on the peripheral clock (PCLK) and a multiplier. + * These CLKIN values are provided in the board.h file. + * The prescaler value is then that CLKIN value divided by the configured + * CLKOUT value (minus one). + * + * It was determined that this configration makes no sense for a qencoder. + * If we are doing precise shaft positioning, each qe pulse is important. + * So the STM32L4 has direct config control on the pulse count prescaler, + * instead of deriving this value from an obscure "output"setting AND the + * timer input clock. This input clock just limits the incoming pulse rate, + * which should be lower than the peripheral clock due to resynchronization, + * but it is the responsibility of the system designer to decide the + * correct prescaler value, because it has a direct influence on the + * encoder resolution. */ stm32l4_putreg16(priv, STM32L4_GTIM_PSC_OFFSET, (uint16_t)priv->config->psc); @@ -1184,6 +1172,8 @@ static int stm32l4_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd, unsigned lon { /* No ioctl commands supported */ + /* TODO add an IOCTL to control the encoder pulse count prescaler */ + return -ENOTTY; } From 98088a7456b8f6280dc5dd6bdfa8e05969b948b5 Mon Sep 17 00:00:00 2001 From: Sebastien Lorquet Date: Wed, 9 Nov 2016 19:52:29 +0100 Subject: [PATCH 131/155] typos --- arch/arm/src/stm32l4/stm32l4_qencoder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/src/stm32l4/stm32l4_qencoder.c b/arch/arm/src/stm32l4/stm32l4_qencoder.c index 647d151fb3..4e0ebb0283 100644 --- a/arch/arm/src/stm32l4/stm32l4_qencoder.c +++ b/arch/arm/src/stm32l4/stm32l4_qencoder.c @@ -402,7 +402,7 @@ static const struct stm32l4_qeconfig_s g_tim5config = .width = TIM5_BITWIDTH, #endif .base = STM32L4_TIM5_BASE, - .psc = CONFIG_STM32L4_TI55_QEPSC, + .psc = CONFIG_STM32L4_TIM5_QEPSC, .ti1cfg = GPIO_TIM5_CH1IN, .ti2cfg = GPIO_TIM5_CH2IN, #if TIM5_BITWIDTH == 16 @@ -787,10 +787,10 @@ static int stm32l4_setup(FAR struct qe_lowerhalf_s *lower) * The prescaler value is then that CLKIN value divided by the configured * CLKOUT value (minus one). * - * It was determined that this configration makes no sense for a qencoder. + * It was determined that this configuration makes no sense for a qencoder. * If we are doing precise shaft positioning, each qe pulse is important. * So the STM32L4 has direct config control on the pulse count prescaler, - * instead of deriving this value from an obscure "output"setting AND the + * instead of deriving this value from an obscure "output" setting AND the * timer input clock. This input clock just limits the incoming pulse rate, * which should be lower than the peripheral clock due to resynchronization, * but it is the responsibility of the system designer to decide the From b7ed12ebd38bf3c70b51d5b40ef71d0bbb1860e2 Mon Sep 17 00:00:00 2001 From: Juha Niskanen Date: Thu, 10 Nov 2016 06:09:57 -0600 Subject: [PATCH 132/155] Patch brings strtol() and related functions more conformant with POSIX. Corner cases like strtol(-2147483648, NULL, 10) now pass clang -fsanitize=integer without warnings. --- libc/stdlib/lib_strtol.c | 27 ++++++++++++++++++++++++--- libc/stdlib/lib_strtoll.c | 29 +++++++++++++++++++++++++---- libc/stdlib/lib_strtoul.c | 7 ++++--- libc/stdlib/lib_strtoull.c | 7 ++++--- 4 files changed, 57 insertions(+), 13 deletions(-) diff --git a/libc/stdlib/lib_strtol.c b/libc/stdlib/lib_strtol.c index 8c7f639901..2c6c6a24de 100644 --- a/libc/stdlib/lib_strtol.c +++ b/libc/stdlib/lib_strtol.c @@ -41,6 +41,7 @@ #include #include +#include #include "libc.h" @@ -60,7 +61,13 @@ * nptr to a long integer value according to the given base, which must be * between 2 and 36 inclusive, or be the special value 0. * - * Warning: does not check for integer overflow! + * Returns: + * - The converted value, if the base and number are valid + * - 0 if an error occurs, and set errno to: + * * EINVAL if base < 2 or base > 36 + * - LONG_MIN or LONG_MAX, of correct sign, if an overflow occurs, + * and set errno to: + * * ERANGE if the number cannot be represented using long * ****************************************************************************/ @@ -91,11 +98,25 @@ long strtol(FAR const char *nptr, FAR char **endptr, int base) accum = strtoul(nptr, endptr, base); - /* Correct the sign of the result */ + /* Correct the sign of the result and check for overflow */ if (negate) { - return -(long)accum; + const unsigned long limit = ((unsigned long)-(LONG_MIN + 1)) + 1; + + if (accum > limit) + { + set_errno(ERANGE); + return LONG_MIN; + } + + return (accum == limit) ? LONG_MIN : -(long)accum; + } + + if (accum > LONG_MAX) + { + set_errno(ERANGE); + return LONG_MAX; } } diff --git a/libc/stdlib/lib_strtoll.c b/libc/stdlib/lib_strtoll.c index bc8cc2eb6f..a5f8b2cdc3 100644 --- a/libc/stdlib/lib_strtoll.c +++ b/libc/stdlib/lib_strtoll.c @@ -41,6 +41,7 @@ #include #include +#include #include "libc.h" @@ -58,11 +59,17 @@ * Name: strtoll * * Description: - * The strtol() function converts the initial part of the string in + * The strtoll() function converts the initial part of the string in * nptr to a long long integer value according to the given base, which * must be between 2 and 36 inclusive, or be the special value 0. * - * Warning: does not check for integer overflow! + * Returns: + * - The converted value, if the base and number are valid + * - 0 if an error occurs, and set errno to: + * * EINVAL if base < 2 or base > 36 + * - LLONG_MIN or LLONG_MAX, of correct sign, if an overflow occurs, + * and set errno to: + * * ERANGE if the number cannot be represented using long long * ****************************************************************************/ @@ -93,11 +100,25 @@ long long strtoll(FAR const char *nptr, FAR char **endptr, int base) accum = strtoull(nptr, endptr, base); - /* Correct the sign of the result */ + /* Correct the sign of the result and check for overflow */ if (negate) { - return -(long long)accum; + const unsigned long long limit = ((unsigned long long)-(LLONG_MIN + 1)) + 1; + + if (accum > limit) + { + set_errno(ERANGE); + return LLONG_MIN; + } + + return (accum == limit) ? LLONG_MIN : -(long long)accum; + } + + if (accum > LLONG_MAX) + { + set_errno(ERANGE); + return LLONG_MAX; } } diff --git a/libc/stdlib/lib_strtoul.c b/libc/stdlib/lib_strtoul.c index 30ffbd31c3..1dec49e146 100644 --- a/libc/stdlib/lib_strtoul.c +++ b/libc/stdlib/lib_strtoul.c @@ -52,14 +52,15 @@ * Name: strtoul * * Description: - * The strtol() function converts the initial part of the string in + * The strtoul() function converts the initial part of the string in * nptr to a long unsigned integer value according to the given base, which * must be between 2 and 36 inclusive, or be the special value 0. * * Returns: * - The converted value, if the base and number are valid - * - 0 if an error occurs, and seterrno to: + * - 0 if an error occurs, and set errno to: * * EINVAL if base < 2 or base > 36 + * - ULONG_MAX if an overflow occurs, and set errno to: * * ERANGE if the number cannot be represented using unsigned long * ****************************************************************************/ @@ -99,7 +100,7 @@ unsigned long strtoul(FAR const char *nptr, FAR char **endptr, int base) if (accum < prev) { set_errno(ERANGE); - accum = 0; + accum = ULONG_MAX; break; } } diff --git a/libc/stdlib/lib_strtoull.c b/libc/stdlib/lib_strtoull.c index fab588891b..fe13b63249 100644 --- a/libc/stdlib/lib_strtoull.c +++ b/libc/stdlib/lib_strtoull.c @@ -55,14 +55,15 @@ * Name: strtoull * * Description: - * The strtol() function converts the initial part of the string in + * The strtoull() function converts the initial part of the string in * nptr to a long unsigned integer value according to the given base, which * must be between 2 and 36 inclusive, or be the special value 0. * * Returns: * - The converted value, if the base and number are valid - * - 0 if an error occurs, and seterrno to: + * - 0 if an error occurs, and set errno to: * * EINVAL if base < 2 or base > 36 + * - ULLONG_MAX if an overflow occurs, and set errno to: * * ERANGE if the number cannot be represented using unsigned long long * ****************************************************************************/ @@ -102,7 +103,7 @@ unsigned long long strtoull(FAR const char *nptr, FAR char **endptr, int base) if (accum < prev) { set_errno(ERANGE); - accum = 0; + accum = ULLONG_MAX; break; } } From f22c41c7cd3c927b8f9f0487e30dc9aa01b2fc6e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 12 Nov 2016 15:10:23 -0600 Subject: [PATCH 133/155] Updae README --- configs/esp32-core/README.txt | 56 +++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 12fdbc4581..acdebf3cfc 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -19,6 +19,7 @@ Contents o STATUS o ESP32 Features o ESP32 Toolchain + o Memory Map o Serial Console o Buttons and LEDs o SMP @@ -79,6 +80,61 @@ ESP32 Toolchain NOTE: The xtensa-esp32-elf configuration is only available in the xtensa-1.22.x branch. +Memory Map +========== + + Embedded Memory + --------------- + BUS TYPE START LAST DESCRIPTION NOTES + Data 0x3ff80000 0x3ff81fff RTC FAST Memory PRO_CPU Only + 0x3ff82000 0x3ff8ffff Reserved + Data 0x3ff90000 0x3ff9ffff Internal ROM 1 + 0x3ffa0000 0x3ffadfff Reserved + Data 0x3ffae000 0x3ffdffff Internal SRAM 2 DMA + Data 0x3ffe0000 0x3fffffff Internal SRAM 1 DMA + + Boundary Address + ---------------- + BUS TYPE START LAST DESCRIPTION NOTES + Instruction 0x40000000 0x40007fff Internal ROM 0 Remap + Instruction 0x40008000 0x4005ffff Internal ROM 0 + 0x40060000 0x4006ffff Reserved + Instruction 0x40070000 0x4007ffff Internal SRAM 0 Cache + Instruction 0x40080000 0x4009ffff Internal SRAM 0 + Instruction 0x400a0000 0x400affff Internal SRAM 1 + Instruction 0x400b0000 0x400b7FFF Internal SRAM 1 Remap + Instruction 0x400b8000 0x400bffff Internal SRAM 1 + Instruction 0x400c0000 0x400c1FFF RTC FAST Memory PRO_CPU Only + Data / 0x50000000 0x50001fff RTC SLOW Memory + Instruction + + External Memory + --------------- + BUS TYPE START LAST DESCRIPTION NOTES + Data 0x3f400000 0x3f7fffff External Flash Read + Data 0x3f800000 0x3fbfffff External SRAM Read and Write + + Boundary Address + ---------------- + Instruction 0x400c2000 0x40bfffff 11512 KB External Flash Read + + Linker Segments + --------------- + DESCRIPTION START END ATTR LINKER SEGMENT NAME + FLASH mapped data: 0x3f400010 - 0x3fc00010 R dram_0_seg + COMMON data RAM: 0x3ffb0000 - 0x40000000 RW dram_0_seg (NOTE 1,2) + IRAM for PRO cpu: 0x40080000 - 0x400a0000 RX iram0_0_seg + RTC fast memory: 0x400c0000 - 0x400c2000 RWX rtc_iram_seg + FLASH: 0x400d0018 - 0x40400018 RX iram0_2_seg (actually FLASH) + RTC slow memory: 0x50000000 - 0x50001000 RW rtc_slow_seg (NOTE 3) + + NOTE 1: Linker script will reserved space at the beginning of the segment + for BT and at the end for trace memory. + NOTE 2: Heap enads at the top of dram0_0_seg + NOTE 3: Linker script will reserved space at the beginning of the segment + for co-processor reserve memory and at the end for ULP coprocessor + reserve memory. + Serial Console ============== From e87f1360c6722e1c5401212a79cb73ab0227c949 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 12 Nov 2016 15:51:14 -0600 Subject: [PATCH 134/155] Update README --- configs/esp32-core/README.txt | 45 +++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index acdebf3cfc..6d7e09c4b6 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -83,9 +83,27 @@ ESP32 Toolchain Memory Map ========== - Embedded Memory - --------------- + Address Mapping + ----------- ---------- ---------- --------------- --------------- BUS TYPE START LAST DESCRIPTION NOTES + ----------- ---------- ---------- --------------- --------------- + 0x00000000 0x3F3FFFFF Reserved + Data 0x3F400000 0x3F7FFFFF External Memory + Data 0x3F800000 0x3FBFFFFF External Memory + 0x3FC00000 0x3FEFFFFF Reserved + Data 0x3FF00000 0x3FF7FFFF Peripheral + Data 0x3FF80000 0x3FFFFFFF Embedded Memory + Instruction 0x40000000 0x400C1FFF Embedded Memory + Instruction 0x400C2000 0x40BFFFFF External Memory + 0x40C00000 0x4FFFFFFF Reserved + Data / 0x50000000 0x50001FFF Embedded Memory + Instruction + 0x50002000 0xFFFFFFFF Reserved + + Embedded Memory + ----------- ---------- ---------- --------------- --------------- + BUS TYPE START LAST DESCRIPTION NOTES + ----------- ---------- ---------- --------------- --------------- Data 0x3ff80000 0x3ff81fff RTC FAST Memory PRO_CPU Only 0x3ff82000 0x3ff8ffff Reserved Data 0x3ff90000 0x3ff9ffff Internal ROM 1 @@ -94,8 +112,9 @@ Memory Map Data 0x3ffe0000 0x3fffffff Internal SRAM 1 DMA Boundary Address - ---------------- + ----------- ---------- ---------- --------------- --------------- BUS TYPE START LAST DESCRIPTION NOTES + ----------- ---------- ---------- --------------- --------------- Instruction 0x40000000 0x40007fff Internal ROM 0 Remap Instruction 0x40008000 0x4005ffff Internal ROM 0 0x40060000 0x4006ffff Reserved @@ -109,8 +128,9 @@ Memory Map Instruction External Memory - --------------- + ----------- ---------- ---------- --------------- --------------- BUS TYPE START LAST DESCRIPTION NOTES + ----------- ---------- ---------- --------------- --------------- Data 0x3f400000 0x3f7fffff External Flash Read Data 0x3f800000 0x3fbfffff External SRAM Read and Write @@ -119,14 +139,15 @@ Memory Map Instruction 0x400c2000 0x40bfffff 11512 KB External Flash Read Linker Segments - --------------- - DESCRIPTION START END ATTR LINKER SEGMENT NAME - FLASH mapped data: 0x3f400010 - 0x3fc00010 R dram_0_seg - COMMON data RAM: 0x3ffb0000 - 0x40000000 RW dram_0_seg (NOTE 1,2) - IRAM for PRO cpu: 0x40080000 - 0x400a0000 RX iram0_0_seg - RTC fast memory: 0x400c0000 - 0x400c2000 RWX rtc_iram_seg - FLASH: 0x400d0018 - 0x40400018 RX iram0_2_seg (actually FLASH) - RTC slow memory: 0x50000000 - 0x50001000 RW rtc_slow_seg (NOTE 3) + ------------------ ---------- ---------- ---- ---------------------------- + DESCRIPTION START END ATTR LINKER SEGMENT NAME + ------------------ ---------- ---------- ---- ---------------------------- + FLASH mapped data: 0x3f400010 0x3fc00010 R dram_0_seg + COMMON data RAM: 0x3ffb0000 0x40000000 RW dram_0_seg (NOTE 1,2) + IRAM for PRO cpu: 0x40080000 0x400a0000 RX iram0_0_seg + RTC fast memory: 0x400c0000 0x400c2000 RWX rtc_iram_seg + FLASH: 0x400d0018 0x40400018 RX iram0_2_seg (actually FLASH) + RTC slow memory: 0x50000000 0x50001000 RW rtc_slow_seg (NOTE 3) NOTE 1: Linker script will reserved space at the beginning of the segment for BT and at the end for trace memory. From 102abb380d6106676cc46685accd2c83bad7c191 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 13 Nov 2016 07:55:34 -0600 Subject: [PATCH 135/155] Update README --- configs/esp32-core/README.txt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 6d7e09c4b6..75fcf9442a 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -149,10 +149,10 @@ Memory Map FLASH: 0x400d0018 0x40400018 RX iram0_2_seg (actually FLASH) RTC slow memory: 0x50000000 0x50001000 RW rtc_slow_seg (NOTE 3) - NOTE 1: Linker script will reserved space at the beginning of the segment + NOTE 1: Linker script will reserve space at the beginning of the segment for BT and at the end for trace memory. NOTE 2: Heap enads at the top of dram0_0_seg - NOTE 3: Linker script will reserved space at the beginning of the segment + NOTE 3: Linker script will reserve space at the beginning of the segment for co-processor reserve memory and at the end for ULP coprocessor reserve memory. @@ -330,10 +330,12 @@ Things to Do ============ 1. There is no support for an interrupt stack yet. + 2. There is no clock intialization logic in place. This depends on logic in Expressif libriaries. The board comes up using that basic 40 Mhz crystal for clocking. Getting to 80 MHz will require clocking initialization in esp32_clockconfig.c. + 3. I did not implement the lazy co-processor save logic supported by Xtensa. That logic works like this: @@ -344,7 +346,9 @@ Things to Do c. The co-processor exception handler re-enables the co-processor. Instead, the NuttX logic saves and restores CPENABLE on each context - switch. + switch. This has disadvantages in that (1) co-processor context will + be saved and restored even if the co-processor was never used, and (2) + tasks must explicitly enable and disable co-processors. 4. Currently the Xtensa port copies register state save information from the stack into the TCB. A more efficient alternative would be to just From c7b5f20b5de82ddfc015be6e788700051bc55947 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 13 Nov 2016 09:30:45 -0600 Subject: [PATCH 136/155] Update README --- configs/esp32-core/README.txt | 122 +++++++++++++++++++++++++--------- 1 file changed, 92 insertions(+), 30 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 75fcf9442a..579978d1d7 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -142,16 +142,25 @@ Memory Map ------------------ ---------- ---------- ---- ---------------------------- DESCRIPTION START END ATTR LINKER SEGMENT NAME ------------------ ---------- ---------- ---- ---------------------------- - FLASH mapped data: 0x3f400010 0x3fc00010 R dram_0_seg - COMMON data RAM: 0x3ffb0000 0x40000000 RW dram_0_seg (NOTE 1,2) + FLASH mapped data: 0x3f400010 0x3fc00010 R drom0_0_seg + - .rodata + - Constructors/destructors + COMMON data RAM: 0x3ffb0000 0x40000000 RW dram0_0_seg (NOTE 1,2) + - .bss/.data IRAM for PRO cpu: 0x40080000 0x400a0000 RX iram0_0_seg - RTC fast memory: 0x400c0000 0x400c2000 RWX rtc_iram_seg - FLASH: 0x400d0018 0x40400018 RX iram0_2_seg (actually FLASH) + - Interrupt Vectors + - Low level handlers + - Xtensa/Expressif libraries + RTC fast memory: 0x400c0000 0x400c2000 RWX rtc_iram_seg (PRO_CPU only) + - .rtc.text (unused?) + FLASH: 0x400d0018 0x40400018 RX iram0_2_seg (actually FLASH) + - .text RTC slow memory: 0x50000000 0x50001000 RW rtc_slow_seg (NOTE 3) + - .rtc.data/rodata (unused?) NOTE 1: Linker script will reserve space at the beginning of the segment for BT and at the end for trace memory. - NOTE 2: Heap enads at the top of dram0_0_seg + NOTE 2: Heap enads at the top of dram_0_seg NOTE 3: Linker script will reserve space at the beginning of the segment for co-processor reserve memory and at the end for ULP coprocessor reserve memory. @@ -216,18 +225,50 @@ SMP Debug Issues ============ - I basically need the debug environment and a step-by-step procedure. + You basically need the debug environment and a step-by-step procedure. - First in need some debug environment which would be a JTAG emulator - and software. + and the ESP32 OpenOCD software which is available here: + https://github.com/espressif/openocd-esp32 - - I don't see any way to connect JTAG to the ESP32 Core V2 board. There - is a USB/Serial converter chip, but that does not look like it - supports JTAG. + - There is on overiew of the use of OpenOCD here: + https://dl.espressif.com/doc/esp-idf/latest/openocd.html + This document is also available in ESP-IDF source tree in docs + directory (https://github.com/espressif/esp-idf). - It may be necessary to make cable. Refer to - http://www.esp32.com/viewtopic.php?t=381 "How to debug ESP32 with - JTAG / OpenOCD / GDB 1st part connect the hardware." + A template ESP32 OpenOCD configuration file is provided in + ESP-IDF docs directory (esp32.cfg). Since you are not using + FreeRTOS, you will need to uncomment the "set ESP32_RTOS none" + line in OpenOCD configuration file. + + The documentation indicates that you need to use an external JTAG + like the TIAO USB Multi-protocol Adapter and the Flyswatter2. + The instructions at http://www.esp32.com/viewtopic.php?t=381 show + use of an FTDI C232HM-DDHSL-0 USB 2.0 high speed to MPSSE cable. + + - The ESP32 Core v2 board has no on board JTAG connector. It will + be necessary to make a cable or some other board to connect a JTAG + emulator. Refer to http://www.esp32.com/viewtopic.php?t=381 "How + to debug ESP32 with JTAG / OpenOCD / GDB 1st part connect the + hardware." + + Relevant pin-out: + + -------- ---------- + PIN JTAG + LABEL FUNCTION + -------- ---------- + IO14 TMS + IO12 TDI + GND GND + IO13 TCK + -------- ---------- + IO15 TDO + -------- ---------- + + You can find the mapping of JTAG signals to ESP32 GPIO numbers in + "ESP32 Pin List" document found here: + http://espressif.com/en/support/download/documents?keys=&field_type_tid%5B%5D=13 - I need to understand how to use the secondary bootloader. My understanding is that it will configure hardware, read a partition @@ -237,26 +278,47 @@ Debug Issues - Do I need to create a partition table at 0x5000? Should this be part of the NuttX build? - I see https://github.com/espressif/esp-idf/tree/master/components/bootloader - and https://github.com/espressif/esp-idf/tree/master/components/partition_table. - I suppose some of what I need is in there, but I am not sure what I am - looking at right now. + See https://github.com/espressif/esp-idf/tree/master/components/bootloader + and https://github.com/espressif/esp-idf/tree/master/components/partition_table. + I suppose some of what I need is in there, but I am not sure what I am + looking at right now. - There is an OpenOCD port here: https://github.com/espressif/openocd-esp32 - and I see some additional OpenOCD documentation in - https://github.com/espressif/esp-idf/tree/master/docs. This documentation - raises some more questions. It says I need to use and external JTAG like - the TIAO USB Multi-protocol Adapter and the Flyswatter2. I don't have - either of those. I am not sure if I have any USB serial JTAG. I have some - older ones that might work, however. + It is possible to skip the secondary bootloader and run out of IRAM using + only the primary bootloader if your application of small enough (< 128KiB code, + <180KiB data), then you can simplify initial bring-up by avoiding second stage + bootloader. Your application will be loaded into IRAM using first stage + bootloader present in ESP32 ROM. To achieve this, you need two things: - My understanding when I started this was that I could use my trusty Segger - J-Link. But that won't work with OpenOCD. Is the J-Link that also a - possibility? + 1. Have a linker script which places all code into IRAM and all data into DRAM - I also see that I can now get an ESP32 board from Sparkfun: - https://www.sparkfun.com/products/13907 But I don't see JTAG there either: - https://cdn.sparkfun.com/assets/learn_tutorials/5/0/7/esp32-thing-schematic.pdf + 2. Use "esptool.py" utility found in ESP-IDF to convert application .elf file + into binary format which can be loaded by first stage bootloader. + + The default linker script in ESP-IDF places most code into memory-mapped flash: + https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L178-L186 + + You would need to remove this section and move its contents into the end of .iram0.text section: + https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L85 + + Same with constant data: move contents of .flash.rodata section: + https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L134-L173 + + into the end of .dram0.data section (before _heap_start): + https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L128 + + With these modifications, all code and data should be moved into IRAM/DRAM. Next, you would + need to link the ELF file and convert it to binary format suitable for flashing into the + board. The xommand should to convert ELF file to binary image looks as follows: + + python esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 elf2image --flash_mode "dio" --flash_freq "40m" --flash_size "2MB" -o app.bin app.elf + + To flash binary image to your development board, use the same esptool.py utility: + + python esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 write_flash -z --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 app.bin + + The argument before app.bin (0x1000) indicates the offset in flash where binary + will be written. ROM bootloader expects to find an application (or second stage + bootloader) image at offset 0x1000, so we are writing the binary there. Right now, the NuttX port depends on the bootloader to initialize hardware, including basic (slow) clocking. If I had the clock configuration logic, From a6b7730f8c04e34361ccd93cef00e59322c0c8a2 Mon Sep 17 00:00:00 2001 From: Alan Carvalho de Assis Date: Sun, 13 Nov 2016 11:44:28 -0600 Subject: [PATCH 137/155] Add Vishay VEML6070 driver and support for STM32F103-Minimum board --- configs/stm32f103-minimum/README.txt | 6 + configs/stm32f103-minimum/src/Makefile | 4 + configs/stm32f103-minimum/src/stm32_bringup.c | 10 + .../stm32f103-minimum/src/stm32_veml6070.c | 105 ++ .../stm32f103-minimum/src/stm32f103_minimum.h | 13 + configs/stm32f103-minimum/veml6070/Make.defs | 113 ++ configs/stm32f103-minimum/veml6070/defconfig | 1201 +++++++++++++++++ configs/stm32f103-minimum/veml6070/setenv.sh | 100 ++ drivers/sensors/Kconfig | 7 + drivers/sensors/Make.defs | 6 + drivers/sensors/veml6070.c | 352 +++++ include/nuttx/sensors/veml6070.h | 121 ++ 12 files changed, 2038 insertions(+) create mode 100644 configs/stm32f103-minimum/src/stm32_veml6070.c create mode 100644 configs/stm32f103-minimum/veml6070/Make.defs create mode 100644 configs/stm32f103-minimum/veml6070/defconfig create mode 100644 configs/stm32f103-minimum/veml6070/setenv.sh create mode 100644 drivers/sensors/veml6070.c create mode 100644 include/nuttx/sensors/veml6070.h diff --git a/configs/stm32f103-minimum/README.txt b/configs/stm32f103-minimum/README.txt index 145f6af0e4..112182b032 100644 --- a/configs/stm32f103-minimum/README.txt +++ b/configs/stm32f103-minimum/README.txt @@ -636,3 +636,9 @@ Where is one of the following: CONFIG_CDCACM_CONSOLE=y : The CDC/ACM serial device is NOT the console CONFIG_PL2303=y : The Prolifics PL2303 emulation is enabled CONFIG_PL2303_CONSOLE=y : The PL2303 serial device is the console + + veml6070: + -------- + This is a config example to use the Vishay VEML6070 UV-A sensor. To use this + sensor you need to connect PB6 (I2C1 CLK) to SCL; PB7 (I2C1 SDA) to SDA of + sensor module. I used a GY-VEML6070 module to test this driver. diff --git a/configs/stm32f103-minimum/src/Makefile b/configs/stm32f103-minimum/src/Makefile index 3baf4b64dc..4ecd9086ae 100644 --- a/configs/stm32f103-minimum/src/Makefile +++ b/configs/stm32f103-minimum/src/Makefile @@ -73,4 +73,8 @@ ifeq ($(CONFIG_LCD_ST7567),y) CSRCS += stm32_lcd.c endif +ifeq ($(CONFIG_VEML6070),y) +CSRCS += stm32_veml6070.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/stm32f103-minimum/src/stm32_bringup.c b/configs/stm32f103-minimum/src/stm32_bringup.c index 7c81c59c07..ed1cd3d415 100644 --- a/configs/stm32f103-minimum/src/stm32_bringup.c +++ b/configs/stm32f103-minimum/src/stm32_bringup.c @@ -163,5 +163,15 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_VEML6070 + /* Register the UV-A light sensor */ + + ret = stm32_veml6070initialize("/dev/uvlight0"); + if (ret < 0) + { + syslog(LOG_ERR, "ERROR: stm32_veml6070initialize() failed: %d\n", ret); + } +#endif + return ret; } diff --git a/configs/stm32f103-minimum/src/stm32_veml6070.c b/configs/stm32f103-minimum/src/stm32_veml6070.c new file mode 100644 index 0000000000..72c6583bbc --- /dev/null +++ b/configs/stm32f103-minimum/src/stm32_veml6070.c @@ -0,0 +1,105 @@ +/************************************************************************************ + * configs/stm32f103-minimum/src/stm32_veml6070.c + * + * Copyright (C) 2016 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 "stm32.h" +#include "stm32_i2c.h" +#include "stm32f103_minimum.h" + +#if defined(CONFIG_I2C) && defined(CONFIG_VEML6070) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define VEML6070_I2C_PORTNO 1 /* On I2C1 */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_veml6070initialize + * + * Description: + * Initialize and register the VEML6070 UV-A Light sensor. + * + * Input parameters: + * devpath - The full path to the driver to register. E.g., "/dev/uvlight0" + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +int stm32_veml6070initialize(FAR const char *devpath) +{ + FAR struct i2c_master_s *i2c; + int ret; + + sninfo("Initializing VEML6070!\n"); + + /* Initialize I2C */ + + i2c = stm32_i2cbus_initialize(VEML6070_I2C_PORTNO); + + if (!i2c) + { + return -ENODEV; + } + + /* Then register the light sensor */ + + ret = veml6070_register(devpath, i2c, VEML6070_I2C_DATA_LSB_CMD_ADDR); + if (ret < 0) + { + snerr("ERROR: Error registering BM180\n"); + } + + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_VEML6070 && CONFIG_STM32_I2C1 */ diff --git a/configs/stm32f103-minimum/src/stm32f103_minimum.h b/configs/stm32f103-minimum/src/stm32f103_minimum.h index b3d4ff0a91..7b0f69ddf3 100644 --- a/configs/stm32f103-minimum/src/stm32f103_minimum.h +++ b/configs/stm32f103-minimum/src/stm32f103_minimum.h @@ -192,5 +192,18 @@ int stm32_mfrc522initialize(FAR const char *devpath); int stm32_tone_setup(void); #endif +/*********************************************************************************** + * Name: stm32_veml6070initialize + * + * Description: + * Called to configure an I2C and to register VEML6070 for the stm32f103-minimum + * board. + * + ***********************************************************************************/ + +#ifdef CONFIG_VEML6070 +int stm32_veml6070initialize(FAR const char *devpath); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_STM32F103_MINIMUM_SRC_STM32F103_MINIMUM_H */ diff --git a/configs/stm32f103-minimum/veml6070/Make.defs b/configs/stm32f103-minimum/veml6070/Make.defs new file mode 100644 index 0000000000..c6d573f6ea --- /dev/null +++ b/configs/stm32f103-minimum/veml6070/Make.defs @@ -0,0 +1,113 @@ +############################################################################ +# configs/stm32f103-minimum/vem6070/Make.defs +# +# Copyright (C) 2016 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. +# +############################################################################ + +include ${TOPDIR}/.config +include ${TOPDIR}/tools/Config.mk +include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs + +LDSCRIPT = ld.script + +ifeq ($(WINTOOL),y) + # Windows-native toolchains + DIRLINK = $(TOPDIR)/tools/copydir.sh + DIRUNLINK = $(TOPDIR)/tools/unlink.sh + MKDEP = $(TOPDIR)/tools/mkwindeps.sh + ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" + ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}" + ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}" +else + # Linux/Cygwin-native toolchain + MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT) + ARCHINCLUDES = -I. -isystem $(TOPDIR)/include + ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx + ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT) +endif + +CC = $(CROSSDEV)gcc +CXX = $(CROSSDEV)g++ +CPP = $(CROSSDEV)gcc -E +LD = $(CROSSDEV)ld +AR = $(CROSSDEV)ar rcs +NM = $(CROSSDEV)nm +OBJCOPY = $(CROSSDEV)objcopy +OBJDUMP = $(CROSSDEV)objdump + +ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'} +ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1} + +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + ARCHOPTIMIZATION = -g +endif + +ifneq ($(CONFIG_DEBUG_NOOPT),y) + ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer +endif + +ARCHCFLAGS = -fno-builtin +ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new +ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef +ARCHWARNINGSXX = -Wall -Wshadow -Wundef +ARCHDEFINES = +ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10 + +CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS) +CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe +CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS) +CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) +AFLAGS = $(CFLAGS) -D__ASSEMBLY__ + +NXFLATLDFLAGS1 = -r -d -warn-common +NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections +LDNXFLATFLAGS = -e main -s 2048 + +ASMEXT = .S +OBJEXT = .o +LIBEXT = .a +EXEEXT = + +ifneq ($(CROSSDEV),arm-nuttx-elf-) + LDFLAGS += -nostartfiles -nodefaultlibs +endif +ifeq ($(CONFIG_DEBUG_SYMBOLS),y) + LDFLAGS += -g +endif + + +HOSTCC = gcc +HOSTINCLUDES = -I. +HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe +HOSTLDFLAGS = + diff --git a/configs/stm32f103-minimum/veml6070/defconfig b/configs/stm32f103-minimum/veml6070/defconfig new file mode 100644 index 0000000000..fa44438359 --- /dev/null +++ b/configs/stm32f103-minimum/veml6070/defconfig @@ -0,0 +1,1201 @@ +# +# Automatically generated file; DO NOT EDIT. +# Nuttx/ Configuration +# + +# +# Build Setup +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_DEFAULT_SMALL=y +CONFIG_HOST_LINUX=y +# CONFIG_HOST_OSX is not set +# CONFIG_HOST_WINDOWS is not set +# CONFIG_HOST_OTHER is not set + +# +# Build Configuration +# +# CONFIG_APPS_DIR="../apps" +CONFIG_BUILD_FLAT=y +# CONFIG_BUILD_2PASS is not set + +# +# Binary Output Formats +# +# CONFIG_RRLOAD_BINARY is not set +# CONFIG_INTELHEX_BINARY is not set +# CONFIG_MOTOROLA_SREC is not set +CONFIG_RAW_BINARY=y +# CONFIG_UBOOT_UIMAGE is not set + +# +# Customize Header Files +# +# CONFIG_ARCH_STDINT_H is not set +# CONFIG_ARCH_STDBOOL_H is not set +# CONFIG_ARCH_MATH_H is not set +# CONFIG_ARCH_FLOAT_H is not set +# CONFIG_ARCH_STDARG_H is not set +# CONFIG_ARCH_DEBUG_H is not set + +# +# Debug Options +# +CONFIG_DEBUG_ALERT=y +# CONFIG_DEBUG_FEATURES is not set +CONFIG_ARCH_HAVE_STACKCHECK=y +# CONFIG_STACK_COLORATION is not set +CONFIG_ARCH_HAVE_HEAPCHECK=y +# CONFIG_HEAP_COLORATION is not set +# CONFIG_DEBUG_SYMBOLS is not set +CONFIG_ARCH_HAVE_CUSTOMOPT=y +# CONFIG_DEBUG_NOOPT is not set +# CONFIG_DEBUG_CUSTOMOPT is not set +CONFIG_DEBUG_FULLOPT=y + +# +# System Type +# +CONFIG_ARCH_ARM=y +# CONFIG_ARCH_AVR is not set +# CONFIG_ARCH_HC is not set +# CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set +# CONFIG_ARCH_RGMP is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set +# CONFIG_ARCH_SIM is not set +# CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set +# CONFIG_ARCH_Z16 is not set +# CONFIG_ARCH_Z80 is not set +CONFIG_ARCH="arm" + +# +# ARM Options +# +# CONFIG_ARCH_CHIP_A1X is not set +# CONFIG_ARCH_CHIP_C5471 is not set +# CONFIG_ARCH_CHIP_CALYPSO is not set +# CONFIG_ARCH_CHIP_DM320 is not set +# CONFIG_ARCH_CHIP_EFM32 is not set +# CONFIG_ARCH_CHIP_IMX1 is not set +# CONFIG_ARCH_CHIP_IMX6 is not set +# CONFIG_ARCH_CHIP_KINETIS is not set +# CONFIG_ARCH_CHIP_KL is not set +# CONFIG_ARCH_CHIP_LM is not set +# CONFIG_ARCH_CHIP_TIVA is not set +# CONFIG_ARCH_CHIP_LPC11XX is not set +# CONFIG_ARCH_CHIP_LPC17XX is not set +# CONFIG_ARCH_CHIP_LPC214X is not set +# CONFIG_ARCH_CHIP_LPC2378 is not set +# CONFIG_ARCH_CHIP_LPC31XX is not set +# CONFIG_ARCH_CHIP_LPC43XX is not set +# CONFIG_ARCH_CHIP_NUC1XX is not set +# CONFIG_ARCH_CHIP_SAMA5 is not set +# CONFIG_ARCH_CHIP_SAMD is not set +# CONFIG_ARCH_CHIP_SAML is not set +# CONFIG_ARCH_CHIP_SAM34 is not set +# CONFIG_ARCH_CHIP_SAMV7 is not set +CONFIG_ARCH_CHIP_STM32=y +# CONFIG_ARCH_CHIP_STM32F7 is not set +# CONFIG_ARCH_CHIP_STM32L4 is not set +# CONFIG_ARCH_CHIP_STR71X is not set +# CONFIG_ARCH_CHIP_TMS570 is not set +# CONFIG_ARCH_CHIP_MOXART is not set +# CONFIG_ARCH_ARM7TDMI is not set +# CONFIG_ARCH_ARM926EJS is not set +# CONFIG_ARCH_ARM920T is not set +# CONFIG_ARCH_CORTEXM0 is not set +CONFIG_ARCH_CORTEXM3=y +# CONFIG_ARCH_CORTEXM4 is not set +# CONFIG_ARCH_CORTEXM7 is not set +# CONFIG_ARCH_CORTEXA5 is not set +# CONFIG_ARCH_CORTEXA8 is not set +# CONFIG_ARCH_CORTEXA9 is not set +# CONFIG_ARCH_CORTEXR4 is not set +# CONFIG_ARCH_CORTEXR4F is not set +# CONFIG_ARCH_CORTEXR5 is not set +# CONFIG_ARCH_CORTEX5F is not set +# CONFIG_ARCH_CORTEXR7 is not set +# CONFIG_ARCH_CORTEXR7F is not set +CONFIG_ARCH_FAMILY="armv7-m" +CONFIG_ARCH_CHIP="stm32" +# CONFIG_ARM_TOOLCHAIN_IAR is not set +CONFIG_ARM_TOOLCHAIN_GNU=y +# CONFIG_ARMV7M_USEBASEPRI is not set +CONFIG_ARCH_HAVE_CMNVECTOR=y +# CONFIG_ARMV7M_CMNVECTOR is not set +# CONFIG_ARMV7M_LAZYFPU is not set +# CONFIG_ARCH_HAVE_FPU is not set +# CONFIG_ARCH_HAVE_DPFPU is not set +# CONFIG_ARCH_HAVE_TRUSTZONE is not set +CONFIG_ARM_HAVE_MPU_UNIFIED=y +# CONFIG_ARM_MPU is not set +# CONFIG_DEBUG_HARDFAULT is not set + +# +# ARMV7M Configuration Options +# +# CONFIG_ARMV7M_HAVE_ICACHE is not set +# CONFIG_ARMV7M_HAVE_DCACHE is not set +# CONFIG_ARMV7M_HAVE_ITCM is not set +# CONFIG_ARMV7M_HAVE_DTCM is not set +# CONFIG_ARMV7M_TOOLCHAIN_IARL is not set +# CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set +# CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set +CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y +CONFIG_ARMV7M_HAVE_STACKCHECK=y +# CONFIG_ARMV7M_STACKCHECK is not set +# CONFIG_ARMV7M_ITMSYSLOG is not set +CONFIG_SERIAL_TERMIOS=y + +# +# STM32 Configuration Options +# +# CONFIG_ARCH_CHIP_STM32L151C6 is not set +# CONFIG_ARCH_CHIP_STM32L151C8 is not set +# CONFIG_ARCH_CHIP_STM32L151CB is not set +# CONFIG_ARCH_CHIP_STM32L151R6 is not set +# CONFIG_ARCH_CHIP_STM32L151R8 is not set +# CONFIG_ARCH_CHIP_STM32L151RB is not set +# CONFIG_ARCH_CHIP_STM32L151V6 is not set +# CONFIG_ARCH_CHIP_STM32L151V8 is not set +# CONFIG_ARCH_CHIP_STM32L151VB is not set +# CONFIG_ARCH_CHIP_STM32L152C6 is not set +# CONFIG_ARCH_CHIP_STM32L152C8 is not set +# CONFIG_ARCH_CHIP_STM32L152CB is not set +# CONFIG_ARCH_CHIP_STM32L152R6 is not set +# CONFIG_ARCH_CHIP_STM32L152R8 is not set +# CONFIG_ARCH_CHIP_STM32L152RB is not set +# CONFIG_ARCH_CHIP_STM32L152V6 is not set +# CONFIG_ARCH_CHIP_STM32L152V8 is not set +# CONFIG_ARCH_CHIP_STM32L152VB is not set +# CONFIG_ARCH_CHIP_STM32L162ZD is not set +# CONFIG_ARCH_CHIP_STM32L162VE is not set +# CONFIG_ARCH_CHIP_STM32F100C8 is not set +# CONFIG_ARCH_CHIP_STM32F100CB is not set +# CONFIG_ARCH_CHIP_STM32F100R8 is not set +# CONFIG_ARCH_CHIP_STM32F100RB is not set +# CONFIG_ARCH_CHIP_STM32F100RC is not set +# CONFIG_ARCH_CHIP_STM32F100RD is not set +# CONFIG_ARCH_CHIP_STM32F100RE is not set +# CONFIG_ARCH_CHIP_STM32F100V8 is not set +# CONFIG_ARCH_CHIP_STM32F100VB is not set +# CONFIG_ARCH_CHIP_STM32F100VC is not set +# CONFIG_ARCH_CHIP_STM32F100VD is not set +# CONFIG_ARCH_CHIP_STM32F100VE is not set +# CONFIG_ARCH_CHIP_STM32F102CB is not set +# CONFIG_ARCH_CHIP_STM32F103T8 is not set +# CONFIG_ARCH_CHIP_STM32F103TB is not set +# CONFIG_ARCH_CHIP_STM32F103C4 is not set +CONFIG_ARCH_CHIP_STM32F103C8=y +# CONFIG_ARCH_CHIP_STM32F103CB is not set +# CONFIG_ARCH_CHIP_STM32F103R8 is not set +# CONFIG_ARCH_CHIP_STM32F103RB is not set +# CONFIG_ARCH_CHIP_STM32F103RC is not set +# CONFIG_ARCH_CHIP_STM32F103RD is not set +# CONFIG_ARCH_CHIP_STM32F103RE is not set +# CONFIG_ARCH_CHIP_STM32F103RG is not set +# CONFIG_ARCH_CHIP_STM32F103V8 is not set +# CONFIG_ARCH_CHIP_STM32F103VB is not set +# CONFIG_ARCH_CHIP_STM32F103VC is not set +# CONFIG_ARCH_CHIP_STM32F103VE is not set +# CONFIG_ARCH_CHIP_STM32F103ZE is not set +# CONFIG_ARCH_CHIP_STM32F105VB is not set +# CONFIG_ARCH_CHIP_STM32F105RB is not set +# CONFIG_ARCH_CHIP_STM32F107VC is not set +# CONFIG_ARCH_CHIP_STM32F205RG is not set +# CONFIG_ARCH_CHIP_STM32F207IG is not set +# CONFIG_ARCH_CHIP_STM32F207ZE is not set +# CONFIG_ARCH_CHIP_STM32F302K6 is not set +# CONFIG_ARCH_CHIP_STM32F302K8 is not set +# CONFIG_ARCH_CHIP_STM32F302CB is not set +# CONFIG_ARCH_CHIP_STM32F302CC is not set +# CONFIG_ARCH_CHIP_STM32F302RB is not set +# CONFIG_ARCH_CHIP_STM32F302RC is not set +# CONFIG_ARCH_CHIP_STM32F302VB is not set +# CONFIG_ARCH_CHIP_STM32F302VC is not set +# CONFIG_ARCH_CHIP_STM32F303K6 is not set +# CONFIG_ARCH_CHIP_STM32F303K8 is not set +# CONFIG_ARCH_CHIP_STM32F303C6 is not set +# CONFIG_ARCH_CHIP_STM32F303C8 is not set +# CONFIG_ARCH_CHIP_STM32F303CB is not set +# CONFIG_ARCH_CHIP_STM32F303CC is not set +# CONFIG_ARCH_CHIP_STM32F303RB is not set +# CONFIG_ARCH_CHIP_STM32F303RC is not set +# CONFIG_ARCH_CHIP_STM32F303RD is not set +# CONFIG_ARCH_CHIP_STM32F303RE is not set +# CONFIG_ARCH_CHIP_STM32F303VB is not set +# CONFIG_ARCH_CHIP_STM32F303VC is not set +# CONFIG_ARCH_CHIP_STM32F372C8 is not set +# CONFIG_ARCH_CHIP_STM32F372R8 is not set +# CONFIG_ARCH_CHIP_STM32F372V8 is not set +# CONFIG_ARCH_CHIP_STM32F372CB is not set +# CONFIG_ARCH_CHIP_STM32F372RB is not set +# CONFIG_ARCH_CHIP_STM32F372VB is not set +# CONFIG_ARCH_CHIP_STM32F372CC is not set +# CONFIG_ARCH_CHIP_STM32F372RC is not set +# CONFIG_ARCH_CHIP_STM32F372VC is not set +# CONFIG_ARCH_CHIP_STM32F373C8 is not set +# CONFIG_ARCH_CHIP_STM32F373R8 is not set +# CONFIG_ARCH_CHIP_STM32F373V8 is not set +# CONFIG_ARCH_CHIP_STM32F373CB is not set +# CONFIG_ARCH_CHIP_STM32F373RB is not set +# CONFIG_ARCH_CHIP_STM32F373VB is not set +# CONFIG_ARCH_CHIP_STM32F373CC is not set +# CONFIG_ARCH_CHIP_STM32F373RC is not set +# CONFIG_ARCH_CHIP_STM32F373VC is not set +# CONFIG_ARCH_CHIP_STM32F401RE is not set +# CONFIG_ARCH_CHIP_STM32F411RE is not set +# CONFIG_ARCH_CHIP_STM32F411VE is not set +# CONFIG_ARCH_CHIP_STM32F405RG is not set +# CONFIG_ARCH_CHIP_STM32F405VG is not set +# CONFIG_ARCH_CHIP_STM32F405ZG is not set +# CONFIG_ARCH_CHIP_STM32F407VE is not set +# CONFIG_ARCH_CHIP_STM32F407VG is not set +# CONFIG_ARCH_CHIP_STM32F407ZE is not set +# CONFIG_ARCH_CHIP_STM32F407ZG is not set +# CONFIG_ARCH_CHIP_STM32F407IE is not set +# CONFIG_ARCH_CHIP_STM32F407IG is not set +# CONFIG_ARCH_CHIP_STM32F427V is not set +# CONFIG_ARCH_CHIP_STM32F427Z is not set +# CONFIG_ARCH_CHIP_STM32F427I is not set +# CONFIG_ARCH_CHIP_STM32F429V is not set +# CONFIG_ARCH_CHIP_STM32F429Z is not set +# CONFIG_ARCH_CHIP_STM32F429I is not set +# CONFIG_ARCH_CHIP_STM32F429B is not set +# CONFIG_ARCH_CHIP_STM32F429N is not set +# CONFIG_ARCH_CHIP_STM32F446M is not set +# CONFIG_ARCH_CHIP_STM32F446R is not set +# CONFIG_ARCH_CHIP_STM32F446V is not set +# CONFIG_ARCH_CHIP_STM32F446Z is not set +# CONFIG_ARCH_CHIP_STM32F469A is not set +# CONFIG_ARCH_CHIP_STM32F469I is not set +# CONFIG_ARCH_CHIP_STM32F469B is not set +# CONFIG_ARCH_CHIP_STM32F469N is not set +CONFIG_STM32_FLASH_CONFIG_DEFAULT=y +# CONFIG_STM32_FLASH_CONFIG_4 is not set +# CONFIG_STM32_FLASH_CONFIG_6 is not set +# CONFIG_STM32_FLASH_CONFIG_8 is not set +# CONFIG_STM32_FLASH_CONFIG_B is not set +# CONFIG_STM32_FLASH_CONFIG_C is not set +# CONFIG_STM32_FLASH_CONFIG_D is not set +# CONFIG_STM32_FLASH_CONFIG_E is not set +# CONFIG_STM32_FLASH_CONFIG_F is not set +# CONFIG_STM32_FLASH_CONFIG_G is not set +# CONFIG_STM32_FLASH_CONFIG_I is not set +# CONFIG_STM32_STM32L15XX is not set +# CONFIG_STM32_ENERGYLITE is not set +CONFIG_STM32_STM32F10XX=y +# CONFIG_STM32_VALUELINE is not set +# CONFIG_STM32_CONNECTIVITYLINE is not set +CONFIG_STM32_PERFORMANCELINE=y +# CONFIG_STM32_USBACCESSLINE is not set +# CONFIG_STM32_HIGHDENSITY is not set +CONFIG_STM32_MEDIUMDENSITY=y +# CONFIG_STM32_LOWDENSITY is not set +# CONFIG_STM32_STM32F20XX is not set +# CONFIG_STM32_STM32F205 is not set +# CONFIG_STM32_STM32F207 is not set +# CONFIG_STM32_STM32F30XX is not set +# CONFIG_STM32_STM32F302 is not set +# CONFIG_STM32_STM32F303 is not set +# CONFIG_STM32_STM32F37XX is not set +# CONFIG_STM32_STM32F40XX is not set +# CONFIG_STM32_STM32F401 is not set +# CONFIG_STM32_STM32F411 is not set +# CONFIG_STM32_STM32F405 is not set +# CONFIG_STM32_STM32F407 is not set +# CONFIG_STM32_STM32F427 is not set +# CONFIG_STM32_STM32F429 is not set +# CONFIG_STM32_STM32F446 is not set +# CONFIG_STM32_STM32F469 is not set +# CONFIG_STM32_DFU is not set + +# +# STM32 Peripheral Support +# +# CONFIG_STM32_HAVE_CCM is not set +CONFIG_STM32_HAVE_USBDEV=y +# CONFIG_STM32_HAVE_OTGFS is not set +# CONFIG_STM32_HAVE_FSMC is not set +# CONFIG_STM32_HAVE_LTDC is not set +CONFIG_STM32_HAVE_USART3=y +CONFIG_STM32_HAVE_UART4=y +CONFIG_STM32_HAVE_UART5=y +# CONFIG_STM32_HAVE_USART6 is not set +# CONFIG_STM32_HAVE_UART7 is not set +# CONFIG_STM32_HAVE_UART8 is not set +CONFIG_STM32_HAVE_TIM1=y +# CONFIG_STM32_HAVE_TIM2 is not set +CONFIG_STM32_HAVE_TIM3=y +CONFIG_STM32_HAVE_TIM4=y +CONFIG_STM32_HAVE_TIM5=y +CONFIG_STM32_HAVE_TIM6=y +CONFIG_STM32_HAVE_TIM7=y +CONFIG_STM32_HAVE_TIM8=y +# CONFIG_STM32_HAVE_TIM9 is not set +# CONFIG_STM32_HAVE_TIM10 is not set +# CONFIG_STM32_HAVE_TIM11 is not set +# CONFIG_STM32_HAVE_TIM12 is not set +# CONFIG_STM32_HAVE_TIM13 is not set +# CONFIG_STM32_HAVE_TIM14 is not set +# CONFIG_STM32_HAVE_TIM15 is not set +# CONFIG_STM32_HAVE_TIM16 is not set +# CONFIG_STM32_HAVE_TIM17 is not set +CONFIG_STM32_HAVE_ADC2=y +CONFIG_STM32_HAVE_ADC3=y +# CONFIG_STM32_HAVE_ADC4 is not set +# CONFIG_STM32_HAVE_ADC1_DMA is not set +# CONFIG_STM32_HAVE_ADC2_DMA is not set +# CONFIG_STM32_HAVE_ADC3_DMA is not set +# CONFIG_STM32_HAVE_ADC4_DMA is not set +# CONFIG_STM32_HAVE_SDADC1 is not set +# CONFIG_STM32_HAVE_SDADC2 is not set +# CONFIG_STM32_HAVE_SDADC3 is not set +# CONFIG_STM32_HAVE_SDADC1_DMA is not set +# CONFIG_STM32_HAVE_SDADC2_DMA is not set +# CONFIG_STM32_HAVE_SDADC3_DMA is not set +CONFIG_STM32_HAVE_CAN1=y +# CONFIG_STM32_HAVE_CAN2 is not set +# CONFIG_STM32_HAVE_DAC1 is not set +# CONFIG_STM32_HAVE_DAC2 is not set +# CONFIG_STM32_HAVE_RNG is not set +# CONFIG_STM32_HAVE_ETHMAC is not set +CONFIG_STM32_HAVE_I2C2=y +# CONFIG_STM32_HAVE_I2C3 is not set +CONFIG_STM32_HAVE_SPI2=y +CONFIG_STM32_HAVE_SPI3=y +# CONFIG_STM32_HAVE_SPI4 is not set +# CONFIG_STM32_HAVE_SPI5 is not set +# CONFIG_STM32_HAVE_SPI6 is not set +# CONFIG_STM32_HAVE_SAIPLL is not set +# CONFIG_STM32_HAVE_I2SPLL is not set +# CONFIG_STM32_ADC1 is not set +# CONFIG_STM32_ADC2 is not set +# CONFIG_STM32_ADC3 is not set +# CONFIG_STM32_BKP is not set +# CONFIG_STM32_CAN1 is not set +# CONFIG_STM32_CRC is not set +# CONFIG_STM32_DMA1 is not set +# CONFIG_STM32_DMA2 is not set +CONFIG_STM32_I2C1=y +# CONFIG_STM32_I2C2 is not set +# CONFIG_STM32_PWR is not set +# CONFIG_STM32_SDIO is not set +# CONFIG_STM32_SPI1 is not set +# CONFIG_STM32_SPI2 is not set +# CONFIG_STM32_SPI3 is not set +# CONFIG_STM32_TIM1 is not set +# CONFIG_STM32_TIM2 is not set +# CONFIG_STM32_TIM3 is not set +# CONFIG_STM32_TIM4 is not set +# CONFIG_STM32_TIM5 is not set +# CONFIG_STM32_TIM6 is not set +# CONFIG_STM32_TIM7 is not set +# CONFIG_STM32_TIM8 is not set +CONFIG_STM32_USART1=y +# CONFIG_STM32_USART2 is not set +# CONFIG_STM32_USART3 is not set +# CONFIG_STM32_UART4 is not set +# CONFIG_STM32_UART5 is not set +# CONFIG_STM32_USB is not set +# CONFIG_STM32_IWDG is not set +# CONFIG_STM32_WWDG is not set +CONFIG_STM32_I2C=y +# CONFIG_STM32_NOEXT_VECTORS is not set + +# +# Alternate Pin Mapping +# +# CONFIG_STM32_I2C1_REMAP is not set +# CONFIG_STM32_USART1_REMAP is not set +# CONFIG_STM32_JTAG_DISABLE is not set +# CONFIG_STM32_JTAG_FULL_ENABLE is not set +# CONFIG_STM32_JTAG_NOJNTRST_ENABLE is not set +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG=y +# CONFIG_STM32_FORCEPOWER is not set +# CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set + +# +# Timer Configuration +# +# CONFIG_STM32_ONESHOT is not set +# CONFIG_STM32_FREERUN is not set +# CONFIG_STM32_TIM1_CAP is not set +# CONFIG_STM32_TIM3_CAP is not set +# CONFIG_STM32_TIM4_CAP is not set +# CONFIG_STM32_TIM5_CAP is not set +# CONFIG_STM32_TIM8_CAP is not set +CONFIG_STM32_USART=y +CONFIG_STM32_SERIALDRIVER=y + +# +# U[S]ART Configuration +# + +# +# U[S]ART Device Configuration +# +CONFIG_STM32_USART1_SERIALDRIVER=y +# CONFIG_STM32_USART1_1WIREDRIVER is not set +# CONFIG_USART1_RS485 is not set + +# +# Serial Driver Configuration +# +# CONFIG_SERIAL_DISABLE_REORDERING is not set +# CONFIG_STM32_FLOWCONTROL_BROKEN is not set +# CONFIG_STM32_USART_BREAKS is not set +# CONFIG_STM32_USART_SINGLEWIRE is not set + +# +# I2C Configuration +# +CONFIG_STM32_I2C_ALT=y +# CONFIG_STM32_I2C_DYNTIMEO is not set +CONFIG_STM32_I2CTIMEOSEC=0 +CONFIG_STM32_I2CTIMEOMS=500 +CONFIG_STM32_I2CTIMEOTICKS=500 +# CONFIG_STM32_I2C_DUTY16_9 is not set +CONFIG_STM32_HAVE_RTC_COUNTER=y +# CONFIG_STM32_HAVE_RTC_SUBSECONDS is not set + +# +# USB FS Host Configuration +# + +# +# USB HS Host Configuration +# + +# +# USB Host Debug Configuration +# + +# +# USB Device Configuration +# + +# +# Architecture Options +# +# CONFIG_ARCH_NOINTC is not set +# CONFIG_ARCH_VECNOTIRQ is not set +# CONFIG_ARCH_DMA is not set +CONFIG_ARCH_HAVE_IRQPRIO=y +# CONFIG_ARCH_L2CACHE is not set +# CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set +# CONFIG_ARCH_HAVE_ADDRENV is not set +# CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set +# CONFIG_ARCH_HAVE_MULTICPU is not set +CONFIG_ARCH_HAVE_VFORK=y +# CONFIG_ARCH_HAVE_MMU is not set +CONFIG_ARCH_HAVE_MPU=y +# CONFIG_ARCH_NAND_HWECC is not set +# CONFIG_ARCH_HAVE_EXTCLK is not set +# CONFIG_ARCH_HAVE_POWEROFF is not set +CONFIG_ARCH_HAVE_RESET=y +# CONFIG_ARCH_USE_MPU is not set +# CONFIG_ARCH_IRQPRIO is not set +CONFIG_ARCH_STACKDUMP=y +# CONFIG_ENDIAN_BIG is not set +# CONFIG_ARCH_IDLE_CUSTOM is not set +# CONFIG_ARCH_HAVE_RAMFUNCS is not set +CONFIG_ARCH_HAVE_RAMVECTORS=y +# CONFIG_ARCH_RAMVECTORS is not set + +# +# Board Settings +# +CONFIG_BOARD_LOOPSPERMSEC=5483 +# CONFIG_ARCH_CALIBRATION is not set + +# +# Interrupt options +# +CONFIG_ARCH_HAVE_INTERRUPTSTACK=y +CONFIG_ARCH_INTERRUPTSTACK=0 +CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y +# CONFIG_ARCH_HIPRI_INTERRUPT is not set + +# +# Boot options +# +# CONFIG_BOOT_RUNFROMEXTSRAM is not set +CONFIG_BOOT_RUNFROMFLASH=y +# CONFIG_BOOT_RUNFROMISRAM is not set +# CONFIG_BOOT_RUNFROMSDRAM is not set +# CONFIG_BOOT_COPYTORAM is not set + +# +# Boot Memory Configuration +# +CONFIG_RAM_START=0x20000000 +CONFIG_RAM_SIZE=20480 +# CONFIG_ARCH_HAVE_SDRAM is not set + +# +# Board Selection +# +# CONFIG_ARCH_BOARD_STM32_TINY is not set +CONFIG_ARCH_BOARD_STM32F103_MINIMUM=y +# CONFIG_ARCH_BOARD_CUSTOM is not set +CONFIG_ARCH_BOARD="stm32f103-minimum" + +# +# Common Board Options +# +CONFIG_ARCH_HAVE_LEDS=y +CONFIG_ARCH_LEDS=y +CONFIG_ARCH_HAVE_BUTTONS=y +# CONFIG_ARCH_BUTTONS is not set +CONFIG_ARCH_HAVE_IRQBUTTONS=y + +# +# Board-Specific Options +# +# CONFIG_BOARD_CRASHDUMP is not set +CONFIG_LIB_BOARDCTL=y +# CONFIG_BOARDCTL_RESET is not set +# CONFIG_BOARDCTL_UNIQUEID is not set +# CONFIG_BOARDCTL_TSCTEST is not set +# CONFIG_BOARDCTL_ADCTEST is not set +# CONFIG_BOARDCTL_PWMTEST is not set +# CONFIG_BOARDCTL_GRAPHICS is not set +# CONFIG_BOARDCTL_IOCTL is not set + +# +# RTOS Features +# +# CONFIG_DISABLE_OS_API is not set + +# +# Clocks and Timers +# +CONFIG_ARCH_HAVE_TICKLESS=y +# CONFIG_SCHED_TICKLESS is not set +CONFIG_USEC_PER_TICK=10000 +# CONFIG_SYSTEM_TIME64 is not set +# CONFIG_CLOCK_MONOTONIC is not set +CONFIG_ARCH_HAVE_TIMEKEEPING=y +# CONFIG_JULIAN_TIME is not set +CONFIG_START_YEAR=2011 +CONFIG_START_MONTH=7 +CONFIG_START_DAY=5 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_PREALLOC_WDOGS=4 +CONFIG_WDOG_INTRESERVE=0 +CONFIG_PREALLOC_TIMERS=4 + +# +# Tasks and Scheduling +# +# CONFIG_INIT_NONE is not set +CONFIG_INIT_ENTRYPOINT=y +# CONFIG_INIT_FILEPATH is not set +CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_RR_INTERVAL=200 +# CONFIG_SCHED_SPORADIC is not set +CONFIG_TASK_NAME_SIZE=0 +CONFIG_MAX_TASKS=16 +# CONFIG_SCHED_HAVE_PARENT is not set +CONFIG_SCHED_WAITPID=y + +# +# Pthread Options +# +# CONFIG_MUTEX_TYPES is not set +CONFIG_NPTHREAD_KEYS=4 + +# +# Performance Monitoring +# +# CONFIG_SCHED_CPULOAD is not set +# CONFIG_SCHED_INSTRUMENTATION is not set + +# +# Files and I/O +# +CONFIG_DEV_CONSOLE=y +# CONFIG_FDCLONE_DISABLE is not set +# CONFIG_FDCLONE_STDIO is not set +CONFIG_SDCLONE_DISABLE=y +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NAME_MAX=32 +# CONFIG_PRIORITY_INHERITANCE is not set + +# +# RTOS hooks +# +CONFIG_BOARD_INITIALIZE=y +# CONFIG_BOARD_INITTHREAD is not set +# CONFIG_SCHED_STARTHOOK is not set +# CONFIG_SCHED_ATEXIT is not set +# CONFIG_SCHED_ONEXIT is not set +# CONFIG_SIG_EVTHREAD is not set + +# +# Signal Numbers +# +CONFIG_SIG_SIGUSR1=1 +CONFIG_SIG_SIGUSR2=2 +CONFIG_SIG_SIGALARM=3 +CONFIG_SIG_SIGCONDTIMEDOUT=16 +CONFIG_SIG_SIGWORK=17 + +# +# POSIX Message Queue Options +# +CONFIG_PREALLOC_MQ_MSGS=4 +CONFIG_MQ_MAXMSGSIZE=32 +# CONFIG_MODULE is not set + +# +# Work queue support +# +CONFIG_SCHED_WORKQUEUE=y +CONFIG_SCHED_HPWORK=y +CONFIG_SCHED_HPWORKPRIORITY=192 +CONFIG_SCHED_HPWORKPERIOD=50000 +CONFIG_SCHED_HPWORKSTACKSIZE=2048 +# CONFIG_SCHED_LPWORK is not set + +# +# Stack and heap information +# +CONFIG_IDLETHREAD_STACKSIZE=1024 +CONFIG_USERMAIN_STACKSIZE=2048 +CONFIG_PTHREAD_STACK_MIN=256 +CONFIG_PTHREAD_STACK_DEFAULT=2048 +# CONFIG_LIB_SYSCALL is not set + +# +# Device Drivers +# +# CONFIG_DISABLE_POLL is not set +CONFIG_DEV_NULL=y +# CONFIG_DEV_ZERO is not set +# CONFIG_DEV_URANDOM is not set +# CONFIG_DEV_LOOP is not set + +# +# Buffering +# +# CONFIG_DRVR_WRITEBUFFER is not set +# CONFIG_DRVR_READAHEAD is not set +# CONFIG_RAMDISK is not set +# CONFIG_CAN is not set +# CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set +# CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set +# CONFIG_PWM is not set +CONFIG_ARCH_HAVE_I2CRESET=y +CONFIG_I2C=y +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_POLLED is not set +# CONFIG_I2C_RESET is not set +# CONFIG_I2C_TRACE is not set +# CONFIG_I2C_DRIVER is not set +# CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +CONFIG_ARCH_HAVE_SPI_BITORDER=y +# CONFIG_I2S is not set + +# +# Timer Driver Support +# +# CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set +# CONFIG_RTC is not set +# CONFIG_WATCHDOG is not set +# CONFIG_TIMERS_CS2100CP is not set +# CONFIG_ANALOG is not set +# CONFIG_AUDIO_DEVICES is not set +# CONFIG_VIDEO_DEVICES is not set +# CONFIG_BCH is not set +# CONFIG_INPUT is not set + +# +# IO Expander/GPIO Support +# +# CONFIG_IOEXPANDER is not set +# CONFIG_DEV_GPIO is not set + +# +# LCD Driver Support +# +# CONFIG_LCD is not set +# CONFIG_SLCD is not set + +# +# LED Support +# +# CONFIG_USERLED is not set +# CONFIG_RGBLED is not set +# CONFIG_PCA9635PW is not set +# CONFIG_NCP5623C is not set +# CONFIG_MMCSD is not set +# CONFIG_MODEM is not set +# CONFIG_MTD is not set +# CONFIG_EEPROM is not set +# CONFIG_PIPES is not set +# CONFIG_PM is not set +# CONFIG_POWER is not set +CONFIG_SENSORS=y +# CONFIG_AS5048B is not set +# CONFIG_BH1750FVI is not set +# CONFIG_BMG160 is not set +# CONFIG_BMP180 is not set +# CONFIG_SENSOR_KXTJ9 is not set +# CONFIG_LIS3DSH is not set +# CONFIG_LIS331DL is not set +# CONFIG_SN_LSM9DS1 is not set +# CONFIG_MB7040 is not set +# CONFIG_MLX90393 is not set +# CONFIG_MCP9844 is not set +# CONFIG_MS58XX is not set +CONFIG_MS58XX_VDD=30 +# CONFIG_MPL115A is not set +# CONFIG_SENSORS_ADXL345 is not set +# CONFIG_MAX31855 is not set +# CONFIG_MAX6675 is not set +# CONFIG_LIS3MDL is not set +# CONFIG_LM75 is not set +# CONFIG_LM92 is not set +# CONFIG_QENCODER is not set +CONFIG_VEML6070=y +# CONFIG_XEN1210 is not set +# CONFIG_ZEROCROSS is not set +# CONFIG_SERCOMM_CONSOLE is not set +CONFIG_SERIAL=y +# CONFIG_DEV_LOWCONSOLE is not set +# CONFIG_SERIAL_REMOVABLE is not set +CONFIG_SERIAL_CONSOLE=y +# CONFIG_16550_UART is not set +# CONFIG_UART_SERIALDRIVER is not set +# CONFIG_UART0_SERIALDRIVER is not set +# CONFIG_UART1_SERIALDRIVER is not set +# CONFIG_UART2_SERIALDRIVER is not set +# CONFIG_UART3_SERIALDRIVER is not set +# CONFIG_UART4_SERIALDRIVER is not set +# CONFIG_UART5_SERIALDRIVER is not set +# CONFIG_UART6_SERIALDRIVER is not set +# CONFIG_UART7_SERIALDRIVER is not set +# CONFIG_UART8_SERIALDRIVER is not set +# CONFIG_SCI0_SERIALDRIVER is not set +# CONFIG_SCI1_SERIALDRIVER is not set +# CONFIG_USART0_SERIALDRIVER is not set +CONFIG_USART1_SERIALDRIVER=y +# CONFIG_USART2_SERIALDRIVER is not set +# CONFIG_USART3_SERIALDRIVER is not set +# CONFIG_USART4_SERIALDRIVER is not set +# CONFIG_USART5_SERIALDRIVER is not set +# CONFIG_USART6_SERIALDRIVER is not set +# CONFIG_USART7_SERIALDRIVER is not set +# CONFIG_USART8_SERIALDRIVER is not set +# CONFIG_OTHER_UART_SERIALDRIVER is not set +CONFIG_MCU_SERIAL=y +CONFIG_STANDARD_SERIAL=y +CONFIG_SERIAL_NPOLLWAITERS=2 +# CONFIG_SERIAL_IFLOWCONTROL is not set +# CONFIG_SERIAL_OFLOWCONTROL is not set +# CONFIG_SERIAL_DMA is not set +# CONFIG_SERIAL_TIOCSERGSTRUCT is not set +CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y +CONFIG_USART1_SERIAL_CONSOLE=y +# CONFIG_OTHER_SERIAL_CONSOLE is not set +# CONFIG_NO_SERIAL_CONSOLE is not set + +# +# USART1 Configuration +# +CONFIG_USART1_RXBUFSIZE=256 +CONFIG_USART1_TXBUFSIZE=256 +CONFIG_USART1_BAUD=115200 +CONFIG_USART1_BITS=8 +CONFIG_USART1_PARITY=0 +CONFIG_USART1_2STOP=0 +# CONFIG_USART1_IFLOWCONTROL is not set +# CONFIG_USART1_OFLOWCONTROL is not set +# CONFIG_USART1_DMA is not set +# CONFIG_PSEUDOTERM is not set +# CONFIG_USBDEV is not set +# CONFIG_USBHOST is not set +# CONFIG_HAVE_USBTRACE is not set +# CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set + +# +# System Logging +# +# CONFIG_ARCH_SYSLOG is not set +# CONFIG_RAMLOG is not set +# CONFIG_SYSLOG_INTBUFFER is not set +# CONFIG_SYSLOG_TIMESTAMP is not set +CONFIG_SYSLOG_SERIAL_CONSOLE=y +# CONFIG_SYSLOG_CHAR is not set +CONFIG_SYSLOG_CONSOLE=y +# CONFIG_SYSLOG_NONE is not set +# CONFIG_SYSLOG_FILE is not set +# CONFIG_SYSLOG_CHARDEV is not set + +# +# Networking Support +# +# CONFIG_ARCH_HAVE_NET is not set +# CONFIG_ARCH_HAVE_PHY is not set +# CONFIG_NET is not set + +# +# Crypto API +# +# CONFIG_CRYPTO is not set + +# +# File Systems +# + +# +# File system configuration +# +# CONFIG_DISABLE_MOUNTPOINT is not set +# CONFIG_FS_AUTOMOUNTER is not set +CONFIG_DISABLE_PSEUDOFS_OPERATIONS=y +# CONFIG_FS_READABLE is not set +# CONFIG_FS_WRITABLE is not set +# CONFIG_FS_NAMED_SEMAPHORES is not set +CONFIG_FS_MQUEUE_MPATH="/var/mqueue" +# CONFIG_FS_RAMMAP is not set +# CONFIG_FS_FAT is not set +# CONFIG_FS_NXFFS is not set +# CONFIG_FS_ROMFS is not set +# CONFIG_FS_TMPFS is not set +# CONFIG_FS_SMARTFS is not set +# CONFIG_FS_BINFS is not set +# CONFIG_FS_PROCFS is not set +# CONFIG_FS_UNIONFS is not set + +# +# Graphics Support +# +# CONFIG_NX is not set + +# +# Memory Management +# +# CONFIG_MM_SMALL is not set +CONFIG_MM_REGIONS=1 +# CONFIG_ARCH_HAVE_HEAP2 is not set +# CONFIG_GRAN is not set + +# +# Audio Support +# +# CONFIG_AUDIO is not set + +# +# Wireless Support +# + +# +# Binary Loader +# +# CONFIG_BINFMT_DISABLE is not set +# CONFIG_BINFMT_EXEPATH is not set +# CONFIG_NXFLAT is not set +# CONFIG_ELF is not set +CONFIG_BUILTIN=y +# CONFIG_PIC is not set +CONFIG_SYMTAB_ORDEREDBYNAME=y + +# +# Library Routines +# + +# +# Standard C Library Options +# +CONFIG_STDIO_BUFFER_SIZE=64 +CONFIG_STDIO_LINEBUFFER=y +CONFIG_NUNGET_CHARS=2 +CONFIG_LIB_HOMEDIR="/" +# CONFIG_LIBM is not set +# CONFIG_NOPRINTF_FIELDWIDTH is not set +# CONFIG_LIBC_FLOATINGPOINT is not set +# CONFIG_LIBC_LONG_LONG is not set +# CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set +CONFIG_LIB_RAND_ORDER=1 +# CONFIG_EOL_IS_CR is not set +# CONFIG_EOL_IS_LF is not set +# CONFIG_EOL_IS_BOTH_CRLF is not set +CONFIG_EOL_IS_EITHER_CRLF=y +# CONFIG_LIBC_EXECFUNCS is not set +CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 +CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 +# CONFIG_LIBC_STRERROR is not set +# CONFIG_LIBC_PERROR_STDOUT is not set +CONFIG_ARCH_LOWPUTC=y +# CONFIG_LIBC_LOCALTIME is not set +# CONFIG_TIME_EXTENDED is not set +CONFIG_LIB_SENDFILE_BUFSIZE=512 +# CONFIG_ARCH_ROMGETC is not set +# CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set +CONFIG_ARCH_HAVE_TLS=y +# CONFIG_TLS is not set +# CONFIG_LIBC_NETDB is not set + +# +# Non-standard Library Support +# +# CONFIG_LIB_CRC64_FAST is not set +# CONFIG_LIB_KBDCODEC is not set +# CONFIG_LIB_SLCDCODEC is not set +# CONFIG_LIB_HEX2BIN is not set + +# +# Basic CXX Support +# +# CONFIG_C99_BOOL8 is not set +# CONFIG_HAVE_CXX is not set + +# +# Application Configuration +# + +# +# Built-In Applications +# +CONFIG_BUILTIN_PROXY_STACKSIZE=1024 + +# +# CAN Utilities +# + +# +# Examples +# +# CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set +# CONFIG_EXAMPLES_CHAT is not set +# CONFIG_EXAMPLES_CONFIGDATA is not set +# CONFIG_EXAMPLES_DHCPD is not set +# CONFIG_EXAMPLES_ELF is not set +# CONFIG_EXAMPLES_FTPC is not set +# CONFIG_EXAMPLES_FTPD is not set +# CONFIG_EXAMPLES_HELLO is not set +# CONFIG_EXAMPLES_HIDKBD is not set +# CONFIG_EXAMPLES_IGMP is not set +# CONFIG_EXAMPLES_JSON is not set +# CONFIG_EXAMPLES_KEYPADTEST is not set +# CONFIG_EXAMPLES_MEDIA is not set +# CONFIG_EXAMPLES_MM is not set +# CONFIG_EXAMPLES_MODBUS is not set +# CONFIG_EXAMPLES_MOUNT is not set +# CONFIG_EXAMPLES_NRF24L01TERM is not set +CONFIG_EXAMPLES_NSH=y +# CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NXFFS is not set +# CONFIG_EXAMPLES_NXHELLO is not set +# CONFIG_EXAMPLES_NXIMAGE is not set +# CONFIG_EXAMPLES_NX is not set +# CONFIG_EXAMPLES_NXLINES is not set +# CONFIG_EXAMPLES_NXTERM is not set +# CONFIG_EXAMPLES_NXTEXT is not set +# CONFIG_EXAMPLES_OSTEST is not set +# CONFIG_EXAMPLES_PCA9635 is not set +# CONFIG_EXAMPLES_POSIXSPAWN is not set +# CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set +# CONFIG_EXAMPLES_RGBLED is not set +# CONFIG_EXAMPLES_RGMP is not set +# CONFIG_EXAMPLES_SENDMAIL is not set +# CONFIG_EXAMPLES_SERIALBLASTER is not set +# CONFIG_EXAMPLES_SERIALRX is not set +# CONFIG_EXAMPLES_SERLOOP is not set +# CONFIG_EXAMPLES_SLCD is not set +# CONFIG_EXAMPLES_SMART is not set +# CONFIG_EXAMPLES_SMART_TEST is not set +# CONFIG_EXAMPLES_SMP is not set +# CONFIG_EXAMPLES_TCPECHO is not set +# CONFIG_EXAMPLES_TELNETD is not set +# CONFIG_EXAMPLES_TIFF is not set +# CONFIG_EXAMPLES_TOUCHSCREEN is not set +# CONFIG_EXAMPLES_USBSERIAL is not set +# CONFIG_EXAMPLES_USBTERM is not set +# CONFIG_EXAMPLES_WATCHDOG is not set +# CONFIG_EXAMPLES_WEBSERVER is not set + +# +# File System Utilities +# +# CONFIG_FSUTILS_INIFILE is not set + +# +# GPS Utilities +# +# CONFIG_GPSUTILS_MINMEA_LIB is not set + +# +# Graphics Support +# +# CONFIG_TIFF is not set +# CONFIG_GRAPHICS_TRAVELER is not set + +# +# Interpreters +# +# CONFIG_INTERPRETERS_FICL is not set +# CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set +# CONFIG_INTERPRETERS_PCODE is not set + +# +# FreeModBus +# +# CONFIG_MODBUS is not set + +# +# Network Utilities +# +# CONFIG_NETUTILS_CHAT is not set +# CONFIG_NETUTILS_CODECS is not set +# CONFIG_NETUTILS_ESP8266 is not set +# CONFIG_NETUTILS_FTPC is not set +# CONFIG_NETUTILS_JSON is not set +# CONFIG_NETUTILS_SMTP is not set + +# +# NSH Library +# +CONFIG_NSH_LIBRARY=y +# CONFIG_NSH_MOTD is not set + +# +# Command Line Configuration +# +CONFIG_NSH_READLINE=y +# CONFIG_NSH_CLE is not set +CONFIG_NSH_LINELEN=80 +CONFIG_NSH_DISABLE_SEMICOLON=y +# CONFIG_NSH_CMDPARMS is not set +CONFIG_NSH_MAXARGUMENTS=6 +# CONFIG_NSH_ARGCAT is not set +CONFIG_NSH_NESTDEPTH=3 +CONFIG_NSH_DISABLEBG=y +CONFIG_NSH_BUILTIN_APPS=y + +# +# Disable Individual commands +# +CONFIG_NSH_DISABLE_ADDROUTE=y +CONFIG_NSH_DISABLE_BASENAME=y +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +CONFIG_NSH_DISABLE_CMP=y +CONFIG_NSH_DISABLE_DATE=y +# CONFIG_NSH_DISABLE_DD is not set +CONFIG_NSH_DISABLE_DF=y +CONFIG_NSH_DISABLE_DELROUTE=y +CONFIG_NSH_DISABLE_DIRNAME=y +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +CONFIG_NSH_DISABLE_IFCONFIG=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +# CONFIG_NSH_DISABLE_KILL is not set +CONFIG_NSH_DISABLE_LOSETUP=y +CONFIG_NSH_DISABLE_LOSMART=y +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MB is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKRD is not set +# CONFIG_NSH_DISABLE_MH is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y +# CONFIG_NSH_DISABLE_PS is not set +# CONFIG_NSH_DISABLE_PUT is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SH is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +CONFIG_NSH_DISABLE_TIME=y +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +CONFIG_NSH_DISABLE_UNAME=y +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_NSH_DISABLE_WGET is not set +# CONFIG_NSH_DISABLE_XD is not set +CONFIG_NSH_MMCSDMINOR=0 + +# +# Configure Command Options +# +CONFIG_NSH_CODECS_BUFSIZE=128 +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +CONFIG_NSH_FILEIOSIZE=1024 + +# +# Scripting Support +# +# CONFIG_NSH_DISABLESCRIPT is not set +CONFIG_NSH_DISABLE_ITEF=y +CONFIG_NSH_DISABLE_LOOPS=y + +# +# Console Configuration +# +CONFIG_NSH_CONSOLE=y +# CONFIG_NSH_ALTCONDEV is not set +CONFIG_NSH_ARCHINIT=y +# CONFIG_NSH_LOGIN is not set +# CONFIG_NSH_CONSOLE_LOGIN is not set + +# +# NxWidgets/NxWM +# + +# +# Platform-specific Support +# +# CONFIG_PLATFORM_CONFIGDATA is not set + +# +# System Libraries and NSH Add-Ons +# +# CONFIG_SYSTEM_CLE is not set +# CONFIG_SYSTEM_CUTERM is not set +# CONFIG_SYSTEM_FREE is not set +# CONFIG_SYSTEM_HEX2BIN is not set +# CONFIG_SYSTEM_HEXED is not set +# CONFIG_SYSTEM_I2CTOOL is not set +# CONFIG_SYSTEM_INSTALL is not set +# CONFIG_SYSTEM_RAMTEST is not set +CONFIG_READLINE_HAVE_EXTMATCH=y +CONFIG_SYSTEM_READLINE=y +CONFIG_READLINE_ECHO=y +# CONFIG_READLINE_TABCOMPLETION is not set +# CONFIG_READLINE_CMD_HISTORY is not set +# CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_SYSTEM is not set +# CONFIG_SYSTEM_TEE is not set +# CONFIG_SYSTEM_UBLOXMODEM is not set +# CONFIG_SYSTEM_VI is not set +# CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/stm32f103-minimum/veml6070/setenv.sh b/configs/stm32f103-minimum/veml6070/setenv.sh new file mode 100644 index 0000000000..efcbfee142 --- /dev/null +++ b/configs/stm32f103-minimum/veml6070/setenv.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# configs//stm32f103-minimum/veml6070/setenv.sh +# +# Copyright (C) 2016 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. +# + +# 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. +# + +if [ "$_" = "$0" ] ; then + echo "You must source this script, not run it!" 1>&2 + exit 1 +fi + +WD=`pwd` +if [ ! -x "setenv.sh" ]; then + echo "This script must be executed from the top-level NuttX build directory" + exit 1 +fi + +if [ -z "${PATH_ORIG}" ]; then + export PATH_ORIG="${PATH}" +fi + +# This is the Cygwin path to the location where I installed the CodeSourcery +# toolchain under windows. You will also have to edit this if you install +# the CodeSourcery toolchain in any other location +#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery G++ Lite/bin" +#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_EABI/bin" +# export TOOLCHAIN_BIN="/cygdrive/c/Users/MyName/MentorGraphics/Sourcery_CodeBench_Lite_for_ARM_EABI/bin" + +# This is the location where I installed the ARM "GNU Tools for ARM Embedded Processors" +# You can this free toolchain here https://launchpad.net/gcc-arm-embedded +export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/GNU Tools ARM Embedded/4.9 2015q2/bin" + +# This is the path to the location where I installed the devkitARM toolchain +# You can get this free toolchain from http://devkitpro.org/ or http://sourceforge.net/projects/devkitpro/ +#export TOOLCHAIN_BIN="/cygdrive/c/Program Files (x86)/devkitARM/bin" + +# This is the Cygwin path to the location where I build the buildroot +# toolchain. +# export TOOLCHAIN_BIN="${WD}/../buildroot/build_arm_nofpu/staging_dir/bin" + +# Add the path to the toolchain to the PATH varialble +export PATH="${TOOLCHAIN_BIN}:/sbin:/usr/sbin:${PATH_ORIG}" + +echo "PATH : ${PATH}" diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 3b852a1cd4..d43362eb6c 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -234,6 +234,13 @@ config QENCODER bool "Qencoder" default n +config VEML6070 + bool "Vishay VEML6070 UV-A Light Sensor support" + default n + select I2C + ---help--- + Enable driver support for the Vishay VEML6070 UV-A light sensor. + config XEN1210 bool "Sensixs XEN1210 Magnetometer" default n diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs index 9c2bce29e8..4a21504281 100644 --- a/drivers/sensors/Make.defs +++ b/drivers/sensors/Make.defs @@ -138,6 +138,12 @@ ifeq ($(CONFIG_QENCODER),y) CSRCS += qencoder.c endif +# Vishay VEML6070 + +ifeq ($(CONFIG_VEML6070),y) + CSRCS += veml6070.c +endif + # Sensixs XEN1210 ifeq ($(CONFIG_XEN1210),y) diff --git a/drivers/sensors/veml6070.c b/drivers/sensors/veml6070.c new file mode 100644 index 0000000000..28030ba7ce --- /dev/null +++ b/drivers/sensors/veml6070.c @@ -0,0 +1,352 @@ +/**************************************************************************** + * drivers/sensors/veml6070.c + * Character driver for the Vishay UV-A Light Sensor VEML6070 + * + * Copyright (C) 2016 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_VEML6070) + +/**************************************************************************** + * Pre-process Definitions + ****************************************************************************/ + +#ifndef CONFIG_VEML6070_I2C_FREQUENCY +# define CONFIG_VEML6070_I2C_FREQUENCY 100000 +#endif + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct veml6070_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* I2C Helpers */ + +static int veml6070_read8(FAR struct veml6070_dev_s *priv, int offset, + FAR uint8_t *regval); +static int veml6070_write8(FAR struct veml6070_dev_s *priv, + uint8_t regval); + +/* Character driver methods */ + +static int veml6070_open(FAR struct file *filep); +static int veml6070_close(FAR struct file *filep); +static ssize_t veml6070_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t veml6070_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_veml6070_fops = +{ + veml6070_open, /* open */ + veml6070_close, /* close */ + veml6070_read, /* read */ + veml6070_write, /* write */ + NULL, /* seek */ + NULL /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + , NULL /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + , NULL /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: veml6070_read8 + * + * Description: + * Read 8-bit register + * + ****************************************************************************/ + +static int veml6070_read8(FAR struct veml6070_dev_s *priv, int offset, + FAR uint8_t *regval) +{ + struct i2c_config_s config; + uint8_t data[1]; + int ret = -1; + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_VEML6070_I2C_FREQUENCY; + config.address = priv->addr + offset; + config.addrlen = 7; + + /* Read 8-bits from the device */ + + ret = i2c_read(priv->i2c, &config, data, 1); + if (ret < 0) + { + snerr ("i2c_read failed: %d\n", ret); + return ret; + } + + /* Copy the content of the buffer to the location of the uint8_t pointer */ + + *regval = data[0]; + + sninfo("value: %08x ret: %d\n", *regval, ret); + return OK; +} + +/**************************************************************************** + * Name: veml6070_write8 + * + * Description: + * Write from an 8-bit register + * + ****************************************************************************/ + +static int veml6070_write8(FAR struct veml6070_dev_s *priv, uint8_t regval) +{ + struct i2c_config_s config; + int ret; + + sninfo("value: %02x\n", regval); + + /* Set up the I2C configuration */ + + config.frequency = CONFIG_VEML6070_I2C_FREQUENCY; + config.address = priv->addr; + config.addrlen = 7; + + /* Write 8 bits to device */ + + ret = i2c_write(priv->i2c, &config, ®val, 1); + if (ret < 0) + { + snerr("ERROR: i2c_write failed: %d\n", ret); + } + + return ret; +} + +/**************************************************************************** + * Name: veml6070_open + * + * Description: + * This function is called whenever the VEML6070 device is opened. + * + ****************************************************************************/ + +static int veml6070_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: veml6070_close + * + * Description: + * This routine is called when the VEML6070 device is closed. + * + ****************************************************************************/ + +static int veml6070_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: veml6070_read + ****************************************************************************/ + +static ssize_t veml6070_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + int ret; + FAR struct inode *inode; + FAR struct veml6070_dev_s *priv; + int msb = 1; + uint16_t regdata; + + DEBUGASSERT(filep); + inode = filep->f_inode; + + DEBUGASSERT(inode && inode->i_private); + priv = (FAR struct veml6070_dev_s *)inode->i_private; + + /* Check if the user is reading the right size */ + + if (buflen != 2) + { + snerr("ERROR: You need to read 2 bytes from this sensor!\n"); + return -EINVAL; + } + + /* Enable the sensor */ + + ret = veml6070_write8(priv, VEML6070_CMD_RSV & ~VEML6070_CMD_SD); + if (ret < 0) + { + snerr("ERROR: Failed to enable the VEML6070!\n"); + return -EINVAL; + } + + /* 1T for Rset 270Kohms is 125ms */ + + usleep(125000); + + /* Read the MSB first */ + + ret = veml6070_read8(priv, msb, (FAR uint8_t *) ®data); + if (ret < 0) + { + snerr("ERROR: Error reading light sensor!\n"); + return ret; + } + + buffer[1] = regdata; + + /* Read the LSB */ + + msb = 0; + ret = veml6070_read8(priv, msb, (FAR uint8_t *) ®data); + if (ret < 0) + { + snerr("ERROR: Error reading light sensor!\n"); + return ret; + } + + buffer[0] = regdata; + + return buflen; +} + +/**************************************************************************** + * Name: veml6070_write + ****************************************************************************/ + +static ssize_t veml6070_write(FAR struct file *filep, + FAR const char *buffer, size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: veml6070_register + * + * Description: + * Register the VEML6070 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/uvlight0" + * i2c - An instance of the I2C interface to use to communicate with VEML6070 + * addr - The I2C address of the VEML6070. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int veml6070_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr) +{ + int ret; + + /* Sanity check */ + + DEBUGASSERT(i2c != NULL); + + /* Initialize the VEML6070 device structure */ + + FAR struct veml6070_dev_s *priv = + (FAR struct veml6070_dev_s *)kmm_malloc(sizeof(struct veml6070_dev_s)); + + if (priv == NULL) + { + snerr("ERROR: Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = addr; + + /* Initialize the device (shut it down) */ + + ret = veml6070_write8(priv, VEML6070_CMD_RSV | VEML6070_CMD_SD); + if (ret < 0) + { + snerr("ERROR: Failed to initialize the VEML6070!\n"); + return ret; + } + + /* Register the character driver */ + + ret = register_driver(devpath, &g_veml6070_fops, 0666, priv); + if (ret < 0) + { + snerr("ERROR: Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_VEML6070 */ diff --git a/include/nuttx/sensors/veml6070.h b/include/nuttx/sensors/veml6070.h new file mode 100644 index 0000000000..a143f1ee8d --- /dev/null +++ b/include/nuttx/sensors/veml6070.h @@ -0,0 +1,121 @@ +/**************************************************************************** + * include/nuttx/input/veml6070.h + * + * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2016 Alan Carvalho de Assis. All rights reserved. + * Author: Alan Carvalho de Assis + * + * 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 __INCLUDE_NUTTX_SENSORS_VEML6070_H +#define __INCLUDE_NUTTX_SENSORS_VEML6070_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#if defined(CONFIG_VEML6070) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Device I2C Address */ + +#define VEML6070_I2C_DATA_LSB_CMD_ADDR 0x38 +#define VEML6070_I2C_DATA_MSB_ADDR 0x39 + +/* Command Register Format + * Bits: + * 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + * RSV | RSV | ACK | ACK_THD | IT1 | IT0 | RSV | SD | + * + * NOTE: The RSV Bit 1 needs to be always 1 + */ + + +#define VEML6070_CMD_SD 0x01 /* Shutdown command */ +#define VEML6070_CMD_RSV 0x02 +#define VEML6070_CMD_IT_0_5T 0x00 /* IT1=0 : IT0=0 */ +#define VEML6070_CMD_IT_1T 0x04 /* IT1=0 : IT0=1 */ +#define VEML6070_CMD_IT_2T 0x08 /* IT1=1 : IT0=0 */ +#define VEML6070_CMD_IT_4T 0x0c /* IT1=1 : IT0=1 */ +#define VEML6070_CMD_ACK_THD 0x10 /* Acknowledge thresold: + 0 = 102 steps + 1 = 145 steps */ +#define VEML6070_CMD_ACK 0x20 /* Acknowledge activity */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: veml6070_register + * + * Description: + * Register the VEML6070 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/uvlight0" + * i2c - An instance of the I2C interface to use to communicate with + * VEML6070 + * addr - The I2C address of the VEML6070. + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int veml6070_register(FAR const char *devpath, FAR struct i2c_master_s *i2c, + uint8_t addr); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_VEML6070 */ +#endif /* __INCLUDE_NUTTX_SENSORS_VEML6070_H */ From 31d9565f0fea4b31f012f14455678509d50244a1 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Mon, 14 Nov 2016 07:18:33 -0600 Subject: [PATCH 138/155] Misoc LM32: Corrects a bug that never occured in qemu on simulation or real fpga. The error was that the r1 register was being modified out of context switching and not restoring it. --- arch/misoc/src/lm32/lm32_vectors.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/misoc/src/lm32/lm32_vectors.S b/arch/misoc/src/lm32/lm32_vectors.S index 94521a3a69..4cc83a3919 100644 --- a/arch/misoc/src/lm32/lm32_vectors.S +++ b/arch/misoc/src/lm32/lm32_vectors.S @@ -240,7 +240,6 @@ _do_reset: .restore_all_and_eret: /* r1 should have the place where we restore ! */ - lw r2, (r1+REG_X2) lw r3, (r1+REG_X3) lw r4, (r1+REG_X4) lw r5, (r1+REG_X5) @@ -270,8 +269,9 @@ _do_reset: lw r29, (r1+REG_RA) lw r30, (r1+REG_EA) lw r31, (r1+REG_BA) - lw r1, (r1+REG_INT_CTX) - wcsr IE, r1 + lw r2, (r1+REG_INT_CTX) + wcsr IE, r2 + lw r2, (r1+REG_X2) lw r1, (r1+REG_X1) eret From efbb622ab8baf09a11b273bec00b24218321792c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 10:30:10 -0600 Subject: [PATCH 139/155] Update README --- configs/esp32-core/README.txt | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 579978d1d7..eb97058275 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -270,6 +270,37 @@ Debug Issues "ESP32 Pin List" document found here: http://espressif.com/en/support/download/documents?keys=&field_type_tid%5B%5D=13 + I put the ESP32 on a prototyping board and used a standard JTAG 20-pin + connector with an older Olimex JTAG that I had. Here is how I wired + the 20-pin connector: + + ----------------- ---------- + 20-PIN JTAG ESP32 PIN + CONNECTOR LABEL + ----------------- ---------- + 1 VREF INPUT 3V3 + 3 nTRST OUTPUT N/C + 5 TDI OUTPUT IO12 + 7 TMS OUTPUT IO14 + 9 TCLK OUTPUT IO13 + 11 RTCK INPUT N/C + 13 TDO INPUT IO15 + 15 RESET I/O N/C + 17 DBGRQ OUTPUT N/C + 19 5V OUTPUT N/C + ------------ ---------- + 2 VCC INPUT 3V3 + 4 GND N/A GND + 6 GND N/A GND + 8 GND N/A GND + 10 GND N/A GND + 12 GND N/A GND + 14 GND N/A GND + 16 GND N/A GND + 18 GND N/A GND + 20 GND N/A GND + ------------ ---------- + - I need to understand how to use the secondary bootloader. My understanding is that it will configure hardware, read a partition table at address 0x5000, and then load code into memory. I do need to From bf096873a1b88ad600445b0b349a5d097dedfea4 Mon Sep 17 00:00:00 2001 From: "Kolb, Stefan" Date: Mon, 14 Nov 2016 10:32:49 -0600 Subject: [PATCH 140/155] SAMV7 USBDEVHS: A problem occurred if the USB cable is unplugged while a large amount of data is send over an IN endpoint using DMA. If the USB cable is plugged in again after a few seconds it is not possible to send data over this IN endpoint again, all other endpoints work as expected. The problem occurs because if the USB cable is unplugged while an DMA transfer is in flight the transfer is canceled but the register SAM_USBHS_DEVDMACTRL is left in an undefined state. The problem was fixed the problem by resetting the register SAM_USBHS_DEVDMACTRL to a known state. Additionally all pending interrupts are cleared. --- arch/arm/src/samv7/sam_usbdevhs.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/src/samv7/sam_usbdevhs.c b/arch/arm/src/samv7/sam_usbdevhs.c index 087db9c0e1..1d48ca410a 100644 --- a/arch/arm/src/samv7/sam_usbdevhs.c +++ b/arch/arm/src/samv7/sam_usbdevhs.c @@ -3333,6 +3333,17 @@ static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno) sam_putreg(USBHS_DEVINT_PEP(epno), SAM_USBHS_DEVIDR); + /* Clear all pending interrupts */ + + sam_putreg(USBHS_DEVEPTICR_ALLINTS, SAM_USBHS_DEVEPTICR(epno)); + + /* Set DMA control register to a defined state */ + + if ((SAM_EPSET_DMA & SAM_EP_BIT(epno)) != 0) + { + sam_putreg(0, SAM_USBHS_DEVDMACTRL(epno)); + } + /* Cancel any queued requests. Since they are cancelled with status * -ESHUTDOWN, then will not be requeued until the configuration is reset. * NOTE: This should not be necessary... the CLASS_DISCONNECT above From 74089c5198f70a575c16ccfd3a2ba5fabe042fa2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 11:30:40 -0600 Subject: [PATCH 141/155] ESP32 Core v2: Include a copy of the OpenOCD config file. --- configs/esp32-core/README.txt | 4 +++ configs/esp32-core/scripts/esp32.cfg | 51 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 configs/esp32-core/scripts/esp32.cfg diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index eb97058275..081cfad732 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -241,6 +241,10 @@ Debug Issues FreeRTOS, you will need to uncomment the "set ESP32_RTOS none" line in OpenOCD configuration file. + NOTE: A copy of this OpenOCD configuration file (with the referenced + line uncommented). Is available in the NuttX source tree at + nuttx/config/esp32-core/scripts/esp32.cfg. + The documentation indicates that you need to use an external JTAG like the TIAO USB Multi-protocol Adapter and the Flyswatter2. The instructions at http://www.esp32.com/viewtopic.php?t=381 show diff --git a/configs/esp32-core/scripts/esp32.cfg b/configs/esp32-core/scripts/esp32.cfg new file mode 100644 index 0000000000..68c594c101 --- /dev/null +++ b/configs/esp32-core/scripts/esp32.cfg @@ -0,0 +1,51 @@ +# +# Example configuration file to hook up an ESP32 module or board to a JTAG +# adapter. Please modify this file to your local setup. +# +# + + +# Include the configuration for the JTAG adapter. We use the Tian TUMPA here. +# If you have a different interface, please edit this to include the +# configuration file of yours. +source [find interface/ftdi/tumpa.cfg] + +# The ESP32 only supports JTAG. +transport select jtag + +# The speed of the JTAG interface, in KHz. If you get DSR/DIR errors (and they +# do not relate to OpenOCD trying to read from a memory range without physical +# memory being present there), you can try lowering this. +adapter_khz 200 + +# With no variables set, openocd will configure JTAG for the two cores of the ESP32 and +# will do automatic RTOS detection. This can be be adjusted by uncommenting any of the +# following lines: + +# Only configure the PRO CPU +#set ESP32_ONLYCPU 1 +# Only configure the APP CPU +#set ESP32_ONLYCPU 2 +# Disable RTOS support +set ESP32_RTOS none +# Force RTOS to be FreeRTOS +#set ESP32_RTOS FreeRTOS + +#Source the ESP32 configuration file +source [find target/esp32.cfg] + + +# The TDI pin of ESP32 is also a bootstrap pin that selects the voltage the SPI flash +# chip runs at. When a hard reset happens (e.g. because someone switches the board off +# and on) the ESP32 will use the current TDI value as the bootstrap value because the +# JTAG adapter overrides the pull-up or pull-down resistor that is supposed to do the +# bootstrapping. These lines basically set the idle value of the TDO line to a +# specified value, therefore reducing the chance of a bad bootup due to a bad flash +# voltage greatly. + +# Enable this for 1.8V SPI flash +esp108 flashbootstrap 1.8 +# Enable this for 3.3V SPI flash +#esp108 flashbootstrap 3.3 + + From c7dad4ffe091625ec01e32f9ffa22d47bc58633c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 11:52:33 -0600 Subject: [PATCH 142/155] Update README --- configs/esp32-core/README.txt | 210 +++++++++++++++++---------- configs/esp32-core/scripts/esp32.cfg | 6 +- 2 files changed, 135 insertions(+), 81 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 081cfad732..75f4e34307 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -225,99 +225,151 @@ SMP Debug Issues ============ - You basically need the debug environment and a step-by-step procedure. + First you in need some debug environment which would be a JTAG emulator + and the ESP32 OpenOCD software which is available here: + https://github.com/espressif/openocd-esp32 - - First in need some debug environment which would be a JTAG emulator - and the ESP32 OpenOCD software which is available here: - https://github.com/espressif/openocd-esp32 + OpenOCD Documentation + --------------------- + There is on overiew of the use of OpenOCD here: + https://dl.espressif.com/doc/esp-idf/latest/openocd.html + This document is also available in ESP-IDF source tree in docs + directory (https://github.com/espressif/esp-idf). - - There is on overiew of the use of OpenOCD here: - https://dl.espressif.com/doc/esp-idf/latest/openocd.html - This document is also available in ESP-IDF source tree in docs - directory (https://github.com/espressif/esp-idf). + OpenOCD Configuration File + -------------------------- + A template ESP32 OpenOCD configuration file is provided in + ESP-IDF docs directory (esp32.cfg). Since you are not using + FreeRTOS, you will need to uncomment the "set ESP32_RTOS none" + line in OpenOCD configuration file. - A template ESP32 OpenOCD configuration file is provided in - ESP-IDF docs directory (esp32.cfg). Since you are not using - FreeRTOS, you will need to uncomment the "set ESP32_RTOS none" - line in OpenOCD configuration file. + You will still need to change the source line from: - NOTE: A copy of this OpenOCD configuration file (with the referenced - line uncommented). Is available in the NuttX source tree at - nuttx/config/esp32-core/scripts/esp32.cfg. + find interface/ftdi/tumpa.cfg line - The documentation indicates that you need to use an external JTAG - like the TIAO USB Multi-protocol Adapter and the Flyswatter2. - The instructions at http://www.esp32.com/viewtopic.php?t=381 show - use of an FTDI C232HM-DDHSL-0 USB 2.0 high speed to MPSSE cable. + to reflect the physical JTAG adapter connected. - - The ESP32 Core v2 board has no on board JTAG connector. It will - be necessary to make a cable or some other board to connect a JTAG - emulator. Refer to http://www.esp32.com/viewtopic.php?t=381 "How - to debug ESP32 with JTAG / OpenOCD / GDB 1st part connect the - hardware." + NOTE: A copy of this OpenOCD configuration file (with the referenced + line RTOS uncommented but with no change to JTAG interface). Is + available in the NuttX source tree at + nuttx/config/esp32-core/scripts/esp32.cfg. - Relevant pin-out: + General OpenOCD build instructions + ---------------------------------- + Installing OpenOCD. The sources for the ESP32-enabled variant of + OpenOCD are available from Espressifs Github. To download the source, + use the following commands: - -------- ---------- - PIN JTAG - LABEL FUNCTION - -------- ---------- - IO14 TMS - IO12 TDI - GND GND - IO13 TCK - -------- ---------- - IO15 TDO - -------- ---------- + git clone https://github.com/espressif/openocd-esp32.git + cd openocd-esp32 + git submodule init + git submodule update - You can find the mapping of JTAG signals to ESP32 GPIO numbers in - "ESP32 Pin List" document found here: - http://espressif.com/en/support/download/documents?keys=&field_type_tid%5B%5D=13 + Then look at the README file in the openocd-esp32 directory. - I put the ESP32 on a prototyping board and used a standard JTAG 20-pin - connector with an older Olimex JTAG that I had. Here is how I wired - the 20-pin connector: + Running OpenOCD + -------------- - ----------------- ---------- - 20-PIN JTAG ESP32 PIN - CONNECTOR LABEL - ----------------- ---------- - 1 VREF INPUT 3V3 - 3 nTRST OUTPUT N/C - 5 TDI OUTPUT IO12 - 7 TMS OUTPUT IO14 - 9 TCLK OUTPUT IO13 - 11 RTCK INPUT N/C - 13 TDO INPUT IO15 - 15 RESET I/O N/C - 17 DBGRQ OUTPUT N/C - 19 5V OUTPUT N/C - ------------ ---------- - 2 VCC INPUT 3V3 - 4 GND N/A GND - 6 GND N/A GND - 8 GND N/A GND - 10 GND N/A GND - 12 GND N/A GND - 14 GND N/A GND - 16 GND N/A GND - 18 GND N/A GND - 20 GND N/A GND - ------------ ---------- + cd to openocd-esp32 directory + copy the modified esp32.cfg script to this directory + Run ./src/openocd -s ./tcl -f ./esp32.cfg to start OpenOCD - - I need to understand how to use the secondary bootloader. My - understanding is that it will configure hardware, read a partition - table at address 0x5000, and then load code into memory. I do need to - download and build the bootloader? + Connecting a debugger to OpenOCD + -------------------------------- + OpenOCD should now be ready to accept gdb connections. If you have + compiled the ESP32 toolchain using Crosstool-NG, or if you have + downloaded a precompiled toolchain from the Espressif website, you + should already have xtensa-esp32-elf-gdb, a version of gdb that can + be used for this - - Do I need to create a partition table at 0x5000? Should this be part - of the NuttX build? + First, make sure the project you want to debug is compiled and + flashed into the ESP32’s SPI flash. Then, in a different console + than OpenOCD is running in, invoke gdb. For example, for the + template app, you would do this like such: - See https://github.com/espressif/esp-idf/tree/master/components/bootloader - and https://github.com/espressif/esp-idf/tree/master/components/partition_table. - I suppose some of what I need is in there, but I am not sure what I am - looking at right now. + cd esp-idf-template + xtensa-esp32-elf-gdb -ex 'target remote localhost:3333' ./build/app-template.elf + This should give you a gdb prompt. + JTAG Emulator + ------------- + The documentation indicates that you need to use an external JTAG + like the TIAO USB Multi-protocol Adapter and the Flyswatter2. + The instructions at http://www.esp32.com/viewtopic.php?t=381 show + use of an FTDI C232HM-DDHSL-0 USB 2.0 high speed to MPSSE cable. + + The ESP32 Core v2 board has no on board JTAG connector. It will + be necessary to make a cable or some other board to connect a JTAG + emulator. Refer to http://www.esp32.com/viewtopic.php?t=381 "How + to debug ESP32 with JTAG / OpenOCD / GDB 1st part connect the + hardware." + + Relevant pin-out: + + -------- ---------- + PIN JTAG + LABEL FUNCTION + -------- ---------- + IO14 TMS + IO12 TDI + GND GND + IO13 TCK + -------- ---------- + IO15 TDO + -------- ---------- + + You can find the mapping of JTAG signals to ESP32 GPIO numbers in + "ESP32 Pin List" document found here: + http://espressif.com/en/support/download/documents?keys=&field_type_tid%5B%5D=13 + + I put the ESP32 on a prototyping board and used a standard JTAG 20-pin + connector with an older Olimex JTAG that I had. Here is how I wired + the 20-pin connector: + + ----------------- ---------- + 20-PIN JTAG ESP32 PIN + CONNECTOR LABEL + ----------------- ---------- + 1 VREF INPUT 3V3 + 3 nTRST OUTPUT N/C + 5 TDI OUTPUT IO12 + 7 TMS OUTPUT IO14 + 9 TCLK OUTPUT IO13 + 11 RTCK INPUT N/C + 13 TDO INPUT IO15 + 15 RESET I/O N/C + 17 DBGRQ OUTPUT N/C + 19 5V OUTPUT N/C + ------------ ---------- + 2 VCC INPUT 3V3 + 4 GND N/A GND + 6 GND N/A GND + 8 GND N/A GND + 10 GND N/A GND + 12 GND N/A GND + 14 GND N/A GND + 16 GND N/A GND + 18 GND N/A GND + 20 GND N/A GND + ------------ ---------- + + Secondary Boot Loader / Partition Table + --------------------------------------- + I need to understand how to use the secondary bootloader. My + understanding is that it will configure hardware, read a partition + table at address 0x5000, and then load code into memory. I do need to + download and build the bootloader? + + Do I need to create a partition table at 0x5000? Should this be part + of the NuttX build? + + See https://github.com/espressif/esp-idf/tree/master/components/bootloader + and https://github.com/espressif/esp-idf/tree/master/components/partition_table. + I suppose some of what I need is in there, but I am not sure what I am + looking at right now. + + Running from IRAM + ----------------- It is possible to skip the secondary bootloader and run out of IRAM using only the primary bootloader if your application of small enough (< 128KiB code, <180KiB data), then you can simplify initial bring-up by avoiding second stage @@ -355,6 +407,8 @@ Debug Issues will be written. ROM bootloader expects to find an application (or second stage bootloader) image at offset 0x1000, so we are writing the binary there. + Clocking + -------- Right now, the NuttX port depends on the bootloader to initialize hardware, including basic (slow) clocking. If I had the clock configuration logic, would I be able to run directly out of IRAM without a bootloader? That diff --git a/configs/esp32-core/scripts/esp32.cfg b/configs/esp32-core/scripts/esp32.cfg index 68c594c101..ec04c4a079 100644 --- a/configs/esp32-core/scripts/esp32.cfg +++ b/configs/esp32-core/scripts/esp32.cfg @@ -1,12 +1,12 @@ # -# Example configuration file to hook up an ESP32 module or board to a JTAG +# Example configuration file to hook up an ESP32 module or board to a JTAG # adapter. Please modify this file to your local setup. # # # Include the configuration for the JTAG adapter. We use the Tian TUMPA here. -# If you have a different interface, please edit this to include the +# If you have a different interface, please edit this to include the # configuration file of yours. source [find interface/ftdi/tumpa.cfg] @@ -39,7 +39,7 @@ source [find target/esp32.cfg] # chip runs at. When a hard reset happens (e.g. because someone switches the board off # and on) the ESP32 will use the current TDI value as the bootstrap value because the # JTAG adapter overrides the pull-up or pull-down resistor that is supposed to do the -# bootstrapping. These lines basically set the idle value of the TDO line to a +# bootstrapping. These lines basically set the idle value of the TDO line to a # specified value, therefore reducing the chance of a bad bootup due to a bad flash # voltage greatly. From 3b6c4b37b0c2325a943dca5d1b7f180f5b51c224 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 12:54:29 -0600 Subject: [PATCH 143/155] Update README --- configs/esp32-core/README.txt | 53 +++++++++++++++++++++------- configs/esp32-core/scripts/esp32.cfg | 2 +- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 75f4e34307..36a6468d2c 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -240,19 +240,25 @@ Debug Issues -------------------------- A template ESP32 OpenOCD configuration file is provided in ESP-IDF docs directory (esp32.cfg). Since you are not using - FreeRTOS, you will need to uncomment the "set ESP32_RTOS none" - line in OpenOCD configuration file. + FreeRTOS, you will need to uncomment the line: - You will still need to change the source line from: + set ESP32_RTOS none - find interface/ftdi/tumpa.cfg line + in the OpenOCD configuration file. You will also need to change + the source line from: + + find interface/ftdi/tumpa.cfg to reflect the physical JTAG adapter connected. - NOTE: A copy of this OpenOCD configuration file (with the referenced - line RTOS uncommented but with no change to JTAG interface). Is - available in the NuttX source tree at - nuttx/config/esp32-core/scripts/esp32.cfg. + NOTE: A copy of this OpenOCD configuration file available in the NuttX + source tree at nuttx/config/esp32-core/scripts/esp32.cfg.. It has these + modifications: + + - The referenced "set ESP32_RTOS none" line has been uncommented + - The "ind interface/ftdi/tumpa.cfg". This means that you will + need to specify the interface configuration file on the OpenOCD + command line. General OpenOCD build instructions ---------------------------------- @@ -265,14 +271,37 @@ Debug Issues git submodule init git submodule update - Then look at the README file in the openocd-esp32 directory. + Then look at the README and the docs/INSTALL.txt files in the + openocd-esp32 directory for further instructions. There area + separate README files for Linux/Cygwin, OSX, and Windows. Here + is what I ended up doing (under Linux): + + cd openocd-esp32 + ./bootstrap + ./configure + make + + If you do not do the install step, then you will have a localhost + version of the OpenOCD binary at openocd-esp32/src. Running OpenOCD -------------- - cd to openocd-esp32 directory - copy the modified esp32.cfg script to this directory - Run ./src/openocd -s ./tcl -f ./esp32.cfg to start OpenOCD + - cd to openocd-esp32 directory + - copy the modified esp32.cfg script to this directory + + Then start OpenOCD by executing a command like the following. Here + I assume that: + + - You did not install OpenOCD; binararies are avalable at + openocd-esp32/src and interface scripts are in + openocd-eps32/tcl/interface + - I select the configuration for the Olimex ARM-USB-OCD + debugger. + + Then the command to start OpenOCD is: + + sudo ./src/openocd -s ./tcl -f tcl/interface/ftdi/olimex-arm-usb-ocd.cfg -f ./esp32.cfg Connecting a debugger to OpenOCD -------------------------------- diff --git a/configs/esp32-core/scripts/esp32.cfg b/configs/esp32-core/scripts/esp32.cfg index ec04c4a079..0bd581f40a 100644 --- a/configs/esp32-core/scripts/esp32.cfg +++ b/configs/esp32-core/scripts/esp32.cfg @@ -8,7 +8,7 @@ # Include the configuration for the JTAG adapter. We use the Tian TUMPA here. # If you have a different interface, please edit this to include the # configuration file of yours. -source [find interface/ftdi/tumpa.cfg] +# source [find interface/ftdi/olimex-arm-usb-ocd.cfg] # The ESP32 only supports JTAG. transport select jtag From c84db681036b9f43f1301648e01e009b6aa636e5 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 13:29:08 -0600 Subject: [PATCH 144/155] Xtensa ESP32: Fix some compilation errors that snuck with some of the last changes --- arch/xtensa/src/common/xtensa_windowspill.S | 6 +++--- configs/esp32-core/Kconfig | 11 +++++++++++ configs/esp32-core/README.txt | 17 ++++++++++++++++- configs/esp32-core/include/board.h | 8 ++++++-- configs/esp32-core/nsh/defconfig | 9 ++++++--- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/arch/xtensa/src/common/xtensa_windowspill.S b/arch/xtensa/src/common/xtensa_windowspill.S index bba79e14ee..336e5cd431 100644 --- a/arch/xtensa/src/common/xtensa_windowspill.S +++ b/arch/xtensa/src/common/xtensa_windowspill.S @@ -40,7 +40,7 @@ ****************************************************************************/ #include -#include +#include #include "xtensa_abi.h" /**************************************************************************** @@ -148,7 +148,7 @@ _xtensa_window_spill: rsr a3, WINDOWSTART srl a2, a3 /* a2 is 0... | 000000xxxxxxxxxx = WINDOWSTART >> sar */ sll a3, a3 /* a3 is 1yyyyy0000000000 | 0... = WINDOWSTART << (32 - sar) */ - bgez a3, .Linvalid_ws /* verify that msbit is indeed set + bgez a3, .Linvalid_ws /* verify that msbit is indeed set */ srli a3, a3, 32-WSBITS /* a3 is 0... | 1yyyyy0000000000 = a3 >> (32-NAREG/4) */ or a2, a2, a3 /* a2 is 0... | 1yyyyyxxxxxxxxxx */ @@ -202,7 +202,7 @@ _xtensa_window_spill: add a3, a2, a3 /* a3 = WINDOWBASE + index */ #endif /* XCHAL_HAVE_NSA */ - wsr a 3, WINDOWBASE /* Effectively do: rotw index */ + wsr a3, WINDOWBASE /* Effectively do: rotw index */ rsync /* Wait for write to WINDOWBASE to complete */ /* Now our registers have changed! */ diff --git a/configs/esp32-core/Kconfig b/configs/esp32-core/Kconfig index 719b83d1a5..8e3da8ac64 100644 --- a/configs/esp32-core/Kconfig +++ b/configs/esp32-core/Kconfig @@ -5,4 +5,15 @@ if ARCH_BOARD_ESP32CORE +choice + prompt "On-board Crystal Frequency" + default ESP32CORE_XTAL_40MZ + +config ESP32CORE_XTAL_40MZ + bool "40MHz" + +config ESP32CORE_XTAL_26MHz + bool "26MHz" + +endchoice # On-board Crystal Frequency endif # ARCH_BOARD_ESP32CORE diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 36a6468d2c..c3fdd0795b 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -303,6 +303,20 @@ Debug Issues sudo ./src/openocd -s ./tcl -f tcl/interface/ftdi/olimex-arm-usb-ocd.cfg -f ./esp32.cfg + I then see: + + Open On-Chip Debugger 0.10.0-dev-g3098897 (2016-11-14-12:19) + Licensed under GNU GPL v2 + For bug reports, read + http://openocd.org/doc/doxygen/bugs.html + adapter speed: 200 kHz + force hard breakpoints + Info : clock speed 200 kHz + Info : JTAG tap: esp32.cpu0 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1) + Info : JTAG tap: esp32.cpu1 tap/device found: 0x120034e5 (mfg: 0x272 (Tensilica), part: 0x2003, ver: 0x1) + Info : esp32.cpu0: Debug controller was reset (pwrstat=0x5F, after clear 0x0F). + Info : esp32.cpu0: Core was reset (pwrstat=0x5F, after clear 0x0F). + Connecting a debugger to OpenOCD -------------------------------- OpenOCD should now be ready to accept gdb connections. If you have @@ -318,7 +332,8 @@ Debug Issues cd esp-idf-template xtensa-esp32-elf-gdb -ex 'target remote localhost:3333' ./build/app-template.elf - This should give you a gdb prompt. + + This should give you a gdb prompt. JTAG Emulator ------------- diff --git a/configs/esp32-core/include/board.h b/configs/esp32-core/include/board.h index a08840fbe0..e3b2e85a87 100644 --- a/configs/esp32-core/include/board.h +++ b/configs/esp32-core/include/board.h @@ -41,9 +41,13 @@ ****************************************************************************/ /* Clocking ****************************************************************/ -/* The ESP32 Core board V2 is fitted with a 40MHz crystal */ +/* The ESP32 Core board V2 is fitted with either a 26 a 40MHz crystal */ -#define BOARD_XTAL_FREQUENCY 40000000 +#ifdef CONFIG_ESP32CORE_XTAL_26MHz +# define BOARD_XTAL_FREQUENCY 26000000 +#else +# define BOARD_XTAL_FREQUENCY 40000000 +#endif /* Clock reconfiguration is currently disabled, so the CPU will be running * at the XTAL frequency. diff --git a/configs/esp32-core/nsh/defconfig b/configs/esp32-core/nsh/defconfig index 96bb1c7bd3..2d68310f33 100644 --- a/configs/esp32-core/nsh/defconfig +++ b/configs/esp32-core/nsh/defconfig @@ -62,6 +62,7 @@ CONFIG_DEBUG_FULLOPT=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_RISCV is not set @@ -170,6 +171,8 @@ CONFIG_ARCH_BOARD="esp32-core" # # Board-Specific Options # +CONFIG_ESP32CORE_XTAL_40MZ=y +# CONFIG_ESP32CORE_XTAL26MHz is not set # CONFIG_BOARD_CRASHDUMP is not set # CONFIG_LIB_BOARDCTL is not set @@ -299,14 +302,14 @@ CONFIG_DEV_NULL=y # CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set CONFIG_SPI=y +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_SPI_SLAVE is not set CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CMDDATA is not set # CONFIG_SPI_CALLBACK is not set # CONFIG_SPI_HWFEATURES is not set -# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set -# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set -# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_SPI_DRIVER is not set # CONFIG_SPI_BITBANG is not set From 0ed0217be2e99b1a0d33879e5eb97ede3bb74a25 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 13:41:30 -0600 Subject: [PATCH 145/155] ESP32: Trivial typo prevent good link --- configs/esp32-core/README.txt | 4 ++-- configs/esp32-core/scripts/esp32_common.ld | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index c3fdd0795b..59cc9d4ab8 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -330,8 +330,8 @@ Debug Issues than OpenOCD is running in, invoke gdb. For example, for the template app, you would do this like such: - cd esp-idf-template - xtensa-esp32-elf-gdb -ex 'target remote localhost:3333' ./build/app-template.elf + cd nuttx + xtensa-esp32-elf-gdb -ex 'target remote localhost:3333' nuttx This should give you a gdb prompt. diff --git a/configs/esp32-core/scripts/esp32_common.ld b/configs/esp32-core/scripts/esp32_common.ld index cfabd62087..ba67d87451 100644 --- a/configs/esp32-core/scripts/esp32_common.ld +++ b/configs/esp32-core/scripts/esp32_common.ld @@ -135,7 +135,7 @@ SECTIONS /* C++ constructor and destructor tables, properly ordered: */ - __sinit = ABSOLUTE(.); + _sinit = ABSOLUTE(.); KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*))) From 96e7d1c310c316c980f15165bf8eb2ab0da580bf Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 16:41:37 -0600 Subject: [PATCH 146/155] Update REAMME --- Documentation/README.html | 5 +++-- README.txt | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Documentation/README.html b/Documentation/README.html index 8751b6b37c..a9577df8ce 100644 --- a/Documentation/README.html +++ b/Documentation/README.html @@ -8,7 +8,7 @@

NuttX README Files

-

Last Updated: November 4, 2016

+

Last Updated: November 14, 2016

@@ -384,7 +384,8 @@ apps/ |- gpsutils/ | `- "minmea/README.txt |- graphics/ - | `- "tiff/README.txt + | |- "tiff/README.txt + | `- "traveler/tools/tcledit/README.txt |- interpreters/ | |- bas/README.txt | |- ficl/README.txt diff --git a/README.txt b/README.txt index d2a9a7b9fe..3a673b7e9a 100644 --- a/README.txt +++ b/README.txt @@ -1597,7 +1597,8 @@ apps/ |- gpsutils/ | `- minmea/README.txt |- graphics/ - | `- tiff/README.txt + | |- tiff/README.txt + | `- traveler/tools/tcledit/README.txt |- interpreters/ | |- bas | | `- README.txt From 5dfc5f1da585d1bf2a87d68e3c1f6690a612bd6c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 14 Nov 2016 17:51:50 -0600 Subject: [PATCH 147/155] ESP32 Core v2: Add configuration to supporting linking NuttX for execution out of IRAM. --- configs/esp32-core/Kconfig | 11 + configs/esp32-core/README.txt | 98 ++++++--- configs/esp32-core/nsh/Make.defs | 7 +- .../{esp32_common.ld => esp32_flash.ld} | 2 +- configs/esp32-core/scripts/esp32_iram.ld | 191 ++++++++++++++++++ configs/esp32-core/smp/Make.defs | 7 +- 6 files changed, 282 insertions(+), 34 deletions(-) rename configs/esp32-core/scripts/{esp32_common.ld => esp32_flash.ld} (98%) create mode 100644 configs/esp32-core/scripts/esp32_iram.ld diff --git a/configs/esp32-core/Kconfig b/configs/esp32-core/Kconfig index 8e3da8ac64..3f73b4052a 100644 --- a/configs/esp32-core/Kconfig +++ b/configs/esp32-core/Kconfig @@ -16,4 +16,15 @@ config ESP32CORE_XTAL_26MHz bool "26MHz" endchoice # On-board Crystal Frequency + +config ESP32CORE_RUN_IRAM + bool "Run from IRAM" + default n + ---help--- + The default configuration is set up run from IRAM. However, the + current (2016-11-14) OpenOCD for ESP32 does not support writing to + FLASH. This option sets up the liner scripts to support execution + from IRAM. In this case, OpenOCD can be used to load directly into + IRAM. + endif # ARCH_BOARD_ESP32CORE diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 59cc9d4ab8..59636eb113 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -23,7 +23,8 @@ Contents o Serial Console o Buttons and LEDs o SMP - o Debug Issues + o OpenOCD for the ESP32 + o Executing and Debugging from FLASH and IRAM o Configurations o Things to Do @@ -222,8 +223,8 @@ SMP 3. Assertions. On a fatal assertions, other CPUs need to be stopped. -Debug Issues -============ +OpenOCD for the ESP32 +===================== First you in need some debug environment which would be a JTAG emulator and the ESP32 OpenOCD software which is available here: @@ -335,6 +336,16 @@ Debug Issues This should give you a gdb prompt. + Breakpoints + ----------- + You can set up to 2 hardware breakpoints, which can be anywhere in the + address space. Also 2 hardware watchpoints. + + The openocd esp32.cfg file currently forces gdb to use hardware + breakpoints, I believe because software breakpoints (or, at least, the + memory map for automatically choosing them) aren't implemented yet + (as of 2016-11-14). + JTAG Emulator ------------- The documentation indicates that you need to use an external JTAG @@ -397,49 +408,74 @@ Debug Issues 20 GND N/A GND ------------ ---------- + Executing and Debugging from FLASH and IRAM + =========================================== + + FLASH + ----- + OpenOCD currently doesn't have a FLASH driver for ESP32, so you can load + code into IRAM only via JTAG. FLASH-resident sections like .FLASH.rodata + will fail to load. The bootloader in ROM doesn't parse ELF, so any imag + which is bootloaded from FLASH has to be converted into a custom image + format first. + + The tool esp-idf uses for flashing is a command line Python tool called + "esptool.py" which talks to a serial bootloader in ROM. A version is + supplied in the esp-idf codebase in components/esptool_py/esptool, the + "upstream" for that tool is here: + + https://github.com/espressif/esptool/pull/121 + + The master branch for esptool.py is currently ESP8266-only (as of 2016-11-14), + this PR has the ESP32 support which still needs some final tidying up before + it's + merged. + + To FLASH an ELF via the command line is a two step process, something like + this: + + esptool.py --chip esp32 elf2image --flash_mode dio --flash_size 4MB -o ./nuttx.bin nuttx.elf + esptool.py --chip esp32 --port COMx write_flash 0x1000 bootloader.bin 0x4000 partition_table.bin 0x10000 nuttx.bin + + The first step converts an ELF image into an ESP32-compatible binary + image format, and the second step flashes it (along with bootloader image and + partition table binary.) + + To put the ESP32 into serial flashing mode, it needs to be reset with IO0 held + low. On the Core boards this can be accomplished by holding the button marked + "Boot" and pressing then releasing the button marked "EN". Actually, esptool.py + can enter bootloader mode automatically (via RTS/DTR control lines), but + unfortunately a timing interaction between the Windows CP2012 driver and the + hardware means this doesn't currently work on Windows. + Secondary Boot Loader / Partition Table --------------------------------------- - I need to understand how to use the secondary bootloader. My - understanding is that it will configure hardware, read a partition - table at address 0x5000, and then load code into memory. I do need to - download and build the bootloader? - - Do I need to create a partition table at 0x5000? Should this be part - of the NuttX build? - See https://github.com/espressif/esp-idf/tree/master/components/bootloader and https://github.com/espressif/esp-idf/tree/master/components/partition_table. - I suppose some of what I need is in there, but I am not sure what I am - looking at right now. Running from IRAM ----------------- + Running from IRAM is a good debug option. You should be able to load the ELF directly via JTAG in this case, and you may not need the bootloader. The one "gotcha" for needing the bootloader is disabling the initial watchdog, there is code in bootloader_start.c that does this. + It is possible to skip the secondary bootloader and run out of IRAM using only the primary bootloader if your application of small enough (< 128KiB code, <180KiB data), then you can simplify initial bring-up by avoiding second stage bootloader. Your application will be loaded into IRAM using first stage bootloader present in ESP32 ROM. To achieve this, you need two things: - 1. Have a linker script which places all code into IRAM and all data into DRAM + 1. Have a linker script which places all code into IRAM and all data into + IRAM/DRAM - 2. Use "esptool.py" utility found in ESP-IDF to convert application .elf file - into binary format which can be loaded by first stage bootloader. + 2. Use "esptool.py" utility found in ESP-IDF to convert application .elf + file into binary format which can be loaded by first stage bootloader. - The default linker script in ESP-IDF places most code into memory-mapped flash: - https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L178-L186 + NuttX supports a configuration option, CONFIG_ESP32CORE_RUN_IRAM, that may be + selected for execution from IRAM. This option simply selects the correct + linker script for IRAM execution. - You would need to remove this section and move its contents into the end of .iram0.text section: - https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L85 - - Same with constant data: move contents of .flash.rodata section: - https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L134-L173 - - into the end of .dram0.data section (before _heap_start): - https://github.com/espressif/esp-idf/blob/master/components/esp32/ld/esp32.common.ld#L128 - - With these modifications, all code and data should be moved into IRAM/DRAM. Next, you would - need to link the ELF file and convert it to binary format suitable for flashing into the - board. The xommand should to convert ELF file to binary image looks as follows: + Again you would need to link the ELF file and convert it to binary format suitable + for flashing into the board. The command should to convert ELF file to binary + image looks as follows: python esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 elf2image --flash_mode "dio" --flash_freq "40m" --flash_size "2MB" -o app.bin app.elf @@ -554,4 +590,4 @@ Things to Do 5. See SMP-related issues above - 6. See Debug Issues above + 6. See OpenOCD for the ESP32 above diff --git a/configs/esp32-core/nsh/Make.defs b/configs/esp32-core/nsh/Make.defs index f8901d0f8b..8b4dd25b40 100644 --- a/configs/esp32-core/nsh/Make.defs +++ b/configs/esp32-core/nsh/Make.defs @@ -38,10 +38,15 @@ include ${TOPDIR}/tools/Config.mk include ${TOPDIR}/arch/xtensa/src/lx6/Toolchain.defs LDSCRIPT1 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_out.ld -LDSCRIPT2 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_common.ld LDSCRIPT3 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_rom.ld LDSCRIPT4 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_peripherals.ld +ifeq ($(CONFIG_ESP32CORE_RUN_IRAM),y) + LDSCRIPT2 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_iram.ld +else + LDSCRIPT2 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_flash.ld +endif + ifeq ($(WINTOOL),y) # Windows-native toolchains DIRLINK = $(TOPDIR)/tools/copydir.sh diff --git a/configs/esp32-core/scripts/esp32_common.ld b/configs/esp32-core/scripts/esp32_flash.ld similarity index 98% rename from configs/esp32-core/scripts/esp32_common.ld rename to configs/esp32-core/scripts/esp32_flash.ld index ba67d87451..5a1ffe0562 100644 --- a/configs/esp32-core/scripts/esp32_common.ld +++ b/configs/esp32-core/scripts/esp32_flash.ld @@ -1,5 +1,5 @@ /**************************************************************************** - * configs/elf32-core/scripts/esp32_common.ld + * configs/elf32-core/scripts/esp32_flash.ld ****************************************************************************/ /* Default entry point: */ diff --git a/configs/esp32-core/scripts/esp32_iram.ld b/configs/esp32-core/scripts/esp32_iram.ld new file mode 100644 index 0000000000..605ea54e5a --- /dev/null +++ b/configs/esp32-core/scripts/esp32_iram.ld @@ -0,0 +1,191 @@ +/**************************************************************************** + * configs/elf32-core/scripts/esp32_iram.ld + ****************************************************************************/ + +/* Default entry point: */ + +ENTRY(__start); + +SECTIONS +{ + /* Send .iram0 code to iram */ + + .iram0.vectors : + { + /* Vectors go to IRAM */ + + _init_start = ABSOLUTE(.); + + /* Vectors according to builds/RF-2015.2-win32/esp108_v1_2_s5_512int_2/config.html */ + + . = 0x0; + KEEP(*(.window_vectors.text)); + . = 0x180; + KEEP(*(.xtensa_level2_vector.text)); + . = 0x1c0; + KEEP(*(.xtensa_level3_vector.text)); + . = 0x200; + KEEP(*(.xtensa_level4_vector.text)); + . = 0x240; + KEEP(*(.xtensa_level5_vector.text)); + . = 0x280; + KEEP(*(.debug_exception_vector.text)); + . = 0x2c0; + KEEP(*(.nmi_vector.text)); + . = 0x300; + KEEP(*(.kernel_exception_vector.text)); + . = 0x340; + KEEP(*(.user_exception_vector.text)); + . = 0x3c0; + KEEP(*(.double_exception_vector.text)); + . = 0x400; + *(.*_vector.literal) + + . = ALIGN (16); + *(.entry.text) + *(.init.literal) + *(.init) + _init_end = ABSOLUTE(.); + } > iram0_0_seg + + .iram0.text : + { + /* Code marked as runnning out of IRAM */ + + _iram_text_start = ABSOLUTE(.); + *(.iram1 .iram1.*) + *libphy.a:(.literal .text .literal.* .text.*) + *librtc.a:(.literal .text .literal.* .text.*) + *libpp.a:(.literal .text .literal.* .text.*) + *libhal.a:(.literal .text .literal.* .text.*) + _iram_text_end = ABSOLUTE(.); + + _stext = .; + _text_start = ABSOLUTE(.); + *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) + *(.irom0.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.fini.literal) + *(.fini) + *(.gnu.version) + _text_end = ABSOLUTE(.); + _etext = .; + + } > iram0_0_seg + + /* Shared RAM */ + + .dram0.bss (NOLOAD) : + { + /* .bss initialized on power-up */ + + . = ALIGN (8); + _sbss = ABSOLUTE(.); + *(.dynsbss) + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + *(.scommon) + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + *(.dynbss) + KEEP(*(.bss)) + *(.bss.*) + *(.share.mem) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN (8); + _ebss = ABSOLUTE(.); + + /* Uninitialized .bss */ + + *(.noinit) + } >dram0_0_seg + + .dram0.data : + { + /* .data initialized on power-up in ROMed configurations. */ + + _sdata = ABSOLUTE(.); + KEEP(*(.data)) + KEEP(*(.data.*)) + KEEP(*(.gnu.linkonce.d.*)) + KEEP(*(.data1)) + KEEP(*(.sdata)) + KEEP(*(.sdata.*)) + KEEP(*(.gnu.linkonce.s.*)) + KEEP(*(.sdata2)) + KEEP(*(.sdata2.*)) + KEEP(*(.gnu.linkonce.s2.*)) + KEEP(*(.jcr)) + *(.dram1 .dram1.*) + _edata = ABSOLUTE(.); + . = ALIGN(4); + + _srodata = ABSOLUTE(.); + *(.rodata) + *(.rodata.*) + *(.irom1.text) /* catch stray ICACHE_RODATA_ATTR */ + *(.gnu.linkonce.r.*) + *(.rodata1) + __XT_EXCEPTION_TABLE_ = ABSOLUTE(.); + *(.xt_except_table) + *(.gcc_except_table) + *(.gnu.linkonce.e.*) + *(.gnu.version_r) + *(.eh_frame) + + . = (. + 3) & ~ 3; + + /* C++ constructor and destructor tables, properly ordered: */ + + _sinit = ABSOLUTE(.); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + _einit = ABSOLUTE(.); + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + + /* C++ exception handlers table: */ + + __XT_EXCEPTION_DESCS_ = ABSOLUTE(.); + *(.xt_except_desc) + *(.gnu.linkonce.h.*) + __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); + *(.xt_except_desc_end) + *(.dynamic) + *(.gnu.version_d) + _erodata = ABSOLUTE(.); + /* Literals are also RO data. */ + _lit4_start = ABSOLUTE(.); + *(*.lit4) + *(.lit4.*) + *(.gnu.linkonce.lit4.*) + _lit4_end = ABSOLUTE(.); + . = ALIGN(4); + + /* Heap starts at the end of .data */ + + _sheap = ABSOLUTE(.); + } >dram0_0_seg + + .flash.rodata : + { + } >drom0_0_seg + + .rtc.text : + { + . = ALIGN(4); + *(.rtc.literal .rtc.text) + } >rtc_iram_seg + + .rtc.data : + { + *(.rtc.data) + *(.rtc.rodata) + } > rtc_slow_seg +} diff --git a/configs/esp32-core/smp/Make.defs b/configs/esp32-core/smp/Make.defs index f8901d0f8b..8b4dd25b40 100644 --- a/configs/esp32-core/smp/Make.defs +++ b/configs/esp32-core/smp/Make.defs @@ -38,10 +38,15 @@ include ${TOPDIR}/tools/Config.mk include ${TOPDIR}/arch/xtensa/src/lx6/Toolchain.defs LDSCRIPT1 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_out.ld -LDSCRIPT2 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_common.ld LDSCRIPT3 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_rom.ld LDSCRIPT4 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_peripherals.ld +ifeq ($(CONFIG_ESP32CORE_RUN_IRAM),y) + LDSCRIPT2 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_iram.ld +else + LDSCRIPT2 = $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/esp32_flash.ld +endif + ifeq ($(WINTOOL),y) # Windows-native toolchains DIRLINK = $(TOPDIR)/tools/copydir.sh From 4545af3249485271ad91da1a3200fad35ad134de Mon Sep 17 00:00:00 2001 From: Eunbong Song Date: Tue, 15 Nov 2016 06:47:59 -0600 Subject: [PATCH 148/155] sleep() was returning remaining nanoseconds (kind of), instead the remaining seconds. --- libc/unistd/lib_sleep.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/libc/unistd/lib_sleep.c b/libc/unistd/lib_sleep.c index 785d76b63b..70f763f0ce 100644 --- a/libc/unistd/lib_sleep.c +++ b/libc/unistd/lib_sleep.c @@ -45,26 +45,6 @@ #include #include -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Type Definitions - ****************************************************************************/ - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -150,7 +130,7 @@ unsigned int sleep(unsigned int seconds) if (ret < 0) { - remaining = rmtp.tv_nsec; + remaining = rmtp.tv_sec; if (remaining < seconds && rmtp.tv_nsec >= 500000000) { /* Round up */ From a2531cea0c2c276d9054bfa6a21e36513b01088d Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 15 Nov 2016 07:28:37 -0600 Subject: [PATCH 149/155] ESP32: Refresh configurations, update README --- configs/esp32-core/README.txt | 22 ++++++++++++++++------ configs/esp32-core/nsh/defconfig | 5 +++-- configs/esp32-core/smp/defconfig | 12 ++++++++---- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 59636eb113..193a51a7dd 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -169,7 +169,7 @@ Memory Map Serial Console ============== - USART0 is, by default, the serial console. It connects to the on-board + UART0 is, by default, the serial console. It connects to the on-board CP2102 converter and is available on the USB connector USB CON8 (J1). Buttons and LEDs @@ -532,14 +532,24 @@ NOTES: 1. These configurations use the mconf-based configuration tool. To change any of these configurations using that tool, you should: - a. Build and install the kconfig-mconf tool. See nuttx/README.txt - see additional README.txt files in the NuttX tools repository. + a. Build and install the kconfig-mconf tool. See nuttx/README.txt + see additional README.txt files in the NuttX tools repository. - b. Execute 'make menuconfig' in nuttx/ in order to start the - reconfiguration process. + b. Execute 'make menuconfig' in nuttx/ in order to start the + reconfiguration process. 2. Unless stated otherwise, all configurations generate console - output on [To be provided]. + output on UART0 (see the "Serial Console" section above). + + 3. By default, these configurations assume a 40MHz crystal on- + board: + + CONFIG_ESP32CORE_XTAL_40MZ=y + # CONFIG_ESP32CORE_XTAL_26MHz is not set + + 4. Default configurations are set to run from FLASH. You will need + to set CONFIG_ESP32CORE_RUN_IRAM=y for now (see the " Executing + and Debugging from FLASH and IRAM" section above). Configuration sub-directories ----------------------------- diff --git a/configs/esp32-core/nsh/defconfig b/configs/esp32-core/nsh/defconfig index 2d68310f33..18cdefc0be 100644 --- a/configs/esp32-core/nsh/defconfig +++ b/configs/esp32-core/nsh/defconfig @@ -172,7 +172,8 @@ CONFIG_ARCH_BOARD="esp32-core" # Board-Specific Options # CONFIG_ESP32CORE_XTAL_40MZ=y -# CONFIG_ESP32CORE_XTAL26MHz is not set +# CONFIG_ESP32CORE_XTAL_26MHz is not set +# CONFIG_ESP32CORE_RUN_IRAM is not set # CONFIG_BOARD_CRASHDUMP is not set # CONFIG_LIB_BOARDCTL is not set @@ -599,10 +600,10 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 CONFIG_EXAMPLES_NSH=y CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set diff --git a/configs/esp32-core/smp/defconfig b/configs/esp32-core/smp/defconfig index 403a5e3c8d..d9641480ce 100644 --- a/configs/esp32-core/smp/defconfig +++ b/configs/esp32-core/smp/defconfig @@ -62,6 +62,7 @@ CONFIG_DEBUG_FULLOPT=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_RISCV is not set @@ -170,6 +171,9 @@ CONFIG_ARCH_BOARD="esp32-core" # # Board-Specific Options # +CONFIG_ESP32CORE_XTAL_40MZ=y +# CONFIG_ESP32CORE_XTAL_26MHz is not set +# CONFIG_ESP32CORE_RUN_IRAM is not set # CONFIG_BOARD_CRASHDUMP is not set # CONFIG_LIB_BOARDCTL is not set @@ -302,14 +306,14 @@ CONFIG_DEV_NULL=y # CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set CONFIG_SPI=y +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_SPI_SLAVE is not set CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CMDDATA is not set # CONFIG_SPI_CALLBACK is not set # CONFIG_SPI_HWFEATURES is not set -# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set -# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set -# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_SPI_DRIVER is not set # CONFIG_SPI_BITBANG is not set @@ -599,10 +603,10 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 CONFIG_EXAMPLES_NSH=y CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NULL is not set +# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set -# CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set From e2f999a5df3d3e188ca69ffe375ea320b33d0992 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 15 Nov 2016 07:35:30 -0600 Subject: [PATCH 150/155] Update Changelog --- configs/sabre-6quad/README.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configs/sabre-6quad/README.txt b/configs/sabre-6quad/README.txt index f94614ae63..beb140cd8b 100644 --- a/configs/sabre-6quad/README.txt +++ b/configs/sabre-6quad/README.txt @@ -498,6 +498,15 @@ Open Issues: CPU (which may not be CPU0). Perhaps that should be a spinlock to prohibit execution of interrupts on CPU0 when other CPUs are in a critical section? + 2016-11-15: When the critical section is used to lock a resource that is also + used by interupt handling, I believe that what is required is that the interrupt + handling logic must also take the spinlock. This will cause the interrupt handlers + on other CPUs to spin until leave_critical_section() is called. + + NOTE: Currently enter_critical section takes the spinlock before disabling + (local) interrupts. That orderwould have to change or you could potentially get + deadlocks if the interrupt handler on the same CPU tries to take the spinlock. + 2. Cache Concurency. This is a complex problem. There is logic in place now to clean CPU0 D-cache before starting a new CPU and for invalidating the D-Cache when the new CPU is started. REVISIT: Seems that this should not be necessary. From b53866c8729590c9d585d624cd905cde79c86549 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 15 Nov 2016 07:54:18 -0600 Subject: [PATCH 151/155] sched/irq: Change order for SMP case in enter_critical_section: Disble local interrupts BEFORE taking spinlock. --- configs/sabre-6quad/README.txt | 4 ---- configs/sabre-6quad/nsh/defconfig | 37 ++++++++++++++++++++++++++----- configs/sabre-6quad/smp/defconfig | 36 +++++++++++++++++++++++++----- sched/irq/irq_csection.c | 21 ++++++++++++++---- 4 files changed, 80 insertions(+), 18 deletions(-) diff --git a/configs/sabre-6quad/README.txt b/configs/sabre-6quad/README.txt index beb140cd8b..e784bae735 100644 --- a/configs/sabre-6quad/README.txt +++ b/configs/sabre-6quad/README.txt @@ -503,10 +503,6 @@ Open Issues: handling logic must also take the spinlock. This will cause the interrupt handlers on other CPUs to spin until leave_critical_section() is called. - NOTE: Currently enter_critical section takes the spinlock before disabling - (local) interrupts. That orderwould have to change or you could potentially get - deadlocks if the interrupt handler on the same CPU tries to take the spinlock. - 2. Cache Concurency. This is a complex problem. There is logic in place now to clean CPU0 D-cache before starting a new CPU and for invalidating the D-Cache when the new CPU is started. REVISIT: Seems that this should not be necessary. diff --git a/configs/sabre-6quad/nsh/defconfig b/configs/sabre-6quad/nsh/defconfig index ee0f283912..dfc9ef8d6f 100644 --- a/configs/sabre-6quad/nsh/defconfig +++ b/configs/sabre-6quad/nsh/defconfig @@ -64,10 +64,13 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -260,11 +263,11 @@ CONFIG_ARCH_HAVE_BUTTONS=y CONFIG_ARCH_BUTTONS=y CONFIG_ARCH_HAVE_IRQBUTTONS=y CONFIG_ARCH_IRQBUTTONS=y -CONFIG_NSH_MMCSDMINOR=0 # # Board-Specific Options # +# CONFIG_BOARD_CRASHDUMP is not set CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_UNIQUEID is not set # CONFIG_BOARDCTL_TSCTEST is not set @@ -289,6 +292,7 @@ CONFIG_DISABLE_OS_API=y CONFIG_USEC_PER_TICK=10000 # CONFIG_SYSTEM_TIME64 is not set # CONFIG_CLOCK_MONOTONIC is not set +# CONFIG_ARCH_HAVE_TIMEKEEPING is not set # CONFIG_JULIAN_TIME is not set CONFIG_START_YEAR=2016 CONFIG_START_MONTH=3 @@ -301,6 +305,7 @@ CONFIG_PREALLOC_TIMERS=4 # # Tasks and Scheduling # +# CONFIG_SMP is not set # CONFIG_INIT_NONE is not set CONFIG_INIT_ENTRYPOINT=y # CONFIG_INIT_FILEPATH is not set @@ -386,6 +391,7 @@ CONFIG_PTHREAD_STACK_DEFAULT=2048 # CONFIG_DISABLE_POLL is not set CONFIG_DEV_NULL=y CONFIG_DEV_ZERO=y +# CONFIG_DEV_URANDOM is not set # CONFIG_DEV_LOOP is not set # @@ -401,12 +407,16 @@ CONFIG_DEV_ZERO=y # CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_I2S is not set # # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set @@ -414,7 +424,12 @@ CONFIG_DEV_ZERO=y # CONFIG_VIDEO_DEVICES is not set # CONFIG_BCH is not set # CONFIG_INPUT is not set + +# +# IO Expander/GPIO Support +# # CONFIG_IOEXPANDER is not set +# CONFIG_DEV_GPIO is not set # # LCD Driver Support @@ -488,9 +503,12 @@ CONFIG_UART1_2STOP=0 # CONFIG_UART1_IFLOWCONTROL is not set # CONFIG_UART1_OFLOWCONTROL is not set # CONFIG_UART1_DMA is not set +# CONFIG_PSEUDOTERM is not set # CONFIG_USBDEV is not set # CONFIG_USBHOST is not set +# CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -511,6 +529,7 @@ CONFIG_RAMLOG_SYSLOG=y # CONFIG_SYSLOG_NONE is not set # CONFIG_SYSLOG_FILE is not set # CONFIG_CONSOLE_SYSLOG is not set +# CONFIG_SYSLOG_CHARDEV is not set # # Networking Support @@ -606,6 +625,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -633,6 +654,7 @@ CONFIG_ARCH_HAVE_TLS=y # CONFIG_LIB_CRC64_FAST is not set # CONFIG_LIB_KBDCODEC is not set # CONFIG_LIB_SLCDCODEC is not set +# CONFIG_LIB_HEX2BIN is not set # # Basic CXX Support @@ -663,10 +685,11 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # # Examples # +# CONFIG_EXAMPLES_ARCHBUTTONS is not set # CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set -# CONFIG_EXAMPLES_CPUHOG is not set # CONFIG_EXAMPLES_CXXTEST is not set # CONFIG_EXAMPLES_DHCPD is not set # CONFIG_EXAMPLES_ELF is not set @@ -695,9 +718,9 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NXTEXT is not set # CONFIG_EXAMPLES_OSTEST is not set # CONFIG_EXAMPLES_PCA9635 is not set -# CONFIG_EXAMPLES_PIPE is not set # CONFIG_EXAMPLES_POSIXSPAWN is not set # CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set # CONFIG_EXAMPLES_RGBLED is not set # CONFIG_EXAMPLES_RGMP is not set # CONFIG_EXAMPLES_SENDMAIL is not set @@ -740,6 +763,7 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_INTERPRETERS_BAS is not set # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -806,12 +830,12 @@ CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_LS is not set # CONFIG_NSH_DISABLE_MB is not set # CONFIG_NSH_DISABLE_MKDIR is not set -# CONFIG_NSH_DISABLE_MKFIFO is not set # CONFIG_NSH_DISABLE_MKRD is not set # CONFIG_NSH_DISABLE_MH is not set # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set # CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y # CONFIG_NSH_DISABLE_PS is not set # CONFIG_NSH_DISABLE_PUT is not set # CONFIG_NSH_DISABLE_PWD is not set @@ -828,6 +852,7 @@ CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_USLEEP is not set # CONFIG_NSH_DISABLE_WGET is not set # CONFIG_NSH_DISABLE_XD is not set +CONFIG_NSH_MMCSDMINOR=0 # # Configure Command Options @@ -869,7 +894,7 @@ CONFIG_NSH_ARCHINIT=y # CONFIG_SYSTEM_CLE is not set # CONFIG_SYSTEM_CUTERM is not set # CONFIG_SYSTEM_FREE is not set -# CONFIG_LIB_HEX2BIN is not set +# CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set # CONFIG_SYSTEM_INSTALL is not set # CONFIG_SYSTEM_RAMTEST is not set @@ -879,6 +904,8 @@ CONFIG_READLINE_ECHO=y # CONFIG_READLINE_TABCOMPLETION is not set # CONFIG_READLINE_CMD_HISTORY is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_SYSTEM is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set diff --git a/configs/sabre-6quad/smp/defconfig b/configs/sabre-6quad/smp/defconfig index 4205d00781..23afd07fe9 100644 --- a/configs/sabre-6quad/smp/defconfig +++ b/configs/sabre-6quad/smp/defconfig @@ -64,10 +64,13 @@ CONFIG_ARCH_ARM=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" @@ -263,11 +266,11 @@ CONFIG_ARCH_HAVE_BUTTONS=y CONFIG_ARCH_BUTTONS=y CONFIG_ARCH_HAVE_IRQBUTTONS=y CONFIG_ARCH_IRQBUTTONS=y -CONFIG_NSH_MMCSDMINOR=0 # # Board-Specific Options # +# CONFIG_BOARD_CRASHDUMP is not set CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_UNIQUEID is not set # CONFIG_BOARDCTL_TSCTEST is not set @@ -292,6 +295,7 @@ CONFIG_DISABLE_OS_API=y CONFIG_USEC_PER_TICK=10000 # CONFIG_SYSTEM_TIME64 is not set # CONFIG_CLOCK_MONOTONIC is not set +# CONFIG_ARCH_HAVE_TIMEKEEPING is not set # CONFIG_JULIAN_TIME is not set CONFIG_START_YEAR=2016 CONFIG_START_MONTH=3 @@ -393,6 +397,7 @@ CONFIG_PTHREAD_STACK_DEFAULT=2048 # CONFIG_DISABLE_POLL is not set CONFIG_DEV_NULL=y CONFIG_DEV_ZERO=y +# CONFIG_DEV_URANDOM is not set # CONFIG_DEV_LOOP is not set # @@ -408,12 +413,16 @@ CONFIG_DEV_ZERO=y # CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_I2S is not set # # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set @@ -421,7 +430,12 @@ CONFIG_DEV_ZERO=y # CONFIG_VIDEO_DEVICES is not set # CONFIG_BCH is not set # CONFIG_INPUT is not set + +# +# IO Expander/GPIO Support +# # CONFIG_IOEXPANDER is not set +# CONFIG_DEV_GPIO is not set # # LCD Driver Support @@ -495,9 +509,12 @@ CONFIG_UART1_2STOP=0 # CONFIG_UART1_IFLOWCONTROL is not set # CONFIG_UART1_OFLOWCONTROL is not set # CONFIG_UART1_DMA is not set +# CONFIG_PSEUDOTERM is not set # CONFIG_USBDEV is not set # CONFIG_USBHOST is not set +# CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -518,6 +535,7 @@ CONFIG_RAMLOG_SYSLOG=y # CONFIG_SYSLOG_NONE is not set # CONFIG_SYSLOG_FILE is not set # CONFIG_CONSOLE_SYSLOG is not set +# CONFIG_SYSLOG_CHARDEV is not set # # Networking Support @@ -614,6 +632,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -641,6 +661,7 @@ CONFIG_ARCH_HAVE_TLS=y # CONFIG_LIB_CRC64_FAST is not set # CONFIG_LIB_KBDCODEC is not set # CONFIG_LIB_SLCDCODEC is not set +# CONFIG_LIB_HEX2BIN is not set # # Basic CXX Support @@ -671,10 +692,11 @@ CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # # Examples # +# CONFIG_EXAMPLES_ARCHBUTTONS is not set # CONFIG_EXAMPLES_BUTTONS is not set +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set -# CONFIG_EXAMPLES_CPUHOG is not set # CONFIG_EXAMPLES_CXXTEST is not set # CONFIG_EXAMPLES_DHCPD is not set # CONFIG_EXAMPLES_ELF is not set @@ -703,9 +725,9 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NXTEXT is not set # CONFIG_EXAMPLES_OSTEST is not set # CONFIG_EXAMPLES_PCA9635 is not set -# CONFIG_EXAMPLES_PIPE is not set # CONFIG_EXAMPLES_POSIXSPAWN is not set # CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set # CONFIG_EXAMPLES_RGBLED is not set # CONFIG_EXAMPLES_RGMP is not set # CONFIG_EXAMPLES_SENDMAIL is not set @@ -748,6 +770,7 @@ CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_INTERPRETERS_BAS is not set # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -814,12 +837,12 @@ CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_LS is not set # CONFIG_NSH_DISABLE_MB is not set # CONFIG_NSH_DISABLE_MKDIR is not set -# CONFIG_NSH_DISABLE_MKFIFO is not set # CONFIG_NSH_DISABLE_MKRD is not set # CONFIG_NSH_DISABLE_MH is not set # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set # CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y # CONFIG_NSH_DISABLE_PS is not set # CONFIG_NSH_DISABLE_PUT is not set # CONFIG_NSH_DISABLE_PWD is not set @@ -836,6 +859,7 @@ CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_USLEEP is not set # CONFIG_NSH_DISABLE_WGET is not set # CONFIG_NSH_DISABLE_XD is not set +CONFIG_NSH_MMCSDMINOR=0 # # Configure Command Options @@ -877,7 +901,7 @@ CONFIG_NSH_ARCHINIT=y # CONFIG_SYSTEM_CLE is not set # CONFIG_SYSTEM_CUTERM is not set # CONFIG_SYSTEM_FREE is not set -# CONFIG_LIB_HEX2BIN is not set +# CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set # CONFIG_SYSTEM_INSTALL is not set # CONFIG_SYSTEM_RAMTEST is not set @@ -887,6 +911,8 @@ CONFIG_READLINE_ECHO=y # CONFIG_READLINE_TABCOMPLETION is not set # CONFIG_READLINE_CMD_HISTORY is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_SYSTEM is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index 4cc2412ae7..115b717a18 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -86,6 +86,21 @@ volatile cpu_set_t g_cpu_irqset; irqstate_t enter_critical_section(void) { FAR struct tcb_s *rtcb; + irqstate_t ret; + + /* Disable interrupts. + * + * NOTE 1: Ideally this should disable interrupts on all CPUs, but most + * architectures only support disabling interrupts on the local CPU. + * NOTE 2: Interrupts may already be disabled, but we call up_irq_save() + * unconditionally because we need to return valid interrupt status in any + * event. + * NOTE 3: We disable local interrupts BEFORE taking the spinlock in order + * to prevent possible waits on the spinlock from interrupt handling on + * the local CPU. + */ + + ret = up_irq_save(); /* Check if we were called from an interrupt handler and that the tasks * lists have been initialized. @@ -133,11 +148,9 @@ irqstate_t enter_critical_section(void) } } - /* Then disable interrupts (they may already be disabled, be we need to - * return valid interrupt status in any event). - */ + /* Return interrupt status */ - return up_irq_save(); + return ret; } #else /* defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION) */ irqstate_t enter_critical_section(void) From 65ab12fbb90accd50bd5602660394568ed18a1a2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 15 Nov 2016 08:37:58 -0600 Subject: [PATCH 152/155] If SMP is enabled, if any interrupt handler calls enter_critical_section(), it should take the spinlock. --- sched/irq/irq_csection.c | 167 ++++++++++++++++++++++++--------------- 1 file changed, 104 insertions(+), 63 deletions(-) diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index 115b717a18..29b917d7b1 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -102,51 +102,72 @@ irqstate_t enter_critical_section(void) ret = up_irq_save(); - /* Check if we were called from an interrupt handler and that the tasks - * lists have been initialized. + /* Verify that the system has sufficient initialized so that the task lists + * are valid. */ - if (!up_interrupt_context() && g_os_initstate >= OSINIT_TASKLISTS) + if (g_os_initstate >= OSINIT_TASKLISTS) { - /* Do we already have interrupts disabled? */ + /* If called from an interrupt handler, then just take the spinlock. + * If we are already in a critical section, this will lock the CPU + * in the interrupt handler. Sounds worse than it is. + */ - rtcb = this_task(); - DEBUGASSERT(rtcb != NULL); - - if (rtcb->irqcount > 0) + if (up_interrupt_context()) { - /* Yes... make sure that the spinlock is set and increment the IRQ - * lock count. + /* We are in an interrupt handler but within a critical section. + * Wait until we can get the spinlock (meaning that we are no + * longer in the critical section). */ - DEBUGASSERT(g_cpu_irqlock == SP_LOCKED && rtcb->irqcount < INT16_MAX); - rtcb->irqcount++; + spin_lock(&g_cpu_irqlock); } else { - /* NO.. Take the spinlock to get exclusive access and set the lock - * count to 1. - * - * We must avoid that case where a context occurs between taking the - * g_cpu_irqlock and disabling interrupts. Also interrupts disables - * must follow a stacked order. We cannot other context switches to - * re-order the enabling/disabling of interrupts. - * - * The scheduler accomplishes this by treating the irqcount like - * lockcount: Both will disable pre-emption. - */ + /* Normal tasking environment. */ + /* Do we already have interrupts disabled? */ - spin_setbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock, - &g_cpu_irqlock); - rtcb->irqcount = 1; + rtcb = this_task(); + DEBUGASSERT(rtcb != NULL); + + if (rtcb->irqcount > 0) + { + /* Yes... make sure that the spinlock is set and increment the + * IRQ lock count. + */ + + DEBUGASSERT(g_cpu_irqlock == SP_LOCKED && + rtcb->irqcount < INT16_MAX); + rtcb->irqcount++; + } + else + { + /* NO.. Take the spinlock to get exclusive access and set the + * lock count to 1. + * + * We must avoid that case where a context occurs between + * taking the g_cpu_irqlock and disabling interrupts. Also + * interrupts disables must follow a stacked order. We + * cannot other context switches to re-order the enabling/ + * disabling of interrupts. + * + * The scheduler accomplishes this by treating the irqcount + * like lockcount: Both will disable pre-emption. + */ + + spin_setbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock, + &g_cpu_irqlock); + rtcb->irqcount = 1; #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - /* Note that we have entered the critical section */ + /* Note that we have entered the critical section */ - sched_note_csection(rtcb, true); + sched_note_csection(rtcb, true); #endif + } } - } + } + /* Return interrupt status */ @@ -187,59 +208,79 @@ irqstate_t enter_critical_section(void) #ifdef CONFIG_SMP void leave_critical_section(irqstate_t flags) { - /* Check if we were called from an interrupt handler and that the tasks - * lists have been initialized. + /* Verify that the system has sufficient initialized so that the task lists + * are valid. */ - if (!up_interrupt_context() && g_os_initstate >= OSINIT_TASKLISTS) + if (g_os_initstate >= OSINIT_TASKLISTS) { - FAR struct tcb_s *rtcb = this_task(); - DEBUGASSERT(rtcb != 0 && rtcb->irqcount > 0); - - /* Will we still have interrupts disabled after decrementing the - * count? + /* If called from an interrupt handler, then just take the spinlock. + * If we are already in a critical section, this will lock the CPU + * in the interrupt handler. Sounds worse than it is. */ - if (rtcb->irqcount > 1) + if (up_interrupt_context()) { - /* Yes... make sure that the spinlock is set */ + /* We are in an interrupt handler but within a critical section. + * Wait until we can get the spinlock (meaning that we are no + * longer in the critical section). + */ DEBUGASSERT(g_cpu_irqlock == SP_LOCKED); - rtcb->irqcount--; + spin_unlock(&g_cpu_irqlock); } else { -#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - /* No.. Note that we have entered the critical section */ + FAR struct tcb_s *rtcb = this_task(); + DEBUGASSERT(rtcb != 0 && rtcb->irqcount > 0); - sched_note_csection(rtcb, false); -#endif - /* Decrement our count on the lock. If all CPUs have released, - * then unlock the spinlock. - */ + /* Normal tasking context */ + /* Will we still have interrupts disabled after decrementing the + * count? + */ - rtcb->irqcount = 0; - spin_clrbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock, - &g_cpu_irqlock); - - /* Have all CPUs release the lock? */ - - if (!spin_islocked(&g_cpu_irqlock)) + if (rtcb->irqcount > 1) { - /* Check if there are pending tasks and that pre-emption is - * also enabled. + /* Yes... make sure that the spinlock is set */ + + DEBUGASSERT(g_cpu_irqlock == SP_LOCKED); + rtcb->irqcount--; + } + else + { +#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION + /* No.. Note that we have entered the critical section */ + + sched_note_csection(rtcb, false); +#endif + /* Decrement our count on the lock. If all CPUs have + * released, then unlock the spinlock. */ - if (g_pendingtasks.head != NULL && !spin_islocked(&g_cpu_schedlock)) + rtcb->irqcount = 0; + spin_clrbit(&g_cpu_irqset, this_cpu(), &g_cpu_irqsetlock, + &g_cpu_irqlock); + + /* Have all CPUs release the lock? */ + + if (!spin_islocked(&g_cpu_irqlock)) { - /* Release any ready-to-run tasks that have collected in - * g_pendingtasks if the scheduler is not locked. - * - * NOTE: This operation has a very high likelihood of causing - * this task to be switched out! + /* Check if there are pending tasks and that pre-emption + * is also enabled. */ - up_release_pending(); + if (g_pendingtasks.head != NULL && + !spin_islocked(&g_cpu_schedlock)) + { + /* Release any ready-to-run tasks that have collected + * in g_pendingtasks if the scheduler is not locked. + * + * NOTE: This operation has a very high likelihood of + * causing this task to be switched out! + */ + + up_release_pending(); + } } } } From 21f92ba601f8286b057f4fc9c1582eef4018fd06 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 15 Nov 2016 09:24:00 -0600 Subject: [PATCH 153/155] Review some SMP logic; update comments; refresh configuration. --- configs/sim/README.txt | 3 --- configs/sim/ostest/defconfig | 22 +++++++++++++++++++--- sched/irq/irq_csection.c | 28 ++++++++++++++++------------ 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/configs/sim/README.txt b/configs/sim/README.txt index df8a231553..e3712b11f9 100644 --- a/configs/sim/README.txt +++ b/configs/sim/README.txt @@ -243,9 +243,6 @@ SMP You can enable SMP for ostest configuration by enabling: - -# CONFIG_EXPERIMENTAL is not set - +CONFIG_EXPERIMENTAL=y - +CONFIG_SPINLOCK=y +CONFIG_SMP=y +CONFIG_SMP_NCPUS=2 diff --git a/configs/sim/ostest/defconfig b/configs/sim/ostest/defconfig index e48035058d..182af156ed 100644 --- a/configs/sim/ostest/defconfig +++ b/configs/sim/ostest/defconfig @@ -58,10 +58,13 @@ CONFIG_DEBUG_NOOPT=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_MISOC is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_RISCV is not set CONFIG_ARCH_SIM=y # CONFIG_ARCH_X86 is not set +# CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="sim" @@ -79,6 +82,7 @@ CONFIG_SIM_NET_HOST_ROUTE=y # CONFIG_SIM_NET_BRIDGE is not set # CONFIG_SIM_FRAMEBUFFER is not set # CONFIG_SIM_SPIFLASH is not set +# CONFIG_SIM_QSPIFLASH is not set # # Architecture Options @@ -168,6 +172,7 @@ CONFIG_ARCH_HAVE_TICKLESS=y CONFIG_USEC_PER_TICK=10000 # CONFIG_SYSTEM_TIME64 is not set # CONFIG_CLOCK_MONOTONIC is not set +# CONFIG_ARCH_HAVE_TIMEKEEPING is not set # CONFIG_JULIAN_TIME is not set CONFIG_START_YEAR=2007 CONFIG_START_MONTH=2 @@ -180,6 +185,7 @@ CONFIG_PREALLOC_TIMERS=8 # # Tasks and Scheduling # +# CONFIG_SMP is not set # CONFIG_INIT_NONE is not set CONFIG_INIT_ENTRYPOINT=y # CONFIG_INIT_FILEPATH is not set @@ -262,6 +268,7 @@ CONFIG_PTHREAD_STACK_DEFAULT=8192 CONFIG_DISABLE_POLL=y CONFIG_DEV_NULL=y # CONFIG_DEV_ZERO is not set +# CONFIG_DEV_URANDOM is not set # CONFIG_DEV_LOOP is not set # @@ -277,12 +284,16 @@ CONFIG_DEV_NULL=y # CONFIG_ARCH_HAVE_I2CRESET is not set # CONFIG_I2C is not set # CONFIG_SPI is not set +# CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set +# CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set +# CONFIG_ARCH_HAVE_SPI_BITORDER is not set # CONFIG_I2S is not set # # Timer Driver Support # # CONFIG_TIMER is not set +# CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set @@ -351,10 +362,12 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_OFLOWCONTROL is not set # CONFIG_SERIAL_DMA is not set # CONFIG_ARCH_HAVE_SERIAL_TERMIOS is not set +# CONFIG_PSEUDOTERM is not set # CONFIG_USBDEV is not set # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set +# CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging @@ -456,6 +469,8 @@ CONFIG_LIB_HOMEDIR="/" # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set +# CONFIG_LIBC_WCHAR is not set +# CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set @@ -501,9 +516,9 @@ CONFIG_ARCH_HAVE_TLS=y # # Examples # +# CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set -# CONFIG_EXAMPLES_CPUHOG is not set # CONFIG_EXAMPLES_DHCPD is not set # CONFIG_EXAMPLES_ELF is not set # CONFIG_EXAMPLES_FTPC is not set @@ -535,10 +550,9 @@ CONFIG_EXAMPLES_OSTEST_RR_RANGE=10000 CONFIG_EXAMPLES_OSTEST_RR_RUNS=10 CONFIG_EXAMPLES_OSTEST_WAITRESULT=y # CONFIG_EXAMPLES_PCA9635 is not set -# CONFIG_EXAMPLES_PIPE is not set -# CONFIG_EXAMPLES_POLL is not set # CONFIG_EXAMPLES_POSIXSPAWN is not set # CONFIG_EXAMPLES_PPPD is not set +# CONFIG_EXAMPLES_RFID_READUID is not set # CONFIG_EXAMPLES_RGBLED is not set # CONFIG_EXAMPLES_RGMP is not set # CONFIG_EXAMPLES_SENDMAIL is not set @@ -577,6 +591,7 @@ CONFIG_EXAMPLES_OSTEST_WAITRESULT=y # # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set +# CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # @@ -620,6 +635,7 @@ CONFIG_EXAMPLES_OSTEST_WAITRESULT=y # CONFIG_READLINE_HAVE_EXTMATCH is not set # CONFIG_SYSTEM_READLINE is not set # CONFIG_SYSTEM_SUDOKU is not set +# CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index 29b917d7b1..67383f4019 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -214,34 +214,38 @@ void leave_critical_section(irqstate_t flags) if (g_os_initstate >= OSINIT_TASKLISTS) { - /* If called from an interrupt handler, then just take the spinlock. - * If we are already in a critical section, this will lock the CPU - * in the interrupt handler. Sounds worse than it is. + /* If called from an interrupt handler, then just release the + * spinlock. The interrupt handling logic should already hold the + * spinlock if enter_critical_section() has been called. Unlocking + * the spinlock will allow interrupt handlers on other CPUs to execute + * again. */ if (up_interrupt_context()) { - /* We are in an interrupt handler but within a critical section. - * Wait until we can get the spinlock (meaning that we are no - * longer in the critical section). - */ + /* We are in an interrupt handler. Release the spinlock. */ DEBUGASSERT(g_cpu_irqlock == SP_LOCKED); - spin_unlock(&g_cpu_irqlock); + if (g_cpu_irqset == 0) + { + spin_unlock(&g_cpu_irqlock); + } } else { FAR struct tcb_s *rtcb = this_task(); DEBUGASSERT(rtcb != 0 && rtcb->irqcount > 0); - /* Normal tasking context */ - /* Will we still have interrupts disabled after decrementing the + /* Normal tasking context. We need to coordinate with other + * tasks. + * + * Will we still have interrupts disabled after decrementing the * count? - */ + */ if (rtcb->irqcount > 1) { - /* Yes... make sure that the spinlock is set */ + /* Yes... the spinlock should remain set */ DEBUGASSERT(g_cpu_irqlock == SP_LOCKED); rtcb->irqcount--; From 23d2915179986f33e6b1444529ba61c2a6ad3d56 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 15 Nov 2016 13:25:30 -0600 Subject: [PATCH 154/155] Update README --- configs/esp32-core/README.txt | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/configs/esp32-core/README.txt b/configs/esp32-core/README.txt index 193a51a7dd..0688c2aad7 100644 --- a/configs/esp32-core/README.txt +++ b/configs/esp32-core/README.txt @@ -285,8 +285,8 @@ OpenOCD for the ESP32 If you do not do the install step, then you will have a localhost version of the OpenOCD binary at openocd-esp32/src. - Running OpenOCD - -------------- + Starting the OpenOCD Server + --------------------------- - cd to openocd-esp32 directory - copy the modified esp32.cfg script to this directory @@ -411,6 +411,18 @@ OpenOCD for the ESP32 Executing and Debugging from FLASH and IRAM =========================================== + Enable Debug Symbols + -------------------- + To debug with GDB, you will need to enable symbols in the build. You do this + with 'make menuconfig' then selecting: + + - "Build Setup" -> "Debug Options" -> "Generate Debug Symbols" + + And, to make debugging easier, also disable optimizations. This will make + your code a lot bigger: + + - "Build Setup" -> "Optimization Level" -> "Suppress Optimization" + FLASH ----- OpenOCD currently doesn't have a FLASH driver for ESP32, so you can load @@ -477,11 +489,11 @@ OpenOCD for the ESP32 for flashing into the board. The command should to convert ELF file to binary image looks as follows: - python esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 elf2image --flash_mode "dio" --flash_freq "40m" --flash_size "2MB" -o app.bin app.elf + python esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 elf2image --flash_mode "dio" --flash_freq "40m" --flash_size "2MB" -o nuttx.bin nuttx To flash binary image to your development board, use the same esptool.py utility: - python esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 write_flash -z --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 app.bin + python esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 --port /dev/ttyUSB0 --baud 921600 write_flash -z --flash_mode dio --flash_freq 40m --flash_size 2MB 0x1000 nuttx.bin The argument before app.bin (0x1000) indicates the offset in flash where binary will be written. ROM bootloader expects to find an application (or second stage @@ -551,6 +563,9 @@ NOTES: to set CONFIG_ESP32CORE_RUN_IRAM=y for now (see the " Executing and Debugging from FLASH and IRAM" section above). + To select this option, do 'make menuconfig'. Then you can find + the selection under the "Board Selection" menu as "Run from IRAM". + Configuration sub-directories ----------------------------- From 6683f014445f9ed062649a0e042f1054a98269c0 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 15 Nov 2016 13:38:43 -0600 Subject: [PATCH 155/155] Trivial change to comment --- sched/irq/irq_csection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index 67383f4019..ee1c7da234 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -253,7 +253,7 @@ void leave_critical_section(irqstate_t flags) else { #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - /* No.. Note that we have entered the critical section */ + /* No.. Note that we have left the critical section */ sched_note_csection(rtcb, false); #endif