This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Minimalist setup for nrf5340 programming - almost works....

Hello,

I am learning how to program my nrf5340DK

I started using the ncs setup but it is too much overhead for me and I wanted to try a more bare setup and I dont mind if I have to work on a low level.

The following seems to work if I only want to operate on register level - trying out the examples in the PS:

1. Download SES and install

2. Download JLink and install

3. Enable nordic and CMIS support packages under Tools -> Package Manager

4. Create a new project for ncs chips selecting nrf5340_xxA_Application as target

These steps seemed to be enough to get started.

Here is an example directly from the datasheet.

I had to change PWM0 to PWM0_NS but it seems to build and upload to the board.

File    : main.c
Purpose : Generic application start

*/
#include <nrf5340_application.h>
#include <nrf.h>
#include <nrf5340_application_peripherals.h>
#include <stdio.h>
#include <stdlib.h>

#define PWM_CH0_DUTY 8000
#define PWM_CH1_DUTY 8000
#define PWM_CH2_DUTY 8000
#define PWM_CH3_DUTY 8000

#define first_pin 28  // 0.28 = LED1
#define second_pin 29 // 0.29 = LED2

int main(void) {

uint16_t pwm_seq[4] = {PWM_CH0_DUTY, PWM_CH1_DUTY, PWM_CH2_DUTY, PWM_CH3_DUTY};

NRF_PWM0_NS->PSEL.OUT[0] = (first_pin << PWM_PSEL_OUT_PIN_Pos) | 
                        (PWM_PSEL_OUT_CONNECT_Connected <<
                                                 PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM0_NS->PSEL.OUT[1] = (second_pin << PWM_PSEL_OUT_PIN_Pos) | 
                        (PWM_PSEL_OUT_CONNECT_Connected <<
                                                 PWM_PSEL_OUT_CONNECT_Pos);
NRF_PWM0_NS->ENABLE      = (PWM_ENABLE_ENABLE_Enabled << PWM_ENABLE_ENABLE_Pos);
NRF_PWM0_NS->MODE        = (PWM_MODE_UPDOWN_Up << PWM_MODE_UPDOWN_Pos);
NRF_PWM0_NS->PRESCALER   = (PWM_PRESCALER_PRESCALER_DIV_1 <<
                                                 PWM_PRESCALER_PRESCALER_Pos);
NRF_PWM0_NS->COUNTERTOP  = (16000 << PWM_COUNTERTOP_COUNTERTOP_Pos); //1 msec
NRF_PWM0_NS->LOOP        = (PWM_LOOP_CNT_Disabled << PWM_LOOP_CNT_Pos);
NRF_PWM0_NS->DECODER   = (PWM_DECODER_LOAD_Individual << PWM_DECODER_LOAD_Pos) | 
                      (PWM_DECODER_MODE_RefreshCount << PWM_DECODER_MODE_Pos);
NRF_PWM0_NS->SEQ[0].PTR  = ((uint32_t)(pwm_seq) << PWM_SEQ_PTR_PTR_Pos);
NRF_PWM0_NS->SEQ[0].CNT  = ((sizeof(pwm_seq) / sizeof(uint16_t)) <<
                                                 PWM_SEQ_CNT_CNT_Pos);
NRF_PWM0_NS->SEQ[0].REFRESH  = 0;
NRF_PWM0_NS->SEQ[0].ENDDELAY = 0;
NRF_PWM0_NS->TASKS_SEQSTART[0] = 1;


while(1) {
    // Do nothing
};  

}

However, LED1 (pin 0.28 or 28 in this example) does not light up.

Any Ideas on what I am missing make the example work? 

Thanks

/Jonas

Parents
  • I am replying to my own post in order to share the answer.

    Here is an example of a simple LED1 blink.

    /*********************************************************************
    *                    SEGGER Microcontroller GmbH                     *
    *                        The Embedded Experts                        *
    **********************************************************************
    
    -------------------------- END-OF-HEADER -----------------------------
    
    File    : main.c
    Purpose : Generic application start
    
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <nrf.h>
    #include <nrf5340_application.h>
    #include <nrf5340_application_peripherals.h>
    
    #define PIN_GPIO  (28UL)  // Use pin 28 on the board which also is LED1
    
    int main(void)
    {
    
      // Configure GPIO pin as output with standard drive strength.
      NRF_P0_S->PIN_CNF[PIN_GPIO] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
                                    (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                    (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
                                    (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
                                    (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
      
      
      // Toggle GPIO ON/OFF.
      while (1)
      {
        uint32_t volatile tmo;
        
        tmo = 1000000;
        while (tmo--);
        NRF_P0_S->OUTSET = (1UL << PIN_GPIO);    
        
        tmo = 1000000;
        while (tmo--);
        NRF_P0_S->OUTCLR = (1UL << PIN_GPIO);  
      }
    }
    
    /*************************** End of file ****************************/

    In general, there are two main things I needed to fix.

    The first was to realize that the old NRF_GPIO register is now replaced by NRF_P0_S and NRFP1_S (there is also NS) to refer to the two banks of GPIO pins.

    The second is that I needed to use the S appendix and not NS. By default Segger uploads to the Secure area.

    For those who like to start with nrf53 and want to understand the low level things first, perhaps this can be a way. It can be a bit much with the nrfx library and Zephyr on top of that when you come from the arduino world.

  • Hey Jonas! 

    Glad you figured it out! Yes, you should use the secure partition. And I think the NCS setup wont be too much overhead, especially starting out. It would also result in an easier time for us providing you with support. But good thing that you found something that works for you!

    Best regards,

    Elfving

Reply Children
No Data
Related