System Management code
Dependencies: mbed CANBuffer Watchdog MODSERIAL mbed-rtos xbeeRelay IAP
Fork of SystemManagement by
Revision 33:6bc82b6b62e5, committed 2015-01-06
- Comitter:
- pspatel321
- Date:
- Tue Jan 06 20:45:26 2015 +0000
- Parent:
- 32:e70407021ad2
- Child:
- 34:18bcf276d3bf
- Commit message:
- Updated IDs to match AMS, added a constants.h file.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Constants.h Tue Jan 06 20:45:26 2015 +0000 @@ -0,0 +1,19 @@ +#ifndef CONSTANTS_H +#define CONSTATNS_H + +#define BAUD 460800 // Serial port baud rate +#define CHAR_TIME 0.00002 // Time to send 1 char @ above baud +#define TX_SIZE 1000 // Serial buffer TX size +#define RX_SIZE 100 // Serial buffer RX size + +#define XBEE_BAUD 250000 // 250k baud serial for xbees +#define XBEE_TX_SIZE 1000 // Serial buffer TX size for xbees +#define XBEE_RX_SIZE 100 // Serial buffer RX size for xbees + +#define START_DELAY 10 // Startup delay for latch monitor circuits +#define FAST_LOOP 0.01 // Period (seconds) for fast loop (sampling, filters) +#define GATHER_LOOP 0.1 // Period (seconds) for main data processing loop +#define WDT_TIME 0.1 // Normal, running mode WDT timeout +#define CAN_LOOP 0.1 // Output period for CAN transmissions + +#endif \ No newline at end of file
--- a/IOobjects/CAN_Filter_LUT.h Sun Nov 16 02:43:58 2014 +0000 +++ b/IOobjects/CAN_Filter_LUT.h Tue Jan 06 20:45:26 2015 +0000 @@ -39,7 +39,7 @@ // STANDARD ID RANGES - CAN CONTROLLER 2 //( 0xLOWERBOUND & STDMASK | 1<<13) << 16 | ( 0xUPPERBOUND & STDMASK | 1<<13), lower/upperbounds are inclusive -//( 0xLOWERBOUND & STDMASK | 1<<13) << 16 | ( 0xUPPERBOUND & STDMASK | 1<<13), lower/upperbounds are inclusive +( 0x200 & STDMASK | 1<<13) << 16 | ( 0x7FF & STDMASK | 1<<13), //lower/upperbounds are inclusive, 0x200 to 0x7FF includes everything except motor controller messages };
--- a/IOobjects/CAN_RxIDs.h Sun Nov 16 02:43:58 2014 +0000 +++ b/IOobjects/CAN_RxIDs.h Tue Jan 06 20:45:26 2015 +0000 @@ -1,15 +1,18 @@ #ifndef CAN_RXIDS_H #define CAN_RXIDS_H +#define BASE_ID 0x500 // Start at 0x500 for this device + // Receive IDs -#define FAN_CONTROL_ID 0x480 -#define PUMP_CONTROL_ID 0x481 -#define DCDC_CONTROL_ID 0x482 +#define FAN_CONTROL_ID BASE_ID + 80 +#define PUMP_CONTROL_ID BASE_ID + 81 +#define DCDC_CONTROL_ID BASE_ID + 82 -#define AMS_RELAYS_ID 0x30E +#define GLVBAT_CLEARSOC_ID BASE_ID + 90 +#define GLVBAT_CLEARAH_ID BASE_ID + 91 +#define GLVBAT_SETCAPAC_ID BASE_ID + 92 -#define GLVBAT_CLEARSOC_ID 0x490 -#define GLVBAT_CLEARAH_ID 0x491 -#define GLVBAT_SETCAPAC_ID 0x492 +#define AMS_RELAYS_ID 0x303 +#define STEERING_RESET_ID 0x602 #endif \ No newline at end of file
--- a/IOobjects/CAN_TxIDs.h Sun Nov 16 02:43:58 2014 +0000 +++ b/IOobjects/CAN_TxIDs.h Tue Jan 06 20:45:26 2015 +0000 @@ -1,36 +1,38 @@ #ifndef CAN_TXIDS_H #define CAN_TXIDS_H +#define BASE_ID 0x500 // Start at 0x500 for this device + // Transmit IDs - System Mgmt Specific // Operating diagnostics -#define SYS_ERROR_ID 0x400 // Error frame - critical errors that require shutdown -#define SYS_XBEE1_ID 0x401 // Message in/out counter for xbee1 -#define SYS_XBEE2_ID 0x402 // Message in/out counter for xbee2 -#define SYS_TEMP_ID 0x403 // Internal temperature of the glv battery chargerFET +#define SYS_ERROR_ID BASE_ID + 00 // Error frame - critical errors that require shutdown +#define SYS_XBEE1_ID BASE_ID + 01 // Message in/out counter for xbee1 +#define SYS_XBEE2_ID BASE_ID + 02 // Message in/out counter for xbee2 +#define SYS_TEMP_ID BASE_ID + 03 // Internal temperature of the glv battery chargerFET // GLV Battery -#define SYS_GLV_CURRENT_ID 0x410 // GLV battery current -#define SYS_GLV_CAPACITY_ID 0x411 // GLV battery capacity setting -#define SYS_GLV_AH_ID 0x412 // GLV battery amphours -#define SYS_GLV_SOC_ID 0x413 // GLV battery SOC +#define SYS_GLV_CURRENT_ID BASE_ID + 10 // GLV battery current +#define SYS_GLV_CAPACITY_ID BASE_ID + 11 // GLV battery capacity setting +#define SYS_GLV_AH_ID BASE_ID + 12 // GLV battery amphours +#define SYS_GLV_SOC_ID BASE_ID + 13 // GLV battery SOC // DC-DC Converter -#define SYS_DCDC_CURRENT_ID 0x420 // DC-DC current -#define SYS_DCDC_STATUS_ID 0x421 // DC-DC status byte +#define SYS_DCDC_CURRENT_ID BASE_ID + 20 // DC-DC current +#define SYS_DCDC_STATUS_ID BASE_ID + 21 // DC-DC status byte // PWM Channels -#define SYS_PWM_FAN_ID 0x430 // FAN1 actual pwm -#define SYS_PWM_PUMP_ID 0x431 // PUMP1 actual pwm +#define SYS_PWM_FAN_ID BASE_ID + 30 // FAN1 actual pwm +#define SYS_PWM_PUMP_ID BASE_ID + 31 // PUMP1 actual pwm // IMD -#define SYS_IMD_STATUS_ID 0x440 // IMD status byte -#define SYS_IMD_RESIST_ID 0x441 // IMD resistance measurement +#define SYS_IMD_STATUS_ID BASE_ID + 40 // IMD status byte +#define SYS_IMD_RESIST_ID BASE_ID + 41 // IMD resistance measurement // Latch Supervisor states -#define SYS_IMD_LATCH_ID 0x450 // IMD Latch circuit error byte -#define SYS_AMS_LATCH_ID 0x451 // AMS Latch circuit error byte +#define SYS_IMD_LATCH_ID BASE_ID + 50 // IMD Latch circuit error byte +#define SYS_AMS_LATCH_ID BASE_ID + 51 // AMS Latch circuit error byte // Shutdown Switches -#define SYS_SWITCHES_ID 0x460 // Shutdown Switch State +#define SYS_SWITCHES_ID BASE_ID + 60 // Shutdown Switch State #endif \ No newline at end of file
--- a/IOobjects/IOobjects.cpp Sun Nov 16 02:43:58 2014 +0000
+++ b/IOobjects/IOobjects.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -1,5 +1,6 @@
#include "IOobjects.h"
+Watchdog wdt(1); // Watchdog timer (TIMEOUT (sec))
LPCDigitalIn sw[]={ // Shutdown switch sense lines
LPCDigitalIn(p1_0, PullUp), // Sense0 - fuse power
LPCDigitalIn(p1_1, PullUp), // Sense1 - AMS latch
@@ -14,20 +15,20 @@
LPCDigitalIn(p1_27, PullUp), // Sense10 - HVD/Charger
LPCDigitalIn(p1_28, PullUp), // Sense11 - TSMS/tractive enable
};
-
CANBuffer can(CAN2, MEDIUM, p4_28); // Buffered CAN interface (PORT, SPEED, SILENT PIN)
-CoulombCounter glvBat(p19, 10); // Coulomb counter battery monitor for GLV Battery (CURRENT SENSE PIN, INTEGRATION TIME)
+CoulombCounter glvBat(p19, FAST_LOOP*1000); // Coulomb counter battery monitor for GLV Battery (CURRENT SENSE PIN, INTEGRATION TIME)
DC_DC dcdc(p18, p20, p26, p25, p24, p23, 0.01, 1); // DC-DC converter & high-current load control (CONTROL PIN< CURRENT SENSE PIN, FAN1 PIN, FAN2 PIN, PUMP1 PIN, PUMP2 PIN, PWM PERIOD (sec), FULL-SCALE SLEW (sec))
IMD imd(p1_26); // IMD PWM sense channel to read status and resistance (IMD PWM PIN)
-LatchMonitor AMSlatch(p0_18, p0_22, 15000); // Supervisor for AMS hardware latch/reset circuit (OK PIN, FAULT PIN, STARTUP DELAY (ms))
-LatchMonitor IMDlatch(p0_17, p0_21, 15000); // Supervisor for IMD hardware latch/reset circuit (OK PIN, FAULT PIN, STARTUP DELAY (ms))
-MODSERIAL pc(USBTX, USBRX, 3072, 256); // Serial to computer for diagnostics, 3kB output buffer, 256 byte input buffer
+LatchMonitor AMSlatch(p0_18, p0_22, START_DELAY*1000); // Supervisor for AMS hardware latch/reset circuit (OK PIN, FAULT PIN, STARTUP DELAY (ms))
+LatchMonitor IMDlatch(p0_17, p0_21, START_DELAY*1000); // Supervisor for IMD hardware latch/reset circuit (OK PIN, FAULT PIN, STARTUP DELAY (ms))
+MODSERIAL pc(USBTX, USBRX, TX_SIZE, RX_SIZE); // Serial to computer for diagnostics, 3kB output buffer, 256 byte input buffer
Temperature internalTmp(&NXFT15XH103_TABLE, p15); // Temperature conversion look-up table for internal temperature on the GLV bat charger FET (TABLE PTR, PIN)
PollSwitch switches(sw, sizeof(sw)/sizeof(sw[0])); // Shutdown switch sense pins (SWITCH PIN ARRAY, NUM PINS)
-Watchdog wdt(0.25); // Watchdog timer (TIMEOUT (sec))
-//Xbee xbee1(p9, p10, 250000, 1000, '\n'); // Software buffered Xbee 1 of 2 for wireless comms (TX, RX, BAUD, BUFFERSIZE, DELIM CHAR)
-//Xbee xbee2(p13, p14, 250000, 1000, '\n'); // Software buffered Xbee 2 of 2 for wireless comms (TX, RX, BAUD, BUFFERSIZE, DELIM CHAR)
-XbeeRelay xbee;
+
+CANxbee xbee1(p9, p10, XBEE_BAUD, XBEE_TX_SIZE, XBEE_RX_SIZE);
+CANxbee xbee2(p13, p14, XBEE_BAUD, XBEE_TX_SIZE, XBEE_RX_SIZE);
+XbeeManager xbeeRelay(&xbee1, &xbee2);
+//XbeeRelay xbee;
DigitalOut extras[] = {(p16), (p17)}; // Unused analog pins driven low
Inputs data;
--- a/IOobjects/IOobjects.h Sun Nov 16 02:43:58 2014 +0000
+++ b/IOobjects/IOobjects.h Tue Jan 06 20:45:26 2015 +0000
@@ -2,7 +2,9 @@
#define _IO_OBJECTS_H
#include "mbed.h"
-#include "rtos.h"
+#include "Constants.h"
+#include "CAN_RxIDs.h"
+#include "CAN_TxIDs.h"
#include "CANBuffer.h"
#include "CoulombCounter.h"
#include "DC_DC.h"
@@ -12,8 +14,11 @@
#include "PollSwitch.h"
#include "Temperature.h"
#include "Watchdog.h"
-#include "Xbee.h"
-#include "XbeeRelay.h"
+#include "XbeeManager.h"
+//#include "XbeeRelay.h"
+
+#define OS_TIMERPRIO 6
+#include "rtos.h"
extern CANBuffer can;
extern CoulombCounter glvBat;
@@ -25,56 +30,52 @@
extern PollSwitch switches;
extern Temperature internalTmp;
extern Watchdog wdt;
-extern XbeeRelay xbee;
+//extern XbeeRelay xbee;
+extern XbeeManager xbeeRelay;
// Shared data updated by producer threads
class Inputs {
public:
- volatile float glvCurrent;
- volatile float glvAmphours;
- volatile float glvSOC;
- volatile float glvCapacity;
- volatile bool glvOverCurrent; // Error bit, turn off car
+ float glvCurrent;
+ float glvAmphours;
+ float glvSOC;
+ float glvCapacity;
+ bool glvOverCurrent; // Error bit, turn off car
- volatile char dcdcStatus;
- volatile bool dcdcError; // Error bit, turn off car
- volatile float dcdcCurrent;
- volatile float dcdcFan1Duty;
- volatile float dcdcFan2Duty;
- volatile float dcdcPump1Duty;
- volatile float dcdcPump2Duty;
+ char dcdcStatus;
+ bool dcdcError; // Error bit, turn off car
+ float dcdcCurrent;
+ float dcdcFan1Duty;
+ float dcdcFan2Duty;
+ float dcdcPump1Duty;
+ float dcdcPump2Duty;
- volatile char imdStatus;
- volatile float imdResistance;
- volatile bool imdError; // Error bit, turn off car
+ char imdStatus;
+ float imdResistance;
+ bool imdError; // Error bit, turn off car
- volatile char AMSlatchError; // Error bit, turn off car
- volatile char IMDlatchError; // Error bit, turn off car
+ char AMSlatchError; // Error bit, turn off car
+ char IMDlatchError; // Error bit, turn off car
- volatile char switchState;
-
- volatile float internalTemp;
- volatile bool internalOverTemp; // Error bit, turn off car
+ char switchState;
- volatile unsigned int xbee1MessagesIn;
- volatile unsigned int xbee2MessagesIn;
- volatile unsigned int xbee1MessagesOut;
- volatile unsigned int xbee2MessagesOut;
-
- volatile bool watchdogReset; // Error bit, turn off car
- volatile bool canFault; // Error bit, turn off car
+ float internalTemp;
+ bool internalOverTemp; // Error bit, turn off car
+
+ bool watchdogReset; // Error bit, turn off car
+ bool canFault; // Error bit, turn off car
- volatile char errorFrame;
+ char errorFrame;
};
// Shared data updated by CAN messeges
class CANinputs {
public:
- volatile bool airsClosed;
- volatile float dcdcFan1Duty;
- volatile float dcdcFan2Duty;
- volatile float dcdcPump1Duty;
- volatile float dcdcPump2Duty;
+ bool airsClosed;
+ float dcdcFan1Duty;
+ float dcdcFan2Duty;
+ float dcdcPump1Duty;
+ float dcdcPump2Duty;
};
extern CANinputs CANdata;
--- a/Libs/CoulombCounter/CoulombCounter.cpp Sun Nov 16 02:43:58 2014 +0000
+++ b/Libs/CoulombCounter/CoulombCounter.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -16,12 +16,11 @@
if (capReg < 1.0 || capReg > 5.0) { // Bad, write default
store.write(defaultAh, rtcGPREG_capacity);
}
- capReg = store.read(rtcGPREG_capacity);
// Default SOC if blank or corrupted
float Ah = store.read(rtcGPREG_counter);
- if (Ah < 0 || Ah > capReg) { // Bad, write default
- store.write(defaultSOC*capReg, rtcGPREG_counter);
+ if (Ah < 0 || Ah > defaultAh) { // Bad, write default
+ store.write(defaultSOC*defaultAh, rtcGPREG_counter);
}
// Take the initial readings, fill the buffer
--- a/Libs/MODDMA.lib Sun Nov 16 02:43:58 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/AjK/code/MODDMA/#97a16bf2ff43
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Libs/MODSERIAL.lib Tue Jan 06 20:45:26 2015 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/AjK/code/MODSERIAL/#ae0408ebdd68
--- a/Libs/MODSERIAL/ChangeLog.c Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/* $Id:$
-
-1.25 8th January 2013
-
- * Bring back into line with MBed libraries.
- * Credits:
- Erik Olieman : http://mbed.org/users/Sissors/code/MODSERIAL/rev/3ba4341d74d6
- Erik Olieman : http://mbed.org/users/Sissors/code/MODSERIAL/rev/a469aa702bab
-
-
-1.24 6th Dec 2012
-
- * Beta release for new Mbed library.
-
-1.23 25th July 2012
-
- * LPC1768 code as was. This release includes "alpha" support for the LPC11U24
-
-1.22 19th April 2012
-
- * http://mbed.org/forum/bugs-suggestions/topic/2936/
- * Bug fix, protect important buffer pointers from IRQ corruption.
- * Credits:
- Anthony Wieser http://mbed.org/users/WieserSoftwareLtd/ for the fix.
- BlazeX http://mbed.org/users/BlazeX/ for the alert that a fix was needed!
-
-1.21 10 May 2011
-
- * http://mbed.org/forum/mbed/topic/2264
-
-1.20 26 April 2011
-
- * Bug fix, not blocking on transmit
- by Erik Petrich, http://mbed.org/forum/bugs-suggestions/topic/2200
-
-1.19 20 April 2011
-
- * Fixed some doxygen comment bugs.
-
-1.18 20 April 2011
-
- * All callbacks now use MODSERIAL_callback (rather than Mbed's FunctionPointer[1] type)
- to store and invoke it's callbacks. This allows MODSERIAL to pass a parameter
- to callbacks. The function prototype is now void func(MODSERIAL_IRQ_INFO *q).
- * Callbacks now pass a pointer to a MODSERIAL_IRQ_INFO class type.
- This class holds a pointer to the MODSERIAL object that invoked the callback
- thus freeing callbacks need to use the global variable of the original
- MODSERIAL instance.
- * MODSERIAL_IRQ_INFO also declares public functions that are protected within MODSERIAL
- thus allowing certain functions to be restricted to callback context only.
- * New function MODSERIAL_IRQ_INFO::rxDiscardLastChar() allows an rxCallback function
- to remove the character that was just placed into the RX buffer.
-
- [1] http://mbed.org/users/AjK/libraries/FPointer/latest/docs/
-
-1.17 08/Mar/2011
- Fixed a memory leak in the DMA code.
-
-1.16 - 12 Feb 2011
-
- * Missed one, doh!
-
-1.15 - 12 Feb 2011
-
- * Fixed some typos.
-
-1.14 - 7 Feb 2011
-
- * Fixed a bug in __putc() that caused the output buffer pointer to
- become corrupted.
-
-1.13 - 20/01/2011
-
- * Added extra documentation.
- * Fixed some typos.
-
-1.12 - 20/01/2011
-
- * Added new "autoDetectChar()" function. To use:-
- 1st: Add a callback to invoke when the char is detected:-
- .attach(&detectedChar, MODSERIAL::RxAutoDetect);
- 2nd: Send the char to detect.
- .autoDectectChar('\n');
- Whenever that char goes into the RX buffer your callback will be invoked.
- Added example2.cpp to demo a simple messaging system using this auto feature.
-
-
-1.11 - 23/11/2010
-
- * Fixed a minor issue with 1.10 missed an alteration of name change.
-
-1.10 - 23/11/2010
-
- * Rename the DMA callback from attach_dma_complete() to attach_dmaSendComplete()
-
-1.9 - 23/11/2010
-
- * Added support for DMA sending of characters. Required is
- the MODDMA library module:-
- http://mbed.org/users/AjK/libraries/MODDMA/latest
- See example_dma.cpp for more information.
-
-1.8 - 22/11/2010
-
- * Added code so that if a buffer is set to zero length then
- MODSERIAL defaults to just using the FIFO for that stream
- thus making the library "fall back" to teh same operation
- that the Mbed Serial library performs.
- * Removed dmaSend() function that should have been removed
- at 1.7
-
-1.7 - 21/11/2010
-
- * Remove the DMA enum from MODSERIAL.h as it's not currently
- ready for release.
- * Added page doxygen comments.
-
-1.6 - 21/11/2010
-
- * Version 1.5 solved a blocking problem on putc() when called
- from another ISR. However, isr_tx() invokes a callback of it's
- own when a byte is tranferred from TX buffer to TX FIFO. User
- programs may interpret that as an IRQ callback. That's an ISR
- call from within an existing ISR which is not good. So the
- TxIrq callback from isr_tx is now conditional. It will only
- be called when isr_tx() is actually within it's own ISR and
- not when called from alternate ISR handlers.
-
-1.5 - 21/11/2010
-
- * Calling putc() (or any derived function that uses it like
- printf()) while inside an interrupt service routine can
- cause the system to lock up if the TX buffer is full. This
- is because bytes are only transferred from the TX buffer to
- the TX FIFO via the TX ISR. If we are, say in an RX ISR already,
- then the TX ISR will never trigger. The TX buffer stays full and
- there is never space to putc() the byte. So, while putc() blocks
- waiting for space it calls isr_tx() to ensure if TX FIFO space
- becomes available it will move bytes from the TX buffer to TX
- FIFO thus removing the blocking condition within putc().
-
-1.4 - 21/11/2010
-
- * Removed all the new DMA code. I wish mbed.org had proper SVN
- versioning, I'm use to working in HEAD and BRANCHES after I've
- released a project. Getting bug reports in current releases
- while trying to dev new code is hard to manage without source
- control of some type!
-
-1.3 - 21/11/2010
-
- * Fixed a macro problem with txIsBusy()
- * Started adding code to use "block data" sending using DMA
- * Removed #include "IOMACROS.h"
-
-1.2 - 21/11/2010
-
- * Removed unsed variables from flushBuffer()
- * Fixed a bug where both RX AND TX fifos are cleared/reset
- when just TX OR RX should be cleared.
- * Fixed a bug that cleared IIR when in fact it should be left
- alone so that any pending interrupt after flush is handled.
- * Merged setBase() into init() as it wasn't required anywhere else.
- * Changed init() to enforce _uidx is set by Serial to define the _base
- address of the Uart in use.
-
-1.1 - 20/11/2010
-
- * Added this file
- * Removed cruft from GETC.cpp
- * "teh" should be "the", why do my fingers do that?
-
-1.0 - 20/11/2010
-
- * First release.
-
-*/
\ No newline at end of file
--- a/Libs/MODSERIAL/FLUSH.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-namespace AjK {
-
-void
-MODSERIAL::flushBuffer(IrqType type)
-{
- uint32_t ier = _IER;
- switch(type) {
- case TxIrq: _IER &= ~(1UL << 1); break;
- case RxIrq: _IER &= ~(1UL << 0); break;
- }
- buffer_in[type] = 0;
- buffer_out[type] = 0;
- buffer_count[type] = 0;
- buffer_overflow[type] = 0;
- switch(type) {
- case TxIrq: _FCR = MODSERIAL_FIFO_TX_RESET; break;
- case RxIrq: _FCR = MODSERIAL_FIFO_RX_RESET; break;
- }
- _IER = ier;
-}
-
-}; // namespace AjK ends
--- a/Libs/MODSERIAL/GETC.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-namespace AjK {
-
-int
-MODSERIAL::__getc(bool block)
-{
- // If no buffer is in use fall back to standard RX FIFO usage.
- // Note, we must block in this case and ignore bool "block"
- // so as to maintain compat with Mbed Serial.
- if (buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) {
- while(! MODSERIAL_RBR_HAS_DATA ) ;
- return (int)(_RBR & 0xFF);
- }
-
- if (block) { while ( MODSERIAL_RX_BUFFER_EMPTY ) ; } // Blocks.
- else if ( MODSERIAL_RX_BUFFER_EMPTY ) return -1;
-
- int c = buffer[RxIrq][buffer_out[RxIrq]];
- buffer_out[RxIrq]++;
- if (buffer_out[RxIrq] >= buffer_size[RxIrq]) {
- buffer_out[RxIrq] = 0;
- }
-
- // If we have made space in the RX Buffer then copy over
- // any characters in the RX FIFO that my reside there.
- // Temporarily disable the RX IRQ so that we do not re-enter
- // it under interrupts.
- if ( ! MODSERIAL_RX_BUFFER_FULL ) {
- uint32_t ier = _IER;
- _IER &= ~(1UL << 0);
- isr_rx();
- _IER = ier;
- }
-
- __disable_irq();
- buffer_count[RxIrq]--;
- __enable_irq();
- return c;
-}
-
-}; // namespace AjK ends
--- a/Libs/MODSERIAL/INIT.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-
-namespace AjK {
-
-void
-MODSERIAL::init( int txSize, int rxSize, PinName rx )
-{
- disableIrq();
-
- callbackInfo.setSerial(this);
-
-#ifdef __LPC11UXX_H__
-
- _base = LPC_USART;
-
-#else
- switch( _serial.index ) {
- case 0: _base = LPC_UART0; break;
- case 1: _base = LPC_UART1; break;
- case 2: _base = LPC_UART2; break;
- case 3: _base = LPC_UART3; break;
- default: _base = NULL; break;
- }
-#endif
-
- dmaSendChannel = -1;
- moddma_p = (void *)NULL;
-
- if ( _base != NULL ) {
- buffer_size[RxIrq] = rxSize;
- buffer[RxIrq] = rxSize > 0 ? (char *)malloc(buffer_size[RxIrq]) : (char *)NULL;
- buffer_in[RxIrq] = 0;
- buffer_out[RxIrq] = 0;
- buffer_count[RxIrq] = 0;
- buffer_overflow[RxIrq] = 0;
- Serial::attach( this, &MODSERIAL::isr_rx, Serial::RxIrq );
-
- buffer_size[TxIrq] = txSize;
- buffer[TxIrq] = txSize > 0 ? (char *)malloc(buffer_size[TxIrq]) : (char *)NULL;
- buffer_in[TxIrq] = 0;
- buffer_out[TxIrq] = 0;
- buffer_count[TxIrq] = 0;
- buffer_overflow[TxIrq] = 0;
- Serial::attach( this, &MODSERIAL::isr_tx, Serial::TxIrq );
- }
- else {
- error("MODSERIAL must have a defined UART to function.");
- }
-
- _FCR = MODSERIAL_FIFO_ENABLE | MODSERIAL_FIFO_RX_RESET | MODSERIAL_FIFO_TX_RESET;
-
- auto_detect_char = 0;
-
- enableIrq();
-}
-
-}; // namespace AjK ends
--- a/Libs/MODSERIAL/ISR_RX.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-namespace AjK {
-
-void
-MODSERIAL::isr_rx(void)
-{
- if (! _base || buffer_size[RxIrq] == 0 || buffer[RxIrq] == (char *)NULL) {
- _isr[RxIrq].call(&this->callbackInfo);
- return;
- }
-
- while( MODSERIAL_RBR_HAS_DATA ) {
- rxc = (char)(_RBR & 0xFF);
- if ( MODSERIAL_RX_BUFFER_FULL ) {
- buffer_overflow[RxIrq] = rxc; // Oh dear, no room in buffer.
- _isr[RxOvIrq].call(&this->callbackInfo);
- }
- else {
- if (buffer[RxIrq] != (char *)NULL) {
- buffer[RxIrq][buffer_in[RxIrq]] = rxc;
- buffer_count[RxIrq]++;
- buffer_in[RxIrq]++;
- if (buffer_in[RxIrq] >= buffer_size[RxIrq]) {
- buffer_in[RxIrq] = 0;
- }
- }
- _isr[RxIrq].call(&this->callbackInfo);
- }
- if (auto_detect_char == rxc) {
- _isr[RxAutoDetect].call(&this->callbackInfo);
- }
- }
-}
-
-}; // namespace AjK ends
-
--- a/Libs/MODSERIAL/ISR_TX.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-namespace AjK {
-
-void
-MODSERIAL::isr_tx(bool doCallback)
-{
- if (! _base || buffer_size[TxIrq] == 0 || buffer[TxIrq] == (char *)NULL) {
- _isr[TxIrq].call(&this->callbackInfo);
- return;
- }
-
- while (! MODSERIAL_TX_BUFFER_EMPTY && MODSERIAL_THR_HAS_SPACE ) {
- _THR = txc = (uint8_t)(buffer[TxIrq][buffer_out[TxIrq]]);
- buffer_count[TxIrq]--;
- buffer_out[TxIrq]++;
- if (buffer_out[TxIrq] >= buffer_size[TxIrq]) {
- buffer_out[TxIrq] = 0;
- }
- if (doCallback) _isr[TxIrq].call(&this->callbackInfo);
- }
-
- if ( MODSERIAL_TX_BUFFER_EMPTY ) {
- _IER = 1;
- _isr[TxEmpty].call(&this->callbackInfo);
- }
-}
-
-}; // namespace AjK ends
-
-
--- a/Libs/MODSERIAL/MACROS.h Sun Nov 16 02:43:58 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - Copyright (c) 2010 Andy Kirkham - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. -*/ - -#ifndef MODSERIAL_MACROS_H -#define MODSERIAL_MACROS_H - -#define MODSERIAL_RBR 0x00 -#define MODSERIAL_THR 0x00 -#define MODSERIAL_DLL 0x00 -#define MODSERIAL_IER 0x04 -#define MODSERIAL_DML 0x04 -#define MODSERIAL_IIR 0x08 -#define MODSERIAL_FCR 0x08 -#define MODSERIAL_LCR 0x0C -#define MODSERIAL_LSR 0x14 -#define MODSERIAL_SCR 0x1C -#define MODSERIAL_ACR 0x20 -#define MODSERIAL_ICR 0x24 -#define MODSERIAL_FDR 0x28 -#define MODSERIAL_TER 0x30 - -#define MODSERIAL_LSR_RDR (1UL << 0) -#define MODSERIAL_LSR_OE (1UL << 1) -#define MODSERIAL_LSR_PE (1UL << 2) -#define MODSERIAL_LSR_FE (1UL << 3) -#define MODSERIAL_LSR_BR (1UL << 4) -#define MODSERIAL_LSR_THRE (1UL << 5) -#define MODSERIAL_LSR_TEMT (1UL << 6) -#define MODSERIAL_LSR_RXFE (1UL << 7) - -#define MODSERIAL_FIFO_ENABLE 1 -#define MODSERIAL_FIFO_RX_RESET 2 -#define MODSERIAL_FIFO_TX_RESET 4 - -#define _RBR *((char *)_base+MODSERIAL_RBR) -#define _THR *((char *)_base+MODSERIAL_THR) -#define _IIR *((char *)_base+MODSERIAL_IIR) -#define _IER *((char *)_base+MODSERIAL_IER) -#define _LSR *((char *)_base+MODSERIAL_LSR) -#define _FCR *((char *)_base+MODSERIAL_FCR) - -#define MODSERIAL_TX_BUFFER_EMPTY (buffer_count[TxIrq]==0) -#define MODSERIAL_RX_BUFFER_EMPTY (buffer_count[RxIrq]==0) -#define MODSERIAL_TX_BUFFER_FULL (buffer_count[TxIrq]==buffer_size[TxIrq]) -#define MODSERIAL_RX_BUFFER_FULL (buffer_count[RxIrq]==buffer_size[RxIrq]) - -#define MODSERIAL_THR_HAS_SPACE ((int)_LSR&MODSERIAL_LSR_THRE) -#define MODSERIAL_TEMT_IS_EMPTY ((int)_LSR&MODSERIAL_LSR_TEMT) -#define MODSERIAL_RBR_HAS_DATA ((int)_LSR&MODSERIAL_LSR_RDR) - -#endif
--- a/Libs/MODSERIAL/MODSERIAL.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
- @file MODSERIAL.h
- @purpose Extends Serial to provide fully buffered IO
- @version 1.6
- @date Nov 2010
- @author Andy Kirkham
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-namespace AjK {
-
-MODSERIAL::MODSERIAL( PinName tx, PinName rx, const char* name ) : Serial( tx, rx, name )
-{
- init( MODSERIAL_DEFAULT_TX_BUFFER_SIZE, MODSERIAL_DEFAULT_RX_BUFFER_SIZE, rx );
-}
-
-MODSERIAL::MODSERIAL( PinName tx, PinName rx, int bufferSize, const char* name ) : Serial( tx, rx, name )
-{
- init( bufferSize, bufferSize, rx );
-}
-
-MODSERIAL::MODSERIAL( PinName tx, PinName rx, int txSize, int rxSize, const char* name ) : Serial( tx, rx, name )
-{
- init( txSize, rxSize, rx );
-}
-
-MODSERIAL::~MODSERIAL()
-{
- disableIrq();
- if ( buffer[0] != NULL) free((char *)buffer[0] );
- if ( buffer[1] != NULL) free((char *)buffer[1] );
-}
-
-bool
-MODSERIAL::txBufferFull( void )
-{
- return MODSERIAL_TX_BUFFER_FULL;
-}
-
-bool
-MODSERIAL::rxBufferFull( void )
-{
- return MODSERIAL_RX_BUFFER_FULL;
-}
-
-bool
-MODSERIAL::txBufferEmpty( void )
-{
- return MODSERIAL_TX_BUFFER_EMPTY;
-}
-
-bool
-MODSERIAL::rxBufferEmpty( void )
-{
- return MODSERIAL_RX_BUFFER_EMPTY;
-}
-
-bool
-MODSERIAL::txIsBusy( void )
-{
- return ( _LSR & ( 3UL << 5 ) == 0 ) ? true : false;
-}
-
-void
-MODSERIAL::disableIrq( void )
-{
-
-#ifdef __LPC11UXX_H__
- NVIC_DisableIRQ( UART_IRQn );
-#else
- switch( _serial.index ) {
- case 0: NVIC_DisableIRQ( UART0_IRQn ); break;
- case 1: NVIC_DisableIRQ( UART1_IRQn ); break;
- case 2: NVIC_DisableIRQ( UART2_IRQn ); break;
- case 3: NVIC_DisableIRQ( UART3_IRQn ); break;
- }
-#endif
-}
-
-void
-MODSERIAL::enableIrq(void)
-{
-#ifdef __LPC11UXX_H__
- NVIC_EnableIRQ( UART_IRQn );
-#else
- switch( _serial.index ) {
- case 0: NVIC_EnableIRQ( UART0_IRQn ); break;
- case 1: NVIC_EnableIRQ( UART1_IRQn ); break;
- case 2: NVIC_EnableIRQ( UART2_IRQn ); break;
- case 3: NVIC_EnableIRQ( UART3_IRQn ); break;
- }
-#endif
-}
-
-int
-MODSERIAL::rxDiscardLastChar( void )
-{
- // This function can only be called indirectly from
- // an rxCallback function. Therefore, we know we
- // just placed a char into the buffer.
- char c = buffer[RxIrq][buffer_in[RxIrq]];
-
- if (buffer_count[RxIrq]) {
- buffer_count[RxIrq]--;
- buffer_in[RxIrq]--;
- if (buffer_in[RxIrq] < 0) {
- buffer_in[RxIrq] = buffer_size[RxIrq] - 1;
- }
- }
-
- return (int)c;
-}
-
-
-}; // namespace AjK ends
--- a/Libs/MODSERIAL/MODSERIAL.h Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1089 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
- @file MODSERIAL.h
- @purpose Extends Serial to provide fully buffered IO
- @version see ChangeLog.c
- @date Nov 2010
- @author Andy Kirkham
-*/
-
-#ifndef MODSERIAL_H
-#define MODSERIAL_H
-
-/** @defgroup API The MODSERIAL API */
-/** @defgroup MISC Misc MODSERIAL functions */
-/** @defgroup INTERNALS MODSERIAL Internals */
-
-#ifndef MODSERIAL_DEFAULT_RX_BUFFER_SIZE
-#define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 256
-#endif
-
-#ifndef MODSERIAL_DEFAULT_TX_BUFFER_SIZE
-#define MODSERIAL_DEFAULT_TX_BUFFER_SIZE 256
-#endif
-
-#include "mbed.h"
-#include "serial_api.h"
-
-namespace AjK {
-
-// Forward reference.
-class MODSERIAL;
-
-/**
- * @author Andy Kirkham
- * @see http://mbed.org/cookbook/MODSERIAL
- * @see example3a.cpp
- * @see example3b.cpp
- * @see API
- *
- * <b>MODSERIAL_IRQ_INFO</b> is a class used to pass information (and access to protected
- * MODSERIAL functions) to IRQ callbacks.
- */
-class MODSERIAL_IRQ_INFO
-{
-public:
- friend class MODSERIAL;
-
- MODSERIAL *serial;
-
- MODSERIAL_IRQ_INFO() { serial = 0; }
-
- /** rxDiscardLastChar()
- *
- * Remove the last char placed into the rx buffer.
- * This is an operation that can only be performed
- * by an rxCallback function.
- * @ingroup API
- * @return The byte removed from the buffer.
- */
- int rxDiscardLastChar(void);
-
-protected:
-
- /** setSerial()
- *
- * Used internally by MODSERIAL to set the "this" pointer
- * of the MODSERIAL that created this object.
- * @ingroup INTERNAL
- * @param A pointer to a MODSERIAL object instance.
- */
- void setSerial(MODSERIAL *s) { serial = s; }
-};
-
-// Forward reference dummy class.
-class MODSERIAL_callback_dummy;
-
-/**
- * @author Andy Kirkham
- * @see http://mbed.org/cookbook/MODSERIAL
- * @see example3a.cpp
- * @see example3b.cpp
- * @see API
- *
- * <b>MODSERIAL_callback</b> is a class used to hold application callbacks that
- * MODSERIAL can invoke on certain events.
- */
-class MODSERIAL_callback
-{
-protected:
-
- //! C callback function pointer.
- void (*c_callback)(MODSERIAL_IRQ_INFO *);
-
- //! C++ callback object/method pointer (the object part).
- MODSERIAL_callback_dummy *obj_callback;
-
- //! C++ callback object/method pointer (the method part).
- void (MODSERIAL_callback_dummy::*method_callback)(MODSERIAL_IRQ_INFO *);
-
-public:
-
- /** Constructor
- */
- MODSERIAL_callback() {
- c_callback = 0;
- obj_callback = 0;
- method_callback = 0;
- }
-
- /** attach - Overloaded attachment function.
- *
- * Attach a C type function pointer as the callback.
- *
- * Note, the callback function prototype must be:-
- * @code
- * void myCallbackFunction(MODSERIAL_IRQ_INFO *);
- * @endcode
- * @param A C function pointer to call.
- */
- void attach(void (*function)(MODSERIAL_IRQ_INFO *) = 0) { c_callback = function; }
-
- /** attach - Overloaded attachment function.
- *
- * Attach a C++ type object/method pointer as the callback.
- *
- * Note, the callback method prototype must be:-
- * @code
- * public:
- * void myCallbackFunction(MODSERIAL_IRQ_INFO *);
- * @endcode
- * @param A C++ object pointer.
- * @param A C++ method within the object to call.
- */
- template<class T>
- void attach(T* item, void (T::*method)(MODSERIAL_IRQ_INFO *)) {
- obj_callback = (MODSERIAL_callback_dummy *)item;
- method_callback = (void (MODSERIAL_callback_dummy::*)(MODSERIAL_IRQ_INFO *))method;
- }
-
- /** call - Overloaded callback initiator.
- *
- * call the callback function.
- *
- * @param A pointer to a MODSERIAL_IRQ_INFO object.
- */
- void call(MODSERIAL_IRQ_INFO *arg) {
- if (c_callback != 0) {
- (*c_callback)(arg);
- }
- else {
- if (obj_callback != 0 && method_callback != 0) {
- (obj_callback->*method_callback)(arg);
- }
- }
- }
-};
-
-/**
- * @author Andy Kirkham
- * @see http://mbed.org/cookbook/MODSERIAL
- * @see http://mbed.org/handbook/Serial
- * @see example1.cpp
- * @see example2.cpp
- * @see example3a.cpp
- * @see example3b.cpp
- * @see example_dma.cpp
- * @see API
- *
- * <b>MODSERIAL</b> extends the Mbed library <a href="/handbook/Serial">Serial</a> to provide fully buffered
- * TX and RX streams. Buffer length is fully customisable.
- *
- * Before using MODSERIAL users should be familar with Mbed's standard <a href="/handbook/Serial">Serial</a>
- * library object. MODSERIAL is a direct "drop in" replacement for <a href="/handbook/Serial">Serial</a>. Where
- * previously Serial was used, MODSERIAL can be used as adirect replacement instantly offering standard
- * TX and RX buffering. By default, both TX and RX buffers are 256 bytes in length.
- *
- * @image html /media/uploads/mbedofficial/serial_interfaces.png
- *
- * Standard example:
- * @code
- * #include "mbed.h"
- * #include "MODSERIAL.h"
- *
- * MODSERIAL pc(USBTX, USBRX); // tx, rx
- *
- * int main() {
- * pc.printf("Hello World!");
- * while(1) {
- * pc.putc(pc.getc() + 1);
- * }
- * }
- * @endcode
- *
- * Example with alternate buffer length:
- * @code
- * #include "mbed.h"
- * #include "MODSERIAL.h"
- *
- * // Make TX and RX buffers 512byes in length
- * MODSERIAL pc(USBTX, USBRX, 512); // tx, rx
- *
- * int main() {
- * pc.printf("Hello World!");
- * while(1) {
- * pc.putc(pc.getc() + 1);
- * }
- * }
- * @endcode
- *
- * Example with alternate buffer length:
- * @code
- * #include "mbed.h"
- * #include "MODSERIAL.h"
- *
- * // Make TX 1024bytes and RX 512byes in length
- * MODSERIAL pc(USBTX, USBRX, 1024, 512); // tx, rx
- *
- * int main() {
- * pc.printf("Hello World!");
- * while(1) {
- * pc.putc(pc.getc() + 1);
- * }
- * }
- * @endcode
- */
-class MODSERIAL : public Serial
-{
-public:
-
- // Allow instances of MODSERIAL_IRQ_INFO to use protected properties and methods.
- friend class MODSERIAL_IRQ_INFO;
-
- //! A copy of the Serial parity enum
- /** @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format */
- enum Parity {
- None = 0
- , Odd
- , Even
- , Forced1
- , Forced0
- };
-
- //! A copy of the Serial IrqType enum
- enum IrqType {
- RxIrq = 0
- , TxIrq
- , RxOvIrq
- , TxOvIrq
- , TxEmpty
- , RxAutoDetect
- , NumOfIrqTypes
- };
-
- //! Non-blocking functions return code.
- enum Result {
- Ok = 0 /*!< Ok. */
- , NoMemory = -1 /*!< Memory allocation failed. */
- , NoChar = -1 /*!< No character in buffer. */
- , BufferOversize = -2 /*!< Oversized buffer. */
- };
-
- /**
- * The MODSERIAL constructor is used to initialise the serial object.
- *
- * @param tx PinName of the TX pin.
- * @param rx PinName of the TX pin.
- */
- MODSERIAL(PinName tx, PinName rx, const char* name = NULL);
-
- /**
- * The MODSERIAL constructor is used to initialise the serial object.
- *
- * @param tx PinName of the TX pin.
- * @param rx PinName of the TX pin.
- * @param bufferSize Integer of the TX and RX buffer sizes.
- */
- MODSERIAL(PinName tx, PinName rx, int bufferSize, const char* name = NULL);
-
- /**
- * The MODSERIAL constructor is used to initialise the serial object.
- *
- * @param tx PinName of the TX pin.
- * @param rx PinName of the TX pin.
- * @param txBufferSize Integer of the TX buffer sizes.
- * @param rxBufferSize Integer of the RX buffer sizes.
- */
- MODSERIAL(PinName tx, PinName rx, int txBufferSize, int rxBufferSize, const char* name = NULL);
-
- virtual ~MODSERIAL();
-
- /**
- * Function: attach
- *
- * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback
- * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts
- * to enable it's buffering system. However, after the byte has been received/sent under interrupt control,
- * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not
- * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should
- * be used.
- *
- * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty,
- * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and
- * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled
- * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY
- * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character
- * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may
- * never come into play.
- *
- * @code
- * #include "mbed.h"
- * #include "MODSERIAL.h"
- *
- * DigitalOut led1(LED1);
- * DigitalOut led2(LED2);
- * DigitalOut led3(LED3);
- *
- * // To test, connect p9 to p10 as a loopback.
- * MODSERIAL pc(p9, p10);
- *
- * // This function is called when a character goes into the TX buffer.
- * void txCallback(void) {
- * led2 = !led2;
- * }
- *
- * // This function is called when a character goes into the RX buffer.
- * void rxCallback(void) {
- * led3 = !led3;
- * }
- *
- * int main() {
- * pc.baud(115200);
- * pc.attach(&txCallback, MODSERIAL::TxIrq);
- * pc.attach(&rxCallback, MODSERIAL::RxIrq);
- *
- * while(1) {
- * led1 = !led1;
- * wait(0.5);
- * pc.putc('A');
- * wait(0.5);
- * }
- * ]
- * @endcode
- *
- * @ingroup API
- * @param fptr A pointer to a void function, or 0 to set as none
- * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
- */
- void attach(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[type].attach(fptr); }
-
- /**
- * Function: attach
- *
- * The Mbed standard <a href="/handbook/Serial">Serial</a> library object allows an interrupt callback
- * to be made when a byte is received by the TX or RX UART hardware. MODSERIAL traps these interrupts
- * to enable it's buffering system. However, after the byte has been received/sent under interrupt control,
- * MODSERIAL can callback a user function as a notification of the interrupt. Note, user code should not
- * directly interact with the Uart hardware, MODSERIAL does that, instead, MODSERIAL API functions should
- * be used.
- *
- * <b>Note</b>, a character is written out then, if there is room in the TX FIFO and the TX buffer is empty,
- * putc() will put the character directly into THR (the output holding register). If the TX FIFO is full and
- * cannot accept the character, it is placed into the TX output buffer. The TX interrupts are then enabled
- * so that when the TX FIFO empties, the TX buffer is then transferred to the THR FIFO. The TxIrq will ONLY
- * be activated when this transfer of a character from BUFFER to THR FIFO takes place. If your character
- * throughput is not high bandwidth, then the 16 byte TX FIFO may be enough and the TX output buffer may
- * never come into play.
- *
- * @code
- * #include "mbed.h"
- * #include "MODSERIAL.h"
- *
- * DigitalOut led1(LED1);
- * DigitalOut led2(LED2);
- * DigitalOut led3(LED3);
- *
- * // To test, connect p9 to p10 as a loopback.
- * MODSERIAL pc(p9, p10);
- *
- * class Foo {
- * public:
- * // This method is called when a character goes into the TX buffer.
- * void txCallback(void) { led2 = !led2; }
- *
- * // This method is called when a character goes into the RX buffer.
- * void rxCallback(void) { led3 = !led3; }
- * };
- *
- * Foo foo;
- *
- * int main() {
- * pc.baud(115200);
- * pc.attach(&foo, &Foo::txCallback, MODSERIAL::TxIrq);
- * pc.attach(&foo, &Foo::rxCallback, MODSERIAL::RxIrq);
- *
- * while(1) {
- * led1 = !led1;
- * wait(0.5);
- * pc.putc('A');
- * wait(0.5);
- * }
- * ]
- * @endcode
- *
- * @ingroup API
- * @param tptr A pointer to the object to call the member function on
- * @param mptr A pointer to the member function to be called
- * @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
- */
- template<typename T>
- void attach(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) {
- if((mptr != 0) && (tptr != 0)) {
- _isr[type].attach(tptr, mptr);
- }
- }
-
- /**
- * @see attach
- * @ingroup API
- */
- void connect(void (*fptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) { _isr[RxIrq].attach(fptr); }
-
- /**
- * @see attach
- * @ingroup API
- */
- template<typename T>
- void connect(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *), IrqType type = RxIrq) {
- if((mptr != 0) && (tptr != 0)) {
- _isr[type].attach(tptr, mptr);
- }
- }
-
- /**
- * Function: writeable
- *
- * Determine if there is space available to write a byte
- *
- * @ingroup API
- * @return 1 if there is space to write a character, else 0
- */
- int writeable() { return txBufferFull() ? 0 : 1; }
-
- /**
- * Function: readable
- *
- * Determine if there is a byte available to read
- *
- * @ingroup API
- * @return 1 if there is a character available to read, else 0
- */
- int readable() { return rxBufferEmpty() ? 0 : 1; }
-
- /**
- * Function: txBufferSane
- *
- * Determine if the TX buffer has been initialized.
- *
- * @ingroup API
- * @return true if the buffer is initialized, else false
- */
- bool txBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; }
-
- /**
- * Function: rxBufferSane
- *
- * Determine if the RX buffer has been initialized.
- *
- * @ingroup API
- * @return true if the buffer is initialized, else false
- */
- bool rxBufferSane(void) { return buffer[TxIrq] != (char *)NULL ? true : false; }
-
- /**
- * Function: txBufferGetCount
- *
- * Returns how many bytes are in the TX buffer
- *
- * @ingroup API
- * @return The number of bytes in the TX buffer
- */
- int txBufferGetCount(void) { return buffer_count[TxIrq]; }
-
- /**
- * Function: rxBufferGetCount
- *
- * Returns how many bytes are in the RX buffer
- *
- * @ingroup API
- * @return The number of bytes in the RX buffer
- */
- int rxBufferGetCount(void) { return buffer_count[RxIrq]; }
-
- /**
- * Function: txBufferGetSize
- *
- * Returns the current size of the TX buffer
- *
- * @ingroup API
- * @return The length iof the TX buffer in bytes
- */
- int txBufferGetSize(int size) { return buffer_size[TxIrq]; }
-
- /**
- * Function: rxBufferGetSize
- *
- * Returns the current size of the RX buffer
- *
- * @ingroup API
- * @return The length iof the RX buffer in bytes
- */
- int rxBufferGetSize(int size) { return buffer_size[RxIrq]; }
-
- /**
- * Function: txBufferFull
- *
- * Is the TX buffer full?
- *
- * @ingroup API
- * @return true if the TX buffer is full, otherwise false
- */
- bool txBufferFull(void);
-
- /**
- * Function: rxBufferFull
- *
- * Is the RX buffer full?
- *
- * @ingroup API
- * @return true if the RX buffer is full, otherwise false
- */
- bool rxBufferFull(void);
-
- /**
- * Function: txBufferEmpty
- *
- * Is the TX buffer empty?
- *
- * @ingroup API
- * @return true if the TX buffer is empty, otherwise false
- */
- bool txBufferEmpty(void);
-
- /**
- * Function: rxBufferEmpty
- *
- * Is the RX buffer empty?
- *
- * @ingroup API
- * @return true if the RX buffer is empty, otherwise false
- */
- bool rxBufferEmpty(void);
-
- /**
- * Function: txBufferSetSize
- *
- * Change the TX buffer size.
- *
- * @see Result
- * @ingroup API
- * @param size The new TX buffer size in bytes.
- * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails.
- * @return Result Ok on success.
- */
- int txBufferSetSize(int size, bool m) { return resizeBuffer(size, TxIrq, m); }
-
- /**
- * Function: rxBufferSetSize
- *
- * Change the RX buffer size.
- *
- * @see Result
- * @ingroup API
- * @param size The new RX buffer size in bytes.
- * @param m Perform a memory sanity check. Errs the Mbed if memory alloc fails.
- * @return Result Ok on success.
- */
- int rxBufferSetSize(int size, bool m) { return resizeBuffer(size, RxIrq, m); }
-
- /**
- * Function: txBufferSetSize
- *
- * Change the TX buffer size.
- * Always performs a memory sanity check, halting the Mbed on failure.
- *
- * @see Result
- * @ingroup API
- * @param size The new TX buffer size in bytes.
- * @return Result Ok on success.
- */
- int txBufferSetSize(int size) { return resizeBuffer(size, TxIrq, true); }
-
- /**
- * Function: rxBufferSetSize
- *
- * Change the RX buffer size.
- * Always performs a memory sanity check, halting the Mbed on failure.
- *
- * @see Result
- * @ingroup API
- * @param size The new RX buffer size in bytes.
- * @return Result Ok on success.
- */
- int rxBufferSetSize(int size) { return resizeBuffer(size, RxIrq, true); }
-
- /**
- * Function: txBufferFlush
- *
- * Remove all bytes from the TX buffer.
- * @ingroup API
- */
- void txBufferFlush(void) { flushBuffer(TxIrq); }
-
- /**
- * Function: rxBufferFlush
- *
- * Remove all bytes from the RX buffer.
- * @ingroup API
- */
- void rxBufferFlush(void) { flushBuffer(RxIrq); }
-
- /**
- * Function: getcNb
- *
- * Like getc() but is non-blocking. If no bytes are in the RX buffer this
- * function returns Result::NoChar (-1)
- *
- * @ingroup API
- * @return A byte from the RX buffer or Result::NoChar (-1) if bufer empty.
- */
- int getcNb() { return __getc(false); }
-
- /**
- * Function: getc
- *
- * Overloaded version of Serial::getc()
- *
- * This function blocks (if the RX buffer is empty the function will wait for a
- * character to arrive and then return that character).
- *
- * @ingroup API
- * @return A byte from the RX buffer
- */
- int getc() { return __getc(true); }
-
- /**
- * Function: txGetLastChar
- *
- * Rteurn the last byte to pass through the TX interrupt handler.
- *
- * @ingroup MISC
- * @return The byte
- */
- char txGetLastChar(void) { return txc; }
-
- /**
- * Function: rxGetLastChar
- *
- * Return the last byte to pass through the RX interrupt handler.
- *
- * @ingroup MISC
- * @return The byte
- */
- char rxGetLastChar(void) { return rxc; }
-
- /**
- * Function: txIsBusy
- *
- * If the Uart is still actively sending characters this
- * function will return true.
- *
- * @ingroup API
- * @return bool
- */
- bool txIsBusy(void);
-
- /**
- * Function: autoDetectChar
- *
- * Set the char that, if seen incoming, invokes the AutoDetectChar callback.
- *
- * @ingroup API
- * @param int c The character to detect.
- */
- void autoDetectChar(char c) { auto_detect_char = c; }
-
- /**
- * Function: move
- *
- * Move contents of RX buffer to external buffer. Stops if "end" detected.
- *
- * @ingroup API
- * @param char *s The destination buffer address
- * @param int max The maximum number of chars to move.
- * @param char end If this char is detected stop moving.
- */
- int move(char *s, int max, char end) {
- int counter = 0;
- char c;
- while(readable()) {
- c = getc();
- if (c == end) break;
- *(s++) = c;
- counter++;
- if (counter == max) break;
- }
- return counter;
- }
-
- /**
- * Function: move (overloaded)
- *
- * Move contents of RX buffer to external buffer. Stops if auto_detect_char detected.
- *
- * @ingroup API
- * @param int max The maximum number of chars to move.
- * @param char *s The destination buffer address
- */
- int move(char *s, int max) {
- return move(s, max, auto_detect_char);
- }
-
- #if 0 // Inhereted from Serial/Stream, for documentation only
- /**
- * Function: putc
- *
- * Write a character
- * Inhereted from Serial/Stream
- *
- * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.putc
- * @ingroup API
- * @param c The character to write to the serial port
- */
- int putc(int c);
- #endif
-
- #if 0 // Inhereted from Serial/Stream, for documentation only
- /**
- * Function: printf
- *
- * Write a formated string
- * Inhereted from Serial/Stream
- *
- * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.printf
- * @ingroup API
- * @param format A printf-style format string, followed by the variables to use in formating the string.
- */
- int printf(const char* format, ...);
- #endif
-
- #if 0 // Inhereted from Serial/Stream, for documentation only
- /**
- * Function: scanf
- *
- * Read a formated string
- * Inhereted from Serial/Stream
- *
- * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.scanf
- * @ingroup API
- * @param format - A scanf-style format string, followed by the pointers to variables to store the results.
- */
- int scanf(const char* format, ...);
- #endif
-
-protected:
- /**
- * Used to pass information to callbacks.
- * @ingroup INTERNALS
- */
- MODSERIAL_IRQ_INFO callbackInfo;
-
- /**
- * Remove the last char placed into the rx buffer.
- * This is an operation that can only be performed
- * by an rxCallback function. To protect the buffers
- * this function is defined protected so that a
- * regular application cannot call it directly. It
- * can only be called by the public version within a
- * MODSERIAL_IRQ_INFO class.
- * @ingroup INTERNALS
- * @return The byte removed from the buffer.
- */
- int rxDiscardLastChar(void);
-
-private:
-
- /**
- * A pointer to the UART peripheral base address being used.
- * @ingroup INTERNALS
- */
- void *_base;
-
- /**
- * The last byte to pass through the TX IRQ handler.
- * @ingroup INTERNALS
- */
- volatile char txc;
-
- /**
- * The last byte to pass through the RX IRQ handler.
- * @ingroup INTERNALS
- */
- volatile char rxc;
-
- /**
- * Pointers to the TX and RX buffers.
- * @ingroup INTERNALS
- */
- volatile char *buffer[2];
-
- /**
- * Buffer in pointers.
- * @ingroup INTERNALS
- */
- volatile int buffer_in[2];
-
- /**
- * Buffer out pointers.
- * @ingroup INTERNALS
- */
- volatile int buffer_out[2];
-
- /**
- * Buffer lengths.
- * @ingroup INTERNALS
- */
- volatile int buffer_size[2];
-
- /**
- * Buffer content counters.
- * @ingroup INTERNALS
- */
- volatile int buffer_count[2];
-
- /**
- * Buffer overflow.
- * @ingroup INTERNALS
- */
- volatile int buffer_overflow[2];
-
- /**
- * Auto-detect character.
- * @ingroup INTERNALS
- */
- volatile char auto_detect_char;
-
- /**
- * Callback system.
- * @ingroup INTERNALS
- */
- MODSERIAL_callback _isr[NumOfIrqTypes];
-
- /**
- * TX Interrupt Service Routine.
- * @ingroup INTERNALS
- */
- void isr_tx(bool doCallback);
-
- /**
- * TX Interrupt Service Routine stub version.
- * @ingroup INTERNALS
- */
- void isr_tx(void) { isr_tx(true); }
-
-
- /**
- * RX Interrupt Service Routine.
- * @ingroup INTERNALS
- */
- void isr_rx(void);
-
- /**
- * Disable the interrupts for this Uart.
- * @ingroup INTERNALS
- */
- void disableIrq(void);
-
- /**
- * Enable the interrupts for this Uart.
- * @ingroup INTERNALS
- */
- void enableIrq(void);
-
- /**
- * Get a character from the RX buffer
- * @ingroup INTERNALS
- * @param bool True to block (wait for input)
- * @return A byte from the buffer.
- */
- int __getc(bool);
-
- /**
- * Put a character from the TX buffer
- * @ingroup INTERNALS
- * @param bool True to block (wait for space in the TX buffer if full)
- * @return 0 on success
- */
- int __putc(int c, bool);
-
- /**
- * Function: _putc
- * Overloaded virtual function.
- */
- virtual int _putc(int c) { return __putc(c, true); }
-
- /**
- * Function: _getc
- * Overloaded virtual function.
- */
- virtual int _getc() { return __getc(true); }
-
- /**
- * Function: init
- * Initialize the MODSERIAL object
- * @ingroup INTERNALS
- */
- void init(int txSize, int rxSize, PinName rx);
-
- /**
- * Function: flushBuffer
- * @ingroup INTERNALS
- */
- void flushBuffer(IrqType type);
-
- /**
- * Function: resizeBuffer
- * @ingroup INTERNALS
- */
- int resizeBuffer(int size, IrqType type = RxIrq, bool memory_check = true);
-
- /**
- * Function: downSizeBuffer
- * @ingroup INTERNALS
- */
- int downSizeBuffer(int size, IrqType type, bool memory_check);
-
- /**
- * Function: upSizeBuffer
- * @ingroup INTERNALS
- */
- int upSizeBuffer(int size, IrqType type, bool memory_check);
-
- /*
- * If MODDMA is available the compile in code to handle sending
- * an arbitary char buffer. Note, the parts before teh #ifdef
- * are declared so that MODSERIAL can access then even if MODDMA
- * isn't avaiable. Since MODDMA.h is only available at this point
- * all DMA functionality must be declared inline in the class
- * definition.
- */
-public:
-
- int dmaSendChannel;
- void *moddma_p;
-
-#ifdef MODDMA_H
-
- MODDMA_Config *config;
-
- /**
- * Set the "void pointer" moddma_p to be a pointer to a
- * MODDMA controller class instance. Used to manage the
- * data transfer of DMA configurations.
- *
- * @ingroup API
- * @param p A pointer to "the" instance of MODDMA.
- */
- void MODDMA(MODDMA *p) { moddma_p = p; }
-
- /**
- * Send a char buffer to the Uarts TX system
- * using DMA. This blocks regular library
- * sending.
- *
- * @param buffer A char buffer of bytes to send.
- * @param len The length of the buffer to send.
- * @param dmaChannel The DMA channel to use, defaults to 7
- * @return MODDMA::Status MODDMA::ok if all went ok
- */
- int dmaSend(char *buffer, int len, int dmaChannel = 7)
- {
- if (moddma_p == (void *)NULL) return -2;
- class MODDMA *dma = (class MODDMA *)moddma_p;
-
- dmaSendChannel = dmaChannel & 0x7;
-
- uint32_t conn = MODDMA::UART0_Tx;
- switch(_serial.index) {
- case 0: conn = MODDMA::UART0_Tx; break;
- case 1: conn = MODDMA::UART1_Tx; break;
- case 2: conn = MODDMA::UART2_Tx; break;
- case 3: conn = MODDMA::UART3_Tx; break;
- }
-
- config = new MODDMA_Config;
- config
- ->channelNum ( (MODDMA::CHANNELS)(dmaSendChannel & 0x7) )
- ->srcMemAddr ( (uint32_t) buffer )
- ->transferSize ( len )
- ->transferType ( MODDMA::m2p )
- ->dstConn ( conn )
- ->attach_tc ( this, &MODSERIAL::dmaSendCallback )
- ->attach_err ( this, &MODSERIAL::dmaSendCallback )
- ; // config end
-
- // Setup the configuration.
- if (dma->Setup(config) == 0) {
- return -1;
- }
-
- //dma.Enable( MODDMA::Channel_0 );
- dma->Enable( config->channelNum() );
- return MODDMA::Ok;
- }
-
- /**
- * Attach a callback to the DMA completion.
- *
- * @ingroup API
- * @param fptr A function pointer to call
- * @return this
- */
- void attach_dmaSendComplete(void (*fptr)(MODSERIAL_IRQ_INFO *)) {
- _isrDmaSendComplete.attach(fptr);
- }
-
- /**
- * Attach a callback to the DMA completion.
- *
- * @ingroup API
- * @param tptr A template pointer to the calling object
- * @param mptr A method pointer within the object to call.
- * @return this
- */
- template<typename T>
- void attach_dmaSendComplete(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *)) {
- if((mptr != NULL) && (tptr != NULL)) {
- _isrDmaSendComplete.attach(tptr, mptr);
- }
- }
-
- MODSERIAL_callback _isrDmaSendComplete;
-
-protected:
- /**
- * Callback for dmaSend().
- */
- void dmaSendCallback(void)
- {
- if (moddma_p == (void *)NULL) return;
- class MODDMA *dma = (class MODDMA *)moddma_p;
-
- MODDMA_Config *config = dma->getConfig();
- dma->haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
- dma->Disable( (MODDMA::CHANNELS)config->channelNum() );
- if (dma->irqType() == MODDMA::TcIrq) dma->clearTcIrq();
- if (dma->irqType() == MODDMA::ErrIrq) dma->clearErrIrq();
- dmaSendChannel = -1;
- _isrDmaSendComplete.call(&this->callbackInfo);
- delete(config);
- }
-
-#endif // MODDMA_H
-
-};
-
-}; // namespace AjK ends
-
-using namespace AjK;
-
-#endif
--- a/Libs/MODSERIAL/MODSERIAL_IRQ_INFO.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
- @file MODSERIAL_IRQ_INFO.cpp
- @author Andy Kirkham
-*/
-
-#include "MODSERIAL.h"
-
-namespace AjK {
-
-int
-MODSERIAL_IRQ_INFO::rxDiscardLastChar(void)
-{
- if (!serial) return -1;
-
- return serial->rxDiscardLastChar();
-}
-
-}; // namespace AjK ends
--- a/Libs/MODSERIAL/PUTC.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-namespace AjK {
-
-int
-MODSERIAL::__putc(int c, bool block) {
-
- // If no buffer is in use fall back to standard TX FIFO usage.
- // Note, we must block in this case and ignore bool "block"
- // so as to maintain compat with Mbed Serial.
- if (buffer[TxIrq] == (char *)NULL || buffer_size[TxIrq] == 0) {
- while (! MODSERIAL_THR_HAS_SPACE) ; // Wait for space in the TX FIFO.
- _THR = (uint32_t)c;
- return 0;
- }
-
- if ( MODSERIAL_THR_HAS_SPACE && MODSERIAL_TX_BUFFER_EMPTY && dmaSendChannel == -1 ) {
- _THR = (uint32_t)c;
- }
- else {
- if (block) {
- uint32_t ier = _IER; _IER = 1;
- while ( MODSERIAL_TX_BUFFER_FULL ) { // Blocks!
- // If putc() is called from an ISR then we are stuffed
- // because in an ISR no bytes from the TX buffer will
- // get transferred to teh TX FIFOs while we block here.
- // So, to work around this, instead of sitting in a
- // loop waiting for space in the TX buffer (which will
- // never happen in IRQ context), check to see if the
- // TX FIFO has space available to move bytes from the
- // TX buffer to TX FIFO to make space. The easiest way
- // to do this is to poll the isr_tx() function while we
- // are blocking.
- isr_tx(false);
- }
- _IER = ier;
- }
- else if( MODSERIAL_TX_BUFFER_FULL ) {
- buffer_overflow[TxIrq] = c; // Oh dear, no room in buffer.
- _isr[TxOvIrq].call(&this->callbackInfo);
- return -1;
- }
- _IER &= ~2;
- buffer[TxIrq][buffer_in[TxIrq]] = c;
- __disable_irq();
- buffer_count[TxIrq]++;
- __enable_irq();
- buffer_in[TxIrq]++;
- if (buffer_in[TxIrq] >= buffer_size[TxIrq]) {
- buffer_in[TxIrq] = 0;
- }
- _IER |= 2;
- }
-
- return 0;
-}
-
-}; // namespace AjK ends
--- a/Libs/MODSERIAL/RESIZE.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- Copyright (c) 2010 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-*/
-
-#include "MODSERIAL.h"
-#include "MACROS.h"
-
-namespace AjK {
-
-int
-MODSERIAL::resizeBuffer(int size, IrqType type, bool memory_check)
-{
- int rval = Ok;
-
- // If the requested size is the same as the current size there's nothing to do,
- // just continue to use the same buffer as it's fine as it is.
- if (buffer_size[type] == size) return rval;
-
- // Make sure the ISR cannot use the buffers while we are manipulating them.
- disableIrq();
-
- // If the requested buffer size is larger than the current size,
- // attempt to create a new buffer and use it.
- if (buffer_size[type] < size) {
- rval = upSizeBuffer(size, type, memory_check);
- }
- else if (buffer_size[type] > size) {
- rval = downSizeBuffer(size, type, memory_check);
- }
-
- // Start the ISR system again with the new buffers.
- enableIrq();
-
- return rval;
-}
-
-int
-MODSERIAL::downSizeBuffer(int size, IrqType type, bool memory_check)
-{
- if (size >= buffer_count[type]) {
- return BufferOversize;
- }
-
- char *s = (char *)malloc(size);
-
- if (s == (char *)NULL) {
- if (memory_check) {
- error("Failed to allocate memory for %s buffer", type == TxIrq ? "TX" : "RX");
- }
- return NoMemory;
- }
-
- int c, new_in = 0;
-
- do {
- c = __getc(false);
- if (c != -1) s[new_in++] = (char)c;
- if (new_in >= size) new_in = 0;
- }
- while (c != -1);
-
- free((char *)buffer[type]);
- buffer[type] = s;
- buffer_in[type] = new_in;
- buffer_out[type] = 0;
- return Ok;
-}
-
-int
-MODSERIAL::upSizeBuffer(int size, IrqType type, bool memory_check)
-{
- char *s = (char *)malloc(size);
-
- if (s == (char *)NULL) {
- if (memory_check) {
- error("Failed to allocate memory for %s buffer", type == TxIrq ? "TX" : "RX");
- }
- return NoMemory;
- }
-
- if (buffer_count[type] == 0) { // Current buffer empty?
- free((char *)buffer[type]);
- buffer[type] = s;
- buffer_in[type] = 0;
- buffer_out[type] = 0;
- }
- else { // Copy the current contents into the new buffer.
- int c, new_in = 0;
- do {
- c = __getc(false);
- if (c != -1) s[new_in++] = (char)c;
- if (new_in >= size) new_in = 0; // Shouldn't happen, but be sure.
- }
- while (c != -1);
- free((char *)buffer[type]);
- buffer[type] = s;
- buffer_in[type] = new_in;
- buffer_out[type] = 0;
- }
-
- buffer_size[type] = size;
- return Ok;
-}
-
-}; // namespace AjK ends
--- a/Libs/MODSERIAL/example1.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-#ifdef COMPILE_EXAMPLE1_CODE_MODSERIAL
-
-/*
- * To run this test program, link p9 to p10 so the Serial loops
- * back and receives characters it sends.
- */
-
-#include "mbed.h"
-#include "MODSERIAL.h"
-
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-
-MODSERIAL pc(USBTX, USBRX);
-
-/*
- * As experiement, you can define MODSERIAL as show here and see what
- * effects it has on the LEDs.
- *
- * MODSERIAL uart(TX_PIN, RX_PIN, 512);
- * With this, the 512 characters sent can straight into the buffer
- * vary quickly. This means LED1 is only on briefly as the TX buffer
- * fills.
- *
- * MODSERIAL uart(TX_PIN, RX_PIN, 32);
- * With this, the buffer is smaller than the default 256 bytes and
- * therefore LED1 stays on much longer while the system waits for
- * room in the TX buffer.
- */
-MODSERIAL uart(TX_PIN, RX_PIN);
-
-// This function is called when a character goes from the TX buffer
-// to the Uart THR FIFO register.
-void txCallback(MODSERIAL_IRQ_INFO *q) {
- led2 = !led2;
-}
-
-// This function is called when TX buffer goes empty
-void txEmpty(MODSERIAL_IRQ_INFO *q) {
- led2 = 0;
- pc.puts(" Done. ");
-}
-
-// This function is called when a character goes into the RX buffer.
-void rxCallback(MODSERIAL_IRQ_INFO *q) {
- led3 = !led3;
- pc.putc(uart.getc());
-}
-
-int main() {
- int c = 'A';
-
- // Ensure the baud rate for the PC "USB" serial is much
- // higher than "uart" baud rate below.
- pc.baud(PC_BAUD);
-
- // Use a deliberatly slow baud to fill up the TX buffer
- uart.baud(1200);
-
- uart.attach(&txCallback, MODSERIAL::TxIrq);
- uart.attach(&rxCallback, MODSERIAL::RxIrq);
- uart.attach(&txEmpty, MODSERIAL::TxEmpty);
-
- // Loop sending characters. We send 512
- // which is twice the default TX/RX buffer size.
-
- led1 = 1; // Show start of sending with LED1.
-
- for (int loop = 0; loop < 512; loop++) {
- uart.printf("%c", c);
- c++;
- if (c > 'Z') c = 'A';
- }
-
- led1 = 0; // Show the end of sending by switching off LED1.
-
- // End program. Flash LED4. Notice how LED 2 and 3 continue
- // to flash for a short period while the interrupt system
- // continues to send the characters left in the TX buffer.
-
- while(1) {
- led4 = !led4;
- wait(0.25);
- }
-}
-
-/*
- * Notes. Here is the sort of output you can expect on your PC/Mac/Linux host
- * machine that is connected to the "pc" USB serial port.
- *
- * ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUV
- * WXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQR
- * STUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMN
- * OPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJ
- * KLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEF
- * GHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZAB
- * CDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ Done. R
- *
- * Of interest is that last "R" character after the system has said "Done."
- * This comes from the fact that the TxEmpty callback is made when the TX buffer
- * becomes empty. MODSERIAL makes use of the fact that the Uarts built into the
- * LPC17xx device use a 16 byte FIFO on both RX and TX channels. This means that
- * when the TxEmpty callback is made, the TX buffer is empty, but that just means
- * the "last few characters" were written to the TX FIFO. So although the TX
- * buffer has gone empty, the Uart's transmit system is still sending any remaining
- * characters from it's TX FIFO. If you want to be truely sure all the characters
- * you have sent have left the Mbed then call txIsBusy(); This function will
- * return true if characters are still being sent. If it returns false after
- * the Tx buffer is empty then all your characters have been sent.
- *
- * In a similar way, when characters are received into the RX FIFO, the entire
- * FIFO contents is moved to the RX buffer, assuming there is room left in the
- * RX buffer. If there is not, any remaining characters are left in the RX FIFO
- * and will be moved to the RX buffer on the next interrupt or when the running
- * program removes a character(s) from the RX buffer with the getc() method.
- */
-
-#endif
--- a/Libs/MODSERIAL/example2.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-/*
- Copyright (c) 2011 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
- @file example2.cpp
- @purpose Demos a simple messaging system.
- @version see ChangeLog.c
- @date Jan 2011
- @author Andy Kirkham
-*/
-
-/*
- This example demostrates a simple "messaging" system. You can use it with
- a terminal program to test it out or write a cusom C#/C++/VB/etc program
- to read and write messages to or from the Mbed. The default baud rate in
- this example is 115200.
-
- In this example, the LEDs are controlled and pins p21 to p24 are set as
- InterruptIn and send messages out when their value changes.
-
- To use, hook up the MBed USB and open your fav terminal. All messages
- end with the \n character, don't forget to hit carriage return!.
- As an example:-
-
- to switch on LED1 send LED1:1\n, off is LED1:0\n and toggle is LED1:2\n
- to switch on LED2 send LED2:1\n, off is LED2:0\n and toggle is LED2:2\n
- to switch on LED3 send LED3:1\n, off is LED3:0\n and toggle is LED3:2\n
- to switch on LED4 send LED4:1\n, off is LED4:0\n and toggle is LED4:2\n
-
- When a pin change on p21 to p24 happens, a message is sent. As an example
- when p21 goes low PIN21:0\n is sent, when goes high PIN21:1\n is sent.
-
- Note, the InterruptIn pins p21 to p24 are setup to have pullups. This means
- they are high. To activate them use a wire to short the pin to 0volts.
-
- If you find that p21 to p24 sent a lot of on/off/on/off then it's probably
- due to "bounce". If you are connecting a mechanical switch to a pin you
- may prefer to use the PinDetect library rather than using InterruptIn.
- @see http://mbed.org/users/AjK/libraries/PinDetect/latest
-
- One point you may notice. Incoming messages are processed via main()'s
- while(1) loop whereas pin changes have their messages directly sent.
- The reason for this is when MODSERIAL makes callbacks to your application
- it is in "interrupt context". And one thing you want to avoid is spending
- lots of CPU time in that context. So, the callback moves the message from
- the input buffer to a local holding buffer and it then sets a bool flag
- which tells main()'s while(1) loop to process that buffer. This means the
- time spent doing the real incoming message handing is within your program
- and not within MODSERIAL's interrupt context. So you may ask, why not do
- the same for out going messages? Well, because MODSERIAL output buffers
- all your sent content then sending chars is very fast. MODSERIAL handles
- all the nitty gritty bits for you. You can just send. This example uses
- puts() to send the message. If you can, always try and use sprintf()+puts()
- rathe than printf(), printf() is known to often screw things up when used
- within an interrupt context. Better still, just use puts() and do away
- with any of the crappy ?printf() calls if possible. But I found the code
- below to work fine even at 115200baud.
-
-*/
-
-
-#ifdef COMPILE_EXAMPLE1_CODE_MODSERIAL
-
-#include "mbed.h"
-#include "MODSERIAL.h"
-
-#define MESSAGE_BUFFER_SIZE 32
-
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-
-InterruptIn P21(p21);
-InterruptIn P22(p22);
-InterruptIn P23(p23);
-InterruptIn P24(p24);
-
-MODSERIAL messageSystem(USBTX, USBRX);
-
-char messageBufferIncoming[MESSAGE_BUFFER_SIZE];
-char messageBufferOutgoing[MESSAGE_BUFFER_SIZE];
-bool messageReceived;
-
-void messageReceive(MODSERIAL_IRQ_INFO *q) {
- MODSERIAL *sys = q->serial;
- sys->move(messageBufferIncoming, MESSAGE_BUFFER_SIZE);
- messageReceived = true;
- return 0;
-}
-
-void messageProcess(void) {
- if (!strncmp(messageBufferIncoming, "LED1:1", sizeof("LED1:1")-1)) led1 = 1;
- else if (!strncmp(messageBufferIncoming, "LED1:0", sizeof("LED1:0")-1)) led1 = 0;
- else if (!strncmp(messageBufferIncoming, "LED1:2", sizeof("LED1:2")-1)) led1 = !led1;
-
- else if (!strncmp(messageBufferIncoming, "LED2:1", sizeof("LED2:1")-1)) led2 = 1;
- else if (!strncmp(messageBufferIncoming, "LED2:0", sizeof("LED2:0")-1)) led2 = 0;
- else if (!strncmp(messageBufferIncoming, "LED2:2", sizeof("LED2:2")-1)) led2 = !led2;
-
- else if (!strncmp(messageBufferIncoming, "LED3:1", sizeof("LED3:1")-1)) led3 = 1;
- else if (!strncmp(messageBufferIncoming, "LED3:0", sizeof("LED3:0")-1)) led3 = 0;
- else if (!strncmp(messageBufferIncoming, "LED3:2", sizeof("LED3:2")-1)) led3 = !led3;
-
- else if (!strncmp(messageBufferIncoming, "LED4:1", sizeof("LED4:1")-1)) led4 = 1;
- else if (!strncmp(messageBufferIncoming, "LED4:0", sizeof("LED4:0")-1)) led4 = 0;
- else if (!strncmp(messageBufferIncoming, "LED4:2", sizeof("LED4:2")-1)) led4 = !led4;
-
- messageReceived = false;
-}
-
-#define PIN_MESSAGE_SEND(x,y) \
- sprintf(messageBufferOutgoing,"PIN%02d:%d\n",x,y);\
- messageSystem.puts(messageBufferOutgoing);
-
-void pin21Rise(void) { PIN_MESSAGE_SEND(21, 1); }
-void pin21Fall(void) { PIN_MESSAGE_SEND(21, 0); }
-void pin22Rise(void) { PIN_MESSAGE_SEND(22, 1); }
-void pin22Fall(void) { PIN_MESSAGE_SEND(22, 0); }
-void pin23Rise(void) { PIN_MESSAGE_SEND(23, 1); }
-void pin23Fall(void) { PIN_MESSAGE_SEND(23, 0); }
-void pin24Rise(void) { PIN_MESSAGE_SEND(24, 1); }
-void pin24Fall(void) { PIN_MESSAGE_SEND(24, 0); }
-
-int main() {
-
- messageReceived = false;
- messageSystem.baud(115200);
- messageSystem.attach(&messageReceive, MODSERIAL::RxAutoDetect);
- messageSystem.autoDetectChar('\n');
-
- // Enable pullup resistors on pins.
- P21.mode(PullUp); P22.mode(PullUp); P23.mode(PullUp); P24.mode(PullUp);
-
- // Fix Mbed library bug, see http://mbed.org/forum/bugs-suggestions/topic/1498
- LPC_GPIOINT->IO2IntClr = (1UL << 5) | (1UL << 4) | (1UL << 3) | (1UL << 2);
-
- // Attach InterruptIn pin callbacks.
- P21.rise(&pin21Rise); P21.fall(&pin21Fall);
- P22.rise(&pin22Rise); P22.fall(&pin22Fall);
- P23.rise(&pin23Rise); P23.fall(&pin23Fall);
- P24.rise(&pin24Rise); P24.fall(&pin24Fall);
-
- while(1) {
- // Process incoming messages.
- if (messageReceived) messageProcess();
- }
-}
-
-#endif
--- a/Libs/MODSERIAL/example3a.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- Copyright (c) 2011 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
- @file example3.cpp
- @purpose Demos a simple filter.
- @version see ChangeLog.c
- @author Andy Kirkham
-*/
-
-/*
- This example shows how to use the new callback system. In the old system
- Mbed's FunctionPointer[1] type was used to store abd make calls to callbacks.
- However, that limits the callback function prototype to void func(void);
- which means we cannot pass parameters.
-
- This latest version of MODSERIAL now uses its own callback object. This allows
- the passing of a pointer to a class that holds information about the MODSERIAL
- object making the callback. As of version 1.18 one critcal piece of information
- is passed, a pointer to the MODSERIAL object. This allows callbacks to use the
- MODSERIAL functions and data.
-
- Additionally, since MODSERIAL and the callback parameter class MODSERIAL_IRQ_INFO
- are friends, MODSERIAL_IRQ_INFO can access the protected functions of MODSERIAL.
- This is used to ensure functions that can only be called during a callback
- can be invoked from a callback.
-
- [1] http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h
-*/
-
-#ifdef COMPILE_EXAMPLE3_CODE_MODSERIAL
-
-#include "mbed.h"
-#include "MODSERIAL.h"
-
-DigitalOut led1(LED1);
-
-MODSERIAL pc(USBTX, USBRX);
-
-// The following callback is defined in example3b.cpp
-//! @see example3b.cpp
-void rxCallback(MODSERIAL_IRQ_INFO *info);
-
-int main() {
-
- int life_counter = 0;
-
- pc.baud(115200);
-
- pc.attach(&rxCallback, MODSERIAL::RxIrq);
-
- while(1) {
- // Echo back any chars we get except 'A' which is filtered by the rxCallback.
- if (pc.readable()) {
- pc.putc(pc.getc());
- }
-
- // Toggle LED1 every so often to show we are alive.
- if (life_counter++ == 1000000) {
- life_counter = 0;
- led1 = !led1;
- }
- }
-}
-
-#endif
--- a/Libs/MODSERIAL/example3b.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- Copyright (c) 2011 Andy Kirkham
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
-
- @file example3b.cpp
- @purpose Demos a simple filter.
- @version see ChangeLog.c
- @author Andy Kirkham
-*/
-
-/*
- This example shows how to use the new callback system. In the old system
- Mbed's FunctionPointer[1] type was used to store abd make calls to callbacks.
- However, that limits the callback function prototype to void func(void);
- which means we cannot pass parameters.
-
- This latest version of MODSERIAL now uses its own callback object. This allows
- the passing of a pointer to a class that holds information about the MODSERIAL
- object making the callback. As of version 1.18 one critcal piece of information
- is passed, a pointer to the MODSERIAL object. This allows callbacks to use the
- MODSERIAL functions and data.
-
- Additionally, since MODSERIAL and the callback parameter class MODSERIAL_IRQ_INFO
- are friends, MODSERIAL_IRQ_INFO can access the protected functions of MODSERIAL.
- This is used to ensure functions that can only be called during a callback
- can be invoked from a callback.
-
- [1] http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h
-*/
-
-
-#ifdef COMPILE_EXAMPLE3_CODE_MODSERIAL
-
-#include "mbed.h"
-#include "MODSERIAL.h"
-
-void rxCallback(MODSERIAL_IRQ_INFO *info) {
-
- // Get the pointer to our MODSERIAL object that invoked this callback.
- MODSERIAL *pc = info->serial;
-
- // info->serial points at the MODSERIAL instance so we can use it to call
- // any of the public MODSERIAL functions that are normally available. So
- // there's now no need to use the global version (pc in our case) inside
- // callback functions.
- char c = pc->rxGetLastChar(); // Where local pc variable is a pointer to the global MODSERIAL pc object.
-
- // The following is rather daft but demos the point.
- // Don't allow the letter "A" go into the RX buffer.
- // Basically acts as a filter to remove the letter "A"
- // if it goes into the RX buffer.
- if (c == 'A') {
- // Note, we call the MODSERIAL_IRQ_INFO::rxDiscardLastChar() public function which
- // is permitted access to the protected version of MODSERIAL::rxDiscardLastChar()
- // within MODSERIAL (because they are friends). This ensures rxDiscardLastChar()
- // can only be called within an rxCallback function.
- info->rxDiscardLastChar();
- }
-}
-
-#endif
--- a/Libs/MODSERIAL/example_dma.cpp Sun Nov 16 02:43:58 2014 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-#ifdef COMPILE_EXAMPLE_CODE_MODSERIAL_MODDMA
-
-/*
- * To run this test program, link p9 to p10 so the Serial loops
- * back and receives characters it sends.
- */
-
-#include "mbed.h"
-
-/* Note, this example requires that you also import into the Mbed
- compiler the MODDMA project as well as MODSERIAL
- http://mbed.org/users/AjK/libraries/MODDMA/latest
- MODDMA.h MUST come before MODSERIAL.h */
-#include "MODDMA.h" // <--- Declare first
-#include "MODSERIAL.h" // Flollowed by MODSERIAL
-
-DigitalOut led1(LED1);
-DigitalOut led2(LED2);
-DigitalOut led3(LED3);
-DigitalOut led4(LED4);
-
-MODSERIAL pc(USBTX, USBRX);
-
-/*
- * As experiement, you can define MODSERIAL as show here and see what
- * effects it has on the LEDs.
- *
- * MODSERIAL uart(TX_PIN, RX_PIN, 512);
- * With this, the 512 characters sent can straight into the buffer
- * vary quickly. This means LED1 is only on briefly as the TX buffer
- * fills.
- *
- * MODSERIAL uart(TX_PIN, RX_PIN, 32);
- * With this, the buffer is smaller than the default 256 bytes and
- * therefore LED1 stays on much longer while the system waits for
- * room in the TX buffer.
- */
-MODSERIAL uart(TX_PIN, RX_PIN);
-
-MODDMA dma;
-
-// This function is called when a character goes from the TX buffer
-// to the Uart THR FIFO register.
-void txCallback(void) {
- led2 = !led2;
-}
-
-// This function is called when TX buffer goes empty
-void txEmpty(void) {
- led2 = 0;
- pc.puts(" Done. ");
-}
-
-void dmaComplete(void) {
- led1 = 1;
-}
-
-// This function is called when a character goes into the RX buffer.
-void rxCallback(void) {
- led3 = !led3;
- pc.putc(uart.getc());
-}
-
-int main() {
- char s1[] = " *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* ";
- int c = 'A';
-
- // Tell MODSERIAL where the MODDMA controller is.
- pc.MODDMA( &dma );
-
- // Ensure the baud rate for the PC "USB" serial is much
- // higher than "uart" baud rate below.
- pc.baud( PC_BAUD );
-
- // Use a deliberatly slow baud to fill up the TX buffer
- uart.baud(1200);
-
- uart.attach( &txCallback, MODSERIAL::TxIrq );
- uart.attach( &rxCallback, MODSERIAL::RxIrq );
- uart.attach( &txEmpty, MODSERIAL::TxEmpty );
-
- // Loop sending characters. We send 512
- // which is twice the default TX/RX buffer size.
-
- led1 = 0;
-
- // Send the buffer s using DMA channel 7
- pc.attach_dmaSendComplete( &dmaComplete );
- pc.dmaSend( s1, sizeof(s1), MODDMA::Channel_7 );
-
- for (int loop = 0; loop < 512; loop++) {
- uart.printf("%c", c);
- c++;
- if (c > 'Z') c = 'A';
- }
-
- led1 = 0; // Show the end of sending by switching off LED1.
-
- // End program. Flash LED4. Notice how LED 2 and 3 continue
- // to flash for a short period while the interrupt system
- // continues to send the characters left in the TX buffer.
-
- while(1) {
- led4 = !led4;
- wait(0.25);
- }
-}
-
-/*
- * Notes. Here is the sort of output you can expect on your PC/Mac/Linux host
- * machine that is connected to the "pc" USB serial port.
- *
- * *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* ABCDEFGHIJKLMNOPQRSTUVWXYZABCDE
- * FGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZA
- * BCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW
- * XYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRS
- * TUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNO
- * PQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJK
- * LMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFG
- * HIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ Done. R
- *
- * Note how the DMA blocks the TX buffer sending under standard interrupt control.
- * Not until the DMA transfer is complete will "normal" buffered TX sending resume.
- *
- * Of interest is that last "R" character after the system has said "Done."
- * This comes from the fact that the TxEmpty callback is made when the TX buffer
- * becomes empty. MODSERIAL makes use of the fact that the Uarts built into the
- * LPC17xx device use a 16 byte FIFO on both RX and TX channels. This means that
- * when the TxEmpty callback is made, the TX buffer is empty, but that just means
- * the "last few characters" were written to the TX FIFO. So although the TX
- * buffer has gone empty, the Uart's transmit system is still sending any remaining
- * characters from it's TX FIFO. If you want to be truely sure all the characters
- * you have sent have left the Mbed then call txIsBusy(); This function will
- * return true if characters are still being sent. If it returns false after
- * the Tx buffer is empty then all your characters have been sent.
- *
- * In a similar way, when characters are received into the RX FIFO, the entire
- * FIFO contents is moved to the RX buffer, assuming there is room left in the
- * RX buffer. If there is not, any remaining characters are left in the RX FIFO
- * and will be moved to the RX buffer on the next interrupt or when the running
- * program removes a character(s) from the RX buffer with the getc() method.
- */
-
-#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/XbeeManager/CAN-xbee/CAN-xbee.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -0,0 +1,120 @@
+#include "CAN-xbee.h"
+
+CANxbee::CANxbee(PinName tx, PinName rx, int _baud, int txSize, int rxSize) : serial(tx, rx, txSize, rxSize) {
+ serial.baud(_baud);
+ rx_i = 0;
+ rxBuff[0] = 0;
+ building = false;
+}
+
+// Send a CAN message, first reformat it into a char array, then send over Xbees
+bool CANxbee::send(CANMessage &msg) {
+ char buff[14]; // Build the string-ified CAN message here
+ int size;
+
+ buff[0] = 'C';
+ int i;
+ if (msg.format == 0) { // Standard, 11-bit ID
+ buff[1] = (0 << 0) | (msg.type << 1) | ((msg.len & 0xf) << 2);
+ buff[2] = msg.id & 0xFF; // Lower byte of ID
+ buff[3] = (msg.id & 0x7FF) >> 8;
+ for (i = 0; (i < msg.len) && (i < 8); i++) {
+ buff[i+4] = msg.data[i]; // Get data bytes
+ }
+ buff[i+4] = '\n'; // Terminate message
+ size = i+4+1;
+
+ } else if (msg.format == 1) { // Extended, 29-bit ID
+ buff[1] = (1 << 0) | (msg.type << 1) | ((msg.len & 0xf) << 2);
+ buff[2] = msg.id & 0x000000FF; // Lower byte of ID
+ buff[3] = msg.id & 0x0000FF00 >> 8;
+ buff[4] = msg.id & 0x00FF0000 >> 16;
+ buff[5] = msg.id & 0x1F000000 >> 24;
+ for (i = 0; (i < msg.len) && (i < 8); i++) {
+ buff[i+6] = msg.data[i]; // Get data bytes
+ }
+ buff[i+6] = '\n'; // Terminate message
+ size = i+6+1;
+ } else return false; // Bad message
+
+ bool success=false;
+
+ // Begin thread-safe section
+ __disable_irq();
+
+ // Check if enough spaces in buffer
+ if ((serial.txBufferGetSize(0) - serial.txBufferGetCount()) >= size) {
+ for (int i = 0; i < size; i++) serial.putc(buff[i]); // Send the message out
+ success = true;
+ }
+
+ // End thread-safe section
+ __enable_irq();
+
+ return success;
+}
+
+// Continuously call this function in main program, when it returns true, it holds a newly received CAN message that came via Xbee
+bool CANxbee::receive(CANMessage &msg) {
+ int newChar = serial.getcNb();
+ if (newChar == -1) return false; // No new char
+ char c = newChar & 0xFF; // Cast to char
+ bool process=false;
+
+ char len=0;
+ // Listen for a 'C', start of new message
+ if (c == 'C' && !building) {
+ rxBuff[rx_i] = 'C';
+ rx_i++;
+ building = true; // Now building a string
+ return false;
+ }
+ // Keep building a new message until too big or encounter '\n'
+ if (building) {
+ rxBuff[rx_i] = c;
+ rx_i++;
+ if (c == '\n') { // Newline! process this string
+ process = true;
+ building = false; // Reset to keep capturing on next call
+ len = rx_i;
+ rx_i = 0;
+ }
+ else if (rx_i >= sizeof(rxBuff)) { // Too big, bad string
+ rx_i = 0;
+ building = false;
+ return false;
+ }
+ }
+ if (!process) return false;
+
+ // A string is ready, process it here
+ if (rxBuff[0] != 'C') return false; // No start char, not valid
+
+ // Extract the data from the header byte
+ bool extended = rxBuff[1] & 1;
+ bool rtr = rxBuff[1] & 2;
+ char DLC = rxBuff[1] >> 2;
+ int id=0;
+ if (DLC > 8) return false; // Bad DLC
+ if (!extended) { // Standard ID
+ if (len > 12 || len < 5) return false; // Too big/too small for standard size
+ if (rxBuff[3] & 0x7 != rxBuff[3]) return false; // Last byte of ID bad
+ if (len != 5 + DLC) return false; // Improper number of bytes
+ id = rxBuff[2] | (rxBuff[3] << 8); // Build the ID
+ for (int i = 0; i < DLC; i++) msg.data[i] = rxBuff[i+4]; // Build the data array
+
+ } else { // Extended ID
+ if (len > 14 || len < 7) return false; // Too big/too small for extended size
+ if (rxBuff[5] & 0x1F != rxBuff[5]) return false; // Last byte of ID bad
+ if (len != 7 + DLC) return false; // Improper number of bytes
+ id = rxBuff[2] | (rxBuff[3] << 8) | (rxBuff[4] << 16) | (rxBuff[5] << 24); // Build the ID
+ for (int i = 0; i < DLC; i++) msg.data[i] = rxBuff[i+6]; // Build the data array
+ }
+ msg.id = id;
+ msg.len = DLC;
+ if (rtr) msg.type = CANRemote;
+ else msg.type = CANData;
+ if (extended) msg.format = CANExtended;
+ else msg.format = CANStandard;
+ return true; // Successfully parsed, passed all checks, arguement was updated
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/XbeeManager/CAN-xbee/CAN-xbee.h Tue Jan 06 20:45:26 2015 +0000
@@ -0,0 +1,32 @@
+#ifndef CAN_XBEE_H
+#define CAN_XBEE_H
+
+#include "mbed.h"
+#include "MODSERIAL.h"
+
+// The string format of a CAN message shall be:
+// char0: Letter 'C' - start of a CAN message
+// char1: message type = (extended?1:0 << 0) | (RTR?1:0 << 1) | (DLC << 2)
+// char1: ID lower byte
+// char2: ID upper byte
+// char3-10: data bytes (lowest first)
+// lastChar: \n - newline = end of message
+//
+// Extended ID message is the same but with more ID bytes.
+// RTR messages show up as empty messages (no data, DLC=0) but are otherwise indistinguishable.
+
+class CANxbee {
+public:
+ CANxbee(PinName tx, PinName rx, int baud, int txSize, int rxSize);
+
+ bool send(CANMessage &msg); // Send a CANMessage object over the xbee (first converts to serial)
+ bool receive(CANMessage &msg); // Receive a CANMessage object over the xbee (converts from serial message to CAN)
+
+private:
+ MODSERIAL serial;
+ char rxBuff[14];
+ int rx_i;
+ bool building;
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/XbeeManager/XbeeManager.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -0,0 +1,53 @@
+#include "XbeeManager.h"
+
+XbeeManager::XbeeManager(CANxbee* _x1, CANxbee* _x2)
+{
+ x1 = _x1;
+ x2 = _x2;
+ alternate = false;
+ extraAvail = false;
+ counterX1in = 0;
+ counterX2in = 0;
+ counterX1out = 0;
+ counterX2out = 0;
+}
+
+bool XbeeManager::send(CANMessage &msg)
+{
+ alternate = !alternate;
+ if (alternate) {
+ if (x1->send(msg)) {
+ counterX1out++;
+ return true;
+ }
+ } else {
+ if (x2->send(msg)) {
+ counterX2out++;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool XbeeManager::receive(CANMessage &msg)
+{
+ if (extraAvail) {
+ extraAvail = false;
+ memcpy((void*)&msg, (void*)&extra, sizeof(CANMessage));
+ counterX2in++;
+ return true;
+ }
+ if (x1->receive(msg)) {
+ if (x2->receive(extra)) {
+ extraAvail = true;
+ }
+ counterX1in++;
+ return true;
+ } else {
+ if (x2->receive(msg)) {
+ counterX2in++;
+ return true;
+ }
+ }
+ return false;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/XbeeManager/XbeeManager.h Tue Jan 06 20:45:26 2015 +0000
@@ -0,0 +1,25 @@
+#ifndef XBEE_MANAGER_H
+#define XBEE_MANAGER_H
+
+#include "mbed.h"
+#include "CAN-xbee.h"
+
+class XbeeManager {
+public:
+ XbeeManager(CANxbee* x1, CANxbee* x2);
+ bool send(CANMessage &msg);
+ bool receive(CANMessage &msg);
+ unsigned int counterX1in;
+ unsigned int counterX2in;
+ unsigned int counterX1out;
+ unsigned int counterX2out;
+
+private:
+ bool alternate;
+ CANxbee* x1;
+ CANxbee* x2;
+ CANMessage extra;
+ bool extraAvail;
+};
+
+#endif
\ No newline at end of file
--- a/Libs/mbed-rtos.lib Sun Nov 16 02:43:58 2014 +0000 +++ b/Libs/mbed-rtos.lib Tue Jan 06 20:45:26 2015 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/users/mbed_official/code/mbed-rtos/#a3452b867ec3 +http://developer.mbed.org/users/mbed_official/code/mbed-rtos/#13a25134ac60
--- a/Libs/xbeeRelay/XbeeRelay.cpp Sun Nov 16 02:43:58 2014 +0000
+++ b/Libs/xbeeRelay/XbeeRelay.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -1,7 +1,7 @@
#include "XbeeRelay.h"
#include "mbed.h"
-#include "MODDMA.h"
-#include "MODSERIAL.h"
+//#include "MODDMA.h"
+//#include "MODSERIAL.h"
#include "PERMessage.h"
#define MOTORCONID 0x181
@@ -17,8 +17,8 @@
XbeeRelay::XbeeRelay() : Xbee_e1(p9,p10), Xbee_e2(p13,p14), counter(0) {
Xbee_e1.baud(250000);
Xbee_e2.baud(250000);
- Xbee_e1.MODDMA(&dma);
- Xbee_e2.MODDMA(&dma);
+ // Xbee_e1.MODDMA(&dma);
+ //Xbee_e2.MODDMA(&dma);
}
bool XbeeRelay::receive(CANMessage cm) {
@@ -52,13 +52,13 @@
char dataarr[pm.getLength() + 2];
pm.getDataArray(dataarr);
- if (!dma.Enabled(DMA_CHANNEL_XBEE_1)) {
- Xbee_e1.dmaSend(dataarr, sizeof(dataarr), DMA_CHANNEL_XBEE_1);
+ /* if (!dma.Enabled(DMA_CHANNEL_XBEE_1)) {
+ // Xbee_e1.dmaSend(dataarr, sizeof(dataarr), DMA_CHANNEL_XBEE_1);
return true;
} else if (!dma.Enabled(DMA_CHANNEL_XBEE_2)) {
- Xbee_e2.dmaSend(dataarr, sizeof(dataarr), DMA_CHANNEL_XBEE_2);
+ // Xbee_e2.dmaSend(dataarr, sizeof(dataarr), DMA_CHANNEL_XBEE_2);
return true;
}
-
+ */
return false;
}
\ No newline at end of file
--- a/Libs/xbeeRelay/XbeeRelay.h Sun Nov 16 02:43:58 2014 +0000
+++ b/Libs/xbeeRelay/XbeeRelay.h Tue Jan 06 20:45:26 2015 +0000
@@ -3,7 +3,7 @@
#define XBEERELAY
#include "mbed.h"
-#include "MODDMA.h"
+//#include "MODDMA.h"
#include "MODSERIAL.h"
#include "PERMessage.h"
@@ -25,7 +25,7 @@
MODSERIAL Xbee_e1;
MODSERIAL Xbee_e2;
unsigned int counter;
- MODDMA dma;
+ //MODDMA dma;
CANMessage cm;
PERMessage pm;
};
--- a/main.cpp Sun Nov 16 02:43:58 2014 +0000
+++ b/main.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -4,32 +4,49 @@
#include "serviceCAN.h"
int main() {
- wdt.kick(0.11); // Kick the watchdog timer, set the timeout to 110ms
- pc.baud(921600);
- pc.printf("\r\n\r\nSys Mgmt Reset\r\n");
- can.mode(FIFO); // Use FIFO mode
- NVIC_SetPriority(TIMER3_IRQn, 2); // Decrease timer3 priority (mbed timer, rtos)
- NVIC_SetPriority(UART0_IRQn, 1); // Decrease serial priority to give CAN higher priority
+ wdt.kick(); // Kick the watchdog timer
+ pc.baud(BAUD);
+ pc.format(8, SerialBase::None, 2); // 2 Stop bits, reduce bad serial packets
+ can.mode(FIFO);
+ DigitalOut led1(LED1);
+
+ bool normalReset = true;
// Did a watchdog reset occur since last power cycle?
if (wdt.checkFlag()) {
+ wdt.clearFlag(); // Clear flag
data.watchdogReset = true;
- pc.printf("Watchdog Reset\r\n");
+ pc.printf("Sys Mgmt Watchdog Reset\r\n");
+ led1=1;
+ normalReset=false;
}
-
+ // Did a brownout reset occur since last power cycle?
+ if (LPC_SC->RSID & (1<<3)) {
+ LPC_SC->RSID = (1<<3); // Clear flag
+ pc.printf("Sys Mgmt Brownout Reset\r\n");
+ normalReset=false;
+ }
+ // Print normal reset string
+ if (normalReset) pc.printf("Sys Mgmt Reset\r\n");
+
// Start the 10Hz data thread
- Thread gather_10Hz(runTime::thread_gather_10Hz, 0, osPriorityHigh);
+ // Thread gather(runTime::thread_gather, 0, osPriorityHigh);
// Start the 100Hz data timer (more time critical than thread)
- Thread gather_100Hz(runTime::thread_gather_100Hz, 0, osPriorityRealtime);
-
+ //RtosTimer sample(runTime::thread_sample, osTimerPeriodic);
+ //sample.start(FAST_LOOP*1000);
+
// Start the serial, CAN threads
Thread serial_out(outDiagnostics::thread_serialOut, 0, osPriorityAboveNormal, 6000); // Allocate 6kB RAM stack
- Thread can_out(outDiagnostics::thread_canOut, 0, osPriorityAboveNormal); // Allocate 256B RAM stack
+ //Thread can_out(outDiagnostics::thread_canOut, 0, osPriorityAboveNormal); // Allocate 256B RAM stack
+
+ wdt.kick(WDT_TIME); // Startup complete, normal timeout
// Background task
while(1) {
// Service CAN and Xbee logic
- if (canbus::serviceCAN());
+ //if (canbus::serviceCAN());
+ //canbus::receiveMsgXbee();
+ wdt.kick();
}
}
\ No newline at end of file
--- a/outDiagnostics/outDiagnostics.cpp Sun Nov 16 02:43:58 2014 +0000
+++ b/outDiagnostics/outDiagnostics.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -1,5 +1,4 @@
#include "outDiagnostics.h"
-#include "CAN_TxIDs.h"
// Macros for working with the string
#define ADD_LINE len+=sprintf(buff+len,"%s\r\n",line); // Add newlines, add it to the working buffer
@@ -76,11 +75,11 @@
else sprintf(temp, "%s is OPEN.", switchNames[switches-1]);
ADD_SPRINTF_LINE
- /* padCenter(line, max_charsPerLine-2, " ", ' '); ADD_LINE // Generate blank line
+ padCenter(line, max_charsPerLine-2, " ", ' '); ADD_LINE // Generate blank line
padCenter(line, max_charsPerLine-2, " Telemetry ", '*'); ADD_LINE
- sprintf(temp, "Channel 1: MessagesIn: %d MessagesOut: %d", data.xbee1MessagesIn, data.xbee1MessagesOut); ADD_SPRINTF_LINE
- sprintf(temp, "Channel 2: MessagesIn: %d MessagesOut: %d", data.xbee2MessagesIn, data.xbee2MessagesOut); ADD_SPRINTF_LINE
-*/
+ sprintf(temp, "Channel 1: MessagesIn: %d MessagesOut: %d", xbeeRelay.counterX1in, xbeeRelay.counterX1out); ADD_SPRINTF_LINE
+ sprintf(temp, "Channel 2: MessagesIn: %d MessagesOut: %d", xbeeRelay.counterX2in, xbeeRelay.counterX2out); ADD_SPRINTF_LINE
+
padCenter(line, max_charsPerLine-2, " ", ' '); ADD_LINE // Generate blank line
padCenter(line, max_charsPerLine-2, " Miscellaneous ", '*'); ADD_LINE
sprintf(temp, "Temp: %5.1fC OverTemp: %s canFault: %s WatchdogReset: %s ErrorFrame: 0x%x", data.internalTemp, BOOL(data.internalOverTemp), BOOL(data.canFault), BOOL(data.watchdogReset), data.errorFrame); ADD_SPRINTF_LINE
@@ -106,7 +105,7 @@
msg.len = sizeof(T);
memcpy(&msg.data[0], (void*)&dat, sizeof(T));
if (!can.txWrite(msg)) data.canFault = true;
- xbee.receive(msg);
+ xbeeRelay.send(msg);
}
void outDiagnostics::thread_canOut(void const *args) {
@@ -120,18 +119,18 @@
// Xbee1 Counter
msg.id = SYS_XBEE1_ID;
msg.len = 2*sizeof(int);
- memcpy(&msg.data[0], (void*)&data.xbee1MessagesIn, sizeof(int));
- memcpy(&msg.data[4], (void*)&data.xbee1MessagesOut, sizeof(int));
+ memcpy(&msg.data[0], (void*)&xbeeRelay.counterX1in, sizeof(int));
+ memcpy(&msg.data[4], (void*)&xbeeRelay.counterX1out, sizeof(int));
if (!can.txWrite(msg)) data.canFault = true;
- xbee.receive(msg);
+ xbeeRelay.send(msg);
// Xbee2 Counter
msg.id = SYS_XBEE2_ID;
msg.len = 2*sizeof(int);
- memcpy(&msg.data[0], (void*)&data.xbee2MessagesIn, sizeof(int));
- memcpy(&msg.data[4], (void*)&data.xbee2MessagesOut, sizeof(int));
+ memcpy(&msg.data[0], (void*)&xbeeRelay.counterX2in, sizeof(int));
+ memcpy(&msg.data[4], (void*)&xbeeRelay.counterX2out, sizeof(int));
if (!can.txWrite(msg)) data.canFault = true;
- xbee.receive(msg);
+ xbeeRelay.send(msg);
// Internal temperature
sendCAN(SYS_TEMP_ID, data.internalTemp);
@@ -152,14 +151,14 @@
memcpy(&msg.data[0], (void*)&data.dcdcFan1Duty, sizeof(float));
memcpy(&msg.data[4], (void*)&data.dcdcFan2Duty, sizeof(float));
if (!can.txWrite(msg)) data.canFault = true;
- xbee.receive(msg);
+ xbeeRelay.send(msg);
msg.id = SYS_PWM_PUMP_ID;
msg.len = 2*sizeof(float);
memcpy(&msg.data[0], (void*)&data.dcdcPump1Duty, sizeof(float));
memcpy(&msg.data[4], (void*)&data.dcdcPump2Duty, sizeof(float));
if (!can.txWrite(msg)) data.canFault = true;
- xbee.receive(msg);
+ xbeeRelay.send(msg);
// IMD
sendCAN(SYS_IMD_STATUS_ID, data.imdStatus);
@@ -172,6 +171,6 @@
// Shutdown Switches
sendCAN(SYS_SWITCHES_ID, data.switchState);
- Thread::wait(100);
+ Thread::wait(CAN_LOOP*1000);
}
}
\ No newline at end of file
--- a/outDiagnostics/outDiagnostics.h Sun Nov 16 02:43:58 2014 +0000
+++ b/outDiagnostics/outDiagnostics.h Tue Jan 06 20:45:26 2015 +0000
@@ -2,7 +2,6 @@
#define _OUT_DIAGNOSTICS_H
#include "IOobjects.h"
-#include "rtos.h"
namespace outDiagnostics {
--- a/runTime/runTime.cpp Sun Nov 16 02:43:58 2014 +0000
+++ b/runTime/runTime.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -2,9 +2,8 @@
const float INTERNAL_OVER_TEMP_THRES = 60; // Overtemp at 60C
-void runTime::thread_gather_10Hz(void const* args) {
+void runTime::thread_gather(void const* args) {
while(1) {
- wdt.kick();
// GLV battery coulomb counter
data.glvCurrent = glvBat.current();
@@ -39,20 +38,12 @@
if (data.internalTemp > INTERNAL_OVER_TEMP_THRES) data.internalOverTemp = true;
else data.internalOverTemp = false;
- // Xbees
-/* data.xbee1MessagesIn = xbee1.messagesProcessedIn();
- data.xbee2MessagesIn = xbee2.messagesProcessedIn();
- data.xbee1MessagesOut = xbee1.messagesProcessedOut();
- data.xbee2MessagesOut = xbee2.messagesProcessedOut();
-*/
+ // Error frame
data.errorFrame = data.canFault<<0 | data.watchdogReset<<1 | data.internalOverTemp<<2 | (data.IMDlatchError!=0)<<3 | (data.AMSlatchError!=0)<<4 | data.imdError<<5 | data.dcdcError<<6 | data.glvOverCurrent<<7;
- Thread::wait(100);
+ Thread::wait(GATHER_LOOP*1000);
}
}
-void runTime::thread_gather_100Hz(void const* args) {
- while(1) {
- glvBat.sample(); // Integrate next sample in GLV Battery coulomb counter
- dcdc.sample(); // Handle dc-dc filter and errors
- Thread::wait(10);
- }
+void runTime::thread_sample(void const* args) {
+ glvBat.sample(); // Integrate next sample in GLV Battery coulomb counter
+ dcdc.sample(); // Handle dc-dc filter and errors
}
\ No newline at end of file
--- a/runTime/runTime.h Sun Nov 16 02:43:58 2014 +0000
+++ b/runTime/runTime.h Tue Jan 06 20:45:26 2015 +0000
@@ -5,8 +5,8 @@
namespace runTime {
- void thread_gather_10Hz(void const* args);
- void thread_gather_100Hz(void const* args);
+ void thread_gather(void const* args);
+ void thread_sample(void const* args);
}
#endif
\ No newline at end of file
--- a/serviceCAN/serviceCAN.cpp Sun Nov 16 02:43:58 2014 +0000
+++ b/serviceCAN/serviceCAN.cpp Tue Jan 06 20:45:26 2015 +0000
@@ -1,64 +1,80 @@
#include "serviceCAN.h"
#include "CAN_RxIDs.h"
-
-bool canbus::serviceCAN() {
+bool canbus::serviceCAN(CANMessage* fromXbee)
+{
CANMessage msg;
- if (can.rxRead(msg)) {
- switch (msg.id) {
- case FAN_CONTROL_ID:
- if (msg.len != 2*sizeof(float)) break;
- memcpy((void*)&CANdata.dcdcFan1Duty, &msg.data[0], sizeof(float));
- memcpy((void*)&CANdata.dcdcFan2Duty, &msg.data[4], sizeof(float));
- dcdc.setPwm(FAN1, CANdata.dcdcFan1Duty);
- dcdc.setPwm(FAN2, CANdata.dcdcFan2Duty);
- break;
-
- case PUMP_CONTROL_ID:
- if (msg.len != 2*sizeof(float)) break;
- memcpy((void*)&CANdata.dcdcPump1Duty, &msg.data[0], sizeof(float));
- memcpy((void*)&CANdata.dcdcPump2Duty, &msg.data[4], sizeof(float));
- dcdc.setPwm(PUMP1, CANdata.dcdcPump1Duty);
- dcdc.setPwm(PUMP2, CANdata.dcdcPump2Duty);
- break;
-
- case DCDC_CONTROL_ID:
- if (msg.len != sizeof(char)) break;
- if (msg.data[0] == 1) dcdc.set(1);
- else dcdc.set(0);
- break;
-
- case AMS_RELAYS_ID:
- if (msg.len != sizeof(char)) break;
- if ((msg.data[0] & 0xC0) == 0xC0) {
- CANdata.airsClosed = true;
- dcdc.set(1);
- } else {
- CANdata.airsClosed = false;
- dcdc.set(0);
- }
- break;
-
- case GLVBAT_CLEARSOC_ID:
- if (msg.len != sizeof(float)) break;
- glvBat.resetToSOC(*((float*)(&msg.data[0])));
- break;
-
- case GLVBAT_CLEARAH_ID:
- if (msg.len != sizeof(float)) break;
- glvBat.resetToAh(*((float*)(&msg.data[0])));
- break;
-
- case GLVBAT_SETCAPAC_ID:
- if (msg.len != sizeof(float)) break;
- glvBat.changeCapacity(*((float*)(&msg.data[0])));
- break;
-
- default:
- break;
- }
- xbee.receive(msg);
+ if (fromXbee != NULL) {
+ memcpy((void*)&msg, (void*)fromXbee, sizeof(CANMessage));
+ } else {
+ if (!can.rxRead(msg)) return false;
+ }
+
+ switch (msg.id) {
+ case FAN_CONTROL_ID:
+ if (msg.len != 2*sizeof(float)) break;
+ memcpy((void*)&CANdata.dcdcFan1Duty, &msg.data[0], sizeof(float));
+ memcpy((void*)&CANdata.dcdcFan2Duty, &msg.data[4], sizeof(float));
+ dcdc.setPwm(FAN1, CANdata.dcdcFan1Duty);
+ dcdc.setPwm(FAN2, CANdata.dcdcFan2Duty);
+ break;
+
+ case PUMP_CONTROL_ID:
+ if (msg.len != 2*sizeof(float)) break;
+ memcpy((void*)&CANdata.dcdcPump1Duty, &msg.data[0], sizeof(float));
+ memcpy((void*)&CANdata.dcdcPump2Duty, &msg.data[4], sizeof(float));
+ dcdc.setPwm(PUMP1, CANdata.dcdcPump1Duty);
+ dcdc.setPwm(PUMP2, CANdata.dcdcPump2Duty);
+ break;
+
+ case DCDC_CONTROL_ID:
+ if (msg.len != sizeof(char)) break;
+ if (msg.data[0] == 1) dcdc.set(1);
+ else dcdc.set(0);
+ break;
+
+ case AMS_RELAYS_ID:
+ if (msg.len != sizeof(char)) break;
+ if ((msg.data[0] & (1<<3|1<<4|1<<5)) == (1<<3|1<<4|1<<5)) { // AIRs closed? 1<<3=posAIR, 1<<4=negAIR, 1<<5=tractiveEnable signal
+ CANdata.airsClosed = true;
+ dcdc.set(1);
+ } else {
+ CANdata.airsClosed = false;
+ dcdc.set(0);
+ }
+ break;
+
+ case GLVBAT_CLEARSOC_ID:
+ if (msg.len != sizeof(float)) break;
+ glvBat.resetToSOC(*((float*)(&msg.data[0])));
+ break;
+
+ case GLVBAT_CLEARAH_ID:
+ if (msg.len != sizeof(float)) break;
+ glvBat.resetToAh(*((float*)(&msg.data[0])));
+ break;
+
+ case GLVBAT_SETCAPAC_ID:
+ if (msg.len != sizeof(float)) break;
+ glvBat.changeCapacity(*((float*)(&msg.data[0])));
+ break;
+ case STEERING_RESET_ID:
+ NVIC_SystemReset();
+ break;
+ default:
+ break;
+ }
+
+ return true;
+
+}
+// Check for incoming messages from the xbees
+bool canbus::receiveMsgXbee()
+{
+ CANMessage msg;
+ if (xbeeRelay.receive(msg)) { // Incoming CAN message string received
+ if (!can.txWrite(msg)) data.canFault = true; // Send it out on the CAN bus
+ serviceCAN(&msg); // Send it into the local serviceCAN routine
return true;
- }
- return false;
+ } else return false;
}
\ No newline at end of file
--- a/serviceCAN/serviceCAN.h Sun Nov 16 02:43:58 2014 +0000
+++ b/serviceCAN/serviceCAN.h Tue Jan 06 20:45:26 2015 +0000
@@ -1,13 +1,13 @@
#ifndef _SERVICE_CAN_H
#define _SERVICE_CAN_H
-#include "mbed.h"
#include "IOobjects.h"
const int DEVICE_CAN_TIMEOUT = 0.25; // Comms. lost to external device if a message is not received within 200 ms
namespace canbus {
- bool serviceCAN();
+ bool serviceCAN(CANMessage* fromXbee=0);
+ bool receiveMsgXbee();
}
#endif
\ No newline at end of file
