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

nRF51822 PWM and GPIOTE: differrences between Keil MDK(ARMCC) and GNU_GCC_ARM Compiler

Hello everybody!

I have a problem with compilers for nRF51822. My problems: I create a pwm signal ~38Khz, duty 30% at pin 30 of nRF51822. This process is work well. I want use the function:

nrf_drv_gpiote_out_task_enable(pin)
nrf_drv_gpiote_out_task_disable(pin)

to Enable and Disable pwm signal to GPIO (pin 30). With Keil MDK is good (as the followd picture), but with gcc compiler is not good (as the second picture). I use SDK11, pwm_library example

Source code:

APP_PWM_INSTANCE(PWM1,1);                   // Create the instance "PWM1" using TIMER1.

static volatile bool ready_flag;            // A flag indicating PWM status.

void pwm_ready_callback(uint32_t pwm_id)    // PWM callback function
{
    ready_flag = true;
}

#define enable_pwm_out(pin)			nrf_drv_gpiote_out_task_enable(pin)
#define disable_pwm_out(pin)		nrf_drv_gpiote_out_task_disable(pin)
int main(void)
{
    ret_code_t err_code;
    
	
	/*2 channels PWM, 38,4Khz - 26us, p30 and p8*/
    app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_2CH(26L, 30, 8);
    
    /* Switch the polarity of the second channel. */
		pwm1_cfg.pin_polarity[0] = APP_PWM_POLARITY_ACTIVE_HIGH;
    pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
    
    /* Initialize and enable PWM. */
    err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
    APP_ERROR_CHECK(err_code);
    app_pwm_enable(&PWM1);
    
    
    while(true)
    {
			
				disable_pwm_out(30);
				while (app_pwm_channel_duty_set(&PWM1, 0, 30) == NRF_ERROR_BUSY);
				//while (app_pwm_channel_duty_set(&PWM1, 1, 70) == NRF_ERROR_BUSY);
				
				//Create timing
				while(1){
					
					enable_pwm_out(30);	
					nrf_delay_us(2400);
					
					disable_pwm_out(30);
					nrf_delay_us(600);
					
					enable_pwm_out(30);	
					nrf_delay_us(1200);
					
					disable_pwm_out(30);
					nrf_delay_us(600);
					
					enable_pwm_out(30);	
					nrf_delay_us(600);
					
					disable_pwm_out(30);	
					nrf_delay_us(600);
				}
    }
    
}

Results with Keil MDK: image description

Results with ARM_GCC: image description

I do not understand why gcc_arm compiler is not good with my problems. Thanks for your watching!

  • Which optimization level are you using when you're compiling with GCC? It could be that the delays are optimized, i.e. removed. Could you try to set the optimization level to 0, i.e.

    CFLAGS +=  -Wall -Werror -O0 -g3
    
  • The followed code is a part of Makefile:

    #flags common to all targets
    CFLAGS  = -DNRF51
    CFLAGS += -DBOARD_PCA10028
    CFLAGS += -DBSP_DEFINES_ONLY
    CFLAGS += -mcpu=cortex-m0
    CFLAGS += -mthumb -mabi=aapcs --std=gnu99
    CFLAGS += -Wall -Werror -O3 -g3
    CFLAGS += -mfloat-abi=soft
    # keep every function in separate section. This will allow linker to dump unused functions
    CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
    CFLAGS += -fno-builtin --short-enums 
    # keep every function in separate section. This will allow linker to dump unused functions
    LDFLAGS += -Xlinker -Map=$(LISTING_DIRECTORY)/$(OUTPUT_FILENAME).map
    LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
    LDFLAGS += -mcpu=cortex-m0
    # let linker to dump unused sections
    LDFLAGS += -Wl,--gc-sections
    # use newlib in nano version
    LDFLAGS += --specs=nano.specs -lc -lnosys
    
    # Assembler flags
    ASMFLAGS += -x assembler-with-cpp
    ASMFLAGS += -DNRF51
    ASMFLAGS += -DBOARD_PCA10028
    ASMFLAGS += -DBSP_DEFINES_ONLY
    
Related