From 11ca2c3847391e3c857005042d6931efe2edeece Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 11 Dec 2017 13:28:55 -0600 Subject: [PATCH] arch/arm/src/lpc54xx: Rename I2C and SPI configurations to make room in the namespace for future slave support. Add fragmenenty skeleon of I2C driver just as a starting point. --- arch/arm/src/lpc54xx/Kconfig | 164 ++--- arch/arm/src/lpc54xx/Make.defs | 8 +- arch/arm/src/lpc54xx/lpc54_config.h | 155 ++++- arch/arm/src/lpc54xx/lpc54_i2c_master.c | 779 ++++++++++++++++++++++++ arch/arm/src/lpc54xx/lpc54_i2c_master.h | 87 +++ 5 files changed, 1091 insertions(+), 102 deletions(-) create mode 100644 arch/arm/src/lpc54xx/lpc54_i2c_master.c create mode 100644 arch/arm/src/lpc54xx/lpc54_i2c_master.h diff --git a/arch/arm/src/lpc54xx/Kconfig b/arch/arm/src/lpc54xx/Kconfig index 08b468961b3..d4eb722e031 100644 --- a/arch/arm/src/lpc54xx/Kconfig +++ b/arch/arm/src/lpc54xx/Kconfig @@ -109,7 +109,7 @@ config ARCH_LPC54_HAVE_SHA # Peripheral Selection -config LPC54_HAVE_I2C +config LPC54_HAVE_I2C_MASTER bool default n @@ -167,7 +167,7 @@ config LPC54_FLEXCOMM9 default n select LPC54_HAVE_FLEXCOMM -config LPC54_HAVE_SPI +config LPC54_HAVE_SPI_MASTER bool default n @@ -177,144 +177,144 @@ config LPC54_HAVE_USART menu "LPC54xx Peripheral Selection" -config LPC54_I2C0 - bool "I2C0" +config LPC54_I2C0_MASTER + bool "I2C0 Master" default n select LPC54_FLEXCOMM0 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C1 - bool "I2C1" +config LPC54_I2C1_MASTER + bool "I2C1 Master" default n select LPC54_FLEXCOMM1 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C2 - bool "I2C2" +config LPC54_I2C2_MASTER + bool "I2C2 Master" default n select LPC54_FLEXCOMM2 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C3 - bool "I2C3" +config LPC54_I2C3_MASTER + bool "I2C3 Master" default n select LPC54_FLEXCOMM3 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C4 - bool "I2C4" +config LPC54_I2C4_MASTER + bool "I2C4 Master" default n select LPC54_FLEXCOMM4 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C5 - bool "I2C5" +config LPC54_I2C5_MASTER + bool "I2C5 Master" default n select LPC54_FLEXCOMM5 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C6 - bool "I2C6" +config LPC54_I2C6_MASTER + bool "I2C6 Master" default n select LPC54_FLEXCOMM6 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C7 - bool "I2C7" +config LPC54_I2C7_MASTER + bool "I2C7 Master" default n select LPC54_FLEXCOMM7 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C8 - bool "I2C8" +config LPC54_I2C8_MASTER + bool "I2C8 Master" default n select LPC54_FLEXCOMM8 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER -config LPC54_I2C9 - bool "I2C9" +config LPC54_I2C9_MASTER + bool "I2C9 Master" default n select LPC54_FLEXCOMM9 - select LPC54_HAVE_I2C + select LPC54_HAVE_I2C_MASTER config LPC54_EMC bool "External Memory Controller (EMC)" default n -config LPC54_SPI0 - bool "SPI0" +config LPC54_SPI0_MASTER + bool "SPI0 Master" default n - depends on !LPC54_I2C0 + depends on !LPC54_I2C0_MASTER select LPC54_FLEXCOMM0 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI1 - bool "SPI1" +config LPC54_SPI1_MASTER + bool "SPI1 Master" default n - depends on !LPC54_I2C1 + depends on !LPC54_I2C1_MASTER select LPC54_FLEXCOMM1 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI2 - bool "SPI2" +config LPC54_SPI2_MASTER + bool "SPI2 Master" default n - depends on !LPC54_I2C2 + depends on !LPC54_I2C2_MASTER select LPC54_FLEXCOMM2 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI3 - bool "SPI3" +config LPC54_SPI3_MASTER + bool "SPI3 Master" default n - depends on !LPC54_I2C3 + depends on !LPC54_I2C3_MASTER select LPC54_FLEXCOMM3 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI4 - bool "SPI4" +config LPC54_SPI4_MASTER + bool "SPI4 Master" default n - depends on !LPC54_I2C4 + depends on !LPC54_I2C4_MASTER select LPC54_FLEXCOMM4 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI5 - bool "SPI5" +config LPC54_SPI5_MASTER + bool "SPI5 Master" default n - depends on !LPC54_I2C5 + depends on !LPC54_I2C5_MASTER select LPC54_FLEXCOMM5 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI6 - bool "SPI6" +config LPC54_SPI6_MASTER + bool "SPI6 Master" default n - depends on !LPC54_I2C6 + depends on !LPC54_I2C6_MASTER select LPC54_FLEXCOMM6 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI7 - bool "SPI7" +config LPC54_SPI7_MASTER + bool "SPI7 Master" default n - depends on !LPC54_I2C7 + depends on !LPC54_I2C7_MASTER select LPC54_FLEXCOMM7 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI8 - bool "SPI8" +config LPC54_SPI8_MASTER + bool "SPI8 Master" default n - depends on !LPC54_I2C8 + depends on !LPC54_I2C8_MASTER select LPC54_FLEXCOMM8 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER -config LPC54_SPI9 - bool "SPI9" +config LPC54_SPI9_MASTER + bool "SPI9 Master" default n - depends on !LPC54_I2C9 + depends on !LPC54_I2C9_MASTER select LPC54_FLEXCOMM9 - select LPC54_HAVE_SPI + select LPC54_HAVE_SPI_MASTER config LPC54_USART0 bool "USART0" default n - depends on !LPC54_I2C0 && !LPC54_SPI0 + depends on !LPC54_I2C0_MASTER && !LPC54_SPI0_MASTER select LPC54_FLEXCOMM0 select USART0_SERIALDRIVER select LPC54_HAVE_USART @@ -322,7 +322,7 @@ config LPC54_USART0 config LPC54_USART1 bool "USART1" default n - depends on !LPC54_I2C1 && !LPC54_SPI1 + depends on !LPC54_I2C1_MASTER && !LPC54_SPI1_MASTER select LPC54_FLEXCOMM1 select USART1_SERIALDRIVER select LPC54_HAVE_USART @@ -330,7 +330,7 @@ config LPC54_USART1 config LPC54_USART2 bool "USART2" default n - depends on !LPC54_I2C2 && !LPC54_SPI2 + depends on !LPC54_I2C2_MASTER && !LPC54_SPI2_MASTER select LPC54_FLEXCOMM2 select USART2_SERIALDRIVER select LPC54_HAVE_USART @@ -338,7 +338,7 @@ config LPC54_USART2 config LPC54_USART3 bool "USART3" default n - depends on !LPC54_I2C3 && !LPC54_SPI3 + depends on !LPC54_I2C3_MASTER && !LPC54_SPI3_MASTER select LPC54_FLEXCOMM3 select USART3_SERIALDRIVER select LPC54_HAVE_USART @@ -346,7 +346,7 @@ config LPC54_USART3 config LPC54_USART4 bool "USART4" default n - depends on !LPC54_I2C4 && !LPC54_SPI4 + depends on !LPC54_I2C4_MASTER && !LPC54_SPI4_MASTER select LPC54_FLEXCOMM4 select USART4_SERIALDRIVER select LPC54_HAVE_USART @@ -354,7 +354,7 @@ config LPC54_USART4 config LPC54_USART5 bool "USART5" default n - depends on !LPC54_I2C5 && !LPC54_SPI5 + depends on !LPC54_I2C5_MASTER && !LPC54_SPI5_MASTER select LPC54_FLEXCOMM5 select USART5_SERIALDRIVER select LPC54_HAVE_USART @@ -362,7 +362,7 @@ config LPC54_USART5 config LPC54_USART6 bool "USART6" default n - depends on !LPC54_I2C6 && !LPC54_SPI6 + depends on !LPC54_I2C6_MASTER && !LPC54_SPI6_MASTER select LPC54_FLEXCOMM6 select USART6_SERIALDRIVER select LPC54_HAVE_USART @@ -370,7 +370,7 @@ config LPC54_USART6 config LPC54_USART7 bool "USART7" default n - depends on !LPC54_I2C7 && !LPC54_SPI7 + depends on !LPC54_I2C7_MASTER && !LPC54_SPI7_MASTER select LPC54_FLEXCOMM7 select USART7_SERIALDRIVER select LPC54_HAVE_USART @@ -378,7 +378,7 @@ config LPC54_USART7 config LPC54_USART8 bool "USART8" default n - depends on !LPC54_I2C8 && !LPC54_SPI8 + depends on !LPC54_I2C8_MASTER && !LPC54_SPI8_MASTER select LPC54_FLEXCOMM8 select USART8_SERIALDRIVER select LPC54_HAVE_USART @@ -386,7 +386,7 @@ config LPC54_USART8 config LPC54_USART9 bool "USART9" default n - depends on !LPC54_I2C9 && !LPC54_SPI9 + depends on !LPC54_I2C9_MASTER && !LPC54_SPI9_MASTER select LPC54_FLEXCOMM9 select USART9_SERIALDRIVER select LPC54_HAVE_USART diff --git a/arch/arm/src/lpc54xx/Make.defs b/arch/arm/src/lpc54xx/Make.defs index 7e15297ba73..bfd2db5e002 100644 --- a/arch/arm/src/lpc54xx/Make.defs +++ b/arch/arm/src/lpc54xx/Make.defs @@ -105,12 +105,12 @@ ifeq ($(CONFIG_LPC54_HAVE_USART),y) CHIP_CSRCS += lpc54_serial.c endif -ifeq ($(CONFIG_LPC54_HAVE_I2C),y) -CHIP_CSRCS += lpc54_i2c.c +ifeq ($(CONFIG_LPC54_HAVE_I2C_MASTER),y) +CHIP_CSRCS += lpc54_i2c_master.c endif -ifeq ($(CONFIG_LPC54_HAVE_SPI),y) -CHIP_CSRCS += lpc54_spi.c +ifeq ($(CONFIG_LPC54_HAVE_SPI_MASTER),y) +CHIP_CSRCS += lpc54_spi_master.c endif ifeq ($(CONFIG_LPC54_EMC),y) diff --git a/arch/arm/src/lpc54xx/lpc54_config.h b/arch/arm/src/lpc54xx/lpc54_config.h index 2a1a447e2dd..362e330355e 100644 --- a/arch/arm/src/lpc54xx/lpc54_config.h +++ b/arch/arm/src/lpc54xx/lpc54_config.h @@ -50,40 +50,161 @@ ************************************************************************************/ /* Configuration *********************************************************************/ -/* Make sure that no unsupported UARTs are enabled */ +/* Make sure that no unsupported USART, I2C master, or SPI masgter peripherals are + * enabled. + */ #ifndef CONFIG_LPC54_FLEXCOMM0 +# undef CONFIG_LPC54_I2C0_MASTER +# undef CONFIG_LPC54_SPI0_MASTER # undef CONFIG_LPC54_USART0 #endif #ifndef CONFIG_LPC54_FLEXCOMM1 +# undef CONFIG_LPC54_I2C1_MASTER +# undef CONFIG_LPC54_SPI1_MASTER # undef CONFIG_LPC54_USART1 #endif #ifndef CONFIG_LPC54_FLEXCOMM2 +# undef CONFIG_LPC54_I2C2_MASTER +# undef CONFIG_LPC54_SPI2_MASTER # undef CONFIG_LPC54_USART2 #endif #ifndef CONFIG_LPC54_FLEXCOMM3 +# undef CONFIG_LPC54_I2C3_MASTER +# undef CONFIG_LPC54_SPI3_MASTER # undef CONFIG_LPC54_USART3 #endif #ifndef CONFIG_LPC54_FLEXCOMM4 +# undef CONFIG_LPC54_I2C4_MASTER +# undef CONFIG_LPC54_SPI4_MASTER # undef CONFIG_LPC54_USART4 #endif #ifndef CONFIG_LPC54_FLEXCOMM5 +# undef CONFIG_LPC54_I2C5_MASTER +# undef CONFIG_LPC54_SPI5_MASTER # undef CONFIG_LPC54_USART5 #endif #ifndef CONFIG_LPC54_FLEXCOMM6 +# undef CONFIG_LPC54_I2C6_MASTER +# undef CONFIG_LPC54_SPI6_MASTER # undef CONFIG_LPC54_USART6 #endif #ifndef CONFIG_LPC54_FLEXCOMM7 +# undef CONFIG_LPC54_I2C7_MASTER +# undef CONFIG_LPC54_SPI7_MASTER # undef CONFIG_LPC54_USART7 #endif #ifndef CONFIG_LPC54_FLEXCOMM8 +# undef CONFIG_LPC54_I2C8_MASTER +# undef CONFIG_LPC54_SPI8_MASTER # undef CONFIG_LPC54_USART8 #endif #ifndef CONFIG_LPC54_FLEXCOMM9 +# undef CONFIG_LPC54_I2C9_MASTER +# undef CONFIG_LPC54_SPI9_MASTER # undef CONFIG_LPC54_USART9 #endif -/* Map logical UART names (Just for simplicity of naming) */ +#ifdef CONFIG_LPC54_I2C0_MASTER +# undef CONFIG_LPC54_SPI0_MASTER +# undef CONFIG_LPC54_USART0 +#endif +#ifdef CONFIG_LPC54_I2C1_MASTER +# undef CONFIG_LPC54_SPI1_MASTER +# undef CONFIG_LPC54_USART1 +#endif +#ifdef CONFIG_LPC54_I2C2_MASTER +# undef CONFIG_LPC54_SPI2_MASTER +# undef CONFIG_LPC54_USART2 +#endif +#ifdef CONFIG_LPC54_I2C3_MASTER +# undef CONFIG_LPC54_SPI3_MASTER +# undef CONFIG_LPC54_USART3 +#endif +#ifdef CONFIG_LPC54_I2C4_MASTER +# undef CONFIG_LPC54_SPI4_MASTER +# undef CONFIG_LPC54_USART4 +#endif +#ifdef CONFIG_LPC54_I2C5_MASTER +# undef CONFIG_LPC54_SPI5_MASTER +# undef CONFIG_LPC54_USART5 +#endif +#ifdef CONFIG_LPC54_I2C6_MASTER +# undef CONFIG_LPC54_SPI6_MASTER +# undef CONFIG_LPC54_USART6 +#endif +#ifdef CONFIG_LPC54_I2C7_MASTER +# undef CONFIG_LPC54_SPI7_MASTER +# undef CONFIG_LPC54_USART7 +#endif +#ifdef CONFIG_LPC54_I2C8_MASTER +# undef CONFIG_LPC54_SPI8_MASTER +# undef CONFIG_LPC54_USART8 +#endif +#ifdef CONFIG_LPC54_I2C9_MASTER +# undef CONFIG_LPC54_SPI9_MASTER +# undef CONFIG_LPC54_USART9 +#endif + +#ifdef CONFIG_LPC54_SPI0_MASTER +# undef CONFIG_LPC54_USART0 +#endif +#ifdef CONFIG_LPC54_SPI1_MASTER +# undef CONFIG_LPC54_USART1 +#endif +#ifdef CONFIG_LPC54_SPI2_MASTER +# undef CONFIG_LPC54_USART2 +#endif +#ifdef CONFIG_LPC54_SPI3_MASTER +# undef CONFIG_LPC54_USART3 +#endif +#ifdef CONFIG_LPC54_SPI4_MASTER +# undef CONFIG_LPC54_USART4 +#endif +#ifdef CONFIG_LPC54_SPI5_MASTER +# undef CONFIG_LPC54_USART5 +#endif +#ifdef CONFIG_LPC54_SPI6_MASTER +# undef CONFIG_LPC54_USART6 +#endif +#ifdef CONFIG_LPC54_SPI7_MASTER +# undef CONFIG_LPC54_USART7 +#endif +#ifdef CONFIG_LPC54_SPI8_MASTER +# undef CONFIG_LPC54_USART8 +#endif +#ifdef CONFIG_LPC54_SPI9_MASTER +# undef CONFIG_LPC54_USART9 +#endif + +/* Check if we have an I2C device */ + + +#undef CONFIG_LPC54_HAVE_I2C_MASTER +#undef HAVE_I2C_MASTER_DEVICE + +#if defined(CONFIG_LPC54_I2C0_MASTER) || defined(CONFIG_LPC54_I2C1_MASTER) || \ + defined(CONFIG_LPC54_I2C1_MASTER) || defined(CONFIG_LPC54_I2C3_MASTER) || \ + defined(CONFIG_LPC54_I2C_MASTER4) || defined(CONFIG_LPC54_I2C5_MASTER) || \ + defined(CONFIG_LPC54_I2C6_MASTER) || defined(CONFIG_LPC54_I2C7_MASTER) || \ + defined(CONFIG_LPC54_I2C8_MASTER) || defined(CONFIG_LPC54_I2C9_MASTER) +# define HAVE_MASTER_I2C_MASTER_DEVICE 1 +#endif + +/* Check if we have an SPI device */ + +#undef CONFIG_LPC54_HAVE_SPI_MASTER +#undef HAVE_SP_MASTERI_DEVICE + +#if defined(CONFIG_LPC54_SPI0_MASTER) || defined(CONFIG_LPC54_SPI1_MASTER) || \ + defined(CONFIG_LPC54_SPI2_MASTER) || defined(CONFIG_LPC54_SPI3_MASTER) || \ + defined(CONFIG_LPC54_SPI4_MASTER) || defined(CONFIG_LPC54_SPI5_MASTER) || \ + defined(CONFIG_LPC54_SPI6_MASTER) || defined(CONFIG_LPC54_SPI7_MASTER) || \ + defined(CONFIG_LPC54_SPI8_MASTER) || defined(CONFIG_LPC54_SPI9_MASTER) +# define HAVE_SPI_MASTER_DEVICE 1 +#endif + +/* Map logical USART names (Just for simplicity of naming) */ #undef HAVE_USART0 #undef HAVE_USART1 @@ -97,39 +218,41 @@ #undef HAVE_USART9 #ifdef CONFIG_LPC54_USART0 -# define HAVE_USART0 +# define HAVE_USART0 1 #endif #ifdef CONFIG_LPC54_USART1 -# define HAVE_USART1 +# define HAVE_USART1 1 #endif #ifdef CONFIG_LPC54_USART2 -# define HAVE_USART2 +# define HAVE_USART2 1 #endif #ifdef CONFIG_LPC54_USART3 -# define HAVE_USART3 +# define HAVE_USART3 1 #endif #ifdef CONFIG_LPC54_USART4 -# define HAVE_USART4 +# define HAVE_USART4 1 #endif #ifdef CONFIG_LPC54_USART5 -# define HAVE_USART5 +# define HAVE_USART5 1 #endif #ifdef CONFIG_LPC54_USART6 -# define HAVE_USART6 +# define HAVE_USART6 1 #endif #ifdef CONFIG_LPC54_USART7 -# define HAVE_USART7 +# define HAVE_USART7 1 #endif #ifdef CONFIG_LPC54_USART8 -# define HAVE_USART8 +# define HAVE_USART8 1 #endif #ifdef CONFIG_LPC54_USART9 -# define HAVE_USART9 +# define HAVE_USART9 1 #endif -/* Are any UARTs enabled? */ +/* Check if we have a USART device */ +#undef CONFIG_LPC54_HAVE_USART #undef HAVE_USART_DEVICE + #if defined(HAVE_USART0) || defined(HAVE_USART1) || defined(HAVE_USART2) || \ defined(HAVE_USART3) || defined(HAVE_USART4) || defined(HAVE_USART5) || \ defined(HAVE_USART6) || defined(HAVE_USART7) || defined(HAVE_USART8) || \ @@ -138,7 +261,7 @@ #endif /* Is there a serial console? There should be at most one defined. It could be on - * any UARTn, n=0,1,2,3,4,5 + * any USARTn, n=0,1,2,3,4,5 */ #undef HAVE_USART_CONSOLE @@ -255,7 +378,7 @@ # define HAVE_USART_CONSOLE 1 #else # ifdef CONFIG_DEV_CONSOLE -# warning "No valid CONFIG_[LP]UART[n]_SERIAL_CONSOLE Setting" +# warning "No valid CONFIG_[LP]USART[n]_SERIAL_CONSOLE Setting" # endif # undef CONFIG_USART0_SERIAL_CONSOLE # undef CONFIG_USART1_SERIAL_CONSOLE @@ -269,7 +392,7 @@ # undef CONFIG_USART9_SERIAL_CONSOLE #endif -/* Check UART flow control (Not yet supported) */ +/* Check USART flow control (Not yet supported) */ # undef CONFIG_USART0_FLOWCONTROL # undef CONFIG_USART1_FLOWCONTROL diff --git a/arch/arm/src/lpc54xx/lpc54_i2c_master.c b/arch/arm/src/lpc54xx/lpc54_i2c_master.c new file mode 100644 index 00000000000..a4e8eaf7140 --- /dev/null +++ b/arch/arm/src/lpc54xx/lpc54_i2c_master.c @@ -0,0 +1,779 @@ +/**************************************************************************** + * arch/arm/src/lpc54xx/lpc54_i2c_master.c + * + * Copyright (C) 2017 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 "chip.h" +#include "up_arch.h" +#include "up_internal.h" + +#include "chip/lpc54_pinmux.h" +#include "chip/lpc54_syscon.h" +#include "chip/lpc54_flexcomm.h" +#include "chip/lpc54_i2c.h" +#include "lpc54_config.h" +#include "lpc54_i2c_master.h" + +#ifdef HAVE_SPI_MASTER_DEVICE + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +struct lpc54_i2cdev_s +{ + struct i2c_master_s dev; /* Generic I2C device */ + unsigned int base; /* Base address of registers */ + uint16_t irqid; /* IRQ for this device */ + uint32_t inclck; /* I2C input clock frequency */ + + sem_t exclsem; /* Only one thread can access at a time */ + sem_t waitsem; /* Supports wait for state machine completion */ + volatile uint8_t state; /* State of state machine */ + WDOG_ID timeout; /* watchdog to timeout when bus hung */ + uint32_t frequency; /* Current I2C frequency */ + + struct i2c_msg_s *msgs; /* remaining transfers - first one is in progress */ + unsigned int nmsg; /* number of transfer remaining */ + + uint16_t wrcnt; /* number of bytes sent to tx fifo */ + uint16_t rdcnt; /* number of bytes read from rx fifo */ +}; + +#ifdef CONFIG_LPC54_I2C0_MASTER +static struct lpc54_i2cdev_s g_i2c0_dev; +#endif +#ifdef CONFIG_LPC54_I2C1_MASTER +static struct lpc54_i2cdev_s g_i2c1_dev; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static int lpc54_i2c_start(struct lpc54_i2cdev_s *priv); +static void lpc54_i2c_stop(struct lpc54_i2cdev_s *priv); +static int lpc54_i2c_interrupt(int irq, FAR void *context, FAR void *arg); +static void lpc54_i2c_timeout(int argc, uint32_t arg, ...); +static void lpc54_i2c_setfrequency(struct lpc54_i2cdev_s *priv, + uint32_t frequency); +static int lpc54_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count); +#ifdef CONFIG_I2C_RESET +static int lpc54_i2c_reset(FAR struct i2c_master_s * dev); +#endif + +/**************************************************************************** + * I2C device operations + ****************************************************************************/ + +struct i2c_ops_s lpc54_i2c_ops = +{ + .transfer = lpc54_i2c_transfer +#ifdef CONFIG_I2C_RESET + , .reset = lpc54_i2c_reset +#endif +}; + +/**************************************************************************** + * Name: lpc54_i2c_setfrequency + * + * Description: + * Set the frequency for the next transfer + * + ****************************************************************************/ + +static void lpc54_i2c_setfrequency(struct lpc54_i2cdev_s *priv, + uint32_t frequency) +{ + /* Has the I2C frequency changed? */ + + if (frequency != priv->frequency) + { + /* Yes.. instantiate the new I2C frequency */ +#warning Missing logic + + priv->frequency = frequency; + } +} + +/**************************************************************************** + * Name: lpc54_i2c_start + * + * Description: + * Perform a I2C transfer start + * + ****************************************************************************/ + +static int lpc54_i2c_start(struct lpc54_i2cdev_s *priv) +{ +#warning Missing logic + return priv->nmsg; +} + +/**************************************************************************** + * Name: lpc54_i2c_stop + * + * Description: + * Perform a I2C transfer stop + * + ****************************************************************************/ + +static void lpc54_i2c_stop(struct lpc54_i2cdev_s *priv) +{ +#warning Missing logic + nxsem_post(&priv->waitsem); +} + +/**************************************************************************** + * Name: lpc54_i2c_timeout + * + * Description: + * Watchdog timer for timeout of I2C operation + * + ****************************************************************************/ + +static void lpc54_i2c_timeout(int argc, uint32_t arg, ...) +{ + struct lpc54_i2cdev_s *priv = (struct lpc54_i2cdev_s *)arg; + + irqstate_t flags = enter_critical_section(); + priv->state = 0xff; + nxsem_post(&priv->waitsem); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: lpc32_i2c_nextmsg + * + * Description: + * Setup for the next message. + * + ****************************************************************************/ + +void lpc32_i2c_nextmsg(struct lpc54_i2cdev_s *priv) +{ + priv->nmsg--; + + if (priv->nmsg > 0) + { + priv->msgs++; +#warning Missing logic + } + else + { + lpc54_i2c_stop(priv); + } +} + +/**************************************************************************** + * Name: lpc54_i2c_interrupt + * + * Description: + * The I2C Interrupt Handler + * + ****************************************************************************/ + +static int lpc54_i2c_interrupt(int irq, FAR void *context, FAR void *arg) +{ + struct lpc54_i2cdev_s *priv = (struct lpc54_i2cdev_s *)arg; + struct i2c_msg_s *msg; + uint32_t state; + + DEBUGASSERT(priv != NULL); + + state = getreg32(priv->base + LPC54_I2C_STAT_OFFSET); + msg = priv->msgs; +#warning Missing logic + + priv->state = state; + switch (state) + { +#warning Missing logic + default: + lpc54_i2c_stop(priv); + break; + } + +#warning Missing logic + return OK; +} + +/**************************************************************************** + * Name: lpc54_i2c_transfer + * + * Description: + * Perform a sequence of I2C transfers + * + ****************************************************************************/ + +static int lpc54_i2c_transfer(FAR struct i2c_master_s *dev, + FAR struct i2c_msg_s *msgs, int count) +{ + struct lpc54_i2cdev_s *priv = (struct lpc54_i2cdev_s *)dev; + int ret; + + DEBUGASSERT(dev != NULL); + + /* Get exclusive access to the I2C bus */ + + nxsem_wait(&priv->exclsem); + + /* Set up for the transfer */ + + priv->wrcnt = 0; + priv->rdcnt = 0; + priv->msgs = msgs; + priv->nmsg = count; + + /* Configure the I2C frequency. + * REVISIT: Note that the frequency is set only on the first message. + * This could be extended to support different transfer frequencies for + * each message segment. + */ + + lpc54_i2c_setfrequency(priv, msgs->frequency); + + /* Perform the transfer */ + + ret = lpc54_i2c_start(priv); + + nxsem_post(&priv->exclsem); + return ret; +} + +/************************************************************************************ + * Name: lpc54_i2c_reset + * + * Description: + * Perform an I2C bus reset in an attempt to break loose stuck I2C devices. + * + * Input Parameters: + * dev - Device-specific state data + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#ifdef CONFIG_I2C_RESET +static int lpc54_i2c_reset(FAR struct i2c_master_s * dev) +{ +#warning Missing logic + return OK; +} +#endif /* CONFIG_I2C_RESET */ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc54_i2cbus_initialize + * + * Description: + * Initialise an I2C device + * + ****************************************************************************/ + +struct i2c_master_s *lpc54_i2cbus_initialize(int port) +{ + struct lpc54_i2cdev_s *priv; + irqstate_t flags; + uint32_t regval; + uint32_t deffreq; + + flags = enter_critical_section(); + + /* Configure the requestin I2C peripheral */ + /* NOTE: The basic FLEXCOMM initialization was performed in + * lpc54_lowputc.c. + */ + +#ifdef CONFIG_LPC54_I2C0_MASTER + if (port == 0) + { + /* Attach 12 MHz clock to FLEXCOMM0 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM0, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM0 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM0_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c0_dev; + priv->base = LPC54_FLEXCOMM0_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM0; + priv->inclck = BOARD_FLEXCOMM0_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C0_SCL); + lpc54_gpio_config(GPIO_I2C0_SDA); + + /* Set up the FLEXCOMM0 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C0_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C1_MASTER + if (port == 1) + { + /* Attach 12 MHz clock to FLEXCOMM1 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM1, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM1 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM1_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c1_dev; + priv->base = LPC54_FLEXCOMM1_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM1; + priv->inclck = BOARD_FLEXCOMM1_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C1_SCL); + lpc54_gpio_config(GPIO_I2C1_SDA); + + /* Set up the FLEXCOMM1 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C1_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C2_MASTER + if (port == 2) + { + /* Attach 12 MHz clock to FLEXCOMM2 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM2, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM2 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM2_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c2_dev; + priv->base = LPC54_FLEXCOMM2_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM2; + priv->inclck = BOARD_FLEXCOMM2_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C2_SCL); + lpc54_gpio_config(GPIO_I2C2_SDA); + + /* Set up the FLEXCOMM2 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C2_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C3_MASTER + if (port == 3) + { + /* Attach 12 MHz clock to FLEXCOMM3 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM3, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM3 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM3_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c3_dev; + priv->base = LPC54_FLEXCOMM3_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM3; + priv->inclck = BOARD_FLEXCOMM3_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C3_SCL); + lpc54_gpio_config(GPIO_I2C3_SDA); + + /* Set up the FLEXCOMM3 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C3_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C4_MASTER + if (port == 4) + { + /* Attach 12 MHz clock to FLEXCOMM4 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM4, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM4 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM4_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c4_dev; + priv->base = LPC54_FLEXCOMM4_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM4; + priv->inclck = BOARD_FLEXCOMM4_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C4_SCL); + lpc54_gpio_config(GPIO_I2C4_SDA); + + /* Set up the FLEXCOMM4 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C4_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C5_MASTER + if (port == 5) + { + /* Attach 12 MHz clock to FLEXCOMM5 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM5, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM5 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM5_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c5_dev; + priv->base = LPC54_FLEXCOMM5_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM5; + priv->inclck = BOARD_FLEXCOMM5_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C5_SCL); + lpc54_gpio_config(GPIO_I2C5_SDA); + + /* Set up the FLEXCOMM5 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C5_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C6_MASTER + if (port == 6) + { + /* Attach 12 MHz clock to FLEXCOMM6 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM6, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM6 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM6_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c6_dev; + priv->base = LPC54_FLEXCOMM6_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM6; + priv->inclck = BOARD_FLEXCOMM6_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C6_SCL); + lpc54_gpio_config(GPIO_I2C6_SDA); + + /* Set up the FLEXCOMM6 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C6_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C7_MASTER + if (port == 7) + { + /* Attach 12 MHz clock to FLEXCOMM7 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM7, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM7 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM7_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c7_dev; + priv->base = LPC54_FLEXCOMM7_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM7; + priv->inclck = BOARD_FLEXCOMM7_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C7_SCL); + lpc54_gpio_config(GPIO_I2C7_SDA); + + /* Set up the FLEXCOMM7 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C7_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C8_MASTER + if (port == 8) + { + /* Attach 12 MHz clock to FLEXCOMM8 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM8, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM8 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM8_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c8_dev; + priv->base = LPC54_FLEXCOMM8_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM8; + priv->inclck = BOARD_FLEXCOMM8_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C8_SCL); + lpc54_gpio_config(GPIO_I2C8_SDA); + + /* Set up the FLEXCOMM8 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C8_DEFAULT_FREQUENCY; + } + else +#endif +#ifdef CONFIG_LPC54_I2C9_MASTER + if (port == 9) + { + /* Attach 12 MHz clock to FLEXCOMM9 */ + + putreg32(SYSCON_AHBCLKCTRL1_FLEXCOMM9, LPC54_SYSCON_AHBCLKCTRLSET1); + + /* Set FLEXCOMM9 to the I2C peripheral, locking that configuration + * in place. + */ + + putreg32(FLEXCOMM_PSELID_PERSEL_I2C | FLEXCOMM_PSELID_LOCK, + LPC54_FLEXCOMM9_PSELID); + + /* Initialize the state structure */ + + priv = &g_i2c9_dev; + priv->base = LPC54_FLEXCOMM9_BASE; + priv->irqid = LPC54_IRQ_FLEXCOMM9; + priv->inclck = BOARD_FLEXCOMM9_FCLK; + + /* Configure I2C pins (defined in board.h) */ + + lpc54_gpio_config(GPIO_I2C9_SCL); + lpc54_gpio_config(GPIO_I2C9_SDA); + + /* Set up the FLEXCOMM9 function clock */ + + putreg32(BOARD_FLEXCOMM2_CLKSEL, LPC54_SYSCON_FCLKSEL2); + + /* Set the default I2C frequency */ + + deffreq = I2C9_DEFAULT_FREQUENCY; + } + else +#endif + { + return NULL; + } + + leave_critical_section(flags); + + /* Enable the I2C peripheral and configure master mode */ +#Missing logic + + /* Set the default I2C frequency */ + + lpc54_i2c_setfrequency(priv, deffreq); + + /* Initialize semaphores */ + + nxsem_init(&priv->exclsem, 0, 1); + nxsem_init(&priv->waitsem, 0, 0); + + /* The waitsem semaphore is used for signaling and, hence, should not have + * priority inheritance enabled. + */ + + nxsem_setprotocol(&priv->waitsem, SEM_PRIO_NONE); + + /* Allocate a watchdog timer */ + + priv->timeout = wd_create(); + DEBUGASSERT(priv->timeout != 0); + + /* Attach Interrupt Handler */ + + irq_attach(priv->irqid, lpc54_i2c_interrupt, priv); + + /* Enable Interrupt Handler */ + + up_enable_irq(priv->irqid); + + /* Install our operations */ + + priv->dev.ops = &lpc54_i2c_ops; + return &priv->dev; +} + +/**************************************************************************** + * Name: lpc54_i2cbus_uninitialize + * + * Description: + * Uninitialise an I2C device + * + ****************************************************************************/ + +int lpc54_i2cbus_uninitialize(FAR struct i2c_master_s * dev) +{ + struct lpc54_i2cdev_s *priv = (struct lpc54_i2cdev_s *) dev; + + /* Disable I2C interrupts */ +#warning Missing logic + + /* Disable the I2C perifpheral */ + + putreg32(0, base + LPC54_USART_CFG_OFFSET); +#warning Missing logic + + /* Disables the Flexcomm interface at the NVIC and detach the interrupt. */ + + up_disable_irq(priv->irqid); + irq_detach(priv->irqid); + return OK; +} + +#endif /* HAVE_SPI_MASTER_DEVICE */ diff --git a/arch/arm/src/lpc54xx/lpc54_i2c_master.h b/arch/arm/src/lpc54xx/lpc54_i2c_master.h new file mode 100644 index 00000000000..1655d0fec5e --- /dev/null +++ b/arch/arm/src/lpc54xx/lpc54_i2c_master.h @@ -0,0 +1,87 @@ +/**************************************************************************** + * arch/arm/src/lpc54xx/lpc54_i2c.h + * + * Copyright (C) 2017 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_LPC54XX_LPC54_I2C_MASTER_H +#define __ARCH_ARM_SRC_LPC54XX_LPC54_I2C_MASTER_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include "chip/lpc54_i2c.h" + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: lpc54_i2cbus_initialize + * + * Description: + * Initialize the selected I2C port. And return a unique instance of struct + * struct i2c_master_s. This function may be called to obtain multiple + * instances of the interface, each of which may be set up with a + * different frequency and slave address. + * + * Input Parameter: + * Port number (for hardware that has multiple I2C interfaces) + * + * Returned Value: + * Valid I2C device structure reference on succcess; a NULL on failure + * + ****************************************************************************/ + +FAR struct i2c_master_s *lpc54_i2cbus_initialize(int port); + +/**************************************************************************** + * Name: lpc54_i2cbus_uninitialize + * + * Description: + * De-initialize the selected I2C port, and power down the device. + * + * Input Parameter: + * Device structure as returned by the lpc54_i2cbus_initialize() + * + * Returned Value: + * OK on success, ERROR when internal reference count mismatch or dev + * points to invalid hardware device. + * + ****************************************************************************/ + +int lpc54_i2cbus_uninitialize(FAR struct i2c_master_s *dev); + +#endif /* __ARCH_ARM_SRC_LPC54XX_LPC54_I2C_MASTER_H */