sandeepmistry / arduino-BLEPeripheral

An Arduino library for creating custom BLE peripherals with Nordic Semiconductor's nRF8001 or nR51822.
MIT License
463 stars 179 forks source link

nRF5 branch: bondStore->putData(...) does block working #68

Closed bojh closed 8 years ago

bojh commented 8 years ago

pairing a device the program stops at: experimental branch: nRF5 File: nrf51822.cpp line 717:

#ifdef NRF_51822_DEBUG
        Serial.println(F("Evt Auth Status"));
        Serial.println(bleEvt->evt.gap_evt.params.auth_status.auth_status);
#endif
        if (BLE_GAP_SEC_STATUS_SUCCESS == bleEvt->evt.gap_evt.params.auth_status.auth_status) {
#if !defined(NRF5) && !defined(NRF51_S130)
          *this->_authStatus = bleEvt->evt.gap_evt.params.auth_status;
#endif
          if (this->_bondStore) {
#ifdef NRF_51822_DEBUG
            Serial.println(F("Storing bond data"));
#endif
#if defined(NRF5) || defined(NRF51_S130)
            this->_bondStore->putData(this->_bondData, 0, sizeof(this->_bondData));  // <==!!!
#else
            this->_bondStore->putData(this->_authStatusBuffer, 0, sizeof(this->_authStatusBuffer));
#endif
          }
bojh commented 8 years ago

with further investigation some method in/out println()'s and defined NRF_51822_DEBUG the pairing event does result in a a log:

Evt Connected 50:94:68:03:f4:de
Peri. Connected event,     central: 50:94:68:03:f4:de, BS: BS.hasData()...
0
Evt Write, handle = 11
02 00 
Evt Sec Params Request  1 1 4 0 0 16
BS.hasData()...
Evt Conn Sec Update 1 2 16
Evt Write, handle = 8192
00 20 0C 05 00 20 B8 03 00 20 00 00 00 00 15 78 00 00 01 00 00 00 1C 01 00 20 D4 1B 00 20 1B 82 01 00 04 01 00 20 00 00 00 00 00 00 00 00 1C 01 00 20 00 00 00 00 00 00 00 00 00 80 00 40 A1 00 00 20 44 85 00 40 04 15 00 40 00 00 00 00 81 88 01 00 70 0D 00 20 70 00 00 00 D4 09 00 20 B3 0C 00 20 00 00 00 00 7A 00 00 20 D8 0B 00 20 7E CF 0C 00 C0 0C 00 20 02 00 00 00 00 00 00 00 40 00 00 20 01 00 00 01 02 00 00 00 01 00 00 01 CA 29 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 20 97 93 00 00 CC 29 
Evt Auth Status
0
Storing bond data
BS.putData()...
BS.clearData()...

and it seems that the 1st FLASH_WAIT_READY in BLEBondStore::clearData() does loop for ever. Because this is more or less the same code as in the nordic nrf_nvmc.c it seems some preconditions are not correct at this time.

sandeepmistry commented 8 years ago

@bojh any more insights on this?

bojh commented 8 years ago

@sandeepmistry I have not gotten for deeper investigation

bojh commented 8 years ago

I've given it another chance. Still the same issue: BLEBondStore::clearData() in the nRF5 branch setting the register: NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos); does halt running. NRF_NVMC pointer=4001E000h is OK and _flashPageStartAddress=7F000h is OK ... as i understand - I can't understand that. The source seems completly correct in comparison with the nordic examples and other people seems are working with the non volatile memory (NVM) with success. This suggests me, that any curious circumstance happens: board revision?

Does anybody has a NVM-working nRF52-DK board using BondStore?

By the way: Two times, the lines with: offset = offset; in the NRF5 source case in BLEBondStore::putData() and BLEBondStore::getData() are curious and seems to be a relic.

bojh commented 8 years ago

I have tested a new board, just received with: BN: nRF52 DK VID: 1366, PID: 1015, SN: 000682092612 and V1.1.0 2016.16 ... but still the same problem! No new idea to solve the issue at the moment!

bojh commented 8 years ago

light at the horizone: just found: https://devzone.nordicsemi.com/question/12293/nvmc-writing-hangs-after-enabling-softdevice/ .. looks more or less easy :-)

bojh commented 8 years ago

Some progress before holiday. With the help of Nordic examples, I have found and adapted a softdevice aware BLEBondStore::clearData() & putData() function implementation. It is realized in a simple blocking way implementation - but is working well. (TODO: Debugging output for do-while loop does quit with a real error!):

#include "nrf_soc.h"
void BLEBondStore::clearData() {
#if defined(__AVR__) || defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__)
  eeprom_write_byte((unsigned char *)this->_offset, 0x00);
#elif defined(NRF51) || defined(NRF52) || defined(__RFduino__)

  int32_t pageNo = (uint32_t)_flashPageStartAddress/NRF_FICR->CODEPAGESIZE;
  uint32_t err_code;
  do{
        err_code = sd_flash_page_erase(pageNo);
  } while(err_code == NRF_ERROR_BUSY);

#endif
}

void BLEBondStore::putData(const unsigned char* data, unsigned int offset, unsigned int length) {
#if defined(__AVR__) || defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MKL26Z64__)
  eeprom_write_byte((unsigned char *)this->_offset, 0x01);

  for (unsigned int i = 0; i < length; i++) {
    eeprom_write_byte((unsigned char *)this->_offset + offset + i + 1, data[i]);
  }
#elif defined(NRF51) || defined(NRF52) || defined(__RFduino__) // ignores offset
  this->clearData();
  // offset = offset;   //!..?

  uint32_t err_code;
  do{
      err_code = sd_flash_write((uint32_t*)_flashPageStartAddress, (uint32_t*)data, (uint32_t)length/4);
  } while(err_code == NRF_ERROR_BUSY);

#endif
}

@sandeepmistry As I have understand this context, this changes have to be done for using all newer softdevices versions (6.x ff). With that inital help I would kindly ask you, to validate improve and merge a solution into the project to get it fixed.

sandeepmistry commented 8 years ago

@bojh please submit a pull request for the suggested changes.

bojh commented 8 years ago

I am now allowed to provide a PR, see: https://github.com/sandeepmistry/arduino-BLEPeripheral/pull/92

sandeepmistry commented 8 years ago

Closed via #92.