/**
*
*
*
*
* Copyright (C) Sierra Wireless Inc.
*/
#include "legato.h"
#include "interfaces.h"
#include "le_spiLibrary.h"
#include
#include
#include
//--------------------------------------------------------------------------------------------------
/**
* Configures the SPI bus for use with a specific device.
*/
//--------------------------------------------------------------------------------------------------
void le_spiLib_Configure
(
int fd, ///< [in] name of device file. dont pass */dev* prefix
int mode, ///< [in] mode options for the bus as defined in spidev.h.
uint8_t bits, ///< [in] bits per word, typically 8 bits per word
uint32_t speed, ///< [in] max speed (Hz), this is slave dependant
int msb ///< [in] set as 0 for MSB as first bit or 1 for LSB as first bit
)
{
LE_DEBUG("Running the configure library call");
int ret;
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_WR_MODE, &mode)) < 0),
"SPI modeset failed with error %d: %d (%m)",
ret,
errno);
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_RD_MODE, &mode)) < 0),
"SPI modeget failed with error %d: %d (%m)",
ret,
errno);
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits)) < 0),
"SPI bitset failed with error %d : %d (%m)",
ret,
errno);
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits)) < 0),
"SPI bitget failed with error %d : %d (%m)",
ret,
errno);
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed)) < 0),
"SPI speedset failed with error %d : %d (%m)",
ret,
errno);
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed)) < 0),
"SPI speedget failed with error %d : %d (%m)",
ret,
errno);
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_WR_LSB_FIRST, &msb)) < 0),
"SPI MSB/LSB write failed with error %d : %d (%m)",
ret,
errno);
LE_FATAL_IF(
((ret = ioctl(fd, SPI_IOC_RD_LSB_FIRST, &msb)) < 0),
"SPI MSB/LSB read failed with error %d : %d (%m)",
ret,
errno);
LE_DEBUG("Mode = %d, Speed = %d, Bits = %d, MSB = %d", mode, speed, bits, msb);
}
/**-----------------------------------------------------------------------------------------------
* Performs SPI WriteRead Half Duplex. You can send send Read command/ address of data to read.
*
* @return
* - LE_OK
* - LE_FAULT
*
* @note
* Some devices do not support this mode. Check the data sheet of the device.
*/
//--------------------------------------------------------------------------------------------------
le_result_t le_spiLib_WriteReadHD
(
int fd, ///< [in] open file descriptor of SPI port
const uint8_t* writeData, ///< [in] tx command/address being sent to slave
size_t writeDataLength, ///< [in] number of bytes in tx message
uint8_t* readData, ///< [out] rx response from slave
size_t* readDataLength ///< [in/out] number of bytes in rx message
)
{
int transferResult;
le_result_t result;
struct spi_ioc_transfer tr[] =
{
{
.tx_buf = (unsigned long)writeData,
.rx_buf = (unsigned long)NULL,
.len = writeDataLength,
// .delay_usecs = delay_out,
.cs_change = 0
},
{
.tx_buf = (unsigned long)NULL,
.rx_buf = (unsigned long)readData,
.len = *readDataLength,
// .delay_usecs = delay_in,
.cs_change = 0
}
};
/*LE_DEBUG("Transmitting this message...len:%zu", writeDataLength);
for (size_t i = 0; i < writeDataLength; i++)
{
LE_DEBUG("%.2X ", writeData[i]);
}*/
transferResult = ioctl(fd, SPI_IOC_MESSAGE(2), tr);
if (transferResult < 1)
{
/*LE_ERROR("Transfer failed with error %d : %d (%m)", transferResult, errno);
LE_ERROR("can't send spi message");*/
result = LE_FAULT;
}
else
{
//LE_DEBUG("Successful transmission with success %d", transferResult);
result = LE_OK;
}
/*LE_DEBUG("Received message...");
for (size_t i = 0; i < *readDataLength; i++)
{
LE_DEBUG("%.2X ", readData[i]);
}*/
return result;
}
//--------------------------------------------------------------------------------------------------
/**
* Performs SPI Write Half Duplex. You can send send Write command/ address of data to write/data
* to write.
*
* @return
* - LE_OK
* - LE_FAULT
*
* @note
* Some devices do not support this mode. Check the data sheet of the device.
*/
//--------------------------------------------------------------------------------------------------
le_result_t le_spiLib_WriteHD
(
int fd, ///< [in] open file descriptor of SPI port
const uint8_t* writeData, ///< [in] command/address being sent to slave
size_t writeDataLength ///< [in] number of bytes in tx message
)
{
int transferResult;
le_result_t result;
struct spi_ioc_transfer tr[] =
{
{
.tx_buf = (unsigned long)writeData,
.rx_buf = (unsigned long)NULL,
.len = writeDataLength,
// .delay_usecs = delay_out,
.cs_change = 0
}
};
/*LE_DEBUG("Transferring this message...len: %zu", writeDataLength);
for (size_t i = 0; i < writeDataLength; i++)
{
LE_DEBUG("%.2X ", writeData[i]);
}*/
transferResult = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
if (transferResult < 1)
{
/*LE_ERROR("Transfer failed with error %d : %d (%m)", transferResult, errno);
LE_ERROR("can't send spi message");*/
result = LE_FAULT;
}
else
{
//LE_DEBUG("%d", transferResult);
result = LE_OK;
}
return result;
}
/**-----------------------------------------------------------------------------------------------
* Performs SPI WriteRead Full Duplex. You can send send Read command/ address of data to read.
*
* @return
* - LE_OK
* - LE_FAULT
*
* @note
* Some devices do not support this mode. Check the data sheet of the device.
*/
//--------------------------------------------------------------------------------------------------
le_result_t le_spiLib_WriteReadFD
(
int fd, ///< [in] open file descriptor of SPI port
const uint8_t* writeData, ///< [in] tx command/address being sent to slave
uint8_t* readData, ///< [out] rx response from slave
size_t dataLength ///< [in/out] number of bytes in tx message
)
{
int transferResult;
le_result_t result;
struct spi_ioc_transfer tr[] =
{
{
.tx_buf = (unsigned long)writeData,
.rx_buf = (unsigned long)readData,
.len = dataLength,
// .delay_usecs = delay_out,
.cs_change = 0
},
};
/*LE_DEBUG("Transmitting this message...len:%zu", dataLength);
for (size_t i = 0; i < dataLength; i++)
{
LE_DEBUG("%.2X ", writeData[i]);
}*/
transferResult = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
if (transferResult < 1)
{
/*LE_ERROR("Transfer failed with error %d : %d (%m)", transferResult, errno);
LE_ERROR("can't send spi message");*/
result = LE_FAULT;
}
else
{
//LE_DEBUG("Successful transmission with success %d", transferResult);
result = LE_OK;
}
/*LE_DEBUG("Received message...");
for (size_t i = 0; i < dataLength; i++)
{
LE_DEBUG("%.2X ", readData[i]);
}*/
return result;
}
//--------------------------------------------------------------------------------------------------
/**
* Performs SPI Read. You can send send Write command/ address of data to write/data to write.
*
* @return
* - LE_OK
* - LE_FAULT
*
* @note
* Some devices do not support this mode. Check the data sheet of the device.
*/
//--------------------------------------------------------------------------------------------------
le_result_t le_spiLib_ReadHD
(
int fd, ///< [in] open file descriptor of SPI port
uint8_t* readData, ///< [out] data being sent by slave
size_t* readDataLength ///< [in/out] number of bytes in rx message
)
{
int transferResult;
le_result_t result;
struct spi_ioc_transfer tr[] =
{
{
.tx_buf = (unsigned long)NULL,
.rx_buf = (unsigned long)readData,
.len = *readDataLength,
// .delay_usecs = delay_out,
.cs_change = 0
}
};
transferResult = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
if (transferResult < 1)
{
/*LE_ERROR("Transfer failed with error %d : %d (%m)", transferResult, errno);
LE_ERROR("can't receive spi message");*/
result = LE_FAULT;
}
else
{
//LE_DEBUG("%d", transferResult);
result = LE_OK;
}
/*LE_DEBUG("Received message...");
for (size_t i = 0; i < *readDataLength; i++)
{
LE_DEBUG("%.2X ", readData[i]);
}*/
return result;
}
/*COMPONENT_INIT
{
LE_DEBUG("spiLibrary initializing");
}*/