Understand how to turn a pin on from the bootloader?

Just curious if anyone can clarify or correct me if I'm missing something. For project specific reasons I need to write a pin high during the bootloader process. It is a design flaw that I will eliminate on the next version I build but for now I have to work with what I have. If anyone knows or is able can you correct or verify that I am going about this correctly. I've tried 2 methods but this is slightly out of my wheel house and I am grasping at straws.

This I figured would work but it won't compile and program correctly

DDRB = DDRB |=0b00000001;
PORTB = PORTB |=0b00000001;

14:58:34: [ERROR] Verifying Flash...Failed! address=0x1fffe expected=0x09 actual=0x00

Don't know what my thought process is here but it didn't work either. I'm including both the top section
for setting the pin and the section from the main section of the bootloader

  #define MEMON_PORT	  PORTB
  #define MEMON_DDR		  DDRB
  #define MEMON_PIN		  PINB
  #define MEMON			  PINB0
int main(void) {
  uint8_t ch;
  
  //	POWER ON THE FLASH MEMORY -ADDED BY CHARLIE
  	MEMON_DDR |=_BV(MEMON);
  	MEMON_PIN |=_BV(MEMON);

Because the obvious question is why do I need to do it. The external flash memory is on a separate power circuit and I need to turn it on, so that the bootloader can use it for reprogramming the mcu if needed.

This I figured would work but it won't compile and program correctly

What does that mean? It doesn't compile because it's written correctly this way:

DDRB |= 0b00000001;
PORTB |= 0b00000001;

This configures B1 as an output and sets it HIGH.

14:58:34: [ERROR] Verifying Flash...Failed! address=0x1fffe expected=0x09 actual=0x00

What would you like to tell us with that error line? Is it the output of uploading? Why don't you tell us what avrdude command line you used? It's definitely not compiler output.

  	MEMON_DDR |=_BV(MEMON);

Although that works it's definitely bad programming style. You should use the input register bit definition to set the data direction register.

MEMON_PIN |=_BV(MEMON);

Why do you set the port input register?
I guess the intention is to set the output register:

PORTB |= _BV(PORTB0);

You can do the abstracting defines yourself.

Sorry sometime words and I don't work so well together.

this error

14:58:34: [ERROR] Verifying Flash...Failed! address=0x1fffe expected=0x09 actual=0x00

is what atmel studio throws out when I try to burn that bootloader to the chip. I have and often use avrdude for the same purpose but haven't actually tried burning this bootloader to this chip with avrdude. Good idea and thank you for that.

This configures B1 as an output and sets it HIGH.

Sleep deprivation has my mind fried but if it is B1 then that is 100% my problem and you are my hero. If that is the case how do I set B0 as I have a 1 in the zero position of the 8 bits. Sorry for such a stupid question but I am scratching my head in confusion and hoping against hope that you are correct :slight_smile:

Charlie1985:
Because the obvious question is why do I need to do it. The external flash memory is on a separate power circuit and I need to turn it on, so that the bootloader can use it for reprogramming the mcu if needed.

Can you just add a pullup resistor on the pin instead? The pins powerup in input mode so the pullup will give you the needed high signal.

Sleep deprivation has my mind fried but if it is B1 then that is 100% my problem and you are my hero.

Excuse me, it's B0.

If that is the case how do I set B0 as I have a 1 in the zero position of the 8 bits.

Your code is doing that and my last snippet is doing the same (as I wrote).

Thank you two so much for your help. I gotta tell you when I read what you wrote about me writing B1 high I started jumping around the room with excitement. Mostly running on caffine these days with no actual nutrition. Even though it was already correct I needed a little hope. Thank you both. I actually tested it with a pullup to ensure that the pin never actually went low. Ultimately my real problem isn’t being caused by my not turning the pin on, because the pin is on, and it appears to be on with enough time to activate. The fact that the pullup didn’t solve the problem only confirms that lacking voltage on that pin was not my real problem.

Here is the solution to the posed question though for anyone who ever needs it.

Arduino bootloaders include a pinsdef file which is where the pins and ports are defined so you can use the variables PORTB and DDRB if you don’t want to try to read and write registers using their address. Here is code for turning a pin into an output and writing it high.

DDRB |= 0b00010111;     // SETS PINS PB0,PB1,PB2, AND PB4 AS OUTPUTS  LEAVES PINS PB3, PB5, PB6, AND PB7 AS WHATEVER THEY AREADY WERE (NOTE THE   |=)
PORTB |= 0b00010101;    // THIS WRITES PINS PB0, PB2, AND PB4 HIGH

//   NOTE THIS OPERATION IS SIGNIFICANTLY FASTER THAN digitalWrite(<pin>,HIGH);

when coding this each bit represents one pin on the port.
DDR sets the direction of the pin 0 is input 1 is output
DDRB is specific to Port B on the chip. So there are 8 pins on that port 0-7. each is represented by one of the bits.
0b indicates binary
|= basically leaves 1s in every spot that was already a one but will change 0s to 1s everywhere that a 1 is added on the right of the equal sign

Example: DDRB=0b11000000 (this has a 1 in the 6 and 7 address of the byte)
if I write DDRB |=0b00000001 (I’m telling it if either of the bit strings is a 1 then make the result a 1
now DDRB is going to be equal to 0b11000001

Hope that’s easy to understand.

Same deal with PORTB except this basically chooses if the pin is HIGH or LOW 1=high 0=low.

Good luck and happy coding