Add z8 I2C driver

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1680 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-04-04 20:53:06 +00:00
parent affc606a1d
commit 6d10d5deb9
6 changed files with 648 additions and 23 deletions

View File

@ -688,3 +688,6 @@
* eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards. * eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards.
* Add a setmode() method to the SPI interface to handle parts with differing * Add a setmode() method to the SPI interface to handle parts with differing
mode requirements. mode requirements.
* include/nuttx/i2c.h: Defined a standard I2C interface
* eZ80Acclaim!: Add an I2C driver.
* eZ8Encore!: Add an I2C driver.

View File

@ -8,7 +8,7 @@
<tr align="center" bgcolor="#e4e4e4"> <tr align="center" bgcolor="#e4e4e4">
<td> <td>
<h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1> <h1><big><font color="#3c34ec"><i>NuttX RTOS</i></font></big></h1>
<p>Last Updated: March 29, 2009</p> <p>Last Updated: April 4, 2009</p>
</td> </td>
</tr> </tr>
</table> </table>
@ -948,7 +948,7 @@ BFD_ASSERT (*plt_offset != (bfd_vma) -1);
Integration and testing of NuttX on the ZiLOG ez80f0910200zcog-d is complete. Integration and testing of NuttX on the ZiLOG ez80f0910200zcog-d is complete.
The first integrated version was released in NuttX version 0.4.2 (with important early bugfixes The first integrated version was released in NuttX version 0.4.2 (with important early bugfixes
in 0.4.3 and 0.4.4). in 0.4.3 and 0.4.4).
As of this writing, that port provides basic board support with a serial console and eZ80F91 EMAC driver. As of this writing, that port provides basic board support with a serial console, SPI, and eZ80F91 EMAC driver.
</p> </p>
</td> </td>
</tr> </tr>
@ -1361,11 +1361,16 @@ nuttx-0.4.5 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
* eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards. * eZ80Acclaim!: Add a generic SPI driver for all eZ80 boards.
* Add a setmode() method to the SPI interface to handle parts with differing * Add a setmode() method to the SPI interface to handle parts with differing
mode requirements. mode requirements.
* include/nuttx/i2c.h: Defined a standard I2C interface
* eZ80Acclaim!: Add an I2C driver.
* eZ8Encore!: Add an I2C driver.
pascal-0.1.3 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt; pascal-0.1.3 2009-xx-xx Gregory Nutt &lt;spudmonkey@racsa.co.cr&gt;
buildroot-0.1.4 2009-xx-xx &lt;spudmonkey@racsa.co.cr&gt; buildroot-0.1.4 2009-xx-xx &lt;spudmonkey@racsa.co.cr&gt;
* Add support for a blackfin toolchain using GCC 4.2.4 and binutils 2.19
</pre></ul> </pre></ul>
<table width ="100%"> <table width ="100%">

10
TODO
View File

@ -688,8 +688,14 @@ o z80/z8/ez80 (arch/z80)
Status: Open Status: Open
Priority: High if you happen to be working with XTRS. Priority: High if you happen to be working with XTRS.
Description: A "generic" SPI driver has been coded for the eZ80Acclaim! Description: A "generic" SPI and I2C drivers have been coded for the eZ80Acclaim!
However, this remains untested since I have no SPI devices for However, these remains untested since I have no SPI or I2C devices for
the board (yet).
Status: Open
Priority: Med
Description: A "generic" I2C driver has been coded for the eZ8Encore!
However, this remains untested since I have no I2C devices for
the board (yet). the board (yet).
Status: Open Status: Open
Priority: Med Priority: Med

View File

@ -1,7 +1,7 @@
############################################################################ ############################################################################
# arch/z80/src/z8/Make.defs # arch/z80/src/z8/Make.defs
# #
# Copyright (C) 2008 Gregory Nutt. All rights reserved. # Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <spudmonkey@racsa.co.cr> # Author: Gregory Nutt <spudmonkey@racsa.co.cr>
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -45,5 +45,5 @@ CMN_CSRCS = up_initialize.c up_allocateheap.c up_createstack.c \
CHIP_SSRCS = z8_vector.S z8_saveusercontext.S z8_restorecontext.S CHIP_SSRCS = z8_vector.S z8_saveusercontext.S z8_restorecontext.S
CHIP_CSRCS = z8_initialstate.c z8_irq.c z8_saveirqcontext.c \ CHIP_CSRCS = z8_initialstate.c z8_irq.c z8_saveirqcontext.c \
z8_schedulesigaction.c z8_sigdeliver.c z8_timerisr.c \ z8_schedulesigaction.c z8_sigdeliver.c z8_timerisr.c \
z8_lowuart.c z8_serial.c z8_registerdump.c z8_lowuart.c z8_serial.c z8_i2c.c z8_registerdump.c

View File

@ -2,7 +2,7 @@
* arch/z80/src/z8/chip.h * arch/z80/src/z8/chip.h
* arch/z80/src/chip/chip.h * arch/z80/src/chip/chip.h
* *
* Copyright (C) 2008 Gregory Nutt. All rights reserved. * Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr> * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -167,27 +167,35 @@
/* I2C Status Register Bit Definitions **********************************************/ /* I2C Status Register Bit Definitions **********************************************/
#if defined(_Z8FMC16) || defined(_Z8F1680) #if defined(_Z8FMC16) || defined(_Z8F1680)
# define I2C_ISTAT_NCKI (1 << 0) /* Bit 0: 1=NAK Interrupt */
# define I2C_ISTAT_SPRS (1 << 1) /* Bit 1: 1=STOP/RESTART condition Interrupt */
# define I2C_ISTAT_ARBLST (1 << 2) /* Bit 2: 1=Arbitration lost */
# define I2C_ISTAT_RD (1 << 3) /* Bit 3: 1=Read */
# define I2C_ISTAT_GCA (1 << 4) /* Bit 4: 1=General Call Address */
# define I2C_ISTAT_SAM (1 << 5) /* Bit 5: 1=Slave address match */
# define I2C_ISTAT_RDRF (1 << 6) /* Bit 6: 1=Receive Data Register Full */
# define I2C_ISTAT_TDRE (1 << 7) /* Bit 7: 1=Transmit Data Register Empty */
#else #else
# define I2C_STAT_NCKI (1 << 0) /* Bit 0: 1=NACK Interrupt */ # define I2C_STAT_NCKI (1 << 0) /* Bit 0: 1=NAK Interrupt */
# define I2C_STAT_DSS (1 << 1) /* Bit 1: 1=Data Shift State */ # define I2C_STAT_DSS (1 << 1) /* Bit 1: 1=Data Shift State */
# define I2C_STAT_TAS (1 << 2) /* Bit 2: 1=Transmit Address State */ # define I2C_STAT_TAS (1 << 2) /* Bit 2: 1=Transmit Address State */
# define I2C_STAT_RD (1 << 3) /* Bit 3: 1=Read */ # define I2C_STAT_RD (1 << 3) /* Bit 3: 1=Read */
# define I2C_STAT_10B (1 << 4) /* Bit 4: 1=10-Bit Address */ # define I2C_STAT_10B (1 << 4) /* Bit 4: 1=10-Bit Address */
# define I2C_STAT_ACK (1 << 5) /* Bit 5: 1=Acknowledge */ # define I2C_STAT_ACK (1 << 5) /* Bit 5: 1=Acknowledge */
# define I2C_STAT_RDRF (1 << 6) /* Bit 6: 1=Receive Data Register Full */ # define I2C_STAT_RDRF (1 << 6) /* Bit 6: 1=Receive Data Register Full */
# define I2C_STAT_TDRE (1 << 7) /* Bit 7: 1=Transmit Data Register Empty */ # define I2C_STAT_TDRE (1 << 7) /* Bit 7: 1=Transmit Data Register Empty */
#endif #endif
/* I2C Control Register Bit Definitions *********************************************/ /* I2C Control Register Bit Definitions *********************************************/
#define I2C_CTL_FILTEN (1 << 0) /* Bit 0: 1=I2C Signal Filter Enable */ #define I2C_CTL_FILTEN (1 << 0) /* Bit 0: 1=I2C Signal Filter Enable */
#define I2C_CTL_FLUSH (1 << 1) /* Bit 1: 1=Flush Data */ #define I2C_CTL_FLUSH (1 << 1) /* Bit 1: 1=Flush Data */
#define I2C_CTL_NAK (1 << 2) /* Bit 2: 1=Send NAK */ #define I2C_CTL_NAK (1 << 2) /* Bit 2: 1=Send NAK */
#define I2C_CTL_TXI (1 << 3) /* Bit 3: 1=Enable TDRE interrupts */ #define I2C_CTL_TXI (1 << 3) /* Bit 3: 1=Enable TDRE interrupts */
#define I2C_CTL_BIRQ (1 << 4) /* Bit 4: 1=Baud Rate Generator Interrupt Request */ #define I2C_CTL_BIRQ (1 << 4) /* Bit 4: 1=Baud Rate Generator Interrupt Request */
#define I2C_CTL_STOP (1 << 5) /* Bit 5: 1=Send Stop Condition */ #define I2C_CTL_STOP (1 << 5) /* Bit 5: 1=Send Stop Condition */
#define I2C_CTL_START (1 << 6) /* Bit 6: 1=Send Start Condition */ #define I2C_CTL_START (1 << 6) /* Bit 6: 1=Send Start Condition */
#define I2C_CTL_IEN (1 << 7) /* Bit 7: 1=I2C Enable */ #define I2C_CTL_IEN (1 << 7) /* Bit 7: 1=I2C Enable */
/* Register access macros *********************************************************** /* Register access macros ***********************************************************
* *

603
arch/z80/src/z8/z8_i2c.c Executable file
View File

@ -0,0 +1,603 @@
/****************************************************************************
* arch/z80/src/z8/z8_i2c.c
*
* Copyright(C) 2009 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* 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 <nuttx/config.h>
#include <sys/types.h>
#include <stdlib.h>
#include <semaphore.h>
#include <errno.h>
#include <assert.h>
#include <debug.h>
#include <nuttx/i2c.h>
#include <arch/board/board.h>
#include <eZ8.h> /* eZ8 Register definitions */
#include "chip.h" /* Register bit definitions */
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Types
****************************************************************************/
struct z8_i2cdev_s
{
const struct i2c_ops_s *ops; /* I2C vtable */
uint16 brg; /* Baud rate generator value */
ubyte addr; /* 8-bit address */
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Misc. Helpers */
static void i2c_waittxempty(void);
static void i2c_waitrxavail(void);
static void i2c_setbrg(uint16 brg);
static uint16 i2c_getbrg(uint32 frequency);
/* I2C methods */
static uint32 i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32 frequency);
static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits);
static int i2c_write(FAR struct i2c_dev_s *dev, const ubyte *buffer, int buflen);
static int i2c_read(FAR struct i2c_dev_s *dev, ubyte *buffer, int buflen);
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* This function is normally prototyped int the ZiLOG header file sio.h */
extern uint32 get_freq(void);
/****************************************************************************
* Private Data
****************************************************************************/
static uint16 g_currbrg; /* Current BRG setting */
static boolean g_initialized; /* TRUE:I2C has been initialized */
static sem_t g_i2csem; /* Serialize I2C transfers */
const struct i2c_ops_s g_ops =
{
i2c_setfrequency,
i2c_setaddress,
i2c_write,
i2c_read,
};
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: i2c_semtake/i2c_semgive
*
* Description:
* Take/Give the I2C semaphore.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void i2c_semtake(void)
{
/* Take the I2C semaphore (perhaps waiting) */
while (sem_wait(&g_i2csem) != 0)
{
/* The only case that an error should occr here is if
* the wait was awakened by a signal.
*/
ASSERT(errno == EINTR);
}
}
#define i2c_semgive() sem_post(&g_i2csem)
/****************************************************************************
* Name: i2c_waittxempty
*
* Description:
* Wait for the transmit data register to become empty.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void i2c_waittxempty(void)
{
int i;
for (i = 0; i < 10000 && (I2CSTAT & I2C_STAT_TDRE) == 0; i++);
}
/****************************************************************************
* Name: i2c_waitrxavail
*
* Description:
* Wait until we have received a full byte of data.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
static void i2c_waitrxavail(void)
{
int i;
for (i = 0; i <= 10000 && (I2CSTAT & (I2C_STAT_RDRF | I2C_STAT_NCKI)) == 0; i++);
}
/****************************************************************************
* Name: i2c_setbrg
*
* Description:
* Set the current BRG value for this transaction
*
* Input Parameters:
* brg - BRG to set
*
* Returned Value:
* None
*
****************************************************************************/
static void i2c_setbrg(uint16 brg)
{
if (g_currbrg != brg)
{
I2CBRH = (ubyte)(brg >> 8);
I2CBRL = (ubyte)(brg & 0xff);
g_currbrg = brg;
}
}
/****************************************************************************
* Name: i2c_getbrg
*
* Description:
* Calculate the BRG value
*
* Input Parameters:
* frequency - The I2C frequency requested
*
* Returned Value:
* Returns the actual frequency selected
*
****************************************************************************/
static uint16 i2c_getbrg(uint32 frequency)
{
uint32 sysclock = get_freq();
/* Max is 400 Kb/sec */
if (frequency > 400*1000)
{
dbg("Invalid inputs\n");
frequency = 400*1000;
}
/* BRG = sysclock / (4 * frequency) */
return ((sysclock >> 2) + (frequency >> 1)) / frequency;
}
/****************************************************************************
* Name: i2c_setfrequency
*
* Description:
* Set the I2C frequency. This frequency will be retained in the struct
* i2c_dev_s instance and will be used with all transfers. Required.
*
* Input Parameters:
* dev - Device-specific state data
* frequency - The I2C frequency requested
*
* Returned Value:
* Returns the actual frequency selected
*
****************************************************************************/
static uint32 i2c_setfrequency(FAR struct i2c_dev_s *dev, uint32 frequency)
{
FAR struct z8_i2cdev_s *priv = (FAR struct z8_i2cdev_s *)dev;
/* Sanity Check */
#ifdef CONFIG_DEBUG
if (!dev)
{
dbg("Invalid inputs\n");
return -EINVAL;
}
#endif
/* Calculate and save the BRG (we won't apply it until the first transfer) */
priv->brg = i2c_getbrg(frequency);
return OK;
}
/****************************************************************************
* Name: i2c_setaddress
*
* Description:
* Set the I2C slave address. This frequency will be retained in the struct
* i2c_dev_s instance and will be used with all transfers. Required.
*
* Input Parameters:
* dev - Device-specific state data
* address - The I2C slave address
* nbits - The number of address bits provided (7 or 10)
*
* Returned Value:
* Returns the actual frequency selected
*
****************************************************************************/
static int i2c_setaddress(FAR struct i2c_dev_s *dev, int addr, int nbits)
{
FAR struct z8_i2cdev_s *priv = (FAR struct z8_i2cdev_s *)dev;
/* Sanity Check */
#ifdef CONFIG_DEBUG
if (!dev || (unsigned)addr > 0x7f)
{
dbg("Invalid inputs\n");
return -EINVAL;
}
#endif
/* Save the 7-bit address (10-bit address not yet supported) */
DEBUGASSERT(nbits == 7);
priv->addr = (ubyte)addr;
return OK;
}
/****************************************************************************
* Name: i2c_write
*
* Description:
* Send a block of data on I2C using the previously selected I2C
* frequency and slave address. Each write operational will be an 'atomic'
* operation in the sense that any other I2C actions will be serialized
* and pend until this write completes. Required.
*
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to the read-only buffer of data to be written to device
* buflen - The number of bytes to send from the buffer
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
static int i2c_write(FAR struct i2c_dev_s *dev, const ubyte *buffer, int buflen)
{
FAR struct z8_i2cdev_s *priv = (FAR struct z8_i2cdev_s *)dev;
const ubyte *ptr;
int retry;
int count;
#ifdef CONFIG_DEBUG
if (!priv || !buffer || buflen < 1)
{
dbg("Invalid inputs\n");
return -EINVAL;
}
#endif
/* Get exclusive access */
i2c_semtake();
/* Set the frequency */
i2c_setbrg(priv->brg);
/* Retry as necessary to send this whole message */
for (retry = 0; retry < 100; retry++)
{
/* Load the address into the transmit register. It is not sent
* until the START bit is set.
*/
I2CD = I2C_WRITEADDR8(priv->addr);
I2CCTL |= I2C_CTL_START;
/* Wait for the xmt buffer to become empty */
i2c_waittxempty();
/* Then send all of the bytes in the buffer */
ptr = buffer;
for (count = buflen; count; count--)
{
/* Send a byte of data and wait for it to be sent */
I2CD = *ptr++;
i2c_waittxempty();
/* If this was the last byte, then send STOP immediately. This
* is because the ACK will not be valid until the STOP clocks out
* the last bit.. Hmmm. If this true then we will never be
* able to send more than one data byte???
*/
if (count == 1)
{
I2CCTL |= I2C_CTL_STOP;
/* If this last byte was ACKed, then the whole buffer
* was successfully sent and we can return success.
*/
if ((I2CSTAT & I2C_STAT_ACK) != 0)
{
i2c_semgive();
return OK;
}
/* If was was not ACKed, then this inner loop will
* terminated (because count will decrement to zero
* and the whole message will be resent
*/
}
/* Not the last byte... was this byte ACKed? */
else if ((I2CSTAT & I2C_STAT_ACK) == 0)
{
/* No, flush the buffer and toggle the I2C on and off */
I2CCTL |= I2C_CTL_FLUSH;
I2CCTL &= ~I2C_CTL_IEN;
I2CCTL |= I2C_CTL_IEN;
/* Break out of the loop early and try again */
break;
}
}
}
i2c_semgive();
return -ETIMEDOUT;
}
/****************************************************************************
* Name: i2c_read
*
* Description:
* Receive a block of data from I2C using the previously selected I2C
* frequency and slave address. Each read operational will be an 'atomic'
* operation in the sense that any other I2C actions will be serialized
* and pend until this read completes. Required.
*
* Input Parameters:
* dev - Device-specific state data
* buffer - A pointer to a buffer of data to receive the data from the device
* buflen - The requested number of bytes to be read
*
* Returned Value:
* 0: success, <0: A negated errno
*
****************************************************************************/
static int i2c_read(FAR struct i2c_dev_s *dev, ubyte *buffer, int buflen)
{
FAR struct z8_i2cdev_s *priv = (FAR struct z8_i2cdev_s *)dev;
ubyte *ptr;
int retry;
int count;
#ifdef CONFIG_DEBUG
if (!priv || !buffer || buflen < 1)
{
dbg("Invalid inputs\n");
return -EINVAL;
}
#endif
/* Get exclusive access */
i2c_semtake();
/* Set the frequency */
i2c_setbrg(priv->brg);
/* Retry as necessary to receive the whole message */
for (retry = 0; retry < 100; retry++)
{
/* Load the address into the transmit register. It is not sent
* until the START bit is set.
*/
I2CD = I2C_READADDR8(priv->addr);
/* If we want only a single byte of data, then set the NACK
* bit now.
*/
I2CCTL |= I2C_CTL_NAK;
/* The START bit begins the transaction */
I2CCTL |= I2C_CTL_START;
/* Now loop to receive each data byte */
ptr = buffer;
for (count = buflen; count; count--)
{
/* Wait for the receive buffer to fill */
i2c_waitrxavail();
/* Did we get a byte? Or did an error occur? */
if (I2CSTAT & I2C_STAT_RDRF)
{
/* Save the data byte */
*ptr++ = I2CD;
/* If the next byte is the last byte, then set NAK now */
if (count == 2)
{
I2CCTL |= I2C_CTL_NAK;
}
/* If this was the last byte, then set STOP and return success */
else if (count == 1)
{
I2CCTL |= I2C_CTL_STOP;
i2c_semgive();
return OK;
}
}
/* An error occurred. Clear byte bus and break out of the loop
* to retry now.
*/
else
{
/* No, flush the buffer and toggle the I2C on and off */
I2CCTL |= I2C_CTL_FLUSH;
I2CCTL &= ~I2C_CTL_IEN;
I2CCTL |= I2C_CTL_IEN;
/* Break out of the loop early and try again */
break;
}
}
}
i2c_semgive();
return -ETIMEDOUT;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: up_i2cinitialize
*
* Description:
* Initialize the selected I2C port. And return a unique instance of struct
* struct i2c_dev_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 mutiple I2C interfaces)
*
* Returned Value:
* Valid I2C device structre reference on succcess; a NULL on failure
*
****************************************************************************/
FAR struct i2c_dev_s *up_i2cinitialize(int port)
{
FAR struct z8_i2cdev_s *i2c;
if (!g_initialized)
{
/* Set up some initial BRG value */
uint16 brg = i2c_getbrg(100*1000);
i2c_setbrg(brg);
/* Make sure that GPIOs are configured for the alternate function (this
* varies with silicon revisions).
*/
PAADDR = 0x02;
PACTL |= 0xc0;
/* This semaphore enforces serialized access for I2C transfers */
sem_init(&g_i2csem, 0, 1);
/* Enable I2C -- no interrupts */
I2CCTL = I2C_CTL_IEN;
}
/* Now, allocate an I2C instance for this caller */
i2c = (FAR struct z8_i2cdev_s *)malloc(sizeof(FAR struct z8_i2cdev_s));
if (i2c)
{
/* Initialize the allocated instance */
i2c->ops = &g_ops;
i2c->brg = g_currbrg;
}
return (FAR struct i2c_dev_s *)i2c;
}