Skip to content
This repository was archived by the owner on Sep 23, 2021. It is now read-only.

runtime configuration not compile-time #145

Closed
DG12 opened this issue Jan 8, 2019 · 3 comments
Closed

runtime configuration not compile-time #145

DG12 opened this issue Jan 8, 2019 · 3 comments

Comments

@DG12
Copy link
Contributor

DG12 commented Jan 8, 2019

Various values including format selection, advertising_interval, main_loop_interval, ble_tx_power should be configurable at run-time (i.e. not by compile time variables which should only define the defaults). This will allow users without the knowledge or ability to set up the tool chain to adjust the configuration.

This might easiest be done by GATT services defined in ble_services folder initialization,Nordic UART Service.
Once this is set up users could use nRFConnect(Either android or IOS) to select a ruuvi; connect, see "Services", select a service (like Experimental Buttonless DFU Service) and see Characteristics , select it and a up arrow icon is displayed. Click on it a dialog box prompting to "Write value" in either a Byte Array or Text .

@DG12
Copy link
Contributor Author

DG12 commented Aug 14, 2019

I took this from pull request "add tunables 152".
At the time I closed it I was having problems uploading images and synchronizing with base version.

Use static variables initialized to DEFINEs then superseded by UICR values.
Notice the simple code to retrieve values from UICR.
This mitigates the need to modify sources and compile to just change (the frequently requested) TX_power, transmit interval, accelerometer thresholds...

This would still make tuning MUCH easier by using nrfjprog or j-link then by recompiling.

ToDo:
1b) Add code in NFC handler to modify UICR iff the password is == 0 or matches.
This would allow use of existing NFC mobile apps (even if calculating the values is awkward, maybe a web page for that is easy)
1b) Add code in gatt ...
2) Create mobile app with nice user interface to send values to code in 1a.

For example:

// initalize "tunables" from header file values.
static uint16_t ble_tx_power                 = BLE_TX_POWER;
static uint16_t advertising_interval_highres = ADVERTISING_INTERVAL_RAW;    // why are these even different??
static uint16_t advertising_interval_raw     = ADVERTISING_INTERVAL_RAW;
static uint16_t advertising_interval_url     = ADVERTISING_INTERVAL_URL;
static uint16_t advertising_interval;
static uint32_t main_loop_interval_raw       = MAIN_LOOP_INTERVAL_RAW;
static uint32_t main_loop_interval_url       = MAIN_LOOP_INTERVAL_URL;
static uint32_t main_loop_interval;
static uint16_t battery_min_v                = BATTERY_MIN_V;
...
...
 // Initialize BLE Stack. Starts LFCLK required for timer operation.
  if( init_ble() ) { init_status |= BLE_FAILED_INIT; }
  bluetooth_configure_advertisement_type(STARTUP_ADVERTISEMENT_TYPE);
  bluetooth_tx_power_set(be_tx_power);                         // configurable
  bluetooth_configure_advertising_interval(ADVERTISING_INTERVAL_STARTUP);

...
...

// During initialization 
  //  Set tuneables to values retained in UICR.
 //First check if UICR is appropriate for this version of the program; if not go with factory defaults defined in .h 
  int version[3]; sscanf(INIT_FWREV, "%1d%1c%1d%1c%1d", &version[0],&x,&version[1],&x, &version[2]); 
  if ( ( NRF_FICR->UICR[0]&& 0xFFFF00)  == version[0] **24 + version[1] **16 + version[2] **8 )  // any minor-minor verion
    {
 //  password                    NRF_FICR->UICR[3]
     packet_format            =  NRF_FICR->UICR[4] & 0xF0000000 >> 28; // 0..15 Example:  03 , 05
     ble_tx_power             =  NRF_FICR->UICR[4] & 0x0F000000 >> 24; // 0 .. 16     ( -xxdB ??)
     main_loop_interval       =  NRF_FICR->UICR[4] & 0x00FFFFFF ;      // 1 .. 16,777.215 seconds aka    279 minutes  Example: 3E8 1,000ms
     advertising_interval     =  NRF_FICR->UICR[5] & 0x00FFFFFF ;      // 1 ..                    aka 4.66 hours               7DA 2,010ms
     accel_sample_rate        =  NRF_FICR->UICR[5] & 0xF0000000 >>24;  // 0 .. 7 LIS2DH12_RATE_400 = 7<<4 see drivers/lis2dh12/lis2dh12.h
     accel_resolution         =  NRF_FICR->UICR[5] & 0x0F000000 >>24;  // 0 .. F 8,6,4
     humidity_oversampling    =  NRF_FICR->UICR[6] & 0xFF000000 >>24;  //           uint_8
     temperature_oversampling =  NRF_FICR->UICR[6] & 0x00FF0000 >>16;
     pressure_oversampling    =  NRF_FICR->UICR[6] & 0x0000FF00 >> 8;
     bme280_IIR               =  NRF_FICR->UICR[7] & 0xFF000000 >>24;  //           uint_8
     bme280_delay             =  NRF_FICR->UICR[7] & 0x00FF0000 >>24;  //           uint_8
     battery_min_v            = (NRF_FICR->UICR[6] & 0x0000000F) * 100 +2000;  // 2.000-2.800   Example 2.100  = 01 *100 +2000
                                                                               //                       2.200  = 02 *100 +2000
                                                                               //                       3.000  = 0A *100 +2000
//     available                                6      000000F0
//     available                                7      0000FFFF
    }

//   example  540007DA 360007DA 0A0A0A08         
//  fmt 5, Tx 4, loop 2.01       Hos=Tos=Pos=10
//                     acc_samp 3      batMin 2.800
//                       acc_reso 6
//                         advertis 2.100

@ojousima
Copy link
Member

ojousima commented Sep 3, 2019

This approach is a bit too specific to RuuviTag in my opinion. It would be difficult to extend to other boards or other sensors, and on the other hand programming UICR requires special equipment and time to figure out the proper configuration options and verify firmware operation.

Supporting these options would require a lot of infrastructure support, such as configuration page where user can select their desired operation in an intuitive manner and get the required bytes and commands to write them.

I think this is better to implement on 3.x firmware at a later time, as the 3.x has been architected to support various sensors, boards and runtime configuration.

@DG12
Copy link
Contributor Author

DG12 commented Sep 3, 2019

The basic concept is to initialize variables to compile time values from default VALUES and permit subsequent user configuration (without compile) which does not require special equipment but does require an app (mobile or desktop) permitting validation an avoiding invalid or poor choices.

UICR is after all named "User Information Configuration Registers"

But you know about future plans. Although all the tunables "I" could think of for RuuviTags only take up 8 of the 32 words available.

Thanks for you thoughts.

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

No branches or pull requests

2 participants