[sw] update GPTMR HAL

This commit is contained in:
stnolting 2024-01-06 16:57:46 +01:00
parent d31320a501
commit 500f3b647e
3 changed files with 158 additions and 28 deletions

View file

@ -3,7 +3,7 @@
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2024, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
@ -49,22 +49,29 @@
/**@{*/
/** GPTMR module prototype */
typedef volatile struct __attribute__((packed,aligned(4))) {
uint32_t CTRL; /**< offset 0: control register (#NEORV32_GPTMR_CTRL_enum) */
uint32_t THRES; /**< offset 4: threshold register */
uint32_t COUNT; /**< offset 8: counter register */
const uint32_t reserved; /**< offset 12: reserved */
uint32_t CTRL; /**< offset 0: control register (#NEORV32_GPTMR_CTRL_enum) */
uint32_t THRES; /**< offset 4: threshold register */
uint32_t COUNT; /**< offset 8: counter register */
uint32_t CAPTURE; /**< offset 12: capture register */
} neorv32_gptmr_t;
/** GPTMR module hardware access (#neorv32_gptmr_t) */
#define NEORV32_GPTMR ((neorv32_gptmr_t*) (NEORV32_GPTMR_BASE))
/** GPTMR control/data register bits */
/** GPTMR control register bits */
enum NEORV32_GPTMR_CTRL_enum {
GPTMR_CTRL_EN = 0, /**< GPTIMR control register(0) (r/w): Timer unit enable */
GPTMR_CTRL_PRSC0 = 1, /**< GPTIMR control register(1) (r/w): Clock prescaler select bit 0 */
GPTMR_CTRL_PRSC1 = 2, /**< GPTIMR control register(2) (r/w): Clock prescaler select bit 1 */
GPTMR_CTRL_PRSC2 = 3, /**< GPTIMR control register(3) (r/w): Clock prescaler select bit 2 */
GPTMR_CTRL_MODE = 4 /**< GPTIMR control register(4) (r/w): Timer mode: 0=single-shot mode, 1=continuous mode */
GPTMR_CTRL_EN = 0, /**< GPTMR control register(0) (r/w): GPTMR enable */
GPTMR_CTRL_PRSC0 = 1, /**< GPTMR control register(1) (r/w): Clock prescaler select bit 0 */
GPTMR_CTRL_PRSC1 = 2, /**< GPTMR control register(2) (r/w): Clock prescaler select bit 1 */
GPTMR_CTRL_PRSC2 = 3, /**< GPTMR control register(3) (r/w): Clock prescaler select bit 2 */
GPTMR_CTRL_IRQM = 4, /**< GPTMR control register(4) (r/w): Enable interrupt on timer match */
GPTMR_CTRL_IRQC = 5, /**< GPTMR control register(5) (r/w): Enable interrupt on capture trigger */
GPTMR_CTRL_RISE = 6, /**< GPTMR control register(6) (r/w): Capture on rising edge; capture-mode only */
GPTMR_CTRL_FALL = 7, /**< GPTMR control register(7) (r/w): Capture on falling edge; capture-mode only */
GPTMR_CTRL_FILTER = 8, /**< GPTMR control register(8) (r/w): Filter capture input; capture-mode only */
GPTMR_CTRL_TRIGM = 30, /**< GPTMR control register(30) (r/c): Timer-match has fired, cleared by writing 0 */
GPTMR_CTRL_TRIGC = 31, /**< GPTMR control register(31) (r/c): Capture-trigger has fired, cleared by writing 0 */
};
/**@}*/
@ -73,11 +80,16 @@ enum NEORV32_GPTMR_CTRL_enum {
* @name Prototypes
**************************************************************************/
/**@{*/
int neorv32_gptmr_available(void);
void neorv32_gptmr_setup(int prsc, int mode, uint32_t threshold);
void neorv32_gptmr_disable(void);
void neorv32_gptmr_enable(void);
void neorv32_gptmr_restart(void);
int neorv32_gptmr_available(void);
void neorv32_gptmr_setup(int prsc, uint32_t threshold, int match_irq);
void neorv32_gptmr_capture(int rising, int falling, int filter, int capture_irq);
void neorv32_gptmr_disable(void);
void neorv32_gptmr_enable(void);
int neorv32_gptmr_trigger_matched(void);
int neorv32_gptmr_trigger_captured(void);
void neorv32_gptmr_restart(void);
uint32_t neorv32_gptmr_counter_get(void);
uint32_t neorv32_gptmr_capture_get(void);
/**@}*/

View file

@ -3,7 +3,7 @@
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2024, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
@ -61,22 +61,42 @@ int neorv32_gptmr_available(void) {
/**********************************************************************//**
* Enable and configure general purpose timer.
* Reset, enable and configure general purpose timer.
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] mode 0=single-shot mode, 1=continuous mode
* @param[in] threshold Threshold value to trigger interrupt.
* @param[in] threshold Threshold value, counter will reset to zero when reaching this.
* @param[in] match_irq Fire interrupt when counter matches threshold value.
**************************************************************************/
void neorv32_gptmr_setup(int prsc, int mode, uint32_t threshold) {
void neorv32_gptmr_setup(int prsc, uint32_t threshold, int match_irq) {
NEORV32_GPTMR->CTRL = 0; // reset
NEORV32_GPTMR->CTRL = 0; // reset configuration
NEORV32_GPTMR->THRES = threshold;
NEORV32_GPTMR->COUNT = 0; // reset counter
uint32_t tmp = 0;
tmp |= (uint32_t)(1 & 0x01) << GPTMR_CTRL_EN;
tmp |= (uint32_t)(prsc & 0x07) << GPTMR_CTRL_PRSC0;
tmp |= (uint32_t)(mode & 0x01) << GPTMR_CTRL_MODE;
tmp |= (uint32_t)(1 & 0x01) << GPTMR_CTRL_EN;
tmp |= (uint32_t)(prsc & 0x07) << GPTMR_CTRL_PRSC0;
tmp |= (uint32_t)(match_irq & 0x01) << GPTMR_CTRL_IRQM;
NEORV32_GPTMR->CTRL = tmp;
}
/**********************************************************************//**
* Configure timer capture feature.
* @note This function needs to be called after the general GPTMR setup #neorv32_gptmr_setup.
*
* @param[in] rising Capture on rising edge.
* @param[in] falling Capture on falling edge.
* @param[in] filter Enable filtering of capture input.
* @param[in] capture_irq Fire interrupt when on capture trigger.
**************************************************************************/
void neorv32_gptmr_capture(int rising, int falling, int filter, int capture_irq) {
uint32_t tmp = NEORV32_GPTMR->CTRL;
tmp |= (uint32_t)(rising & 0x01) << GPTMR_CTRL_RISE;
tmp |= (uint32_t)(falling & 0x01) << GPTMR_CTRL_FALL;
tmp |= (uint32_t)(filter & 0x01) << GPTMR_CTRL_FILTER;
tmp |= (uint32_t)(capture_irq & 0x01) << GPTMR_CTRL_IRQC;
NEORV32_GPTMR->CTRL = tmp;
}
@ -100,9 +120,71 @@ void neorv32_gptmr_enable(void) {
/**********************************************************************//**
* Reset general purpose timer's counter register.
* Check if timer match has triggered. Clear trigger flag in that case.
*
* @return 1 if match trigger has fired, 0 if not.
**************************************************************************/
int neorv32_gptmr_trigger_matched(void) {
uint32_t tmp = NEORV32_GPTMR->CTRL;
if (tmp & (1 << GPTMR_CTRL_TRIGM)) {
tmp &= ~((uint32_t)(1 << GPTMR_CTRL_TRIGM));
NEORV32_GPTMR->CTRL = tmp;
return 1;
}
else {
return 0;
}
}
/**********************************************************************//**
* Check if capture input has triggered. Clear trigger flag in that case.
*
* @return 1 if capture trigger has fired, 0 if not.
**************************************************************************/
int neorv32_gptmr_trigger_captured(void) {
uint32_t tmp = NEORV32_GPTMR->CTRL;
if (tmp & (1 << GPTMR_CTRL_TRIGC)) {
tmp &= ~((uint32_t)(1 << GPTMR_CTRL_TRIGC));
NEORV32_GPTMR->CTRL = tmp;
return 1;
}
else {
return 0;
}
}
/**********************************************************************//**
* Reset general purpose timer's counter register (timer-mode only).
**************************************************************************/
void neorv32_gptmr_restart(void) {
NEORV32_GPTMR->COUNT = 0;
}
/**********************************************************************//**
* Get current counter value.
*
* @return Current counter value.
**************************************************************************/
uint32_t neorv32_gptmr_counter_get(void) {
return NEORV32_GPTMR->COUNT;
}
/**********************************************************************//**
* Get latest capture value.
*
* @return Capture timer value.
**************************************************************************/
uint32_t neorv32_gptmr_capture_get(void) {
return NEORV32_GPTMR->CAPTURE;
}

View file

@ -674,9 +674,39 @@
<description>Clock prescaler select</description>
</field>
<field>
<name>GPTMR_CTRL_MODE</name>
<name>GPTMR_CTRL_IRQM</name>
<bitRange>[4:4]</bitRange>
<description>Timer mode: 0=single-shot mode, 1=continuous mode</description>
<description>Enable interrupt on timer match</description>
</field>
<field>
<name>GPTMR_CTRL_IRQC</name>
<bitRange>[5:5]</bitRange>
<description>Enable interrupt on capture trigger</description>
</field>
<field>
<name>GPTMR_CTRL_RISE</name>
<bitRange>[6:6]</bitRange>
<description>Capture on rising edge; capture-mode only</description>
</field>
<field>
<name>GPTMR_CTRL_FALL</name>
<bitRange>[7:7]</bitRange>
<description>Capture on falling edge; capture-mode only</description>
</field>
<field>
<name>GPTMR_CTRL_FILTER</name>
<bitRange>[8:8]</bitRange>
<description>Filter capture input; capture-mode only</description>
</field>
<field>
<name>GPTMR_CTRL_TRIGM</name>
<bitRange>[30:30]</bitRange>
<description>Timer-match has fired, cleared by writing 0</description>
</field>
<field>
<name>GPTMR_CTRL_TRIGC</name>
<bitRange>[31:31]</bitRange>
<description>Capture-trigger has fired, cleared by writing</description>
</field>
</fields>
</register>
@ -690,6 +720,12 @@
<description>Counter register</description>
<addressOffset>0x08</addressOffset>
</register>
<register>
<name>CAPTURE</name>
<description>Capture register</description>
<addressOffset>0x0C</addressOffset>
<access>read-only</access>
</register>
</registers>
</peripheral>