0

I have a code that spit out random number when the ISR register is ready:

#define TRNG_KEY  0x524E47
uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
uint32_t msk = 0x1FE;

void setup() { Serial.begin(9600); PIOC->PIO_PER = msk; PIOC->PIO_OER = msk; PIOC->PIO_OWDR = ~msk;

PMC->PMC_PCER1 = PMC_PCER1_PID41; TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY); TRNG->TRNG_IER = 1 << 0; }

void loop() { if (TRNG->TRNG_ISR == 1) { PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10]; } delay(500); }

The code above works. However, when I tried to switch to internal interrupt:

#define TRNG_KEY  0x524E47
uint8_t lut[10] = {0xF6, 0x12, 0xAE, 0xEC, 0xD8, 0x7C, 0x7E, 0xE0, 0xFE, 0xFC};
uint32_t msk = 0x1FE;

void setup() { Serial.begin(9600); PIOC->PIO_PER = msk; PIOC->PIO_OER = msk; PIOC->PIO_OWDR = ~msk;

PMC->PMC_PCER1 = PMC_PCER1_PID41; TRNG->TRNG_CR = TRNG_CR_ENABLE | TRNG_CR_KEY(TRNG_KEY); TRNG->TRNG_IER = 1 << 0;

NVIC_EnableIRQ(TRNG_IRQn); }

void loop() {

}

void TRNG_Handler(void) { PIOC->PIO_ODSR = lut[REG_TRNG_ODATA % 10]; }

The code only spit out one random number and then freezes, indicating TRNG_Handler(void) was only executed once. I cannot figure out why.

Thanks in Advance !

7E10FC9A
  • 209
  • 1
  • 6

1 Answers1

2

Two things:

  1. Never use delay() inside an ISR. On some systems it may work, but on most it will just block. It's bad practice to have your ISRs run for more time that absolutely needed anyway.
  2. You need to read the status register for the TRNG to clear the interrupt flag. You're doing that in your first code sample with if (TRNG->TRNG_ISR == 1) {.
Majenko
  • 105,851
  • 5
  • 82
  • 139