From ba482c3346c04fbec46b15122cd8b19a6a3f2f11 Mon Sep 17 00:00:00 2001 From: bigmagic Date: Fri, 13 Mar 2020 15:15:53 +0800 Subject: [PATCH] add raspi3-64 i2c driver --- bsp/raspberry-pi/raspi3-64/.config | 39 +-- bsp/raspberry-pi/raspi3-64/driver/board.c | 2 + bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c | 251 ++++++++++++-------- bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h | 6 +- bsp/raspberry-pi/raspi3-64/rtconfig.h | 11 +- 5 files changed, 173 insertions(+), 136 deletions(-) diff --git a/bsp/raspberry-pi/raspi3-64/.config b/bsp/raspberry-pi/raspi3-64/.config index 432d1cea83..c34aca6c96 100644 --- a/bsp/raspberry-pi/raspi3-64/.config +++ b/bsp/raspberry-pi/raspi3-64/.config @@ -148,7 +148,10 @@ CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_CAN is not set CONFIG_RT_USING_HWTIMER=y # CONFIG_RT_USING_CPUTIME is not set -# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_I2C=y +CONFIG_RT_I2C_DEBUG=y +CONFIG_RT_USING_I2C_BITOPS=y +# CONFIG_RT_I2C_BITOPS_DEBUG is not set CONFIG_RT_USING_PIN=y # CONFIG_RT_USING_ADC is not set # CONFIG_RT_USING_PWM is not set @@ -420,36 +423,6 @@ CONFIG_RT_USING_POSIX=y # CONFIG_PKG_USING_VT100 is not set # CONFIG_PKG_USING_ULAPACK is not set # CONFIG_PKG_USING_UKAL is not set - -# -# Privated Packages of RealThread -# -# CONFIG_PKG_USING_CODEC is not set -# CONFIG_PKG_USING_PLAYER is not set -# CONFIG_PKG_USING_MPLAYER is not set -# CONFIG_PKG_USING_PERSIMMON_SRC is not set -# CONFIG_PKG_USING_JS_PERSIMMON is not set -# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set - -# -# Network Utilities -# -# CONFIG_PKG_USING_WICED is not set -# CONFIG_PKG_USING_CLOUDSDK is not set -# CONFIG_PKG_USING_POWER_MANAGER is not set -# CONFIG_PKG_USING_RT_OTA is not set -# CONFIG_PKG_USING_RDBD_SRC is not set -# CONFIG_PKG_USING_RTINSIGHT is not set -# CONFIG_PKG_USING_SMARTCONFIG is not set -# CONFIG_PKG_USING_RTX is not set -# CONFIG_RT_USING_TESTCASE is not set -# CONFIG_PKG_USING_NGHTTP2 is not set -# CONFIG_PKG_USING_AVS is not set -# CONFIG_PKG_USING_JOYLINK is not set -# CONFIG_PKG_USING_STS is not set -# CONFIG_PKG_USING_DLMS is not set -# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set -# CONFIG_PKG_USING_ZBAR is not set CONFIG_BCM2836_SOC=y # CONFIG_BSP_SUPPORT_FPU is not set @@ -468,7 +441,9 @@ CONFIG_BSP_USING_CORETIMER=y CONFIG_BSP_USING_SYSTIMER=y CONFIG_RT_USING_SYSTIMER1=y CONFIG_RT_USING_SYSTIMER3=y -# CONFIG_BSP_USING_I2C is not set +CONFIG_BSP_USING_I2C=y +# CONFIG_BSP_USING_I2C0 is not set +CONFIG_BSP_USING_I2C1=y # CONFIG_BSP_USING_SPI is not set CONFIG_BSP_USING_WDT=y # CONFIG_BSP_USING_RTC is not set diff --git a/bsp/raspberry-pi/raspi3-64/driver/board.c b/bsp/raspberry-pi/raspi3-64/driver/board.c index 19a232272f..0305dda8d9 100644 --- a/bsp/raspberry-pi/raspi3-64/driver/board.c +++ b/bsp/raspberry-pi/raspi3-64/driver/board.c @@ -100,6 +100,8 @@ void rt_hw_board_init(void) armv8_map(0x40000000, 0x40000000, 0x1000, MEM_ATTR_IO);//core timer armv8_map(0x3F300000, 0x3F300000, 0x1000, MEM_ATTR_IO);//sdio armv8_map(0xc00000, 0xc00000, 0x1000, MEM_ATTR_IO);//mbox + armv8_map(0x3f804000, 0x3f804000, 0x1000, MEM_ATTR_IO);//i2c0 + armv8_map(0x3f205000, 0x3f205000, 0x1000, MEM_ATTR_IO);//i2c1 mmu_enable(); /* initialize hardware interrupt */ diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c index 5163af60ee..ce0fd7ae74 100644 --- a/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,55 +8,103 @@ * 2019-07-29 zdzn first version */ +#include "raspi.h" #include "drv_i2c.h" -#if defined (BSP_USING_I2C0) -#define I2C1BUS_NAME "i2c0" -#endif /*BSP_USING_I2C0*/ - -#if defined (BSP_USING_I2C1) -#define I2C2BUS_NAME "i2c1" -#endif /*BSP_USING_I2C1*/ - -static int i2c_byte_wait_us = 0; - -#ifdef BSP_USING_I2C0 +//Maybe redefined +typedef unsigned long rt_ubase_t; +typedef rt_ubase_t rt_size_t; -static struct raspi_i2c_bus raspi_i2c0 = +rt_uint8_t i2c_read_or_write(volatile rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len, rt_uint8_t flag) { - .device_name = I2C1BUS_NAME, -}; + rt_uint32_t status; + rt_uint32_t remaining = len; + rt_uint32_t i = 0; + rt_uint8_t reason = BCM283X_I2C_REASON_OK; + + /* Clear FIFO */ + BCM283X_BSC_C(base) |= (BSC_C_CLEAR_1 & BSC_C_CLEAR_1); + /* Clear Status */ + BCM283X_BSC_S(base) = BSC_S_CLKT | BSC_S_ERR | BSC_S_DONE; + /* Set Data Length */ + BCM283X_BSC_DLEN(base) = len; + if (flag) + { + /* Start read */ + BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST | BSC_C_READ; + /* wait for transfer to complete */ + while (!(BCM283X_BSC_S(base) & BSC_S_DONE)) + { + /* we must empty the FIFO as it is populated and not use any delay */ + while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD)) + { + /* Read from FIFO, no barrier */ + buf[i] = BCM283X_BSC_FIFO(base); + i++; + remaining--; + } + } + /* transfer has finished - grab any remaining stuff in FIFO */ + while (remaining && (BCM283X_BSC_S(base) & BSC_S_RXD)) + { + /* Read from FIFO, no barrier */ + buf[i] = BCM283X_BSC_FIFO(base); + i++; + remaining--; + } + } + else + { + /* pre populate FIFO with max buffer */ + while (remaining && (i < BSC_FIFO_SIZE)) + { + BCM283X_BSC_FIFO(base) = buf[i]; + i++; + remaining--; + } -static struct raspi_master_config_t raspi_i2c0_cfg = -{ - .sdl_pin = BCM_GPIO_PIN_0, - .scl_pin = BCM_GPIO_PIN_1, - .sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0, - .scl_pin_mode = BCM283X_GPIO_FSEL_ALT0, - .slave_address = 8, - .bsc_base = (PER_BASE + BCM283X_BSC0_BASE), - .clk_div = BCM283X_I2C_CLOCK_DIVIDER_148, -}; + /* Enable device and start transfer */ + BCM283X_BSC_C(base) = BSC_C_I2CEN | BSC_C_ST; -#endif /* RT_USING_HW_I2C1 */ + /* Transfer is over when BCM2835_BSC_S_DONE */ + while (!(BCM283X_BSC_S(base) & BSC_S_DONE)) + { + while (remaining && (BCM283X_BSC_S(base) & BSC_S_TXD)) + { + /* Write to FIFO */ + BCM283X_BSC_FIFO(base) = buf[i]; + i++; + remaining--; + } + } + } -#ifdef BSP_USING_I2C1 -static struct raspi_i2c_bus raspi_i2c1 = -{ - .device_name = I2C2BUS_NAME, -}; + status = BCM283X_BSC_S(base); + if (status & BSC_S_ERR) + { + reason = BCM283X_I2C_REASON_ERROR_NACK; + } + else if (status & BSC_S_CLKT) + { + reason = BCM283X_I2C_REASON_ERROR_CLKT; + } + else if (remaining) + { + reason = BCM283X_I2C_REASON_ERROR_DATA; + } + BCM283X_BSC_C(base) |= (BSC_S_DONE & BSC_S_DONE); + + return reason; +} -static struct raspi_master_config_t raspi_i2c1_cfg = +struct raspi_i2c_hw_config { - .sdl_pin = BCM_GPIO_PIN_2, - .scl_pin = BCM_GPIO_PIN_3, - .sdl_pin_mode = BCM283X_GPIO_FSEL_ALT0, - .scl_pin_mode = BCM283X_GPIO_FSEL_ALT0, - .slave_address = 9, - .bsc_base = (PER_BASE + BCM283X_BSC1_BASE), - .clk_div = BCM283X_I2C_CLOCK_DIVIDER_148, + rt_uint8_t bsc_num; + rt_uint8_t sdl_pin; + rt_uint8_t scl_pin; + rt_uint8_t sdl_mode; + rt_uint8_t scl_mode; }; -#endif /* RT_USING_HW_I2C2 */ #if (defined(BSP_USING_I2C0) || defined(BSP_USING_I2C1)) @@ -70,58 +118,32 @@ static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t, rt_uint32_t); -void i2c_master_init(struct raspi_master_config_t *cfg) -{ - volatile rt_uint32_t addr; - rt_uint32_t data; - - bcm283x_gpio_fsel(cfg->sdl_pin, cfg->sdl_pin_mode); /* SDA */ - bcm283x_gpio_fsel(cfg->scl_pin, cfg->scl_pin_mode); /* SCL */ - - addr = cfg->bsc_base + BCM283X_BSC_DIV; - data = bcm283x_peri_read(addr); - i2c_byte_wait_us = ( data * 1000000 / BCM283X_CORE_CLK_HZ) * 9; - - addr = cfg->bsc_base + BCM283X_BSC_DIV; - bcm283x_peri_write(addr, cfg->clk_div); - - //update - i2c_byte_wait_us = (cfg->clk_div * 1000000 * 9 / BCM283X_CORE_CLK_HZ); -} - +static rt_uint32_t i2c_byte_wait_us = 0; static rt_size_t raspi_i2c_mst_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) { - volatile rt_uint32_t addr; - struct raspi_i2c_bus *raspi_i2c; rt_size_t i; + rt_uint8_t reason; RT_ASSERT(bus != RT_NULL); - raspi_i2c = (struct raspi_i2c_bus *) bus; - raspi_i2c->msg = msgs; - raspi_i2c->msg_ptr = 0; - raspi_i2c->msg_cnt = num; - raspi_i2c->dptr = 0; - addr = raspi_i2c->cfg->bsc_base + BCM283X_BSC_A; - bcm283x_peri_write(addr, msgs->addr); + volatile rt_base_t base = (volatile rt_base_t)(bus->parent.user_data); + + if (bus->addr == 0) + base = BCM283X_BSC0_BASE; + else + base = BCM283X_BSC1_BASE; + + BCM283X_BSC_A(base) = msgs->addr; for (i = 0; i < num; i++) { - if ( raspi_i2c->msg[i].flags & RT_I2C_RD ) - { - bcm283x_i2c_read(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num); - } + if (msgs[i].flags & RT_I2C_RD) + reason = i2c_read_or_write(base, msgs->buf, msgs->len, 1); else - { - bcm283x_i2c_write(raspi_i2c->cfg->bsc_base, raspi_i2c->msg->buf, num); - } + reason = i2c_read_or_write(base, msgs->buf, msgs->len, 0); } - raspi_i2c->msg = RT_NULL; - raspi_i2c->msg_ptr = 0; - raspi_i2c->msg_cnt = 0; - raspi_i2c->dptr = 0; - return i; + return (reason == 0)? i : 0; } static rt_size_t raspi_i2c_slv_xfer(struct rt_i2c_bus_device *bus, @@ -134,7 +156,7 @@ static rt_err_t raspi_i2c_bus_control(struct rt_i2c_bus_device *bus, rt_uint32_t cmd, rt_uint32_t arg) { - return RT_ERROR; + return RT_EOK; } static const struct rt_i2c_bus_device_ops raspi_i2c_ops = @@ -144,33 +166,72 @@ static const struct rt_i2c_bus_device_ops raspi_i2c_ops = .i2c_bus_control = raspi_i2c_bus_control, }; -static rt_err_t raspi_i2c_configure(struct raspi_i2c_bus *bus, struct raspi_master_config_t *cfg) + +static rt_err_t raspi_i2c_configure(struct raspi_i2c_hw_config *cfg) { - RT_ASSERT(bus != RT_NULL); RT_ASSERT(cfg != RT_NULL); - bus->device.ops = &raspi_i2c_ops; - bus->cfg = cfg; + volatile rt_uint32_t base = cfg->scl_mode ? BCM283X_BSC1_BASE : BCM283X_BSC0_BASE; + + GPIO_FSEL(cfg->sdl_pin, cfg->sdl_mode); /* SDA */ + GPIO_FSEL(cfg->scl_pin, cfg->scl_mode); /* SCL */ + /* use 0xFFFE mask to limit a max value and round down any odd number */ + rt_uint32_t divider = (BCM283X_CORE_CLK_HZ / 10000) & 0xFFFE; + BCM283X_BSC_DIV(base) = (rt_uint16_t) divider; + i2c_byte_wait_us = (divider * 1000000 * 9 / BCM283X_CORE_CLK_HZ); - i2c_master_init(cfg); return RT_EOK; } #endif -int rt_hw_i2c_init(void) +#if defined (BSP_USING_I2C0) +#define I2C0_BUS_NAME "i2c0" +static struct raspi_i2c_hw_config hw_device0 = { + .bsc_num = 0, + .sdl_pin = RPI_GPIO_P1_27, + .scl_pin = RPI_GPIO_P1_28, + .sdl_mode = BCM283X_GPIO_FSEL_ALT0, + .scl_mode = BCM283X_GPIO_FSEL_ALT0, +}; -#if defined(BSP_USING_I2C0) - raspi_i2c_configure(&raspi_i2c0 , &raspi_i2c0_cfg); - rt_i2c_bus_device_register(&raspi_i2c0.device, raspi_i2c0.device_name); -#endif /* BSP_USING_I2C1 */ +struct rt_i2c_bus_device device0 = +{ + .ops = &raspi_i2c_ops, + .addr = 0, +}; -#if defined(BSP_USING_I2C1) +#endif - raspi_i2c_configure(&raspi_i2c1 , &raspi_i2c1_cfg); - rt_i2c_bus_device_register(&raspi_i2c1.device, raspi_i2c1.device_name); +#if defined (BSP_USING_I2C1) +#define I2C1_BUS_NAME "i2c1" +static struct raspi_i2c_hw_config hw_device1 = +{ + .bsc_num = 1, + .sdl_pin = RPI_GPIO_P1_03, + .scl_pin = RPI_GPIO_P1_05, + .sdl_mode = BCM283X_GPIO_FSEL_ALT0, + .scl_mode = BCM283X_GPIO_FSEL_ALT0, +}; +struct rt_i2c_bus_device device1 = +{ + .ops = &raspi_i2c_ops, + .addr = 1, +}; -#endif /* BSP_USING_I2C2 */ +#endif + +int rt_hw_i2c_init(void) +{ +#if defined(BSP_USING_I2C0) + raspi_i2c_configure(&hw_device0); + rt_i2c_bus_device_register(&device0, I2C0_BUS_NAME); +#endif + +#if defined(BSP_USING_I2C1) + raspi_i2c_configure(&hw_device1); + rt_i2c_bus_device_register(&device1, I2C1_BUS_NAME); +#endif return 0; } diff --git a/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h index 041d6b00db..9b652b746f 100644 --- a/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h +++ b/bsp/raspberry-pi/raspi3-64/driver/drv_i2c.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2019, RT-Thread Development Team + * Copyright (c) 2006-2020, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -11,10 +11,10 @@ #ifndef __DRV_I2C_H__ #define __DRV_I2C_H__ -#include #include #include -#include "bcm283x.h" + +#include "board.h" struct raspi_master_config_t { diff --git a/bsp/raspberry-pi/raspi3-64/rtconfig.h b/bsp/raspberry-pi/raspi3-64/rtconfig.h index 02c51bbd34..19e18a299d 100644 --- a/bsp/raspberry-pi/raspi3-64/rtconfig.h +++ b/bsp/raspberry-pi/raspi3-64/rtconfig.h @@ -102,6 +102,9 @@ #define RT_USING_SERIAL #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_HWTIMER +#define RT_USING_I2C +#define RT_I2C_DEBUG +#define RT_USING_I2C_BITOPS #define RT_USING_PIN #define RT_USING_SDIO #define RT_SDIO_STACK_SIZE 2048 @@ -179,12 +182,6 @@ /* samples: kernel and components samples */ - -/* Privated Packages of RealThread */ - - -/* Network Utilities */ - #define BCM2836_SOC /* Hardware Drivers Config */ @@ -198,6 +195,8 @@ #define BSP_USING_SYSTIMER #define RT_USING_SYSTIMER1 #define RT_USING_SYSTIMER3 +#define BSP_USING_I2C +#define BSP_USING_I2C1 #define BSP_USING_WDT #define BSP_USING_SDIO #define BSP_USING_SDIO0 -- GitLab