Created Sat, 02 Jan 2021 11:32:31 +0000 by sundar@19
Sat, 02 Jan 2021 11:32:31 +0000
Hi , Just wanted to share the merging of CAN bus and Ethernet in chipkit network shield This code acts a TCP server
/************************************************************************/
/* */
/* Example Sketch for sending CAN data thru ethernet TCP using chipKIT Max32/Network Shield */
/* */
/************************************************************************/
/* Author: Gene Apperson */
/* Copyright (c) 2011, Digilent Inc. */
/************************************************************************/
/* This sketch is derived from a CAN demonstration program written */
/* by Fred Eady. It is essentially his program translated to use the */
/* chipKIT CAN low level library rather than using the Microchip C32 */
/* Peripheral Library CAN functions directly. */
/************************************************************************/
/*
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/************************************************************************/
/* Module Description: */
/* */
/* This sketch is an example of using the CAN controllers on the */
/* on the chipKIT Max32 with the Network Shield. It illustrates the */
/* use of the low level CAN library provided for use with the Network */
/* shield. */
/* */
/* This sketch assumes that CAN1 is looped back to CAN2 on the Network */
/* shield. It initializes the two CAN modules, sends a packet */
/* containing a single character from CAN2 to CAN1, prints the */
/* character received by CAN1, then sends a packet containing a single */
/* character from CAN1 to CAN2 and prints the character received by */
/* CAN2. The sending of packets back and forth is repeated for ever. */
/* */
/************************************************************************/
/* Revision History: */
/* */
/* 08/21/2011(GeneApperson): Created */
/* */
/************************************************************************/
/* ------------------------------------------------------------ */
/* Include File Definitions */
/* ------------------------------------------------------------ */
#include <WProgram.h>
#include "chipKITCAN.h"
#include <NetworkShield.h>
#include <DNETcK.h>
/* ------------------------------------------------------------ */
/* Local Type and Constant Definitions */
/* ------------------------------------------------------------ */
IPv4 ipServer = {10,0,0,20};
unsigned short portServer = 65432;
typedef enum
{
NONE = 0,
LISTEN,
ISLISTENING,
AVAILABLECLIENT,
ACCEPTCLIENT,
READ,
WRITE,
CLOSE,
EXIT,
DONE
} STATE;
STATE state = LISTEN;
unsigned tStart = 0;
unsigned tWait = 5000;
TcpServer tcpServer;
TcpClient tcpClient;
DNETcK::STATUS status;
/* Network Node Addresses
*/
#define node1can1 0x101L
#define node2can1 0x201L
#define node1can2 0x102L
#define node2can2 0x202L
#define SYS_FREQ (80000000L)
#define CAN_BUS_SPEED 250000 // CAN Speed
/* ------------------------------------------------------------ */
/* Global Variables */
/* ------------------------------------------------------------ */
byte rgbRead[1024];
byte customWrite[]= {'a'}; //change here
int customSize = sizeof(customWrite);
byte dataWrite[]= {'b'}; //change here
int dataSize = sizeof(dataWrite);
byte wrongWrite[]= {'W','R','O','N','G'};
int wrongSize = sizeof(wrongWrite);
int cbRead = 0;
int count = 0;
/* CAN controller interface object instances.
*/
CAN canMod1(CAN::CAN1); // this object uses CAN module 1
CAN canMod2(CAN::CAN2); // this object uses CAN module 2
/* ------------------------------------------------------------ */
/* Local Variables */
/* ------------------------------------------------------------ */
/* CAN Message Buffers
*/
uint8_t CAN1MessageFifoArea[2 * 8 * 16];
uint8_t CAN2MessageFifoArea[2 * 8 * 16];
/* These are used as event flags by the interrupt service routines.
*/
static volatile bool isCAN1MsgReceived = false;
static volatile bool isCAN2MsgReceived = false;
/* ------------------------------------------------------------ */
/* Forward Declarations */
/* ------------------------------------------------------------ */
void initCan1(uint32_t myaddr);
void initCan2(uint32_t myaddr);
void doCan1Interrupt();
void doCan2Interrupt();
void txCAN1(uint32_t rxnode);
void txCAN2(uint32_t rxnode);
void rxCAN1(void);
void rxCAN2(void);
void doCan1Interrupt();
void doCan2Interrupt();
/* ------------------------------------------------------------ */
/* Procedure Definitions */
/* ------------------------------------------------------------ */
/*** setup
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Initialize the program for execution. Initialize the
** CAN controller modules before use. Install the interrupt
** service routines used to indicate packet reception.
** Initialize the serial interface to print the activity
** to the serial monitor.
*/
void
setup() {
/* Set up the serial monitor to show program activity.
*/
Serial.begin(9600);
/* Init each CAN controller module for use.
*/
Serial.println("TCPEchoServer 1.0");
Serial.println("Digilent, Copyright 2011");
Serial.println("");
// intialize the stack with a static IP
DNETcK::begin(ipServer);
Serial.println("Server initialized..");
initCan1(node1can1);
initCan2(node1can2);
/* Install the interrupt service routines.
*/
canMod1.attachInterrupt(doCan1Interrupt);
canMod2.attachInterrupt(doCan2Interrupt);
}
/* ------------------------------------------------------------ */
/*** loop
**
** Parameters:
**
** Return Value:
**
** Errors:
**
** Description:
** Program event loop. This function is called repeatedly forever
** after setup has been executed. Send a packet from CAN2 to CAN1.
** Receive the packet on CAN1 and print the result. Send a
** packet from CAN1 to CAN2. Have CAN2 receive the packet and
** print the result.
*/
void
loop() {
switch(state)
{
// say to listen on the port
case LISTEN:
if(tcpServer.startListening(portServer))
{
Serial.println("Started Listening");
state = ISLISTENING;
}
else
{
state = EXIT;
}
break;
// not specifically needed, we could go right to AVAILABLECLIENT
// but this is a nice way to print to the serial monitor that we are
// actively listening.
// Remember, this can have non-fatal falures, so check the status
case ISLISTENING:
if(tcpServer.isListening(&status))
{
Serial.print("Listening on port: ");
Serial.print(portServer, DEC);
Serial.println("");
state = AVAILABLECLIENT;
}
else if(DNETcK::isStatusAnError(status))
{
state = EXIT;
}
break;
// wait for a connection
case AVAILABLECLIENT:
if((count = tcpServer.availableClients()) > 0)
{
Serial.print("Got ");
Serial.print(count, DEC);
Serial.println(" clients pending");
state = ACCEPTCLIENT;
}
break;
// accept the connection
case ACCEPTCLIENT:
// probably unneeded, but just to make sure we have
// tcpClient in the "just constructed" state
tcpClient.close();
// accept the client
if(tcpServer.acceptClient(&tcpClient))
{
Serial.println("Got a Connection");
state = READ;
tStart = (unsigned) millis();
}
// this probably won't happen unless the connection is dropped
// if it is, just release our socket and go back to listening
else
{
state = CLOSE;
}
break;
// wait fot the read, but if too much time elapses (5 seconds)
// we will just close the tcpClient and go back to listening
case READ:
// see if we got anything to read
if((cbRead = tcpClient.available()) > 0)
{
cbRead = cbRead < sizeof(rgbRead) ? cbRead : sizeof(rgbRead);
cbRead = tcpClient.readStream(rgbRead, cbRead);
Serial.print("Got ");
Serial.print(cbRead, DEC);
Serial.println(" bytes");
state = WRITE;
}
// If too much time elapsed between reads, close the connection
/*
else if( (((unsigned) millis()) - tStart) > tWait )
{
state = CLOSE;
}*/
break;
// echo back the string
case WRITE:
if(tcpClient.isConnected())
{
//Serial.println("Writing: ");
for(int i=0; i < cbRead; i++)
{
Serial.print((char) rgbRead[i]);
}
Serial.println("");
if(rgbRead[0] == 'a')
{
txCAN2(node1can1);
delay(100);
rxCAN1();
tcpClient.writeStream(customWrite, customSize); //change
state = READ;
tStart = (unsigned) millis();
}
else if (rgbRead[0] == 'b')
{
txCAN1(node1can2);
delay(100);
rxCAN2();
tcpClient.writeStream(dataWrite, dataSize); //change
state = READ;
tStart = (unsigned) millis();
}
else
{
tcpClient.writeStream(wrongWrite, wrongSize);
state = READ;
tStart = (unsigned) millis();
}
}
// the connection was closed on us, go back to listening
/* else
{
Serial.println("Unable to write back.");
state = CLOSE;
}*/
break;
// close our tcpClient and go back to listening
case CLOSE:
//tcpClient.close();
Serial.println("Closing TcpClient");
Serial.println("");
state = ISLISTENING;
break;
// something bad happen, just exit out of the program
case EXIT:
//tcpClient.close();
//tcpServer.close();
Serial.println("Something went wrong, sketch is done.");
state = DONE;
break;
// do nothing in the loop
case DONE:
default:
break;
}
// every pass through loop(), keep the stack alive
/* Send an ASCII character from CAN2 to CAN1
** Note: The txCAN2 function initializes the transmit buffer.
*/
// txCAN2(node1can1);
// delay(100);
/* Receive the character from CAN2
*/
//wait so that the character has time to be delivered
// rxCAN1();
/* Send an ASCII character from CAN1 to CAN2
*/
// txCAN1(node1can2);
// delay(100);
/* Receive the character from CAN1
*/
// rxCAN2();
DNETcK::periodicTasks();
}
/* ------------------------------------------------------------ */
/* CAN Utility Functions */
/* ------------------------------------------------------------ */
/*** initCan1
**
** Parameters:
** myaddr - network address
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Initialize the CAN controller. See inline comments
** for description of the process.
*/
void
initCan1(uint32_t myaddr) {
CAN::BIT_CONFIG canBitConfig;
/* Step 1: Switch the CAN module
* ON and switch it to Configuration
* mode. Wait till the switch is
* complete */
canMod1.enableModule(true);
canMod1.setOperatingMode(CAN::CONFIGURATION);
while(canMod1.getOperatingMode() != CAN::CONFIGURATION);
/* Step 2: Configure the CAN Module Clock. The
* CAN::BIT_CONFIG data structure is used
* for this purpose. The propagation,
* phase segment 1 and phase segment 2
* are configured to have 3TQ. The CANSetSpeed()
* function sets the baud. */
canBitConfig.phaseSeg2Tq = CAN::BIT_3TQ;
canBitConfig.phaseSeg1Tq = CAN::BIT_3TQ;
canBitConfig.propagationSegTq = CAN::BIT_3TQ;
canBitConfig.phaseSeg2TimeSelect = CAN::TRUE;
canBitConfig.sample3Time = CAN::TRUE;
canBitConfig.syncJumpWidth = CAN::BIT_2TQ;
canMod1.setSpeed(&canBitConfig,SYS_FREQ,CAN_BUS_SPEED);
/* Step 3: Assign the buffer area to the
* CAN module.
*/
/* Note the size of each Channel area.
* It is 2 (Channels) * 8 (Messages Buffers)
* 16 (bytes/per message buffer) bytes. Each
* CAN module should have its own message
* area. */
canMod1.assignMemoryBuffer(CAN1MessageFifoArea,2 * 8 * 16);
/* Step 4: Configure channel 0 for TX and size of
* 8 message buffers with RTR disabled and low medium
* priority. Configure channel 1 for RX and size
* of 8 message buffers and receive the full message.
*/
canMod1.configureChannelForTx(CAN::CHANNEL0,8,CAN::TX_RTR_DISABLED,CAN::LOW_MEDIUM_PRIORITY);
canMod1.configureChannelForRx(CAN::CHANNEL1,8,CAN::RX_FULL_RECEIVE);
/* Step 5: Configure filters and mask. Configure
* filter 0 to accept SID messages with ID 0x200.
* Configure filter mask 0 to compare all the ID
* bits and to filter by the ID type specified in
* the filter configuration. Filter 0 accepted
* messages are stored in channel 1. */
canMod1.configureFilter (CAN::FILTER0, myaddr, CAN::SID);
canMod1.configureFilterMask (CAN::FILTER_MASK0, 0xFFF, CAN::SID, CAN::FILTER_MASK_IDE_TYPE);
canMod1.linkFilterToChannel (CAN::FILTER0, CAN::FILTER_MASK0, CAN::CHANNEL1);
canMod1.enableFilter (CAN::FILTER0, true);
/* Step 6: Enable interrupt and events. Enable the receive
* channel not empty event (channel event) and the receive
* channel event (module event).
* The interrrupt peripheral library is used to enable
* the CAN interrupt to the CPU. */
canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true);
canMod1.enableModuleEvent(CAN::RX_EVENT, true);
/* Step 7: Switch the CAN mode
* to normal mode. */
canMod1.setOperatingMode(CAN::NORMAL_OPERATION);
while(canMod1.getOperatingMode() != CAN::NORMAL_OPERATION);
}
/* ------------------------------------------------------------ */
/*** initCan2
**
** Parameters:
** myaddr - network address
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Initialize the CAN controller. See inline comments
** for description of the process.
*/
void
initCan2(uint32_t myaddr) {
CAN::BIT_CONFIG canBitConfig;
/* Step 1: Switch the CAN module
* ON and switch it to Configuration
* mode. Wait till the switch is
* complete */
canMod2.enableModule(true);
canMod2.setOperatingMode(CAN::CONFIGURATION);
while(canMod2.getOperatingMode() != CAN::CONFIGURATION);
/* Step 2: Configure the CAN Module Clock. The
* CAN::BIT_CONFIG data structure is used
* for this purpose. The propagation,
* phase segment 1 and phase segment 2
* are configured to have 3TQ. The CANSetSpeed()
* function sets the baud. */
canBitConfig.phaseSeg2Tq = CAN::BIT_3TQ;
canBitConfig.phaseSeg1Tq = CAN::BIT_3TQ;
canBitConfig.propagationSegTq = CAN::BIT_3TQ;
canBitConfig.phaseSeg2TimeSelect = CAN::TRUE;
canBitConfig.sample3Time = CAN::TRUE;
canBitConfig.syncJumpWidth = CAN::BIT_2TQ;
canMod2.setSpeed(&canBitConfig,SYS_FREQ,CAN_BUS_SPEED);
/* Step 3: Assign the buffer area to the
* CAN module.
*/
/* Note the size of each Channel area.
* It is 2 (Channels) * 8 (Messages Buffers)
* 16 (bytes/per message buffer) bytes. Each
* CAN module should have its own message
* area. */
canMod2.assignMemoryBuffer(CAN2MessageFifoArea,2 * 8 * 16);
/* Step 4: Configure channel 0 for TX and size of
* 8 message buffers with RTR disabled and low medium
* priority. Configure channel 1 for RX and size
* of 8 message buffers and receive the full message.
*/
canMod2.configureChannelForTx(CAN::CHANNEL0,8,CAN::TX_RTR_DISABLED,CAN::LOW_MEDIUM_PRIORITY);
canMod2.configureChannelForRx(CAN::CHANNEL1,8,CAN::RX_FULL_RECEIVE);
/* Step 5: Configure filters and mask. Configure
* filter 0 to accept SID messages with ID 0x200.
* Configure filter mask 0 to compare all the ID
* bits and to filter by the ID type specified in
* the filter configuration. Filter 0 accepted
* messages are stored in channel 1. */
canMod2.configureFilter (CAN::FILTER0, myaddr, CAN::SID);
canMod2.configureFilterMask (CAN::FILTER_MASK0, 0xFFF, CAN::SID, CAN::FILTER_MASK_IDE_TYPE);
canMod2.linkFilterToChannel (CAN::FILTER0, CAN::FILTER_MASK0, CAN::CHANNEL1);
canMod2.enableFilter (CAN::FILTER0, true);
/* Step 6: Enable interrupt and events. Enable the receive
* channel not empty event (channel event) and the receive
* channel event (module event).
* The interrrupt peripheral library is used to enable
* the CAN interrupt to the CPU. */
canMod2.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true);
canMod2.enableModuleEvent(CAN::RX_EVENT, true);
/* Step 7: Switch the CAN mode
* to normal mode. */
canMod2.setOperatingMode(CAN::NORMAL_OPERATION);
while(canMod2.getOperatingMode() != CAN::NORMAL_OPERATION);
}
/* ------------------------------------------------------------ */
/*** txCAN1
**
** Parameters:
** rxnode - address of network node to receive the packet
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Initialize a packet buffer with the packet header and the
** packet payload. The payload in this case is a single
** ASCII character (0x31 = '1'). Transmit the packet.
*/
void
txCAN1(uint32_t rxnode) {
CAN::TxMessageBuffer * message;
message = canMod1.getTxMessageBuffer(CAN::CHANNEL0);
if (message != NULL) {
// clear buffer
message->messageWord[0] = 0;
message->messageWord[1] = 0;
message->messageWord[2] = 0;
message->messageWord[3] = 0;
message->msgSID.SID = rxnode; //receiving node
message->msgEID.IDE = 0;
message->msgEID.DLC = 1;
message->data[0] = 0x31;
//message->data[1] = 0x31;
//message->data[2] = 0x32;
//message->data[3] = 0x33;
//message->data[4] = 0x34;
//message->data[5] = 0x35;
//message->data[6] = 0x36;
//message->data[7] = 0x37;
/* This function lets the CAN module
* know that the message processing is done
* and message is ready to be processed. */
canMod1.updateChannel(CAN::CHANNEL0);
/* Direct the CAN module to flush the
* TX channel. This will send any pending
* message in the TX channel. */
canMod1.flushTxChannel(CAN::CHANNEL0);
}
}
/* ------------------------------------------------------------ */
/*** txCAN2
**
** Parameters:
** rxnode - address of network node to receive the packet
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Initialize a packet buffer with the packet header and the
** packet payload. The payload in this case is a single
** ASCII character (0x32 = '2'). Transmit the packet.
*/
void
txCAN2(uint32_t rxnode) {
CAN::TxMessageBuffer * message;
message = canMod2.getTxMessageBuffer(CAN::CHANNEL0);
if (message != NULL) {
// clear buffer
message->messageWord[0] = 0;
message->messageWord[1] = 0;
message->messageWord[2] = 0;
message->messageWord[3] = 0;
message->msgSID.SID = rxnode; //receiving node
message->msgEID.IDE = 0;
message->msgEID.DLC = 1;
message->data[0] = 0x32;
//message->data[1] = 0x31;
//message->data[2] = 0x32;
//message->data[3] = 0x33;
//message->data[4] = 0x34;
//message->data[5] = 0x35;
//message->data[6] = 0x36;
//message->data[7] = 0x37;
/* This function lets the CAN module
* know that the message processing is done
* and message is ready to be processed. */
canMod2.updateChannel(CAN::CHANNEL0);
/* Direct the CAN module to flush the
* TX channel. This will send any pending
* message in the TX channel. */
canMod2.flushTxChannel(CAN::CHANNEL0);
}
}
/* ------------------------------------------------------------ */
/*** rxCAN1
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Check to see if a packet has been received. If so, read
** the packet and print the packet payload to the serial
** monitor.
*/
void
rxCAN1(void) {
CAN::RxMessageBuffer * message;
if (isCAN1MsgReceived == false) {
/* CAN2 did not receive any message
* so exit the function. Note that the
* isCAN2MsgReceived flag is updated
* by the CAN2 ISR. */
return;
}
/* Message was received. Reset isCAN2MsgReceived flag
* to catch the next message. */
isCAN1MsgReceived = false;
message = canMod1.getRxMessage(CAN::CHANNEL1);
/* Print the first byte of the packet payload area
* as an ASCII character on the serial monitor. */
// byte customWrite[] ={};
customWrite[0] = byte(message->data[0]);
Serial.print(byte(message->data[0]));
/* Call the CAN::updateChannel() function to let
* the CAN module know that the message processing
* is done. Enable the event so that the CAN module
* generates an interrupt when the event occurs.*/
canMod1.updateChannel(CAN::CHANNEL1);
canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true);
}
/* ------------------------------------------------------------ */
/*** rxCAN2
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Check to see if a packet has been received. If so, read
** the packet and print the packet payload to the serial
** monitor.
*/
void
rxCAN2(void) {
CAN::RxMessageBuffer * message;
if (isCAN2MsgReceived == false) {
/* CAN2 did not receive any message
* so exit the function. Note that the
* isCAN2MsgReceived flag is updated
* by the CAN2 ISR. */
return;
}
/* Message was received. Reset isCAN2MsgReceived flag
* to catch the next message. */
isCAN2MsgReceived = false;
message = canMod2.getRxMessage(CAN::CHANNEL1);
/* Print the first byte of the packet payload area
* as an ASCII character on the serial monitor. */
// byte dataWrite[] = {};
dataWrite[0] = byte(message->data[0]);
Serial.print(byte(message->data[0]));
/* Call the CAN::updateChannel() function to let
* the CAN module know that the message processing
* is done. Enable the event so that the CAN module
* generates an interrupt when the event occurs.*/
canMod2.updateChannel(CAN::CHANNEL1);
canMod2.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, true);
}
/* ------------------------------------------------------------ */
/* Interrupt Handler Functions */
/* ------------------------------------------------------------ */
/*** doCan1Interrupt
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Interrupt service routine to handle interrupt level
** events for CAN module 1.
*/
void
doCan1Interrupt() {
/* This is the CAN1 Interrupt Handler.
* This is not the actual Interrupt Service Routine,
* but is the user interrupt handler installed by
* CAN::attachInterrupt. This is called by the ISR.
* Note that there are many events in the CAN1 module
* that can cause this interrupt. These events are
* enabled by the CAN::enableModuleEvent() function.
* In this example, only the CAN::RX_EVENT is enabled. */
/* Check if the source of the interrupt is CAN::RX_EVENT.
* This is redundant since only this event is enabled
* in this example but this shows one scheme for handling
* interrupts. */
if ((canMod1.getModuleEvent() & CAN::RX_EVENT) != 0) {
/* Within this, you can check which event caused the
* interrupt by using the CAN::getPendingEventCode() function
* to get a code representing the highest priority active
* event.*/
if(canMod1.getPendingEventCode() == CAN::CHANNEL1_EVENT) {
/* This means that channel 1 caused the event.
* The CAN::RX_CHANNEL_NOT_EMPTY event is persistent. You
* could either read the channel in the ISR
* to clear the event condition or as done
* here, disable the event source, and set
* an application flag to indicate that a message
* has been received. The event can be
* enabled by the application when it has processed
* one message.
*
* Note that leaving the event enabled would
* cause the CPU to keep executing the ISR since
* the CAN::RX_CHANNEL_NOT_EMPTY event is persistent (unless
* the not empty condition is cleared.)
* */
canMod1.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, false);
isCAN1MsgReceived = true;
}
}
/* The CAN1 Interrupt flag is cleared by the interrupt service routine
* after this function returns. This will succeed because the event
* that caused this interrupt to occur (CAN::RX_CHANNEL_NOT_EMPTY) is disabled.
* The ISR's attempt to clear the CAN1 interrupt flag would fail if the
* CAN::RX_CHANNEL_NOT_EMPTY event were still enabled because the base event
* is still present. In this case, another interrupt would occur immediately */
}
/* ------------------------------------------------------------ */
/*** doCan2Interrupt
**
** Parameters:
** none
**
** Return Value:
** none
**
** Errors:
** none
**
** Description:
** Interrupt service routine to handle interrupt level
** events for CAN module 2.
*/
void
doCan2Interrupt() {
/* This is the CAN2 Interrupt Handler.
* This is not the actual Interrupt Service Routine,
* but is the user interrupt handler installd by
* CAN::attachInterrupt. This is called by the ISR.
* Note that there are many events in the CAN2 module
* that can cause this interrupt. These events are
* enabled by the CAN::enableModuleEvent() function.
* In this example, only the CAN::RX_EVENT is enabled. */
/* Check if the source of the interrupt is CAN::RX_EVENT.
* This is redundant since only this event is enabled
* in this example but this shows one scheme for handling
* interrupts. */
if ((canMod2.getModuleEvent() & CAN::RX_EVENT) != 0) {
/* Within this, you can check which event caused the
* interrupt by using the CAN::getPendingEventCode() function
* to get a code representing the highest priority active
* event.*/
if(canMod2.getPendingEventCode() == CAN::CHANNEL1_EVENT) {
/* This means that channel 1 caused the event.
* The CAN::RX_CHANNEL_NOT_EMPTY event is persistent. You
* could either read the channel in the ISR
* to clear the event condition or as done
* here, disable the event source, and set
* an application flag to indicate that a message
* has been received. The event can be
* enabled by the application when it has processed
* one message.
*
* Note that leaving the event enabled would
* cause the CPU to keep executing the ISR since
* the CAN::RX_CHANNEL_NOT_EMPTY event is persistent (unless
* the not empty condition is cleared.)
* */
canMod2.enableChannelEvent(CAN::CHANNEL1, CAN::RX_CHANNEL_NOT_EMPTY, false);
isCAN2MsgReceived = true;
}
}
/* The CAN2 Interrupt flag is cleared by the interrupt service routine
* after this function returns. This will succeed because the event
* that caused this interrupt to occur (CAN::RX_CHANNEL_NOT_EMPTY) is disabled.
* The ISR's attempt to clear the CAN2 interrupt flag would fail if the
* CAN::RX_CHANNEL_NOT_EMPTY event were still enabled because the base event
* is still present. In this case, another interrupt would occur immediately */
}
/* ------------------------------------------------------------ */
/*** ProcName
**
** Parameters:
**
** Return Value:
**
** Errors:
**
** Description:
**
*/
/* ------------------------------------------------------------ */
/************************************************************************/
For a TCP client you can use a Raspberry Pi or similar ,
#!/usr/bin/env python3
import socket
HOST = '10.0.0.20' # The server's hostname or IP address
PORT = 65432 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
while True:
print("Enter 'a' for CAN_1 data or 'b' for CAN_2 data")
x = input()
if(x == 'a'):
print("Receiving CAN_1 data ...")
s.sendall(b'a')
elif (x == 'b'):
print("Receiving CAN_2 data...")
s.sendall(b'b')
else:
print("invalid")
s.sendall(b'x')
data = s.recv(1024)
print(data)
#print(struct.unpack('B',data))
1.Connect RPi and chipikt with an ethernet cable 2.Remember to assign a static IP address to raspberry pi ethernet(eth0) socket like 10.0.0.10 (refer here How to set static IP to Raspberry Pi?)