lynxis lazus has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-asf4-dfu/+/42250?usp=email )
Change subject: Implement a blinking LED using Timer Counter 0
......................................................................
Implement a blinking LED using Timer Counter 0
Sadly the LED is connected to a GPIO doesn't have useful functions.
The only other function is ETM tracing.
The GPIO can't be controlled by a Timer Counter (TC) or
Timer Counter for Control (TCC) because only certain GPIOs
are able to be controlled by it.
Use a Timer Counter to count the time in one-shot mode
and trigger the LED from the main main loop.
This has the advantage of keeping the interference to a minimum in difference
to a Timer Counter interrupt.
Additional by using the ARM core to change the LED, it can be used as heart
beat,
if the LED blinks, the ARM core is still 'alive'.
There are other possibilities to trigger the LED:
- use a TC to trigger the Event System, which toggles the GPIO.
- use a TC to trigger the DMA engine, which transfer 1 byte toggles the GPIO.
Change-Id: I8144120d07f73356855d084016edcb77d202da7f
---
M driver_init.c
M driver_init.h
M gcc/Makefile
A timer.c
M usb_start.c
5 files changed, 83 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-asf4-dfu refs/changes/50/42250/1
diff --git a/driver_init.c b/driver_init.c
index d873230..1ec2435 100644
--- a/driver_init.c
+++ b/driver_init.c
@@ -157,6 +157,11 @@
#endif
}
+void LED_SYSTEM_toggle(void)
+{
+ gpio_toggle_pin_level(LED_SYSTEM);
+}
+
void system_init(void)
{
init_mcu();
diff --git a/driver_init.h b/driver_init.h
index 8d8a30b..97896fd 100644
--- a/driver_init.h
+++ b/driver_init.h
@@ -43,6 +43,11 @@
void LED_SYSTEM_off(void);
/**
+ * \brief Toggle system LED
+ */
+void LED_SYSTEM_toggle(void);
+
+/**
* \brief Perform system initialization, initialize pins and clocks for
* peripherals
*/
diff --git a/gcc/Makefile b/gcc/Makefile
index 27a9143..bfe2ca0 100644
--- a/gcc/Makefile
+++ b/gcc/Makefile
@@ -50,7 +50,8 @@
hpl/cmcc/hpl_cmcc.o \
atmel_start.o \
usb/device/usbdc.o \
-hal/src/hal_atomic.o
+hal/src/hal_atomic.o \
+timer.o
SRC_hosttools = crc_code.c
SRC_dfu = usb_dfu_main.c crc_code.c crc_params.c
diff --git a/timer.c b/timer.c
new file mode 100644
index 0000000..1c1a2f5
--- /dev/null
+++ b/timer.c
@@ -0,0 +1,61 @@
+/*
+ * (C) 2026 sysmocom -s.f.m.c. GmbH
+ * Author: Alexander Couzens <[email protected]>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
+ */
+
+#include "atmel_start.h"
+
+/* configure tc0 for 0.5s, oneshot mode */
+void tc0_setup(void)
+{
+ /* set TC0 to global clock 3 / 32 khz*/
+ hri_gclk_write_PCHCTRL_reg(GCLK, TC0_GCLK_ID, 3 | GCLK_PCHCTRL_CHEN);
+
+ /* enable ABPA access for TC0 */
+ hri_mclk_set_APBAMASK_TC0_bit(MCLK);
+
+ hri_tc_wait_for_sync(TC0, TC_SYNCBUSY_SWRST);
+
+ /* disable the TC, to enable access to ctrl registers */
+ hri_tc_clear_CTRLA_ENABLE_bit(TC0);
+
+ /* 32 kHz / 64 with an 8 bit counter gives 0.5 seconds, use one shot */
+ hri_tc_write_CTRLA_reg(TC0, TC_CTRLA_MODE_COUNT8 |
TC_CTRLA_PRESCALER_DIV64);
+
+ hri_tc_set_CTRLB_ONESHOT_bit(TC0);
+
+ /* normal frequency, count between 0 and TOP */
+ hri_tc_set_WAVE_WAVEGEN_bf(TC0, 0);
+
+ /* set PERIOD/TOP value to 0xff */
+ hri_tccount8_set_PER_PER_bf(TC0, 0xff);
+
+ /* Start the TC0 */
+ hri_tc_set_CTRLA_ENABLE_bit(TC0);
+}
+
+/* returns true if the tc0 has been re-armed */
+bool tc0_finished_rearm(void)
+{
+ /* still running, do nothing */
+ if (!hri_tc_get_STATUS_STOP_bit(TC0)) {
+ return false;
+ }
+
+ hri_tc_set_CTRLB_CMD_bf(TC0, TC_CTRLBSET_CMD_RETRIGGER_Val);
+ return true;
+}
diff --git a/usb_start.c b/usb_start.c
index 47e287f..95bf2e7 100644
--- a/usb_start.c
+++ b/usb_start.c
@@ -18,6 +18,7 @@
#include "atmel_start.h"
#include "usb_start.h"
#include "config/usbd_config.h"
+#include "timer.h"
#if CONF_USBD_HS_SP
static uint8_t single_desc_bytes[] = {
@@ -152,13 +153,20 @@
*/
void usb_dfu(void)
{
- while (!dfudf_is_enabled()); // wait for DFU to be installed
- LED_SYSTEM_on(); // switch LED on to indicate USB DFU stack is ready
+ tc0_setup();
uint32_t application_start_address = BL_SIZE_BYTE;
ASSERT(application_start_address > 0);
while (true) { // main DFU infinite loop
+ /* blink the led with 0.5s off, 0.5s on */
+ if (tc0_finished_rearm())
+ LED_SYSTEM_toggle();
+
+ // wait for DFU to be installed
+ if (!dfudf_is_enabled())
+ continue;
+
// run the second part of the USB DFU state machine handling
non-USB aspects
if (USB_DFU_STATE_DFU_DNLOAD_SYNC == dfu_state ||
USB_DFU_STATE_DFU_DNBUSY == dfu_state) { // there is some data to be flashed
LED_SYSTEM_off(); // switch LED off to indicate we are
flashing
--
To view, visit https://gerrit.osmocom.org/c/osmo-asf4-dfu/+/42250?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: osmo-asf4-dfu
Gerrit-Branch: master
Gerrit-Change-Id: I8144120d07f73356855d084016edcb77d202da7f
Gerrit-Change-Number: 42250
Gerrit-PatchSet: 1
Gerrit-Owner: lynxis lazus <[email protected]>