summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--movement/watch_faces/complication/randonaut_face.c2
-rw-r--r--movement/watch_faces/complication/toss_up_face.c3
-rw-r--r--watch-library/hardware/watch/watch_private.c11
-rw-r--r--watch-library/shared/watch/watch.h6
4 files changed, 18 insertions, 4 deletions
diff --git a/movement/watch_faces/complication/randonaut_face.c b/movement/watch_faces/complication/randonaut_face.c
index bca334fb..886aabb7 100644
--- a/movement/watch_faces/complication/randonaut_face.c
+++ b/movement/watch_faces/complication/randonaut_face.c
@@ -357,7 +357,7 @@ static uint32_t _get_true_entropy(void) {
while (!hri_trng_get_INTFLAG_reg(TRNG, TRNG_INTFLAG_DATARDY)); // Wait for TRNG data to be ready
- hri_trng_clear_CTRLA_ENABLE_bit(TRNG);
+ watch_disable_TRNG(TRNG);
hri_mclk_clear_APBCMASK_TRNG_bit(MCLK);
return hri_trng_read_DATA_reg(TRNG); // Read a single 32-bit word from TRNG and return it
#endif
diff --git a/movement/watch_faces/complication/toss_up_face.c b/movement/watch_faces/complication/toss_up_face.c
index 08dd0052..dedc9042 100644
--- a/movement/watch_faces/complication/toss_up_face.c
+++ b/movement/watch_faces/complication/toss_up_face.c
@@ -255,7 +255,8 @@ uint32_t get_true_entropy(void) {
while (!hri_trng_get_INTFLAG_reg(TRNG, TRNG_INTFLAG_DATARDY)); // Wait for TRNG data to be ready
- hri_trng_clear_CTRLA_ENABLE_bit(TRNG);
+ watch_disable_TRNG(TRNG);
+
hri_mclk_clear_APBCMASK_TRNG_bit(MCLK);
return hri_trng_read_DATA_reg(TRNG); // Read a single 32-bit word from TRNG and return it
#endif
diff --git a/watch-library/hardware/watch/watch_private.c b/watch-library/hardware/watch/watch_private.c
index cd607b8e..4cae3ccb 100644
--- a/watch-library/hardware/watch/watch_private.c
+++ b/watch-library/hardware/watch/watch_private.c
@@ -106,12 +106,21 @@ int getentropy(void *buf, size_t buflen) {
}
}
- hri_trng_clear_CTRLA_ENABLE_bit(TRNG);
+ watch_disable_TRNG(TRNG);
hri_mclk_clear_APBCMASK_TRNG_bit(MCLK);
return 0;
}
+void watch_disable_TRNG(Trng *hw) {
+ hri_trng_clear_CTRLA_ENABLE_bit(hw);
+ // silicon erratum: the TRNG may leave internal components powered after disable.
+ // the workaround is to clear the register twice.
+ hri_trng_write_CTRLA_reg(hw, 0);
+ hri_trng_write_CTRLA_reg(hw, 0);
+}
+
+
void _watch_enable_tcc(void) {
// clock TCC0 with the main clock (8 MHz) and enable the peripheral clock.
hri_gclk_write_PCHCTRL_reg(GCLK, TCC0_GCLK_ID, GCLK_PCHCTRL_GEN_GCLK0_Val | GCLK_PCHCTRL_CHEN);
diff --git a/watch-library/shared/watch/watch.h b/watch-library/shared/watch/watch.h
index 790f9a16..4043fdf7 100644
--- a/watch-library/shared/watch/watch.h
+++ b/watch-library/shared/watch/watch.h
@@ -96,4 +96,8 @@ void watch_reset_to_bootloader(void);
*/
int read(int file, char *ptr, int len);
-#endif /* WATCH_H_ */ \ No newline at end of file
+/** @brief Disables the TRNG, working around a silicon erratum.
+ */
+void watch_disable_TRNG(Trng* hw);
+
+#endif /* WATCH_H_ */