Skip to content

Commit

Permalink
Merge pull request #6 from ttlappalainen/master
Browse files Browse the repository at this point in the history
FlexCAN support for different revisions
  • Loading branch information
sarfata authored Jun 20, 2017
2 parents 62ef011 + 2d1fc05 commit 0f5e0e9
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 18 deletions.
108 changes: 94 additions & 14 deletions NMEA2000_teensy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,87 @@
Requires FlexCAN library.
*/

#include <NMEA2000_teensy.h>

#include "NMEA2000_teensy.h"
#include <FlexCAN.h>
#include <kinetis_flexcan.h>

//*****************************************************************************
tNMEA2000_teensy::tNMEA2000_teensy(uint16_t _DefTimeOut) : tNMEA2000() {
tNMEA2000_teensy::tNMEA2000_teensy(uint16_t _DefTimeOut, uint8_t CANBusIndex) : tNMEA2000() {
#if defined(FlexCAN_MAILBOX_TX_BUFFER_SUPPORT)
NumTxMailBoxes=3; // Use different buffers for high and low priorities and fast packet
#else
NumTxMailBoxes=1; // Force all to be sent through one mail box.
#endif

#if NMEA2000_TEENSY_VER == 1
CANbus = new FlexCAN(250000);
#else

#if NMEA2000_TEENSY_MAX_CAN_BUSSES == 2 && NMEA2000_TEENSY_VER>1
if ( CANBusIndex>1 ) CANBusIndex=1;
if ( CANBusIndex==0 ) {
CANbus = &Can0;
} else {
CANbus = &Can1;
}
#else
CANBusIndex=0;
CANbus = &Can0;
#endif

#endif
DefTimeOut=_DefTimeOut;
}

//*****************************************************************************
bool tNMEA2000_teensy::CANSendFrame(unsigned long id, unsigned char len, const unsigned char *buf, bool wait_sent) {
CAN_message_t out;
out.id = id;
out.ext = 1;
out.len = len;
out.ext = 1;
#if NMEA2000_TEENSY_VER == 1
out.timeout = (wait_sent?DefTimeOut:0);
#endif
#if NMEA2000_TEENSY_VER == 2
out.rtr=0;
#endif

// Fill the frame buffer
for (int i=0; i<len && i<8; i++) out.buf[i] = buf[i];

return CANbus->write(out) == 1;
#if defined(FlexCAN_MAILBOX_TX_BUFFER_SUPPORT)
if ( wait_sent ) {
// Use last mail box for fast packet
return CANbus->write(out,CANbus->getLastTxBox());
} else {
uint8_t prio = (uint8_t) ((id >> 26) & 0x7);
// For high priority messages use first mail box and rest for others.
return (prio<4?CANbus->write(out,CANbus->getFirstTxBox()):CANbus->write(out)) == 1;
}
#else
return (CANbus->write(out) == 1);
#endif

// FIXME: The Arduino Due had a retry mechanism here. Check whether we need it on Teensy.
/*
do {
if (TryCount>0) delay(3);
result=CAN.sendFrame(output);
TryCount++;
} while (TryCount<2 && !result);
*/
}

//*****************************************************************************
bool tNMEA2000_teensy::CANOpen() {
CANbus->begin();
#if NMEA2000_TEENSY_VER == 1
CANbus->begin();
#else
CANbus->begin(250000);
CANbus->setNumTXBoxes(NumTxMailBoxes);

CAN_filter_t filter;
filter.rtr=0;
filter.ext=1;
filter.id=0;
// Leave one box for other than extended messages
for (int box=1; box<NUM_MAILBOXES; box++) CANbus->setFilter(filter,box);
// Set mask to all rx mailboxes. Just fix error on FlexCAN constructor, where numTxMailboxes where not initialized.
for (int box=0; box<NUM_MAILBOXES; box++) CANbus->setMask(0,box);
#endif
return true;
}

Expand All @@ -71,7 +117,7 @@ bool tNMEA2000_teensy::CANGetFrame(unsigned long &id, unsigned char &len, unsign
CAN_message_t incoming;

if (CANbus->available() > 0) {
CANbus->read(incoming);
CANbus->read(incoming);
id = incoming.id;
len = incoming.len;
for (int i = 0; i < len && i < 8; i++) {
Expand All @@ -84,3 +130,37 @@ bool tNMEA2000_teensy::CANGetFrame(unsigned long &id, unsigned char &len, unsign
}
}

//*****************************************************************************
void tNMEA2000_teensy::InitCANFrameBuffers() {
#if defined(FlexCAN_DYNAMIC_BUFFER_SUPPORT)
if ( MaxCANReceiveFrames<10 ) MaxCANReceiveFrames=10;
CANbus->setRxBufferSize(MaxCANReceiveFrames);

if (MaxCANSendFrames<30 ) MaxCANSendFrames=30;

uint16_t TotalFrames=MaxCANSendFrames;
MaxCANSendFrames=4; // we do not need libary internal buffer since driver has them.
uint16_t CANGlobalBufSize=TotalFrames-5;

#if defined(FlexCAN_MAILBOX_TX_BUFFER_SUPPORT)
CANbus->setNumTXBoxes(NumTxMailBoxes);

// With this support system can have different buffers for high and low priority and fast packet messages.
// After message has been sent to driver, it buffers it automatically and sends it by interrupt.
// We may need to make these possible to set.
uint16_t HighPriorityBufferSize=CANGlobalBufSize / 10;
HighPriorityBufferSize=(HighPriorityBufferSize<15?HighPriorityBufferSize:15); // just guessing
CANGlobalBufSize-=HighPriorityBufferSize;
uint16_t FastPacketBufferSize= (CANGlobalBufSize * 9 / 10);
CANGlobalBufSize-=FastPacketBufferSize;

CANbus->setMailBoxTxBufferSize(CANbus->getFirstTxBox(),HighPriorityBufferSize); // Highest priority buffer
CANbus->setMailBoxTxBufferSize(CANbus->getLastTxBox(),FastPacketBufferSize); // Fastpacket buffer
#endif
CANbus->setTxBufferSize(CANGlobalBufSize);

#endif

tNMEA2000::InitCANFrameBuffers(); // call main initialization
}

21 changes: 17 additions & 4 deletions NMEA2000_teensy.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,35 @@
#ifndef _NMEA2000_TEENSY_H_
#define _NMEA2000_TEENSY_H_

#include <NMEA2000.h>
#include <NMEA2000.h>
#include <N2kMsg.h>

#include <FlexCAN.h>
#if !defined(NUM_MAILBOXES)
#define NMEA2000_TEENSY_VER 1
#else
#define NMEA2000_TEENSY_VER 2
#endif

#if defined(__MK66FX1M0__)
#define NMEA2000_TEENSY_MAX_CAN_BUSSES 2
#else
#define NMEA2000_TEENSY_MAX_CAN_BUSSES 1
#endif

class tNMEA2000_teensy : public tNMEA2000
{
protected:
FlexCAN *CANbus;
uint16_t DefTimeOut;
uint16_t DefTimeOut;
uint8_t NumTxMailBoxes;
bool CANSendFrame(unsigned long id, unsigned char len, const unsigned char *buf, bool wait_sent);
bool CANOpen();
bool CANGetFrame(unsigned long &id, unsigned char &len, unsigned char *buf);

void InitCANFrameBuffers();

public:
tNMEA2000_teensy(uint16_t _DefTimeOut=2);
tNMEA2000_teensy(uint16_t _DefTimeOut=4, uint8_t CANBusIndex=0);
};

#endif

0 comments on commit 0f5e0e9

Please sign in to comment.