Reading firmware out of a mask ROM microcontroller - Page 1
Forum section: electronics / general

author: canadaboy25
author_rank: Regular Contributor
timestamp: January 29, 2021, 09:31:29 pm
content: Hey everyone,I have a Renesas M306H5MC microcontroller on a logic board for a Hitachi plasma TV I am working on. The microcontroller only seems to control a few functions but is not outputting an enable signal when I feel it should be. I was hoping to dump the firmware and take a look at it since the datasheet is available and I should be able to decode some of the instructions. However, this is a mask ROM chip which I've read is not able to be dumped.The microcontroller has different modes that are set by the state of the CNVss pin. The snippet I have attached from the datasheet says that the ROM is unable to be read out if the CNVss pin is high on reset. This seems to imply to me that it should be possible to read out the ROM if the CNVss pin is low on reset.Is it actually possible to dump the firmware from this chip or is the manual just referring to the chip being able to access its own ROM?

author: T3sl4co1l
author_rank: Super Contributor
timestamp: January 29, 2021, 10:35:41 pm
content: A few options:0. Semiconductors rarely fail on their own. It's probably not the issue, something else is.0a. But yeah, if something caused it to fail (surge, ESD, crossed wiring, etc.), it can be toast. In which case both the underlying cause, and the chip, need to be replaced. Find a replacement board and, well, replace the board, no need to transfer just the chip at that point, huh?..1. Sometimes, firmware functions include limited inspection or debugging or modification (code execution) operations. You'll have to poke extensively at the chip. A logic analyzer and generator -- often an FPGA or MCU board -- can be used to fuzz the inputs, and discover potentially useful internal state.The actual hacking process is lengthy, requires careful observation and insight, and commitment -- likely, millions of input combinations will fail before finding interesting ones.Once you find a foot in the door, you can leverage memory data or pointers to modify or read out some things. For example, writes to the stack (assuming it's not a dedicated hardware stack) can be used to generate arbitrary return jumps (ROP, return oriented programming). Blindly discovering function pointers in this way, isn't very attractive (probably it'll lead to a lot of crashes, hangups or resets -- automatic power cycling is often a necessary part of the setup..), but it's at least... plausible. Eventually, you can build up a kit of "gadgets" that seem to do useful things without disturbing overall state (crashing), and potentially read out the program memory for complete disassembly.Also, this assumes the chip is okay, or a replacement can be found.1a. Even if its exact functions cannot be read out, in the process you may simply end up measuring the totality of its external function -- as a black box. In which case you can simply write your own state machine and drop in any new MCU that is capable (via pin converter PCB, most likely).2. Especially if it's dead-dead -- you can decap it and read it out directly. Decapping typically isn't hard: the risky way is to simply heat the chip until its plastic softens (something like 300-400°C), and gently twisting it so that the plastic peels away from the die,without bending the die. Typically the die is soldered or epoxied to a metal tab, and it can be gently pried or slid out of the remaining package. See:https://youtu.be/ZQeHHYJYWXoYou do, of course, need a microscope to image the ROM. If it truly is the mask ROM version, it should be pretty obvious, given adequate magnification. Downside: if it happens to be a fine-pitch device, it might end up needing an electron microscope instead...The safer method is boiling in acid, dissolving the plastic chemically. This requires some dangerous materials not usually available to the public -- fortunately there are more than a few people, so equipped, on the internet, who can perform this service for a modest fee or donation (sometimes just the die itself, I think?).And if an electron microscope is still required, all hope is not lost; there are commercial decapping and inspection services, of course the bill goes up considerably at this point; but if you were concerned about sheer possibility over economics, yes, it certainly is......But more available perhaps, there are a few netizens also with such microscopes, who you might be able to schmooze some machine time with. Or probably more local, many universities are so equipped -- ask around, faculty are happy to respond and may be able to offer you some time on their machine, school year allowing. Typical uses include, well, the same exact thing, micro-fabrication; as well as geology, metallurgy, chemical analysis, physics... So, just because a university doesn't have a specialty like IC fabrication, doesn't mean they won't have one.Tim

author: canadaboy25
author_rank: Regular Contributor
timestamp: January 30, 2021, 03:18:47 am
content: Thanks for the in depth response!Sorry, I should've been more clear in my original post. I don't think the microcontroller itself is faulty. Like you said, it is unlikely for them to just die for no reason. I think it is most likely seeing something on one of its other inputs that it does not like and is not sending out my enable signal. If I were able to dissasemble some of the code and see what the requirements were to enable that signal, it would point me in the right direction.I just also found out that the micro has a rs232 port directly connected to it for service of the TV. I hooked up a serial cable and terminal program but there is no activity from it at any time. Perhaps I need to enable some special mode for it to become active?And yes I saw some articles about decapping a chip and reading the ROM manually. Even though this is a last resort and I could probably get access to a microscope, I do not think it is an option as there are no replacement chips available even if I was able to get the ROM and at that point it would be dead.Any ideas on how to get the rs232 serial port to do anything?

author: T3sl4co1l
author_rank: Super Contributor
timestamp: January 30, 2021, 03:40:35 am
content: Ooh, nice. Could be that it needs an enable pin, probably a nearby testpoint or connector; maybe more likely, it only responds to properly formed requests, in which case you need to guess baud rate first, and then message format if any? Any hints you can find from nearby stuff (crystal? other onboard comm channels?) or service tools (find a manual? sometimes the actual service program itself is floating around?) would greatly speed that up.Also, literal RS-232, or just async serial (logic level)? Seems like the former would be unlikely for just a service port. (It matters: logic level is inverted!)Tim

author: canadaboy25
author_rank: Regular Contributor
timestamp: January 30, 2021, 04:26:32 am
content: This TV is a Hitachi P42H4011. The service manual for a Hitachi L37X01E plasma has the entire schematic for the main board in it. It seems the same main board was used for both TVs.It appears to be a proper RS232 port as it has a dedicated driver chip interfacing the port with the micro.Also, I somehow managed to miss the fact there is a 3.5mm audio jack right beside the RS232 jack. It is labelled "Service use only" on the back panel of the TV. This obviously has something to do with it. I will take a look in the schematic for the other TV and see if it has the same jack.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: January 30, 2021, 04:32:44 am
content: Neat, most likely real 232 then. Should be measuring something like -3 to -12V from TX at line-idle?Hah, y'know, serial has been put into those jacks before. I have... no idea if anyone's used that since the 70s or 80s, but, three wires is all you need...I don't know anything about Hitachi TVs, but if you can find service info for any of them, it may be it's compatible. Would be a shame to have a service tool specific to one model or line, eh?(I have however done this with the Trinitron monitor I used to have; but in that case, Sony's service program is available on the internets. Easy.)Tim

author: canadaboy25
author_rank: Regular Contributor
timestamp: January 30, 2021, 04:44:52 am
content: After a bit more poking it seems the audio connector is likely not related to the RS232 port as there is an audio jack labelled IR_out on the schematic.Yes, the TX line is steady at -10 volts and the RX line is steady at +10 volts. There is no activity on the port looking at it with a scope.

author: canadaboy25
author_rank: Regular Contributor
timestamp: January 30, 2021, 05:01:25 am
content: After you mentioned the software being avaialable for some devices, I did a quick search and found a pdf detailing the communication protocol.It seems the port is just used as a remote control pretty much. Adjusting things like volume and picture settings.In the pdf it shows 4 different options for cables to use for connecting to it. I'm not sure which one is for what.

author: amyk
author_rank: Super Contributor
timestamp: January 30, 2021, 05:31:08 am
content: That MCU looks very similar to some of the early Motorola ones in basic architecture --- and if they are indeed taking inspiration from those, then one or more of the "do not use" modes are actually test modes that let you read out the memory contents.

author: canadaboy25
author_rank: Regular Contributor
timestamp: January 30, 2021, 05:46:16 am
content: Quote from: amyk on January 30, 2021, 05:31:08 amAre you referring to the modes that I referenced in the original post?

author: amyk
author_rank: Super Contributor
timestamp: January 31, 2021, 02:37:23 am
content: Yes. The HCS11/12 which was used in many automotive ECUs works that way.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 01, 2021, 04:27:34 pm
content: Looking around through the schematic I found another interesting interface.There is a 3 wire synchronous I/O interface connected directly to the microcontroller. It is labelled as flash/Jig and goes to an unused external connector which I would imagine is for factory use. The CNVss pin for setting the processor mode is also connected to this interface along with a reset line.This seems like a much better target for gaining access to the internal memory.Any tips on where to start with this?

author: Kerlin
author_rank: Regular Contributor
timestamp: February 02, 2021, 10:27:02 pm
content: I have a friend who says he was able to successfully read code out of a locked micro.He told me that to allow or disallow access to the ROM the micro has to run its own internal instruction set micro code.He found if the clock speed is run lower than the recommended speed the micro cannot run its micro code to block ROM access and he says he was able to get it.To me this sounded a bit far fetched but he made good money cloning the device, so good he ended up in court, and was in the newspaper, so seems it did work.

author: tru
author_rank: Regular Contributor
timestamp: February 03, 2021, 03:27:22 am
content: The MCU belongs to M16C/60 series group.Where did you get the usage mode from?Anyway doesn't matter, the masked ROM can be read-out by putting it into special programming boot mode. This makes the MCU run the special built-in boot loader program so you can send commands to it from a computer via RS232.Cool, the flash jig seems to have all necessary pinouts, except perhaps for pin M1 (pin 36), but perhaps that doesn't matter, i.e. not needed for the masked ROM version.I have successfully read out FLASH from a different MCU of the same series group (M16C/60):M30624FGPGPYou will need a RS232 TTL converter, if you have Windows 10 I recommend getting a cheap ebay USB TTL one that I use, example:https://www.ebay.co.uk/itm/310931472288I attach picture of the standard Renesas programming boot mode wiring circuit.Note, though the boot loader's function is protected by a password (Renesas calls this an ID), but usually most companies leave it as default, which is all 0x00 or all 0xFF.You will also need my M16C/60 reader/flasher program (Windows console application) to communicate with it, because the official FlashStart program seems to be buggy.I will try to upload it to github or somewhere. Alternatively there is a German reader/flasher program that should work, but it cannot read some areas (user block A) on some MCUs (mine can read all areas):https://m16c.mikrokopter.de/M16C-Flasher.19.0.htmlSet the baud rate to:9600, 8 bits data, no parity, 1 stop bit

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 03, 2021, 05:00:35 am
content: Quote from: tru on February 03, 2021, 03:27:22 amWow that is great news! Thanks for all the info!I got all of my information from the datasheet for the micro and the service manual for a Hitachi P50T01E.According to the schematic, the M1 and CNVSS pins are pulled low through pulldown resistors. Pin 53 is already pulled high through a pullup resistor. So I will just have to set the CNVSS pin high according to your schematic.I have a usb to TTL converter already so I will try to rig it up and see what I can do with the German reader.It would be awesome if I could get a link to yours so I could read all of the data.Thanks again.

author: tru
author_rank: Regular Contributor
timestamp: February 03, 2021, 02:40:30 pm
content: Quote from: canadaboy25 on February 03, 2021, 05:00:35 amHmm, according to the official Renesas datasheet this MCU doesn't have the user block A, so the German program is all you need. The M306H5MC datasheet can be downloaded here:https://media.digikey.com/pdf/Data%20Sheets/Renesas/M306H5.pdfThe usage notes I think only applies when running in normal mode, it doesn't apply to the special programming bootloader mode.Caution: don't press the Erase or Prog (program), even though your chip is masked ROM I think those functions can damage the data.If you look at the memory map shown in the datasheet, the M306H5MC contains only 128K byte ROM:so use read address range: 0x0E0000 to 0x0FFFFFMy application is here:https://github.com/truhy/m16c-flasherTry issuing the version command - this is not password protected so it must return an ASCII string if the circuit is wired up correctly and the bootloader wasn't erased (I doubt anyone would go to extreme by erasing the bootloader).If the default passwords (all 0x00 or 0xFF) doesn't unlock the read command then there is actually a hack to determine the password:https://hackaday.io/project/723-reverse-engineering-toshiba-r100-bios

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 04, 2021, 03:38:54 am
content: Well I am unable to get the microcontroller to respond at all.I wired up some mod wires to the header and connected everything up. I was not getting any response and the German software kept failing to connect. I took a look at the reset line with my scope and whenever I pulled CNVSS high, the reset line would continually pulse. Looking at the schematic, I found there is a separate watchdog timer chip that can also reset the microcontroller. The watchdog chip has an inhibit pin that is exposed on the service header so I added a wire to that too. If I pull the inhibit pin high to disable the watchdog, I no longer get any pulsing on the reset line.Even doing that I still get no activity on the TX line of the microcontroller. I can see the data on the RX line of the micro, but it never responds to any messages. Not sure what else to do at this point. I know all my connections are good as I can see the signals at the traces on the board.

author: amyk
author_rank: Super Contributor
timestamp: February 04, 2021, 04:28:44 am
content: Quote from: Kerlin on February 02, 2021, 10:27:02 pmYes it does - it's called clock/power glitching and usually works better on MCUs with a bootloader.https://hackaday.com/2020/07/04/the-cheap-way-to-glitch-an-stm8-microcontroller/There are of course services for doing this in China (search for "MCU break") but they are likely too expensive for a one-off like this --- unless whatever you're trying to repair is also equally rare and expensive.

author: tru
author_rank: Regular Contributor
timestamp: February 04, 2021, 06:25:57 am
content: Quote from: canadaboy25 on February 04, 2021, 03:38:54 amThe reset line should remain high because it is an active low reset. The controller I read from also has a reset watchdog chip, Sipex SP705, I left the reset line untouched.With my setup I have:1. the ground of USB TTL connected to ground of the controller board, hmm there is no ground pin on the flash jig connector - perhaps this doesn't matter,2. I have the CNVSS pin connected permanently to VCC (+5V, LM7805 on the PCB controller board) so it is pulled high before powering up the controller, hmm there is no VCC output pin on the flash jig connector3. I have the SCLK connected to ground

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 04, 2021, 06:40:18 am
content: Quote from: tru on February 04, 2021, 06:25:57 amYes, I am leaving the reset line high and only grounding when I need to reset the micro. The problem was that the watchdog chip monitors a clock signal that the micro outputs. However, when I pulled the CNVSS pin high on the micro, it stopped outputting the watchdog clock which caused the watchdog to continually reset the microcontroller. I have attached the page of the schematic showing the micro and watchdog circuit. The watchdog is to the lower left of the micro.My connections are as follows:GND of my USB to TTL converter is connected to ground of the main boardRx of my TTL converter is connected to the micro's Tx pinTx of my TTL converter is connected to the micro's Rx pinCNVSS of the micro is pulled to +5VThe reset line is left high unless I pull it low momentarily to reset the chipThe watchdog inhibit line is held high to prevent it constantly resetting the micro.Is there the possibility that there is no bootloader since it is a mask ROM chip? Wouldn't the bootloader have to be a part of the ROM mask itself?

author: tru
author_rank: Regular Contributor
timestamp: February 04, 2021, 06:53:16 am
content: Quote from: canadaboy25 on February 04, 2021, 06:40:18 amLooks good, and the S_SCLK on the flash/jig connector, did you connect that to ground?The bootloader is flashed in by Renesas manufacturer, so no, it is pre-flashed and can only be erased by their special parallel programmer, but perhaps you have a good point, maybe masked ROM version doesn't have the built-in bootloader, not sure.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 04, 2021, 07:00:14 am
content: Quote from: tru on February 04, 2021, 06:53:16 amI have not done anything with the S_SCLK pin. It is listed as an output in the schematic so I didn't want to pull it to ground if the micro was trying to pull it high. However, the flash/jig header has a resistor between it and the MCU so I suppose I could pull it low without risking damage to the chip.Would it matter what state the S_SCLK pin is at if it is listed as an output of the micro? Or does the pin become an input when the micro is in bootloader mode?

author: tru
author_rank: Regular Contributor
timestamp: February 04, 2021, 07:06:45 am
content: Quote from: canadaboy25 on February 04, 2021, 07:00:14 amIs S_SCLK pin, pin 40 of the Renesas MCU? If yes, it is a bidirectional pin, and yes on my MCU the SCLK must be pulled low for it to go into bootloader mode.Just something else unrelated, I noticed the schematic shows M306H5FGFP - this is a flash memory version (256kB), I guess they've changed it on the actual PCB to a masked ROM version?

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 04, 2021, 07:12:48 am
content: Quote from: tru on February 04, 2021, 07:06:45 amOh very interesting. Yes it is pin 40. I will have to give it a try with pin 40 pulled low. It is currently held high with a pullup resistor.And yes, I noticed it has the wrong number on the micro as well. They must've switched it to a mask ROM chip for production. The actual chip on my board is in fact a mask ROM chip.

author: tru
author_rank: Regular Contributor
timestamp: February 04, 2021, 08:07:33 am
content: Quote from: canadaboy25 on February 04, 2021, 07:00:14 amJust some thoughts on the S_CLK line because you mentioned it was listed as an output, the MCU can operate in 2 serial modes:Mode 1: clock synchronous mode (not compatible with RS232), where there is a serial common clock with MCU and the programmer. Depending on the registers the clock can be supplied by the MCU or an input clock.Mode 2: clock asynchronous mode (UART RS232 TTL mode), serial common clock is not used, pull the SCLK1 lowIf Hitachi is using mode 1 then that line will pulse, perhaps a good idea to check that. If it pulses then there is a circuit on the PCB that is generating a serial clock, and as you said risky to pull it low.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 04, 2021, 09:47:18 am
content: I connected everything up and probed the SCLK pin. I found something that I had missed before. On reset of the microcontroller, the SCLK pin is high and gets pulled low by the MCU shortly after. This happens regardless of whether the CNVSS pin is high or low. There is no activity on the SCLK pin after the initial change of state.I tried grounding the SCLK pin and resetting the micro in case the pulse on reset was a detection pulse, but no change. Still no response from the micro when trying to connect to it with the software.Another interesting observation is that when the CNVSS pin is pulled high, the blue light on the front of the TV is on. Without the CNVSS pin pulled high I could only ever get a red standby light. When resetting the micro with the reset line, the blue LED goes out and then comes back on. These LEDs are controlled directly by the micro so it is obviously changing modes when the CNVSS pin is pulled high.Since the micro is pulling the SCLK line low, I would think this means it is not expecting a clock for synchronous communication as there would be two sources driving the same line. I feel like I`m close as the micro is changing modes but I must still be missing something.I assume I should be using the M16Cxx option in the software and not the M16C80/M32C option?EDIT: Looking through the pdf included in your github files that shows the connections for the programmer, it says P5_5(EPM) should be low. According to the MCU datasheet this is pin 48 and according to the schematic for the TV, it is an input which is pulled high by a pullup resistor. The line also runs to an unpopulated transistor for a fan failure alarm. Perhaps this pin needs to be pulled low as well? It just seems strange that Hitachi has included all of the other pins on the service connector but not this one. If this seems important I will pull the board out and solder a wire to the MCU and try pulling it low.

author: tru
author_rank: Regular Contributor
timestamp: February 04, 2021, 10:43:08 am
content: Interesting.The P5_5(EPM) doesn't apply to your MCU because there is no EPM multiplexed on Port 5-5.Most likely the equivalent to that is M1 which is pin 36, but you mentioned that it is already pulled low on the PCB.Yes, the M16Cxx option is correct, which works for the MCU I read from (M30624FGPGP).Perhaps this isn't your problem, but I did noticed that sometimes after powering the controller on and issuing the Get version command, sometimes it doesn't work, no response from the micro. I have to retry by power it off and on a few times.

author: tru
author_rank: Regular Contributor
timestamp: February 04, 2021, 10:49:39 am
content: Perhaps I've missed something and you have better luck, have a look at:in the M306H5.pdf datasheet:see page 302:Figure 4.3.6. Pin Connections for Serial I/O ModeAlso, the following pages shows example serial circuits for serial mode 1 and mode 2.see page 279:Boot rom area (containing the bootloader), it mentions about CNVSS, P5_0 and M1.Although it didn't work for me, try the official FlashStart program, a compiled version can be found in the Release folder:https://drive.google.com/file/d/1cEjUK_z3p0rtq663KCi4mHj0KYs0C_Vf/view?usp=sharing

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 04, 2021, 07:01:02 pm
content: Quote from: tru on February 04, 2021, 10:49:39 amI took a look at the pages you indicated and it would seem that I have everything configured the way that they specify for the type 2 asynchronous communication. I do not think it could be trying to use the synchronous mode 1 as the datasheet shows a pullup resistor on the SCLK input pin but my MCU is pulling that low. So there would be no way to input a clock even if I wanted to. The other thing that worries me is all of that information is in the flash ROM section of the datasheet. Perhaps that means it does not apply to the mask ROM version. After all, what is the use of a flash read/write interface on a chip that does not have a rewritable ROM? Perhaps the serial interface on the flash/jig header is just a hangover from the development of the board when they were using a flash ROM version.You mentioned a problem with the timing of the flash program on newer computers. I have an old Pentium III system I could load Windows 2000 up on to try the original Flash Start program if you think that would be something worth trying. I also could try a computer with a physical RS232 port and use some transistors to make a logic level shifter in case my USB to TTL converter is not interpreting the commands properly. However, I don't think this is likely as I have used the converter for other projects and it has worked fine. I can also see the data being sent to the MCU from the converter with my scope.The other thing I could possibly try is removing the MCU from the board and just putting it on a temporary board with voltage supply and the crystal oscillator. I wonder if the main board of the TV is interfering with an output of the micro if it is in flash mode. Since the blue LED lights up when the CNVSS pin is high, the MCU must be setting some of its outputs high when it normally wouldn't. Perhaps it is setting a pin to an output that is fighting with something else on the board and causing it to lock up?The other thing that is in the back of my mind is the page of the datasheet that I attached in my original post. "In the mask ROM version, contents of internal ROM cannot be read out when reseting the CNVSS pin with "H" input." This definitely suggests it should be possible to read the contents of the mask ROM, however, they say the ROM cannot be read with the CNVSS pin high which contradicts everything else we have been doing. This seems strange to me.Let me know what you think.Thanks for all the help so far!

author: tru
author_rank: Regular Contributor
timestamp: February 04, 2021, 08:11:41 pm
content: Quote from: canadaboy25 on February 04, 2021, 07:01:02 pmThe timing problem only happens for a few tries (quite rare), it generally works most of the time, I don't think an old system will help. I think your point about the flash/jig being left over from when they used the flash version of the chip sounds about right.The section about not being about to read out internal ROM is referring to the Microprocessor mode (function as CPU with no internal ROM or RAM, i.e. the addresses are remapped to external bus) vs Single processor mode (MCU mode with ROM and RAM, not remapped)Man, they have a round about way of describing things, the title gives some evidence of my reasoning: Precautions for External Bus = Precautions for Microprocessor modeAlso further evidence is in the text:"...In the flash memory version, contents of internal ROM cannot be read out when resetting the CNVSS pin and the M1 pin with "H" input", which refers to flash version set to microprocessor mode, and obviously in that mode it cannot read out ROM or RAM since the addresses are remapped to external bus.I've just noticed something in the datasheet (page 11, Table 1.5.3 Pin Description), it says for mask ROM version, connect M1 pin to VSS or VDD2, that suggests M1 is ignored, so perhaps cannot be put into bootloader mode anyway?

author: bson
author_rank: Unknown
timestamp: February 04, 2021, 08:56:59 pm
content: Check the 9-pin D sub interfaces/inputs/drivers. Those connectors were (are?) used for proprietary remote control in mid/high end AV equipment, so say a Toshiba AV receiver could turn on/off the TV, or other basic control. The TV might think there's something plugged in and that it's under remote control if something on the interface isn't working right. It may or may not be an actual RS-232 port, and if it's not while someone applied actual RS-232 signalling to it, well that could explain why it's dead if that's the problem.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 04, 2021, 10:43:19 pm
content: Quote from: tru on February 04, 2021, 08:11:41 pmYeah, this datasheet is definitely not the clearest one I have seen before. They talk about different modes and pins but do not give a concrete description of what they are or how they work.It is definitely looking like this chip does not have the serial bootloader interface built in. I have probed the MCU's Tx pin with my scope while sending it commands from the software and never received any activity from it at all. It would make sense that they wouldn't include the bootloader in the mask ROM version as they would never be able to modify anything anyways, and by the time they were producing the mask ROM, they likely would've had everything the way they wanted it for production.Sort of a shame because I had the Rensas documents with all of the machine codes for this MCU ready to decode the firmware if I could get it out.The enable signal I am missing is generated by an Altera CPLD. The power button on the TV connects directly to the Renesas MCU. So the MCU has to send some sort of signal out to the CPLD for it to activate the other PSU enable line. The only communication lines the MCU has with the rest of the system is one UART interface and a "SlowBus" interface, whatever that is. I would think the MCU is seeing something it doesn't like as it never turns on the blue power LED when the power button is pressed. I have no idea what a "SlowBus" interface is so that one would likely be tricky to analyze.I'm not sure what half of the connections to the MCU are even for. A lot of them seem to lead to unpopulated connectors on the PCB which I suppose may have been for different models. I don't think the MCU is damaged as it still does perform some functions such as outputting the watchdog clock when the CNVSS pin is lowQuote from: bson on February 04, 2021, 08:56:59 pmI wondered that as well. It is a proper RS-232 port as it has a dedicated driver chip and I found the protocol description in a pdf I posted previously. However, it doesn't seem like there is any way for the MCU to detect something being plugged in as there is only the 4 UART signal lines going to the driver chip. I also think I read somewhere that the TV will revert back to the standard operation mode after power is removed.

author: tru
author_rank: Regular Contributor
timestamp: February 05, 2021, 12:06:34 pm
content: Ouch, I've made a few mistakes regarding the Microprocessor mode.I'm not sure if this is worth doing or looking into, but perhaps when bored and with lots of free time...Correction: The Microprocessor mode doesn't remap RAM or registers, it only remaps the internal ROM/FLASH address range, and also enables the reserved address range.You made me go and look into the Renesas bootloader disassembly code again. Good news, it appears that boot mode (bootloader mode) is really just Microprocessor mode + the EPM or M1 pin (in your case) is simply used to switch (bank) in the boot rom area (containing the bootloader), the bootloader code is then in the same memory address as the internal ROM so it can run. As a further protection, Renesas prevents the processor mode from being changed when code is run in this address range, but it copies itself into RAM and jumps execution to RAM address 0x600 which is then able to switch processor mode.The bootloader disassembly shows that it does indeed rewrite the PM0 and PM1 (processor mode select registers) back into Single processor mode!! There also appears some secret code stuff in there, modifying reserved address.It sounds possible that we can wire up the MCU for Microprocessor mode, i.e. pins: D0 to D15 (16 bits data bus), and pins: A0 to A19 (address bus), and connect to a suitable parallel FLASH memory chip with the bootloader stored on it! Hopefully it should run the same way as boot mode.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 05, 2021, 10:37:29 pm
content: That sounds promising! In microprocessor mode with an external memory we can make it load up whatever code we want it to. The function of it copying code to RAM and executing from address 0x600 is definitely an interesting behavior.Sounds like it would take a lot of tinkering, but I am up for the challenge. I am much too interested about what is in the ROM to let it keep its secrets without a fight.Since we would have to wire up the data and address buses, it seems like I will have to remove the chip from the board and make a test board to mount it on. Otherwise, I would have to remove a bunch of the Hitachi logic board components to free up all of those pins. Seems like a good move though as it will remove any unknowns from the test setup because there won't be anything else connected that could possibly interfere with the chip.I have a CNC mill and blank PCB material so I would be able to quite easily make up a test board to mount the chip on and be able to hook up anything else we wanted to it. I'm sure I have a flash chip on some junk board somewhere that would work for the project as the ROM on my chip is only 128K.I also have an Altera DE2-115 FPGA development board that we could use to implement a flash chip and any other functions we may need. The FPGA board has a header with exactly 36 GPIO pins on it so we could just hook the data and address buses from the MCU directly to it. Perhaps this could be easier than reading and writing flash chips.If I were to leave the chip on the board, I would have to remove 6 transistors, and 9 resistors and then run 36 mod wires to an external mod board. I am not sure which will be less work. I definitely like the idea of putting the MCU on a custom made testing board as it would provide the best connections and remove the rest of the logic board circuitry from the equation, but I am slightly worried about overheating of the chip while removing it just because it is pretty large.Let me know what your thoughts are. Definitely looking forward to the challenge though!

author: tru
author_rank: Regular Contributor
timestamp: February 06, 2021, 12:35:08 am
content: Cool!I have the same thoughts! Yep, removing such a big chip is risky but I think that may give less problems than modifying the existing PCB. I do have a controller with a broken display that has Renesas M30624FGPGP on it that I can try this on (doesn't matter if I break it), but I don't have any FLASH chip on hand at the moment, nor do I have any experience on building such a circuit with external FLASH memory + MCU and because it would need the minimum supporting stuff like oscillator, capacitors, etc.For anyone interested in the reverse engineering, I attach link of the bootloader V4.04 that I extracted from the M30624FGPGP:https://drive.google.com/file/d/1vXizFkau_73ImZyE0IEJnIaVDyKl-Id-/view?usp=sharingThe .asm file is the interesting file and I've partly commented the good parts. I'm too lazy to go through every line of code in there.The other 2 files are the raw dumps: .mot (motorola srecord format) and .bin (binary format).

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 06, 2021, 02:09:59 am
content: Yeah it is a tough call. Looking through the schematic it seems possible to isolate every line of the MCU from the rest of the system except for the Vcc and GND pins as they are hardwired on the PCB with no series resistors. I can even isolate the MCU's power rail from the rest of the system by removing a 0 ohm link to prevent the rest of the board from being powered.I will go through the schematic and map out all of the pins that are connected to Vcc and GND and see if they are going to be a problem for what we want to do. If they won't cause a problem I will probably go with the option of removing all the series resistors and adding mod wires to break out the MCU pins to a header PCB. I have a large spool of 38AWG enamel coated magnet wire which works really good for that sort of thing. This seems like the safest option as I would never stop kicking myself if I killed the chip while removing it. And even if I removed it successfully, it would have to be soldered down to my custom PCB, removed again, and then resoldered to the original board. That is a lot of heat/cool cycles for this old thing. Leaving it on the original board also lets us take advantage of the support circuitry that is already present such as the oscillator and some capacitors.I will also have a dig though some of my junk to see what flash chips I have around. When reading though the Renesas datasheet I realized my FPGA board does not have enough pins for all 36 bus data lines and the required control signals. So perhaps I will have to make up a little board to solder a flash chip to.I will also spend some time looking through the bootloader you uploaded. Very interesting stuff!

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 06, 2021, 09:58:13 pm
content: After going through the schematic, it looks like all of the I/O pins should be able to be isolated from the logic board without removing the chip itself.I've been reading through the datasheet for the Renesas MCU but I can't seem to find where it shows the reset vector. I see in your disassembly file that you have 0xFF020 listed as the reset vector. How did you determine that was the reset vector? Did you find it listed somewhere or did you determine that from the code?I am trying to understand how we can know where the MCU will start executing code from in the flash memory if we are using microprocessor mode. Also, since the address and data buses can operate in multiplexed or separate bus mode, how do you know which one will be used when the MCU resets in microprocessor mode?Perhaps I am missing it in the datasheet, but I have not seen it anywhere.

author: tru
author_rank: Regular Contributor
timestamp: February 06, 2021, 11:28:39 pm
content: Quote from: canadaboy25 on February 06, 2021, 09:58:13 pmYou're right the reset vector address is not fixed, and is determined from a fixed location, and in this case at the end of the code, see page 62, Table 2.7.1. Fixed Vector Tables.The reset vector address is stored as the low 20 bits at addresses 0x0FFFFC to 0x0FFFFF (low byte ordering), if you open the .bin file and go to the end you will see the last hex values are:20 F0 0F FF, reversed byte ordering gives:FF 0F F0 20, and the low 20 bits gives:0F F0 20The BYTE pin sets the external bus width:low for 16 bit data bushigh for 8 bit data busSingle chip works only in 16 bit data bus so best we pull it lowI'm not sure about the multiplexing, hmm still looking at the datasheet.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 06, 2021, 11:42:52 pm
content: Quote from: tru on February 06, 2021, 11:28:39 pmAhh, that's how it works. Makes sense! I figured it had to be something like that but couldn't quite see it.I think I may have found something about the multiplexed bus. On page 24 it shows the Processor Mode 0 (PM0) register. It shows the reset values for the register if the CNVSS pin is high or low. In both cases the 5th and 6th bits are 0 which means the bus is in separate bus mode.I'm just not sure how the bus would be changed to multiplexed bus mode as you would have to modify the bits in the control register but to do that you would have to run some code from flash.

author: tru
author_rank: Regular Contributor
timestamp: February 06, 2021, 11:50:23 pm
content: Ah, I see so is set by software, I was looking at the pins!You're right, since the reset values is separate bus we can just leave as is, so the data bus is separate from the address bus, which is easier to work with I think.Yes to change it to multiplex bus you would set them inside your code.

author: tru
author_rank: Regular Contributor
timestamp: February 06, 2021, 11:52:41 pm
content: Ops, I see what you mean, if you need to run code to set them for multiplex mode, your circuit needs to start from separate bus mode, that's crazy!

author: tru
author_rank: Regular Contributor
timestamp: February 07, 2021, 12:06:01 am
content: In the bootloader code, something still puzzles me, near the start there is a loop that checks whether port 8 pin 5 (pin P8-5) is pulled high, nothing is mentioned about that in the documents, or perhaps I've made a mistake and it's not port 8, hmm. I think we will need to disable that anyway.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 07, 2021, 01:00:13 am
content: Quote from: tru on February 06, 2021, 11:52:41 pmYeah, that's what I was wondering about. Definitely doesn't seem like the most efficient setup! Would've thought an external pin to set the bus mode seemed more logical.I was going to get started removing some of the series resistors and running wires to a breakout board. Looking at the physical board, some of the pins are frustratingly close to other pads and vias which will make running wires quite difficult as the bare part of the wire may want to touch these points after soldering. Now I'm back to contemplating removing the entire chip. I have removed and replaced larger chips with the annoying thermal pad underneath without issue. This one should be easier as it has no thermal pad and the PCB pads will have a low thermal mass so it should come off pretty easy.I think I'm just going to try and remove it unless I can think of a better idea.Quote from: tru on February 07, 2021, 12:06:01 amHmm, interesting. The part you have labelled as "doing secret stuff" where it writes to a "do not use" memory address is also very interesting. It seems there are a few hidden features that they do not want people knowing about. Or perhaps it is generic code that was used on different chip families and that is just a leftover that they did not remove or change. Quite strange.

author: tru
author_rank: Regular Contributor
timestamp: February 07, 2021, 01:31:40 am
content: Just discovered that P8_5 is shared with NMI, so the code is actually checking NMI, and this makes sense now. NMI is normally connected to a pull-up resistor.Good point, the secret stuff may be just left over code.

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 10, 2021, 07:56:47 am
content: Quote from: tru on February 07, 2021, 01:31:40 amThat definitely makes sense. P8_5 is connected to a pullup resistor but a CPLD on the board can pull it low to signal an interrupt.I was about to pull the MCU off the board and my hot air station burned out. Quite the timing. While I've been waiting for a new one I've been looking through the bootloader code.It's interesting to see the code on such a low level and notice the places the compiler could have done better optimization. Such as places where two values are compared, then a jump if equal instruction that jumps two lines down, which is followed by a jump instruction to somewhere else in the case of not equal. Instead there could've been a jump if not equal instruction and the second jump could've been omitted. Such as at address 0xFF08C. Unless I'm missing something.Everything has more or less made sense except for one thing. At address 0xFF094, the value at 0x600 is moved to R0L, R0L is moved to address 0x3BE, the value at 0x601 is moved to R0L, R0L is then again moved to address 0x3BE. The first two instructions seem to be redundant as the value at 0x3BE is overwritten without being used. I must be missing something as I can't imagine why those instructions would be there if they aren't serving any purpose. Any idea what's going on there?

author: tru
author_rank: Regular Contributor
timestamp: February 10, 2021, 01:13:02 pm
content: Quote from: canadaboy25 on February 10, 2021, 07:56:47 amYou're right, also a lot of the code is duplicated, first half for synchronous mode 1 and second half with similar code for asynchronous mode 2, and no effort to merge the common parts together.I forgot to link the M16C/60 series group that is relevant for the M30624FGPGP where the bootloader came from:Hardware Manual - contains Special Function Registers (SFR, memory mapped registers), memory map, vector table, pinouts, etc:http://www.symmetron.ru/suppliers/renesas/pdf/rej09b0185_16c62pthm.pdfSoftware Manual = contains MCU machine instructions:https://www.renesas.com/eu/en/document/man/m16c60-m16c20-m16ctiny-series-software-manual?language=enThe destination address 0x03BE is a memory mapped register (SFR), data byte input to the in-built hardware CRC calculator, see page 15 of hardware manual.The bootloader pushes the two values into the CRC calculator which automatically updates a CRC result.Code:FF094 72C00006 MOV.B:G 0600H,R0L ;MOV byte at address (0600h + A0) to R0L register. A0 = 0000h (I didn't see where it is set so is default reset value I guess) this becomes MOV byte at 0600h to R0L registerFF098 03BE03 MOV.B:S R0L,03BEH ;MOV ROL to CRC calculator (03BEh = SFR to CRC data input)FF09B 72C00106 MOV.B:G 0601H,R0L ;MOV byte at address (0601h + A0) to R0L register. A0 = 0000h this becomes MOV byte at 0601h to R0L registerFF09F 03BE03 MOV.B:S R0L,03BEH ;MOV ROL to CRC calculator (03BEh = SFR to CRC data input)Something unrelated, with some instructions there is a size specifier and format type, e.g.:MOV.B:GThe MOV instruction syntax is as follows:MOV.size(:format) src,destYou can see that there is a size specifier and a format type.In the above example:.B = size specifier meaning MOV byte:G = General formatFor more information see the software manual. Specifically see page 52 of software manual, "3.1 Guide to This Chapter".

author: canadaboy25
author_rank: Regular Contributor
timestamp: February 10, 2021, 05:15:23 pm
content: Ah, I completely forgot to check where that address actually lead to. I just assumed it was a RAM address. Thanks for clearing that up.I have the software manual but I didn't have the hardware manual. Looks like lots of interesting stuff in there.Also, in the code snippet you posted, I believe A0 would have the value 0x6FD as there is a jump to subroutine instruction at 0xFF91 which jumps to the block you have labelled as Part 4: Calculate CRC.One more question, what disassembler did you use to generate the assembly?I suppose I should also order some flash chips while I wait for my hot air station.

author: tru
author_rank: Regular Contributor
timestamp: February 10, 2021, 08:12:49 pm
content: I used the official (evaluation version) compiler/debugger called "High-performance Embedded Workshop" (HEW):https://www.renesas.com/us/en/software-tool/evaluation-software-toolsGo down to section:C/C++ Compiler Package for RX Family(for High-performance Embedded Workshop)To download you need to register an account - I registered with some bogus informationThe evaluation version is crippled so that "Save Assembly Text..." can only output a limited length, so if you want to save disassembly out to a file you will have to manually enter start and end address (of limited length) and repeat. Then merge the files together into one. I've already done this with the bootloader, but if you need to do for other code.The debugger requires the SEGGER simulator driver to be installed but doesn't seem to be included, however Microchip MPLAB X v5.30 (not sure about latest version) does include it so if you install that first then install HEW, the debug menu will be available, and you can then step into the disassembly, view addresses, e.g. RAM, etc.To save you fiddling with the IDE I'll upload the HEW project file with the bootloader added to the project.https://drive.google.com/file/d/1XTvn-dG0XC1l06mifZUPhTah52_6QtVq/view?usp=sharingBtw, anyone has a full version of HEW?

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 16, 2021, 05:16:53 am
content: Hi, sorry for the long absence from the project, I've been very busy lately.I have done a bit of work on this since my last post. I have purchased an FPGA board with enough I/O pins to connect up all the bus address and data line signals and also the control lines. I think the FPGA will be the easiest solution since it will be very simple to configure it as a simple flash memory. I did look for dedicated chips, but finding a 5V flash memory with the correct parallel bus sizes and control lines was very difficult. I have also decided to remove the MCU from the board. I am in the process of designing a PCB to mount it on and implement the plan.In the meantime, I got my hands on a broken 60" LED TV. All it does is blink an error code for the backlights. I have tested all the backlight strings and they are all fine. I have also probed the signals coming to the backlight inverter board from the main board and there is nothing at all. So there is no way the main board would even be able to know if the backlights are defective and I suspect there is a problem on the main board.The main board is controlled by a Renesas M16C-R5F364A6N MCU. I figured I may as well try and dump the firmware from it since it is a flash version instead of mask ROM. However, I must be doing something wrong as I cannot connect to this one either.There is a debug header beside the chip that exposes pins 7,29,30,31,32,33,34,39 of the MCU. Pins 29 and 30 are TXD1 and RXD1 while pins 33 and 34 are TXD0 and RXD0. Pin 7 is the CNVSS pin. The datasheet for this MCU is not near as comprehensive as the other one, but I was not able to find any reference to an M1 pin anywhere so I suppose this chip does not have one.I used a logic level converter to connect my 5V UART to USB converter to the MCU since it runs off 3.3V. I pulled CNVSS high, powered on the MCU, and tried both the RX0/TX0 and RX1/TX1 lines but never got any response. Probing the RX line of the MCU I can see a nice clear 3.3V signal getting to the chip, but the chip never transmits anything in response.I must be doing something wrong or missing something since this is a bit different MCU than the last one. I find it strange how little information there is about programming these chips or I am not looking in the right place.Any ideas on what I am missing here?I will post back when I get the other MCU mounted on a PCB breakout board and connected up to the FPGA.

author: tru
author_rank: Regular Contributor
timestamp: April 16, 2021, 09:24:09 am
content: I agree, their documentation is all over the place!That M16C-R5F364A6N MCU doesn't have the M1 pin, instead it uses EPM pin (pin 39) which I guess serves a similar purpose - and that needs connecting to low.Have you also checked the CE (pin 44) is high and the CLK1 (pin 31) is low?These are the details:To enter Single-chip boot (loader) mode in serial I/O asynchronous mode:CNVSS = VCC1 (high) = PIN7P5_5/EPM = VSS (low) = PIN39RESET = VSS to VCC1 (low then high) = PIN10P5_0/CE = VCC2 (high) = PIN44P6_5/CLK1 = VSS (low) = PIN31P6_7/TXD1 = (TTL) serial out = PIN29P6_6/RXD1 = (TTL) serial in = PIN30Power (note: it is best to power on the TV and let itself supply the voltage - no need to inject any power):VSS = groundVCC1 = 3 to 5VVCC2 = 3 to 5V*VCC1 >= VCC2 or simply apply same voltage.Documents can be downloaded from here:https://www.renesas.com/us/en/products/microcontrollers-microprocessors/other-mcus-mpus/m16c-family-mcus-r32c-m32c-m16c/m16c64a-16-bit-microcomputers-non-promotionHardware manual:https://www.renesas.com/eu/en/document/man/m16c64a-group-users-manual-hardware?language=enPages of interest (Hardware manual):Page 41 = Pinout of chipPage 51 = Memory map (Single-Chip Mode)Page 728 = Setting of Standard Serial I/O Mode 2

author: tru
author_rank: Regular Contributor
timestamp: April 16, 2021, 10:06:06 am
content: Forgot to add, the M16C-R5F364A6N MCU is the same setup as with the controller I read from (M30624FGPGP).Just to reiterate my setup:- made up a debug header cable and wired as above (except for reset), so on the cable directly wired SCLK, EPM to ground (low) and CNVSS to 5v (high), connected TXD1 and RXD1 to TTL UART/USB- on the PCB the CE pin is already pulled-up to 5V through a resistor so left that pin untouched- the ground of TTL UART/USB connected to ground of the controller board (I used multi-meter to make sure the debug header ground is really earth ground!)- turned on the controller normally (using it's own circuit)- waited 1 to 2 seconds for MCU to boot the loader- send the read version command from the PC (this command doesn't need a password ID)- when working I see VER 4.04 displayedNoted: I didn't need to toggle the RESET pin low then high, it was left untouched.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 17, 2021, 10:10:49 am
content: Quote from: tru on April 16, 2021, 10:06:06 amAh, so that's where they're hiding all the information. The hardware manual is what I should've been looking at.I wired everything up how you specified and sure enough, I was able to read the flash! My bootloader version number was 1.00. I had to change the user ID to all FF to get it to read the firmware, but for some reason after that, all 00 worked as well. Not sure why that is.So now I have a dump of the firmware, I need to get it disassembled. I tried following the steps you posted previously but I cannot get the project you posted to load up in HEW. For some reason it is just blank. Had a short go at trying to get my bin file loaded in but didn't get very far. I'll have to try some more to find some documentation on how to use the disassembly feature properly. That seems to be the main challenge with these MCUs, finding the relevant documentation...Thanks for helping me get this far!

author: tru
author_rank: Regular Contributor
timestamp: April 17, 2021, 12:08:47 pm
content: Wow, cool!Interesting it has bootloader 1.00 and the user ID is FF.By the way, are you able to dump the data ROM and program ROM 2 (ROM they mean flash)?On your chip there are 3 separate flash areas:00E000h to 00FFFFh - Internal data ROM (8KB flash area)010000h to 013FFFh - Internal program ROM 2 (16KB flash area)0E0000h to 0FFFFFh - Internal program ROM 1 (128KB flash area)Strange, when you open the .hws file did you get a debug settings dialog?See in my screenshot, once the project is opened, on the left hand side you can double-click the "boot area mot - 00000000" (hex .mot file) item, and it should disassemble the code.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 18, 2021, 10:16:23 pm
content: Quote from: tru on April 17, 2021, 12:08:47 pmAh, I found the problem. When I opened your project, the file path for the bootloader hex file was still set to reference the file using the file paths from your computer. Once I found the right settings page I was able to point it to the file and then disassemble it. I then pointed it to my file, selected the correct MCU and was able to disassemble it.Exporting the disassembly to a text file was a pain with the 10000 line limit and it ended up taking 14 partial files to get it completely exported.I tried dumping the program ROM2 and the data ROM but the German flash tool just said invalid data range. Is there somewhere in your program where I can edit what addresses get dumped?

author: tru
author_rank: Regular Contributor
timestamp: April 19, 2021, 03:27:34 pm
content: My tool is command line only - the easiest way is to make 3 copies of a sample batch file, e.g.: copy the read flash block A.cmdOpen each in Notepad and replace the line with one of:Code:m16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x00E000 /to_addr=0x00FFFF /file=data-rom.binm16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x010000 /to_addr=0x013FFF /file=program-rom2.binm16cflasher /read /com=4 /id_addr=0x0FFFDF /id=FFFFFFFFFFFFFF /from_addr=0x0E0000 /to_addr=0x0FFFFF /file=program-rom1.bin*replace /com=4 with the com port number of the USB/UARTThe output is unfortunately in .bin (binary format). I was too lazy to code the .mot file format. If I have some spare time, I will add in that feature in.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 19, 2021, 11:00:14 pm
content: Quote from: tru on April 19, 2021, 03:27:34 pmAwesome! I was able to read out the main program ROM using your tool and I compared it to the bin file I dumped using the German tool and the files were identical.I then read the program ROM2 and the data ROM but the resulting files were just FF. They must not be using these memory areas.I have been looking through the disassembly to find the part that gives the LED flash error code. When the TV is plugged in, the power LEDs flash in a long, short, long, short pattern. The power LEDs are connected to P8_0 (pin 20) of the MCU. I found a subroutine at FE376 that looks to toggle that pin. The subroutine also has no exit so if the subroutine was ever entered, it would run forever. The subroutine also toggles P9_6 and P9_7. I took a look at those pins on the scope and P9_6 is toggling but P9_7 is stuck high. Both pins have been previously set as outputs so I would expect both to be toggling.I've attached the disassembled code including some comments I've made. I have found a few mistakes that I've made after looking trough it a few times and I wouldn't be surprised if there was more.I'm wondering if there's anything stopping me from making a small modification to the ROM and reflashing the MCU to see if the processor is ending up where I think it is. Something like changing the code in that subroutine to keep the LED on instead of toggling it. Then if the LED stayed on I would know that is the subroutine that I am interested in. Or is there some problem with this that I am not thinking of?

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 20, 2021, 05:08:23 am
content: After mapping out the flow of the endless subroutine I found, it seems to continually flash the LEDs at a constant pulse width. I calculated the number of processor cycles that one pulse would take and compared that to the actual lengths of the slow and fast flashes of the LED on my TV. If the pulses correspond to a "short" pulse, then the MCU must be running at about 21MHz. This seems reasonable and the (very sparse) service manual for the TV confirms that a continuous short flashing pattern is an error code for a failed firmware update. So this must not be the correct subroutine.I searched the code for other places that bit 0 in the Port 8 register was referenced and found two small subroutines at FF862 and FF874. These subroutines turn the LEDs on or off and are called from a couple nested subroutines that originate from an interrupt handler at FF554. I assume this is an interrupt handler since the REIT instruction is called at the end. However, I cannot figure out what interrupt would be calling it. I mapped out all the interrupts from the relocatable interrupt vector table but none of them corresponded to this interrupt handler. I can't find any references to FF554 in any other part of the code so I have no idea what would be calling it.I thought possibly the code was being copied to RAM and executed from there but that does not make sense as there are jump instructions in the interrupt handler that reference absolute memory locations in the flash memory.Any ideas where this interrupt handler could be getting called from?I've updated the assembly code in my last post with my most recent comments.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 20, 2021, 10:02:50 am
content: Your guess is correct, those two subs at FFxxx are executed from RAM. The code at FE336+ copies 57F words from FF000 to A08 then jumps there. That A08 code looks like a firmware updater - it talks over UART6 and calls functions manipulating FMRx regs (toggling p9_6 all the way).BTW, something is wrong with your .asm file. I've tried to convert it back to bin (by extracting addr/data from first two columns) and found 3 gaps: 3 bytes at E752F, 1 byte at E9C40, 2 bytes at EEA60. Looks like your disassembler silently drops bytes it doesn't understand. I've filled the gaps with NOPs and loaded the bin into IDA Pro finally.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 20, 2021, 10:44:16 am
content: Quote from: abyrvalg on April 20, 2021, 10:02:50 amSorry, I have attached the raw .bin file. I should've included it before.That is interesting, I will take a closer look at it. I too have switched over to IDA Pro and have gotten a bit further. So far in IDA the only references to the LED I/O pin are two port initialization functions and that infinite subroutine I found. I will try looking at the copy in RAM that you described.The missing addresses may be errors from when I merged all the disassembly files but I was pretty careful to get the indexes correct. It seems the HEW disassembler treats everything as instructions because viewing the bin file in a hex editor I am able to see a large string pool that HEW tried to interpret as instructions. IDA also finds some large jump tables.I am hoping to find the function that does the long-short blink pattern or a general purpose function that blinks the LED in a certain pattern as required. Attached is the segment from the service manual showing all of the different blink patterns.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 20, 2021, 11:05:57 am
content: Since the Reset vector at the end of the firmware points to FE000, the program should start from there. It sets up a few system things like stack and interrupt pointers and then goes to the subroutine at FE05C. Double clicking on "sub_FE05C" at FE054 gets me to the graph view.The subroutine seems to do two quick checks on the firmware image and if there is an error, enters an infinite loop. Otherwise, it does 3 more checks that should all pass and does an indirect jump to subroutine at E0102 which I assume is the main program. Otherwise it follows the tree down and that code at FE336+ you mentioned is at the bottom of the tree.The 3 checks are all simply copying a value from the flash to RAM and then checking it against a known value which should never fail in normal operation. I'm guessing these checks will fail when the MCU is started in "bootloader" mode which is really just microprocessor mode then switches the mode back to MCU mode.So I should never be getting to the bootloader or firmware updater in normal operation, or have I misunderstood how these checks work?

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 20, 2021, 01:48:26 pm
content: Yes, that RAM code shouldn't be executed in your case (one of the first things it does is erasing a sector at E0000, you'd see it blank if it does). So your blinking must be coming from the "app" code (E0000-EFFFF). But are you sure that LED is on P8_0? Some things don't match: you've mentioned pin 20 but it is P8_1, your manual screenshot shows P8_0 as CECoUT.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 20, 2021, 03:05:53 pm
content: Quote from: abyrvalg on April 20, 2021, 01:48:26 pmYes, I am very sure that it is on pin 20, at least by the second diagram in the M16C/64A Hardware manual. The first diagram is for a rectangular version of the M16C/64A and the second diagram is for the square version which I have. On the square version which I have attached pin 20 is P8_0. I know for a fact that the LEDs are connected to pin 20 as I can see the trace running to a transistor and then to the LEDs using continuity test. I have also tested pin 20 with the scope while running and verified that it is in fact an active-high output for the LEDs.If you are referencing the screenshot from the first page of the thread where pin 20 is P8_1, that is for a completely different MCU that tru has been helping me try to get the firmware out of and it does in fact have P8_1 on pin 20.tru, was the bootloader that you extracted from the main program ROM1 or from one of the other two flash areas? Because in the bin file you posted it clearly has VER.4.04 at the beginning of the file. You mention you get that string as a response when issuing the "get version" command from the bootloader. Since I get "VER.1.00" as a response I would expect to see that string somewhere in my bin file but I do not. Of course it may not be stored as a plain string but it seems strange that it wouldn't be. Does it seem odd that my other two memory areas are all FF, or is that normal?

author: tru
author_rank: Regular Contributor
timestamp: April 20, 2021, 03:49:29 pm
content: Cool, IDA Pro is perfect for this. The free version only provides Intel disassembly, assuming both of you using free version can I know where to get M16C module/driver from?The bootloader code I worked on is the Renesas internal bootloader (stored in a separate hidden area). It is extracted with a different command, my tool using this script hopefully should be able to extract it:"read bootarea.cmd"*you will need to open in Notepad and change the com port and the user IDThe hidden area uses the same addressing as the main program ROM: 0x0FF000 0x0FFFFF. When the debug header is plugged in it pulls some PINs, getting the MCU to switch those addresses to access the hidden area instead of the main program ROM.Note, though this bootloader isn't part of the TV firmware. Under normal operation, I don't think the TV runs the Renesas internal bootloader. It is really for the serial programming debug header, when it is plugged in the Renesas bootloader runs instead of the TV firmware.What you've already extracted (Program ROM1) is the whole TV firmware, that is assuming program ROM2 is unused - I think is the case as you mentioned it is all FFs.

author: tru
author_rank: Regular Contributor
timestamp: April 20, 2021, 04:19:14 pm
content: Quote from: canadaboy25 on April 19, 2021, 11:00:14 pmThere isn't anything special for flashing, except for erasing - the flash erase command can only erase entire blocks, i.e. you cannot erase single bytes of your choosing. In the hardware manual there is a diagram which displays the blocks (numbers):Hardware manual:https://www.renesas.com/eu/en/document/man/m16c64a-group-users-manual-hardware?language=enpage 705, Figure 30.4 Program Starting Address in User Boot ModePerhaps what might get in the way is the TV firmware code, checking the integrity of the firmware and whether it covers the parts you want to modify, but from your discoveries it looks like only a few bytes here and there is checked.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 20, 2021, 06:05:33 pm
content: The "main" code (E0000-EFFFF) accesses all GPIOs in a centralized fashion using package pin numbers translated to IO block:pin using a table at EED9E (bits 7-4 are IO block, 3-0 are pin). The P8_0 is 20th in that table as expected, the function at ECE20 is gpio_read(R1L=pin_idx), the function at ECDCA is gpio_write(R1L=pin_idx, arg_0=value), but there are no calls to these functions passing pin 20! (I'm pretty sure, checked all refs to P8 reg, to gpio_control func, searched for MOV.B #14h, R1L opcode - nothing).So the only code that manipulates this pin is "bootloader" (F0000+).

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 20, 2021, 10:46:36 pm
content: Quote from: tru on April 20, 2021, 03:49:29 pmUnfortunately I'm running the pro version so I'm not sure where or if a plugin is available. I had a look through the program files and it doesn't seem to be as simple as a folder full of the different instruction sets it supports.Quote from: tru on April 20, 2021, 03:49:29 pmThat's interesting, I had no idea they hid it like that. I'm not sure if I would've figured that out. I'll have a go at dumping the bootloader from my chip just to have a look at it. Really impressive that your program can do all that!Quote from: tru on April 20, 2021, 04:19:14 pmGood to know. If it comes down to it I suppose the worst that will happen is it fails some check and halts the program, in that case I can just reflash the original.Quote from: abyrvalg on April 20, 2021, 06:05:33 pmTo make sure I wasn't making a mistake, I checked every pin with the scope to see if any other pins are active. Only 4 pins were active (other than the two crystal oscillator pins obviously). P9_6 (pin 99) is toggling at a constant rate and pins 45 and 46 are also toggling but are not correlated to the rate that the LEDs are flashing. Pin 20 is obviously the pin that is controlling the LEDs.However, I took a closer look at the waveform for pin 20 and I can see that it is pulsing very quickly while high. It looks like a PWM signal at 99% duty cycle while high. This made me think it was being controlled by a hardware timer or PWM function. Looking back at the pinout of the chip, pin 20 is not only P8_0, but also TA4OUT. I had a quick look in IDA and there are multiple references to the timer 4 control registers throughout the code. It makes sense that they would be using a hardware timer as a PWM drive since the snippet from the service manual shows that the LED can be made to "pulsate" with gradual intensity changes. It would also make sense why we couldn't find the right references to P8_0 since the pin seems to be driven by a timer instead.I will look into the code manipulating the Timer A4 registers to see if I can confirm my thoughts.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 21, 2021, 11:14:01 am
content: You were right, it is TA4, the func at ED354 controls LED PWM duty cycle (R1L=0-100%), func at E844A blinks error code patterns defined by table at EE324. Pattern is selected by vars at D48, D49 set by a func at E8560, which is called from a func at E79E6, which is something like SetErrorCode(R1L=code). For example see E086A:SetErrorCode(0x16);DbgPrintf(9, "Lamp error over 5 times -> ERR_STBY");Tracking the 0x16 error code transformation to a bit pattern gets us to a 0x80000000 bit mask - a single blink, which matches your error table from manual. What pattern do you see on your TV?Upd: the func at E8560 is like SetLEDPattern(R1L=n_slow_pulses, arg_0=n_fast_pulses)One more idea: you can try acquiring a RAM dump of your error state. Turn on the TV normally (with CNVSS at "normal" level), let it enter error loop, switch CNVSS to BootROM mode, pulse RESET pin of the MCU to go to BootROM, read out the RAM region (0x400-0x33FF).Actual values of variables and last addresses in stack area could hint something.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 22, 2021, 06:10:56 pm
content: Quote from: abyrvalg on April 21, 2021, 11:14:01 amVery interesting discoveries! You are much quicker at finding the relevant functions than I am. It is tricky to follow the program flow once everything starts getting referenced from RAM.When plugging in the TV, it flashes the fast-slow-fast-slow pattern from the first row in the service manual snippet I posted.Another interesting note, while originally troubleshooting the TV I did some research and found that other similar Sharp TVs could be forced to power up and ignore backlight errors by holding a combination of the menu buttons while plugging the TV in. I tried every combination of buttons listed online but never was able to get it to power up in this special mode. I assumed it was because this TV uses capacitive touch sensors as the buttons instead of physical switches. However, one of the text strings at 0E96E says "Specail start: No Error" (funny how they misspelled "special" in all the messages). Searching for references to "E96E" in IDA gives a branch at E0E61 which sets byte_D21 that is checked in the set_error_code function to 5 which means no error. So it seems the functionality is in fact there, but it is so far down many different branches that I am having trouble finding what conditions actually have to be met to enter this mode.On the note of trying to get a RAM dump, I think the bootloader that tru posted ended up copying itself into RAM and executing itself from there which would defeat the purpose of trying to get a memory dump. Perhaps it would leave enough of the memory unaffected. I tried extracting the bootloader from my chip to see if this was the case but I couldn't get it to work. I used the read_bootarea tool with updated COM port and user ID and it verified the ID successfully but timed out trying to read the first chunk of data. I was still able to issue the get version command after the failed attempts so the MCU wasn't locked up, it just wasn't responding to that command. Any ideas what I am doing wrong with the tool?

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 22, 2021, 09:16:12 pm
content: I attempted the RAM dump anyways without much result. I first tried dumping the ram after starting the TV in bootloader mode and the resulting file was all FF. I then powered on the TV normally and switched the CNVSS high, pulsed the reset line, and dumped the RAM again. Still all FF. It seems strange to me that I'm getting all FF for the program ROM2, data flash, RAM, and also can't dump the bootloader. I know tru's tool is set up correctly and working since I can dump the main firmware with it. Perhaps the bootloader version 1.00 doesn't support these other areas?

author: tru
author_rank: Regular Contributor
timestamp: April 22, 2021, 11:14:32 pm
content: Quote from: canadaboy25 on April 22, 2021, 06:10:56 pmI've looked into the hardware manual again, the boot loader software commands for single chip boot mode is not listed in your model. In the manual of the M30624FGPGP it lists all software commands for single chip mode. Perhaps being v1.00 it doesn't include such read boot area code command.

author: tru
author_rank: Regular Contributor
timestamp: April 22, 2021, 11:19:03 pm
content: In page 712 of your hardware manual:There is table of boot loader software commands for Rewrite mode (different mode from single chip mode):Table 30.15 Software Commands:Code:Read array WriteRead status register WriteClear status register WriteProgram WriteBlock erase WriteLock bit program WriteRead lock bit status WriteBlock blank checkHowever, I think that isn't the complete list because the read version command is not listed there.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 23, 2021, 11:14:20 am
content: That "special mode: no error" is entered by holding some 3 touch keys pressed (0x49 bitmask of pressed keys). Possible masks/modes:45 - special: inspection29 - special: hotel (public)25 - special: hotel2 (public2)49 - special: no error15 - special: calibration09 - special: version upLooks like the "version up" is firmware upgrade mode, so if you know a 2-key combination to enter it - just try it with all possible 3rd keys.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 23, 2021, 11:36:21 am
content: Quote from: tru on April 22, 2021, 11:14:32 pmHmm, that's interesting. The hardware manual for the flash version of the other Renesas MCU we were working on has the same incomplete table. However, it describes the possibility of rewriting the bootloader while the hardware manual for the 16C/64A doesn't seem to. Perhaps they disabled this and that's why it is still Ver 1.00? Either way it's probably close enough to the version you were able to dump to have an idea of how it works.Quote from: abyrvalg on April 23, 2021, 11:14:20 amWow, nice! I'm not sure what the combination for the firmware upgrade is either. Very sparce information on this TV. Either way, there are only about 6 keys. Won't take long to try all combinations. I was previously just trying 2-key combinations. I'll give it a shot and see if anything happens.I got sidetracked in IDA looking through the function at E5F4E which is an EEPROM integrity check function. The external EEPROM is connected via the UART2 interface in I2C mode. Throughout this function values are being copied to the RAM from the EEPROM. I took a quick look at the lines with the scope and there is in fact a good chunk of data being transferred on power-up. Makes it even trickier to trace the exact place that I am failing this backlight check in the code. Perhaps it would be easier to try modding the firmware to dump RAM values out an unused UART interface. It wouldn't take long to try modifying some values in the large unused space in the firmware to see if I trip some type of checksum. Let me know what you think about this.

author: tru
author_rank: Regular Contributor
timestamp: April 23, 2021, 02:52:21 pm
content: I forgot to mention that there is another special software command, I think is for debugging purposes, it downloads code to RAM (from 0x600), does integrity check then jumps to your code which executes it. It works on the VER.4.04 boot loader.I've included a HEW project with the sample code that sets port P8_0 to high for you.It also contains the required code to pass the boot loader integrity check.If it works on VER.1.00 you should see the LED constantly lit.I've added 3 files to:https://github.com/truhy/m16c-flasher/tree/main/Sourcecode/Release"boot_dl_P8_0 source code - HEW project.zip" = source code of below"boot_dl_p8_0.bin" = program to be uploaded into RAM"upload to ram - p8_0.cmd"The files are prepared and ready to go, simply edit the batch file "upload to ram - p8_0.cmd" with your COM port and try.If you want to modify and recompile the test code:Note, as you've found out already, since HEW was made in the past the workspace and project files (plain text files) stores absolute paths and needs correcting (find and replace).There is another small problem, unfortunately my tool supports only input binary file so I have included srec_cat with a batch file to convert motorola into binary, but it also fills in zeroes before 0x600 so you will need to remove them.

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 23, 2021, 08:09:26 pm
content: I tried holding down every combination of 3 buttons while plugging in the TV and nothing changed. I'm not sure if it is even reading the buttons or not. Really hard to tell with the capacative touch buttons.Quote from: tru on April 23, 2021, 02:52:21 pmCool! I gave your sample script a try and it worked perfectly. LED was lit up solid. I wonder if it is possible to switch over to this special command mode without losing the values stored in the RAM. If so, I would theoretically be able to set up the UART interface in code and dump out the rest of the RAM that hasn't been overwritten. I'll give getting a UART set up a try to see if I can at least get it printing data.

author: tru
author_rank: Regular Contributor
timestamp: April 23, 2021, 09:32:48 pm
content: Wow, I thought that it would not work!The special command is part of the boot loader code - not a hardware command. Unfortunately when the boot loader starts up, it copies main part of itself into RAM and runs from there, some of the RAM is overwritten, but then the required reset for boot mode will destroy the RAM content anyway?Have a look at the test source code included in the HEW project to get an idea of what's happening (plain text file):ncrt0.a30It is in assembly. I've marked a user code section where the port P8_0 is set to high. If you don't want to jump back into the Renesas boot loader code you can add in an infinite loop and remove all of the following code, except for the CRC code at the end. The integrity check is simply the CRC of your code, which is automatically calculated by that code.Since the command works, now there is possibilty we can write own code to dump out the boot loader code!

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 23, 2021, 10:14:23 pm
content: Quote from: tru on April 23, 2021, 09:32:48 pmIt is encouraging to be able to make the LED actually do something other than blink at me!Even though the bootloader is copied to RAM, I'm hoping it doesn't overwrite the select few bytes that are important to ending up in the lamp error mode. Being able to examine the bootloader would allow us to see if this is the case or not. On page 86 of the hardware manual pdf (page 53 in the document), it says that the internal RAM is not reset by pulling the reset line low. It does say that the RAM will be undefined if the MCU is reset during a write operation though.I'll definitely take a look at the HEW project to get up to speed with how it is working. Do you know the process to make the hidden bootloader are accessible from software? I can't really find anything in the hardware manual about it which is probably intentional or I'm not looking for the right terms.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: April 26, 2021, 10:22:58 am
content: Just a thought: if it’s a lamp error - why dig the code further? Check the backlight circuitry instead? Or you want to know exact MCU pin to narrow down the search?

author: canadaboy25
author_rank: Regular Contributor
timestamp: April 26, 2021, 09:26:00 pm
content: Quote from: abyrvalg on April 26, 2021, 10:22:58 amYes, when I first found out that it was a backlight error I figured that it would be a simple fix. The LEDs are in parallel sets of series connected LEDs like most TVs. I powered up each set expecting to find one that wouldn't light. However, every string lit up and the current draw was identical between all the strings. So obviously the physical LEDs were fine. There is a large inverter board connected to the strings of LEDs that connects to the logic board and the power supply. There is no voltage coming from the power supply to the inverter board but that is because the main board is not enabling the power supply. I manually jumped the enable pin on the power supply to verify it and all voltages are correct. So that leaves the main board or the inverter board. I probed each of the signal lines between the main board and inverter board with the scope and there are no signals at any time, even at power up. This seems like a problem since I don't see any way the main board could tell if there is a baclkight issue without even communicating with the inverter board.There is an Altera CPLD on the inverter board that communicates with the main board. This is basically a black box because I strongly doubt that the designers have left the lock bit clear in the CPLD firmware. It would also be a much more difficult task to reverse engineer a CPLD firmware with no documentation if I could get it dumped. I don't know if the main board first sends a signal to the CPLD on the inverter board and waits for a response, or if it happens the other way round. It seems unlikely for a CPLD to just die, so I though it must be the main board seeing some other input that it doesn't like. Seeing that the main board had a flash memory Renesas MCU, I figured that dumping the firmware and figuring out what specific conditions trigger the lamp error would give me a lot more direction in my troubleshooting.Looking through the bootloader that tru posted previously, it overwrites a lot of the RAM with its own code so that will make getting a RAM dump quite hard. I did find one interesting place in the TV firmware, though you may have already ruled this out.In the function at E06A0 at address E0856 is the code that would print the "Lamp error over 5 times" string. At address E080E the code would print "Normal Start". There is one jump instruction that chooses between these cases based on the value of byte_D21 in RAM. If byte_D21 == 05H, the TV starts normally, otherwise the TV goes into lamp error mode. Further up in that function, byte_D21 is set to the value of byte_D0E. At the top of the function, byte_D0E is set to either 05H or 04H based on the value in R0L. If R0L == 12H, the TV will end up in lamp error mode. R0L gets set by the function at E7494. R0L gets set to 12H based on the values calculated from ADC pins AN0_4 and AN0_3. There is also a function at ECE20 that seems to reference a lot of ROM addresses and then return a result based on the state of P2_4 if I have followed the function correctly.It seems to me that either this P2_4 or the two ADC pins could be where something is going wrong unless you have already looked at this and I am missing something.

author: tru
author_rank: Regular Contributor
timestamp: April 26, 2021, 10:34:38 pm
content: Quote from: canadaboy25 on April 23, 2021, 10:14:23 pmOn V4.04 bootloader, the download to RAM command keeps the hidden addressing mode so a downloaded code should already be able to read the hidden area if V1.00 is same. For other commands the mode is switched to normal addressing, e.g. when reading flash.I think now I know what controls it and they've intentionally made the setting reserved. In the M16C/64A hardware manual see PDF reader page 694 (document page 661):Flash Memory Control Register 0 (FMR0), bit 5In the processor of my one, the M16C/62 hardware manual says (rather than being reserved):Flash Memory Control Register 0 (FMR0):bit 5:0 = boot ROM area (addressing mapped to hidden flash area)1 = user ROM area (addressing mapped to normal flash area)If I have some free time, I'll try to write some code to see if I can read out the bootloader VER.4.04 using a downloaded code.User boot mode - another thing to look at----------------------------------------------I've also noticed what ROM2 area is for, it is for user boot mode (for executing customer's own bootloader). I am guessing, V1.00 bootloader doesn't just enter into serial bootloader mode, it first checks some values inside ROM2 area, and if they pass it executes from start of ROM2 instead (address 0x10000).The checks is described on page 702 (document page 669):So to boot into user boot mode, flash a program into flash ROM2 area so that it has:ASCII string "UserBoot" at addresses: 0x13FF0 to 0x13FF70x00 at addresses: 0x13FF8 to 0x13FFBIt will never enter serial mode anymore, to revert back simply write 0xFF to those areas in ROM2, or just erase ROM2 area.This user boot mode could mean RAM will not be overwritten, I assume it doesn't use it and execution is directly from ROM2 area.

author: canadaboy25
author_rank: Regular Contributor
timestamp: May 01, 2021, 02:15:51 pm
content: Quote from: tru on April 26, 2021, 10:34:38 pmCool, so they've hid the control for the hidden memory command in plain sight. It shouldn't be to difficult to write a simple program to read the bootloader out.I am away for work right now but when I get back I will definitely give that a try!

author: tru
author_rank: Regular Contributor
timestamp: May 01, 2021, 03:12:39 pm
content: Ouch, just a warning regarding the ROM2 user boot mode - I've just realised that if you can't get back into the standard serial bootloader mode then you can't erase! Unless of course you code in your own erase function into your ROM2 bootloader.

author: canadaboy25
author_rank: Regular Contributor
timestamp: September 13, 2021, 05:39:46 am
content: Hi, sorry for the extended absence, I've been away for work all summer and have not had physical access to the TV. I am back now and ready to get this thing figured out!A few posts ago, I mentioned finding conditional jumps based off of two analog inputs. I probed these two inputs while turning on the TV and they were both a constant 3.3V. I traced them out and they seem to go to pullup resistors and an unpopulated 3 pin header. So it looks like they are not even used in this model. I am having a hard time figuring out what value the ADC would return given a 3.3V input.Since we are able to read and write the firmware, do you think it would be possible to modify the firmware to somehow add print("Here") type instructions in critical places? Something like flashing the power LEDs or an unused output? Or even maybe enable a UART bus on some unused outputs? There are just so many paths the program can take and it is very tricky to infer where exactly in the code it is getting stuck. If the edit does not work, I can just reflash the original firmware right? Or is there something I am overlooking about the process?

author: tru
author_rank: Regular Contributor
timestamp: September 13, 2021, 07:31:13 am
content: Quote from: canadaboy25 on September 13, 2021, 05:39:46 amThat is a very good idea to flash a LED. There is only the software integrity check where it checks the copy of the code to RAM using the hardware CRC generator, but from memory I think it calculates that on the fly so modifying the binary code should still pass the check - I will re-look at the code when I have a bit of free time. The only problem I see is that you cannot insert code and can only overwrite, because that would affect other code that is using relative address offsets. The best approach is probably to modify the disassembly and recompile, but I think HEW trial version limits the compile input assembly size - you will need a full version of HEW. Alternatively, perhaps IDA Pro allows inserting code?

author: canadaboy25
author_rank: Regular Contributor
timestamp: September 13, 2021, 10:18:25 pm
content: Quote from: tru on September 13, 2021, 07:31:13 amYes, I had thought about the problem of inserting code messing up the relative addressing. I figured that since there are plenty of instructions that just move a constant value to a register or RAM, one of these instructions could be replaced with a subroutine call. The subroutine could be placed in an unused portion of the firmware and then the removed instruction could be executed inside the subroutine. Then an LED blink could be added and the subroutine would return. This should have the desired effect without removing any existing code and without messing up the offsets.I do not know of any way to edit the firmware from IDA but I am relatively new to using it. It will probably be easiest for me to just compile the instructions I want to add in HEW and then splice them into the binary manually. I shouldn't need to add that many to figure out what path the program is taking.I will take a look at the CRC check in the bootloader you posted to see what will be required for it to accept the modified code.

author: canadaboy25
author_rank: Regular Contributor
timestamp: November 02, 2021, 09:44:06 am
content: I have a bit of a problem. I made a small modification to the TV firmware binary by changing an OR #0x10 to OR #0x0 so that timer A4 would never be activated. This would mean that the LED would never blink and would be a good test to see if the modification was applied successfully.I tried flashing using the M16C-flasher tool but it failed immediately after erasing. It appears it does not like bin files as an input. I tried reflashing the original firmware from a .mot backup file I made and it wrote the entire thing except for the vector table at the end of the firmware. Places where there should be FF are 00 on a subsequent read. I converted the .mot file to a .bin file to ensure it wasn't damaged and it is in fact fine. For some reason the tool is incorrectly programming the last few bytes.I tried using your command line tool and was able to flash block 6 (0xE0000 - 0xEFFFF) and block 5 (0xF0000 - 0xF7FFF) but the tool just errors out while trying to flash the final block (0xF8000 - 0xFFFFF).Is there something I am doing wrong here? I don't know why the M16C-flasher tool cannot reflash a backup that it made itself...UPDATE: I was able to get the original firmware loaded back on using the Renesas FlashStart tool and the original .mot backup. So I guess I will have to figure out how to convert my modified bin file to a .mot file that the FlashStart tool likes.

author: tru
author_rank: Regular Contributor
timestamp: November 03, 2021, 08:56:09 am
content: Quote from: canadaboy25 on November 02, 2021, 09:44:06 amI've noticed that you mentioned the final block is 0xF8000 - 0xFFFFF. But my program assumes that there are more blocks 4, 3, 2, 1, 0. See the source file m16c_mem_map.h where I list each block and their address range. Perhaps that could be the problem - when I get more time I will compare with your MCU datasheet. The erase procedure is in blocks, and if successful all addresses will be set to 0xFF so I guess that the final block did not erase.To convert to .mot file try the srec_cat program, I've place a copy of it on my github with an example .cmd script:https://github.com/truhy/m16c-flasher/tree/main/Convert%20Binary%20to%20Motorola%20formatThis may be useful, here's some examples from manual of srec_cat:http://srecord.sourceforge.net/man/man1/srec_examples.html

author: canadaboy25
author_rank: Regular Contributor
timestamp: November 04, 2021, 12:25:16 am
content: Quote from: tru on November 03, 2021, 08:56:09 amI think the erase was successful because I did a read on the chip after a failed programming attempt and all addresses were 0xFF.I gave the srec_cat program a try previously but the FlashStart tool did not seem to like the file it generated. It may have been some other fluke though. I also noticed while using your tool that if I didn't do the programming in separate blocks it would just get stuck on the first block and program it over and over. So there must be some incompatibility between the two chipsI used the backup .mot file that I reflashed to the chip as a template and wrote a quick python script to convert my bin file to the .mot file that the FlashStart tool likes.In my edited bin file I removed the enable instruction for the timer A4 so the LED will not be blinking and I then replaced the printf subroutine in the lamp error branch of the code with a subroutine that just turns the LED on solid. So if my code works, the LED should come on solid. I disassembled my newly modified firmware with IDA Pro and all of the changes looked good.Upon flashing the firmware, the LED just stays off. So either the code is not running the branch that I think it is, or the LED output pin is configured as a timer output and needs something configured differently for it to function as a GPIO pin. Or there is a checksum somewhere that does not like my modification. I may re-enable the timer just so I can see if the code will still run after I have added an extra subroutine, converted it, and flashed it.

author: canadaboy25
author_rank: Regular Contributor
timestamp: November 04, 2021, 07:43:54 pm
content: I was finally able to get my own code to run. I removed the call to the subroutine which initializes timer A4 and also the instruction that enables timer A4. This prevented the LED from blinking and also ensured P8_0 was free to use as a GPIO. I then replaced the call to the printf stub in the branch which prints the backlight error message with a subroutine that I added in unused memory. Inside my subroutine I set P8_0 to an output and set it high. I did this by manually editing the .bin file and then converting it to a .mot file with my python script. Flashing this code with the FlashStart tool and running it makes the LED come on and stay on solid. So everything is working properly!There are still so many branches that manually moving the call for my subroutine and reprogramming the chip will take ages. I think the best thing to do is get a printf function and a UART setup. Luckily UART0 does not seem to be used by the code at all and it is also wired up to the debug header on the board that I am connected to. It seems likely that this was the UART originally used for debugging purposes. I will try my best to get the UART set up correctly and then try to implement a basic printf function. If I get that working then I can really get down to some serious debugging.

author: canadaboy25
author_rank: Regular Contributor
timestamp: November 07, 2021, 08:32:22 am
content: Success!! Well, sort of.I replaced the function which initializes the PWM timer for the LED with a function that initializes the UART0 interface. I then used HEW to compile my own little subroutine which I can use to do whatever I want. I then wrote a python script which converts the .mot file from HEW to .bin and copies the subroutine to an unused portion of the firmware. I can then manually replace any instruction with a jump to my new subroutine and convert the file back to a .mot to be flashed to the chip. The instruction that I replaced in the code is run from my subroutine so the program flow is not altered.I was eventually able to implement a very basic printf and see the debug codes on a terminal! I got "No need to init EEPROM" and "Lamp error over 5 times -> ERR_STBY". So the code was ending up where we though it was.Looking at the graph view in IDA (attached image), there are 4 conditional branches that stand between a normal start and a backlight error. For it to get to the backlight error, all 4 checks must fail. I started with the first one which compares the byte 0xFE9 in RAM to 0x5 and goes to a normal start if the value is less than 5. This really stands out as the number of attempts since the error code says 5 failed backlight attempts.After spending hours editing the firmware and placing print statements at different locations, and even dumping the whole RAM, I traced byte_FE9 to the EEPROM integrity check function. Before the function is called FE9 is 0 and after the function FE9 is 5. After digging deeper into the function, byte FE9 is loaded straight into the RAM from the on-board EEPROM that I mentioned quite a few posts back. It seems unlikely that the EEPROM happened to have that specific byte corrupted but it sure seems strange.I decided to take a shot in the dark and "patched" the firmware to set FE9 back to 0 after the EEPROM function and flashed it to the TV. Plugged the TV in and it powered right up! I can play video from an HDMI source and all of the controls seem to work. So clearly there are no major faults with the backlight circuitry. It is really tempting to just close it up and call it a win, but I would like to repair it properly. Obviously it is one of the other 3 conditional branches in the image I attached that is responsible for the error detection.Looking at it again, it would make sense for it to be the last branch since as I mentioned, there is a mode to force power-up and disable error detection so that branch would have to be before the actual error detection in order to bypass it. I suppose the next step is to start tracing the RAM value D21 and see what is controlling it.Modifying the firmware binary by hand is a huge pain so if anyone has any ideas about how to improve the process or any thoughts about my troubleshooting logic then let me know!

author: tru
author_rank: Regular Contributor
timestamp: November 07, 2021, 08:14:16 pm
content: Cool, I see I'm a bit tooo late, you've already found a nice solution with Python script. But just to let you know, I've found out that the FlashStart tool simply doesn't like the first line that srec_cat generates. The first line is S0 record, which is some sort of ID, replacing it with this short one should work:S0030000FCImpressive work, and unfortunately I can't think of any other easier way than what you're doing already.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: November 07, 2021, 10:53:48 pm
content: > Modifying the firmware binary by hand is a huge painAutomate it in Python at least, make a tool that takes an asm file containing the code to insert and two addresses - code insertion and jump pathching, and do all necessary steps programmatically - call HEW to assemble the asm, insert the result into the fw file at the correct offset derived from code insertion address, create a jump to your code at the patch address (a jump instruction shouldn’t be that hard to encode).Or if you are really serious into that, try implementing the Edit->Patch program->Assemble command support in IDA plugin (take an asm line input, produce a temporary asm file containing necessary headers/footers and your line between, invoke HEW, collect resulting bytes, pass them back to IDA)

author: canadaboy25
author_rank: Regular Contributor
timestamp: November 08, 2021, 07:43:52 am
content: Quote from: tru on November 07, 2021, 08:14:16 pmOh, that is good to know. Will probably come in handy for a future project. I'm glad I wrote the python script as it forced me to learn how the Motorola format works which is never a bad thing.Thanks for the kind words.Quote from: abyrvalg on November 07, 2021, 10:53:48 pmThis is exactly what I was planning on doing but dealing with different instruction lengths and types and also sometimes having to shuffle a few things around as to not upset the program flow seemed like more work than it was worth.I hate to give up before I find the root of the problem, but I'm running out of places to look. I traced that last jump branch back to the functions which take an analog to digital sample and compare it to a lookup table in ROM. Adding a print statement to the ADC function prints FF continuously like I expected as I previously traced those pins to an unused connector with pullup resistors. I pulled the pins low on the unused connector and was able to get a corresponding readout on my debug terminal. So unless those two pins also run somewhere else on the board though an internal layer, that functionality must just not be used. I tried probing around but could not find any other connections. Very hard to tell for sure without a schematic.One of the other jump branches is determined by a RAM value set by reading data from UART7. UART7 is connected to the soft touch buttons so this must be the branch for the special start mode. There are other clues to this throughout the firmware.The two other branches seem to be statically set based on some values loaded in from the EEPROM upon startup.Apparently this is a very common issue to occur on these Sharp TV's after a power outage. This suggests that it is in fact some values getting corrupted in memory somewhere. The "fix" online for this problem is to just disable the backlight error check in the service menu, but this only lasts as long as power is applied. So even if I did find the corrupt value and repair it, there is a good chance that it may happen again. At least with the firmware patch, the TV will keep working after it is unplugged. I'll leave my little debug connector soldered to the board in case it acts up again in the future.Big thanks to abyrvalg for finding and understanding so many relevant parts of the firmware, and a massive thanks to tru for the wealth of knowledge about these microcontrollers. Without the help I wouldn't have known where to start. Hopefully I'll have a chance in the future to have another go at getting the firmware out of that mask ROM chip from the other TV!

author: abyrvalg
author_rank: Frequent Contributor
timestamp: November 08, 2021, 12:12:23 pm
content: Maybe it's too late but I took a look into EEPROM load func (the one at 0xE5F4E - right?). LampErrorCount (that byte at 0xFE9) is loaded from EEPROM address 0x11 and this is the only possible source of non-zero value there.There is an EEPROM map at 0xEDE3A:struct {uint16 ram_addr;uint8 unk;uint8 ee_addr;uint8 i2c_slave_addr; //always A0uint8 default_value;uint8 unk;} LampErrorCount address is 0x11, defalut value is 0.BTW, looks like it is possible to force defaults by holding SCL or SDA low at start. The first thing the load func does is dummy I2C access to test that SCL/SDA are not held by someone (calls at E5F51, E5F54). If there is any error it takes the E5F5E path, calling the debug printf stub to print "EEPROM access failure", then load all RAM vars with defaults from the table.

author: canadaboy25
author_rank: Regular Contributor
timestamp: November 08, 2021, 11:13:25 pm
content: Quote from: abyrvalg on November 08, 2021, 12:12:23 pmYes that is the EEPROM function I was talking about. FE9 gets 0x5 loaded to it straight from the EEPROM. I noticed the default settings branch too and thought perhaps the stored EEPROM value got changed. However, if that is the only place that the FE9 byte gets modified, how does the code check for an actual backlight error if it is just supposed to load a 0 by default? I have not been able to find any code that actually seems to check external inputs except for that ADC function which does not seem to be used.Were you able to find any code that looks like it actually checks for backlight errors? I'm not sure how it would work since the only place the printf("Lamp error") is called is during the startup process. I don't see any way for it to detect an error while the TV is running. Unless there is an interrupt service routine somewhere that is checking for errors?

author: abyrvalg
author_rank: Frequent Contributor
timestamp: November 11, 2021, 12:03:47 am
content: The actual lamp error condition check is in func at 0xE03BC. Pin 40 (P5.4) is checked there (by calling gpio_read(40)) to be in good (0) / bad (1) state long enough (the function looks like being called periodically, it counts good/bad state duration as number of invocations). An error 0x16 (lamp error) gets posted to some queue from there in case of error (at 000E041B, 000E0470). The EEPROM lamp error counter gets cleared (call from 000E0448) in good case.

author: gashtaan
author_rank: Regular Contributor
timestamp: February 21, 2022, 05:52:30 am
content: Quote from: tru on February 03, 2021, 02:40:30 pmI believe this is not true for v4 bootloader, ID is checked without using branches there, so code will be executed always in same amount of time. Though, I'm surprised that Renesas would make such a rookie mistake in v1 bootloader. By any chance, haven't you dumped also v1 bootloader from something?

author: tru
author_rank: Regular Contributor
timestamp: February 21, 2022, 09:25:47 am
content: Quote from: gashtaan on February 21, 2022, 05:52:30 amOh, so they've fixed the hack. No I have not dumped v1 bootloader. I've only encountered v4 bootloader and default password, but then again I'm not interested in hacking it. I was only trying to repair a control panel as a challenge. This was a result after offering to pay the manufacturer to repair it, which they replied that their control panels are advanced and are not repairable, and we should purchase a new unit.

author: gashtaan
author_rank: Regular Contributor
timestamp: February 25, 2022, 01:37:19 pm
content: I'm interested in downloading firmware from some device using M3062 MCU, but this one is unfortunately locked with unknown ID. I'd like to try to test glitching on it, but it would be much helpful to have some unlocked chip to do experiments.Quote from: tru on February 21, 2022, 09:25:47 amWhat is that control panel you have with the chip unlocked? It's long-shot, but maybe it would be cheaper to buy some salvaged board with this chip on it.

author: limbast
author_rank: Contributor
timestamp: July 17, 2025, 06:44:51 pm
content: Quote from: tru on April 19, 2021, 03:27:34 pmHello and sorry to bring up an old topic. I would like to contact tru, but I just registered and I am not allowed to send private messages. I did not dare to create a new topic either, because it was addressed directly to tru, I thought it was unacceptable.Here is my problem.I have on the table the boards of a FAS snack machine: a control board and two power boards. When connecting one power board (not working) to the control board, the bundle "hangs" on displaying the firmware version of the control board. When connecting the other power board (working) to the control board, the bundle works, displaying the firmware version of the power board and then the bundle goes into working mode. The boards communicate with each other via UART. Signals from the MCU of the control board reach the MCU of the power board in both cases. I used a logic analyzer to understand what the problem was. The control board MCU sends several different commands to the power board, the power board MCU responds to all commands, then the same command is sent continuously until (about 5 seconds on a working power board) one bit in the response changes, after which the control board MCU sends several other commands, including reading the power board firmware version (the codes in the response and the firmware version displayed on the machine's display are the same). In a non-working board this bit never changes and therefore the control board does not send other commands.I rechecked all the electronic components on both boards, they are fully functional and identical.I thought that the problem was in the software.The power boards have M30262F8 MCUs and there is a programming connector. The MCUs are not locked. I used the M16C Flasher program to read the firmware. The firmware was the same. Then I re-soldered the MCU and the problem moved from one board to another, that is, the problem is 100% in the MCU. I had an idea that the problem might be in the Virtual EEPROM memory area. M16C Flasher can't read this area, but I found your programhttps://github.com/truhy/m16c-flasherand this thread on this forum.I read this area with your program, but they were the same, both MCUs had 0xFF.I was surprised. Then I read full dumps from MCUs from 0x000000 to 0x0FFFFF. Several differences in the SFR area 0x000000-0x000400, then in the RAM area 0x000400-0x000582 are the same, in the RAM area 0x746-0xBFF everything is absolutely different (I think these are the results of your RAM area program), and then to the very end the dump is completely the same.I don't understand what the difference is, why do MCUs work differently?Please give me some thought or idea.

author: tru
author_rank: Regular Contributor
timestamp: July 17, 2025, 11:19:10 pm
content: Interesting. That MCU belongs to the M16C/26 series. The memory map is different from my M16C/62P series, but addresses do sort of align.I think I may have found your problem... looking in the "M16C/Tiny Rewriting the User ROM Area in EW0 Mode" PDF, which you can get from here:https://www.renesas.com/en/document/apn/m16ctiny-rewriting-user-rom-area-ew0-mode?r=1053151It says block A and B (the virtual EEPROM areas) are not readable until you set the PM10 bit to a 1, which is part of the PM1 register.QuoteIn the datasheet, the PM1 register is located at address 0x0005, but I don't know which bit is the PM10. Perhaps someone can let us know which document lists the various bits of the registers (SFRs)? The list of available docs are here:https://www.renesas.com/en/products/m16c-26?srsltid=AfmBOoqpkL-_8H0XfHaC-XK56cBqUKKcrKtGtKTqWtBzXN04iRctHLI7#documentsI assume PM10 by default is set to 0, meaning to read out blocks A and B you will need to first write a program that is able to run in RAM and then jump back into the bootloader after setting the bit. Your program will need to be downloaded into RAM using the download switch of my m16c flasher. I think I have a sample LED blink (GPIO) program that I wrote a while back that jumps back to the bootloader. I will see if I can find it.

author: limbast
author_rank: Contributor
timestamp: July 18, 2025, 07:47:44 am
content: Hello.The description of the PM1 register bits is in the M16C/26 Hardware Manual on page 31.https://www.farnell.com/datasheets/17451.pdfI compared the M16C/26 and M16C/62P Hardware Manuals. The PM1 registers are at the same address, but the bits have completely different purposes.After reset, access to block A and B is prohibited, for access, the PM10 (B0) bit must be set.

author: tru
author_rank: Regular Contributor
timestamp: July 24, 2025, 10:44:38 pm
content: Ok, I had some spare time and coded it for you. I think this will only work on bootloader V4.04, not sure what your version is, but you can find that out by running my m16cflasher.The binary file and bat script to upload and run it:https://drive.google.com/file/d/1irQrziR5RjSqoqwbHgP8jesq2tBIZ4yw/view?usp=drive_linkThe source code (Renesas HEW IDE):https://drive.google.com/file/d/1IQOE0Jk7IvsWC5HmFdv14cnuWKkOvJvq/view?usp=drive_linkThe assembly file is named ncrt0.a30, which you can view in notepad if you just want to look at the source.Renesas HEW IDE can be downloaded here (requires free registration then login):https://www.renesas.com/en/software-tool/cc-compiler-package-r8c-and-m16c-families#downloadsIt is commercial but the eval version can compile short sources, so you may want to download [Evaluation Software] C/C++ Compiler Package for M16C Series and R8C Family M3T-NC30WA V.6.00 Release 00

author: limbast
author_rank: Contributor
timestamp: July 25, 2025, 06:44:00 pm
content: Thank you!I used your program m16cflasher to read the dump, but the bat files you wrote don't work for some reason, I think it's related to the location of m16cflasher. I used your program simply with parameters.The program responded "VER.0.10" to the command "m16cflasher path=\\.\com4 ver", that is, the bootloader version is not the one you specified, but I'll try anyway.

author: limbast
author_rank: Contributor
timestamp: August 11, 2025, 02:09:15 pm
content: Tru, I used your program. But it didn't work to read areas A and B.You made a bat file to load the program into the MCU. Its contents are as follows:m16cflasher /download /com=4 /id_addr=0x0FFFDF /id=00000000000000 /file=enable_blockab.mot.binI downloaded your m16cflasher flasher from githubhttps://github.com/truhy/m16c-flasher.The version from github does not understand the parameters as you specified them in your bat file. The flasher does not understand the slash before the parameters, and the COM port is specified by the path parameter and backslashes. Below is a screenshot of the program running.When I specify the parameters as the flasher understands (the last line on the screenshot), it crashes.Maybe I have the wrong version of the m16cflasher flasher? The size of my version from github is 453210 bytes.

author: tru
author_rank: Regular Contributor
timestamp: August 11, 2025, 05:03:25 pm
content: Sorry, I had modified a bat file taken from an older version (before adding linux support). In the newer version to align with linux, slash was removed and we supply physical serial com path instead. I've updated the zip in the previous post. Or edit your bat file with this instead:m16cflasher download path=\\.\COM4 id_addr=0x0FFFDF id=00000000000000 file=enable_blockab.mot.bin*Don't forget to change the COM4 to your detected serial device.The download (upload to ram) command may not be supported by your bootloader version, but let's see.Ouch, just noticed you've tried latest version and added it crashes. I'll test in a few days on my side.

author: limbast
author_rank: Contributor
timestamp: August 11, 2025, 06:06:01 pm
content: That's exactly what I did, you can see it on the screenshot (last line), I didn't use a bat file, I wrote commands in the command line. But the flasher crashes when I press ENTER.It seems that the flasher doesn't work correctly with the bootloader of my MCU VER.0.10 and that's why it crashes?

author: tru
author_rank: Regular Contributor
timestamp: August 11, 2025, 06:49:50 pm
content: Just tried a quick test, and noticed the binary file that was converted from .mot (compiled file) was zero padded from the beginning of the file, and doesn't work. I've removed these zeroes and is fine now. It loads and run on the MCU (M30624FGPGP) but then again it's got V4.04 bootloader.Again, I've updated the link in the previous post with the updated enable_blockab.mot.bin download file.I'm not sure yet why it crashes on yours, if I may ask what version of Windows you are on (I am on Windows 10)?- noted from your screenshot you are using Windows 10 also.We need to sort out the crashing first before ruling out the V0.10 bootloader support for the download command.Failing all this, there is one last trick to readout blocks A+B, which is to backup the entire flash (except A & B of course), then write and flash (say only block 0) with your own program to enable A+B areas, read those areas and finally send them out the serial port yourself. After that you would restore the original flash area. I must warn you to be careful with the m16cflasher not to do an erase all blocks command.

author: limbast
author_rank: Contributor
timestamp: August 12, 2025, 06:14:54 pm
content: After you corrected the enable_blockab.mot.bin file, your program loaded successfully without a crash.After that, I tried to read the VirtualEEPROM area (0xF000-0xFFFF), but it still doesn't contain data.After loading your program, do I need to activate it somehow or does it start itself immediately after loading?

author: tru
author_rank: Regular Contributor
timestamp: August 12, 2025, 08:01:24 pm
content: The program starts running immediately after loading, areas A+B should then be enabled. After that, the program rereads the bootloader back into RAM and jumps to the start of it (i.e. re-run it) so that we can get back control of bootloader commands, this is because the bootloader overwrote parts of itself with our program in RAM.Hmm, I've just realised there may be a problem, if the bootloader at the start of it has initialization that sets the PM1 register (i.e. locks A+B) then that will revert the bits we set. Perhaps we may need to jump back to bootloader but somewhere after the initialisation code. We can find this out by looking at a dump of your V0.10 bootloader code.

author: limbast
author_rank: Contributor
timestamp: August 13, 2025, 12:53:31 pm
content: I looked through the M16C/26 Hardware Manual and did not find the addresses where the bootloader is located.How can I dump the bootloader?With your flasher I can read a full MCU dump, will this be useful?

author: tru
author_rank: Regular Contributor
timestamp: August 13, 2025, 08:02:17 pm
content: The bootloader (boot ROM area) is held in a separate bank that must be switched into in order to read it out. The address range is from 0xfe000 to 0xfffff, and is the same as part of block 1 flash.The memory map is shown here in this document:https://www.renesas.com/en/document/apn/programming-flash-memory-flash-over-usb?srsltid=AfmBOop0OiDD0oNLTGNvVHFkL_z02Kr0FOoV5Yq64EiaXznL3FOR_cUZThere is a dedicated command for dumping the bootloader out but I'm not sure if it is supported by your version:m16cflasher ba_output path=\\.\COM4 id_addr=0x0FFFDF id=00000000000000 from_addr=0x0FF000 to_addr=0x0FFFFF file=bootarea.bin

author: limbast
author_rank: Contributor
timestamp: August 14, 2025, 05:34:07 am
content: Indeed, the location of the Boot ROM area is specified in the Hardware Manual. My mistake is that I searched for the word "bootloader" and studied the section 3.Memory, but it does not show the Boot ROM area. The memory block addresses are specified in section 17.2.Memory Map, I did not look at this section.

author: tru
author_rank: Regular Contributor
timestamp: August 14, 2025, 08:13:29 am
content: A small correction, just noticed that your boot ROM area starts from a slightly lower address than mine so the command to use is:m16cflasher ba_output path=\\.\COM4 id_addr=0x0FFFDF id=00000000000000 from_addr=0x0FE000 to_addr=0x0FFFFF file=bootarea.bin

author: limbast
author_rank: Contributor
timestamp: August 14, 2025, 03:12:39 pm
content: The dump of the VER.0.10 bootloader is in the attachment

author: tru
author_rank: Regular Contributor
timestamp: August 15, 2025, 08:31:24 am
content: That is cool - it seems all of the commands work on older bootloader! I've converted the binary into .mot (motorola hex format) using srec_cat tool. Also generated the disassembly file.The disassembly made using trial version of Renesas development IDE (HEW) with the included M16C/R8 software debugger, and selecting the .mot file as a download module. Also of note, I had to replace the S-record footer in the .mot file for it to be seen as a valid file in HEW.When I get some time will look at it in more detail - other members are welcome to help here. For reference we need these two manuals:https://www.renesas.com/en/document/mah/m16c60-m16c20-m16ctiny-series-software-manual?r=1053151: Software manual which describes the assembly instruction sethttps://www.farnell.com/datasheets/17451.pdf: Hardware manual which describes the MCU's own memory mapped registers, SFR (Special Function Registers)I find it strange that the hardware manual is not actually listed on the Renesas list of documents page!Anyway, as starter, we are interested in the PM1 SFR register and bit0, and as described in the hardware manual it is at address 0x0005. Opening the .asm file in notepad++ and searching for 0005H we find two matches, and I can see they don't modify bit0 so the virtual EEPROM areas are not disabled by it.

author: limbast
author_rank: Contributor
timestamp: August 15, 2025, 10:37:17 am
content: Tru, I found that I initially gave a link to the wrong Hardware Manualhttps://www.farnell.com/datasheets/17451.pdfThis is for the M16C26A MCU. It describes the M30260 and M30263 MCUs.Here is a link to the Hardware Manual for the M16C26 which describes my M30262.https://www.alldatasheet.com/datasheet-pdf/pdf/249845/RENESAS/M16C26.htmlThe documents are different, including the PM1 byte, although the PM10 bit is in the same place.In addition, I noticed that my MCU, in which I loaded your program and tried to read Virtual EEPROM, no longer responds to the main board's messages, although the status LED is still blinking.Before all the experiments, I read several versions of dumps with both the M16C-Flasher program (mot) and your flasher (bin).First, I flashed the MCU with the M16C-Flasher program (Addresses from FA000 to FFFFF). The MCU did not establish communication, there is no response via UART.Then I tried to flash it with your flasher. I read the dump from address F8000 to FFFFF. The flasher gets looping when loading Block 3 from address FA000-FC000. That is, it reaches FBFFF, again reports that it will flash Block 3 and starts flashing from FA000 and so on in a circle.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: August 16, 2025, 01:37:28 pm
content: I can confirm that the upper 4K code of bootarea.bin (the one you've converted to mot) doesn't touch PM1 bits other that bit 7.But what is in low 4K of the same dump? It should belong to 0xFE000-0xFF000 addresses, but looking at the disassembly shows that it treats itself as being mapped to 0xFF000-0xFFFFF indeed. It initializes some SFRs (writing 0x8C to PM1 among them), copies another piece of code from 0xFF1E0 to 0x400 RAM and jumps there. The RAM code part seems to be doing flash programming. There are another two PM1 writes in other parts of that code, one writes 0x08 to entire reg, another one clear bit3. This code also manipulates several undocumented SFRs located near FMRx ones: 0x1B1, 0x1B6, 0x1BF.

author: tru
author_rank: Regular Contributor
timestamp: August 16, 2025, 05:23:37 pm
content: @abyrvalg, thanks. Interesting you're right.Just some extra info... on these MCUs, the reset entry address is user configured, execution starts from the 20bit address (almost 3 bytes) stored in the reset vector address in the vector table. The reset vector address is located inside the dump at 0xFFFFC to 0xFFFFF:0xFFFFC: 000xFFFFD: F00xFFFFE: 0F0xFFFFF: FFOnly the first 3 bytes is used and since the first byte is LSB we need to reverse the order, which gives the reset entry address as: 0x0FF000So the code from 0xFF000 to 0xFFFFF is what I thought was the only code, but we should also look at 0xFE000-0xFEFFF, which abyrvalg did for us already. I have attached the disassembly of the full range.@limbastI should have warned you earlier, that my code was made mostly by copying and pasting from my other projects. It was a 1 hour rush job so no validations and very little testing, etc.I think I know why my program hangs - it is because with some serial drivers (depends on your serial adapter) they do not respect the timeout setting - they simply hang when the MCU does not respond (not sending anything back). I did implement Windows Asynchronous mode - which will always timeout even if the driver does not respect the timeout serial setting, but it is off by default because I didn't have time to test it.Another thing, flashing requires the correct block addresses to be set inside the m16c_mem_map.h source file and I didn't want to go through all documents + models to put them in, only added for my MCU. I don't recommend you do any flashing yet, until we can dump out the virtual EEPROM area using the download to RAM command we are using.

author: abyrvalg
author_rank: Frequent Contributor
timestamp: August 17, 2025, 01:40:57 pm
content: @tru, looks like I've found why your enable_blockab payload doesn't work on limbast's MCU: you don't need that complex "jump back to bootloader" code on this MCU/boot version, just do this instead:Code:BSET 0, 0005H ; set PM10JMP.A 0FF088H ; jump back to serial bootloader entry pointlimbast's VER.0.10 BootROM doesn't copy itself to 0x600 RAM buffer, it runs from 0xFFxxx addresses directly, copying to RAM only small funcs like "read SR", "program 1 page" etc when it receives corresponding commands. Also the DOWNLOAD command (0xFA) RAM address is different, it is 0x546 (version header) / 0x54E (actual code entry point).

author: tru
author_rank: Regular Contributor
timestamp: August 18, 2025, 07:21:15 pm
content: Wow, abyrvalg very nice, I've just tried that with my VER.4.04 bootloader, simply jumping to 0xFF020 does indeed get me back into the bootloader!In the assembly I have assembly .org directive set to 0x600 which is correct for my version, but for limbast, perhaps we need to set to 0x546.Also, I've noticed that some SFRs are write protected by default, controlled with the Protect Register (address 0x000A). The correct download code for limbast could be this:Code:.section rom,code.org 0546h ; Download starting RAM address.byte 'VER.1.00' ; Version headerBSET 1,000AH ; Enable write to PM1 registerBSET 0,0005H ; Set PM10 (bit 0) to 1 in PM1 register (0005H) - enable A+B accessBCLR 1,000AH ; Disable write to PM1 registerJMP 0FF088H ; jump back to serial bootloader entry pointAttached is updated payload binary, and source with corrected srec_cat.bat so it doesn't fill in zeroes. I cannot test it - we will have to wait for limbast.

author: tru
author_rank: Regular Contributor
timestamp: August 18, 2025, 07:43:34 pm
content: My mistake shows I am a noob at assembly. I've just realised that the .org directive will only affect relative addressing instructions, and I could have just used your mentioned code JMP.A instead, which is jump to absolute address.

author: limbast
author_rank: Contributor
timestamp: August 22, 2025, 04:16:02 pm
content: tru, I loaded your program into the MCU using the command:Code:m16cflasher download path=\\.\COM4 id_addr=0x0FFFDF id=00000000000000 file=enable_blockab.mot-v2.binThen I read the "eeprom" using the command:Code:m16cflasher path=\\.\com4 read id_addr=0x0fffdf id=0000000000 from_addr=0x00f000 to_addr=0x00ffff file=eeprom.binThe dump was empty, all bytes are FF.To make sure that access to block A and B works, I wrote data (I just used your BIN) to this area using the command:Code:m16cflasher path=\\.\com4 program id_addr=0x0fffdf id=0000000000 from_addr=0x00f000 to_addr=0x00f017 file=enable_blockab.mot-v2.binYour flasher flashed the entire 4kb area, and not the 24 byte range I specified.I don't know if the data in this area would have been erased if it had been there. Maybe I can't specify the address range to the flasher, since it only works with memory in blocks.Then I read this area and the data was read as it was written. Your program works!Thanks!But there's something else.

author: limbast
author_rank: Contributor
timestamp: August 22, 2025, 04:50:58 pm
content: As I wrote above, after loading the first version of your program (size 140 bytes) and reading the "eeprom" area, my board stopped responding to requests from the main board.I have a second board, it responds to the request, but gives a temperature error. The problem is not in the board, but in the MCU: the MCU ADC pins on both boards have the same voltage. Moreover, I swapped the microcontrollers, and the temperature measurement problem moved from one board to another. Maybe this is a hardware problem with the microcontroller, maybe its internal ADC is broken, or maybe it is software. I managed to order a new MCU, I received it a few days ago, installed it and flashed it with M16C-Flasher, and the board worked fine. I was confused. Since the new MCU is completely empty, including the "eeprom" area, and it worked, I assume that nothing is written to the "eeprom" area, and the data from this area is not used. Am I right? However, I do not exclude that the MCU determines that the "eeprom" area is clean and initializes it with some data. Now, with the help of your program, I have verified that in the MCU that does not communicate with the main board, the EEPROM area is clean, as in the new MCU (and it communicates with the main board), it is not initialized with any data.So, a new question arose: what could have changed in the MCU after loading your first version of the program, which memory areas could have been changed and how to flash a full copy of one MCU to another? Before loading your latest version of the program into the "working" MCU, I can read the dumps of both MCUs, will this be informative for you, tru?PS you need to add to github what you did, thanks for your work!

author: tru
author_rank: Regular Contributor
timestamp: August 22, 2025, 07:36:59 pm
content: Thanks for the insight - very helpful. You are correct, the erase can only do entire blocks, i.e partial block erase is not possible.Programming (flashing) will not work correct for your MCU due to the wrong erase block list, which is defined only for my MCU (M16C/62P). Most likely, it is erasing the wrong block or trying to erase a partial block but failing, because that is not allowed. When I have a bit more time, I will modify the block list to support your M16C/26 series, as well as a new commandline option to select the MCU series.Regarding github, yes, I've recently merged in pull request with changes made by someone else. I think he fixed the retry and loop issue that you mentioned in an earlier post.