avatar

spencerogden

Member Since: October 10, 2011

Country: United States

  • Thanks bboy, I was able to hookup an I2C device using your instructions on pins 16 and 17 of the nRF52832 Breakout.

  • NVMC Non-Volatile Memory Storage in Flash

    I’m trying to work out an example of storing values between resets in Flash. I seem to have succeeded, but have wiped out the boot loader. At the moment, my sketch is loaded, and it is reading the correct value from Flash, but I cannot get the Breakout board into boot loader mode. I assume this is because I have written over a critical page of memory in the boot loader code. So I’m left with 2 questions:

    1) How can I determine what a safe address is to write to? Some code uses CODEPAGESIZE times CODESIZE minus 1 to determine the last page of flash, and uses that. Using that method, I calculated an address of 0x7F000. But writing to that cause the board to go into bootloader mode on startup, even when pin6 was not pressed. So, following another example which had a hardcoded address, I rolled the dice and used 0x1000108C (EDIT: digging further, this is the address for a UICR register, which is not to be set during operation, whoops). This succeeded insofar as I was able to reboot the device into normal mode, and my sketch correctly read the value, however, as described above, the device no longer goes into bootloader mode. So, How to calculate a safe address space to use for storing values which doesn’t impact the bootloader or the sketch code? Perhaps some hints here

    2) Is my device bricked? I assume it would be possible to program with a JTAG to regain function, but seeing as I don’t have one, and don’t have the first clue on how to use one, am I out of luck?

    Code for writing to Flash, CAREFUL, it would appear this code can brick your device:

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(38400);
    
      uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
      uint32_t pg_num = NRF_FICR->CODESIZE - 1;
      Serial.print("Page Size: "); Serial.println(pg_size);
      Serial.print("Page Num: "); Serial.println(pg_num);
    
      uint32_t *calc_addr = (uint32_t *)(pg_size * pg_num);
      Serial.print("Suggested Address: ");
      Serial.println((uint32_t)calc_addr);
    
      uint32_t *addr = (uint32_t *)0x1000108C;
      Serial.print("Used Address: ");
      Serial.println((uint32_t)addr);
    
      Serial.print("Value before test: ");
      Serial.println(*addr);
    
      // Change the false on the next line to true to enable writing
      // Be extremely CAREFUL, this code may brick your device. DO NOT USE
      if(*addr != 1234 && false){
        Serial.print("Value before erase: ");
        Serial.println(*addr);
        flash_page_erase(addr);
        Serial.print("Value after erase: ");
        Serial.println(*addr);
        flash_word_write(addr,1234);
        Serial.print("Value after write: ");
        Serial.println(*addr);
      }else{
        Serial.print("Retrieved: ");
        Serial.println(*addr);
      }
    
    
    }
    
    void flash_word_write(uint32_t *addr, uint32_t value){
      NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);
      while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};
      *addr = value;
      while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};
      NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
      while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};
    }
    
    void flash_page_erase(uint32_t *addr){
      NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Een << NVMC_CONFIG_WEN_Pos);
      while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};
      NRF_NVMC->ERASEPAGE = (uint32_t)addr;
      while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};
      NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);
      while (NRF_NVMC->READY == NVMC_READY_READY_Busy){};
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
    }
    
  • The timing is difficult. I suggest unplugging the FTDI to power down the nrf52, holding down the pin6 button, then plugging in the FTDI. This should get you into the boot loader every time.

  • I ended up editing Phat.cpp and editing out:

    //#include <avr/pgmspace.h>

    I’m not sure what that does to the PROGMEM tag on the following consts, but it does compile and work. Perhaps if would be more proper to comment out that line and include the ESP library, but I haven’t tested that.

  • I got Blink working, and then was working through the Posting to Phant tutorial.

    I downloaded the Phant library and added to Documents/Arduino/libraries/Phant/ Then used the Arduino Library manager to see that it was available. On compile I get: /Users/spencerogden/Documents/Arduino/libraries/Phant/src/Phant.cpp:23:26: fatal error: avr/pgmspace.h: No such file or directory #include <avr/pgmspace.h>

    Am I missing a library? Since everything else is spelled out very clearly, a note that you have to install the Phant library on this page would be helpful.

  • Any thoughts on how well this would work pointing at a water surface?

  • Agree, very eager for a dev board like the GPS-09133.

No public wish lists :(