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;
	}
}
Related