In my computer science blog I will try to provide source code snippets and small solutions, to small problems that occur often and take unexpected long time to solve :P
I am publishing these solutions in order to equalize somehow the huge amount of computer science shared knowledge, that helped me to become a better programmer :)
To all other "ambush" style "scientists" I would like to take the quote as a personal greeting:
"The secret to creativity is knowing how to hide your sources"
So I'll let those people prove themselves "creative" and will share stuff I didn't found that much online :)
- Details
Here you go a class for Serial Communication with Texas Instruments eZ430-TMS37157 RFID written on C#. I had some lot of troubles by creating this class mainly due to the lack of documentation from TI side. Nevertheless, I found a lot of sources online that I've combined and wrote some stuff by myself so I hope this code will help you too! :)
Note that the code might be a little bit inconsistent in terms of variable naming and also the communication protocol is only partially implemented, because I've needed only the message part.
// // Serial Class with all stuff for communication with eZ430-TMS37157 written on C# // // by svilen.info :) // using System; using System.Collections.Generic; using System.Diagnostics; using System.IO.Ports; using System.Linq; using System.Management; using System.Runtime.Remoting.Metadata.W3cXsd2001; namespace tudos { /// <summary> /// The Type of the Serial Error /// </summary> enum SerialErrorType { OK, SEND_TIMEOUT, SEND_INVALID_OPERATION, READ_OVERLOAD, READ_TIMEOUT, NO_ANSWER } /// <summary> /// Whole Serial Message used to determine errors when class is deployed /// </summary> class SerialMessage { public string message = "OK :)"; public SerialErrorType type = SerialErrorType.OK; public object exceptionObject = null; } /// <summary> /// Serial class to deal with eZ430-TMS37157 /// </summary> class Serial { /// <summary> /// No Answer Standard /// </summary> const string NOANSWER = "010B00000000000000000000000B"; /// <summary> /// Serial Port instance /// </summary> private static SerialPort _serialPort; /// <summary> /// Last Serial Message /// </summary> public SerialMessage LastMessage { get; private set; } /// <summary> /// All received Buffers stored when debugging /// </summary> public List<byte[]> ReceivedBuffers { get; private set; } /// <summary> /// All sent buffers stored when debugging /// </summary> public List<byte[]> SentBuffers { get; private set; } /// <summary> /// Save the available comports to enable switching /// </summary> public List<COMPortInfo> AvailableComports { get; private set; } /// <summary> /// Standard Constructor to connect to eZ430-TMS37157 /// </summary> public Serial() { OpenSerial(RefreshAvailablePorts()); #if DEBUG { ReceivedBuffers = new List<byte[]>(); SentBuffers = new List<byte[]>(); } #endif LastMessage = new SerialMessage { message = "Serial Class Initialized" + DateTime.Now }; } ~Serial() { _serialPort.Close(); } /// <summary> /// Open serial port /// </summary> /// <param name="name">the unfriendly name</param> private void OpenSerial(string name) { // taking the standard settnigs of eZ430-TMS37157 _serialPort = new SerialPort { PortName = name, BaudRate = 9600, Parity = Parity.None, DataBits = 8, StopBits = StopBits.One, Handshake = Handshake.None, ReadTimeout = 500, WriteTimeout = 500 }; _serialPort.Open(); _serialPort.ErrorReceived += ErrorEvent; } /// <summary> /// Refreshes the serial ports /// </summary> /// <returns>gives back the probable unfriendly comport name of some eZ430-TMS37157</returns> private string RefreshAvailablePorts() { string portName = String.Empty; AvailableComports = COMPortInfo.GetCOMPortsInfo(); foreach (COMPortInfo comPort in AvailableComports) { Debug.WriteLine(string.Format("{0} – {1}", comPort.Name, comPort.Description)); // query the friendly name if (comPort.Description.Contains("USB Serial Port")) { portName = comPort.Name; } } return portName; } /// <summary> /// Catching the errors out of the Serial Class /// </summary> /// The Serial Class is pretty strange, as the functions don't return success parameter /// <param name="sender">Serial Class</param> /// <param name="e">System.IO.Ports.SerialError</param> private void ErrorEvent(object sender, EventArgs e) { SerialError errorOccured = ((SerialErrorReceivedEventArgs)e).EventType; switch (errorOccured) { case SerialError.TXFull: break; case SerialError.RXOver: break; case SerialError.Overrun: break; case SerialError.RXParity: break; case SerialError.Frame: break; default: throw new ArgumentOutOfRangeException(); } } /// <summary> /// Read One Buffer /// </summary> /// <param name="receivedBuffer"></param> /// <returns></returns> public SerialMessage ReadBuffer(out byte[] receivedBuffer) { try { if (!_serialPort.IsOpen) { _serialPort.Open(); } string buffer = _serialPort.ReadTo("\r\n "); buffer = _serialPort.ReadTo("\r\n"); if ("" != _serialPort.ReadExisting()) { receivedBuffer = null; return new SerialMessage { message = "Serial Receive Overload", type = SerialErrorType.READ_OVERLOAD }; } if (buffer == NOANSWER) { receivedBuffer = null; return new SerialMessage { message = "Serial Received No Answer", type = SerialErrorType.NO_ANSWER }; } byte[] framedBuffer = BufferConverter.GetStringToBytes(buffer); receivedBuffer = RemoveFrames(framedBuffer); #if DEBUG { ReceivedBuffers.Add(receivedBuffer); } #endif return new SerialMessage(); } catch (TimeoutException e) { receivedBuffer = null; return new SerialMessage { message = "Serial", exceptionObject = e, type = SerialErrorType.READ_TIMEOUT }; } } /// <summary> /// Writes buffer to the comport /// </summary> /// <param name="buffer">buffer to write</param> /// <returns>success status</returns> public SerialMessage WriteBuffer(byte[] buffer) { try { if (!_serialPort.IsOpen) { _serialPort.Open(); } byte[] fullBuffer = AddFrames(buffer); _serialPort.Write(BufferConverter.GetBytesToString(fullBuffer)); #if DEBUG { SentBuffers.Add(fullBuffer); } #endif //_serialPort.Close(); } catch(TimeoutException e) { LastMessage = new SerialMessage { message = "Command Send Time Out: " + e.Message, type = SerialErrorType.SEND_TIMEOUT, exceptionObject = e }; return LastMessage; } catch (InvalidOperationException e) { LastMessage = new SerialMessage { message = "Command Send Invalid Operation: " + e.Message, type = SerialErrorType.SEND_INVALID_OPERATION, exceptionObject = e }; return LastMessage; } LastMessage = new SerialMessage { message = "Command Sent", }; return LastMessage; } /// <summary> /// Add the headers to the raw buffer /// </summary> /// <param name="rawBuffer">buffer body</param> /// <returns>framed buffer</returns> byte[] AddFrames(byte[] rawBuffer) { const int HEADERS_LENGHT = 6; const int FOOTERS_LENGHT = 5; const int FRAMES_LENGTH = HEADERS_LENGHT + FOOTERS_LENGHT; byte[] buffer = new byte[rawBuffer.Length + FRAMES_LENGTH]; buffer[0] = 0x01; // fixed buffer[1] = (byte)(rawBuffer.Length + FRAMES_LENGTH - 3); // size of buffer buffer[2] = 0x06; // CMD1 buffer[3] = 0x32; // PB1 buffer[4] = 0x48; // #TX Bits buffer[5] = 0x7d; // MSP ACCESS Write Address Array.Copy(rawBuffer, 0, buffer, 6, rawBuffer.Length); // Actual Data byte[] CRCData = buffer.Skip(5).Take(7).ToArray(); // Data for the CRC byte[] CRC = Crc16Ccitt.GetCRC(CRCData); // The Actual CRC buffer[HEADERS_LENGHT + rawBuffer.Length] = CRC[0]; // CRC MSB buffer[HEADERS_LENGHT + rawBuffer.Length + 1] = CRC[1]; // CRC LSB buffer[HEADERS_LENGHT + rawBuffer.Length + 2] = 0x0F; // PB2 buffer[HEADERS_LENGHT + rawBuffer.Length + 3] = 0x0A; // Size of awaited Answer (add this to variable some day to check...) byte[] LRCData = buffer.Skip(1).Take(buffer.Length - 2).ToArray(); byte lrc = LRC.calculateLRC(LRCData); buffer[buffer.Length - 1] = lrc; // LRC return buffer; } /// <summary> /// Remove frames from the buffer /// </summary> /// <param name="rawBuffer">framed buffer</param> /// <returns>body buffer</returns> byte[] RemoveFrames(byte[] rawBuffer) { const int HEADERS_LENGHT = 6; const int BODY_LENGTH = 6; byte[] CRCData = rawBuffer.Skip(5).Take(7).ToArray(); // Data for the CRC byte[] CRC = Crc16Ccitt.GetCRC(CRCData); // The Actual CRC if (CRC[0] != rawBuffer[HEADERS_LENGHT + BODY_LENGTH] && CRC[1] != rawBuffer[HEADERS_LENGHT + BODY_LENGTH + 1]) { // throw CRC error } byte[] LRCData = rawBuffer.Skip(1).Take(rawBuffer.Length - 2).ToArray(); byte lrc = LRC.calculateLRC(LRCData); if (rawBuffer[rawBuffer.Length - 1] != lrc) { // throw LRC error } return rawBuffer.Skip(4).Take(6).ToArray(); } } /// <summary> /// Convert byte buffers back and forth /// </summary> static class BufferConverter { static public byte[] GetStringToBytes(string value) { SoapHexBinary shb = SoapHexBinary.Parse(value); return shb.Value; } static public string GetBytesToString(byte[] value) { SoapHexBinary shb = new SoapHexBinary(value); return shb.ToString(); } } /// <summary> /// Cyclic Redundancy Check (CRC) /// </summary> /// CCITT (x^16 + x^12 + x^5 + 1) public static class Crc16Ccitt { public static byte[] GetCRC(byte[] data) { ushort crc = 0x3791; // eZ430-TMS37157 initial value for (byte i = 0; i < data.Length; i++) { byte bits = 8; byte current = data[i]; // Next byte while (bits-- > 0) { bool lsb = (crc & 1) > 0; // Store LSB crc >>= 1; // Shift right 1 bit bool rxdt = (current & 1) > 0; if (rxdt) { crc |= 0x8000; // Shift in next bit } if (lsb) // Check stored LSB { crc ^= 0x8000; // Invert MSB } if (0x8000 == (crc & 0x8000)) // Check MSB { crc ^= 0x0408; // Invert bits 3 and 10 (have in mind those are x^12 and x^5) } current >>= 1; // Next bit } } return BitConverter.GetBytes(crc); } } /// <summary> /// Longitudinal Redundancy Check (LRC) /// </summary> public static class LRC { public static byte calculateLRC(byte[] bytes) { byte LRC = 0; for (int i = 0; i < bytes.Length; i++) { LRC ^= bytes[i]; } return LRC; } } /// <summary> /// Get Friendly Comport Names :) /// </summary> /// based on http://dariosantarelli.wordpress.com/2010/10/18/c-how-to-programmatically-find-a-com-port-by-friendly-name/ public class COMPortInfo { public string Name; public string Description; public static List<COMPortInfo> GetCOMPortsInfo() { List<COMPortInfo> comPortInfoList = new List<COMPortInfo>(); ManagementScope connectionScope = new ManagementScope { Path = new ManagementPath(@"\\" + Environment.MachineName + @"\root\CIMV2"), Options = new ConnectionOptions { Impersonation = ImpersonationLevel.Impersonate, Authentication = AuthenticationLevel.Default, EnablePrivileges = true } }; connectionScope.Connect(); ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0"); ManagementObjectSearcher comPortSearcher = new ManagementObjectSearcher(connectionScope, objectQuery); using (comPortSearcher) { string caption; foreach (ManagementObject obj in comPortSearcher.Get()) { if (obj != null) { object captionObj = obj["Caption"]; if (captionObj != null) { caption = captionObj.ToString(); if (caption.Contains("(COM")) { COMPortInfo comPortInfo = new COMPortInfo { Name = caption.Substring(caption.LastIndexOf("(COM")).Replace("(", string.Empty).Replace(")", string.Empty), Description = caption }; comPortInfoList.Add(comPortInfo); } } } } } return comPortInfoList; } } }
- Details
It's time for new blog post, briefly about how to deal with implementing easy bit field structure layout in C :)
Let us see the following structure in C++
10 /*****************************************************************************
11 *
12 * Splitt structure we are about to cast :)
13 *
14 *****************************************************************************/
15
16 // prototype C++
17
18 const int A_Flag_width = 2;
19 const int A_FrameID_width = 6;
20 const int A_Link_width = 8;
21 const int A_SplittID_width = 8;
22 const int A_Empty_width = 8;
23
24 typedef struct
25 {
26 DWORD32 A_Flag : A_Flag_width;
27 DWORD32 A_FrameID : A_FrameID_width;
28 DWORD32 A_Link: A_Link_width;
29 DWORD32 A_SplittID : A_SplittID_width;
30 DWORD32 A_Empty: A_Empty_width;
31 DWORD32 B_CRC;
32 char * Data;
33 }
34 splitt_struct;
35
36 /****************************************************************************/
It represents a recent structure I wanted to code in C about some Frame with header, which should be splitted in structure called Splitt, that has also some header and look like above declared. So to spare space you might wanna have precise bit layout. One way to deal nicely with bitlayouts are the bitfields like this (click), other way is to use bitsets (click), also few others using diverse libraries.
Anyway, enough said, the C variant is this:
39 /*****************************************************************************
40 *
41 * This is the nice C variant :)
42 *
43 *****************************************************************************/
44
45 // define shit C
46
47 typedef char structure;
48 typedef structure * p_structure;
49
50
51 #define MEMBER_POINTER(number,t) (t *)((p_structure)Example + number * sizeof(t))
52 #define MEMBER_VALUE(number,t) (*MEMBER_POINTER(number, t))
53
54 #define SUBMEMBER_CLEAR(member, t, start, end) do { MEMBER_VALUE(member, t) &= ~(((SIZE_MAX << end) >> (end + start)) << start); } while (0);
55 #define SUBMEMBER_GET(member, t, start, end) ((MEMBER_VALUE(member, t) << end) >> (end + start))
56 #define SUBMEMBER_SET(member, t, val, start, end) do { SUBMEMBER_CLEAR(member, t, start, end); MEMBER_VALUE(member, t) |= val << start ; } while (0);
57
58 #define MEMBER_LAST_BIT(t) (8 * sizeof(t) - 1)
59 #define END_OFFSET(t, end) (MEMBER_LAST_BIT(t) - end)
60
61
62 typedef structure Splitt;
63 typedef p_structure p_Splitt;
64
65 #define splitt Example
66
67 #define A 0
68 #define CRC 1
69 #define DATA 2
70
71 #define A_flag_start 0
72 #define A_flag_end END_OFFSET(size_t, 1)
73 #define A_FID_start 2
74 #define A_FID_end END_OFFSET(size_t, 7)
75 #define A_Link_start 8
76 #define A_Link_end END_OFFSET(size_t, 15)
77 #define A_SID_start 16
78 #define A_SID_end END_OFFSET(size_t, 23)
79 #define A_Empty_start 24
80 #define A_Empty_end END_OFFSET(size_t, 31)
81
82 #define splitt_flag_get (SUBMEMBER_GET(A, DWORD32, A_flag_start, A_flag_end))
83 #define splitt_flag_set(val) SUBMEMBER_SET(A, DWORD32, val, A_flag_start, A_flag_end)
84 #define splitt_FID_get (SUBMEMBER_GET(A, DWORD32, A_FID_start, A_FID_end))
85 #define splitt_FID_set(val) SUBMEMBER_SET(A, DWORD32, val, A_FID_start, A_FID_end)
86 #define splitt_link_get (SUBMEMBER_GET(A, DWORD32, A_Link_start, A_Link_end))
87 #define splitt_link_set(val) SUBMEMBER_SET(A, DWORD32, val, A_Link_start, A_Link_end)
88 #define splitt_SID_get (SUBMEMBER_GET(A, DWORD32, A_SID_start, A_SID_end))
89 #define splitt_SID_set(val) SUBMEMBER_SET(A, DWORD32, val, A_SID_start, A_SID_end)
90 #define splitt_empty_get (SUBMEMBER_GET(A, DWORD32, A_Empty_start, A_Empty_end))
91 #define splitt_empty_set(val) SUBMEMBER_SET(A, DWORD32, val, A_Empty_start, A_Empty_end)
92
93 #define p_splitt_CRC (MEMBER_POINTER(CRC, DWORD32))
94 #define splitt_CRC (*p_splitt_CRC)
95
96 #define splitt_data MEMBER_POINTER(DATA, p_Splitt)
97
98
99 /****************************************************************************/
Nice :)
To explain briefly, I cast all to byte buffer and then use some shifting functions to extract different bit fields! (taking mask for example is pretty easy by shifting the other bits left and right to clear them). The code shown also forces using the name splitt for Splitt (e.g. you cannot use the functions after declaring "Splitt bubble")(I find this good).
What you can further do is to have the nice defines in "template style" way and then cast a multiple structures with the token pasting operator, which will make your code to look like the real deal! (I did it but then reduced the structures so it turned out to be obsolete)
You can also nest common headers with defines, which I also did with the structures later on (not shown, too much stuff)
Anyway, I don't intend to explain any further for now, just click to download the code with example test!
- Details
Heyo this is a small example, how to Marshall c structures to c# for the usb chip. The example shows a static c# class :)
1 ///
2 /// author svilen.info / svilen.de
3 ///
4 /// no copyright, however please cite source XD
5 ///
6 /// some small example, how the c -> c# marshalling works here!
7 ///
8
9 using System;
10 using System.Diagnostics;
11 using System.Runtime.InteropServices;
12 using System.Text;
13
14 namespace Zarlink.Adk.Forms
15 {
16 /// <summary>
17 /// This class will deal with the USB communication
18 /// </summary>
19 /// Here we will cast all the ftd2xx.h functions and structure that we need
20 /// and will add some other specific communaction protocols
21 static class Communication
22 {
23 #region My Variables
24
25 public static FT_STATUS status; // represents the FT status. To be updated after every action!
26
27 public static IntPtr handle; // represents the FT device handle. Should be always the same, if varies then something is wrong (like more usbs)
28
29
30 public struct Buffer
31 {
32 public byte[] data; // data from the last successful transfer
33 public DateTime lastSuccessfulUse; // if connection lost, to check the date and time of the last successful data transfer
34 }
35
36 public static Buffer inBuffer; // what we received last
37 public static Buffer outBuffer; // what we sent last
38
39 #endregion My Variables
40
41 #region Stupid defines from the dll
42
43 // FT_OpenEx Flags
44 private const UInt16 FT_OPEN_BY_SERIAL_NUMBER = 1;
45 private const UInt16 FT_OPEN_BY_DESCRIPTION = 2;
46 private const UInt16 FT_OPEN_BY_LOCATION = 4;
47
48 // Baud Rates
49 private const UInt32 FT_BAUD_300 = 300;
50 private const UInt32 FT_BAUD_600 = 600;
51 private const UInt32 FT_BAUD_1200 = 1200;
52 private const UInt32 FT_BAUD_2400 = 2400;
53 private const UInt32 FT_BAUD_4800 = 4800;
54 private const UInt32 FT_BAUD_9600 = 9600;
55 private const UInt32 FT_BAUD_14400 = 14400;
56 private const UInt32 FT_BAUD_19200 = 19200;
57 private const UInt32 FT_BAUD_38400 = 38400;
58 private const UInt32 FT_BAUD_57600 = 57600;
59 private const UInt32 FT_BAUD_115200 = 115200;
60 private const UInt32 FT_BAUD_230400 = 230400;
61 private const UInt32 FT_BAUD_460800 = 460800;
62 private const UInt32 FT_BAUD_921600 = 921600;
63
64 // Word Lengths
65 private const byte FT_BITS_8 = 8;
66 private const byte FT_BITS_7 = 7;
67 private const byte FT_BITS_6 = 6;
68 private const byte FT_BITS_5 = 5;
69
70
71 // Stop Bits
72 private const byte FT_STOP_BITS_1 = 0;
73 private const byte FT_STOP_BITS_1_5 = 1;
74 private const byte FT_STOP_BITS_2 = 2;
75
76 // Parity
77 private const byte FT_PARITY_NONE = 0;
78 private const byte FT_PARITY_ODD = 1;
79 private const byte FT_PARITY_EVEN = 2;
80 private const byte FT_PARITY_MARK = 3;
81 private const byte FT_PARITY_SPACE = 4;
82
83 // Flow Control
84 private const UInt16 FT_FLOW_NONE = 0x0000;
85 private const UInt16 FT_FLOW_RTS_CTS = 0x0100;
86 private const UInt16 FT_FLOW_DTR_DSR = 0x0200;
87 private const UInt16 FT_FLOW_XON_XOFF = 0x0400;
88
89 // Purge rx and tx buffers
90 public const byte FT_PURGE_RX = 1;
91 public const byte FT_PURGE_TX = 2;
92
93 // Events
94 public const byte FT_EVENT_RXCHAR = 1;
95 public const byte FT_EVENT_MODEM_STATUS = 2;
96 public const byte FT_EVENT_LINE_STATUS = 4;
97
98 // Timeouts
99 private const UInt32 FT_DEFAULT_RX_TIMEOUT = 300;
100 private const UInt32 FT_DEFAULT_TX_TIMEOUT = 300;
101
102 #endregion Stupid defines
103
104 #region Stupid Marshals
105
106 /// <summary>
107 /// marshalling the structure...
108 /// </summary>
109 [StructLayout(LayoutKind.Sequential)]
110 public struct LPFTDCB
111 {
112 public UInt32 DCBlength; /* sizeof(FTDCB) */
113 public UInt32 BaudRate; /* Baudrate at which running */
114
115 public UInt32 fBits; // bits layout is inportable so have the flag and take out the bits
116 //ulong fBinary: 1; /* Binary Mode (skip EOF check) */
117 //ulong fParity: 1; /* Enable parity checking */
118 //ulong fOutxCtsFlow:1; /* CTS handshaking on output */
119 //ulong fOutxDsrFlow:1; /* DSR handshaking on output */
120 //ulong fDtrControl:2; /* DTR Flow control */
121 //ulong fDsrSensitivity:1; /* DSR Sensitivity */
122 //ulong fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */
123 //ulong fOutX: 1; /* Enable output X-ON/X-OFF */
124 //ulong fInX: 1; /* Enable input X-ON/X-OFF */
125 //ulong fErrorChar: 1; /* Enable Err Replacement */
126 //ulong fNull: 1; /* Enable Null stripping */
127 //ulong fRtsControl:2; /* Rts Flow control */
128 //ulong fAbortOnError:1; /* Abort all reads and writes on Error */
129 //ulong fDummy2:17; /* Reserved */
130
131 public UInt16 wReserved; /* Not currently used */
132 public UInt16 XonLim; /* Transmit X-ON threshold */
133 public UInt16 XoffLim; /* Transmit X-OFF threshold */
134
135 public byte ByteSize; /* Number of bits/byte, 4-8 */
136 public byte Parity; /* 0-4=None,Odd,Even,Mark,Space */
137 public byte StopBits; /* 0,1,2 = 1, 1.5, 2 */
138
139 public char XonChar; /* Tx and Rx X-ON character */
140 public char XoffChar; /* Tx and Rx X-OFF character */
141 public char ErrorChar; /* Error replacement char */
142 public char EofChar; /* End of Input character */
143 public char EvtChar; /* Received Event character */
144
145 public ushort wReserved1; /* Fill for now. */
146 } ;
147
148 #endregion Stupid Marshals
149
150 #region Constructors, Destructors ...
151
152 static Communication()
153 {
154 handle = IntPtr.Zero;
155
156 outBuffer = new Buffer { data = new byte[140], lastSuccessfulUse = DateTime.Now };
157 inBuffer = new Buffer { data = new byte[140], lastSuccessfulUse = DateTime.Now };
158 }
159
160 //static ~Communication()
161 //{
162 // Close();
163 //}
164
165 #endregion Constructors, Destructors ...
166
167 #region W32 Functions from the dll
168 // note: W32 should not be mixed with non W32 unless explicitly stated
169
170
171 /// <summary>
172 /// This function gets the current device state.
173 /// </summary>
174 /// <param name="ftHandle">Cast PVOID to IntPtr to have system specific handle pointer size</param>
175 /// <param name="lpftDcb">the status</param>
176 /// <returns>If the function is successful, the return value is nonzero</returns>
177 [DllImport("ftd2xx")]
178 public static extern bool FT_W32_GetCommState(IntPtr ftHandle, ref LPFTDCB lpftDcb);
179
180 #endregion W32 Functions
181
182 #region Normal Functions that we use from the dll
183
184 [DllImport("ftd2xx")]
185 public static extern FT_STATUS FT_ResetDevice(IntPtr ftHandle);
186
187 [DllImport("ftd2xx")]
188 public static extern FT_STATUS FT_ClrDtr(IntPtr ftHandle);
189
190 [DllImport("ftd2xx")]
191 public static extern FT_STATUS FT_ClrRts(IntPtr ftHandle);
192
193 [DllImport("ftd2xx")]
194 public static extern FT_STATUS FT_Open(UInt32 uiPort, IntPtr ftHandle);
195
196 [DllImport("ftd2xx")]
197 public static extern FT_STATUS FT_Close(IntPtr ftHandle);
198
199 [DllImport("ftd2xx")]
200 public static extern FT_STATUS FT_Read(IntPtr ftHandle, out byte[] lpBuffer, UInt32 dwBytesToRead, out UInt32 lpdwBytesReturned);
201
202 [DllImport("ftd2xx")]
203 public static extern FT_STATUS FT_Write(IntPtr ftHandle, IntPtr lpBuffer, UInt32 dwBytesToRead, ref UInt32 lpdwBytesWritten);
204
205 [DllImport("ftd2xx")]
206 public static extern FT_STATUS FT_SetLatencyTimer(IntPtr ftHandle, byte ucTimer);
207
208 [DllImport("ftd2xx")]
209 public static extern FT_STATUS FT_SetDataCharacteristics(IntPtr ftHandle, byte uWordLength, byte uStopBits, byte uParity);
210
211 [DllImport("ftd2xx")]
212 public static extern FT_STATUS FT_SetFlowControl(IntPtr ftHandle, ushort usFlowControl, byte uXon, byte uXoff);
213
214 [DllImport("ftd2xx")]
215 public static extern FT_STATUS FT_GetModemStatus(IntPtr ftHandle, ref UInt32 lpdwModemStatus);
216
217 [DllImport("ftd2xx")]
218 public static extern FT_STATUS FT_Purge(IntPtr ftHandle, UInt32 dwMask);
219
220 [DllImport("ftd2xx")]
221 public static extern FT_STATUS FT_SetBreakOn(IntPtr ftHandle);
222
223 [DllImport("ftd2xx")]
224 public static extern FT_STATUS FT_SetBreakOff(IntPtr ftHandle);
225
226 [DllImport("ftd2xx")]
227 public static extern FT_STATUS FT_GetStatus(IntPtr ftHandle, ref UInt32 lpdwAmountInRxQueue, ref UInt32 lpdwAmountInTxQueue, ref UInt32 lpdwEventStatus);
228
229 [DllImport("ftd2xx")]
230 public static extern FT_STATUS FT_SetDivisor(IntPtr ftHandle, char usDivisor);
231
232 #endregion Normal Functions
233
234 #region Functions written by Svilen ;)
235
236 public static void DebugInformation(string step = "")
237 {
238 Debug.WriteLine(step + " status: " + status);
239 Debug.WriteLine("handle address: " + handle);
240 unsafe
241 {
242 if (handle != null)
243 {
244 Debug.WriteLine("handle value: " + *(uint*) handle.ToPointer()); // to use in unsafed code
245 }
246 }
247 //Debug.WriteLine("handle value: " + *(uint *)handle.ToPointer()); // to use in unsafed code
248 }
249
250 public static void Init()
251 {
252 // > open >
253 FT_Open(0, handle);
254 DebugInformation("open");
255 // < open <
256
257 // > reset! >
258 FT_ResetDevice(handle);
259 DebugInformation("reset");
260 // < reset! <
261
262 // > set reply rate
263 FT_SetLatencyTimer(handle, 2);
264 DebugInformation("latency timer");
265 // < set reply rate <
266
267 // > set same flow control
268 FT_SetFlowControl(handle, FT_FLOW_RTS_CTS, 0, 0);
269 DebugInformation("flow control");
270 // < set flow control <
271
272
273 // > clear the buffers >
274 FT_Purge(handle, FT_PURGE_TX + FT_PURGE_RX);
275 DebugInformation("purge");
276 // < clear the buffers <
277 }
278
279 public static void ReadTest()
280 {
281 byte[] bytes = new byte[20];
282 IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
283 Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);
284 IntPtr bytesLeft = (IntPtr)10;
285
286 // FT_Read(handle, unmanagedPointer, (UInt32)bytes.Length, bytesLeft);
287 DebugInformation("read");
288
289 Marshal.Copy(unmanagedPointer, bytes, 0, bytes.Length);
290 ASCIIEncoding enc = new ASCIIEncoding();
291 Debug.WriteLine("buffer has: " + enc.GetString(bytes));
292
293 Marshal.FreeHGlobal(unmanagedPointer);
294 }
295
296 public static int ReadBuffer()
297 {
298 UInt32 bytesLeft;
299 inBuffer.data = new byte[140];
300
301 FT_Read(handle, out inBuffer.data, (UInt32)inBuffer.data.Length, out bytesLeft);
302 DebugInformation("read");
303
304 ASCIIEncoding enc = new ASCIIEncoding();
305 if (inBuffer.data != null)
306 Debug.WriteLine("buffer has: " + enc.GetString(inBuffer.data));
307
308 return 0;
309 }
310
311 public static void WriteTest()
312 {
313 IntPtr ptr = Marshal.AllocHGlobal(4);
314 Marshal.Copy(outBuffer.data, 0, ptr, 4);
315
316 uint bytesWritten = 0;
317 FT_Write(handle, ptr, 4, ref bytesWritten);
318
319 DebugInformation("write");
320 }
321
322 public static void Close()
323 {
324 if (handle == IntPtr.Zero)
325 {
326 FT_Close(handle);
327 DebugInformation("close");
328 }
329 }
330
331 #endregion Functions
332
333 #region other defines and enumerations for the communication namespace
334
335 /// <summary>
336 /// Enumaration containing the varios return status for the DLL functions.
337 /// </summary>
338 public enum FT_STATUS
339 {
340 FT_OK = 0,
341 FT_INVALID_HANDLE,
342 FT_DEVICE_NOT_FOUND,
343 FT_DEVICE_NOT_OPENED,
344 FT_IO_ERROR,
345 FT_INSUFFICIENT_RESOURCES,
346 FT_INVALID_PARAMETER,
347 FT_INVALID_BAUD_RATE,
348 FT_DEVICE_NOT_OPENED_FOR_ERASE,
349 FT_DEVICE_NOT_OPENED_FOR_WRITE,
350 FT_FAILED_TO_WRITE_DEVICE,
351 FT_EEPROM_READ_FAILED,
352 FT_EEPROM_WRITE_FAILED,
353 FT_EEPROM_ERASE_FAILED,
354 FT_EEPROM_NOT_PRESENT,
355 FT_EEPROM_NOT_PROGRAMMED,
356 FT_INVALID_ARGS,
357 FT_OTHER_ERROR
358 }
359
360 #endregion other defines and enumerations for the communication namespace
361 }
362 }
363
- Details
Simle test of my Compute Frequency function using some code citation tool...