Program the control the fischertechnik robo interface or intelligent interface via tcp socket or via a java gui.
libft.c@1:2c9d412ad471, 2011-05-04 (annotated)
- Committer:
- networker
- Date:
- Wed May 04 15:42:13 2011 +0000
- Revision:
- 1:2c9d412ad471
- Parent:
- 0:7f26f0680202
first publication (mbed challenge submission)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
networker | 0:7f26f0680202 | 1 | //this file was adapted by Ad for use in the mbed environment |
networker | 0:7f26f0680202 | 2 | //currently all USB functionality has been disabled, this may change in the future |
networker | 0:7f26f0680202 | 3 | //the comport functionality has been adapted to the mbed serial class |
networker | 0:7f26f0680202 | 4 | //threads and semphores were replaced by other primitives |
networker | 0:7f26f0680202 | 5 | //as a consequence also the ftlib.h was adapted |
networker | 0:7f26f0680202 | 6 | |
networker | 0:7f26f0680202 | 7 | /** @file |
networker | 0:7f26f0680202 | 8 | * |
networker | 0:7f26f0680202 | 9 | * Copyright (C) 2007 Erik Andresen erik@vontaene.de |
networker | 0:7f26f0680202 | 10 | * |
networker | 0:7f26f0680202 | 11 | * Open Source version of the fischertechnik ROBO Interface Library for Unix like systems |
networker | 0:7f26f0680202 | 12 | * |
networker | 0:7f26f0680202 | 13 | * Communication is done through a "transfer area" this is constantly updated. |
networker | 0:7f26f0680202 | 14 | * |
networker | 0:7f26f0680202 | 15 | * This library is free software; you can redistribute it and/or |
networker | 0:7f26f0680202 | 16 | * modify it under the terms of the GNU Lesser General Public |
networker | 0:7f26f0680202 | 17 | * License as published by the Free Software Foundation; either |
networker | 0:7f26f0680202 | 18 | * version 2.1 of the License, or (at your option) any later version. |
networker | 0:7f26f0680202 | 19 | * |
networker | 0:7f26f0680202 | 20 | * This library is distributed in the hope that it will be useful, |
networker | 0:7f26f0680202 | 21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
networker | 0:7f26f0680202 | 22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
networker | 0:7f26f0680202 | 23 | * Lesser General Public License for more details. |
networker | 0:7f26f0680202 | 24 | * |
networker | 0:7f26f0680202 | 25 | * You should have received a copy of the GNU Lesser General Public |
networker | 0:7f26f0680202 | 26 | * License along with this library; if not, write to the Free Software |
networker | 0:7f26f0680202 | 27 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
networker | 0:7f26f0680202 | 28 | * |
networker | 0:7f26f0680202 | 29 | */ |
networker | 0:7f26f0680202 | 30 | |
networker | 0:7f26f0680202 | 31 | /** |
networker | 0:7f26f0680202 | 32 | * \example example.c |
networker | 0:7f26f0680202 | 33 | * |
networker | 0:7f26f0680202 | 34 | * \mainpage libft Index Page |
networker | 0:7f26f0680202 | 35 | * |
networker | 0:7f26f0680202 | 36 | * \section intro_sec Introduction |
networker | 0:7f26f0680202 | 37 | * |
networker | 0:7f26f0680202 | 38 | * libft is an Open Source version of the fischertechnik ROBO Interface Library for Unix like systems |
networker | 0:7f26f0680202 | 39 | * |
networker | 0:7f26f0680202 | 40 | * The goal is to create a library that is fully compatible with the ftlib by knobloch eletronic. |
networker | 0:7f26f0680202 | 41 | * |
networker | 0:7f26f0680202 | 42 | * This library should work on any systems supported by libusb, like Linux, BSD and Mac OS X and is released |
networker | 0:7f26f0680202 | 43 | * under the GNU Lesser General Public License (LGPL) |
networker | 0:7f26f0680202 | 44 | * |
networker | 0:7f26f0680202 | 45 | * Included is the helper program "ftuploader" which allows you to upload programs to the Robo Interface.\n |
networker | 0:7f26f0680202 | 46 | * Running ftuploader --help should give you an idea how to use it.\n |
networker | 0:7f26f0680202 | 47 | * Also included is an Interface Diagnose utility. See section Interface Diagnose |
networker | 0:7f26f0680202 | 48 | * |
networker | 0:7f26f0680202 | 49 | * \section dl_sec Download |
networker | 0:7f26f0680202 | 50 | * Current Version: 0.4.3 |
networker | 0:7f26f0680202 | 51 | * |
networker | 0:7f26f0680202 | 52 | * See http://defiant.homedns.org/~erik/ft/libft/files/ \n |
networker | 0:7f26f0680202 | 53 | * Download Latest version: http://defiant.homedns.org/~erik/ft/libft/files/libft-current.tar.gz |
networker | 0:7f26f0680202 | 54 | * |
networker | 0:7f26f0680202 | 55 | * \section req_sec Requirements |
networker | 0:7f26f0680202 | 56 | * - libusb - http://libusb.sourceforge.net/ |
networker | 0:7f26f0680202 | 57 | * - cmake at least version 2.4 - http://cmake.org |
networker | 0:7f26f0680202 | 58 | * - pthreads (Should be included with every modern posix compatible OS) |
networker | 0:7f26f0680202 | 59 | * |
networker | 0:7f26f0680202 | 60 | * |
networker | 0:7f26f0680202 | 61 | * \section apidoc_sec API Documentation |
networker | 0:7f26f0680202 | 62 | * \see libft.c |
networker | 0:7f26f0680202 | 63 | * |
networker | 0:7f26f0680202 | 64 | * \section install_sec Installation |
networker | 0:7f26f0680202 | 65 | * |
networker | 0:7f26f0680202 | 66 | * \subsection step1 Step 1: Compiling |
networker | 0:7f26f0680202 | 67 | * |
networker | 0:7f26f0680202 | 68 | * Type |
networker | 0:7f26f0680202 | 69 | * - cmake . |
networker | 0:7f26f0680202 | 70 | * - make |
networker | 0:7f26f0680202 | 71 | * \subsection step2 Step 2: Installation |
networker | 0:7f26f0680202 | 72 | * Type |
networker | 0:7f26f0680202 | 73 | * - make install |
networker | 0:7f26f0680202 | 74 | * |
networker | 0:7f26f0680202 | 75 | * After installing you should run |
networker | 0:7f26f0680202 | 76 | * - ldconfig |
networker | 0:7f26f0680202 | 77 | * |
networker | 0:7f26f0680202 | 78 | * to make the library known to your system. Make sure that /etc/ld.so.conf is configured to include /usr/local/li |
networker | 0:7f26f0680202 | 79 | * |
networker | 0:7f26f0680202 | 80 | * To install the diagnose utility type |
networker | 0:7f26f0680202 | 81 | * - make diag |
networker | 0:7f26f0680202 | 82 | * |
networker | 0:7f26f0680202 | 83 | * Debian packages are available. Please read http://vontaene.de/apt/README.txt.\n |
networker | 0:7f26f0680202 | 84 | * You can install them with apt-get install libft0 libft-doc libft-python libft-diag |
networker | 0:7f26f0680202 | 85 | * |
networker | 0:7f26f0680202 | 86 | * \subsection step3 Step 3: udev |
networker | 0:7f26f0680202 | 87 | * When running udev you might want to copy the file fischertechnik.rules from the udev folder to /etc/udev/rules.d/ to get the correct permissions.\n |
networker | 0:7f26f0680202 | 88 | * Udev then needs a reload with |
networker | 0:7f26f0680202 | 89 | * - udevcontrol reload_rules |
networker | 0:7f26f0680202 | 90 | * |
networker | 0:7f26f0680202 | 91 | * You will now need to replug your device. |
networker | 0:7f26f0680202 | 92 | * |
networker | 0:7f26f0680202 | 93 | * \subsection step4 Step 4: Create Documentation\n |
networker | 0:7f26f0680202 | 94 | * Type\n |
networker | 0:7f26f0680202 | 95 | * - make doc\n |
networker | 0:7f26f0680202 | 96 | * to create the html API documentation. |
networker | 0:7f26f0680202 | 97 | * |
networker | 0:7f26f0680202 | 98 | * \subsection step5 Step 5: Python |
networker | 0:7f26f0680202 | 99 | * A Python interface to this library is available, see the python folder for details.\n |
networker | 0:7f26f0680202 | 100 | * Type\n |
networker | 0:7f26f0680202 | 101 | * make python\n |
networker | 0:7f26f0680202 | 102 | * |
networker | 0:7f26f0680202 | 103 | * in the python/ -folder to install the python module. |
networker | 0:7f26f0680202 | 104 | * Use pydoc to read its documentation: |
networker | 0:7f26f0680202 | 105 | * - pydoc robointerface in the shell |
networker | 0:7f26f0680202 | 106 | * - help(robointerface) from the python interpreter |
networker | 0:7f26f0680202 | 107 | * |
networker | 0:7f26f0680202 | 108 | * \section diag_sec Interface Diagnose |
networker | 0:7f26f0680202 | 109 | * You can find it in the folder diag/.\n |
networker | 0:7f26f0680202 | 110 | * It requires the python module (see above) and PyQT4. You can launch it by running "sh ftdiagnose" |
networker | 0:7f26f0680202 | 111 | * \image html diag1.png |
networker | 0:7f26f0680202 | 112 | * |
networker | 0:7f26f0680202 | 113 | * \section author_sec Author |
networker | 0:7f26f0680202 | 114 | * Erik Andresen - erik@vontaene.de |
networker | 0:7f26f0680202 | 115 | * |
networker | 0:7f26f0680202 | 116 | * Please contact me for bugs or any suggestions |
networker | 0:7f26f0680202 | 117 | * |
networker | 0:7f26f0680202 | 118 | * Homepage of libft: http://defiant.homedns.org/~erik/ft/libft/ |
networker | 0:7f26f0680202 | 119 | * |
networker | 0:7f26f0680202 | 120 | * |
networker | 0:7f26f0680202 | 121 | * \section changes_sec Changes |
networker | 0:7f26f0680202 | 122 | * |
networker | 0:7f26f0680202 | 123 | * - 0.4.3: - Bug fix: Extension digital inputs at RoboRF |
networker | 0:7f26f0680202 | 124 | * - ftdiagnose: Display connection status |
networker | 0:7f26f0680202 | 125 | * - Added functions: (not in Knobloch lib): |
networker | 0:7f26f0680202 | 126 | * - IsFtInterfaceConnected() |
networker | 0:7f26f0680202 | 127 | * - Python added functions: |
networker | 0:7f26f0680202 | 128 | * - IsConnected() |
networker | 0:7f26f0680202 | 129 | * - 0.4.2: - Python support to open the interface by serial |
networker | 0:7f26f0680202 | 130 | * - Some Bug fixes |
networker | 0:7f26f0680202 | 131 | * - Added functions: (not in Knobloch lib) |
networker | 0:7f26f0680202 | 132 | * - SetRealSerial() |
networker | 0:7f26f0680202 | 133 | * - 0.4.1: |
networker | 0:7f26f0680202 | 134 | * - Added support to change the RF address. |
networker | 0:7f26f0680202 | 135 | * - Added functions: (not in Knobloch lib) |
networker | 0:7f26f0680202 | 136 | * - SetRFMode() |
networker | 0:7f26f0680202 | 137 | * - GetRFMode() |
networker | 0:7f26f0680202 | 138 | * - Added support for functions: |
networker | 0:7f26f0680202 | 139 | * - GetFtManufacturerStrg() |
networker | 0:7f26f0680202 | 140 | * - GetFtShortNameStrg() |
networker | 0:7f26f0680202 | 141 | * - GetFtLongNameStrg() |
networker | 0:7f26f0680202 | 142 | * - GetFtLibErrorString() |
networker | 0:7f26f0680202 | 143 | * - Some minor Bug fixes |
networker | 0:7f26f0680202 | 144 | * - 0.4: |
networker | 0:7f26f0680202 | 145 | * - Hopefully support for more then one Robo Interface attached to an RF Link. |
networker | 0:7f26f0680202 | 146 | * - InitFtUsbDeviceList() will now also count the number of Robo Interfaces attached to an RF Link |
networker | 0:7f26f0680202 | 147 | * - Added support for the ft distance sensor |
networker | 0:7f26f0680202 | 148 | * - Added functions: |
networker | 0:7f26f0680202 | 149 | * - GetFtDeviceTypeString() (not in Knobloch lib) |
networker | 0:7f26f0680202 | 150 | * - Added support for functions: |
networker | 0:7f26f0680202 | 151 | * - SetFtDistanceSensorMode() |
networker | 0:7f26f0680202 | 152 | * - Python added functions: |
networker | 0:7f26f0680202 | 153 | * - GetNumFtUsbDevices() |
networker | 0:7f26f0680202 | 154 | * - RoboInterface.GetDeviceTypeString() |
networker | 0:7f26f0680202 | 155 | * - GetD1() |
networker | 0:7f26f0680202 | 156 | * - GetD2() |
networker | 0:7f26f0680202 | 157 | * - Added ft Diagnose utility. |
networker | 0:7f26f0680202 | 158 | * - 0.3: |
networker | 0:7f26f0680202 | 159 | * - added (overwrite) --target option to the ftuploader |
networker | 0:7f26f0680202 | 160 | * - included some documentation |
networker | 0:7f26f0680202 | 161 | * - minor fixes |
networker | 0:7f26f0680202 | 162 | * - enhanced python layer |
networker | 0:7f26f0680202 | 163 | * - support for RF Module |
networker | 0:7f26f0680202 | 164 | * - 0.2.1: |
networker | 0:7f26f0680202 | 165 | * - fixed Analog/Voltage Sensor calculations |
networker | 0:7f26f0680202 | 166 | * - 0.2: |
networker | 0:7f26f0680202 | 167 | * - added udev file |
networker | 0:7f26f0680202 | 168 | * - experimental support for uploading to the interface (usb only) |
networker | 0:7f26f0680202 | 169 | * - included program ftuploader |
networker | 0:7f26f0680202 | 170 | * - add support for functions: |
networker | 0:7f26f0680202 | 171 | * - DownloadFtProgram() |
networker | 0:7f26f0680202 | 172 | * - StartFtProgram() |
networker | 0:7f26f0680202 | 173 | * - StopFtProgram() |
networker | 0:7f26f0680202 | 174 | * - DeleteFtProgram() |
networker | 0:7f26f0680202 | 175 | * - SetFtProgramActiv() |
networker | 0:7f26f0680202 | 176 | * - GetFtProgramName() |
networker | 0:7f26f0680202 | 177 | * - GetFtStatus() |
networker | 0:7f26f0680202 | 178 | * - GetFtFirmware() |
networker | 0:7f26f0680202 | 179 | * - GetFtFirmwareStrg() |
networker | 0:7f26f0680202 | 180 | * - GetFtSerialNr() |
networker | 0:7f26f0680202 | 181 | * - GetFtSerialNrStrg() |
networker | 0:7f26f0680202 | 182 | * |
networker | 0:7f26f0680202 | 183 | * |
networker | 0:7f26f0680202 | 184 | * \section porting_sec Porting your program from the Knobloch Windows Library |
networker | 0:7f26f0680202 | 185 | * When porting your program from the Knobloch Library for Microsoft Windows operation systems please note the following: |
networker | 0:7f26f0680202 | 186 | * - The name of this library is libft, not ftlib (the Knobloch original) to follow the UNIX naming scheme |
networker | 0:7f26f0680202 | 187 | * - Types like DWORD are replaced with their logical ANSI-C counterparts, like |
networker | 0:7f26f0680202 | 188 | * -# DWORD - long int |
networker | 0:7f26f0680202 | 189 | * -# LPCSTR - char * |
networker | 0:7f26f0680202 | 190 | * -# LPVOID - void * |
networker | 0:7f26f0680202 | 191 | * -# BYTE - unsigned char |
networker | 0:7f26f0680202 | 192 | * -# USHORT - unsigned short int |
networker | 0:7f26f0680202 | 193 | * -# UINT - unsigned int |
networker | 0:7f26f0680202 | 194 | * -# UCHAR - unsigned char |
networker | 0:7f26f0680202 | 195 | * - The Windows Notifications stuff will probably never be supported. |
networker | 0:7f26f0680202 | 196 | * - Some return codes might be different, so if something is going wrong, check this manual. |
networker | 0:7f26f0680202 | 197 | * |
networker | 0:7f26f0680202 | 198 | */ |
networker | 0:7f26f0680202 | 199 | #define MBED |
networker | 0:7f26f0680202 | 200 | #define NOTNOW |
networker | 0:7f26f0680202 | 201 | #define SPLITTRANSFER |
networker | 0:7f26f0680202 | 202 | |
networker | 0:7f26f0680202 | 203 | #ifdef MBED |
networker | 0:7f26f0680202 | 204 | #include "mbed.h" |
networker | 0:7f26f0680202 | 205 | #define usleep(x) wait_us(x) |
networker | 0:7f26f0680202 | 206 | #define sleep(x) wait(x) |
networker | 0:7f26f0680202 | 207 | #define LIBFT_VERSION_MAJOR 1 |
networker | 0:7f26f0680202 | 208 | #define LIBFT_VERSION_MINOR 0 |
networker | 0:7f26f0680202 | 209 | #define LIBFT_VERSION_PATCH 0 |
networker | 1:2c9d412ad471 | 210 | Serial viaUsb(USBTX, USBRX); |
networker | 0:7f26f0680202 | 211 | #else |
networker | 0:7f26f0680202 | 212 | #include <stdio.h> |
networker | 0:7f26f0680202 | 213 | #include <string.h> |
networker | 0:7f26f0680202 | 214 | #include <pthread.h> |
networker | 0:7f26f0680202 | 215 | #include <semaphore.h> |
networker | 0:7f26f0680202 | 216 | #include <termios.h> |
networker | 0:7f26f0680202 | 217 | #include <fcntl.h> |
networker | 0:7f26f0680202 | 218 | #endif |
networker | 0:7f26f0680202 | 219 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 220 | #include <usb.h> |
networker | 0:7f26f0680202 | 221 | #else |
networker | 0:7f26f0680202 | 222 | //some dummy USB stuff |
networker | 0:7f26f0680202 | 223 | #endif |
networker | 0:7f26f0680202 | 224 | #ifdef USE_DOWNLOAD |
networker | 0:7f26f0680202 | 225 | #include "crc.h" |
networker | 0:7f26f0680202 | 226 | #endif |
networker | 0:7f26f0680202 | 227 | #include "ftlib.h" |
networker | 0:7f26f0680202 | 228 | |
networker | 0:7f26f0680202 | 229 | /** \cond doxygen ignore start */ |
networker | 0:7f26f0680202 | 230 | #define VERSION_MAJOR LIBFT_VERSION_MAJOR |
networker | 0:7f26f0680202 | 231 | #define VERSION_MINOR LIBFT_VERSION_MINOR |
networker | 0:7f26f0680202 | 232 | #define VERSION_PATCH LIBFT_VERSION_PATCH |
networker | 0:7f26f0680202 | 233 | #define FT_VENDOR_ID 0x146a |
networker | 0:7f26f0680202 | 234 | #define ROBO_IF_PRODUCT_ID 0x1 |
networker | 0:7f26f0680202 | 235 | #define EXT_IF_PRODUCT_ID 0x2 |
networker | 0:7f26f0680202 | 236 | #define RF_DATA_LINK_PRODUCT_ID 0x3 |
networker | 0:7f26f0680202 | 237 | #define ABF_IF_COMPLETE 0x8b // 0xf2 |
networker | 0:7f26f0680202 | 238 | #define INTERFACE_QUERY_TIME 10000 // �s == 5ms |
networker | 0:7f26f0680202 | 239 | #define INTERFACE_QUERY_TIME_SERIAL 10000 |
networker | 0:7f26f0680202 | 240 | #define FT_ENDPOINT_INTERRUPT_IN 0x81 |
networker | 0:7f26f0680202 | 241 | #define FT_ENDPOINT_INTERRUPT_OUT 0x1 |
networker | 0:7f26f0680202 | 242 | #define FT_ENDPOINT_BULK_IN 0x82 |
networker | 0:7f26f0680202 | 243 | #define FT_ENDPOINT_BULK_OUT 0x2 |
networker | 0:7f26f0680202 | 244 | #define FT_RF_ENDPOINT_INTERRUPT_IN 0x82 |
networker | 0:7f26f0680202 | 245 | #define FT_RF_ENDPOINT_INTERRUPT_OUT 0x2 |
networker | 0:7f26f0680202 | 246 | #define FT_USB_TIMEOUT 1000 |
networker | 0:7f26f0680202 | 247 | #define FT_USB_TIMEOUT_LONG 10000 |
networker | 0:7f26f0680202 | 248 | |
networker | 0:7f26f0680202 | 249 | #ifdef MBED |
networker | 0:7f26f0680202 | 250 | #define BAUDRATE_II 9600 |
networker | 0:7f26f0680202 | 251 | #define BAUDRATE_RI 38400 |
networker | 0:7f26f0680202 | 252 | #else |
networker | 0:7f26f0680202 | 253 | #define BAUDRATE_II B9600 |
networker | 0:7f26f0680202 | 254 | #define BAUDRATE_RI B38400 |
networker | 0:7f26f0680202 | 255 | #endif |
networker | 0:7f26f0680202 | 256 | #define PROGRAM_UPLOAD_PACKET_SIZE 128 |
networker | 0:7f26f0680202 | 257 | |
networker | 0:7f26f0680202 | 258 | #ifndef MIN |
networker | 0:7f26f0680202 | 259 | #define MIN(a, b) ( (a)<=(b) ? (a) : (b) ) |
networker | 0:7f26f0680202 | 260 | #endif |
networker | 0:7f26f0680202 | 261 | /** \endcond doxygen ignore end */ |
networker | 0:7f26f0680202 | 262 | |
networker | 0:7f26f0680202 | 263 | |
networker | 0:7f26f0680202 | 264 | /** |
networker | 0:7f26f0680202 | 265 | * \brief Returns lib version |
networker | 0:7f26f0680202 | 266 | * |
networker | 0:7f26f0680202 | 267 | * Returns the library version. |
networker | 0:7f26f0680202 | 268 | * |
networker | 0:7f26f0680202 | 269 | * @return version as Major Minor Patch |
networker | 0:7f26f0680202 | 270 | */ |
networker | 0:7f26f0680202 | 271 | long int GetLibVersion() { |
networker | 0:7f26f0680202 | 272 | return VERSION_MAJOR<<16 | VERSION_MINOR<<8 | VERSION_PATCH; |
networker | 0:7f26f0680202 | 273 | } |
networker | 0:7f26f0680202 | 274 | |
networker | 0:7f26f0680202 | 275 | |
networker | 0:7f26f0680202 | 276 | /** |
networker | 0:7f26f0680202 | 277 | * \brief Returns lib version |
networker | 0:7f26f0680202 | 278 | * |
networker | 0:7f26f0680202 | 279 | * Returns the library version. |
networker | 0:7f26f0680202 | 280 | * The allocated space should be freed with free() later. |
networker | 0:7f26f0680202 | 281 | * |
networker | 0:7f26f0680202 | 282 | * @return Pointer to a string with the serial |
networker | 0:7f26f0680202 | 283 | */ |
networker | 0:7f26f0680202 | 284 | char *GetLibVersionStrg() { |
networker | 0:7f26f0680202 | 285 | long int ver = GetLibVersion(); |
networker | 0:7f26f0680202 | 286 | char *s = (char *)malloc(16); |
networker | 0:7f26f0680202 | 287 | int byte1 = ver & 0xff; |
networker | 0:7f26f0680202 | 288 | int byte2 = (ver & 0xff00) >> 8; |
networker | 0:7f26f0680202 | 289 | int byte3 = (ver & 0xff0000) >> 16; |
networker | 0:7f26f0680202 | 290 | |
networker | 0:7f26f0680202 | 291 | snprintf(s, 16, "%d.%02d.%02d", byte3, byte2, byte1); |
networker | 0:7f26f0680202 | 292 | |
networker | 0:7f26f0680202 | 293 | return s; |
networker | 0:7f26f0680202 | 294 | } |
networker | 0:7f26f0680202 | 295 | |
networker | 0:7f26f0680202 | 296 | |
networker | 0:7f26f0680202 | 297 | /** |
networker | 0:7f26f0680202 | 298 | * \brief Library initialization (dummy) |
networker | 0:7f26f0680202 | 299 | * |
networker | 0:7f26f0680202 | 300 | * Dummy for compatibility. Only used in original library. |
networker | 0:7f26f0680202 | 301 | * @return Always FTLIB_ERR_SUCCESS |
networker | 0:7f26f0680202 | 302 | */ |
networker | 0:7f26f0680202 | 303 | long int InitFtLib() { |
networker | 0:7f26f0680202 | 304 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 305 | } |
networker | 0:7f26f0680202 | 306 | |
networker | 0:7f26f0680202 | 307 | |
networker | 0:7f26f0680202 | 308 | /** |
networker | 0:7f26f0680202 | 309 | * \brief Initiates and scans the USB bus |
networker | 0:7f26f0680202 | 310 | * |
networker | 0:7f26f0680202 | 311 | * This function has to be called before any other USB action. |
networker | 0:7f26f0680202 | 312 | * It will set up USB basic variables and then scan the USB bus. |
networker | 0:7f26f0680202 | 313 | * |
networker | 0:7f26f0680202 | 314 | * @return Always FTLIB_ERR_SUCCESS. Not able to fail. |
networker | 0:7f26f0680202 | 315 | */ |
networker | 0:7f26f0680202 | 316 | long int InitFtUsbDeviceList() { |
networker | 0:7f26f0680202 | 317 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 318 | usb_init(); |
networker | 0:7f26f0680202 | 319 | usb_find_busses(); |
networker | 0:7f26f0680202 | 320 | usb_find_devices(); |
networker | 0:7f26f0680202 | 321 | #endif |
networker | 0:7f26f0680202 | 322 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 323 | } |
networker | 0:7f26f0680202 | 324 | |
networker | 0:7f26f0680202 | 325 | |
networker | 0:7f26f0680202 | 326 | /** \cond doxygen ignore start */ |
networker | 0:7f26f0680202 | 327 | static unsigned int GetNumFtDevicesFromRF(struct usb_device *dev) { |
networker | 0:7f26f0680202 | 328 | unsigned int iNum = 0; |
networker | 0:7f26f0680202 | 329 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 330 | usb_dev_handle *device; |
networker | 0:7f26f0680202 | 331 | int ret; |
networker | 0:7f26f0680202 | 332 | unsigned char buffer[35] = { 0 }; |
networker | 0:7f26f0680202 | 333 | int i; |
networker | 0:7f26f0680202 | 334 | |
networker | 0:7f26f0680202 | 335 | device = usb_open(dev); |
networker | 0:7f26f0680202 | 336 | |
networker | 0:7f26f0680202 | 337 | for (i=1; i<9; i++) { |
networker | 0:7f26f0680202 | 338 | ret = usb_control_msg(device, 0xc0, 0x52, i<<8 | 0x05, 0, buffer, 35, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 339 | if (ret < 0) fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker | 0:7f26f0680202 | 340 | else if (buffer[0] == 0xfa && buffer[1] == 0) iNum++; // buffer[1] == 0xff => no device |
networker | 0:7f26f0680202 | 341 | } |
networker | 0:7f26f0680202 | 342 | |
networker | 0:7f26f0680202 | 343 | usb_close(device); |
networker | 0:7f26f0680202 | 344 | #endif |
networker | 0:7f26f0680202 | 345 | return iNum; |
networker | 0:7f26f0680202 | 346 | } |
networker | 0:7f26f0680202 | 347 | |
networker | 0:7f26f0680202 | 348 | |
networker | 0:7f26f0680202 | 349 | static unsigned int GetNthFtDeviceFromRF(struct usb_device *dev, int iNum) { |
networker | 0:7f26f0680202 | 350 | int ret=0; |
networker | 0:7f26f0680202 | 351 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 352 | usb_dev_handle *device; |
networker | 0:7f26f0680202 | 353 | unsigned char buffer[35] = { 0 }; |
networker | 0:7f26f0680202 | 354 | int i; |
networker | 0:7f26f0680202 | 355 | |
networker | 0:7f26f0680202 | 356 | device = usb_open(dev); |
networker | 0:7f26f0680202 | 357 | |
networker | 0:7f26f0680202 | 358 | for (i=1; i<9, iNum>0; i++) { |
networker | 0:7f26f0680202 | 359 | ret = usb_control_msg(device, 0xc0, 0x52, i<<8 | 0x05, 0, buffer, 35, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 360 | if (ret < 0) fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker | 0:7f26f0680202 | 361 | else if (buffer[0] == 0xfa && buffer[1] == 0) iNum--; // buffer[1] == 0xff => no device |
networker | 0:7f26f0680202 | 362 | |
networker | 0:7f26f0680202 | 363 | ret = i; |
networker | 0:7f26f0680202 | 364 | } |
networker | 0:7f26f0680202 | 365 | |
networker | 0:7f26f0680202 | 366 | usb_close(device); |
networker | 0:7f26f0680202 | 367 | #endif |
networker | 0:7f26f0680202 | 368 | return ret; |
networker | 0:7f26f0680202 | 369 | } |
networker | 0:7f26f0680202 | 370 | |
networker | 0:7f26f0680202 | 371 | |
networker | 0:7f26f0680202 | 372 | static int GetFtDeviceFromRFWithSerial(struct usb_device *dev, long int dwSN) { |
networker | 0:7f26f0680202 | 373 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 374 | usb_dev_handle *device; |
networker | 0:7f26f0680202 | 375 | int ret; |
networker | 0:7f26f0680202 | 376 | unsigned char buffer[35] = { 0 }; |
networker | 0:7f26f0680202 | 377 | int i; |
networker | 0:7f26f0680202 | 378 | long int serial; |
networker | 0:7f26f0680202 | 379 | |
networker | 0:7f26f0680202 | 380 | device = usb_open(dev); |
networker | 0:7f26f0680202 | 381 | |
networker | 0:7f26f0680202 | 382 | for (i=1; i<9; i++) { |
networker | 0:7f26f0680202 | 383 | ret = usb_control_msg(device, 0xc0, 0x52, i<<8 | 0x05, 0, buffer, 35, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 384 | if (ret < 0) fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker | 0:7f26f0680202 | 385 | else if (buffer[0] == 0xfa && buffer[1] == 0) { // buffer[1] == 0xff => no device |
networker | 0:7f26f0680202 | 386 | serial = buffer[6]<<24 | buffer[5]<<16 | buffer[4]<<8 | buffer[3]; |
networker | 0:7f26f0680202 | 387 | |
networker | 0:7f26f0680202 | 388 | if (serial == dwSN) { |
networker | 0:7f26f0680202 | 389 | return i; |
networker | 0:7f26f0680202 | 390 | } |
networker | 0:7f26f0680202 | 391 | } |
networker | 0:7f26f0680202 | 392 | } |
networker | 0:7f26f0680202 | 393 | |
networker | 0:7f26f0680202 | 394 | usb_close(device); |
networker | 0:7f26f0680202 | 395 | #endif |
networker | 0:7f26f0680202 | 396 | return 0; |
networker | 0:7f26f0680202 | 397 | } |
networker | 0:7f26f0680202 | 398 | /** \endcond doxygen ignore end */ |
networker | 0:7f26f0680202 | 399 | |
networker | 0:7f26f0680202 | 400 | |
networker | 0:7f26f0680202 | 401 | /** |
networker | 0:7f26f0680202 | 402 | * \brief Get the count of found ft Interfaces over USB. |
networker | 0:7f26f0680202 | 403 | * |
networker | 0:7f26f0680202 | 404 | * If we find a Robo RF Data Link we will count the devices attached to it instead |
networker | 0:7f26f0680202 | 405 | * |
networker | 0:7f26f0680202 | 406 | * @return Number of ft Interface devices on the USB bus found. |
networker | 0:7f26f0680202 | 407 | */ |
networker | 0:7f26f0680202 | 408 | unsigned int GetNumFtUsbDevice() { |
networker | 0:7f26f0680202 | 409 | unsigned int iNum = 0; |
networker | 0:7f26f0680202 | 410 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 411 | struct usb_device *dev; |
networker | 0:7f26f0680202 | 412 | struct usb_bus *busses; |
networker | 0:7f26f0680202 | 413 | struct usb_bus *bus; |
networker | 0:7f26f0680202 | 414 | busses = usb_get_busses(); |
networker | 0:7f26f0680202 | 415 | |
networker | 0:7f26f0680202 | 416 | for (bus = busses; bus; bus = bus->next) { |
networker | 0:7f26f0680202 | 417 | for (dev = bus->devices; dev; dev = dev->next) { |
networker | 0:7f26f0680202 | 418 | if (dev->descriptor.idVendor == FT_VENDOR_ID) { |
networker | 0:7f26f0680202 | 419 | if (dev->descriptor.idProduct == RF_DATA_LINK_PRODUCT_ID) { |
networker | 0:7f26f0680202 | 420 | iNum+=GetNumFtDevicesFromRF(dev); |
networker | 0:7f26f0680202 | 421 | } |
networker | 0:7f26f0680202 | 422 | iNum++; |
networker | 0:7f26f0680202 | 423 | } |
networker | 0:7f26f0680202 | 424 | } |
networker | 0:7f26f0680202 | 425 | } |
networker | 0:7f26f0680202 | 426 | #endif |
networker | 0:7f26f0680202 | 427 | return iNum; |
networker | 0:7f26f0680202 | 428 | } |
networker | 0:7f26f0680202 | 429 | |
networker | 0:7f26f0680202 | 430 | |
networker | 0:7f26f0680202 | 431 | /** \cond doxygen ignore start */ |
networker | 0:7f26f0680202 | 432 | static int FtproductIDToInterfaceID(int iProductID) { |
networker | 0:7f26f0680202 | 433 | switch (iProductID) { |
networker | 0:7f26f0680202 | 434 | case ROBO_IF_PRODUCT_ID: |
networker | 0:7f26f0680202 | 435 | return FT_ROBO_IF_USB; |
networker | 0:7f26f0680202 | 436 | case EXT_IF_PRODUCT_ID: |
networker | 0:7f26f0680202 | 437 | return FT_ROBO_IO_EXTENSION; |
networker | 0:7f26f0680202 | 438 | case RF_DATA_LINK_PRODUCT_ID: |
networker | 0:7f26f0680202 | 439 | return FT_ROBO_RF_DATA_LINK; |
networker | 0:7f26f0680202 | 440 | } |
networker | 0:7f26f0680202 | 441 | |
networker | 0:7f26f0680202 | 442 | return 0; |
networker | 0:7f26f0680202 | 443 | } |
networker | 0:7f26f0680202 | 444 | |
networker | 0:7f26f0680202 | 445 | |
networker | 0:7f26f0680202 | 446 | static int FtInterfaceIDToProductID(int InterfaceID) { |
networker | 0:7f26f0680202 | 447 | switch (InterfaceID) { |
networker | 0:7f26f0680202 | 448 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 449 | return ROBO_IF_PRODUCT_ID; |
networker | 0:7f26f0680202 | 450 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 451 | return EXT_IF_PRODUCT_ID; |
networker | 0:7f26f0680202 | 452 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 453 | return RF_DATA_LINK_PRODUCT_ID; |
networker | 0:7f26f0680202 | 454 | } |
networker | 0:7f26f0680202 | 455 | |
networker | 0:7f26f0680202 | 456 | return 0; |
networker | 0:7f26f0680202 | 457 | } |
networker | 0:7f26f0680202 | 458 | /** \endcond doxygen ignore end */ |
networker | 0:7f26f0680202 | 459 | |
networker | 0:7f26f0680202 | 460 | |
networker | 0:7f26f0680202 | 461 | /** |
networker | 0:7f26f0680202 | 462 | * \brief Gets the handle to a ft USB device. |
networker | 0:7f26f0680202 | 463 | * |
networker | 0:7f26f0680202 | 464 | * Get the handle for the ft USB device with this number. |
networker | 0:7f26f0680202 | 465 | * Passing just 0 as argument will use the first device found. |
networker | 0:7f26f0680202 | 466 | * |
networker | 0:7f26f0680202 | 467 | * Count the interfaces with GetNumFtUsbDevice() |
networker | 0:7f26f0680202 | 468 | * |
networker | 0:7f26f0680202 | 469 | * @see GetNumFtUsbDevice() |
networker | 0:7f26f0680202 | 470 | * @param Num selected Interface. If unsure try 0. |
networker | 0:7f26f0680202 | 471 | * @return The ft device or NULL if error |
networker | 0:7f26f0680202 | 472 | */ |
networker | 0:7f26f0680202 | 473 | FT_HANDLE GetFtUsbDeviceHandle(unsigned char Num) { |
networker | 0:7f26f0680202 | 474 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 475 | struct usb_device *dev; |
networker | 0:7f26f0680202 | 476 | struct usb_bus *busses; |
networker | 0:7f26f0680202 | 477 | struct usb_bus *bus; |
networker | 0:7f26f0680202 | 478 | int i=0; |
networker | 0:7f26f0680202 | 479 | FT_HANDLE ret; |
networker | 0:7f26f0680202 | 480 | int count_ri_at_rf; |
networker | 0:7f26f0680202 | 481 | busses = usb_get_busses(); |
networker | 0:7f26f0680202 | 482 | |
networker | 0:7f26f0680202 | 483 | for (bus = busses; bus; bus = bus->next) { |
networker | 0:7f26f0680202 | 484 | for (dev = bus->devices; dev; dev = dev->next) { |
networker | 0:7f26f0680202 | 485 | if (dev->descriptor.idVendor == FT_VENDOR_ID) { |
networker | 0:7f26f0680202 | 486 | if (dev->descriptor.idProduct == RF_DATA_LINK_PRODUCT_ID) { |
networker | 0:7f26f0680202 | 487 | count_ri_at_rf = GetNumFtDevicesFromRF(dev); |
networker | 0:7f26f0680202 | 488 | i+=count_ri_at_rf; |
networker | 0:7f26f0680202 | 489 | } |
networker | 0:7f26f0680202 | 490 | if (i >= Num) { // '>=' because any RF will add more then 1 to the count |
networker | 0:7f26f0680202 | 491 | ret = (FT_HANDLE) malloc (sizeof(struct ft_handle_devices)); |
networker | 0:7f26f0680202 | 492 | if (ret == NULL) { |
networker | 0:7f26f0680202 | 493 | perror("GetFtUsbDeviceHandle malloc"); |
networker | 0:7f26f0680202 | 494 | return NULL; |
networker | 0:7f26f0680202 | 495 | } |
networker | 0:7f26f0680202 | 496 | ret->device = NULL; |
networker | 0:7f26f0680202 | 497 | ret->dev = dev; |
networker | 0:7f26f0680202 | 498 | ret->sdev = 0; |
networker | 0:7f26f0680202 | 499 | ret->type = FtproductIDToInterfaceID(dev->descriptor.idProduct); |
networker | 0:7f26f0680202 | 500 | sem_init(&ret->lock, 0, 1); |
networker | 0:7f26f0680202 | 501 | memset(&ret->transfer_area, 0, sizeof(struct _FT_TRANSFER_AREA)); |
networker | 0:7f26f0680202 | 502 | ret->transfer_area.TransferAktiv = 0; |
networker | 0:7f26f0680202 | 503 | ret->query_time = INTERFACE_QUERY_TIME; |
networker | 0:7f26f0680202 | 504 | ret->transfer_area.RfModulNr = -1; |
networker | 0:7f26f0680202 | 505 | ret->interface_connected = 0; |
networker | 0:7f26f0680202 | 506 | |
networker | 0:7f26f0680202 | 507 | if (dev->descriptor.idProduct == RF_DATA_LINK_PRODUCT_ID) { |
networker | 0:7f26f0680202 | 508 | ret->transfer_area.RfModulNr = GetNthFtDeviceFromRF(dev, Num); |
networker | 0:7f26f0680202 | 509 | if (ret->transfer_area.RfModulNr == 0) // user has chosen the RF Modul, so choose the first Interface at RF for the user |
networker | 0:7f26f0680202 | 510 | ret->transfer_area.RfModulNr = GetNthFtDeviceFromRF(dev, 1); |
networker | 0:7f26f0680202 | 511 | else |
networker | 0:7f26f0680202 | 512 | ret->type = FT_ROBO_IF_OVER_RF; |
networker | 0:7f26f0680202 | 513 | } |
networker | 0:7f26f0680202 | 514 | |
networker | 0:7f26f0680202 | 515 | return ret; |
networker | 0:7f26f0680202 | 516 | } |
networker | 0:7f26f0680202 | 517 | i++; |
networker | 0:7f26f0680202 | 518 | } |
networker | 0:7f26f0680202 | 519 | } |
networker | 0:7f26f0680202 | 520 | } |
networker | 0:7f26f0680202 | 521 | #endif |
networker | 0:7f26f0680202 | 522 | return NULL; |
networker | 0:7f26f0680202 | 523 | } |
networker | 0:7f26f0680202 | 524 | |
networker | 0:7f26f0680202 | 525 | |
networker | 0:7f26f0680202 | 526 | /** |
networker | 0:7f26f0680202 | 527 | * \brief Gets the handle to a ft USB device with a specific serial number. |
networker | 0:7f26f0680202 | 528 | * |
networker | 0:7f26f0680202 | 529 | * Get the handle for the ft USB device with this number. |
networker | 0:7f26f0680202 | 530 | * Serial is 1 for most devices, unless explicitly changed in the device. |
networker | 0:7f26f0680202 | 531 | * Second argument can be FT_AUTO_TYPE. |
networker | 0:7f26f0680202 | 532 | * |
networker | 0:7f26f0680202 | 533 | * @param dwSN Serial of the USB Device |
networker | 0:7f26f0680202 | 534 | * @param dwTyp Type of the USB Device: FT_AUTO_TYPE, FT_ROBO_IF_USB, FT_ROBO_IO_EXTENSION, FT_ROBO_IF_OVER_RF or FT_ROBO_RF_DATA_LINK |
networker | 0:7f26f0680202 | 535 | * @return The ft device or NULL on error |
networker | 0:7f26f0680202 | 536 | */ |
networker | 0:7f26f0680202 | 537 | FT_HANDLE GetFtUsbDeviceHandleSerialNr(long int dwSN, long int dwTyp) { |
networker | 0:7f26f0680202 | 538 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 539 | int i; |
networker | 0:7f26f0680202 | 540 | FT_HANDLE ret; |
networker | 0:7f26f0680202 | 541 | for (i=0; i < GetNumFtUsbDevice(); i++) { |
networker | 0:7f26f0680202 | 542 | ret = GetFtUsbDeviceHandle(i); |
networker | 0:7f26f0680202 | 543 | OpenFtUsbDevice(ret); |
networker | 0:7f26f0680202 | 544 | |
networker | 0:7f26f0680202 | 545 | if ((dwTyp == FT_AUTO_TYPE || ret->type == dwTyp) && GetFtSerialNr(ret) == dwSN) { |
networker | 0:7f26f0680202 | 546 | CloseFtDevice(ret); |
networker | 0:7f26f0680202 | 547 | return ret; |
networker | 0:7f26f0680202 | 548 | } |
networker | 0:7f26f0680202 | 549 | |
networker | 0:7f26f0680202 | 550 | CloseFtDevice(ret); |
networker | 0:7f26f0680202 | 551 | } |
networker | 0:7f26f0680202 | 552 | #endif |
networker | 0:7f26f0680202 | 553 | return NULL; |
networker | 0:7f26f0680202 | 554 | } |
networker | 0:7f26f0680202 | 555 | |
networker | 0:7f26f0680202 | 556 | |
networker | 0:7f26f0680202 | 557 | //blocking |
networker | 0:7f26f0680202 | 558 | int read(Serial *d, unsigned char *ptr, int n) { |
networker | 0:7f26f0680202 | 559 | for (int i = 0; i< n; i++) { |
networker | 0:7f26f0680202 | 560 | ptr[i] = d->getc(); |
networker | 0:7f26f0680202 | 561 | } |
networker | 0:7f26f0680202 | 562 | return n; |
networker | 0:7f26f0680202 | 563 | } |
networker | 0:7f26f0680202 | 564 | int read(Serial *stream, unsigned char *buf, int n, int timeout_ms) { |
networker | 0:7f26f0680202 | 565 | Timer t; |
networker | 0:7f26f0680202 | 566 | t.start(); |
networker | 0:7f26f0680202 | 567 | int i = 0; |
networker | 0:7f26f0680202 | 568 | while (t.read_ms() < timeout_ms && i < n) { |
networker | 0:7f26f0680202 | 569 | if (stream->readable()) |
networker | 0:7f26f0680202 | 570 | buf[i++] = stream->getc(); |
networker | 0:7f26f0680202 | 571 | } |
networker | 0:7f26f0680202 | 572 | return i; |
networker | 0:7f26f0680202 | 573 | } |
networker | 0:7f26f0680202 | 574 | |
networker | 0:7f26f0680202 | 575 | //blocking |
networker | 0:7f26f0680202 | 576 | int write(Serial *d, unsigned char *ptr, int n) { |
networker | 0:7f26f0680202 | 577 | for (int i = 0; i< n; i++) { |
networker | 0:7f26f0680202 | 578 | d->putc(ptr[i]); |
networker | 0:7f26f0680202 | 579 | } |
networker | 0:7f26f0680202 | 580 | return n; |
networker | 0:7f26f0680202 | 581 | } |
networker | 0:7f26f0680202 | 582 | int write(Serial *d, unsigned char *ptr, int n, int timeout_ms) { |
networker | 0:7f26f0680202 | 583 | Timer t; |
networker | 0:7f26f0680202 | 584 | t.start(); |
networker | 0:7f26f0680202 | 585 | int i = 0; |
networker | 0:7f26f0680202 | 586 | while (t.read_ms() < timeout_ms && i < n) { |
networker | 0:7f26f0680202 | 587 | if (d->writeable()) |
networker | 0:7f26f0680202 | 588 | d->putc(ptr[i++]); |
networker | 0:7f26f0680202 | 589 | } |
networker | 0:7f26f0680202 | 590 | return i; |
networker | 0:7f26f0680202 | 591 | } |
networker | 0:7f26f0680202 | 592 | |
networker | 0:7f26f0680202 | 593 | //non-blocking |
networker | 0:7f26f0680202 | 594 | int ft_handle_devices::write() { |
networker | 0:7f26f0680202 | 595 | windex = 0; |
networker | 0:7f26f0680202 | 596 | //sdev->attach(this, &ft_handle_devices::writeByte, Serial::TxIrq);//could be moved to FtThreadInit |
networker | 0:7f26f0680202 | 597 | //sdev->attach(this, &ft_handle_devices::readByte, Serial::RxIrq); |
networker | 0:7f26f0680202 | 598 | writeByte(); //write the first byte, callback will take care of the rest |
networker | 0:7f26f0680202 | 599 | return num_write; |
networker | 0:7f26f0680202 | 600 | } |
networker | 0:7f26f0680202 | 601 | void ft_handle_devices::writeByte() { |
networker | 0:7f26f0680202 | 602 | if (windex < num_write) { |
networker | 0:7f26f0680202 | 603 | sdev->putc(out[windex++]); |
networker | 0:7f26f0680202 | 604 | if (windex == num_write) |
networker | 0:7f26f0680202 | 605 | rindex = 0; |
networker | 0:7f26f0680202 | 606 | } |
networker | 0:7f26f0680202 | 607 | } |
networker | 0:7f26f0680202 | 608 | void ft_handle_devices::readByte() { |
networker | 0:7f26f0680202 | 609 | if (rindex < num_read) { |
networker | 0:7f26f0680202 | 610 | in[rindex++] = sdev->getc(); |
networker | 0:7f26f0680202 | 611 | if (rindex == num_read) { |
networker | 0:7f26f0680202 | 612 | //sdev->attach(0,Serial::RxIrq);//could be moved to FtThreadFinish |
networker | 0:7f26f0680202 | 613 | //sdev->attach(0,Serial::TxIrq); |
networker | 0:7f26f0680202 | 614 | FtThreadEnd(); |
networker | 0:7f26f0680202 | 615 | } |
networker | 0:7f26f0680202 | 616 | } |
networker | 0:7f26f0680202 | 617 | } |
networker | 0:7f26f0680202 | 618 | /** |
networker | 0:7f26f0680202 | 619 | * \brief Gets the handle to a ft serial device. |
networker | 0:7f26f0680202 | 620 | * |
networker | 0:7f26f0680202 | 621 | * Get the handle for the ft Serial device at the selected serial port. |
networker | 0:7f26f0680202 | 622 | * |
networker | 0:7f26f0680202 | 623 | * @param sDevice filename of your serial device, like /dev/ttyS0. |
networker | 0:7f26f0680202 | 624 | * @param dwTyp Interface type. FT_INTELLIGENT_IF, FT_INTELLIGENT_IF_SLAVE or FT_ROBO_IF_COM. |
networker | 0:7f26f0680202 | 625 | * @param dwZyklus Cycle to retrieve analog values (only II). Try 10. |
networker | 0:7f26f0680202 | 626 | * @return The ft device or NULL if error. |
networker | 0:7f26f0680202 | 627 | */ |
networker | 0:7f26f0680202 | 628 | FT_HANDLE OpenFtCommDevice(char *sDevice, long int dwTyp, long int dwZyklus) {//makes a (blocking) comm request to the interface |
networker | 0:7f26f0680202 | 629 | FT_HANDLE ret; |
networker | 0:7f26f0680202 | 630 | unsigned char in[5]; |
networker | 0:7f26f0680202 | 631 | unsigned char on[] = " ft-Robo-ON-V1"; |
networker | 0:7f26f0680202 | 632 | on[0] = 0xA1; |
networker | 0:7f26f0680202 | 633 | #ifdef MBED |
networker | 0:7f26f0680202 | 634 | Serial *dev; |
networker | 0:7f26f0680202 | 635 | switch (sDevice[3]) { |
networker | 0:7f26f0680202 | 636 | case '1': |
networker | 0:7f26f0680202 | 637 | dev = new Serial(p9, p10); |
networker | 0:7f26f0680202 | 638 | break; |
networker | 0:7f26f0680202 | 639 | case '2': |
networker | 0:7f26f0680202 | 640 | dev = new Serial(p13, p14); |
networker | 0:7f26f0680202 | 641 | break; |
networker | 0:7f26f0680202 | 642 | case '3': |
networker | 0:7f26f0680202 | 643 | dev = new Serial(p28, p27); |
networker | 0:7f26f0680202 | 644 | break; |
networker | 0:7f26f0680202 | 645 | // default: dev = new Serial(p9, p10); break; |
networker | 0:7f26f0680202 | 646 | default: |
networker | 0:7f26f0680202 | 647 | dev = &viaUsb; |
networker | 0:7f26f0680202 | 648 | break; |
networker | 0:7f26f0680202 | 649 | } |
networker | 0:7f26f0680202 | 650 | ret = new ft_handle_devices; |
networker | 0:7f26f0680202 | 651 | #else |
networker | 0:7f26f0680202 | 652 | long int dev; |
networker | 0:7f26f0680202 | 653 | if ((dev = open(sDevice, O_RDWR | O_NOCTTY)) < 0) { |
networker | 0:7f26f0680202 | 654 | perror("OpenFtCommDevice open"); |
networker | 0:7f26f0680202 | 655 | return NULL; |
networker | 0:7f26f0680202 | 656 | } |
networker | 0:7f26f0680202 | 657 | |
networker | 0:7f26f0680202 | 658 | if ((ret = (FT_HANDLE) malloc (sizeof(struct ft_handle_devices))) == NULL) { |
networker | 0:7f26f0680202 | 659 | perror("GetFtUsbDeviceHandle malloc"); |
networker | 0:7f26f0680202 | 660 | return NULL; |
networker | 0:7f26f0680202 | 661 | } |
networker | 0:7f26f0680202 | 662 | ret->device = NULL; |
networker | 0:7f26f0680202 | 663 | ret->dev = NULL; |
networker | 0:7f26f0680202 | 664 | #endif |
networker | 0:7f26f0680202 | 665 | ret->type = dwTyp; |
networker | 0:7f26f0680202 | 666 | memset(&ret->transfer_area, 0, sizeof(struct _FT_TRANSFER_AREA)); |
networker | 0:7f26f0680202 | 667 | ret->transfer_area.TransferAktiv = 0; |
networker | 0:7f26f0680202 | 668 | ret->analogcycle = dwZyklus/2.0+0.5; |
networker | 0:7f26f0680202 | 669 | ret->query_time = INTERFACE_QUERY_TIME_SERIAL; |
networker | 0:7f26f0680202 | 670 | ret->transfer_area.RfModulNr = -1; |
networker | 0:7f26f0680202 | 671 | ret->interface_connected = 0; |
networker | 0:7f26f0680202 | 672 | #ifdef MBED |
networker | 0:7f26f0680202 | 673 | ret->lock = 1; //init the semaphore |
networker | 0:7f26f0680202 | 674 | if (dev != &viaUsb) { |
networker | 0:7f26f0680202 | 675 | if (dwTyp == FT_INTELLIGENT_IF || dwTyp == FT_INTELLIGENT_IF_SLAVE || dwTyp == FT_ROBO_IF_IIM) |
networker | 0:7f26f0680202 | 676 | dev->baud(BAUDRATE_II); |
networker | 0:7f26f0680202 | 677 | else // dwTyp == FT_ROBO_IF_COM |
networker | 0:7f26f0680202 | 678 | dev->baud(BAUDRATE_RI); |
networker | 0:7f26f0680202 | 679 | } |
networker | 0:7f26f0680202 | 680 | ret->sdev = dev; |
networker | 0:7f26f0680202 | 681 | if (dwTyp == FT_INTELLIGENT_IF) ret->transfer_area.BusModules = 1; |
networker | 0:7f26f0680202 | 682 | else if (dwTyp == FT_INTELLIGENT_IF_SLAVE) ret->transfer_area.BusModules = 2; |
networker | 0:7f26f0680202 | 683 | printf("about to send '%s'\n", on); |
networker | 0:7f26f0680202 | 684 | if (dwTyp == FT_ROBO_IF_COM) { |
networker | 0:7f26f0680202 | 685 | int sent = write(dev, on, strlen((const char*)on), 100/*ms*/); |
networker | 0:7f26f0680202 | 686 | // int sent = dev->printf("%s", on); |
networker | 0:7f26f0680202 | 687 | printf("sent %d bytes to COM\n", sent); |
networker | 0:7f26f0680202 | 688 | if (sent == strlen((const char*)on)) { |
networker | 0:7f26f0680202 | 689 | if (read(dev, in, 5, 1000/*ms*/) == 5) { // if (dev->scanf("%5c", in) == 1) { does not work, could have to do with NUL chars or needs a lookahead char |
networker | 0:7f26f0680202 | 690 | printf("%02X: interface version: %d.%d.%d.%d\n", in[0], in[4], in[3], in[2], in[1]); |
networker | 0:7f26f0680202 | 691 | if ((in[0] ^ on[0]) == 0x0FFU) { |
networker | 0:7f26f0680202 | 692 | printf("opening of %s OK\n", sDevice); |
networker | 0:7f26f0680202 | 693 | } else { |
networker | 0:7f26f0680202 | 694 | printf("return code is %02X but should be %02X\n", in[0], ~on[0]&0xFF); |
networker | 0:7f26f0680202 | 695 | delete ret; |
networker | 0:7f26f0680202 | 696 | return NULL; |
networker | 0:7f26f0680202 | 697 | } |
networker | 0:7f26f0680202 | 698 | } else { |
networker | 0:7f26f0680202 | 699 | printf("read did not return 5\n"); |
networker | 0:7f26f0680202 | 700 | delete ret; |
networker | 0:7f26f0680202 | 701 | return NULL; |
networker | 0:7f26f0680202 | 702 | } |
networker | 0:7f26f0680202 | 703 | } else { |
networker | 0:7f26f0680202 | 704 | printf("only %d chars were sent i.o %d\n", sent, strlen((const char*)on)); |
networker | 0:7f26f0680202 | 705 | delete ret; |
networker | 0:7f26f0680202 | 706 | return NULL; |
networker | 0:7f26f0680202 | 707 | } |
networker | 0:7f26f0680202 | 708 | } |
networker | 0:7f26f0680202 | 709 | //printf("OpenFtCommDevice: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 710 | //delete ret; |
networker | 0:7f26f0680202 | 711 | //return NULL; |
networker | 0:7f26f0680202 | 712 | //} |
networker | 0:7f26f0680202 | 713 | #else |
networker | 0:7f26f0680202 | 714 | sem_init(&ret->lock, 0, 1); |
networker | 0:7f26f0680202 | 715 | tcgetattr(dev, &ret->saveioset); /* save current modem settings */ |
networker | 0:7f26f0680202 | 716 | bzero(&ret->newioset, sizeof(struct termios)); |
networker | 0:7f26f0680202 | 717 | ret->newioset.c_cflag = CS8 | CLOCAL | CREAD; |
networker | 0:7f26f0680202 | 718 | if (dwTyp == FT_INTELLIGENT_IF || dwTyp == FT_INTELLIGENT_IF_SLAVE || dwTyp == FT_ROBO_IF_IIM) |
networker | 0:7f26f0680202 | 719 | ret->newioset.c_cflag |= BAUDRATE_II; |
networker | 0:7f26f0680202 | 720 | else // dwTyp == FT_ROBO_IF_COM |
networker | 0:7f26f0680202 | 721 | ret->newioset.c_cflag |= BAUDRATE_RI; |
networker | 0:7f26f0680202 | 722 | ret->newioset.c_oflag = 0; |
networker | 0:7f26f0680202 | 723 | ret->newioset.c_lflag = 0; |
networker | 0:7f26f0680202 | 724 | ret->newioset.c_cc[VTIME] = 1; |
networker | 0:7f26f0680202 | 725 | ret->newioset.c_cc[VMIN] = 0; |
networker | 0:7f26f0680202 | 726 | tcflush(dev, TCIFLUSH); |
networker | 0:7f26f0680202 | 727 | tcsetattr(dev, TCSANOW, &ret->newioset); |
networker | 0:7f26f0680202 | 728 | ret->sdev = dev; |
networker | 0:7f26f0680202 | 729 | if (dwTyp == FT_INTELLIGENT_IF) ret->transfer_area.BusModules = 1; |
networker | 0:7f26f0680202 | 730 | else if (dwTyp == FT_INTELLIGENT_IF_SLAVE) ret->transfer_area.BusModules = 2; |
networker | 0:7f26f0680202 | 731 | |
networker | 0:7f26f0680202 | 732 | if (dwTyp == FT_ROBO_IF_COM && ((write(dev, &on, 14)) != 14 || (read(dev, &in, 5)) != 5 || in[0] != 0x5E)) { |
networker | 0:7f26f0680202 | 733 | fprintf(stderr, "OpenFtCommDevice: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 734 | free(ret); |
networker | 0:7f26f0680202 | 735 | return NULL; |
networker | 0:7f26f0680202 | 736 | } |
networker | 0:7f26f0680202 | 737 | #endif |
networker | 0:7f26f0680202 | 738 | return ret; |
networker | 0:7f26f0680202 | 739 | } |
networker | 0:7f26f0680202 | 740 | |
networker | 0:7f26f0680202 | 741 | |
networker | 0:7f26f0680202 | 742 | /** |
networker | 0:7f26f0680202 | 743 | * \brief Returns type of the interface |
networker | 0:7f26f0680202 | 744 | * |
networker | 0:7f26f0680202 | 745 | * This function will return the type of the interface that is behind the handle. |
networker | 0:7f26f0680202 | 746 | * |
networker | 0:7f26f0680202 | 747 | * @param hFt Handle of the device |
networker | 0:7f26f0680202 | 748 | * @return NO_FT_DEVICE, FT_INTELLIGENT_IF, FT_INTELLIGENT_IF_SLAVE, FT_ROBO_IF_COM, FT_ROBO_IF_USB, FT_ROBO_IF_IIM, FT_ROBO_IF_OVER_RF, FT_ROBO_IO_EXTENSION or FT_ROBO_RF_DATA_LINK |
networker | 0:7f26f0680202 | 749 | */ |
networker | 0:7f26f0680202 | 750 | long int GetFtDeviceTyp(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 751 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 752 | fprintf(stderr, "GetFtDeviceTyp: No such device\n"); |
networker | 0:7f26f0680202 | 753 | return NO_FT_DEVICE; |
networker | 0:7f26f0680202 | 754 | } |
networker | 0:7f26f0680202 | 755 | |
networker | 0:7f26f0680202 | 756 | return hFt->type; |
networker | 0:7f26f0680202 | 757 | } |
networker | 0:7f26f0680202 | 758 | |
networker | 0:7f26f0680202 | 759 | |
networker | 0:7f26f0680202 | 760 | /** |
networker | 0:7f26f0680202 | 761 | * \brief Returns a string that identifies the interface with human words |
networker | 0:7f26f0680202 | 762 | * |
networker | 0:7f26f0680202 | 763 | * This function will give you a human readable string like "Robo Interface" you can work with. |
networker | 0:7f26f0680202 | 764 | * |
networker | 0:7f26f0680202 | 765 | * @param hFt Handle of the device |
networker | 0:7f26f0680202 | 766 | * @param dest Buffer we can write the string to |
networker | 0:7f26f0680202 | 767 | * @param len Maximum length of this buffer |
networker | 0:7f26f0680202 | 768 | * @return FTLIB_ERR_SUCCESS or a failure |
networker | 0:7f26f0680202 | 769 | */ |
networker | 0:7f26f0680202 | 770 | long int GetFtDeviceTypeString(FT_HANDLE hFt, char *dest, int len) { |
networker | 0:7f26f0680202 | 771 | // Todo: Maybe let usb query the string from the device? |
networker | 0:7f26f0680202 | 772 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 773 | fprintf(stderr, "GetFtDeviceTyp: No such device\n"); |
networker | 0:7f26f0680202 | 774 | return NO_FT_DEVICE; |
networker | 0:7f26f0680202 | 775 | } |
networker | 0:7f26f0680202 | 776 | |
networker | 0:7f26f0680202 | 777 | switch (GetFtDeviceTyp(hFt)) { |
networker | 0:7f26f0680202 | 778 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 779 | strncpy(dest, "Intelligent Interface", len); |
networker | 0:7f26f0680202 | 780 | break; |
networker | 0:7f26f0680202 | 781 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 782 | strncpy(dest, "Intelligent Interface with slave", len); |
networker | 0:7f26f0680202 | 783 | break; |
networker | 0:7f26f0680202 | 784 | case FT_ROBO_IF_IIM: |
networker | 0:7f26f0680202 | 785 | strncpy(dest, "Robo Interface II mode", len); |
networker | 0:7f26f0680202 | 786 | break; |
networker | 0:7f26f0680202 | 787 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 788 | strncpy(dest, "Robo Interface over serial", len); |
networker | 0:7f26f0680202 | 789 | break; |
networker | 0:7f26f0680202 | 790 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 791 | strncpy(dest, "Robo Interface over USB", len); |
networker | 0:7f26f0680202 | 792 | break; |
networker | 0:7f26f0680202 | 793 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 794 | strncpy(dest, "Robo IO Extension", len); |
networker | 0:7f26f0680202 | 795 | break; |
networker | 0:7f26f0680202 | 796 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 797 | strncpy(dest, "Robo RF Datalink", len); |
networker | 0:7f26f0680202 | 798 | break; |
networker | 0:7f26f0680202 | 799 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 800 | strncpy(dest, "Robo Interface over RF Datalink", len); |
networker | 0:7f26f0680202 | 801 | break; |
networker | 0:7f26f0680202 | 802 | default: |
networker | 0:7f26f0680202 | 803 | strncpy(dest, "Unknown", len); |
networker | 0:7f26f0680202 | 804 | } |
networker | 0:7f26f0680202 | 805 | |
networker | 0:7f26f0680202 | 806 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 807 | } |
networker | 0:7f26f0680202 | 808 | |
networker | 0:7f26f0680202 | 809 | |
networker | 0:7f26f0680202 | 810 | |
networker | 0:7f26f0680202 | 811 | /** |
networker | 0:7f26f0680202 | 812 | * \brief Opens this USB device. |
networker | 0:7f26f0680202 | 813 | * |
networker | 0:7f26f0680202 | 814 | * This function will try to open the ft USB device that belongs to the ft handle hFt. |
networker | 0:7f26f0680202 | 815 | * You can get the ft handle with GetFtUsbDeviceHandle() or GetFtUsbDeviceHandleSerialNr(). |
networker | 0:7f26f0680202 | 816 | * |
networker | 0:7f26f0680202 | 817 | * @see GetFtUsbDeviceHandle() |
networker | 0:7f26f0680202 | 818 | * @see GetFtUsbDeviceHandleSerialNr() |
networker | 0:7f26f0680202 | 819 | * @param hFt ft USB Device to open |
networker | 0:7f26f0680202 | 820 | * @return Number >= 0 on success, < 0 on error |
networker | 0:7f26f0680202 | 821 | */ |
networker | 0:7f26f0680202 | 822 | long int OpenFtUsbDevice(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 823 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 824 | long int ret; |
networker | 0:7f26f0680202 | 825 | |
networker | 0:7f26f0680202 | 826 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 827 | fprintf(stderr, "OpenFtUsbDevice: No such device\n"); |
networker | 0:7f26f0680202 | 828 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 829 | } |
networker | 0:7f26f0680202 | 830 | hFt->device = usb_open(hFt->dev); |
networker | 0:7f26f0680202 | 831 | ret = usb_claim_interface(hFt->device, 0); |
networker | 0:7f26f0680202 | 832 | if (ret < 0) perror("usb_claim_interface"); |
networker | 0:7f26f0680202 | 833 | |
networker | 0:7f26f0680202 | 834 | return ret; |
networker | 0:7f26f0680202 | 835 | #else |
networker | 0:7f26f0680202 | 836 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 837 | #endif |
networker | 0:7f26f0680202 | 838 | } |
networker | 0:7f26f0680202 | 839 | |
networker | 0:7f26f0680202 | 840 | |
networker | 0:7f26f0680202 | 841 | /** |
networker | 0:7f26f0680202 | 842 | * \brief Close the ft Device |
networker | 0:7f26f0680202 | 843 | * |
networker | 0:7f26f0680202 | 844 | * This function will close the ft Device and free its memory. |
networker | 0:7f26f0680202 | 845 | * |
networker | 0:7f26f0680202 | 846 | * @param hFt Handle of the Device to close. |
networker | 0:7f26f0680202 | 847 | * @return A number < 0 on error. |
networker | 0:7f26f0680202 | 848 | */ |
networker | 0:7f26f0680202 | 849 | long int CloseFtDevice(FT_HANDLE hFt) {//sends a comm request |
networker | 0:7f26f0680202 | 850 | int ret = 0; |
networker | 0:7f26f0680202 | 851 | unsigned char off = 0xA2; |
networker | 0:7f26f0680202 | 852 | unsigned char in[1]; |
networker | 0:7f26f0680202 | 853 | unsigned char buf[1]; |
networker | 0:7f26f0680202 | 854 | |
networker | 0:7f26f0680202 | 855 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 856 | fprintf(stderr, "CloseFtDevice: No such device\n"); |
networker | 0:7f26f0680202 | 857 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 858 | } |
networker | 0:7f26f0680202 | 859 | |
networker | 0:7f26f0680202 | 860 | while (hFt->transfer_area.TransferAktiv != 0) { |
networker | 0:7f26f0680202 | 861 | fprintf(stderr, "Transfer area still active\n"); |
networker | 0:7f26f0680202 | 862 | sleep(1); |
networker | 0:7f26f0680202 | 863 | } |
networker | 0:7f26f0680202 | 864 | |
networker | 0:7f26f0680202 | 865 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 866 | // usb |
networker | 0:7f26f0680202 | 867 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 868 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 869 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 870 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 871 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 872 | ret = usb_release_interface(hFt->device, 0); |
networker | 0:7f26f0680202 | 873 | if (ret < 0) { |
networker | 0:7f26f0680202 | 874 | fprintf(stderr, "CloseFtDevice(): Error in usb_release_interface()\n"); |
networker | 0:7f26f0680202 | 875 | break; |
networker | 0:7f26f0680202 | 876 | } |
networker | 0:7f26f0680202 | 877 | ret = usb_close(hFt->device); |
networker | 0:7f26f0680202 | 878 | break; |
networker | 0:7f26f0680202 | 879 | #endif |
networker | 0:7f26f0680202 | 880 | // serial |
networker | 0:7f26f0680202 | 881 | #ifdef MBED |
networker | 0:7f26f0680202 | 882 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 883 | if (write(hFt->sdev, &off, 1) != 1 || read(hFt->sdev, in, 1) != 1 || (in[0]^off != 0xFF)) { |
networker | 0:7f26f0680202 | 884 | fprintf(stderr, "CloseFtDevice: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 885 | } |
networker | 0:7f26f0680202 | 886 | case FT_ROBO_IF_IIM: |
networker | 0:7f26f0680202 | 887 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 888 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 889 | delete hFt->sdev; |
networker | 0:7f26f0680202 | 890 | ret = 0; |
networker | 0:7f26f0680202 | 891 | break; |
networker | 0:7f26f0680202 | 892 | #else |
networker | 0:7f26f0680202 | 893 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 894 | if ((write(hFt->sdev, &off, 1)) != 1 || (read(hFt->sdev, &in, 1)) != 1 || in[0] != 0x5D) { |
networker | 0:7f26f0680202 | 895 | fprintf(stderr, "CloseFtDevice: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 896 | } |
networker | 0:7f26f0680202 | 897 | case FT_ROBO_IF_IIM: |
networker | 0:7f26f0680202 | 898 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 899 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 900 | tcsetattr(hFt->sdev, TCSANOW, &hFt->saveioset); |
networker | 0:7f26f0680202 | 901 | ret = close(hFt->sdev); |
networker | 0:7f26f0680202 | 902 | break; |
networker | 0:7f26f0680202 | 903 | #endif |
networker | 0:7f26f0680202 | 904 | } |
networker | 0:7f26f0680202 | 905 | #ifdef MBED |
networker | 0:7f26f0680202 | 906 | delete hFt; |
networker | 0:7f26f0680202 | 907 | #else |
networker | 0:7f26f0680202 | 908 | free(hFt); |
networker | 0:7f26f0680202 | 909 | #endif |
networker | 0:7f26f0680202 | 910 | hFt = NULL; |
networker | 0:7f26f0680202 | 911 | return ret; |
networker | 0:7f26f0680202 | 912 | } |
networker | 0:7f26f0680202 | 913 | |
networker | 0:7f26f0680202 | 914 | |
networker | 0:7f26f0680202 | 915 | /** |
networker | 0:7f26f0680202 | 916 | * \brief Library deinitialization (dummy) |
networker | 0:7f26f0680202 | 917 | * |
networker | 0:7f26f0680202 | 918 | * Dummy for compatibility. Only used in original library. |
networker | 0:7f26f0680202 | 919 | * @return Always FTLIB_ERR_SUCCESS |
networker | 0:7f26f0680202 | 920 | */ |
networker | 0:7f26f0680202 | 921 | long int CloseFtLib() { |
networker | 0:7f26f0680202 | 922 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 923 | } |
networker | 0:7f26f0680202 | 924 | |
networker | 0:7f26f0680202 | 925 | |
networker | 0:7f26f0680202 | 926 | /** |
networker | 0:7f26f0680202 | 927 | * \brief Check for Library initialization (dummy) |
networker | 0:7f26f0680202 | 928 | * |
networker | 0:7f26f0680202 | 929 | * Dummy for compatibility. Only used in original library. |
networker | 0:7f26f0680202 | 930 | * @return Always FTLIB_ERR_LIB_IS_INITIALIZED since initialization is ignored in this version |
networker | 0:7f26f0680202 | 931 | */ |
networker | 0:7f26f0680202 | 932 | long int IsFtLibInit() { |
networker | 0:7f26f0680202 | 933 | return FTLIB_ERR_LIB_IS_INITIALIZED; |
networker | 0:7f26f0680202 | 934 | } |
networker | 0:7f26f0680202 | 935 | |
networker | 0:7f26f0680202 | 936 | bool test_and_set(int& s) { |
networker | 0:7f26f0680202 | 937 | bool tmp; |
networker | 0:7f26f0680202 | 938 | __disable_irq(); |
networker | 0:7f26f0680202 | 939 | if (tmp = s>0) |
networker | 0:7f26f0680202 | 940 | s--; |
networker | 0:7f26f0680202 | 941 | __enable_irq(); |
networker | 0:7f26f0680202 | 942 | return tmp; |
networker | 0:7f26f0680202 | 943 | } |
networker | 0:7f26f0680202 | 944 | |
networker | 0:7f26f0680202 | 945 | void increment(int& s) { |
networker | 0:7f26f0680202 | 946 | __disable_irq(); |
networker | 0:7f26f0680202 | 947 | s++; |
networker | 0:7f26f0680202 | 948 | __enable_irq(); |
networker | 0:7f26f0680202 | 949 | } |
networker | 0:7f26f0680202 | 950 | #ifdef SPLITTRANSFER |
networker | 0:7f26f0680202 | 951 | |
networker | 0:7f26f0680202 | 952 | //version for mbed with split functionality |
networker | 0:7f26f0680202 | 953 | |
networker | 0:7f26f0680202 | 954 | void ft_handle_devices::FtThreadInit() {//setup buffers for this type of interface |
networker | 0:7f26f0680202 | 955 | FT_TRANSFER_AREA *area = &transfer_area; |
networker | 0:7f26f0680202 | 956 | num_write = ABF_IF_COMPLETE_NUM_WRITE; |
networker | 0:7f26f0680202 | 957 | num_read = ABF_IF_COMPLETE_NUM_READ; |
networker | 0:7f26f0680202 | 958 | usb_endpoint_write = FT_ENDPOINT_INTERRUPT_OUT; |
networker | 0:7f26f0680202 | 959 | usb_endpoint_read = FT_ENDPOINT_INTERRUPT_IN; |
networker | 0:7f26f0680202 | 960 | cycle=0; |
networker | 0:7f26f0680202 | 961 | |
networker | 0:7f26f0680202 | 962 | out[0] = ABF_IF_COMPLETE; |
networker | 0:7f26f0680202 | 963 | area->TransferAktiv = 1; |
networker | 0:7f26f0680202 | 964 | sdev->attach(this, &ft_handle_devices::writeByte, Serial::TxIrq); |
networker | 0:7f26f0680202 | 965 | sdev->attach(this, &ft_handle_devices::readByte, Serial::RxIrq); |
networker | 0:7f26f0680202 | 966 | busy = false; |
networker | 0:7f26f0680202 | 967 | |
networker | 0:7f26f0680202 | 968 | switch (type) { |
networker | 0:7f26f0680202 | 969 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 970 | out[0] = 0xf2; |
networker | 0:7f26f0680202 | 971 | num_write = 17; |
networker | 0:7f26f0680202 | 972 | num_read = 21; |
networker | 0:7f26f0680202 | 973 | break; |
networker | 0:7f26f0680202 | 974 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 975 | num_write = 2; |
networker | 0:7f26f0680202 | 976 | break; |
networker | 0:7f26f0680202 | 977 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 978 | num_write = 3; |
networker | 0:7f26f0680202 | 979 | break; |
networker | 0:7f26f0680202 | 980 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 981 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 982 | out[0] = 0xf2; |
networker | 0:7f26f0680202 | 983 | num_write = 6; |
networker | 0:7f26f0680202 | 984 | num_read = 6; |
networker | 0:7f26f0680202 | 985 | break; |
networker | 0:7f26f0680202 | 986 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 987 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 988 | usb_endpoint_write = FT_RF_ENDPOINT_INTERRUPT_OUT; |
networker | 0:7f26f0680202 | 989 | usb_endpoint_read = FT_RF_ENDPOINT_INTERRUPT_IN; |
networker | 0:7f26f0680202 | 990 | |
networker | 0:7f26f0680202 | 991 | // init RF |
networker | 0:7f26f0680202 | 992 | // 0x102 == first RF |
networker | 0:7f26f0680202 | 993 | // 0x202 == 2nd RF |
networker | 0:7f26f0680202 | 994 | // ... |
networker | 0:7f26f0680202 | 995 | //ret = usb_control_msg(hFt->device, 0xc0, 0xfb, 0x102, 0x1, in, 2, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 996 | ret = usb_control_msg(hFt->device, 0xc0, 0xfb, hFt->transfer_area.RfModulNr << 8 | 0x02, 0x1, in, 2, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 997 | if (ret != 2) { |
networker | 0:7f26f0680202 | 998 | fprintf(stderr, "%d FtThread: Error initiating RF Module!\n"); |
networker | 0:7f26f0680202 | 999 | area->TransferAktiv = 0; |
networker | 0:7f26f0680202 | 1000 | } |
networker | 0:7f26f0680202 | 1001 | break; |
networker | 0:7f26f0680202 | 1002 | #endif |
networker | 0:7f26f0680202 | 1003 | } |
networker | 0:7f26f0680202 | 1004 | } |
networker | 0:7f26f0680202 | 1005 | |
networker | 0:7f26f0680202 | 1006 | extern int trigger_interface; |
networker | 0:7f26f0680202 | 1007 | |
networker | 0:7f26f0680202 | 1008 | bool ft_handle_devices::guardedFtThreadBegin() {//called every 10ms by the main loop to issue a request, should be non-blocking, guarded by busy flag to avoid multiple pending requests |
networker | 0:7f26f0680202 | 1009 | //viaUsb.putc('.'); |
networker | 0:7f26f0680202 | 1010 | __disable_irq(); |
networker | 0:7f26f0680202 | 1011 | if (busy) { |
networker | 0:7f26f0680202 | 1012 | if (trigger_interface > 10) { //interface has not responded within 10 slots or response was missed |
networker | 0:7f26f0680202 | 1013 | putc('?',stderr); |
networker | 0:7f26f0680202 | 1014 | busy = false; //release the busy flag to reenable the request-reply process |
networker | 0:7f26f0680202 | 1015 | } |
networker | 0:7f26f0680202 | 1016 | __enable_irq(); |
networker | 0:7f26f0680202 | 1017 | return false; //skip the timeslot when previous was not yet handled |
networker | 0:7f26f0680202 | 1018 | } |
networker | 0:7f26f0680202 | 1019 | busy = true; |
networker | 0:7f26f0680202 | 1020 | __enable_irq(); |
networker | 0:7f26f0680202 | 1021 | FtThreadBegin();//here the request is sent to the interface |
networker | 0:7f26f0680202 | 1022 | return true; |
networker | 0:7f26f0680202 | 1023 | } |
networker | 0:7f26f0680202 | 1024 | |
networker | 0:7f26f0680202 | 1025 | void ft_handle_devices::FtThreadTrigger() { |
networker | 0:7f26f0680202 | 1026 | trigger_interface++;//this is polled by the main loop |
networker | 0:7f26f0680202 | 1027 | //printf("%d ", trigger_interface); |
networker | 0:7f26f0680202 | 1028 | } |
networker | 0:7f26f0680202 | 1029 | |
networker | 0:7f26f0680202 | 1030 | //here the real data exchange starts |
networker | 0:7f26f0680202 | 1031 | void ft_handle_devices::FtThreadBegin() {//called every 10ms to issue a request, should be non-blocking |
networker | 0:7f26f0680202 | 1032 | int ii_speed = 0; |
networker | 0:7f26f0680202 | 1033 | FT_TRANSFER_AREA *area = &transfer_area; |
networker | 0:7f26f0680202 | 1034 | if (!test_and_set(lock)) {//return when transferarea is in use |
networker | 0:7f26f0680202 | 1035 | busy = false; //release the mutex, otherwise the thread effectively stops |
networker | 0:7f26f0680202 | 1036 | return;//return because there is no point in sending a nonsense request, alternatively the lock can be ignored in which case the data may be inconsistent |
networker | 0:7f26f0680202 | 1037 | } |
networker | 0:7f26f0680202 | 1038 | out[1] = area->M_Main; |
networker | 0:7f26f0680202 | 1039 | out[2] = (area->MPWM_Main[0] & 0x7) | (area->MPWM_Main[1]<<3 & 0x38) | (area->MPWM_Main[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 1040 | out[3] = (area->MPWM_Main[2] & 0x1) | (area->MPWM_Main[3]<<1 & 0xE) | (area->MPWM_Main[4]<<4 & 0x70) | (area->MPWM_Main[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 1041 | out[4] = (area->MPWM_Main[5] & 0x3) | (area->MPWM_Main[6]<<2 & 0x1C) | (area->MPWM_Main[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 1042 | out[5] = area->M_Sub1; |
networker | 0:7f26f0680202 | 1043 | out[6] = (area->MPWM_Sub1[0] & 0x7) | (area->MPWM_Sub1[1]<<3 & 0x38) | (area->MPWM_Sub1[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 1044 | out[7] = (area->MPWM_Sub1[2] & 0x1) | (area->MPWM_Sub1[3]<<1 & 0xE) | (area->MPWM_Sub1[4]<<4 & 0x70) | (area->MPWM_Sub1[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 1045 | out[8] = (area->MPWM_Sub1[5] & 0x3) | (area->MPWM_Sub1[6]<<2 & 0x1C) | (area->MPWM_Sub1[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 1046 | out[9] = area->M_Sub2; |
networker | 0:7f26f0680202 | 1047 | out[10] = (area->MPWM_Sub2[0] & 0x7) | (area->MPWM_Sub2[1]<<3 & 0x38) | (area->MPWM_Sub2[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 1048 | out[11] = (area->MPWM_Sub2[2] & 0x1) | (area->MPWM_Sub2[3]<<1 & 0xE) | (area->MPWM_Sub2[4]<<4 & 0x70) | (area->MPWM_Sub2[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 1049 | out[12] = (area->MPWM_Sub2[5] & 0x3) | (area->MPWM_Sub2[6]<<2 & 0x1C) | (area->MPWM_Sub2[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 1050 | out[13] = area->M_Sub3; |
networker | 0:7f26f0680202 | 1051 | out[14] = (area->MPWM_Sub3[0] & 0x7) | (area->MPWM_Sub3[1]<<3 & 0x38) | (area->MPWM_Sub3[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 1052 | out[15] = (area->MPWM_Sub3[2] & 0x1) | (area->MPWM_Sub3[3]<<1 & 0xE) | (area->MPWM_Sub3[4]<<4 & 0x70) | (area->MPWM_Sub3[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 1053 | out[16] = (area->MPWM_Sub3[5] & 0x3) | (area->MPWM_Sub3[6]<<2 & 0x1C) | (area->MPWM_Sub3[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 1054 | out[17] = 0; |
networker | 0:7f26f0680202 | 1055 | out[18] = 0; |
networker | 0:7f26f0680202 | 1056 | out[19] = 0; |
networker | 0:7f26f0680202 | 1057 | out[20] = 0; |
networker | 0:7f26f0680202 | 1058 | out[21] = 0; |
networker | 0:7f26f0680202 | 1059 | out[22] = 0; |
networker | 0:7f26f0680202 | 1060 | out[23] = 0; |
networker | 0:7f26f0680202 | 1061 | out[24] = 0; |
networker | 0:7f26f0680202 | 1062 | out[25] = 0; |
networker | 0:7f26f0680202 | 1063 | out[26] = 0; |
networker | 0:7f26f0680202 | 1064 | out[27] = 0; |
networker | 0:7f26f0680202 | 1065 | out[28] = 0; |
networker | 0:7f26f0680202 | 1066 | out[29] = 0; |
networker | 0:7f26f0680202 | 1067 | out[30] = 0; |
networker | 0:7f26f0680202 | 1068 | out[31] = 0; |
networker | 0:7f26f0680202 | 1069 | |
networker | 0:7f26f0680202 | 1070 | // For the II we need to simulate different speeds here |
networker | 0:7f26f0680202 | 1071 | if (type == FT_INTELLIGENT_IF || type == FT_INTELLIGENT_IF_SLAVE) { |
networker | 0:7f26f0680202 | 1072 | int iCurMotor; |
networker | 0:7f26f0680202 | 1073 | for (iCurMotor = 0; iCurMotor < 7; iCurMotor++) { |
networker | 0:7f26f0680202 | 1074 | if (area->MPWM_Main[iCurMotor] < ii_speed) out[1] &= ~(1 << iCurMotor); |
networker | 0:7f26f0680202 | 1075 | if (area->MPWM_Sub1[iCurMotor] < ii_speed) out[5] &= ~(1 << iCurMotor); |
networker | 0:7f26f0680202 | 1076 | } |
networker | 0:7f26f0680202 | 1077 | |
networker | 0:7f26f0680202 | 1078 | ii_speed++; |
networker | 0:7f26f0680202 | 1079 | if (ii_speed > 7) ii_speed = 0; |
networker | 0:7f26f0680202 | 1080 | } |
networker | 0:7f26f0680202 | 1081 | |
networker | 0:7f26f0680202 | 1082 | if (type == FT_INTELLIGENT_IF) { |
networker | 0:7f26f0680202 | 1083 | cycle++; |
networker | 0:7f26f0680202 | 1084 | num_read = 1; |
networker | 0:7f26f0680202 | 1085 | out[0] = 0xC1; |
networker | 0:7f26f0680202 | 1086 | if (cycle % 20) { // EX |
networker | 0:7f26f0680202 | 1087 | out[0] = 0xC5; |
networker | 0:7f26f0680202 | 1088 | num_read = 3; |
networker | 0:7f26f0680202 | 1089 | } else if (cycle % 10) { // EY |
networker | 0:7f26f0680202 | 1090 | out[0] = 0xC9; |
networker | 0:7f26f0680202 | 1091 | num_read = 3; |
networker | 0:7f26f0680202 | 1092 | } |
networker | 0:7f26f0680202 | 1093 | } else if (type == FT_INTELLIGENT_IF_SLAVE) { |
networker | 0:7f26f0680202 | 1094 | cycle++; |
networker | 0:7f26f0680202 | 1095 | num_read = 2; |
networker | 0:7f26f0680202 | 1096 | out[0] = 0xC2; |
networker | 0:7f26f0680202 | 1097 | out[2] = out[5]; |
networker | 0:7f26f0680202 | 1098 | if (cycle % 20) { // EX |
networker | 0:7f26f0680202 | 1099 | out[0] = 0xC6; |
networker | 0:7f26f0680202 | 1100 | num_read = 4; |
networker | 0:7f26f0680202 | 1101 | } else if (cycle % 10) { // EY |
networker | 0:7f26f0680202 | 1102 | out[0] = 0xCA; |
networker | 0:7f26f0680202 | 1103 | num_read = 4; |
networker | 0:7f26f0680202 | 1104 | } |
networker | 0:7f26f0680202 | 1105 | } |
networker | 0:7f26f0680202 | 1106 | //viaUsb.putc('-'); |
networker | 0:7f26f0680202 | 1107 | increment(lock);//release the lock on shared memeory |
networker | 0:7f26f0680202 | 1108 | int ret = 0; |
networker | 0:7f26f0680202 | 1109 | switch (type) {//send the request |
networker | 0:7f26f0680202 | 1110 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 1111 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1112 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 1113 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 1114 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 1115 | ret = usb_interrupt_write(hFt->device, usb_endpoint_write, out, num_write, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1116 | break; |
networker | 0:7f26f0680202 | 1117 | #endif |
networker | 0:7f26f0680202 | 1118 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1119 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 1120 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 1121 | // ret = write(sdev, out, num_write); |
networker | 0:7f26f0680202 | 1122 | //sdev->dmaSend(out, num_write); |
networker | 0:7f26f0680202 | 1123 | ret = write();//start the transfer of the 'out' buffer, when complete the read_callback will receive the reply and when the reply is complete FtThreadEnd will be called |
networker | 0:7f26f0680202 | 1124 | // viaUsb.putc(';'); |
networker | 0:7f26f0680202 | 1125 | break; |
networker | 0:7f26f0680202 | 1126 | } |
networker | 0:7f26f0680202 | 1127 | if (ret != num_write) { |
networker | 0:7f26f0680202 | 1128 | interface_connected = 0; |
networker | 0:7f26f0680202 | 1129 | fprintf(stderr, "FtThread: Error writing to the Interface...exiting!\n"); |
networker | 0:7f26f0680202 | 1130 | } |
networker | 0:7f26f0680202 | 1131 | } |
networker | 0:7f26f0680202 | 1132 | |
networker | 0:7f26f0680202 | 1133 | void ft_handle_devices::FtThreadEnd() {//called by the receiver/dma callback when the reply is complete |
networker | 0:7f26f0680202 | 1134 | int ret = 0; |
networker | 0:7f26f0680202 | 1135 | FT_TRANSFER_AREA *area = &transfer_area; |
networker | 0:7f26f0680202 | 1136 | switch (type) { //receive the reply |
networker | 0:7f26f0680202 | 1137 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 1138 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1139 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 1140 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 1141 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 1142 | ret = usb_interrupt_read(hFt->device, usb_endpoint_read, in, num_read, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1143 | break; |
networker | 0:7f26f0680202 | 1144 | #endif |
networker | 0:7f26f0680202 | 1145 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1146 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 1147 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 1148 | // ret = read(sdev, in, num_read); |
networker | 0:7f26f0680202 | 1149 | ret = num_read; |
networker | 0:7f26f0680202 | 1150 | // viaUsb.putc('/'); |
networker | 0:7f26f0680202 | 1151 | break; |
networker | 0:7f26f0680202 | 1152 | } |
networker | 0:7f26f0680202 | 1153 | if (ret != num_read) { |
networker | 0:7f26f0680202 | 1154 | interface_connected = 0; |
networker | 0:7f26f0680202 | 1155 | fprintf(stderr, "FtThread: Error reading from the Interface\n"); |
networker | 0:7f26f0680202 | 1156 | return; |
networker | 0:7f26f0680202 | 1157 | } |
networker | 0:7f26f0680202 | 1158 | |
networker | 0:7f26f0680202 | 1159 | if (!test_and_set(lock)) {//skip when busy |
networker | 0:7f26f0680202 | 1160 | busy = false; |
networker | 0:7f26f0680202 | 1161 | return; |
networker | 0:7f26f0680202 | 1162 | } |
networker | 0:7f26f0680202 | 1163 | area->ChangeEg = area->E_Main != in[0] || area->E_Sub1 != in[1] || area->E_Sub2 != in[2] || area->E_Sub3 != in[3]; |
networker | 0:7f26f0680202 | 1164 | area->E_Main = in[0]; |
networker | 0:7f26f0680202 | 1165 | area->E_Sub1 = in[1]; |
networker | 0:7f26f0680202 | 1166 | area->E_Sub2 = in[2]; |
networker | 0:7f26f0680202 | 1167 | area->E_Sub3 = in[3]; |
networker | 0:7f26f0680202 | 1168 | area->ChangeAn = 1; //assume that analog always changes (noise) |
networker | 0:7f26f0680202 | 1169 | area->AX = in[4]; |
networker | 0:7f26f0680202 | 1170 | area->AY = in[5]; |
networker | 0:7f26f0680202 | 1171 | area->A1 = in[6]; |
networker | 0:7f26f0680202 | 1172 | area->A2 = in[7]; |
networker | 0:7f26f0680202 | 1173 | area->AX |= (in[8] & 0x3) << 8; |
networker | 0:7f26f0680202 | 1174 | area->AY |= (in[8] & 0xC) << 6; |
networker | 0:7f26f0680202 | 1175 | area->A1 |= (in[8] & 0x30) << 4; |
networker | 0:7f26f0680202 | 1176 | area->A2 |= (in[8] & 0xC0) << 2; |
networker | 0:7f26f0680202 | 1177 | area->AZ = in[9]; |
networker | 0:7f26f0680202 | 1178 | area->D1 = in[10]; |
networker | 0:7f26f0680202 | 1179 | area->D2 = in[11]; |
networker | 0:7f26f0680202 | 1180 | area->AV = in[12]; |
networker | 0:7f26f0680202 | 1181 | area->AZ |= (in[13] & 0x3) << 8; |
networker | 0:7f26f0680202 | 1182 | area->D1 |= (in[13] & 0xC) << 6; |
networker | 0:7f26f0680202 | 1183 | area->D2 |= (in[13] & 0x30) << 4; |
networker | 0:7f26f0680202 | 1184 | area->AV |= (in[13] & 0xC0) << 2; |
networker | 0:7f26f0680202 | 1185 | if (area->IRKeys != in[14]) |
networker | 0:7f26f0680202 | 1186 | area->ChangeIr = 1; |
networker | 0:7f26f0680202 | 1187 | area->IRKeys = in[14]; |
networker | 0:7f26f0680202 | 1188 | area->BusModules = in[15]; |
networker | 0:7f26f0680202 | 1189 | // 16 |
networker | 0:7f26f0680202 | 1190 | area->AXS1 = in[17]; |
networker | 0:7f26f0680202 | 1191 | area->AXS2 = in[18]; |
networker | 0:7f26f0680202 | 1192 | area->AXS3 = in[19]; |
networker | 0:7f26f0680202 | 1193 | area->AXS1 |= (in[20] & 0x3) << 8; |
networker | 0:7f26f0680202 | 1194 | area->AXS2 |= (in[20] & 0xC) << 6; |
networker | 0:7f26f0680202 | 1195 | area->AXS3 |= (in[20] & 0x30) << 4; |
networker | 0:7f26f0680202 | 1196 | // 21 |
networker | 0:7f26f0680202 | 1197 | area->AVS1 = in[22]; |
networker | 0:7f26f0680202 | 1198 | area->AVS2 = in[23]; |
networker | 0:7f26f0680202 | 1199 | area->AVS3 = in[24]; |
networker | 0:7f26f0680202 | 1200 | area->AVS1 |= (in[25] & 0x3) << 8; |
networker | 0:7f26f0680202 | 1201 | area->AVS2 |= (in[25] & 0xC) << 6; |
networker | 0:7f26f0680202 | 1202 | area->AVS3 |= (in[25] & 0x30) << 4; |
networker | 0:7f26f0680202 | 1203 | // 26...42 |
networker | 0:7f26f0680202 | 1204 | if (type == FT_INTELLIGENT_IF) { |
networker | 0:7f26f0680202 | 1205 | if (cycle % analogcycle) { // EX |
networker | 0:7f26f0680202 | 1206 | area->AX = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 1207 | } else if (cycle % (2*analogcycle)) { // EY |
networker | 0:7f26f0680202 | 1208 | area->AY = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 1209 | } |
networker | 0:7f26f0680202 | 1210 | } else if (type == FT_INTELLIGENT_IF_SLAVE) { |
networker | 0:7f26f0680202 | 1211 | if (cycle % analogcycle) { // EX |
networker | 0:7f26f0680202 | 1212 | area->AX = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 1213 | } else if (cycle % (2*analogcycle)) { // EY |
networker | 0:7f26f0680202 | 1214 | area->AY = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 1215 | } |
networker | 0:7f26f0680202 | 1216 | } |
networker | 0:7f26f0680202 | 1217 | increment(lock); |
networker | 0:7f26f0680202 | 1218 | interface_connected = 1; |
networker | 0:7f26f0680202 | 1219 | if (ne.NotificationCallback) { |
networker | 0:7f26f0680202 | 1220 | // printf("%02X\r", transfer_area.E_Main); |
networker | 0:7f26f0680202 | 1221 | (*ne.NotificationCallback)(ne.Context); |
networker | 0:7f26f0680202 | 1222 | } |
networker | 0:7f26f0680202 | 1223 | busy = false; |
networker | 0:7f26f0680202 | 1224 | } |
networker | 0:7f26f0680202 | 1225 | |
networker | 0:7f26f0680202 | 1226 | void ft_handle_devices::FtThreadFinish() {//called by StopFtTransferArea |
networker | 0:7f26f0680202 | 1227 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 1228 | if (hFt->type == FT_ROBO_IF_OVER_RF || hFt->type == FT_ROBO_RF_DATA_LINK) { |
networker | 0:7f26f0680202 | 1229 | ret = usb_control_msg(hFt->device, 0xc0, 0x21, hFt->transfer_area.RfModulNr << 8, 0, in, 1, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1230 | if (ret != 1 || in[0] != 0xd7) { |
networker | 0:7f26f0680202 | 1231 | fprintf(stderr, "Error uninitiating RF Module!\n"); |
networker | 0:7f26f0680202 | 1232 | } |
networker | 0:7f26f0680202 | 1233 | } |
networker | 0:7f26f0680202 | 1234 | #endif |
networker | 0:7f26f0680202 | 1235 | #ifdef MBED |
networker | 0:7f26f0680202 | 1236 | sdev->attach(0,Serial::RxIrq); |
networker | 0:7f26f0680202 | 1237 | sdev->attach(0,Serial::TxIrq); |
networker | 0:7f26f0680202 | 1238 | #endif |
networker | 0:7f26f0680202 | 1239 | transfer_area.TransferAktiv = 0; |
networker | 0:7f26f0680202 | 1240 | } |
networker | 0:7f26f0680202 | 1241 | |
networker | 0:7f26f0680202 | 1242 | void ft_handle_devices::FtThread() { |
networker | 0:7f26f0680202 | 1243 | // ::FtThread(this); |
networker | 0:7f26f0680202 | 1244 | // printf("%02X\r", transfer_area.E_Main); |
networker | 0:7f26f0680202 | 1245 | // viaUsb.putc('.'); |
networker | 0:7f26f0680202 | 1246 | } |
networker | 0:7f26f0680202 | 1247 | |
networker | 0:7f26f0680202 | 1248 | #endif |
networker | 0:7f26f0680202 | 1249 | |
networker | 0:7f26f0680202 | 1250 | /** |
networker | 0:7f26f0680202 | 1251 | * \brief reset outputs |
networker | 0:7f26f0680202 | 1252 | * |
networker | 0:7f26f0680202 | 1253 | * Will clear all outputs. |
networker | 0:7f26f0680202 | 1254 | * |
networker | 0:7f26f0680202 | 1255 | * @return Always FTLIB_ERR_SUCCESS |
networker | 0:7f26f0680202 | 1256 | */ |
networker | 0:7f26f0680202 | 1257 | long int ResetFtTransfer(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1258 | FT_TRANSFER_AREA *area = &hFt->transfer_area; |
networker | 0:7f26f0680202 | 1259 | |
networker | 0:7f26f0680202 | 1260 | area->M_Main = 0; |
networker | 0:7f26f0680202 | 1261 | area->M_Sub1 = 0; |
networker | 0:7f26f0680202 | 1262 | area->M_Sub2 = 0; |
networker | 0:7f26f0680202 | 1263 | area->M_Sub3 = 0; |
networker | 0:7f26f0680202 | 1264 | |
networker | 0:7f26f0680202 | 1265 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1266 | } |
networker | 0:7f26f0680202 | 1267 | |
networker | 0:7f26f0680202 | 1268 | |
networker | 0:7f26f0680202 | 1269 | /** |
networker | 0:7f26f0680202 | 1270 | * \brief Starts the communication thread. |
networker | 0:7f26f0680202 | 1271 | * |
networker | 0:7f26f0680202 | 1272 | * This function is needed to start the communication with the interface in passive mode. |
networker | 0:7f26f0680202 | 1273 | * Get the handle with GetFtUsbDeviceHandle(), GetFtUsbDeviceHandleSerialNr() or OpenFtCommDevice(). |
networker | 0:7f26f0680202 | 1274 | * |
networker | 0:7f26f0680202 | 1275 | * @see GetFtUsbDeviceHandle() |
networker | 0:7f26f0680202 | 1276 | * @see GetFtUsbDeviceHandleSerialNr() |
networker | 0:7f26f0680202 | 1277 | * @see OpenFtCommDevice() |
networker | 0:7f26f0680202 | 1278 | * @param hFt Handle of the interface. |
networker | 0:7f26f0680202 | 1279 | * @param ignored The second argument is ignored in this version. |
networker | 0:7f26f0680202 | 1280 | * @return Everything except FTLIB_ERR_SUCCESS indicates an error. |
networker | 0:7f26f0680202 | 1281 | */ |
networker | 0:7f26f0680202 | 1282 | long int StartFtTransferArea(FT_HANDLE hFt, NOTIFICATION_EVENTS* ev) { |
networker | 0:7f26f0680202 | 1283 | int ret; |
networker | 0:7f26f0680202 | 1284 | |
networker | 0:7f26f0680202 | 1285 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1286 | fprintf(stderr, "StartFtTransferArea: No such device\n"); |
networker | 0:7f26f0680202 | 1287 | return NO_FT_DEVICE; |
networker | 0:7f26f0680202 | 1288 | } |
networker | 0:7f26f0680202 | 1289 | if (ev) |
networker | 0:7f26f0680202 | 1290 | hFt->ne = *ev; //copy the entire struct |
networker | 0:7f26f0680202 | 1291 | else |
networker | 0:7f26f0680202 | 1292 | memset(&hFt->ne, 0, sizeof(NOTIFICATION_EVENTS)); |
networker | 0:7f26f0680202 | 1293 | #ifdef MBED |
networker | 0:7f26f0680202 | 1294 | //at least for serial devices another solution must be found. A normal request/reply uses the entire 10 ms, this is OK but the CPU should not wait for it |
networker | 0:7f26f0680202 | 1295 | //either a buffer or a DMA scheme must be used to free CPU time, this means that at the beginning of the time slot the req. buffer is prepared and |
networker | 0:7f26f0680202 | 1296 | //handed over to IRQ/USB, the reply is gathered in a buffer and when complete the transfer area is updated. |
networker | 0:7f26f0680202 | 1297 | hFt->t = new Ticker; |
networker | 0:7f26f0680202 | 1298 | //printf("ticker created\n"); |
networker | 0:7f26f0680202 | 1299 | hFt->FtThreadInit();//setup buffers and serial handlers |
networker | 0:7f26f0680202 | 1300 | //hFt->t->attach_us(hFt, &ft_handle_devices::FtThreadBegin, INTERFACE_QUERY_TIME); |
networker | 0:7f26f0680202 | 1301 | hFt->t->attach_us(hFt, &ft_handle_devices::FtThreadTrigger, INTERFACE_QUERY_TIME);//FtThreadTrigger just sets a global variable that is polled by the main loop, which subsequently calls guardedFtThreadBegin |
networker | 0:7f26f0680202 | 1302 | printf("thread attached\n"); |
networker | 0:7f26f0680202 | 1303 | ret = 0; |
networker | 0:7f26f0680202 | 1304 | #else |
networker | 0:7f26f0680202 | 1305 | ret = pthread_create(&hFt->t, NULL, (void *)FtThread, hFt); |
networker | 0:7f26f0680202 | 1306 | #endif |
networker | 0:7f26f0680202 | 1307 | usleep(INTERFACE_QUERY_TIME*10); |
networker | 0:7f26f0680202 | 1308 | if (ret != 0) { |
networker | 0:7f26f0680202 | 1309 | perror("StartFtTransferArea pthread_create"); |
networker | 0:7f26f0680202 | 1310 | return ret; |
networker | 0:7f26f0680202 | 1311 | } |
networker | 0:7f26f0680202 | 1312 | |
networker | 0:7f26f0680202 | 1313 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1314 | } |
networker | 0:7f26f0680202 | 1315 | |
networker | 0:7f26f0680202 | 1316 | |
networker | 0:7f26f0680202 | 1317 | /** |
networker | 0:7f26f0680202 | 1318 | * \brief Starts the communication thread. |
networker | 0:7f26f0680202 | 1319 | * |
networker | 0:7f26f0680202 | 1320 | * Since notification are ignored in this version, will just call StartFtTransferArea(). |
networker | 0:7f26f0680202 | 1321 | * |
networker | 0:7f26f0680202 | 1322 | * @see StartFtTransferArea() |
networker | 0:7f26f0680202 | 1323 | */ |
networker | 0:7f26f0680202 | 1324 | long int StartFtTransferAreaWithCommunication(FT_HANDLE hFt, NOTIFICATION_EVENTS* ignored) { |
networker | 0:7f26f0680202 | 1325 | return StartFtTransferArea(hFt, ignored); |
networker | 0:7f26f0680202 | 1326 | } |
networker | 0:7f26f0680202 | 1327 | |
networker | 0:7f26f0680202 | 1328 | |
networker | 0:7f26f0680202 | 1329 | /** |
networker | 0:7f26f0680202 | 1330 | * \brief Get the transfer area |
networker | 0:7f26f0680202 | 1331 | * |
networker | 0:7f26f0680202 | 1332 | * This function will return a pointer to the transfer area of the given handle. |
networker | 0:7f26f0680202 | 1333 | * |
networker | 0:7f26f0680202 | 1334 | * @param hFt Handle of the device. |
networker | 0:7f26f0680202 | 1335 | * @return transfer area or NULL on error. |
networker | 0:7f26f0680202 | 1336 | */ |
networker | 0:7f26f0680202 | 1337 | FT_TRANSFER_AREA* GetFtTransferAreaAddress(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1338 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1339 | fprintf(stderr, "GetFtTransferAreaAddress: No such device\n"); |
networker | 0:7f26f0680202 | 1340 | return NULL; |
networker | 0:7f26f0680202 | 1341 | } |
networker | 0:7f26f0680202 | 1342 | return &hFt->transfer_area; |
networker | 0:7f26f0680202 | 1343 | } |
networker | 0:7f26f0680202 | 1344 | |
networker | 0:7f26f0680202 | 1345 | |
networker | 0:7f26f0680202 | 1346 | /** |
networker | 0:7f26f0680202 | 1347 | * \brief Stops the communication thread. |
networker | 0:7f26f0680202 | 1348 | * \warning Will block a few microseconds until thread stopped. |
networker | 0:7f26f0680202 | 1349 | * |
networker | 0:7f26f0680202 | 1350 | * This function will stop the communication thread. |
networker | 0:7f26f0680202 | 1351 | * |
networker | 0:7f26f0680202 | 1352 | * @see StartFtTransferArea() |
networker | 0:7f26f0680202 | 1353 | * @param hFt Handle of the Interface. |
networker | 0:7f26f0680202 | 1354 | * @return Everything except FTLIB_ERR_SUCCESS indicates an error. |
networker | 0:7f26f0680202 | 1355 | */ |
networker | 0:7f26f0680202 | 1356 | long int StopFtTransferArea(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1357 | int ret; |
networker | 0:7f26f0680202 | 1358 | |
networker | 0:7f26f0680202 | 1359 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1360 | fprintf(stderr, "StopFtTransferArea: No such device\n"); |
networker | 0:7f26f0680202 | 1361 | return NO_FT_DEVICE; |
networker | 0:7f26f0680202 | 1362 | } |
networker | 0:7f26f0680202 | 1363 | |
networker | 0:7f26f0680202 | 1364 | #ifdef MBED |
networker | 0:7f26f0680202 | 1365 | hFt->t->detach(); |
networker | 0:7f26f0680202 | 1366 | delete hFt->t; |
networker | 0:7f26f0680202 | 1367 | hFt->FtThreadFinish(); |
networker | 0:7f26f0680202 | 1368 | #else |
networker | 0:7f26f0680202 | 1369 | usleep(INTERFACE_QUERY_TIME*10); // wait to make sure the last command is send to the interface |
networker | 0:7f26f0680202 | 1370 | if (hFt->transfer_area.TransferAktiv == 1) { |
networker | 0:7f26f0680202 | 1371 | hFt->transfer_area.TransferAktiv = 2; // cleaner then pthread_cancel() |
networker | 0:7f26f0680202 | 1372 | } |
networker | 0:7f26f0680202 | 1373 | if ((ret = pthread_join(hFt->t, NULL)) != 0) return ret; |
networker | 0:7f26f0680202 | 1374 | #endif |
networker | 0:7f26f0680202 | 1375 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1376 | } |
networker | 0:7f26f0680202 | 1377 | |
networker | 0:7f26f0680202 | 1378 | |
networker | 0:7f26f0680202 | 1379 | /** |
networker | 0:7f26f0680202 | 1380 | * \brief check if transfer is active. |
networker | 0:7f26f0680202 | 1381 | * |
networker | 0:7f26f0680202 | 1382 | * Check if we are currently communicating with the device. |
networker | 0:7f26f0680202 | 1383 | * |
networker | 0:7f26f0680202 | 1384 | * @param hFt Handle of the Interface. |
networker | 0:7f26f0680202 | 1385 | * @return FTLIB_ERR_THREAD_IS_RUNNING or FTLIB_ERR_THREAD_NOT_RUNNING |
networker | 0:7f26f0680202 | 1386 | */ |
networker | 0:7f26f0680202 | 1387 | long int IsFtTransferActiv(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1388 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1389 | fprintf(stderr, "StopFtTransferArea: No such device\n"); |
networker | 0:7f26f0680202 | 1390 | return NO_FT_DEVICE; |
networker | 0:7f26f0680202 | 1391 | } |
networker | 0:7f26f0680202 | 1392 | |
networker | 0:7f26f0680202 | 1393 | if (hFt->transfer_area.TransferAktiv) return FTLIB_ERR_THREAD_IS_RUNNING; |
networker | 0:7f26f0680202 | 1394 | |
networker | 0:7f26f0680202 | 1395 | return FTLIB_ERR_THREAD_NOT_RUNNING; |
networker | 0:7f26f0680202 | 1396 | } |
networker | 0:7f26f0680202 | 1397 | |
networker | 0:7f26f0680202 | 1398 | |
networker | 0:7f26f0680202 | 1399 | #ifdef USE_DOWNLOAD |
networker | 0:7f26f0680202 | 1400 | /** |
networker | 0:7f26f0680202 | 1401 | * \brief Upload a program to the interface |
networker | 0:7f26f0680202 | 1402 | * |
networker | 0:7f26f0680202 | 1403 | * Upload (download from the perspective of the interface) a program to the interface. |
networker | 0:7f26f0680202 | 1404 | * |
networker | 0:7f26f0680202 | 1405 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1406 | * @param dwMemBlock Destination 0 (Flash 1), 1 (Flash 2) or 2 (Ram) |
networker | 0:7f26f0680202 | 1407 | * @param pbArray Pointer to the program to upload |
networker | 0:7f26f0680202 | 1408 | * @param dwSize Size of the program to upload |
networker | 0:7f26f0680202 | 1409 | * @param dwParameter 1 to Autostart this program, else 0. |
networker | 0:7f26f0680202 | 1410 | * @param pbName Name of the program to upload |
networker | 0:7f26f0680202 | 1411 | * @param dwNameLen Length of the name |
networker | 0:7f26f0680202 | 1412 | * @return FTLIB_ERR_SUCCESS if you got lucky |
networker | 0:7f26f0680202 | 1413 | */ |
networker | 0:7f26f0680202 | 1414 | long int DownloadFtProgram(FT_HANDLE hFt, long int dwMemBlock, unsigned char *pbArray, long int dwSize, long int dwParameter, unsigned char *pbName, long int dwNameLen) { |
networker | 0:7f26f0680202 | 1415 | int ret; |
networker | 0:7f26f0680202 | 1416 | unsigned char buffer[128]; |
networker | 0:7f26f0680202 | 1417 | long int i; |
networker | 0:7f26f0680202 | 1418 | crc_t crc; |
networker | 0:7f26f0680202 | 1419 | int memblockarg; |
networker | 0:7f26f0680202 | 1420 | |
networker | 0:7f26f0680202 | 1421 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1422 | fprintf(stderr, "DownloadFtProgram: No such device\n"); |
networker | 0:7f26f0680202 | 1423 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1424 | } else if (hFt->type != FT_ROBO_IF_USB) { |
networker | 0:7f26f0680202 | 1425 | fprintf(stderr, "DownloadFtProgram: Sorry, I can only handle the Robo Interface over USB at this time.\n"); |
networker | 0:7f26f0680202 | 1426 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1427 | } |
networker | 0:7f26f0680202 | 1428 | |
networker | 0:7f26f0680202 | 1429 | switch (dwMemBlock) { |
networker | 0:7f26f0680202 | 1430 | case 0x0: // flash 1 |
networker | 0:7f26f0680202 | 1431 | memblockarg = 0x100; |
networker | 0:7f26f0680202 | 1432 | if (dwParameter == 1) memblockarg += 0x100; |
networker | 0:7f26f0680202 | 1433 | break; |
networker | 0:7f26f0680202 | 1434 | case 0x1: // flash 2 |
networker | 0:7f26f0680202 | 1435 | memblockarg = 0x101; |
networker | 0:7f26f0680202 | 1436 | if (dwParameter == 1) fprintf(stderr, "Warning: Autostart for flash 2 not supported\n"); |
networker | 0:7f26f0680202 | 1437 | break; |
networker | 0:7f26f0680202 | 1438 | case 0x2: // ram |
networker | 0:7f26f0680202 | 1439 | memblockarg = 0x102; |
networker | 0:7f26f0680202 | 1440 | if (dwParameter == 1) fprintf(stderr, "Warning: Autostart for RAM not supported\n"); |
networker | 0:7f26f0680202 | 1441 | break; |
networker | 0:7f26f0680202 | 1442 | case 0xf0: // firmware A |
networker | 0:7f26f0680202 | 1443 | memblockarg = 0xf200; |
networker | 0:7f26f0680202 | 1444 | break; |
networker | 0:7f26f0680202 | 1445 | case 0xf1: // firmware B |
networker | 0:7f26f0680202 | 1446 | memblockarg = 0xf201; |
networker | 0:7f26f0680202 | 1447 | break; |
networker | 0:7f26f0680202 | 1448 | default: |
networker | 0:7f26f0680202 | 1449 | fprintf(stderr, "Unknown Memblock Target\n"); |
networker | 0:7f26f0680202 | 1450 | return FTLIB_ERR_DOWNLOAD_WRONG_MEM_BLOCK; |
networker | 0:7f26f0680202 | 1451 | } |
networker | 0:7f26f0680202 | 1452 | |
networker | 0:7f26f0680202 | 1453 | // init upload |
networker | 0:7f26f0680202 | 1454 | ret = usb_control_msg(hFt->device, 0xc0, 0xf0, 0x20, 0, buffer, 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1455 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1456 | fprintf(stderr, "Error sending control msg 0xC0 0xF0\n"); |
networker | 0:7f26f0680202 | 1457 | return ret; |
networker | 0:7f26f0680202 | 1458 | } |
networker | 0:7f26f0680202 | 1459 | if (buffer[0] != 1) { |
networker | 0:7f26f0680202 | 1460 | fprintf(stderr, "Error uploading Program: Return value for 0xC0 0xF0 is 0x%x\n", buffer[0]); |
networker | 0:7f26f0680202 | 1461 | return FTLIB_ERR_DOWNLOAD; |
networker | 0:7f26f0680202 | 1462 | } |
networker | 0:7f26f0680202 | 1463 | |
networker | 0:7f26f0680202 | 1464 | // write name |
networker | 0:7f26f0680202 | 1465 | memset(buffer, 0, 128); // clean buffer |
networker | 0:7f26f0680202 | 1466 | if (pbName != NULL) |
networker | 0:7f26f0680202 | 1467 | strncpy(buffer, pbName, MIN(dwNameLen, 80)); // copy to buffer, so we not change the original content |
networker | 0:7f26f0680202 | 1468 | ret = usb_control_msg(hFt->device, 0x40, 0x10, memblockarg, dwSize/PROGRAM_UPLOAD_PACKET_SIZE, buffer, 80, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1469 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1470 | fprintf(stderr, "Error sending control msg 0x40 0x10\n"); |
networker | 0:7f26f0680202 | 1471 | return ret; |
networker | 0:7f26f0680202 | 1472 | } |
networker | 0:7f26f0680202 | 1473 | |
networker | 0:7f26f0680202 | 1474 | // check |
networker | 0:7f26f0680202 | 1475 | ret = usb_control_msg(hFt->device, 0xC0, 0x20, 0x0, 0x0, buffer, 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1476 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1477 | fprintf(stderr, "Error sending control ms 0xC0 0x20g\n"); |
networker | 0:7f26f0680202 | 1478 | return ret; |
networker | 0:7f26f0680202 | 1479 | } |
networker | 0:7f26f0680202 | 1480 | if (buffer[0] != dwMemBlock || (buffer[0] == 0 && memblockarg == 0xf200) || (buffer[0] == 1 && memblockarg == 0xf201)) { |
networker | 0:7f26f0680202 | 1481 | fprintf(stderr, "Upload Error: Target mismatch\n"); |
networker | 0:7f26f0680202 | 1482 | } |
networker | 0:7f26f0680202 | 1483 | |
networker | 0:7f26f0680202 | 1484 | // write the data |
networker | 0:7f26f0680202 | 1485 | for (i=0; dwSize >= PROGRAM_UPLOAD_PACKET_SIZE; i++, dwSize -= PROGRAM_UPLOAD_PACKET_SIZE) { |
networker | 0:7f26f0680202 | 1486 | memset(buffer, 0, 128); // clean buffer |
networker | 0:7f26f0680202 | 1487 | memcpy(buffer, pbArray + (i*PROGRAM_UPLOAD_PACKET_SIZE), MIN(dwSize, PROGRAM_UPLOAD_PACKET_SIZE)); // make sure we not change the original content |
networker | 0:7f26f0680202 | 1488 | |
networker | 0:7f26f0680202 | 1489 | crc = crc_init(); |
networker | 0:7f26f0680202 | 1490 | crc = crc_update(crc, buffer, PROGRAM_UPLOAD_PACKET_SIZE); |
networker | 0:7f26f0680202 | 1491 | crc = crc_finalize(crc); |
networker | 0:7f26f0680202 | 1492 | |
networker | 0:7f26f0680202 | 1493 | // write 128 byte |
networker | 0:7f26f0680202 | 1494 | /*printf("CRC: 0x%x\n", crc); |
networker | 0:7f26f0680202 | 1495 | printf("Paket: 0x%x\n", i+1); |
networker | 0:7f26f0680202 | 1496 | for(k=0; k<128; k++) { |
networker | 0:7f26f0680202 | 1497 | printf("0x%x ", buffer[k]); |
networker | 0:7f26f0680202 | 1498 | if ((k+1) % 16 == 0 && k != 0) printf("\n"); |
networker | 0:7f26f0680202 | 1499 | } |
networker | 0:7f26f0680202 | 1500 | printf("\n");*/ |
networker | 0:7f26f0680202 | 1501 | ret = usb_control_msg(hFt->device, 0x40, 0x11, i+1, crc, buffer, PROGRAM_UPLOAD_PACKET_SIZE, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1502 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1503 | fprintf(stderr, "Error sending control msg 0x40 0x11 0x%x\n", i+1); |
networker | 0:7f26f0680202 | 1504 | return ret; |
networker | 0:7f26f0680202 | 1505 | } |
networker | 0:7f26f0680202 | 1506 | |
networker | 0:7f26f0680202 | 1507 | // check |
networker | 0:7f26f0680202 | 1508 | ret = usb_control_msg(hFt->device, 0xC0, 0x20, 0x0, 0x0, buffer, 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1509 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1510 | fprintf(stderr, "Error sending control msg 0xC0 0x20\n"); |
networker | 0:7f26f0680202 | 1511 | return ret; |
networker | 0:7f26f0680202 | 1512 | } |
networker | 0:7f26f0680202 | 1513 | if (buffer[0] != 1) { |
networker | 0:7f26f0680202 | 1514 | fprintf(stderr, "Error uploading Program: Return value for 0xC0, 0x20 is 0x%x\n", buffer[0]); |
networker | 0:7f26f0680202 | 1515 | return FTLIB_ERR_DOWNLOAD; |
networker | 0:7f26f0680202 | 1516 | } |
networker | 0:7f26f0680202 | 1517 | } |
networker | 0:7f26f0680202 | 1518 | |
networker | 0:7f26f0680202 | 1519 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1520 | } |
networker | 0:7f26f0680202 | 1521 | |
networker | 0:7f26f0680202 | 1522 | |
networker | 0:7f26f0680202 | 1523 | /** |
networker | 0:7f26f0680202 | 1524 | * \brief Start a program |
networker | 0:7f26f0680202 | 1525 | * |
networker | 0:7f26f0680202 | 1526 | * Will start a program that has been Successfully uploaded to the interface. |
networker | 0:7f26f0680202 | 1527 | * |
networker | 0:7f26f0680202 | 1528 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1529 | * @param dwMemBlock Destination 0 (Flash 1), 1 (Flash 2) or 2 (Ram) |
networker | 0:7f26f0680202 | 1530 | * @return FTLIB_ERR_SUCCESS or FTLIB_ERR_IF_NO_PROGRAM |
networker | 0:7f26f0680202 | 1531 | */ |
networker | 0:7f26f0680202 | 1532 | long int StartFtProgram(FT_HANDLE hFt, long int dwMemBlock) { |
networker | 0:7f26f0680202 | 1533 | int ret; |
networker | 0:7f26f0680202 | 1534 | unsigned char buffer[2]; |
networker | 0:7f26f0680202 | 1535 | |
networker | 0:7f26f0680202 | 1536 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1537 | fprintf(stderr, "StartFtProgram: No such device\n"); |
networker | 0:7f26f0680202 | 1538 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1539 | } |
networker | 0:7f26f0680202 | 1540 | |
networker | 0:7f26f0680202 | 1541 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1542 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1543 | // note: serial documentation says 0xf4 here, sniffer says 0x12 |
networker | 0:7f26f0680202 | 1544 | ret = usb_control_msg(hFt->device, 0xc0, 0x12, dwMemBlock, 0, buffer, 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1545 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1546 | fprintf(stderr, "Error sending control msg 0xC0 0xF4\n"); |
networker | 0:7f26f0680202 | 1547 | return ret; |
networker | 0:7f26f0680202 | 1548 | } |
networker | 0:7f26f0680202 | 1549 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1550 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1551 | break; |
networker | 0:7f26f0680202 | 1552 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1553 | buffer[0] = 0xf4; |
networker | 0:7f26f0680202 | 1554 | buffer[1] = dwMemBlock; |
networker | 0:7f26f0680202 | 1555 | if ((write(hFt->sdev, &buffer, 2)) != 2 || (read(hFt->sdev, &buffer, 1)) != 1) { |
networker | 0:7f26f0680202 | 1556 | return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1557 | } |
networker | 0:7f26f0680202 | 1558 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1559 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1560 | break; |
networker | 0:7f26f0680202 | 1561 | } |
networker | 0:7f26f0680202 | 1562 | |
networker | 0:7f26f0680202 | 1563 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1564 | } |
networker | 0:7f26f0680202 | 1565 | |
networker | 0:7f26f0680202 | 1566 | |
networker | 0:7f26f0680202 | 1567 | /** |
networker | 0:7f26f0680202 | 1568 | * \brief Stop a program |
networker | 0:7f26f0680202 | 1569 | * |
networker | 0:7f26f0680202 | 1570 | * Will stop the current running program that has been uploaded to the interface. |
networker | 0:7f26f0680202 | 1571 | * |
networker | 0:7f26f0680202 | 1572 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1573 | * @return FTLIB_ERR_SUCCESS or FTLIB_ERR_IF_NO_PROGRAM |
networker | 0:7f26f0680202 | 1574 | */ |
networker | 0:7f26f0680202 | 1575 | long int StopFtProgram(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1576 | int ret; |
networker | 0:7f26f0680202 | 1577 | unsigned char buffer[1]; |
networker | 0:7f26f0680202 | 1578 | |
networker | 0:7f26f0680202 | 1579 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1580 | fprintf(stderr, "StopFtProgram: No such device\n"); |
networker | 0:7f26f0680202 | 1581 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1582 | } |
networker | 0:7f26f0680202 | 1583 | |
networker | 0:7f26f0680202 | 1584 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1585 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1586 | // note: serial documentation says 0xf8 here, sniffer says 0x13 |
networker | 0:7f26f0680202 | 1587 | ret = usb_control_msg(hFt->device, 0xc0, 0x13, 0, 0, buffer, 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1588 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1589 | fprintf(stderr, "Error sending control msg 0xC0 0x13\n"); |
networker | 0:7f26f0680202 | 1590 | return ret; |
networker | 0:7f26f0680202 | 1591 | } |
networker | 0:7f26f0680202 | 1592 | |
networker | 0:7f26f0680202 | 1593 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1594 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1595 | break; |
networker | 0:7f26f0680202 | 1596 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1597 | buffer[0] = 0xf8; |
networker | 0:7f26f0680202 | 1598 | if ((write(hFt->sdev, &buffer, 1)) != 1 || (read(hFt->sdev, &buffer, 1)) != 1) { |
networker | 0:7f26f0680202 | 1599 | return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1600 | } |
networker | 0:7f26f0680202 | 1601 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1602 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1603 | break; |
networker | 0:7f26f0680202 | 1604 | } |
networker | 0:7f26f0680202 | 1605 | |
networker | 0:7f26f0680202 | 1606 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1607 | } |
networker | 0:7f26f0680202 | 1608 | |
networker | 0:7f26f0680202 | 1609 | |
networker | 0:7f26f0680202 | 1610 | /** |
networker | 0:7f26f0680202 | 1611 | * \brief Delete a program |
networker | 0:7f26f0680202 | 1612 | * |
networker | 0:7f26f0680202 | 1613 | * Will delete a program that has been uploaded to the interface. |
networker | 0:7f26f0680202 | 1614 | * |
networker | 0:7f26f0680202 | 1615 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1616 | * @param dwMemBlock Destination 0 (Flash 1), 1 (Flash 2) or 2 (Ram) |
networker | 0:7f26f0680202 | 1617 | * @return FTLIB_ERR_SUCCESS or FTLIB_ERR_IF_NO_PROGRAM |
networker | 0:7f26f0680202 | 1618 | */ |
networker | 0:7f26f0680202 | 1619 | long int DeleteFtProgram(FT_HANDLE hFt, long int dwMemBlock) { |
networker | 0:7f26f0680202 | 1620 | int ret; |
networker | 0:7f26f0680202 | 1621 | unsigned char buffer[2]; |
networker | 0:7f26f0680202 | 1622 | |
networker | 0:7f26f0680202 | 1623 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1624 | fprintf(stderr, "DeleteFtProgram: No such device\n"); |
networker | 0:7f26f0680202 | 1625 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1626 | } |
networker | 0:7f26f0680202 | 1627 | |
networker | 0:7f26f0680202 | 1628 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1629 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1630 | ret = usb_control_msg(hFt->device, 0xc0, 0xf5, dwMemBlock, 0, buffer, 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1631 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1632 | fprintf(stderr, "Error sending control msg 0xC0 0xF5\n"); |
networker | 0:7f26f0680202 | 1633 | return ret; |
networker | 0:7f26f0680202 | 1634 | } |
networker | 0:7f26f0680202 | 1635 | |
networker | 0:7f26f0680202 | 1636 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1637 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1638 | break; |
networker | 0:7f26f0680202 | 1639 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1640 | buffer[0] = 0xf5; |
networker | 0:7f26f0680202 | 1641 | buffer[1] = dwMemBlock; |
networker | 0:7f26f0680202 | 1642 | if ((write(hFt->sdev, &buffer, 2)) != 2 || (read(hFt->sdev, &buffer, 1)) != 1) { |
networker | 0:7f26f0680202 | 1643 | return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1644 | } |
networker | 0:7f26f0680202 | 1645 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1646 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1647 | break; |
networker | 0:7f26f0680202 | 1648 | } |
networker | 0:7f26f0680202 | 1649 | |
networker | 0:7f26f0680202 | 1650 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1651 | } |
networker | 0:7f26f0680202 | 1652 | |
networker | 0:7f26f0680202 | 1653 | |
networker | 0:7f26f0680202 | 1654 | /** |
networker | 0:7f26f0680202 | 1655 | * \brief Activate a program |
networker | 0:7f26f0680202 | 1656 | * |
networker | 0:7f26f0680202 | 1657 | * Will activate a program that has been uploaded to the interface. |
networker | 0:7f26f0680202 | 1658 | * |
networker | 0:7f26f0680202 | 1659 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1660 | * @param dwMemBlock Destination 0 (Flash 1) or 1 (Flash 2) |
networker | 0:7f26f0680202 | 1661 | * @return FTLIB_ERR_SUCCESS or FTLIB_ERR_IF_NO_PROGRAM |
networker | 0:7f26f0680202 | 1662 | */ |
networker | 0:7f26f0680202 | 1663 | long int SetFtProgramActiv(FT_HANDLE hFt, long int dwMemBlock) { |
networker | 0:7f26f0680202 | 1664 | int ret; |
networker | 0:7f26f0680202 | 1665 | unsigned char buffer[1]; |
networker | 0:7f26f0680202 | 1666 | |
networker | 0:7f26f0680202 | 1667 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1668 | fprintf(stderr, "SetFtProgramActiv: No such device\n"); |
networker | 0:7f26f0680202 | 1669 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1670 | } |
networker | 0:7f26f0680202 | 1671 | |
networker | 0:7f26f0680202 | 1672 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1673 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1674 | ret = usb_control_msg(hFt->device, 0xc0, 0xf9, dwMemBlock, 0, buffer, 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1675 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1676 | fprintf(stderr, "Error sending control msg 0xC0 0xf9\n"); |
networker | 0:7f26f0680202 | 1677 | return ret; |
networker | 0:7f26f0680202 | 1678 | } |
networker | 0:7f26f0680202 | 1679 | |
networker | 0:7f26f0680202 | 1680 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1681 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1682 | break; |
networker | 0:7f26f0680202 | 1683 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1684 | buffer[0] = 0xf9; |
networker | 0:7f26f0680202 | 1685 | buffer[1] = dwMemBlock; |
networker | 0:7f26f0680202 | 1686 | if ((write(hFt->sdev, &buffer, 2)) != 2 || (read(hFt->sdev, &buffer, 1)) != 1) { |
networker | 0:7f26f0680202 | 1687 | return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1688 | } |
networker | 0:7f26f0680202 | 1689 | if ((buffer[0]) == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1690 | else return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1691 | break; |
networker | 0:7f26f0680202 | 1692 | } |
networker | 0:7f26f0680202 | 1693 | |
networker | 0:7f26f0680202 | 1694 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1695 | } |
networker | 0:7f26f0680202 | 1696 | |
networker | 0:7f26f0680202 | 1697 | |
networker | 0:7f26f0680202 | 1698 | /** |
networker | 0:7f26f0680202 | 1699 | * \brief Get the name of a program |
networker | 0:7f26f0680202 | 1700 | * |
networker | 0:7f26f0680202 | 1701 | * Will write the name of a program that has been uploaded to the interface to a given area. |
networker | 0:7f26f0680202 | 1702 | * |
networker | 0:7f26f0680202 | 1703 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1704 | * @param dwMemBlock Destination 0 (Flash 1), 1 (Flash 2) or 2 (Ram) |
networker | 0:7f26f0680202 | 1705 | * @param pName Pointer to the area where we can store the name |
networker | 0:7f26f0680202 | 1706 | * @param dwSize Size of the area to store the name to |
networker | 0:7f26f0680202 | 1707 | * @return FTLIB_ERR_SUCCESS or FTLIB_ERR_IF_NO_PROGRAM |
networker | 0:7f26f0680202 | 1708 | */ |
networker | 0:7f26f0680202 | 1709 | long int GetFtProgramName(FT_HANDLE hFt, long int dwMemBlock, long int dwSize, void *pName) { |
networker | 0:7f26f0680202 | 1710 | int ret; |
networker | 0:7f26f0680202 | 1711 | unsigned char buffer[dwSize+1]; |
networker | 0:7f26f0680202 | 1712 | |
networker | 0:7f26f0680202 | 1713 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1714 | fprintf(stderr, "GetFtProgramName: No such device\n"); |
networker | 0:7f26f0680202 | 1715 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1716 | } |
networker | 0:7f26f0680202 | 1717 | |
networker | 0:7f26f0680202 | 1718 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1719 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1720 | ret = usb_control_msg(hFt->device, 0xc0, 0xfa, dwMemBlock, 0, buffer, dwSize + 1, FT_USB_TIMEOUT_LONG); |
networker | 0:7f26f0680202 | 1721 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1722 | fprintf(stderr, "Error sending control msg 0xC0 0xFA\n"); |
networker | 0:7f26f0680202 | 1723 | return ret; |
networker | 0:7f26f0680202 | 1724 | } |
networker | 0:7f26f0680202 | 1725 | memcpy(pName, buffer+1, ret-1); |
networker | 0:7f26f0680202 | 1726 | |
networker | 0:7f26f0680202 | 1727 | if (buffer[0] == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1728 | if (buffer[0] == 0xf3) return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1729 | return buffer[1]; |
networker | 0:7f26f0680202 | 1730 | break; |
networker | 0:7f26f0680202 | 1731 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1732 | buffer[0] = 0xfa; |
networker | 0:7f26f0680202 | 1733 | buffer[1] = dwMemBlock; |
networker | 0:7f26f0680202 | 1734 | if ((write(hFt->sdev, &buffer, 2)) != 2 || (ret = read(hFt->sdev, &buffer, dwSize+1)) < 0 || buffer[0] != 0x01) { |
networker | 0:7f26f0680202 | 1735 | return FTLIB_ERR_IF_NO_PROGRAM; |
networker | 0:7f26f0680202 | 1736 | } |
networker | 0:7f26f0680202 | 1737 | memcpy(pName, buffer+1, ret-1); |
networker | 0:7f26f0680202 | 1738 | if (buffer[0] == 0x1) return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 1739 | break; |
networker | 0:7f26f0680202 | 1740 | } |
networker | 0:7f26f0680202 | 1741 | |
networker | 0:7f26f0680202 | 1742 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1743 | } |
networker | 0:7f26f0680202 | 1744 | |
networker | 0:7f26f0680202 | 1745 | |
networker | 0:7f26f0680202 | 1746 | /** |
networker | 0:7f26f0680202 | 1747 | * \brief Checks if a program is running |
networker | 0:7f26f0680202 | 1748 | * |
networker | 0:7f26f0680202 | 1749 | * Checks if a program is currently running. |
networker | 0:7f26f0680202 | 1750 | * |
networker | 0:7f26f0680202 | 1751 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1752 | * @param num Area where we can store the number of the running program. |
networker | 0:7f26f0680202 | 1753 | * @return 1 if a program is running, else 0 |
networker | 0:7f26f0680202 | 1754 | */ |
networker | 0:7f26f0680202 | 1755 | int GetFtStatus(FT_HANDLE hFt, int *num) { |
networker | 0:7f26f0680202 | 1756 | int ret; |
networker | 0:7f26f0680202 | 1757 | unsigned char buffer[3]; |
networker | 0:7f26f0680202 | 1758 | |
networker | 0:7f26f0680202 | 1759 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1760 | fprintf(stderr, "GetFtStatus: No such device\n"); |
networker | 0:7f26f0680202 | 1761 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1762 | } |
networker | 0:7f26f0680202 | 1763 | |
networker | 0:7f26f0680202 | 1764 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1765 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1766 | // test replace 0xf0 with 0x50 |
networker | 0:7f26f0680202 | 1767 | ret = usb_control_msg(hFt->device, 0xc0, 0xf0, 0x3, 0, buffer, 3, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1768 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1769 | fprintf(stderr, "Error sending control msg 0xC0 0xF0\n"); |
networker | 0:7f26f0680202 | 1770 | return ret; |
networker | 0:7f26f0680202 | 1771 | } |
networker | 0:7f26f0680202 | 1772 | ret = buffer[1]; |
networker | 0:7f26f0680202 | 1773 | *num = buffer[2]; |
networker | 0:7f26f0680202 | 1774 | break; |
networker | 0:7f26f0680202 | 1775 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1776 | buffer[0] = 0xf0; |
networker | 0:7f26f0680202 | 1777 | buffer[1] = 0x3; |
networker | 0:7f26f0680202 | 1778 | if ((write(hFt->sdev, &buffer, 2)) != 2 || (ret = read(hFt->sdev, &buffer, 3)) < 0 || buffer[0] != 0xfc) { |
networker | 0:7f26f0680202 | 1779 | return ret; |
networker | 0:7f26f0680202 | 1780 | } |
networker | 0:7f26f0680202 | 1781 | ret = buffer[1]; |
networker | 0:7f26f0680202 | 1782 | *num = buffer[2]; |
networker | 0:7f26f0680202 | 1783 | break; |
networker | 0:7f26f0680202 | 1784 | default: |
networker | 0:7f26f0680202 | 1785 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1786 | } |
networker | 0:7f26f0680202 | 1787 | |
networker | 0:7f26f0680202 | 1788 | return ret; |
networker | 0:7f26f0680202 | 1789 | } |
networker | 0:7f26f0680202 | 1790 | #endif //USE_DOWNLOAD |
networker | 0:7f26f0680202 | 1791 | |
networker | 0:7f26f0680202 | 1792 | /** |
networker | 0:7f26f0680202 | 1793 | * \brief Get the firmware number of this interface. |
networker | 0:7f26f0680202 | 1794 | * |
networker | 0:7f26f0680202 | 1795 | * Returns the firmware number of the interface squashed into a single int. |
networker | 0:7f26f0680202 | 1796 | * |
networker | 0:7f26f0680202 | 1797 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1798 | * @return Firmware number as int byte4 | byte3 | byte2 | byte1, 0 on error. |
networker | 0:7f26f0680202 | 1799 | */ |
networker | 0:7f26f0680202 | 1800 | long int GetFtFirmware(FT_HANDLE hFt) {//makes a blocking comm request |
networker | 0:7f26f0680202 | 1801 | int ret; |
networker | 0:7f26f0680202 | 1802 | unsigned char buffer[35] = { 0 }; |
networker | 0:7f26f0680202 | 1803 | long int firmware = 0; |
networker | 0:7f26f0680202 | 1804 | |
networker | 0:7f26f0680202 | 1805 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1806 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 1807 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1808 | } |
networker | 0:7f26f0680202 | 1809 | |
networker | 0:7f26f0680202 | 1810 | |
networker | 0:7f26f0680202 | 1811 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1812 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 1813 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 1814 | return 0; |
networker | 0:7f26f0680202 | 1815 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 1816 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1817 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 1818 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 1819 | ret = usb_control_msg(hFt->device, 0xc0, 0xf0, 0x1, 0, buffer, 5, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1820 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1821 | fprintf(stderr, "Error sending control msg 0xC0 0xF0\n"); |
networker | 0:7f26f0680202 | 1822 | return 0; |
networker | 0:7f26f0680202 | 1823 | } |
networker | 0:7f26f0680202 | 1824 | firmware = buffer[1] | buffer[2]<<8 | buffer[3]<<16 | buffer[4]<<24; |
networker | 0:7f26f0680202 | 1825 | break; |
networker | 0:7f26f0680202 | 1826 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 1827 | ret = usb_control_msg(hFt->device, 0xc0, 0x52, hFt->transfer_area.RfModulNr<<8 | 0x05, 0, buffer, 35, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1828 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1829 | fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker | 0:7f26f0680202 | 1830 | return 0; |
networker | 0:7f26f0680202 | 1831 | } |
networker | 0:7f26f0680202 | 1832 | if (buffer[0] == 0xfa && buffer[1] == 0) { // buffer[1] == 0xff => no device |
networker | 0:7f26f0680202 | 1833 | firmware = buffer[23]<<24 | buffer[22]<<16 | buffer[21]<<8 | buffer[20]; |
networker | 0:7f26f0680202 | 1834 | } |
networker | 0:7f26f0680202 | 1835 | break; |
networker | 0:7f26f0680202 | 1836 | #endif |
networker | 0:7f26f0680202 | 1837 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1838 | buffer[0] = 0xf0; |
networker | 0:7f26f0680202 | 1839 | buffer[1] = 0x01; |
networker | 0:7f26f0680202 | 1840 | #ifdef MBED |
networker | 0:7f26f0680202 | 1841 | //printf("requesting FW\n"); |
networker | 0:7f26f0680202 | 1842 | //ret = hFt->sdev->printf("%2c", buffer); |
networker | 0:7f26f0680202 | 1843 | ret = write(hFt->sdev, buffer, 2); |
networker | 0:7f26f0680202 | 1844 | // printf("request was sent %d\n", ret); |
networker | 0:7f26f0680202 | 1845 | #else |
networker | 0:7f26f0680202 | 1846 | ret = write(hFt->sdev, &buffer, 2); |
networker | 0:7f26f0680202 | 1847 | #endif |
networker | 0:7f26f0680202 | 1848 | if (ret != 2) { |
networker | 0:7f26f0680202 | 1849 | fprintf(stderr, "Error writing msg 0xF0 0x01\n"); |
networker | 0:7f26f0680202 | 1850 | return 0; |
networker | 0:7f26f0680202 | 1851 | } |
networker | 0:7f26f0680202 | 1852 | #ifdef MBED |
networker | 0:7f26f0680202 | 1853 | //ret = hFt->sdev->scanf("%5c", buffer)==1 ? 5 : 0 ; |
networker | 0:7f26f0680202 | 1854 | ret = read(hFt->sdev, buffer, 5); |
networker | 0:7f26f0680202 | 1855 | #else |
networker | 0:7f26f0680202 | 1856 | ret = read(hFt->sdev, &buffer, 5); |
networker | 0:7f26f0680202 | 1857 | #endif |
networker | 0:7f26f0680202 | 1858 | if (ret != 5) { |
networker | 0:7f26f0680202 | 1859 | fprintf(stderr, "Error reading msg 0xF0 0x01\n"); |
networker | 0:7f26f0680202 | 1860 | return 0; |
networker | 0:7f26f0680202 | 1861 | } |
networker | 0:7f26f0680202 | 1862 | firmware = buffer[1] | buffer[2]<<8 | buffer[3]<<16 | buffer[4]<<24; |
networker | 0:7f26f0680202 | 1863 | // printf("fw: %ld\n", firmware); |
networker | 0:7f26f0680202 | 1864 | break; |
networker | 0:7f26f0680202 | 1865 | default: |
networker | 0:7f26f0680202 | 1866 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1867 | } |
networker | 0:7f26f0680202 | 1868 | |
networker | 0:7f26f0680202 | 1869 | return firmware; |
networker | 0:7f26f0680202 | 1870 | } |
networker | 0:7f26f0680202 | 1871 | |
networker | 0:7f26f0680202 | 1872 | |
networker | 0:7f26f0680202 | 1873 | /** |
networker | 0:7f26f0680202 | 1874 | * \brief Get the firmware number of this interface. |
networker | 0:7f26f0680202 | 1875 | * |
networker | 0:7f26f0680202 | 1876 | * Returns the firmware number of the interface with this handle. |
networker | 0:7f26f0680202 | 1877 | * The allocated space should be freed with free() later. |
networker | 0:7f26f0680202 | 1878 | * |
networker | 0:7f26f0680202 | 1879 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1880 | * @return Pointer to a string with the firmware |
networker | 0:7f26f0680202 | 1881 | */ |
networker | 0:7f26f0680202 | 1882 | char *GetFtFirmwareStrg(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1883 | long int ifw = GetFtFirmware(hFt); |
networker | 0:7f26f0680202 | 1884 | char *s = (char *)malloc(16); |
networker | 0:7f26f0680202 | 1885 | int byte1 = ifw & 0xff; |
networker | 0:7f26f0680202 | 1886 | int byte2 = (ifw & 0xff00) >> 8; |
networker | 0:7f26f0680202 | 1887 | int byte3 = (ifw & 0xff0000) >> 16; |
networker | 0:7f26f0680202 | 1888 | int byte4 = (ifw & 0xff000000) >> 24; |
networker | 0:7f26f0680202 | 1889 | |
networker | 0:7f26f0680202 | 1890 | snprintf(s, 16, "%d.%02d.%02d.%02d", byte4, byte3, byte2, byte1); |
networker | 0:7f26f0680202 | 1891 | |
networker | 0:7f26f0680202 | 1892 | return s; |
networker | 0:7f26f0680202 | 1893 | } |
networker | 0:7f26f0680202 | 1894 | |
networker | 0:7f26f0680202 | 1895 | |
networker | 0:7f26f0680202 | 1896 | #ifndef NOTNOW |
networker | 0:7f26f0680202 | 1897 | /** |
networker | 0:7f26f0680202 | 1898 | * \brief Get the serial number of this interface. |
networker | 0:7f26f0680202 | 1899 | * |
networker | 0:7f26f0680202 | 1900 | * Returns the serial number of the interface squashed into a single int. |
networker | 0:7f26f0680202 | 1901 | * |
networker | 0:7f26f0680202 | 1902 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1903 | * @return Serial number as int byte4 | byte3 | byte2 | byte1, 0 on error. |
networker | 0:7f26f0680202 | 1904 | */ |
networker | 0:7f26f0680202 | 1905 | long int GetFtSerialNr(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1906 | int ret; |
networker | 0:7f26f0680202 | 1907 | unsigned char buffer[35] = { 0 }; |
networker | 0:7f26f0680202 | 1908 | long int serial = 0; |
networker | 0:7f26f0680202 | 1909 | |
networker | 0:7f26f0680202 | 1910 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 1911 | fprintf(stderr, "GetFtSerialNr: No such device\n"); |
networker | 0:7f26f0680202 | 1912 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 1913 | } |
networker | 0:7f26f0680202 | 1914 | |
networker | 0:7f26f0680202 | 1915 | |
networker | 0:7f26f0680202 | 1916 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 1917 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 1918 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 1919 | return 0; |
networker | 0:7f26f0680202 | 1920 | break; |
networker | 0:7f26f0680202 | 1921 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 1922 | ret = usb_control_msg(hFt->device, 0xc0, 0xf0, 0x2, 0, buffer, 5, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1923 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1924 | fprintf(stderr, "Error sending control msg 0xC0 0xF0\n"); |
networker | 0:7f26f0680202 | 1925 | return 0; |
networker | 0:7f26f0680202 | 1926 | } |
networker | 0:7f26f0680202 | 1927 | serial = buffer[1] + buffer[2]*100 + buffer[3]*10000 + buffer[4]*1000000; |
networker | 0:7f26f0680202 | 1928 | break; |
networker | 0:7f26f0680202 | 1929 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 1930 | ret = usb_control_msg(hFt->device, 0xc0, 0xf0, 0x2, 0, buffer, 14, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1931 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1932 | fprintf(stderr, "Error sending control msg 0xC0 0xF0\n"); |
networker | 0:7f26f0680202 | 1933 | return 0; |
networker | 0:7f26f0680202 | 1934 | } |
networker | 0:7f26f0680202 | 1935 | serial = buffer[1] + buffer[2]*100 + buffer[3]*10000 + buffer[4]*1000000; |
networker | 0:7f26f0680202 | 1936 | break; |
networker | 0:7f26f0680202 | 1937 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 1938 | ret = usb_control_msg(hFt->device, 0xc0, 0xf0, 0x2, 0, buffer, 14, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1939 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1940 | fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker | 0:7f26f0680202 | 1941 | return 0; |
networker | 0:7f26f0680202 | 1942 | } |
networker | 0:7f26f0680202 | 1943 | serial = buffer[1] + buffer[2]*100 + buffer[3]*10000 + buffer[4]*1000000; |
networker | 0:7f26f0680202 | 1944 | break; |
networker | 0:7f26f0680202 | 1945 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 1946 | ret = usb_control_msg(hFt->device, 0xc0, 0x52, hFt->transfer_area.RfModulNr<<8 | 0x05, 0, buffer, 35, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 1947 | if (ret < 0) { |
networker | 0:7f26f0680202 | 1948 | fprintf(stderr, "Error sending control msg 0xC0 0x52\n"); |
networker | 0:7f26f0680202 | 1949 | return 0; |
networker | 0:7f26f0680202 | 1950 | } |
networker | 0:7f26f0680202 | 1951 | if (buffer[0] == 0xfa && buffer[1] == 0) { // buffer[1] == 0xff => no device |
networker | 0:7f26f0680202 | 1952 | serial = buffer[6]*1000000 + buffer[5]*10000 + buffer[4]*100 + buffer[3]; |
networker | 0:7f26f0680202 | 1953 | } |
networker | 0:7f26f0680202 | 1954 | break; |
networker | 0:7f26f0680202 | 1955 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 1956 | buffer[0] = 0xf0; |
networker | 0:7f26f0680202 | 1957 | buffer[1] = 0x02; |
networker | 0:7f26f0680202 | 1958 | ret = write(hFt->sdev, &buffer, 2); |
networker | 0:7f26f0680202 | 1959 | if (ret != 2) { |
networker | 0:7f26f0680202 | 1960 | fprintf(stderr, "Error writing msg 0xF0 0x02\n"); |
networker | 0:7f26f0680202 | 1961 | return 0; |
networker | 0:7f26f0680202 | 1962 | } |
networker | 0:7f26f0680202 | 1963 | ret = read(hFt->sdev, &buffer, 5); |
networker | 0:7f26f0680202 | 1964 | if (ret != 5) { |
networker | 0:7f26f0680202 | 1965 | fprintf(stderr, "Error reading msg 0xF0 0x02\n"); |
networker | 0:7f26f0680202 | 1966 | return 0; |
networker | 0:7f26f0680202 | 1967 | } |
networker | 0:7f26f0680202 | 1968 | serial = buffer[1] + buffer[2]*100 + buffer[3]*10000 + buffer[4]*1000000; |
networker | 0:7f26f0680202 | 1969 | break; |
networker | 0:7f26f0680202 | 1970 | default: |
networker | 0:7f26f0680202 | 1971 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 1972 | } |
networker | 0:7f26f0680202 | 1973 | |
networker | 0:7f26f0680202 | 1974 | return serial; |
networker | 0:7f26f0680202 | 1975 | } |
networker | 0:7f26f0680202 | 1976 | |
networker | 0:7f26f0680202 | 1977 | |
networker | 0:7f26f0680202 | 1978 | /** |
networker | 0:7f26f0680202 | 1979 | * \brief Get the serial number of this interface. |
networker | 0:7f26f0680202 | 1980 | * |
networker | 0:7f26f0680202 | 1981 | * Returns the serial number of the interface with this handle. |
networker | 0:7f26f0680202 | 1982 | * The allocated space should be freed with free() later. |
networker | 0:7f26f0680202 | 1983 | * |
networker | 0:7f26f0680202 | 1984 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 1985 | * @return Pointer to a string with the serial |
networker | 0:7f26f0680202 | 1986 | */ |
networker | 0:7f26f0680202 | 1987 | char *GetFtSerialNrStrg(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 1988 | long int ifw = GetFtSerialNr(hFt); |
networker | 0:7f26f0680202 | 1989 | char *s = (char *)malloc(16); |
networker | 0:7f26f0680202 | 1990 | int byte1, byte2, byte3, byte4; |
networker | 0:7f26f0680202 | 1991 | |
networker | 0:7f26f0680202 | 1992 | byte1 = ifw % 100; |
networker | 0:7f26f0680202 | 1993 | ifw /= 100; |
networker | 0:7f26f0680202 | 1994 | byte2 = ifw % 100; |
networker | 0:7f26f0680202 | 1995 | ifw /= 100; |
networker | 0:7f26f0680202 | 1996 | byte3 = ifw % 100; |
networker | 0:7f26f0680202 | 1997 | ifw /= 100; |
networker | 0:7f26f0680202 | 1998 | byte4 = ifw % 100; |
networker | 0:7f26f0680202 | 1999 | ifw /= 100; |
networker | 0:7f26f0680202 | 2000 | |
networker | 0:7f26f0680202 | 2001 | snprintf(s, 16, "%d.%02d.%02d.%02d", byte4, byte3, byte2, byte1); |
networker | 0:7f26f0680202 | 2002 | |
networker | 0:7f26f0680202 | 2003 | return s; |
networker | 0:7f26f0680202 | 2004 | } |
networker | 0:7f26f0680202 | 2005 | |
networker | 0:7f26f0680202 | 2006 | |
networker | 0:7f26f0680202 | 2007 | /** |
networker | 0:7f26f0680202 | 2008 | * \brief Close all ft devices |
networker | 0:7f26f0680202 | 2009 | * |
networker | 0:7f26f0680202 | 2010 | * Dummy. Can't be supported. Only used in original library. |
networker | 0:7f26f0680202 | 2011 | * |
networker | 0:7f26f0680202 | 2012 | * @return Always FTLIB_ERR_NOT_SUPPORTED |
networker | 0:7f26f0680202 | 2013 | */ |
networker | 0:7f26f0680202 | 2014 | long int CloseAllFtDevices() { |
networker | 0:7f26f0680202 | 2015 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 2016 | } |
networker | 0:7f26f0680202 | 2017 | |
networker | 0:7f26f0680202 | 2018 | |
networker | 0:7f26f0680202 | 2019 | /** |
networker | 0:7f26f0680202 | 2020 | * \brief Set the inputs D1 and D2 to distance oder voltage measuring |
networker | 0:7f26f0680202 | 2021 | * |
networker | 0:7f26f0680202 | 2022 | * This function allows to enable the inputs D1 and D2 to measure distances. |
networker | 0:7f26f0680202 | 2023 | * Must be called before StartFtTransferArea() |
networker | 0:7f26f0680202 | 2024 | * |
networker | 0:7f26f0680202 | 2025 | * Note by Hardware Vendor: |
networker | 0:7f26f0680202 | 2026 | * "Since the operating mode of the D1 / D2 inputs can be set by means of software, we recommend that no |
networker | 0:7f26f0680202 | 2027 | * voltage be supplied 'directly' to these connections in order to avoid damage to the interface during software |
networker | 0:7f26f0680202 | 2028 | * errors. Since the inputs are highly resistive, a resistance of approximately 200 Ohm - 470 Ohm should be |
networker | 0:7f26f0680202 | 2029 | * directly connected to the D1 / D2 socket (series connection). We recommend to connect the voltage range to |
networker | 0:7f26f0680202 | 2030 | * be measured 'behind' it." |
networker | 0:7f26f0680202 | 2031 | * |
networker | 0:7f26f0680202 | 2032 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2033 | * @param dwMode Set mode to IF_DS_INPUT_VOLTAGE (measure voltage) or IF_DS_INPUT_DISTANCE (measure distance) |
networker | 0:7f26f0680202 | 2034 | * @param dwTol1 Range of tolerance for D1. Try IF_DS_INPUT_TOL_STD (20). |
networker | 0:7f26f0680202 | 2035 | * @param dwTol2 Range of tolerance for D2. Try IF_DS_INPUT_TOL_STD (20). |
networker | 0:7f26f0680202 | 2036 | * @param dwLevel1 Threshold for D1. Try 100. |
networker | 0:7f26f0680202 | 2037 | * @param dwLevel2 Threshold for D2. Try 100. |
networker | 0:7f26f0680202 | 2038 | * @param dwRepeat1 Repition value for D1. Try IF_DS_INPUT_REP_STD (3). |
networker | 0:7f26f0680202 | 2039 | * @param dwRepeat2 Repition value for D2. Try IF_DS_INPUT_REP_STD (3). |
networker | 0:7f26f0680202 | 2040 | * @return FTLIB_ERR_SUCCESS on success |
networker | 0:7f26f0680202 | 2041 | */ |
networker | 0:7f26f0680202 | 2042 | long int SetFtDistanceSensorMode(FT_HANDLE hFt, long int dwMode, long int dwTol1, long int dwTol2, long int dwLevel1, long int dwLevel2, long int dwRepeat1, long int dwRepeat2) { |
networker | 0:7f26f0680202 | 2043 | int ret; |
networker | 0:7f26f0680202 | 2044 | unsigned char buffer[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // 34 |
networker | 0:7f26f0680202 | 2045 | int i; |
networker | 0:7f26f0680202 | 2046 | |
networker | 0:7f26f0680202 | 2047 | buffer[1] = dwTol1; |
networker | 0:7f26f0680202 | 2048 | buffer[2] = dwTol2; |
networker | 0:7f26f0680202 | 2049 | buffer[3] = dwLevel1; |
networker | 0:7f26f0680202 | 2050 | buffer[4] = dwLevel1>>8; |
networker | 0:7f26f0680202 | 2051 | buffer[5] = dwLevel2; |
networker | 0:7f26f0680202 | 2052 | buffer[6] = dwLevel2>>8; |
networker | 0:7f26f0680202 | 2053 | buffer[7] = dwRepeat1; |
networker | 0:7f26f0680202 | 2054 | buffer[8] = dwRepeat2; |
networker | 0:7f26f0680202 | 2055 | |
networker | 0:7f26f0680202 | 2056 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 2057 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 2058 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 2059 | } |
networker | 0:7f26f0680202 | 2060 | |
networker | 0:7f26f0680202 | 2061 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2062 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2063 | ret = usb_control_msg(hFt->device, 0x40, 0xf1, 0x1, dwMode, buffer+1, 8, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2064 | if (ret != 8) { |
networker | 0:7f26f0680202 | 2065 | fprintf(stderr, "Error sending control msg 0x40 0xf1\n"); |
networker | 0:7f26f0680202 | 2066 | return ret; |
networker | 0:7f26f0680202 | 2067 | } |
networker | 0:7f26f0680202 | 2068 | break; |
networker | 0:7f26f0680202 | 2069 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2070 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2071 | ret = usb_control_msg(hFt->device, 0x40, 0x53, hFt->transfer_area.RfModulNr<<8 | 0x01, 0, buffer, 34, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2072 | if (ret != 34) { |
networker | 0:7f26f0680202 | 2073 | fprintf(stderr, "Error sending control msg 0x40 0x53\n"); |
networker | 0:7f26f0680202 | 2074 | return ret; |
networker | 0:7f26f0680202 | 2075 | } |
networker | 0:7f26f0680202 | 2076 | break; |
networker | 0:7f26f0680202 | 2077 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 2078 | // move data in array for two bytes |
networker | 0:7f26f0680202 | 2079 | for (i=10; i>=3; i--) { |
networker | 0:7f26f0680202 | 2080 | buffer[i] = buffer[i-2]; |
networker | 0:7f26f0680202 | 2081 | } |
networker | 0:7f26f0680202 | 2082 | buffer[0] = 0xf1; |
networker | 0:7f26f0680202 | 2083 | buffer[1] = 0x01; |
networker | 0:7f26f0680202 | 2084 | buffer[2] = dwMode; |
networker | 0:7f26f0680202 | 2085 | if ((write(hFt->sdev, &buffer, 11)) != 11 || (read(hFt->sdev, &buffer, 1)) != 1 || buffer[0] != 0x01) { |
networker | 0:7f26f0680202 | 2086 | fprintf(stderr, "SetFtDistanceSensorMode: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 2087 | return buffer[0]; |
networker | 0:7f26f0680202 | 2088 | } |
networker | 0:7f26f0680202 | 2089 | break; |
networker | 0:7f26f0680202 | 2090 | default: |
networker | 0:7f26f0680202 | 2091 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 2092 | } |
networker | 0:7f26f0680202 | 2093 | |
networker | 0:7f26f0680202 | 2094 | usleep(100000); // wait before continue, else it doesn't always work |
networker | 0:7f26f0680202 | 2095 | |
networker | 0:7f26f0680202 | 2096 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 2097 | } |
networker | 0:7f26f0680202 | 2098 | |
networker | 0:7f26f0680202 | 2099 | |
networker | 0:7f26f0680202 | 2100 | /** |
networker | 0:7f26f0680202 | 2101 | * \brief Sets the frequency and call sign for a Robo Interface or RF Data Link. |
networker | 0:7f26f0680202 | 2102 | * |
networker | 0:7f26f0680202 | 2103 | * Sets the frequency and call sign which allows to control multiple Interfaces at one RF Data Link. |
networker | 0:7f26f0680202 | 2104 | * The value won't be lost on power failure. |
networker | 0:7f26f0680202 | 2105 | * |
networker | 0:7f26f0680202 | 2106 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2107 | * @param frequency to use. May be between 2 and 80. |
networker | 0:7f26f0680202 | 2108 | * @param callSign call sign for this Interface. May be between 1 and 8. (ignored for the RF Data Link) |
networker | 0:7f26f0680202 | 2109 | * @return FTLIB_ERR_SUCCESS on success |
networker | 0:7f26f0680202 | 2110 | */ |
networker | 0:7f26f0680202 | 2111 | long int SetRFMode(FT_HANDLE hFt, long int frequency, long int callSign) { |
networker | 0:7f26f0680202 | 2112 | int ret; |
networker | 0:7f26f0680202 | 2113 | unsigned char buffer[5]; |
networker | 0:7f26f0680202 | 2114 | |
networker | 0:7f26f0680202 | 2115 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 2116 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 2117 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 2118 | } else if (frequency < 2 || frequency > 80) { |
networker | 0:7f26f0680202 | 2119 | return FTLIB_ERR_INVALID_PARAM; |
networker | 0:7f26f0680202 | 2120 | } else if (callSign > 8) { |
networker | 0:7f26f0680202 | 2121 | return FTLIB_ERR_INVALID_PARAM; |
networker | 0:7f26f0680202 | 2122 | } |
networker | 0:7f26f0680202 | 2123 | |
networker | 0:7f26f0680202 | 2124 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2125 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2126 | ret = usb_control_msg(hFt->device, 0xc0, 0xfb, 1, frequency, buffer, 2, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2127 | if (ret != 2 || buffer[0] != 0xfe || buffer[1] != 0) { |
networker | 0:7f26f0680202 | 2128 | fprintf(stderr, "Error sending control msg 0xc0 0xfb\n"); |
networker | 0:7f26f0680202 | 2129 | return ret; |
networker | 0:7f26f0680202 | 2130 | } |
networker | 0:7f26f0680202 | 2131 | break; |
networker | 0:7f26f0680202 | 2132 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2133 | // not or-ing 1 to frequency seems to disable the modul |
networker | 0:7f26f0680202 | 2134 | ret = usb_control_msg(hFt->device, 0xc0, 0xfb, (callSign<<8) | 1, (1<<8) | frequency, buffer, 2, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2135 | if (ret != 2 || buffer[0] != 0xfe || buffer[1] != 0) { |
networker | 0:7f26f0680202 | 2136 | fprintf(stderr, "Error sending control msg 0xc0 0xfb\n"); |
networker | 0:7f26f0680202 | 2137 | return ret; |
networker | 0:7f26f0680202 | 2138 | } |
networker | 0:7f26f0680202 | 2139 | break; |
networker | 0:7f26f0680202 | 2140 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 2141 | buffer[0] = 0xfb; |
networker | 0:7f26f0680202 | 2142 | buffer[1] = 0x1; |
networker | 0:7f26f0680202 | 2143 | buffer[2] = 0x7f; |
networker | 0:7f26f0680202 | 2144 | buffer[3] = frequency; |
networker | 0:7f26f0680202 | 2145 | buffer[4] = callSign; |
networker | 0:7f26f0680202 | 2146 | if ((write(hFt->sdev, &buffer, 5)) != 5 || (ret = read(hFt->sdev, &buffer, 2)) != 2 || buffer[0] != 0xfe) { |
networker | 0:7f26f0680202 | 2147 | fprintf(stderr, "SetRFMode: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 2148 | return ret; |
networker | 0:7f26f0680202 | 2149 | } |
networker | 0:7f26f0680202 | 2150 | break; |
networker | 0:7f26f0680202 | 2151 | default: |
networker | 0:7f26f0680202 | 2152 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 2153 | } |
networker | 0:7f26f0680202 | 2154 | |
networker | 0:7f26f0680202 | 2155 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 2156 | } |
networker | 0:7f26f0680202 | 2157 | |
networker | 0:7f26f0680202 | 2158 | |
networker | 0:7f26f0680202 | 2159 | /** |
networker | 0:7f26f0680202 | 2160 | * \brief Gets the frequency and call sign of a Robo Interface or RF Data Link. |
networker | 0:7f26f0680202 | 2161 | * |
networker | 0:7f26f0680202 | 2162 | * Sets the frequency and call sign which allows to control multiple Interfaces at one RF Data Link. |
networker | 0:7f26f0680202 | 2163 | * |
networker | 0:7f26f0680202 | 2164 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2165 | * @param frequency Points to a place to store the frequency. |
networker | 0:7f26f0680202 | 2166 | * @param callSign Points to a place to store the callSign. (Value will be 0 for the RF Data Link) |
networker | 0:7f26f0680202 | 2167 | * @return FTLIB_ERR_SUCCESS on success |
networker | 0:7f26f0680202 | 2168 | */ |
networker | 0:7f26f0680202 | 2169 | long int GetRFMode(FT_HANDLE hFt, long int *frequency, long int *callSign) { |
networker | 0:7f26f0680202 | 2170 | int ret; |
networker | 0:7f26f0680202 | 2171 | unsigned char buffer[8]; |
networker | 0:7f26f0680202 | 2172 | |
networker | 0:7f26f0680202 | 2173 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 2174 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 2175 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 2176 | } |
networker | 0:7f26f0680202 | 2177 | |
networker | 0:7f26f0680202 | 2178 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2179 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2180 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2181 | ret = usb_control_msg(hFt->device, 0xc0, 0xfb, 0x81, 0, buffer, 8, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2182 | if (ret != 8) { |
networker | 0:7f26f0680202 | 2183 | fprintf(stderr, "Error sending control msg 0xc0 0xfb\n"); |
networker | 0:7f26f0680202 | 2184 | return ret; |
networker | 0:7f26f0680202 | 2185 | } |
networker | 0:7f26f0680202 | 2186 | *frequency = buffer[6]; |
networker | 0:7f26f0680202 | 2187 | *callSign = buffer[7]; |
networker | 0:7f26f0680202 | 2188 | break; |
networker | 0:7f26f0680202 | 2189 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 2190 | buffer[0] = 0xfb; |
networker | 0:7f26f0680202 | 2191 | buffer[1] = 0x81; |
networker | 0:7f26f0680202 | 2192 | if ((write(hFt->sdev, &buffer, 2)) != 2 || (ret = read(hFt->sdev, &buffer, 8)) != 8 || buffer[0] != 0x7e) { |
networker | 0:7f26f0680202 | 2193 | fprintf(stderr, "GetRFMode: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 2194 | return ret; |
networker | 0:7f26f0680202 | 2195 | } |
networker | 0:7f26f0680202 | 2196 | *frequency = buffer[6]; |
networker | 0:7f26f0680202 | 2197 | *callSign = buffer[7]; |
networker | 0:7f26f0680202 | 2198 | break; |
networker | 0:7f26f0680202 | 2199 | default: |
networker | 0:7f26f0680202 | 2200 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 2201 | } |
networker | 0:7f26f0680202 | 2202 | |
networker | 0:7f26f0680202 | 2203 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 2204 | } |
networker | 0:7f26f0680202 | 2205 | |
networker | 0:7f26f0680202 | 2206 | |
networker | 0:7f26f0680202 | 2207 | /** |
networker | 0:7f26f0680202 | 2208 | * \brief Switches between the real serial and 0001 of a device. |
networker | 0:7f26f0680202 | 2209 | * |
networker | 0:7f26f0680202 | 2210 | * Every ft Interface is shipped with 0001 as serial. |
networker | 0:7f26f0680202 | 2211 | * Nevertheless each has its own serial which can be activated. |
networker | 0:7f26f0680202 | 2212 | * |
networker | 0:7f26f0680202 | 2213 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2214 | * @param bOn 0 to use 0001, else the real serial |
networker | 0:7f26f0680202 | 2215 | * @return FTLIB_ERR_SUCCESS on success |
networker | 0:7f26f0680202 | 2216 | */ |
networker | 0:7f26f0680202 | 2217 | long int SetRealSerial(FT_HANDLE hFt, unsigned char bOn) { |
networker | 0:7f26f0680202 | 2218 | int ret; |
networker | 0:7f26f0680202 | 2219 | // on: 2 0xd2 0x3a |
networker | 0:7f26f0680202 | 2220 | // off: 1 0x81 0x6f |
networker | 0:7f26f0680202 | 2221 | // RF: 2 d8 77 vs 1 8b 22 |
networker | 0:7f26f0680202 | 2222 | // Whats the number? |
networker | 0:7f26f0680202 | 2223 | // SetSerial(hFt, 5386); |
networker | 0:7f26f0680202 | 2224 | unsigned char buffer[16] = {0xaf, 0x83, 0x55, 0xa1, 1, 0, 0, 0, 1, 0x81, 0x6f, 0, 0, 0, 0, 0}; |
networker | 0:7f26f0680202 | 2225 | |
networker | 0:7f26f0680202 | 2226 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 2227 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 2228 | return FTLIB_ERR_PORT_NUMBER_IS_NULL; |
networker | 0:7f26f0680202 | 2229 | } |
networker | 0:7f26f0680202 | 2230 | |
networker | 0:7f26f0680202 | 2231 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2232 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2233 | if (bOn) { |
networker | 0:7f26f0680202 | 2234 | buffer[8] = 2; |
networker | 0:7f26f0680202 | 2235 | buffer[9] = 0xd2; |
networker | 0:7f26f0680202 | 2236 | buffer[10] = 0x3a; |
networker | 0:7f26f0680202 | 2237 | } else { |
networker | 0:7f26f0680202 | 2238 | buffer[8] = 1; |
networker | 0:7f26f0680202 | 2239 | buffer[9] = 0x81; |
networker | 0:7f26f0680202 | 2240 | buffer[10] = 0x6f; |
networker | 0:7f26f0680202 | 2241 | } |
networker | 0:7f26f0680202 | 2242 | ret = usb_control_msg(hFt->device, 0x40, 0xaf, 0x83, 0, buffer, 16, 200000); |
networker | 0:7f26f0680202 | 2243 | if (ret != 16) { |
networker | 0:7f26f0680202 | 2244 | fprintf(stderr, "Error sending control msg 0x40 0xaf\n"); |
networker | 0:7f26f0680202 | 2245 | return ret; |
networker | 0:7f26f0680202 | 2246 | } |
networker | 0:7f26f0680202 | 2247 | break; |
networker | 0:7f26f0680202 | 2248 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2249 | if (bOn) { |
networker | 0:7f26f0680202 | 2250 | buffer[8] = 2; |
networker | 0:7f26f0680202 | 2251 | buffer[9] = 0xd8; |
networker | 0:7f26f0680202 | 2252 | buffer[10] = 0x77; |
networker | 0:7f26f0680202 | 2253 | } else { |
networker | 0:7f26f0680202 | 2254 | buffer[8] = 1; |
networker | 0:7f26f0680202 | 2255 | buffer[9] = 0x8b; |
networker | 0:7f26f0680202 | 2256 | buffer[10] = 0x22; |
networker | 0:7f26f0680202 | 2257 | } |
networker | 0:7f26f0680202 | 2258 | ret = usb_control_msg(hFt->device, 0x40, 0xaf, 0x83, 0, buffer, 16, 200000); |
networker | 0:7f26f0680202 | 2259 | if (ret != 16) { |
networker | 0:7f26f0680202 | 2260 | fprintf(stderr, "Error sending control msg 0x40 0xaf\n"); |
networker | 0:7f26f0680202 | 2261 | return ret; |
networker | 0:7f26f0680202 | 2262 | } |
networker | 0:7f26f0680202 | 2263 | break; |
networker | 0:7f26f0680202 | 2264 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 2265 | if (bOn) { |
networker | 0:7f26f0680202 | 2266 | buffer[8] = 2; |
networker | 0:7f26f0680202 | 2267 | buffer[9] = 0x5f; |
networker | 0:7f26f0680202 | 2268 | buffer[10] = 0x28; |
networker | 0:7f26f0680202 | 2269 | } else { |
networker | 0:7f26f0680202 | 2270 | buffer[8] = 1; |
networker | 0:7f26f0680202 | 2271 | buffer[9] = 0x0c; |
networker | 0:7f26f0680202 | 2272 | buffer[10] = 0x7d; |
networker | 0:7f26f0680202 | 2273 | } |
networker | 0:7f26f0680202 | 2274 | ret = usb_control_msg(hFt->device, 0x40, 0xaf, 0x83, 0, buffer, 16, 200000); |
networker | 0:7f26f0680202 | 2275 | if (ret != 16) { |
networker | 0:7f26f0680202 | 2276 | fprintf(stderr, "Error sending control msg 0x40 0xaf\n"); |
networker | 0:7f26f0680202 | 2277 | return ret; |
networker | 0:7f26f0680202 | 2278 | } |
networker | 0:7f26f0680202 | 2279 | break; |
networker | 0:7f26f0680202 | 2280 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 2281 | if ((write(hFt->sdev, &buffer, 16)) != 16 || (ret = read(hFt->sdev, &buffer, 2)) != 2 || buffer[0] != 0x7c) { |
networker | 0:7f26f0680202 | 2282 | fprintf(stderr, "SetRealSerial: Error communicating with serial\n"); |
networker | 0:7f26f0680202 | 2283 | return ret; |
networker | 0:7f26f0680202 | 2284 | } |
networker | 0:7f26f0680202 | 2285 | break; |
networker | 0:7f26f0680202 | 2286 | default: |
networker | 0:7f26f0680202 | 2287 | return FTLIB_ERR_NOT_SUPPORTED; |
networker | 0:7f26f0680202 | 2288 | } |
networker | 0:7f26f0680202 | 2289 | |
networker | 0:7f26f0680202 | 2290 | return FTLIB_ERR_SUCCESS; |
networker | 0:7f26f0680202 | 2291 | } |
networker | 0:7f26f0680202 | 2292 | |
networker | 0:7f26f0680202 | 2293 | |
networker | 0:7f26f0680202 | 2294 | |
networker | 0:7f26f0680202 | 2295 | /** |
networker | 0:7f26f0680202 | 2296 | * @brief Gets the Manufacturer of the Interface |
networker | 0:7f26f0680202 | 2297 | * |
networker | 0:7f26f0680202 | 2298 | * Will return the Manufacturer of a fischertechnik USB device. |
networker | 0:7f26f0680202 | 2299 | * The allocated space should be freed with free() later. |
networker | 0:7f26f0680202 | 2300 | * |
networker | 0:7f26f0680202 | 2301 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2302 | * @return Pointer to the string with the name |
networker | 0:7f26f0680202 | 2303 | */ |
networker | 0:7f26f0680202 | 2304 | char *GetFtManufacturerStrg(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 2305 | char *buffer = (char *)malloc(128); |
networker | 0:7f26f0680202 | 2306 | memset(buffer, '\0', 128); |
networker | 0:7f26f0680202 | 2307 | |
networker | 0:7f26f0680202 | 2308 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 2309 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 2310 | } |
networker | 0:7f26f0680202 | 2311 | |
networker | 0:7f26f0680202 | 2312 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2313 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2314 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2315 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2316 | usb_get_string_simple(hFt->device, 1, buffer, 128); |
networker | 0:7f26f0680202 | 2317 | break; |
networker | 0:7f26f0680202 | 2318 | } |
networker | 0:7f26f0680202 | 2319 | |
networker | 0:7f26f0680202 | 2320 | return buffer; |
networker | 0:7f26f0680202 | 2321 | } |
networker | 0:7f26f0680202 | 2322 | |
networker | 0:7f26f0680202 | 2323 | |
networker | 0:7f26f0680202 | 2324 | /** |
networker | 0:7f26f0680202 | 2325 | * @brief Gets the short name of the Interface |
networker | 0:7f26f0680202 | 2326 | * |
networker | 0:7f26f0680202 | 2327 | * Will return the short name of a fischertechnik USB device. |
networker | 0:7f26f0680202 | 2328 | * The allocated space should be freed with free() later. |
networker | 0:7f26f0680202 | 2329 | * |
networker | 0:7f26f0680202 | 2330 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2331 | * @return Pointer to the string with the name |
networker | 0:7f26f0680202 | 2332 | */ |
networker | 0:7f26f0680202 | 2333 | char *GetFtShortNameStrg(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 2334 | char *buffer = (char *)malloc(128); |
networker | 0:7f26f0680202 | 2335 | memset(buffer, '\0', 128); |
networker | 0:7f26f0680202 | 2336 | |
networker | 0:7f26f0680202 | 2337 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 2338 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 2339 | } |
networker | 0:7f26f0680202 | 2340 | |
networker | 0:7f26f0680202 | 2341 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2342 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2343 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2344 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2345 | usb_get_string_simple(hFt->device, 5, buffer, 128); |
networker | 0:7f26f0680202 | 2346 | break; |
networker | 0:7f26f0680202 | 2347 | } |
networker | 0:7f26f0680202 | 2348 | |
networker | 0:7f26f0680202 | 2349 | return buffer; |
networker | 0:7f26f0680202 | 2350 | } |
networker | 0:7f26f0680202 | 2351 | |
networker | 0:7f26f0680202 | 2352 | |
networker | 0:7f26f0680202 | 2353 | /** |
networker | 0:7f26f0680202 | 2354 | * @brief Gets the long name of the Interface |
networker | 0:7f26f0680202 | 2355 | * |
networker | 0:7f26f0680202 | 2356 | * Will return the long name of a fischertechnik USB device. |
networker | 0:7f26f0680202 | 2357 | * The allocated space should be freed with free() later. |
networker | 0:7f26f0680202 | 2358 | * |
networker | 0:7f26f0680202 | 2359 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2360 | * @return Pointer to the string with the name |
networker | 0:7f26f0680202 | 2361 | */ |
networker | 0:7f26f0680202 | 2362 | char *GetFtLongNameStrg(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 2363 | char *buffer = (char *)malloc(128); |
networker | 0:7f26f0680202 | 2364 | memset(buffer, '\0', 128); |
networker | 0:7f26f0680202 | 2365 | |
networker | 0:7f26f0680202 | 2366 | if (hFt == NULL) { |
networker | 0:7f26f0680202 | 2367 | fprintf(stderr, "GetFtFirmware: No such device\n"); |
networker | 0:7f26f0680202 | 2368 | } |
networker | 0:7f26f0680202 | 2369 | |
networker | 0:7f26f0680202 | 2370 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2371 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2372 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2373 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2374 | usb_get_string_simple(hFt->device, 2, buffer, 128); |
networker | 0:7f26f0680202 | 2375 | break; |
networker | 0:7f26f0680202 | 2376 | } |
networker | 0:7f26f0680202 | 2377 | |
networker | 0:7f26f0680202 | 2378 | return buffer; |
networker | 0:7f26f0680202 | 2379 | } |
networker | 0:7f26f0680202 | 2380 | #endif //NOTNOW |
networker | 0:7f26f0680202 | 2381 | |
networker | 0:7f26f0680202 | 2382 | /** |
networker | 0:7f26f0680202 | 2383 | * @brief Tells if we successfuly got a connection to the Interface |
networker | 0:7f26f0680202 | 2384 | * |
networker | 0:7f26f0680202 | 2385 | * @param hFt Handle of the Interface |
networker | 0:7f26f0680202 | 2386 | * @return 0 if the Interface is not connected |
networker | 0:7f26f0680202 | 2387 | */ |
networker | 0:7f26f0680202 | 2388 | char IsFtInterfaceConnected(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 2389 | return hFt->interface_connected; |
networker | 0:7f26f0680202 | 2390 | } |
networker | 0:7f26f0680202 | 2391 | |
networker | 0:7f26f0680202 | 2392 | |
networker | 0:7f26f0680202 | 2393 | /** |
networker | 0:7f26f0680202 | 2394 | * @brief Gets the description of an error |
networker | 0:7f26f0680202 | 2395 | * |
networker | 0:7f26f0680202 | 2396 | * Will return a description of an error. |
networker | 0:7f26f0680202 | 2397 | * The allocated space should be freed with free() later. |
networker | 0:7f26f0680202 | 2398 | * |
networker | 0:7f26f0680202 | 2399 | * The return value is the constant as string if parameter dwTyp is 0, |
networker | 0:7f26f0680202 | 2400 | * else a verbose description of the error. |
networker | 0:7f26f0680202 | 2401 | * |
networker | 0:7f26f0680202 | 2402 | * @param dwErrorCode Error Code |
networker | 0:7f26f0680202 | 2403 | * @param dwTyp Type of the return value (see description) |
networker | 0:7f26f0680202 | 2404 | * @return Pointer to a string (see description) |
networker | 0:7f26f0680202 | 2405 | */ |
networker | 0:7f26f0680202 | 2406 | char *GetFtLibErrorString(long int dwErrorCode, long int dwTyp) { |
networker | 0:7f26f0680202 | 2407 | char *buffer = (char *)malloc(128); |
networker | 0:7f26f0680202 | 2408 | |
networker | 0:7f26f0680202 | 2409 | switch (dwErrorCode) { |
networker | 0:7f26f0680202 | 2410 | case FTLIB_ERR_IF_NO_PROGRAM: |
networker | 0:7f26f0680202 | 2411 | if (dwTyp) strncpy(buffer, "There is no program stored to work with", 128); |
networker | 0:7f26f0680202 | 2412 | else strncpy(buffer, "FTLIB_ERR_IF_NO_PROGRAM", 128); |
networker | 0:7f26f0680202 | 2413 | break; |
networker | 0:7f26f0680202 | 2414 | case FTLIB_ERR_SUCCESS: |
networker | 0:7f26f0680202 | 2415 | if (dwTyp) strncpy(buffer, "Everything is fine", 128); |
networker | 0:7f26f0680202 | 2416 | else strncpy(buffer, "FTLIB_ERR_SUCCESS", 128); |
networker | 0:7f26f0680202 | 2417 | break; |
networker | 0:7f26f0680202 | 2418 | case FTLIB_ERR_THREAD_IS_RUNNING: |
networker | 0:7f26f0680202 | 2419 | if (dwTyp) strncpy(buffer, "Thread has been started successfully", 128); |
networker | 0:7f26f0680202 | 2420 | else strncpy(buffer, "FTLIB_ERR_THREAD_IS_RUNNING", 128); |
networker | 0:7f26f0680202 | 2421 | break; |
networker | 0:7f26f0680202 | 2422 | case FTLIB_ERR_DOWNLOAD: |
networker | 0:7f26f0680202 | 2423 | if (dwTyp) strncpy(buffer, "Failed to upload the program", 128); |
networker | 0:7f26f0680202 | 2424 | else strncpy(buffer, "FTLIB_ERR_DOWNLOAD", 128); |
networker | 0:7f26f0680202 | 2425 | break; |
networker | 0:7f26f0680202 | 2426 | case FTLIB_ERR_DOWNLOAD_WRONG_MEM_BLOCK: |
networker | 0:7f26f0680202 | 2427 | if (dwTyp) strncpy(buffer, "Bad target to upload the program to", 128); |
networker | 0:7f26f0680202 | 2428 | else strncpy(buffer, "FTLIB_ERR_DOWNLOAD_WRONG_MEM_BLOCK", 128); |
networker | 0:7f26f0680202 | 2429 | break; |
networker | 0:7f26f0680202 | 2430 | case FTLIB_ERR_INVALID_PARAM: |
networker | 0:7f26f0680202 | 2431 | if (dwTyp) strncpy(buffer, "A parameter specified has a wrong value", 128); |
networker | 0:7f26f0680202 | 2432 | else strncpy(buffer, "FTLIB_ERR_INVALID_PARAM", 128); |
networker | 0:7f26f0680202 | 2433 | break; |
networker | 0:7f26f0680202 | 2434 | case FTLIB_ERR_LIB_IS_INITIALIZED: |
networker | 0:7f26f0680202 | 2435 | if (dwTyp) strncpy(buffer, "This library has been initialized", 128); |
networker | 0:7f26f0680202 | 2436 | else strncpy(buffer, "FTLIB_ERR_LIB_IS_INITIALIZED", 128); |
networker | 0:7f26f0680202 | 2437 | break; |
networker | 0:7f26f0680202 | 2438 | case FTLIB_ERR_NOT_SUPPORTED: |
networker | 0:7f26f0680202 | 2439 | if (dwTyp) strncpy(buffer, "The requested action is not supported", 128); |
networker | 0:7f26f0680202 | 2440 | else strncpy(buffer, "FTLIB_ERR_NOT_SUPPORTED", 128); |
networker | 0:7f26f0680202 | 2441 | break; |
networker | 0:7f26f0680202 | 2442 | case FTLIB_ERR_PORT_NUMBER_IS_NULL: |
networker | 0:7f26f0680202 | 2443 | if (dwTyp) strncpy(buffer, "No handle given", 128); |
networker | 0:7f26f0680202 | 2444 | else strncpy(buffer, "FTLIB_ERR_PORT_NUMBER_IS_NULL", 128); |
networker | 0:7f26f0680202 | 2445 | break; |
networker | 0:7f26f0680202 | 2446 | case FTLIB_ERR_THREAD_NOT_RUNNING: |
networker | 0:7f26f0680202 | 2447 | if (dwTyp) strncpy(buffer, "Unable to start the thread", 128); |
networker | 0:7f26f0680202 | 2448 | else strncpy(buffer, "FTLIB_ERR_THREAD_NOT_RUNNING", 128); |
networker | 0:7f26f0680202 | 2449 | break; |
networker | 0:7f26f0680202 | 2450 | default: |
networker | 0:7f26f0680202 | 2451 | strncpy(buffer, "Unknown", 128); |
networker | 0:7f26f0680202 | 2452 | } |
networker | 0:7f26f0680202 | 2453 | |
networker | 0:7f26f0680202 | 2454 | return buffer; |
networker | 0:7f26f0680202 | 2455 | } |
networker | 0:7f26f0680202 | 2456 | |
networker | 0:7f26f0680202 | 2457 | |
networker | 0:7f26f0680202 | 2458 | /** \cond doxygen ignore start */ |
networker | 0:7f26f0680202 | 2459 | //! \todo |
networker | 0:7f26f0680202 | 2460 | long int SetFtDeviceCommMode(FT_HANDLE hFt, long int dwMode, long int dwParameter, unsigned short *puiValue) { |
networker | 0:7f26f0680202 | 2461 | return 0; |
networker | 0:7f26f0680202 | 2462 | } |
networker | 0:7f26f0680202 | 2463 | |
networker | 0:7f26f0680202 | 2464 | |
networker | 0:7f26f0680202 | 2465 | //! \todo |
networker | 0:7f26f0680202 | 2466 | long int GetFtDeviceSetting(FT_HANDLE hFt, FT_SETTING *pSet) { |
networker | 0:7f26f0680202 | 2467 | return 0; |
networker | 0:7f26f0680202 | 2468 | } |
networker | 0:7f26f0680202 | 2469 | |
networker | 0:7f26f0680202 | 2470 | |
networker | 0:7f26f0680202 | 2471 | //! \todo |
networker | 0:7f26f0680202 | 2472 | long int SetFtDeviceSetting(FT_HANDLE hFt, FT_SETTING *pSet) { |
networker | 0:7f26f0680202 | 2473 | return 0; |
networker | 0:7f26f0680202 | 2474 | } |
networker | 0:7f26f0680202 | 2475 | |
networker | 0:7f26f0680202 | 2476 | |
networker | 0:7f26f0680202 | 2477 | //! \todo |
networker | 0:7f26f0680202 | 2478 | long int SendFtMessage(FT_HANDLE hFt, unsigned char bHwId, unsigned char bSubId, long int dwMessage, long int dwWaitTime, long int dwOption) { |
networker | 0:7f26f0680202 | 2479 | return 0; |
networker | 0:7f26f0680202 | 2480 | } |
networker | 0:7f26f0680202 | 2481 | |
networker | 0:7f26f0680202 | 2482 | |
networker | 0:7f26f0680202 | 2483 | //! \todo |
networker | 0:7f26f0680202 | 2484 | long int ClearFtMessageBuffer(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 2485 | return 0; |
networker | 0:7f26f0680202 | 2486 | } |
networker | 0:7f26f0680202 | 2487 | |
networker | 0:7f26f0680202 | 2488 | |
networker | 0:7f26f0680202 | 2489 | //! \todo |
networker | 0:7f26f0680202 | 2490 | long int GetFtMemoryLayout(FT_HANDLE hFt, unsigned char* pbArray, long int dwSize) { |
networker | 0:7f26f0680202 | 2491 | return 0; |
networker | 0:7f26f0680202 | 2492 | } |
networker | 0:7f26f0680202 | 2493 | |
networker | 0:7f26f0680202 | 2494 | |
networker | 0:7f26f0680202 | 2495 | //! \todo |
networker | 0:7f26f0680202 | 2496 | long int GetFtMemoryData(FT_HANDLE hFt, unsigned char * pbArray, long int dwSize, long int dwAddress) { |
networker | 0:7f26f0680202 | 2497 | return 0; |
networker | 0:7f26f0680202 | 2498 | } |
networker | 0:7f26f0680202 | 2499 | |
networker | 0:7f26f0680202 | 2500 | |
networker | 0:7f26f0680202 | 2501 | //! \todo |
networker | 0:7f26f0680202 | 2502 | long int WriteFtMemoryData(FT_HANDLE hFt, long int dwData, long int dwAddress) { |
networker | 0:7f26f0680202 | 2503 | return 0; |
networker | 0:7f26f0680202 | 2504 | } |
networker | 0:7f26f0680202 | 2505 | |
networker | 0:7f26f0680202 | 2506 | #ifndef SPLITTRANSFER |
networker | 0:7f26f0680202 | 2507 | /** \cond doxygen ignore start */ |
networker | 0:7f26f0680202 | 2508 | static void *FtThread(FT_HANDLE hFt) { |
networker | 0:7f26f0680202 | 2509 | FT_TRANSFER_AREA *area = &hFt->transfer_area; |
networker | 0:7f26f0680202 | 2510 | int ret; |
networker | 0:7f26f0680202 | 2511 | unsigned char out[ABF_IF_COMPLETE_NUM_WRITE]; //= {ABF_IF_COMPLETE,1,0x07,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
networker | 0:7f26f0680202 | 2512 | unsigned char in[ABF_IF_COMPLETE_NUM_READ]; |
networker | 0:7f26f0680202 | 2513 | int num_write = ABF_IF_COMPLETE_NUM_WRITE; |
networker | 0:7f26f0680202 | 2514 | int num_read = ABF_IF_COMPLETE_NUM_READ; |
networker | 0:7f26f0680202 | 2515 | int usb_endpoint_write = FT_ENDPOINT_INTERRUPT_OUT; |
networker | 0:7f26f0680202 | 2516 | int usb_endpoint_read = FT_ENDPOINT_INTERRUPT_IN; |
networker | 0:7f26f0680202 | 2517 | int i=0; |
networker | 0:7f26f0680202 | 2518 | int ii_speed = 0; |
networker | 0:7f26f0680202 | 2519 | |
networker | 0:7f26f0680202 | 2520 | out[0] = ABF_IF_COMPLETE; |
networker | 0:7f26f0680202 | 2521 | area->TransferAktiv = 1; |
networker | 0:7f26f0680202 | 2522 | |
networker | 0:7f26f0680202 | 2523 | switch (hFt->type) { |
networker | 0:7f26f0680202 | 2524 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 2525 | out[0] = 0xf2; |
networker | 0:7f26f0680202 | 2526 | num_write = 17; |
networker | 0:7f26f0680202 | 2527 | num_read = 21; |
networker | 0:7f26f0680202 | 2528 | break; |
networker | 0:7f26f0680202 | 2529 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 2530 | num_write = 2; |
networker | 0:7f26f0680202 | 2531 | break; |
networker | 0:7f26f0680202 | 2532 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 2533 | num_write = 3; |
networker | 0:7f26f0680202 | 2534 | break; |
networker | 0:7f26f0680202 | 2535 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 2536 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 2537 | out[0] = 0xf2; |
networker | 0:7f26f0680202 | 2538 | num_write = 6; |
networker | 0:7f26f0680202 | 2539 | num_read = 6; |
networker | 0:7f26f0680202 | 2540 | break; |
networker | 0:7f26f0680202 | 2541 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2542 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2543 | usb_endpoint_write = FT_RF_ENDPOINT_INTERRUPT_OUT; |
networker | 0:7f26f0680202 | 2544 | usb_endpoint_read = FT_RF_ENDPOINT_INTERRUPT_IN; |
networker | 0:7f26f0680202 | 2545 | |
networker | 0:7f26f0680202 | 2546 | // init RF |
networker | 0:7f26f0680202 | 2547 | // 0x102 == first RF |
networker | 0:7f26f0680202 | 2548 | // 0x202 == 2nd RF |
networker | 0:7f26f0680202 | 2549 | // ... |
networker | 0:7f26f0680202 | 2550 | //ret = usb_control_msg(hFt->device, 0xc0, 0xfb, 0x102, 0x1, in, 2, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2551 | ret = usb_control_msg(hFt->device, 0xc0, 0xfb, hFt->transfer_area.RfModulNr << 8 | 0x02, 0x1, in, 2, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2552 | if (ret != 2) { |
networker | 0:7f26f0680202 | 2553 | fprintf(stderr, "%d FtThread: Error initiating RF Module!\n"); |
networker | 0:7f26f0680202 | 2554 | area->TransferAktiv = 0; |
networker | 0:7f26f0680202 | 2555 | } |
networker | 0:7f26f0680202 | 2556 | break; |
networker | 0:7f26f0680202 | 2557 | #endif |
networker | 0:7f26f0680202 | 2558 | } |
networker | 0:7f26f0680202 | 2559 | //here the real data exchange starts |
networker | 0:7f26f0680202 | 2560 | #ifdef MBED |
networker | 0:7f26f0680202 | 2561 | //viaUsb.putc('.'); |
networker | 0:7f26f0680202 | 2562 | /*while (area->TransferAktiv == 1)*/ { //procedure runs only once |
networker | 0:7f26f0680202 | 2563 | if (!test_and_set(hFt->lock)) //return when busy |
networker | 0:7f26f0680202 | 2564 | return 0;//return because there is no point in sending a nonsense request, alternatively the lock can be ignored in which case the data may be inconsistent |
networker | 0:7f26f0680202 | 2565 | #else |
networker | 0:7f26f0680202 | 2566 | while (area->TransferAktiv == 1) {//thread runs continuously |
networker | 0:7f26f0680202 | 2567 | sem_wait(&hFt->lock);//wait when busy |
networker | 0:7f26f0680202 | 2568 | #endif |
networker | 0:7f26f0680202 | 2569 | out[1] = area->M_Main; |
networker | 0:7f26f0680202 | 2570 | out[2] = (area->MPWM_Main[0] & 0x7) | (area->MPWM_Main[1]<<3 & 0x38) | (area->MPWM_Main[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 2571 | out[3] = (area->MPWM_Main[2] & 0x1) | (area->MPWM_Main[3]<<1 & 0xE) | (area->MPWM_Main[4]<<4 & 0x70) | (area->MPWM_Main[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 2572 | out[4] = (area->MPWM_Main[5] & 0x3) | (area->MPWM_Main[6]<<2 & 0x1C) | (area->MPWM_Main[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 2573 | out[5] = area->M_Sub1; |
networker | 0:7f26f0680202 | 2574 | out[6] = (area->MPWM_Sub1[0] & 0x7) | (area->MPWM_Sub1[1]<<3 & 0x38) | (area->MPWM_Sub1[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 2575 | out[7] = (area->MPWM_Sub1[2] & 0x1) | (area->MPWM_Sub1[3]<<1 & 0xE) | (area->MPWM_Sub1[4]<<4 & 0x70) | (area->MPWM_Sub1[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 2576 | out[8] = (area->MPWM_Sub1[5] & 0x3) | (area->MPWM_Sub1[6]<<2 & 0x1C) | (area->MPWM_Sub1[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 2577 | out[9] = area->M_Sub2; |
networker | 0:7f26f0680202 | 2578 | out[10] = (area->MPWM_Sub2[0] & 0x7) | (area->MPWM_Sub2[1]<<3 & 0x38) | (area->MPWM_Sub2[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 2579 | out[11] = (area->MPWM_Sub2[2] & 0x1) | (area->MPWM_Sub2[3]<<1 & 0xE) | (area->MPWM_Sub2[4]<<4 & 0x70) | (area->MPWM_Sub2[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 2580 | out[12] = (area->MPWM_Sub2[5] & 0x3) | (area->MPWM_Sub2[6]<<2 & 0x1C) | (area->MPWM_Sub2[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 2581 | out[13] = area->M_Sub3; |
networker | 0:7f26f0680202 | 2582 | out[14] = (area->MPWM_Sub3[0] & 0x7) | (area->MPWM_Sub3[1]<<3 & 0x38) | (area->MPWM_Sub3[2]<<6 & 0xC0); |
networker | 0:7f26f0680202 | 2583 | out[15] = (area->MPWM_Sub3[2] & 0x1) | (area->MPWM_Sub3[3]<<1 & 0xE) | (area->MPWM_Sub3[4]<<4 & 0x70) | (area->MPWM_Sub3[5]<<7 & 0x80); |
networker | 0:7f26f0680202 | 2584 | out[16] = (area->MPWM_Sub3[5] & 0x3) | (area->MPWM_Sub3[6]<<2 & 0x1C) | (area->MPWM_Sub3[7]<<5 & 0xE0); |
networker | 0:7f26f0680202 | 2585 | out[17] = 0; |
networker | 0:7f26f0680202 | 2586 | out[18] = 0; |
networker | 0:7f26f0680202 | 2587 | out[19] = 0; |
networker | 0:7f26f0680202 | 2588 | out[20] = 0; |
networker | 0:7f26f0680202 | 2589 | out[21] = 0; |
networker | 0:7f26f0680202 | 2590 | out[22] = 0; |
networker | 0:7f26f0680202 | 2591 | out[23] = 0; |
networker | 0:7f26f0680202 | 2592 | out[24] = 0; |
networker | 0:7f26f0680202 | 2593 | out[25] = 0; |
networker | 0:7f26f0680202 | 2594 | out[26] = 0; |
networker | 0:7f26f0680202 | 2595 | out[27] = 0; |
networker | 0:7f26f0680202 | 2596 | out[28] = 0; |
networker | 0:7f26f0680202 | 2597 | out[29] = 0; |
networker | 0:7f26f0680202 | 2598 | out[30] = 0; |
networker | 0:7f26f0680202 | 2599 | out[31] = 0; |
networker | 0:7f26f0680202 | 2600 | |
networker | 0:7f26f0680202 | 2601 | // For the II we need to simulate different speeds here |
networker | 0:7f26f0680202 | 2602 | if (hFt->type == FT_INTELLIGENT_IF || hFt->type == FT_INTELLIGENT_IF_SLAVE) { |
networker | 0:7f26f0680202 | 2603 | int iCurMotor; |
networker | 0:7f26f0680202 | 2604 | for (iCurMotor = 0; iCurMotor < 7; iCurMotor++) { |
networker | 0:7f26f0680202 | 2605 | if (area->MPWM_Main[iCurMotor] < ii_speed) out[1] &= ~(1 << iCurMotor); |
networker | 0:7f26f0680202 | 2606 | if (area->MPWM_Sub1[iCurMotor] < ii_speed) out[5] &= ~(1 << iCurMotor); |
networker | 0:7f26f0680202 | 2607 | } |
networker | 0:7f26f0680202 | 2608 | |
networker | 0:7f26f0680202 | 2609 | ii_speed++; |
networker | 0:7f26f0680202 | 2610 | if (ii_speed > 7) ii_speed = 0; |
networker | 0:7f26f0680202 | 2611 | } |
networker | 0:7f26f0680202 | 2612 | |
networker | 0:7f26f0680202 | 2613 | if (hFt->type == FT_INTELLIGENT_IF) { |
networker | 0:7f26f0680202 | 2614 | i++; |
networker | 0:7f26f0680202 | 2615 | num_read = 1; |
networker | 0:7f26f0680202 | 2616 | out[0] = 0xC1; |
networker | 0:7f26f0680202 | 2617 | if (i % 20) { // EX |
networker | 0:7f26f0680202 | 2618 | out[0] = 0xC5; |
networker | 0:7f26f0680202 | 2619 | num_read = 3; |
networker | 0:7f26f0680202 | 2620 | } else if (i % 10) { // EY |
networker | 0:7f26f0680202 | 2621 | out[0] = 0xC9; |
networker | 0:7f26f0680202 | 2622 | num_read = 3; |
networker | 0:7f26f0680202 | 2623 | } |
networker | 0:7f26f0680202 | 2624 | } else if (hFt->type == FT_INTELLIGENT_IF_SLAVE) { |
networker | 0:7f26f0680202 | 2625 | i++; |
networker | 0:7f26f0680202 | 2626 | num_read = 2; |
networker | 0:7f26f0680202 | 2627 | out[0] = 0xC2; |
networker | 0:7f26f0680202 | 2628 | out[2] = out[5]; |
networker | 0:7f26f0680202 | 2629 | if (i % 20) { // EX |
networker | 0:7f26f0680202 | 2630 | out[0] = 0xC6; |
networker | 0:7f26f0680202 | 2631 | num_read = 4; |
networker | 0:7f26f0680202 | 2632 | } else if (i % 10) { // EY |
networker | 0:7f26f0680202 | 2633 | out[0] = 0xCA; |
networker | 0:7f26f0680202 | 2634 | num_read = 4; |
networker | 0:7f26f0680202 | 2635 | } |
networker | 0:7f26f0680202 | 2636 | } |
networker | 0:7f26f0680202 | 2637 | #ifdef MBED |
networker | 0:7f26f0680202 | 2638 | //viaUsb.putc('-'); |
networker | 0:7f26f0680202 | 2639 | increment(hFt->lock);//release the lock on shared memeory |
networker | 0:7f26f0680202 | 2640 | #else |
networker | 0:7f26f0680202 | 2641 | sem_post(&hFt->lock); |
networker | 0:7f26f0680202 | 2642 | #endif |
networker | 0:7f26f0680202 | 2643 | ret = 0; |
networker | 0:7f26f0680202 | 2644 | switch (hFt->type) {//send the request |
networker | 0:7f26f0680202 | 2645 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 2646 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2647 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 2648 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2649 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2650 | ret = usb_interrupt_write(hFt->device, usb_endpoint_write, out, num_write, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2651 | break; |
networker | 0:7f26f0680202 | 2652 | #endif |
networker | 0:7f26f0680202 | 2653 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 2654 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 2655 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 2656 | #ifdef MBED |
networker | 0:7f26f0680202 | 2657 | //ret = hFt->sdev->printf("%*c", num_write, out); |
networker | 0:7f26f0680202 | 2658 | ret = write(hFt->sdev, out, num_write); |
networker | 0:7f26f0680202 | 2659 | // viaUsb.putc(';'); |
networker | 0:7f26f0680202 | 2660 | #else |
networker | 0:7f26f0680202 | 2661 | ret = write(hFt->sdev, &out, num_write); |
networker | 0:7f26f0680202 | 2662 | #endif |
networker | 0:7f26f0680202 | 2663 | break; |
networker | 0:7f26f0680202 | 2664 | } |
networker | 0:7f26f0680202 | 2665 | if (ret != num_write) { |
networker | 0:7f26f0680202 | 2666 | hFt->interface_connected = 0; |
networker | 0:7f26f0680202 | 2667 | fprintf(stderr, "FtThread: Error writing to the Interface...exiting!\n"); |
networker | 0:7f26f0680202 | 2668 | #ifdef MBED |
networker | 0:7f26f0680202 | 2669 | return 0; |
networker | 0:7f26f0680202 | 2670 | #else |
networker | 0:7f26f0680202 | 2671 | break; |
networker | 0:7f26f0680202 | 2672 | #endif |
networker | 0:7f26f0680202 | 2673 | } |
networker | 0:7f26f0680202 | 2674 | |
networker | 0:7f26f0680202 | 2675 | ret = 0; |
networker | 0:7f26f0680202 | 2676 | switch (hFt->type) { //receive the reply |
networker | 0:7f26f0680202 | 2677 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 2678 | case FT_ROBO_IF_USB: |
networker | 0:7f26f0680202 | 2679 | case FT_ROBO_IO_EXTENSION: |
networker | 0:7f26f0680202 | 2680 | case FT_ROBO_IF_OVER_RF: |
networker | 0:7f26f0680202 | 2681 | case FT_ROBO_RF_DATA_LINK: |
networker | 0:7f26f0680202 | 2682 | ret = usb_interrupt_read(hFt->device, usb_endpoint_read, in, num_read, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2683 | break; |
networker | 0:7f26f0680202 | 2684 | #endif |
networker | 0:7f26f0680202 | 2685 | case FT_ROBO_IF_COM: |
networker | 0:7f26f0680202 | 2686 | case FT_INTELLIGENT_IF: |
networker | 0:7f26f0680202 | 2687 | case FT_INTELLIGENT_IF_SLAVE: |
networker | 0:7f26f0680202 | 2688 | #ifdef MBED |
networker | 0:7f26f0680202 | 2689 | //ret = hFt->sdev->scanf("%*c", num_read, in)==1 ? num_read : 0 ; |
networker | 0:7f26f0680202 | 2690 | ret = read(hFt->sdev, in, num_read); |
networker | 0:7f26f0680202 | 2691 | // viaUsb.putc('/'); |
networker | 0:7f26f0680202 | 2692 | #else |
networker | 0:7f26f0680202 | 2693 | ret = read(hFt->sdev, &in, num_read); |
networker | 0:7f26f0680202 | 2694 | #endif |
networker | 0:7f26f0680202 | 2695 | break; |
networker | 0:7f26f0680202 | 2696 | } |
networker | 0:7f26f0680202 | 2697 | if (ret != num_read) { |
networker | 0:7f26f0680202 | 2698 | hFt->interface_connected = 0; |
networker | 0:7f26f0680202 | 2699 | fprintf(stderr, "FtThread: Error reading from the Interface\n"); |
networker | 0:7f26f0680202 | 2700 | #ifdef MBED |
networker | 0:7f26f0680202 | 2701 | return 0; |
networker | 0:7f26f0680202 | 2702 | #else |
networker | 0:7f26f0680202 | 2703 | usleep(hFt->query_time); |
networker | 0:7f26f0680202 | 2704 | continue; |
networker | 0:7f26f0680202 | 2705 | #endif |
networker | 0:7f26f0680202 | 2706 | } |
networker | 0:7f26f0680202 | 2707 | |
networker | 0:7f26f0680202 | 2708 | #ifdef MBED |
networker | 0:7f26f0680202 | 2709 | if (!test_and_set(hFt->lock))//skip when busy |
networker | 0:7f26f0680202 | 2710 | return 0; |
networker | 0:7f26f0680202 | 2711 | #else |
networker | 0:7f26f0680202 | 2712 | sem_wait(&hFt->lock);//wait when busy |
networker | 0:7f26f0680202 | 2713 | #endif |
networker | 0:7f26f0680202 | 2714 | area->E_Main = in[0]; |
networker | 0:7f26f0680202 | 2715 | area->E_Sub1 = in[1]; |
networker | 0:7f26f0680202 | 2716 | area->E_Sub2 = in[2]; |
networker | 0:7f26f0680202 | 2717 | area->E_Sub3 = in[3]; |
networker | 0:7f26f0680202 | 2718 | area->AX = in[4]; |
networker | 0:7f26f0680202 | 2719 | area->AY = in[5]; |
networker | 0:7f26f0680202 | 2720 | area->A1 = in[6]; |
networker | 0:7f26f0680202 | 2721 | area->A2 = in[7]; |
networker | 0:7f26f0680202 | 2722 | area->AX |= (in[8] & 0x3) << 8; |
networker | 0:7f26f0680202 | 2723 | area->AY |= (in[8] & 0xC) << 6; |
networker | 0:7f26f0680202 | 2724 | area->A1 |= (in[8] & 0x30) << 4; |
networker | 0:7f26f0680202 | 2725 | area->A2 |= (in[8] & 0xC0) << 2; |
networker | 0:7f26f0680202 | 2726 | area->AZ = in[9]; |
networker | 0:7f26f0680202 | 2727 | area->D1 = in[10]; |
networker | 0:7f26f0680202 | 2728 | area->D2 = in[11]; |
networker | 0:7f26f0680202 | 2729 | area->AV = in[12]; |
networker | 0:7f26f0680202 | 2730 | area->AZ |= (in[13] & 0x3) << 8; |
networker | 0:7f26f0680202 | 2731 | area->D1 |= (in[13] & 0xC) << 6; |
networker | 0:7f26f0680202 | 2732 | area->D2 |= (in[13] & 0x30) << 4; |
networker | 0:7f26f0680202 | 2733 | area->AV |= (in[13] & 0xC0) << 2; |
networker | 0:7f26f0680202 | 2734 | area->IRKeys = in[14]; |
networker | 0:7f26f0680202 | 2735 | area->BusModules = in[15]; |
networker | 0:7f26f0680202 | 2736 | // 16 |
networker | 0:7f26f0680202 | 2737 | area->AXS1 = in[17]; |
networker | 0:7f26f0680202 | 2738 | area->AXS2 = in[18]; |
networker | 0:7f26f0680202 | 2739 | area->AXS3 = in[19]; |
networker | 0:7f26f0680202 | 2740 | area->AXS1 |= (in[20] & 0x3) << 8; |
networker | 0:7f26f0680202 | 2741 | area->AXS2 |= (in[20] & 0xC) << 6; |
networker | 0:7f26f0680202 | 2742 | area->AXS3 |= (in[20] & 0x30) << 4; |
networker | 0:7f26f0680202 | 2743 | // 21 |
networker | 0:7f26f0680202 | 2744 | area->AVS1 = in[22]; |
networker | 0:7f26f0680202 | 2745 | area->AVS2 = in[23]; |
networker | 0:7f26f0680202 | 2746 | area->AVS3 = in[24]; |
networker | 0:7f26f0680202 | 2747 | area->AVS1 |= (in[25] & 0x3) << 8; |
networker | 0:7f26f0680202 | 2748 | area->AVS2 |= (in[25] & 0xC) << 6; |
networker | 0:7f26f0680202 | 2749 | area->AVS3 |= (in[25] & 0x30) << 4; |
networker | 0:7f26f0680202 | 2750 | // 26...42 |
networker | 0:7f26f0680202 | 2751 | if (hFt->type == FT_INTELLIGENT_IF) { |
networker | 0:7f26f0680202 | 2752 | if (i % hFt->analogcycle) { // EX |
networker | 0:7f26f0680202 | 2753 | area->AX = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 2754 | } else if (i % (2*hFt->analogcycle)) { // EY |
networker | 0:7f26f0680202 | 2755 | area->AY = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 2756 | } |
networker | 0:7f26f0680202 | 2757 | } else if (hFt->type == FT_INTELLIGENT_IF_SLAVE) { |
networker | 0:7f26f0680202 | 2758 | if (i % hFt->analogcycle) { // EX |
networker | 0:7f26f0680202 | 2759 | area->AX = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 2760 | } else if (i % (2*hFt->analogcycle)) { // EY |
networker | 0:7f26f0680202 | 2761 | area->AY = in[1] & (8<<in[2]); |
networker | 0:7f26f0680202 | 2762 | } |
networker | 0:7f26f0680202 | 2763 | } |
networker | 0:7f26f0680202 | 2764 | #ifdef MBED |
networker | 0:7f26f0680202 | 2765 | increment(hFt->lock); |
networker | 0:7f26f0680202 | 2766 | hFt->interface_connected = 1; |
networker | 0:7f26f0680202 | 2767 | #else |
networker | 0:7f26f0680202 | 2768 | sem_post(&hFt->lock); |
networker | 0:7f26f0680202 | 2769 | |
networker | 0:7f26f0680202 | 2770 | hFt->interface_connected = 1; |
networker | 0:7f26f0680202 | 2771 | |
networker | 0:7f26f0680202 | 2772 | usleep(hFt->query_time); |
networker | 0:7f26f0680202 | 2773 | #endif |
networker | 0:7f26f0680202 | 2774 | }//end of the while loop (end of task) |
networker | 0:7f26f0680202 | 2775 | #ifdef USE_USB |
networker | 0:7f26f0680202 | 2776 | if (hFt->type == FT_ROBO_IF_OVER_RF || hFt->type == FT_ROBO_RF_DATA_LINK) { |
networker | 0:7f26f0680202 | 2777 | ret = usb_control_msg(hFt->device, 0xc0, 0x21, hFt->transfer_area.RfModulNr << 8, 0, in, 1, FT_USB_TIMEOUT); |
networker | 0:7f26f0680202 | 2778 | if (ret != 1 || in[0] != 0xd7) { |
networker | 0:7f26f0680202 | 2779 | fprintf(stderr, "Error uninitiating RF Module!\n"); |
networker | 0:7f26f0680202 | 2780 | } |
networker | 0:7f26f0680202 | 2781 | } |
networker | 0:7f26f0680202 | 2782 | #endif |
networker | 0:7f26f0680202 | 2783 | #ifdef MBED |
networker | 0:7f26f0680202 | 2784 | return 0; |
networker | 0:7f26f0680202 | 2785 | #else |
networker | 0:7f26f0680202 | 2786 | hFt->transfer_area.TransferAktiv = 0; |
networker | 0:7f26f0680202 | 2787 | pthread_exit((void *) 0); |
networker | 0:7f26f0680202 | 2788 | #endif |
networker | 0:7f26f0680202 | 2789 | } |
networker | 0:7f26f0680202 | 2790 | |
networker | 0:7f26f0680202 | 2791 | void ft_handle_devices::FtThread() { |
networker | 0:7f26f0680202 | 2792 | ::FtThread(this); |
networker | 0:7f26f0680202 | 2793 | // printf("%02X\r", transfer_area.E_Main); |
networker | 0:7f26f0680202 | 2794 | // viaUsb.putc('.'); |
networker | 0:7f26f0680202 | 2795 | } |
networker | 0:7f26f0680202 | 2796 | /** \endcond doxygen ignore end */ |
networker | 0:7f26f0680202 | 2797 | |
networker | 0:7f26f0680202 | 2798 | #endif |
networker | 0:7f26f0680202 | 2799 | |
networker | 0:7f26f0680202 | 2800 | /** \endcond doxygen ignore end */ |
networker | 0:7f26f0680202 | 2801 |