Example #1
0
        public void FirmwareValidate(TestData.Fw fw_paths)
        {
            foreach (TestData.Fw fw in fw_paths.GetFlags())
            {
                FwTools.FwInfo ret = FwTools.Validate(TestData.GetFwPath(fw));

                Assert.NotNull(ret);
                Assert.True(ret.SizeCode > 0);
            }
        }
Example #2
0
            private Status ParseFirmware(string firmware_path, out List <Rx_Block> rx_blocks, out FwTools.FwInfo fw_info)
            {
                fw_info   = null;
                rx_blocks = new List <Rx_Block>();
                FwTools.Firmware code_to_upload    = null;
                FwTools.Firmware code_full_for_crc = null;
                bool             fill_FF           = false;

                if (protocol == Protocol.USB_5_6)
                {
                    fill_FF = true;
                }

                try
                {
                    code_to_upload    = FwTools.Parse(firmware_path, FillFF: fill_FF);
                    code_full_for_crc = FwTools.Parse(firmware_path, FillFF: true);

                    // slice data to bigger blocks that fit buffer size
                    int buff_size = GetBufferSize(protocol);
                    if (fill_FF)
                    {
                        for (int i = 0; i < code_to_upload.Nodes.Count; i += buff_size)
                        {
                            rx_blocks.Add(new Rx_Block
                            {
                                addr = (int)code_to_upload.Nodes[i].Addr,
                                data = code_to_upload.Nodes.Skip(i).Take(buff_size).Select(nod => nod.Data).ToArray()
                            });
                        }
                    }
                    else
                    {
                        for (int i = 0, j = 0; i < code_to_upload.Nodes.Count; i++)
                        {
                            if (i == code_to_upload.Nodes.Count - 1 ||
                                code_to_upload.Nodes[i + 1].Addr - code_to_upload.Nodes[i].Addr > 1 ||
                                j + 1 >= buff_size)
                            {
                                rx_blocks.Add(new Rx_Block
                                {
                                    addr = (int)code_to_upload.Nodes[i - j].Addr,
                                    data = code_to_upload.Nodes.Skip(i - j).Take(j + 1).Select(nod => nod.Data).ToArray()
                                });
                                j = 0;
                            }
                            else
                            {
                                j++;
                            }
                        }
                    }

                    code_to_upload.Info.Crc16 = code_full_for_crc.Info.Crc16;
                    fw_info = code_to_upload.Info;

                    if (rx_blocks == null || rx_blocks.Count < 1)
                    {
                        throw new Bsl430NetException(445);
                    }
                    else
                    {
                        return(Utils.StatusCreate(0));
                    }
                }
                catch (Exception ex)
                {
                    if (ex is Bsl430NetException)
                    {
                        return(Utils.StatusCreate(450, ((Bsl430NetException)ex).Status));
                    }
                    else if (ex is FirmwareToolsException)
                    {
                        Status fw_ex = new Status()
                        {
                            Error = ((FirmwareToolsException)ex).Error,
                            Msg   = ((FirmwareToolsException)ex).Msg
                        };
                        return(Utils.StatusCreate(450, fw_ex));
                    }
                    else
                    {
                        return(Utils.StatusCreate(450, ex.Message));
                    }
                }
            }
Example #3
0
            private StatusEx LoadEx(Bsl430NetDevice device,
                                    Command cmd, byte[] password,
                                    string firmware_path,
                                    int?addr_start,
                                    int?data_size,
                                    out List <byte> output)
            {
                output = new List <byte>();
                byte[] bsl_version = new byte[0];
                Debug.Assert(cmd == Command.Upload || cmd == Command.Download || cmd == Command.MassErase);
                List <Rx_Block> rx_blocks = new List <Rx_Block>();

                FwTools.FwInfo fw_info        = new FwTools.FwInfo();
                bool           baud_rate_fail = false;

                block_pending    = false;
                progress_pending = 0.0;
                byte[] pw;

                try
                {
                    string dev_name = (device != null) ? device.Name : CommGetDefaultDevice().Name;
                    pw = ValidatePassword(password, out bool pw_overide);

                    UpdateProgress(5, $"INIT '{mode}'");

                    if (cmd == Command.Upload)
                    {
                        BlockStart("FW READ", 10);

                        Status parsed_fw = ParseFirmware(firmware_path, out rx_blocks, out fw_info);
                        if (!parsed_fw.OK)
                        {
                            BlockEnd(ReportResult.FAILED);
                            Task.Delay(Const.DELAY_ERR_RET).Wait();
                            return(Utils.StatusCreateEx(180, parsed_fw, reports, report, bsl_version,
                                                        (fw_info == null) ? 0 : fw_info.SizeFull));
                        }
                        BlockEnd($"FW {fw_info.Format.ToString().Replace('_', '-')} x{fw_info.AddrFirst.ToString("X4")} " +
                                 $"{(fw_info.SizeFull / 1024.0).ToString("F1", CultureInfo.InvariantCulture)}K");
                    }
                    else if (cmd == Command.Download)
                    {
                        BlockStart("PREPARE FW DATA", 10);

                        fw_info = new FwTools.FwInfo(addr_start ?? 0,
                                                     (addr_start ?? 0) + (data_size ?? 0),
                                                     data_size ?? 0,
                                                     GetBufferSize(protocol));
                        BlockEnd();
                    }

                    if (fw_info != null && fw_info.AddrLast > int.MaxValue)
                    {
                        return(Utils.StatusCreateEx(100, reports, report, bsl_version, fw_info.SizeFull));
                    }

                    // ---

                    BlockStart($"OPEN '{dev_name}'", 15);

                    CommOpen(device);
                    CommSet(Utility.Utility.GetEnumDefaultValue <BaudRate>());

                    BlockEnd();

                    // ---

                    BlockStart($"INVOKE '{invoke}'", 20, true);

                    if (mode != Mode.USB_HID && invoke != InvokeMechanism.MANUAL)
                    {
                        skipped = false;
                        InvokeBSL(invoke);
                        Task.Delay(100).Wait();
                    }

                    BlockEnd();

                    // --

                    CommClrBuff();

                    BlockStart($"#BAUD RATE '{(int)baud_rate}'", 25, true);

                    if (mode != Mode.USB_HID && baud_rate != BaudRate.BAUD_9600)
                    {
                        skipped = false;

                        Result <Data_Void> result_baudrate = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.BaudRate)));

                        if (!result_baudrate.ok)
                        {
                            baud_rate_fail = true;
                        }

                        Task.Delay(5).Wait();

                        if (baud_rate_fail)
                        {
                            BlockEnd(ReportResult.FAILED);
                            if (result_baudrate.status.ToString().Contains("timeout"))
                            {
                                CommClose(true);
                                Task.Delay(Const.DELAY_ERR_RET).Wait();
                                return(Utils.StatusCreateEx(100, result_baudrate.status, reports, report, bsl_version, fw_info.SizeFull));
                            }
#if BREAK_ON_BAUD_CHANGE_ERROR
                            CommClose(true);
                            Task.Delay(Const.DELAY_ERR_RET).Wait();
                            return(Utils.StatusCreateEx(100, result_baudrate.status, reports, report, bsl_version, fw_info.SizeFull));
#endif
                        }
                        else
                        {
                            BlockEnd(ReportResult.SUCCESS);
                            CommSet(baud_rate);
                        }
                        Task.Delay(10).Wait();
                    }
                    else
                    {
                        BlockEnd();
                    }

                    // --

                    if ((pw_overide || protocol == Protocol.USB_5_6 || cmd == Command.Download) && cmd != Command.MassErase)
                    {
                        BlockStart("#PASSWORD (CUSTOM)", 35);

                        if (pw_overide &&
                            ((protocol == Protocol.UART_1_2_4 && pw.Length == 20) ||
                             ((mcu == MCU.MSP430_F543x_NON_A && pw.Length == 16) || pw.Length == 32)))
                        {
                            Result <Data_Void> result_password = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.Password, pw)));

                            if (!result_password.ok)
                            {
                                BlockEnd(ReportResult.FAILED);
                                CommClose(true);
                                Task.Delay(Const.DELAY_ERR_RET).Wait();
                                return(Utils.StatusCreateEx(120, result_password.status, reports, report, bsl_version, fw_info.SizeFull));
                            }
                            else
                            {
                                pw_overide = true;
                            }
                        }
                        else
                        {
                            return(Utils.StatusCreateEx(470, reports, report, bsl_version, fw_info.SizeFull));
                        }

                        Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait();

                        BlockEnd();
                    }
                    else // if (!pw_overide && protocol != Protocol.USB_5_6)
                    {
                        BlockStart("#MASS ERASE", 30);

                        Result <Data_Void> result_masserase = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.MassErase)));

                        if (!result_masserase.ok)
                        {
                            BlockEnd(ReportResult.FAILED);
                            CommClose(true);
                            Task.Delay(Const.DELAY_ERR_RET).Wait();
                            return(Utils.StatusCreateEx(110, result_masserase.status, reports, report, bsl_version, fw_info.SizeFull));
                        }

                        BlockEnd();

                        Task.Delay(100).Wait();

                        // --

                        BlockStart("#PASSWORD (DEFAULT)", 35);

                        Result <Data_Void> result_password = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.Password, pw)));

                        if (!result_password.ok)
                        {
                            BlockEnd(ReportResult.FAILED);
                            CommClose(true);
                            Task.Delay(Const.DELAY_ERR_RET).Wait();
                            return(Utils.StatusCreateEx(120, result_password.status, reports, report, bsl_version, fw_info.SizeFull));
                        }
                        Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait();

                        BlockEnd();
                    }

                    // --

                    BlockStart("#BSL VERSION", 40, true);

                    if (mode != Mode.USB_HID)
                    {
                        skipped = false;

                        Result <Data_BSLVersion> result_ver = ParseResp <Data_BSLVersion>(ProcessMsg(BuildMsg(Command.BSLVersion)));

                        if (!result_ver.ok)
                        {
                            BlockEnd(ReportResult.FAILED);
                        }
                        else
                        {
                            BlockEnd(ReportResult.SUCCESS,
                                     $"#BSL VERSION {BitConverter.ToString(result_ver.data.version).Replace("-", ".")}");
                            bsl_version = result_ver.data.version.ToArray();
                        }
                        Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait();
                    }
                    else
                    {
                        BlockEnd();
                    }

                    // --

                    if (mode == Mode.USB_HID)
                    {
                        // TODO Upload RAM BSL
                        // TODO Load PC
                    }

                    // --

                    if (cmd == Command.Upload)
                    {
                        double quantum = 50.0 / (double)rx_blocks.Count;
                        double _prg    = 40;

                        Result <Data_Void> result_rx;
                        for (int x = 0; x < rx_blocks.Count; x++)
                        {
                            BlockStart($"#UPLOADING ({x + 1}/{rx_blocks.Count})", _prg);

                            result_rx = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.Upload,
                                                                                  rx_blocks[x].addr,
                                                                                  rx_blocks[x].data)));
                            if (!result_rx.ok)
                            {
                                BlockEnd(ReportResult.FAILED);
                                CommClose(true);
                                Task.Delay(Const.DELAY_ERR_RET).Wait();
                                return(Utils.StatusCreateEx(140,
                                                            result_rx.status,
                                                            (x + 1) + "/" + rx_blocks.Count,
                                                            reports,
                                                            report,
                                                            bsl_version,
                                                            fw_info.SizeFull));
                            }
                            _prg += quantum;

                            Task.Delay(5).Wait();

                            if (x == rx_blocks.Count - 1)
                            {
                                BlockEnd($"#UPLOADED ({x + 1}/{rx_blocks.Count})");
                            }
                            else
                            {
                                BlockEnd();
                            }
                        }
                        Task.Delay(5).Wait();
                    }
                    else if (cmd == Command.Download)
                    {
                        int    _data_size = (data_size ?? 0);
                        int    total      = (_data_size + fw_info.SizeBuffer - 1) / fw_info.SizeBuffer;
                        double quantum    = 50.0 / (double)total;
                        double _prg       = 40;

                        Result <Data_Download> result_tx;
                        for (int x = 0; x < total; x++)
                        {
                            BlockStart($"#DOWNLOADING ({x + 1}/{total})", _prg);

                            int len = data_size ?? 0;
                            if (len > fw_info.SizeBuffer)
                            {
                                len = fw_info.SizeBuffer;
                            }

                            result_tx = ParseResp <Data_Download>(ProcessMsg(BuildMsg(Command.Download,
                                                                                      addr_start,
                                                                                      new byte[2] {
                                (byte)(len & 0x00FF),
                                (byte)(len >> 8)
                            })));
                            if (!result_tx.ok)
                            {
                                BlockEnd(ReportResult.FAILED);
                                CommClose(true);
                                Task.Delay(Const.DELAY_ERR_RET).Wait();
                                return(Utils.StatusCreateEx(150,
                                                            result_tx.status,
                                                            x + "/" + rx_blocks.Count,
                                                            reports,
                                                            report,
                                                            bsl_version,
                                                            fw_info.SizeFull));
                            }

                            output.AddRange(result_tx.data.bytes.ToList());
                            _prg       += quantum;
                            addr_start += fw_info.SizeBuffer;
                            data_size  -= fw_info.SizeBuffer;
                            Task.Delay(5).Wait();

                            if (x == total - 1)
                            {
                                BlockEnd($"#DOWNLOADED ({x + 1}/{total})");
                            }
                            else
                            {
                                BlockEnd();
                            }
                        }
                        fw_info.Crc16 = output.Crc16Ccitt();
                        Task.Delay(5).Wait();
                    }

                    // --

                    if (cmd != Command.MassErase)
                    {
                        BlockStart($"#CRC CHECK ({fw_info.Crc16.ToString("X4")})", 95, true);

                        if (protocol != Protocol.UART_1_2_4 && fw_info != null && !(pw_overide && cmd == Command.Upload))
                        {
                            skipped = false;

                            Result <Data_CRC> result_crc = ParseResp <Data_CRC>(ProcessMsg(BuildMsg(Command.CRC,
                                                                                                    (int)fw_info.AddrFirst,
                                                                                                    new byte[2] {
                                (byte)(fw_info.SizeFull & 0x00FF),
                                (byte)(fw_info.SizeFull >> 8)
                            })));
                            if (!result_crc.ok)
                            {
                                BlockEnd(ReportResult.FAILED);
                                CommClose(true);
                                Task.Delay(Const.DELAY_ERR_RET).Wait();
                                return(Utils.StatusCreateEx(160, result_crc.status, reports, report, bsl_version, fw_info.SizeFull));
                            }
                            if (result_crc.data.crc != fw_info.Crc16)
                            {
                                BlockEnd(ReportResult.FAILED, $"#CRC CHECK ({fw_info.Crc16.ToString("X4")}!={result_crc.data.crc.ToString("X4")})");
                                CommClose(true);
                                Task.Delay(Const.DELAY_ERR_RET).Wait();
                                return(Utils.StatusCreateEx(161, reports, report, bsl_version, fw_info.SizeFull));
                            }
                            Task.Delay(Const.BSL430_DELAY_BETWEEN_CMDS).Wait();

                            BlockEnd($"#CRC CHECK ({fw_info.Crc16.ToString("X4")}=={result_crc.data.crc.ToString("X4")})");
                        }
                        else
                        {
                            BlockEnd();
                        }
                    }

                    // --

                    if (cmd != Command.MassErase)
                    {
                        BlockStart("#LOAD USER PROGRAM", 98, true);

                        if (fw_info.ResetVector != null)
                        {
                            skipped = false;

                            Result <Data_Void> result_load = ParseResp <Data_Void>(ProcessMsg(BuildMsg(Command.LoadPC, (int)fw_info.ResetVector)));

                            if (result_load.ok)
                            {
                                BlockEnd(ReportResult.SUCCESS);
                            }
                            else
                            {
                                BlockEnd(ReportResult.FAILED);
                                //Task.Delay(Const.DELAY_ERR_RET).Wait();
                                //return Utils.StatusCreateEx(170);
                            }
                        }
                        else
                        {
                            BlockEnd();
                        }
                    }

                    // --

                    BlockStart($"RESET '{mcu}'", 99, true);

                    if (mode != Mode.USB_HID)
                    {
                        skipped = false;
                        ResetMCU(invoke);
                    }

                    BlockEnd();

                    // --

                    BlockStart($"FINISH", 100);

                    CommClose();

                    BlockEnd();
                    Task.Delay(Const.DELAY_OK_RET).Wait();

                    return(Utils.StatusCreateEx(0, reports, null, bsl_version, fw_info.SizeFull));
                }
                catch (Exception ex)
                {
                    CommClose(true);

                    if (block_pending)
                    {
                        BlockEnd(ReportResult.FAILED);
                        Task.Delay(Const.DELAY_ERR_RET).Wait();
                    }

                    if (ex is Bsl430NetException)
                    {
                        return(Utils.StatusCreateEx((ex as Bsl430NetException).Status.Error,
                                                    (ex as Bsl430NetException).Status,
                                                    reports,
                                                    report,
                                                    bsl_version,
                                                    fw_info.SizeFull));
                    }
                    else
                    {
                        return(Utils.StatusCreateEx(
                                   Utils.StatusCreate(467, ex.Message + ((Const.IS_DEBUG) ? ex.StackTrace : "")),
                                   reports,
                                   report,
                                   bsl_version,
                                   fw_info.SizeFull));
                    }
                }
            }