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
ftlib/ftlibclassdev.h@1:4676e8b9b357, 2013-03-11 (annotated)
- Committer:
- networker
- Date:
- Mon Mar 11 08:04:37 2013 +0000
- Revision:
- 1:4676e8b9b357
- Parent:
- 0:7da612835693
first publication of this experimental class, just for sharing wip
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| networker |
0:7da612835693 | 1 | #ifndef FTLIBCLASSDEV_H |
| networker |
0:7da612835693 | 2 | #define FTLIBCLASSDEV_H |
| networker |
0:7da612835693 | 3 | |
| networker |
0:7da612835693 | 4 | #include "ftlib.h" |
| networker |
0:7da612835693 | 5 | #include "message.h" |
| networker |
0:7da612835693 | 6 | |
| networker |
0:7da612835693 | 7 | #define ABF_IF_COMPLETE_NUM_WRITE 32 |
| networker |
0:7da612835693 | 8 | #define ABF_IF_COMPLETE_NUM_READ 42 |
| networker |
0:7da612835693 | 9 | |
| networker |
0:7da612835693 | 10 | /***************************************************************************************** |
| networker |
0:7da612835693 | 11 | The interfaces use a combination of synchronous (blocking) and asynchronous (non-blocking) |
| networker |
0:7da612835693 | 12 | I/O. For serial I/O it is essential that non-blocking I/O is used otherwise the entire |
| networker |
0:7da612835693 | 13 | transfer timeslot would be consumed with busy waiting. For USB this constraint is less |
| networker |
0:7da612835693 | 14 | severe but I nevertheless used non-blocking I/O also for USB in the transfer thread (which |
| networker |
0:7da612835693 | 15 | is not a real thread). Outside the transfer thread, I/O can be synchronous which I indeed |
| networker |
0:7da612835693 | 16 | used because it is easier to write and easier to understand. |
| networker |
0:7da612835693 | 17 | The timing of the transfer thread is determined by a Ticker interrupt. But in order not |
| networker |
0:7da612835693 | 18 | to occupy the interrupt system for too long, it just increments a counter in every |
| networker |
0:7da612835693 | 19 | interface object. The main event loop polls this counter, initiates a transfer and resets |
| networker |
0:7da612835693 | 20 | it. Starting a thread works by calling FtThreadInit (which does some initialisation) and |
| networker |
0:7da612835693 | 21 | setting transferAktiv to FTX1RUN. The poll routine will then call guardedFtThreadBegin |
| networker |
0:7da612835693 | 22 | which in turn will call FtThreadBegin provided the previous run of the thread has ended. |
| networker |
0:7da612835693 | 23 | The thead is protected by a busy flag which is set in guardedFtThreadBegin and released |
| networker |
0:7da612835693 | 24 | in FtThreadEnd, as long as busy is active a new thread should not be begun (enforced by |
| networker |
0:7da612835693 | 25 | guardedFtThreadBegin). FtThreadBegin copies the transferArea (TA) to a buffer and calls |
| networker |
0:7da612835693 | 26 | the send routine which (being non-blocking) returns immediately. When the send completes |
| networker |
0:7da612835693 | 27 | a callback (interrupt) occurs which initiates the corresponding read (request-reply model). |
| networker |
0:7da612835693 | 28 | When the read finished another callback (interrupt) occurs which invokes FtThreadEnd. |
| networker |
0:7da612835693 | 29 | FtThreadEnd may call notification routines which will all like FtThreadEnd but unlike |
| networker |
0:7da612835693 | 30 | FtThreadBegin run in interrupt context. Both FtThreadBegin and FtThreadEnd operate on |
| networker |
0:7da612835693 | 31 | the TA which is shared between the application and the transfer thread. As this transfer- |
| networker |
0:7da612835693 | 32 | thread is not a real thread synchronisation is not strictly neccesary because FtThreadBegin |
| networker |
0:7da612835693 | 33 | runs in the background (like the application) and FtThreadEnd+callback run as interrupt |
| networker |
0:7da612835693 | 34 | and cannot be interrupted by the background. Still a semaphore 'lock' is in place to |
| networker |
0:7da612835693 | 35 | protect the TA from simultaneous access. When the area is locked, the transfer is simply |
| networker |
0:7da612835693 | 36 | skipped. A user application cal call test_and_set() which returns falls when the area is |
| networker |
0:7da612835693 | 37 | locked and true when it is free. After using the TA the user must then call increment() |
| networker |
0:7da612835693 | 38 | to release the lock on the TA. At the moment the onlu use-case is to provide a consistent |
| networker |
0:7da612835693 | 39 | set of motor-settings to the TX which will be communicated in the same packet. |
| networker |
0:7da612835693 | 40 | *****************************************************************************************/ |
| networker |
0:7da612835693 | 41 | |
| networker |
0:7da612835693 | 42 | inline char* strdup(const char *s) { |
| networker |
0:7da612835693 | 43 | char *d = new char[strlen(s)+1]; |
| networker |
0:7da612835693 | 44 | strcpy(d, s); |
| networker |
0:7da612835693 | 45 | return d; |
| networker |
0:7da612835693 | 46 | } |
| networker |
0:7da612835693 | 47 | |
| networker |
0:7da612835693 | 48 | class ftdev { |
| networker |
0:7da612835693 | 49 | protected: |
| networker |
0:7da612835693 | 50 | FT_TRANSFER_AREA* ta; |
| networker |
0:7da612835693 | 51 | NOTIFICATION_EVENTS ne; |
| networker |
0:7da612835693 | 52 | msgbuffer<SMESSAGE, 10> *messages; |
| networker |
0:7da612835693 | 53 | int type, sn; |
| networker |
0:7da612835693 | 54 | unsigned fw; |
| networker |
0:7da612835693 | 55 | unsigned char out[ABF_IF_COMPLETE_NUM_WRITE]; //these buffers have maximum size, alternatively each subclass could have its own properly sized buffer |
| networker |
0:7da612835693 | 56 | unsigned char in[ABF_IF_COMPLETE_NUM_READ]; |
| networker |
0:7da612835693 | 57 | int num_write, num_read; |
| networker |
0:7da612835693 | 58 | enum _ta_state {FTX1STOP, FTX1RUN, FTX1SYNC} transferAktiv; |
| networker |
0:7da612835693 | 59 | volatile int lock; //semaphore to control concurrent access to transferarea, FtThreadEnd is called in interrupt context |
| networker |
0:7da612835693 | 60 | volatile bool busy; //semaphore to prevent a transfer from being started while another is still in progress |
| networker |
0:7da612835693 | 61 | volatile bool interface_connected; |
| networker |
0:7da612835693 | 62 | volatile int triggered;//when >0 indicates that the next transfer should take place |
| networker |
0:7da612835693 | 63 | ftdev() {} //private default, construction takes place through subclasses |
| networker |
0:7da612835693 | 64 | ftdev(int t, int s): type(t), sn(s) { |
| networker |
0:7da612835693 | 65 | ta = 0; |
| networker |
0:7da612835693 | 66 | fw = 0; |
| networker |
0:7da612835693 | 67 | triggered = 0; |
| networker |
0:7da612835693 | 68 | busy = false; |
| networker |
0:7da612835693 | 69 | lock = 1; |
| networker |
0:7da612835693 | 70 | interface_connected = false; |
| networker |
0:7da612835693 | 71 | messages = 0; |
| networker |
0:7da612835693 | 72 | transferAktiv = FTX1STOP; |
| networker |
0:7da612835693 | 73 | } |
| networker |
0:7da612835693 | 74 | void trigger() { |
| networker |
0:7da612835693 | 75 | if (transferAktiv != FTX1STOP) triggered++; //called by onTick |
| networker |
0:7da612835693 | 76 | } |
| networker |
0:7da612835693 | 77 | bool guardedFtThreadBegin(); //called by 'poll' |
| networker |
0:7da612835693 | 78 | bool guardedStop(); |
| networker |
0:7da612835693 | 79 | virtual void FtThreadInit() { busy = false; if (ta) ta->TransferAktiv = true;} //called by StartFtTransferArea |
| networker |
0:7da612835693 | 80 | virtual void FtThreadBegin() = 0; //called by 'guardedFtThreadBegin' |
| networker |
0:7da612835693 | 81 | virtual void FtThreadEnd(); //called by interrupt when transfer completes |
| networker |
0:7da612835693 | 82 | virtual void FtThreadFinish() { if(ta) ta->TransferAktiv = false;} //called by StopFtTransferArea |
| networker |
0:7da612835693 | 83 | bool test_and_set(); //'lock' semphore |
| networker |
0:7da612835693 | 84 | void increment(); //'lock' semphore |
| networker |
0:7da612835693 | 85 | virtual unsigned pgm_message(unsigned code, unsigned dwMemBlock) = 0; |
| networker |
0:7da612835693 | 86 | public: |
| networker |
0:7da612835693 | 87 | virtual ~ftdev() { |
| networker |
0:7da612835693 | 88 | delete ta; |
| networker |
0:7da612835693 | 89 | delete messages; |
| networker |
0:7da612835693 | 90 | } |
| networker |
0:7da612835693 | 91 | //public API: These functions match those of the original ftlib |
| networker |
0:7da612835693 | 92 | virtual unsigned CloseFtDevice() = 0; |
| networker |
0:7da612835693 | 93 | virtual unsigned GetFtDeviceTyp() { |
| networker |
0:7da612835693 | 94 | return type; |
| networker |
0:7da612835693 | 95 | } |
| networker |
0:7da612835693 | 96 | virtual char* GetFtSerialNrStrg(); |
| networker |
0:7da612835693 | 97 | virtual unsigned GetFtSerialNr() { |
| networker |
0:7da612835693 | 98 | return sn; |
| networker |
0:7da612835693 | 99 | } |
| networker |
0:7da612835693 | 100 | virtual char* GetFtFirmwareStrg(); |
| networker |
0:7da612835693 | 101 | virtual unsigned GetFtFirmware() { |
| networker |
0:7da612835693 | 102 | return fw; |
| networker |
0:7da612835693 | 103 | } |
| networker |
0:7da612835693 | 104 | virtual char* GetFtManufacturerStrg() = 0; |
| networker |
0:7da612835693 | 105 | virtual char* GetFtShortNameStrg() = 0; |
| networker |
0:7da612835693 | 106 | virtual char* GetFtLongNameStrg() = 0; |
| networker |
0:7da612835693 | 107 | /* |
| networker |
0:7da612835693 | 108 | virtual unsigned GetFtDeviceSetting(FT_SETTING *pSet); |
| networker |
0:7da612835693 | 109 | virtual unsigned SetFtDeviceSetting(FT_SETTING *pSet); |
| networker |
0:7da612835693 | 110 | */ |
| networker |
0:7da612835693 | 111 | virtual unsigned SetFtDistanceSensorMode(unsigned dwMode, unsigned dwTol1, unsigned dwTol2, |
| networker |
0:7da612835693 | 112 | unsigned dwSchwell1, unsigned dwSchwell2, unsigned dwRepeat1, unsigned dwRepeat2) { |
| networker |
0:7da612835693 | 113 | return FTLIB_ERR_NOT_SUPPORTED; |
| networker |
0:7da612835693 | 114 | } |
| networker |
0:7da612835693 | 115 | virtual unsigned StartFtTransferArea(NOTIFICATION_EVENTS* sNEvent = 0); |
| networker |
0:7da612835693 | 116 | virtual unsigned StartFtTransferAreaWithCommunication(NOTIFICATION_EVENTS* sNEvent = 0); |
| networker |
0:7da612835693 | 117 | virtual unsigned StopFtTransferArea(); |
| networker |
0:7da612835693 | 118 | virtual FT_TRANSFER_AREA* GetFtTransferAreaAddress() { |
| networker |
0:7da612835693 | 119 | return ta; |
| networker |
0:7da612835693 | 120 | } |
| networker |
0:7da612835693 | 121 | virtual unsigned IsFtTransferActiv(); |
| networker |
0:7da612835693 | 122 | unsigned ResetFtTransfer (); |
| networker |
0:7da612835693 | 123 | unsigned SendFtMessage(unsigned char bHwId, unsigned char bSubId, unsigned dwMessage, unsigned dwWaitTime, unsigned dwOption); |
| networker |
0:7da612835693 | 124 | unsigned ClearFtMessageBuffer(); |
| networker |
0:7da612835693 | 125 | virtual unsigned StartFtProgram(unsigned dwMemBlock) { |
| networker |
0:7da612835693 | 126 | return FTLIB_ERR_NOT_SUPPORTED; |
| networker |
0:7da612835693 | 127 | } |
| networker |
0:7da612835693 | 128 | virtual unsigned StopFtProgram() { |
| networker |
0:7da612835693 | 129 | return FTLIB_ERR_NOT_SUPPORTED; |
| networker |
0:7da612835693 | 130 | } |
| networker |
0:7da612835693 | 131 | unsigned DeleteFtProgram(unsigned dwMemBlock) { |
| networker |
0:7da612835693 | 132 | return pgm_message(0xf5, dwMemBlock); |
| networker |
0:7da612835693 | 133 | } |
| networker |
0:7da612835693 | 134 | unsigned SetFtProgramActiv(unsigned dwMemBlock) { |
| networker |
0:7da612835693 | 135 | return pgm_message(0xf9, dwMemBlock); |
| networker |
0:7da612835693 | 136 | } |
| networker |
0:7da612835693 | 137 | }; |
| networker |
0:7da612835693 | 138 | |
| networker |
0:7da612835693 | 139 | |
| networker |
0:7da612835693 | 140 | /* still to be implemented |
| networker |
0:7da612835693 | 141 | unsigned GetFtMemoryLayout(unsigned char * pbArray, unsigned dwSize); |
| networker |
0:7da612835693 | 142 | unsigned DownloadFtProgram(unsigned dwMemBlock, unsigned char* pbArray, unsigned dwSize, unsigned dwParameter, unsigned char *pbName, unsigned dwNameLen); |
| networker |
0:7da612835693 | 143 | unsigned GetFtProgramName(unsigned dwMemBlock, unsigned dwSize, char* pName); |
| networker |
0:7da612835693 | 144 | unsigned WriteFtMemoryData(unsigned dwData, unsigned dwAddress); |
| networker |
0:7da612835693 | 145 | unsigned GetFtMemoryData(unsigned char * pbArray, unsigned dwSize, unsigned dwAddress); |
| networker |
0:7da612835693 | 146 | */ |
| networker |
0:7da612835693 | 147 | |
| networker |
0:7da612835693 | 148 | #endif |