mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 02:48:37 +08:00
Compare commits
17 commits
3cff6dc97a
...
f041ae5ca8
Author | SHA1 | Date | |
---|---|---|---|
|
f041ae5ca8 | ||
|
aa0aecbd80 | ||
|
39780fdae1 | ||
|
ee2f3df2ff | ||
|
ff488133c9 | ||
|
48846954d8 | ||
|
657247bda8 | ||
|
be40c01ddd | ||
|
91c71ed00a | ||
|
1d8ce18d7f | ||
|
558fe83f6d | ||
|
7c7a64c84c | ||
|
f2a88059e7 | ||
|
4bd8d9eac7 | ||
|
69ee240b45 | ||
|
b9837bed08 | ||
|
d84ba608a1 |
47 changed files with 1430 additions and 267 deletions
|
@ -87,7 +87,7 @@ find_program(KCONFIGLIB olddefconfig)
|
|||
if(NOT KCONFIGLIB)
|
||||
message(
|
||||
FATAL_ERROR "Kconfig environment depends on kconfiglib, Please install:
|
||||
$ sudo apt install python3-kconfiglib")
|
||||
$ sudo pip3 install kconfiglib")
|
||||
endif()
|
||||
|
||||
# BOARD CONFIG can be set to directory path, or <board-name>[/:]<config-name>
|
||||
|
|
|
@ -27,9 +27,11 @@
|
|||
#include <nuttx/config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/can/can.h>
|
||||
|
||||
|
@ -205,6 +207,8 @@ static struct can_dev_s g_can1dev =
|
|||
};
|
||||
#endif
|
||||
|
||||
static spinlock_t g_can_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -1079,7 +1083,8 @@ struct can_dev_s *am335x_can_initialize(int port)
|
|||
|
||||
syslog(LOG_DEBUG, "CAN%d\n", port);
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_can_lock);
|
||||
sched_lock();
|
||||
|
||||
#ifdef CONFIG_AM335X_CAN0
|
||||
if (port == 0)
|
||||
|
@ -1109,11 +1114,13 @@ struct can_dev_s *am335x_can_initialize(int port)
|
|||
{
|
||||
canerr("Unsupported port: %d\n", port);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_can_lock, flags);
|
||||
sched_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_can_lock, flags);
|
||||
sched_unlock();
|
||||
|
||||
return candev;
|
||||
}
|
||||
|
@ -1124,7 +1131,8 @@ void am335x_can_uninitialize(struct can_dev_s *dev)
|
|||
|
||||
DEBUGASSERT(dev);
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_can_lock);
|
||||
sched_lock();
|
||||
|
||||
#ifdef CONFIG_AM335X_CAN0
|
||||
if (dev == &g_can0dev)
|
||||
|
@ -1151,7 +1159,8 @@ void am335x_can_uninitialize(struct can_dev_s *dev)
|
|||
canerr("Not a CAN device: %p\n", dev);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_can_lock, flags);
|
||||
sched_unlock();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "arm_internal.h"
|
||||
|
@ -219,6 +220,8 @@ static const uint8_t *g_gpio_padctl[AM335X_GPIO_NPORTS] =
|
|||
g_gpio3_padctl, /* GPIO3 */
|
||||
};
|
||||
|
||||
static spinlock_t g_gpio_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
@ -364,7 +367,7 @@ int am335x_gpio_config(gpio_pinset_t pinset)
|
|||
|
||||
/* Configure the pin as an input initially to avoid any spurious outputs */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
|
||||
/* Configure based upon the pin mode */
|
||||
|
||||
|
@ -407,7 +410,7 @@ int am335x_gpio_config(gpio_pinset_t pinset)
|
|||
break;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -425,9 +428,9 @@ void am335x_gpio_write(gpio_pinset_t pinset, bool value)
|
|||
int port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
|
||||
int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
am335x_gpio_setoutput(port, pin, value);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -445,9 +448,9 @@ bool am335x_gpio_read(gpio_pinset_t pinset)
|
|||
int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
bool value;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
value = am335x_gpio_getinput(port, pin);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/mutex.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
@ -185,6 +186,7 @@ struct am335x_i2c_priv_s
|
|||
|
||||
int refs; /* Reference count */
|
||||
mutex_t lock; /* Mutual exclusion mutex */
|
||||
spinlock_t spinlock; /* Spinlock */
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
sem_t sem_isr; /* Interrupt wait semaphore */
|
||||
#endif
|
||||
|
@ -317,6 +319,7 @@ static struct am335x_i2c_priv_s am335x_i2c0_priv =
|
|||
.config = &am335x_i2c0_config,
|
||||
.refs = 0,
|
||||
.lock = NXMUTEX_INITIALIZER,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
.sem_isr = SEM_INITIALIZER(0),
|
||||
#endif
|
||||
|
@ -352,6 +355,7 @@ static struct am335x_i2c_priv_s am335x_i2c1_priv =
|
|||
.config = &am335x_i2c1_config,
|
||||
.refs = 0,
|
||||
.lock = NXMUTEX_INITIALIZER,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
.sem_isr = SEM_INITIALIZER(0),
|
||||
#endif
|
||||
|
@ -387,6 +391,7 @@ static struct am335x_i2c_priv_s am335x_i2c2_priv =
|
|||
.config = &am335x_i2c2_config,
|
||||
.refs = 0,
|
||||
.lock = NXMUTEX_INITIALIZER,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
#ifndef CONFIG_I2C_POLLED
|
||||
.sem_isr = SEM_INITIALIZER(0),
|
||||
#endif
|
||||
|
@ -492,7 +497,7 @@ static inline int am335x_i2c_sem_waitdone(struct am335x_i2c_priv_s *priv)
|
|||
uint32_t regval;
|
||||
int ret;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&priv->spinlock);
|
||||
|
||||
/* Enable Interrupts when master mode */
|
||||
|
||||
|
@ -529,6 +534,8 @@ static inline int am335x_i2c_sem_waitdone(struct am335x_i2c_priv_s *priv)
|
|||
*/
|
||||
|
||||
priv->intstate = INTSTATE_WAITING;
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
|
||||
do
|
||||
{
|
||||
/* Wait until either the transfer is complete or the timeout expires */
|
||||
|
@ -551,6 +558,8 @@ static inline int am335x_i2c_sem_waitdone(struct am335x_i2c_priv_s *priv)
|
|||
}
|
||||
}
|
||||
|
||||
flags = spin_lock_irqsave(&priv->spinlock);
|
||||
|
||||
/* Loop until the interrupt level transfer is complete. */
|
||||
|
||||
while (priv->intstate != INTSTATE_DONE);
|
||||
|
@ -563,7 +572,7 @@ static inline int am335x_i2c_sem_waitdone(struct am335x_i2c_priv_s *priv)
|
|||
|
||||
am335x_i2c_putreg(priv, AM335X_I2C_IRQ_EN_CLR_OFFSET, I2C_ICR_CLEARMASK);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
@ -992,7 +1001,7 @@ static int am335x_i2c_isr_process(struct am335x_i2c_priv_s *priv)
|
|||
*/
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&priv->spinlock);
|
||||
#endif
|
||||
|
||||
/* Transmit a byte */
|
||||
|
@ -1001,7 +1010,7 @@ static int am335x_i2c_isr_process(struct am335x_i2c_priv_s *priv)
|
|||
priv->dcnt--;
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
#endif
|
||||
if ((priv->dcnt == 0) && ((priv->flags & I2C_M_NOSTOP) == 0))
|
||||
{
|
||||
|
@ -1026,7 +1035,7 @@ static int am335x_i2c_isr_process(struct am335x_i2c_priv_s *priv)
|
|||
*/
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&priv->spinlock);
|
||||
#endif
|
||||
|
||||
/* Receive a byte */
|
||||
|
@ -1036,7 +1045,7 @@ static int am335x_i2c_isr_process(struct am335x_i2c_priv_s *priv)
|
|||
priv->dcnt--;
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
#endif
|
||||
if ((priv->msgc <= 0) && (priv->dcnt == 0))
|
||||
{
|
||||
|
@ -1100,7 +1109,7 @@ static int am335x_i2c_isr_process(struct am335x_i2c_priv_s *priv)
|
|||
*/
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&priv->spinlock);
|
||||
#endif
|
||||
|
||||
/* Transmit a byte */
|
||||
|
@ -1109,7 +1118,7 @@ static int am335x_i2c_isr_process(struct am335x_i2c_priv_s *priv)
|
|||
priv->dcnt--;
|
||||
|
||||
#ifdef CONFIG_I2C_POLLED
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
#endif
|
||||
if ((priv->dcnt == 0) && ((priv->flags & I2C_M_NOSTOP) == 0))
|
||||
{
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "sctlr.h"
|
||||
|
@ -36,6 +37,13 @@
|
|||
#include "am335x_gpio.h"
|
||||
#include "am335x_irq.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
#ifdef CONFIG_ARCH_IRQPRIO
|
||||
static spinlock_t g_irq_lock = SP_UNLOCKED;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
@ -328,7 +336,7 @@ int up_prioritize_irq(int irq, int priority)
|
|||
{
|
||||
/* These operations must be atomic */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_irq_lock);
|
||||
|
||||
#if 0 // TODO
|
||||
/* Set the new priority */
|
||||
|
@ -340,7 +348,7 @@ int up_prioritize_irq(int irq, int priority)
|
|||
putreg32(regval, regaddr);
|
||||
#endif
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_irq_lock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#endif
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
#include <nuttx/serial/serial.h>
|
||||
|
@ -76,13 +77,14 @@
|
|||
|
||||
struct up_dev_s
|
||||
{
|
||||
uint32_t uartbase; /* Base address of UART registers */
|
||||
uint32_t baud; /* Configured baud */
|
||||
uint32_t ier; /* Saved IER value */
|
||||
uint8_t irq; /* IRQ associated with this UART */
|
||||
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||
uint8_t bits; /* Number of bits (7 or 8) */
|
||||
bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */
|
||||
uint32_t uartbase; /* Base address of UART registers */
|
||||
uint32_t baud; /* Configured baud */
|
||||
uint32_t ier; /* Saved IER value */
|
||||
uint8_t irq; /* IRQ associated with this UART */
|
||||
uint8_t parity; /* 0=none, 1=odd, 2=even */
|
||||
uint8_t bits; /* Number of bits (7 or 8) */
|
||||
bool stopbits2; /* true: Configure with 2 stop bits instead of 1 */
|
||||
spinlock_t spinlock; /* Spinlock */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -169,6 +171,7 @@ static struct up_dev_s g_uart0priv =
|
|||
.parity = CONFIG_UART0_PARITY,
|
||||
.bits = CONFIG_UART0_BITS,
|
||||
.stopbits2 = CONFIG_UART0_2STOP,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
};
|
||||
|
||||
static uart_dev_t g_uart0port =
|
||||
|
@ -200,6 +203,7 @@ static struct up_dev_s g_uart1priv =
|
|||
.parity = CONFIG_UART1_PARITY,
|
||||
.bits = CONFIG_UART1_BITS,
|
||||
.stopbits2 = CONFIG_UART1_2STOP,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
};
|
||||
|
||||
static uart_dev_t g_uart1port =
|
||||
|
@ -230,6 +234,7 @@ static struct up_dev_s g_uart2priv =
|
|||
.parity = CONFIG_UART2_PARITY,
|
||||
.bits = CONFIG_UART2_BITS,
|
||||
.stopbits2 = CONFIG_UART2_2STOP,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
};
|
||||
|
||||
static uart_dev_t g_uart2port =
|
||||
|
@ -260,6 +265,7 @@ static struct up_dev_s g_uart3priv =
|
|||
.parity = CONFIG_UART3_PARITY,
|
||||
.bits = CONFIG_UART3_BITS,
|
||||
.stopbits2 = CONFIG_UART3_2STOP,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
};
|
||||
|
||||
static uart_dev_t g_uart3port =
|
||||
|
@ -290,6 +296,7 @@ static struct up_dev_s g_uart4priv =
|
|||
.parity = CONFIG_UART4_PARITY,
|
||||
.bits = CONFIG_UART4_BITS,
|
||||
.stopbits2 = CONFIG_UART4_2STOP,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
};
|
||||
|
||||
static uart_dev_t g_uart4port =
|
||||
|
@ -320,6 +327,7 @@ static struct up_dev_s g_uart5priv =
|
|||
.parity = CONFIG_UART5_PARITY,
|
||||
.bits = CONFIG_UART5_BITS,
|
||||
.stopbits2 = CONFIG_UART5_2STOP,
|
||||
.spinlock = SP_UNLOCKED,
|
||||
};
|
||||
|
||||
static uart_dev_t g_uart5port =
|
||||
|
@ -484,6 +492,10 @@ static uart_dev_t g_uart5port =
|
|||
# define UART5_ASSIGNED 1
|
||||
#endif
|
||||
|
||||
/* Spinlock */
|
||||
|
||||
static spinlock_t g_gpio_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Inline Functions
|
||||
****************************************************************************/
|
||||
|
@ -567,7 +579,7 @@ static inline void am335x_uart0config(void)
|
|||
|
||||
/* Step 1: Enable power to UART0 */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
#warning Missing logic
|
||||
|
||||
/* Step 2: Enable clocking to UART0 */
|
||||
|
@ -577,7 +589,7 @@ static inline void am335x_uart0config(void)
|
|||
|
||||
am335x_gpio_config(GPIO_UART0_TXD);
|
||||
am335x_gpio_config(GPIO_UART0_RXD);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -588,7 +600,7 @@ static inline void am335x_uart1config(void)
|
|||
|
||||
/* Step 1: Enable power to UART1 */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
#warning Missing logic
|
||||
|
||||
/* Step 2: Enable clocking to UART1 */
|
||||
|
@ -598,7 +610,7 @@ static inline void am335x_uart1config(void)
|
|||
|
||||
am335x_gpio_config(GPIO_UART1_TXD);
|
||||
am335x_gpio_config(GPIO_UART1_RXD);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -609,7 +621,7 @@ static inline void am335x_uart2config(void)
|
|||
|
||||
/* Step 1: Enable power to UART2 */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
#warning Missing logic
|
||||
|
||||
/* Step 2: Enable clocking on UART2 */
|
||||
|
@ -619,7 +631,7 @@ static inline void am335x_uart2config(void)
|
|||
|
||||
am335x_gpio_config(GPIO_UART2_TXD);
|
||||
am335x_gpio_config(GPIO_UART2_RXD);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -630,7 +642,7 @@ static inline void am335x_uart3config(void)
|
|||
|
||||
/* Step 1: Enable power to UART3 */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
#warning Missing logic
|
||||
|
||||
/* Step 2: Enable clocking to UART3 */
|
||||
|
@ -640,7 +652,7 @@ static inline void am335x_uart3config(void)
|
|||
|
||||
am335x_gpio_config(GPIO_UART3_TXD);
|
||||
am335x_gpio_config(GPIO_UART3_RXD);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -651,7 +663,7 @@ static inline void am335x_uart4config(void)
|
|||
|
||||
/* Step 1: Enable power to UART4 */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
#warning Missing logic
|
||||
|
||||
/* Step 2: Enable clocking to UART4 */
|
||||
|
@ -661,7 +673,7 @@ static inline void am335x_uart4config(void)
|
|||
|
||||
am335x_gpio_config(GPIO_UART4_TXD);
|
||||
am335x_gpio_config(GPIO_UART4_RXD);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -672,7 +684,7 @@ static inline void am335x_uart5config(void)
|
|||
|
||||
/* Step 1: Enable power to UART5 */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
#warning Missing logic
|
||||
|
||||
/* Step 2: Enable clocking to UART5 */
|
||||
|
@ -682,7 +694,7 @@ static inline void am335x_uart5config(void)
|
|||
|
||||
am335x_gpio_config(GPIO_UART5_TXD);
|
||||
am335x_gpio_config(GPIO_UART5_RXD);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -1029,18 +1041,18 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg)
|
|||
|
||||
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
|
||||
{
|
||||
irqstate_t flags = enter_critical_section();
|
||||
irqstate_t flags = spin_lock_irqsave(&priv->spinlock);
|
||||
up_enablebreaks(priv, true);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */
|
||||
{
|
||||
irqstate_t flags;
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&priv->spinlock);
|
||||
up_enablebreaks(priv, false);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1204,13 +1216,15 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
|
|||
struct up_dev_s *priv = (struct up_dev_s *)dev->priv;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&priv->spinlock);
|
||||
if (enable)
|
||||
{
|
||||
#ifndef CONFIG_SUPPRESS_SERIAL_INTS
|
||||
priv->ier |= UART_IER_THR;
|
||||
up_serialout(priv, AM335X_UART_IER_OFFSET, priv->ier);
|
||||
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
|
||||
/* Fake a TX interrupt here by just calling uart_xmitchars() with
|
||||
* interrupts disabled (note this may recurse).
|
||||
*/
|
||||
|
@ -1222,9 +1236,9 @@ static void up_txint(struct uart_dev_s *dev, bool enable)
|
|||
{
|
||||
priv->ier &= ~UART_IER_THR;
|
||||
up_serialout(priv, AM335X_UART_IER_OFFSET, priv->ier);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -31,11 +31,18 @@
|
|||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMVECTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_ramvec_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -68,7 +75,7 @@ int arm_ramvec_attach(int irq, up_vector_t vector)
|
|||
* common exception handler.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_ramvec_lock);
|
||||
if (vector == NULL)
|
||||
{
|
||||
/* Disable the interrupt if we can before detaching it. We might
|
||||
|
@ -87,7 +94,7 @@ int arm_ramvec_attach(int irq, up_vector_t vector)
|
|||
/* Save the new vector in the vector table */
|
||||
|
||||
g_ram_vectors[irq] = vector;
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_ramvec_lock, flags);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,18 @@
|
|||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMVECTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_ramvec_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -68,7 +75,7 @@ int arm_ramvec_attach(int irq, up_vector_t vector)
|
|||
* common exception handler.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_ramvec_lock);
|
||||
if (vector == NULL)
|
||||
{
|
||||
/* Disable the interrupt if we can before detaching it. We might
|
||||
|
@ -87,7 +94,7 @@ int arm_ramvec_attach(int irq, up_vector_t vector)
|
|||
/* Save the new vector in the vector table */
|
||||
|
||||
g_ram_vectors[irq] = vector;
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_ramvec_lock, flags);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,18 @@
|
|||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include "ram_vectors.h"
|
||||
|
||||
#ifdef CONFIG_ARCH_RAMVECTORS
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static spinlock_t g_ramvec_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -68,7 +75,7 @@ int arm_ramvec_attach(int irq, up_vector_t vector)
|
|||
* common exception handler.
|
||||
*/
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_ramvec_lock);
|
||||
if (vector == NULL)
|
||||
{
|
||||
/* Disable the interrupt if we can before detaching it. We might
|
||||
|
@ -87,7 +94,7 @@ int arm_ramvec_attach(int irq, up_vector_t vector)
|
|||
/* Save the new vector in the vector table */
|
||||
|
||||
g_ram_vectors[irq] = vector;
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_ramvec_lock, flags);
|
||||
ret = OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -546,7 +546,9 @@ ifeq ($(CONFIG_PIC),y)
|
|||
# Generate an executable elf, need to ignore undefined symbols
|
||||
LDELFFLAGS += --unresolved-symbols=ignore-in-object-files --emit-relocs
|
||||
else
|
||||
LDELFFLAGS += -r
|
||||
ifneq ($(CONFIG_BINFMT_ELF_EXECUTABLE),y)
|
||||
LDELFFLAGS += -r
|
||||
endif
|
||||
endif
|
||||
|
||||
LDELFFLAGS += -e main -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)modlib$(DELIM)gnu-elf.ld)
|
||||
|
|
|
@ -15,6 +15,7 @@ config ARCH_CHIP_QEMU_CORTEXA7
|
|||
bool "Qemu virtual Processor (cortex-a7)"
|
||||
select ARCH_CORTEXA7
|
||||
select ARCH_HAVE_ADDRENV
|
||||
select ARCH_HAVE_ELF_EXECUTABLE
|
||||
select ARCH_HAVE_LOWVECTORS
|
||||
select ARCH_HAVE_MULTICPU
|
||||
select ARCH_NEED_ADDRENV_MAPPING
|
||||
|
|
|
@ -59,8 +59,8 @@
|
|||
#define hw_claim_lock() spin_lock_irqsave(&pio_lock)
|
||||
#define hw_claim_unlock(save) spin_unlock_irqrestore(&pio_lock, save)
|
||||
#else
|
||||
#define hw_claim_lock() spin_lock_irqsave(NULL)
|
||||
#define hw_claim_unlock(save) spin_unlock_irqrestore(NULL, save)
|
||||
#define hw_claim_lock() up_irq_save()
|
||||
#define hw_claim_unlock(save) up_irq_restore(save)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -2920,10 +2920,10 @@ config STM32H5_ADC1_SAMPLE_FREQUENCY
|
|||
config STM32H5_ADC1_TIMTRIG
|
||||
int "ADC1 Timer Trigger"
|
||||
default 0
|
||||
range 0 4
|
||||
range 0 5
|
||||
depends on STM32H5_HAVE_ADC1_TIMER
|
||||
---help---
|
||||
Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
|
||||
Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO 5:TRGO2
|
||||
|
||||
config STM32H5_ADC2_SAMPLE_FREQUENCY
|
||||
int "ADC2 Sampling Frequency"
|
||||
|
@ -2935,10 +2935,10 @@ config STM32H5_ADC2_SAMPLE_FREQUENCY
|
|||
config STM32H5_ADC2_TIMTRIG
|
||||
int "ADC2 Timer Trigger"
|
||||
default 0
|
||||
range 0 4
|
||||
range 0 5
|
||||
depends on STM32H5_HAVE_ADC2_TIMER
|
||||
---help---
|
||||
Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO
|
||||
Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO 5:TRGO2
|
||||
|
||||
config STM32H5_TIM1_CAP
|
||||
bool "TIM1 Capture"
|
||||
|
|
|
@ -363,6 +363,26 @@
|
|||
#define STM32_TIM16_DCR (STM32_TIM16_BASE+STM32_GTIM_DCR_OFFSET)
|
||||
#define STM32_TIM16_DMAR (STM32_TIM16_BASE+STM32_GTIM_DMAR_OFFSET)
|
||||
|
||||
#define STM32_TIM17_CR1 (STM32_TIM17_BASE+STM32_GTIM_CR1_OFFSET)
|
||||
#define STM32_TIM17_CR2 (STM32_TIM17_BASE+STM32_GTIM_CR2_OFFSET)
|
||||
#define STM32_TIM17_DIER (STM32_TIM17_BASE+STM32_GTIM_DIER_OFFSET)
|
||||
#define STM32_TIM17_SR (STM32_TIM17_BASE+STM32_GTIM_SR_OFFSET)
|
||||
#define STM32_TIM17_EGR (STM32_TIM17_BASE+STM32_GTIM_EGR_OFFSET)
|
||||
#define STM32_TIM17_CCMR1 (STM32_TIM17_BASE+STM32_GTIM_CCMR1_OFFSET)
|
||||
#define STM32_TIM17_CCER (STM32_TIM17_BASE+STM32_GTIM_CCER_OFFSET)
|
||||
#define STM32_TIM17_CNT (STM32_TIM17_BASE+STM32_GTIM_CNT_OFFSET)
|
||||
#define STM32_TIM17_PSC (STM32_TIM17_BASE+STM32_GTIM_PSC_OFFSET)
|
||||
#define STM32_TIM17_ARR (STM32_TIM17_BASE+STM32_GTIM_ARR_OFFSET)
|
||||
#define STM32_TIM17_RCR (STM32_TIM17_BASE+STM32_GTIM_RCR_OFFSET)
|
||||
#define STM32_TIM17_CCR1 (STM32_TIM17_BASE+STM32_GTIM_CCR1_OFFSET)
|
||||
#define STM32_TIM17_BDTR (STM32_TIM17_BASE+STM32_GTIM_BDTR_OFFSET)
|
||||
#define STM32_TIM17_DTR2 (STM32_TIM17_BASE+STM32_GTIM_DTR2_OFFSET)
|
||||
#define STM32_TIM17_TISEL (STM32_TIM17_BASE+STM32_GTIM_TISEL_OFFSET)
|
||||
#define STM32_TIM17_AF1 (STM32_TIM17_BASE+STM32_GTIM_AF1_OFFSET)
|
||||
#define STM32_TIM17_AF2 (STM32_TIM17_BASE+STM32_GTIM_AF2_OFFSET)
|
||||
#define STM32_TIM17_DCR (STM32_TIM17_BASE+STM32_GTIM_DCR_OFFSET)
|
||||
#define STM32_TIM17_DMAR (STM32_TIM17_BASE+STM32_GTIM_DMAR_OFFSET)
|
||||
|
||||
/* Register Bitfield Definitions ********************************************/
|
||||
|
||||
/* Basic Timers - TIM6 and TIM7 */
|
||||
|
@ -764,6 +784,12 @@
|
|||
#define ATIM_CCER_CC4E (1 << 12) /* Bit 12: Capture/Compare 4 output enable */
|
||||
#define ATIM_CCER_CC4P (1 << 13) /* Bit 13: Capture/Compare 4 output Polarity */
|
||||
#define ATIM_CCER_CC4NE (1 << 14) /* Bit 14: Capture/compare 4 Complementary output enable */
|
||||
#define ATIM_CCER_CC4NP (1 << 15) /* Bit 15: Capture/Compare 4 Complementary output polarity */
|
||||
#define ATIM_CCER_CC5E (1 << 16) /* Bit 16: Capture/Compare 5 output enable */
|
||||
#define ATIM_CCER_CC5P (1 << 17) /* Bit 17: Capture/Compare 5 output Polarity */
|
||||
#define ATIM_CCER_CC6E (1 << 20) /* Bit 20: Capture/Compare 6 output enable */
|
||||
#define ATIM_CCER_CC6P (1 << 21) /* Bit 21: Capture/Compare 6 output Polarity */
|
||||
|
||||
#define ATIM_CCER_CCXBASE(ch) ((ch) << 2) /* Each channel uses 4-bits */
|
||||
|
||||
/* Counter Register */
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
|
||||
#include "chip.h"
|
||||
#include "stm32_adc.h"
|
||||
#include "stm32_tim.h"
|
||||
#include "stm32_rcc.h"
|
||||
|
||||
#ifdef CONFIG_ADC
|
||||
|
@ -166,6 +167,16 @@ static void adc_putreg(struct stm32_dev_s *priv, int offset, uint32_t value);
|
|||
static void adc_modifyreg(struct stm32_dev_s *priv, int offset,
|
||||
uint32_t clrbits, uint32_t setbits);
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static uint16_t tim_getreg(struct stm32_dev_s *priv, int offset);
|
||||
static void tim_putreg(struct stm32_dev_s *priv, int offset,
|
||||
uint16_t value);
|
||||
static void tim_modifyreg(struct stm32_dev_s *priv, int offset,
|
||||
uint16_t clrbits, uint16_t setbits);
|
||||
static void tim_dumpregs(struct stm32_dev_s *priv,
|
||||
const char *msg);
|
||||
#endif
|
||||
|
||||
/* ADC Miscellaneous Helpers */
|
||||
|
||||
static void adc_rccreset(struct stm32_dev_s *priv, bool reset);
|
||||
|
@ -178,6 +189,11 @@ static bool adc_internal(struct stm32_dev_s * priv, uint32_t *adc_ccr);
|
|||
static void adc_startconv(struct stm32_dev_s *priv, bool enable);
|
||||
static void adc_wdog_enable(struct stm32_dev_s *priv);
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static void adc_timstart(struct stm32_dev_s *priv, bool enable);
|
||||
static int adc_timinit(struct stm32_dev_s *priv);
|
||||
#endif
|
||||
|
||||
/* ADC Interrupt Handler */
|
||||
|
||||
static int adc_interrupt(struct adc_dev_s *dev, uint32_t regval);
|
||||
|
@ -220,6 +236,15 @@ static struct stm32_dev_s g_adcpriv1 =
|
|||
.base = STM32_ADC1_BASE,
|
||||
.mbase = STM32_ADC1_BASE,
|
||||
.initialized = false,
|
||||
#ifdef ADC1_HAVE_TIMER
|
||||
.trigger = CONFIG_STM32H5_ADC1_TIMTRIG,
|
||||
.tbase = ADC1_TIMER_BASE,
|
||||
.trcc_enr = ADC1_TIMER_RCC_ENR,
|
||||
.trcc_en = ADC1_TIMER_RCC_EN,
|
||||
.extsel = ADC1_EXTSEL_VALUE,
|
||||
.pclck = ADC1_TIMER_PCLK_FREQUENCY,
|
||||
.freq = CONFIG_STM32H5_ADC1_SAMPLE_FREQUENCY,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct adc_dev_s g_adcdev1 =
|
||||
|
@ -240,6 +265,15 @@ static struct stm32_dev_s g_adcpriv2 =
|
|||
.base = STM32_ADC2_BASE,
|
||||
.mbase = STM32_ADC2_BASE,
|
||||
.initialized = false,
|
||||
#ifdef ADC2_HAVE_TIMER
|
||||
.trigger = CONFIG_STM32H5_ADC2_TIMTRIG,
|
||||
.tbase = ADC2_TIMER_BASE,
|
||||
.trcc_enr = ADC2_TIMER_RCC_ENR,
|
||||
.trcc_en = ADC2_TIMER_RCC_EN,
|
||||
.extsel = ADC2_EXTSEL_VALUE,
|
||||
.pclck = ADC2_TIMER_PCLK_FREQUENCY,
|
||||
.freq = CONFIG_STM32H5_ADC2_SAMPLE_FREQUENCY,
|
||||
#endif
|
||||
};
|
||||
|
||||
static struct adc_dev_s g_adcdev2 =
|
||||
|
@ -1212,7 +1246,7 @@ static int adc_interrupt(struct adc_dev_s *dev, uint32_t adcisr)
|
|||
if ((adcisr & ADC_INT_EOC) != 0)
|
||||
{
|
||||
/* Read from the ADC_DR register until 8 stage FIFO is empty.
|
||||
* The FIFO is first mentioned in STM32H7 Reference Manual
|
||||
* The FIFO is first mentioned in STM32H5 Reference Manual
|
||||
* rev. 7, though, not yet indicated in the block diagram!
|
||||
*/
|
||||
|
||||
|
@ -1307,6 +1341,521 @@ static int adc12_interrupt(int irq, void *context, void *arg)
|
|||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tim_getreg
|
||||
*
|
||||
* Description:
|
||||
* Read the value of an ADC timer register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the ADC block status
|
||||
* offset - The offset to the register to read
|
||||
*
|
||||
* Returned Value:
|
||||
* The current contents of the specified register
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static uint16_t tim_getreg(struct stm32_dev_s *priv, int offset)
|
||||
{
|
||||
return getreg16(priv->tbase + offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tim_putreg
|
||||
*
|
||||
* Description:
|
||||
* Write a value to an ADC timer register.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the ADC block status
|
||||
* offset - The offset to the register to write to
|
||||
* value - The value to write to the register
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static void tim_putreg(struct stm32_dev_s *priv, int offset,
|
||||
uint16_t value)
|
||||
{
|
||||
putreg16(value, priv->tbase + offset);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tim_modifyreg
|
||||
*
|
||||
* Description:
|
||||
* Modify the value of an ADC timer register (not atomic).
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the ADC block status
|
||||
* offset - The offset to the register to modify
|
||||
* clrbits - The bits to clear
|
||||
* setbits - The bits to set
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static void tim_modifyreg(struct stm32_dev_s *priv, int offset,
|
||||
uint16_t clrbits, uint16_t setbits)
|
||||
{
|
||||
tim_putreg(priv, offset, (tim_getreg(priv, offset) & ~clrbits) | setbits);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: tim_dumpregs
|
||||
*
|
||||
* Description:
|
||||
* Dump all timer registers.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the ADC block status
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static void tim_dumpregs(struct stm32_dev_s *priv, const char *msg)
|
||||
{
|
||||
ainfo("%s:\n", msg);
|
||||
ainfo(" CR1: %04x CR2: %04x SMCR: %04x DIER: %04x\n",
|
||||
tim_getreg(priv, STM32_GTIM_CR1_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_CR2_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_SMCR_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_DIER_OFFSET));
|
||||
ainfo(" SR: %04x EGR: 0000 CCMR1: %04x CCMR2: %04x\n",
|
||||
tim_getreg(priv, STM32_GTIM_SR_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_CCMR1_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_CCMR2_OFFSET));
|
||||
ainfo(" CCER: %04x CNT: %04x PSC: %04x ARR: %04x\n",
|
||||
tim_getreg(priv, STM32_GTIM_CCER_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_CNT_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_PSC_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_ARR_OFFSET));
|
||||
ainfo(" CCR1: %04x CCR2: %04x CCR3: %04x CCR4: %04x\n",
|
||||
tim_getreg(priv, STM32_GTIM_CCR1_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_CCR2_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_CCR3_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_CCR4_OFFSET));
|
||||
|
||||
if (priv->tbase == STM32_TIM1_BASE || priv->tbase == STM32_TIM8_BASE)
|
||||
{
|
||||
ainfo(" RCR: %04x BDTR: %04x DCR: %04x DMAR: %04x\n",
|
||||
tim_getreg(priv, STM32_ATIM_RCR_OFFSET),
|
||||
tim_getreg(priv, STM32_ATIM_BDTR_OFFSET),
|
||||
tim_getreg(priv, STM32_ATIM_DCR_OFFSET),
|
||||
tim_getreg(priv, STM32_ATIM_DMAR_OFFSET));
|
||||
}
|
||||
else
|
||||
{
|
||||
ainfo(" DCR: %04x DMAR: %04x\n",
|
||||
tim_getreg(priv, STM32_GTIM_DCR_OFFSET),
|
||||
tim_getreg(priv, STM32_GTIM_DMAR_OFFSET));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_timstart
|
||||
*
|
||||
* Description:
|
||||
* Start (or stop) the timer counter
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the ADC block status
|
||||
* enable - True: Start conversion
|
||||
*
|
||||
* Returned Value:
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static void adc_timstart(struct stm32_dev_s *priv, bool enable)
|
||||
{
|
||||
ainfo("enable: %d\n", enable ? 1 : 0);
|
||||
|
||||
if (enable)
|
||||
{
|
||||
/* Start the counter */
|
||||
|
||||
tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_CEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the counter */
|
||||
|
||||
tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, GTIM_CR1_CEN, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: adc_timinit
|
||||
*
|
||||
* Description:
|
||||
* Initialize the timer that drivers the ADC sampling for this channel
|
||||
* using the pre-calculated timer divider definitions.
|
||||
*
|
||||
* Input Parameters:
|
||||
* priv - A reference to the ADC block status
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef ADC_HAVE_TIMER
|
||||
static int adc_timinit(struct stm32_dev_s *priv)
|
||||
{
|
||||
uint32_t prescaler;
|
||||
uint32_t reload;
|
||||
uint32_t timclk;
|
||||
|
||||
uint16_t clrbits = 0;
|
||||
uint16_t setbits = 0;
|
||||
uint16_t cr2;
|
||||
uint16_t ccmr1;
|
||||
uint16_t ccmr2;
|
||||
uint16_t ocmode1;
|
||||
uint16_t ocmode2;
|
||||
uint16_t ccenable;
|
||||
uint16_t ccer;
|
||||
uint16_t egr;
|
||||
|
||||
/* If the timer base address is zero, then this ADC was not configured to
|
||||
* use a timer.
|
||||
*/
|
||||
|
||||
if (priv->tbase == 0)
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* EXTSEL selection: These bits select the external event used to trigger
|
||||
* the start of conversion of a regular group. NOTE:
|
||||
*
|
||||
* - The position with of the EXTSEL field varies from one STM32 MCU
|
||||
* to another.
|
||||
* - The width of the EXTSEL field varies from one STM32 MCU to another.
|
||||
* - The value in priv->extsel is already shifted into the correct bit
|
||||
* position.
|
||||
*/
|
||||
|
||||
ainfo("Initializing timers extsel = 0x%08" PRIx32 "\n", priv->extsel);
|
||||
|
||||
adc_modifyreg(priv, STM32_ADC_CFGR_OFFSET,
|
||||
ADC_CFGR_EXTEN_MASK | ADC_CFGR_EXTSEL_MASK,
|
||||
ADC_CFGR_EXTEN_RISING | priv->extsel);
|
||||
|
||||
/* Configure the timer channel to drive the ADC */
|
||||
|
||||
/* Enable Timer clocking */
|
||||
|
||||
modifyreg32(priv->trcc_enr, 0, priv->trcc_en);
|
||||
|
||||
/* Calculate optimal values for the timer prescaler and for the timer
|
||||
* reload register. If freq is the desired frequency, then
|
||||
*
|
||||
* reload = timclk / freq
|
||||
* reload = (pclck / prescaler) / freq
|
||||
*
|
||||
* There are many solutions to do this, but the best solution will be the
|
||||
* one that has the largest reload value and the smallest prescaler value.
|
||||
* That is the solution that should give us the most accuracy in the timer
|
||||
* control. Subject to:
|
||||
*
|
||||
* 0 <= prescaler <= 65536
|
||||
* 1 <= reload <= 65535
|
||||
*
|
||||
* So ( prescaler = pclck / 65535 / freq ) would be optimal.
|
||||
*/
|
||||
|
||||
prescaler = (priv->pclck / priv->freq + 65534) / 65535;
|
||||
|
||||
/* We need to decrement the prescaler value by one, but only, the value
|
||||
* does not underflow.
|
||||
*/
|
||||
|
||||
if (prescaler < 1)
|
||||
{
|
||||
awarn("WARNING: Prescaler underflowed.\n");
|
||||
prescaler = 1;
|
||||
}
|
||||
|
||||
/* Check for overflow */
|
||||
|
||||
else if (prescaler > 65536)
|
||||
{
|
||||
awarn("WARNING: Prescaler overflowed.\n");
|
||||
prescaler = 65536;
|
||||
}
|
||||
|
||||
timclk = priv->pclck / prescaler;
|
||||
|
||||
reload = timclk / priv->freq;
|
||||
if (reload < 1)
|
||||
{
|
||||
awarn("WARNING: Reload value underflowed.\n");
|
||||
reload = 1;
|
||||
}
|
||||
|
||||
else if (reload > 65535)
|
||||
{
|
||||
awarn("WARNING: Reload value overflowed.\n");
|
||||
reload = 65535;
|
||||
}
|
||||
|
||||
/* Disable the timer until we get it configured */
|
||||
|
||||
adc_timstart(priv, false);
|
||||
|
||||
/* Set up the timer CR1 register.
|
||||
*
|
||||
* Select the Counter Mode == count up:
|
||||
*
|
||||
* ATIM_CR1_EDGE: The counter counts up or down depending on the
|
||||
* direction bit(DIR).
|
||||
* ATIM_CR1_DIR: 0: count up, 1: count down
|
||||
*
|
||||
* Set the clock division to zero for all
|
||||
*/
|
||||
|
||||
clrbits = GTIM_CR1_DIR | GTIM_CR1_CMS_MASK | GTIM_CR1_CKD_MASK;
|
||||
setbits = GTIM_CR1_EDGE;
|
||||
tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, clrbits, setbits);
|
||||
|
||||
/* Set the reload and prescaler values */
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_PSC_OFFSET, prescaler - 1);
|
||||
tim_putreg(priv, STM32_GTIM_ARR_OFFSET, reload);
|
||||
|
||||
/* Clear the advanced timers repetition counter in TIM1 */
|
||||
|
||||
if (priv->tbase == STM32_TIM1_BASE || priv->tbase == STM32_TIM8_BASE)
|
||||
{
|
||||
tim_putreg(priv, STM32_ATIM_RCR_OFFSET, 0);
|
||||
tim_putreg(priv, STM32_ATIM_BDTR_OFFSET, ATIM_BDTR_MOE); /* Check me */
|
||||
}
|
||||
|
||||
/* TIMx event generation: Bit 0 UG: Update generation */
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_EGR_OFFSET, GTIM_EGR_UG);
|
||||
|
||||
/* Handle channel specific setup */
|
||||
|
||||
ocmode1 = 0;
|
||||
ocmode2 = 0;
|
||||
|
||||
switch (priv->trigger)
|
||||
{
|
||||
case 0: /* TimerX CC1 event */
|
||||
{
|
||||
ccenable = ATIM_CCER_CC1E;
|
||||
ocmode1 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC1S_SHIFT) |
|
||||
(ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC1M_SHIFT) |
|
||||
ATIM_CCMR1_OC1PE;
|
||||
|
||||
/* Set the event CC1 */
|
||||
|
||||
egr = ATIM_EGR_CC1G;
|
||||
|
||||
/* Set the duty cycle by writing to the CCR register for this
|
||||
* channel
|
||||
*/
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_CCR1_OFFSET, (uint16_t)(reload >> 1));
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* TimerX CC2 event */
|
||||
{
|
||||
ccenable = ATIM_CCER_CC2E;
|
||||
ocmode1 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR1_CC2S_SHIFT) |
|
||||
(ATIM_CCMR_MODE_PWM1 << ATIM_CCMR1_OC2M_SHIFT) |
|
||||
ATIM_CCMR1_OC2PE;
|
||||
|
||||
/* Set the event CC2 */
|
||||
|
||||
egr = ATIM_EGR_CC2G;
|
||||
|
||||
/* Set the duty cycle by writing to the CCR register for this
|
||||
* channel
|
||||
*/
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_CCR2_OFFSET, (uint16_t)(reload >> 1));
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* TimerX CC3 event */
|
||||
{
|
||||
ccenable = ATIM_CCER_CC3E;
|
||||
ocmode2 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC3S_SHIFT) |
|
||||
(ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC3M_SHIFT) |
|
||||
ATIM_CCMR2_OC3PE;
|
||||
|
||||
/* Set the event CC3 */
|
||||
|
||||
egr = ATIM_EGR_CC3G;
|
||||
|
||||
/* Set the duty cycle by writing to the CCR register for this
|
||||
* channel
|
||||
*/
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_CCR3_OFFSET, (uint16_t)(reload >> 1));
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: /* TimerX CC4 event */
|
||||
{
|
||||
ccenable = ATIM_CCER_CC4E;
|
||||
ocmode2 = (ATIM_CCMR_CCS_CCOUT << ATIM_CCMR2_CC4S_SHIFT) |
|
||||
(ATIM_CCMR_MODE_PWM1 << ATIM_CCMR2_OC4M_SHIFT) |
|
||||
ATIM_CCMR2_OC4PE;
|
||||
|
||||
/* Set the event CC4 */
|
||||
|
||||
egr = ATIM_EGR_CC4G;
|
||||
|
||||
/* Set the duty cycle by writing to the CCR register for this
|
||||
* channel
|
||||
*/
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_CCR4_OFFSET, (uint16_t)(reload >> 1));
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: /* TimerX TRGO event */
|
||||
{
|
||||
/* TODO: TRGO support not yet implemented */
|
||||
|
||||
/* Set the event TRGO */
|
||||
|
||||
ccenable = 0;
|
||||
egr = GTIM_EGR_TG;
|
||||
|
||||
/* Set the duty cycle by writing to the CCR register for this
|
||||
* channel
|
||||
*/
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_CCR4_OFFSET, (uint16_t)(reload >> 1));
|
||||
}
|
||||
break;
|
||||
|
||||
case 5: /* TimerX TRGO2 event */
|
||||
{
|
||||
/* TODO: TRGO2 support not yet implemented */
|
||||
|
||||
/* Set the event TRGO2 */
|
||||
|
||||
ccenable = 0;
|
||||
egr = GTIM_EGR_TG;
|
||||
|
||||
/* Set the duty cycle by writing to the CCR register for this
|
||||
* channel
|
||||
*/
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_CCR4_OFFSET, (uint16_t)(reload >> 1));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
aerr("ERROR: No such trigger: %d\n", priv->trigger);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Disable the Channel by resetting the CCxE Bit in the CCER register */
|
||||
|
||||
ccer = tim_getreg(priv, STM32_GTIM_CCER_OFFSET);
|
||||
ccer &= ~ccenable;
|
||||
tim_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer);
|
||||
|
||||
/* Fetch the CR2, CCMR1, and CCMR2 register (already have ccer) */
|
||||
|
||||
cr2 = tim_getreg(priv, STM32_GTIM_CR2_OFFSET);
|
||||
ccmr1 = tim_getreg(priv, STM32_GTIM_CCMR1_OFFSET);
|
||||
ccmr2 = tim_getreg(priv, STM32_GTIM_CCMR2_OFFSET);
|
||||
|
||||
/* Reset the Output Compare Mode Bits and set the select output compare
|
||||
* mode
|
||||
*/
|
||||
|
||||
ccmr1 &= ~(ATIM_CCMR1_CC1S_MASK | ATIM_CCMR1_OC1M_MASK | ATIM_CCMR1_OC1PE |
|
||||
ATIM_CCMR1_CC2S_MASK | ATIM_CCMR1_OC2M_MASK | ATIM_CCMR1_OC2PE);
|
||||
ccmr2 &= ~(ATIM_CCMR2_CC3S_MASK | ATIM_CCMR2_OC3M_MASK | ATIM_CCMR2_OC3PE |
|
||||
ATIM_CCMR2_CC4S_MASK | ATIM_CCMR2_OC4M_MASK | ATIM_CCMR2_OC4PE);
|
||||
ccmr1 |= ocmode1;
|
||||
ccmr2 |= ocmode2;
|
||||
|
||||
/* Reset the output polarity level of all channels (selects high
|
||||
* polarity)
|
||||
*/
|
||||
|
||||
ccer &= ~(ATIM_CCER_CC1P | ATIM_CCER_CC2P |
|
||||
ATIM_CCER_CC3P | ATIM_CCER_CC4P);
|
||||
|
||||
/* Enable the output state of the selected channel (only) */
|
||||
|
||||
ccer &= ~(ATIM_CCER_CC1E | ATIM_CCER_CC2E |
|
||||
ATIM_CCER_CC3E | ATIM_CCER_CC4E);
|
||||
ccer |= ccenable;
|
||||
|
||||
if (priv->tbase == STM32_TIM1_BASE || priv->tbase == STM32_TIM8_BASE)
|
||||
{
|
||||
/* Reset output N polarity level, output N state, output compare state,
|
||||
* output compare N idle state.
|
||||
*/
|
||||
|
||||
ccer &= ~(ATIM_CCER_CC1NE | ATIM_CCER_CC1NP |
|
||||
ATIM_CCER_CC2NE | ATIM_CCER_CC2NP |
|
||||
ATIM_CCER_CC3NE | ATIM_CCER_CC3NP |
|
||||
ATIM_CCER_CC4NP);
|
||||
|
||||
/* Reset the output compare and output compare N IDLE State */
|
||||
|
||||
cr2 &= ~(ATIM_CR2_OIS1 | ATIM_CR2_OIS1N |
|
||||
ATIM_CR2_OIS2 | ATIM_CR2_OIS2N |
|
||||
ATIM_CR2_OIS3 | ATIM_CR2_OIS3N |
|
||||
ATIM_CR2_OIS4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ccer &= ~(GTIM_CCER_CC1NP | GTIM_CCER_CC2NP | GTIM_CCER_CC3NP);
|
||||
}
|
||||
|
||||
/* Save the modified register values */
|
||||
|
||||
tim_putreg(priv, STM32_GTIM_CR2_OFFSET, cr2);
|
||||
tim_putreg(priv, STM32_GTIM_CCMR1_OFFSET, ccmr1);
|
||||
tim_putreg(priv, STM32_GTIM_CCMR2_OFFSET, ccmr2);
|
||||
tim_putreg(priv, STM32_GTIM_CCER_OFFSET, ccer);
|
||||
tim_putreg(priv, STM32_GTIM_EGR_OFFSET, egr);
|
||||
|
||||
/* Set the ARR Preload Bit */
|
||||
|
||||
tim_modifyreg(priv, STM32_GTIM_CR1_OFFSET, 0, GTIM_CR1_ARPE);
|
||||
|
||||
/* Enable the timer counter */
|
||||
|
||||
adc_timstart(priv, true);
|
||||
|
||||
tim_dumpregs(priv, "After starting timers");
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -1369,3 +1918,4 @@ struct adc_dev_s *stm32h5_adc_initialize(int intf,
|
|||
}
|
||||
#endif /* CONFIG_STM32H5_ADC1 || CONFIG_STM32H5_ADC2 */
|
||||
#endif /* CONFIG_ADC */
|
||||
|
||||
|
|
|
@ -38,6 +38,462 @@
|
|||
|
||||
#if defined(CONFIG_STM32H5_ADC1) || defined(CONFIG_STM32H5_ADC2)
|
||||
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/* Timer devices may be used for different purposes. One special purpose is
|
||||
* to control periodic ADC sampling. If CONFIG_STM32H5_TIMn is defined then
|
||||
* CONFIG_STM32H5_TIMn_ADC must also be defined to indicate that timer "n"
|
||||
* is intended to be used for that purpose. Timers 1,2,3,6 and 15 may be
|
||||
* used on STM32H5X3, while STM32H5X6 adds support for timers 4 and 8 as
|
||||
* well.
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_STM32H5_TIM1
|
||||
# undef CONFIG_STM32H5_TIM1_ADC
|
||||
# undef CONFIG_STM32H5_TIM1_ADC1
|
||||
# undef CONFIG_STM32H5_TIM1_ADC2
|
||||
# undef CONFIG_STM32H5_TIM1_ADC3
|
||||
#endif
|
||||
#ifndef CONFIG_STM32H5_TIM2
|
||||
# undef CONFIG_STM32H5_TIM2_ADC
|
||||
# undef CONFIG_STM32H5_TIM2_ADC1
|
||||
# undef CONFIG_STM32H5_TIM2_ADC2
|
||||
# undef CONFIG_STM32H5_TIM2_ADC3
|
||||
#endif
|
||||
#ifndef CONFIG_STM32H5_TIM3
|
||||
# undef CONFIG_STM32H5_TIM3_ADC
|
||||
# undef CONFIG_STM32H5_TIM3_ADC1
|
||||
# undef CONFIG_STM32H5_TIM3_ADC2
|
||||
# undef CONFIG_STM32H5_TIM3_ADC3
|
||||
#endif
|
||||
#ifndef CONFIG_STM32H5_TIM4
|
||||
# undef CONFIG_STM32H5_TIM4_ADC
|
||||
# undef CONFIG_STM32H5_TIM4_ADC1
|
||||
# undef CONFIG_STM32H5_TIM4_ADC2
|
||||
# undef CONFIG_STM32H5_TIM4_ADC3
|
||||
#endif
|
||||
#ifndef CONFIG_STM32H5_TIM6
|
||||
# undef CONFIG_STM32H5_TIM6_ADC
|
||||
# undef CONFIG_STM32H5_TIM6_ADC1
|
||||
# undef CONFIG_STM32H5_TIM6_ADC2
|
||||
# undef CONFIG_STM32H5_TIM6_ADC3
|
||||
#endif
|
||||
#ifndef CONFIG_STM32H5_TIM8
|
||||
# undef CONFIG_STM32H5_TIM8_ADC
|
||||
# undef CONFIG_STM32H5_TIM8_ADC1
|
||||
# undef CONFIG_STM32H5_TIM8_ADC2
|
||||
# undef CONFIG_STM32H5_TIM8_ADC3
|
||||
#endif
|
||||
#ifndef CONFIG_STM32H5_TIM15
|
||||
# undef CONFIG_STM32H5_TIM15_ADC
|
||||
# undef CONFIG_STM32H5_TIM15_ADC1
|
||||
# undef CONFIG_STM32H5_TIM15_ADC2
|
||||
# undef CONFIG_STM32H5_TIM15_ADC3
|
||||
#endif
|
||||
|
||||
/* Timer configuration: If a timer trigger is specified, then get
|
||||
* information about the timer.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_STM32H5_TIM1_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# define ADC1_TIMER_BASE STM32_TIM1_BASE
|
||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM1_CLKIN
|
||||
# define ADC1_TIMER_RCC_ENR STM32_RCC_APB2ENR
|
||||
# define ADC1_TIMER_RCC_EN RCC_APB2ENR_TIM1EN
|
||||
#elif defined(CONFIG_STM32H5_TIM2_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# define ADC1_TIMER_BASE STM32_TIM2_BASE
|
||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN
|
||||
# define ADC1_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC1_TIMER_RCC_EN RCC_APB1LENR_TIM2EN
|
||||
#elif defined(CONFIG_STM32H5_TIM3_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# define ADC1_TIMER_BASE STM32_TIM3_BASE
|
||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN
|
||||
# define ADC1_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC1_TIMER_RCC_EN RCC_APB1LENR_TIM3EN
|
||||
#elif defined(CONFIG_STM32H5_TIM4_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# define ADC1_TIMER_BASE STM32_TIM4_BASE
|
||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN
|
||||
# define ADC1_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC1_TIMER_RCC_EN RCC_APB1LENR_TIM4EN
|
||||
#elif defined(CONFIG_STM32H5_TIM6_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# define ADC1_TIMER_BASE STM32_TIM6_BASE
|
||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB1_TIM6_CLKIN
|
||||
# define ADC1_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC1_TIMER_RCC_EN RCC_APB1LENR_TIM6EN
|
||||
#elif defined(CONFIG_STM32H5_TIM8_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# define ADC1_TIMER_BASE STM32_TIM8_BASE
|
||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_CLKIN
|
||||
# define ADC1_TIMER_RCC_ENR STM32_RCC_APB2ENR
|
||||
# define ADC1_TIMER_RCC_EN RCC_APB2ENR_TIM8EN
|
||||
#elif defined(CONFIG_STM32H5_TIM15_ADC1)
|
||||
# define ADC1_HAVE_TIMER 1
|
||||
# define ADC1_TIMER_BASE STM32_TIM15_BASE
|
||||
# define ADC1_TIMER_PCLK_FREQUENCY STM32_APB2_TIM15_CLKIN
|
||||
# define ADC1_TIMER_RCC_ENR STM32_RCC_APB2ENR
|
||||
# define ADC1_TIMER_RCC_EN RCC_APB2ENR_TIM15EN
|
||||
#else
|
||||
# undef ADC1_HAVE_TIMER
|
||||
#endif
|
||||
|
||||
#ifdef ADC1_HAVE_TIMER
|
||||
# ifndef CONFIG_STM32H5_ADC1_SAMPLE_FREQUENCY
|
||||
# error "CONFIG_STM32H5_ADC1_SAMPLE_FREQUENCY not defined"
|
||||
# endif
|
||||
# ifndef CONFIG_STM32H5_ADC1_TIMTRIG
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG not defined"
|
||||
# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32H5_TIM1_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# define ADC2_TIMER_BASE STM32_TIM1_BASE
|
||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM1_CLKIN
|
||||
# define ADC2_TIMER_RCC_ENR STM32_RCC_APB2ENR
|
||||
# define ADC2_TIMER_RCC_EN RCC_APB2ENR_TIM1EN
|
||||
#elif defined(CONFIG_STM32H5_TIM2_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# define ADC2_TIMER_BASE STM32_TIM2_BASE
|
||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM2_CLKIN
|
||||
# define ADC2_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC2_TIMER_RCC_EN RCC_APB1LENR_TIM2EN
|
||||
#elif defined(CONFIG_STM32H5_TIM3_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# define ADC2_TIMER_BASE STM32_TIM3_BASE
|
||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM3_CLKIN
|
||||
# define ADC2_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC2_TIMER_RCC_EN RCC_APB1LENR_TIM3EN
|
||||
#elif defined(CONFIG_STM32H5_TIM4_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# define ADC2_TIMER_BASE STM32_TIM4_BASE
|
||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM4_CLKIN
|
||||
# define ADC2_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC2_TIMER_RCC_EN RCC_APB1LENR_TIM4EN
|
||||
#elif defined(CONFIG_STM32H5_TIM6_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# define ADC2_TIMER_BASE STM32_TIM6_BASE
|
||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB1_TIM6_CLKIN
|
||||
# define ADC2_TIMER_RCC_ENR STM32_RCC_APB1LENR
|
||||
# define ADC2_TIMER_RCC_EN RCC_APB1LENR_TIM6EN
|
||||
#elif defined(CONFIG_STM32H5_TIM8_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# define ADC2_TIMER_BASE STM32_TIM8_BASE
|
||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM8_CLKIN
|
||||
# define ADC2_TIMER_RCC_ENR STM32_RCC_APB2ENR
|
||||
# define ADC2_TIMER_RCC_EN RCC_APB2ENR_TIM8EN
|
||||
#elif defined(CONFIG_STM32H5_TIM15_ADC2)
|
||||
# define ADC2_HAVE_TIMER 1
|
||||
# define ADC2_TIMER_BASE STM32_TIM15_BASE
|
||||
# define ADC2_TIMER_PCLK_FREQUENCY STM32_APB2_TIM15_CLKIN
|
||||
# define ADC2_TIMER_RCC_ENR STM32_RCC_APB2ENR
|
||||
# define ADC2_TIMER_RCC_EN RCC_APB2ENR_TIM15EN
|
||||
#else
|
||||
# undef ADC2_HAVE_TIMER
|
||||
#endif
|
||||
|
||||
#ifdef ADC2_HAVE_TIMER
|
||||
# ifndef CONFIG_STM32H5_ADC2_SAMPLE_FREQUENCY
|
||||
# error "CONFIG_STM32H5_ADC2_SAMPLE_FREQUENCY not defined"
|
||||
# endif
|
||||
# ifndef CONFIG_STM32H5_ADC2_TIMTRIG
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG not defined"
|
||||
# warning "Values 0:CC1 1:CC2 2:CC3 3:CC4 4:TRGO"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(ADC1_HAVE_TIMER) || defined(ADC2_HAVE_TIMER)
|
||||
# define ADC_HAVE_TIMER 1
|
||||
#else
|
||||
# undef ADC_HAVE_TIMER
|
||||
#endif
|
||||
|
||||
/* Timer 1 */
|
||||
|
||||
#define ADC1_EXTSEL_T1CC1 ADC_CFGR_EXTSEL_T1CC1
|
||||
#define ADC1_EXTSEL_T1CC2 ADC_CFGR_EXTSEL_T1CC2
|
||||
#define ADC1_EXTSEL_T1CC3 ADC_CFGR_EXTSEL_T1CC3
|
||||
#define ADC1_EXTSEL_T1CC4 ADC_CFGR_EXTSEL_T1CC4
|
||||
#define ADC1_EXTSEL_T1TRGO ADC_CFGR_EXTSEL_T1TRGO
|
||||
#define ADC1_EXTSEL_T1TRGO2 ADC_CFGR_EXTSEL_T1TRGO2
|
||||
#define ADC2_EXTSEL_T1CC1 ADC_CFGR_EXTSEL_T1CC1
|
||||
#define ADC2_EXTSEL_T1CC2 ADC_CFGR_EXTSEL_T1CC2
|
||||
#define ADC2_EXTSEL_T1CC3 ADC_CFGR_EXTSEL_T1CC3
|
||||
#define ADC2_EXTSEL_T1CC4 ADC_CFGR_EXTSEL_T1CC4
|
||||
#define ADC2_EXTSEL_T1TRGO ADC_CFGR_EXTSEL_T1TRGO
|
||||
#define ADC2_EXTSEL_T1TRGO2 ADC_CFGR_EXTSEL_T1TRGO2
|
||||
|
||||
/* Timer 2 */
|
||||
|
||||
#define ADC1_EXTSEL_T2CC2 ADC_CFGR_EXTSEL_T2CC2
|
||||
#define ADC1_EXTSEL_T2TRGO ADC_CFGR_EXTSEL_T2TRGO
|
||||
#define ADC2_EXTSEL_T2CC2 ADC_CFGR_EXTSEL_T2CC2
|
||||
#define ADC2_EXTSEL_T2TRGO ADC_CFGR_EXTSEL_T2TRGO
|
||||
|
||||
/* Timer 3 */
|
||||
|
||||
#define ADC1_EXTSEL_T3CC4 ADC_CFGR_EXTSEL_T3CC4
|
||||
#define ADC1_EXTSEL_T3TRGO ADC_CFGR_EXTSEL_T3TRGO
|
||||
#define ADC2_EXTSEL_T3CC4 ADC_CFGR_EXTSEL_T3CC4
|
||||
#define ADC2_EXTSEL_T3TRGO ADC_CFGR_EXTSEL_T3TRGO
|
||||
|
||||
/* Timer 4 */
|
||||
|
||||
#define ADC1_EXTSEL_T4CC4 ADC_CFGR_EXTSEL_T4CC4
|
||||
#define ADC1_EXTSEL_T4TRGO ADC_CFGR_EXTSEL_T4TRGO
|
||||
#define ADC2_EXTSEL_T4CC4 ADC_CFGR_EXTSEL_T4CC4
|
||||
#define ADC2_EXTSEL_T4TRGO ADC_CFGR_EXTSEL_T4TRGO
|
||||
|
||||
/* Timer 6 */
|
||||
|
||||
#define ADC1_EXTSEL_T6TRGO ADC_CFGR_EXTSEL_T6TRGO
|
||||
#define ADC2_EXTSEL_T6TRGO ADC_CFGR_EXTSEL_T6TRGO
|
||||
|
||||
/* Timer 8 */
|
||||
|
||||
#define ADC1_EXTSEL_T8TRGO ADC_CFGR_EXTSEL_T8TRGO
|
||||
#define ADC1_EXTSEL_T8TRGO2 ADC_CFGR_EXTSEL_T8TRGO2
|
||||
#define ADC2_EXTSEL_T8TRGO ADC_CFGR_EXTSEL_T8TRGO
|
||||
#define ADC2_EXTSEL_T8TRGO2 ADC_CFGR_EXTSEL_T8TRGO2
|
||||
|
||||
/* Timer 15 */
|
||||
|
||||
#define ADC1_EXTSEL_T15TRGO ADC_CFGR_EXTSEL_T15TRGO
|
||||
#define ADC2_EXTSEL_T15TRGO ADC_CFGR_EXTSEL_T15TRGO
|
||||
|
||||
#if defined(CONFIG_STM32H5_TIM1_ADC1)
|
||||
# if CONFIG_STM32H5_ADC1_TIMTRIG == 0
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC1
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 1
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC2
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 2
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC3
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 3
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1CC4
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 4
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1TRGO
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 5
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T1TRGO2
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is out of range (TIM1)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM2_ADC1)
|
||||
# if CONFIG_STM32H5_ADC1_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM2)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 1
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T2CC2
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM2)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM2)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 4
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T2TRGO
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM2)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is out of range (TIM2)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM3_ADC1)
|
||||
# if CONFIG_STM32H5_ADC1_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM3)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM3)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM3)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 3
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T3CC4
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 4
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T3TRGO
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM3)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is out of range (TIM3)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM4_ADC1)
|
||||
# if CONFIG_STM32H5_ADC1_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM4)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM4)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM4)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 3
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T4CC4
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 4
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T4TRGO
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM4)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is out of range (TIM4)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM6_ADC1)
|
||||
# if CONFIG_STM32H5_ADC1_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 4
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T6TRGO
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM6)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is out of range (TIM6)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM8_ADC1)
|
||||
# if CONFIG_STM32H5_ADC1_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 4
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T8TRGO
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 5
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T8TRGO2
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is out of range (TIM8)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM15_ADC1)
|
||||
# if CONFIG_STM32H5_ADC1_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 4
|
||||
# define ADC1_EXTSEL_VALUE ADC1_EXTSEL_T15TRGO
|
||||
# elif CONFIG_STM32H5_ADC1_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is invalid (TIM15)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC1_TIMTRIG is out of range (TIM15)"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_STM32H5_TIM1_ADC2)
|
||||
# if CONFIG_STM32H5_ADC2_TIMTRIG == 0
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC1
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 1
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC2
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 2
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC3
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 3
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1CC4
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 4
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1TRGO
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 5
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T1TRGO2
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is out of range (TIM1)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM2_ADC2)
|
||||
# if CONFIG_STM32H5_ADC2_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM2)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 1
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T2CC2
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM2)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM2)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 4
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T2TRGO
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM2)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is out of range (TIM2)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM3_ADC2)
|
||||
# if CONFIG_STM32H5_ADC2_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM3)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM3)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM3)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 3
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T3CC4
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 4
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T3TRGO
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM3)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is out of range (TIM3)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM4_ADC2)
|
||||
# if CONFIG_STM32H5_ADC2_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM4)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM4)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM4)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 3
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T4CC4
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 4
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T4TRGO
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM4)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is out of range (TIM4)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM6_ADC2)
|
||||
# if CONFIG_STM32H5_ADC2_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM6)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 4
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T6TRGO
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM6)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is out of range (TIM6)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM8_ADC2)
|
||||
# if CONFIG_STM32H5_ADC2_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM8)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 4
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T8TRGO
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 5
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T8TRGO2
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is out of range (TIM8)"
|
||||
# endif
|
||||
#elif defined(CONFIG_STM32H5_TIM15_ADC2)
|
||||
# if CONFIG_STM32H5_ADC2_TIMTRIG == 0
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 1
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 2
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 3
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM15)"
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 4
|
||||
# define ADC2_EXTSEL_VALUE ADC2_EXTSEL_T15TRGO
|
||||
# elif CONFIG_STM32H5_ADC2_TIMTRIG == 5
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is invalid (TIM15)"
|
||||
# else
|
||||
# error "CONFIG_STM32H5_ADC2_TIMTRIG is out of range (TIM15)"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <errno.h>
|
||||
|
||||
#include <nuttx/irq.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#include <imx9_gpiobase.c>
|
||||
|
||||
|
@ -45,6 +46,10 @@
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Spinlock */
|
||||
|
||||
static spinlock_t g_gpio_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Name: imx9_gpio_dirout
|
||||
****************************************************************************/
|
||||
|
@ -174,7 +179,7 @@ int imx9_config_gpio(gpio_pinset_t pinset)
|
|||
|
||||
/* Configure the pin as an input initially to avoid any spurious outputs */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
|
||||
/* Configure based upon the pin mode */
|
||||
|
||||
|
@ -223,7 +228,7 @@ int imx9_config_gpio(gpio_pinset_t pinset)
|
|||
break;
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -243,9 +248,9 @@ void imx9_gpio_write(gpio_pinset_t pinset, bool value)
|
|||
|
||||
DEBUGASSERT((unsigned int)port < IMX9_GPIO_NPORTS);
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
imx9_gpio_setoutput(port, pin, value);
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -265,7 +270,7 @@ bool imx9_gpio_read(gpio_pinset_t pinset)
|
|||
|
||||
DEBUGASSERT((unsigned int)port < IMX9_GPIO_NPORTS);
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&g_gpio_lock);
|
||||
if ((pinset & (GPIO_OUTPUT)) == (GPIO_OUTPUT))
|
||||
{
|
||||
value = imx9_gpio_get_pinstatus(port, pin);
|
||||
|
@ -275,6 +280,6 @@ bool imx9_gpio_read(gpio_pinset_t pinset)
|
|||
value = imx9_gpio_getinput(port, pin);
|
||||
}
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&g_gpio_lock, flags);
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -2438,7 +2438,7 @@ int imx9_i2cbus_uninitialize(struct i2c_master_s *dev)
|
|||
|
||||
if (--priv->refs > 0)
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&priv->spinlock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -1798,8 +1798,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
|
|||
{
|
||||
struct imx9_lpspidev_s *priv = NULL;
|
||||
|
||||
irqstate_t flags = enter_critical_section();
|
||||
|
||||
#ifdef CONFIG_IMX9_LPSPI1
|
||||
if (bus == 1)
|
||||
{
|
||||
|
@ -2017,7 +2015,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
leave_critical_section(flags);
|
||||
spierr("ERROR: Unsupported SPI bus: %d\n", bus);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2061,7 +2058,6 @@ struct spi_dev_s *imx9_lpspibus_initialize(int bus)
|
|||
}
|
||||
#endif
|
||||
|
||||
leave_critical_section(flags);
|
||||
return (struct spi_dev_s *)priv;
|
||||
}
|
||||
|
||||
|
|
|
@ -2319,9 +2319,9 @@ static int imx9_epdisable(struct usbdev_ep_s *ep)
|
|||
|
||||
/* Cancel any ongoing activity */
|
||||
|
||||
spin_unlock_irqrestore(&privep->spinlock, flags);
|
||||
imx9_cancelrequests(privep, -ESHUTDOWN);
|
||||
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&privep->spinlock, flags);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
|
||||
|
@ -90,6 +91,7 @@ static uint32_t g_timer_active;
|
|||
|
||||
static irqstate_t g_tmr_sync_count;
|
||||
static irqstate_t g_tmr_flags;
|
||||
static spinlock_t g_tmr_lock = SP_UNLOCKED;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
|
@ -161,7 +163,7 @@ static inline void up_tmr_sync_up(void)
|
|||
{
|
||||
if (!g_tmr_sync_count)
|
||||
{
|
||||
g_tmr_flags = enter_critical_section();
|
||||
g_tmr_flags = spin_lock_irqsave(&g_tmr_lock);
|
||||
}
|
||||
|
||||
g_tmr_sync_count++;
|
||||
|
@ -171,7 +173,7 @@ static inline void up_tmr_sync_down(void)
|
|||
{
|
||||
if (g_tmr_sync_count == 1)
|
||||
{
|
||||
leave_critical_section(g_tmr_flags);
|
||||
spin_unlock_irqrestore(&g_tmr_lock, g_tmr_flags);
|
||||
}
|
||||
|
||||
if (g_tmr_sync_count > 0)
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/spinlock.h>
|
||||
#include <nuttx/vhost/vhost.h>
|
||||
#include <nuttx/wqueue.h>
|
||||
|
||||
|
@ -151,7 +152,7 @@ static int vhost_rng_probe(FAR struct vhost_device *hdev)
|
|||
|
||||
vqnames[0] = "virtio_rng";
|
||||
callback[0] = vhost_rng_handler;
|
||||
ret = vhost_create_virtqueues(hdev, 0, 1, vqnames, callback);
|
||||
ret = vhost_create_virtqueues(hdev, 0, 1, vqnames, callback, NULL);
|
||||
if (ret < 0)
|
||||
{
|
||||
vhosterr("virtio_device_create_virtqueue failed, ret=%d\n", ret);
|
||||
|
|
|
@ -83,8 +83,15 @@ static struct vhost_bus_s g_vhost_bus =
|
|||
|
||||
static bool vhost_status_driver_ok(FAR struct vhost_device *hdev)
|
||||
{
|
||||
uint8_t status = vhost_get_status(hdev);
|
||||
bool driver_ok = false;
|
||||
uint8_t status;
|
||||
int ret;
|
||||
|
||||
ret = vhost_get_status(hdev, &status);
|
||||
if (ret)
|
||||
{
|
||||
return driver_ok;
|
||||
}
|
||||
|
||||
/* Busy wait until the remote is ready */
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
# include <signal.h>
|
||||
#endif
|
||||
|
@ -40,6 +42,8 @@
|
|||
|
||||
#include <arch/arch.h>
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -241,6 +245,9 @@
|
|||
(CONFIG_ARCH_PGPOOL_VBASE + CONFIG_ARCH_PGPOOL_SIZE)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/****************************************************************************
|
||||
* Public Type Definitions
|
||||
****************************************************************************/
|
||||
|
@ -251,8 +258,6 @@ struct tcb_s; /* Forward reference to TCB */
|
|||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
struct addrenv_s
|
||||
{
|
||||
struct arch_addrenv_s addrenv; /* The address environment page directory */
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef ALIGN_UP
|
||||
# define ALIGN_UP(x,a) (((x) + ((a) - 1)) & ~((a) - 1))
|
||||
# define ALIGN_UP(x,a) ((((x) + (a) - 1) / (a)) * (a))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_UP_MASK
|
||||
|
@ -56,7 +56,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef ALIGN_DOWN
|
||||
# define ALIGN_DOWN(x,a) ((x) & (~((a) - 1)))
|
||||
# define ALIGN_DOWN(x,a) (((x) / (a)) * (a))
|
||||
#endif
|
||||
|
||||
#ifndef ALIGN_DOWN_MASK
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <nuttx/net/net.h>
|
||||
#include <nuttx/mm/map.h>
|
||||
#include <nuttx/tls.h>
|
||||
#include <nuttx/spinlock_type.h>
|
||||
|
||||
#include <arch/arch.h>
|
||||
|
||||
|
@ -737,6 +738,10 @@ struct tcb_s
|
|||
size_t level_deepest;
|
||||
size_t level;
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||
spinlock_t mutex_lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* struct task_tcb_s ********************************************************/
|
||||
|
|
|
@ -106,14 +106,6 @@ void sched_note_spinlock_unlock(FAR volatile spinlock_t *spinlock);
|
|||
* Public Data Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Used for access control */
|
||||
|
||||
extern volatile spinlock_t g_irq_spin;
|
||||
|
||||
/* Handles nested calls to spin_lock_irqsave and spin_unlock_irqrestore */
|
||||
|
||||
extern volatile uint8_t g_irq_spin_count[CONFIG_SMP_NCPUS];
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_testset
|
||||
*
|
||||
|
@ -448,26 +440,12 @@ static inline_function void spin_unlock(FAR volatile spinlock_t *lock)
|
|||
static inline_function
|
||||
irqstate_t spin_lock_irqsave_wo_note(FAR volatile spinlock_t *lock)
|
||||
{
|
||||
irqstate_t ret;
|
||||
ret = up_irq_save();
|
||||
irqstate_t flags;
|
||||
flags = up_irq_save();
|
||||
|
||||
if (NULL == lock)
|
||||
{
|
||||
int me = this_cpu();
|
||||
if (0 == g_irq_spin_count[me])
|
||||
{
|
||||
spin_lock_wo_note(&g_irq_spin);
|
||||
}
|
||||
spin_lock_wo_note(lock);
|
||||
|
||||
g_irq_spin_count[me]++;
|
||||
DEBUGASSERT(0 != g_irq_spin_count[me]);
|
||||
}
|
||||
else
|
||||
{
|
||||
spin_lock_wo_note(lock);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return flags;
|
||||
}
|
||||
#else
|
||||
# define spin_lock_irqsave_wo_note(l) ((void)(l), up_irq_save())
|
||||
|
@ -478,14 +456,7 @@ irqstate_t spin_lock_irqsave_wo_note(FAR volatile spinlock_t *lock)
|
|||
*
|
||||
* Description:
|
||||
* If SMP is enabled:
|
||||
* If the argument lock is not specified (i.e. NULL),
|
||||
* disable local interrupts and take the global spinlock (g_irq_spin)
|
||||
* if the call counter (g_irq_spin_count[cpu]) equals to 0. Then the
|
||||
* counter on the CPU is incremented to allow nested calls and return
|
||||
* the interrupt state.
|
||||
*
|
||||
* If the argument lock is specified,
|
||||
* disable local interrupts and take the lock spinlock and return
|
||||
* Disable local interrupts and take the lock spinlock and return
|
||||
* the interrupt state.
|
||||
*
|
||||
* NOTE: This API is very simple to protect data (e.g. H/W register
|
||||
|
@ -496,9 +467,7 @@ irqstate_t spin_lock_irqsave_wo_note(FAR volatile spinlock_t *lock)
|
|||
* This function is equivalent to up_irq_save().
|
||||
*
|
||||
* Input Parameters:
|
||||
* lock - Caller specific spinlock. If specified NULL, g_irq_spin is used
|
||||
* and can be nested. Otherwise, nested call for the same lock
|
||||
* would cause a deadlock
|
||||
* lock - Caller specific spinlock. not NULL.
|
||||
*
|
||||
* Returned Value:
|
||||
* An opaque, architecture-specific value that represents the state of
|
||||
|
@ -618,21 +587,7 @@ static inline_function
|
|||
void spin_unlock_irqrestore_wo_note(FAR volatile spinlock_t *lock,
|
||||
irqstate_t flags)
|
||||
{
|
||||
if (NULL == lock)
|
||||
{
|
||||
int me = this_cpu();
|
||||
DEBUGASSERT(0 < g_irq_spin_count[me]);
|
||||
g_irq_spin_count[me]--;
|
||||
|
||||
if (0 == g_irq_spin_count[me])
|
||||
{
|
||||
spin_unlock_wo_note(&g_irq_spin);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spin_unlock_wo_note(lock);
|
||||
}
|
||||
spin_unlock_wo_note(lock);
|
||||
|
||||
up_irq_restore(flags);
|
||||
}
|
||||
|
@ -645,21 +600,14 @@ void spin_unlock_irqrestore_wo_note(FAR volatile spinlock_t *lock,
|
|||
*
|
||||
* Description:
|
||||
* If SMP is enabled:
|
||||
* If the argument lock is not specified (i.e. NULL),
|
||||
* decrement the call counter (g_irq_spin_count[cpu]) and if it
|
||||
* decrements to zero then release the spinlock (g_irq_spin) and
|
||||
* restore the interrupt state as it was prior to the previous call to
|
||||
* spin_lock_irqsave(NULL).
|
||||
*
|
||||
* If the argument lock is specified, release the lock and
|
||||
* restore the interrupt state as it was prior to the previous call to
|
||||
* spin_lock_irqsave(lock).
|
||||
* Release the lock and restore the interrupt state as it was prior
|
||||
* to the previous call to spin_lock_irqsave(lock).
|
||||
*
|
||||
* If SMP is not enabled:
|
||||
* This function is equivalent to up_irq_restore().
|
||||
*
|
||||
* Input Parameters:
|
||||
* lock - Caller specific spinlock. If specified NULL, g_irq_spin is used.
|
||||
* lock - Caller specific spinlock. not NULL
|
||||
*
|
||||
* flags - The architecture-specific value that represents the state of
|
||||
* the interrupts prior to the call to spin_lock_irqsave(lock);
|
||||
|
|
1
libs/libc/.gitignore
vendored
1
libs/libc/.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
/exec_symtab.c
|
||||
/modlib_symtab.c
|
||||
modlib/gnu-elf.ld
|
||||
|
|
|
@ -183,6 +183,10 @@ context:: bin kbin
|
|||
ifeq ($(CONFIG_LIBC_ZONEINFO_ROMFS),y)
|
||||
$(Q) $(MAKE) -C zoneinfo context BIN=$(BIN)
|
||||
endif
|
||||
ifeq ($(CONFIG_LIBC_MODLIB),y)
|
||||
$(Q) $(MAKE) -C modlib context
|
||||
endif
|
||||
|
||||
|
||||
# Dependencies
|
||||
|
||||
|
@ -210,6 +214,7 @@ depend:: .depend
|
|||
|
||||
clean::
|
||||
$(Q) $(MAKE) -C zoneinfo clean BIN=$(BIN)
|
||||
$(Q) $(MAKE) -C modlib clean
|
||||
$(call DELFILE, $(BIN))
|
||||
$(call DELFILE, $(KBIN))
|
||||
$(call CLEAN)
|
||||
|
@ -218,6 +223,7 @@ clean::
|
|||
|
||||
distclean:: clean
|
||||
$(Q) $(MAKE) -C zoneinfo distclean BIN=$(BIN)
|
||||
$(Q) $(MAKE) -C modlib distclean
|
||||
$(call DELFILE, exec_symtab.c)
|
||||
$(call DELFILE, .depend)
|
||||
$(call DELDIR, bin)
|
||||
|
|
40
libs/libc/modlib/Makefile
Normal file
40
libs/libc/modlib/Makefile
Normal file
|
@ -0,0 +1,40 @@
|
|||
############################################################################
|
||||
# libs/libc/modlib/Makefile
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership. The
|
||||
# ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance with the
|
||||
# License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
include $(TOPDIR)/Make.defs
|
||||
|
||||
# Generate gnu-elf.ld from gnu-elf.ld.in
|
||||
|
||||
gnu-elf.ld: gnu-elf.ld.in
|
||||
$(call PREPROCESS, $<, $@)
|
||||
|
||||
# Create initial context
|
||||
|
||||
context: gnu-elf.ld
|
||||
|
||||
.PHONY: context clean distclean
|
||||
|
||||
clean:
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
||||
$(call DELFILE, gnu-elf.ld)
|
|
@ -1,5 +1,5 @@
|
|||
/****************************************************************************
|
||||
* libs/libc/modlib/gnu-elf.ld
|
||||
* libs/libc/modlib/gnu-elf.ld.in
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
|
@ -18,9 +18,23 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#if defined(CONFIG_BUILD_KERNEL) && defined(CONFIG_BINFMT_ELF_EXECUTABLE)
|
||||
# define __ASSEMBLY__
|
||||
# include <nuttx/addrenv.h>
|
||||
|
||||
# define TEXT CONFIG_ARCH_TEXT_VBASE
|
||||
# define DATA CONFIG_ARCH_DATA_VBASE + ARCH_DATA_RESERVE_SIZE
|
||||
#else
|
||||
# define TEXT 0x0
|
||||
# define DATA
|
||||
#endif
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text 0x00000000 :
|
||||
.text TEXT :
|
||||
{
|
||||
_stext = . ;
|
||||
*(.text)
|
||||
|
@ -58,7 +72,7 @@ SECTIONS
|
|||
_erodata = . ;
|
||||
}
|
||||
|
||||
.data :
|
||||
.data DATA :
|
||||
{
|
||||
_sdata = . ;
|
||||
*(.data)
|
|
@ -397,16 +397,17 @@ retry:
|
|||
|
||||
pool->nalloc++;
|
||||
spin_unlock_irqrestore(&pool->lock, flags);
|
||||
blk = kasan_unpoison(blk, pool->blocksize);
|
||||
#ifdef CONFIG_MM_FILL_ALLOCATIONS
|
||||
memset(blk, MM_ALLOC_MAGIC, pool->blocksize);
|
||||
#endif
|
||||
|
||||
#if CONFIG_MM_BACKTRACE >= 0
|
||||
mempool_add_backtrace(pool, (FAR struct mempool_backtrace_s *)
|
||||
((FAR char *)blk + pool->blocksize));
|
||||
#endif
|
||||
|
||||
blk = kasan_unpoison(blk, pool->blocksize);
|
||||
#ifdef CONFIG_MM_FILL_ALLOCATIONS
|
||||
memset(blk, MM_ALLOC_MAGIC, pool->blocksize);
|
||||
#endif
|
||||
|
||||
return blk;
|
||||
}
|
||||
|
||||
|
|
|
@ -282,6 +282,8 @@ typedef CODE void (*mm_node_handler_t)(FAR struct mm_allocnode_s *node,
|
|||
|
||||
int mm_lock(FAR struct mm_heap_s *heap);
|
||||
void mm_unlock(FAR struct mm_heap_s *heap);
|
||||
irqstate_t mm_lock_irq(FAR struct mm_heap_s *heap);
|
||||
void mm_unlock_irq(FAR struct mm_heap_s *heap, irqstate_t state);
|
||||
|
||||
/* Functions contained in mm_shrinkchunk.c **********************************/
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||
|
||||
/* Delay the deallocation until a more appropriate time. */
|
||||
|
||||
flags = up_irq_save();
|
||||
flags = mm_lock_irq(heap);
|
||||
|
||||
# ifdef CONFIG_DEBUG_ASSERTIONS
|
||||
FAR struct mm_freenode_s *node;
|
||||
|
@ -65,7 +65,7 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||
heap->mm_delaycount[this_cpu()]++;
|
||||
#endif
|
||||
|
||||
up_irq_restore(flags);
|
||||
mm_unlock_irq(heap, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -117,3 +117,31 @@ void mm_unlock(FAR struct mm_heap_s *heap)
|
|||
|
||||
DEBUGVERIFY(nxmutex_unlock(&heap->mm_lock));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_lock_irq
|
||||
*
|
||||
* Description:
|
||||
* Locking by pausing interruption
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
irqstate_t mm_lock_irq(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
UNUSED(heap);
|
||||
return up_irq_save();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_unlock_irq
|
||||
*
|
||||
* Description:
|
||||
* Release the lock by resuming the interrupt
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void mm_unlock_irq(FAR struct mm_heap_s *heap, irqstate_t state)
|
||||
{
|
||||
UNUSED(heap);
|
||||
up_irq_restore(state);
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool force)
|
|||
|
||||
/* Move the delay list to local */
|
||||
|
||||
flags = up_irq_save();
|
||||
flags = mm_lock_irq(heap);
|
||||
|
||||
tmp = heap->mm_delaylist[this_cpu()];
|
||||
|
||||
|
@ -74,7 +74,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool force)
|
|||
(!force &&
|
||||
heap->mm_delaycount[this_cpu()] < CONFIG_MM_FREE_DELAYCOUNT_MAX))
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
mm_unlock_irq(heap, flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool force)
|
|||
|
||||
heap->mm_delaylist[this_cpu()] = NULL;
|
||||
|
||||
up_irq_restore(flags);
|
||||
mm_unlock_irq(heap, flags);
|
||||
|
||||
/* Test if the delayed is empty */
|
||||
|
||||
|
|
|
@ -181,6 +181,34 @@ static void mm_delayfree(struct mm_heap_s *heap, void *mem, bool delay);
|
|||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_lock_irq
|
||||
*
|
||||
* Description:
|
||||
* Locking by pausing interruption
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static irqstate_t mm_lock_irq(FAR struct mm_heap_s *heap)
|
||||
{
|
||||
UNUSED(heap);
|
||||
return up_irq_save();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mm_unlock_irq
|
||||
*
|
||||
* Description:
|
||||
* Release the lock by resuming the interrupt
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void mm_unlock_irq(FAR struct mm_heap_s *heap, irqstate_t state)
|
||||
{
|
||||
UNUSED(heap);
|
||||
up_irq_restore(state);
|
||||
}
|
||||
|
||||
static void memdump_allocnode(FAR void *ptr, size_t size)
|
||||
{
|
||||
#if CONFIG_MM_BACKTRACE < 0
|
||||
|
@ -301,7 +329,7 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||
|
||||
/* Delay the deallocation until a more appropriate time. */
|
||||
|
||||
flags = up_irq_save();
|
||||
flags = mm_lock_irq(heap);
|
||||
|
||||
tmp->flink = heap->mm_delaylist[this_cpu()];
|
||||
heap->mm_delaylist[this_cpu()] = tmp;
|
||||
|
@ -310,7 +338,7 @@ static void add_delaylist(FAR struct mm_heap_s *heap, FAR void *mem)
|
|||
heap->mm_delaycount[this_cpu()]++;
|
||||
#endif
|
||||
|
||||
up_irq_restore(flags);
|
||||
mm_unlock_irq(heap, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -327,7 +355,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool force)
|
|||
|
||||
/* Move the delay list to local */
|
||||
|
||||
flags = up_irq_save();
|
||||
flags = mm_lock_irq(heap);
|
||||
|
||||
tmp = heap->mm_delaylist[this_cpu()];
|
||||
|
||||
|
@ -336,7 +364,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool force)
|
|||
(!force &&
|
||||
heap->mm_delaycount[this_cpu()] < CONFIG_MM_FREE_DELAYCOUNT_MAX))
|
||||
{
|
||||
up_irq_restore(flags);
|
||||
mm_unlock_irq(heap, flags);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -345,7 +373,7 @@ static bool free_delaylist(FAR struct mm_heap_s *heap, bool force)
|
|||
|
||||
heap->mm_delaylist[this_cpu()] = NULL;
|
||||
|
||||
up_irq_restore(flags);
|
||||
mm_unlock_irq(heap, flags);
|
||||
|
||||
/* Test if the delayed is empty */
|
||||
|
||||
|
|
|
@ -469,6 +469,10 @@ static void idle_group_initialize(void)
|
|||
|
||||
nxtask_joininit(tcb);
|
||||
|
||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||
spin_lock_init(&tcb->mutex_lock);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Create a stack for all CPU IDLE threads (except CPU0 which already
|
||||
* has a stack).
|
||||
|
|
|
@ -39,14 +39,6 @@
|
|||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Used for access control */
|
||||
|
||||
volatile spinlock_t g_irq_spin = SP_UNLOCKED;
|
||||
|
||||
/* Handles nested calls to spin_lock_irqsave and spin_unlock_irqrestore */
|
||||
|
||||
volatile uint8_t g_irq_spin_count[CONFIG_SMP_NCPUS];
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
|
|
@ -46,8 +46,7 @@ if(NOT CONFIG_DISABLE_PTHREAD)
|
|||
pthread_setschedprio.c)
|
||||
|
||||
if(NOT CONFIG_PTHREAD_MUTEX_UNSAFE)
|
||||
list(APPEND SRCS pthread_mutex.c pthread_mutexconsistent.c
|
||||
pthread_mutexinconsistent.c)
|
||||
list(APPEND SRCS pthread_mutex.c pthread_mutexconsistent.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SMP)
|
||||
|
|
|
@ -32,7 +32,7 @@ CSRCS += pthread_completejoin.c pthread_findjoininfo.c
|
|||
CSRCS += pthread_release.c pthread_setschedprio.c
|
||||
|
||||
ifneq ($(CONFIG_PTHREAD_MUTEX_UNSAFE),y)
|
||||
CSRCS += pthread_mutex.c pthread_mutexconsistent.c pthread_mutexinconsistent.c
|
||||
CSRCS += pthread_mutex.c pthread_mutexconsistent.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
|
|
|
@ -222,6 +222,10 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
|
|||
|
||||
nxtask_joininit(&ptcb->cmn);
|
||||
|
||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||
spin_lock_init(&ptcb->cmn.mutex_lock);
|
||||
#endif
|
||||
|
||||
/* Bind the parent's group to the new TCB (we have not yet joined the
|
||||
* group).
|
||||
*/
|
||||
|
|
|
@ -65,10 +65,10 @@ static void pthread_mutex_add(FAR struct pthread_mutex_s *mutex)
|
|||
|
||||
/* Add the mutex to the list of mutexes held by this pthread */
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&rtcb->mutex_lock);
|
||||
mutex->flink = rtcb->mhead;
|
||||
rtcb->mhead = mutex;
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&rtcb->mutex_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -92,7 +92,7 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex)
|
|||
FAR struct pthread_mutex_s *prev;
|
||||
irqstate_t flags;
|
||||
|
||||
flags = enter_critical_section();
|
||||
flags = spin_lock_irqsave(&rtcb->mutex_lock);
|
||||
|
||||
/* Remove the mutex from the list of mutexes held by this task */
|
||||
|
||||
|
@ -118,7 +118,7 @@ static void pthread_mutex_remove(FAR struct pthread_mutex_s *mutex)
|
|||
}
|
||||
|
||||
mutex->flink = NULL;
|
||||
leave_critical_section(flags);
|
||||
spin_unlock_irqrestore(&rtcb->mutex_lock, flags);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -346,3 +346,49 @@ int pthread_mutex_restorelock(FAR struct pthread_mutex_s *mutex,
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pthread_mutex_inconsistent
|
||||
*
|
||||
* Description:
|
||||
* This function is called when a pthread is terminated via either
|
||||
* pthread_exit() or pthread_cancel(). It will check for any mutexes
|
||||
* held by exitting thread. It will mark them as inconsistent and
|
||||
* then wake up the highest priority waiter for the mutex. That
|
||||
* instance of pthread_mutex_lock() will then return EOWNERDEAD.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb -- a reference to the TCB of the exitting pthread.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void pthread_mutex_inconsistent(FAR struct tcb_s *tcb)
|
||||
{
|
||||
FAR struct pthread_mutex_s *mutex;
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(tcb != NULL);
|
||||
|
||||
flags = spin_lock_irqsave(&tcb->mutex_lock);
|
||||
|
||||
/* Remove and process each mutex held by this task */
|
||||
|
||||
while (tcb->mhead != NULL)
|
||||
{
|
||||
/* Remove the mutex from the TCB list */
|
||||
|
||||
mutex = tcb->mhead;
|
||||
tcb->mhead = mutex->flink;
|
||||
mutex->flink = NULL;
|
||||
|
||||
/* Mark the mutex as INCONSISTENT and wake up any waiting thread */
|
||||
|
||||
mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT;
|
||||
mutex_unlock(&mutex->mutex);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&tcb->mutex_lock, flags);
|
||||
}
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/****************************************************************************
|
||||
* sched/pthread/pthread_mutexinconsistent.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <nuttx/sched.h>
|
||||
#include <nuttx/semaphore.h>
|
||||
|
||||
#include "pthread/pthread.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: pthread_mutex_inconsistent
|
||||
*
|
||||
* Description:
|
||||
* This function is called when a pthread is terminated via either
|
||||
* pthread_exit() or pthread_cancel(). It will check for any mutexes
|
||||
* held by exitting thread. It will mark them as inconsistent and
|
||||
* then wake up the highest priority waiter for the mutex. That
|
||||
* instance of pthread_mutex_lock() will then return EOWNERDEAD.
|
||||
*
|
||||
* Input Parameters:
|
||||
* tcb -- a reference to the TCB of the exitting pthread.
|
||||
*
|
||||
* Returned Value:
|
||||
* None.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void pthread_mutex_inconsistent(FAR struct tcb_s *tcb)
|
||||
{
|
||||
FAR struct pthread_mutex_s *mutex;
|
||||
irqstate_t flags;
|
||||
|
||||
DEBUGASSERT(tcb != NULL);
|
||||
|
||||
sched_lock();
|
||||
|
||||
/* Remove and process each mutex held by this task */
|
||||
|
||||
while (tcb->mhead != NULL)
|
||||
{
|
||||
/* Remove the mutex from the TCB list */
|
||||
|
||||
flags = enter_critical_section();
|
||||
mutex = tcb->mhead;
|
||||
tcb->mhead = mutex->flink;
|
||||
mutex->flink = NULL;
|
||||
leave_critical_section(flags);
|
||||
|
||||
/* Mark the mutex as INCONSISTENT and wake up any waiting thread */
|
||||
|
||||
mutex->flags |= _PTHREAD_MFLAGS_INCONSISTENT;
|
||||
mutex_unlock(&mutex->mutex);
|
||||
}
|
||||
|
||||
sched_unlock();
|
||||
}
|
|
@ -164,6 +164,10 @@ FAR struct task_tcb_s *nxtask_setup_fork(start_t retaddr)
|
|||
|
||||
nxtask_joininit(&child->cmn);
|
||||
|
||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||
spin_lock_init(&child->cmn.mutex_lock);
|
||||
#endif
|
||||
|
||||
/* Allocate a new task group with the same privileges as the parent */
|
||||
|
||||
ret = group_initialize(child, ttype);
|
||||
|
|
|
@ -126,6 +126,10 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
|
|||
nxtask_joininit(&tcb->cmn);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||
spin_lock_init(&tcb->cmn.mutex_lock);
|
||||
#endif
|
||||
|
||||
/* Duplicate the parent tasks environment */
|
||||
|
||||
ret = env_dup(tcb->cmn.group, envp);
|
||||
|
|
|
@ -617,6 +617,17 @@ static const char *g_white_content_list[] =
|
|||
"unzGetCurrentFileInfo64",
|
||||
"unzGoToNextFile",
|
||||
"unzGoToFirstFile",
|
||||
|
||||
/* Ref:
|
||||
* apps/netutils/telnetc/telnetc.c
|
||||
*/
|
||||
|
||||
"deflateInit",
|
||||
"deflateEnd",
|
||||
"inflateInit",
|
||||
"inflateEnd",
|
||||
"zError",
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue