mirror of https://github.com/ARMmbed/mbed-os.git
202 lines
4.9 KiB
C
202 lines
4.9 KiB
C
/**
|
|
*******************************************************************************
|
|
* @file i2c.c
|
|
* @brief Implementation of an i2c api
|
|
* @internal
|
|
* @author ON Semiconductor
|
|
* $Rev: 3525 $
|
|
* $Date: 2015-07-20 15:24:25 +0530 (Mon, 20 Jul 2015) $
|
|
******************************************************************************
|
|
* Copyright 2016 Semiconductor Components Industries LLC (d/b/a “ON Semiconductor”).
|
|
* All rights reserved. This software and/or documentation is licensed by ON Semiconductor
|
|
* under limited terms and conditions. The terms and conditions pertaining to the software
|
|
* and/or documentation are available at http://www.onsemi.com/site/pdf/ONSEMI_T&C.pdf
|
|
* (“ON Semiconductor Standard Terms and Conditions of Sale, Section 8 Software”) and
|
|
* if applicable the software license agreement. Do not use this software and/or
|
|
* documentation unless you have carefully read and you agree to the limited terms and
|
|
* conditions. By using this software and/or documentation, you agree to the limited
|
|
* terms and conditions.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
|
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
|
* ON SEMICONDUCTOR SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL,
|
|
* INCIDENTAL, OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
|
* @endinternal
|
|
*
|
|
* @ingroup i2c
|
|
*
|
|
*/
|
|
#if DEVICE_I2C
|
|
|
|
#include "i2c.h"
|
|
#include "i2c_api.h"
|
|
#include "mbed_wait_api.h"
|
|
|
|
#define I2C_READ_WRITE_BIT_MASK 0xFE
|
|
|
|
/* See i2c_api.h for details */
|
|
void i2c_init(i2c_t *obj, PinName sda, PinName scl)
|
|
{
|
|
fI2cInit(obj, sda, scl);
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
void i2c_frequency(i2c_t *obj, int hz)
|
|
{
|
|
fI2cFrequency(obj, hz);
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
int i2c_start(i2c_t *obj)
|
|
{
|
|
return(fI2cStart(obj));
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
int i2c_stop(i2c_t *obj)
|
|
{
|
|
return(fI2cStop(obj));
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
|
|
{
|
|
/* TODO address parameter not usable */
|
|
int Count, status;
|
|
const char WriteData = (address | (~I2C_READ_WRITE_BIT_MASK)) & 0xFF;
|
|
|
|
/* Send start bit */
|
|
status = fI2cStart(obj);
|
|
if(status) {
|
|
/* Error sending start bit */
|
|
return status;
|
|
}
|
|
|
|
/* Send address | read */
|
|
Count = fI2cWriteB(obj, &WriteData, 1);
|
|
if(Count != 1) {
|
|
/* Error sending address */
|
|
return Count;
|
|
}
|
|
|
|
/* Send command/s */
|
|
Count = fI2cReadB(obj, data, length);
|
|
if(Count != length) {
|
|
/* Error sending coomand/s */
|
|
return Count;
|
|
}
|
|
if(stop) { /* Send stop bit if requested */
|
|
status = fI2cStop(obj);
|
|
if(status) {
|
|
/* Error sending stop bit */
|
|
return status;
|
|
}
|
|
}
|
|
return Count;
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
|
|
{
|
|
int Count, status;
|
|
const char WriteData = (address & I2C_READ_WRITE_BIT_MASK) & 0xFF;
|
|
|
|
/* Send start bit */
|
|
status = fI2cStart(obj);
|
|
if(status) {
|
|
/* Error sending start bit */
|
|
return status;
|
|
}
|
|
|
|
/* Send address | write */
|
|
Count = fI2cWriteB(obj, &WriteData, 1);
|
|
if(Count != 1) {
|
|
/* Error sending address */
|
|
return Count;
|
|
}
|
|
|
|
/* Sens command, [data] */
|
|
Count = fI2cWriteB(obj, data, length);
|
|
if(Count != length) {
|
|
/* Error sending address */
|
|
return Count;
|
|
}
|
|
|
|
if(stop) { /* If stop requested */
|
|
/* Send stop bit */
|
|
status = fI2cStop(obj);
|
|
if(status) {
|
|
/* Error sending stop bit */
|
|
return status;
|
|
}
|
|
}
|
|
return Count;
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
void i2c_reset(i2c_t *obj)
|
|
{
|
|
(void)fI2cStop(obj);
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
int i2c_byte_read(i2c_t *obj, int last) /* TODO return size can be uint8_t */
|
|
{
|
|
int Count;
|
|
char data;
|
|
Count = fI2cReadB(obj, &data, 1);
|
|
if(Count != 1) {
|
|
/* Error */
|
|
return Count;
|
|
}
|
|
if(last) {
|
|
/* ACK */
|
|
SEND_COMMAND(I2C_CMD_WDAT0);
|
|
} else {
|
|
/* No ACK */
|
|
SEND_COMMAND(I2C_CMD_WDAT1);
|
|
}
|
|
return data;
|
|
}
|
|
|
|
/* See i2c_api.h for details */
|
|
int i2c_byte_write(i2c_t *obj, int data)
|
|
{
|
|
int Count;
|
|
Count = fI2cWriteB(obj, (const char *)&data, 1);
|
|
if(Count != 1) {
|
|
return Count;
|
|
}
|
|
|
|
if(I2C_BUS_ERR_CHECK) {
|
|
/* Bus error means NAK received */
|
|
return 0;
|
|
} else {
|
|
/* ACK received */
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
const PinMap *i2c_master_sda_pinmap()
|
|
{
|
|
return PinMap_I2C_SDA;
|
|
}
|
|
|
|
const PinMap *i2c_master_scl_pinmap()
|
|
{
|
|
return PinMap_I2C_SCL;
|
|
}
|
|
|
|
const PinMap *i2c_slave_sda_pinmap()
|
|
{
|
|
return PinMap_I2C_SDA;
|
|
}
|
|
|
|
const PinMap *i2c_slave_scl_pinmap()
|
|
{
|
|
return PinMap_I2C_SCL;
|
|
}
|
|
|
|
#endif /* DEVICE_I2C */
|