mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-23 13:47:33 -04:00
[sw] update GPTMR HAL
This commit is contained in:
parent
d31320a501
commit
500f3b647e
3 changed files with 158 additions and 28 deletions
|
@ -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);
|
||||
/**@}*/
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue