示例#1
0
        private void ProgramMemoryRegion(IntelHexFile hexFile, MemoryRegionStruct memoryRegion)
        {
            using (var pipe = HidDevice.Open()) {
                byte currentByteInAddress = 1;
                bool skippedBlock         = false;

                // Obtain the data related to the current memory region
                var regionData = hexFile.MapMemory(memoryRegion.Address, memoryRegion.Size, _bytesPerAddress);
                int j          = 0;

                // While the current address is less than the end address
                uint address    = memoryRegion.Address;
                uint endAddress = memoryRegion.Address + memoryRegion.Size;
                while (address < endAddress)
                {
                    // Prepare command
                    ProgramDeviceStruct myCommand = new ProgramDeviceStruct {
                        ReportID = 0,
                        Command  = BootloaderCommand.Program,
                        Address  = address
                    };
                    myCommand.Data = new byte[ProgramPacketDataSize];

                    // If a block consists of all 0xFF, then there is no need to write the block
                    // as the erase cycle will have set everything to 0xFF
                    bool skipBlock = true;

                    byte i;
                    for (i = 0; i < _bytesPerPacket; i++)
                    {
                        byte data = regionData[j++];

                        myCommand.Data[i + (myCommand.Data.Length - _bytesPerPacket)] = data;

                        if (data != 0xFF)
                        {
                            // We can skip a block if all bytes are 0xFF.
                            // Bytes are also ignored if it is byte 4 of a 3 word instruction on PIC24 (bytesPerAddress=2, currentByteInAddress=2, even address)

                            if ((_bytesPerAddress != 2) || ((address % 2) == 0) || (currentByteInAddress != 2))
                            {
                                // Then we can't skip this block of data
                                skipBlock = false;
                            }
                        }

                        if (currentByteInAddress == _bytesPerAddress)
                        {
                            // If we haven't written enough bytes per address to be at the next address
                            address++;
                            currentByteInAddress = 1;
                        }
                        else
                        {
                            // If we haven't written enough bytes to fill this address
                            currentByteInAddress++;
                        }

                        //If we have reached the end of the memory region, then we
                        //  need to pad the data at the end of the packet instead
                        //  of the front of the packet so we need to shift the data
                        //  to the back of the packet.
                        if (address >= endAddress)
                        {
                            byte n;
                            i++;

                            int len = myCommand.Data.Length;
                            for (n = 0; n < len; n++)
                            {
                                if (n < i)
                                {
                                    // Move it from where it is to the back of the packet, thus shifting all of the data down.
                                    myCommand.Data[len - n - 1] = myCommand.Data[i + (len - _bytesPerPacket) - n - 1];
                                }
                                else
                                {
                                    myCommand.Data[len - n - 1] = 0x00;
                                }
                            }

                            // Break out of the for loop now that all the data has been padded out.
                            break;
                        }
                    }                    //end for

                    // Use the counter to determine how many bytes were written
                    myCommand.BytesPerPacket = i;

                    //If the block was all 0xFF then we can just skip actually programming
                    //  this device.  Otherwise enter the programming sequence
                    if (!skipBlock)
                    {
                        //If we skipped one block before this block then we may need
                        //  to send a proramming complete command to the device before
                        //  sending the data for this command.
                        if (skippedBlock)
                        {
                            SendCommandPacket(pipe, new BootloaderCommandStruct {
                                ReportID = 0,
                                Command  = BootloaderCommand.ProgramComplete
                            });

                            //since we have now indicated that the programming is complete
                            //  then we now mark that we haven't skipped any blocks
                            skippedBlock = false;
                        }

                        SendCommandPacket(pipe, myCommand);
                        FlashCount += ProgramPacketDataSize;
                    }
                    else
                    {
                        // We are skipping the block
                        skippedBlock = true;
                        FlashCount  += ProgramPacketDataSize;
                    }
                }                //end while

                // All data for this region has been programmed
                SendCommandPacket(pipe, new BootloaderCommandStruct {
                    ReportID = 0,
                    Command  = BootloaderCommand.ProgramComplete
                });
                ProgressChanged?.Invoke(this, new ProgressChangedEventArgs(0, null));
            }            //end using
        }
示例#2
0
        /// <summary>
        /// Program the target PIC memory region using the provided hex file
        /// </summary>
        /// <param name="hexFile">Hexfile containing data to program</param>
        /// <param name="memoryRegion">The target memory region to program</param>
        private void ProgramMemoryRegion(HexFile hexFile, MemoryRegionStruct memoryRegion)
        {
            using (var WriteFile = HidDevice.GetWriteFile())
            {
                byte currentByteInAddress = 1;
                bool skippedBlock         = false;

                // Obtain the data related to the current memory region
                var regionData = hexFile.GetMemoryRegion(memoryRegion.Address, memoryRegion.Size, bytesPerAddress);
                int j          = 0;

                // While the current address is less than the end address
                uint address    = memoryRegion.Address;
                uint endAddress = memoryRegion.Address + memoryRegion.Size;
                while (address < endAddress)
                {
                    // Prepare command
                    ProgramDeviceStruct myCommand = new ProgramDeviceStruct
                    {
                        WindowsReserved = 0,
                        Command         = PROGRAM_DEVICE,
                        Address         = address
                    };
                    myCommand.Data = new byte[PROGRAM_PACKET_DATA_SIZE];

                    // If a block consists of all 0xFF, then there is no need to write the block
                    // as the erase cycle will have set everything to 0xFF
                    bool skipBlock = true;

                    byte i;
                    for (i = 0; i < bytesPerPacket; i++)
                    {
                        byte data = regionData[j++];

                        myCommand.Data[i + (myCommand.Data.Length - bytesPerPacket)] = data;

                        if (data != 0xFF)
                        {
                            // We can skip a block if all bytes are 0xFF.
                            // Bytes are also ignored if it is byte 4 of a 3 word instruction on PIC24 (bytesPerAddress=2, currentByteInAddress=2, even address)

                            if ((bytesPerAddress != 2) || ((address % 2) == 0) || (currentByteInAddress != 2))
                            {
                                // Then we can't skip this block of data
                                skipBlock = false;
                            }
                        }

                        if (currentByteInAddress == bytesPerAddress)
                        {
                            // If we haven't written enough bytes per address to be at the next address
                            address++;
                            currentByteInAddress = 1;
                        }
                        else
                        {
                            // If we haven't written enough bytes to fill this address
                            currentByteInAddress++;
                        }

                        //If we have reached the end of the memory region, then we
                        //  need to pad the data at the end of the packet instead
                        //  of the front of the packet so we need to shift the data
                        //  to the back of the packet.
                        if (address >= endAddress)
                        {
                            byte n;
                            i++;

                            int len = myCommand.Data.Length;
                            for (n = 0; n < len; n++)
                            {
                                if (n < i)
                                {
                                    // Move it from where it is to the back of the packet, thus shifting all of the data down.
                                    myCommand.Data[len - n - 1] = myCommand.Data[i + (len - bytesPerPacket) - n - 1];
                                }
                                else
                                {
                                    myCommand.Data[len - n - 1] = 0x00;
                                }
                            }

                            // Break out of the for loop now that all the data has been padded out.
                            break;
                        }
                    }//end for

                    // Use the counter to determine how many bytes were written
                    myCommand.BytesPerPacket = i;

                    //If the block was all 0xFF then we can just skip actually programming
                    //  this device.  Otherwise enter the programming sequence
                    if (!skipBlock)
                    {
                        //If we skipped one block before this block then we may need
                        //  to send a proramming complete command to the device before
                        //  sending the data for this command.
                        if (skippedBlock)
                        {
                            SendCommandPacket <BootloaderCommandStruct>(new BootloaderCommandStruct
                            {
                                WindowsReserved = 0,
                                Command         = PROGRAM_COMPLETE
                            });

                            //since we have now indicated that the programming is complete
                            //  then we now mark that we haven't skipped any blocks
                            skippedBlock = false;
                        }

                        // Write the packet data!

                        /*string debug = "";
                         * foreach (byte b in myCommand.Data)
                         *  debug += b.ToString("x2") + " ";
                         * Console.WriteLine(">>> USB OUT Packet >>>\n{0}", debug);*/

                        SendCommandPacket <ProgramDeviceStruct>(myCommand);
                    }
                    else
                    {
                        // We are skipping the block
                        skippedBlock = true;
                    }
                }//end while

                // All data for this region has been programmed
                SendCommandPacket <BootloaderCommandStruct>(new BootloaderCommandStruct
                {
                    WindowsReserved = 0,
                    Command         = PROGRAM_COMPLETE
                });
            }//end using
        }