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

SW-23. Adjust BLE TX frequency based on 802.15.4 RX frequency #20

Open
wants to merge 32 commits into
base: develop
Choose a base branch
from

Conversation

tryuan99
Copy link
Collaborator

@tryuan99 tryuan99 commented May 2, 2020

This PR builds on top of #17. SCuM is continuously listening for 802.15.4 packets being transmitted from an external OpenMote and broadcasts them as BLE packets. In the meantime, however, it tunes the BLE TX frequency based on the 802.15.4 RX frequency.

This code contains two applications ble_tx_154_rx_track_if and ble_tx_154_rx_track_mean that allow ScuM to adjust the BLE TX frequency tuning code based on the 802.15.4 RX frequency tuning code.

For ble_tx_154_rx_track_if, SCuM records the IF estimate of the received 802.15.4 packets and filters them all of the IF estimates to get an estimated IF estimate. The IF estimate counts how many zero crossings there are in the last 100us, so at the nominal IF frequency of 2.5MHz, there should be 500 zero crossings. Tune the RX fine code until IF estimate is closest to 500 and adjust the TX fine code by the same amount.

For ble_tx_154_rx_track_mean, every few seconds, SCuM stops and listens for packets from the Openmote within +-2 of the current fine code for 800ms each. It then finds the weighted average of the fine codes of all packets received. Find the difference between the current fine code and the average of the received packets and adjust the RX and TX fine codes by that difference.

It also fixes reading the LQI and IF estimate when a 802.15.4 packet is received.

lydia-lee and others added 30 commits October 18, 2019 09:55
[ll] Adding temperature sensor Python code (plotting, taking readings)
app_vars.IF_offset_prev = app_vars.IF_offset;
app_vars.IF_offset = radio_get_IF_estimate();

diff = app_vars.IF_offset / 12; // empirically tuned
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi @tryuan99 could you explain how this 12 is obtained? You said it's empirically tuned. Is there a theoretical number you are referring to start the tuning?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The original value was 20. The reason for this is that a fine code corresponds to around 100kHz in the LO frequency. In 100us, this corresponds to a difference of 20 zero-crossings. Therefore, I adjust the LC frequency code for every IF offset of 20.

However, while testing in the temperature chamber with a ramp rate of 1.5C/min and updating the IF estimate every 800ms, I found 12 to work a bit better (it overshot once and then returned back to its correct value).

app_vars.IF_offset = radio_get_IF_estimate();

diff = app_vars.IF_offset / 12; // empirically tuned
app_vars.rx_fine += diff;
Copy link
Contributor

Choose a reason for hiding this comment

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

This only assumes the LC oscillator drifts within a range that only need to tune the fine code, right? When it is not, such as a large temperature change, mid code calibration may need.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, but since the LC frequency code is not monotonic, I think in order to support a large temperature range, it's probably best to find the coarse/mid codes for different ranges of temperature and then do this "local" fine code calibration with the previously found coarse/mid code in this temperature range.

signed short cdr_tau_history[11] = {0};
#define FILTER_WINDOWS_LEN 11

uint8_t FIR_coeff[FILTER_WINDOWS_LEN] = {4,16,37,64,87,96,87,64,37,16,4};
Copy link
Contributor

@changtengfei changtengfei May 4, 2020

Choose a reason for hiding this comment

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

How does the value of each elements in the coeff arrary come?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmm, I used the same filter that Brad used to have for his radio_housekeeping() function. I can email him.

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