예제 #1
0
        static private bool SendBulkData(byte[] Data)
        {
            /* From MPPICKIT3:
             *
             * This class allows the user to send/receive any amount of data as a series of
             * HID reports. It isolates the user from knowing how to hook to MPLABComm
             * and from knowing how data is turned into reports. You basically, open,
             * read, write and close. It extends HID which is the class that actually
             * knows how to send/receive reports.
             *
             * Protocol notes: HID wants to send information in reports. We chose a report size of 64 bytes.
             * The Real ICE/ICD3/PK3, do not have a symetric protocol implementation with respect to the PC.
             * In other words, the requirements for the USB driver implementation in the embedded side of
             * these tools are not the same as the requirements of the USB driver in the PC side.
             * If you look at the PK3 FW driver you will see it does not look like the GetData/SendData defined
             * here. However, both the transmission and reception use the same protocol format.
             * In the PC side, GetData gets called and we can safely assume that GetData will not
             * need to read from the middle of a message. GetData is called to get a message. This message
             * might have the excepted len (passed as a parameter) or any other len. As long as a message
             * is received, GetData must return indicating how much data it got.
             * Of course, that means that when calling GetData, you'd better pass a buffer big enough
             * to handle the largest possible response (which might not be the one you were expecting)
             * the PK3 can send.
             * This allows the following situation to occur:
             *      PC -> Send command
             *      PK3 -> Send response
             *  Or
             *      PC -> Send command
             *      PK3 -> Send working indication
             *      PK3 -> Send response
             *
             * Note: the following examples show how data is packetized into reports. The
             * examples are the same regardless of who is sending our who is receiving
             * (PC or PK3 FW).*
             * An example of 32 (0x20) bytes of data being sent in s single report
             *
             *     +----------+
             *     | data1    | byte 0      <-- beginnig of report 1
             *     | data2    | byte 6
             *     :          :
             *     | 0x20     | byte 60     <- length of data in this message (little endian)
             *     | 0x00     | byte 61        In this case the length is 0x20 or 32 bytes
             *     | 0x00     | byte 62
             *     | 0x00     | byte 63     <-- end of report 1. End of transmission
             *     +----------+
             *
             *
             * An example of 67 bytes (0x43 in hex) being sent. It
             * requires sending 2 reports with 60 bytes in the first one (64 bytes of
             * report size - 4 bytes for the length) and 7 in the
             *
             *     +----------+
             *     | data1    | byte 0      <-- beginnig of report 1
             *     | data2    | byte 6
             *     :          :
             *     | 0x43     | byte 60     <- length of data in this message (little endian)
             *     | 0x00     | byte 61        In this case the length is 0x43 or 67 bytes
             *     | 0x00     | byte 62
             *     | 0x00     | byte 63     <-- end of report 1
             *     +----------+
             *     +----------+
             *     | data61   | byte 0      <-- beginning of report 2
             *     | data62   |
             *     | data63   |
             *     | data64   |
             *     | data65   |
             *     | data66   |
             *     :          :
             *     :          :
             *     | padding  | byte 60     <--- note NO length included here. Only in the
             *     | padding  | byte 61          very first report
             *     | padding  | byte 62
             *     | padding  | byte 63     <-- end of report 2
             *     +----------+
             *
             * @author jose
             */

            // Add the total message length at the end of the first USB report
            int size = Data.Length + 2 + 4;

            // Round the packet size up to the nearest USB report size
            if (size % 64 != 0)
            {
                size = size + (64 - size % 64);
            }
            byte[] TotalData = new byte[size];

            // Fill the buffer with our pad value. Useful data will overwrite as necessary.
            for (int i = 0; i < TotalData.Length; i++)
            {
                TotalData[i] = 0x5B;
            }

            if (Data.Length <= 60)
            { // Only one report needed
                Array.Copy(Data, 0, TotalData, 0, Data.Length);
            }
            else
            { // Muliple reports needed
                Array.Copy(Data, 0, TotalData, 0, 60);
                Array.Copy(Data, 60, TotalData, 64, Data.Length - 60);
            }

            TotalData[60] = Convert.ToByte((Data.Length + 2) & 0xFF);
            TotalData[61] = Convert.ToByte(((Data.Length + 2) >> 8) & 0xFF);
            TotalData[62] = Convert.ToByte(((Data.Length + 2) >> 16) & 0xFF);
            TotalData[63] = Convert.ToByte(((Data.Length + 2) >> 24) & 0xFF);

            uint Checksum = GetTwosCompWordChecksum(Data);

            // If the data packet is more than one report big, add 4 to the index to skip
            // over the Bulk Transfer Checksum
            if (TotalData.Length > 0x40)
            {
                TotalData[Data.Length + 4 + 0] = Convert.ToByte(Checksum & 0xFF);
                TotalData[Data.Length + 4 + 1] = Convert.ToByte((Checksum >> 8) & 0xFF);
            }
            else
            { // The packet is only 1 report, so we don't need to adjust for the DWORD Length
                TotalData[Data.Length + 0] = Convert.ToByte(Checksum & 0xFF);
                TotalData[Data.Length + 1] = Convert.ToByte((Checksum >> 8) & 0xFF);
            }

            byte[] outgoingData = new byte[64];

            ResetStatusBar((int)(TotalData.Length / 64));
            for (int reportCount = 0; reportCount * 64 < TotalData.Length; reportCount++)
            {
                Array.Copy(TotalData, reportCount * 64, outgoingData, 0, 64);

                Pk3.writeUSB(outgoingData);

                StepStatusBar();
            }

            if (Pk3.readUSB())
            {
                // Evaluate response to determine success or failure
                if ((Pk3.Usb_read_array[1] == 0x00) && (Pk3.Usb_read_array[2] == 0x00))
                { // we got a "success" indicator
                    return(true);
                }
                else
                { // we got something crazy
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
예제 #2
0
        static private void SendCommandWithDataNoResponse(uint Command, byte[] Data)
        {
            /* HID report payloads are 64 bytes. The PICkit3 message structure requires the first
             * report have the 2-byte command and 4-byte message size. The rest of that report can
             * be payload for the command. Subsequent reports in the same message do not require
             * the command or the size. Message size is Data Bytes + Command Bytes.
             */

            byte[] usbCommand = new byte[] { (byte)(((ushort)Command) & 0xFF), (byte)(((ushort)Command >> 8) & 0xFF) };
            //byte[] usbWriteBuffer = new byte[64];
            int DataLength = 0;

            if (Data == null)
            {
                DataLength = 0;
            }
            else
            {
                DataLength = Data.Length;
            }

            //// WARNING: This assumes ONLY ONE report is needed (So don't do memory transfers yet!).
            //if ((Data != null) && (Data.Length > 58)) // 64 - 4 (length) - 2 (command)
            //    throw new ArgumentException("Data transfer must require only one USB transaction.", "Data");

            // Add the total message length at the end of the first USB report
            int size = DataLength + 2 + 4;

            // Round the packet size up to the nearest USB report size
            if (size % 64 != 0)
            {
                size = size + (64 - size % 64);
            }
            byte[] usbWriteBuffer = new byte[size];

            // Fill the buffer with our pad value. Useful data will overwrite as necessary.
            for (int i = 0; i < usbWriteBuffer.Length; i++)
            {
                usbWriteBuffer[i] = 0x5B;
            }

            // Copy the command into the buffer.
            usbWriteBuffer[0] = (byte)(((ushort)Command) & 0xFF);
            usbWriteBuffer[1] = (byte)(((ushort)Command >> 8) & 0xFF);

            // Copy the data into the buffer.
            if (Data == null)
            {                           // No data to send. Only one report needed.
            }
            else if (Data.Length <= 58) // 64 - 4 (length) - 2 (command)
            {                           // Only one report needed
                Array.Copy(Data, 0, usbWriteBuffer, 2, Data.Length);
            }
            else
            { // Muliple reports needed
                Array.Copy(Data, 0, usbWriteBuffer, 2, 60);
                Array.Copy(Data, 58, usbWriteBuffer, 64, Data.Length - 58);
            }

            // Fill in the length of the message
            usbWriteBuffer[60] = Convert.ToByte(DataLength + usbCommand.Length & 0xFF);
            usbWriteBuffer[61] = Convert.ToByte(DataLength + usbCommand.Length >> 8 & 0xFF);
            usbWriteBuffer[62] = Convert.ToByte(DataLength + usbCommand.Length >> 16 & 0xFF);
            usbWriteBuffer[63] = Convert.ToByte(DataLength + usbCommand.Length >> 24 & 0xFF);

            // Note that a checksum is not sent in this type of transaction.

            byte[] outgoingData = new byte[64];

            for (int reportCount = 0; reportCount * 64 < usbWriteBuffer.Length; reportCount++)
            {
                Array.Copy(usbWriteBuffer, reportCount * 64, outgoingData, 0, 64);

                Pk3.writeUSB(outgoingData);
            }
        }