Skip to content
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. nRF5 action!
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

nRF5 action!

Scheduled Pinned Locked Moved My Project
1.9k Posts 49 Posters 630.7k Views 44 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Nca78N Nca78

    @Jokgi said in nRF5 Bluetooth action!:

    @NeverDie I am not sure about all the boards for sell on that site. but I would have to say that any J-link programmer that is packaged as such for $12-$40 dollars is probably counterfeit. Updating these items with newer J-link firmware would more then likely disable them. (On purpose)

    Yes they are of course counterfeit, and using old firmware. You have a message when you use them with Segger software asking you to upgrade to newer firmware and if you accept your programmer is disabled (web is full of solutions to reflash a firmware).
    But if you don't upgrade the firmware it works fine as a SWD programmer, at least for basic use (programming). I have not tried any debugging.

    JokgiJ Offline
    JokgiJ Offline
    Jokgi
    wrote on last edited by
    #901

    @Nca78 Corrrect. It seems to me that a < 50 dollar Nordic nRF52 based Dev kit (or similar) which can be updated would be much less hassle.

    1 Reply Last reply
    1
    • NeverDieN Offline
      NeverDieN Offline
      NeverDie
      Hero Member
      wrote on last edited by NeverDie
      #902

      Are we limited to using RTC0? I've tried switching to RTC1 and RTC2, and I get the sense there are conflicts with both of them and the MySensors code if they're used.

      d00616D 1 Reply Last reply
      0
      • NeverDieN NeverDie

        Are we limited to using RTC0? I've tried switching to RTC1 and RTC2, and I get the sense there are conflicts with both of them and the MySensors code if they're used.

        d00616D Offline
        d00616D Offline
        d00616
        Contest Winner
        wrote on last edited by
        #903

        @NeverDie said in nRF5 Bluetooth action!:

        Are we limited to using RTC0? I've tried switching to RTC1 and RTC2, and I get the sense there are conflicts with both of them and the MySensors code if they're used.

        RTC1 is blocked by arduino (nRF5/delay.c) and RTC0 (nRF51) and RTC2 (nRF52) is used in MySensors (hal/architecture/MyHwNRF5.cpp)

        1 Reply Last reply
        1
        • NeverDieN Offline
          NeverDieN Offline
          NeverDie
          Hero Member
          wrote on last edited by NeverDie
          #904

          Success. I now have a "listen mode" for the nRF52832 radio that's completely controlled by the PPI while the MCU sleeps. Presently, it wakes up the radio every 100ms and listens for 1ms. This means no wasted power from oversight by the MCU. Using just the PPI, I can control to within about 30us over how long to make the cycle period and/or the listening duration.
          0_1505768284420_NewFile2.jpg
          0_1505768305717_NewFile1.jpg

          The scope shots show the current drawn. Scale: 1mv=1ma. As you can see, the DCDC regulator is engaged.

          Next step will be to have packet receipt wake up the MCU via an ISR, so that the packet can be processed. After that, I'll see how narrow I can make the receive window and still receive packets reliably. I think under 100us will be possible. Maybe even less than 60us if the bitrate is 2mbps. :)

          JokgiJ 1 Reply Last reply
          1
          • NeverDieN NeverDie

            Success. I now have a "listen mode" for the nRF52832 radio that's completely controlled by the PPI while the MCU sleeps. Presently, it wakes up the radio every 100ms and listens for 1ms. This means no wasted power from oversight by the MCU. Using just the PPI, I can control to within about 30us over how long to make the cycle period and/or the listening duration.
            0_1505768284420_NewFile2.jpg
            0_1505768305717_NewFile1.jpg

            The scope shots show the current drawn. Scale: 1mv=1ma. As you can see, the DCDC regulator is engaged.

            Next step will be to have packet receipt wake up the MCU via an ISR, so that the packet can be processed. After that, I'll see how narrow I can make the receive window and still receive packets reliably. I think under 100us will be possible. Maybe even less than 60us if the bitrate is 2mbps. :)

            JokgiJ Offline
            JokgiJ Offline
            Jokgi
            wrote on last edited by
            #905

            @NeverDie Great Job!!!! Suggestion... If you are going to use the BTLE Softdevice you will have a smaller receive window if you use the external 32khz crystal option rather then the internal 32khz RC one. (+/- 20ppm with the crystal vs +/- 250 or 500ppm with the RC.

            1 Reply Last reply
            1
            • NeverDieN Offline
              NeverDieN Offline
              NeverDie
              Hero Member
              wrote on last edited by NeverDie
              #906

              At the extreme, one of the questions that will need answering is: what's the minimum number of bytes in a transmitted frame that you really do need before the receiver starts receiving garbage packets? For instance, a 10 byte frame, which should be more than adequate, would take 40us of airtime to either transmit or receive at 2mbps bitrate. One could get to a lower number by maybe sending a null packet as a wake-up packet, in which case maybe you also don't need CRC. So, that leaves you with some preamble, a network ID, and maybe a destination ID--or about 5 bytes. So, that would be around 20us of airtime. One could shrink that further by reducing the number of network ID bytes, but too much of that and possibly one starts to receive garbage packets.

              The RFM69 doesn't try to decode packets whose RSSI is below a specific programmable threshhold. I don't believe the nRF52 radio uses RSSI as a filter in that way though. It seems that the nRF52832 radio tries to decode whatever it's receiving, regardless of the RSSI. Or, at least, that's how I remember it. Anyone else played around with it?

              mfalkviddM 1 Reply Last reply
              0
              • NeverDieN Offline
                NeverDieN Offline
                NeverDie
                Hero Member
                wrote on last edited by
                #907

                @d00616

                I adapted your RTC0 code for handling IRQ's, and it looks like this:

                
                  NRF_RADIO->INTENSET = B100;  //interrupt MCU if a payload is received.
                  // Enable interrupt
                  NVIC_SetPriority(RADIO_IRQn, 15);
                  NVIC_ClearPendingIRQ(RADIO_IRQn);
                  NVIC_EnableIRQ(RADIO_IRQn);
                
                #if __CORTEX_M == 0x04
                #define NRF5_RESET_EVENT(event)                                                 \
                        event = 0;                                                                   \
                        (void)event
                #else
                #define NRF5_RESET_EVENT(event) event = 0
                #endif
                
                
                // This must be in one line
                extern "C" { void RADIO_IRQHandler(void) {packetCounter++; NRF5_RESET_EVENT(NRF_RADIO->EVENTS_PAYLOAD); NRF_RADIO->EVENTS_PAYLOAD=0; }}
                

                Question: Is

                NRF5_RESET_EVENT(NRF_RADIO->EVENTS_PAYLOAD); 
                

                doing anything more than

                NRF_RADIO->EVENTS_PAYLOAD=0;
                

                is?

                d00616D 1 Reply Last reply
                0
                • NeverDieN Offline
                  NeverDieN Offline
                  NeverDie
                  Hero Member
                  wrote on last edited by NeverDie
                  #908

                  The good news is that I can now literally "see" that the listen-mode is receiving packets, because I've programmed the PPI to toggle an LED every time a packet is received (and it only toggles the LED if and only if I know that I'm sending the node packets from a different node). The bad news is that--so far, anyway--it doesn't appear to trigger an IRQ event that wakes up the MCU and runs the ISR.

                  1 Reply Last reply
                  0
                  • NeverDieN NeverDie

                    At the extreme, one of the questions that will need answering is: what's the minimum number of bytes in a transmitted frame that you really do need before the receiver starts receiving garbage packets? For instance, a 10 byte frame, which should be more than adequate, would take 40us of airtime to either transmit or receive at 2mbps bitrate. One could get to a lower number by maybe sending a null packet as a wake-up packet, in which case maybe you also don't need CRC. So, that leaves you with some preamble, a network ID, and maybe a destination ID--or about 5 bytes. So, that would be around 20us of airtime. One could shrink that further by reducing the number of network ID bytes, but too much of that and possibly one starts to receive garbage packets.

                    The RFM69 doesn't try to decode packets whose RSSI is below a specific programmable threshhold. I don't believe the nRF52 radio uses RSSI as a filter in that way though. It seems that the nRF52832 radio tries to decode whatever it's receiving, regardless of the RSSI. Or, at least, that's how I remember it. Anyone else played around with it?

                    mfalkviddM Offline
                    mfalkviddM Offline
                    mfalkvidd
                    Mod
                    wrote on last edited by
                    #909

                    @NeverDie it seems like the preamble can be configured to be either 8 or 16 bits. Not sure if that's of any use, but I've been thinking about adjusting the LoRa preamble to get better sleep times. Maybe that could be applicable for nrf as well.

                    1 Reply Last reply
                    1
                    • NeverDieN Offline
                      NeverDieN Offline
                      NeverDie
                      Hero Member
                      wrote on last edited by NeverDie
                      #910

                      It turns out that using just the standard radiohead packet/frame structure, I'm able to 100% reliably receive a two byte string (in this case, the letter "H" followed by a zero as the termination character) using the above PPI solution with a receive window of about 200ms. That includes preamble, CRC, and a long network ID number.

                      I'm pleased with that result. It's vastly better than without the PPI solution.

                      1 Reply Last reply
                      0
                      • NeverDieN Offline
                        NeverDieN Offline
                        NeverDie
                        Hero Member
                        wrote on last edited by NeverDie
                        #911

                        OK, I'm going to start with this, which works:

                        //A simplified re-mix of code mostly written by d00616
                        
                        #include <nrf.h>
                        #include <MySensors.h>
                        
                        int interrupt = 0;
                        uint32_t theCounter;
                        
                        
                        int8_t myHwSleep(unsigned long ms)
                        {
                          hwSleepPrepare(ms);
                          //while (nrf5_rtc_event_triggered == false) {
                            hwSleep();
                          //}
                          hwSleepEnd(ms);
                          return MY_WAKE_UP_BY_TIMER;
                        }
                        
                        
                        void setup() {
                          // put your setup code here, to run once:
                          Serial.begin(250000);
                          Serial.println("Start");
                        
                          // Configure RTC
                          NRF_RTC0->TASKS_STOP = 1;
                          NRF_RTC0->PRESCALER = 32;  
                          NRF_RTC0->CC[0] = NRF_RTC0->COUNTER + (655);  //comparison for when to turn off the Rx.
                          NRF_RTC0->EVTENSET = RTC_EVTENSET_COMPARE0_Msk;
                          NRF_RTC0->INTENSET = RTC_INTENSET_COMPARE0_Msk;
                          NRF_RTC0->TASKS_START = 1;
                          NRF_RTC0->EVENTS_COMPARE[0] = 0;
                        
                          // Enable interrupt
                          NVIC_SetPriority(RTC0_IRQn, 15);
                          NVIC_ClearPendingIRQ(RTC0_IRQn);
                          NVIC_EnableIRQ(RTC0_IRQn);
                          Serial.println();
                          Serial.println();
                          Serial.println("Starting...");
                        }
                        
                        
                        void loop() {
                        
                          Serial.print(millis());
                          Serial.print(" ");
                          Serial.print(theCounter);
                          Serial.print(" ");
                          Serial.println(interrupt);
                          myHwSleep(5000000);
                        }
                        
                        /**
                         * Reset events and read back on nRF52
                         * http://infocenter.nordicsemi.com/pdf/nRF52_Series_Migration_v1.0.pdf
                         */
                        #if __CORTEX_M == 0x04
                        #define NRF5_RESET_EVENT(event)                                                 \
                                event = 0;                                                                   \
                                (void)event
                        #else
                        #define NRF5_RESET_EVENT(event) event = 0
                        #endif
                        
                        // This must be in one line
                        extern "C" { void RTC0_IRQHandler(void) {   theCounter=NRF_RTC0->COUNTER; NRF5_RESET_EVENT(NRF_RTC0->EVENTS_COMPARE[0]); interrupt++; NRF_RTC0->TASKS_CLEAR = 1; }}
                        

                        and see if I can generate equivalent code which triggers on a pin change instead of an RTC event. If I can get that to work, then I'll take another stab at getting it to work based on the radio receiving a packet.

                        1 Reply Last reply
                        0
                        • NeverDieN Offline
                          NeverDieN Offline
                          NeverDie
                          Hero Member
                          wrote on last edited by NeverDie
                          #912

                          I was only partially done with the code, but I decided to run it anyway. Oddly enough, even though there is no reference to " RTC0_IRQHandler(void)" as being the event handler, it gets fired off anyway whenever I press the button (pin P0.16):

                          
                          #include <nrf.h>
                          #include <MySensors.h>
                          
                          int interrupt = 0;
                          uint32_t theCounter;
                          
                          
                          int8_t myHwSleep(unsigned long ms)
                          {
                            hwSleepPrepare(ms);
                             hwSleep();
                            hwSleepEnd(ms);
                            return MY_WAKE_UP_BY_TIMER;
                          }
                          
                          
                          void setup() {
                            // put your setup code here, to run once:
                            Serial.begin(250000);
                            Serial.println("Start");
                          
                            //Configure GPIOTE 
                            NRF_GPIOTE->CONFIG[0]=0x31001;  // Toggle Event; Pin P0.16; Event Mode 
                                                            //So, any pin change on P0.16 will trigger an event.
                                                             //On the Nordic nRF52 DK, Pin 0.16 is a button.
                                                             
                            NRF_GPIOTE->CONFIG[1]=0x131203;  //Initial setting: HIGH; Toggle Task; Pin P0.18; Task Mode
                                                             //On the Nordic nRF52 DK, Pin 0.18 is an LED.
                                                             //Note: initial setting of HIGH means that the LED will be initially OFF.
                          
                            NRF_GPIOTE->INTENSET=1;  //Enable an event on Pin P0.16 to trigger an interrupt.
                                                             
                            NRF_PPI->CH[0].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];  //P0.16 pin change occured.
                            NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1]; //Toggle LED on pin P0.18.
                            
                            NRF_PPI->CHENSET=B1; //enable Channel 0.
                          
                            // Enable interrupt
                            NVIC_SetPriority(GPIOTE_IRQn, 15);
                            NVIC_ClearPendingIRQ(GPIOTE_IRQn);
                            NVIC_EnableIRQ(GPIOTE_IRQn);
                            Serial.println();
                            Serial.println();
                            Serial.println("Starting...");
                          }
                          
                          
                          void loop() {
                          
                            Serial.print(millis());
                            Serial.print(" ");
                            Serial.print(theCounter);
                            Serial.print(" ");
                            Serial.println(interrupt);
                            myHwSleep(5000000);
                          }
                          
                          /**
                           * Reset events and read back on nRF52
                           * http://infocenter.nordicsemi.com/pdf/nRF52_Series_Migration_v1.0.pdf
                           */
                          #if __CORTEX_M == 0x04
                          #define NRF5_RESET_EVENT(event)                                                 \
                                  event = 0;                                                                   \
                                  (void)event
                          #else
                          #define NRF5_RESET_EVENT(event) event = 0
                          #endif
                          
                          // This must be in one line
                          extern "C" { void RTC0_IRQHandler(void) {   theCounter=NRF_RTC0->COUNTER; NRF5_RESET_EVENT(NRF_RTC0->EVENTS_COMPARE[0]); interrupt++; NRF_RTC0->TASKS_CLEAR = 1; }}
                          

                          So, it looks as though, at present, there can be only a single ISR for an entire sketch?

                          1 Reply Last reply
                          0
                          • NeverDieN Offline
                            NeverDieN Offline
                            NeverDie
                            Hero Member
                            wrote on last edited by NeverDie
                            #913

                            Interesting result. I eliminated most of the sample code, and it actually manages to work even without an ISR! Instead of running an ISR, it appears to simply wake up from exactly where it last fell asleep. Then it continues running until it's put to sleep again:

                            #include <nrf.h>
                            #include <MySensors.h>
                            
                            uint32_t buttonPressCounter=0;
                            
                            
                            int8_t myHwSleep(unsigned long ms)
                            {
                              hwSleepPrepare(ms);
                              hwSleep();
                              hwSleepEnd(ms);
                              return MY_WAKE_UP_BY_TIMER;
                            }
                            
                            
                            void setup() {
                              // put your setup code here, to run once:
                              Serial.begin(250000);
                              Serial.println("Start");
                            
                              //Configure GPIOTE 
                              NRF_GPIOTE->CONFIG[0]=0x31001;  // Toggle Event; Pin P0.16; Event Mode 
                                                              //So, any pin change on P0.16 will trigger an event.
                                                               //On the Nordic nRF52 DK, Pin 0.16 is a button.
                                                               
                              NRF_GPIOTE->CONFIG[1]=0x131203;  //Initial setting: HIGH; Toggle Task; Pin P0.18; Task Mode
                                                               //On the Nordic nRF52 DK, Pin 0.18 is an LED.
                                                               //Note: initial setting of HIGH means that the LED will be initially OFF.
                            
                              NRF_GPIOTE->INTENSET=1;  //Enable an event on Pin P0.16 to trigger an interrupt.
                                                               
                              NRF_PPI->CH[0].EEP = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];  //P0.16 pin change occured.
                              NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[1]; //Toggle LED on pin P0.18.
                              
                              NRF_PPI->CHENSET=B1; //enable Channel 0.
                            
                              // Enable interrupt
                              NVIC_SetPriority(GPIOTE_IRQn, 15);
                              NVIC_ClearPendingIRQ(GPIOTE_IRQn);
                              NVIC_EnableIRQ(GPIOTE_IRQn);
                              Serial.println();
                              Serial.println();
                              Serial.println("Starting...");
                            }
                            
                            
                            void loop() {
                              Serial.print("time=");
                              Serial.print(millis());
                              Serial.print(", buttonPressCounter=");
                              Serial.println(buttonPressCounter++);
                              myHwSleep(5000000);
                            }
                            
                            1 Reply Last reply
                            0
                            • NeverDieN NeverDie

                              @d00616

                              I adapted your RTC0 code for handling IRQ's, and it looks like this:

                              
                                NRF_RADIO->INTENSET = B100;  //interrupt MCU if a payload is received.
                                // Enable interrupt
                                NVIC_SetPriority(RADIO_IRQn, 15);
                                NVIC_ClearPendingIRQ(RADIO_IRQn);
                                NVIC_EnableIRQ(RADIO_IRQn);
                              
                              #if __CORTEX_M == 0x04
                              #define NRF5_RESET_EVENT(event)                                                 \
                                      event = 0;                                                                   \
                                      (void)event
                              #else
                              #define NRF5_RESET_EVENT(event) event = 0
                              #endif
                              
                              
                              // This must be in one line
                              extern "C" { void RADIO_IRQHandler(void) {packetCounter++; NRF5_RESET_EVENT(NRF_RADIO->EVENTS_PAYLOAD); NRF_RADIO->EVENTS_PAYLOAD=0; }}
                              

                              Question: Is

                              NRF5_RESET_EVENT(NRF_RADIO->EVENTS_PAYLOAD); 
                              

                              doing anything more than

                              NRF_RADIO->EVENTS_PAYLOAD=0;
                              

                              is?

                              d00616D Offline
                              d00616D Offline
                              d00616
                              Contest Winner
                              wrote on last edited by
                              #914

                              @NeverDie said in nRF5 Bluetooth action!:

                              Question: Is
                              NRF5_RESET_EVENT(NRF_RADIO->EVENTS_PAYLOAD);

                              doing anything more than
                              NRF_RADIO->EVENTS_PAYLOAD=0;

                              is?

                              Yes. It reads back the register. http://infocenter.nordicsemi.com/topic/com.nordic.infocenter.nrf52/dita/nrf52/migration/functional.html?cp=2_4_0

                              1 Reply Last reply
                              0
                              • NeverDieN Offline
                                NeverDieN Offline
                                NeverDie
                                Hero Member
                                wrote on last edited by
                                #915

                                Whenever I use:

                                #include <MySensors.h>
                                

                                on the nRF52832, there is around a 10 second delay between the end of "void startup()" and the beginning of "loop()". Why is that, and what is the MySensors library doing during that interval?

                                mfalkviddM d00616D 2 Replies Last reply
                                0
                                • NeverDieN NeverDie

                                  Whenever I use:

                                  #include <MySensors.h>
                                  

                                  on the nRF52832, there is around a 10 second delay between the end of "void startup()" and the beginning of "loop()". Why is that, and what is the MySensors library doing during that interval?

                                  mfalkviddM Offline
                                  mfalkviddM Offline
                                  mfalkvidd
                                  Mod
                                  wrote on last edited by
                                  #916

                                  @NeverDie it depends on the value of MY_TRANSPORT_WAIT_READY_MS
                                  See https://github.com/mysensors/MySensors/issues/927 for a discussion on what happens when - we're trying to clarify the documentation.

                                  1 Reply Last reply
                                  0
                                  • d00616D d00616

                                    @NeverDie said in nRF5 Bluetooth action!:
                                    If your goal is to minimize the RX-on time, then you can trigger the RX start and stop by a timer for your minimal window where the frame must be start. Then use the bitcounter top stop the timer in case a packet is received. A shortcut to the end is disabling the RX mode. You can wakeup the CPU with the END event.

                                    P.S.: you can reduce the RX/TX time by enabling fast ramp up in MODECNF0 if you haven't to care about nRF51 compatibility.

                                    NeverDieN Offline
                                    NeverDieN Offline
                                    NeverDie
                                    Hero Member
                                    wrote on last edited by NeverDie
                                    #917

                                    @d00616 said in nRF5 Bluetooth action!:

                                    P.S.: you can reduce the RX/TX time by enabling fast ramp up in MODECNF0 if you haven't to care about nRF51 compatibility.

                                    Thanks for the tip. I tried it both ways. The first scope capture below is taken without MODECNF0 enabled on bit 0, and the second is with it enabled on bit 0.
                                    0_1505865330798_NewFile5.png
                                    0_1505865340675_NewFile6.png

                                    I don't really see any difference. Do you?
                                    Scale: 1mv=1ma. Scope captures of current drawn.

                                    Maybe @jokgi can comment? His bio says he's a Senior Field Application Engineer at Nordic Semiconductor.
                                    Maybe he sees (or knows) something that's not apparent about the fast ramp enable bit?

                                    1 Reply Last reply
                                    0
                                    • NeverDieN NeverDie

                                      Whenever I use:

                                      #include <MySensors.h>
                                      

                                      on the nRF52832, there is around a 10 second delay between the end of "void startup()" and the beginning of "loop()". Why is that, and what is the MySensors library doing during that interval?

                                      d00616D Offline
                                      d00616D Offline
                                      d00616
                                      Contest Winner
                                      wrote on last edited by
                                      #918

                                      @NeverDie said in nRF5 Bluetooth action!:

                                      Whenever I use:
                                      #include <MySensors.h>

                                      on the nRF52832, there is around a 10 second delay between the end of "void startup()" and the beginning of "loop()". Why is that, and what is the MySensors library doing during that interval?

                                      As an alternative, you can define '#define MY_CORE_ONLY' and use ' transportInit(); transportSetAddress(MY_NODE_ID);' to initialize the radio. This dosn't work at the moment with the nRF5. I'm currently looking what the reason is. All radio registers are equal when it's initialized after MySensors normal and my setup(). It's not able to send or receive packages.

                                      Maybe someone has an idea about the reason. Here is my code for nRF5 and other with nRF24.

                                      // Undefine to work in gateway mode
                                      #define MY_CORE_ONLY
                                      
                                      
                                      #define MY_NODE_ID (0)
                                      
                                      // Enable debug
                                      #define MY_DEBUG
                                      #define MY_DEBUG_VERBOSE_RF24
                                      #define MY_DEBUG_VERBOSE_NRF5_ESB
                                      
                                      // Enable and select radio type attached
                                      #ifndef ARDUINO_ARCH_NRF5
                                      #define MY_RADIO_NRF24
                                      #else
                                      #define MY_RADIO_NRF5_ESB
                                      #include <nrf.h>
                                      #endif
                                      //#define MY_RADIO_RFM69
                                      //#define MY_RADIO_RFM95
                                      
                                      //#define MY_OTA_LOG_SENDER_FEATURE
                                      //#define MY_OTA_LOG_RECEIVER_FEATURE
                                      
                                      #ifndef MY_CORE_ONLY
                                      #define MY_GATEWAY_SERIAL
                                      #endif
                                      #include <MySensors.h>
                                      
                                      void state() {
                                      #ifdef ARDUINO_ARCH_NRF5
                                       Serial.println("----------------------------------");
                                       Serial.print("NRF_RADIO->STATE  ");
                                       Serial.println(NRF_RADIO->STATE, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_READY  ");
                                       Serial.println(NRF_RADIO->EVENTS_READY, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_ADDRESS  ");
                                       Serial.println(NRF_RADIO->EVENTS_ADDRESS, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_PAYLOAD  ");
                                       Serial.println(NRF_RADIO->EVENTS_PAYLOAD, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_END  ");
                                       Serial.println(NRF_RADIO->EVENTS_END, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_DISABLED  ");
                                       Serial.println(NRF_RADIO->EVENTS_DISABLED, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_DEVMATCH  ");
                                       Serial.println(NRF_RADIO->EVENTS_DEVMATCH, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_DEVMISS  ");
                                       Serial.println(NRF_RADIO->EVENTS_DEVMISS, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_RSSIEND  ");
                                       Serial.println(NRF_RADIO->EVENTS_RSSIEND, HEX);
                                       Serial.print("NRF_RADIO->EVENTS_BCMATCH  ");
                                       Serial.println(NRF_RADIO->EVENTS_BCMATCH, HEX);
                                       Serial.print("NRF_RADIO->CRCSTATUS  ");
                                       Serial.println(NRF_RADIO->CRCSTATUS, HEX);
                                       Serial.print("NRF_RADIO->RXMATCH  ");
                                       Serial.println(NRF_RADIO->RXMATCH, HEX);
                                       Serial.print("NRF_RADIO->RXCRC  ");
                                       Serial.println(NRF_RADIO->RXCRC, HEX);
                                       Serial.print("NRF_RADIO->DAI  ");
                                       Serial.println(NRF_RADIO->DAI, HEX);
                                       Serial.print("NRF_RADIO->PACKETPTR  ");
                                       Serial.println(NRF_RADIO->PACKETPTR, HEX);
                                       Serial.print("NRF_RADIO->FREQUENCY  ");
                                       Serial.println(NRF_RADIO->FREQUENCY, HEX);
                                       Serial.print("NRF_RADIO->TXPOWER  ");
                                       Serial.println(NRF_RADIO->TXPOWER, HEX);
                                       Serial.print("NRF_RADIO->MODE  ");
                                       Serial.println(NRF_RADIO->MODE, HEX);
                                       Serial.print("NRF_RADIO->PCNF0  ");
                                       Serial.println(NRF_RADIO->PCNF0, HEX);
                                       Serial.print("NRF_RADIO->PCNF1  ");
                                       Serial.println(NRF_RADIO->PCNF1, HEX);
                                       Serial.print("NRF_RADIO->BASE0  ");
                                       Serial.println(NRF_RADIO->BASE0, HEX);
                                       Serial.print("NRF_RADIO->BASE1  ");
                                       Serial.println(NRF_RADIO->BASE1, HEX);
                                       Serial.print("NRF_RADIO->PREFIX0  ");
                                       Serial.println(NRF_RADIO->PREFIX0, HEX);
                                       Serial.print("NRF_RADIO->PREFIX1  ");
                                       Serial.println(NRF_RADIO->PREFIX1, HEX);
                                       Serial.print("NRF_RADIO->TXADDRESS  ");
                                       Serial.println(NRF_RADIO->TXADDRESS, HEX);
                                       Serial.print("NRF_RADIO->RXADDRESSES  ");
                                       Serial.println(NRF_RADIO->RXADDRESSES, HEX);
                                       Serial.print("NRF_RADIO->CRCCNF  ");
                                       Serial.println(NRF_RADIO->CRCCNF, HEX);
                                       Serial.print("NRF_RADIO->SHORTS  ");
                                       Serial.println(NRF_RADIO->SHORTS, HEX);
                                       Serial.print("NRF5_RADIO_TIMER->MODE ");
                                       Serial.println(NRF5_RADIO_TIMER->MODE);
                                       Serial.print("NRF5_RADIO_TIMER->BITMODE ");
                                       Serial.println(NRF5_RADIO_TIMER->BITMODE);
                                       Serial.print("NRF5_RADIO_TIMER->SHORTS ");
                                       Serial.println(NRF5_RADIO_TIMER->SHORTS);
                                       Serial.print("NRF5_RADIO_TIMER->PRESCALER ");
                                       Serial.println(NRF5_RADIO_TIMER->PRESCALER);
                                        // Reset compare events
                                      #ifdef NRF51
                                        for (uint8_t i=0;i<4;i++) {
                                      #else
                                        for (uint8_t i=0;i<6;i++) {
                                      #endif
                                       Serial.print("NRF5_RADIO_TIMER->EVENTS_COMPARE[");
                                       Serial.print(i);
                                       Serial.print("] ");
                                       Serial.println(NRF5_RADIO_TIMER->EVENTS_COMPARE[i]);
                                      }
                                      Serial.println("----------------------------------");
                                      #endif
                                      }
                                      
                                      void setup() {
                                        Serial.begin(115200);
                                        
                                        #ifdef MY_CORE_ONLY
                                        transportInit();
                                        delay(1000);
                                        transportSetAddress(MY_NODE_ID);
                                        #endif
                                      }
                                      
                                      void loop() {
                                        state();
                                      
                                        #ifdef MY_CORE_ONLY
                                        // Check for packages
                                        if (transportAvailable()) {
                                          uint8_t buffer[256];
                                          uint8_t num = transportReceive(&buffer);
                                          for (int i=0;i<num;i++) {
                                            if (buffer[i]<0x10) Serial.print("0");
                                            Serial.print(buffer[i], HEX);
                                            Serial.print(" ");
                                          }
                                          Serial.println();
                                        }
                                        #endif
                                      
                                        // Pause
                                        //sleep(1000); don't use this on SAMD. The device must be restored with reset doubleclick
                                        delay(1000);
                                        
                                        // Send data
                                        //transportSend(MY_NODE_ID, "abcd", 4, false);
                                      }
                                      

                                      @NeverDie said in nRF5 Bluetooth action!:

                                      @d00616 said in nRF5 Bluetooth action!:

                                      P.S.: you can reduce the RX/TX time by enabling fast ramp up in MODECNF0 if you haven't to care about nRF51 compatibility.

                                      Thanks for the tip. I tried it both ways. The first scope capture below is taken without MODECNF0 enabled on bit 0, and the second is with it enabled on bit 0.

                                      Have you checked the MODECNF0 register after ramp up? Maybe the register must be changed in a specific state?

                                      d00616D 1 Reply Last reply
                                      1
                                      • NeverDieN Offline
                                        NeverDieN Offline
                                        NeverDie
                                        Hero Member
                                        wrote on last edited by NeverDie
                                        #919

                                        Not sure why, but so far I haven't been able to get the radio to generate an interrupt (after it receives a packet) that directly wakes the MCU. So, as a workaround, I'm using PPI to have the radio toggle a GPIO output pin, which is directly shorted to a GPIO input pin. Changes in that input pin are able to trigger an interrupt which wakes the MCU. So, in this circuitous way, I'm able to get the radio to wake the MCU. It works, but with a propagation delay, and obviously I shouldn't have to be doing it so indirectly.

                                        Has anyone else had any success yet in waking the MCU from sleep upon packet receipt by the radio?

                                        Which interrupt register in the MCU is the interrupt generated by the radio tied to? Perhaps it needs to be premptively cleared. I think the next step is to check whether the radio's interrupt is even being received by the MCU.

                                        1 Reply Last reply
                                        0
                                        • d00616D d00616

                                          @NeverDie said in nRF5 Bluetooth action!:

                                          Whenever I use:
                                          #include <MySensors.h>

                                          on the nRF52832, there is around a 10 second delay between the end of "void startup()" and the beginning of "loop()". Why is that, and what is the MySensors library doing during that interval?

                                          As an alternative, you can define '#define MY_CORE_ONLY' and use ' transportInit(); transportSetAddress(MY_NODE_ID);' to initialize the radio. This dosn't work at the moment with the nRF5. I'm currently looking what the reason is. All radio registers are equal when it's initialized after MySensors normal and my setup(). It's not able to send or receive packages.

                                          Maybe someone has an idea about the reason. Here is my code for nRF5 and other with nRF24.

                                          // Undefine to work in gateway mode
                                          #define MY_CORE_ONLY
                                          
                                          
                                          #define MY_NODE_ID (0)
                                          
                                          // Enable debug
                                          #define MY_DEBUG
                                          #define MY_DEBUG_VERBOSE_RF24
                                          #define MY_DEBUG_VERBOSE_NRF5_ESB
                                          
                                          // Enable and select radio type attached
                                          #ifndef ARDUINO_ARCH_NRF5
                                          #define MY_RADIO_NRF24
                                          #else
                                          #define MY_RADIO_NRF5_ESB
                                          #include <nrf.h>
                                          #endif
                                          //#define MY_RADIO_RFM69
                                          //#define MY_RADIO_RFM95
                                          
                                          //#define MY_OTA_LOG_SENDER_FEATURE
                                          //#define MY_OTA_LOG_RECEIVER_FEATURE
                                          
                                          #ifndef MY_CORE_ONLY
                                          #define MY_GATEWAY_SERIAL
                                          #endif
                                          #include <MySensors.h>
                                          
                                          void state() {
                                          #ifdef ARDUINO_ARCH_NRF5
                                           Serial.println("----------------------------------");
                                           Serial.print("NRF_RADIO->STATE  ");
                                           Serial.println(NRF_RADIO->STATE, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_READY  ");
                                           Serial.println(NRF_RADIO->EVENTS_READY, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_ADDRESS  ");
                                           Serial.println(NRF_RADIO->EVENTS_ADDRESS, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_PAYLOAD  ");
                                           Serial.println(NRF_RADIO->EVENTS_PAYLOAD, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_END  ");
                                           Serial.println(NRF_RADIO->EVENTS_END, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_DISABLED  ");
                                           Serial.println(NRF_RADIO->EVENTS_DISABLED, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_DEVMATCH  ");
                                           Serial.println(NRF_RADIO->EVENTS_DEVMATCH, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_DEVMISS  ");
                                           Serial.println(NRF_RADIO->EVENTS_DEVMISS, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_RSSIEND  ");
                                           Serial.println(NRF_RADIO->EVENTS_RSSIEND, HEX);
                                           Serial.print("NRF_RADIO->EVENTS_BCMATCH  ");
                                           Serial.println(NRF_RADIO->EVENTS_BCMATCH, HEX);
                                           Serial.print("NRF_RADIO->CRCSTATUS  ");
                                           Serial.println(NRF_RADIO->CRCSTATUS, HEX);
                                           Serial.print("NRF_RADIO->RXMATCH  ");
                                           Serial.println(NRF_RADIO->RXMATCH, HEX);
                                           Serial.print("NRF_RADIO->RXCRC  ");
                                           Serial.println(NRF_RADIO->RXCRC, HEX);
                                           Serial.print("NRF_RADIO->DAI  ");
                                           Serial.println(NRF_RADIO->DAI, HEX);
                                           Serial.print("NRF_RADIO->PACKETPTR  ");
                                           Serial.println(NRF_RADIO->PACKETPTR, HEX);
                                           Serial.print("NRF_RADIO->FREQUENCY  ");
                                           Serial.println(NRF_RADIO->FREQUENCY, HEX);
                                           Serial.print("NRF_RADIO->TXPOWER  ");
                                           Serial.println(NRF_RADIO->TXPOWER, HEX);
                                           Serial.print("NRF_RADIO->MODE  ");
                                           Serial.println(NRF_RADIO->MODE, HEX);
                                           Serial.print("NRF_RADIO->PCNF0  ");
                                           Serial.println(NRF_RADIO->PCNF0, HEX);
                                           Serial.print("NRF_RADIO->PCNF1  ");
                                           Serial.println(NRF_RADIO->PCNF1, HEX);
                                           Serial.print("NRF_RADIO->BASE0  ");
                                           Serial.println(NRF_RADIO->BASE0, HEX);
                                           Serial.print("NRF_RADIO->BASE1  ");
                                           Serial.println(NRF_RADIO->BASE1, HEX);
                                           Serial.print("NRF_RADIO->PREFIX0  ");
                                           Serial.println(NRF_RADIO->PREFIX0, HEX);
                                           Serial.print("NRF_RADIO->PREFIX1  ");
                                           Serial.println(NRF_RADIO->PREFIX1, HEX);
                                           Serial.print("NRF_RADIO->TXADDRESS  ");
                                           Serial.println(NRF_RADIO->TXADDRESS, HEX);
                                           Serial.print("NRF_RADIO->RXADDRESSES  ");
                                           Serial.println(NRF_RADIO->RXADDRESSES, HEX);
                                           Serial.print("NRF_RADIO->CRCCNF  ");
                                           Serial.println(NRF_RADIO->CRCCNF, HEX);
                                           Serial.print("NRF_RADIO->SHORTS  ");
                                           Serial.println(NRF_RADIO->SHORTS, HEX);
                                           Serial.print("NRF5_RADIO_TIMER->MODE ");
                                           Serial.println(NRF5_RADIO_TIMER->MODE);
                                           Serial.print("NRF5_RADIO_TIMER->BITMODE ");
                                           Serial.println(NRF5_RADIO_TIMER->BITMODE);
                                           Serial.print("NRF5_RADIO_TIMER->SHORTS ");
                                           Serial.println(NRF5_RADIO_TIMER->SHORTS);
                                           Serial.print("NRF5_RADIO_TIMER->PRESCALER ");
                                           Serial.println(NRF5_RADIO_TIMER->PRESCALER);
                                            // Reset compare events
                                          #ifdef NRF51
                                            for (uint8_t i=0;i<4;i++) {
                                          #else
                                            for (uint8_t i=0;i<6;i++) {
                                          #endif
                                           Serial.print("NRF5_RADIO_TIMER->EVENTS_COMPARE[");
                                           Serial.print(i);
                                           Serial.print("] ");
                                           Serial.println(NRF5_RADIO_TIMER->EVENTS_COMPARE[i]);
                                          }
                                          Serial.println("----------------------------------");
                                          #endif
                                          }
                                          
                                          void setup() {
                                            Serial.begin(115200);
                                            
                                            #ifdef MY_CORE_ONLY
                                            transportInit();
                                            delay(1000);
                                            transportSetAddress(MY_NODE_ID);
                                            #endif
                                          }
                                          
                                          void loop() {
                                            state();
                                          
                                            #ifdef MY_CORE_ONLY
                                            // Check for packages
                                            if (transportAvailable()) {
                                              uint8_t buffer[256];
                                              uint8_t num = transportReceive(&buffer);
                                              for (int i=0;i<num;i++) {
                                                if (buffer[i]<0x10) Serial.print("0");
                                                Serial.print(buffer[i], HEX);
                                                Serial.print(" ");
                                              }
                                              Serial.println();
                                            }
                                            #endif
                                          
                                            // Pause
                                            //sleep(1000); don't use this on SAMD. The device must be restored with reset doubleclick
                                            delay(1000);
                                            
                                            // Send data
                                            //transportSend(MY_NODE_ID, "abcd", 4, false);
                                          }
                                          

                                          @NeverDie said in nRF5 Bluetooth action!:

                                          @d00616 said in nRF5 Bluetooth action!:

                                          P.S.: you can reduce the RX/TX time by enabling fast ramp up in MODECNF0 if you haven't to care about nRF51 compatibility.

                                          Thanks for the tip. I tried it both ways. The first scope capture below is taken without MODECNF0 enabled on bit 0, and the second is with it enabled on bit 0.

                                          Have you checked the MODECNF0 register after ramp up? Maybe the register must be changed in a specific state?

                                          d00616D Offline
                                          d00616D Offline
                                          d00616
                                          Contest Winner
                                          wrote on last edited by
                                          #920

                                          @d00616 said in nRF5 Bluetooth action!:

                                          Maybe someone has an idea about the reason. Here is my code for nRF5 and other with nRF24.

                                          Now, I have the NRF5_ESB working under MY_CORE_ONLY condition. The HFCLK is not initialized. I do some code changes to allow using the radio in core only mode.

                                          NeverDieN 2 Replies Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          13

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular