arch/stm32h7: add HSEM support
This commit is contained in:
parent
a967da5270
commit
4c9d405a97
@ -31,13 +31,16 @@ list(
|
||||
stm32_rcc.c
|
||||
stm32_lowputc.c
|
||||
stm32_serial.c
|
||||
stm32_uid.c
|
||||
)
|
||||
stm32_uid.c)
|
||||
|
||||
if(CONFIG_STM32H7_PROGMEM)
|
||||
list(APPEND SRCS stm32_flash.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_STM32H7_HSEM)
|
||||
list(APPEND SRCS stm32_hsem.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SCHED_TICKLESS)
|
||||
list(APPEND SRCS stm32_tickless.c)
|
||||
else()
|
||||
|
@ -633,6 +633,10 @@ config STM32H7_LPTIM
|
||||
bool
|
||||
default n
|
||||
|
||||
config STM32H7_HSEM
|
||||
bool "Hardware semaphore"
|
||||
default n
|
||||
|
||||
config STM32H7_RTC
|
||||
bool "RTC"
|
||||
default n
|
||||
|
@ -29,6 +29,10 @@ ifeq ($(CONFIG_STM32H7_PROGMEM),y)
|
||||
CHIP_CSRCS += stm32_flash.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_STM32H7_HSEM),y)
|
||||
CHIP_CSRCS += stm32_hsem.c
|
||||
endif
|
||||
|
||||
# Required STM32H7 files
|
||||
|
||||
CHIP_CSRCS += stm32_allocateheap.c stm32_exti_gpio.c stm32_gpio.c stm32_irq.c
|
||||
|
83
arch/arm/src/stm32h7/hardware/stm32_hsem.h
Normal file
83
arch/arm/src/stm32h7/hardware/stm32_hsem.h
Normal file
@ -0,0 +1,83 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/hardware/stm32_hsem.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32_HSEM_H
|
||||
#define __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32_HSEM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include "chip.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define STM32_HSEM_CHANS (32)
|
||||
#define HSEM_COREID_CPU1 (3)
|
||||
#define HSEM_COREID_CPU2 (1)
|
||||
|
||||
/* Register Offsets *********************************************************/
|
||||
|
||||
#define STM32_HSEM_RX_OFFSET(n) (0x0000 + (0x4 * n)) /* HSEM register semaphore x */
|
||||
#define STM32_HSEM_RLRX_OFFSET(n) (0x0080 + (0x4 * n)) /* HSEM read lock register semaphore x */
|
||||
#define STM32_HSEM_CXIER_OFFSET(n) (0x0100 + (0x10 * n)) /* HSEM interrupt enable register */
|
||||
#define STM32_HSEM_CXICR_OFFSET(n) (0x0104 + (0x10 * n)) /* HSEM interrupt clear register */
|
||||
#define STM32_HSEM_CXISR_OFFSET(n) (0x0108 + (0x10 * n)) /* HSEM interrupt status register */
|
||||
#define STM32_HSEM_CXMISR_OFFSET(n) (0x010c + (0x10 * n)) /* HSEM interrupt status register */
|
||||
#define STM32_HSEM_CR_OFFSET (0x0140) /* HSEM clear register */
|
||||
#define STM32_HSEM_KEYR_OFFSET (0x0144) /* HSEM semaphore clear key */
|
||||
|
||||
/* Register Addresses *******************************************************/
|
||||
|
||||
#define STM32_HSEM_RX(x) (STM32_HSEM_BASE+STM32_HSEM_RX_OFFSET(x))
|
||||
#define STM32_HSEM_RLRX(x) (STM32_HSEM_BASE+STM32_HSEM_RLRX_OFFSET(x))
|
||||
#define STM32_HSEM_CXIER(x) (STM32_HSEM_BASE+STM32_HSEM_CXIER_OFFSET(x))
|
||||
#define STM32_HSEM_CXICR(x) (STM32_HSEM_BASE+STM32_HSEM_CXICR_OFFSET(x))
|
||||
#define STM32_HSEM_CXISR(x) (STM32_HSEM_BASE+STM32_HSEM_CXISR_OFFSET(x))
|
||||
#define STM32_HSEM_CXMISR(x) (STM32_HSEM_BASE+STM32_HSEM_CXMISR_OFFSET(x))
|
||||
#define STM32_HSEM_CXMISRCR (STM32_HSEM_BASE+STM32_HSEM_CR_OFFSET)
|
||||
#define STM32_HSEM_KEYR (STM32_HSEM_BASE+STM32_HSEM_KEYR_OFFSET)
|
||||
|
||||
/* Register Bitfield Definitions ********************************************/
|
||||
|
||||
/* Semaphore x registers */
|
||||
|
||||
#define HSEM_SEMX_PROCID_SHIFT (0) /* Bits 0-8: Semaphore PROCID */
|
||||
#define HSEM_SEMX_PROCID_MASK (0xff << HSEM_SEMX_PROCID_SHIFT)
|
||||
#define HSEM_SEMX_COREID_SHIFT (8) /* Bits 8-11: Semaphore COREID */
|
||||
#define HSEM_SEMX_COREID_MASK (0xf << HSEM_SEMX_COREID_SHIFT)
|
||||
/* Bits 12-30: reserved */
|
||||
#define HSEM_SEMX_LOCK (1 << 31) /* Bit 31: Lock indication */
|
||||
|
||||
/* Clear register */
|
||||
|
||||
#define HSEM_CR_COREID_SHIFT (8) /* Bits 8-11: COREID of semaphores to be cleared */
|
||||
#define HSEM_CR_COREID_MASK (0xf << HSEM_CR_COREID_SHIFT)
|
||||
#define HSEM_CR_KEY_SHIFT (16) /* Bits 16-31: Semaphore clear Key */
|
||||
#define HSEM_CR_KEY_MASK (0xffff << HSEM_CR_KEY_SHIFT)
|
||||
|
||||
/* Interrupts */
|
||||
|
||||
#define HSEM_CHAN_ID(n) (1 << n)
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_STM32H7_HARDWARE_STM32_HSEM_H */
|
291
arch/arm/src/stm32h7/stm32_hsem.c
Normal file
291
arch/arm/src/stm32h7/stm32_hsem.c
Normal file
@ -0,0 +1,291 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/stm32_hsem.c
|
||||
*
|
||||
* 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 <debug.h>
|
||||
|
||||
#include "nvic.h"
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "stm32_hsem.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* HSEM receive channel configuration */
|
||||
|
||||
struct stm32_hsem_recv_s
|
||||
{
|
||||
hsem_callback_t callback;
|
||||
void *args;
|
||||
};
|
||||
|
||||
/* HSEM device */
|
||||
|
||||
struct stm32_hsem_s
|
||||
{
|
||||
struct stm32_hsem_recv_s recv[STM32_HSEM_CHANS];
|
||||
uint32_t irq;
|
||||
uint8_t block;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
struct stm32_hsem_s g_stm32_hsem;
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_interrupt
|
||||
****************************************************************************/
|
||||
|
||||
static int stm32_hsem_interrupt(int irq, void *context, void *args)
|
||||
{
|
||||
struct stm32_hsem_s *dev = args;
|
||||
uint32_t regval = 0;
|
||||
int i = 0;
|
||||
|
||||
regval = getreg32(STM32_HSEM_CXMISR(dev->block));
|
||||
|
||||
_info("HSEM interrupt 0x%" PRIx32 "\n", regval);
|
||||
|
||||
for (i = 0; i < STM32_HSEM_CHANS; i++)
|
||||
{
|
||||
if (regval & HSEM_CHAN_ID(i))
|
||||
{
|
||||
if (dev->recv[i].callback)
|
||||
{
|
||||
dev->recv[i].callback(i, dev->recv[i].args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear events */
|
||||
|
||||
putreg32(regval, STM32_HSEM_CXICR(dev->block));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_subscribe
|
||||
*
|
||||
* Description:
|
||||
* Subscribe to event on a given semaphore
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_hsem_subscribe(uint8_t id, hsem_callback_t callback, void *args)
|
||||
{
|
||||
struct stm32_hsem_s *dev = &g_stm32_hsem;
|
||||
|
||||
DEBUGASSERT(id < STM32_HSEM_CHANS);
|
||||
|
||||
_info("HSEM subscribe %d\n", id);
|
||||
|
||||
/* Register callaback */
|
||||
|
||||
dev->recv[id].callback = callback;
|
||||
dev->recv[id].args = args;
|
||||
|
||||
if (callback)
|
||||
{
|
||||
/* Clear pending */
|
||||
|
||||
putreg32(HSEM_CHAN_ID(id), STM32_HSEM_CXICR(dev->block));
|
||||
|
||||
/* Enable interrupt */
|
||||
|
||||
modifyreg32(STM32_HSEM_CXIER(dev->block), 0, HSEM_CHAN_ID(id));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable interrupts */
|
||||
|
||||
modifyreg32(STM32_HSEM_CXIER(dev->block), HSEM_CHAN_ID(id), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_signal
|
||||
*
|
||||
* Description:
|
||||
* Signal on a semaphore (free and lock again)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_hsem_signal(uint8_t id)
|
||||
{
|
||||
DEBUGASSERT(id < STM32_HSEM_CHANS);
|
||||
|
||||
_info("HSEM signal %d\n", id);
|
||||
|
||||
/* Lock semaphore */
|
||||
|
||||
while (stm32_hsem_take(id) == 0);
|
||||
|
||||
/* Free semaphore to signal event */
|
||||
|
||||
stm32_hsem_free(id);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_busywait_lock
|
||||
*
|
||||
* Description:
|
||||
* Busy wait for a semaphore to be locked
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_hsem_busywait_lock(uint8_t id)
|
||||
{
|
||||
DEBUGASSERT(id < STM32_HSEM_CHANS);
|
||||
|
||||
_info("HSEM busywait lock %d\n", id);
|
||||
|
||||
/* Wait for semaphore lock */
|
||||
|
||||
while ((getreg32(STM32_HSEM_RX(id)) & HSEM_SEMX_LOCK) == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_busywait_free
|
||||
*
|
||||
* Description:
|
||||
* Busy wait for a semaphore to be free
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_hsem_busywait_free(uint8_t id)
|
||||
{
|
||||
DEBUGASSERT(id < STM32_HSEM_CHANS);
|
||||
|
||||
_info("HSEM busywait free %d\n", id);
|
||||
|
||||
/* Wait for semaphore free */
|
||||
|
||||
while ((getreg32(STM32_HSEM_RX(id)) & HSEM_SEMX_LOCK) != 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_wait_take
|
||||
*
|
||||
* Description:
|
||||
* Take a semaphore (1-step lock)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_hsem_wait_take(uint8_t id)
|
||||
{
|
||||
DEBUGASSERT(id < STM32_HSEM_CHANS);
|
||||
|
||||
_info("HSEM wait take %d\n", id);
|
||||
|
||||
stm32_hsem_busywait_free(id);
|
||||
while (stm32_hsem_take(id) == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_take
|
||||
*
|
||||
* Description:
|
||||
* Take a semaphore (1-step lock)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
bool stm32_hsem_take(uint8_t id)
|
||||
{
|
||||
DEBUGASSERT(id < STM32_HSEM_CHANS);
|
||||
|
||||
_info("HSEM take %d\n", id);
|
||||
|
||||
/* Take semaphore */
|
||||
|
||||
#ifdef CONFIG_ARCH_CHIP_STM32H7_CORTEXM7
|
||||
return (getreg32(STM32_HSEM_RLRX(id)) ==
|
||||
((HSEM_COREID_CPU1 << HSEM_SEMX_COREID_SHIFT) | HSEM_SEMX_LOCK));
|
||||
#else
|
||||
return (getreg32(STM32_HSEM_RLRX(id)) ==
|
||||
((HSEM_COREID_CPU2 << HSEM_SEMX_COREID_SHIFT) | HSEM_SEMX_LOCK));
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_free
|
||||
*
|
||||
* Description:
|
||||
* Free a semaphore
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_hsem_free(uint8_t id)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_CHIP_STM32H7_CORTEXM7
|
||||
putreg32((HSEM_COREID_CPU1 << HSEM_CR_COREID_SHIFT) , STM32_HSEM_RX(id));
|
||||
#else
|
||||
putreg32((HSEM_COREID_CPU2 << HSEM_CR_COREID_SHIFT) , STM32_HSEM_RX(id));
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_hsem_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize the hardware semaphore driver
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_hsem_init(void)
|
||||
{
|
||||
struct stm32_hsem_s *dev = &g_stm32_hsem;
|
||||
|
||||
/* Reset device */
|
||||
|
||||
memset(dev, 0, sizeof(struct stm32_hsem_s));
|
||||
|
||||
/* Set block id */
|
||||
|
||||
#ifdef CONFIG_ARCH_CHIP_STM32H7_CORTEXM7
|
||||
dev->block = 0;
|
||||
dev->irq = STM32_IRQ_HSEM0;
|
||||
#else
|
||||
dev->block = 1;
|
||||
dev->irq = STM32_IRQ_HSEM1;
|
||||
#endif
|
||||
|
||||
/* Attach and enable the IRQ */
|
||||
|
||||
irq_attach(dev->irq, stm32_hsem_interrupt, dev);
|
||||
up_enable_irq(dev->irq);
|
||||
}
|
68
arch/arm/src/stm32h7/stm32_hsem.h
Normal file
68
arch/arm/src/stm32h7/stm32_hsem.h
Normal file
@ -0,0 +1,68 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/stm32h7/stm32_hsem.h
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_STM32H7_STM32_HSEM_H
|
||||
#define __ARCH_ARM_SRC_STM32H7_STM32_HSEM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "hardware/stm32_hsem.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
typedef void (*hsem_callback_t)(uint8_t id, void *arg);
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#ifdef __cplusplus
|
||||
#define EXTERN extern "C"
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
void stm32_hsem_subscribe(uint8_t id, hsem_callback_t callback, void *args);
|
||||
void stm32_hsem_signal(uint8_t id);
|
||||
void stm32_hsem_busywait_lock(uint8_t id);
|
||||
void stm32_hsem_busywait_free(uint8_t id);
|
||||
void stm32_hsem_wait_take(uint8_t id);
|
||||
bool stm32_hsem_take(uint8_t id);
|
||||
void stm32_hsem_free(uint8_t id);
|
||||
void stm32_hsem_init(void);
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_STM32H7_STM32_HSEM_H */
|
@ -416,6 +416,12 @@ static inline void rcc_enableahb4(void)
|
||||
regval |= RCC_AHB4ENR_BKPSRAMEN;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_STM32H7_HSEM
|
||||
/* HSEM clock enable */
|
||||
|
||||
regval |= RCC_AHB4ENR_HSEMEN;
|
||||
#endif
|
||||
|
||||
putreg32(regval, STM32_RCC_AHB4ENR); /* Enable peripherals */
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user