I am working on updating my Entropy library to work on the Due platform, using the trng instead of timer jitter as the entropy source.
I need to make a small block of code atomic and can't find any way other than some references I found online to two functions __disable_interrupts() and __enable_interrupts(). The only definition I found in the Arduino 1.5.x directory tree for those is for a Wifi related library, so I don't think they exist for my purpose. I would appreciate any suggestions.
Here is my current test code
#include <sam.h>
#include <sam3xa/include/component/component_trng.h>
const uint8_t ENTROPY_POOL_SIZE=32;
volatile uint8_t g_entropy_pool_start;
volatile uint8_t g_entropy_pool_end;
volatile uint32_t g_entropy_pool[ENTROPY_POOL_SIZE+1];
uint32_t test_random(void)
{
uint32_t retVal;
retVal = g_entropy_pool[0]; // Place holder until atomic issue addressed
// __disable_interrupt(); // NEED TO MAKE THIS BLOCK ATTOMIC
// retVal = g_entropy_pool[g_entropy_pool_start];
// g_entropy_pool_start = (g_entropy_pool_start + 1) % ENTROPY_POOL_SIZE;
// --g_entropy_pool_count;
// __enable_interrupt(); // NEED TO MAKE ABOVE BLOCK ATOMIC
return(retVal);
}
void TRNG_Handler(void)
{
uint32_t tmp;
// g_entropy_pool[0] = TRNG->TRNG_ODATA;
g_entropy_pool[g_entropy_pool_end] = TRNG->TRNG_ODATA;
// g_entropy_pool_end = (g_entropy_pool_end + 1) % ENTROPY_POOL_SIZE;
// As it stands if the following two lines are uncommented the program ceases to produce output.
// if (g_entropy_pool_end == g_entropy_pool_start) // The entropy pool is full
// g_entropy_pool_start = (g_entropy_pool_start + 1) % ENTROPY_POOL_SIZE;
tmp = TRNG->TRNG_ISR; // Need to read the status register to clear it
}
void setup_trng(void)
{
// Circular buffer pointers for entropy
g_entropy_pool_start = 0;
g_entropy_pool_end = 0;
pmc_enable_periph_clk(ID_TRNG); // Turn on the trng peripheral clock
TRNG->TRNG_IER = 0xFFFFFFFF; // Set the interrupt enable register
TRNG->TRNG_CR = TRNG_CR_KEY(0x524e47) | TRNG_CR_ENABLE;// Turn on the generator
NVIC_ClearPendingIRQ(TRNG_IRQn);
NVIC_EnableIRQ(TRNG_IRQn); // Activate the TRNG Interrupts
}
void setup()
{
Serial.begin(115200);
setup_trng();
}
void loop()
{
Serial.println(test_random(),DEC);
}