So I am working with the SoftwareSerial library. I'm looking at the write function and I see a *reg value being manipulate. I want to find the value of *reg so I traced the value by stepping into each function call.so here we go.
*reg = _transmitPortRegister
_transmitPortRegister = portOutputRegister(port) //I'm working with pin 1 in register D
Continuing...
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
const uint16_t PROGMEM port_to_output_PGM[] = {
NOT_A_PORT,
NOT_A_PORT,
(uint16_t) &PORTB,
(uint16_t) &PORTC,
(uint16_t) &PORTD,
};
My first question is what is the point of (uint16_t) &PORTD? I am assuming that's just the value of PORTD's register because it is being anded with an empty 16 bit int.
Continuing on,
#define PORTB _SFR_IO8(0x05)
#define PORTC _SFR_IO8(0x08)
#define PORTD _SFR_IO8(0x0B)
#define _SFR_IO8(io_addr) _MMIO_BYTE((io_addr) + __SFR_OFFSET)
#define __SFR_OFFSET 0x20
#define _MMIO_BYTE(mem_addr) (*(volatile uint8_t *)(mem_addr))
Now, I followed it all the way here. But how do I find out what actually is the deferenced value? Since this is all IDE, i'm not sure how to GDB this either.
LASTLY, the write function takes in a parameter b, which is a byte. Now in the write function, this is the code to write.
// Write each of the 8 bits
for (uint8_t i = 8; i > 0; --i)
{
if (b & 1) // choose bit
*reg |= reg_mask; // send 1
else
*reg &= inv_mask; // send 0
tunedDelay(delay);
b >>= 1;
}
In that block of code, I am not quite sure why they are doing b & 1. Are they just anding the whole byte with 1? If so, then why comment it as "choose byte" and inside the if-else blocks, they're just oring *reg with reg_mask. How does that translate to sending a one?
Sorry for any confusion, i am glad to clarify any confusing parts of this question. Please let me know.
&is used, since that is the address that the value is stored at. Don't sweat it, it took me years to get my head around pointers. – Majenko Oct 02 '15 at 18:23&= inv_maskclears the same bit. – Majenko Oct 02 '15 at 19:20*reg = *reg | reg_mask. If*regcontains, say0b00101001andreg_maskcontains0b00000010then*regends up as0b00101011and the pin goes high. That register is more than just memory - it is actually the physical hardware of the IO pin. You're not just setting values, you're directly affecting real hardware. By setting a bit in the PORT register you are physically changing the voltage level on the pin from 0V to 5V. – Majenko Oct 02 '15 at 19:26regis0x2b,*regis whatever is at0x2b. – Majenko Oct 02 '15 at 19:34*regorPORTD. Why do you need to "figure out" what is at that address anyway? You are just setting or clearing one bit in it. The rest shouldn't concern you – Majenko Oct 02 '15 at 19:52