add sdio driver for GD32F4

This commit is contained in:
GD32-MCU 2023-06-03 14:47:40 +08:00 committed by Xiang Xiao
parent 0a9279f672
commit fdfc25cf56
12 changed files with 3921 additions and 8 deletions

View file

@ -377,6 +377,10 @@ config GD32F4_PMU
config GD32F4_SDIO
bool "SDIO"
default n
select ARCH_HAVE_SDIO
select ARCH_HAVE_SDIOWAIT_WRCOMPLETE
select ARCH_HAVE_SDIO_PREFLIGHT
config GD32F4_SPI0
bool "SPI0"
@ -2135,6 +2139,35 @@ endmenu # RTC configuration
menu "SDIO Configuration"
depends on GD32F4_SDIO
config GD32F4_SDIO_CARD
bool "SDIO Card support"
default n
---help---
Build in additional support needed only for SDIO cards (vs. SD
memory cards)
config GD32F4_SDIO_PULLUP
bool "Enable internal Pull-Ups"
default n
---help---
If you are using an external SDCard module that does not have the
pull-up resistors for the SDIO interface (like the Gadgeteer SD Card
Module) then enable this option to activate the internal pull-up
resistors.
config GD32F4_SDIO_DMA
bool "Support DMA data transfers"
select SDIO_DMA
depends on GD32F4_DMA1
---help---
Support DMA data transfers. Requires GD32_SDIO and config GD32_DMA1.
config GD32F4_SDIO_WIDTH_D1_ONLY
bool "Use D1 only"
default n
---help---
Select 1-bit transfer mode. Default: 4-bit transfer mode.
endmenu

View file

@ -59,3 +59,6 @@ endif
ifeq ($(CONFIG_GD32F4_I2C),y)
CHIP_CSRCS += gd32f4xx_i2c.c
endif
ifeq ($(CONFIG_GD32F4_SDIO),y)
CHIP_CSRCS += gd32f4xx_sdio.c
endif

View file

@ -47,5 +47,6 @@
#include "gd32f4xx_spi.h"
#include "gd32f4xx_i2c.h"
#include "gd32f4xx_syscfg.h"
#include "gd32f4xx_sdio.h"
#endif /* __ARCH_ARM_SRC_GD32F4_GD32F4XX_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,134 @@
/****************************************************************************
* arch/arm/src/gd32f4/gd32f4xx_sdio.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_GD32F4_GD32F4XX_SDIO_H
#define __ARCH_ARM_SRC_GD32F4_GD32F4XX_SDIO_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdbool.h>
#include "chip.h"
#include "hardware/gd32f4xx_sdio.h"
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#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 Value:
* A reference to an SDIO interface structure. NULL is returned on
* failures.
*
****************************************************************************/
struct sdio_dev_s; /* See include/nuttx/sdio.h */
struct sdio_dev_s *sdio_initialize(int slotno);
/****************************************************************************
* Name: sdio_mediachange
*
* Description:
* Called by board-specific logic -- possibly 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 Value:
* None
*
****************************************************************************/
void sdio_mediachange(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 Value:
* None
*
****************************************************************************/
void sdio_wrprotect(struct sdio_dev_s *dev, bool wrprotect);
/****************************************************************************
* Name: sdio_set_sdio_card_isr
*
* Description:
* SDIO card generates interrupt via SDIO_DATA_1 pin.
* Called by board-specific logic to register an ISR for SDIO card.
*
* Input Parameters:
* func - callback function.
* arg - arg to be passed to the function.
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_GD32F4_SDIO_CARD
void sdio_set_sdio_card_isr(struct sdio_dev_s *dev,
int (*func)(void *), void *arg);
#endif
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* ARCH_ARM_SRC_GD32F4_GD32F4XX_SDIO_H */

View file

@ -0,0 +1,277 @@
/****************************************************************************
* arch/arm/src/gd32f4/hardware/gd32f4xx_sdio.h
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
#ifndef __ARCH_ARM_SRC_GD32F4_HARDWARE_GD32F4XX_SDIO_H
#define __ARCH_ARM_SRC_GD32F4_HARDWARE_GD32F4XX_SDIO_H
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Register Offsets *********************************************************/
#define GD32_SDIO_PWRCTL_OFFSET 0x0000 /* SDIO power control register offset */
#define GD32_SDIO_CLKCTL_OFFSET 0x0004 /* SDI clock control register offset*/
#define GD32_SDIO_CMDAGMT_OFFSET 0x0008 /* SDIO argument register offset*/
#define GD32_SDIO_CMDCTL_OFFSET 0x000C /* SDIO command register offset*/
#define GD32_SDIO_RSPCMDIDX_OFFSET 0x0010 /* SDIO command response register offset*/
#define GD32_SDIO_RESP0_OFFSET 0x0014 /* SDIO response register 0 offset*/
#define GD32_SDIO_RESP1_OFFSET 0x0018 /* SDIO response register 1 offset*/
#define GD32_SDIO_RESP2_OFFSET 0x001c /* SDIO response register 2 offset*/
#define GD32_SDIO_RESP3_OFFSET 0x0020 /* SDIO response register 3 offset*/
#define GD32_SDIO_DATATO_OFFSET 0x0024 /* SDIO data timeout register offset*/
#define GD32_SDIO_DATALEN_OFFSET 0x0028 /* SDIO data length register offset*/
#define GD32_SDIO_DATACTL_OFFSET 0x002c /* SDIO data control register offset*/
#define GD32_SDIO_DATACNT_OFFSET 0x0030 /* SDIO data counter register offset*/
#define GD32_SDIO_STAT_OFFSET 0x0034 /* SDIO status register offset*/
#define GD32_SDIO_INTC_OFFSET 0x0038 /* SDIO interrupt clear register offset*/
#define GD32_SDIO_INTEN_OFFSET 0x003c /* SDIO interrupt enable register offset */
#define GD32_SDIO_FIFOCNT_OFFSET 0x0048 /* SDIO FIFO counter register offset*/
#define GD32_SDIO_FIFO_OFFSET 0x0080 /* SDIO FIFO data register offset*/
/* Register Addresses *******************************************************/
#define GD32_SDIO_PWRCTL (GD32_SDIO_BASE+GD32_SDIO_PWRCTL_OFFSET) /* SDIO power control register */
#define GD32_SDIO_CLKCTL (GD32_SDIO_BASE+GD32_SDIO_CLKCTL_OFFSET) /* SDI clock control register */
#define GD32_SDIO_CMDAGMT (GD32_SDIO_BASE+GD32_SDIO_CMDAGMT_OFFSET) /* SDIO argument register */
#define GD32_SDIO_CMDCTL (GD32_SDIO_BASE+GD32_SDIO_CMDCTL_OFFSET) /* SDIO command register */
#define GD32_SDIO_RSPCMDIDX (GD32_SDIO_BASE+GD32_SDIO_RSPCMDIDX_OFFSET) /* SDIO command response register */
#define GD32_SDIO_RESP0 (GD32_SDIO_BASE+GD32_SDIO_RESP0_OFFSET) /* SDIO response register 0 */
#define GD32_SDIO_RESP1 (GD32_SDIO_BASE+GD32_SDIO_RESP1_OFFSET) /* SDIO response register 1 */
#define GD32_SDIO_RESP2 (GD32_SDIO_BASE+GD32_SDIO_RESP2_OFFSET) /* SDIO response register 2 */
#define GD32_SDIO_RESP3 (GD32_SDIO_BASE+GD32_SDIO_RESP3_OFFSET) /* SDIO response register 3 */
#define GD32_SDIO_DATATO (GD32_SDIO_BASE+GD32_SDIO_DATATO_OFFSET) /* SDIO data timeout register */
#define GD32_SDIO_DATALEN (GD32_SDIO_BASE+GD32_SDIO_DATALEN_OFFSET) /* SDIO data length register */
#define GD32_SDIO_DATACTL (GD32_SDIO_BASE+GD32_SDIO_DATACTL_OFFSET) /* SDIO data control register */
#define GD32_SDIO_DATACNT (GD32_SDIO_BASE+GD32_SDIO_DATACNT_OFFSET) /* SDIO data counter register */
#define GD32_SDIO_STAT (GD32_SDIO_BASE+GD32_SDIO_STAT_OFFSET) /* SDIO status register */
#define GD32_SDIO_INTC (GD32_SDIO_BASE+GD32_SDIO_INTC_OFFSET) /* SDIO interrupt clear register */
#define GD32_SDIO_INTEN (GD32_SDIO_BASE+GD32_SDIO_INTEN_OFFSET) /* SDIO interrupt enable register */
#define GD32_SDIO_FIFOCNT (GD32_SDIO_BASE+GD32_SDIO_FIFOCNT_OFFSET) /* SDIO FIFO counter register */
#define GD32_SDIO_FIFO (GD32_SDIO_BASE+GD32_SDIO_FIFO_OFFSET) /* SDIO FIFO data register */
/* Register Bitfield Definitions ********************************************/
/* SDIO_PWRCTL */
#define SDIO_PWRCTL_SHIFT (0) /* Bits 0-1: SDIO power control bits */
#define SDIO_PWRCTL_MASK (3 << SDIO_PWRCTL_SHIFT)
#define SDIO_PWRCTL_OFF (0 << SDIO_PWRCTL_SHIFT) /* 00: Power-off: card clock stopped */
#define SDIO_PWRCTL_PWRUP (2 << SDIO_PWRCTL_SHIFT) /* 10: Reserved power-up */
#define SDIO_PWRCTL_ON (3 << SDIO_PWRCTL_SHIFT) /* 11: Power-on: card is clocked */
#define SDIO_PWRCTL_RESET (0) /* Reset value */
/* SDIO_CLKCTL */
#define SDIO_CLKCTL_CLKDIV_SHIFT (0) /* Bits 7-0: clock division */
#define SDIO_CLKCTL_CLKDIV_MASK (0xff << SDIO_CLKCTL_CLKDIV_SHIFT)
#define SDIO_CLKCTL_CLKEN (1 << 8) /* Bit 8: SDIO_CLK clock output enable bit */
#define SDIO_CLKCTL_CLKPWRSAV (1 << 9) /* Bit 9: SDIO_CLK clock dynamic switch on/off for power saving */
#define SDIO_CLKCTL_CLKBYP (1 << 10) /* Bit 10: clock bypass enable bit */
#define SDIO_CLKCTL_WIDBUS_SHIFT (11) /* Bits 12-11: SDIO card bus mode control bit */
#define SDIO_CLKCTL_WIDBUS_MASK (3 << SDIO_CLKCTL_WIDBUS_SHIFT)
#define SDIO_CLKCTL_WIDBUS_D1 (0 << SDIO_CLKCTL_WIDBUS_SHIFT) /* 00: Default (SDIO_D0) */
#define SDIO_CLKCTL_WIDBUS_D4 (1 << SDIO_CLKCTL_WIDBUS_SHIFT) /* 01: 4-wide (SDIO_D[3:0]) */
#define SDIO_CLKCTL_WIDBUS_D8 (2 << SDIO_CLKCTL_WIDBUS_SHIFT) /* 10: 8-wide (SDIO_D[7:0]) */
#define SDIO_CLKCTL_NEGEDGE (1 << 13) /* Bit 13: SDIO_CK dephasing selection bit */
#define SDIO_CLKCTL_HWFC_EN (1 << 14) /* Bit 14: HW Flow Control enable */
#define SDIO_CLKCTL_RESET (0) /* Reset value */
/* SDIO_CMDAGMT */
#define SDIO_CMDAGMT_RESET (0) /* Reset value */
/* SDIO_CMDCTL */
#define SDIO_CMDCTL_CMDINDEX_SHIFT (0)
#define SDIO_CMDCTL_CMDINDEX_MASK (0x3f << SDIO_CMDCTL_CMDINDEX_SHIFT)
#define SDIO_CMDCTL_WAITRESP_SHIFT (6) /* Bits 7-6: command response type bits */
#define SDIO_CMDCTL_WAITRESP_MASK (3 << SDIO_CMDCTL_WAITRESP_SHIFT)
#define SDIO_CMDCTL_NORESPONSE (0 << SDIO_CMDCTL_WAITRESP_SHIFT) /* 00/10: No response */
#define SDIO_CMDCTL_SHORTRESPONSE (1 << SDIO_CMDCTL_WAITRESP_SHIFT) /* 01: Short response */
#define SDIO_CMDCTL_LONGRESPONSE (3 << SDIO_CMDCTL_WAITRESP_SHIFT) /* 11: Long response */
#define SDIO_CMDCTL_INTWAIT (1 << 8) /* Bit 8: nterrupt wait instead of timeout */
#define SDIO_CMDCTL_WAITDEND (1 << 9) /* Bit 9: wait for ends of data transfer */
#define SDIO_CMDCTL_CSMEN (1 << 10) /* Bit 10: command state machine(CSM) enable bit */
#define SDIO_CMDCTL_SUSPEND (1 << 11) /* Bit 11: SD I/O suspend command(SD I/O only) */
#define SDIO_CMDCTL_ENDCMDC (1 << 12) /* Bit 12: CMD completion signal enabled (CE-ATA only) */
#define SDIO_CMDCTL_NINTEN (1 << 13) /* Bit 13: no CE-ATA interrupt (CE-ATA only) */
#define SDIO_CMDCTL_ATAEN (1 << 14) /* Bit 14: CE-ATA command enable(CE-ATA only) */
#define SDIO_CMDCTL_RESET (0) /* Reset value */
/* SDIO_RSPCMDIDX */
#define SDIO_RSPCMDIDX_SHIFT (0)
#define SDIO_RSPCMDIDX_MASK (0x3f << SDIO_RSPCMDIDX_SHIFT)
/* SDIO_DATATO */
#define SDIO_DATATO_RESET (0) /* Reset value */
/* SDIO_DATALEN */
#define SDIO_DATALEN_SHIFT (0)
#define SDIO_DATALEN_MASK (0x01ffffff << SDIO_DATALEN_SHIFT)
#define SDIO_DATALEN_RESET (0) /* Reset value */
/* SDIO_DATACTL */
#define SDIO_DATACTL_DATAEN (1 << 0) /* Bit 0: data transfer enabled bit */
#define SDIO_DATACTL_DATADIR (1 << 1) /* Bit 1: data transfer direction */
#define SDIO_DATACTL_TRANSMOD (1 << 2) /* Bit 2: data transfer mode */
#define SDIO_DATACTL_DMAEN (1 << 3) /* Bit 3: DMA enable bit */
#define SDIO_DATACTL_DBLOCKSIZE_SHIFT (4) /* Bits 7-4: data block size */
#define SDIO_DATACTL_DBLOCKSIZE_MASK (15 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_1BYTE (0 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_2BYTES (1 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_4BYTES (2 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_8BYTES (3 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_16BYTES (4 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_32BYTES (5 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_64BYTES (6 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_128BYTES (7 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_256BYTES (8 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_512BYTES (9 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_1KBYTE (10 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_2KBYTES (11 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_4KBYTES (12 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_8KBYTES (13 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_16KBYTES (14 << SDIO_DATACTL_DBLOCKSIZE_SHIFT)
#define SDIO_DATACTL_RWEN (1 << 8) /* Bit 8: read wait mode enabled(SD I/O only) */
#define SDIO_DATACTL_RWSTOP (1 << 9) /* Bit 9: read wait stop(SD I/O only) */
#define SDIO_DATACTL_RWTYPE (1 << 10) /* Bit 10: read wait type(SD I/O only) */
#define SDIO_DATACTL_IOEN (1 << 11) /* Bit 11: SD I/O specific function enable(SD I/O only) */
#define SDIO_DATACTL_RESET (0) /* Reset value */
/* SDIO_DATACOUNT */
#define SDIO_DATACOUNT_SHIFT (0)
#define SDIO_DATACOUNT_MASK (0x01ffffff << SDIO_DATACOUNT_SHIFT)
/* SDIO_STAT */
#define SDIO_STAT_CCRCERR (1 << 0) /* Bit 0: command response received (CRC check failed) */
#define SDIO_STAT_DTCRCERR (1 << 1) /* Bit 1: data block sent/received (CRC check failed) */
#define SDIO_STAT_CMDTMOUT (1 << 2) /* Bit 2: command response timeout */
#define SDIO_STAT_DTTMOUT (1 << 3) /* Bit 3: data timeout */
#define SDIO_STAT_TXURE (1 << 4) /* Bit 4: transmit FIFO underrun error occurs */
#define SDIO_STAT_RXORE (1 << 5) /* Bit 5: received FIFO overrun error occurs */
#define SDIO_STAT_CMDRECV (1 << 6) /* Bit 6: command response received (CRC check passed) */
#define SDIO_STAT_CMDSEND (1 << 7) /* Bit 7: command sent (no response required) */
#define SDIO_STAT_DTEND (1 << 8) /* Bit 8: data end (data counter, SDIO_DATACNT, is zero) */
#define SDIO_STAT_STBITE (1 << 9) /* Bit 9: start bit error in the bus */
#define SDIO_STAT_DTBLKEND (1 << 10) /* Bit 10: data block sent/received (CRC check passed) */
#define SDIO_STAT_CMDRUN (1 << 11) /* Bit 11: command transmission in progress */
#define SDIO_STAT_TXRUN (1 << 12) /* Bit 12: data transmission in progress */
#define SDIO_STAT_RXRUN (1 << 13) /* Bit 13: data reception in progress */
#define SDIO_STAT_TFH (1 << 14) /* Bit 14: transmit FIFO is half empty: at least 8 words can be written into the FIFO */
#define SDIO_STAT_RFH (1 << 15) /* Bit 15: receive FIFO is half full: at least 8 words can be read in the FIFO */
#define SDIO_STAT_TFF (1 << 16) /* Bit 16: transmit FIFO is full */
#define SDIO_STAT_RFF (1 << 17) /* Bit 17: receive FIFO is full */
#define SDIO_STAT_TFE (1 << 18) /* Bit 18: transmit FIFO is empty */
#define SDIO_STAT_RFE (1 << 19) /* Bit 19: receive FIFO is empty */
#define SDIO_STAT_TXDTVAL (1 << 20) /* Bit 20: data is valid in transmit FIFO */
#define SDIO_STAT_RXDTVAL (1 << 21) /* Bit 21: data is valid in receive FIFO */
#define SDIO_STAT_SDIOINT (1 << 22) /* Bit 22: SD I/O interrupt received */
#define SDIO_STAT_ATAEND (1 << 23) /* Bit 23: CE-ATA command completion signal received (only for CMD61) */
/* SDIO_INTC */
#define SDIO_INTC_CCRCERRC (1 << 0) /* Bit 0: CCRCERR flag clear bit */
#define SDIO_INTC_DTCRCERRC (1 << 1) /* Bit 1: DTCRCERR flag clear bit */
#define SDIO_INTC_CMDTMOUTC (1 << 2) /* Bit 2: CMDTMOUT flag clear bit */
#define SDIO_INTC_DTTMOUTC (1 << 3) /* Bit 3: DTTMOUT flag clear bit */
#define SDIO_INTC_TXUREC (1 << 4) /* Bit 4: TXURE flag clear bit */
#define SDIO_INTC_RXOREC (1 << 5) /* Bit 5: RXORE flag clear bit */
#define SDIO_INTC_CMDRECVC (1 << 6) /* Bit 6: CMDRECV flag clear bit */
#define SDIO_INTC_CMDSENDC (1 << 7) /* Bit 7: CMDSEND flag clear bit */
#define SDIO_INTC_DTENDC (1 << 8) /* Bit 8: DTEND flag clear bit */
#define SDIO_INTC_STBITEC (1 << 9) /* Bit 9: STBITE flag clear bit */
#define SDIO_INTC_DTBLKENDC (1 << 10) /* Bit 10: DTBLKEND flag clear bit */
#define SDIO_INTC_SDIOINTC (1 << 22) /* Bit 22: SDIOINT flag clear bit */
#define SDIO_INTC_ATAENDC (1 << 23) /* Bit 23: ATAEND flag clear bit */
#define SDIO_INTC_RESET 0x00c007ff
#define SDIO_INTC_STATICFLAGS 0x000005ff
/* SDIO_INTEN */
#define SDIO_INTEN_CCRCERRIE (1 << 0) /* Bit 0: command response CRC fail interrupt enable */
#define SDIO_INTEN_DTCRCERRIE (1 << 1) /* Bit 1: data CRC fail interrupt enable */
#define SDIO_INTEN_CMDTMOUTIE (1 << 2) /* Bit 2: command response timeout interrupt enable */
#define SDIO_INTEN_DTTMOUTIE (1 << 3) /* Bit 3: data timeout interrupt enable */
#define SDIO_INTEN_TXUREIE (1 << 4) /* Bit 4: transmit FIFO underrun error interrupt enable */
#define SDIO_INTEN_RXOREIE (1 << 5) /* Bit 5: received FIFO overrun error interrupt enable */
#define SDIO_INTEN_CMDRECVIE (1 << 6) /* Bit 6: command response received interrupt enable */
#define SDIO_INTEN_CMDSENDIE (1 << 7) /* Bit 7: command sent interrupt enable */
#define SDIO_INTEN_DTENDIE (1 << 8) /* Bit 8: data end interrupt enable */
#define SDIO_INTEN_STBITEIE (1 << 9) /* Bit 9: start bit error interrupt enable */
#define SDIO_INTEN_DTBLKENDIE (1 << 10) /* Bit 10: data block end interrupt enable */
#define SDIO_INTEN_CMDRUNIE (1 << 11) /* Bit 11: command transmission interrupt enable */
#define SDIO_INTEN_TXRUNIE (1 << 12) /* Bit 12: data transmission interrupt enable */
#define SDIO_INTEN_RXRUNIE (1 << 13) /* Bit 13: data reception interrupt enable */
#define SDIO_INTEN_TFHIE (1 << 14) /* Bit 14: transmit FIFO half empty interrupt enable */
#define SDIO_INTEN_RFHIE (1 << 15) /* Bit 15: receive FIFO half full interrupt enable */
#define SDIO_INTEN_TFFIE (1 << 16) /* Bit 16: transmit FIFO full interrupt enable */
#define SDIO_INTEN_RFFIE (1 << 17) /* Bit 17: receive FIFO full interrupt enable */
#define SDIO_INTEN_TFEIE (1 << 18) /* Bit 18: transmit FIFO empty interrupt enable */
#define SDIO_INTEN_RFEIE (1 << 19) /* Bit 19: receive FIFO empty interrupt enable */
#define SDIO_INTEN_TXDTVALIE (1 << 20) /* Bit 20: data valid in transmit FIFO interrupt enable */
#define SDIO_INTEN_RXDTVALIE (1 << 21) /* Bit 21: data valid in receive FIFO interrupt enable */
#define SDIO_INTEN_SDIOINTIE (1 << 22) /* Bit 22: SD I/O interrupt received interrupt enable */
#define SDIO_INTEN_ATAENDIE (1 << 23) /* Bit 23: CE-ATA command completion signal received interrupt enable */
#define SDIO_INTEN_RESET (0)
/* 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 SDIO_INIT_CLKDIV (118 << SDIO_CLKCTL_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 SDIO_MMCXFR_CLKDIV (1 << SDIO_CLKCTL_CLKDIV_SHIFT)
#else
# define SDIO_MMCXFR_CLKDIV (2 << SDIO_CLKCTL_CLKDIV_SHIFT)
#endif
#ifdef CONFIG_SDIO_DMA
# define SDIO_SDXFR_CLKDIV (1 << SDIO_CLKCTL_CLKDIV_SHIFT)
#else
# define SDIO_SDXFR_CLKDIV (2 << SDIO_CLKCTL_CLKDIV_SHIFT)
#endif
#endif /* __ARCH_ARM_SRC_GD32F4_HARDWARE_GD32F4XX_SDIO_H */

View file

@ -0,0 +1,95 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_FPU is not set
CONFIG_ARCH="arm"
CONFIG_ARCH_BOARD="gd32f450zk-eval"
CONFIG_ARCH_BOARD_GD32F450ZK_EVAL=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="gd32f4"
CONFIG_ARCH_CHIP_GD32F450ZK=y
CONFIG_ARCH_CHIP_GD32F4=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_DEBUG_CUSTOMOPT=y
CONFIG_DEBUG_OPTLEVEL="-O0"
CONFIG_DEBUG_SYMBOLS=y
CONFIG_ETH0_PHY_DP83848C=y
CONFIG_FAT_COMPUTE_FSINFO=y
CONFIG_FAT_FORCE_INDIRECT=y
CONFIG_FAT_LCNAMES=y
CONFIG_FAT_LFN=y
CONFIG_FS_FAT=y
CONFIG_FS_LARGEFILE=y
CONFIG_FS_PROCFS=y
CONFIG_FS_PROCFS_REGISTER=y
CONFIG_FS_TMPFS=y
CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
CONFIG_GD32F4_ENETMAC=y
CONFIG_GD32F4_FLASH_CONFIG_K=y
CONFIG_GD32F4_PHY_SR=16
CONFIG_GD32F4_PHY_SR_100FD=0x0004
CONFIG_GD32F4_PHY_SR_100HD=0x0000
CONFIG_GD32F4_PHY_SR_10FD=0x0006
CONFIG_GD32F4_PHY_SR_10HD=0x0002
CONFIG_GD32F4_PHY_SR_ALTCONFIG=y
CONFIG_GD32F4_PHY_SR_ALTMODE=0x006
CONFIG_GD32F4_RMII_EXTCLK=y
CONFIG_GD32F4_SDIO=y
CONFIG_GD32F4_SDIO_PULLUP=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INTELHEX_BINARY=y
CONFIG_MKFATFS_BUFFER_ALIGNMENT=10
CONFIG_MMCSD=y
CONFIG_MMCSD_SDIO=y
CONFIG_MM_REGIONS=2
CONFIG_NET=y
CONFIG_NETDB_DNSCLIENT=y
CONFIG_NETINIT_DRIPADDR=0x0a320301
CONFIG_NETINIT_IPADDR=0x0a320336
CONFIG_NETINIT_MACADDR_1=0x20304050
CONFIG_NETINIT_MACADDR_2=0x6080
CONFIG_NETINIT_NOMAC=y
CONFIG_NETUTILS_DISCOVER=y
CONFIG_NETUTILS_WEBCLIENT=y
CONFIG_NET_ARP_IPIN=y
CONFIG_NET_ARP_SEND=y
CONFIG_NET_BROADCAST=y
CONFIG_NET_ETH_PKTSIZE=1500
CONFIG_NET_ICMP=y
CONFIG_NET_ICMP_SOCKET=y
CONFIG_NET_IGMP=y
CONFIG_NET_LOOPBACK=y
CONFIG_NET_ROUTE=y
CONFIG_NET_STATISTICS=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
CONFIG_NET_UDP_CHECKSUMS=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RAW_BINARY=y
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_HPWORK=y
CONFIG_SCHED_LPWORK=y
CONFIG_SCHED_WAITPID=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_SYSTEM_DHCPC_RENEW=y
CONFIG_SYSTEM_NSH=y
CONFIG_SYSTEM_PING=y
CONFIG_TASK_NAME_SIZE=0
CONFIG_USART0_SERIAL_CONSOLE=y

View file

@ -358,4 +358,26 @@ typedef enum
# define GPIO_ENET_PPS_OUT GPIO_ENET_PPS_OUT_1
#endif
/* SDIO gpios
*
* PD2 SDIO_CMD
* PC12 SDIO_CLK
* PC8 SDIO_DAT0
* PC9 SDIO_DAT1
* PC10 SDIO_DAT2
* PC11 SDIO_DAT3
*
*/
#define GPIO_SDIO_CMD_PIN GPIO_SDIO_CMD_2
#define GPIO_SDIO_CLK_PIN GPIO_SDIO_CK_2
#define GPIO_SDIO_DAT0_PIN GPIO_SDIO_D0_2
#define GPIO_SDIO_DAT1_PIN GPIO_SDIO_D1_3
#define GPIO_SDIO_DAT2_PIN GPIO_SDIO_D2_3
#define GPIO_SDIO_DAT3_PIN GPIO_SDIO_D3
#ifdef CONFIG_GD32F4_SDIO_DMA
# define SDIO_DMA_INTEN (DMA_CHXCTL_SDEIE | DMA_CHXCTL_TAEIE | DMA_CHXCTL_FTFIE)
#endif
#endif /* __BOARDS_ARM_GD32F450ZK_EVAL_INCLUDE_BOARD_H */

View file

@ -42,11 +42,15 @@ CSRCS += gd32f4xx_gpio.c
endif
ifeq ($(CONFIG_ARCH_BUTTONS),y)
CSRCS += gd32f4xx_buttons.c
CSRCS += gd32f4xx_buttons.c
endif
ifeq ($(CONFIG_SPI),y)
CSRCS += gd32f4xx_spi.c
CSRCS += gd32f4xx_spi.c
endif
ifeq ($(CONFIG_MMCSD),y)
CSRCS += gd32f4xx_sdio.c
endif
ifeq ($(CONFIG_MTD_GD25),y)

View file

@ -147,6 +147,33 @@
GPIO_CFG_PORT_B | GPIO_CFG_PIN_1)
#define GPIO_INT1 (GPIO_CFG_MODE_INPUT | GPIO_CFG_PUPD_NONE | GPIO_CFG_PORT_B | GPIO_CFG_PIN_2)
/* Can't support MMC/SD features if mountpoints are disabled or if SDIO
* support is not enabled.
*/
#if defined(CONFIG_DISABLE_MOUNTPOINT) || !defined(CONFIG_GD32_SDIO)
# undef HAVE_SDIO
#endif
#define SDIO_MINOR 0 /* Any minor number, default 0 */
#define SDIO_SLOTNO 0 /* Only one slot */
#ifdef HAVE_SDIO
# if !defined(CONFIG_NSH_MMCSDSLOTNO)
# define CONFIG_NSH_MMCSDSLOTNO SDIO_SLOTNO
# elif CONFIG_NSH_MMCSDSLOTNO != 0
# warning "Only one MMC/SD slot, slot 0"
# undef CONFIG_NSH_MMCSDSLOTNO
# define CONFIG_NSH_MMCSDSLOTNO SDIO_SLOTNO
# endif
# if defined(CONFIG_NSH_MMCSDMINOR)
# define SDIO_MINOR CONFIG_NSH_MMCSDMINOR
# else
# define SDIO_MINOR 0
# endif
#endif
/****************************************************************************
* Public Data
****************************************************************************/

View file

@ -204,12 +204,12 @@ int board_app_initialize(uintptr_t arg)
#ifdef CONFIG_INPUT_BUTTONS_LOWER
/* Register the BUTTON driver */
ret = btn_lower_initialize("/dev/buttons");
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
return ret;
}
ret = btn_lower_initialize("/dev/buttons");
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
return ret;
}
#else
/* Enable BUTTON support for some other purpose */
@ -228,6 +228,34 @@ int board_app_initialize(uintptr_t arg)
}
#endif
/* Configure SDIO chip selects */
#ifdef CONFIG_ARCH_HAVE_SDIO
ret = gd32_sdio_initialize();
if (ret != OK)
{
syslog(LOG_ERR, "ERROR: gd32_sdio_initialize() failed: %d\n", ret);
return ret;
}
/* Mount the file system at /mnt/sd */
ret = nx_mount("/dev/mmcsd0", "/mnt/sd", "vfat", 0, NULL);
if (ret < 0)
{
ret = nx_mount("/dev/mmcsd0", "/mnt/sd", "vfat", 0,
"forceformat");
if (ret < 0)
{
ferr("ERROR: Failed to mount the SD card: %d\n", ret);
return ret;
}
}
syslog(LOG_INFO, "INFO: FAT volume /mnt/sd mount " \
"sd card success: %d\n", ret);
#endif
/* Now we are initialized */
initialized = true;

View file

@ -0,0 +1,156 @@
/****************************************************************************
* boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_sdio.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdio.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/sdio.h>
#include <nuttx/mmcsd.h>
#include "chip.h"
#include "gd32f4xx.h"
#include "gd32f450z_eval.h"
#ifdef CONFIG_MMCSD
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
/* Card detections requires card support and a card detection GPIO */
#define HAVE_NCD 1
#if !defined(GPIO_SDMMC1_NCD)
# undef HAVE_NCD
#endif
/****************************************************************************
* Private Data
****************************************************************************/
static struct sdio_dev_s *g_sdio_dev;
#ifdef HAVE_NCD
static bool g_sd_inserted = 0xff; /* Impossible value */
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: gd32_ncd_interrupt
*
* Description:
* Card detect interrupt handler.
*
****************************************************************************/
#ifdef HAVE_NCD
static int gd32_ncd_interrupt(int irq, void *context)
{
bool present;
present = !gd32_gpio_read(GPIO_SDMMC1_NCD);
if (g_sdio_dev && present != g_sd_inserted)
{
sdio_mediachange(g_sdio_dev, present);
g_sd_inserted = present;
}
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: gd32_sdio_initialize
*
* Description:
* Initialize SDIO-based MMC/SD card support
*
****************************************************************************/
int gd32_sdio_initialize(void)
{
int ret;
#ifdef HAVE_NCD
/* Card detect */
bool cd_status;
#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 = !gd32_gpio_read(GPIO_SDMMC1_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;
}
#endif /* CONFIG_MMCSD */