Breadcrumbs


Subscribe RSS


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 :)

As part of Max Ophuels Preis we demonstrated our markerless motion capturing system to visitors in form of real-time Unity virtual reality game, where you have jump on boxes over lava and avoid flying ball, tracked and augmented as a fireball.


http://thecaptury.com/
http://www.max-ophuels-preis.de/informationen_fuer_branchenvertreter/mop_industry/mop_industry_panels_und_workshops/k8_open_lab

Running is one of the most natural human activities, yet it yields all sorts of injuries, causing dissatisfaction often followed by a withdraw. In this video we explore in depth how you can improve your running style and avoid injuries all together with the help of a motion capturing system.

1. 0:36 Foot Strike: Start from the bottom where the foot hits the ground. It’s called foot-strike and most people hit it with their heel at first. This is not only inefficient, because it breaks your forward motion, but it creates a shock that goes all the way from your heels through the ankles, shins and knees, to reach your hips and waist, making all of them vulnerable to injuries. To avoid this first try to land between the middle and the front part of your feet with a slightly bent knee. Thus you won’t create a breaking force against your motion. Having your knee not fully extended will allow your muscles to absorb the landing impact instead of your joints and bones. This is believed to be the leading cause of the so called Patellofemoral pain syndrome or runner’s knee and Plantar fasciitis or heel pain. Furthermore, you should always strive to step close to your center of mass projection on the floor. The farther you step from your center of gravity the more your muscles and joints will have to compensate in order to keep you balanced. Besides wasting energy you are opening yourself for injuries not only at your ankle area, but also at the inner- and outer-side of the knee. Mostly it irritates your so called iliotibial band, causing the ITB syndrome, which feels like a fire on the outer-side of the knee and it’s like someone is stabbing you there with a needle on each step. Further indicators for stepping far from the center of mass are high ankle pronation and supination.

2. 2:00 Knee Motion: Same goes for your knees – their main motion should be flexion and extension and they should point towards your running direction and rotate as little as possible. Having your knees pointing inwards is a common for woman and having them pointing outwards is common for man, both contributing for the medial tibial stress syndrome (MTSS) a.k.a. shin splints.

3. 2:23 Hip Motion: Next crucial point are your hips – you should have strong hip abductors to be able to take the step impact without going up and down absorbing the force instead of carrying out the body. High variation of hip ab- and adduction slowly causes all kinds of injuries in the waist area, including lumbar spinal disk herniation.

4. 2:43 Upper Body: From there on, you should have a straight posture between your upper-body and your head to avoid bending on each step. Lastly, your elbow flexion should be around a right angle and your hands should move forward as well. So don’t do such over-exaggerating motions and postures while running, because this will twist your spine, neck and everything around unnecessarily.

5. 3:06 Putting All Together: Try to be conscious about each aspect of you running, as well as all together, because all parts are somewhat connected. Bad knee rotations are likely to connect with crooked ankles, which leads to bad body balance and so on. On the good side of things is that if you make some parameter better, it will improve others as well. Like, if you strive to move your hands forward with your running rhythm, you are likely to improve your upper-body posture to support them.

6. 3:43 Side Balance: Further aspect, you should keep an eye on is how balanced is your running. Just compare your left and right strides in terms of length, width and joint angles across foot strikes. Those can indicate possible misalignments that can result in long term injuries. It might be the case that you are doing things wrong from one side only, thus result in injuries on that side, which happened to me many times already. If your numbers seem fine, it can also be the case, that your corresponding body parts are just in different sizes, which causes the imbalance.

7. 4:36 Different Speeds: Keep in mind that you should do this check at different speeds as well, because they have different mechanics. Here you can see when lowering your run speed, you’ll have less hip ab- and adduction, as well as less knee flexion angle variance. Hence you might have already noticed your injuries often occur when you are running at your limits. Still you should pay attention at your running style at lower speeds, because you might be slowly building up an injury – step by step, run after run.

8. 5:10 Different Runs at Same Speed: It is important to compare your stats among same speed runs, yet this is what everyone already does, thus only briefly mentioned here.

9. 5:16 Same Run at Different Times: Even more important is how your running style evolves along a long run. You can compare the beginning versus the end of your run, to see indications towards wrong running style. Some muscles might get tired faster than others and despite your good feeling of proceeding with your training, you’ll literally run against your rest muscles, joints, bones and tendons, because they’ll be the one to absorb and compensate for the tired muscles.

10. 6:10 Enjoy: Joy is very overlooked aspect of running, yet the most important. If you don’t like running, but do it a lot for whatever reasons, it is absolutely sure that you’ll get injured, which will increase your hatred towards running. If you don’t enjoy running you’ll hardly get motivated to pay attention to any of the aspects mentioned above and when something happens to your condition you’ll blame it all to running and quit. Just ask yourself, how often have you spotted people dressed with the latest sports industry fashion clothes with all of their devices, earphones and chewing gums doing strange movements that should resemble running? How persistent are those people? Couple of days, week, maybe a month? Don’t run just because you are required to do so in order to loose weight or gain endurance. That’s why my final wish to all of you is to enjoy running and stay healthy to be able to do it as long as you wish!

Thanks for watching! If you are interested in our motion capturing system visit our website http://thecaptury.com/

Further Links:
1. Runner’s World: The Big 7 Body Breakdowns - https://www.runnersworld.com/health/the-big-7-body-breakdowns
2. Competitor Running: The 5 Most Troublesome Running Injuries - http://running.competitor.com/2014/07/injury-prevention/5-troublesome-running-injuries_11316/
3. UWTV: Common Running Injuries - https://www.youtube.com/watch?v=nmdTFkYQsko
4. Howcast: How to have proper running form - https://www.youtube.com/watch?v=e7m205ZIxBE
5. Sage Running: Essential Running Technique Tips for Proper Form & How to Run Faster - https://www.youtube.com/watch?v=3RlvKMxPMr0

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; } } }

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!

Heyo this is a small example, how to Marshall c structures to c# for the usb chip. The example shows a static c# class :)

(Download .cs)

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