Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add shadow register for UBRRH to keep it separate from UCSRC #309

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

StefanKrupop
Copy link

In e.g. ATmega8 UBRRH and UCSRC registers share the same I/O location.
Bit URSEL decides in which physical register written data should go.
As there are now more registers then I/O locations, "shadow" versions of
certain regbit functions that store to a pointer ("shadow register")
instead of the main registers in avr->data[] were introduced.
UBRRH was moved into a shadow register, while UCSRC stays a regular register.
Therefore, writes to UBRRH/UCSRC with URSEL bit set do not set the baudrate
falsely anymore.

In e.g. ATmega8 UBRRH and UCSRC registers share the same I/O location.
Bit URSEL decides in which physical register written data should go.
As there are now more registers then I/O locations, "shadow" versions of
certain regbit functions that store to a pointer ("shadow register")
instead of the main registers in avr->data[] were introduced.
UBRRH was moved into a shadow register, while UCSRC stays a regular register.
Therefore, writes to UBRRH/UCSRC with URSEL bit set do not set the baudrate
falsely anymore.
@tykefcz
Copy link

tykefcz commented Jan 18, 2019

Thank You, I applied Your patch and working well. Great job.
Tykef.

Comment on lines +242 to +259
if (addr == p->ubrrh.reg) {
if (p->ubrrh.reg == p->r_ucsrc) {
// UBRRH and UCSRC registers can share the same I/O location.
// URSEL bit decides which register gets written. If it's UBRRH,
// store to shadow register, else to regular register
if ((v & (1 << 7)) == 0) { // URSEL
avr_regbit_setto_shadow(avr, p->ubrrh, v, &p->ubrrh_shadow);
} else {
avr_core_watch_write(avr, addr, v);
}
} else {
// If UBRRH have different I/O locations, update shadow register and
// regular register
avr_core_watch_write(avr, addr, v);
avr_regbit_setto_shadow(avr, p->ubrrh, v, &p->ubrrh_shadow);
}
return;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that sort of behaviour should be encoded in the core declaration, for example a new field with 'ursel' would both allow feature testing and encode the feature in a generic way. here it's all hard coded.
Also for that sort of feature, I don't /think/ we really need the new _shadow accessors for regbits, it's a simple enough behaviour that is just visible in the set/get for this feature, AFAIK...

Personally, I would introduce a more generic behaviour where the two (or more) values are stored part of a regbit with a discriminant, instead of having to carry around a pointer to an uint8_t...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants