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
asked Jan 31, 2021 at 15:21
1 Answer 1
Two things:
- 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. - 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) {
.
answered Jan 31, 2021 at 16:35
-
Isn't
if (TRNG->TRNG_ISR = 1) {.
an assignment?TRNG->TRNG_ISR
is not read - 1 is assigned to it. I think it is intended to be a comparisson. That's an error in the first example. But the condition was always true, and the generator is fast enough to gnerate a number every 500ms it seems ;-).Peter Paul Kiefer– Peter Paul Kiefer2021年01月31日 20:23:23 +00:00Commented Jan 31, 2021 at 20:23 -
@PeterPaulKiefer You might be right... The end result would probably be reading the register before writing the changed content back.Majenko– Majenko2021年01月31日 20:25:01 +00:00Commented Jan 31, 2021 at 20:25
delay
will internally wait on some millisecond variable to be incremented, and that only happens in some timer ISR, that you may be blocking by delaying in the first place. You might want to setup a hardware timer in the needed interval or use a flag insideloop
to toggle a boolean "it's okay to update" value every 500ms, that is then reset in the TRNG_Handler.This interrupt is set when a new random value is available and is cleared when the status register is read(TRNG_SR register).
TheSR
is probably a typo and meansISR
. Can you try and read the status register the same as in github.com/davecheney/trng/blob/master/arduino-due-trng/… ?