Example #1
0
        public BaseWorker(RTD266x rtd)
        {
            _rtd = rtd;

            _backgroundWorker                     = new BackgroundWorker();
            _backgroundWorker.DoWork             += _backgroundWorker_DoWork;
            _backgroundWorker.RunWorkerCompleted += _backgroundWorker_RunWorkerCompleted;
        }
 public ModifyFirmwareWorker(RTD266x rtd, string logoFileName, Color logoBackground, Color logoForeground, Color displayBackground, bool removeHdmi, string replaceHdmi) : base(rtd)
 {
     _logoFileName      = logoFileName;
     _logoBackground    = logoBackground;
     _logoForeground    = logoForeground;
     _displayBackground = displayBackground;
     _removeHdmi        = removeHdmi;
     _replaceHdmi       = replaceHdmi;
 }
Example #3
0
        private void btnDisconnect_Click(object sender, EventArgs e)
        {
            if (_comPort != null && _comPort.IsOpen)
            {
                _comPort.Close();

                AppendConsoleText("Disconnected\r\n");
            }

            UpdateConnected(false);

            _rtd = null;
        }
Example #4
0
        private void btnClearLock_Click(object sender, EventArgs e)
        {
            AppendConsoleText("Clearing lock bits... ");

            RTD266x.Result result = _rtd.WriteStatus(0x00, 0x00);

            if (result == RTD266x.Result.Ok)
            {
                AppendConsoleText("done\r\n");
            }
            else
            {
                AppendConsoleText(RTD266x.ResultToString(result) + "\r\n");
            }
        }
Example #5
0
        private void ReadWorkerFinished(RTD266x.Result result, byte[] data)
        {
            UpdateBackgroundWorkerActive(false);

            if (result != RTD266x.Result.Ok)
            {
                AppendConsoleText(RTD266x.ResultToString(result) + "\r\n");
                return;
            }

            AppendConsoleText("done\r\n");

            if (chkReadConsole.Checked)
            {
                StringBuilder dataLog = new StringBuilder();
                int           column  = 0;

                foreach (byte dataByte in data)
                {
                    dataLog.Append($"{dataByte:X2} ");

                    column++;

                    if (column == 16)
                    {
                        dataLog.Append("\r\n");
                        column = 0;
                    }
                }

                AppendConsoleText(dataLog.ToString());
            }

            if (chkReadFile.Checked)
            {
                try
                {
                    File.WriteAllBytes(txtReadFileName.Text, data);
                    AppendConsoleText($"Data successfully written to \"{txtReadFileName.Text}\"\r\n");
                }
                catch (Exception ex)
                {
                    AppendConsoleText($"Cannot write file \"{txtReadFileName.Text}\"! {ex.Message}\r\n");
                }
            }
        }
        private RTD266x.Result WritePatchedSector(byte[] firmware, int address)
        {
            int sectorAddress = (address / 4096) * 4096;

            byte[] sector = new byte[4096];

            Array.Copy(firmware, sectorAddress, sector, 0, sector.Length);

            ReportStatus("Writing patched sector...\r\n");

            RTD266x.Result result = Write(sectorAddress, sector, true);

            if (result != RTD266x.Result.Ok)
            {
                ReportStatus(RTD266x.ResultToString(result) + "\r\n");
            }

            return(result);
        }
Example #7
0
        private void btnEraseChip_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Do you really want to erase the whole chip?", "Erase chip", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
            {
                return;
            }

            AppendConsoleText("Erasing chip (all data)... ");

            RTD266x.Result result = _rtd.EraseChip();

            if (result == RTD266x.Result.Ok)
            {
                AppendConsoleText("done\r\n");
            }
            else
            {
                AppendConsoleText(RTD266x.ResultToString(result) + "\r\n");
            }
        }
Example #8
0
        private void btnReadStatus_Click(object sender, EventArgs e)
        {
            AppendConsoleText("Reading status info... ");

            RTD266x.StatusInfo statusInfo;

            RTD266x.Result result = _rtd.ReadStatus(out statusInfo);

            if (result != RTD266x.Result.Ok)
            {
                AppendConsoleText(RTD266x.ResultToString(result) + "\r\n");
                return;
            }

            AppendConsoleText("done\r\n");

            AppendConsoleText($"Manufacturer ID: 0x{statusInfo.ManufacturerId:X2} ({statusInfo.Manufacturer})\r\n");
            AppendConsoleText($"Device ID: 0x{statusInfo.DeviceId:X2} ({statusInfo.Type})\r\n");
            AppendConsoleText($"JEDEC Manufacturer ID: 0x{statusInfo.JedecManufacturerId:X2} ({statusInfo.Manufacturer})\r\n");
            AppendConsoleText($"JEDEC Memory Type: 0x{statusInfo.JedecMemoryType:X2}\r\n");
            AppendConsoleText($"JEDEC Capacity: 0x{statusInfo.JedecCapacity:X2} ({statusInfo.Capacity})\r\n");
            AppendConsoleText($"Status: 0x{statusInfo.Status:X4}\r\n");
        }
Example #9
0
        private void btnConnect_Click(object sender, EventArgs e)
        {
            if (_comPort != null && _comPort.IsOpen)
            {
                _comPort.Close();
            }

            _comPort           = new SerialPort(comboBoxPorts.Text, (int)numericBaudRate.Value);
            _comPort.Parity    = Parity.None;
            _comPort.StopBits  = StopBits.One;
            _comPort.DataBits  = 8;
            _comPort.Handshake = Handshake.None;

            AppendConsoleText("Connecting...\r\n");

            try
            {
                _comPort.Open();
            }
            catch (Exception ex)
            {
                AppendConsoleText($"Error! Cannot open {comboBoxPorts.Text}: {ex.Message}");
                UpdateConnected(false);
                return;
            }

            _rtd = new RTD266x(_comPort);

            UpdateConnected(true);

            RTD266x.ErrorCode errorCode = RTD266x.ErrorCode.NoError;
            uint errorInfo = 0;

            RTD266x.Result result  = RTD266x.Result.NotOk;
            int            retries = 5;

            // try to connect a few times
            for (int i = 0; i < retries; i++)
            {
                result = _rtd.ReadErrorCode(out errorCode, out errorInfo);

                if (result == RTD266x.Result.Ok)
                {
                    break;
                }

                _rtd.ClearReadBuffer();

                AppendConsoleText($"Connection error: {RTD266x.ResultToString(result)}, retrying... ({i + 1}/{retries})\r\n");
            }

            if (result != RTD266x.Result.Ok)
            {
                AppendConsoleText($"Connection error: {RTD266x.ResultToString(result)}\r\n");
                AppendConsoleText("Did you download the sketch RTD266xArduino to your Arduino?\r\n");
                AppendConsoleText("Is the Arduino connected properly to the display?\r\n");
                AppendConsoleText("Did you select the correct COM port?\r\n");
                AppendConsoleText("Is the display powered?\r\n");
                AppendConsoleText("If the Arduino's user LED is on, the I2C connection to the display does not work.\r\n");
                AppendConsoleText("Press the Arduino's reset button and try again.\r\n\r\n");

                btnDisconnect_Click(null, null);
                return;
            }

            if (errorCode == RTD266x.ErrorCode.NoError)
            {
                AppendConsoleText("Connection successful!\r\n");
            }
            else
            {
                AppendConsoleText("Initialization error: ");
                AppendConsoleText(RTD266x.ErrorCodeToString(errorCode, errorInfo) + "\r\n");

                btnDisconnect_Click(null, null);
            }
        }
        protected override void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            string error;

            if (!string.IsNullOrEmpty(_logoFileName))
            {
                ReportStatus("Checking logo file... ");

                if (!FontCoder.CheckFile(_logoFileName, FontCoder.FontWidthKedei, FontCoder.FontHeightKedei, out error))
                {
                    ReportStatus($"Error! {error}\r\n");
                    e.Result = RTD266x.Result.NotOk;
                    return;
                }

                ReportStatus("ok\r\n");
            }

            if (!string.IsNullOrEmpty(_replaceHdmi))
            {
                ReportStatus("Checking \"HDMI\" replacement... ");

                if (!FirmwareModifier.CheckHdmiReplacement(_replaceHdmi, out error))
                {
                    ReportStatus($"{error}\r\n");
                    e.Result = RTD266x.Result.NotOk;
                    return;
                }

                ReportStatus("ok\r\n");
            }

            ReportStatus("Identifying device... ");

            RTD266x.Result     result;
            RTD266x.StatusInfo status;

            result = _rtd.ReadStatus(out status);

            if (result != RTD266x.Result.Ok || (status.ManufacturerId != 0xC8 && status.ManufacturerId != 0x1C && status.ManufacturerId != 0xC2 && status.ManufacturerId != 0x85) || status.DeviceId != 0x12)
            {
                ReportStatus("Error! Cannot identify chip.\r\n");
                e.Result = result;
                return;
            }

            ReportStatus("ok\r\n");
            ReportStatus("Reading firmware...\r\n");

            byte[] firmware;

            result = Read(0, 512 * 1024, out firmware, true);

            if (result != RTD266x.Result.Ok)
            {
                ReportStatus(RTD266x.ResultToString(result) + "\r\n");
                e.Result = result;
                return;
            }

            string backupFirmwareFileName = "firmware-" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ".bin";

            ReportStatus($"Creating firmware backup file \"{backupFirmwareFileName}\"... ");

            try
            {
                File.WriteAllBytes(backupFirmwareFileName, firmware);
            }
            catch (Exception ex)
            {
                ReportStatus($"Error! Could not save file \"{backupFirmwareFileName}\". {ex.Message}\r\n");
                e.Result = result;
                return;
            }

            ReportStatus("ok\r\n");
            ReportStatus("Checking firmware... ");

            Firmware detectedFirmware = FirmwareModifier.DetectFirmware(firmware);

            if (detectedFirmware == null)
            {
                ReportStatus("Error! Unknown firmware. You can send your firmware and the name of the display (printed on the cable on the back side) to the author ([email protected]), maybe it can be added to the known firmwares.\r\n");
                e.Result = result;
                return;
            }

            ReportStatus("ok\r\n");
            ReportStatus($"Detected firmware is {detectedFirmware.Name}\r\n");

            if (!string.IsNullOrEmpty(_logoFileName))
            {
                ReportStatus("Converting and embedding the new logo... ");

                if (!FirmwareModifier.ChangeLogo(_logoFileName, firmware, detectedFirmware, out error))
                {
                    ReportStatus($"{error}\r\n");
                    e.Result = result;
                    return;
                }

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.LogoOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            if (_logoBackground != Color.Empty)
            {
                ReportStatus("Patching logo background color... ");

                FirmwareModifier.ChangeLogoBackgroundColor(_logoBackground, firmware, detectedFirmware);

                ReportStatus("ok\r\n");
            }

            if (_logoForeground != Color.Empty)
            {
                ReportStatus("Patching logo foreground color... ");

                FirmwareModifier.ChangeLogoForegroundColor(_logoForeground, firmware, detectedFirmware);

                ReportStatus("ok\r\n");
            }

            if ((_logoBackground != Color.Empty) || (_logoForeground != Color.Empty))
            {
                result = WritePatchedSector(firmware, detectedFirmware.PaletteOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            if (_displayBackground != Color.Empty)
            {
                ReportStatus("Patching display background color... ");

                FirmwareModifier.ChangeBackgroundColor(_displayBackground, firmware, detectedFirmware);

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.AdjustBackgroundColorOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            if (_removeHdmi)
            {
                ReportStatus("Removing \"HDMI\" pop-up... ");

                FirmwareModifier.ToggleHdmiPopup(false, firmware, detectedFirmware);

                ReportStatus("ok\r\n");
            }
            else
            {
                ReportStatus("Enabling \"HDMI\" pop-up... ");

                FirmwareModifier.ToggleHdmiPopup(true, firmware, detectedFirmware);

                ReportStatus("ok\r\n");
            }

            result = WritePatchedSector(firmware, detectedFirmware.ShowNoteOffset);

            if (result != RTD266x.Result.Ok)
            {
                e.Result = result;
                return;
            }

            if (_removeNoSignal)
            {
                ReportStatus("Removing \"No Signal\" pop-up...");

                FirmwareModifier.ToggleNoSignalPopup(false, firmware, detectedFirmware);

                ReportStatus("ok\r\n");
            }
            else
            {
                ReportStatus("Enabling \"No Signal\" pop-up...");

                FirmwareModifier.ToggleNoSignalPopup(true, firmware, detectedFirmware);

                ReportStatus("ok\r\n");
            }

            result = WritePatchedSector(firmware, detectedFirmware.NoSignalOffset);

            if (result != RTD266x.Result.Ok)
            {
                e.Result = result;
                return;
            }

            if (!string.IsNullOrEmpty(_replaceHdmi))
            {
                ReportStatus($"Replacing \"HDMI\" pop-up with \"{_replaceHdmi}\"... ");

                FirmwareModifier.ReplaceHdmiPopup(_replaceHdmi, firmware, detectedFirmware);

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.HdmiStringOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            ReportStatus("Finished! Now reboot the display and enjoy your new firmware :)\r\n");

            e.Result = RTD266x.Result.Ok;
        }
        protected override void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (!string.IsNullOrEmpty(_logoFileName))
            {
                ReportStatus("Checking logo file... ");

                string error;

                if (!FontCoder.CheckFile(_logoFileName, FontCoder.FontWidthKedei, FontCoder.FontHeightKedei, out error))
                {
                    ReportStatus($"Error! {error}\r\n");
                    e.Result = RTD266x.Result.NotOk;
                    return;
                }

                ReportStatus("ok\r\n");
            }

            if (!string.IsNullOrEmpty(_replaceHdmi))
            {
                ReportStatus("Checking \"HDMI\" replacement... ");

                if (_replaceHdmi.Length > 8)
                {
                    ReportStatus("Error! String is too long!\r\n");
                    e.Result = RTD266x.Result.NotOk;
                    return;
                }

                foreach (char chr in _replaceHdmi)
                {
                    if (!_osdCharacters.ContainsKey(chr))
                    {
                        ReportStatus($"Error! Invalid character \"{chr}\"!\r\n");
                        e.Result = RTD266x.Result.NotOk;
                        return;
                    }
                }

                ReportStatus("ok\r\n");
            }

            ReportStatus("Identifying device... ");

            RTD266x.Result     result;
            RTD266x.StatusInfo status;

            result = _rtd.ReadStatus(out status);

            if (result != RTD266x.Result.Ok || (status.ManufacturerId != 0xC8 && status.ManufacturerId != 0x1C) || status.DeviceId != 0x12)
            {
                ReportStatus("Error! Cannot identify chip.\r\n");
                e.Result = result;
                return;
            }

            ReportStatus("ok\r\n");
            ReportStatus("Reading firmware...\r\n");

            byte[] firmware;

            result = Read(0, 512 * 1024, out firmware, true);

            if (result != RTD266x.Result.Ok)
            {
                ReportStatus(RTD266x.ResultToString(result) + "\r\n");
                e.Result = result;
                return;
            }

            string backupFirmwareFileName = "firmware-" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".bin";

            ReportStatus($"Creating firmware backup file \"{backupFirmwareFileName}\"... ");

            try
            {
                File.WriteAllBytes(backupFirmwareFileName, firmware);
            }
            catch (Exception ex)
            {
                ReportStatus($"Error! Could not save file \"{backupFirmwareFileName}\". {ex.Message}\r\n");
                e.Result = result;
                return;
            }

            ReportStatus("ok\r\n");
            ReportStatus("Checking firmware... ");

            Firmware detectedFirmware = null;

            foreach (Firmware fw in _firmwares)
            {
                if (fw.CheckHash(firmware))
                {
                    detectedFirmware = fw;
                    break;
                }
            }

            if (detectedFirmware == null)
            {
                ReportStatus("Error! Could not detect firmware.\r\n");
                e.Result = result;
                return;
            }

            ReportStatus("ok\r\n");
            ReportStatus($"Detected firmware is {detectedFirmware.Name}\r\n");

            if (!string.IsNullOrEmpty(_logoFileName))
            {
                ReportStatus("Converting logo... ");

                FontCoder logo = new FontCoder(FontCoder.FontWidthKedei, FontCoder.FontHeightKedei);

                if (!logo.LoadImage(_logoFileName))
                {
                    ReportStatus($"Error! Cannot load logo from \"{_logoFileName}\".\r\n");
                    e.Result = result;
                    return;
                }

                byte[] logoBytes = logo.Encode();

                if (logoBytes.Length > detectedFirmware.MaxLogoLength)
                {
                    ReportStatus("Error! Encoded logo is too long and would overwrite other firmware parts.\r\n");
                    e.Result = result;
                    return;
                }

                ReportStatus("ok\r\n");
                ReportStatus("Embedding the new logo... ");

                Array.Copy(logoBytes, 0, firmware, detectedFirmware.LogoOffset, logoBytes.Length);

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.LogoOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            if (_logoBackground != Color.Empty)
            {
                ReportStatus("Patching logo background color... ");

                firmware[detectedFirmware.PaletteOffset + 42] = _logoBackground.R;
                firmware[detectedFirmware.PaletteOffset + 43] = _logoBackground.G;
                firmware[detectedFirmware.PaletteOffset + 44] = _logoBackground.B;

                ReportStatus("ok\r\n");
            }

            if (_logoForeground != Color.Empty)
            {
                ReportStatus("Patching logo foreground color... ");

                firmware[detectedFirmware.PaletteOffset + 12] = _logoForeground.R;
                firmware[detectedFirmware.PaletteOffset + 13] = _logoForeground.G;
                firmware[detectedFirmware.PaletteOffset + 14] = _logoForeground.B;

                ReportStatus("ok\r\n");
            }

            if ((_logoBackground != Color.Empty) || (_logoForeground != Color.Empty))
            {
                result = WritePatchedSector(firmware, detectedFirmware.PaletteOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            if (_displayBackground != Color.Empty)
            {
                ReportStatus("Patching display background color... ");

                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x1D] = 0x7D; // MOV R5
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x1E] = _displayBackground.R;
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x1F] = 0x00; // NOP

                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x23] = 0x7D; // MOV R5
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x24] = _displayBackground.G;
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x25] = 0x00; // NOP

                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x29] = 0x7D; // MOV R5
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x2A] = _displayBackground.B;
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x2B] = 0x00; // NOP
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x2C] = 0x00; // NOP
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x2D] = 0x00; // NOP

                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x3C] = 0x00; // NOP
                firmware[detectedFirmware.AdjustBackgroundColorOffset + 0x3D] = 0x00; // NOP

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.AdjustBackgroundColorOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            if (_removeHdmi)
            {
                ReportStatus("Removing \"HDMI\" pop-up... ");

                firmware[detectedFirmware.ShowNoteOffset] = 0x22; // RET

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.ShowNoteOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }
            else
            {
                ReportStatus("Enabling \"HDMI\" pop-up... ");

                firmware[detectedFirmware.ShowNoteOffset] = 0xE4; // CLR A

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.ShowNoteOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            if (!string.IsNullOrEmpty(_replaceHdmi))
            {
                ReportStatus($"Replacing \"HDMI\" pop-up with \"{_replaceHdmi}\"... ");

                int offset = 0;

                foreach (char chr in _replaceHdmi)
                {
                    byte[] bytes = _osdCharacters[chr];

                    foreach (byte b in bytes)
                    {
                        firmware[detectedFirmware.HdmiStringOffset + offset] = b;
                        offset++;
                    }
                }

                firmware[detectedFirmware.HdmiStringOffset + offset] = 0x00;

                ReportStatus("ok\r\n");

                result = WritePatchedSector(firmware, detectedFirmware.HdmiStringOffset);

                if (result != RTD266x.Result.Ok)
                {
                    e.Result = result;
                    return;
                }
            }

            ReportStatus("Finished! Now reboot the display and enjoy your new firmware :)\r\n");

            e.Result = RTD266x.Result.Ok;
        }
Example #12
0
 public ReadWorker(RTD266x rtd, int address, int length, bool updateConsole) : base(rtd)
 {
     _address       = address;
     _length        = length;
     _updateConsole = updateConsole;
 }
Example #13
0
        protected RTD266x.Result Write(int address, byte[] data, bool updateConsole)
        {
            int         offset  = 0;
            List <byte> segment = new List <byte>();

            RTD266x.Result result;

            while (data.Length - offset > 0)
            {
                if (address % RTD266x.SectorSize == 0)
                {
                    if (updateConsole)
                    {
                        ReportStatus($"Erasing sector at address {address}... ");
                    }

                    result = _rtd.EraseSector(address);

                    if (result == RTD266x.Result.Ok)
                    {
                        if (updateConsole)
                        {
                            ReportStatus("done\r\n");
                        }
                    }
                    else
                    {
                        if (updateConsole)
                        {
                            ReportStatus(RTD266x.ResultToString(result) + "\r\n");
                        }

                        return(result);
                    }
                }

                int length;

                if (data.Length - offset >= RTD266x.MaxSegmentSize)
                {
                    length = RTD266x.MaxSegmentSize;
                }
                else
                {
                    length = data.Length - offset;
                }

                if (updateConsole)
                {
                    ReportStatus($"Writing {length} bytes to address {address}... ");
                }

                segment.Clear();

                for (int i = 0; i < length; i++)
                {
                    segment.Add(data[offset + i]);
                }

                result = _rtd.WriteData(segment.ToArray(), address);

                offset  += length;
                address += length;

                if (result == RTD266x.Result.Ok)
                {
                    if (updateConsole)
                    {
                        ReportStatus($"done ({offset * 100 / data.Length} %)\r\n");
                    }
                }
                else
                {
                    if (updateConsole)
                    {
                        ReportStatus(RTD266x.ResultToString(result) + "\r\n");
                    }

                    return(result);
                }
            }

            return(RTD266x.Result.Ok);
        }
Example #14
0
 public WriteWorker(RTD266x rtd, int address, byte[] data, bool updateConsole) : base(rtd)
 {
     _address       = address;
     _data          = data;
     _updateConsole = updateConsole;
 }