Skip to content

Commit

Permalink
flatten out SPI driver for MCP2515.
Browse files Browse the repository at this point in the history
  • Loading branch information
bakerstu committed Jun 9, 2018
1 parent ccd51f0 commit d5bb2af
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 182 deletions.
4 changes: 4 additions & 0 deletions include/spi/spidev.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@
*/
#define SPI_IOC_WR_MAX_SPEED_HZ IOW(SPI_IOC_MAGIC, 4, sizeof(uint32_t))

/** Get an object pointer for the SPI device
*/
#define SPI_IOC_GET_OBJECT_REFERENCE IOR(SPI_IOC_MAGIC, 5, sizeof(void*))

#else
#error SPI drivers not supported on this OS
#endif
Expand Down
28 changes: 16 additions & 12 deletions src/freertos_drivers/common/MCP2515Can.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,11 @@ const MCP2515Can::BitModify MCP2515Can::tx1TransmitEnable(CANINTE, TX0I << 1,
*/
void MCP2515Can::init(const char *spi_name, uint32_t freq, uint32_t baud)
{
spi = ::open(spi_name, O_RDWR);
HASSERT(spi >= 0);
spiFd = ::open(spi_name, O_RDWR);
HASSERT(spiFd >= 0);

::ioctl(spiFd, SPI_IOC_GET_OBJECT_REFERENCE, &spi);
HASSERT(spi);

/* configure SPI bus settings */
uint8_t spi_mode = SPI_MODE_0;
Expand All @@ -108,9 +111,9 @@ void MCP2515Can::init(const char *spi_name, uint32_t freq, uint32_t baud)
{
spi_max_speed_hz = SPI_MAX_SPEED_HZ;
}
::ioctl(spi, SPI_IOC_WR_MODE, &spi_mode);
::ioctl(spi, SPI_IOC_WR_BITS_PER_WORD, &spi_bpw);
::ioctl(spi, SPI_IOC_WR_MAX_SPEED_HZ, &spi_max_speed_hz);
::ioctl(spiFd, SPI_IOC_WR_MODE, &spi_mode);
::ioctl(spiFd, SPI_IOC_WR_BITS_PER_WORD, &spi_bpw);
::ioctl(spiFd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_max_speed_hz);

/* reset device */
reset();
Expand Down Expand Up @@ -247,10 +250,11 @@ void MCP2515Can::tx_msg_locked()
}
++count;

HASSERT(count <= ARRAYSIZE(xfer_));
//HASSERT(count <= ARRAYSIZE(xfer_));

// tranfer the messages
::ioctl(spi, SPI_IOC_MESSAGE(count), xfer_);
//::ioctl(spiFd, SPI_IOC_MESSAGE(count), xfer_);
SPI::transfer_messages(spi, xfer_, count);
}
else
{
Expand Down Expand Up @@ -310,7 +314,7 @@ void *MCP2515Can::entry()
xfer[1].rx_buf = (unsigned long)regs;
xfer[1].len = sizeof(regs);
xfer[1].cs_change = 1;
::ioctl(spi, SPI_IOC_MESSAGE(2), xfer);
::ioctl(spiFd, SPI_IOC_MESSAGE(2), xfer);
lock_.unlock();
continue;
}
Expand Down Expand Up @@ -375,7 +379,7 @@ void *MCP2515Can::entry()
{
/* receive interrupt active */
new (&rx_buf) BufferRead(xfer_ + count, 0);
count += rx_buf.xfer_count();
++count;
receive = true;
}

Expand Down Expand Up @@ -430,7 +434,7 @@ void *MCP2515Can::entry()
txBuf->consume(1);
portEXIT_CRITICAL();

count += tx_buf.xfer_count();
++count;;
txPending |= (0x1 << index);

/* request to send at lowest priority */
Expand All @@ -456,7 +460,7 @@ void *MCP2515Can::entry()
}
}

HASSERT(count <= ARRAYSIZE(xfer_));
//HASSERT(count <= ARRAYSIZE(xfer_));

// tranfer the messages
if (count == 0)
Expand All @@ -465,7 +469,7 @@ void *MCP2515Can::entry()
}
else
{
::ioctl(spi, SPI_IOC_MESSAGE(count), xfer_);
SPI::transfer_messages(spi, xfer_, count);
}

if (receive)
Expand Down
29 changes: 20 additions & 9 deletions src/freertos_drivers/common/MCP2515Can.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public:
, gpoData(0x0)
, gpiData(0x7)
, ioPending(false)
, spi(-1)
, spiFd(-1)
, spi(nullptr)
, sem()
{
}
Expand Down Expand Up @@ -652,7 +653,7 @@ private:
void reset()
{
uint8_t reset = RESET;
::write(spi, &reset, 1);
::write(spiFd, &reset, 1);
}

/** Read from a SPI register.
Expand All @@ -671,7 +672,8 @@ private:
xfer[1].rx_buf = (unsigned long)rd_data;
xfer[1].len = sizeof(rd_data);
xfer[1].cs_change = 1;
::ioctl(spi, SPI_IOC_MESSAGE(2), xfer);

SPI::transfer_messages(spi, xfer, 2);

return rd_data[0];
}
Expand All @@ -692,7 +694,7 @@ private:
xfer[1].rx_buf = (unsigned long)buffer;
xfer[1].len = 13;
xfer[1].cs_change = 1;
::ioctl(spi, SPI_IOC_MESSAGE(2), xfer);
::ioctl(spiFd, SPI_IOC_MESSAGE(2), xfer);
}

/** Write to a SPI register.
Expand All @@ -702,8 +704,15 @@ private:
__attribute__((optimize("-O3")))
void register_write(Registers address, uint8_t data)
{
spi_ioc_transfer xfer[1];
memset(xfer, 0, sizeof(xfer));
uint8_t payload[] = {WRITE, address, data};
::write(spi, payload, sizeof(payload));

xfer[0].tx_buf = (unsigned long)payload;
xfer[0].len = sizeof(payload);
xfer[0].cs_change = 1;

SPI::transfer_messages(spi, xfer, 1);
}

/** Write to a TX buffer.
Expand All @@ -722,7 +731,7 @@ private:
xfer[1].tx_buf = (unsigned long)buffer;
xfer[1].len = 13;
xfer[1].cs_change = 1;
::ioctl(spi, SPI_IOC_MESSAGE(2), xfer);
::ioctl(spiFd, SPI_IOC_MESSAGE(2), xfer);
}

/** Bit modify to a SPI register.
Expand All @@ -733,7 +742,7 @@ private:
void bit_modify(Registers address, uint8_t data, uint8_t mask)
{
uint8_t payload[] = {BIT_MODIFY, address, mask, data};
::write(spi, payload, sizeof(payload));
::write(spiFd, payload, sizeof(payload));
}

/** Request a transmit buffer to send.
Expand All @@ -743,7 +752,7 @@ private:
void request_to_send(int index)
{
uint8_t rts = RTS | (0x01 << index);
::write(spi, &rts, 1);
::write(spiFd, &rts, 1);
}

/** Request that the GPIO cache be refreshed.
Expand All @@ -762,7 +771,9 @@ private:
unsigned gpiData : 3; /**< local copy of the I/O expansion input data */
unsigned ioPending : 1; /**< true if an I/O update is pending */

int spi; /**< SPI bus that accesses MCP2515 */
int spiFd; /**< SPI bus that accesses MCP2515 */
SPI *spi; /**< pointer to a SPI object instance */

OSSem sem; /**< semaphore for posting events */
#if MCP2515_DEBUG
volatile uint8_t regs[128]; /**< debug copy of MCP2515 registers */
Expand Down
50 changes: 6 additions & 44 deletions src/freertos_drivers/common/SPI.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
*/

#include <cstdint>
#include <unistd.h>
#include <fcntl.h>
#include "Devtab.hxx"
#include "SPI.hxx"
Expand Down Expand Up @@ -136,6 +135,12 @@ int SPI::ioctl(File *file, unsigned long int key, unsigned long data)
{
default:
return -EINVAL;
case SPI_IOC_GET_OBJECT_REFERENCE:
{
SPI **self = (SPI**)data;
*self = this;
return 0;
}
case SPI_IOC_RD_MODE:
{
uint8_t *m = (uint8_t*)data;
Expand Down Expand Up @@ -196,46 +201,3 @@ int SPI::ioctl(File *file, unsigned long int key, unsigned long data)
return result;
}

/** Conduct multiple message transfers with one stop at the end.
* @param msgs array of messages to transfer
* @param num number of messages to transfer
* @return total number of bytes transfered, -errno upon failure
*/
__attribute__((optimize("-O3")))
int SPI::transfer_messages(struct spi_ioc_transfer *msgs, int num)
{
HASSERT(num > 0);

int count = 0;
int result;

lock_.lock();
bus_lock();
for (int i = 0; i < num; ++i, ++msgs)
{
count += msgs->len;
csAssert();
result = transfer(msgs);
if (result < 0)
{
/* something bad happened, reset the bus and bail */
csDeassert();
bus_unlock();
lock_.unlock();
return result;
}
if (msgs->cs_change)
{
if (msgs->delay_usec)
{
usleep(msgs->delay_usec);
}
csDeassert();
}
}
bus_unlock();
lock_.unlock();

return count;
}

52 changes: 50 additions & 2 deletions src/freertos_drivers/common/SPI.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#ifndef _FREERTOS_DRIVERS_COMMON_SPI_HXX_
#define _FREERTOS_DRIVERS_COMMON_SPI_HXX_


#include <unistd.h>

#include "BlockOrWakeUp.hxx"
#include "SimpleLog.hxx"
Expand All @@ -54,6 +54,18 @@ public:
/** Function point for the chip select assert and deassert methods */
typedef void (*ChipSelectMethod)();

/** Conduct multiple message transfers with one stop at the end.
* @param self pointer to a SPI object instance
* @param msgs array of messages to transfer
* @param num number of messages to transfer
* @return total number of bytes transfered, -errno upon failure
*/
static int transfer_messages(SPI *self,
struct spi_ioc_transfer *msgs, int num)
{
return self->transfer_messages(msgs, num);
}

protected:
/** Constructor
* @param name device name in file system
Expand Down Expand Up @@ -113,7 +125,43 @@ protected:
* @param num number of messages to transfer
* @return total number of bytes transfered, -errno upon failure
*/
virtual int transfer_messages(struct spi_ioc_transfer *msgs, int num);
__attribute__((optimize("-O3")))
int transfer_messages(struct spi_ioc_transfer *msgs, int num)
{
//HASSERT(num > 0);

int count = 0;
int result;

//lock_.lock();
//bus_lock();
for (int i = 0; i < num; ++i, ++msgs)
{
count += msgs->len;
csAssert();
result = transfer(msgs);
if (result < 0)
{
/* something bad happened, reset the bus and bail */
csDeassert();
//bus_unlock();
//lock_.unlock();
return result;
}
if (msgs->cs_change)
{
//if (msgs->delay_usec)
{
//usleep(msgs->delay_usec);
}
csDeassert();
}
}
//bus_unlock();
//lock_.unlock();

return count;
}

/** Update the configuration of the bus.
* @return >= 0 upon success, -errno upon failure
Expand Down
Loading

0 comments on commit d5bb2af

Please sign in to comment.