SX1302_HAL/libloragw/src/loragw_i2c.c
Michael Coracin 4c61c5d48e v1.0.0
* Initial release for SX1302 CoreCell Reference Design.
2019-07-12 15:40:13 +02:00

157 lines
4.8 KiB
C

/*
/ _____) _ | |
( (____ _____ ____ _| |_ _____ ____| |__
\____ \| ___ | (_ _) ___ |/ ___) _ \
_____) ) ____| | | || |_| ____( (___| | | |
(______/|_____)_|_|_| \__)_____)\____)_| |_|
(C)2019 Semtech
Description:
Host specific functions to address the LoRa concentrator I2C peripherals.
License: Revised BSD License, see LICENSE.TXT file include in the project
*/
/* -------------------------------------------------------------------------- */
/* --- DEPENDANCIES --------------------------------------------------------- */
#include <stdint.h> /* C99 types */
#include <stdio.h> /* printf fprintf */
#include <stdlib.h> /* malloc free */
#include <unistd.h> /* lseek, close */
#include <fcntl.h> /* open */
#include <string.h> /* memset */
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include "loragw_i2c.h"
#include "loragw_aux.h"
/* -------------------------------------------------------------------------- */
/* --- PRIVATE MACROS ------------------------------------------------------- */
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#if DEBUG_I2C == 1
#define DEBUG_MSG(str) fprintf(stderr, str)
#define DEBUG_PRINTF(fmt, args...) fprintf(stderr,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
#define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_SPI_ERROR;}
#else
#define DEBUG_MSG(str)
#define DEBUG_PRINTF(fmt, args...)
#define CHECK_NULL(a) if(a==NULL){return LGW_SPI_ERROR;}
#endif
/* -------------------------------------------------------------------------- */
/* --- PRIVATE CONSTANTS ---------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
int i2c_linuxdev_open(const char *path, uint8_t device_addr, int *i2c_fd) {
int dev;
/* Check input variables */
if (path == NULL) {
DEBUG_MSG("ERROR: null pointer path");
return LGW_I2C_ERROR;
}
if (i2c_fd == NULL) {
DEBUG_MSG("ERROR: null pointer i2c_fd");
return LGW_I2C_ERROR;
}
/* Open I2C device */
dev = open(path, O_RDWR);
if (dev < 0) {
DEBUG_PRINTF("ERROR: Failed to open I2C %s - %s", path, strerror(errno));
return LGW_I2C_ERROR;
}
/* Setting I2C device mode to slave */
if (ioctl(dev, I2C_SLAVE, device_addr) < 0) {
DEBUG_PRINTF("ERROR: Failed to acquire bus access and/or talk to slave - %s\n", strerror(errno));
return LGW_I2C_ERROR;
}
DEBUG_MSG("INFO: I2C port opened successfully");
*i2c_fd = dev; /* return file descriptor index */
return LGW_I2C_SUCCESS;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int i2c_linuxdev_read(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_t *data) {
uint8_t *inbuff, outbuff;
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[2];
outbuff = reg_addr;
messages[0].addr = device_addr;
messages[0].flags= 0;
messages[0].len = sizeof(outbuff);
messages[0].buf = &outbuff;
inbuff = data;
messages[1].addr = device_addr;
messages[1].flags = I2C_M_RD;
messages[1].len = sizeof(*inbuff);
messages[1].buf = inbuff;
packets.msgs = messages;
packets.nmsgs = 2;
if (ioctl(i2c_fd, I2C_RDWR, &packets) < 0) {
DEBUG_PRINTF("ERROR: Read from I2C Device failed (%d, 0x%02x, 0x%02x) - %s", i2c_fd, device_addr, reg_addr, strerror(errno));
return LGW_I2C_ERROR;
}
return LGW_I2C_SUCCESS;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int i2c_linuxdev_write(int i2c_fd, uint8_t device_addr, uint8_t reg_addr, uint8_t data) {
unsigned char buff[2];
struct i2c_rdwr_ioctl_data packets;
struct i2c_msg messages[1];
buff[0] = reg_addr;
buff[1] = data;
messages[0].addr = device_addr;
messages[0].flags = 0;
messages[0].len = sizeof(buff);
messages[0].buf = buff;
packets.msgs = messages;
packets.nmsgs = 1;
if (ioctl(i2c_fd, I2C_RDWR, &packets) < 0) {
DEBUG_PRINTF("ERROR: Write to I2C Device failed (%d, 0x%02x, 0x%02x) - %s", i2c_fd, device_addr, reg_addr, strerror(errno));
return LGW_I2C_ERROR;
}
return LGW_I2C_SUCCESS;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
int i2c_linuxdev_close(int i2c_fd) {
int i;
i = close(i2c_fd);
if (i == 0) {
DEBUG_MSG("INFO: I2C port closed successfully");
return LGW_I2C_SUCCESS;
} else {
DEBUG_PRINTF("ERROR: Failed to close I2C - %s", strerror(errno));
return LGW_I2C_ERROR;
}
}
/* --- EOF ------------------------------------------------------------------ */