Questions regarding PORT functions and bare ATMega328

This may belong in the programming section, but here goes...

I am wanting to program a bare ATMega328 and I have several questions regarding setup and programming:

+I currently have a chip with the UNO bootloader. Is it possible to place a no XTAL (lily?) bootloader on the chip? If so, how would I go about this? Should I get an ISP like the Sparkfun Pocket programmer, or can I use Nick Gammon's sketch like I did for the UNO bootloader?

+If I can place a non-XTAL bootloader on the device, are the two freed pins available as I/O? (Using PORTB)

+Also, could I use PORTA without affecting interrupts on pins 2 and 3? If so, how?

Thanks!

Yes, it is able use bootloader which is use internal clock. It can be burned by the same way as "XTAL bootloader". During this process you have to use a crystal. XTAL pins then can be used as IO. Sorry I don't understand to your last question. Are you discussing ATmega328?

Thanks!

My last question was a bit more on the programming side of things...

Would using the PORTD (sorry) affect anything if I were to have external interrupts on pins 2 and 3? (int.0 and int.1)

This post on Nick Gammons site shows how to put the lilypad bootloader on a Uno (external crystal) chip without the need for the crystal and caps using an external oscillator signal from the Uno programmer.
http://www.gammon.com.au/forum/?id=11637

Would using the PORTD (sorry) affect anything if I were to have external interrupts on pins 2 and 3? (int.0 and int.1)

It is still not clear for me, sorry. Port can be configured by user but only one thing at time also it can be reconfigured in time during APP run. For example you can connect input and output device at once to one pin and switching between. Nice example is use a set of 4 ports as output for display an input for buttons. They wiil work mainly in output mode and let say 30-50 times in second switched to input mode to check the state of buttons. But for INT it have to be continuously input.

Budvar10: It is still not clear for me, sorry. Port can be configured by user but only one thing at time also it can be reconfigured in time during APP run. For example you can connect input and output device at once to one pin and switching between. Nice example is use a set of 4 ports as output for display an input for buttons. They wiil work mainly in output mode and let say 30-50 times in second switched to input mode to check the state of buttons. But for INT it have to be continuously input.

So if I start playing with the values in PORTD for digital outputs, my external interrupts on pins 2 and 3 will not be affected, correct?

What do you mean by affected?

Aha, you mean PORTD on ATmega then you have play with this the way which has not affect to PD2, PD3. If you expect an interrupt on the pin you cannot use it for other things otherwise you could miss an interrupt occurance. You can play with the rest of pins on PORTD. Do we understand together now? Maybe my bad English.

You may have to manipulate pins_arduino.h to add the xtal pins so PB6, PB7 can be called out as additional IO.
Update this area for 2 more pins if they support interrupts, PCINT6 and PCINT7.

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))
#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))

Add two more PB entries to the end of this list for D21, D22

const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
	PD, /* 0 */
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PB, /* 8 */
	PB,
	PB,
	PB,
	PB,
	PB,
	PC, /* 14 */
	PC,
	PC,
	PC,
	PC,
	PC,
};

Add 6,7 to the end of this list for PortB 6 and 7

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
	_BV(0), /* 0, port D */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(0), /* 8, port B */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(0), /* 14, port C */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
};

Also

If the Internal Calibrated RC Oscillator is used as chip clock source, PB7…6 is used as TOSC2…1 input for the
Asynchronous Timer/Counter2 if the AS2 bit in ASSR is set.

I don’t know if the Arduino core files support this directly, you might be on your own if that function is needed.

Or you can use direct port manipulation to control them.
You’ll need to DDRB and set bits 6,7 as 1 or 0 depending on if you want input or output.
Then
byte dataInB = PINB; to read the port, and do something based on bit 6 or 7
PORTB = dataOutB; to write the port.
PORTB = PORTB & 0b01111111; to clear only bit 7
PORTB = PORTB | 0b10000000; to set only bit 7

or the various macros to do the same, I can never rememnber them so I just do it as above.

This is not working anymore?

Budvar10: Aha, you mean PORTD on ATmega then you have play with this the way which has not affect to PD2, PD3. If you expect an interrupt on the pin you cannot use it for other things otherwise you could miss an interrupt occurance. You can play with the rest of pins on PORTD. Do we understand together now? Maybe my bad English.

That was what I was looking for... so I can use the other pins on PORTD as long as I do not change the values of PD2 and PD3.

Also, could I set an internal pull up resistor on those interrupt pins?

CrossRoads:
You may have to manipulate pins_arduino.h to add the xtal pins so PB6, PB7 can be called out as additional IO.
Update this area for 2 more pins if they support interrupts, PCINT6 and PCINT7.

#define digitalPinToPCICR(p)    (((p) >= 0 && (p) <= 21) ? (&PCICR) : ((uint8_t *)0))

#define digitalPinToPCICRbit(p) (((p) <= 7) ? 2 : (((p) <= 13) ? 0 : 1))
#define digitalPinToPCMSK(p)    (((p) <= 7) ? (&PCMSK2) : (((p) <= 13) ? (&PCMSK0) : (((p) <= 21) ? (&PCMSK1) : ((uint8_t *)0))))
#define digitalPinToPCMSKbit(p) (((p) <= 7) ? (p) : (((p) <= 13) ? ((p) - 8) : ((p) - 14)))



Add two more PB entries to the end of this list for D21, D22


const uint8_t PROGMEM digital_pin_to_port_PGM = {
PD, /* 0 /
PD,
PD,
PD,
PD,
PD,
PD,
PD,
PB, /
8 /
PB,
PB,
PB,
PB,
PB,
PC, /
14 */
PC,
PC,
PC,
PC,
PC,
};




Add 6,7 to the end of this list for PortB 6 and 7


const uint8_t PROGMEM digital_pin_to_bit_mask_PGM = {
_BV(0), /* 0, port D /
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6),
_BV(7),
_BV(0), /
8, port B /
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(0), /
14, port C */
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
};




AlsoI don't know if the Arduino core files support this directly, you might be on your own if that function is needed.


Or you can use direct port manipulation to control them.
You'll need to DDRB and set bits 6,7 as 1 or 0 depending on if you want input or output.
Then
byte dataInB = PINB; to read the port, and do something based on bit 6 or 7
PORTB = dataOutB; to write the port.
PORTB = PORTB & 0b01111111; to clear only bit 7
PORTB = PORTB | 0b10000000; to set only bit 7

or the various macros to do the same, I can never rememnber them so I just do it as above.

Thanks for the info! I’m assuming that the changes are for the digitalWrite functions, correct? That my very well be something I may use in the future, although my current project deals with the PORT functions.

Yes, digitalRead & digitalWrite.
The PORT functions will work, you need to set the Data Direction Register (DDRx) for the port.
There’s another register for the pullup resistors as well if you want to enable/disable those.
See Section 14 of the datasheet:

Three I/O memory address locations are allocated for each port, one each for the Data Register – PORTx, Data
Direction Register – DDRx, and the Port Input Pins – PINx. The Port Input Pins I/O location is read only, while the
Data Register and the Data Direction Register are read/write. However, writing a logic one to a bit in the PINx Register,
will result in a toggle in the corresponding bit in the Data Register. In addition, the Pull-up Disable – PUD bit
in MCUCR disables the pull-up function for all pins in all ports when set.

CrossRoads: Yes, digitalRead & digitalWrite. The PORT functions will work, you need to set the Data Direction Register (DDRx) for the port. There's another register for the pullup resistors as well if you want to enable/disable those.

So by setting the PORTD to 1 on both of the external interrupt pins, I can use the internal pull-ups for, say, a button press?

Yes.

So now I have successfully modified the values on PORTB (including XTAL pins) but am having trouble with PORTD.

For some reason, I can't seem to set them to HIGH, even with the digitalWrite function...

Also, I am having to reprogram the bootloader every time I upload code to keep from getting the error while using arduino as isp:

avrdude: verification error, first mismatch at byte 0x0006
         0x64 != 0x60
avrdude: verification error; content mismatch

(The "mismatch at byte XxXXXX" seems to be different every time...)

Now, I have a new problem... Whenever I try to reprogram the bootloader, the serial display gets stuck here:

Atmega chip programmer.
Written by Nick Gammon.
Version 1.28
Compiled on Dec 22 2014 at 16:01:26
Attempting to enter programming mode ...

Did I brick my chip?

Not necessarily.

It could be faulty wiring, or no clock possibly, or the wrong fuse settings.

[quote author=Nick Gammon link=msg=2012802 date=1419295037] Not necessarily.

It could be faulty wiring, or no clock possibly, or the wrong fuse settings. [/quote]

Thanks! It was the clock :)

So now, why do I get the error from avrdude after an upload or two?

Loose wire.