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

Feat/nrf52xxx/adc/make resolution changeable #4701

Draft
wants to merge 5 commits into
base: dev
Choose a base branch
from

Conversation

milkpirate
Copy link

@milkpirate milkpirate commented Jan 14, 2025

As requested per #4660 (review)

What I did

ADC

  • Change ADC methods to pointer receivers
  • Make ADC resolution adjustable
  • Remove nonsensical calculations (at least to me they seemed like, please correct me if I'm wrong)
  • Update ADC documentation reference

Open questions

  • Will make sense to change the signature of ADC.Get() to return an error? Since it will change the interface and might break things.


// Return 16-bit result from 12-bit value.
return uint16(value << 4)
return rawValue.Get()
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this break something? Like a client code out there in the wild expects 16bit value.

Copy link
Author

Choose a reason for hiding this comment

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

Well, honestly this whole block makes no sense to me:

  • Why convert a Uint to an int and then check if its <0?
  • Then value << 4 does not convert something from 12 to 16 bit, it multiplies the value by $2^4 = 16$. Why?

I may not be aware of some special cases why this was done like so, maybe @aykevl (the original author) can shed some light on this.

Copy link
Contributor

@ysoldak ysoldak Jan 17, 2025

Choose a reason for hiding this comment

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

I believe the idea is (though I can't find this in documentation, probably picked up this from slack conversations) the value is always 16bit (i.e. ADC max is always 65535). But when hardware can't deliver that, we simply have less resolution. This way the client code does not need to worry about ADC MAX.

Copy link
Author

Choose a reason for hiding this comment

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

Ahhh! Ohhh!... Ok, well then the shift must depend on the resolution. Can add that if you like. Then it remain compatible with current usages.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, correct, shift depends on ADC resolution.

nrf.SAADC.ENABLE.Set(nrf.SAADC_ENABLE_ENABLE_Enabled << nrf.SAADC_ENABLE_ENABLE_Pos)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

So now we going to have ADC automatically enabled on NRF chips. If the comment is true, then probably it's fine.
How can we confirm that? NRF chip is particularly good for projects there extreme low power consumption is required (hibernation). Will this change jeopardise this?

Copy link
Author

Choose a reason for hiding this comment

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

Well I would expect initialization code to be in a function called InitADC(), and not in Configure(). If(!) InitADC() is always called (maybe by tinygo somewhere), then yes, then the ADC will be always on. Further I do not know if the comment is correct 🤷🏻 probably @aykevl known.

If not it will only be turned on if one does InitADC(). I guess it will break every code that does not InitADC().

This poses the question: Whats valued more coherent code or not breaking existing one?

I am defiantly more leaning to the first, but this is not my party 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

Right, I did assume wrong, InitADC() is not called in runtime init method on NRF chips, like InitSerial() does, for example. See https://github.com/tinygo-org/tinygo/blob/release/src/runtime/runtime_nrf.go#L29-L33
And this example confirms that, client code need to call it explicitly: https://github.com/tinygo-org/tinygo/blob/release/src/examples/adc/adc.go#L12

Not sure at the moment if this is by design or simply inconsistency that we want to fix.
@aykevl

Copy link
Member

Choose a reason for hiding this comment

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

This is by design. It you are not using ADC then you don't have to bring it with you.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, why do we init serial unconditionally then?

Copy link
Member

@deadprogram deadprogram Jan 18, 2025

Choose a reason for hiding this comment

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

Several reasons, one of which is that without serial, you cannot use the auto-detect of 1200 baud for kicking into bootloader mode.

Copy link
Author

Choose a reason for hiding this comment

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

So leave it in? @deadprogram

@milkpirate milkpirate force-pushed the feat/nrf52xxx/adc/make-resolution-changeable branch from e993531 to 46150cd Compare January 18, 2025 16:09
case nrf.SAADC_RESOLUTION_VAL_14bit:
rawValue <<= 2
default:
rawValue <<= 4 // 12bit
Copy link
Author

Choose a reason for hiding this comment

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

The switch case can be replaced by:

	// max precision 14bit (<<= 2, for 16 bit value)
	// min precision 8bit (<<= 8, for 16 bit value)
	// resolution constants 8bit ~ 0, 14bit ~ 3
	precisionAdjustment := 8 - 2*nrf.SAADC.RESOLUTION.Get()
        rawValue <<= precisionAdjustment

its more compact, but also "magical". Just tell me what you prefer.

Copy link
Contributor

Choose a reason for hiding this comment

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

I like this simple linear function conversion instead of a multiline switch 👍

nrf.SAADC.ENABLE.Set(nrf.SAADC_ENABLE_ENABLE_Enabled << nrf.SAADC_ENABLE_ENABLE_Pos)
}
Copy link
Author

Choose a reason for hiding this comment

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

So leave it in? @deadprogram

@milkpirate milkpirate force-pushed the feat/nrf52xxx/adc/make-resolution-changeable branch from 46150cd to 7703573 Compare January 18, 2025 17:09
Signed-off-by: Paul Schroeder <[email protected]>
@milkpirate milkpirate force-pushed the feat/nrf52xxx/adc/make-resolution-changeable branch from 7703573 to 33e7cd0 Compare January 18, 2025 17:29
Copy link
Contributor

@ysoldak ysoldak left a comment

Choose a reason for hiding this comment

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

Looks fine to me.
Not 100% onboard with (unnecessary) pointer receiver change, but also have nothing against.
Feel free do 'magic' conversion for resolution adjustment, but it is fine with switch too.
Ready to approve once PR is not a draft anymore.

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