mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 06:42:32 +08:00
Add i2c driver for gd32f450 MCU
This commit is contained in:
@@ -87,7 +87,7 @@ config GD32F4_120MHZ
|
||||
endchoice # CPU Frequency
|
||||
|
||||
|
||||
config GD32F4_GD25_BLOCKMOUNT
|
||||
config GD32F450ZK_EVAL_GD25_BLOCKMOUNT
|
||||
bool "GD25 serial FLASH auto-mount"
|
||||
default n
|
||||
depends on GD32F4_SPI5 && MTD_GD25
|
||||
@@ -96,18 +96,18 @@ config GD32F4_GD25_BLOCKMOUNT
|
||||
|
||||
choice
|
||||
prompt "GD25 SPI FLASH configuration"
|
||||
default GD32F4_GD25_NXFFS
|
||||
depends on GD32F4_GD25_BLOCKMOUNT
|
||||
default GD32F450ZK_EVAL_GD25_NXFFS
|
||||
depends on GD32F450ZK_EVAL_GD25_BLOCKMOUNT
|
||||
|
||||
config GD32F4_GD25_FTL
|
||||
config GD32F450ZK_EVAL_GD25_FTL
|
||||
bool "Create GD25 SPI FLASH block driver"
|
||||
---help---
|
||||
Create the MTD driver for the GD25 and "wrap" the GD25 as a standard
|
||||
block driver that could then, for example, be mounted using FAT or
|
||||
any other file system. Any file system may be used, but there will
|
||||
any other file system. Any file system may be used, but there will
|
||||
be no wear-leveling.
|
||||
|
||||
config GD32F4_GD25_NXFFS
|
||||
config GD32F450ZK_EVAL_GD25_NXFFS
|
||||
bool "Create GD25 serial FLASH NXFFS file system"
|
||||
depends on FS_NXFFS
|
||||
---help---
|
||||
@@ -117,5 +117,20 @@ config GD32F4_GD25_NXFFS
|
||||
|
||||
endchoice # GD25 serial FLASH configuration
|
||||
|
||||
config GD32F450ZK_EVAL_AT24_TEST
|
||||
bool "I2C0 EEPROM AT2402 write and read test"
|
||||
default n
|
||||
depends on NSH_ARCHINIT && GD32F4_I2C0 && MTD_AT24XX
|
||||
---help---
|
||||
Automatically initialize and test the AT24 I2C EEPROM driver when
|
||||
NSH starts. After test the I2C0 will be released.
|
||||
|
||||
config AT24XX_MTD_BLOCKSIZE
|
||||
int "AT24xx MTD block size"
|
||||
default 8
|
||||
depends on GD32F450ZK_EVAL_AT24_TEST
|
||||
---help---
|
||||
The block size must be an even multiple of the pages.
|
||||
The page size of AT2402 on the board is 8 Byte.
|
||||
|
||||
endif # ARCH_BOARD_GD32F450ZK_EVAL
|
||||
|
||||
@@ -29,11 +29,11 @@ CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_FS_TMPFS=y
|
||||
CONFIG_GD25_SPIFREQUENCY=4000000
|
||||
CONFIG_GD32F450ZK_EVAL_GD25_BLOCKMOUNT=y
|
||||
CONFIG_GD32F4_168MHZ=y
|
||||
CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
|
||||
CONFIG_GD32F4_ENETMAC=y
|
||||
CONFIG_GD32F4_FLASH_CONFIG_K=y
|
||||
CONFIG_GD32F4_GD25_BLOCKMOUNT=y
|
||||
CONFIG_GD32F4_PHY_SR=16
|
||||
CONFIG_GD32F4_PHY_SR_100FD=0x0004
|
||||
CONFIG_GD32F4_PHY_SR_100HD=0x0000
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#
|
||||
# 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_INTERRUPTSTACK=256
|
||||
CONFIG_ARCH_STACKDUMP=y
|
||||
CONFIG_AT24XX_SIZE=2
|
||||
CONFIG_BOARD_LOOPSPERMSEC=16717
|
||||
CONFIG_BUILTIN=y
|
||||
CONFIG_DEBUG_CUSTOMOPT=y
|
||||
CONFIG_DEBUG_ERROR=y
|
||||
CONFIG_DEBUG_FEATURES=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_IRQ=y
|
||||
CONFIG_DEBUG_LEDS=y
|
||||
CONFIG_DEBUG_OPTLEVEL="-O0"
|
||||
CONFIG_DEBUG_SCHED=y
|
||||
CONFIG_DEBUG_SYMBOLS=y
|
||||
CONFIG_DEBUG_WARN=y
|
||||
CONFIG_FS_NXFFS=y
|
||||
CONFIG_FS_PROCFS=y
|
||||
CONFIG_GD32F450ZK_EVAL_AT24_TEST=y
|
||||
CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
|
||||
CONFIG_GD32F4_FLASH_CONFIG_K=y
|
||||
CONFIG_GD32F4_I2C0=y
|
||||
CONFIG_HAVE_CXX=y
|
||||
CONFIG_HAVE_CXXINITIALIZE=y
|
||||
CONFIG_I2C_DRIVER=y
|
||||
CONFIG_I2C_POLLED=y
|
||||
CONFIG_I2C_RESET=y
|
||||
CONFIG_INIT_ENTRYPOINT="nsh_main"
|
||||
CONFIG_INTELHEX_BINARY=y
|
||||
CONFIG_MM_REGIONS=2
|
||||
CONFIG_MTD=y
|
||||
CONFIG_MTD_AT24XX=y
|
||||
CONFIG_NSH_ARCHINIT=y
|
||||
CONFIG_NSH_BUILTIN_APPS=y
|
||||
CONFIG_NSH_FILEIOSIZE=512
|
||||
CONFIG_NSH_LINELEN=64
|
||||
CONFIG_NSH_READLINE=y
|
||||
CONFIG_NXFFS_PACKTHRESHOLD=8
|
||||
CONFIG_RAM_SIZE=114688
|
||||
CONFIG_RAM_START=0x20000000
|
||||
CONFIG_RAW_BINARY=y
|
||||
CONFIG_RR_INTERVAL=200
|
||||
CONFIG_SCHED_WAITPID=y
|
||||
CONFIG_START_DAY=6
|
||||
CONFIG_START_MONTH=12
|
||||
CONFIG_START_YEAR=2011
|
||||
CONFIG_SYSTEM_NSH=y
|
||||
CONFIG_TASK_NAME_SIZE=0
|
||||
CONFIG_USART0_SERIAL_CONSOLE=y
|
||||
@@ -25,11 +25,11 @@ CONFIG_FS_PROCFS=y
|
||||
CONFIG_FS_PROCFS_REGISTER=y
|
||||
CONFIG_FS_TMPFS=y
|
||||
CONFIG_GD25_SPIFREQUENCY=4000000
|
||||
CONFIG_GD32F450ZK_EVAL_GD25_BLOCKMOUNT=y
|
||||
CONFIG_GD32F4_168MHZ=y
|
||||
CONFIG_GD32F4_DISABLE_IDLE_SLEEP_DURING_DEBUG=y
|
||||
CONFIG_GD32F4_ENETMAC=y
|
||||
CONFIG_GD32F4_FLASH_CONFIG_K=y
|
||||
CONFIG_GD32F4_GD25_BLOCKMOUNT=y
|
||||
CONFIG_GD32F4_PHY_SR=16
|
||||
CONFIG_GD32F4_PHY_SR_100FD=0x0004
|
||||
CONFIG_GD32F4_PHY_SR_100HD=0x0000
|
||||
|
||||
@@ -283,6 +283,16 @@ typedef enum
|
||||
# define GPIO_USART3_TX GPIO_USART3_TX_3
|
||||
#endif
|
||||
|
||||
/* I2C0 gpios:
|
||||
*
|
||||
* PB6 I2C0_SCL
|
||||
* PB7 I2C0_SDA
|
||||
*
|
||||
*/
|
||||
|
||||
#define GPIO_I2C0_SCL GPIO_I2C0_SCL_1
|
||||
#define GPIO_I2C0_SDA GPIO_I2C0_SDA_1
|
||||
|
||||
/* SPI flash
|
||||
*
|
||||
* PG12 SPI5_MISO
|
||||
|
||||
@@ -53,4 +53,8 @@ ifeq ($(CONFIG_MTD_GD25),y)
|
||||
CSRCS += gd32f4xx_gd25.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_MTD_AT24XX), y)
|
||||
CSRCS += gd32f4xx_at24.c
|
||||
endif
|
||||
|
||||
include $(TOPDIR)/boards/Board.mk
|
||||
|
||||
@@ -101,6 +101,41 @@
|
||||
|
||||
#define HAVE_GD25 1
|
||||
|
||||
#if !defined(CONFIG_MTD_GD25) || !defined(CONFIG_GD32F4_SPI5)
|
||||
# undef HAVE_GD25
|
||||
#endif
|
||||
|
||||
/* Can't support AT24 features if mountpoints are disabled or if we were not
|
||||
* asked to mount the AT25 part
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_DISABLE_MOUNTPOINT) || \
|
||||
!defined(CONFIG_GD32F450ZK_EVAL_GD25_BLOCKMOUNT)
|
||||
# undef HAVE_GD25
|
||||
#endif
|
||||
|
||||
#define HAVE_AT24 1
|
||||
|
||||
/* AT24 Serial EEPROM
|
||||
*
|
||||
* A AT24C02C Serial EEPPROM was used for tested I2C0.
|
||||
*/
|
||||
|
||||
#define AT24_BUS 0
|
||||
#define AT24_MINOR 0
|
||||
|
||||
#if !defined(CONFIG_MTD_AT24XX) || !defined(CONFIG_GD32F4_I2C0)
|
||||
# undef HAVE_AT24
|
||||
#endif
|
||||
|
||||
/* Can't support AT24 features if mountpoints are disabled or if we were not
|
||||
* asked to mount the AT25 part
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_GD32F450ZK_EVAL_AT24_TEST
|
||||
# undef HAVE_AT24
|
||||
#endif
|
||||
|
||||
/* GPIO pins used by the GPIO Subsystem */
|
||||
|
||||
#define BOARD_NGPIOIN 1 /* Amount of GPIO Input pins */
|
||||
@@ -144,6 +179,18 @@ void gd32_spidev_initialize(void);
|
||||
int gd32_gd25_automount(int minor);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gd32_at24_wr_test
|
||||
*
|
||||
* Description:
|
||||
* Write and read the AT24 serial EEPROM test.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_AT24
|
||||
int gd32_at24_wr_test(int minor);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gd32_gpio_initialize
|
||||
*
|
||||
|
||||
@@ -138,7 +138,7 @@ int board_app_initialize(uintptr_t arg)
|
||||
|
||||
# endif
|
||||
|
||||
# ifdef CONFIG_MTD_GD25
|
||||
# ifdef HAVE_GD25
|
||||
|
||||
ret = gd32_gd25_automount(0);
|
||||
if (ret < 0)
|
||||
@@ -149,7 +149,18 @@ int board_app_initialize(uintptr_t arg)
|
||||
|
||||
# endif
|
||||
|
||||
#endif
|
||||
# ifdef HAVE_AT24
|
||||
|
||||
ret = gd32_at24_wr_test(AT24_MINOR);
|
||||
if (ret < 0)
|
||||
{
|
||||
syslog(LOG_ERR, "ERROR: I2C EEPROM write and read test fail: \
|
||||
%d\n", ret);
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
#endif /* CONFIG_FS_NXFFS */
|
||||
|
||||
#ifdef CONFIG_DEV_GPIO
|
||||
/* Register the GPIO driver */
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/****************************************************************************
|
||||
* boards/arm/gd32f4/gd32f450zk-eval/src/gd32f4xx_at24.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 <errno.h>
|
||||
#include <debug.h>
|
||||
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/mtd/mtd.h>
|
||||
#include <nuttx/kmalloc.h>
|
||||
|
||||
#include "gd32f4xx.h"
|
||||
#include "gd32f450z_eval.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gd32_at24_wr_test
|
||||
*
|
||||
* Description:
|
||||
* Write and read the AT24 serial EEPROM test.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef HAVE_AT24
|
||||
|
||||
#define BUFFSIZE 16
|
||||
#define START_BLOCK 0
|
||||
|
||||
#if BUFFSIZE>=CONFIG_AT24XX_MTD_BLOCKSIZE
|
||||
# define NBLOCK (BUFFSIZE/CONFIG_AT24XX_MTD_BLOCKSIZE)
|
||||
#else
|
||||
# error "BUFFSIZE should bigger than CONFIG_AT24XX_MTD_BLOCKSIZE"
|
||||
#endif
|
||||
|
||||
const uint8_t write_buf[BUFFSIZE] =
|
||||
{
|
||||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
|
||||
0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
|
||||
};
|
||||
|
||||
int gd32_at24_wr_test(int minor)
|
||||
{
|
||||
struct i2c_master_s *i2c;
|
||||
struct mtd_dev_s *at24;
|
||||
static bool initialized = false;
|
||||
int ret;
|
||||
ssize_t nblocks;
|
||||
uint8_t *read_buf;
|
||||
|
||||
/* Have we already initialized? */
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
/* No.. Get the I2C port driver */
|
||||
|
||||
finfo("Initialize TWI%d\n", AT24_BUS);
|
||||
i2c = gd32_i2cbus_initialize(AT24_BUS);
|
||||
if (!i2c)
|
||||
{
|
||||
ferr("ERROR: Failed to initialize TWI%d\n", AT24_BUS);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Now bind the I2C interface to the AT24 I2C EEPROM driver */
|
||||
|
||||
finfo("Bind the AT24 EEPROM driver to TWI%d\n", AT24_BUS);
|
||||
at24 = at24c_initialize(i2c);
|
||||
if (!at24)
|
||||
{
|
||||
ferr("ERROR: Failed to bind TWI%d to the AT24 EEPROM driver\n",
|
||||
AT24_BUS);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Now we are initializeed */
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
/* Write start block is START_BLOCK, number of block is 2 */
|
||||
|
||||
nblocks = at24->bwrite(at24, START_BLOCK, NBLOCK, write_buf);
|
||||
if (nblocks < NBLOCK)
|
||||
{
|
||||
ferr("ERROR: AT24 write failed: %zd\n", nblocks);
|
||||
gd32_i2cbus_uninitialize(i2c);
|
||||
return (int)nblocks;
|
||||
}
|
||||
|
||||
read_buf = (uint8_t *)kmm_malloc(BUFFSIZE);
|
||||
|
||||
/* Read the data write before */
|
||||
|
||||
nblocks = at24->bread(at24, START_BLOCK, NBLOCK, read_buf);
|
||||
if (nblocks < NBLOCK)
|
||||
{
|
||||
ferr("ERROR: AT24 read failed: %zd\n", nblocks);
|
||||
gd32_i2cbus_uninitialize(i2c);
|
||||
return (int)nblocks;
|
||||
}
|
||||
|
||||
if (memcmp(read_buf, write_buf, BUFFSIZE) != 0)
|
||||
{
|
||||
ferr("ERROR: Read buffer does not match write buffer\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Release the I2C instance.
|
||||
* REVISIT: Need an interface to release the AT24 instance too
|
||||
*/
|
||||
|
||||
ret = gd32_i2cbus_uninitialize(i2c);
|
||||
if (ret < 0)
|
||||
{
|
||||
ferr("ERROR: Failed to release the I2C interface: %d\n", ret);
|
||||
}
|
||||
|
||||
syslog(LOG_INFO, "INFO: I2C EEPROM write and read success: \
|
||||
%d\n", ret);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
#endif /* HAVE_AT24 */
|
||||
@@ -87,7 +87,7 @@ int gd32_gd25_automount(int minor)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_GD32F4_GD25_FTL)
|
||||
#if defined(CONFIG_GD32F450ZK_EVAL_GD25_FTL)
|
||||
/* And finally, use the FTL layer to wrap the MTD driver as a block
|
||||
* driver at /dev/mtdblockN, where N=minor device number.
|
||||
*/
|
||||
@@ -100,7 +100,7 @@ int gd32_gd25_automount(int minor)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_GD32F4_GD25_NXFFS)
|
||||
#elif defined(CONFIG_GD32F450ZK_EVAL_GD25_NXFFS)
|
||||
/* Initialize to provide NXFFS on the MTD interface */
|
||||
|
||||
ret = nxffs_initialize(mtd);
|
||||
|
||||
Reference in New Issue
Block a user