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

CCM module resets the mcu

I have written a simple implementation for using the ccm module with mesh. It encrypts and decrypts as it should but when enabled the processor makes a soft reset. It happens quiet often but not on every sent or received packet. In addition to the code below, I have modified the packet format to match what the ccm needs and declared som data structures. The code is based on https://github.com/NordicSemiconductor/nRF51-ble-bcast-mesh

The source as follows( crypto.c):

#include <string.h>
#include "services.h"
#include "crypto.h"
#include "nrf.h"
#include "rand.h"
#include "nrf_drv_ppi.h"


uint8_t aes_ccm_key[16] = {'N', 'O', 'T', 'A', 'G', 'O', 'O', 'D', 'P', 'A', 'S', 'S', 'W', 'O', 'R', 'D'};

uint8_t scratch_area[16+255];//16 bytes + 2^(max(length field size))

ccm_data_t ccm_data;

typedef uint32_t pkt_counter_t[5];

void crypto_encrypt(uint32_t *in_ptr, uint32_t *out_ptr)
{
	uint32_t i;
	for(i= 0; i<16; i++)
		ccm_data.KEY[i] = aes_ccm_key[i];

	for(i=0;i<5;i++)
		ccm_data.PKTCTR[i] = packet_counter(i);

	ccm_data.dir =0; //undocumented does 1 mean encrypt or decrypt?
	//rand_hw_rng_get(&ccm_data.IV, 8); //random initialisation vector

	NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) & AAR_ENABLE_ENABLE_Msk; //make sure AAR is disabled
	NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;
	NRF_CCM->CNFPTR =(uint32_t) &ccm_data;
	NRF_CCM->SCRATCHPTR =(uint32_t) &scratch_area;
	NRF_CCM->MODE = 1<<24|1<<16|0<<0; // mode length extended, 1 mbit datarate, encrypt
	NRF_CCM->INPTR = (uint32_t)in_ptr;
	NRF_CCM->OUTPTR = (uint32_t)out_ptr;
	NRF_CCM->SHORTS = 1; //Shorts enabled'
	NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;

}

void crypto_decrypt(uint32_t *in_ptr, uint32_t *out_ptr)
{
	uint32_t i;
	for(i= 0; i<16; i++)
		ccm_data.KEY[i] = aes_ccm_key[i];

	for(i=0;i<5;i++)
		ccm_data.PKTCTR[i] = packet_counter(i);

	ccm_data.dir = 0; //undocumented does 1 mean encrypt or decrypt?

	NRF_AAR->ENABLE = (AAR_ENABLE_ENABLE_Disabled << AAR_ENABLE_ENABLE_Pos) & AAR_ENABLE_ENABLE_Msk; //make sure AAR is disabled
	NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Disabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;
	NRF_CCM->CNFPTR =(uint32_t) &ccm_data;
	NRF_CCM->SCRATCHPTR =(uint32_t) &scratch_area;
	NRF_CCM->MODE = 1<<24|1<<16|1<<0; // mode length extended, 1 mbit datarate, decrypt
	NRF_CCM->INPTR = (uint32_t)in_ptr;
	NRF_CCM->OUTPTR = (uint32_t)out_ptr;
	NRF_CCM->SHORTS = 1; //Shorts enabled'
	NRF_CCM->ENABLE = (CCM_ENABLE_ENABLE_Enabled << CCM_ENABLE_ENABLE_Pos) & CCM_ENABLE_ENABLE_Msk;
}

Radio_control.c is modified to call the above functions:

static void setup_event(radio_event_t* p_evt)
{
	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_ADDRESS_RSSISTART_Msk;
	radio_channel_set(p_evt->channel);
	NRF_RADIO->PACKETPTR = (uint32_t)packet_buffer;
	//NRF_RADIO->PACKETPTR =(uint32_t)p_evt->packet_ptr;
	NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
	NRF_RADIO->EVENTS_END = 0;
	NRF_RADIO->PREFIX0 |= (((m_alt_aa >> 24) << 8) & 0x0000FF00);
	NRF_RADIO->BASE1    = ((m_alt_aa <<  8) & 0xFFFFFF00);

	nrf_drv_ppi_channel_enable(24); //activate ppi between ccm and radio
	NRF_CCM->EVENTS_ENDCRYPT=0;

	if (p_evt->event_type == RADIO_EVENT_TYPE_TX)
	{

    	crypto_encrypt((uint32_t *)p_evt->packet_ptr,(uint32_t *)packet_buffer);
    	DEBUG_RADIO_SET_STATE(PIN_RADIO_STATE_TX);
        NRF_RADIO->TXADDRESS = p_evt->access_address;
        NRF_RADIO->TXPOWER  = p_evt->tx_power;
        NRF_RADIO->TASKS_TXEN = 1;
    	NRF_CCM->TASKS_KSGEN =1;
        m_radio_state = RADIO_STATE_TX;
	}
	else
	{

		DEBUG_RADIO_SET_STATE(PIN_RADIO_STATE_RX);
		if (m_alt_aa != RADIO_DEFAULT_ADDRESS)
		{
			/* only enable alt-addr if it's different */
			NRF_RADIO->RXADDRESSES = 0x03;
		}
		else
		{
			NRF_RADIO->RXADDRESSES = 0x01;
		}
		crypto_decrypt((uint32_t *)packet_buffer, (uint32_t *)p_evt->packet_ptr);

		NRF_CCM->TASKS_KSGEN =1;

		NRF_RADIO->TASKS_RXEN = 1;
		m_radio_state = RADIO_STATE_RX;
	}
}
Parents
  • What's the nature of your soft reset? is it a hardfault, a softdevice assert?

    The code that executes in radio.c is extremely sensitive to timing, and spending too much time in setup_event or other radio-related functions can make the Softdevice end your timeslot, and asserting. This will only happen when the code executes near the end of the timeslot, which could explain your inconsistent errors.

Reply
  • What's the nature of your soft reset? is it a hardfault, a softdevice assert?

    The code that executes in radio.c is extremely sensitive to timing, and spending too much time in setup_event or other radio-related functions can make the Softdevice end your timeslot, and asserting. This will only happen when the code executes near the end of the timeslot, which could explain your inconsistent errors.

Children
No Data
Related