Is there a way to rescue my processor from a reset deadlock - microcontroller

I have a board with an XMC1400 MCU on it. It is a custom board with LEDs and buttons and so on.
So I accidentally add a '''XMC_SCU_RESET_AssertMasterReset()''' line at the beginning of the code... This function cause xmc to reset but it doesn't just reset the program counter, it also clears everything and ends the debug connection. And since it happens so quickly I cannot reconnect before it resets again. For the one who doesn't know, when you load a program to the xmc, it gets written to the flash, and once it's loaded it will always run with power up.
I know in some boards there are some pins used to clear to board when shorted but there is no such a thing in this one.
There are however several bootstrap loaders(can and uart). But they are disabled by a flash parameter called BMI. I don't have much hope but is there a way to rescue this processor?
Thanks!

Related

Cannot clone nRF52840 to reproduce low deep sleep current

I currently have firmware that can reach an average deep sleep current of ~130uA. I can reach this level reproducibly on one of the boards I have.
successful deep sleep
Trouble is, when I try to clone this chip onto other chips using the nRF Programmer (Connect) app, I get extremely high power consumption, average of ~20mA at all times, seems the device doesn't reach deep sleep properly. Tried this on several other boards, so I don't believe it's simply a problem of something shorting. Strangely, the application just runs fine, the current is just several times normal for the same functionality.
unsuccessful deep sleep
Does anyone have any ideas on how I can truly clone the flash of one device, onto another? Clearly the "save as file" on nRF Connect isn't doing this. Erasing all and reuploading, starting from a blank chip and writing,
FYI I'm using the nRF52840 module by Raytac (MDBT50Q), implemented on a custom board. This board SHOULD be capable of going down to ~33uA, which I have observed in the past with this very board. By some combination of erasing all, reprogramming, setting the 3.3V logic level(nrfjprog --memwr 0x10001304 --val 5), etc,
For posterity, I did actually find the solution! For anyone else in a similar boat to me, the winning command is:
nrfjprog.exe --readcode --readuicr --readram [filename.hex]
Apparently, the --readram was the winning flag, as without it the sketch simply doesn't run at the same current consumption for whatever reason. But now, I can reproducibly image and transfer identical firmware, which was what I was after.

How do I make sure the Arduino only run this line of code once even after reset?

I have a real-time Clock module and I'm trying to make an RGB Clock out of it. There is a particular line of code that sets the time and date to the real-time clock module. I put this in the setup code but every time I reset the Arduino it runs that line of code again. Is there any way that I can make sure that once this line in of code is run it will never run again even if I reset the Arduino?
It is a broad question which goes beyond programming. The answer to your concrete problem is "Remove that line of code" from setup, it will not run (I am sure you know this). However, you should provide some physical input (buttons + rudimentary menu-like interface) to set the clock on first usage. A second way of setting the time can be a serial port to which you can physically connect. This requires some code to read that serial port in your loop method.
In the release version of you Clock firmware I would leave just reading the time stored in EEPROM (from RTC module or an external chip), not the hard-coded value in setup.
Your RTC might have a bit saying "RTC stopped", which you might use to switch to "normal behavior". It will be set when removing power and the RTC-battery. The RTC will probably read "1-Jan-1970 00:00" then, and won't increment unless set.
However, your demo code to set the RTC is just demo code, not intended to really use as is. (See Victor's response for more details)

Monitor buttons acting totally incorrectly - trying to switch input source instead of showing the OSD

I am a bit new here, English is not my native, so I am sorry for any possible misspelling.
I have a very odd problem - my Xiaomi Mi Surface Display 34" (XMMNTWQ34 model) monitor buttons act really strange - instead of calling the monitor OSD, pressing any of 4 present buttons tries to switch to another possible input source (this is even not their function!), but no luck: just 3 seconds of the black screen and it turns back to the initial image. Let me explain how I got into this.
I have a monitor named before, which has 4 input ports: 2 DP and 2 HDMI. There is a PC always connected to the monitor via the DP interface (DP1 to be exact). Today I tried to connect a second PC via HDMI to the HDMI1 port. It went totally good, I was able to switch between PCs using a monitor OSD. But I thought it was too long and complicated to press a dozen buttons on OSD just to change an input source, so started to google any other programmatical methods of doing such thing.
Some fact: there are no drivers for this monitor on the Internet (it actually works at full 3440x1440#144 Hz resolution/refresh rate via DP interface without any trouble, but Windows sees it as "Generic PnP Monitor", so I see no way to fix it without a relevant driver).
I have found that any VESA-compatible monitor has the 0x60 parameter, which means exactly "input source", so altering the value of this parameter switches the input source without the need to call an OSD. I have found that the possible values of this 0x60 parameter for my monitor provided by several utilities are: 0x0F, 0x10, 0x11, and 0x12. But setting any of these values got me no luck - the screen just flashed black and nothing more. Moreover, those utilities showed that the current value of the 0x60 parameter was 0x07 - described as "S-Video 1" input source, and it did not change at any made tries. But my monitor does not even have such input ports!
But I discovered a total disaster a bit later - when I tried to switch the input source via OSD, I was not able to call it - any of the 4 buttons on the monitor was causing a black flash and nothing more! So OSD is now totally unavailable! This is madness. I can't enter the OSD, I can't change the input source without turning off any one of 2 connected PCs, I can't do anything which is supposed to be made via OSD. Rebooting and reattaching of every possible thing has no effect - even with 2 PCs being connected to monitor and waiting to enter a BIOS password (no OS loaded whatsoever): pressing any button on the monitor causes only black flash and nothing more, no OSD called. I guess this is a strictly monitor firmware issue because the OSD worked well until yesterday.
I have absolutely no idea how to solve this, I googled this all day long, but no luck. System restore did not change anything. Please help. Thank you all very much.
Same issue after using ControlMyMonitor App. At the time being, i didn't found any solution to get the OSD back. And I didn't found any solution to factory reset the monitor, I don't know if it's possible.
I strongly discourage users to use any kind of VESA com application on this Xiaomi 34 monitor !
Now, the best solution in order to switch inputs, is to disconnect or shutdown one of the computer connected, ans it will switch automaticaly to the only one remaining. (Or use a VESA script...)

Arduino - Trying to keep a pin high, but it's not working

I'm building a small robot that uses a relay to power the motors. To run the relay, I have it connected to pins 11 and 12. If I use something like the Blink example, where it turns the pin on, then off a second later, it works fine. However, what I'm trying to do is keep a pin on until an IF statement is met. When I run it, it turns the pin on for a millisecond or so, then off permanently. How could I get this to work?
Well, I have a couple guesses, but your description is vague without knowing what the IF statement is...maybe it is being met somehow without your knowledge.
I am pretty certain the light is staying on longer than a millisecond in order for you to see it. As a side note, here is an interesting, related article: http://www.100fps.com/how_many_frames_can_humans_see.htm
Are you debouncing? http://arduino.cc/en/Tutorial/Debounce
I can imagine a simple program with an IF to count button presses -- or the timing of -- where, without debouncing, you will meet the conditional without it seeming correct.
This is just one possibility, but without knowing the code, or the setup it's hard to say.

Arduino Bootloader

Can someone please explain how the Arduino bootloader works? I'm not looking for a high level answer here, I've read the code and I get the gist of it.
There's a bunch of protocol interaction that happens between the Arduino IDE and the bootloader code, ultimately resulting in a number of inline assembly instructions that self-program the flash with the program being transmitted over the serial interface.
What I'm not clear on is on line 270:
void (*app_start)(void) = 0x0000;
...which I recognize as the declaration, and initialization to NULL, of a function pointer. There are subsequent calls to app_start in places where the bootloader is intended to delegate to execution of the user-loaded code.
Surely, somehow app_start needs to get a non-NULL value at some point for this to all come together. I'm not seeing that in the bootloader code... is it magically linked by the program that gets loaded by the bootloader? I presume that main of the bootloader is the entry point into software after a reset of the chip.
Wrapped up in the 70 or so lines of assembly must be the secret decoder ring that tells the main program where app_start really is? Or perhaps it's some implicit knowlege being taken advantage of by the Arduino IDE? All I know is that if someone doesn't change app_start to point somewhere other than 0, the bootloader code would just spin on itself forever... so what's the trick?
Edit
I'm interested in trying to port the bootloader to an Tiny AVR that doesn't have separate memory space for boot loader code. As it becomes apparent to me that the bootloader code relies on certain fuse settings and chip support, I guess what I'm really interested in knowing is what does it take to port the bootloader to a chip that doesn't have those fuses and hardware support (but still has self-programming capability)?
On NULL
Address 0 does not a null pointer make. A "null pointer" is something more abstract: a special value that applicable functions should recognize as being invalid. C says the special value is 0, and while the language says dereferencing it is "undefined behavior", in the simple world of microcontrollers it usually has a very well-defined effect.
ATmega Bootloaders
Normally, on reset, the AVR's program counter (PC) is initialized to 0, thus the microcontroller begins executing code at address 0.
However, if the Boot Reset Fuse ("BOOTRST") is set, the program counter is instead initialized to an address of a block at the upper end of the memory (where that is depends on how the fuses are set, see a datasheet (PDF, 7 MB) for specifics). The code that begins there can do anything—if you really wanted you could put your own program there if you use an ICSP (bootloaders generally can't overwrite themselves).
Often though, it's a special program—a bootloader—that is able to read data from an external source (often via UART, I2C, CAN, etc.) to rewrite program code (stored in internal or external memory, depending on the micro). The bootloader will typically look for a "special event" which can literally be anything, but for development is most conveniently something on the data bus it will pull the new code from. (For production it might be a special logic level on a pin as it can be checked nearly-instantly.) If the bootloader sees the special event, it can enter bootloading-mode, where it will reflash the program memory, otherwise it passes control off to user code.
As an aside, the point of the bootloader fuse and upper memory block is to allow the use of a bootloader with no modifications to the original software (so long as it doesn't extend all the way up into the bootloader's address). Instead of flashing with just the original HEX and desired fuses, one can flash the original HEX, bootloader, and modified fuses, and presto, bootloader added.
Anyways, in the case of the Arduino, which I believe uses the protocol from the STK500, it attempts to communicate over the UART, and if it gets either no response in the allotted time:
uint32_t count = 0;
while(!(UCSRA & _BV(RXC))) { // loops until a byte received
count++;
if (count > MAX_TIME_COUNT) // 4 seconds or whatever
app_start();
}
or if it errors too much by getting an unexpected response:
if (++error_count == MAX_ERROR_COUNT)
app_start();
It passes control back to the main program, located at 0. In the Arduino source seen above, this is done by calling app_start();, defined as void (*app_start)(void) = 0x0000;.
Because it's couched as a C function call, before the PC hops over to 0, it will push the current PC value onto the stack which also contains other variables used in the bootloader (e.g. count and error_count from above). Does this steal RAM from your program? Well, after the PC is set to 0, the operations that are executed blatantly "violate" what a proper C function (that would eventually return) should do. Among other initialization steps, it resets the stack pointer (effectively obliterating the call stack and all local variables), reclaiming RAM. Global/static variables are initialized to 0, the address of which can freely overlap with whatever the bootloader was using because the bootloader and user programs were compiled independently.
The only lasting effects from the bootloader are modifications to hardware (peripheral) registers, which a good bootloader won't leave in a detrimental state (turning on peripherals that might waste power when you try to sleep). It's generally good practice to also fully initialize peripherals you will use, so even if the bootloader did something strange you'll set it how you want.
ATtiny Bootloaders
On ATtinys, as you mentioned, there is no luxury of the bootloader fuses or memory, so your code will always start at address 0. You might be able to put your bootloader into some higher pages of memory and point your RESET vector at it, then whenever you receive a new hex file to flash with, take the command that's at address 0:1, replace it with the bootloader address, then store the replaced address somewhere else to call for normal execution. (If it's an RJMP ("relative jump") the value will obviously need to be recalculated)
Edit
I'm interested in trying to port the bootloader to an Tiny AVR that doesn't have separate memory space for boot loader code. As it becomes apparent to me that the bootloader code relies on certain fuse settings and chip support, I guess what I'm really interested in knowing is what does it take to port the bootloader to a chip that doesn't have those fuses and hardware support (but still has self-programming capability)?
Depending on your ultimate goal it may be easier to just create your own bootloader rather than try to port one. You really only need to learn a few items for that part.
1) uart tx
2) uart rx
3) self-flash programming
Which can be learned separately and then combined into a bootloader. You will want a part that you can use spi or whatever to write the flash, so that if your bootloader doesnt work or whatever the part came with gets messed up you can still continue development.
Whether you port or roll your own you will still need to understand those three basic things with respect to that part.

Resources