Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FatFileSystem mbed myBlueUSB neigbourhood rfcomm sdp
Diff: ftlib/ftlibclassdev.h
- Revision:
- 0:7da612835693
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ftlib/ftlibclassdev.h Wed Jun 15 19:12:25 2011 +0000
@@ -0,0 +1,148 @@
+#ifndef FTLIBCLASSDEV_H
+#define FTLIBCLASSDEV_H
+
+#include "ftlib.h"
+#include "message.h"
+
+#define ABF_IF_COMPLETE_NUM_WRITE 32
+#define ABF_IF_COMPLETE_NUM_READ 42
+
+/*****************************************************************************************
+ The interfaces use a combination of synchronous (blocking) and asynchronous (non-blocking)
+ I/O. For serial I/O it is essential that non-blocking I/O is used otherwise the entire
+ transfer timeslot would be consumed with busy waiting. For USB this constraint is less
+ severe but I nevertheless used non-blocking I/O also for USB in the transfer thread (which
+ is not a real thread). Outside the transfer thread, I/O can be synchronous which I indeed
+ used because it is easier to write and easier to understand.
+ The timing of the transfer thread is determined by a Ticker interrupt. But in order not
+ to occupy the interrupt system for too long, it just increments a counter in every
+ interface object. The main event loop polls this counter, initiates a transfer and resets
+ it. Starting a thread works by calling FtThreadInit (which does some initialisation) and
+ setting transferAktiv to FTX1RUN. The poll routine will then call guardedFtThreadBegin
+ which in turn will call FtThreadBegin provided the previous run of the thread has ended.
+ The thead is protected by a busy flag which is set in guardedFtThreadBegin and released
+ in FtThreadEnd, as long as busy is active a new thread should not be begun (enforced by
+ guardedFtThreadBegin). FtThreadBegin copies the transferArea (TA) to a buffer and calls
+ the send routine which (being non-blocking) returns immediately. When the send completes
+ a callback (interrupt) occurs which initiates the corresponding read (request-reply model).
+ When the read finished another callback (interrupt) occurs which invokes FtThreadEnd.
+ FtThreadEnd may call notification routines which will all like FtThreadEnd but unlike
+ FtThreadBegin run in interrupt context. Both FtThreadBegin and FtThreadEnd operate on
+ the TA which is shared between the application and the transfer thread. As this transfer-
+ thread is not a real thread synchronisation is not strictly neccesary because FtThreadBegin
+ runs in the background (like the application) and FtThreadEnd+callback run as interrupt
+ and cannot be interrupted by the background. Still a semaphore 'lock' is in place to
+ protect the TA from simultaneous access. When the area is locked, the transfer is simply
+ skipped. A user application cal call test_and_set() which returns falls when the area is
+ locked and true when it is free. After using the TA the user must then call increment()
+ to release the lock on the TA. At the moment the onlu use-case is to provide a consistent
+ set of motor-settings to the TX which will be communicated in the same packet.
+*****************************************************************************************/
+
+inline char* strdup(const char *s) {
+ char *d = new char[strlen(s)+1];
+ strcpy(d, s);
+ return d;
+}
+
+class ftdev {
+protected:
+ FT_TRANSFER_AREA* ta;
+ NOTIFICATION_EVENTS ne;
+ msgbuffer<SMESSAGE, 10> *messages;
+ int type, sn;
+ unsigned fw;
+ unsigned char out[ABF_IF_COMPLETE_NUM_WRITE]; //these buffers have maximum size, alternatively each subclass could have its own properly sized buffer
+ unsigned char in[ABF_IF_COMPLETE_NUM_READ];
+ int num_write, num_read;
+ enum _ta_state {FTX1STOP, FTX1RUN, FTX1SYNC} transferAktiv;
+ volatile int lock; //semaphore to control concurrent access to transferarea, FtThreadEnd is called in interrupt context
+ volatile bool busy; //semaphore to prevent a transfer from being started while another is still in progress
+ volatile bool interface_connected;
+ volatile int triggered;//when >0 indicates that the next transfer should take place
+ ftdev() {} //private default, construction takes place through subclasses
+ ftdev(int t, int s): type(t), sn(s) {
+ ta = 0;
+ fw = 0;
+ triggered = 0;
+ busy = false;
+ lock = 1;
+ interface_connected = false;
+ messages = 0;
+ transferAktiv = FTX1STOP;
+ }
+ void trigger() {
+ if (transferAktiv != FTX1STOP) triggered++; //called by onTick
+ }
+ bool guardedFtThreadBegin(); //called by 'poll'
+ bool guardedStop();
+ virtual void FtThreadInit() { busy = false; if (ta) ta->TransferAktiv = true;} //called by StartFtTransferArea
+ virtual void FtThreadBegin() = 0; //called by 'guardedFtThreadBegin'
+ virtual void FtThreadEnd(); //called by interrupt when transfer completes
+ virtual void FtThreadFinish() { if(ta) ta->TransferAktiv = false;} //called by StopFtTransferArea
+ bool test_and_set(); //'lock' semphore
+ void increment(); //'lock' semphore
+ virtual unsigned pgm_message(unsigned code, unsigned dwMemBlock) = 0;
+public:
+ virtual ~ftdev() {
+ delete ta;
+ delete messages;
+ }
+//public API: These functions match those of the original ftlib
+ virtual unsigned CloseFtDevice() = 0;
+ virtual unsigned GetFtDeviceTyp() {
+ return type;
+ }
+ virtual char* GetFtSerialNrStrg();
+ virtual unsigned GetFtSerialNr() {
+ return sn;
+ }
+ virtual char* GetFtFirmwareStrg();
+ virtual unsigned GetFtFirmware() {
+ return fw;
+ }
+ virtual char* GetFtManufacturerStrg() = 0;
+ virtual char* GetFtShortNameStrg() = 0;
+ virtual char* GetFtLongNameStrg() = 0;
+ /*
+ virtual unsigned GetFtDeviceSetting(FT_SETTING *pSet);
+ virtual unsigned SetFtDeviceSetting(FT_SETTING *pSet);
+ */
+ virtual unsigned SetFtDistanceSensorMode(unsigned dwMode, unsigned dwTol1, unsigned dwTol2,
+ unsigned dwSchwell1, unsigned dwSchwell2, unsigned dwRepeat1, unsigned dwRepeat2) {
+ return FTLIB_ERR_NOT_SUPPORTED;
+ }
+ virtual unsigned StartFtTransferArea(NOTIFICATION_EVENTS* sNEvent = 0);
+ virtual unsigned StartFtTransferAreaWithCommunication(NOTIFICATION_EVENTS* sNEvent = 0);
+ virtual unsigned StopFtTransferArea();
+ virtual FT_TRANSFER_AREA* GetFtTransferAreaAddress() {
+ return ta;
+ }
+ virtual unsigned IsFtTransferActiv();
+ unsigned ResetFtTransfer ();
+ unsigned SendFtMessage(unsigned char bHwId, unsigned char bSubId, unsigned dwMessage, unsigned dwWaitTime, unsigned dwOption);
+ unsigned ClearFtMessageBuffer();
+ virtual unsigned StartFtProgram(unsigned dwMemBlock) {
+ return FTLIB_ERR_NOT_SUPPORTED;
+ }
+ virtual unsigned StopFtProgram() {
+ return FTLIB_ERR_NOT_SUPPORTED;
+ }
+ unsigned DeleteFtProgram(unsigned dwMemBlock) {
+ return pgm_message(0xf5, dwMemBlock);
+ }
+ unsigned SetFtProgramActiv(unsigned dwMemBlock) {
+ return pgm_message(0xf9, dwMemBlock);
+ }
+};
+
+
+/* still to be implemented
+ unsigned GetFtMemoryLayout(unsigned char * pbArray, unsigned dwSize);
+ unsigned DownloadFtProgram(unsigned dwMemBlock, unsigned char* pbArray, unsigned dwSize, unsigned dwParameter, unsigned char *pbName, unsigned dwNameLen);
+ unsigned GetFtProgramName(unsigned dwMemBlock, unsigned dwSize, char* pName);
+ unsigned WriteFtMemoryData(unsigned dwData, unsigned dwAddress);
+ unsigned GetFtMemoryData(unsigned char * pbArray, unsigned dwSize, unsigned dwAddress);
+*/
+
+#endif
\ No newline at end of file