David Smart / CANPort2
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CANPort.cpp Source File

CANPort.cpp

Go to the documentation of this file.
00001 /// @file CANPort.cpp is where all the port level functionality resides
00002 ///
00003 /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved.
00004 ///     Individuals may use this application for evaluation or non-commercial
00005 ///     purposes. Within this restriction, changes may be made to this application
00006 ///     as long as this copyright notice is retained. The user shall make
00007 ///     clear that their work is a derived work, and not the original.
00008 ///     Users of this application and sources accept this application "as is" and
00009 ///     shall hold harmless Smartware Computing, for any undesired results while
00010 ///     using this application - whether real or imagined.
00011 ///
00012 /// @author David Smart, Smartware Computing
00013 ///
00014 /// 20110718
00015 ///   Fixed a bug in the Receive handler - it was not propagating the message
00016 ///   out.
00017 /// 20110605
00018 ///   Revised the SlopeControl so that it actually works for any change in value
00019 ///   where it was previously able to go low or high, but once as an input it
00020 ///   then would not go back to an output.
00021 ///
00022 #include "mbed.h"
00023 #include "CANPort.h"
00024 #include "Utilities.h"
00025 
00026 #define FLASH_PERIOD (float)0.04
00027 #define FLASH_TX_LEVEL 0.10
00028 #define FLASH_RX_LEVEL 1.00
00029 
00030 
00031 CANPort::CANPort(CANCHANNEL_T chNum, PinName rd, PinName td, PinName _activityPin, PinName _slopePin, CANSlopeControl_T slope) 
00032     : CAN(rd,td) {
00033     channel = chNum;
00034     //can = new CAN(rd, td);
00035     if (_activityPin != NC) {
00036         activityPin = new PwmOut(_activityPin);
00037         activityPin->pulsewidth_us(100);
00038         }
00039     else
00040         activityPin = NULL;
00041     if (_slopePin != NC) {
00042         slopePin = new DigitalInOut(_slopePin);
00043         SetSlopeControl(slope);
00044     } else
00045         slopePin = NULL;
00046     slopePinName = _slopePin;
00047     txCounter = 0;
00048     rxCounter = 0;
00049 }
00050 
00051 
00052 CANPort::~CANPort() {
00053     if (slopePin)
00054         delete slopePin;
00055     if (activityPin)
00056         delete activityPin;
00057     //if (can)
00058     //    delete can;
00059     slopePin = NULL;
00060     activityPin = NULL;
00061     //can = NULL;
00062 }
00063 
00064 
00065 bool CANPort::TransmitMsg(CANmsg msg) {
00066     bool success = false;
00067 
00068     if (msg.dir == xmt) {   // we have to have indicated our intent to transmit
00069         msg.ch = channel;
00070         if ( write(CANMessage(msg.id, (char *)&msg.data, msg.len, CANData, msg.format))) {
00071             txCounter++;
00072             Flash(msg.dir);
00073             success = true;
00074         }
00075     }
00076     return success;
00077 }
00078 
00079 
00080 bool CANPort::ReceiveMsg(CANmsg &msg) {
00081     bool success = false;
00082     CANMessage _msg;
00083 
00084     if (read(_msg)) {
00085         /// @TODO This looks like a very inefficient method, but it works.
00086         CANmsg Xmsg(channel, rcv, _msg);
00087         msg = Xmsg;
00088         rxCounter++;
00089         Flash(msg.dir);
00090         success = true;
00091     }
00092     return success;
00093 }
00094 
00095 
00096 //void CANPort::Attach( void (*fptr)(void) ) {
00097 //    can->attach(fptr);
00098 //}
00099 
00100 
00101 void CANPort::Extinguish(void) {
00102     if (activityPin) {
00103         *activityPin = 0.0;
00104     }
00105 }
00106 
00107 
00108 void CANPort::Flash(CANDIR_T tx) {
00109     if (activityPin) {
00110         *activityPin = (tx == xmt) ? FLASH_TX_LEVEL : FLASH_RX_LEVEL;     // dim for transmit, bright for receive
00111         #if (MBED_MAJOR_VERSION >= 5) || (MBED_LIBRARY_VERSION > 127)
00112         activityTimeout.attach(callback(this, &CANPort::Extinguish), FLASH_PERIOD);
00113         #else
00114         activityTimeout.attach(this, &CANPort::Extinguish, FLASH_PERIOD);
00115         #endif
00116     }
00117 }
00118 
00119 
00120 bool CANPort::SetAutoReset(bool enable) {
00121     autoReset = enable;
00122     return true;
00123 }
00124 
00125 
00126 bool CANPort::SetBusMode(CANBusMode_T mode) {
00127     switch (mode) {
00128         case MONITOR:
00129             monitor(true);
00130             busMode = mode;
00131             break;
00132         case ACTIVE:
00133             monitor(false);
00134             busMode = mode;
00135             break;
00136         default:
00137             return false;
00138     }
00139     return true;
00140 }
00141 
00142 
00143 CANPort::CANBusMode_T CANPort::GetBusMode() {
00144     return busMode;
00145 }
00146 
00147 
00148 bool CANPort::SetSlopeControl(CANSlopeControl_T slope) {
00149     if (slopePin) {
00150         slopeMode = slope;
00151         switch (slope) {
00152             case HIGHSPEED:
00153                 slopePin->output();
00154                 slopePin->write(0);
00155                 break;
00156             case NORMALSPEED:
00157                 slopePin->input();
00158                 slopePin->mode(PullNone);
00159                 break;
00160             case STANDBY:
00161                 slopePin->output();
00162                 slopePin->write(1);
00163                 break;
00164             default:
00165                 return false;
00166         }
00167         return true;
00168     } else
00169         return false;
00170 }
00171 
00172 
00173 CANPort::CANSlopeControl_T CANPort::GetSlopeControl() {
00174     return slopeMode;
00175 }
00176 
00177 
00178 bool CANPort::SetBitRate(uint32_t rate) {
00179     if (frequency(rate)) {
00180         bitRate = rate;
00181         return true;
00182     } else {
00183         return false;
00184     }
00185 }
00186 
00187 
00188 uint32_t CANPort::GetBitRate() {
00189     return bitRate;
00190 }
00191 
00192 
00193 int CANPort::GetTxCounter() {
00194     return txCounter;
00195 }
00196 
00197 
00198 int CANPort::GetRxCounter() {
00199     return rxCounter;
00200 }
00201 
00202 
00203 int CANPort::GetTxErrorCounter() {
00204     return tderror();
00205 }
00206 
00207 
00208 int CANPort::GetRxErrorCounter() {
00209     return rderror();
00210 }
00211 
00212 
00213 bool CANPort::ResetChip() {
00214     reset();
00215     return true;
00216 }
00217 
00218 
00219 void CANPort::PrintInfo(Serial * stream) {
00220     if (stream) {
00221         stream->printf("\r\n");
00222         stream->printf("  Register:       CAN1       CAN2      Register:       CAN1       CAN2\r\n");
00223         stream->printf("       MOD:   %08X   %08X    ", LPC_CAN1->MOD, LPC_CAN2->MOD);
00224         stream->printf("       GSR:   %08X   %08X\r\n", LPC_CAN1->GSR, LPC_CAN2->GSR);
00225         stream->printf("       ICR:   %08X   %08X    ", LPC_CAN1->ICR, LPC_CAN2->ICR);
00226         stream->printf("       IER:   %08X   %08X\r\n", LPC_CAN1->IER, LPC_CAN2->IER);
00227         stream->printf("       BTR:   %08X   %08X    ", LPC_CAN1->BTR, LPC_CAN2->BTR);
00228         stream->printf("       EWL:   %08X   %08X\r\n", LPC_CAN1->EWL, LPC_CAN2->EWL);
00229         stream->printf("        SR:   %08X   %08X    ", LPC_CAN1->SR,  LPC_CAN2->SR );
00230         stream->printf("       RFS:   %08X   %08X\r\n", LPC_CAN1->RFS, LPC_CAN2->RFS);
00231         stream->printf("       RID:   %08X   %08X    ", LPC_CAN1->RID, LPC_CAN2->RID);
00232         stream->printf("       RDA:   %08X   %08X\r\n", LPC_CAN1->RDA, LPC_CAN2->RDA);
00233         stream->printf("       RDB:   %08X   %08X    ", LPC_CAN1->RDB, LPC_CAN2->RDB);
00234         stream->printf("      TFI1:   %08X   %08X\r\n", LPC_CAN1->TFI1, LPC_CAN2->TFI1);
00235         stream->printf("      TID1:   %08X   %08X    ", LPC_CAN1->TID1, LPC_CAN2->TID1);
00236         stream->printf("      TDA1:   %08X   %08X\r\n", LPC_CAN1->TDA1, LPC_CAN2->TDA1);
00237         stream->printf("      TDB1:   %08X   %08X    ", LPC_CAN1->TDB1, LPC_CAN2->TDB1);
00238         stream->printf("      TFI2:   %08X   %08X\r\n", LPC_CAN1->TFI2, LPC_CAN2->TFI2);
00239         stream->printf("      TID2:   %08X   %08X    ", LPC_CAN1->TID2, LPC_CAN2->TID2);
00240         stream->printf("      TDA2:   %08X   %08X\r\n", LPC_CAN1->TDA2, LPC_CAN2->TDA2);
00241         stream->printf("      TDB2:   %08X   %08X    ", LPC_CAN1->TDB2, LPC_CAN2->TDB2);
00242         stream->printf("      TFI3:   %08X   %08X\r\n", LPC_CAN1->TFI3, LPC_CAN2->TFI3);
00243         stream->printf("      TID3:   %08X   %08X    ", LPC_CAN1->TID3, LPC_CAN2->TID3);
00244         stream->printf("      TDA3:   %08X   %08X\r\n", LPC_CAN1->TDA3, LPC_CAN2->TDA3);
00245         stream->printf("      TDB3:   %08X   %08X    ", LPC_CAN1->TDB3, LPC_CAN2->TDB3);
00246         stream->printf("\r\n");
00247     }
00248 }