The data sheet says I can:
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.
Note that the SBI instruction can be used to toggle one single bit in a port.
Smiley
The data sheet says I can:
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.
Note that the SBI instruction can be used to toggle one single bit in a port.
Smiley
If I'm reading the datasheet correctly, writing a 1 to the PINxn register engages the internal pull-up resistor on that particular pin if DDRxn is set to make that pin an input.
So... if the pin is configured as an output, writing a 1 to the PIN register will toggle the pin - while if the pin is an input, writing a 1 will engage the pull-up.
(Of course... I COULD be wrong. :) )
I do this quite often and find it very useful in bit banging code etc. The PINx just became a writable SFR instead of being read only - this allowed to add the toggle feature without wasting a tight SFR address space with a dedicated toggle SFR.
What d.sht. is that for ? I've seen code here that uses it to as a way to toggle an output pin. I GUESS it's smaller code-wise than using the C operator to do it, for 1 bit toggling anyway.
(Of course... I COULD be wrong. :) )
The pullup is turned on by writing a 1 to the PORTx bit while the port is configured as INPUT.
Why on Earth would I ever want to toggle an input?
I've seen code here that uses it to as a way to toggle an output pin.
I GUESS it's smaller code-wise than using the C operator to do it, for 1 bit toggling anyway.
What does a C operator have to do with it, anyway?!?
PORTB ^= (1<<OUTPUT); // C operator used to tog. a bit.
PORTB ^= (1<<OUTPUT); // C operator to tog. a bit.
What does a C operator have to do with it, anyway?!?
The same goes here: What does writing to PINx have to do with the C ^ operator?
Hmm, well I should've said "...than using the PORTx way to do it.", since using ^ would happen using PORTx or PINx.
Set an output then clear an output is 2 instructions. Toggle the output is 1 instruction. Makes tight loops faster. Guys like Igor use this to bitbang fast stuff like usb.
You could toggle to trigger an external ISR. Not sure why.
Set an output then clear an output is 2 instructions.
P.S. KitCarlson, please do not say gibberish.
... Guys like Igor use this to bitbang fast stuff like usb.
I think I need to reread that section of the data sheet though as I'm still not 100% about this. It is difficult to explain to folks how to do something when you aren't completely sure why they would do it.
And more realistic use cases?
[edit]
No, wait, that doesn't make sense. Oh, crap I'm going to bed and rethink this tomorrow if my brain returns to my skull.
[/edit]
Smiley
And more realistic use cases?
Why? Why cares. There has been a LOT of talk here about ARM vs. AVR. All the ARMs I've looked at have set/clear/toggle.
Mostly I find I use it as a debugging toggle on a spare pin/LED. so not that bit a deal, but if using the conventional way be very careful if the port is manipulated i9n an ISR and the mainline.
Lee
Quote:Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.
Why on Earth would I ever want to toggle an input?
You are writing a logic one to PINxn which doesn't seem to make sense since this is where you would normally read the input levels. This unusual operation then causes the output at the corresponding PORTxn pin to toggle.
Don
Okay, this is making sense now. Toggling the output uses a seemingly nonsense operation of setting the PINx bit when that pin is in the output mode - in the same way that setting the pullup resistor uses the also seemingly nonsense operation of setting a bit in PORTx when that pin is in the input mode. I've always used the bitwise operator to toggle bits, but I guess this makes sense if I want to optimize the operation. A bit weird way to toggle a bit, but I get it now.
Smiley
Toggling the output uses a seemingly nonsense operation of setting the PINx bit when that pin is in the output mode
In Xmega you have DIR (DDR), DIRSET, DIRCLR, DIRTGL, OUT (PORT), OUTSET, OUTCLR, OUTTGL, IN (PIN). So they seem to have gone completely over-board to cover all bases ;-) (in case it's not clear *SET sets bits, *CLR clears bits and *TGL toggles bits)
+1 for toggling LEDs (Lee was first) if I don't care about off or on, but about some change in state.
Set an output then clear an output is 2 instructions. Toggle the output is 1 instruction.
It's at least 4 instructions
in temp,SREG cli "set of four" out SREG,temp
if used in main in many cases.
If you consider IO registers as additional low functionality working registers, then:
What is more(rather off topic in PINx subject), read/write to IOs is twice as fast as push/pop so slow pushpopping on ISR entry/return can be cut in half with those IOs, IMHO more suitable for that task.
Bit/nibble low IO locations are good for static variables(with toggling and sbis as if()) while byte IOs (like GPIORs, TCNT, OCR etc) are good for ISR pushpopping.
You could toggle to trigger an external ISR. Not sure why.
I see using this as a way to emulate a "trap" instruction that is sorely missing on the AVRs.
As to why:
I have a backburner project that will use this.
My use is to use it on INT0 to grab control of the processor so that it can then talk to low level code that eventually talks to GDB for
source level debugging using only a serial interface rather than the current method of depending on DW or JTAG.
I've got all the pieces together to do it,
just haven't finished it up.
Down in the bowls of the GDB interface it currently uses the Break instruction.
If that is instead changed to use the single instruction that simulates this high level trap (requires a custom build of GDB), you can leave the guts of the low level GDB code alone.
Anyway, debugging is already possible without this "trap" instruction but you need to have a way to trap into the low level AVR "gdbmon" code for "code" breakpoints.
("code" breakpoints being breakpoints that modify the code/flash with the "trap" instruction).
"code" breakpoints can be done in s/w only without modifying the flash. i.e. "soft" breakpoints.
It requires enabling a hard interrupt that is set but never cleared
while "looking" for the desired breakpoints.
The ISR looks at the PC to see if a desired breakpoint has been reached, if not, it leaves the ISR but does not clear the pending interrupt source. It works but
then the AVR does not run anywhere near full speed.
Having a single instruction that can "trap" into the low level debugger code is key to making real-time breakpoints happen.
The optimum method is to use "soft" breakpoints that monitor the PC in ISR while single stepping but then use the "code" breakpoints to allow the code to run full speed up the desired code breakpoint.
--- bill
If that is instead changed to use the single instruction that simulates this high level trap (requires a custom build of GDB), you can leave the guts of the low level GDB code alone.
The optimum method is to use "soft" breakpoints that monitor the PC in ISR
What about JTAG?
RocketMan_Len wrote:Of course you ARE wrong.
(Of course... I COULD be wrong. :) )The pullup is turned on by writing a 1 to the PORTx bit while the port is configured as INPUT.
Don
Quote:
If that is instead changed to use the single instruction that simulates this high level trap (requires a custom build of GDB), you can leave the guts of the low level GDB code alone.
To generate the INT0 you have to do an OUT or something? If that's the case then why not just an RCALL to the trap code?
RCALL is not good enough. It only gets you +/- 2k
that will not work in the general case.
I need something is only a single word instruction *AND* can block all interrupts.
The goal is to provide source level debugging for something like an Arduino board where the only h/w interface you know you have available is a serial port.
I'll post a new thread with full details when I finally have it fully up and working.
--- bill
RocketMan_Len wrote:Of course you ARE wrong..
(Of course... I COULD be wrong. :) )
Yup - I misread the datasheet. My bad... :oops:
And more realistic use cases?
RCALL is not good enough. It only gets you +/- 2k
Quote:
RCALL is not good enough. It only gets you +/- 2k
So use CALL?
--- bill