Initial commit with the original FW
This FW for the New Packet Radio project was taken from the Hackaday project https://hackaday.io/project/164092-npr-new-packet-radio The source code is original without any modifications, ver. 2020_06_29.
This commit is contained in:
commit
16140fd383
1171 changed files with 507922 additions and 0 deletions
3
NPR_14/.mbed
Normal file
3
NPR_14/.mbed
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
TARGET=NUCLEO_L432KC
|
||||
TOOLCHAIN=GCC_ARM
|
||||
ROOT=.
|
||||
525
NPR_14/Makefile
Normal file
525
NPR_14/Makefile
Normal file
|
|
@ -0,0 +1,525 @@
|
|||
# This file was automagically generated by mbed.org. For more information,
|
||||
# see http://mbed.org/handbook/Exporting-to-GCC-ARM-Embedded
|
||||
|
||||
###############################################################################
|
||||
# Boiler-plate
|
||||
|
||||
# cross-platform directory manipulation
|
||||
ifeq ($(shell echo $$OS),$$OS)
|
||||
MAKEDIR = if not exist "$(1)" mkdir "$(1)"
|
||||
RM = rmdir /S /Q "$(1)"
|
||||
else
|
||||
MAKEDIR = '$(SHELL)' -c "mkdir -p \"$(1)\""
|
||||
RM = '$(SHELL)' -c "rm -rf \"$(1)\""
|
||||
endif
|
||||
|
||||
OBJDIR := BUILD
|
||||
# Move to the build directory
|
||||
ifeq (,$(filter $(OBJDIR),$(notdir $(CURDIR))))
|
||||
.SUFFIXES:
|
||||
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
MAKETARGET = '$(MAKE)' --no-print-directory -C $(OBJDIR) -f '$(mkfile_path)' \
|
||||
'SRCDIR=$(CURDIR)' $(MAKECMDGOALS)
|
||||
.PHONY: $(OBJDIR) clean
|
||||
all:
|
||||
+@$(call MAKEDIR,$(OBJDIR))
|
||||
+@$(MAKETARGET)
|
||||
$(OBJDIR): all
|
||||
Makefile : ;
|
||||
% :: $(OBJDIR) ; :
|
||||
clean :
|
||||
$(call RM,$(OBJDIR))
|
||||
|
||||
else
|
||||
|
||||
# trick rules into thinking we are in the root, when we are in the bulid dir
|
||||
VPATH = ..
|
||||
|
||||
# Boiler-plate
|
||||
###############################################################################
|
||||
# Project settings
|
||||
|
||||
PROJECT := NPR_14
|
||||
|
||||
|
||||
# Project settings
|
||||
###############################################################################
|
||||
# Objects and Paths
|
||||
|
||||
OBJECTS += ./mbed-os/drivers/AnalogIn.o
|
||||
OBJECTS += ./mbed-os/drivers/BusIn.o
|
||||
OBJECTS += ./mbed-os/drivers/BusInOut.o
|
||||
OBJECTS += ./mbed-os/drivers/BusOut.o
|
||||
OBJECTS += ./mbed-os/drivers/CAN.o
|
||||
OBJECTS += ./mbed-os/drivers/Ethernet.o
|
||||
OBJECTS += ./mbed-os/drivers/FlashIAP.o
|
||||
OBJECTS += ./mbed-os/drivers/I2C.o
|
||||
OBJECTS += ./mbed-os/drivers/I2CSlave.o
|
||||
OBJECTS += ./mbed-os/drivers/InterruptIn.o
|
||||
OBJECTS += ./mbed-os/drivers/InterruptManager.o
|
||||
OBJECTS += ./mbed-os/drivers/RawSerial.o
|
||||
OBJECTS += ./mbed-os/drivers/SPI.o
|
||||
OBJECTS += ./mbed-os/drivers/SPISlave.o
|
||||
OBJECTS += ./mbed-os/drivers/Serial.o
|
||||
OBJECTS += ./mbed-os/drivers/SerialBase.o
|
||||
OBJECTS += ./mbed-os/drivers/Ticker.o
|
||||
OBJECTS += ./mbed-os/drivers/Timeout.o
|
||||
OBJECTS += ./mbed-os/drivers/Timer.o
|
||||
OBJECTS += ./mbed-os/drivers/TimerEvent.o
|
||||
OBJECTS += ./mbed-os/drivers/UARTSerial.o
|
||||
OBJECTS += ./mbed-os/events/EventQueue.o
|
||||
OBJECTS += ./mbed-os/events/equeue/equeue.o
|
||||
OBJECTS += ./mbed-os/events/equeue/equeue_mbed.o
|
||||
OBJECTS += ./mbed-os/events/equeue/equeue_posix.o
|
||||
OBJECTS += ./mbed-os/events/mbed_shared_queues.o
|
||||
OBJECTS += ./mbed-os/hal/mbed_flash_api.o
|
||||
OBJECTS += ./mbed-os/hal/mbed_gpio.o
|
||||
OBJECTS += ./mbed-os/hal/mbed_lp_ticker_api.o
|
||||
OBJECTS += ./mbed-os/hal/mbed_pinmap_common.o
|
||||
OBJECTS += ./mbed-os/hal/mbed_sleep_manager.o
|
||||
OBJECTS += ./mbed-os/hal/mbed_ticker_api.o
|
||||
OBJECTS += ./mbed-os/hal/mbed_us_ticker_api.o
|
||||
OBJECTS += ./mbed-os/platform/ATCmdParser.o
|
||||
OBJECTS += ./mbed-os/platform/CallChain.o
|
||||
OBJECTS += ./mbed-os/platform/FileBase.o
|
||||
OBJECTS += ./mbed-os/platform/FileHandle.o
|
||||
OBJECTS += ./mbed-os/platform/FilePath.o
|
||||
OBJECTS += ./mbed-os/platform/FileSystemHandle.o
|
||||
OBJECTS += ./mbed-os/platform/LocalFileSystem.o
|
||||
OBJECTS += ./mbed-os/platform/Stream.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_alloc_wrappers.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_application.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_assert.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_board.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_critical.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_error.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_interface.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_mem_trace.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_mktime.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_poll.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_retarget.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_rtc_time.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_sdk_boot.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_semihost_api.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_stats.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_wait_api_no_rtos.o
|
||||
OBJECTS += ./mbed-os/platform/mbed_wait_api_rtos.o
|
||||
OBJECTS += ./mbed-os/rtos/EventFlags.o
|
||||
OBJECTS += ./mbed-os/rtos/Mutex.o
|
||||
OBJECTS += ./mbed-os/rtos/RtosTimer.o
|
||||
OBJECTS += ./mbed-os/rtos/Semaphore.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/mbed_boot.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/mbed_rtx_handlers.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/mbed_rtx_idle.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx4/cmsis_os1.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/RTX_Config.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC/irq_cm4f.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rt_OsEventObserver.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_delay.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_evflags.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_evr.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_kernel.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_lib.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_memory.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_mempool.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_msgqueue.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_mutex.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_semaphore.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_system.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_thread.o
|
||||
OBJECTS += ./mbed-os/rtos/TARGET_CORTEX/rtx5/rtx_timer.o
|
||||
OBJECTS += ./mbed-os/rtos/Thread.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/PeripheralPins.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/system_clock.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/TOOLCHAIN_GCC_ARM/startup_stm32l432xx.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/analogin_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/analogout_device.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_adc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_adc_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_can.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_comp.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_cortex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_crc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_crc_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_cryp.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_cryp_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_dac.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_dac_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_dcmi.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_dfsdm.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_dma.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_dma2d.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_firewall.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_flash.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_flash_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_flash_ramfunc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_gpio.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_hash.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_hash_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_hcd.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_i2c.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_i2c_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_irda.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_iwdg.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_lcd.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_lptim.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_msp_template.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_nand.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_nor.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_opamp.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_opamp_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_pcd.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_pcd_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_pwr.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_pwr_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_qspi.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rcc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rcc_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rng.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rtc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_rtc_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_sai.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_sd.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_smartcard.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_smartcard_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_smbus.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_spi.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_spi_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_sram.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_swpmi.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_tim.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_tim_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_tsc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_uart.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_uart_ex.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_usart.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_hal_wwdg.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_adc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_comp.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_crc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_crs.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_dac.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_dma.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_dma2d.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_exti.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_fmc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_gpio.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_i2c.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_lptim.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_lpuart.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_opamp.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_pwr.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_rcc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_rng.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_rtc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_sdmmc.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_spi.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_swpmi.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_tim.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_usart.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_usb.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/stm32l4xx_ll_utils.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device/system_stm32l4xx.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/flash_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/gpio_irq_device.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/pwmout_device.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/serial_device.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/TARGET_STM32L4/spi_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/analogout_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/can_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/gpio_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/gpio_irq_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/hal_tick_16b.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/hal_tick_32b.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/i2c_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/lp_ticker.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/mbed_overrides.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/pinmap.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/port_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/pwmout_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/rtc_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/serial_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/sleep.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/stm_spi_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/trng_api.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/us_ticker_16b.o
|
||||
OBJECTS += ./mbed-os/targets/TARGET_STM/us_ticker_32b.o
|
||||
OBJECTS += ./source/DHCP_ARP.o
|
||||
OBJECTS += ./source/Eth_IPv4.o
|
||||
OBJECTS += ./source/HMI_telnet.o
|
||||
OBJECTS += ./source/L1L2_radio.o
|
||||
OBJECTS += ./source/SI4463.o
|
||||
OBJECTS += ./source/TDMA.o
|
||||
OBJECTS += ./source/Virt_Chan.o
|
||||
OBJECTS += ./source/W5500.o
|
||||
OBJECTS += ./source/config_flash.o
|
||||
OBJECTS += ./source/ext_SRAM2.o
|
||||
OBJECTS += ./source/global_variables.o
|
||||
OBJECTS += ./source/main.o
|
||||
OBJECTS += ./source/signaling.o
|
||||
|
||||
|
||||
INCLUDE_PATHS += -I../
|
||||
INCLUDE_PATHS += -I../.
|
||||
INCLUDE_PATHS += -I.././mbed-os
|
||||
INCLUDE_PATHS += -I.././mbed-os/cmsis
|
||||
INCLUDE_PATHS += -I.././mbed-os/cmsis/TARGET_CORTEX_M
|
||||
INCLUDE_PATHS += -I.././mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC
|
||||
INCLUDE_PATHS += -I.././mbed-os/cmsis/TOOLCHAIN_GCC
|
||||
INCLUDE_PATHS += -I.././mbed-os/drivers
|
||||
INCLUDE_PATHS += -I.././mbed-os/events
|
||||
INCLUDE_PATHS += -I.././mbed-os/events/equeue
|
||||
INCLUDE_PATHS += -I.././mbed-os/hal
|
||||
INCLUDE_PATHS += -I.././mbed-os/hal/storage_abstraction
|
||||
INCLUDE_PATHS += -I.././mbed-os/platform
|
||||
INCLUDE_PATHS += -I.././mbed-os/rtos
|
||||
INCLUDE_PATHS += -I.././mbed-os/rtos/TARGET_CORTEX
|
||||
INCLUDE_PATHS += -I.././mbed-os/rtos/TARGET_CORTEX/rtx4
|
||||
INCLUDE_PATHS += -I.././mbed-os/rtos/TARGET_CORTEX/rtx5
|
||||
INCLUDE_PATHS += -I.././mbed-os/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7
|
||||
INCLUDE_PATHS += -I.././mbed-os/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets/TARGET_STM
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets/TARGET_STM/TARGET_STM32L4
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/TOOLCHAIN_GCC_ARM
|
||||
INCLUDE_PATHS += -I.././mbed-os/targets/TARGET_STM/TARGET_STM32L4/device
|
||||
INCLUDE_PATHS += -I.././source
|
||||
INCLUDE_PATHS += -I.././source/SI4463
|
||||
INCLUDE_PATHS += -I.././source/drivers
|
||||
INCLUDE_PATHS += -I.././source/drivers/radio
|
||||
INCLUDE_PATHS += -I.././source/drivers/radio/Si446x
|
||||
|
||||
LIBRARY_PATHS :=
|
||||
LIBRARIES :=
|
||||
LINKER_SCRIPT ?= .././mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/TOOLCHAIN_GCC_ARM/STM32L432XX.ld
|
||||
|
||||
# Objects and Paths
|
||||
###############################################################################
|
||||
# Tools and Flags
|
||||
|
||||
AS = 'arm-none-eabi-gcc' '-x' 'assembler-with-cpp' '-c' '-Wall' '-Wextra' '-Wno-unused-parameter' '-Wno-missing-field-initializers' '-fmessage-length=0' '-fno-exceptions' '-fno-builtin' '-ffunction-sections' '-fdata-sections' '-funsigned-char' '-MMD' '-fno-delete-null-pointer-checks' '-fomit-frame-pointer' '-Os' '-g1' '-DMBED_DEBUG' '-DMBED_TRAP_ERRORS_ENABLED=1' '-mcpu=cortex-m4' '-mthumb' '-mfpu=fpv4-sp-d16' '-mfloat-abi=softfp'
|
||||
CC = 'arm-none-eabi-gcc' '-std=gnu99' '-c' '-Wall' '-Wextra' '-Wno-unused-parameter' '-Wno-missing-field-initializers' '-fmessage-length=0' '-fno-exceptions' '-fno-builtin' '-ffunction-sections' '-fdata-sections' '-funsigned-char' '-MMD' '-fno-delete-null-pointer-checks' '-fomit-frame-pointer' '-Os' '-g1' '-DMBED_DEBUG' '-DMBED_TRAP_ERRORS_ENABLED=1' '-mcpu=cortex-m4' '-mthumb' '-mfpu=fpv4-sp-d16' '-mfloat-abi=softfp'
|
||||
CPP = 'arm-none-eabi-g++' '-std=gnu++98' '-fno-rtti' '-Wvla' '-c' '-Wall' '-Wextra' '-Wno-unused-parameter' '-Wno-missing-field-initializers' '-fmessage-length=0' '-fno-exceptions' '-fno-builtin' '-ffunction-sections' '-fdata-sections' '-funsigned-char' '-MMD' '-fno-delete-null-pointer-checks' '-fomit-frame-pointer' '-Os' '-g1' '-DMBED_DEBUG' '-DMBED_TRAP_ERRORS_ENABLED=1' '-mcpu=cortex-m4' '-mthumb' '-mfpu=fpv4-sp-d16' '-mfloat-abi=softfp'
|
||||
LD = 'arm-none-eabi-gcc'
|
||||
ELF2BIN = 'arm-none-eabi-objcopy'
|
||||
PREPROC = 'arm-none-eabi-cpp' '-E' '-P' '-Wl,--gc-sections' '-Wl,--wrap,main' '-Wl,--wrap,_malloc_r' '-Wl,--wrap,_free_r' '-Wl,--wrap,_realloc_r' '-Wl,--wrap,_memalign_r' '-Wl,--wrap,_calloc_r' '-Wl,--wrap,exit' '-Wl,--wrap,atexit' '-Wl,-n' '-mcpu=cortex-m4' '-mthumb' '-mfpu=fpv4-sp-d16' '-mfloat-abi=softfp'
|
||||
|
||||
|
||||
C_FLAGS += -std=gnu99
|
||||
C_FLAGS += -D__MBED__=1
|
||||
C_FLAGS += -DDEVICE_I2CSLAVE=1
|
||||
C_FLAGS += -D__FPU_PRESENT=1
|
||||
C_FLAGS += -DDEVICE_PORTOUT=1
|
||||
C_FLAGS += -DDEVICE_PORTINOUT=1
|
||||
C_FLAGS += -DTARGET_RTOS_M4_M7
|
||||
C_FLAGS += -DDEVICE_LOWPOWERTIMER=1
|
||||
C_FLAGS += -DDEVICE_RTC=1
|
||||
C_FLAGS += -DTOOLCHAIN_object
|
||||
C_FLAGS += -D__CMSIS_RTOS
|
||||
C_FLAGS += -DTOOLCHAIN_GCC
|
||||
C_FLAGS += -DDEVICE_CAN=1
|
||||
C_FLAGS += -DTARGET_CORTEX_M
|
||||
C_FLAGS += -DTARGET_DEBUG
|
||||
C_FLAGS += -DDEVICE_I2C_ASYNCH=1
|
||||
C_FLAGS += -DTARGET_LIKE_CORTEX_M4
|
||||
C_FLAGS += -DDEVICE_ANALOGOUT=1
|
||||
C_FLAGS += -DTARGET_M4
|
||||
C_FLAGS += -DTARGET_UVISOR_UNSUPPORTED
|
||||
C_FLAGS += -DTARGET_STM32L4
|
||||
C_FLAGS += -DDEVICE_SPI_ASYNCH=1
|
||||
C_FLAGS += -DDEVICE_PWMOUT=1
|
||||
C_FLAGS += -DTARGET_STM32L432xC
|
||||
C_FLAGS += -DTARGET_CORTEX
|
||||
C_FLAGS += -DDEVICE_I2C=1
|
||||
C_FLAGS += -DTRANSACTION_QUEUE_SIZE_SPI=2
|
||||
C_FLAGS += -D__CORTEX_M4
|
||||
C_FLAGS += -DDEVICE_STDIO_MESSAGES=1
|
||||
C_FLAGS += -DTARGET_FAMILY_STM32
|
||||
C_FLAGS += -DTARGET_FF_ARDUINO
|
||||
C_FLAGS += -DDEVICE_PORTIN=1
|
||||
C_FLAGS += -DTARGET_STM
|
||||
C_FLAGS += -DTARGET_STM32L432KC
|
||||
C_FLAGS += -DDEVICE_SERIAL_FC=1
|
||||
C_FLAGS += -DMBED_BUILD_TIMESTAMP=1593423187.67
|
||||
C_FLAGS += -DDEVICE_TRNG=1
|
||||
C_FLAGS += -DTARGET_LIKE_MBED
|
||||
C_FLAGS += -D__MBED_CMSIS_RTOS_CM
|
||||
C_FLAGS += -DDEVICE_SLEEP=1
|
||||
C_FLAGS += -DTOOLCHAIN_GCC_ARM
|
||||
C_FLAGS += -DDEVICE_SPI=1
|
||||
C_FLAGS += -DDEVICE_INTERRUPTIN=1
|
||||
C_FLAGS += -DDEVICE_SPISLAVE=1
|
||||
C_FLAGS += -DDEVICE_ANALOGIN=1
|
||||
C_FLAGS += -DDEVICE_SERIAL=1
|
||||
C_FLAGS += -DDEVICE_FLASH=1
|
||||
C_FLAGS += -DTARGET_NUCLEO_L432KC
|
||||
C_FLAGS += -DARM_MATH_CM4
|
||||
C_FLAGS += -include
|
||||
C_FLAGS += mbed_config.h
|
||||
|
||||
CXX_FLAGS += -std=gnu++98
|
||||
CXX_FLAGS += -fno-rtti
|
||||
CXX_FLAGS += -Wvla
|
||||
CXX_FLAGS += -D__MBED__=1
|
||||
CXX_FLAGS += -DDEVICE_I2CSLAVE=1
|
||||
CXX_FLAGS += -D__FPU_PRESENT=1
|
||||
CXX_FLAGS += -DDEVICE_PORTOUT=1
|
||||
CXX_FLAGS += -DDEVICE_PORTINOUT=1
|
||||
CXX_FLAGS += -DTARGET_RTOS_M4_M7
|
||||
CXX_FLAGS += -DDEVICE_LOWPOWERTIMER=1
|
||||
CXX_FLAGS += -DDEVICE_RTC=1
|
||||
CXX_FLAGS += -DTOOLCHAIN_object
|
||||
CXX_FLAGS += -D__CMSIS_RTOS
|
||||
CXX_FLAGS += -DTOOLCHAIN_GCC
|
||||
CXX_FLAGS += -DDEVICE_CAN=1
|
||||
CXX_FLAGS += -DTARGET_CORTEX_M
|
||||
CXX_FLAGS += -DTARGET_DEBUG
|
||||
CXX_FLAGS += -DDEVICE_I2C_ASYNCH=1
|
||||
CXX_FLAGS += -DTARGET_LIKE_CORTEX_M4
|
||||
CXX_FLAGS += -DDEVICE_ANALOGOUT=1
|
||||
CXX_FLAGS += -DTARGET_M4
|
||||
CXX_FLAGS += -DTARGET_UVISOR_UNSUPPORTED
|
||||
CXX_FLAGS += -DTARGET_STM32L4
|
||||
CXX_FLAGS += -DDEVICE_SPI_ASYNCH=1
|
||||
CXX_FLAGS += -DDEVICE_PWMOUT=1
|
||||
CXX_FLAGS += -DTARGET_STM32L432xC
|
||||
CXX_FLAGS += -DTARGET_CORTEX
|
||||
CXX_FLAGS += -DDEVICE_I2C=1
|
||||
CXX_FLAGS += -DTRANSACTION_QUEUE_SIZE_SPI=2
|
||||
CXX_FLAGS += -D__CORTEX_M4
|
||||
CXX_FLAGS += -DDEVICE_STDIO_MESSAGES=1
|
||||
CXX_FLAGS += -DTARGET_FAMILY_STM32
|
||||
CXX_FLAGS += -DTARGET_FF_ARDUINO
|
||||
CXX_FLAGS += -DDEVICE_PORTIN=1
|
||||
CXX_FLAGS += -DTARGET_STM
|
||||
CXX_FLAGS += -DTARGET_STM32L432KC
|
||||
CXX_FLAGS += -DDEVICE_SERIAL_FC=1
|
||||
CXX_FLAGS += -DMBED_BUILD_TIMESTAMP=1593423187.67
|
||||
CXX_FLAGS += -DDEVICE_TRNG=1
|
||||
CXX_FLAGS += -DTARGET_LIKE_MBED
|
||||
CXX_FLAGS += -D__MBED_CMSIS_RTOS_CM
|
||||
CXX_FLAGS += -DDEVICE_SLEEP=1
|
||||
CXX_FLAGS += -DTOOLCHAIN_GCC_ARM
|
||||
CXX_FLAGS += -DDEVICE_SPI=1
|
||||
CXX_FLAGS += -DDEVICE_INTERRUPTIN=1
|
||||
CXX_FLAGS += -DDEVICE_SPISLAVE=1
|
||||
CXX_FLAGS += -DDEVICE_ANALOGIN=1
|
||||
CXX_FLAGS += -DDEVICE_SERIAL=1
|
||||
CXX_FLAGS += -DDEVICE_FLASH=1
|
||||
CXX_FLAGS += -DTARGET_NUCLEO_L432KC
|
||||
CXX_FLAGS += -DARM_MATH_CM4
|
||||
CXX_FLAGS += -include
|
||||
CXX_FLAGS += mbed_config.h
|
||||
|
||||
ASM_FLAGS += -x
|
||||
ASM_FLAGS += assembler-with-cpp
|
||||
ASM_FLAGS += -DTRANSACTION_QUEUE_SIZE_SPI=2
|
||||
ASM_FLAGS += -D__CORTEX_M4
|
||||
ASM_FLAGS += -DARM_MATH_CM4
|
||||
ASM_FLAGS += -D__FPU_PRESENT=1
|
||||
ASM_FLAGS += -D__MBED_CMSIS_RTOS_CM
|
||||
ASM_FLAGS += -D__CMSIS_RTOS
|
||||
ASM_FLAGS += -I.
|
||||
ASM_FLAGS += -I./mbed-os
|
||||
ASM_FLAGS += -I./mbed-os/cmsis
|
||||
ASM_FLAGS += -I./mbed-os/cmsis/TARGET_CORTEX_M
|
||||
ASM_FLAGS += -I./mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC
|
||||
ASM_FLAGS += -I./mbed-os/cmsis/TOOLCHAIN_GCC
|
||||
ASM_FLAGS += -I./mbed-os/drivers
|
||||
ASM_FLAGS += -I./mbed-os/events
|
||||
ASM_FLAGS += -I./mbed-os/events/equeue
|
||||
ASM_FLAGS += -I./mbed-os/hal
|
||||
ASM_FLAGS += -I./mbed-os/hal/storage_abstraction
|
||||
ASM_FLAGS += -I./mbed-os/platform
|
||||
ASM_FLAGS += -I./mbed-os/rtos
|
||||
ASM_FLAGS += -I./mbed-os/rtos/TARGET_CORTEX
|
||||
ASM_FLAGS += -I./mbed-os/rtos/TARGET_CORTEX/rtx4
|
||||
ASM_FLAGS += -I./mbed-os/rtos/TARGET_CORTEX/rtx5
|
||||
ASM_FLAGS += -I./mbed-os/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7
|
||||
ASM_FLAGS += -I./mbed-os/rtos/TARGET_CORTEX/rtx5/TARGET_RTOS_M4_M7/TOOLCHAIN_GCC
|
||||
ASM_FLAGS += -I./mbed-os/targets
|
||||
ASM_FLAGS += -I./mbed-os/targets/TARGET_STM
|
||||
ASM_FLAGS += -I./mbed-os/targets/TARGET_STM/TARGET_STM32L4
|
||||
ASM_FLAGS += -I./mbed-os/targets/TARGET_STM/TARGET_STM32L4/device
|
||||
ASM_FLAGS += -I./mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC
|
||||
ASM_FLAGS += -I./mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device
|
||||
ASM_FLAGS += -I./mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/device/TOOLCHAIN_GCC_ARM
|
||||
ASM_FLAGS += -I./mbed-os/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC
|
||||
ASM_FLAGS += -I./source
|
||||
ASM_FLAGS += -I./source/drivers
|
||||
ASM_FLAGS += -I./source/drivers/radio
|
||||
ASM_FLAGS += -I./source/drivers/radio/Si446x
|
||||
ASM_FLAGS += -I./source/SI4463
|
||||
|
||||
|
||||
LD_FLAGS :=-Wl,--gc-sections -Wl,--wrap,main -Wl,--wrap,_malloc_r -Wl,--wrap,_free_r -Wl,--wrap,_realloc_r -Wl,--wrap,_memalign_r -Wl,--wrap,_calloc_r -Wl,--wrap,exit -Wl,--wrap,atexit -Wl,-n -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
|
||||
LD_SYS_LIBS :=-Wl,--start-group -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys -Wl,--end-group
|
||||
|
||||
# Tools and Flags
|
||||
###############################################################################
|
||||
# Rules
|
||||
|
||||
.PHONY: all lst size
|
||||
|
||||
|
||||
all: $(PROJECT).bin $(PROJECT).hex size
|
||||
|
||||
|
||||
.s.o:
|
||||
+@$(call MAKEDIR,$(dir $@))
|
||||
+@echo "Assemble: $(notdir $<)"
|
||||
|
||||
@$(AS) -c $(ASM_FLAGS) $(INCLUDE_PATHS) -o $@ $<
|
||||
|
||||
|
||||
|
||||
.S.o:
|
||||
+@$(call MAKEDIR,$(dir $@))
|
||||
+@echo "Assemble: $(notdir $<)"
|
||||
|
||||
@$(AS) -c $(ASM_FLAGS) $(INCLUDE_PATHS) -o $@ $<
|
||||
|
||||
|
||||
.c.o:
|
||||
+@$(call MAKEDIR,$(dir $@))
|
||||
+@echo "Compile: $(notdir $<)"
|
||||
@$(CC) $(C_FLAGS) $(INCLUDE_PATHS) -o $@ $<
|
||||
|
||||
.cpp.o:
|
||||
+@$(call MAKEDIR,$(dir $@))
|
||||
+@echo "Compile: $(notdir $<)"
|
||||
@$(CPP) $(CXX_FLAGS) $(INCLUDE_PATHS) -o $@ $<
|
||||
|
||||
|
||||
$(PROJECT).link_script.ld: $(LINKER_SCRIPT)
|
||||
@$(PREPROC) $< -o $@
|
||||
|
||||
|
||||
|
||||
$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS) $(PROJECT).link_script.ld
|
||||
+@echo "link: $(notdir $@)"
|
||||
@$(LD) $(LD_FLAGS) -T $(filter-out %.o, $^) $(LIBRARY_PATHS) --output $@ $(filter %.o, $^) $(LIBRARIES) $(LD_SYS_LIBS)
|
||||
|
||||
|
||||
$(PROJECT).bin: $(PROJECT).elf
|
||||
$(ELF2BIN) -O binary $< $@
|
||||
+@echo "===== bin file ready to flash: $(OBJDIR)/$@ ====="
|
||||
|
||||
$(PROJECT).hex: $(PROJECT).elf
|
||||
$(ELF2BIN) -O ihex $< $@
|
||||
|
||||
|
||||
# Rules
|
||||
###############################################################################
|
||||
# Dependencies
|
||||
|
||||
DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
|
||||
# Dependencies
|
||||
###############################################################################
|
||||
674
NPR_14/gpl-3.0.txt
Normal file
674
NPR_14/gpl-3.0.txt
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
673
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h
Normal file
673
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/TOOLCHAIN_ARM/cmsis_armcc.h
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_armcc.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.00
|
||||
* @date 22. Feb 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* 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 __CMSIS_ARMCC_H
|
||||
#define __CMSIS_ARMCC_H
|
||||
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler control architecture macros */
|
||||
#if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1))
|
||||
#define __ARM_ARCH_7A__ 1
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_ASM
|
||||
#define __STATIC_ASM static __asm
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
\brief No Operation
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Reverse byte order in signed short value
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __rbit
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
/** \brief Get CPSR Register
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
register uint32_t __regCPSR __ASM("cpsr");
|
||||
return(__regCPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set CPSR Register
|
||||
\param [in] cpsr CPSR value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPSR(uint32_t cpsr)
|
||||
{
|
||||
register uint32_t __regCPSR __ASM("cpsr");
|
||||
__regCPSR = cpsr;
|
||||
}
|
||||
|
||||
/** \brief Get Mode
|
||||
\return Processor Mode
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_mode(void) {
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
}
|
||||
|
||||
/** \brief Set Mode
|
||||
\param [in] mode Mode value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_mode(uint32_t mode) {
|
||||
MOV r1, lr
|
||||
MSR CPSR_C, r0
|
||||
BX r1
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_SP(uint32_t stack)
|
||||
{
|
||||
MOV sp, r0
|
||||
BX lr
|
||||
}
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
ARM
|
||||
PRESERVE8
|
||||
|
||||
BIC R0, R0, #7 ;ensure stack is 8-byte aligned
|
||||
MRS R1, CPSR
|
||||
CPS #0x1F ;no effect in USR mode
|
||||
MOV SP, R0
|
||||
MSR CPSR_c, R1 ;no effect in USR mode
|
||||
ISB
|
||||
BX LR
|
||||
}
|
||||
|
||||
/** \brief Set User Mode
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_CPS_USR(void)
|
||||
{
|
||||
ARM
|
||||
|
||||
CPS #0x10
|
||||
BX LR
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC
|
||||
\return Floating Point Exception Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
register uint32_t __regfpexc __ASM("fpexc");
|
||||
return(__regfpexc);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Set FPEXC
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
register uint32_t __regfpexc __ASM("fpexc");
|
||||
__regfpexc = (fpexc);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPACR
|
||||
\return Coprocessor Access Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPACR(void)
|
||||
{
|
||||
register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2");
|
||||
return __regCPACR;
|
||||
}
|
||||
|
||||
/** \brief Set CPACR
|
||||
\param [in] cpacr Coprocessor Acccess Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPACR(uint32_t cpacr)
|
||||
{
|
||||
register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2");
|
||||
__regCPACR = cpacr;
|
||||
}
|
||||
|
||||
/** \brief Get CBAR
|
||||
\return Configuration Base Address register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CBAR() {
|
||||
register uint32_t __regCBAR __ASM("cp15:4:c15:c0:0");
|
||||
return(__regCBAR);
|
||||
}
|
||||
|
||||
/** \brief Get TTBR0
|
||||
|
||||
This function returns the value of the Translation Table Base Register 0.
|
||||
|
||||
\return Translation Table Base Register 0 value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_TTBR0() {
|
||||
register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0");
|
||||
return(__regTTBR0);
|
||||
}
|
||||
|
||||
/** \brief Set TTBR0
|
||||
|
||||
This function assigns the given value to the Translation Table Base Register 0.
|
||||
|
||||
\param [in] ttbr0 Translation Table Base Register 0 value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) {
|
||||
register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0");
|
||||
__regTTBR0 = ttbr0;
|
||||
}
|
||||
|
||||
/** \brief Get DACR
|
||||
|
||||
This function returns the value of the Domain Access Control Register.
|
||||
|
||||
\return Domain Access Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_DACR() {
|
||||
register uint32_t __regDACR __ASM("cp15:0:c3:c0:0");
|
||||
return(__regDACR);
|
||||
}
|
||||
|
||||
/** \brief Set DACR
|
||||
|
||||
This function assigns the given value to the Domain Access Control Register.
|
||||
|
||||
\param [in] dacr Domain Access Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_DACR(uint32_t dacr) {
|
||||
register uint32_t __regDACR __ASM("cp15:0:c3:c0:0");
|
||||
__regDACR = dacr;
|
||||
}
|
||||
|
||||
/** \brief Set SCTLR
|
||||
|
||||
This function assigns the given value to the System Control Register.
|
||||
|
||||
\param [in] sctlr System Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
|
||||
{
|
||||
register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0");
|
||||
__regSCTLR = sctlr;
|
||||
}
|
||||
|
||||
/** \brief Get SCTLR
|
||||
\return System Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_SCTLR() {
|
||||
register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0");
|
||||
return(__regSCTLR);
|
||||
}
|
||||
|
||||
/** \brief Set ACTRL
|
||||
\param [in] actrl Auxiliary Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_ACTRL(uint32_t actrl)
|
||||
{
|
||||
register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1");
|
||||
__regACTRL = actrl;
|
||||
}
|
||||
|
||||
/** \brief Get ACTRL
|
||||
\return Auxiliary Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_ACTRL(void)
|
||||
{
|
||||
register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1");
|
||||
return(__regACTRL);
|
||||
}
|
||||
|
||||
/** \brief Get MPIDR
|
||||
|
||||
This function returns the value of the Multiprocessor Affinity Register.
|
||||
|
||||
\return Multiprocessor Affinity Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MPIDR(void)
|
||||
{
|
||||
register uint32_t __regMPIDR __ASM("cp15:0:c0:c0:5");
|
||||
return(__regMPIDR);
|
||||
}
|
||||
|
||||
/** \brief Get VBAR
|
||||
|
||||
This function returns the value of the Vector Base Address Register.
|
||||
|
||||
\return Vector Base Address Register
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_VBAR(void)
|
||||
{
|
||||
register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0");
|
||||
return(__regVBAR);
|
||||
}
|
||||
|
||||
/** \brief Set VBAR
|
||||
|
||||
This function assigns the given value to the Vector Base Address Register.
|
||||
|
||||
\param [in] vbar Vector Base Address Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_VBAR(uint32_t vbar)
|
||||
{
|
||||
register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0");
|
||||
__regVBAR = vbar;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_TVAL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\param [in] value CNTP_TVAL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) {
|
||||
register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0");
|
||||
__regCNTP_TVAL = value;
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_TVAL
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\return CNTP_TVAL Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CNTP_TVAL() {
|
||||
register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0");
|
||||
return(__regCNTP_TVAL);
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_CTL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
|
||||
|
||||
\param [in] value CNTP_CTL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) {
|
||||
register uint32_t __regCNTP_CTL __ASM("cp15:0:c14:c2:1");
|
||||
__regCNTP_CTL = value;
|
||||
}
|
||||
|
||||
/** \brief Set TLBIALL
|
||||
|
||||
TLB Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_TLBIALL(uint32_t value) {
|
||||
register uint32_t __TLBIALL __ASM("cp15:0:c8:c7:0");
|
||||
__TLBIALL = value;
|
||||
}
|
||||
|
||||
/** \brief Set BPIALL.
|
||||
|
||||
Branch Predictor Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_BPIALL(uint32_t value) {
|
||||
register uint32_t __BPIALL __ASM("cp15:0:c7:c5:6");
|
||||
__BPIALL = value;
|
||||
}
|
||||
|
||||
/** \brief Set ICIALLU
|
||||
|
||||
Instruction Cache Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_ICIALLU(uint32_t value) {
|
||||
register uint32_t __ICIALLU __ASM("cp15:0:c7:c5:0");
|
||||
__ICIALLU = value;
|
||||
}
|
||||
|
||||
/** \brief Set DCCMVAC
|
||||
|
||||
Data cache clean
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCMVAC(uint32_t value) {
|
||||
register uint32_t __DCCMVAC __ASM("cp15:0:c7:c10:1");
|
||||
__DCCMVAC = value;
|
||||
}
|
||||
|
||||
/** \brief Set DCIMVAC
|
||||
|
||||
Data cache invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCIMVAC(uint32_t value) {
|
||||
register uint32_t __DCIMVAC __ASM("cp15:0:c7:c6:1");
|
||||
__DCIMVAC = value;
|
||||
}
|
||||
|
||||
/** \brief Set DCCIMVAC
|
||||
|
||||
Data cache clean and invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) {
|
||||
register uint32_t __DCCIMVAC __ASM("cp15:0:c7:c14:1");
|
||||
__DCCIMVAC = value;
|
||||
}
|
||||
|
||||
/** \brief Clean and Invalidate the entire data or unified cache
|
||||
|
||||
Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency
|
||||
*/
|
||||
#pragma push
|
||||
#pragma arm
|
||||
__STATIC_INLINE __ASM void __L1C_CleanInvalidateCache(uint32_t op) {
|
||||
ARM
|
||||
|
||||
PUSH {R4-R11}
|
||||
|
||||
MRC p15, 1, R6, c0, c0, 1 // Read CLIDR
|
||||
ANDS R3, R6, #0x07000000 // Extract coherency level
|
||||
MOV R3, R3, LSR #23 // Total cache levels << 1
|
||||
BEQ Finished // If 0, no need to clean
|
||||
|
||||
MOV R10, #0 // R10 holds current cache level << 1
|
||||
Loop1 ADD R2, R10, R10, LSR #1 // R2 holds cache "Set" position
|
||||
MOV R1, R6, LSR R2 // Bottom 3 bits are the Cache-type for this level
|
||||
AND R1, R1, #7 // Isolate those lower 3 bits
|
||||
CMP R1, #2
|
||||
BLT Skip // No cache or only instruction cache at this level
|
||||
|
||||
MCR p15, 2, R10, c0, c0, 0 // Write the Cache Size selection register
|
||||
ISB // ISB to sync the change to the CacheSizeID reg
|
||||
MRC p15, 1, R1, c0, c0, 0 // Reads current Cache Size ID register
|
||||
AND R2, R1, #7 // Extract the line length field
|
||||
ADD R2, R2, #4 // Add 4 for the line length offset (log2 16 bytes)
|
||||
LDR R4, =0x3FF
|
||||
ANDS R4, R4, R1, LSR #3 // R4 is the max number on the way size (right aligned)
|
||||
CLZ R5, R4 // R5 is the bit position of the way size increment
|
||||
LDR R7, =0x7FFF
|
||||
ANDS R7, R7, R1, LSR #13 // R7 is the max number of the index size (right aligned)
|
||||
|
||||
Loop2 MOV R9, R4 // R9 working copy of the max way size (right aligned)
|
||||
|
||||
Loop3 ORR R11, R10, R9, LSL R5 // Factor in the Way number and cache number into R11
|
||||
ORR R11, R11, R7, LSL R2 // Factor in the Set number
|
||||
CMP R0, #0
|
||||
BNE Dccsw
|
||||
MCR p15, 0, R11, c7, c6, 2 // DCISW. Invalidate by Set/Way
|
||||
B cont
|
||||
Dccsw CMP R0, #1
|
||||
BNE Dccisw
|
||||
MCR p15, 0, R11, c7, c10, 2 // DCCSW. Clean by Set/Way
|
||||
B cont
|
||||
Dccisw MCR p15, 0, R11, c7, c14, 2 // DCCISW. Clean and Invalidate by Set/Way
|
||||
cont SUBS R9, R9, #1 // Decrement the Way number
|
||||
BGE Loop3
|
||||
SUBS R7, R7, #1 // Decrement the Set number
|
||||
BGE Loop2
|
||||
Skip ADD R10, R10, #2 // Increment the cache number
|
||||
CMP R3, R10
|
||||
BGT Loop1
|
||||
|
||||
Finished
|
||||
DSB
|
||||
POP {R4-R11}
|
||||
BX lr
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/** \brief Enable Floating Point Unit
|
||||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
#pragma push
|
||||
#pragma arm
|
||||
__STATIC_INLINE __ASM void __FPU_Enable(void) {
|
||||
ARM
|
||||
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
MRC p15,0,R1,c1,c0,2
|
||||
ORR R1,R1,#0x00F00000
|
||||
MCR p15,0,R1,c1,c0,2
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
ISB
|
||||
|
||||
//Enable VFP/NEON
|
||||
VMRS R1,FPEXC
|
||||
ORR R1,R1,#0x40000000
|
||||
VMSR FPEXC,R1
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
MOV R2,#0
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} >= 16
|
||||
//Initialise D16 registers to 0
|
||||
VMOV D0, R2,R2
|
||||
VMOV D1, R2,R2
|
||||
VMOV D2, R2,R2
|
||||
VMOV D3, R2,R2
|
||||
VMOV D4, R2,R2
|
||||
VMOV D5, R2,R2
|
||||
VMOV D6, R2,R2
|
||||
VMOV D7, R2,R2
|
||||
VMOV D8, R2,R2
|
||||
VMOV D9, R2,R2
|
||||
VMOV D10,R2,R2
|
||||
VMOV D11,R2,R2
|
||||
VMOV D12,R2,R2
|
||||
VMOV D13,R2,R2
|
||||
VMOV D14,R2,R2
|
||||
VMOV D15,R2,R2
|
||||
ENDIF
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
|
||||
//Initialise D32 registers to 0
|
||||
VMOV D16,R2,R2
|
||||
VMOV D17,R2,R2
|
||||
VMOV D18,R2,R2
|
||||
VMOV D19,R2,R2
|
||||
VMOV D20,R2,R2
|
||||
VMOV D21,R2,R2
|
||||
VMOV D22,R2,R2
|
||||
VMOV D23,R2,R2
|
||||
VMOV D24,R2,R2
|
||||
VMOV D25,R2,R2
|
||||
VMOV D26,R2,R2
|
||||
VMOV D27,R2,R2
|
||||
VMOV D28,R2,R2
|
||||
VMOV D29,R2,R2
|
||||
VMOV D30,R2,R2
|
||||
VMOV D31,R2,R2
|
||||
ENDIF
|
||||
|
||||
//Initialise FPSCR to a known state
|
||||
VMRS R2,FPSCR
|
||||
LDR R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
AND R2,R2,R3
|
||||
VMSR FPSCR,R2
|
||||
|
||||
BX LR
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
||||
|
|
@ -0,0 +1,646 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_armclang.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.00
|
||||
* @date 05. Apr 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* 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 __CMSIS_ARMCLANG_H
|
||||
#define __CMSIS_ARMCLANG_H
|
||||
|
||||
#ifndef __ARM_COMPAT_H
|
||||
#include <arm_compat.h> /* Compatibility header for ARM Compiler 5 intrinsics */
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_ASM
|
||||
#define __STATIC_ASM static __asm
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
__ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) : "memory");
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
\brief No Operation
|
||||
*/
|
||||
#define __NOP __builtin_arm_nop
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
*/
|
||||
#define __WFI __builtin_arm_wfi
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
*/
|
||||
#define __WFE __builtin_arm_wfe
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
*/
|
||||
#define __SEV __builtin_arm_sev
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__builtin_arm_isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__builtin_arm_dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__builtin_arm_dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __builtin_bswap32
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Reverse byte order in signed short value
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
int32_t result;
|
||||
__ASM volatile("revsh %0, %1" : "=r" (result) : "r" (value));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << (32U - op2));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __builtin_arm_rbit
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __builtin_clz
|
||||
|
||||
/** \brief Get CPSR Register
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, cpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/** \brief Get Mode
|
||||
\return Processor Mode
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_mode(void) {
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
}
|
||||
|
||||
/** \brief Set Mode
|
||||
\param [in] mode Mode value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_mode(uint32_t mode) {
|
||||
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_SP(uint32_t stack)
|
||||
{
|
||||
__ASM volatile("MOV sp, %0" : : "r" (stack) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile(
|
||||
".preserve8 \n"
|
||||
"BIC r0, r0, #7 \n" // ensure stack is 8-byte aligned
|
||||
"MRS r1, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV sp, r0 \n"
|
||||
"MSR cpsr_c, r1 \n" // no effect in USR mode
|
||||
"ISB"
|
||||
);
|
||||
}
|
||||
|
||||
/** \brief Set User Mode
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPS_USR(void)
|
||||
{
|
||||
__ASM volatile("CPS #0x10");
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC
|
||||
\return Floating Point Exception Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, fpexc" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Set FPEXC
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM volatile ("MSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPACR
|
||||
\return Coprocessor Access Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPACR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c1, c0, 2" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CPACR
|
||||
\param [in] cpacr Coprocessor Acccess Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPACR(uint32_t cpacr)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c1, c0, 2" : : "r"(cpacr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get CBAR
|
||||
\return Configuration Base Address register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CBAR() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 4, %0, c15, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get TTBR0
|
||||
|
||||
This function returns the value of the Translation Table Base Register 0.
|
||||
|
||||
\return Translation Table Base Register 0 value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_TTBR0() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c2, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set TTBR0
|
||||
|
||||
This function assigns the given value to the Translation Table Base Register 0.
|
||||
|
||||
\param [in] ttbr0 Translation Table Base Register 0 value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) {
|
||||
__ASM volatile("MCR p15, 0, %0, c2, c0, 0" : : "r"(ttbr0) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get DACR
|
||||
|
||||
This function returns the value of the Domain Access Control Register.
|
||||
|
||||
\return Domain Access Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_DACR() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c3, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set DACR
|
||||
|
||||
This function assigns the given value to the Domain Access Control Register.
|
||||
|
||||
\param [in] dacr Domain Access Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_DACR(uint32_t dacr) {
|
||||
__ASM volatile("MCR p15, 0, %0, c3, c0, 0" : : "r"(dacr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set SCTLR
|
||||
|
||||
This function assigns the given value to the System Control Register.
|
||||
|
||||
\param [in] sctlr System Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c1, c0, 0" : : "r"(sctlr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get SCTLR
|
||||
\return System Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_SCTLR() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c1, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set ACTRL
|
||||
\param [in] actrl Auxiliary Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_ACTRL(uint32_t actrl)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c1, c0, 1" : : "r"(actrl) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get ACTRL
|
||||
\return Auxiliary Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_ACTRL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get MPIDR
|
||||
|
||||
This function returns the value of the Multiprocessor Affinity Register.
|
||||
|
||||
\return Multiprocessor Affinity Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MPIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c0, c0, 5" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get VBAR
|
||||
|
||||
This function returns the value of the Vector Base Address Register.
|
||||
|
||||
\return Vector Base Address Register
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_VBAR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c12, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set VBAR
|
||||
|
||||
This function assigns the given value to the Vector Base Address Register.
|
||||
|
||||
\param [in] vbar Vector Base Address Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_VBAR(uint32_t vbar)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c12, c0, 1" : : "r"(vbar) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_TVAL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\param [in] value CNTP_TVAL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c14, c2, 0" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_TVAL
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\return CNTP_TVAL Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CNTP_TVAL() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c14, c2, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_CTL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
|
||||
|
||||
\param [in] value CNTP_CTL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c14, c2, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set TLBIALL
|
||||
|
||||
TLB Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_TLBIALL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c8, c7, 0" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set BPIALL.
|
||||
|
||||
Branch Predictor Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_BPIALL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c5, 6" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set ICIALLU
|
||||
|
||||
Instruction Cache Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_ICIALLU(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c5, 0" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set DCCMVAC
|
||||
|
||||
Data cache clean
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCMVAC(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c10, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set DCIMVAC
|
||||
|
||||
Data cache invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCIMVAC(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c6, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set DCCIMVAC
|
||||
|
||||
Data cache clean and invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c14, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Clean and Invalidate the entire data or unified cache
|
||||
|
||||
Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency
|
||||
*/
|
||||
__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) {
|
||||
__ASM volatile(
|
||||
" PUSH {R4-R11} \n"
|
||||
|
||||
" MRC p15, 1, R6, c0, c0, 1 \n" // Read CLIDR
|
||||
" ANDS R3, R6, #0x07000000 \n" // Extract coherency level
|
||||
" MOV R3, R3, LSR #23 \n" // Total cache levels << 1
|
||||
" BEQ Finished \n" // If 0, no need to clean
|
||||
|
||||
" MOV R10, #0 \n" // R10 holds current cache level << 1
|
||||
"Loop1: ADD R2, R10, R10, LSR #1 \n" // R2 holds cache "Set" position
|
||||
" MOV R1, R6, LSR R2 \n" // Bottom 3 bits are the Cache-type for this level
|
||||
" AND R1, R1, #7 \n" // Isolate those lower 3 bits
|
||||
" CMP R1, #2 \n"
|
||||
" BLT Skip \n" // No cache or only instruction cache at this level
|
||||
|
||||
" MCR p15, 2, R10, c0, c0, 0 \n" // Write the Cache Size selection register
|
||||
" ISB \n" // ISB to sync the change to the CacheSizeID reg
|
||||
" MRC p15, 1, R1, c0, c0, 0 \n" // Reads current Cache Size ID register
|
||||
" AND R2, R1, #7 \n" // Extract the line length field
|
||||
" ADD R2, R2, #4 \n" // Add 4 for the line length offset (log2 16 bytes)
|
||||
" LDR R4, =0x3FF \n"
|
||||
" ANDS R4, R4, R1, LSR #3 \n" // R4 is the max number on the way size (right aligned)
|
||||
" CLZ R5, R4 \n" // R5 is the bit position of the way size increment
|
||||
" LDR R7, =0x7FFF \n"
|
||||
" ANDS R7, R7, R1, LSR #13 \n" // R7 is the max number of the index size (right aligned)
|
||||
|
||||
"Loop2: MOV R9, R4 \n" // R9 working copy of the max way size (right aligned)
|
||||
|
||||
"Loop3: ORR R11, R10, R9, LSL R5 \n" // Factor in the Way number and cache number into R11
|
||||
" ORR R11, R11, R7, LSL R2 \n" // Factor in the Set number
|
||||
" CMP R0, #0 \n"
|
||||
" BNE Dccsw \n"
|
||||
" MCR p15, 0, R11, c7, c6, 2 \n" // DCISW. Invalidate by Set/Way
|
||||
" B cont \n"
|
||||
"Dccsw: CMP R0, #1 \n"
|
||||
" BNE Dccisw \n"
|
||||
" MCR p15, 0, R11, c7, c10, 2 \n" // DCCSW. Clean by Set/Way
|
||||
" B cont \n"
|
||||
"Dccisw: MCR p15, 0, R11, c7, c14, 2 \n" // DCCISW. Clean and Invalidate by Set/Way
|
||||
"cont: SUBS R9, R9, #1 \n" // Decrement the Way number
|
||||
" BGE Loop3 \n"
|
||||
" SUBS R7, R7, #1 \n" // Decrement the Set number
|
||||
" BGE Loop2 \n"
|
||||
"Skip: ADD R10, R10, #2 \n" // Increment the cache number
|
||||
" CMP R3, R10 \n"
|
||||
" BGT Loop1 \n"
|
||||
|
||||
"Finished: \n"
|
||||
" DSB \n"
|
||||
" POP {R4-R11} "
|
||||
);
|
||||
}
|
||||
|
||||
/** \brief Enable Floating Point Unit
|
||||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
__STATIC_INLINE void __FPU_Enable(void) {
|
||||
__ASM volatile(
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
" MRC p15,0,R1,c1,c0,2 \n"
|
||||
" ORR R1,R1,#0x00F00000 \n"
|
||||
" MCR p15,0,R1,c1,c0,2 \n"
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
" ISB \n"
|
||||
|
||||
//Enable VFP/NEON
|
||||
" VMRS R1,FPEXC \n"
|
||||
" ORR R1,R1,#0x40000000 \n"
|
||||
" VMSR FPEXC,R1 \n"
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
" MOV R2,#0 \n"
|
||||
#if 0 // TODO: Initialize FPU registers according to available register count
|
||||
".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} >= 16 \n"
|
||||
//Initialise D16 registers to 0
|
||||
" VMOV D0, R2,R2 \n"
|
||||
" VMOV D1, R2,R2 \n"
|
||||
" VMOV D2, R2,R2 \n"
|
||||
" VMOV D3, R2,R2 \n"
|
||||
" VMOV D4, R2,R2 \n"
|
||||
" VMOV D5, R2,R2 \n"
|
||||
" VMOV D6, R2,R2 \n"
|
||||
" VMOV D7, R2,R2 \n"
|
||||
" VMOV D8, R2,R2 \n"
|
||||
" VMOV D9, R2,R2 \n"
|
||||
" VMOV D10,R2,R2 \n"
|
||||
" VMOV D11,R2,R2 \n"
|
||||
" VMOV D12,R2,R2 \n"
|
||||
" VMOV D13,R2,R2 \n"
|
||||
" VMOV D14,R2,R2 \n"
|
||||
" VMOV D15,R2,R2 \n"
|
||||
".endif \n"
|
||||
|
||||
".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 \n"
|
||||
//Initialise D32 registers to 0
|
||||
" VMOV D16,R2,R2 \n"
|
||||
" VMOV D17,R2,R2 \n"
|
||||
" VMOV D18,R2,R2 \n"
|
||||
" VMOV D19,R2,R2 \n"
|
||||
" VMOV D20,R2,R2 \n"
|
||||
" VMOV D21,R2,R2 \n"
|
||||
" VMOV D22,R2,R2 \n"
|
||||
" VMOV D23,R2,R2 \n"
|
||||
" VMOV D24,R2,R2 \n"
|
||||
" VMOV D25,R2,R2 \n"
|
||||
" VMOV D26,R2,R2 \n"
|
||||
" VMOV D27,R2,R2 \n"
|
||||
" VMOV D28,R2,R2 \n"
|
||||
" VMOV D29,R2,R2 \n"
|
||||
" VMOV D30,R2,R2 \n"
|
||||
" VMOV D31,R2,R2 \n"
|
||||
".endif \n"
|
||||
#endif
|
||||
//Initialise FPSCR to a known state
|
||||
" VMRS R2,FPSCR \n"
|
||||
" LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
" AND R2,R2,R3 \n"
|
||||
" VMSR FPSCR,R2 "
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
||||
211
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/cmsis_compiler.h
Normal file
211
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/cmsis_compiler.h
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.00
|
||||
* @date 22. Feb 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* 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 __CMSIS_COMPILER_H
|
||||
#define __CMSIS_COMPILER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* ARM Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* ARM Compiler 6 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#include "cmsis_armclang.h"
|
||||
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __noreturn
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __root
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
__packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TI ARM Compiler
|
||||
*/
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TASKING Compiler
|
||||
*/
|
||||
#elif defined ( __TASKING__ )
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
struct __packed__ T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __align(x)
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed__
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* COSMIC Compiler
|
||||
*/
|
||||
#elif defined ( __CSMC__ )
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM _asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
// NO RETURN is automatically detected hence no warning here
|
||||
#define __NO_RETURN
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#warning No compiler specific solution for __USED. __USED is ignored.
|
||||
#define __USED
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
@packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED @packed
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
||||
276
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_ca9.h
Normal file
276
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_ca9.h
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_ca9.h
|
||||
* @brief CMSIS Cortex-A9 Core Peripheral Access Layer Header File
|
||||
* @version
|
||||
* @date 25 March 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CA9_H_GENERIC
|
||||
#define __CORE_CA9_H_GENERIC
|
||||
|
||||
|
||||
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/** \ingroup Cortex_A9
|
||||
@{
|
||||
*/
|
||||
|
||||
/* CMSIS CA9 definitions */
|
||||
#define __CA9_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CA9_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CA9_CMSIS_VERSION ((__CA9_CMSIS_VERSION_MAIN << 16) | \
|
||||
__CA9_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_A (0x09) /*!< Cortex-A Core */
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||
#define __STATIC_INLINE static __inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#include <stdint.h>
|
||||
inline uint32_t __get_PSR(void) {
|
||||
__ASM("mrs r0, cpsr");
|
||||
}
|
||||
|
||||
#elif defined ( __TMS470__ )
|
||||
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#endif
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __TMS470__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h> /*!< standard types definitions */
|
||||
#include "core_caInstr.h" /*!< Core Instruction Access */
|
||||
#include "core_caFunc.h" /*!< Core Function Access */
|
||||
#include "core_cm4_simd.h" /*!< Compiler specific SIMD Intrinsics */
|
||||
|
||||
#endif /* __CORE_CA9_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CA9_H_DEPENDANT
|
||||
#define __CORE_CA9_H_DEPENDANT
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CA9_REV
|
||||
#define __CA9_REV 0x0000
|
||||
#warning "__CA9_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __FPU_PRESENT
|
||||
#define __FPU_PRESENT 1
|
||||
#warning "__FPU_PRESENT not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 1
|
||||
#endif
|
||||
|
||||
#if __Vendor_SysTickConfig == 0
|
||||
#error "__Vendor_SysTickConfig set to 0, but vendor systick timer must be supplied for Cortex-A9"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/*@} end of group Cortex_A9 */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
******************************************************************************/
|
||||
/** \defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-A processor based devices.
|
||||
*/
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
|
||||
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
|
||||
uint32_t reserved1:7; /*!< bit: 20..23 Reserved */
|
||||
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
/*@} end of CMSIS_Core_FPUFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CA9_H_GENERIC */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
1444
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_caFunc.h
Normal file
1444
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_caFunc.h
Normal file
File diff suppressed because it is too large
Load diff
45
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_caInstr.h
Normal file
45
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_caInstr.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_caInstr.h
|
||||
* @brief CMSIS Cortex-A9 Core Peripheral Access Layer Header File
|
||||
* @version
|
||||
* @date 04. December 2012
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __CORE_CAINSTR_H__
|
||||
#define __CORE_CAINSTR_H__
|
||||
|
||||
#define __CORTEX_M 0x3
|
||||
#include "core_cmInstr.h"
|
||||
#undef __CORTEX_M
|
||||
|
||||
#endif
|
||||
|
||||
847
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_ca_mmu.h
Normal file
847
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_ca_mmu.h
Normal file
|
|
@ -0,0 +1,847 @@
|
|||
;/**************************************************************************//**
|
||||
; * @file core_ca_mmu.h
|
||||
; * @brief MMU Startup File for A9_MP Device Series
|
||||
; * @version V1.01
|
||||
; * @date 10 Sept 2014
|
||||
; *
|
||||
; * @note
|
||||
; *
|
||||
; ******************************************************************************/
|
||||
;/* Copyright (c) 2012-2014 ARM LIMITED
|
||||
;
|
||||
; All rights reserved.
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; - Neither the name of ARM nor the names of its contributors may be used
|
||||
; to endorse or promote products derived from this software without
|
||||
; specific prior written permission.
|
||||
; *
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
; POSSIBILITY OF SUCH DAMAGE.
|
||||
; ---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _MMU_FUNC_H
|
||||
#define _MMU_FUNC_H
|
||||
|
||||
#define SECTION_DESCRIPTOR (0x2)
|
||||
#define SECTION_MASK (0xFFFFFFFC)
|
||||
|
||||
#define SECTION_TEXCB_MASK (0xFFFF8FF3)
|
||||
#define SECTION_B_SHIFT (2)
|
||||
#define SECTION_C_SHIFT (3)
|
||||
#define SECTION_TEX0_SHIFT (12)
|
||||
#define SECTION_TEX1_SHIFT (13)
|
||||
#define SECTION_TEX2_SHIFT (14)
|
||||
|
||||
#define SECTION_XN_MASK (0xFFFFFFEF)
|
||||
#define SECTION_XN_SHIFT (4)
|
||||
|
||||
#define SECTION_DOMAIN_MASK (0xFFFFFE1F)
|
||||
#define SECTION_DOMAIN_SHIFT (5)
|
||||
|
||||
#define SECTION_P_MASK (0xFFFFFDFF)
|
||||
#define SECTION_P_SHIFT (9)
|
||||
|
||||
#define SECTION_AP_MASK (0xFFFF73FF)
|
||||
#define SECTION_AP_SHIFT (10)
|
||||
#define SECTION_AP2_SHIFT (15)
|
||||
|
||||
#define SECTION_S_MASK (0xFFFEFFFF)
|
||||
#define SECTION_S_SHIFT (16)
|
||||
|
||||
#define SECTION_NG_MASK (0xFFFDFFFF)
|
||||
#define SECTION_NG_SHIFT (17)
|
||||
|
||||
#define SECTION_NS_MASK (0xFFF7FFFF)
|
||||
#define SECTION_NS_SHIFT (19)
|
||||
|
||||
|
||||
#define PAGE_L1_DESCRIPTOR (0x1)
|
||||
#define PAGE_L1_MASK (0xFFFFFFFC)
|
||||
|
||||
#define PAGE_L2_4K_DESC (0x2)
|
||||
#define PAGE_L2_4K_MASK (0xFFFFFFFD)
|
||||
|
||||
#define PAGE_L2_64K_DESC (0x1)
|
||||
#define PAGE_L2_64K_MASK (0xFFFFFFFC)
|
||||
|
||||
#define PAGE_4K_TEXCB_MASK (0xFFFFFE33)
|
||||
#define PAGE_4K_B_SHIFT (2)
|
||||
#define PAGE_4K_C_SHIFT (3)
|
||||
#define PAGE_4K_TEX0_SHIFT (6)
|
||||
#define PAGE_4K_TEX1_SHIFT (7)
|
||||
#define PAGE_4K_TEX2_SHIFT (8)
|
||||
|
||||
#define PAGE_64K_TEXCB_MASK (0xFFFF8FF3)
|
||||
#define PAGE_64K_B_SHIFT (2)
|
||||
#define PAGE_64K_C_SHIFT (3)
|
||||
#define PAGE_64K_TEX0_SHIFT (12)
|
||||
#define PAGE_64K_TEX1_SHIFT (13)
|
||||
#define PAGE_64K_TEX2_SHIFT (14)
|
||||
|
||||
#define PAGE_TEXCB_MASK (0xFFFF8FF3)
|
||||
#define PAGE_B_SHIFT (2)
|
||||
#define PAGE_C_SHIFT (3)
|
||||
#define PAGE_TEX_SHIFT (12)
|
||||
|
||||
#define PAGE_XN_4K_MASK (0xFFFFFFFE)
|
||||
#define PAGE_XN_4K_SHIFT (0)
|
||||
#define PAGE_XN_64K_MASK (0xFFFF7FFF)
|
||||
#define PAGE_XN_64K_SHIFT (15)
|
||||
|
||||
|
||||
#define PAGE_DOMAIN_MASK (0xFFFFFE1F)
|
||||
#define PAGE_DOMAIN_SHIFT (5)
|
||||
|
||||
#define PAGE_P_MASK (0xFFFFFDFF)
|
||||
#define PAGE_P_SHIFT (9)
|
||||
|
||||
#define PAGE_AP_MASK (0xFFFFFDCF)
|
||||
#define PAGE_AP_SHIFT (4)
|
||||
#define PAGE_AP2_SHIFT (9)
|
||||
|
||||
#define PAGE_S_MASK (0xFFFFFBFF)
|
||||
#define PAGE_S_SHIFT (10)
|
||||
|
||||
#define PAGE_NG_MASK (0xFFFFF7FF)
|
||||
#define PAGE_NG_SHIFT (11)
|
||||
|
||||
#define PAGE_NS_MASK (0xFFFFFFF7)
|
||||
#define PAGE_NS_SHIFT (3)
|
||||
|
||||
#define OFFSET_1M (0x00100000)
|
||||
#define OFFSET_64K (0x00010000)
|
||||
#define OFFSET_4K (0x00001000)
|
||||
|
||||
#define DESCRIPTOR_FAULT (0x00000000)
|
||||
|
||||
/* ########################### MMU Function Access ########################### */
|
||||
/** \ingroup MMU_FunctionInterface
|
||||
\defgroup MMU_Functions MMU Functions Interface
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Attributes enumerations */
|
||||
|
||||
/* Region size attributes */
|
||||
typedef enum
|
||||
{
|
||||
SECTION,
|
||||
PAGE_4k,
|
||||
PAGE_64k,
|
||||
} mmu_region_size_Type;
|
||||
|
||||
/* Region type attributes */
|
||||
typedef enum
|
||||
{
|
||||
NORMAL,
|
||||
DEVICE,
|
||||
SHARED_DEVICE,
|
||||
NON_SHARED_DEVICE,
|
||||
STRONGLY_ORDERED
|
||||
} mmu_memory_Type;
|
||||
|
||||
/* Region cacheability attributes */
|
||||
typedef enum
|
||||
{
|
||||
NON_CACHEABLE,
|
||||
WB_WA,
|
||||
WT,
|
||||
WB_NO_WA,
|
||||
} mmu_cacheability_Type;
|
||||
|
||||
/* Region parity check attributes */
|
||||
typedef enum
|
||||
{
|
||||
ECC_DISABLED,
|
||||
ECC_ENABLED,
|
||||
} mmu_ecc_check_Type;
|
||||
|
||||
/* Region execution attributes */
|
||||
typedef enum
|
||||
{
|
||||
EXECUTE,
|
||||
NON_EXECUTE,
|
||||
} mmu_execute_Type;
|
||||
|
||||
/* Region global attributes */
|
||||
typedef enum
|
||||
{
|
||||
GLOBAL,
|
||||
NON_GLOBAL,
|
||||
} mmu_global_Type;
|
||||
|
||||
/* Region shareability attributes */
|
||||
typedef enum
|
||||
{
|
||||
NON_SHARED,
|
||||
SHARED,
|
||||
} mmu_shared_Type;
|
||||
|
||||
/* Region security attributes */
|
||||
typedef enum
|
||||
{
|
||||
SECURE,
|
||||
NON_SECURE,
|
||||
} mmu_secure_Type;
|
||||
|
||||
/* Region access attributes */
|
||||
typedef enum
|
||||
{
|
||||
NO_ACCESS,
|
||||
RW,
|
||||
READ,
|
||||
} mmu_access_Type;
|
||||
|
||||
/* Memory Region definition */
|
||||
typedef struct RegionStruct {
|
||||
mmu_region_size_Type rg_t;
|
||||
mmu_memory_Type mem_t;
|
||||
uint8_t domain;
|
||||
mmu_cacheability_Type inner_norm_t;
|
||||
mmu_cacheability_Type outer_norm_t;
|
||||
mmu_ecc_check_Type e_t;
|
||||
mmu_execute_Type xn_t;
|
||||
mmu_global_Type g_t;
|
||||
mmu_secure_Type sec_t;
|
||||
mmu_access_Type priv_t;
|
||||
mmu_access_Type user_t;
|
||||
mmu_shared_Type sh_t;
|
||||
|
||||
} mmu_region_attributes_Type;
|
||||
|
||||
/** \brief Set section execution-never attribute
|
||||
|
||||
The function sets section execution-never attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE.
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __xn_section(uint32_t *descriptor_l1, mmu_execute_Type xn)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_XN_MASK;
|
||||
*descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section domain
|
||||
|
||||
The function sets section domain
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] domain Section domain
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __domain_section(uint32_t *descriptor_l1, uint8_t domain)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_DOMAIN_MASK;
|
||||
*descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section parity check
|
||||
|
||||
The function sets section parity check
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __p_section(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_P_MASK;
|
||||
*descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section access privileges
|
||||
|
||||
The function sets section access privileges
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] user User Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] priv Privilege Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] afe Access flag enable
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __ap_section(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe)
|
||||
{
|
||||
uint32_t ap = 0;
|
||||
|
||||
if (afe == 0) { //full access
|
||||
if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
|
||||
else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == READ)) { ap = 0x2; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x7; }
|
||||
}
|
||||
|
||||
else { //Simplified access
|
||||
if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x7; }
|
||||
}
|
||||
|
||||
*descriptor_l1 &= SECTION_AP_MASK;
|
||||
*descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT;
|
||||
*descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section shareability
|
||||
|
||||
The function sets section shareability
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] s_bit Section shareability: NON_SHARED, SHARED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __shared_section(uint32_t *descriptor_l1, mmu_shared_Type s_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_S_MASK;
|
||||
*descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section Global attribute
|
||||
|
||||
The function sets section Global attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __global_section(uint32_t *descriptor_l1, mmu_global_Type g_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_NG_MASK;
|
||||
*descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section Security attribute
|
||||
|
||||
The function sets section Global attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] s_bit Section Security attribute: SECURE, NON_SECURE
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __secure_section(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_NS_MASK;
|
||||
*descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Page 4k or 64k */
|
||||
/** \brief Set 4k/64k page execution-never attribute
|
||||
|
||||
The function sets 4k/64k page execution-never attribute
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE.
|
||||
\param [in] page Page size: PAGE_4k, PAGE_64k,
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __xn_page(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page)
|
||||
{
|
||||
if (page == PAGE_4k)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_XN_4K_MASK;
|
||||
*descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
*descriptor_l2 &= PAGE_XN_64K_MASK;
|
||||
*descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page domain
|
||||
|
||||
The function sets 4k/64k page domain
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] domain Page domain
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __domain_page(uint32_t *descriptor_l1, uint8_t domain)
|
||||
{
|
||||
*descriptor_l1 &= PAGE_DOMAIN_MASK;
|
||||
*descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page parity check
|
||||
|
||||
The function sets 4k/64k page parity check
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __p_page(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_P_MASK;
|
||||
*descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page access privileges
|
||||
|
||||
The function sets 4k/64k page access privileges
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] user User Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] priv Privilege Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] afe Access flag enable
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __ap_page(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe)
|
||||
{
|
||||
uint32_t ap = 0;
|
||||
|
||||
if (afe == 0) { //full access
|
||||
if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
|
||||
else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == READ)) { ap = 0x2; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x6; }
|
||||
}
|
||||
|
||||
else { //Simplified access
|
||||
if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x7; }
|
||||
}
|
||||
|
||||
*descriptor_l2 &= PAGE_AP_MASK;
|
||||
*descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT;
|
||||
*descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page shareability
|
||||
|
||||
The function sets 4k/64k page shareability
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __shared_page(uint32_t *descriptor_l2, mmu_shared_Type s_bit)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_S_MASK;
|
||||
*descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page Global attribute
|
||||
|
||||
The function sets 4k/64k page Global attribute
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __global_page(uint32_t *descriptor_l2, mmu_global_Type g_bit)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_NG_MASK;
|
||||
*descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page Security attribute
|
||||
|
||||
The function sets 4k/64k page Global attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __secure_page(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
|
||||
{
|
||||
*descriptor_l1 &= PAGE_NS_MASK;
|
||||
*descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Section memory attributes
|
||||
|
||||
The function sets section memory attributes
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
|
||||
\param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
\param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __memory_section(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_TEXCB_MASK;
|
||||
|
||||
if (STRONGLY_ORDERED == mem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l1 |= (1 << SECTION_B_SHIFT);
|
||||
}
|
||||
else if (NON_SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l1 |= (1 << SECTION_TEX1_SHIFT);
|
||||
}
|
||||
else if (NORMAL == mem)
|
||||
{
|
||||
*descriptor_l1 |= 1 << SECTION_TEX2_SHIFT;
|
||||
switch(inner)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_B_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l1 |= 1 << SECTION_C_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT);
|
||||
break;
|
||||
}
|
||||
switch(outer)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_TEX0_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l1 |= 1 << SECTION_TEX1_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page memory attributes
|
||||
|
||||
The function sets 4k/64k page memory attributes
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
|
||||
\param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
\param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __memory_page(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_4K_TEXCB_MASK;
|
||||
|
||||
if (page == PAGE_64k)
|
||||
{
|
||||
//same as section
|
||||
__memory_section(descriptor_l2, mem, outer, inner);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (STRONGLY_ORDERED == mem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
|
||||
}
|
||||
else if (NON_SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT);
|
||||
}
|
||||
else if (NORMAL == mem)
|
||||
{
|
||||
*descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT;
|
||||
switch(inner)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l2 |= 1 << PAGE_4K_C_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT);
|
||||
break;
|
||||
}
|
||||
switch(outer)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Create a L1 section descriptor
|
||||
|
||||
The function creates a section descriptor.
|
||||
|
||||
Assumptions:
|
||||
- 16MB super sections not supported
|
||||
- TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
|
||||
- Functions always return 0
|
||||
|
||||
\param [out] descriptor L1 descriptor
|
||||
\param [out] descriptor2 L2 descriptor
|
||||
\param [in] reg Section attributes
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __get_section_descriptor(uint32_t *descriptor, mmu_region_attributes_Type reg)
|
||||
{
|
||||
*descriptor = 0;
|
||||
|
||||
__memory_section(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t);
|
||||
__xn_section(descriptor,reg.xn_t);
|
||||
__domain_section(descriptor, reg.domain);
|
||||
__p_section(descriptor, reg.e_t);
|
||||
__ap_section(descriptor, reg.priv_t, reg.user_t, 1);
|
||||
__shared_section(descriptor,reg.sh_t);
|
||||
__global_section(descriptor,reg.g_t);
|
||||
__secure_section(descriptor,reg.sec_t);
|
||||
*descriptor &= SECTION_MASK;
|
||||
*descriptor |= SECTION_DESCRIPTOR;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** \brief Create a L1 and L2 4k/64k page descriptor
|
||||
|
||||
The function creates a 4k/64k page descriptor.
|
||||
Assumptions:
|
||||
- TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
|
||||
- Functions always return 0
|
||||
|
||||
\param [out] descriptor L1 descriptor
|
||||
\param [out] descriptor2 L2 descriptor
|
||||
\param [in] reg 4k/64k page attributes
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __get_page_descriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg)
|
||||
{
|
||||
*descriptor = 0;
|
||||
*descriptor2 = 0;
|
||||
|
||||
switch (reg.rg_t)
|
||||
{
|
||||
case PAGE_4k:
|
||||
__memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k);
|
||||
__xn_page(descriptor2, reg.xn_t, PAGE_4k);
|
||||
__domain_page(descriptor, reg.domain);
|
||||
__p_page(descriptor, reg.e_t);
|
||||
__ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
|
||||
__shared_page(descriptor2,reg.sh_t);
|
||||
__global_page(descriptor2,reg.g_t);
|
||||
__secure_page(descriptor,reg.sec_t);
|
||||
*descriptor &= PAGE_L1_MASK;
|
||||
*descriptor |= PAGE_L1_DESCRIPTOR;
|
||||
*descriptor2 &= PAGE_L2_4K_MASK;
|
||||
*descriptor2 |= PAGE_L2_4K_DESC;
|
||||
break;
|
||||
|
||||
case PAGE_64k:
|
||||
__memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k);
|
||||
__xn_page(descriptor2, reg.xn_t, PAGE_64k);
|
||||
__domain_page(descriptor, reg.domain);
|
||||
__p_page(descriptor, reg.e_t);
|
||||
__ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
|
||||
__shared_page(descriptor2,reg.sh_t);
|
||||
__global_page(descriptor2,reg.g_t);
|
||||
__secure_page(descriptor,reg.sec_t);
|
||||
*descriptor &= PAGE_L1_MASK;
|
||||
*descriptor |= PAGE_L1_DESCRIPTOR;
|
||||
*descriptor2 &= PAGE_L2_64K_MASK;
|
||||
*descriptor2 |= PAGE_L2_64K_DESC;
|
||||
break;
|
||||
|
||||
case SECTION:
|
||||
//error
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/** \brief Create a 1MB Section
|
||||
|
||||
\param [in] ttb Translation table base address
|
||||
\param [in] base_address Section base address
|
||||
\param [in] count Number of sections to create
|
||||
\param [in] descriptor_l1 L1 descriptor (region attributes)
|
||||
|
||||
*/
|
||||
__STATIC_INLINE void __TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1)
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t entry;
|
||||
uint32_t i;
|
||||
|
||||
offset = base_address >> 20;
|
||||
entry = (base_address & 0xFFF00000) | descriptor_l1;
|
||||
|
||||
//4 bytes aligned
|
||||
ttb = ttb + offset;
|
||||
|
||||
for (i = 0; i < count; i++ )
|
||||
{
|
||||
//4 bytes aligned
|
||||
*ttb++ = entry;
|
||||
entry += OFFSET_1M;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Create a 4k page entry
|
||||
|
||||
\param [in] ttb L1 table base address
|
||||
\param [in] base_address 4k base address
|
||||
\param [in] count Number of 4k pages to create
|
||||
\param [in] descriptor_l1 L1 descriptor (region attributes)
|
||||
\param [in] ttb_l2 L2 table base address
|
||||
\param [in] descriptor_l2 L2 descriptor (region attributes)
|
||||
|
||||
*/
|
||||
__STATIC_INLINE void __TTPage_4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
|
||||
{
|
||||
|
||||
uint32_t offset, offset2;
|
||||
uint32_t entry, entry2;
|
||||
uint32_t i;
|
||||
|
||||
|
||||
offset = base_address >> 20;
|
||||
entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
|
||||
|
||||
//4 bytes aligned
|
||||
ttb += offset;
|
||||
//create l1_entry
|
||||
*ttb = entry;
|
||||
|
||||
offset2 = (base_address & 0xff000) >> 12;
|
||||
ttb_l2 += offset2;
|
||||
entry2 = (base_address & 0xFFFFF000) | descriptor_l2;
|
||||
for (i = 0; i < count; i++ )
|
||||
{
|
||||
//4 bytes aligned
|
||||
*ttb_l2++ = entry2;
|
||||
entry2 += OFFSET_4K;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Create a 64k page entry
|
||||
|
||||
\param [in] ttb L1 table base address
|
||||
\param [in] base_address 64k base address
|
||||
\param [in] count Number of 64k pages to create
|
||||
\param [in] descriptor_l1 L1 descriptor (region attributes)
|
||||
\param [in] ttb_l2 L2 table base address
|
||||
\param [in] descriptor_l2 L2 descriptor (region attributes)
|
||||
|
||||
*/
|
||||
__STATIC_INLINE void __TTPage_64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
|
||||
{
|
||||
uint32_t offset, offset2;
|
||||
uint32_t entry, entry2;
|
||||
uint32_t i,j;
|
||||
|
||||
|
||||
offset = base_address >> 20;
|
||||
entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
|
||||
|
||||
//4 bytes aligned
|
||||
ttb += offset;
|
||||
//create l1_entry
|
||||
*ttb = entry;
|
||||
|
||||
offset2 = (base_address & 0xff000) >> 12;
|
||||
ttb_l2 += offset2;
|
||||
entry2 = (base_address & 0xFFFF0000) | descriptor_l2;
|
||||
for (i = 0; i < count; i++ )
|
||||
{
|
||||
//create 16 entries
|
||||
for (j = 0; j < 16; j++)
|
||||
//4 bytes aligned
|
||||
*ttb_l2++ = entry2;
|
||||
entry2 += OFFSET_64K;
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of MMU_Functions */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
673
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_cm4_simd.h
Normal file
673
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_cm4_simd.h
Normal file
|
|
@ -0,0 +1,673 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm4_simd.h
|
||||
* @brief CMSIS Cortex-M4 SIMD Header File
|
||||
* @version V3.20
|
||||
* @date 25. February 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM4_SIMD_H
|
||||
#define __CORE_CM4_SIMD_H
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* ################### Compiler specific Intrinsics ########################### */
|
||||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||
Access to dedicated SIMD instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#define __SADD8 __sadd8
|
||||
#define __QADD8 __qadd8
|
||||
#define __SHADD8 __shadd8
|
||||
#define __UADD8 __uadd8
|
||||
#define __UQADD8 __uqadd8
|
||||
#define __UHADD8 __uhadd8
|
||||
#define __SSUB8 __ssub8
|
||||
#define __QSUB8 __qsub8
|
||||
#define __SHSUB8 __shsub8
|
||||
#define __USUB8 __usub8
|
||||
#define __UQSUB8 __uqsub8
|
||||
#define __UHSUB8 __uhsub8
|
||||
#define __SADD16 __sadd16
|
||||
#define __QADD16 __qadd16
|
||||
#define __SHADD16 __shadd16
|
||||
#define __UADD16 __uadd16
|
||||
#define __UQADD16 __uqadd16
|
||||
#define __UHADD16 __uhadd16
|
||||
#define __SSUB16 __ssub16
|
||||
#define __QSUB16 __qsub16
|
||||
#define __SHSUB16 __shsub16
|
||||
#define __USUB16 __usub16
|
||||
#define __UQSUB16 __uqsub16
|
||||
#define __UHSUB16 __uhsub16
|
||||
#define __SASX __sasx
|
||||
#define __QASX __qasx
|
||||
#define __SHASX __shasx
|
||||
#define __UASX __uasx
|
||||
#define __UQASX __uqasx
|
||||
#define __UHASX __uhasx
|
||||
#define __SSAX __ssax
|
||||
#define __QSAX __qsax
|
||||
#define __SHSAX __shsax
|
||||
#define __USAX __usax
|
||||
#define __UQSAX __uqsax
|
||||
#define __UHSAX __uhsax
|
||||
#define __USAD8 __usad8
|
||||
#define __USADA8 __usada8
|
||||
#define __SSAT16 __ssat16
|
||||
#define __USAT16 __usat16
|
||||
#define __UXTB16 __uxtb16
|
||||
#define __UXTAB16 __uxtab16
|
||||
#define __SXTB16 __sxtb16
|
||||
#define __SXTAB16 __sxtab16
|
||||
#define __SMUAD __smuad
|
||||
#define __SMUADX __smuadx
|
||||
#define __SMLAD __smlad
|
||||
#define __SMLADX __smladx
|
||||
#define __SMLALD __smlald
|
||||
#define __SMLALDX __smlaldx
|
||||
#define __SMUSD __smusd
|
||||
#define __SMUSDX __smusdx
|
||||
#define __SMLSD __smlsd
|
||||
#define __SMLSDX __smlsdx
|
||||
#define __SMLSLD __smlsld
|
||||
#define __SMLSLDX __smlsldx
|
||||
#define __SEL __sel
|
||||
#define __QADD __qadd
|
||||
#define __QSUB __qsub
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||
|
||||
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||
((int64_t)(ARG3) << 32) ) >> 32))
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SSAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __USAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLALD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLALDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLSLD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLSLDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
if (ARG3 == 0) \
|
||||
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||
else \
|
||||
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
/* not yet supported */
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||
|
||||
|
||||
#endif /* __CORE_CM4_SIMD_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
916
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_cmInstr.h
Normal file
916
NPR_14/mbed-os/cmsis/TARGET_CORTEX_A/core_cmInstr.h
Normal file
|
|
@ -0,0 +1,916 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V4.10
|
||||
* @date 18. March 2015
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2014 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0)
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0)
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0)
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
#define __RBIT __rbit
|
||||
#else
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||
|
||||
result = value; // r will be reversed bits of v; first get LSB of v
|
||||
for (value >>= 1; value; value >>= 1)
|
||||
{
|
||||
result <<= 1;
|
||||
result |= value & 1;
|
||||
s--;
|
||||
}
|
||||
result <<= s; // shift when v's highest bits are zero
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/** \brief Rotate Right with Extend (32 bit)
|
||||
|
||||
This function moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
rrx r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRT(value, ptr) __strt(value, ptr)
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/* Define macros for porting to both thumb1 and thumb2.
|
||||
* For thumb1, use low register (r0-r7), specified by constrant "l"
|
||||
* Otherwise, use general registers, specified by constrant "r" */
|
||||
#if defined (__thumb__) && !defined (__thumb2__)
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||
#else
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||
#endif
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
return __builtin_bswap32(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
return (short)__builtin_bswap16(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << (32 - op2));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
#else
|
||||
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||
|
||||
result = value; // r will be reversed bits of v; first get LSB of v
|
||||
for (value >>= 1; value; value >>= 1)
|
||||
{
|
||||
result <<= 1;
|
||||
result |= value & 1;
|
||||
s--;
|
||||
}
|
||||
result <<= s; // shift when v's highest bits are zero
|
||||
#endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __builtin_clz
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex" ::: "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Rotate Right with Extend (32 bit)
|
||||
|
||||
This function moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
__ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
__ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
__ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
|
||||
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||
/* Cosmic specific functions */
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
||||
809
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h
Normal file
809
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armcc.h
Normal file
|
|
@ -0,0 +1,809 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_armcc.h
|
||||
* @brief CMSIS compiler ARMCC (ARM compiler V5) header file
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* 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 __CMSIS_ARMCC_H
|
||||
#define __CMSIS_ARMCC_H
|
||||
|
||||
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler control architecture macros */
|
||||
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
|
||||
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#endif
|
||||
|
||||
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
|
||||
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#endif
|
||||
|
||||
/* __ARM_ARCH_8M_BASE__ not applicable */
|
||||
/* __ARM_ARCH_8M_MAIN__ not applicable */
|
||||
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Enable IRQ Interrupts
|
||||
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
/* intrinsic void __enable_irq(); */
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable IRQ Interrupts
|
||||
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/**
|
||||
\brief Get Control Register
|
||||
\details Returns the content of the Control Register.
|
||||
\return Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Control Register
|
||||
\details Writes the given value to the Control Register.
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get IPSR Register
|
||||
\details Returns the content of the IPSR Register.
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get APSR Register
|
||||
\details Returns the content of the APSR Register.
|
||||
\return APSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get xPSR Register
|
||||
\details Returns the content of the xPSR Register.
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Process Stack Pointer
|
||||
\details Returns the current value of the Process Stack Pointer (PSP).
|
||||
\return PSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Process Stack Pointer
|
||||
\details Assigns the given value to the Process Stack Pointer (PSP).
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Main Stack Pointer
|
||||
\details Returns the current value of the Main Stack Pointer (MSP).
|
||||
\return MSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Main Stack Pointer
|
||||
\details Assigns the given value to the Main Stack Pointer (MSP).
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Priority Mask
|
||||
\details Returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Priority Mask
|
||||
\details Assigns the given value to the Priority Mask Register.
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief Enable FIQ
|
||||
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable FIQ
|
||||
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Base Priority
|
||||
\details Returns the current value of the Base Priority register.
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Base Priority
|
||||
\details Assigns the given value to the Base Priority register.
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xFFU);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Base Priority with condition
|
||||
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||
or the new value increases the BASEPRI priority level.
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePriMax __ASM("basepri_max");
|
||||
__regBasePriMax = (basePri & 0xFFU);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Fault Mask
|
||||
\details Returns the current value of the Fault Mask register.
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Fault Mask
|
||||
\details Assigns the given value to the Fault Mask register.
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1U);
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
|
||||
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief No Operation
|
||||
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
\details Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or memory,
|
||||
after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
\details Acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
\details Ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in integer value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in two unsigned short values.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order in signed short value
|
||||
\details Reverses the byte order in a signed short value with sign extension to integer.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\details Causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\details Reverses the bit order of the given value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
#define __RBIT __rbit
|
||||
#else
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\details Counts the number of leading zeros of a data value.
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/**
|
||||
\brief Rotate Right with Extend (32 bit)
|
||||
\details Moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
\param [in] value Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
rrx r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRT(value, ptr) __strt(value, ptr)
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
|
||||
/* ################### Compiler specific Intrinsics ########################### */
|
||||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||
Access to dedicated SIMD instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
#define __SADD8 __sadd8
|
||||
#define __QADD8 __qadd8
|
||||
#define __SHADD8 __shadd8
|
||||
#define __UADD8 __uadd8
|
||||
#define __UQADD8 __uqadd8
|
||||
#define __UHADD8 __uhadd8
|
||||
#define __SSUB8 __ssub8
|
||||
#define __QSUB8 __qsub8
|
||||
#define __SHSUB8 __shsub8
|
||||
#define __USUB8 __usub8
|
||||
#define __UQSUB8 __uqsub8
|
||||
#define __UHSUB8 __uhsub8
|
||||
#define __SADD16 __sadd16
|
||||
#define __QADD16 __qadd16
|
||||
#define __SHADD16 __shadd16
|
||||
#define __UADD16 __uadd16
|
||||
#define __UQADD16 __uqadd16
|
||||
#define __UHADD16 __uhadd16
|
||||
#define __SSUB16 __ssub16
|
||||
#define __QSUB16 __qsub16
|
||||
#define __SHSUB16 __shsub16
|
||||
#define __USUB16 __usub16
|
||||
#define __UQSUB16 __uqsub16
|
||||
#define __UHSUB16 __uhsub16
|
||||
#define __SASX __sasx
|
||||
#define __QASX __qasx
|
||||
#define __SHASX __shasx
|
||||
#define __UASX __uasx
|
||||
#define __UQASX __uqasx
|
||||
#define __UHASX __uhasx
|
||||
#define __SSAX __ssax
|
||||
#define __QSAX __qsax
|
||||
#define __SHSAX __shsax
|
||||
#define __USAX __usax
|
||||
#define __UQSAX __uqsax
|
||||
#define __UHSAX __uhsax
|
||||
#define __USAD8 __usad8
|
||||
#define __USADA8 __usada8
|
||||
#define __SSAT16 __ssat16
|
||||
#define __USAT16 __usat16
|
||||
#define __UXTB16 __uxtb16
|
||||
#define __UXTAB16 __uxtab16
|
||||
#define __SXTB16 __sxtb16
|
||||
#define __SXTAB16 __sxtab16
|
||||
#define __SMUAD __smuad
|
||||
#define __SMUADX __smuadx
|
||||
#define __SMLAD __smlad
|
||||
#define __SMLADX __smladx
|
||||
#define __SMLALD __smlald
|
||||
#define __SMLALDX __smlaldx
|
||||
#define __SMUSD __smusd
|
||||
#define __SMUSDX __smusdx
|
||||
#define __SMLSD __smlsd
|
||||
#define __SMLSDX __smlsdx
|
||||
#define __SMLSLD __smlsld
|
||||
#define __SMLSLDX __smlsldx
|
||||
#define __SEL __sel
|
||||
#define __QADD __qadd
|
||||
#define __QSUB __qsub
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||
|
||||
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||
((int64_t)(ARG3) << 32U) ) >> 32U))
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
||||
1795
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h
Normal file
1795
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_ARM/cmsis_armclang.h
Normal file
File diff suppressed because it is too large
Load diff
1958
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h
Normal file
1958
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/TOOLCHAIN_GCC/cmsis_gcc.h
Normal file
File diff suppressed because it is too large
Load diff
315
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/cmsis_compiler.h
Normal file
315
NPR_14/mbed-os/cmsis/TARGET_CORTEX_M/cmsis_compiler.h
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler generic header file
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* 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 __CMSIS_COMPILER_H
|
||||
#define __CMSIS_COMPILER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* ARM Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* ARM Compiler 6 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#include "cmsis_armclang.h"
|
||||
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
/* CMSIS compiler control architecture macros */
|
||||
#if (__CORE__ == __ARM6M__) || (__CORE__ == __ARM6SM__)
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM7M__)
|
||||
#ifndef __ARM_ARCH_7M__
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM7EM__)
|
||||
#ifndef __ARM_ARCH_7EM__
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM8M_BASELINE__)
|
||||
#ifndef __ARM_ARCH_8M_BASE__
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM8M_MAINLINE__)
|
||||
#ifndef __ARM_ARCH_8M_MAIN__
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// IAR version 7.8.1 and earlier do not include __ALIGNED
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __noreturn
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __root
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
__packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TI ARM Compiler
|
||||
*/
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TASKING Compiler
|
||||
*/
|
||||
#elif defined ( __TASKING__ )
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __packed__
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __packed__ T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __align(x)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* COSMIC Compiler
|
||||
*/
|
||||
#elif defined ( __CSMC__ )
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM _asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
// NO RETURN is automatically detected hence no warning here
|
||||
#define __NO_RETURN
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#warning No compiler specific solution for __USED. __USED is ignored.
|
||||
#define __USED
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED @packed
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT @packed struct
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
@packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
||||
94
NPR_14/mbed-os/cmsis/TOOLCHAIN_GCC/TARGET_CORTEX_A/cache.S
Normal file
94
NPR_14/mbed-os/cmsis/TOOLCHAIN_GCC/TARGET_CORTEX_A/cache.S
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Functions
|
||||
*---------------------------------------------------------------------------*/
|
||||
.text
|
||||
.global __v7_all_cache
|
||||
/*
|
||||
* __STATIC_ASM void __v7_all_cache(uint32_t op) {
|
||||
*/
|
||||
__v7_all_cache:
|
||||
.arm
|
||||
|
||||
PUSH {R4-R11}
|
||||
|
||||
MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */
|
||||
ANDS R3, R6, #0x07000000 /* Extract coherency level */
|
||||
MOV R3, R3, LSR #23 /* Total cache levels << 1 */
|
||||
BEQ Finished /* If 0, no need to clean */
|
||||
|
||||
MOV R10, #0 /* R10 holds current cache level << 1 */
|
||||
Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */
|
||||
MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */
|
||||
AND R1, R1, #7 /* Isolate those lower 3 bits */
|
||||
CMP R1, #2
|
||||
BLT Skip /* No cache or only instruction cache at this level */
|
||||
|
||||
MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */
|
||||
ISB /* ISB to sync the change to the CacheSizeID reg */
|
||||
MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */
|
||||
AND R2, R1, #7 /* Extract the line length field */
|
||||
ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */
|
||||
LDR R4, =0x3FF
|
||||
ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */
|
||||
CLZ R5, R4 /* R5 is the bit position of the way size increment */
|
||||
LDR R7, =0x7FFF
|
||||
ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */
|
||||
|
||||
Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */
|
||||
|
||||
Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */
|
||||
ORR R11, R11, R7, LSL R2 /* Factor in the Set number */
|
||||
CMP R0, #0
|
||||
BNE Dccsw
|
||||
MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */
|
||||
B cont
|
||||
Dccsw: CMP R0, #1
|
||||
BNE Dccisw
|
||||
MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */
|
||||
B cont
|
||||
Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */
|
||||
cont: SUBS R9, R9, #1 /* Decrement the Way number */
|
||||
BGE Loop3
|
||||
SUBS R7, R7, #1 /* Decrement the Set number */
|
||||
BGE Loop2
|
||||
Skip: ADD R10, R10, #2 /* increment the cache number */
|
||||
CMP R3, R10
|
||||
BGT Loop1
|
||||
|
||||
Finished:
|
||||
DSB
|
||||
POP {R4-R11}
|
||||
BX lr
|
||||
|
||||
|
||||
.END
|
||||
/*----------------------------------------------------------------------------
|
||||
* end of file
|
||||
*---------------------------------------------------------------------------*/
|
||||
97
NPR_14/mbed-os/cmsis/TOOLCHAIN_IAR/TARGET_CORTEX_A/cache.S
Normal file
97
NPR_14/mbed-os/cmsis/TOOLCHAIN_IAR/TARGET_CORTEX_A/cache.S
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Functions
|
||||
*---------------------------------------------------------------------------*/
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
arm
|
||||
PUBLIC __v7_all_cache
|
||||
/*
|
||||
* __STATIC_ASM void __v7_all_cache(uint32_t op) {
|
||||
*/
|
||||
|
||||
__v7_all_cache:
|
||||
|
||||
|
||||
PUSH {R4-R11}
|
||||
|
||||
MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */
|
||||
ANDS R3, R6, #0x07000000 /* Extract coherency level */
|
||||
MOV R3, R3, LSR #23 /* Total cache levels << 1 */
|
||||
BEQ Finished /* If 0, no need to clean */
|
||||
|
||||
MOV R10, #0 /* R10 holds current cache level << 1 */
|
||||
Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */
|
||||
MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */
|
||||
AND R1, R1, #7 /* Isolate those lower 3 bits */
|
||||
CMP R1, #2
|
||||
BLT Skip /* No cache or only instruction cache at this level */
|
||||
|
||||
MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */
|
||||
ISB /* ISB to sync the change to the CacheSizeID reg */
|
||||
MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */
|
||||
AND R2, R1, #7 /* Extract the line length field */
|
||||
ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */
|
||||
LDR R4, =0x3FF
|
||||
ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */
|
||||
CLZ R5, R4 /* R5 is the bit position of the way size increment */
|
||||
LDR R7, =0x7FFF
|
||||
ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */
|
||||
|
||||
Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */
|
||||
|
||||
Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */
|
||||
ORR R11, R11, R7, LSL R2 /* Factor in the Set number */
|
||||
CMP R0, #0
|
||||
BNE Dccsw
|
||||
MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */
|
||||
B cont
|
||||
Dccsw: CMP R0, #1
|
||||
BNE Dccisw
|
||||
MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */
|
||||
B cont
|
||||
Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */
|
||||
cont: SUBS R9, R9, #1 /* Decrement the Way number */
|
||||
BGE Loop3
|
||||
SUBS R7, R7, #1 /* Decrement the Set number */
|
||||
BGE Loop2
|
||||
Skip: ADD R10, R10, #2 /* increment the cache number */
|
||||
CMP R3, R10
|
||||
BGT Loop1
|
||||
|
||||
Finished:
|
||||
DSB
|
||||
POP {R4-R11}
|
||||
BX lr
|
||||
|
||||
|
||||
END
|
||||
/*----------------------------------------------------------------------------
|
||||
* end of file
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
101
NPR_14/mbed-os/cmsis/TOOLCHAIN_IAR/cmain.S
Normal file
101
NPR_14/mbed-os/cmsis/TOOLCHAIN_IAR/cmain.S
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/**************************************************
|
||||
*
|
||||
* Part two of the system initialization code, contains C-level
|
||||
* initialization, thumb-2 only variant.
|
||||
*
|
||||
* $Revision: 59783 $
|
||||
*
|
||||
**************************************************/
|
||||
/* Copyright 2008-2017, IAR Systems AB.
|
||||
This source code is the property of IAR Systems. The source code may only
|
||||
be used together with the IAR Embedded Workbench. Redistribution and use
|
||||
in source and binary forms, with or without modification, is permitted
|
||||
provided that the following conditions are met:
|
||||
- Redistributions of source code, in whole or in part, must retain the
|
||||
above copyright notice, this list of conditions and the disclaimer below.
|
||||
- IAR Systems name may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
; --------------------------------------------------
|
||||
; Module ?cmain, C-level initialization.
|
||||
;
|
||||
|
||||
|
||||
SECTION SHT$$PREINIT_ARRAY:CONST:NOROOT(2)
|
||||
SECTION SHT$$INIT_ARRAY:CONST:NOROOT(2)
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
PUBLIC __cmain
|
||||
;; Keep ?main for legacy reasons, it is accessed in countless instances of cstartup.s around the world...
|
||||
PUBLIC ?main
|
||||
EXTWEAK __iar_data_init3
|
||||
EXTWEAK __iar_argc_argv
|
||||
EXTERN __low_level_init
|
||||
EXTERN __call_ctors
|
||||
EXTERN main
|
||||
EXTERN exit
|
||||
EXTERN __iar_dynamic_initialization
|
||||
EXTERN mbed_sdk_init
|
||||
EXTERN mbed_main
|
||||
EXTERN SystemInit
|
||||
|
||||
THUMB
|
||||
__cmain:
|
||||
?main:
|
||||
|
||||
; Initialize segments.
|
||||
; __segment_init and __low_level_init are assumed to use the same
|
||||
; instruction set and to be reachable by BL from the ICODE segment
|
||||
; (it is safest to link them in segment ICODE).
|
||||
|
||||
FUNCALL __cmain, __low_level_init
|
||||
bl __low_level_init
|
||||
cmp r0,#0
|
||||
beq ?l1
|
||||
FUNCALL __cmain, __iar_data_init3
|
||||
bl __iar_data_init3
|
||||
MOVS r0,#0 ; No parameters
|
||||
FUNCALL __cmain, mbed_sdk_init
|
||||
BL mbed_sdk_init
|
||||
MOVS r0,#0 ; No parameters
|
||||
FUNCALL __cmain, __iar_dynamic_initialization
|
||||
BL __iar_dynamic_initialization ; C++ dynamic initialization
|
||||
|
||||
?l1:
|
||||
REQUIRE ?l3
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
PUBLIC _main
|
||||
PUBLIC _call_main
|
||||
THUMB
|
||||
|
||||
__iar_init$$done: ; Copy initialization is done
|
||||
|
||||
?l3:
|
||||
_call_main:
|
||||
MOVS r0,#0 ; No parameters
|
||||
FUNCALL __cmain, __iar_argc_argv
|
||||
BL __iar_argc_argv ; Maybe setup command line
|
||||
|
||||
MOVS r0,#0 ; No parameters
|
||||
FUNCALL __cmain, mbed_main
|
||||
BL mbed_main
|
||||
|
||||
FUNCALL __cmain, main
|
||||
BL main
|
||||
_main:
|
||||
FUNCALL __cmain, exit
|
||||
BL exit
|
||||
|
||||
END
|
||||
7257
NPR_14/mbed-os/cmsis/arm_math.h
Normal file
7257
NPR_14/mbed-os/cmsis/arm_math.h
Normal file
File diff suppressed because it is too large
Load diff
1876
NPR_14/mbed-os/cmsis/core_armv8mbl.h
Normal file
1876
NPR_14/mbed-os/cmsis/core_armv8mbl.h
Normal file
File diff suppressed because it is too large
Load diff
2900
NPR_14/mbed-os/cmsis/core_armv8mml.h
Normal file
2900
NPR_14/mbed-os/cmsis/core_armv8mml.h
Normal file
File diff suppressed because it is too large
Load diff
2016
NPR_14/mbed-os/cmsis/core_ca.h
Normal file
2016
NPR_14/mbed-os/cmsis/core_ca.h
Normal file
File diff suppressed because it is too large
Load diff
886
NPR_14/mbed-os/cmsis/core_cm0.h
Normal file
886
NPR_14/mbed-os/cmsis/core_cm0.h
Normal file
|
|
@ -0,0 +1,886 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm0.h
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM0_H_GENERIC
|
||||
#define __CORE_CM0_H_GENERIC
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex_M0
|
||||
@{
|
||||
*/
|
||||
|
||||
/* CMSIS CM0 definitions */
|
||||
#define __CM0_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0U) /*!< Cortex-M Core */
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not.
|
||||
This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0U
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_PCS_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __CSMC__ )
|
||||
#if ( __CSMC__ & 0x400U)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM0_H_DEPENDANT
|
||||
#define __CORE_CM0_H_DEPENDANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM0_REV
|
||||
#define __CM0_REV 0x0000U
|
||||
#warning "__CM0_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2U
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0U
|
||||
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
/*@} end of group Cortex_M0 */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick Register
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
/* APSR Register Definitions */
|
||||
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||
|
||||
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||
|
||||
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||
|
||||
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IPSR_Type;
|
||||
|
||||
/* IPSR Register Definitions */
|
||||
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} xPSR_Type;
|
||||
|
||||
/* xPSR Register Definitions */
|
||||
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||
|
||||
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||
|
||||
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||
|
||||
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||
|
||||
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||
|
||||
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/* CONTROL Register Definitions */
|
||||
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||
\brief Type definitions for the NVIC Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31U];
|
||||
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31U];
|
||||
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31U];
|
||||
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31U];
|
||||
uint32_t RESERVED4[64U];
|
||||
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} end of group CMSIS_NVIC */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||
\brief Type definitions for the System Control Block Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control Block (SCB).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
uint32_t RESERVED0;
|
||||
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||
|
||||
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||
|
||||
/* SCB System Control Register Definitions */
|
||||
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||
|
||||
/* SCB Configuration Control Register Definitions */
|
||||
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||
\brief Type definitions for the System Timer Registers.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Timer (SysTick).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||
|
||||
/* SysTick Reload Register Definitions */
|
||||
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||
|
||||
/* SysTick Current Register Definitions */
|
||||
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||
|
||||
/* SysTick Calibration Register Definitions */
|
||||
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||
|
||||
/*@} end of group CMSIS_SysTick */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||
Therefore they are not covered by the Cortex-M0 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} end of group CMSIS_CoreDebug */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Mask and shift a bit field value for use in a register bit range.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted value.
|
||||
*/
|
||||
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/**
|
||||
\brief Mask and shift a register value to extract a bit filed value.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted bit field value.
|
||||
*/
|
||||
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
/*@} end of group CMSIS_core_bitfield */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_base Core Definitions
|
||||
\brief Definitions for base addresses, unions, and structures.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Memory mapping of Core Hardware */
|
||||
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||
|
||||
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick Functions
|
||||
- Core Register Access Functions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ########################## NVIC functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifdef CMSIS_NVIC_VIRTUAL
|
||||
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
/*#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping not available for Cortex-M0 */
|
||||
/*#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping not available for Cortex-M0 */
|
||||
#define NVIC_EnableIRQ __NVIC_EnableIRQ
|
||||
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
|
||||
#define NVIC_DisableIRQ __NVIC_DisableIRQ
|
||||
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
|
||||
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
|
||||
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
|
||||
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */
|
||||
#define NVIC_SetPriority __NVIC_SetPriority
|
||||
#define NVIC_GetPriority __NVIC_GetPriority
|
||||
#define NVIC_SystemReset __NVIC_SystemReset
|
||||
#endif /* CMSIS_NVIC_VIRTUAL */
|
||||
|
||||
#ifdef CMSIS_VECTAB_VIRTUAL
|
||||
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetVector __NVIC_SetVector
|
||||
#define NVIC_GetVector __NVIC_GetVector
|
||||
#endif /* (CMSIS_VECTAB_VIRTUAL) */
|
||||
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under ARMv6M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||
|
||||
|
||||
/**
|
||||
\brief Enable Interrupt
|
||||
\details Enables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Enable status
|
||||
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt is not enabled.
|
||||
\return 1 Interrupt is enabled.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable Interrupt
|
||||
\details Disables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Pending Interrupt
|
||||
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Pending Interrupt
|
||||
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clear Pending Interrupt
|
||||
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Priority
|
||||
\details Sets the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
\note The priority cannot be set for every processor exception.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Priority
|
||||
\details Reads the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Interrupt Priority.
|
||||
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Vector
|
||||
\details Sets an interrupt vector in SRAM based interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
Address 0 must be mapped to SRAM.
|
||||
\param [in] IRQn Interrupt number
|
||||
\param [in] vector Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Vector
|
||||
\details Reads an interrupt vector from interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief System Reset
|
||||
\details Initiates a system reset request to reset the MCU.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SystemReset(void)
|
||||
{
|
||||
__DSB(); /* Ensure all outstanding memory accesses included
|
||||
buffered write are completed before reset */
|
||||
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
|
||||
for(;;) /* wait until reset */
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_FpuFunctions FPU Functions
|
||||
\brief Function that provides FPU type.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief get FPU type
|
||||
\details returns the FPU type
|
||||
\returns
|
||||
- \b 0: No FPU
|
||||
- \b 1: Single precision FPU
|
||||
- \b 2: Double + Single precision FPU
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
|
||||
{
|
||||
return 0U; /* No FPU */
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_FpuFunctions */
|
||||
|
||||
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||
\brief Functions that configure the System.
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
|
||||
|
||||
/**
|
||||
\brief System Tick Configuration
|
||||
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||
{
|
||||
return (1UL); /* Reload value impossible */
|
||||
}
|
||||
|
||||
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||
return (0UL); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
||||
1012
NPR_14/mbed-os/cmsis/core_cm0plus.h
Normal file
1012
NPR_14/mbed-os/cmsis/core_cm0plus.h
Normal file
File diff suppressed because it is too large
Load diff
1876
NPR_14/mbed-os/cmsis/core_cm23.h
Normal file
1876
NPR_14/mbed-os/cmsis/core_cm23.h
Normal file
File diff suppressed because it is too large
Load diff
1919
NPR_14/mbed-os/cmsis/core_cm3.h
Normal file
1919
NPR_14/mbed-os/cmsis/core_cm3.h
Normal file
File diff suppressed because it is too large
Load diff
2896
NPR_14/mbed-os/cmsis/core_cm33.h
Normal file
2896
NPR_14/mbed-os/cmsis/core_cm33.h
Normal file
File diff suppressed because it is too large
Load diff
2103
NPR_14/mbed-os/cmsis/core_cm4.h
Normal file
2103
NPR_14/mbed-os/cmsis/core_cm4.h
Normal file
File diff suppressed because it is too large
Load diff
2646
NPR_14/mbed-os/cmsis/core_cm7.h
Normal file
2646
NPR_14/mbed-os/cmsis/core_cm7.h
Normal file
File diff suppressed because it is too large
Load diff
201
NPR_14/mbed-os/cmsis/core_cmSecureAccess.h
Normal file
201
NPR_14/mbed-os/cmsis/core_cmSecureAccess.h
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmSecureAccess.h
|
||||
* @brief CMSIS Cortex-M Core Secure Access Header File
|
||||
* @version XXX
|
||||
* @date 10. June 2016
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2016 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __CORE_CM_SECURE_ACCESS_H
|
||||
#define __CORE_CM_SECURE_ACCESS_H
|
||||
|
||||
|
||||
/* ########################### Core Secure Access ########################### */
|
||||
|
||||
#ifdef FEATURE_UVISOR
|
||||
#include "uvisor-lib/uvisor-lib.h"
|
||||
|
||||
/* Secure uVisor implementation. */
|
||||
|
||||
/** Set the value at the target address.
|
||||
*
|
||||
* Equivalent to: `*address = value`.
|
||||
* @param address[in] Target address
|
||||
* @param value[in] Value to write at the address location.
|
||||
*/
|
||||
#define SECURE_WRITE(address, value) \
|
||||
uvisor_write(public_box, UVISOR_RGW_SHARED, address, value, UVISOR_RGW_OP_WRITE, 0xFFFFFFFFUL)
|
||||
|
||||
/** Get the value at the target address.
|
||||
*
|
||||
* @param address[in] Target address
|
||||
* @returns The value `*address`.
|
||||
*/
|
||||
#define SECURE_READ(address) \
|
||||
uvisor_read(public_box, UVISOR_RGW_SHARED, address, UVISOR_RGW_OP_READ, 0xFFFFFFFFUL)
|
||||
|
||||
/** Get the selected bits at the target address.
|
||||
*
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
* @returns The value `*address & mask`.
|
||||
*/
|
||||
#define SECURE_BITS_GET(address, mask) \
|
||||
UVISOR_BITS_GET(public_box, UVISOR_RGW_SHARED, address, mask)
|
||||
|
||||
/** Check the selected bits at the target address.
|
||||
*
|
||||
* @param address[in] Address at which to check the bits
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
* @returns The value `((*address & mask) == mask)`.
|
||||
*/
|
||||
#define SECURE_BITS_CHECK(address, mask) \
|
||||
UVISOR_BITS_CHECK(public_box, UVISOR_RGW_SHARED, address, mask)
|
||||
|
||||
/** Set the selected bits to 1 at the target address.
|
||||
*
|
||||
* Equivalent to: `*address |= mask`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
*/
|
||||
#define SECURE_BITS_SET(address, mask) \
|
||||
UVISOR_BITS_SET(public_box, UVISOR_RGW_SHARED, address, mask)
|
||||
|
||||
/** Clear the selected bits at the target address.
|
||||
*
|
||||
* Equivalent to: `*address &= ~mask`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
*/
|
||||
#define SECURE_BITS_CLEAR(address, mask) \
|
||||
UVISOR_BITS_CLEAR(public_box, UVISOR_RGW_SHARED, address, mask)
|
||||
|
||||
/** Set the selected bits at the target address to the given value.
|
||||
*
|
||||
* Equivalent to: `*address = (*address & ~mask) | (value & mask)`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
* @param value[in] Value to write at the address location. Note: The value
|
||||
* must be already shifted to the correct bit position
|
||||
*/
|
||||
#define SECURE_BITS_SET_VALUE(address, mask, value) \
|
||||
UVISOR_BITS_SET_VALUE(public_box, UVISOR_RGW_SHARED, address, mask, value)
|
||||
|
||||
/** Toggle the selected bits at the target address.
|
||||
*
|
||||
* Equivalent to: `*address ^= mask`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
*/
|
||||
#define SECURE_BITS_TOGGLE(address, mask) \
|
||||
UVISOR_BITS_TOGGLE(public_box, UVISOR_RGW_SHARED, address, mask)
|
||||
|
||||
#else
|
||||
|
||||
/* Insecure fallback implementation. */
|
||||
|
||||
/** Set the value at the target address.
|
||||
*
|
||||
* Equivalent to: `*address = value`.
|
||||
* @param address[in] Target address
|
||||
* @param value[in] Value to write at the address location.
|
||||
*/
|
||||
#define SECURE_WRITE(address, value) \
|
||||
*(address) = (value)
|
||||
|
||||
/** Get the value at the target address.
|
||||
*
|
||||
* @param address[in] Target address
|
||||
* @returns The value `*address`.
|
||||
*/
|
||||
#define SECURE_READ(address) \
|
||||
(*(address))
|
||||
|
||||
/** Get the selected bits at the target address.
|
||||
*
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
* @returns The value `*address & mask`.
|
||||
*/
|
||||
#define SECURE_BITS_GET(address, mask) \
|
||||
(*(address) & (mask))
|
||||
|
||||
/** Check the selected bits at the target address.
|
||||
*
|
||||
* @param address[in] Address at which to check the bits
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
* @returns The value `((*address & mask) == mask)`.
|
||||
*/
|
||||
#define SECURE_BITS_CHECK(address, mask) \
|
||||
((*(address) & (mask)) == (mask))
|
||||
|
||||
/** Set the selected bits to 1 at the target address.
|
||||
*
|
||||
* Equivalent to: `*address |= mask`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
*/
|
||||
#define SECURE_BITS_SET(address, mask) \
|
||||
*(address) |= (mask)
|
||||
|
||||
/** Clear the selected bits at the target address.
|
||||
*
|
||||
* Equivalent to: `*address &= ~mask`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
*/
|
||||
#define SECURE_BITS_CLEAR(address, mask) \
|
||||
*(address) &= ~(mask)
|
||||
|
||||
/** Set the selected bits at the target address to the given value.
|
||||
*
|
||||
* Equivalent to: `*address = (*address & ~mask) | (value & mask)`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
* @param value[in] Value to write at the address location. Note: The value
|
||||
* must be already shifted to the correct bit position
|
||||
*/
|
||||
#define SECURE_BITS_SET_VALUE(address, mask, value) \
|
||||
*(address) = (*(address) & ~(mask)) | ((value) & (mask))
|
||||
|
||||
/** Toggle the selected bits at the target address.
|
||||
*
|
||||
* Equivalent to: `*address ^= mask`.
|
||||
* @param address[in] Target address
|
||||
* @param mask[in] Bits to select out of the target address
|
||||
*/
|
||||
#define SECURE_BITS_TOGGLE(address, mask) \
|
||||
*(address) ^= (mask)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM_SECURE_ACCESS_H */
|
||||
1014
NPR_14/mbed-os/cmsis/core_sc000.h
Normal file
1014
NPR_14/mbed-os/cmsis/core_sc000.h
Normal file
File diff suppressed because it is too large
Load diff
1901
NPR_14/mbed-os/cmsis/core_sc300.h
Normal file
1901
NPR_14/mbed-os/cmsis/core_sc300.h
Normal file
File diff suppressed because it is too large
Load diff
69
NPR_14/mbed-os/cmsis/tz_context.h
Normal file
69
NPR_14/mbed-os/cmsis/tz_context.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2016 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed 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
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* $Date: 21. September 2016
|
||||
* $Revision: V1.0
|
||||
*
|
||||
* Project: TrustZone for ARMv8-M
|
||||
* Title: Context Management for ARMv8-M TrustZone
|
||||
*
|
||||
* Version 1.0
|
||||
* Initial Release
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef TZ_CONTEXT_H
|
||||
#define TZ_CONTEXT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef TZ_MODULEID_T
|
||||
#define TZ_MODULEID_T
|
||||
/// \details Data type that identifies secure software modules called by a process.
|
||||
typedef uint32_t TZ_ModuleId_t;
|
||||
#endif
|
||||
|
||||
/// \details TZ Memory ID identifies an allocated memory slot.
|
||||
typedef uint32_t TZ_MemoryId_t;
|
||||
|
||||
/// Initialize secure context memory system
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_InitContextSystem_S (void);
|
||||
|
||||
/// Allocate context memory for calling secure software modules in TrustZone
|
||||
/// \param[in] module identifies software modules called from non-secure mode
|
||||
/// \return value != 0 id TrustZone memory slot identifier
|
||||
/// \return value 0 no memory available or internal error
|
||||
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
|
||||
|
||||
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Load secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Store secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
|
||||
|
||||
#endif // TZ_CONTEXT_H
|
||||
27
NPR_14/mbed-os/drivers/AnalogIn.cpp
Normal file
27
NPR_14/mbed-os/drivers/AnalogIn.cpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/AnalogIn.h"
|
||||
|
||||
#if DEVICE_ANALOGIN
|
||||
|
||||
namespace mbed {
|
||||
|
||||
SingletonPtr<PlatformMutex> AnalogIn::_mutex;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
130
NPR_14/mbed-os/drivers/AnalogIn.h
Normal file
130
NPR_14/mbed-os/drivers/AnalogIn.h
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_ANALOGIN_H
|
||||
#define MBED_ANALOGIN_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_ANALOGIN) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/analogin_api.h"
|
||||
#include "platform/SingletonPtr.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** An analog input, used for reading the voltage on a pin
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Print messages when the AnalogIn is greater than 50%
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* AnalogIn temperature(p20);
|
||||
*
|
||||
* int main() {
|
||||
* while(1) {
|
||||
* if(temperature > 0.5) {
|
||||
* printf("Too hot! (%f)", temperature.read());
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class AnalogIn {
|
||||
|
||||
public:
|
||||
|
||||
/** Create an AnalogIn, connected to the specified pin
|
||||
*
|
||||
* @param pin AnalogIn pin to connect to
|
||||
*/
|
||||
AnalogIn(PinName pin) {
|
||||
lock();
|
||||
analogin_init(&_adc, pin);
|
||||
unlock();
|
||||
}
|
||||
|
||||
/** Read the input voltage, represented as a float in the range [0.0, 1.0]
|
||||
*
|
||||
* @returns A floating-point value representing the current input voltage, measured as a percentage
|
||||
*/
|
||||
float read() {
|
||||
lock();
|
||||
float ret = analogin_read(&_adc);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Read the input voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
|
||||
*
|
||||
* @returns
|
||||
* 16-bit unsigned short representing the current input voltage, normalised to a 16-bit value
|
||||
*/
|
||||
unsigned short read_u16() {
|
||||
lock();
|
||||
unsigned short ret = analogin_read_u16(&_adc);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** An operator shorthand for read()
|
||||
*
|
||||
* The float() operator can be used as a shorthand for read() to simplify common code sequences
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* float x = volume.read();
|
||||
* float x = volume;
|
||||
*
|
||||
* if(volume.read() > 0.25) { ... }
|
||||
* if(volume > 0.25) { ... }
|
||||
* @endcode
|
||||
*/
|
||||
operator float() {
|
||||
// Underlying call is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
virtual ~AnalogIn() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void lock() {
|
||||
_mutex->lock();
|
||||
}
|
||||
|
||||
virtual void unlock() {
|
||||
_mutex->unlock();
|
||||
}
|
||||
|
||||
analogin_t _adc;
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
153
NPR_14/mbed-os/drivers/AnalogOut.h
Normal file
153
NPR_14/mbed-os/drivers/AnalogOut.h
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_ANALOGOUT_H
|
||||
#define MBED_ANALOGOUT_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_ANALOGOUT) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/analogout_api.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** An analog output, used for setting the voltage on a pin
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Make a sawtooth output
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* AnalogOut tri(p18);
|
||||
* int main() {
|
||||
* while(1) {
|
||||
* tri = tri + 0.01;
|
||||
* wait_us(1);
|
||||
* if(tri == 1) {
|
||||
* tri = 0;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class AnalogOut {
|
||||
|
||||
public:
|
||||
|
||||
/** Create an AnalogOut connected to the specified pin
|
||||
*
|
||||
* @param pin AnalogOut pin to connect to
|
||||
*/
|
||||
AnalogOut(PinName pin) {
|
||||
analogout_init(&_dac, pin);
|
||||
}
|
||||
|
||||
/** Set the output voltage, specified as a percentage (float)
|
||||
*
|
||||
* @param value A floating-point value representing the output voltage,
|
||||
* specified as a percentage. The value should lie between
|
||||
* 0.0f (representing 0v / 0%) and 1.0f (representing 3.3v / 100%).
|
||||
* Values outside this range will be saturated to 0.0f or 1.0f.
|
||||
*/
|
||||
void write(float value) {
|
||||
lock();
|
||||
analogout_write(&_dac, value);
|
||||
unlock();
|
||||
}
|
||||
|
||||
/** Set the output voltage, represented as an unsigned short in the range [0x0, 0xFFFF]
|
||||
*
|
||||
* @param value 16-bit unsigned short representing the output voltage,
|
||||
* normalised to a 16-bit value (0x0000 = 0v, 0xFFFF = 3.3v)
|
||||
*/
|
||||
void write_u16(unsigned short value) {
|
||||
lock();
|
||||
analogout_write_u16(&_dac, value);
|
||||
unlock();
|
||||
}
|
||||
|
||||
/** Return the current output voltage setting, measured as a percentage (float)
|
||||
*
|
||||
* @returns
|
||||
* A floating-point value representing the current voltage being output on the pin,
|
||||
* measured as a percentage. The returned value will lie between
|
||||
* 0.0f (representing 0v / 0%) and 1.0f (representing 3.3v / 100%).
|
||||
*
|
||||
* @note
|
||||
* This value may not match exactly the value set by a previous write().
|
||||
*/
|
||||
float read() {
|
||||
lock();
|
||||
float ret = analogout_read(&_dac);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** An operator shorthand for write()
|
||||
* \sa AnalogOut::write()
|
||||
*/
|
||||
AnalogOut& operator= (float percent) {
|
||||
// Underlying write call is thread safe
|
||||
write(percent);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** An operator shorthand for write()
|
||||
* \sa AnalogOut::write()
|
||||
*/
|
||||
AnalogOut& operator= (AnalogOut& rhs) {
|
||||
// Underlying write call is thread safe
|
||||
write(rhs.read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** An operator shorthand for read()
|
||||
* \sa AnalogOut::read()
|
||||
*/
|
||||
operator float() {
|
||||
// Underlying read call is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
virtual ~AnalogOut() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void lock() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
virtual void unlock() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
dac_t _dac;
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
96
NPR_14/mbed-os/drivers/BusIn.cpp
Normal file
96
NPR_14/mbed-os/drivers/BusIn.cpp
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/BusIn.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
BusIn::BusIn(PinName p0, PinName p1, PinName p2, PinName p3, PinName p4, PinName p5, PinName p6, PinName p7, PinName p8, PinName p9, PinName p10, PinName p11, PinName p12, PinName p13, PinName p14, PinName p15) {
|
||||
PinName pins[16] = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15};
|
||||
|
||||
// No lock needed in the constructor
|
||||
_nc_mask = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
_pin[i] = (pins[i] != NC) ? new DigitalIn(pins[i]) : 0;
|
||||
if (pins[i] != NC) {
|
||||
_nc_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusIn::BusIn(PinName pins[16]) {
|
||||
// No lock needed in the constructor
|
||||
_nc_mask = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
_pin[i] = (pins[i] != NC) ? new DigitalIn(pins[i]) : 0;
|
||||
if (pins[i] != NC) {
|
||||
_nc_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusIn::~BusIn() {
|
||||
// No lock needed in the destructor
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
delete _pin[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BusIn::read() {
|
||||
int v = 0;
|
||||
lock();
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
v |= _pin[i]->read() << i;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return v;
|
||||
}
|
||||
|
||||
void BusIn::mode(PinMode pull) {
|
||||
lock();
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
_pin[i]->mode(pull);
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void BusIn::lock() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void BusIn::unlock() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
BusIn::operator int() {
|
||||
// Underlying read is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
DigitalIn& BusIn::operator[] (int index) {
|
||||
// No lock needed since _pin is not modified outside the constructor
|
||||
MBED_ASSERT(index >= 0 && index <= 16);
|
||||
MBED_ASSERT(_pin[index]);
|
||||
return *_pin[index];
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
127
NPR_14/mbed-os/drivers/BusIn.h
Normal file
127
NPR_14/mbed-os/drivers/BusIn.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_BUSIN_H
|
||||
#define MBED_BUSIN_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "drivers/DigitalIn.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A digital input bus, used for reading the state of a collection of pins
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class BusIn : private NonCopyable<BusIn> {
|
||||
|
||||
public:
|
||||
/* Group: Configuration Methods */
|
||||
|
||||
/** Create an BusIn, connected to the specified pins
|
||||
*
|
||||
* @param p0 DigitalIn pin to connect to bus bit
|
||||
* @param p1 DigitalIn pin to connect to bus bit
|
||||
* @param p2 DigitalIn pin to connect to bus bit
|
||||
* @param p3 DigitalIn pin to connect to bus bit
|
||||
* @param p4 DigitalIn pin to connect to bus bit
|
||||
* @param p5 DigitalIn pin to connect to bus bit
|
||||
* @param p6 DigitalIn pin to connect to bus bit
|
||||
* @param p7 DigitalIn pin to connect to bus bit
|
||||
* @param p8 DigitalIn pin to connect to bus bit
|
||||
* @param p9 DigitalIn pin to connect to bus bit
|
||||
* @param p10 DigitalIn pin to connect to bus bit
|
||||
* @param p11 DigitalIn pin to connect to bus bit
|
||||
* @param p12 DigitalIn pin to connect to bus bit
|
||||
* @param p13 DigitalIn pin to connect to bus bit
|
||||
* @param p14 DigitalIn pin to connect to bus bit
|
||||
* @param p15 DigitalIn pin to connect to bus bit
|
||||
*
|
||||
* @note
|
||||
* It is only required to specify as many pin variables as is required
|
||||
* for the bus; the rest will default to NC (not connected)
|
||||
*/
|
||||
BusIn(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,
|
||||
PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,
|
||||
PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
|
||||
PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
|
||||
|
||||
|
||||
/** Create an BusIn, connected to the specified pins
|
||||
*
|
||||
* @param pins An array of pins to connect to bus bit
|
||||
*/
|
||||
BusIn(PinName pins[16]);
|
||||
|
||||
virtual ~BusIn();
|
||||
|
||||
/** Read the value of the input bus
|
||||
*
|
||||
* @returns
|
||||
* An integer with each bit corresponding to the value read from the associated DigitalIn pin
|
||||
*/
|
||||
int read();
|
||||
|
||||
/** Set the input pin mode
|
||||
*
|
||||
* @param pull PullUp, PullDown, PullNone
|
||||
*/
|
||||
void mode(PinMode pull);
|
||||
|
||||
/** Binary mask of bus pins connected to actual pins (not NC pins)
|
||||
* If bus pin is in NC state make corresponding bit will be cleared (set to 0), else bit will be set to 1
|
||||
*
|
||||
* @returns
|
||||
* Binary mask of connected pins
|
||||
*/
|
||||
int mask() {
|
||||
// No lock needed since _nc_mask is not modified outside the constructor
|
||||
return _nc_mask;
|
||||
}
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa DigitalIn::read()
|
||||
*/
|
||||
operator int();
|
||||
|
||||
/** Access to particular bit in random-iterator fashion
|
||||
* @param index Position of bit
|
||||
*/
|
||||
DigitalIn & operator[] (int index);
|
||||
|
||||
protected:
|
||||
DigitalIn* _pin[16];
|
||||
|
||||
/* Mask of bus's NC pins
|
||||
* If bit[n] is set to 1 - pin is connected
|
||||
* if bit[n] is cleared - pin is not connected (NC)
|
||||
*/
|
||||
int _nc_mask;
|
||||
|
||||
PlatformMutex _mutex;
|
||||
|
||||
private:
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
138
NPR_14/mbed-os/drivers/BusInOut.cpp
Normal file
138
NPR_14/mbed-os/drivers/BusInOut.cpp
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/BusInOut.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
BusInOut::BusInOut(PinName p0, PinName p1, PinName p2, PinName p3, PinName p4, PinName p5, PinName p6, PinName p7, PinName p8, PinName p9, PinName p10, PinName p11, PinName p12, PinName p13, PinName p14, PinName p15) {
|
||||
PinName pins[16] = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15};
|
||||
|
||||
// No lock needed in the constructor
|
||||
_nc_mask = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
_pin[i] = (pins[i] != NC) ? new DigitalInOut(pins[i]) : 0;
|
||||
if (pins[i] != NC) {
|
||||
_nc_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusInOut::BusInOut(PinName pins[16]) {
|
||||
// No lock needed in the constructor
|
||||
_nc_mask = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
_pin[i] = (pins[i] != NC) ? new DigitalInOut(pins[i]) : 0;
|
||||
if (pins[i] != NC) {
|
||||
_nc_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusInOut::~BusInOut() {
|
||||
// No lock needed in the destructor
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
delete _pin[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BusInOut::write(int value) {
|
||||
lock();
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
_pin[i]->write((value >> i) & 1);
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
int BusInOut::read() {
|
||||
lock();
|
||||
int v = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
v |= _pin[i]->read() << i;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return v;
|
||||
}
|
||||
|
||||
void BusInOut::output() {
|
||||
lock();
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
_pin[i]->output();
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void BusInOut::input() {
|
||||
lock();
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
_pin[i]->input();
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void BusInOut::mode(PinMode pull) {
|
||||
lock();
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
_pin[i]->mode(pull);
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
BusInOut& BusInOut::operator= (int v) {
|
||||
// Underlying write is thread safe
|
||||
write(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BusInOut& BusInOut::operator= (BusInOut& rhs) {
|
||||
// Underlying read is thread safe
|
||||
write(rhs.read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
DigitalInOut& BusInOut::operator[] (int index) {
|
||||
// No lock needed since _pin is not modified outside the constructor
|
||||
MBED_ASSERT(index >= 0 && index <= 16);
|
||||
MBED_ASSERT(_pin[index]);
|
||||
return *_pin[index];
|
||||
}
|
||||
|
||||
BusInOut::operator int() {
|
||||
// Underlying read is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
void BusInOut::lock() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void BusInOut::unlock() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
143
NPR_14/mbed-os/drivers/BusInOut.h
Normal file
143
NPR_14/mbed-os/drivers/BusInOut.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_BUSINOUT_H
|
||||
#define MBED_BUSINOUT_H
|
||||
|
||||
#include "drivers/DigitalInOut.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A digital input output bus, used for setting the state of a collection of pins
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class BusInOut : private NonCopyable<BusInOut> {
|
||||
|
||||
public:
|
||||
|
||||
/** Create an BusInOut, connected to the specified pins
|
||||
*
|
||||
* @param p0 DigitalInOut pin to connect to bus bit
|
||||
* @param p1 DigitalInOut pin to connect to bus bit
|
||||
* @param p2 DigitalInOut pin to connect to bus bit
|
||||
* @param p3 DigitalInOut pin to connect to bus bit
|
||||
* @param p4 DigitalInOut pin to connect to bus bit
|
||||
* @param p5 DigitalInOut pin to connect to bus bit
|
||||
* @param p6 DigitalInOut pin to connect to bus bit
|
||||
* @param p7 DigitalInOut pin to connect to bus bit
|
||||
* @param p8 DigitalInOut pin to connect to bus bit
|
||||
* @param p9 DigitalInOut pin to connect to bus bit
|
||||
* @param p10 DigitalInOut pin to connect to bus bit
|
||||
* @param p11 DigitalInOut pin to connect to bus bit
|
||||
* @param p12 DigitalInOut pin to connect to bus bit
|
||||
* @param p13 DigitalInOut pin to connect to bus bit
|
||||
* @param p14 DigitalInOut pin to connect to bus bit
|
||||
* @param p15 DigitalInOut pin to connect to bus bit
|
||||
*
|
||||
* @note
|
||||
* It is only required to specify as many pin variables as is required
|
||||
* for the bus; the rest will default to NC (not connected)
|
||||
*/
|
||||
BusInOut(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,
|
||||
PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,
|
||||
PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
|
||||
PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
|
||||
|
||||
/** Create an BusInOut, connected to the specified pins
|
||||
*
|
||||
* @param pins An array of pins to construct a BusInOut from
|
||||
*/
|
||||
BusInOut(PinName pins[16]);
|
||||
|
||||
virtual ~BusInOut();
|
||||
|
||||
/* Group: Access Methods */
|
||||
|
||||
/** Write the value to the output bus
|
||||
*
|
||||
* @param value An integer specifying a bit to write for every corresponding DigitalInOut pin
|
||||
*/
|
||||
void write(int value);
|
||||
|
||||
/** Read the value currently output on the bus
|
||||
*
|
||||
* @returns
|
||||
* An integer with each bit corresponding to associated DigitalInOut pin setting
|
||||
*/
|
||||
int read();
|
||||
|
||||
/** Set as an output
|
||||
*/
|
||||
void output();
|
||||
|
||||
/** Set as an input
|
||||
*/
|
||||
void input();
|
||||
|
||||
/** Set the input pin mode
|
||||
*
|
||||
* @param pull PullUp, PullDown, PullNone
|
||||
*/
|
||||
void mode(PinMode pull);
|
||||
|
||||
/** Binary mask of bus pins connected to actual pins (not NC pins)
|
||||
* If bus pin is in NC state make corresponding bit will be cleared (set to 0), else bit will be set to 1
|
||||
*
|
||||
* @returns
|
||||
* Binary mask of connected pins
|
||||
*/
|
||||
int mask() {
|
||||
// No lock needed since _nc_mask is not modified outside the constructor
|
||||
return _nc_mask;
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa BusInOut::write()
|
||||
*/
|
||||
BusInOut& operator= (int v);
|
||||
BusInOut& operator= (BusInOut& rhs);
|
||||
|
||||
/** Access to particular bit in random-iterator fashion
|
||||
* @param index Bit Position
|
||||
*/
|
||||
DigitalInOut& operator[] (int index);
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa BusInOut::read()
|
||||
*/
|
||||
operator int();
|
||||
|
||||
protected:
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
DigitalInOut* _pin[16];
|
||||
|
||||
/* Mask of bus's NC pins
|
||||
* If bit[n] is set to 1 - pin is connected
|
||||
* if bit[n] is cleared - pin is not connected (NC)
|
||||
*/
|
||||
int _nc_mask;
|
||||
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
108
NPR_14/mbed-os/drivers/BusOut.cpp
Normal file
108
NPR_14/mbed-os/drivers/BusOut.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/BusOut.h"
|
||||
#include "platform/mbed_assert.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
BusOut::BusOut(PinName p0, PinName p1, PinName p2, PinName p3, PinName p4, PinName p5, PinName p6, PinName p7, PinName p8, PinName p9, PinName p10, PinName p11, PinName p12, PinName p13, PinName p14, PinName p15) {
|
||||
PinName pins[16] = {p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15};
|
||||
|
||||
// No lock needed in the constructor
|
||||
_nc_mask = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
_pin[i] = (pins[i] != NC) ? new DigitalOut(pins[i]) : 0;
|
||||
if (pins[i] != NC) {
|
||||
_nc_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusOut::BusOut(PinName pins[16]) {
|
||||
// No lock needed in the constructor
|
||||
_nc_mask = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
_pin[i] = (pins[i] != NC) ? new DigitalOut(pins[i]) : 0;
|
||||
if (pins[i] != NC) {
|
||||
_nc_mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BusOut::~BusOut() {
|
||||
// No lock needed in the destructor
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
delete _pin[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BusOut::write(int value) {
|
||||
lock();
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
_pin[i]->write((value >> i) & 1);
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
int BusOut::read() {
|
||||
lock();
|
||||
int v = 0;
|
||||
for (int i=0; i<16; i++) {
|
||||
if (_pin[i] != 0) {
|
||||
v |= _pin[i]->read() << i;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
return v;
|
||||
}
|
||||
|
||||
BusOut& BusOut::operator= (int v) {
|
||||
// Underlying write is thread safe
|
||||
write(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BusOut& BusOut::operator= (BusOut& rhs) {
|
||||
// Underlying write is thread safe
|
||||
write(rhs.read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
DigitalOut& BusOut::operator[] (int index) {
|
||||
// No lock needed since _pin is not modified outside the constructor
|
||||
MBED_ASSERT(index >= 0 && index <= 16);
|
||||
MBED_ASSERT(_pin[index]);
|
||||
return *_pin[index];
|
||||
}
|
||||
|
||||
BusOut::operator int() {
|
||||
// Underlying read is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
void BusOut::lock() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void BusOut::unlock() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
127
NPR_14/mbed-os/drivers/BusOut.h
Normal file
127
NPR_14/mbed-os/drivers/BusOut.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_BUSOUT_H
|
||||
#define MBED_BUSOUT_H
|
||||
|
||||
#include "drivers/DigitalOut.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A digital output bus, used for setting the state of a collection of pins
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class BusOut : private NonCopyable<BusOut> {
|
||||
|
||||
public:
|
||||
|
||||
/** Create an BusOut, connected to the specified pins
|
||||
*
|
||||
* @param p0 DigitalOut pin to connect to bus bit
|
||||
* @param p1 DigitalOut pin to connect to bus bit
|
||||
* @param p2 DigitalOut pin to connect to bus bit
|
||||
* @param p3 DigitalOut pin to connect to bus bit
|
||||
* @param p4 DigitalOut pin to connect to bus bit
|
||||
* @param p5 DigitalOut pin to connect to bus bit
|
||||
* @param p6 DigitalOut pin to connect to bus bit
|
||||
* @param p7 DigitalOut pin to connect to bus bit
|
||||
* @param p8 DigitalOut pin to connect to bus bit
|
||||
* @param p9 DigitalOut pin to connect to bus bit
|
||||
* @param p10 DigitalOut pin to connect to bus bit
|
||||
* @param p11 DigitalOut pin to connect to bus bit
|
||||
* @param p12 DigitalOut pin to connect to bus bit
|
||||
* @param p13 DigitalOut pin to connect to bus bit
|
||||
* @param p14 DigitalOut pin to connect to bus bit
|
||||
* @param p15 DigitalOut pin to connect to bus bit
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* @note
|
||||
* It is only required to specify as many pin variables as is required
|
||||
* for the bus; the rest will default to NC (not connected)
|
||||
*/
|
||||
BusOut(PinName p0, PinName p1 = NC, PinName p2 = NC, PinName p3 = NC,
|
||||
PinName p4 = NC, PinName p5 = NC, PinName p6 = NC, PinName p7 = NC,
|
||||
PinName p8 = NC, PinName p9 = NC, PinName p10 = NC, PinName p11 = NC,
|
||||
PinName p12 = NC, PinName p13 = NC, PinName p14 = NC, PinName p15 = NC);
|
||||
|
||||
/** Create an BusOut, connected to the specified pins
|
||||
*
|
||||
* @param pins An array of pins to connect to bus the bit
|
||||
*/
|
||||
BusOut(PinName pins[16]);
|
||||
|
||||
virtual ~BusOut();
|
||||
|
||||
/** Write the value to the output bus
|
||||
*
|
||||
* @param value An integer specifying a bit to write for every corresponding DigitalOut pin
|
||||
*/
|
||||
void write(int value);
|
||||
|
||||
/** Read the value currently output on the bus
|
||||
*
|
||||
* @returns
|
||||
* An integer with each bit corresponding to associated DigitalOut pin setting
|
||||
*/
|
||||
int read();
|
||||
|
||||
/** Binary mask of bus pins connected to actual pins (not NC pins)
|
||||
* If bus pin is in NC state make corresponding bit will be cleared (set to 0), else bit will be set to 1
|
||||
*
|
||||
* @returns
|
||||
* Binary mask of connected pins
|
||||
*/
|
||||
int mask() {
|
||||
// No lock needed since _nc_mask is not modified outside the constructor
|
||||
return _nc_mask;
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa BusOut::write()
|
||||
*/
|
||||
BusOut& operator= (int v);
|
||||
BusOut& operator= (BusOut& rhs);
|
||||
|
||||
/** Access to particular bit in random-iterator fashion
|
||||
* @param index Bit Position
|
||||
*/
|
||||
DigitalOut& operator[] (int index);
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa BusOut::read()
|
||||
*/
|
||||
operator int();
|
||||
|
||||
protected:
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
DigitalOut* _pin[16];
|
||||
|
||||
/* Mask of bus's NC pins
|
||||
* If bit[n] is set to 1 - pin is connected
|
||||
* if bit[n] is cleared - pin is not connected (NC)
|
||||
*/
|
||||
int _nc_mask;
|
||||
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
156
NPR_14/mbed-os/drivers/CAN.cpp
Normal file
156
NPR_14/mbed-os/drivers/CAN.cpp
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/CAN.h"
|
||||
|
||||
#if DEVICE_CAN
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "platform/mbed_sleep.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
CAN::CAN(PinName rd, PinName td) : _can(), _irq() {
|
||||
// No lock needed in constructor
|
||||
|
||||
for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
|
||||
_irq[i] = NULL;
|
||||
}
|
||||
|
||||
can_init(&_can, rd, td);
|
||||
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
|
||||
}
|
||||
|
||||
CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq() {
|
||||
// No lock needed in constructor
|
||||
|
||||
for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
|
||||
_irq[i] = NULL;
|
||||
}
|
||||
|
||||
can_init_freq(&_can, rd, td, hz);
|
||||
can_irq_init(&_can, (&CAN::_irq_handler), (uint32_t)this);
|
||||
}
|
||||
|
||||
CAN::~CAN() {
|
||||
// No lock needed in destructor
|
||||
|
||||
// Detaching interrupts releases the sleep lock if it was locked
|
||||
for (int irq = 0; irq < IrqCnt; irq++) {
|
||||
attach(NULL, (IrqType)irq);
|
||||
}
|
||||
can_irq_free(&_can);
|
||||
can_free(&_can);
|
||||
}
|
||||
|
||||
int CAN::frequency(int f) {
|
||||
lock();
|
||||
int ret = can_frequency(&_can, f);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CAN::write(CANMessage msg) {
|
||||
lock();
|
||||
int ret = can_write(&_can, msg, 0);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CAN::read(CANMessage &msg, int handle) {
|
||||
lock();
|
||||
int ret = can_read(&_can, &msg, handle);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CAN::reset() {
|
||||
lock();
|
||||
can_reset(&_can);
|
||||
unlock();
|
||||
}
|
||||
|
||||
unsigned char CAN::rderror() {
|
||||
lock();
|
||||
int ret = can_rderror(&_can);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned char CAN::tderror() {
|
||||
lock();
|
||||
int ret = can_tderror(&_can);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CAN::monitor(bool silent) {
|
||||
lock();
|
||||
can_monitor(&_can, (silent) ? 1 : 0);
|
||||
unlock();
|
||||
}
|
||||
|
||||
int CAN::mode(Mode mode) {
|
||||
lock();
|
||||
int ret = can_mode(&_can, (CanMode)mode);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle) {
|
||||
lock();
|
||||
int ret = can_filter(&_can, id, mask, format, handle);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CAN::attach(Callback<void()> func, IrqType type) {
|
||||
lock();
|
||||
if (func) {
|
||||
// lock deep sleep only the first time
|
||||
if (!_irq[(CanIrqType)type]) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
}
|
||||
_irq[(CanIrqType)type] = func;
|
||||
can_irq_set(&_can, (CanIrqType)type, 1);
|
||||
} else {
|
||||
// unlock deep sleep only the first time
|
||||
if (_irq[(CanIrqType)type]) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
_irq[(CanIrqType)type] = NULL;
|
||||
can_irq_set(&_can, (CanIrqType)type, 0);
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void CAN::_irq_handler(uint32_t id, CanIrqType type) {
|
||||
CAN *handler = (CAN*)id;
|
||||
if (handler->_irq[type]) {
|
||||
handler->_irq[type].call();
|
||||
}
|
||||
}
|
||||
|
||||
void CAN::lock() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void CAN::unlock() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
299
NPR_14/mbed-os/drivers/CAN.h
Normal file
299
NPR_14/mbed-os/drivers/CAN.h
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_CAN_H
|
||||
#define MBED_CAN_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_CAN) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/can_api.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** CANMessage class
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class CANMessage : public CAN_Message {
|
||||
|
||||
public:
|
||||
/** Creates empty CAN message.
|
||||
*/
|
||||
CANMessage() : CAN_Message() {
|
||||
len = 8;
|
||||
type = CANData;
|
||||
format = CANStandard;
|
||||
id = 0;
|
||||
memset(data, 0, 8);
|
||||
}
|
||||
|
||||
/** Creates CAN message with specific content.
|
||||
*
|
||||
* @param _id Message ID
|
||||
* @param _data Mesaage Data
|
||||
* @param _len Message Data length
|
||||
* @param _type Type of Data: Use enum CANType for valid parameter values
|
||||
* @param _format Data Format: Use enum CANFormat for valid parameter values
|
||||
*/
|
||||
CANMessage(int _id, const char *_data, char _len = 8, CANType _type = CANData, CANFormat _format = CANStandard) {
|
||||
len = _len & 0xF;
|
||||
type = _type;
|
||||
format = _format;
|
||||
id = _id;
|
||||
memcpy(data, _data, _len);
|
||||
}
|
||||
|
||||
/** Creates CAN remote message.
|
||||
*
|
||||
* @param _id Message ID
|
||||
* @param _format Data Format: Use enum CANType for valid parameter values
|
||||
*/
|
||||
CANMessage(int _id, CANFormat _format = CANStandard) {
|
||||
len = 0;
|
||||
type = CANRemote;
|
||||
format = _format;
|
||||
id = _id;
|
||||
memset(data, 0, 8);
|
||||
}
|
||||
};
|
||||
|
||||
/** A can bus client, used for communicating with can devices
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class CAN : private NonCopyable<CAN> {
|
||||
|
||||
public:
|
||||
/** Creates an CAN interface connected to specific pins.
|
||||
*
|
||||
* @param rd read from transmitter
|
||||
* @param td transmit to transmitter
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Ticker ticker;
|
||||
* DigitalOut led1(LED1);
|
||||
* DigitalOut led2(LED2);
|
||||
* CAN can1(p9, p10);
|
||||
* CAN can2(p30, p29);
|
||||
*
|
||||
* char counter = 0;
|
||||
*
|
||||
* void send() {
|
||||
* if(can1.write(CANMessage(1337, &counter, 1))) {
|
||||
* printf("Message sent: %d\n", counter);
|
||||
* counter++;
|
||||
* }
|
||||
* led1 = !led1;
|
||||
* }
|
||||
*
|
||||
* int main() {
|
||||
* ticker.attach(&send, 1);
|
||||
* CANMessage msg;
|
||||
* while(1) {
|
||||
* if(can2.read(msg)) {
|
||||
* printf("Message received: %d\n\n", msg.data[0]);
|
||||
* led2 = !led2;
|
||||
* }
|
||||
* wait(0.2);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
CAN(PinName rd, PinName td);
|
||||
|
||||
/** Initialize CAN interface and set the frequency
|
||||
*
|
||||
* @param rd the rd pin
|
||||
* @param td the td pin
|
||||
* @param hz the bus frequency in hertz
|
||||
*/
|
||||
CAN(PinName rd, PinName td, int hz);
|
||||
|
||||
virtual ~CAN();
|
||||
|
||||
/** Set the frequency of the CAN interface
|
||||
*
|
||||
* @param hz The bus frequency in hertz
|
||||
*
|
||||
* @returns
|
||||
* 1 if successful,
|
||||
* 0 otherwise
|
||||
*/
|
||||
int frequency(int hz);
|
||||
|
||||
/** Write a CANMessage to the bus.
|
||||
*
|
||||
* @param msg The CANMessage to write.
|
||||
*
|
||||
* @returns
|
||||
* 0 if write failed,
|
||||
* 1 if write was successful
|
||||
*/
|
||||
int write(CANMessage msg);
|
||||
|
||||
/** Read a CANMessage from the bus.
|
||||
*
|
||||
* @param msg A CANMessage to read to.
|
||||
* @param handle message filter handle (0 for any message)
|
||||
*
|
||||
* @returns
|
||||
* 0 if no message arrived,
|
||||
* 1 if message arrived
|
||||
*/
|
||||
int read(CANMessage &msg, int handle = 0);
|
||||
|
||||
/** Reset CAN interface.
|
||||
*
|
||||
* To use after error overflow.
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Puts or removes the CAN interface into silent monitoring mode
|
||||
*
|
||||
* @param silent boolean indicating whether to go into silent mode or not
|
||||
*/
|
||||
void monitor(bool silent);
|
||||
|
||||
enum Mode {
|
||||
Reset = 0,
|
||||
Normal,
|
||||
Silent,
|
||||
LocalTest,
|
||||
GlobalTest,
|
||||
SilentTest
|
||||
};
|
||||
|
||||
/** Change CAN operation to the specified mode
|
||||
*
|
||||
* @param mode The new operation mode (CAN::Normal, CAN::Silent, CAN::LocalTest, CAN::GlobalTest, CAN::SilentTest)
|
||||
*
|
||||
* @returns
|
||||
* 0 if mode change failed or unsupported,
|
||||
* 1 if mode change was successful
|
||||
*/
|
||||
int mode(Mode mode);
|
||||
|
||||
/** Filter out incomming messages
|
||||
*
|
||||
* @param id the id to filter on
|
||||
* @param mask the mask applied to the id
|
||||
* @param format format to filter on (Default CANAny)
|
||||
* @param handle message filter handle (Optional)
|
||||
*
|
||||
* @returns
|
||||
* 0 if filter change failed or unsupported,
|
||||
* new filter handle if successful
|
||||
*/
|
||||
int filter(unsigned int id, unsigned int mask, CANFormat format = CANAny, int handle = 0);
|
||||
|
||||
/** Detects read errors - Used to detect read overflow errors.
|
||||
*
|
||||
* @returns number of read errors
|
||||
*/
|
||||
unsigned char rderror();
|
||||
|
||||
/** Detects write errors - Used to detect write overflow errors.
|
||||
*
|
||||
* @returns number of write errors
|
||||
*/
|
||||
unsigned char tderror();
|
||||
|
||||
enum IrqType {
|
||||
RxIrq = 0,
|
||||
TxIrq,
|
||||
EwIrq,
|
||||
DoIrq,
|
||||
WuIrq,
|
||||
EpIrq,
|
||||
AlIrq,
|
||||
BeIrq,
|
||||
IdIrq,
|
||||
|
||||
IrqCnt
|
||||
};
|
||||
|
||||
/** Attach a function to call whenever a CAN frame received interrupt is
|
||||
* generated.
|
||||
*
|
||||
* This function locks the deep sleep while a callback is attached
|
||||
*
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
* @param type Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, CAN::TxIrq for transmitted or aborted, CAN::EwIrq for error warning, CAN::DoIrq for data overrun, CAN::WuIrq for wake-up, CAN::EpIrq for error passive, CAN::AlIrq for arbitration lost, CAN::BeIrq for bus error)
|
||||
*/
|
||||
void attach(Callback<void()> func, IrqType type=RxIrq);
|
||||
|
||||
/** Attach a member function to call whenever a CAN frame received interrupt
|
||||
* is generated.
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param type Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error)
|
||||
* @deprecated
|
||||
* The attach function does not support cv-qualifiers. Replaced by
|
||||
* attach(callback(obj, method), type).
|
||||
*/
|
||||
template<typename T>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The attach function does not support cv-qualifiers. Replaced by "
|
||||
"attach(callback(obj, method), type).")
|
||||
void attach(T* obj, void (T::*method)(), IrqType type=RxIrq) {
|
||||
// Underlying call thread safe
|
||||
attach(callback(obj, method), type);
|
||||
}
|
||||
|
||||
/** Attach a member function to call whenever a CAN frame received interrupt
|
||||
* is generated.
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param type Which CAN interrupt to attach the member function to (CAN::RxIrq for message received, TxIrq for transmitted or aborted, EwIrq for error warning, DoIrq for data overrun, WuIrq for wake-up, EpIrq for error passive, AlIrq for arbitration lost, BeIrq for bus error)
|
||||
* @deprecated
|
||||
* The attach function does not support cv-qualifiers. Replaced by
|
||||
* attach(callback(obj, method), type).
|
||||
*/
|
||||
template<typename T>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The attach function does not support cv-qualifiers. Replaced by "
|
||||
"attach(callback(obj, method), type).")
|
||||
void attach(T* obj, void (*method)(T*), IrqType type=RxIrq) {
|
||||
// Underlying call thread safe
|
||||
attach(callback(obj, method), type);
|
||||
}
|
||||
|
||||
static void _irq_handler(uint32_t id, CanIrqType type);
|
||||
|
||||
protected:
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
can_t _can;
|
||||
Callback<void()> _irq[IrqCnt];
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif // MBED_CAN_H
|
||||
|
||||
118
NPR_14/mbed-os/drivers/DigitalIn.h
Normal file
118
NPR_14/mbed-os/drivers/DigitalIn.h
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_DIGITALIN_H
|
||||
#define MBED_DIGITALIN_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "hal/gpio_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A digital input, used for reading the state of a pin
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Flash an LED while a DigitalIn is true
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* DigitalIn enable(p5);
|
||||
* DigitalOut led(LED1);
|
||||
*
|
||||
* int main() {
|
||||
* while(1) {
|
||||
* if(enable) {
|
||||
* led = !led;
|
||||
* }
|
||||
* wait(0.25);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class DigitalIn {
|
||||
|
||||
public:
|
||||
/** Create a DigitalIn connected to the specified pin
|
||||
*
|
||||
* @param pin DigitalIn pin to connect to
|
||||
*/
|
||||
DigitalIn(PinName pin) : gpio() {
|
||||
// No lock needed in the constructor
|
||||
gpio_init_in(&gpio, pin);
|
||||
}
|
||||
|
||||
/** Create a DigitalIn connected to the specified pin
|
||||
*
|
||||
* @param pin DigitalIn pin to connect to
|
||||
* @param mode the initial mode of the pin
|
||||
*/
|
||||
DigitalIn(PinName pin, PinMode mode) : gpio() {
|
||||
// No lock needed in the constructor
|
||||
gpio_init_in_ex(&gpio, pin, mode);
|
||||
}
|
||||
/** Read the input, represented as 0 or 1 (int)
|
||||
*
|
||||
* @returns
|
||||
* An integer representing the state of the input pin,
|
||||
* 0 for logical 0, 1 for logical 1
|
||||
*/
|
||||
int read() {
|
||||
// Thread safe / atomic HAL call
|
||||
return gpio_read(&gpio);
|
||||
}
|
||||
|
||||
/** Set the input pin mode
|
||||
*
|
||||
* @param pull PullUp, PullDown, PullNone, OpenDrain
|
||||
*/
|
||||
void mode(PinMode pull) {
|
||||
core_util_critical_section_enter();
|
||||
gpio_mode(&gpio, pull);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Return the output setting, represented as 0 or 1 (int)
|
||||
*
|
||||
* @returns
|
||||
* Non zero value if pin is connected to uc GPIO
|
||||
* 0 if gpio object was initialized with NC
|
||||
*/
|
||||
int is_connected() {
|
||||
// Thread safe / atomic HAL call
|
||||
return gpio_is_connected(&gpio);
|
||||
}
|
||||
|
||||
/** An operator shorthand for read()
|
||||
* \sa DigitalIn::read()
|
||||
*/
|
||||
operator int() {
|
||||
// Underlying read is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
protected:
|
||||
gpio_t gpio;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
147
NPR_14/mbed-os/drivers/DigitalInOut.h
Normal file
147
NPR_14/mbed-os/drivers/DigitalInOut.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_DIGITALINOUT_H
|
||||
#define MBED_DIGITALINOUT_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "hal/gpio_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A digital input/output, used for setting or reading a bi-directional pin
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class DigitalInOut {
|
||||
|
||||
public:
|
||||
/** Create a DigitalInOut connected to the specified pin
|
||||
*
|
||||
* @param pin DigitalInOut pin to connect to
|
||||
*/
|
||||
DigitalInOut(PinName pin) : gpio() {
|
||||
// No lock needed in the constructor
|
||||
gpio_init_in(&gpio, pin);
|
||||
}
|
||||
|
||||
/** Create a DigitalInOut connected to the specified pin
|
||||
*
|
||||
* @param pin DigitalInOut pin to connect to
|
||||
* @param direction the initial direction of the pin
|
||||
* @param mode the initial mode of the pin
|
||||
* @param value the initial value of the pin if is an output
|
||||
*/
|
||||
DigitalInOut(PinName pin, PinDirection direction, PinMode mode, int value) : gpio() {
|
||||
// No lock needed in the constructor
|
||||
gpio_init_inout(&gpio, pin, direction, mode, value);
|
||||
}
|
||||
|
||||
/** Set the output, specified as 0 or 1 (int)
|
||||
*
|
||||
* @param value An integer specifying the pin output value,
|
||||
* 0 for logical 0, 1 (or any other non-zero value) for logical 1
|
||||
*/
|
||||
void write(int value) {
|
||||
// Thread safe / atomic HAL call
|
||||
gpio_write(&gpio, value);
|
||||
}
|
||||
|
||||
/** Return the output setting, represented as 0 or 1 (int)
|
||||
*
|
||||
* @returns
|
||||
* an integer representing the output setting of the pin if it is an output,
|
||||
* or read the input if set as an input
|
||||
*/
|
||||
int read() {
|
||||
// Thread safe / atomic HAL call
|
||||
return gpio_read(&gpio);
|
||||
}
|
||||
|
||||
/** Set as an output
|
||||
*/
|
||||
void output() {
|
||||
core_util_critical_section_enter();
|
||||
gpio_dir(&gpio, PIN_OUTPUT);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set as an input
|
||||
*/
|
||||
void input() {
|
||||
core_util_critical_section_enter();
|
||||
gpio_dir(&gpio, PIN_INPUT);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the input pin mode
|
||||
*
|
||||
* @param pull PullUp, PullDown, PullNone, OpenDrain
|
||||
*/
|
||||
void mode(PinMode pull) {
|
||||
core_util_critical_section_enter();
|
||||
gpio_mode(&gpio, pull);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Return the output setting, represented as 0 or 1 (int)
|
||||
*
|
||||
* @returns
|
||||
* Non zero value if pin is connected to uc GPIO
|
||||
* 0 if gpio object was initialized with NC
|
||||
*/
|
||||
int is_connected() {
|
||||
// Thread safe / atomic HAL call
|
||||
return gpio_is_connected(&gpio);
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa DigitalInOut::write()
|
||||
*/
|
||||
DigitalInOut& operator= (int value) {
|
||||
// Underlying write is thread safe
|
||||
write(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa DigitalInOut::write()
|
||||
*/
|
||||
DigitalInOut& operator= (DigitalInOut& rhs) {
|
||||
core_util_critical_section_enter();
|
||||
write(rhs.read());
|
||||
core_util_critical_section_exit();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa DigitalInOut::read()
|
||||
*/
|
||||
operator int() {
|
||||
// Underlying call is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
protected:
|
||||
gpio_t gpio;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
133
NPR_14/mbed-os/drivers/DigitalOut.h
Normal file
133
NPR_14/mbed-os/drivers/DigitalOut.h
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_DIGITALOUT_H
|
||||
#define MBED_DIGITALOUT_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "hal/gpio_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A digital output, used for setting the state of a pin
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Toggle a LED
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* DigitalOut led(LED1);
|
||||
*
|
||||
* int main() {
|
||||
* while(1) {
|
||||
* led = !led;
|
||||
* wait(0.2);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class DigitalOut {
|
||||
|
||||
public:
|
||||
/** Create a DigitalOut connected to the specified pin
|
||||
*
|
||||
* @param pin DigitalOut pin to connect to
|
||||
*/
|
||||
DigitalOut(PinName pin) : gpio() {
|
||||
// No lock needed in the constructor
|
||||
gpio_init_out(&gpio, pin);
|
||||
}
|
||||
|
||||
/** Create a DigitalOut connected to the specified pin
|
||||
*
|
||||
* @param pin DigitalOut pin to connect to
|
||||
* @param value the initial pin value
|
||||
*/
|
||||
DigitalOut(PinName pin, int value) : gpio() {
|
||||
// No lock needed in the constructor
|
||||
gpio_init_out_ex(&gpio, pin, value);
|
||||
}
|
||||
|
||||
/** Set the output, specified as 0 or 1 (int)
|
||||
*
|
||||
* @param value An integer specifying the pin output value,
|
||||
* 0 for logical 0, 1 (or any other non-zero value) for logical 1
|
||||
*/
|
||||
void write(int value) {
|
||||
// Thread safe / atomic HAL call
|
||||
gpio_write(&gpio, value);
|
||||
}
|
||||
|
||||
/** Return the output setting, represented as 0 or 1 (int)
|
||||
*
|
||||
* @returns
|
||||
* an integer representing the output setting of the pin,
|
||||
* 0 for logical 0, 1 for logical 1
|
||||
*/
|
||||
int read() {
|
||||
// Thread safe / atomic HAL call
|
||||
return gpio_read(&gpio);
|
||||
}
|
||||
|
||||
/** Return the output setting, represented as 0 or 1 (int)
|
||||
*
|
||||
* @returns
|
||||
* Non zero value if pin is connected to uc GPIO
|
||||
* 0 if gpio object was initialized with NC
|
||||
*/
|
||||
int is_connected() {
|
||||
// Thread safe / atomic HAL call
|
||||
return gpio_is_connected(&gpio);
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa DigitalOut::write()
|
||||
*/
|
||||
DigitalOut& operator= (int value) {
|
||||
// Underlying write is thread safe
|
||||
write(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa DigitalOut::write()
|
||||
*/
|
||||
DigitalOut& operator= (DigitalOut& rhs) {
|
||||
core_util_critical_section_enter();
|
||||
write(rhs.read());
|
||||
core_util_critical_section_exit();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa DigitalOut::read()
|
||||
*/
|
||||
operator int() {
|
||||
// Underlying call is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
protected:
|
||||
gpio_t gpio;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
73
NPR_14/mbed-os/drivers/Ethernet.cpp
Normal file
73
NPR_14/mbed-os/drivers/Ethernet.cpp
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/Ethernet.h"
|
||||
|
||||
#if DEVICE_ETHERNET
|
||||
|
||||
#include "hal/ethernet_api.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
Ethernet::Ethernet() {
|
||||
ethernet_init();
|
||||
}
|
||||
|
||||
Ethernet::~Ethernet() {
|
||||
ethernet_free();
|
||||
}
|
||||
|
||||
int Ethernet::write(const char *data, int size) {
|
||||
return ethernet_write(data, size);
|
||||
}
|
||||
|
||||
int Ethernet::send() {
|
||||
return ethernet_send();
|
||||
}
|
||||
|
||||
int Ethernet::receive() {
|
||||
return ethernet_receive();
|
||||
}
|
||||
|
||||
int Ethernet::read(char *data, int size) {
|
||||
return ethernet_read(data, size);
|
||||
}
|
||||
|
||||
void Ethernet::address(char *mac) {
|
||||
return ethernet_address(mac);
|
||||
}
|
||||
|
||||
int Ethernet::link() {
|
||||
return ethernet_link();
|
||||
}
|
||||
|
||||
void Ethernet::set_link(Mode mode) {
|
||||
int speed = -1;
|
||||
int duplex = 0;
|
||||
|
||||
switch(mode) {
|
||||
case AutoNegotiate : speed = -1; duplex = 0; break;
|
||||
case HalfDuplex10 : speed = 0; duplex = 0; break;
|
||||
case FullDuplex10 : speed = 0; duplex = 1; break;
|
||||
case HalfDuplex100 : speed = 1; duplex = 0; break;
|
||||
case FullDuplex100 : speed = 1; duplex = 1; break;
|
||||
}
|
||||
|
||||
ethernet_set_link(speed, duplex);
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
176
NPR_14/mbed-os/drivers/Ethernet.h
Normal file
176
NPR_14/mbed-os/drivers/Ethernet.h
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_ETHERNET_H
|
||||
#define MBED_ETHERNET_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if defined (DEVICE_ETHERNET) || defined(DOXYGEN_ONLY)
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** An ethernet interface, to use with the ethernet pins.
|
||||
*
|
||||
* @note Synchronization level: Not protected
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Read destination and source from every ethernet packet
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Ethernet eth;
|
||||
*
|
||||
* int main() {
|
||||
* char buf[0x600];
|
||||
*
|
||||
* while(1) {
|
||||
* int size = eth.receive();
|
||||
* if(size > 0) {
|
||||
* eth.read(buf, size);
|
||||
* printf("Destination: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
* buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
|
||||
* printf("Source: %02X:%02X:%02X:%02X:%02X:%02X\n",
|
||||
* buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]);
|
||||
* }
|
||||
*
|
||||
* wait(1);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class Ethernet : private NonCopyable<Ethernet> {
|
||||
|
||||
public:
|
||||
|
||||
/** Initialise the ethernet interface.
|
||||
*/
|
||||
Ethernet();
|
||||
|
||||
/** Powers the hardware down.
|
||||
*/
|
||||
virtual ~Ethernet();
|
||||
|
||||
enum Mode {
|
||||
AutoNegotiate,
|
||||
HalfDuplex10,
|
||||
FullDuplex10,
|
||||
HalfDuplex100,
|
||||
FullDuplex100
|
||||
};
|
||||
|
||||
/** Writes into an outgoing ethernet packet.
|
||||
*
|
||||
* It will append size bytes of data to the previously written bytes.
|
||||
*
|
||||
* @param data An array to write.
|
||||
* @param size The size of data.
|
||||
*
|
||||
* @returns
|
||||
* The number of written bytes.
|
||||
*/
|
||||
int write(const char *data, int size);
|
||||
|
||||
/** Send an outgoing ethernet packet.
|
||||
*
|
||||
* After filling in the data in an ethernet packet it must be send.
|
||||
* Send will provide a new packet to write to.
|
||||
*
|
||||
* @returns
|
||||
* 0 if the sending was failed,
|
||||
* or the size of the packet successfully sent.
|
||||
*/
|
||||
int send();
|
||||
|
||||
/** Recevies an arrived ethernet packet.
|
||||
*
|
||||
* Receiving an ethernet packet will drop the last received ethernet packet
|
||||
* and make a new ethernet packet ready to read.
|
||||
* If no ethernet packet is arrived it will return 0.
|
||||
*
|
||||
* @returns
|
||||
* 0 if no ethernet packet is arrived,
|
||||
* or the size of the arrived packet.
|
||||
*/
|
||||
int receive();
|
||||
|
||||
/** Read from an recevied ethernet packet.
|
||||
*
|
||||
* After receive returned a number bigger than 0 it is
|
||||
* possible to read bytes from this packet.
|
||||
*
|
||||
* @param data Pointer to data packet
|
||||
* @param size Size of data to be read.
|
||||
* @returns The number of byte read.
|
||||
*
|
||||
* @note It is possible to use read multiple times.
|
||||
* Each time read will start reading after the last read byte before.
|
||||
*
|
||||
*/
|
||||
int read(char *data, int size);
|
||||
|
||||
/** Gives the ethernet address of the mbed.
|
||||
*
|
||||
* @param mac Must be a pointer to a 6 byte char array to copy the ethernet address in.
|
||||
*/
|
||||
void address(char *mac);
|
||||
|
||||
/** Returns if an ethernet link is pressent or not. It takes a wile after Ethernet initializion to show up.
|
||||
*
|
||||
* @returns
|
||||
* 0 if no ethernet link is pressent,
|
||||
* 1 if an ethernet link is pressent.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Using the Ethernet link function
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Ethernet eth;
|
||||
*
|
||||
* int main() {
|
||||
* wait(1); // Needed after startup.
|
||||
* if (eth.link()) {
|
||||
* printf("online\n");
|
||||
* } else {
|
||||
* printf("offline\n");
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
int link();
|
||||
|
||||
/** Sets the speed and duplex parameters of an ethernet link
|
||||
*
|
||||
* - AutoNegotiate Auto negotiate speed and duplex
|
||||
* - HalfDuplex10 10 Mbit, half duplex
|
||||
* - FullDuplex10 10 Mbit, full duplex
|
||||
* - HalfDuplex100 100 Mbit, half duplex
|
||||
* - FullDuplex100 100 Mbit, full duplex
|
||||
*
|
||||
* @param mode the speed and duplex mode to set the link to:
|
||||
*/
|
||||
void set_link(Mode mode);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
168
NPR_14/mbed-os/drivers/FlashIAP.cpp
Normal file
168
NPR_14/mbed-os/drivers/FlashIAP.cpp
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "FlashIAP.h"
|
||||
#include "mbed_assert.h"
|
||||
|
||||
|
||||
#ifdef DEVICE_FLASH
|
||||
|
||||
namespace mbed {
|
||||
|
||||
SingletonPtr<PlatformMutex> FlashIAP::_mutex;
|
||||
|
||||
static inline bool is_aligned(uint32_t number, uint32_t alignment)
|
||||
{
|
||||
if ((number % alignment) != 0) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FlashIAP::FlashIAP()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FlashIAP::~FlashIAP()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int FlashIAP::init()
|
||||
{
|
||||
int ret = 0;
|
||||
_mutex->lock();
|
||||
if (flash_init(&_flash)) {
|
||||
ret = -1;
|
||||
}
|
||||
_mutex->unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FlashIAP::deinit()
|
||||
{
|
||||
int ret = 0;
|
||||
_mutex->lock();
|
||||
if (flash_free(&_flash)) {
|
||||
ret = -1;
|
||||
}
|
||||
_mutex->unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int FlashIAP::read(void *buffer, uint32_t addr, uint32_t size)
|
||||
{
|
||||
int32_t ret = -1;
|
||||
_mutex->lock();
|
||||
ret = flash_read(&_flash, addr, (uint8_t *) buffer, size);
|
||||
_mutex->unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size)
|
||||
{
|
||||
uint32_t page_size = get_page_size();
|
||||
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
|
||||
// addr and size should be aligned to page size, and multiple of page size
|
||||
// page program should not cross sector boundaries
|
||||
if (!is_aligned(addr, page_size) ||
|
||||
!is_aligned(size, page_size) ||
|
||||
(size < page_size) ||
|
||||
(((addr % current_sector_size) + size) > current_sector_size)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
_mutex->lock();
|
||||
if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) {
|
||||
ret = -1;
|
||||
}
|
||||
_mutex->unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool FlashIAP::is_aligned_to_sector(uint32_t addr, uint32_t size)
|
||||
{
|
||||
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr);
|
||||
if (!is_aligned(size, current_sector_size) ||
|
||||
!is_aligned(addr, current_sector_size)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int FlashIAP::erase(uint32_t addr, uint32_t size)
|
||||
{
|
||||
uint32_t current_sector_size = 0UL;
|
||||
|
||||
if (!is_aligned_to_sector(addr, size)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t ret = 0;
|
||||
_mutex->lock();
|
||||
while (size) {
|
||||
ret = flash_erase_sector(&_flash, addr);
|
||||
if (ret != 0) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
current_sector_size = flash_get_sector_size(&_flash, addr);
|
||||
if (!is_aligned_to_sector(addr, size)) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
size -= current_sector_size;
|
||||
addr += current_sector_size;
|
||||
}
|
||||
_mutex->unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t FlashIAP::get_page_size() const
|
||||
{
|
||||
return flash_get_page_size(&_flash);
|
||||
}
|
||||
|
||||
uint32_t FlashIAP::get_sector_size(uint32_t addr) const
|
||||
{
|
||||
return flash_get_sector_size(&_flash, addr);
|
||||
}
|
||||
|
||||
uint32_t FlashIAP::get_flash_start() const
|
||||
{
|
||||
return flash_get_start_address(&_flash);
|
||||
}
|
||||
|
||||
uint32_t FlashIAP::get_flash_size() const
|
||||
{
|
||||
return flash_get_size(&_flash);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
138
NPR_14/mbed-os/drivers/FlashIAP.h
Normal file
138
NPR_14/mbed-os/drivers/FlashIAP.h
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2017 ARM Limited
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef MBED_FLASHIAP_H
|
||||
#define MBED_FLASHIAP_H
|
||||
|
||||
#if defined (DEVICE_FLASH) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "flash_api.h"
|
||||
#include "platform/SingletonPtr.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** Flash IAP driver. It invokes flash HAL functions.
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class FlashIAP : private NonCopyable<FlashIAP> {
|
||||
public:
|
||||
FlashIAP();
|
||||
~FlashIAP();
|
||||
|
||||
/** Initialize a flash IAP device
|
||||
*
|
||||
* Should be called once per lifetime of the object.
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
int init();
|
||||
|
||||
/** Deinitialize a flash IAP device
|
||||
*
|
||||
* @return 0 on success or a negative error code on failure
|
||||
*/
|
||||
int deinit();
|
||||
|
||||
/** Read data from a flash device.
|
||||
*
|
||||
* This method invokes memcpy - reads number of bytes from the address
|
||||
*
|
||||
* @param buffer Buffer to write to
|
||||
* @param addr Flash address to begin reading from
|
||||
* @param size Size to read in bytes
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int read(void *buffer, uint32_t addr, uint32_t size);
|
||||
|
||||
/** Program data to pages
|
||||
*
|
||||
* The sectors must have been erased prior to being programmed
|
||||
*
|
||||
* @param buffer Buffer of data to be written
|
||||
* @param addr Address of a page to begin writing to, must be a multiple of program and sector sizes
|
||||
* @param size Size to write in bytes, must be a multiple of program and sector sizes
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int program(const void *buffer, uint32_t addr, uint32_t size);
|
||||
|
||||
/** Erase sectors
|
||||
*
|
||||
* The state of an erased sector is undefined until it has been programmed
|
||||
*
|
||||
* @param addr Address of a sector to begin erasing, must be a multiple of the sector size
|
||||
* @param size Size to erase in bytes, must be a multiple of the sector size
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
int erase(uint32_t addr, uint32_t size);
|
||||
|
||||
/** Get the sector size at the defined address
|
||||
*
|
||||
* Sector size might differ at address ranges.
|
||||
* An example <0-0x1000, sector size=1024; 0x10000-0x20000, size=2048>
|
||||
*
|
||||
* @param addr Address of or inside the sector to query
|
||||
* @return Size of a sector in bytes or MBED_FLASH_INVALID_SIZE if not mapped
|
||||
*/
|
||||
uint32_t get_sector_size(uint32_t addr) const;
|
||||
|
||||
/** Get the flash start address
|
||||
*
|
||||
* @return Flash start address
|
||||
*/
|
||||
uint32_t get_flash_start() const;
|
||||
|
||||
/** Get the flash size
|
||||
*
|
||||
* @return Flash size
|
||||
*/
|
||||
uint32_t get_flash_size() const;
|
||||
|
||||
/** Get the program page size
|
||||
*
|
||||
* The page size defines the writable page size
|
||||
* @return Size of a program page in bytes
|
||||
*/
|
||||
uint32_t get_page_size() const;
|
||||
|
||||
private:
|
||||
|
||||
/* Check if address and size are aligned to a sector
|
||||
*
|
||||
* @param addr Address of block to check for alignment
|
||||
* @param size Size of block to check for alignment
|
||||
* @return true if the block is sector aligned, false otherwise
|
||||
*/
|
||||
bool is_aligned_to_sector(uint32_t addr, uint32_t size);
|
||||
|
||||
flash_t _flash;
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif /* DEVICE_FLASH */
|
||||
|
||||
#endif /* MBED_FLASHIAP_H */
|
||||
172
NPR_14/mbed-os/drivers/I2C.cpp
Normal file
172
NPR_14/mbed-os/drivers/I2C.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2015 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/I2C.h"
|
||||
|
||||
#if DEVICE_I2C
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
#include "platform/mbed_sleep.h"
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
|
||||
I2C *I2C::_owner = NULL;
|
||||
SingletonPtr<PlatformMutex> I2C::_mutex;
|
||||
|
||||
I2C::I2C(PinName sda, PinName scl) :
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
_irq(this), _usage(DMA_USAGE_NEVER),
|
||||
#endif
|
||||
_i2c(), _hz(100000) {
|
||||
// No lock needed in the constructor
|
||||
|
||||
// The init function also set the frequency to 100000
|
||||
i2c_init(&_i2c, sda, scl);
|
||||
|
||||
// Used to avoid unnecessary frequency updates
|
||||
_owner = this;
|
||||
}
|
||||
|
||||
void I2C::frequency(int hz) {
|
||||
lock();
|
||||
_hz = hz;
|
||||
|
||||
// We want to update the frequency even if we are already the bus owners
|
||||
i2c_frequency(&_i2c, _hz);
|
||||
|
||||
// Updating the frequency of the bus we become the owners of it
|
||||
_owner = this;
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2C::aquire() {
|
||||
lock();
|
||||
if (_owner != this) {
|
||||
i2c_frequency(&_i2c, _hz);
|
||||
_owner = this;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
// write - Master Transmitter Mode
|
||||
int I2C::write(int address, const char* data, int length, bool repeated) {
|
||||
lock();
|
||||
aquire();
|
||||
|
||||
int stop = (repeated) ? 0 : 1;
|
||||
int written = i2c_write(&_i2c, address, data, length, stop);
|
||||
|
||||
unlock();
|
||||
return length != written;
|
||||
}
|
||||
|
||||
int I2C::write(int data) {
|
||||
lock();
|
||||
int ret = i2c_byte_write(&_i2c, data);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// read - Master Reciever Mode
|
||||
int I2C::read(int address, char* data, int length, bool repeated) {
|
||||
lock();
|
||||
aquire();
|
||||
|
||||
int stop = (repeated) ? 0 : 1;
|
||||
int read = i2c_read(&_i2c, address, data, length, stop);
|
||||
|
||||
unlock();
|
||||
return length != read;
|
||||
}
|
||||
|
||||
int I2C::read(int ack) {
|
||||
lock();
|
||||
int ret;
|
||||
if (ack) {
|
||||
ret = i2c_byte_read(&_i2c, 0);
|
||||
} else {
|
||||
ret = i2c_byte_read(&_i2c, 1);
|
||||
}
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void I2C::start(void) {
|
||||
lock();
|
||||
i2c_start(&_i2c);
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2C::stop(void) {
|
||||
lock();
|
||||
i2c_stop(&_i2c);
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2C::lock() {
|
||||
_mutex->lock();
|
||||
}
|
||||
|
||||
void I2C::unlock() {
|
||||
_mutex->unlock();
|
||||
}
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
|
||||
int I2C::transfer(int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t& callback, int event, bool repeated)
|
||||
{
|
||||
lock();
|
||||
if (i2c_active(&_i2c)) {
|
||||
unlock();
|
||||
return -1; // transaction ongoing
|
||||
}
|
||||
sleep_manager_lock_deep_sleep();
|
||||
aquire();
|
||||
|
||||
_callback = callback;
|
||||
int stop = (repeated) ? 0 : 1;
|
||||
_irq.callback(&I2C::irq_handler_asynch);
|
||||
i2c_transfer_asynch(&_i2c, (void *)tx_buffer, tx_length, (void *)rx_buffer, rx_length, address, stop, _irq.entry(), event, _usage);
|
||||
unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void I2C::abort_transfer(void)
|
||||
{
|
||||
lock();
|
||||
i2c_abort_asynch(&_i2c);
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2C::irq_handler_asynch(void)
|
||||
{
|
||||
int event = i2c_irq_handler_asynch(&_i2c);
|
||||
if (_callback && event) {
|
||||
_callback.call(event);
|
||||
}
|
||||
if (event) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
199
NPR_14/mbed-os/drivers/I2C.h
Normal file
199
NPR_14/mbed-os/drivers/I2C.h
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2015 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_I2C_H
|
||||
#define MBED_I2C_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_I2C) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/i2c_api.h"
|
||||
#include "platform/SingletonPtr.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
#include "platform/CThunk.h"
|
||||
#include "hal/dma_api.h"
|
||||
#include "platform/FunctionPointer.h"
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** An I2C Master, used for communicating with I2C slave devices
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Read from I2C slave at address 0x62
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* I2C i2c(p28, p27);
|
||||
*
|
||||
* int main() {
|
||||
* int address = 0x62;
|
||||
* char data[2];
|
||||
* i2c.read(address, data, 2);
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class I2C : private NonCopyable<I2C> {
|
||||
|
||||
public:
|
||||
enum RxStatus {
|
||||
NoData,
|
||||
MasterGeneralCall,
|
||||
MasterWrite,
|
||||
MasterRead
|
||||
};
|
||||
|
||||
enum Acknowledge {
|
||||
NoACK = 0,
|
||||
ACK = 1
|
||||
};
|
||||
|
||||
/** Create an I2C Master interface, connected to the specified pins
|
||||
*
|
||||
* @param sda I2C data line pin
|
||||
* @param scl I2C clock line pin
|
||||
*/
|
||||
I2C(PinName sda, PinName scl);
|
||||
|
||||
/** Set the frequency of the I2C interface
|
||||
*
|
||||
* @param hz The bus frequency in hertz
|
||||
*/
|
||||
void frequency(int hz);
|
||||
|
||||
/** Read from an I2C slave
|
||||
*
|
||||
* Performs a complete read transaction. The bottom bit of
|
||||
* the address is forced to 1 to indicate a read.
|
||||
*
|
||||
* @param address 8-bit I2C slave address [ addr | 1 ]
|
||||
* @param data Pointer to the byte-array to read data in to
|
||||
* @param length Number of bytes to read
|
||||
* @param repeated Repeated start, true - don't send stop at end
|
||||
*
|
||||
* @returns
|
||||
* 0 on success (ack),
|
||||
* non-0 on failure (nack)
|
||||
*/
|
||||
int read(int address, char *data, int length, bool repeated = false);
|
||||
|
||||
/** Read a single byte from the I2C bus
|
||||
*
|
||||
* @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
|
||||
*
|
||||
* @returns
|
||||
* the byte read
|
||||
*/
|
||||
int read(int ack);
|
||||
|
||||
/** Write to an I2C slave
|
||||
*
|
||||
* Performs a complete write transaction. The bottom bit of
|
||||
* the address is forced to 0 to indicate a write.
|
||||
*
|
||||
* @param address 8-bit I2C slave address [ addr | 0 ]
|
||||
* @param data Pointer to the byte-array data to send
|
||||
* @param length Number of bytes to send
|
||||
* @param repeated Repeated start, true - do not send stop at end
|
||||
*
|
||||
* @returns
|
||||
* 0 on success (ack),
|
||||
* non-0 on failure (nack)
|
||||
*/
|
||||
int write(int address, const char *data, int length, bool repeated = false);
|
||||
|
||||
/** Write single byte out on the I2C bus
|
||||
*
|
||||
* @param data data to write out on bus
|
||||
*
|
||||
* @returns
|
||||
* '0' - NAK was received
|
||||
* '1' - ACK was received,
|
||||
* '2' - timeout
|
||||
*/
|
||||
int write(int data);
|
||||
|
||||
/** Creates a start condition on the I2C bus
|
||||
*/
|
||||
|
||||
void start(void);
|
||||
|
||||
/** Creates a stop condition on the I2C bus
|
||||
*/
|
||||
void stop(void);
|
||||
|
||||
/** Acquire exclusive access to this I2C bus
|
||||
*/
|
||||
virtual void lock(void);
|
||||
|
||||
/** Release exclusive access to this I2C bus
|
||||
*/
|
||||
virtual void unlock(void);
|
||||
|
||||
virtual ~I2C() {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
#if DEVICE_I2C_ASYNCH
|
||||
|
||||
/** Start non-blocking I2C transfer.
|
||||
*
|
||||
* This function locks the deep sleep until any event has occured
|
||||
*
|
||||
* @param address 8/10 bit I2c slave address
|
||||
* @param tx_buffer The TX buffer with data to be transfered
|
||||
* @param tx_length The length of TX buffer in bytes
|
||||
* @param rx_buffer The RX buffer which is used for received data
|
||||
* @param rx_length The length of RX buffer in bytes
|
||||
* @param event The logical OR of events to modify
|
||||
* @param callback The event callback function
|
||||
* @param repeated Repeated start, true - do not send stop at end
|
||||
* @return Zero if the transfer has started, or -1 if I2C peripheral is busy
|
||||
*/
|
||||
int transfer(int address, const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length, const event_callback_t& callback, int event = I2C_EVENT_TRANSFER_COMPLETE, bool repeated = false);
|
||||
|
||||
/** Abort the on-going I2C transfer
|
||||
*/
|
||||
void abort_transfer();
|
||||
protected:
|
||||
void irq_handler_asynch(void);
|
||||
event_callback_t _callback;
|
||||
CThunk<I2C> _irq;
|
||||
DMAUsage _usage;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void aquire();
|
||||
|
||||
i2c_t _i2c;
|
||||
static I2C *_owner;
|
||||
int _hz;
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
63
NPR_14/mbed-os/drivers/I2CSlave.cpp
Normal file
63
NPR_14/mbed-os/drivers/I2CSlave.cpp
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/I2CSlave.h"
|
||||
|
||||
#if DEVICE_I2CSLAVE
|
||||
|
||||
namespace mbed {
|
||||
|
||||
I2CSlave::I2CSlave(PinName sda, PinName scl) : _i2c() {
|
||||
i2c_init(&_i2c, sda, scl);
|
||||
i2c_frequency(&_i2c, 100000);
|
||||
i2c_slave_mode(&_i2c, 1);
|
||||
}
|
||||
|
||||
void I2CSlave::frequency(int hz) {
|
||||
i2c_frequency(&_i2c, hz);
|
||||
}
|
||||
|
||||
void I2CSlave::address(int address) {
|
||||
int addr = (address & 0xFF) | 1;
|
||||
i2c_slave_address(&_i2c, 0, addr, 0);
|
||||
}
|
||||
|
||||
int I2CSlave::receive(void) {
|
||||
return i2c_slave_receive(&_i2c);
|
||||
}
|
||||
|
||||
int I2CSlave::read(char *data, int length) {
|
||||
return i2c_slave_read(&_i2c, data, length) != length;
|
||||
}
|
||||
|
||||
int I2CSlave::read(void) {
|
||||
return i2c_byte_read(&_i2c, 0);
|
||||
}
|
||||
|
||||
int I2CSlave::write(const char *data, int length) {
|
||||
return i2c_slave_write(&_i2c, data, length) != length;
|
||||
}
|
||||
|
||||
int I2CSlave::write(int data) {
|
||||
return i2c_byte_write(&_i2c, data);
|
||||
}
|
||||
|
||||
void I2CSlave::stop(void) {
|
||||
i2c_stop(&_i2c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
158
NPR_14/mbed-os/drivers/I2CSlave.h
Normal file
158
NPR_14/mbed-os/drivers/I2CSlave.h
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_I2C_SLAVE_H
|
||||
#define MBED_I2C_SLAVE_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_I2CSLAVE) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/i2c_api.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** An I2C Slave, used for communicating with an I2C Master device
|
||||
*
|
||||
* @note Synchronization level: Not protected
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Simple I2C responder
|
||||
* #include <mbed.h>
|
||||
*
|
||||
* I2CSlave slave(p9, p10);
|
||||
*
|
||||
* int main() {
|
||||
* char buf[10];
|
||||
* char msg[] = "Slave!";
|
||||
*
|
||||
* slave.address(0xA0);
|
||||
* while (1) {
|
||||
* int i = slave.receive();
|
||||
* switch (i) {
|
||||
* case I2CSlave::ReadAddressed:
|
||||
* slave.write(msg, strlen(msg) + 1); // Includes null char
|
||||
* break;
|
||||
* case I2CSlave::WriteGeneral:
|
||||
* slave.read(buf, 10);
|
||||
* printf("Read G: %s\n", buf);
|
||||
* break;
|
||||
* case I2CSlave::WriteAddressed:
|
||||
* slave.read(buf, 10);
|
||||
* printf("Read A: %s\n", buf);
|
||||
* break;
|
||||
* }
|
||||
* for(int i = 0; i < 10; i++) buf[i] = 0; // Clear buffer
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class I2CSlave {
|
||||
|
||||
public:
|
||||
enum RxStatus {
|
||||
NoData = 0,
|
||||
ReadAddressed = 1,
|
||||
WriteGeneral = 2,
|
||||
WriteAddressed = 3
|
||||
};
|
||||
|
||||
/** Create an I2C Slave interface, connected to the specified pins.
|
||||
*
|
||||
* @param sda I2C data line pin
|
||||
* @param scl I2C clock line pin
|
||||
*/
|
||||
I2CSlave(PinName sda, PinName scl);
|
||||
|
||||
/** Set the frequency of the I2C interface
|
||||
*
|
||||
* @param hz The bus frequency in hertz
|
||||
*/
|
||||
void frequency(int hz);
|
||||
|
||||
/** Checks to see if this I2C Slave has been addressed.
|
||||
*
|
||||
* @returns
|
||||
* A status indicating if the device has been addressed, and how
|
||||
* - NoData - the slave has not been addressed
|
||||
* - ReadAddressed - the master has requested a read from this slave
|
||||
* - WriteAddressed - the master is writing to this slave
|
||||
* - WriteGeneral - the master is writing to all slave
|
||||
*/
|
||||
int receive(void);
|
||||
|
||||
/** Read from an I2C master.
|
||||
*
|
||||
* @param data pointer to the byte array to read data in to
|
||||
* @param length maximum number of bytes to read
|
||||
*
|
||||
* @returns
|
||||
* 0 on success,
|
||||
* non-0 otherwise
|
||||
*/
|
||||
int read(char *data, int length);
|
||||
|
||||
/** Read a single byte from an I2C master.
|
||||
*
|
||||
* @returns
|
||||
* the byte read
|
||||
*/
|
||||
int read(void);
|
||||
|
||||
/** Write to an I2C master.
|
||||
*
|
||||
* @param data pointer to the byte array to be transmitted
|
||||
* @param length the number of bytes to transmite
|
||||
*
|
||||
* @returns
|
||||
* 0 on success,
|
||||
* non-0 otherwise
|
||||
*/
|
||||
int write(const char *data, int length);
|
||||
|
||||
/** Write a single byte to an I2C master.
|
||||
*
|
||||
* @param data the byte to write
|
||||
*
|
||||
* @returns
|
||||
* '1' if an ACK was received,
|
||||
* '0' otherwise
|
||||
*/
|
||||
int write(int data);
|
||||
|
||||
/** Sets the I2C slave address.
|
||||
*
|
||||
* @param address The address to set for the slave (ignoring the least
|
||||
* signifcant bit). If set to 0, the slave will only respond to the
|
||||
* general call address.
|
||||
*/
|
||||
void address(int address);
|
||||
|
||||
/** Reset the I2C slave back into the known ready receiving state.
|
||||
*/
|
||||
void stop(void);
|
||||
|
||||
protected:
|
||||
i2c_t _i2c;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
108
NPR_14/mbed-os/drivers/InterruptIn.cpp
Normal file
108
NPR_14/mbed-os/drivers/InterruptIn.cpp
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/InterruptIn.h"
|
||||
|
||||
#if DEVICE_INTERRUPTIN
|
||||
|
||||
namespace mbed {
|
||||
|
||||
InterruptIn::InterruptIn(PinName pin) : gpio(),
|
||||
gpio_irq(),
|
||||
_rise(NULL),
|
||||
_fall(NULL) {
|
||||
// No lock needed in the constructor
|
||||
|
||||
gpio_irq_init(&gpio_irq, pin, (&InterruptIn::_irq_handler), (uint32_t)this);
|
||||
gpio_init_in(&gpio, pin);
|
||||
}
|
||||
|
||||
InterruptIn::~InterruptIn() {
|
||||
// No lock needed in the destructor
|
||||
gpio_irq_free(&gpio_irq);
|
||||
}
|
||||
|
||||
int InterruptIn::read() {
|
||||
// Read only
|
||||
return gpio_read(&gpio);
|
||||
}
|
||||
|
||||
void InterruptIn::mode(PinMode pull) {
|
||||
core_util_critical_section_enter();
|
||||
gpio_mode(&gpio, pull);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void InterruptIn::rise(Callback<void()> func) {
|
||||
core_util_critical_section_enter();
|
||||
if (func) {
|
||||
_rise = func;
|
||||
gpio_irq_set(&gpio_irq, IRQ_RISE, 1);
|
||||
} else {
|
||||
_rise = NULL;
|
||||
gpio_irq_set(&gpio_irq, IRQ_RISE, 0);
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void InterruptIn::fall(Callback<void()> func) {
|
||||
core_util_critical_section_enter();
|
||||
if (func) {
|
||||
_fall = func;
|
||||
gpio_irq_set(&gpio_irq, IRQ_FALL, 1);
|
||||
} else {
|
||||
_fall = NULL;
|
||||
gpio_irq_set(&gpio_irq, IRQ_FALL, 0);
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void InterruptIn::_irq_handler(uint32_t id, gpio_irq_event event) {
|
||||
InterruptIn *handler = (InterruptIn*)id;
|
||||
switch (event) {
|
||||
case IRQ_RISE:
|
||||
if (handler->_rise) {
|
||||
handler->_rise();
|
||||
}
|
||||
break;
|
||||
case IRQ_FALL:
|
||||
if (handler->_fall) {
|
||||
handler->_fall();
|
||||
}
|
||||
break;
|
||||
case IRQ_NONE: break;
|
||||
}
|
||||
}
|
||||
|
||||
void InterruptIn::enable_irq() {
|
||||
core_util_critical_section_enter();
|
||||
gpio_irq_enable(&gpio_irq);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void InterruptIn::disable_irq() {
|
||||
core_util_critical_section_enter();
|
||||
gpio_irq_disable(&gpio_irq);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
InterruptIn::operator int() {
|
||||
// Underlying call is atomic
|
||||
return read();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
162
NPR_14/mbed-os/drivers/InterruptIn.h
Normal file
162
NPR_14/mbed-os/drivers/InterruptIn.h
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_INTERRUPTIN_H
|
||||
#define MBED_INTERRUPTIN_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/gpio_api.h"
|
||||
#include "hal/gpio_irq_api.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A digital interrupt input, used to call a function on a rising or falling edge
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Flash an LED while waiting for events
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* InterruptIn event(p16);
|
||||
* DigitalOut led(LED1);
|
||||
*
|
||||
* void trigger() {
|
||||
* printf("triggered!\n");
|
||||
* }
|
||||
*
|
||||
* int main() {
|
||||
* event.rise(&trigger);
|
||||
* while(1) {
|
||||
* led = !led;
|
||||
* wait(0.25);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class InterruptIn : private NonCopyable<InterruptIn> {
|
||||
|
||||
public:
|
||||
|
||||
/** Create an InterruptIn connected to the specified pin
|
||||
*
|
||||
* @param pin InterruptIn pin to connect to
|
||||
*/
|
||||
InterruptIn(PinName pin);
|
||||
virtual ~InterruptIn();
|
||||
|
||||
/** Read the input, represented as 0 or 1 (int)
|
||||
*
|
||||
* @returns
|
||||
* An integer representing the state of the input pin,
|
||||
* 0 for logical 0, 1 for logical 1
|
||||
*/
|
||||
int read();
|
||||
|
||||
/** An operator shorthand for read()
|
||||
*/
|
||||
operator int();
|
||||
|
||||
|
||||
/** Attach a function to call when a rising edge occurs on the input
|
||||
*
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
*/
|
||||
void rise(Callback<void()> func);
|
||||
|
||||
/** Attach a member function to call when a rising edge occurs on the input
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @deprecated
|
||||
* The rise function does not support cv-qualifiers. Replaced by
|
||||
* rise(callback(obj, method)).
|
||||
*/
|
||||
template<typename T, typename M>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The rise function does not support cv-qualifiers. Replaced by "
|
||||
"rise(callback(obj, method)).")
|
||||
void rise(T *obj, M method) {
|
||||
core_util_critical_section_enter();
|
||||
rise(callback(obj, method));
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Attach a function to call when a falling edge occurs on the input
|
||||
*
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
*/
|
||||
void fall(Callback<void()> func);
|
||||
|
||||
/** Attach a member function to call when a falling edge occurs on the input
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @deprecated
|
||||
* The rise function does not support cv-qualifiers. Replaced by
|
||||
* rise(callback(obj, method)).
|
||||
*/
|
||||
template<typename T, typename M>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The fall function does not support cv-qualifiers. Replaced by "
|
||||
"fall(callback(obj, method)).")
|
||||
void fall(T *obj, M method) {
|
||||
core_util_critical_section_enter();
|
||||
fall(callback(obj, method));
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the input pin mode
|
||||
*
|
||||
* @param pull PullUp, PullDown, PullNone
|
||||
*/
|
||||
void mode(PinMode pull);
|
||||
|
||||
/** Enable IRQ. This method depends on hw implementation, might enable one
|
||||
* port interrupts. For further information, check gpio_irq_enable().
|
||||
*/
|
||||
void enable_irq();
|
||||
|
||||
/** Disable IRQ. This method depends on hw implementation, might disable one
|
||||
* port interrupts. For further information, check gpio_irq_disable().
|
||||
*/
|
||||
void disable_irq();
|
||||
|
||||
static void _irq_handler(uint32_t id, gpio_irq_event event);
|
||||
|
||||
protected:
|
||||
gpio_t gpio;
|
||||
gpio_irq_t gpio_irq;
|
||||
|
||||
Callback<void()> _rise;
|
||||
Callback<void()> _fall;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
137
NPR_14/mbed-os/drivers/InterruptManager.cpp
Normal file
137
NPR_14/mbed-os/drivers/InterruptManager.cpp
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "cmsis.h"
|
||||
#if defined(NVIC_NUM_VECTORS)
|
||||
|
||||
#include "drivers/InterruptManager.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include <string.h>
|
||||
|
||||
#define CHAIN_INITIAL_SIZE 4
|
||||
|
||||
namespace mbed {
|
||||
|
||||
typedef void (*pvoidf)(void);
|
||||
|
||||
InterruptManager* InterruptManager::_instance = (InterruptManager*)NULL;
|
||||
|
||||
InterruptManager* InterruptManager::get() {
|
||||
|
||||
if (NULL == _instance) {
|
||||
InterruptManager* temp = new InterruptManager();
|
||||
|
||||
// Atomically set _instance
|
||||
core_util_critical_section_enter();
|
||||
if (NULL == _instance) {
|
||||
_instance = temp;
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
|
||||
// Another thread got there first so delete ours
|
||||
if (temp != _instance) {
|
||||
delete temp;
|
||||
}
|
||||
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
InterruptManager::InterruptManager() {
|
||||
// No mutex needed in constructor
|
||||
memset(_chains, 0, NVIC_NUM_VECTORS * sizeof(CallChain*));
|
||||
}
|
||||
|
||||
void InterruptManager::destroy() {
|
||||
// Not a good idea to call this unless NO interrupt at all
|
||||
// is under the control of the handler; otherwise, a system crash
|
||||
// is very likely to occur
|
||||
if (NULL != _instance) {
|
||||
delete _instance;
|
||||
_instance = (InterruptManager*)NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InterruptManager::~InterruptManager() {
|
||||
for(int i = 0; i < NVIC_NUM_VECTORS; i++)
|
||||
if (NULL != _chains[i])
|
||||
delete _chains[i];
|
||||
}
|
||||
|
||||
bool InterruptManager::must_replace_vector(IRQn_Type irq) {
|
||||
lock();
|
||||
|
||||
int ret = false;
|
||||
int irq_pos = get_irq_index(irq);
|
||||
if (NULL == _chains[irq_pos]) {
|
||||
_chains[irq_pos] = new CallChain(CHAIN_INITIAL_SIZE);
|
||||
_chains[irq_pos]->add((pvoidf)NVIC_GetVector(irq));
|
||||
ret = true;
|
||||
}
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) {
|
||||
lock();
|
||||
int irq_pos = get_irq_index(irq);
|
||||
bool change = must_replace_vector(irq);
|
||||
|
||||
pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function);
|
||||
if (change)
|
||||
NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
|
||||
unlock();
|
||||
return pf;
|
||||
}
|
||||
|
||||
bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq) {
|
||||
int irq_pos = get_irq_index(irq);
|
||||
bool ret = false;
|
||||
|
||||
lock();
|
||||
if (_chains[irq_pos] != NULL) {
|
||||
if (_chains[irq_pos]->remove(handler)) {
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void InterruptManager::irq_helper() {
|
||||
_chains[__get_IPSR()]->call();
|
||||
}
|
||||
|
||||
int InterruptManager::get_irq_index(IRQn_Type irq) {
|
||||
// Pure function - no lock needed
|
||||
return (int)irq + NVIC_USER_IRQ_OFFSET;
|
||||
}
|
||||
|
||||
void InterruptManager::static_irq_helper() {
|
||||
InterruptManager::get()->irq_helper();
|
||||
}
|
||||
|
||||
void InterruptManager::lock() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void InterruptManager::unlock() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
169
NPR_14/mbed-os/drivers/InterruptManager.h
Normal file
169
NPR_14/mbed-os/drivers/InterruptManager.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_INTERRUPTMANAGER_H
|
||||
#define MBED_INTERRUPTMANAGER_H
|
||||
|
||||
#include "cmsis.h"
|
||||
#include "platform/CallChain.h"
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include <string.h>
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** Use this singleton if you need to chain interrupt handlers.
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* Example (for LPC1768):
|
||||
* @code
|
||||
* #include "InterruptManager.h"
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Ticker flipper;
|
||||
* DigitalOut led1(LED1);
|
||||
* DigitalOut led2(LED2);
|
||||
*
|
||||
* void flip(void) {
|
||||
* led1 = !led1;
|
||||
* }
|
||||
*
|
||||
* void handler(void) {
|
||||
* led2 = !led1;
|
||||
* }
|
||||
*
|
||||
* int main() {
|
||||
* led1 = led2 = 0;
|
||||
* flipper.attach(&flip, 1.0);
|
||||
* InterruptManager::get()->add_handler(handler, TIMER3_IRQn);
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class InterruptManager : private NonCopyable<InterruptManager> {
|
||||
public:
|
||||
/** Get the instance of InterruptManager Class
|
||||
*
|
||||
* @return the only instance of this class
|
||||
*/
|
||||
static InterruptManager* get();
|
||||
|
||||
/** Destroy the current instance of the interrupt manager
|
||||
*/
|
||||
static void destroy();
|
||||
|
||||
/** Add a handler for an interrupt at the end of the handler list
|
||||
*
|
||||
* @param function the handler to add
|
||||
* @param irq interrupt number
|
||||
*
|
||||
* @returns
|
||||
* The function object created for 'function'
|
||||
*/
|
||||
pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) {
|
||||
// Underlying call is thread safe
|
||||
return add_common(function, irq);
|
||||
}
|
||||
|
||||
/** Add a handler for an interrupt at the beginning of the handler list
|
||||
*
|
||||
* @param function the handler to add
|
||||
* @param irq interrupt number
|
||||
*
|
||||
* @returns
|
||||
* The function object created for 'function'
|
||||
*/
|
||||
pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) {
|
||||
// Underlying call is thread safe
|
||||
return add_common(function, irq, true);
|
||||
}
|
||||
|
||||
/** Add a handler for an interrupt at the end of the handler list
|
||||
*
|
||||
* @param tptr pointer to the object that has the handler function
|
||||
* @param mptr pointer to the actual handler function
|
||||
* @param irq interrupt number
|
||||
*
|
||||
* @returns
|
||||
* The function object created for 'tptr' and 'mptr'
|
||||
*/
|
||||
template<typename T>
|
||||
pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
|
||||
// Underlying call is thread safe
|
||||
return add_common(tptr, mptr, irq);
|
||||
}
|
||||
|
||||
/** Add a handler for an interrupt at the beginning of the handler list
|
||||
*
|
||||
* @param tptr pointer to the object that has the handler function
|
||||
* @param mptr pointer to the actual handler function
|
||||
* @param irq interrupt number
|
||||
*
|
||||
* @returns
|
||||
* The function object created for 'tptr' and 'mptr'
|
||||
*/
|
||||
template<typename T>
|
||||
pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
|
||||
// Underlying call is thread safe
|
||||
return add_common(tptr, mptr, irq, true);
|
||||
}
|
||||
|
||||
/** Remove a handler from an interrupt
|
||||
*
|
||||
* @param handler the function object for the handler to remove
|
||||
* @param irq the interrupt number
|
||||
*
|
||||
* @returns
|
||||
* true if the handler was found and removed, false otherwise
|
||||
*/
|
||||
bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq);
|
||||
|
||||
private:
|
||||
InterruptManager();
|
||||
~InterruptManager();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
template<typename T>
|
||||
pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) {
|
||||
_mutex.lock();
|
||||
int irq_pos = get_irq_index(irq);
|
||||
bool change = must_replace_vector(irq);
|
||||
|
||||
pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr);
|
||||
if (change)
|
||||
NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
|
||||
_mutex.unlock();
|
||||
return pf;
|
||||
}
|
||||
|
||||
pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false);
|
||||
bool must_replace_vector(IRQn_Type irq);
|
||||
int get_irq_index(IRQn_Type irq);
|
||||
void irq_helper();
|
||||
void add_helper(void (*function)(void), IRQn_Type irq, bool front=false);
|
||||
static void static_irq_helper();
|
||||
|
||||
CallChain* _chains[NVIC_NUM_VECTORS];
|
||||
static InterruptManager* _instance;
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
49
NPR_14/mbed-os/drivers/LowPowerTicker.h
Normal file
49
NPR_14/mbed-os/drivers/LowPowerTicker.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_LOWPOWERTICKER_H
|
||||
#define MBED_LOWPOWERTICKER_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "drivers/Ticker.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if defined (DEVICE_LOWPOWERTIMER) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/lp_ticker_api.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** Low Power Ticker
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class LowPowerTicker : public Ticker, private NonCopyable<LowPowerTicker> {
|
||||
|
||||
public:
|
||||
LowPowerTicker() : Ticker(get_lp_ticker_data()) {
|
||||
}
|
||||
|
||||
virtual ~LowPowerTicker() {
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
NPR_14/mbed-os/drivers/LowPowerTimeout.h
Normal file
47
NPR_14/mbed-os/drivers/LowPowerTimeout.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_LOWPOWERTIMEOUT_H
|
||||
#define MBED_LOWPOWERTIMEOUT_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_LOWPOWERTIMER) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/lp_ticker_api.h"
|
||||
#include "drivers/LowPowerTicker.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** Low Power Timout
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class LowPowerTimeout : public LowPowerTicker, private NonCopyable<LowPowerTimeout> {
|
||||
|
||||
private:
|
||||
virtual void handler(void) {
|
||||
_function.call();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
47
NPR_14/mbed-os/drivers/LowPowerTimer.h
Normal file
47
NPR_14/mbed-os/drivers/LowPowerTimer.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2015 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_LOWPOWERTIMER_H
|
||||
#define MBED_LOWPOWERTIMER_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "drivers/Timer.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if defined (DEVICE_LOWPOWERTIMER) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/lp_ticker_api.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** Low power timer
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class LowPowerTimer : public Timer, private NonCopyable<LowPowerTimer> {
|
||||
|
||||
public:
|
||||
LowPowerTimer() : Timer(get_lp_ticker_data()) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
102
NPR_14/mbed-os/drivers/PortIn.h
Normal file
102
NPR_14/mbed-os/drivers/PortIn.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_PORTIN_H
|
||||
#define MBED_PORTIN_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_PORTIN) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/port_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A multiple pin digital input
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Switch on an LED if any of mbed pins 21-26 is high
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* PortIn p(Port2, 0x0000003F); // p21-p26
|
||||
* DigitalOut ind(LED4);
|
||||
*
|
||||
* int main() {
|
||||
* while(1) {
|
||||
* int pins = p.read();
|
||||
* if(pins) {
|
||||
* ind = 1;
|
||||
* } else {
|
||||
* ind = 0;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class PortIn {
|
||||
public:
|
||||
|
||||
/** Create an PortIn, connected to the specified port
|
||||
*
|
||||
* @param port Port to connect to (Port0-Port5)
|
||||
* @param mask A bitmask to identify which bits in the port should be included (0 - ignore)
|
||||
*/
|
||||
PortIn(PortName port, int mask = 0xFFFFFFFF) {
|
||||
core_util_critical_section_enter();
|
||||
port_init(&_port, port, mask, PIN_INPUT);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Read the value currently output on the port
|
||||
*
|
||||
* @returns
|
||||
* An integer with each bit corresponding to associated port pin setting
|
||||
*/
|
||||
int read() {
|
||||
return port_read(&_port);
|
||||
}
|
||||
|
||||
/** Set the input pin mode
|
||||
*
|
||||
* @param mode PullUp, PullDown, PullNone, OpenDrain
|
||||
*/
|
||||
void mode(PinMode mode) {
|
||||
core_util_critical_section_enter();
|
||||
port_mode(&_port, mode);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** A shorthand for read()
|
||||
*/
|
||||
operator int() {
|
||||
return read();
|
||||
}
|
||||
|
||||
private:
|
||||
port_t _port;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
122
NPR_14/mbed-os/drivers/PortInOut.h
Normal file
122
NPR_14/mbed-os/drivers/PortInOut.h
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_PORTINOUT_H
|
||||
#define MBED_PORTINOUT_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_PORTINOUT) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/port_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A multiple pin digital in/out used to set/read multiple bi-directional pins
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class PortInOut {
|
||||
public:
|
||||
|
||||
/** Create an PortInOut, connected to the specified port
|
||||
*
|
||||
* @param port Port to connect to (Port0-Port5)
|
||||
* @param mask A bitmask to identify which bits in the port should be included (0 - ignore)
|
||||
*/
|
||||
PortInOut(PortName port, int mask = 0xFFFFFFFF) {
|
||||
core_util_critical_section_enter();
|
||||
port_init(&_port, port, mask, PIN_INPUT);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Write the value to the output port
|
||||
*
|
||||
* @param value An integer specifying a bit to write for every corresponding port pin
|
||||
*/
|
||||
void write(int value) {
|
||||
port_write(&_port, value);
|
||||
}
|
||||
|
||||
/** Read the value currently output on the port
|
||||
*
|
||||
* @returns
|
||||
* An integer with each bit corresponding to associated port pin setting
|
||||
*/
|
||||
int read() {
|
||||
return port_read(&_port);
|
||||
}
|
||||
|
||||
/** Set as an output
|
||||
*/
|
||||
void output() {
|
||||
core_util_critical_section_enter();
|
||||
port_dir(&_port, PIN_OUTPUT);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set as an input
|
||||
*/
|
||||
void input() {
|
||||
core_util_critical_section_enter();
|
||||
port_dir(&_port, PIN_INPUT);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the input pin mode
|
||||
*
|
||||
* @param mode PullUp, PullDown, PullNone, OpenDrain
|
||||
*/
|
||||
void mode(PinMode mode) {
|
||||
core_util_critical_section_enter();
|
||||
port_mode(&_port, mode);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa PortInOut::write()
|
||||
*/
|
||||
PortInOut& operator= (int value) {
|
||||
write(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa PortInOut::write()
|
||||
*/
|
||||
PortInOut& operator= (PortInOut& rhs) {
|
||||
write(rhs.read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa PortInOut::read()
|
||||
*/
|
||||
operator int() {
|
||||
return read();
|
||||
}
|
||||
|
||||
private:
|
||||
port_t _port;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
116
NPR_14/mbed-os/drivers/PortOut.h
Normal file
116
NPR_14/mbed-os/drivers/PortOut.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_PORTOUT_H
|
||||
#define MBED_PORTOUT_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_PORTOUT) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/port_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
/** A multiple pin digital out
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Toggle all four LEDs
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* // LED1 = P1.18 LED2 = P1.20 LED3 = P1.21 LED4 = P1.23
|
||||
* #define LED_MASK 0x00B40000
|
||||
*
|
||||
* PortOut ledport(Port1, LED_MASK);
|
||||
*
|
||||
* int main() {
|
||||
* while(1) {
|
||||
* ledport = LED_MASK;
|
||||
* wait(1);
|
||||
* ledport = 0;
|
||||
* wait(1);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class PortOut {
|
||||
public:
|
||||
|
||||
/** Create an PortOut, connected to the specified port
|
||||
*
|
||||
* @param port Port to connect to (Port0-Port5)
|
||||
* @param mask A bitmask to identify which bits in the port should be included (0 - ignore)
|
||||
*/
|
||||
PortOut(PortName port, int mask = 0xFFFFFFFF) {
|
||||
core_util_critical_section_enter();
|
||||
port_init(&_port, port, mask, PIN_OUTPUT);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Write the value to the output port
|
||||
*
|
||||
* @param value An integer specifying a bit to write for every corresponding PortOut pin
|
||||
*/
|
||||
void write(int value) {
|
||||
port_write(&_port, value);
|
||||
}
|
||||
|
||||
/** Read the value currently output on the port
|
||||
*
|
||||
* @returns
|
||||
* An integer with each bit corresponding to associated PortOut pin setting
|
||||
*/
|
||||
int read() {
|
||||
return port_read(&_port);
|
||||
}
|
||||
|
||||
/** A shorthand for write()
|
||||
* \sa PortOut::write()
|
||||
*/
|
||||
PortOut& operator= (int value) {
|
||||
write(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa PortOut::read()
|
||||
*/
|
||||
PortOut& operator= (PortOut& rhs) {
|
||||
write(rhs.read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A shorthand for read()
|
||||
* \sa PortOut::read()
|
||||
*/
|
||||
operator int() {
|
||||
return read();
|
||||
}
|
||||
|
||||
private:
|
||||
port_t _port;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
212
NPR_14/mbed-os/drivers/PwmOut.h
Normal file
212
NPR_14/mbed-os/drivers/PwmOut.h
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_PWMOUT_H
|
||||
#define MBED_PWMOUT_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_PWMOUT) || defined(DOXYGEN_ONLY)
|
||||
#include "hal/pwmout_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "platform/mbed_sleep.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A pulse-width modulation digital output
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example
|
||||
* @code
|
||||
* // Fade a led on.
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* PwmOut led(LED1);
|
||||
*
|
||||
* int main() {
|
||||
* while(1) {
|
||||
* led = led + 0.01;
|
||||
* wait(0.2);
|
||||
* if(led == 1.0) {
|
||||
* led = 0;
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class PwmOut {
|
||||
|
||||
public:
|
||||
|
||||
/** Create a PwmOut connected to the specified pin
|
||||
*
|
||||
* @param pin PwmOut pin to connect to
|
||||
*/
|
||||
PwmOut(PinName pin) : _deep_sleep_locked(false) {
|
||||
core_util_critical_section_enter();
|
||||
pwmout_init(&_pwm, pin);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
~PwmOut() {
|
||||
core_util_critical_section_enter();
|
||||
unlock_deep_sleep();
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the ouput duty-cycle, specified as a percentage (float)
|
||||
*
|
||||
* @param value A floating-point value representing the output duty-cycle,
|
||||
* specified as a percentage. The value should lie between
|
||||
* 0.0f (representing on 0%) and 1.0f (representing on 100%).
|
||||
* Values outside this range will be saturated to 0.0f or 1.0f.
|
||||
*/
|
||||
void write(float value) {
|
||||
core_util_critical_section_enter();
|
||||
lock_deep_sleep();
|
||||
pwmout_write(&_pwm, value);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Return the current output duty-cycle setting, measured as a percentage (float)
|
||||
*
|
||||
* @returns
|
||||
* A floating-point value representing the current duty-cycle being output on the pin,
|
||||
* measured as a percentage. The returned value will lie between
|
||||
* 0.0f (representing on 0%) and 1.0f (representing on 100%).
|
||||
*
|
||||
* @note
|
||||
* This value may not match exactly the value set by a previous write().
|
||||
*/
|
||||
float read() {
|
||||
core_util_critical_section_enter();
|
||||
float val = pwmout_read(&_pwm);
|
||||
core_util_critical_section_exit();
|
||||
return val;
|
||||
}
|
||||
|
||||
/** Set the PWM period, specified in seconds (float), keeping the duty cycle the same.
|
||||
*
|
||||
* @param seconds Change the period of a PWM signal in seconds (float) without modifying the duty cycle
|
||||
* @note
|
||||
* The resolution is currently in microseconds; periods smaller than this
|
||||
* will be set to zero.
|
||||
*/
|
||||
void period(float seconds) {
|
||||
core_util_critical_section_enter();
|
||||
pwmout_period(&_pwm, seconds);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the PWM period, specified in milli-seconds (int), keeping the duty cycle the same.
|
||||
* @param ms Change the period of a PWM signal in milli-seconds without modifying the duty cycle
|
||||
*/
|
||||
void period_ms(int ms) {
|
||||
core_util_critical_section_enter();
|
||||
pwmout_period_ms(&_pwm, ms);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the PWM period, specified in micro-seconds (int), keeping the duty cycle the same.
|
||||
* @param us Change the period of a PWM signal in micro-seconds without modifying the duty cycle
|
||||
*/
|
||||
void period_us(int us) {
|
||||
core_util_critical_section_enter();
|
||||
pwmout_period_us(&_pwm, us);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the PWM pulsewidth, specified in seconds (float), keeping the period the same.
|
||||
* @param seconds Change the pulse width of a PWM signal specified in seconds (float)
|
||||
*/
|
||||
void pulsewidth(float seconds) {
|
||||
core_util_critical_section_enter();
|
||||
pwmout_pulsewidth(&_pwm, seconds);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the PWM pulsewidth, specified in milli-seconds (int), keeping the period the same.
|
||||
* @param ms Change the pulse width of a PWM signal specified in milli-seconds
|
||||
*/
|
||||
void pulsewidth_ms(int ms) {
|
||||
core_util_critical_section_enter();
|
||||
pwmout_pulsewidth_ms(&_pwm, ms);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Set the PWM pulsewidth, specified in micro-seconds (int), keeping the period the same.
|
||||
* @param us Change the pulse width of a PWM signal specified in micro-seconds
|
||||
*/
|
||||
void pulsewidth_us(int us) {
|
||||
core_util_critical_section_enter();
|
||||
pwmout_pulsewidth_us(&_pwm, us);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** A operator shorthand for write()
|
||||
* \sa PwmOut::write()
|
||||
*/
|
||||
PwmOut& operator= (float value) {
|
||||
// Underlying call is thread safe
|
||||
write(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** A operator shorthand for write()
|
||||
* \sa PwmOut::write()
|
||||
*/
|
||||
PwmOut& operator= (PwmOut& rhs) {
|
||||
// Underlying call is thread safe
|
||||
write(rhs.read());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/** An operator shorthand for read()
|
||||
* \sa PwmOut::read()
|
||||
*/
|
||||
operator float() {
|
||||
// Underlying call is thread safe
|
||||
return read();
|
||||
}
|
||||
|
||||
protected:
|
||||
/** Lock deep sleep only if it is not yet locked */
|
||||
void lock_deep_sleep() {
|
||||
if (_deep_sleep_locked == false) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
_deep_sleep_locked = true;
|
||||
}
|
||||
}
|
||||
|
||||
/** Unlock deep sleep in case it is locked */
|
||||
void unlock_deep_sleep() {
|
||||
if (_deep_sleep_locked == true) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
_deep_sleep_locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
pwmout_t _pwm;
|
||||
bool _deep_sleep_locked;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
95
NPR_14/mbed-os/drivers/RawSerial.cpp
Normal file
95
NPR_14/mbed-os/drivers/RawSerial.cpp
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/RawSerial.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include <stdio.h>
|
||||
#include <cstdarg>
|
||||
|
||||
|
||||
#if DEVICE_SERIAL
|
||||
|
||||
#define STRING_STACK_LIMIT 120
|
||||
|
||||
namespace mbed {
|
||||
|
||||
RawSerial::RawSerial(PinName tx, PinName rx, int baud) : SerialBase(tx, rx, baud) {
|
||||
// No lock needed in the constructor
|
||||
}
|
||||
|
||||
int RawSerial::getc() {
|
||||
lock();
|
||||
int ret = _base_getc();
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int RawSerial::putc(int c) {
|
||||
lock();
|
||||
int ret = _base_putc(c);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int RawSerial::puts(const char *str) {
|
||||
lock();
|
||||
while (*str)
|
||||
putc(*str ++);
|
||||
unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Experimental support for printf in RawSerial. No Stream inheritance
|
||||
// means we can't call printf() directly, so we use sprintf() instead.
|
||||
// We only call malloc() for the sprintf() buffer if the buffer
|
||||
// length is above a certain threshold, otherwise we use just the stack.
|
||||
int RawSerial::printf(const char *format, ...) {
|
||||
lock();
|
||||
std::va_list arg;
|
||||
va_start(arg, format);
|
||||
// ARMCC microlib does not properly handle a size of 0.
|
||||
// As a workaround supply a dummy buffer with a size of 1.
|
||||
char dummy_buf[1];
|
||||
int len = vsnprintf(dummy_buf, sizeof(dummy_buf), format, arg);
|
||||
if (len < STRING_STACK_LIMIT) {
|
||||
char temp[STRING_STACK_LIMIT];
|
||||
vsprintf(temp, format, arg);
|
||||
puts(temp);
|
||||
} else {
|
||||
char *temp = new char[len + 1];
|
||||
vsprintf(temp, format, arg);
|
||||
puts(temp);
|
||||
delete[] temp;
|
||||
}
|
||||
va_end(arg);
|
||||
unlock();
|
||||
return len;
|
||||
}
|
||||
|
||||
/** Acquire exclusive access to this serial port
|
||||
*/
|
||||
void RawSerial::lock() {
|
||||
// No lock used - external synchronization required
|
||||
}
|
||||
|
||||
/** Release exclusive access to this serial port
|
||||
*/
|
||||
void RawSerial::unlock() {
|
||||
// No lock used - external synchronization required
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
106
NPR_14/mbed-os/drivers/RawSerial.h
Normal file
106
NPR_14/mbed-os/drivers/RawSerial.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_RAW_SERIAL_H
|
||||
#define MBED_RAW_SERIAL_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_SERIAL) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "drivers/SerialBase.h"
|
||||
#include "hal/serial_api.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A serial port (UART) for communication with other serial devices
|
||||
* This is a variation of the Serial class that doesn't use streams,
|
||||
* thus making it safe to use in interrupt handlers with the RTOS.
|
||||
*
|
||||
* Can be used for Full Duplex communication, or Simplex by specifying
|
||||
* one pin as NC (Not Connected)
|
||||
*
|
||||
* @note Synchronization level: Not protected
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Send a char to the PC
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* RawSerial pc(USBTX, USBRX);
|
||||
*
|
||||
* int main() {
|
||||
* pc.putc('A');
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class RawSerial: public SerialBase, private NonCopyable<RawSerial> {
|
||||
|
||||
public:
|
||||
/** Create a RawSerial port, connected to the specified transmit and receive pins, with the specified baud.
|
||||
*
|
||||
* @param tx Transmit pin
|
||||
* @param rx Receive pin
|
||||
* @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
|
||||
*
|
||||
* @note
|
||||
* Either tx or rx may be specified as NC if unused
|
||||
*/
|
||||
RawSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
|
||||
/** Write a char to the serial port
|
||||
*
|
||||
* @param c The char to write
|
||||
*
|
||||
* @returns The written char or -1 if an error occured
|
||||
*/
|
||||
int putc(int c);
|
||||
|
||||
/** Read a char from the serial port
|
||||
*
|
||||
* @returns The char read from the serial port
|
||||
*/
|
||||
int getc();
|
||||
|
||||
/** Write a string to the serial port
|
||||
*
|
||||
* @param str The string to write
|
||||
*
|
||||
* @returns 0 if the write succeeds, EOF for error
|
||||
*/
|
||||
int puts(const char *str);
|
||||
|
||||
int printf(const char *format, ...);
|
||||
|
||||
protected:
|
||||
|
||||
/* Acquire exclusive access to this serial port
|
||||
*/
|
||||
virtual void lock(void);
|
||||
|
||||
/* Release exclusive access to this serial port
|
||||
*/
|
||||
virtual void unlock(void);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
258
NPR_14/mbed-os/drivers/SPI.cpp
Normal file
258
NPR_14/mbed-os/drivers/SPI.cpp
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/SPI.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
#include "platform/mbed_sleep.h"
|
||||
#endif
|
||||
|
||||
#if DEVICE_SPI
|
||||
|
||||
namespace mbed {
|
||||
|
||||
#if DEVICE_SPI_ASYNCH && TRANSACTION_QUEUE_SIZE_SPI
|
||||
CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> SPI::_transaction_buffer;
|
||||
#endif
|
||||
|
||||
SPI::SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
|
||||
_spi(),
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
_irq(this),
|
||||
_usage(DMA_USAGE_NEVER),
|
||||
#endif
|
||||
_bits(8),
|
||||
_mode(0),
|
||||
_hz(1000000),
|
||||
_write_fill(SPI_FILL_CHAR) {
|
||||
// No lock needed in the constructor
|
||||
|
||||
spi_init(&_spi, mosi, miso, sclk, ssel);
|
||||
_acquire();
|
||||
}
|
||||
|
||||
void SPI::format(int bits, int mode) {
|
||||
lock();
|
||||
_bits = bits;
|
||||
_mode = mode;
|
||||
// If changing format while you are the owner than just
|
||||
// update format, but if owner is changed than even frequency should be
|
||||
// updated which is done by acquire.
|
||||
if (_owner == this) {
|
||||
spi_format(&_spi, _bits, _mode, 0);
|
||||
} else {
|
||||
_acquire();
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void SPI::frequency(int hz) {
|
||||
lock();
|
||||
_hz = hz;
|
||||
// If changing format while you are the owner than just
|
||||
// update frequency, but if owner is changed than even frequency should be
|
||||
// updated which is done by acquire.
|
||||
if (_owner == this) {
|
||||
spi_frequency(&_spi, _hz);
|
||||
} else {
|
||||
_acquire();
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
SPI* SPI::_owner = NULL;
|
||||
SingletonPtr<PlatformMutex> SPI::_mutex;
|
||||
|
||||
// ignore the fact there are multiple physical spis, and always update if it wasnt us last
|
||||
void SPI::aquire() {
|
||||
lock();
|
||||
if (_owner != this) {
|
||||
spi_format(&_spi, _bits, _mode, 0);
|
||||
spi_frequency(&_spi, _hz);
|
||||
_owner = this;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
// Note: Private function with no locking
|
||||
void SPI::_acquire() {
|
||||
if (_owner != this) {
|
||||
spi_format(&_spi, _bits, _mode, 0);
|
||||
spi_frequency(&_spi, _hz);
|
||||
_owner = this;
|
||||
}
|
||||
}
|
||||
|
||||
int SPI::write(int value) {
|
||||
lock();
|
||||
_acquire();
|
||||
int ret = spi_master_write(&_spi, value);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SPI::write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length) {
|
||||
lock();
|
||||
_acquire();
|
||||
int ret = spi_master_block_write(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, _write_fill);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// NEW FUNCTION F4HDK !!!
|
||||
int SPI::transfer_2(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length) {
|
||||
//lock();
|
||||
//aquire();
|
||||
//int ret = spi_master_write(&_spi, value);
|
||||
int ret = spi_master_transfer_2 (&_spi, tx_buffer, tx_length, rx_buffer, rx_length);
|
||||
//unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SPI::lock() {
|
||||
_mutex->lock();
|
||||
}
|
||||
|
||||
void SPI::unlock() {
|
||||
_mutex->unlock();
|
||||
}
|
||||
|
||||
void SPI::set_default_write_value(char data) {
|
||||
lock();
|
||||
_write_fill = data;
|
||||
unlock();
|
||||
}
|
||||
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
|
||||
int SPI::transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
|
||||
{
|
||||
if (spi_active(&_spi)) {
|
||||
return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event);
|
||||
}
|
||||
start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, bit_width, callback, event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SPI::abort_transfer()
|
||||
{
|
||||
spi_abort_asynch(&_spi);
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||
dequeue_transaction();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void SPI::clear_transfer_buffer()
|
||||
{
|
||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||
_transaction_buffer.reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void SPI::abort_all_transfers()
|
||||
{
|
||||
clear_transfer_buffer();
|
||||
abort_transfer();
|
||||
}
|
||||
|
||||
int SPI::set_dma_usage(DMAUsage usage)
|
||||
{
|
||||
if (spi_active(&_spi)) {
|
||||
return -1;
|
||||
}
|
||||
_usage = usage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SPI::queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
|
||||
{
|
||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||
transaction_t t;
|
||||
|
||||
t.tx_buffer = const_cast<void *>(tx_buffer);
|
||||
t.tx_length = tx_length;
|
||||
t.rx_buffer = rx_buffer;
|
||||
t.rx_length = rx_length;
|
||||
t.event = event;
|
||||
t.callback = callback;
|
||||
t.width = bit_width;
|
||||
Transaction<SPI> transaction(this, t);
|
||||
if (_transaction_buffer.full()) {
|
||||
return -1; // the buffer is full
|
||||
} else {
|
||||
core_util_critical_section_enter();
|
||||
_transaction_buffer.push(transaction);
|
||||
if (!spi_active(&_spi)) {
|
||||
dequeue_transaction();
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SPI::start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event)
|
||||
{
|
||||
sleep_manager_lock_deep_sleep();
|
||||
_acquire();
|
||||
_callback = callback;
|
||||
_irq.callback(&SPI::irq_handler_asynch);
|
||||
spi_master_transfer(&_spi, tx_buffer, tx_length, rx_buffer, rx_length, bit_width, _irq.entry(), event , _usage);
|
||||
}
|
||||
|
||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||
|
||||
void SPI::start_transaction(transaction_t *data)
|
||||
{
|
||||
start_transfer(data->tx_buffer, data->tx_length, data->rx_buffer, data->rx_length, data->width, data->callback, data->event);
|
||||
}
|
||||
|
||||
void SPI::dequeue_transaction()
|
||||
{
|
||||
Transaction<SPI> t;
|
||||
if (_transaction_buffer.pop(t)) {
|
||||
SPI* obj = t.get_object();
|
||||
transaction_t* data = t.get_transaction();
|
||||
obj->start_transaction(data);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void SPI::irq_handler_asynch(void)
|
||||
{
|
||||
int event = spi_irq_handler_asynch(&_spi);
|
||||
if (_callback && (event & SPI_EVENT_ALL)) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
_callback.call(event & SPI_EVENT_ALL);
|
||||
}
|
||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||
if (event & (SPI_EVENT_ALL | SPI_EVENT_INTERNAL_TRANSFER_COMPLETE)) {
|
||||
// SPI peripheral is free (event happend), dequeue transaction
|
||||
dequeue_transaction();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
301
NPR_14/mbed-os/drivers/SPI.h
Normal file
301
NPR_14/mbed-os/drivers/SPI.h
Normal file
|
|
@ -0,0 +1,301 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2015 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_SPI_H
|
||||
#define MBED_SPI_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_SPI) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "platform/PlatformMutex.h"
|
||||
#include "hal/spi_api.h"
|
||||
#include "platform/SingletonPtr.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
#include "platform/CThunk.h"
|
||||
#include "hal/dma_api.h"
|
||||
#include "platform/CircularBuffer.h"
|
||||
#include "platform/FunctionPointer.h"
|
||||
#include "platform/Transaction.h"
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A SPI Master, used for communicating with SPI slave devices
|
||||
*
|
||||
* The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz
|
||||
*
|
||||
* Most SPI devices will also require Chip Select and Reset signals. These
|
||||
* can be controlled using DigitalOut pins
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Send a byte to a SPI slave, and record the response
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* // hardware ssel (where applicable)
|
||||
* //SPI device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
|
||||
*
|
||||
* // software ssel
|
||||
* SPI device(p5, p6, p7); // mosi, miso, sclk
|
||||
* DigitalOut cs(p8); // ssel
|
||||
*
|
||||
* int main() {
|
||||
* // hardware ssel (where applicable)
|
||||
* //int response = device.write(0xFF);
|
||||
*
|
||||
* device.lock();
|
||||
* // software ssel
|
||||
* cs = 0;
|
||||
* int response = device.write(0xFF);
|
||||
* cs = 1;
|
||||
* device.unlock();
|
||||
*
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class SPI : private NonCopyable<SPI> {
|
||||
|
||||
public:
|
||||
|
||||
/** Create a SPI master connected to the specified pins
|
||||
*
|
||||
* mosi or miso can be specfied as NC if not used
|
||||
*
|
||||
* @param mosi SPI Master Out, Slave In pin
|
||||
* @param miso SPI Master In, Slave Out pin
|
||||
* @param sclk SPI Clock pin
|
||||
* @param ssel SPI chip select pin
|
||||
*/
|
||||
SPI(PinName mosi, PinName miso, PinName sclk, PinName ssel=NC);
|
||||
|
||||
/** Configure the data transmission format
|
||||
*
|
||||
* @param bits Number of bits per SPI frame (4 - 16)
|
||||
* @param mode Clock polarity and phase mode (0 - 3)
|
||||
*
|
||||
* @code
|
||||
* mode | POL PHA
|
||||
* -----+--------
|
||||
* 0 | 0 0
|
||||
* 1 | 0 1
|
||||
* 2 | 1 0
|
||||
* 3 | 1 1
|
||||
* @endcode
|
||||
*/
|
||||
void format(int bits, int mode = 0);
|
||||
|
||||
/** Set the spi bus clock frequency
|
||||
*
|
||||
* @param hz SCLK frequency in hz (default = 1MHz)
|
||||
*/
|
||||
void frequency(int hz = 1000000);
|
||||
|
||||
/** Write to the SPI Slave and return the response
|
||||
*
|
||||
* @param value Data to be sent to the SPI slave
|
||||
*
|
||||
* @returns
|
||||
* Response from the SPI slave
|
||||
*/
|
||||
virtual int write(int value);
|
||||
|
||||
/** Write to the SPI Slave and obtain the response
|
||||
*
|
||||
* The total number of bytes sent and recieved will be the maximum of
|
||||
* tx_length and rx_length. The bytes written will be padded with the
|
||||
* value 0xff.
|
||||
*
|
||||
* @param tx_buffer Pointer to the byte-array of data to write to the device
|
||||
* @param tx_length Number of bytes to write, may be zero
|
||||
* @param rx_buffer Pointer to the byte-array of data to read from the device
|
||||
* @param rx_length Number of bytes to read, may be zero
|
||||
* @returns
|
||||
* The number of bytes written and read from the device. This is
|
||||
* maximum of tx_length and rx_length.
|
||||
*/
|
||||
virtual int write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length);
|
||||
|
||||
// NEW FUNCTION F4HDK !!!
|
||||
virtual int transfer_2(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length);
|
||||
|
||||
/** Acquire exclusive access to this SPI bus
|
||||
*/
|
||||
virtual void lock(void);
|
||||
|
||||
/** Release exclusive access to this SPI bus
|
||||
*/
|
||||
virtual void unlock(void);
|
||||
|
||||
/** Set default write data
|
||||
* SPI requires the master to send some data during a read operation.
|
||||
* Different devices may require different default byte values.
|
||||
* For example: A SD Card requires default bytes to be 0xFF.
|
||||
*
|
||||
* @param data Default character to be transmitted while read operation
|
||||
*/
|
||||
void set_default_write_value(char data);
|
||||
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
|
||||
/** Start non-blocking SPI transfer using 8bit buffers.
|
||||
*
|
||||
* This function locks the deep sleep until any event has occured
|
||||
*
|
||||
* @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
|
||||
* the default SPI value is sent
|
||||
* @param tx_length The length of TX buffer in bytes
|
||||
* @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
|
||||
* received data are ignored
|
||||
* @param rx_length The length of RX buffer in bytes
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of events to modify. Look at spi hal header file for SPI events.
|
||||
* @return Zero if the transfer has started, or -1 if SPI peripheral is busy
|
||||
*/
|
||||
template<typename Type>
|
||||
int transfer(const Type *tx_buffer, int tx_length, Type *rx_buffer, int rx_length, const event_callback_t& callback, int event = SPI_EVENT_COMPLETE) {
|
||||
if (spi_active(&_spi)) {
|
||||
return queue_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
|
||||
}
|
||||
start_transfer(tx_buffer, tx_length, rx_buffer, rx_length, sizeof(Type)*8, callback, event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Abort the on-going SPI transfer, and continue with transfer's in the queue if any.
|
||||
*/
|
||||
void abort_transfer();
|
||||
|
||||
/** Clear the transaction buffer
|
||||
*/
|
||||
void clear_transfer_buffer();
|
||||
|
||||
/** Clear the transaction buffer and abort on-going transfer.
|
||||
*/
|
||||
void abort_all_transfers();
|
||||
|
||||
/** Configure DMA usage suggestion for non-blocking transfers
|
||||
*
|
||||
* @param usage The usage DMA hint for peripheral
|
||||
* @return Zero if the usage was set, -1 if a transaction is on-going
|
||||
*/
|
||||
int set_dma_usage(DMAUsage usage);
|
||||
|
||||
protected:
|
||||
/** SPI IRQ handler
|
||||
*
|
||||
*/
|
||||
void irq_handler_asynch(void);
|
||||
|
||||
/** Common transfer method
|
||||
*
|
||||
* @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
|
||||
* the default SPI value is sent
|
||||
* @param tx_length The length of TX buffer in bytes
|
||||
* @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
|
||||
* received data are ignored
|
||||
* @param rx_length The length of RX buffer in bytes
|
||||
* @param bit_width The buffers element width
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of events to modify
|
||||
* @return Zero if the transfer has started or was added to the queue, or -1 if SPI peripheral is busy/buffer is full
|
||||
*/
|
||||
int transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
|
||||
* the default SPI value is sent
|
||||
* @param tx_length The length of TX buffer in bytes
|
||||
* @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
|
||||
* received data are ignored
|
||||
* @param rx_length The length of RX buffer in bytes
|
||||
* @param bit_width The buffers element width
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of events to modify
|
||||
* @return Zero if a transfer was added to the queue, or -1 if the queue is full
|
||||
*/
|
||||
int queue_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
|
||||
|
||||
/** Configures a callback, spi peripheral and initiate a new transfer
|
||||
*
|
||||
* @param tx_buffer The TX buffer with data to be transfered. If NULL is passed,
|
||||
* the default SPI value is sent
|
||||
* @param tx_length The length of TX buffer in bytes
|
||||
* @param rx_buffer The RX buffer which is used for received data. If NULL is passed,
|
||||
* received data are ignored
|
||||
* @param rx_length The length of RX buffer in bytes
|
||||
* @param bit_width The buffers element width
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of events to modify
|
||||
*/
|
||||
void start_transfer(const void *tx_buffer, int tx_length, void *rx_buffer, int rx_length, unsigned char bit_width, const event_callback_t& callback, int event);
|
||||
|
||||
#if TRANSACTION_QUEUE_SIZE_SPI
|
||||
|
||||
/** Start a new transaction
|
||||
*
|
||||
* @param data Transaction data
|
||||
*/
|
||||
void start_transaction(transaction_t *data);
|
||||
|
||||
/** Dequeue a transaction
|
||||
*
|
||||
*/
|
||||
void dequeue_transaction();
|
||||
static CircularBuffer<Transaction<SPI>, TRANSACTION_QUEUE_SIZE_SPI> _transaction_buffer;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual ~SPI() {
|
||||
}
|
||||
|
||||
protected:
|
||||
spi_t _spi;
|
||||
|
||||
#if DEVICE_SPI_ASYNCH
|
||||
CThunk<SPI> _irq;
|
||||
event_callback_t _callback;
|
||||
DMAUsage _usage;
|
||||
#endif
|
||||
|
||||
void aquire(void);
|
||||
static SPI *_owner;
|
||||
static SingletonPtr<PlatformMutex> _mutex;
|
||||
int _bits;
|
||||
int _mode;
|
||||
int _hz;
|
||||
char _write_fill;
|
||||
|
||||
private:
|
||||
/* Private acquire function without locking/unlocking
|
||||
* Implemented in order to avoid duplicate locking and boost performance
|
||||
*/
|
||||
void _acquire(void);
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
58
NPR_14/mbed-os/drivers/SPISlave.cpp
Normal file
58
NPR_14/mbed-os/drivers/SPISlave.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/SPISlave.h"
|
||||
|
||||
#if DEVICE_SPISLAVE
|
||||
|
||||
namespace mbed {
|
||||
|
||||
SPISlave::SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel) :
|
||||
_spi(),
|
||||
_bits(8),
|
||||
_mode(0),
|
||||
_hz(1000000)
|
||||
{
|
||||
spi_init(&_spi, mosi, miso, sclk, ssel);
|
||||
spi_format(&_spi, _bits, _mode, 1);
|
||||
spi_frequency(&_spi, _hz);
|
||||
}
|
||||
|
||||
void SPISlave::format(int bits, int mode) {
|
||||
_bits = bits;
|
||||
_mode = mode;
|
||||
spi_format(&_spi, _bits, _mode, 1);
|
||||
}
|
||||
|
||||
void SPISlave::frequency(int hz) {
|
||||
_hz = hz;
|
||||
spi_frequency(&_spi, _hz);
|
||||
}
|
||||
|
||||
int SPISlave::receive(void) {
|
||||
return(spi_slave_receive(&_spi));
|
||||
}
|
||||
|
||||
int SPISlave::read(void) {
|
||||
return(spi_slave_read(&_spi));
|
||||
}
|
||||
|
||||
void SPISlave::reply(int value) {
|
||||
spi_slave_write(&_spi, value);
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
127
NPR_14/mbed-os/drivers/SPISlave.h
Normal file
127
NPR_14/mbed-os/drivers/SPISlave.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_SPISLAVE_H
|
||||
#define MBED_SPISLAVE_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if defined (DEVICE_SPISLAVE) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "hal/spi_api.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A SPI slave, used for communicating with a SPI Master device
|
||||
*
|
||||
* The default format is set to 8-bits, mode 0, and a clock frequency of 1MHz
|
||||
*
|
||||
* @note Synchronization level: Not protected
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Reply to a SPI master as slave
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* SPISlave device(p5, p6, p7, p8); // mosi, miso, sclk, ssel
|
||||
*
|
||||
* int main() {
|
||||
* device.reply(0x00); // Prime SPI with first reply
|
||||
* while(1) {
|
||||
* if(device.receive()) {
|
||||
* int v = device.read(); // Read byte from master
|
||||
* v = (v + 1) % 0x100; // Add one to it, modulo 256
|
||||
* device.reply(v); // Make this the next reply
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class SPISlave : private NonCopyable<SPISlave> {
|
||||
|
||||
public:
|
||||
|
||||
/** Create a SPI slave connected to the specified pins
|
||||
*
|
||||
* mosi or miso can be specfied as NC if not used
|
||||
*
|
||||
* @param mosi SPI Master Out, Slave In pin
|
||||
* @param miso SPI Master In, Slave Out pin
|
||||
* @param sclk SPI Clock pin
|
||||
* @param ssel SPI chip select pin
|
||||
*/
|
||||
SPISlave(PinName mosi, PinName miso, PinName sclk, PinName ssel);
|
||||
|
||||
/** Configure the data transmission format
|
||||
*
|
||||
* @param bits Number of bits per SPI frame (4 - 16)
|
||||
* @param mode Clock polarity and phase mode (0 - 3)
|
||||
*
|
||||
* @code
|
||||
* mode | POL PHA
|
||||
* -----+--------
|
||||
* 0 | 0 0
|
||||
* 1 | 0 1
|
||||
* 2 | 1 0
|
||||
* 3 | 1 1
|
||||
* @endcode
|
||||
*/
|
||||
void format(int bits, int mode = 0);
|
||||
|
||||
/** Set the spi bus clock frequency
|
||||
*
|
||||
* @param hz SCLK frequency in hz (default = 1MHz)
|
||||
*/
|
||||
void frequency(int hz = 1000000);
|
||||
|
||||
/** Polls the SPI to see if data has been received
|
||||
*
|
||||
* @returns
|
||||
* 0 if no data,
|
||||
* 1 otherwise
|
||||
*/
|
||||
int receive(void);
|
||||
|
||||
/** Retrieve data from receive buffer as slave
|
||||
*
|
||||
* @returns
|
||||
* the data in the receive buffer
|
||||
*/
|
||||
int read(void);
|
||||
|
||||
/** Fill the transmission buffer with the value to be written out
|
||||
* as slave on the next received message from the master.
|
||||
*
|
||||
* @param value the data to be transmitted next
|
||||
*/
|
||||
void reply(int value);
|
||||
|
||||
protected:
|
||||
spi_t _spi;
|
||||
|
||||
int _bits;
|
||||
int _mode;
|
||||
int _hz;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
49
NPR_14/mbed-os/drivers/Serial.cpp
Normal file
49
NPR_14/mbed-os/drivers/Serial.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/Serial.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
|
||||
#if DEVICE_SERIAL
|
||||
|
||||
namespace mbed {
|
||||
|
||||
Serial::Serial(PinName tx, PinName rx, const char *name, int baud) : SerialBase(tx, rx, baud), Stream(name) {
|
||||
}
|
||||
|
||||
Serial::Serial(PinName tx, PinName rx, int baud): SerialBase(tx, rx, baud), Stream(NULL) {
|
||||
}
|
||||
|
||||
int Serial::_getc() {
|
||||
// Mutex is already held
|
||||
return _base_getc();
|
||||
}
|
||||
|
||||
int Serial::_putc(int c) {
|
||||
// Mutex is already held
|
||||
return _base_putc(c);
|
||||
}
|
||||
|
||||
void Serial::lock() {
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void Serial::unlock() {
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
115
NPR_14/mbed-os/drivers/Serial.h
Normal file
115
NPR_14/mbed-os/drivers/Serial.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_SERIAL_H
|
||||
#define MBED_SERIAL_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_SERIAL) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "Stream.h"
|
||||
#include "SerialBase.h"
|
||||
#include "PlatformMutex.h"
|
||||
#include "serial_api.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A serial port (UART) for communication with other serial devices
|
||||
*
|
||||
* Can be used for Full Duplex communication, or Simplex by specifying
|
||||
* one pin as NC (Not Connected)
|
||||
*
|
||||
* @note Synchronization level: Thread safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Print "Hello World" to the PC
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Serial pc(USBTX, USBRX);
|
||||
*
|
||||
* int main() {
|
||||
* pc.printf("Hello World\n");
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class Serial : public SerialBase, public Stream, private NonCopyable<Serial> {
|
||||
|
||||
public:
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
using SerialBase::read;
|
||||
using SerialBase::write;
|
||||
#endif
|
||||
|
||||
/** Create a Serial port, connected to the specified transmit and receive pins
|
||||
*
|
||||
* @param tx Transmit pin
|
||||
* @param rx Receive pin
|
||||
* @param name The name of the stream associated with this serial port (optional)
|
||||
* @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
|
||||
*
|
||||
* @note
|
||||
* Either tx or rx may be specified as NC if unused
|
||||
*/
|
||||
Serial(PinName tx, PinName rx, const char *name=NULL, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
|
||||
|
||||
/** Create a Serial port, connected to the specified transmit and receive pins, with the specified baud
|
||||
*
|
||||
* @param tx Transmit pin
|
||||
* @param rx Receive pin
|
||||
* @param baud The baud rate of the serial port
|
||||
*
|
||||
* @note
|
||||
* Either tx or rx may be specified as NC if unused
|
||||
*/
|
||||
Serial(PinName tx, PinName rx, int baud);
|
||||
|
||||
/* Stream gives us a FileHandle with non-functional poll()/readable()/writable. Pass through
|
||||
* the calls from the SerialBase instead for backwards compatibility. This problem is
|
||||
* part of why Stream and Serial should be deprecated.
|
||||
*/
|
||||
bool readable()
|
||||
{
|
||||
return SerialBase::readable();
|
||||
}
|
||||
bool writable()
|
||||
{
|
||||
return SerialBase::writeable();
|
||||
}
|
||||
bool writeable()
|
||||
{
|
||||
return SerialBase::writeable();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int _getc();
|
||||
virtual int _putc(int c);
|
||||
virtual void lock();
|
||||
virtual void unlock();
|
||||
|
||||
PlatformMutex _mutex;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
292
NPR_14/mbed-os/drivers/SerialBase.cpp
Normal file
292
NPR_14/mbed-os/drivers/SerialBase.cpp
Normal file
|
|
@ -0,0 +1,292 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/SerialBase.h"
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "platform/mbed_sleep.h"
|
||||
|
||||
#if DEVICE_SERIAL
|
||||
|
||||
namespace mbed {
|
||||
|
||||
SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
_thunk_irq(this), _tx_usage(DMA_USAGE_NEVER),
|
||||
_rx_usage(DMA_USAGE_NEVER), _tx_callback(NULL),
|
||||
_rx_callback(NULL),
|
||||
#endif
|
||||
_serial(), _baud(baud) {
|
||||
// No lock needed in the constructor
|
||||
|
||||
for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
|
||||
_irq[i] = NULL;
|
||||
}
|
||||
|
||||
serial_init(&_serial, tx, rx);
|
||||
serial_baud(&_serial, _baud);
|
||||
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
|
||||
}
|
||||
|
||||
void SerialBase::baud(int baudrate) {
|
||||
lock();
|
||||
serial_baud(&_serial, baudrate);
|
||||
_baud = baudrate;
|
||||
unlock();
|
||||
}
|
||||
|
||||
void SerialBase::format(int bits, Parity parity, int stop_bits) {
|
||||
lock();
|
||||
serial_format(&_serial, bits, (SerialParity)parity, stop_bits);
|
||||
unlock();
|
||||
}
|
||||
|
||||
int SerialBase::readable() {
|
||||
lock();
|
||||
int ret = serial_readable(&_serial);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int SerialBase::writeable() {
|
||||
lock();
|
||||
int ret = serial_writable(&_serial);
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SerialBase::attach(Callback<void()> func, IrqType type) {
|
||||
lock();
|
||||
// Disable interrupts when attaching interrupt handler
|
||||
core_util_critical_section_enter();
|
||||
if (func) {
|
||||
// lock deep sleep only the first time
|
||||
if (!_irq[type]) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
}
|
||||
_irq[type] = func;
|
||||
serial_irq_set(&_serial, (SerialIrq)type, 1);
|
||||
} else {
|
||||
// unlock deep sleep only the first time
|
||||
if (_irq[type]) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
_irq[type] = NULL;
|
||||
serial_irq_set(&_serial, (SerialIrq)type, 0);
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) {
|
||||
SerialBase *handler = (SerialBase*)id;
|
||||
if (handler->_irq[irq_type]) {
|
||||
handler->_irq[irq_type]();
|
||||
}
|
||||
}
|
||||
|
||||
int SerialBase::_base_getc() {
|
||||
// Mutex is already held
|
||||
return serial_getc(&_serial);
|
||||
}
|
||||
|
||||
int SerialBase::_base_putc(int c) {
|
||||
// Mutex is already held
|
||||
serial_putc(&_serial, c);
|
||||
return c;
|
||||
}
|
||||
|
||||
void SerialBase::send_break() {
|
||||
lock();
|
||||
// Wait for 1.5 frames before clearing the break condition
|
||||
// This will have different effects on our platforms, but should
|
||||
// ensure that we keep the break active for at least one frame.
|
||||
// We consider a full frame (1 start bit + 8 data bits bits +
|
||||
// 1 parity bit + 2 stop bits = 12 bits) for computation.
|
||||
// One bit time (in us) = 1000000/_baud
|
||||
// Twelve bits: 12000000/baud delay
|
||||
// 1.5 frames: 18000000/baud delay
|
||||
serial_break_set(&_serial);
|
||||
wait_us(18000000/_baud);
|
||||
serial_break_clear(&_serial);
|
||||
unlock();
|
||||
}
|
||||
|
||||
void SerialBase::lock() {
|
||||
// Stub
|
||||
}
|
||||
|
||||
void SerialBase:: unlock() {
|
||||
// Stub
|
||||
}
|
||||
|
||||
SerialBase::~SerialBase()
|
||||
{
|
||||
// No lock needed in destructor
|
||||
|
||||
// Detaching interrupts releases the sleep lock if it was locked
|
||||
for (int irq = 0; irq < IrqCnt; irq++) {
|
||||
attach(NULL, (IrqType)irq);
|
||||
}
|
||||
}
|
||||
|
||||
#if DEVICE_SERIAL_FC
|
||||
void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) {
|
||||
lock();
|
||||
FlowControl flow_type = (FlowControl)type;
|
||||
switch(type) {
|
||||
case RTS:
|
||||
serial_set_flow_control(&_serial, flow_type, flow1, NC);
|
||||
break;
|
||||
|
||||
case CTS:
|
||||
serial_set_flow_control(&_serial, flow_type, NC, flow1);
|
||||
break;
|
||||
|
||||
case RTSCTS:
|
||||
case Disabled:
|
||||
serial_set_flow_control(&_serial, flow_type, flow1, flow2);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
|
||||
int SerialBase::write(const uint8_t *buffer, int length, const event_callback_t& callback, int event)
|
||||
{
|
||||
if (serial_tx_active(&_serial)) {
|
||||
return -1; // transaction ongoing
|
||||
}
|
||||
start_write((void *)buffer, length, 8, callback, event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SerialBase::write(const uint16_t *buffer, int length, const event_callback_t& callback, int event)
|
||||
{
|
||||
if (serial_tx_active(&_serial)) {
|
||||
return -1; // transaction ongoing
|
||||
}
|
||||
start_write((void *)buffer, length, 16, callback, event);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event)
|
||||
{
|
||||
_tx_callback = callback;
|
||||
|
||||
_thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
|
||||
sleep_manager_lock_deep_sleep();
|
||||
serial_tx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, _tx_usage);
|
||||
}
|
||||
|
||||
void SerialBase::abort_write(void)
|
||||
{
|
||||
// rx might still be active
|
||||
if (_rx_callback) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
_tx_callback = NULL;
|
||||
serial_tx_abort_asynch(&_serial);
|
||||
}
|
||||
|
||||
void SerialBase::abort_read(void)
|
||||
{
|
||||
// tx might still be active
|
||||
if (_tx_callback) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
_rx_callback = NULL;
|
||||
serial_rx_abort_asynch(&_serial);
|
||||
}
|
||||
|
||||
int SerialBase::set_dma_usage_tx(DMAUsage usage)
|
||||
{
|
||||
if (serial_tx_active(&_serial)) {
|
||||
return -1;
|
||||
}
|
||||
_tx_usage = usage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SerialBase::set_dma_usage_rx(DMAUsage usage)
|
||||
{
|
||||
if (serial_tx_active(&_serial)) {
|
||||
return -1;
|
||||
}
|
||||
_rx_usage = usage;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SerialBase::read(uint8_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match)
|
||||
{
|
||||
if (serial_rx_active(&_serial)) {
|
||||
return -1; // transaction ongoing
|
||||
}
|
||||
start_read((void*)buffer, length, 8, callback, event, char_match);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SerialBase::read(uint16_t *buffer, int length, const event_callback_t& callback, int event, unsigned char char_match)
|
||||
{
|
||||
if (serial_rx_active(&_serial)) {
|
||||
return -1; // transaction ongoing
|
||||
}
|
||||
start_read((void*)buffer, length, 16, callback, event, char_match);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void SerialBase::start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match)
|
||||
{
|
||||
_rx_callback = callback;
|
||||
_thunk_irq.callback(&SerialBase::interrupt_handler_asynch);
|
||||
sleep_manager_lock_deep_sleep();
|
||||
serial_rx_asynch(&_serial, buffer, buffer_size, buffer_width, _thunk_irq.entry(), event, char_match, _rx_usage);
|
||||
}
|
||||
|
||||
void SerialBase::interrupt_handler_asynch(void)
|
||||
{
|
||||
int event = serial_irq_handler_asynch(&_serial);
|
||||
int rx_event = event & SERIAL_EVENT_RX_MASK;
|
||||
bool unlock_deepsleep = false;
|
||||
|
||||
if (_rx_callback && rx_event) {
|
||||
unlock_deepsleep = true;
|
||||
_rx_callback.call(rx_event);
|
||||
}
|
||||
|
||||
int tx_event = event & SERIAL_EVENT_TX_MASK;
|
||||
if (_tx_callback && tx_event) {
|
||||
unlock_deepsleep = true;
|
||||
_tx_callback.call(tx_event);
|
||||
}
|
||||
// unlock if tx or rx events are generated
|
||||
if (unlock_deepsleep) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
267
NPR_14/mbed-os/drivers/SerialBase.h
Normal file
267
NPR_14/mbed-os/drivers/SerialBase.h
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_SERIALBASE_H
|
||||
#define MBED_SERIALBASE_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined (DEVICE_SERIAL) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "Callback.h"
|
||||
#include "serial_api.h"
|
||||
#include "mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
#include "CThunk.h"
|
||||
#include "dma_api.h"
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A base class for serial port implementations
|
||||
* Can't be instantiated directly (use Serial or RawSerial)
|
||||
*
|
||||
* @note Synchronization level: Set by subclass
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class SerialBase : private NonCopyable<SerialBase> {
|
||||
|
||||
public:
|
||||
/** Set the baud rate of the serial port
|
||||
*
|
||||
* @param baudrate The baudrate of the serial port (default = 9600).
|
||||
*/
|
||||
void baud(int baudrate);
|
||||
|
||||
enum Parity {
|
||||
None = 0,
|
||||
Odd,
|
||||
Even,
|
||||
Forced1,
|
||||
Forced0
|
||||
};
|
||||
|
||||
enum IrqType {
|
||||
RxIrq = 0,
|
||||
TxIrq,
|
||||
|
||||
IrqCnt
|
||||
};
|
||||
|
||||
enum Flow {
|
||||
Disabled = 0,
|
||||
RTS,
|
||||
CTS,
|
||||
RTSCTS
|
||||
};
|
||||
|
||||
/** Set the transmission format used by the serial port
|
||||
*
|
||||
* @param bits The number of bits in a word (5-8; default = 8)
|
||||
* @param parity The parity used (SerialBase::None, SerialBase::Odd, SerialBase::Even, SerialBase::Forced1, SerialBase::Forced0; default = SerialBase::None)
|
||||
* @param stop_bits The number of stop bits (1 or 2; default = 1)
|
||||
*/
|
||||
void format(int bits=8, Parity parity=SerialBase::None, int stop_bits=1);
|
||||
|
||||
/** Determine if there is a character available to read
|
||||
*
|
||||
* @returns
|
||||
* 1 if there is a character available to read,
|
||||
* 0 otherwise
|
||||
*/
|
||||
int readable();
|
||||
|
||||
/** Determine if there is space available to write a character
|
||||
*
|
||||
* @returns
|
||||
* 1 if there is space to write a character,
|
||||
* 0 otherwise
|
||||
*/
|
||||
int writeable();
|
||||
|
||||
/** Attach a function to call whenever a serial interrupt is generated
|
||||
*
|
||||
* @param func A pointer to a void function, or 0 to set as none
|
||||
* @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
|
||||
*/
|
||||
void attach(Callback<void()> func, IrqType type=RxIrq);
|
||||
|
||||
/** Attach a member function to call whenever a serial interrupt is generated
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
|
||||
* @deprecated
|
||||
* The attach function does not support cv-qualifiers. Replaced by
|
||||
* attach(callback(obj, method), type).
|
||||
*/
|
||||
template<typename T>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The attach function does not support cv-qualifiers. Replaced by "
|
||||
"attach(callback(obj, method), type).")
|
||||
void attach(T *obj, void (T::*method)(), IrqType type=RxIrq) {
|
||||
attach(callback(obj, method), type);
|
||||
}
|
||||
|
||||
/** Attach a member function to call whenever a serial interrupt is generated
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param type Which serial interrupt to attach the member function to (Seriall::RxIrq for receive, TxIrq for transmit buffer empty)
|
||||
* @deprecated
|
||||
* The attach function does not support cv-qualifiers. Replaced by
|
||||
* attach(callback(obj, method), type).
|
||||
*/
|
||||
template<typename T>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The attach function does not support cv-qualifiers. Replaced by "
|
||||
"attach(callback(obj, method), type).")
|
||||
void attach(T *obj, void (*method)(T*), IrqType type=RxIrq) {
|
||||
attach(callback(obj, method), type);
|
||||
}
|
||||
|
||||
/** Generate a break condition on the serial line
|
||||
*/
|
||||
void send_break();
|
||||
|
||||
protected:
|
||||
|
||||
/** Acquire exclusive access to this serial port
|
||||
*/
|
||||
virtual void lock(void);
|
||||
|
||||
/** Release exclusive access to this serial port
|
||||
*/
|
||||
virtual void unlock(void);
|
||||
|
||||
public:
|
||||
|
||||
#if DEVICE_SERIAL_FC
|
||||
/** Set the flow control type on the serial port
|
||||
*
|
||||
* @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
|
||||
* @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
|
||||
* @param flow2 the second flow control pin (CTS for RTSCTS)
|
||||
*/
|
||||
void set_flow_control(Flow type, PinName flow1=NC, PinName flow2=NC);
|
||||
#endif
|
||||
|
||||
static void _irq_handler(uint32_t id, SerialIrq irq_type);
|
||||
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
|
||||
/** Begin asynchronous write using 8bit buffer. The completition invokes registered TX event callback
|
||||
*
|
||||
* This function locks the deep sleep until any event has occured
|
||||
*
|
||||
* @param buffer The buffer where received data will be stored
|
||||
* @param length The buffer length in bytes
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of TX events
|
||||
*/
|
||||
int write(const uint8_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_TX_COMPLETE);
|
||||
|
||||
/** Begin asynchronous write using 16bit buffer. The completition invokes registered TX event callback
|
||||
*
|
||||
* This function locks the deep sleep until any event has occured
|
||||
*
|
||||
* @param buffer The buffer where received data will be stored
|
||||
* @param length The buffer length in bytes
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of TX events
|
||||
*/
|
||||
int write(const uint16_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_TX_COMPLETE);
|
||||
|
||||
/** Abort the on-going write transfer
|
||||
*/
|
||||
void abort_write();
|
||||
|
||||
/** Begin asynchronous reading using 8bit buffer. The completition invokes registred RX event callback.
|
||||
*
|
||||
* This function locks the deep sleep until any event has occured
|
||||
*
|
||||
* @param buffer The buffer where received data will be stored
|
||||
* @param length The buffer length in bytes
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of RX events
|
||||
* @param char_match The matching character
|
||||
*/
|
||||
int read(uint8_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_RX_COMPLETE, unsigned char char_match = SERIAL_RESERVED_CHAR_MATCH);
|
||||
|
||||
/** Begin asynchronous reading using 16bit buffer. The completition invokes registred RX event callback.
|
||||
*
|
||||
* This function locks the deep sleep until any event has occured
|
||||
*
|
||||
* @param buffer The buffer where received data will be stored
|
||||
* @param length The buffer length in bytes
|
||||
* @param callback The event callback function
|
||||
* @param event The logical OR of RX events
|
||||
* @param char_match The matching character
|
||||
*/
|
||||
int read(uint16_t *buffer, int length, const event_callback_t& callback, int event = SERIAL_EVENT_RX_COMPLETE, unsigned char char_match = SERIAL_RESERVED_CHAR_MATCH);
|
||||
|
||||
/** Abort the on-going read transfer
|
||||
*/
|
||||
void abort_read();
|
||||
|
||||
/** Configure DMA usage suggestion for non-blocking TX transfers
|
||||
*
|
||||
* @param usage The usage DMA hint for peripheral
|
||||
* @return Zero if the usage was set, -1 if a transaction is on-going
|
||||
*/
|
||||
int set_dma_usage_tx(DMAUsage usage);
|
||||
|
||||
/** Configure DMA usage suggestion for non-blocking RX transfers
|
||||
*
|
||||
* @param usage The usage DMA hint for peripheral
|
||||
* @return Zero if the usage was set, -1 if a transaction is on-going
|
||||
*/
|
||||
int set_dma_usage_rx(DMAUsage usage);
|
||||
|
||||
protected:
|
||||
void start_read(void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event, unsigned char char_match);
|
||||
void start_write(const void *buffer, int buffer_size, char buffer_width, const event_callback_t& callback, int event);
|
||||
void interrupt_handler_asynch(void);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
SerialBase(PinName tx, PinName rx, int baud);
|
||||
virtual ~SerialBase();
|
||||
|
||||
int _base_getc();
|
||||
int _base_putc(int c);
|
||||
|
||||
#if DEVICE_SERIAL_ASYNCH
|
||||
CThunk<SerialBase> _thunk_irq;
|
||||
DMAUsage _tx_usage;
|
||||
DMAUsage _rx_usage;
|
||||
event_callback_t _tx_callback;
|
||||
event_callback_t _rx_callback;
|
||||
#endif
|
||||
|
||||
serial_t _serial;
|
||||
Callback<void()> _irq[IrqCnt];
|
||||
int _baud;
|
||||
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
52
NPR_14/mbed-os/drivers/Ticker.cpp
Normal file
52
NPR_14/mbed-os/drivers/Ticker.cpp
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/Ticker.h"
|
||||
|
||||
#include "drivers/TimerEvent.h"
|
||||
#include "platform/FunctionPointer.h"
|
||||
#include "hal/ticker_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
void Ticker::detach() {
|
||||
core_util_critical_section_enter();
|
||||
remove();
|
||||
// unlocked only if we were attached (we locked it) and this is not low power ticker
|
||||
if(_function && _lock_deepsleep) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
|
||||
_function = 0;
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void Ticker::setup(us_timestamp_t t) {
|
||||
core_util_critical_section_enter();
|
||||
remove();
|
||||
_delay = t;
|
||||
insert_absolute(_delay + ticker_read_us(_ticker_data));
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void Ticker::handler() {
|
||||
insert_absolute(event.timestamp + _delay);
|
||||
if (_function) {
|
||||
_function();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
164
NPR_14/mbed-os/drivers/Ticker.h
Normal file
164
NPR_14/mbed-os/drivers/Ticker.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_TICKER_H
|
||||
#define MBED_TICKER_H
|
||||
|
||||
#include "drivers/TimerEvent.h"
|
||||
#include "platform/Callback.h"
|
||||
#include "platform/mbed_toolchain.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "platform/mbed_sleep.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A Ticker is used to call a function at a recurring interval
|
||||
*
|
||||
* You can use as many separate Ticker objects as you require.
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Toggle the blinking led after 5 seconds
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Ticker timer;
|
||||
* DigitalOut led1(LED1);
|
||||
* DigitalOut led2(LED2);
|
||||
*
|
||||
* int flip = 0;
|
||||
*
|
||||
* void attime() {
|
||||
* flip = !flip;
|
||||
* }
|
||||
*
|
||||
* int main() {
|
||||
* timer.attach(&attime, 5);
|
||||
* while(1) {
|
||||
* if(flip == 0) {
|
||||
* led1 = !led1;
|
||||
* } else {
|
||||
* led2 = !led2;
|
||||
* }
|
||||
* wait(0.2);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class Ticker : public TimerEvent, private NonCopyable<Ticker> {
|
||||
|
||||
public:
|
||||
Ticker() : TimerEvent(), _function(0), _lock_deepsleep(true) {
|
||||
}
|
||||
|
||||
// When low power ticker is in use, then do not disable deep-sleep.
|
||||
Ticker(const ticker_data_t *data) : TimerEvent(data), _function(0), _lock_deepsleep(true) {
|
||||
data->interface->init();
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
_lock_deepsleep = (data != get_lp_ticker_data());
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Attach a function to be called by the Ticker, specifying the interval in seconds
|
||||
*
|
||||
* @param func pointer to the function to be called
|
||||
* @param t the time between calls in seconds
|
||||
*/
|
||||
void attach(Callback<void()> func, float t) {
|
||||
attach_us(func, t * 1000000.0f);
|
||||
}
|
||||
|
||||
/** Attach a member function to be called by the Ticker, specifying the interval in seconds
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param t the time between calls in seconds
|
||||
* @deprecated
|
||||
* The attach function does not support cv-qualifiers. Replaced by
|
||||
* attach(callback(obj, method), t).
|
||||
*/
|
||||
template<typename T, typename M>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The attach function does not support cv-qualifiers. Replaced by "
|
||||
"attach(callback(obj, method), t).")
|
||||
void attach(T *obj, M method, float t) {
|
||||
attach(callback(obj, method), t);
|
||||
}
|
||||
|
||||
/** Attach a function to be called by the Ticker, specifying the interval in micro-seconds
|
||||
*
|
||||
* @param func pointer to the function to be called
|
||||
* @param t the time between calls in micro-seconds
|
||||
*
|
||||
* @note setting @a t to a value shorter that it takes to process the ticker callback
|
||||
* will cause the system to hang. Ticker callback will be called constantly with no time
|
||||
* for threads scheduling.
|
||||
*
|
||||
*/
|
||||
void attach_us(Callback<void()> func, us_timestamp_t t) {
|
||||
core_util_critical_section_enter();
|
||||
// lock only for the initial callback setup and this is not low power ticker
|
||||
if(!_function && _lock_deepsleep) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
}
|
||||
_function = func;
|
||||
setup(t);
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
/** Attach a member function to be called by the Ticker, specifying the interval in micro-seconds
|
||||
*
|
||||
* @param obj pointer to the object to call the member function on
|
||||
* @param method pointer to the member function to be called
|
||||
* @param t the time between calls in micro-seconds
|
||||
* @deprecated
|
||||
* The attach_us function does not support cv-qualifiers. Replaced by
|
||||
* attach_us(callback(obj, method), t).
|
||||
*/
|
||||
template<typename T, typename M>
|
||||
MBED_DEPRECATED_SINCE("mbed-os-5.1",
|
||||
"The attach_us function does not support cv-qualifiers. Replaced by "
|
||||
"attach_us(callback(obj, method), t).")
|
||||
void attach_us(T *obj, M method, us_timestamp_t t) {
|
||||
attach_us(Callback<void()>(obj, method), t);
|
||||
}
|
||||
|
||||
virtual ~Ticker() {
|
||||
detach();
|
||||
}
|
||||
|
||||
/** Detach the function
|
||||
*/
|
||||
void detach();
|
||||
|
||||
protected:
|
||||
void setup(us_timestamp_t t);
|
||||
virtual void handler();
|
||||
|
||||
protected:
|
||||
us_timestamp_t _delay; /**< Time delay (in microseconds) for re-setting the multi-shot callback. */
|
||||
Callback<void()> _function; /**< Callback. */
|
||||
bool _lock_deepsleep; /**< Flag which indicates if deep-sleep should be disabled. */
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
24
NPR_14/mbed-os/drivers/Timeout.cpp
Normal file
24
NPR_14/mbed-os/drivers/Timeout.cpp
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/Timeout.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
void Timeout::handler() {
|
||||
_function.call();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
65
NPR_14/mbed-os/drivers/Timeout.h
Normal file
65
NPR_14/mbed-os/drivers/Timeout.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_TIMEOUT_H
|
||||
#define MBED_TIMEOUT_H
|
||||
|
||||
#include "drivers/Ticker.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "platform/mbed_sleep.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A Timeout is used to call a function at a point in the future
|
||||
*
|
||||
* You can use as many seperate Timeout objects as you require.
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Blink until timeout.
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Timeout timeout;
|
||||
* DigitalOut led(LED1);
|
||||
*
|
||||
* int on = 1;
|
||||
*
|
||||
* void attimeout() {
|
||||
* on = 0;
|
||||
* }
|
||||
*
|
||||
* int main() {
|
||||
* timeout.attach(&attimeout, 5);
|
||||
* while(on) {
|
||||
* led = !led;
|
||||
* wait(0.2);
|
||||
* }
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class Timeout : public Ticker, private NonCopyable<Timeout> {
|
||||
|
||||
protected:
|
||||
virtual void handler();
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
110
NPR_14/mbed-os/drivers/Timer.cpp
Normal file
110
NPR_14/mbed-os/drivers/Timer.cpp
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/Timer.h"
|
||||
#include "hal/ticker_api.h"
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "platform/mbed_critical.h"
|
||||
#include "hal/lp_ticker_api.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
Timer::Timer() : _running(), _start(), _time(), _ticker_data(get_us_ticker_data()), _lock_deepsleep(true) {
|
||||
reset();
|
||||
}
|
||||
|
||||
Timer::Timer(const ticker_data_t *data) : _running(), _start(), _time(), _ticker_data(data), _lock_deepsleep(true) {
|
||||
reset();
|
||||
#if DEVICE_LOWPOWERTIMER
|
||||
_lock_deepsleep = (data != get_lp_ticker_data());
|
||||
#endif
|
||||
}
|
||||
|
||||
Timer::~Timer() {
|
||||
core_util_critical_section_enter();
|
||||
if (_running) {
|
||||
if(_lock_deepsleep) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
}
|
||||
_running = 0;
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void Timer::start() {
|
||||
core_util_critical_section_enter();
|
||||
if (!_running) {
|
||||
if(_lock_deepsleep) {
|
||||
sleep_manager_lock_deep_sleep();
|
||||
}
|
||||
_start = ticker_read_us(_ticker_data);
|
||||
_running = 1;
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
void Timer::stop() {
|
||||
core_util_critical_section_enter();
|
||||
_time += slicetime();
|
||||
if (_running) {
|
||||
if(_lock_deepsleep) {
|
||||
sleep_manager_unlock_deep_sleep();
|
||||
}
|
||||
}
|
||||
_running = 0;
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
int Timer::read_us() {
|
||||
return read_high_resolution_us();
|
||||
}
|
||||
|
||||
float Timer::read() {
|
||||
return (float)read_us() / 1000000.0f;
|
||||
}
|
||||
|
||||
int Timer::read_ms() {
|
||||
return read_high_resolution_us() / 1000;
|
||||
}
|
||||
|
||||
us_timestamp_t Timer::read_high_resolution_us() {
|
||||
core_util_critical_section_enter();
|
||||
us_timestamp_t time = _time + slicetime();
|
||||
core_util_critical_section_exit();
|
||||
return time;
|
||||
}
|
||||
|
||||
us_timestamp_t Timer::slicetime() {
|
||||
us_timestamp_t ret = 0;
|
||||
core_util_critical_section_enter();
|
||||
if (_running) {
|
||||
ret = ticker_read_us(_ticker_data) - _start;
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Timer::reset() {
|
||||
core_util_critical_section_enter();
|
||||
_start = ticker_read_us(_ticker_data);
|
||||
_time = 0;
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
Timer::operator float() {
|
||||
return read();
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
109
NPR_14/mbed-os/drivers/Timer.h
Normal file
109
NPR_14/mbed-os/drivers/Timer.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_TIMER_H
|
||||
#define MBED_TIMER_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "hal/ticker_api.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
#include "platform/mbed_sleep.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** A general purpose timer
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* // Count the time to toggle a LED
|
||||
*
|
||||
* #include "mbed.h"
|
||||
*
|
||||
* Timer timer;
|
||||
* DigitalOut led(LED1);
|
||||
* int begin, end;
|
||||
*
|
||||
* int main() {
|
||||
* timer.start();
|
||||
* begin = timer.read_us();
|
||||
* led = !led;
|
||||
* end = timer.read_us();
|
||||
* printf("Toggle the led takes %d us", end - begin);
|
||||
* }
|
||||
* @endcode
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class Timer : private NonCopyable<Timer> {
|
||||
|
||||
public:
|
||||
Timer();
|
||||
Timer(const ticker_data_t *data);
|
||||
~Timer();
|
||||
|
||||
/** Start the timer
|
||||
*/
|
||||
void start();
|
||||
|
||||
/** Stop the timer
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/** Reset the timer to 0.
|
||||
*
|
||||
* If it was already counting, it will continue
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/** Get the time passed in seconds
|
||||
*
|
||||
* @returns Time passed in seconds
|
||||
*/
|
||||
float read();
|
||||
|
||||
/** Get the time passed in milli-seconds
|
||||
*
|
||||
* @returns Time passed in milli seconds
|
||||
*/
|
||||
int read_ms();
|
||||
|
||||
/** Get the time passed in micro-seconds
|
||||
*
|
||||
* @returns Time passed in micro seconds
|
||||
*/
|
||||
int read_us();
|
||||
|
||||
/** An operator shorthand for read()
|
||||
*/
|
||||
operator float();
|
||||
|
||||
/** Get in a high resolution type the time passed in micro-seconds.
|
||||
*/
|
||||
us_timestamp_t read_high_resolution_us();
|
||||
|
||||
protected:
|
||||
us_timestamp_t slicetime();
|
||||
int _running; // whether the timer is running
|
||||
us_timestamp_t _start; // the start time of the latest slice
|
||||
us_timestamp_t _time; // any accumulated time from previous slices
|
||||
const ticker_data_t *_ticker_data;
|
||||
bool _lock_deepsleep; // flag which indicates if deep-sleep should be disabled
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
55
NPR_14/mbed-os/drivers/TimerEvent.cpp
Normal file
55
NPR_14/mbed-os/drivers/TimerEvent.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 "drivers/TimerEvent.h"
|
||||
#include "cmsis.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include "hal/ticker_api.h"
|
||||
#include "hal/us_ticker_api.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
TimerEvent::TimerEvent() : event(), _ticker_data(get_us_ticker_data()) {
|
||||
ticker_set_handler(_ticker_data, (&TimerEvent::irq));
|
||||
}
|
||||
|
||||
TimerEvent::TimerEvent(const ticker_data_t *data) : event(), _ticker_data(data) {
|
||||
ticker_set_handler(_ticker_data, (&TimerEvent::irq));
|
||||
}
|
||||
|
||||
void TimerEvent::irq(uint32_t id) {
|
||||
TimerEvent *timer_event = (TimerEvent*)id;
|
||||
timer_event->handler();
|
||||
}
|
||||
|
||||
TimerEvent::~TimerEvent() {
|
||||
remove();
|
||||
}
|
||||
|
||||
// insert in to linked list
|
||||
void TimerEvent::insert(timestamp_t timestamp) {
|
||||
ticker_insert_event(_ticker_data, &event, timestamp, (uint32_t)this);
|
||||
}
|
||||
|
||||
void TimerEvent::insert_absolute(us_timestamp_t timestamp) {
|
||||
ticker_insert_event_us(_ticker_data, &event, timestamp, (uint32_t)this);
|
||||
}
|
||||
|
||||
void TimerEvent::remove() {
|
||||
ticker_remove_event(_ticker_data, &event);
|
||||
}
|
||||
|
||||
} // namespace mbed
|
||||
66
NPR_14/mbed-os/drivers/TimerEvent.h
Normal file
66
NPR_14/mbed-os/drivers/TimerEvent.h
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2013 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_TIMEREVENT_H
|
||||
#define MBED_TIMEREVENT_H
|
||||
|
||||
#include "hal/ticker_api.h"
|
||||
#include "hal/us_ticker_api.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
namespace mbed {
|
||||
/** \addtogroup drivers */
|
||||
|
||||
/** Base abstraction for timer interrupts
|
||||
*
|
||||
* @note Synchronization level: Interrupt safe
|
||||
* @ingroup drivers
|
||||
*/
|
||||
class TimerEvent : private NonCopyable<TimerEvent> {
|
||||
public:
|
||||
TimerEvent();
|
||||
TimerEvent(const ticker_data_t *data);
|
||||
|
||||
/** The handler registered with the underlying timer interrupt
|
||||
*
|
||||
* @param id Timer Event ID
|
||||
*/
|
||||
static void irq(uint32_t id);
|
||||
|
||||
/** Destruction removes it...
|
||||
*/
|
||||
virtual ~TimerEvent();
|
||||
|
||||
protected:
|
||||
// The handler called to service the timer event of the derived class
|
||||
virtual void handler() = 0;
|
||||
|
||||
// insert relative timestamp in to linked list
|
||||
void insert(timestamp_t timestamp);
|
||||
|
||||
// insert absolute timestamp into linked list
|
||||
void insert_absolute(us_timestamp_t timestamp);
|
||||
|
||||
// remove from linked list, if in it
|
||||
void remove();
|
||||
|
||||
ticker_event_t event;
|
||||
|
||||
const ticker_data_t *_ticker_data;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif
|
||||
298
NPR_14/mbed-os/drivers/UARTSerial.cpp
Normal file
298
NPR_14/mbed-os/drivers/UARTSerial.cpp
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||
|
||||
#include <errno.h>
|
||||
#include "UARTSerial.h"
|
||||
#include "platform/mbed_poll.h"
|
||||
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
#include "rtos/Thread.h"
|
||||
#else
|
||||
#include "platform/mbed_wait_api.h"
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
|
||||
UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
|
||||
SerialBase(tx, rx, baud),
|
||||
_blocking(true),
|
||||
_tx_irq_enabled(false),
|
||||
_dcd_irq(NULL)
|
||||
{
|
||||
/* Attatch IRQ routines to the serial device. */
|
||||
SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
|
||||
}
|
||||
|
||||
UARTSerial::~UARTSerial()
|
||||
{
|
||||
delete _dcd_irq;
|
||||
}
|
||||
|
||||
void UARTSerial::dcd_irq()
|
||||
{
|
||||
wake();
|
||||
}
|
||||
|
||||
void UARTSerial::set_baud(int baud)
|
||||
{
|
||||
SerialBase::baud(baud);
|
||||
}
|
||||
|
||||
void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high)
|
||||
{
|
||||
delete _dcd_irq;
|
||||
_dcd_irq = NULL;
|
||||
|
||||
if (dcd_pin != NC) {
|
||||
_dcd_irq = new InterruptIn(dcd_pin);
|
||||
if (active_high) {
|
||||
_dcd_irq->fall(callback(this, &UARTSerial::dcd_irq));
|
||||
} else {
|
||||
_dcd_irq->rise(callback(this, &UARTSerial::dcd_irq));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int UARTSerial::close()
|
||||
{
|
||||
/* Does not let us pass a file descriptor. So how to close ?
|
||||
* Also, does it make sense to close a device type file descriptor*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int UARTSerial::isatty()
|
||||
{
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
off_t UARTSerial::seek(off_t offset, int whence)
|
||||
{
|
||||
/*XXX lseek can be done theoratically, but is it sane to mark positions on a dynamically growing/shrinking
|
||||
* buffer system (from an interrupt context) */
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
int UARTSerial::sync()
|
||||
{
|
||||
api_lock();
|
||||
|
||||
while (!_txbuf.empty()) {
|
||||
api_unlock();
|
||||
// Doing better than wait would require TxIRQ to also do wake() when becoming empty. Worth it?
|
||||
wait_ms(1);
|
||||
api_lock();
|
||||
}
|
||||
|
||||
api_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void UARTSerial::sigio(Callback<void()> func) {
|
||||
core_util_critical_section_enter();
|
||||
_sigio_cb = func;
|
||||
if (_sigio_cb) {
|
||||
short current_events = poll(0x7FFF);
|
||||
if (current_events) {
|
||||
_sigio_cb();
|
||||
}
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
ssize_t UARTSerial::write(const void* buffer, size_t length)
|
||||
{
|
||||
size_t data_written = 0;
|
||||
const char *buf_ptr = static_cast<const char *>(buffer);
|
||||
|
||||
api_lock();
|
||||
|
||||
while (_txbuf.full()) {
|
||||
if (!_blocking) {
|
||||
api_unlock();
|
||||
return -EAGAIN;
|
||||
}
|
||||
api_unlock();
|
||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||
api_lock();
|
||||
}
|
||||
|
||||
while (data_written < length && !_txbuf.full()) {
|
||||
_txbuf.push(*buf_ptr++);
|
||||
data_written++;
|
||||
}
|
||||
|
||||
core_util_critical_section_enter();
|
||||
if (!_tx_irq_enabled) {
|
||||
UARTSerial::tx_irq(); // only write to hardware in one place
|
||||
if (!_txbuf.empty()) {
|
||||
SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq);
|
||||
_tx_irq_enabled = true;
|
||||
}
|
||||
}
|
||||
core_util_critical_section_exit();
|
||||
|
||||
api_unlock();
|
||||
|
||||
return data_written;
|
||||
}
|
||||
|
||||
ssize_t UARTSerial::read(void* buffer, size_t length)
|
||||
{
|
||||
size_t data_read = 0;
|
||||
|
||||
char *ptr = static_cast<char *>(buffer);
|
||||
|
||||
api_lock();
|
||||
|
||||
while (_rxbuf.empty()) {
|
||||
if (!_blocking) {
|
||||
api_unlock();
|
||||
return -EAGAIN;
|
||||
}
|
||||
api_unlock();
|
||||
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
|
||||
api_lock();
|
||||
}
|
||||
|
||||
while (data_read < length && !_rxbuf.empty()) {
|
||||
_rxbuf.pop(*ptr++);
|
||||
data_read++;
|
||||
}
|
||||
|
||||
api_unlock();
|
||||
|
||||
return data_read;
|
||||
}
|
||||
|
||||
bool UARTSerial::hup() const
|
||||
{
|
||||
return _dcd_irq && _dcd_irq->read() != 0;
|
||||
}
|
||||
|
||||
void UARTSerial::wake()
|
||||
{
|
||||
if (_sigio_cb) {
|
||||
_sigio_cb();
|
||||
}
|
||||
}
|
||||
|
||||
short UARTSerial::poll(short events) const {
|
||||
|
||||
short revents = 0;
|
||||
/* Check the Circular Buffer if space available for writing out */
|
||||
|
||||
|
||||
if (!_rxbuf.empty()) {
|
||||
revents |= POLLIN;
|
||||
}
|
||||
|
||||
/* POLLHUP and POLLOUT are mutually exclusive */
|
||||
if (hup()) {
|
||||
revents |= POLLHUP;
|
||||
} else if (!_txbuf.full()) {
|
||||
revents |= POLLOUT;
|
||||
}
|
||||
|
||||
/*TODO Handle other event types */
|
||||
|
||||
return revents;
|
||||
}
|
||||
|
||||
void UARTSerial::lock()
|
||||
{
|
||||
// This is the override for SerialBase.
|
||||
// No lock required as we only use SerialBase from interrupt or from
|
||||
// inside our own critical section.
|
||||
}
|
||||
|
||||
void UARTSerial::unlock()
|
||||
{
|
||||
// This is the override for SerialBase.
|
||||
}
|
||||
|
||||
void UARTSerial::api_lock(void)
|
||||
{
|
||||
_mutex.lock();
|
||||
}
|
||||
|
||||
void UARTSerial::api_unlock(void)
|
||||
{
|
||||
_mutex.unlock();
|
||||
}
|
||||
|
||||
void UARTSerial::rx_irq(void)
|
||||
{
|
||||
bool was_empty = _rxbuf.empty();
|
||||
|
||||
/* Fill in the receive buffer if the peripheral is readable
|
||||
* and receive buffer is not full. */
|
||||
while (SerialBase::readable()) {
|
||||
char data = SerialBase::_base_getc();
|
||||
if (!_rxbuf.full()) {
|
||||
_rxbuf.push(data);
|
||||
} else {
|
||||
/* Drop - can we report in some way? */
|
||||
}
|
||||
}
|
||||
|
||||
/* Report the File handler that data is ready to be read from the buffer. */
|
||||
if (was_empty && !_rxbuf.empty()) {
|
||||
wake();
|
||||
}
|
||||
}
|
||||
|
||||
// Also called from write to start transfer
|
||||
void UARTSerial::tx_irq(void)
|
||||
{
|
||||
bool was_full = _txbuf.full();
|
||||
|
||||
/* Write to the peripheral if there is something to write
|
||||
* and if the peripheral is available to write. */
|
||||
while (!_txbuf.empty() && SerialBase::writeable()) {
|
||||
char data;
|
||||
_txbuf.pop(data);
|
||||
SerialBase::_base_putc(data);
|
||||
}
|
||||
|
||||
if (_tx_irq_enabled && _txbuf.empty()) {
|
||||
SerialBase::attach(NULL, TxIrq);
|
||||
_tx_irq_enabled = false;
|
||||
}
|
||||
|
||||
/* Report the File handler that data can be written to peripheral. */
|
||||
if (was_full && !_txbuf.full() && !hup()) {
|
||||
wake();
|
||||
}
|
||||
}
|
||||
|
||||
void UARTSerial::wait_ms(uint32_t millisec)
|
||||
{
|
||||
/* wait_ms implementation for RTOS spins until exact microseconds - we
|
||||
* want to just sleep until next tick.
|
||||
*/
|
||||
#if MBED_CONF_RTOS_PRESENT
|
||||
rtos::Thread::wait(millisec);
|
||||
#else
|
||||
::wait_ms(millisec);
|
||||
#endif
|
||||
}
|
||||
} //namespace mbed
|
||||
|
||||
#endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN)
|
||||
220
NPR_14/mbed-os/drivers/UARTSerial.h
Normal file
220
NPR_14/mbed-os/drivers/UARTSerial.h
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
/* mbed Microcontroller Library
|
||||
* Copyright (c) 2006-2017 ARM Limited
|
||||
*
|
||||
* Licensed 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 MBED_UARTSERIAL_H
|
||||
#define MBED_UARTSERIAL_H
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if (DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||
|
||||
#include "FileHandle.h"
|
||||
#include "SerialBase.h"
|
||||
#include "InterruptIn.h"
|
||||
#include "PlatformMutex.h"
|
||||
#include "serial_api.h"
|
||||
#include "CircularBuffer.h"
|
||||
#include "platform/NonCopyable.h"
|
||||
|
||||
#ifndef MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE
|
||||
#define MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE 256
|
||||
#endif
|
||||
|
||||
#ifndef MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE
|
||||
#define MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE 256
|
||||
#endif
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class UARTSerial : private SerialBase, public FileHandle, private NonCopyable<UARTSerial> {
|
||||
|
||||
public:
|
||||
|
||||
/** Create a UARTSerial port, connected to the specified transmit and receive pins, with a particular baud rate.
|
||||
* @param tx Transmit pin
|
||||
* @param rx Receive pin
|
||||
* @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE)
|
||||
*/
|
||||
UARTSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE);
|
||||
virtual ~UARTSerial();
|
||||
|
||||
/** Equivalent to POSIX poll(). Derived from FileHandle.
|
||||
* Provides a mechanism to multiplex input/output over a set of file handles.
|
||||
*/
|
||||
virtual short poll(short events) const;
|
||||
|
||||
/* Resolve ambiguities versus our private SerialBase
|
||||
* (for writable, spelling differs, but just in case)
|
||||
*/
|
||||
using FileHandle::readable;
|
||||
using FileHandle::writable;
|
||||
|
||||
/** Write the contents of a buffer to a file
|
||||
*
|
||||
* @param buffer The buffer to write from
|
||||
* @param length The number of bytes to write
|
||||
* @return The number of bytes written, negative error on failure
|
||||
*/
|
||||
virtual ssize_t write(const void* buffer, size_t length);
|
||||
|
||||
/** Read the contents of a file into a buffer
|
||||
*
|
||||
* Follows POSIX semantics:
|
||||
*
|
||||
* * if no data is available, and non-blocking set return -EAGAIN
|
||||
* * if no data is available, and blocking set, wait until data is available
|
||||
* * If any data is available, call returns immediately
|
||||
*
|
||||
* @param buffer The buffer to read in to
|
||||
* @param length The number of bytes to read
|
||||
* @return The number of bytes read, 0 at end of file, negative error on failure
|
||||
*/
|
||||
virtual ssize_t read(void* buffer, size_t length);
|
||||
|
||||
/** Close a file
|
||||
*
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual int close();
|
||||
|
||||
/** Check if the file in an interactive terminal device
|
||||
*
|
||||
* @return True if the file is a terminal
|
||||
* @return False if the file is not a terminal
|
||||
* @return Negative error code on failure
|
||||
*/
|
||||
virtual int isatty();
|
||||
|
||||
/** Move the file position to a given offset from from a given location
|
||||
*
|
||||
* Not valid for a device type FileHandle like UARTSerial.
|
||||
* In case of UARTSerial, returns ESPIPE
|
||||
*
|
||||
* @param offset The offset from whence to move to
|
||||
* @param whence The start of where to seek
|
||||
* SEEK_SET to start from beginning of file,
|
||||
* SEEK_CUR to start from current position in file,
|
||||
* SEEK_END to start from end of file
|
||||
* @return The new offset of the file, negative error code on failure
|
||||
*/
|
||||
virtual off_t seek(off_t offset, int whence);
|
||||
|
||||
/** Flush any buffers associated with the file
|
||||
*
|
||||
* @return 0 on success, negative error code on failure
|
||||
*/
|
||||
virtual int sync();
|
||||
|
||||
/** Set blocking or non-blocking mode
|
||||
* The default is blocking.
|
||||
*
|
||||
* @param blocking true for blocking mode, false for non-blocking mode.
|
||||
*/
|
||||
virtual int set_blocking(bool blocking)
|
||||
{
|
||||
_blocking = blocking;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Register a callback on state change of the file.
|
||||
*
|
||||
* The specified callback will be called on state changes such as when
|
||||
* the file can be written to or read from.
|
||||
*
|
||||
* The callback may be called in an interrupt context and should not
|
||||
* perform expensive operations.
|
||||
*
|
||||
* Note! This is not intended as an attach-like asynchronous api, but rather
|
||||
* as a building block for constructing such functionality.
|
||||
*
|
||||
* The exact timing of when the registered function
|
||||
* is called is not guaranteed and susceptible to change. It should be used
|
||||
* as a cue to make read/write/poll calls to find the current state.
|
||||
*
|
||||
* @param func Function to call on state change
|
||||
*/
|
||||
virtual void sigio(Callback<void()> func);
|
||||
|
||||
/** Setup interrupt handler for DCD line
|
||||
*
|
||||
* If DCD line is connected, an IRQ handler will be setup.
|
||||
* Does nothing if DCD is NC, i.e., not connected.
|
||||
*
|
||||
* @param dcd_pin Pin-name for DCD
|
||||
* @param active_high a boolean set to true if DCD polarity is active low
|
||||
*/
|
||||
void set_data_carrier_detect(PinName dcd_pin, bool active_high = false);
|
||||
|
||||
/** Set the baud rate
|
||||
*
|
||||
* @param baud The baud rate
|
||||
*/
|
||||
void set_baud(int baud);
|
||||
|
||||
private:
|
||||
|
||||
void wait_ms(uint32_t millisec);
|
||||
|
||||
/** SerialBase lock override */
|
||||
virtual void lock(void);
|
||||
|
||||
/** SerialBase unlock override */
|
||||
virtual void unlock(void);
|
||||
|
||||
/** Acquire mutex */
|
||||
virtual void api_lock(void);
|
||||
|
||||
/** Release mutex */
|
||||
virtual void api_unlock(void);
|
||||
|
||||
/** Software serial buffers
|
||||
* By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json
|
||||
*/
|
||||
CircularBuffer<char, MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE> _rxbuf;
|
||||
CircularBuffer<char, MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE> _txbuf;
|
||||
|
||||
PlatformMutex _mutex;
|
||||
|
||||
Callback<void()> _sigio_cb;
|
||||
|
||||
bool _blocking;
|
||||
bool _tx_irq_enabled;
|
||||
InterruptIn *_dcd_irq;
|
||||
|
||||
/** Device Hanged up
|
||||
* Determines if the device hanged up on us.
|
||||
*
|
||||
* @return True, if hanged up
|
||||
*/
|
||||
bool hup() const;
|
||||
|
||||
/** ISRs for serial
|
||||
* Routines to handle interrupts on serial pins.
|
||||
* Copies data into Circular Buffer.
|
||||
* Reports the state change to File handle.
|
||||
*/
|
||||
void tx_irq(void);
|
||||
void rx_irq(void);
|
||||
|
||||
void wake(void);
|
||||
|
||||
void dcd_irq(void);
|
||||
|
||||
};
|
||||
} //namespace mbed
|
||||
|
||||
#endif //(DEVICE_SERIAL && DEVICE_INTERRUPTIN) || defined(DOXYGEN_ONLY)
|
||||
#endif //MBED_UARTSERIAL_H
|
||||
13
NPR_14/mbed-os/drivers/mbed_lib.json
Normal file
13
NPR_14/mbed-os/drivers/mbed_lib.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "drivers",
|
||||
"config": {
|
||||
"uart-serial-txbuf-size": {
|
||||
"help": "Default TX buffer size for a UARTSerial instance (unit Bytes))",
|
||||
"value": 256
|
||||
},
|
||||
"uart-serial-rxbuf-size": {
|
||||
"help": "Default RX buffer size for a UARTSerial instance (unit Bytes))",
|
||||
"value": 256
|
||||
}
|
||||
}
|
||||
}
|
||||
3627
NPR_14/mbed-os/events/Event.h
Normal file
3627
NPR_14/mbed-os/events/Event.h
Normal file
File diff suppressed because it is too large
Load diff
66
NPR_14/mbed-os/events/EventQueue.cpp
Normal file
66
NPR_14/mbed-os/events/EventQueue.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/* events
|
||||
* Copyright (c) 2016 ARM Limited
|
||||
*
|
||||
* Licensed 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 "events/EventQueue.h"
|
||||
|
||||
#include "events/mbed_events.h"
|
||||
#include "mbed.h"
|
||||
|
||||
|
||||
EventQueue::EventQueue(unsigned event_size, unsigned char *event_pointer) {
|
||||
if (!event_pointer) {
|
||||
equeue_create(&_equeue, event_size);
|
||||
} else {
|
||||
equeue_create_inplace(&_equeue, event_size, event_pointer);
|
||||
}
|
||||
}
|
||||
|
||||
EventQueue::~EventQueue() {
|
||||
equeue_destroy(&_equeue);
|
||||
}
|
||||
|
||||
void EventQueue::dispatch(int ms) {
|
||||
return equeue_dispatch(&_equeue, ms);
|
||||
}
|
||||
|
||||
void EventQueue::break_dispatch() {
|
||||
return equeue_break(&_equeue);
|
||||
}
|
||||
|
||||
unsigned EventQueue::tick() {
|
||||
return equeue_tick();
|
||||
}
|
||||
|
||||
void EventQueue::cancel(int id) {
|
||||
return equeue_cancel(&_equeue, id);
|
||||
}
|
||||
|
||||
void EventQueue::background(Callback<void(int)> update) {
|
||||
_update = update;
|
||||
|
||||
if (_update) {
|
||||
equeue_background(&_equeue, &Callback<void(int)>::thunk, &_update);
|
||||
} else {
|
||||
equeue_background(&_equeue, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void EventQueue::chain(EventQueue *target) {
|
||||
if (target) {
|
||||
equeue_chain(&_equeue, &target->_equeue);
|
||||
} else {
|
||||
equeue_chain(&_equeue, 0);
|
||||
}
|
||||
}
|
||||
2734
NPR_14/mbed-os/events/EventQueue.h
Normal file
2734
NPR_14/mbed-os/events/EventQueue.h
Normal file
File diff suppressed because it is too large
Load diff
165
NPR_14/mbed-os/events/LICENSE
Normal file
165
NPR_14/mbed-os/events/LICENSE
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, "control" means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object code,
|
||||
generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||
available under the License, as indicated by a copyright notice that is included
|
||||
in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative Works
|
||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||
on behalf of the copyright owner. For the purposes of this definition,
|
||||
"submitted" means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||
the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such Contributor
|
||||
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If You institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||
Contribution incorporated within the Work constitutes direct or contributory
|
||||
patent infringement, then any patent licenses granted to You under this License
|
||||
for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution.
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||
in any medium, with or without modifications, and in Source or Object form,
|
||||
provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source form
|
||||
of the Work, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
153
NPR_14/mbed-os/events/README.md
Normal file
153
NPR_14/mbed-os/events/README.md
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
## The mbed-events library ##
|
||||
|
||||
The mbed-events library provides a flexible queue for scheduling events.
|
||||
|
||||
``` cpp
|
||||
#include "mbed_events.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
// creates a queue with the default size
|
||||
EventQueue queue;
|
||||
|
||||
// events are simple callbacks
|
||||
queue.call(printf, "called immediately\n");
|
||||
queue.call_in(2000, printf, "called in 2 seconds\n");
|
||||
queue.call_every(1000, printf, "called every 1 seconds\n");
|
||||
|
||||
// events are executed by the dispatch method
|
||||
queue.dispatch();
|
||||
}
|
||||
```
|
||||
|
||||
The mbed-events library can be used as a normal event loop, or it can be
|
||||
backgrounded on a single hardware timer or even another event loop. It is
|
||||
both thread and irq safe, and provides functions for easily composing
|
||||
independent event queues.
|
||||
|
||||
The mbed-events library can act as a drop-in scheduler, provide synchronization
|
||||
between multiple threads, or just act as a mechanism for moving events out of
|
||||
interrupt contexts.
|
||||
|
||||
### Usage ###
|
||||
|
||||
The core of the mbed-events library is the [EventQueue](EventQueue.h) class,
|
||||
which represents a single event queue. The `EventQueue::dispatch` function
|
||||
runs the queue, providing the context for executing events.
|
||||
|
||||
``` cpp
|
||||
// Creates an event queue enough buffer space for 32 Callbacks. This
|
||||
// is the default if no argument was provided. Alternatively the size
|
||||
// can just be specified in bytes.
|
||||
EventQueue queue(32*EVENTS_EVENT_SIZE);
|
||||
|
||||
// Events can be posted to the underlying event queue with dynamic
|
||||
// context allocated from the specified buffer
|
||||
queue.call(printf, "hello %d %d %d %d\n", 1, 2, 3, 4);
|
||||
queue.call(&serial, &Serial::printf, "hi\n");
|
||||
|
||||
// The dispatch function provides the context for the running the queue
|
||||
// and can take a millisecond timeout to run for a fixed time or to just
|
||||
// dispatch any pending events
|
||||
queue.dispatch();
|
||||
```
|
||||
|
||||
The EventQueue class provides several call functions for posting events
|
||||
to the underlying event queue. The call functions are thread and irq safe,
|
||||
don't need the underlying loop to be running, and provide an easy mechanism
|
||||
for moving events out of interrupt contexts.
|
||||
|
||||
``` cpp
|
||||
// Simple call function registers events to be called as soon as possible
|
||||
queue.call(doit);
|
||||
queue.call(printf, "called immediately\n");
|
||||
|
||||
// The call_in function registers events to be called after a delay
|
||||
// specified in milliseconds
|
||||
queue.call_in(2000, doit_in_two_seconds);
|
||||
queue.call_in(300, printf, "called in 0.3 seconds\n");
|
||||
|
||||
// The call_every function registers events to be called repeatedly
|
||||
// with a period specified in milliseconds
|
||||
queue.call_every(2000, doit_every_two_seconds);
|
||||
queue.call_every(400, printf, "called every 0.4 seconds\n");
|
||||
```
|
||||
|
||||
The call functions return an id that uniquely represents the event in the
|
||||
the event queue. This id can be passed to `EventQueue::cancel` to cancel
|
||||
an in-flight event.
|
||||
|
||||
``` cpp
|
||||
// The event id uniquely represents the event in the queue
|
||||
int id = queue.call_in(100, printf, "will this work?\n");
|
||||
|
||||
// If there was not enough memory necessary to allocate the event,
|
||||
// an id of 0 is returned from the call functions
|
||||
if (id) {
|
||||
error("oh no!");
|
||||
}
|
||||
|
||||
// Events can be cancelled as long as they have not been dispatched. If the
|
||||
// event has already expired, cancel has no side-effects.
|
||||
queue.cancel(id);
|
||||
```
|
||||
|
||||
For a more fine-grain control of event dispatch, the `Event` class can be
|
||||
manually instantiated and configured. An `Event` represents an event as
|
||||
a C++ style function object and can be directly passed to other APIs that
|
||||
expect a callback.
|
||||
|
||||
``` cpp
|
||||
// Creates an event bound to the specified event queue
|
||||
EventQueue queue;
|
||||
Event<void()> event(&queue, doit);
|
||||
|
||||
// The event can be manually configured for special timing requirements
|
||||
// specified in milliseconds
|
||||
event.delay(10);
|
||||
event.period(10000);
|
||||
|
||||
// Posted events are dispatched in the context of the queue's
|
||||
// dispatch function
|
||||
queue.dispatch();
|
||||
|
||||
// Events can also pass arguments to the underlying callback when both
|
||||
// initially constructed and posted.
|
||||
Event<void(int, int)> event(&queue, printf, "recieved %d and %d\n");
|
||||
|
||||
// Events can be posted multiple times and enqueue gracefully until
|
||||
// the dispatch function is called.
|
||||
event.post(1, 2);
|
||||
event.post(3, 4);
|
||||
event.post(5, 6);
|
||||
|
||||
queue.dispatch();
|
||||
```
|
||||
|
||||
Event queues easily align with module boundaries, where internal state can
|
||||
be implicitly synchronized through event dispatch. Multiple modules can
|
||||
use independent event queues, but still be composed through the
|
||||
`EventQueue::chain` function.
|
||||
|
||||
``` cpp
|
||||
// Create some event queues with pending events
|
||||
EventQueue a;
|
||||
a.call(printf, "hello from a!\n");
|
||||
|
||||
EventQueue b;
|
||||
b.call(printf, "hello from b!\n");
|
||||
|
||||
EventQueue c;
|
||||
c.call(printf, "hello from c!\n");
|
||||
|
||||
// Chain c and b onto a's event queue. Both c and b will be dispatched
|
||||
// in the context of a's dispatch function.
|
||||
c.chain(&a);
|
||||
b.chain(&a);
|
||||
|
||||
// Dispatching a will in turn dispatch b and c, printing hello from
|
||||
// all three queues
|
||||
a.dispatch();
|
||||
```
|
||||
|
||||
|
||||
1
NPR_14/mbed-os/events/equeue/.mbedignore
Normal file
1
NPR_14/mbed-os/events/equeue/.mbedignore
Normal file
|
|
@ -0,0 +1 @@
|
|||
tests/*
|
||||
60
NPR_14/mbed-os/events/equeue/Makefile
Normal file
60
NPR_14/mbed-os/events/equeue/Makefile
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
TARGET = libequeue.a
|
||||
|
||||
CC = gcc
|
||||
AR = ar
|
||||
SIZE = size
|
||||
|
||||
SRC += $(wildcard *.c)
|
||||
OBJ := $(SRC:.c=.o)
|
||||
DEP := $(SRC:.c=.d)
|
||||
ASM := $(SRC:.c=.s)
|
||||
|
||||
ifdef DEBUG
|
||||
CFLAGS += -O0 -g3
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
ifdef WORD
|
||||
CFLAGS += -m$(WORD)
|
||||
endif
|
||||
CFLAGS += -I. -I..
|
||||
CFLAGS += -std=c99
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -D_XOPEN_SOURCE=600
|
||||
|
||||
LFLAGS += -pthread
|
||||
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
test: tests/tests.o $(OBJ)
|
||||
$(CC) $(CFLAGS) $^ $(LFLAGS) -o tests/tests
|
||||
tests/tests
|
||||
|
||||
prof: tests/prof.o $(OBJ)
|
||||
$(CC) $(CFLAGS) $^ $(LFLAGS) -o tests/prof
|
||||
tests/prof
|
||||
|
||||
asm: $(ASM)
|
||||
|
||||
size: $(OBJ)
|
||||
$(SIZE) -t $^
|
||||
|
||||
-include $(DEP)
|
||||
|
||||
%.a: $(OBJ)
|
||||
$(AR) rcs $@ $^
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c -MMD $(CFLAGS) $< -o $@
|
||||
|
||||
%.s: %.c
|
||||
$(CC) -S $(CFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET)
|
||||
rm -f tests/tests tests/tests.o tests/tests.d
|
||||
rm -f tests/prof tests/prof.o tests/prof.d
|
||||
rm -f $(OBJ)
|
||||
rm -f $(DEP)
|
||||
rm -f $(ASM)
|
||||
210
NPR_14/mbed-os/events/equeue/README.md
Normal file
210
NPR_14/mbed-os/events/equeue/README.md
Normal file
|
|
@ -0,0 +1,210 @@
|
|||
## The equeue library ##
|
||||
|
||||
The equeue library is designed as a simple but powerful library for scheduling
|
||||
events on composable queues.
|
||||
|
||||
``` c
|
||||
#include "equeue.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
// creates a queue with space for 32 basic events
|
||||
equeue_t queue;
|
||||
equeue_create(&queue, 32*EQUEUE_EVENT_SIZE);
|
||||
|
||||
// events can be simple callbacks
|
||||
equeue_call(&queue, print, "called immediately");
|
||||
equeue_call_in(&queue, 2000, print, "called in 2 seconds");
|
||||
equeue_call_every(&queue, 1000, print, "called every 1 seconds");
|
||||
|
||||
// events are executed in equeue_dispatch
|
||||
equeue_dispatch(&queue, 3000);
|
||||
|
||||
print("called after 3 seconds");
|
||||
|
||||
equeue_destroy(&queue);
|
||||
}
|
||||
```
|
||||
|
||||
The equeue library can be used as a normal event loop, or it can be
|
||||
backgrounded on a single hardware timer or even another event loop. It
|
||||
is both thread and irq safe, and provides functions for easily composing
|
||||
multiple queues.
|
||||
|
||||
The equeue library can act as a drop-in scheduler, provide synchronization
|
||||
between multiple threads, or just act as a mechanism for moving events
|
||||
out of interrupt contexts.
|
||||
|
||||
## Documentation ##
|
||||
|
||||
The in-depth documentation on specific functions can be found in
|
||||
[equeue.h](equeue.h).
|
||||
|
||||
The core of the equeue library is the `equeue_t` type which represents a
|
||||
single event queue, and the `equeue_dispatch` function which runs the equeue,
|
||||
providing the context for executing events.
|
||||
|
||||
On top of this, `equeue_call`, `equeue_call_in`, and `equeue_call_every`
|
||||
provide easy methods for posting events to execute in the context of the
|
||||
`equeue_dispatch` function.
|
||||
|
||||
``` c
|
||||
#include "equeue.h"
|
||||
#include "game.h"
|
||||
|
||||
equeue_t queue;
|
||||
struct game game;
|
||||
|
||||
// button_isr may be in interrupt context
|
||||
void button_isr(void) {
|
||||
equeue_call(&queue, game_button_update, &game);
|
||||
}
|
||||
|
||||
// a simple user-interface framework
|
||||
int main() {
|
||||
equeue_create(&queue, 4096);
|
||||
game_create(&game);
|
||||
|
||||
// call game_screen_udpate at 60 Hz
|
||||
equeue_call_every(&queue, 1000/60, game_screen_update, &game);
|
||||
|
||||
// dispatch forever
|
||||
equeue_dispatch(&queue, -1);
|
||||
}
|
||||
```
|
||||
|
||||
In addition to simple callbacks, an event can be manually allocated with
|
||||
`equeue_alloc` and posted with `equeue_post` to allow passing an arbitrary
|
||||
amount of context to the execution of the event. This memory is allocated out
|
||||
of the equeue's buffer, and dynamic memory can be completely avoided.
|
||||
|
||||
The equeue allocator is designed to minimize jitter in interrupt contexts as
|
||||
well as avoid memory fragmentation on small devices. The allocator achieves
|
||||
both constant-runtime and zero-fragmentation for fixed-size events, however
|
||||
grows linearly as the quantity of differently-sized allocations increases.
|
||||
|
||||
``` c
|
||||
#include "equeue.h"
|
||||
|
||||
equeue_t queue;
|
||||
|
||||
// arbitrary data can be moved to a different context
|
||||
int enet_consume(void *buffer, int size) {
|
||||
if (size > 512) {
|
||||
size = 512;
|
||||
}
|
||||
|
||||
void *data = equeue_alloc(&queue, 512);
|
||||
memcpy(data, buffer, size);
|
||||
equeue_post(&queue, handle_data_elsewhere, data);
|
||||
|
||||
return size;
|
||||
}
|
||||
```
|
||||
|
||||
Additionally, in-flight events can be cancelled with `equeue_cancel`. Events
|
||||
are given unique ids on post, allowing safe cancellation of expired events.
|
||||
|
||||
``` c
|
||||
#include "equeue.h"
|
||||
|
||||
equeue_t queue;
|
||||
int sonar_value;
|
||||
int sonar_timeout_id;
|
||||
|
||||
void sonar_isr(int value) {
|
||||
equeue_cancel(&queue, sonar_timeout_id);
|
||||
sonar_value = value;
|
||||
}
|
||||
|
||||
void sonar_timeout(void *) {
|
||||
sonar_value = -1;
|
||||
}
|
||||
|
||||
void sonar_read(void) {
|
||||
sonar_timeout_id = equeue_call_in(&queue, 300, sonar_timeout, 0);
|
||||
sonar_start();
|
||||
}
|
||||
```
|
||||
|
||||
From an architectural standpoint, event queues easily align with module
|
||||
boundaries, where internal state can be implicitly synchronized through
|
||||
event dispatch.
|
||||
|
||||
On platforms where multiple threads are unavailable, multiple modules
|
||||
can use independent event queues and still be composed through the
|
||||
`equeue_chain` function.
|
||||
|
||||
``` c
|
||||
#include "equeue.h"
|
||||
|
||||
// run a simultaneous localization and mapping loop in one queue
|
||||
struct slam {
|
||||
equeue_t queue;
|
||||
};
|
||||
|
||||
void slam_create(struct slam *s, equeue_t *target) {
|
||||
equeue_create(&s->queue, 4096);
|
||||
equeue_chain(&s->queue, target);
|
||||
equeue_call_every(&s->queue, 100, slam_filter);
|
||||
}
|
||||
|
||||
// run a sonar with it's own queue
|
||||
struct sonar {
|
||||
equeue_t equeue;
|
||||
struct slam *slam;
|
||||
};
|
||||
|
||||
void sonar_create(struct sonar *s, equeue_t *target) {
|
||||
equeue_create(&s->queue, 64);
|
||||
equeue_chain(&s->queue, target);
|
||||
equeue_call_in(&s->queue, 5, sonar_update, s);
|
||||
}
|
||||
|
||||
// all of the above queues can be combined into a single thread of execution
|
||||
int main() {
|
||||
equeue_t queue;
|
||||
equeue_create(&queue, 1024);
|
||||
|
||||
struct sonar s1, s2, s3;
|
||||
sonar_create(&s1, &queue);
|
||||
sonar_create(&s2, &queue);
|
||||
sonar_create(&s3, &queue);
|
||||
|
||||
struct slam slam;
|
||||
slam_create(&slam, &queue);
|
||||
|
||||
// dispatches events from all of the modules
|
||||
equeue_dispatch(&queue, -1);
|
||||
}
|
||||
```
|
||||
|
||||
## Platform ##
|
||||
|
||||
The equeue library has a minimal porting layer that is flexible depending
|
||||
on the requirements of the underlying platform. Platform specific declarations
|
||||
and more information can be found in [equeue_platform.h](equeue_platform.h).
|
||||
|
||||
## Tests ##
|
||||
|
||||
The equeue library uses a set of local tests based on the posix implementation.
|
||||
|
||||
Runtime tests are located in [tests.c](tests/tests.c):
|
||||
|
||||
``` bash
|
||||
make test
|
||||
```
|
||||
|
||||
Profiling tests based on rdtsc are located in [prof.c](tests/prof.c):
|
||||
|
||||
``` bash
|
||||
make prof
|
||||
```
|
||||
|
||||
To make profiling results more tangible, the profiler also supports percentage
|
||||
comparison with previous runs:
|
||||
``` bash
|
||||
make prof | tee results.txt
|
||||
cat results.txt | make prof
|
||||
```
|
||||
|
||||
574
NPR_14/mbed-os/events/equeue/equeue.c
Normal file
574
NPR_14/mbed-os/events/equeue/equeue.c
Normal file
|
|
@ -0,0 +1,574 @@
|
|||
/*
|
||||
* Flexible event queue for dispatching events
|
||||
*
|
||||
* Copyright (c) 2016 Christopher Haster
|
||||
*
|
||||
* Licensed 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 "equeue/equeue.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// calculate the relative-difference between absolute times while
|
||||
// correctly handling overflow conditions
|
||||
static inline int equeue_tickdiff(unsigned a, unsigned b) {
|
||||
return (int)(unsigned)(a - b);
|
||||
}
|
||||
|
||||
// calculate the relative-difference between absolute times, but
|
||||
// also clamp to zero, resulting in only non-zero values.
|
||||
static inline int equeue_clampdiff(unsigned a, unsigned b) {
|
||||
int diff = equeue_tickdiff(a, b);
|
||||
return ~(diff >> (8*sizeof(int)-1)) & diff;
|
||||
}
|
||||
|
||||
// Increment the unique id in an event, hiding the event from cancel
|
||||
static inline void equeue_incid(equeue_t *q, struct equeue_event *e) {
|
||||
e->id += 1;
|
||||
if (!(e->id << q->npw2)) {
|
||||
e->id = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// equeue lifetime management
|
||||
int equeue_create(equeue_t *q, size_t size) {
|
||||
// dynamically allocate the specified buffer
|
||||
void *buffer = malloc(size);
|
||||
if (!buffer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int err = equeue_create_inplace(q, size, buffer);
|
||||
q->allocated = buffer;
|
||||
return err;
|
||||
}
|
||||
|
||||
int equeue_create_inplace(equeue_t *q, size_t size, void *buffer) {
|
||||
// setup queue around provided buffer
|
||||
q->buffer = buffer;
|
||||
q->allocated = 0;
|
||||
|
||||
q->npw2 = 0;
|
||||
for (unsigned s = size; s; s >>= 1) {
|
||||
q->npw2++;
|
||||
}
|
||||
|
||||
q->chunks = 0;
|
||||
q->slab.size = size;
|
||||
q->slab.data = buffer;
|
||||
|
||||
q->queue = 0;
|
||||
q->tick = equeue_tick();
|
||||
q->generation = 0;
|
||||
q->breaks = 0;
|
||||
|
||||
q->background.active = false;
|
||||
q->background.update = 0;
|
||||
q->background.timer = 0;
|
||||
|
||||
// initialize platform resources
|
||||
int err;
|
||||
err = equeue_sema_create(&q->eventsema);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = equeue_mutex_create(&q->queuelock);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = equeue_mutex_create(&q->memlock);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void equeue_destroy(equeue_t *q) {
|
||||
// call destructors on pending events
|
||||
for (struct equeue_event *es = q->queue; es; es = es->next) {
|
||||
for (struct equeue_event *e = q->queue; e; e = e->sibling) {
|
||||
if (e->dtor) {
|
||||
e->dtor(e + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// notify background timer
|
||||
if (q->background.update) {
|
||||
q->background.update(q->background.timer, -1);
|
||||
}
|
||||
|
||||
// clean up platform resources + memory
|
||||
equeue_mutex_destroy(&q->memlock);
|
||||
equeue_mutex_destroy(&q->queuelock);
|
||||
equeue_sema_destroy(&q->eventsema);
|
||||
free(q->allocated);
|
||||
}
|
||||
|
||||
|
||||
// equeue chunk allocation functions
|
||||
static struct equeue_event *equeue_mem_alloc(equeue_t *q, size_t size) {
|
||||
// add event overhead
|
||||
size += sizeof(struct equeue_event);
|
||||
size = (size + sizeof(void*)-1) & ~(sizeof(void*)-1);
|
||||
|
||||
equeue_mutex_lock(&q->memlock);
|
||||
|
||||
// check if a good chunk is available
|
||||
for (struct equeue_event **p = &q->chunks; *p; p = &(*p)->next) {
|
||||
if ((*p)->size >= size) {
|
||||
struct equeue_event *e = *p;
|
||||
if (e->sibling) {
|
||||
*p = e->sibling;
|
||||
(*p)->next = e->next;
|
||||
} else {
|
||||
*p = e->next;
|
||||
}
|
||||
|
||||
equeue_mutex_unlock(&q->memlock);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
// otherwise allocate a new chunk out of the slab
|
||||
if (q->slab.size >= size) {
|
||||
struct equeue_event *e = (struct equeue_event *)q->slab.data;
|
||||
q->slab.data += size;
|
||||
q->slab.size -= size;
|
||||
e->size = size;
|
||||
e->id = 1;
|
||||
|
||||
equeue_mutex_unlock(&q->memlock);
|
||||
return e;
|
||||
}
|
||||
|
||||
equeue_mutex_unlock(&q->memlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void equeue_mem_dealloc(equeue_t *q, struct equeue_event *e) {
|
||||
equeue_mutex_lock(&q->memlock);
|
||||
|
||||
// stick chunk into list of chunks
|
||||
struct equeue_event **p = &q->chunks;
|
||||
while (*p && (*p)->size < e->size) {
|
||||
p = &(*p)->next;
|
||||
}
|
||||
|
||||
if (*p && (*p)->size == e->size) {
|
||||
e->sibling = *p;
|
||||
e->next = (*p)->next;
|
||||
} else {
|
||||
e->sibling = 0;
|
||||
e->next = *p;
|
||||
}
|
||||
*p = e;
|
||||
|
||||
equeue_mutex_unlock(&q->memlock);
|
||||
}
|
||||
|
||||
void *equeue_alloc(equeue_t *q, size_t size) {
|
||||
struct equeue_event *e = equeue_mem_alloc(q, size);
|
||||
if (!e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
e->target = 0;
|
||||
e->period = -1;
|
||||
e->dtor = 0;
|
||||
|
||||
return e + 1;
|
||||
}
|
||||
|
||||
void equeue_dealloc(equeue_t *q, void *p) {
|
||||
struct equeue_event *e = (struct equeue_event*)p - 1;
|
||||
|
||||
if (e->dtor) {
|
||||
e->dtor(e+1);
|
||||
}
|
||||
|
||||
equeue_mem_dealloc(q, e);
|
||||
}
|
||||
|
||||
|
||||
// equeue scheduling functions
|
||||
static int equeue_enqueue(equeue_t *q, struct equeue_event *e, unsigned tick) {
|
||||
// setup event and hash local id with buffer offset for unique id
|
||||
int id = (e->id << q->npw2) | ((unsigned char *)e - q->buffer);
|
||||
e->target = tick + equeue_clampdiff(e->target, tick);
|
||||
e->generation = q->generation;
|
||||
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
|
||||
// find the event slot
|
||||
struct equeue_event **p = &q->queue;
|
||||
while (*p && equeue_tickdiff((*p)->target, e->target) < 0) {
|
||||
p = &(*p)->next;
|
||||
}
|
||||
|
||||
// insert at head in slot
|
||||
if (*p && (*p)->target == e->target) {
|
||||
e->next = (*p)->next;
|
||||
if (e->next) {
|
||||
e->next->ref = &e->next;
|
||||
}
|
||||
|
||||
e->sibling = *p;
|
||||
e->sibling->ref = &e->sibling;
|
||||
} else {
|
||||
e->next = *p;
|
||||
if (e->next) {
|
||||
e->next->ref = &e->next;
|
||||
}
|
||||
|
||||
e->sibling = 0;
|
||||
}
|
||||
|
||||
*p = e;
|
||||
e->ref = p;
|
||||
|
||||
// notify background timer
|
||||
if ((q->background.update && q->background.active) &&
|
||||
(q->queue == e && !e->sibling)) {
|
||||
q->background.update(q->background.timer,
|
||||
equeue_clampdiff(e->target, tick));
|
||||
}
|
||||
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static struct equeue_event *equeue_unqueue(equeue_t *q, int id) {
|
||||
// decode event from unique id and check that the local id matches
|
||||
struct equeue_event *e = (struct equeue_event *)
|
||||
&q->buffer[id & ((1 << q->npw2)-1)];
|
||||
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
if (e->id != id >> q->npw2) {
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// clear the event and check if already in-flight
|
||||
e->cb = 0;
|
||||
e->period = -1;
|
||||
|
||||
int diff = equeue_tickdiff(e->target, q->tick);
|
||||
if (diff < 0 || (diff == 0 && e->generation != q->generation)) {
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// disentangle from queue
|
||||
if (e->sibling) {
|
||||
e->sibling->next = e->next;
|
||||
if (e->sibling->next) {
|
||||
e->sibling->next->ref = &e->sibling->next;
|
||||
}
|
||||
|
||||
*e->ref = e->sibling;
|
||||
e->sibling->ref = e->ref;
|
||||
} else {
|
||||
*e->ref = e->next;
|
||||
if (e->next) {
|
||||
e->next->ref = e->ref;
|
||||
}
|
||||
}
|
||||
|
||||
equeue_incid(q, e);
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
static struct equeue_event *equeue_dequeue(equeue_t *q, unsigned target) {
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
|
||||
// find all expired events and mark a new generation
|
||||
q->generation += 1;
|
||||
if (equeue_tickdiff(q->tick, target) <= 0) {
|
||||
q->tick = target;
|
||||
}
|
||||
|
||||
struct equeue_event *head = q->queue;
|
||||
struct equeue_event **p = &head;
|
||||
while (*p && equeue_tickdiff((*p)->target, target) <= 0) {
|
||||
p = &(*p)->next;
|
||||
}
|
||||
|
||||
q->queue = *p;
|
||||
if (q->queue) {
|
||||
q->queue->ref = &q->queue;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
|
||||
// reverse and flatten each slot to match insertion order
|
||||
struct equeue_event **tail = &head;
|
||||
struct equeue_event *ess = head;
|
||||
while (ess) {
|
||||
struct equeue_event *es = ess;
|
||||
ess = es->next;
|
||||
|
||||
struct equeue_event *prev = 0;
|
||||
for (struct equeue_event *e = es; e; e = e->sibling) {
|
||||
e->next = prev;
|
||||
prev = e;
|
||||
}
|
||||
|
||||
*tail = prev;
|
||||
tail = &es->next;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
int equeue_post(equeue_t *q, void (*cb)(void*), void *p) {
|
||||
struct equeue_event *e = (struct equeue_event*)p - 1;
|
||||
unsigned tick = equeue_tick();
|
||||
e->cb = cb;
|
||||
e->target = tick + e->target;
|
||||
|
||||
int id = equeue_enqueue(q, e, tick);
|
||||
equeue_sema_signal(&q->eventsema);
|
||||
return id;
|
||||
}
|
||||
|
||||
void equeue_cancel(equeue_t *q, int id) {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct equeue_event *e = equeue_unqueue(q, id);
|
||||
if (e) {
|
||||
equeue_dealloc(q, e + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void equeue_break(equeue_t *q) {
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
q->breaks++;
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
equeue_sema_signal(&q->eventsema);
|
||||
}
|
||||
|
||||
void equeue_dispatch(equeue_t *q, int ms) {
|
||||
unsigned tick = equeue_tick();
|
||||
unsigned timeout = tick + ms;
|
||||
q->background.active = false;
|
||||
|
||||
while (1) {
|
||||
// collect all the available events and next deadline
|
||||
struct equeue_event *es = equeue_dequeue(q, tick);
|
||||
|
||||
// dispatch events
|
||||
while (es) {
|
||||
struct equeue_event *e = es;
|
||||
es = e->next;
|
||||
|
||||
// actually dispatch the callbacks
|
||||
void (*cb)(void *) = e->cb;
|
||||
if (cb) {
|
||||
cb(e + 1);
|
||||
}
|
||||
|
||||
// reenqueue periodic events or deallocate
|
||||
if (e->period >= 0) {
|
||||
e->target += e->period;
|
||||
equeue_enqueue(q, e, equeue_tick());
|
||||
} else {
|
||||
equeue_incid(q, e);
|
||||
equeue_dealloc(q, e+1);
|
||||
}
|
||||
}
|
||||
|
||||
int deadline = -1;
|
||||
tick = equeue_tick();
|
||||
|
||||
// check if we should stop dispatching soon
|
||||
if (ms >= 0) {
|
||||
deadline = equeue_tickdiff(timeout, tick);
|
||||
if (deadline <= 0) {
|
||||
// update background timer if necessary
|
||||
if (q->background.update) {
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
if (q->background.update && q->queue) {
|
||||
q->background.update(q->background.timer,
|
||||
equeue_clampdiff(q->queue->target, tick));
|
||||
}
|
||||
q->background.active = true;
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// find closest deadline
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
if (q->queue) {
|
||||
int diff = equeue_clampdiff(q->queue->target, tick);
|
||||
if ((unsigned)diff < (unsigned)deadline) {
|
||||
deadline = diff;
|
||||
}
|
||||
}
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
|
||||
// wait for events
|
||||
equeue_sema_wait(&q->eventsema, deadline);
|
||||
|
||||
// check if we were notified to break out of dispatch
|
||||
if (q->breaks) {
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
if (q->breaks > 0) {
|
||||
q->breaks--;
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
return;
|
||||
}
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
}
|
||||
|
||||
// update tick for next iteration
|
||||
tick = equeue_tick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// event functions
|
||||
void equeue_event_delay(void *p, int ms) {
|
||||
struct equeue_event *e = (struct equeue_event*)p - 1;
|
||||
e->target = ms;
|
||||
}
|
||||
|
||||
void equeue_event_period(void *p, int ms) {
|
||||
struct equeue_event *e = (struct equeue_event*)p - 1;
|
||||
e->period = ms;
|
||||
}
|
||||
|
||||
void equeue_event_dtor(void *p, void (*dtor)(void *)) {
|
||||
struct equeue_event *e = (struct equeue_event*)p - 1;
|
||||
e->dtor = dtor;
|
||||
}
|
||||
|
||||
|
||||
// simple callbacks
|
||||
struct ecallback {
|
||||
void (*cb)(void*);
|
||||
void *data;
|
||||
};
|
||||
|
||||
static void ecallback_dispatch(void *p) {
|
||||
struct ecallback *e = (struct ecallback*)p;
|
||||
e->cb(e->data);
|
||||
}
|
||||
|
||||
int equeue_call(equeue_t *q, void (*cb)(void*), void *data) {
|
||||
struct ecallback *e = equeue_alloc(q, sizeof(struct ecallback));
|
||||
if (!e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
e->cb = cb;
|
||||
e->data = data;
|
||||
return equeue_post(q, ecallback_dispatch, e);
|
||||
}
|
||||
|
||||
int equeue_call_in(equeue_t *q, int ms, void (*cb)(void*), void *data) {
|
||||
struct ecallback *e = equeue_alloc(q, sizeof(struct ecallback));
|
||||
if (!e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
equeue_event_delay(e, ms);
|
||||
e->cb = cb;
|
||||
e->data = data;
|
||||
return equeue_post(q, ecallback_dispatch, e);
|
||||
}
|
||||
|
||||
int equeue_call_every(equeue_t *q, int ms, void (*cb)(void*), void *data) {
|
||||
struct ecallback *e = equeue_alloc(q, sizeof(struct ecallback));
|
||||
if (!e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
equeue_event_delay(e, ms);
|
||||
equeue_event_period(e, ms);
|
||||
e->cb = cb;
|
||||
e->data = data;
|
||||
return equeue_post(q, ecallback_dispatch, e);
|
||||
}
|
||||
|
||||
|
||||
// backgrounding
|
||||
void equeue_background(equeue_t *q,
|
||||
void (*update)(void *timer, int ms), void *timer) {
|
||||
equeue_mutex_lock(&q->queuelock);
|
||||
if (q->background.update) {
|
||||
q->background.update(q->background.timer, -1);
|
||||
}
|
||||
|
||||
q->background.update = update;
|
||||
q->background.timer = timer;
|
||||
|
||||
if (q->background.update && q->queue) {
|
||||
q->background.update(q->background.timer,
|
||||
equeue_clampdiff(q->queue->target, equeue_tick()));
|
||||
}
|
||||
q->background.active = true;
|
||||
equeue_mutex_unlock(&q->queuelock);
|
||||
}
|
||||
|
||||
struct equeue_chain_context {
|
||||
equeue_t *q;
|
||||
equeue_t *target;
|
||||
int id;
|
||||
};
|
||||
|
||||
static void equeue_chain_dispatch(void *p) {
|
||||
equeue_dispatch((equeue_t *)p, 0);
|
||||
}
|
||||
|
||||
static void equeue_chain_update(void *p, int ms) {
|
||||
struct equeue_chain_context *c = (struct equeue_chain_context *)p;
|
||||
equeue_cancel(c->target, c->id);
|
||||
|
||||
if (ms >= 0) {
|
||||
c->id = equeue_call_in(c->target, ms, equeue_chain_dispatch, c->q);
|
||||
} else {
|
||||
equeue_dealloc(c->target, c);
|
||||
}
|
||||
}
|
||||
|
||||
void equeue_chain(equeue_t *q, equeue_t *target) {
|
||||
if (!target) {
|
||||
equeue_background(q, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
struct equeue_chain_context *c = equeue_alloc(q,
|
||||
sizeof(struct equeue_chain_context));
|
||||
|
||||
c->q = q;
|
||||
c->target = target;
|
||||
c->id = 0;
|
||||
|
||||
equeue_background(q, equeue_chain_update, c);
|
||||
}
|
||||
223
NPR_14/mbed-os/events/equeue/equeue.h
Normal file
223
NPR_14/mbed-os/events/equeue/equeue.h
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
|
||||
/** \addtogroup events */
|
||||
/** @{*/
|
||||
/*
|
||||
* Flexible event queue for dispatching events
|
||||
*
|
||||
* Copyright (c) 2016 Christopher Haster
|
||||
*
|
||||
* Licensed 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 EQUEUE_H
|
||||
#define EQUEUE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Platform specific files
|
||||
#include "equeue/equeue_platform.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
// The minimum size of an event
|
||||
// This size is guaranteed to fit events created by event_call
|
||||
#define EQUEUE_EVENT_SIZE (sizeof(struct equeue_event) + 2*sizeof(void*))
|
||||
|
||||
// Internal event structure
|
||||
struct equeue_event {
|
||||
unsigned size;
|
||||
uint8_t id;
|
||||
uint8_t generation;
|
||||
|
||||
struct equeue_event *next;
|
||||
struct equeue_event *sibling;
|
||||
struct equeue_event **ref;
|
||||
|
||||
unsigned target;
|
||||
int period;
|
||||
void (*dtor)(void *);
|
||||
|
||||
void (*cb)(void *);
|
||||
// data follows
|
||||
};
|
||||
|
||||
// Event queue structure
|
||||
typedef struct equeue {
|
||||
struct equeue_event *queue;
|
||||
unsigned tick;
|
||||
unsigned breaks;
|
||||
uint8_t generation;
|
||||
|
||||
unsigned char *buffer;
|
||||
unsigned npw2;
|
||||
void *allocated;
|
||||
|
||||
struct equeue_event *chunks;
|
||||
struct equeue_slab {
|
||||
size_t size;
|
||||
unsigned char *data;
|
||||
} slab;
|
||||
|
||||
struct equeue_background {
|
||||
bool active;
|
||||
void (*update)(void *timer, int ms);
|
||||
void *timer;
|
||||
} background;
|
||||
|
||||
equeue_sema_t eventsema;
|
||||
equeue_mutex_t queuelock;
|
||||
equeue_mutex_t memlock;
|
||||
} equeue_t;
|
||||
|
||||
|
||||
// Queue lifetime operations
|
||||
//
|
||||
// Creates and destroys an event queue. The event queue either allocates a
|
||||
// buffer of the specified size with malloc or uses a user provided buffer
|
||||
// if constructed with equeue_create_inplace.
|
||||
//
|
||||
// If the event queue creation fails, equeue_create returns a negative,
|
||||
// platform-specific error code.
|
||||
int equeue_create(equeue_t *queue, size_t size);
|
||||
int equeue_create_inplace(equeue_t *queue, size_t size, void *buffer);
|
||||
void equeue_destroy(equeue_t *queue);
|
||||
|
||||
// Dispatch events
|
||||
//
|
||||
// Executes events until the specified milliseconds have passed. If ms is
|
||||
// negative, equeue_dispatch will dispatch events indefinitely or until
|
||||
// equeue_break is called on this queue.
|
||||
//
|
||||
// When called with a finite timeout, the equeue_dispatch function is
|
||||
// guaranteed to terminate. When called with a timeout of 0, the
|
||||
// equeue_dispatch does not wait and is irq safe.
|
||||
void equeue_dispatch(equeue_t *queue, int ms);
|
||||
|
||||
// Break out of a running event loop
|
||||
//
|
||||
// Forces the specified event queue's dispatch loop to terminate. Pending
|
||||
// events may finish executing, but no new events will be executed.
|
||||
void equeue_break(equeue_t *queue);
|
||||
|
||||
// Simple event calls
|
||||
//
|
||||
// The specified callback will be executed in the context of the event queue's
|
||||
// dispatch loop. When the callback is executed depends on the call function.
|
||||
//
|
||||
// equeue_call - Immediately post an event to the queue
|
||||
// equeue_call_in - Post an event after a specified time in milliseconds
|
||||
// equeue_call_every - Post an event periodically every milliseconds
|
||||
//
|
||||
// All equeue_call functions are irq safe and can act as a mechanism for
|
||||
// moving events out of irq contexts.
|
||||
//
|
||||
// The return value is a unique id that represents the posted event and can
|
||||
// be passed to equeue_cancel. If there is not enough memory to allocate the
|
||||
// event, equeue_call returns an id of 0.
|
||||
int equeue_call(equeue_t *queue, void (*cb)(void *), void *data);
|
||||
int equeue_call_in(equeue_t *queue, int ms, void (*cb)(void *), void *data);
|
||||
int equeue_call_every(equeue_t *queue, int ms, void (*cb)(void *), void *data);
|
||||
|
||||
// Allocate memory for events
|
||||
//
|
||||
// The equeue_alloc function allocates an event that can be manually dispatched
|
||||
// with equeue_post. The equeue_dealloc function may be used to free an event
|
||||
// that has not been posted. Once posted, an event's memory is managed by the
|
||||
// event queue and should not be deallocated.
|
||||
//
|
||||
// Both equeue_alloc and equeue_dealloc are irq safe.
|
||||
//
|
||||
// The equeue allocator is designed to minimize jitter in interrupt contexts as
|
||||
// well as avoid memory fragmentation on small devices. The allocator achieves
|
||||
// both constant-runtime and zero-fragmentation for fixed-size events, however
|
||||
// grows linearly as the quantity of different sized allocations increases.
|
||||
//
|
||||
// The equeue_alloc function returns a pointer to the event's allocated memory
|
||||
// and acts as a handle to the underlying event. If there is not enough memory
|
||||
// to allocate the event, equeue_alloc returns null.
|
||||
void *equeue_alloc(equeue_t *queue, size_t size);
|
||||
void equeue_dealloc(equeue_t *queue, void *event);
|
||||
|
||||
// Configure an allocated event
|
||||
//
|
||||
// equeue_event_delay - Millisecond delay before dispatching an event
|
||||
// equeue_event_period - Millisecond period for repeating dispatching an event
|
||||
// equeue_event_dtor - Destructor to run when the event is deallocated
|
||||
void equeue_event_delay(void *event, int ms);
|
||||
void equeue_event_period(void *event, int ms);
|
||||
void equeue_event_dtor(void *event, void (*dtor)(void *));
|
||||
|
||||
// Post an event onto the event queue
|
||||
//
|
||||
// The equeue_post function takes a callback and a pointer to an event
|
||||
// allocated by equeue_alloc. The specified callback will be executed in the
|
||||
// context of the event queue's dispatch loop with the allocated event
|
||||
// as its argument.
|
||||
//
|
||||
// The equeue_post function is irq safe and can act as a mechanism for
|
||||
// moving events out of irq contexts.
|
||||
//
|
||||
// The return value is a unique id that represents the posted event and can
|
||||
// be passed to equeue_cancel.
|
||||
int equeue_post(equeue_t *queue, void (*cb)(void *), void *event);
|
||||
|
||||
// Cancel an in-flight event
|
||||
//
|
||||
// Attempts to cancel an event referenced by the unique id returned from
|
||||
// equeue_call or equeue_post. It is safe to call equeue_cancel after an event
|
||||
// has already been dispatched.
|
||||
//
|
||||
// The equeue_cancel function is irq safe.
|
||||
//
|
||||
// If called while the event queue's dispatch loop is active, equeue_cancel
|
||||
// does not guarantee that the event will not not execute after it returns as
|
||||
// the event may have already begun executing.
|
||||
void equeue_cancel(equeue_t *queue, int id);
|
||||
|
||||
// Background an event queue onto a single-shot timer
|
||||
//
|
||||
// The provided update function will be called to indicate when the queue
|
||||
// should be dispatched. A negative timeout will be passed to the update
|
||||
// function when the timer is no longer needed.
|
||||
//
|
||||
// Passing a null update function disables the existing timer.
|
||||
//
|
||||
// The equeue_background function allows an event queue to take advantage
|
||||
// of hardware timers or even other event loops, allowing an event queue to
|
||||
// be effectively backgrounded.
|
||||
void equeue_background(equeue_t *queue,
|
||||
void (*update)(void *timer, int ms), void *timer);
|
||||
|
||||
// Chain an event queue onto another event queue
|
||||
//
|
||||
// After chaining a queue to a target, calling equeue_dispatch on the
|
||||
// target queue will also dispatch events from this queue. The queues
|
||||
// use their own buffers and events must be managed independently.
|
||||
//
|
||||
// Passing a null queue as the target will unchain the existing queue.
|
||||
//
|
||||
// The equeue_chain function allows multiple equeues to be composed, sharing
|
||||
// the context of a dispatch loop while still being managed independently.
|
||||
void equeue_chain(equeue_t *queue, equeue_t *target);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
158
NPR_14/mbed-os/events/equeue/equeue_mbed.cpp
Normal file
158
NPR_14/mbed-os/events/equeue/equeue_mbed.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Implementation for the mbed library
|
||||
* https://github.com/mbedmicro/mbed
|
||||
*
|
||||
* Copyright (c) 2016 Christopher Haster
|
||||
*
|
||||
* Licensed 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 "equeue/equeue_platform.h"
|
||||
|
||||
#if defined(EQUEUE_PLATFORM_MBED)
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "mbed.h"
|
||||
|
||||
|
||||
// Ticker operations
|
||||
static bool equeue_tick_inited = false;
|
||||
static volatile unsigned equeue_minutes = 0;
|
||||
static unsigned equeue_timer[
|
||||
(sizeof(Timer)+sizeof(unsigned)-1)/sizeof(unsigned)];
|
||||
static unsigned equeue_ticker[
|
||||
(sizeof(Ticker)+sizeof(unsigned)-1)/sizeof(unsigned)];
|
||||
|
||||
static void equeue_tick_update() {
|
||||
equeue_minutes += reinterpret_cast<Timer*>(equeue_timer)->read_ms();
|
||||
reinterpret_cast<Timer*>(equeue_timer)->reset();
|
||||
}
|
||||
|
||||
static void equeue_tick_init() {
|
||||
MBED_STATIC_ASSERT(sizeof(equeue_timer) >= sizeof(Timer),
|
||||
"The equeue_timer buffer must fit the class Timer");
|
||||
MBED_STATIC_ASSERT(sizeof(equeue_ticker) >= sizeof(Ticker),
|
||||
"The equeue_ticker buffer must fit the class Ticker");
|
||||
Timer *timer = new (equeue_timer) Timer;
|
||||
Ticker *ticker = new (equeue_ticker) Ticker;
|
||||
|
||||
equeue_minutes = 0;
|
||||
timer->start();
|
||||
ticker->attach_us(equeue_tick_update, 1000 << 16);
|
||||
|
||||
equeue_tick_inited = true;
|
||||
}
|
||||
|
||||
unsigned equeue_tick() {
|
||||
if (!equeue_tick_inited) {
|
||||
equeue_tick_init();
|
||||
}
|
||||
|
||||
unsigned minutes;
|
||||
unsigned ms;
|
||||
|
||||
do {
|
||||
minutes = equeue_minutes;
|
||||
ms = reinterpret_cast<Timer*>(equeue_timer)->read_ms();
|
||||
} while (minutes != equeue_minutes);
|
||||
|
||||
return minutes + ms;
|
||||
}
|
||||
|
||||
|
||||
// Mutex operations
|
||||
int equeue_mutex_create(equeue_mutex_t *m) { return 0; }
|
||||
void equeue_mutex_destroy(equeue_mutex_t *m) { }
|
||||
|
||||
void equeue_mutex_lock(equeue_mutex_t *m) {
|
||||
core_util_critical_section_enter();
|
||||
}
|
||||
|
||||
void equeue_mutex_unlock(equeue_mutex_t *m) {
|
||||
core_util_critical_section_exit();
|
||||
}
|
||||
|
||||
|
||||
// Semaphore operations
|
||||
#ifdef MBED_CONF_RTOS_PRESENT
|
||||
|
||||
int equeue_sema_create(equeue_sema_t *s) {
|
||||
osEventFlagsAttr_t attr;
|
||||
memset(&attr, 0, sizeof(attr));
|
||||
attr.cb_mem = &s->mem;
|
||||
attr.cb_size = sizeof(s->mem);
|
||||
|
||||
s->id = osEventFlagsNew(&attr);
|
||||
return !s->id ? -1 : 0;
|
||||
}
|
||||
|
||||
void equeue_sema_destroy(equeue_sema_t *s) {
|
||||
osEventFlagsDelete(s->id);
|
||||
}
|
||||
|
||||
void equeue_sema_signal(equeue_sema_t *s) {
|
||||
osEventFlagsSet(s->id, 1);
|
||||
}
|
||||
|
||||
bool equeue_sema_wait(equeue_sema_t *s, int ms) {
|
||||
if (ms < 0) {
|
||||
ms = osWaitForever;
|
||||
}
|
||||
|
||||
return (osEventFlagsWait(s->id, 1, osFlagsWaitAny, ms) == 1);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// Semaphore operations
|
||||
int equeue_sema_create(equeue_sema_t *s) {
|
||||
*s = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void equeue_sema_destroy(equeue_sema_t *s) {
|
||||
}
|
||||
|
||||
void equeue_sema_signal(equeue_sema_t *s) {
|
||||
*s = 1;
|
||||
}
|
||||
|
||||
static void equeue_sema_timeout(equeue_sema_t *s) {
|
||||
*s = -1;
|
||||
}
|
||||
|
||||
bool equeue_sema_wait(equeue_sema_t *s, int ms) {
|
||||
int signal = 0;
|
||||
Timeout timeout;
|
||||
if (ms == 0) {
|
||||
return false;
|
||||
} else if (ms > 0) {
|
||||
timeout.attach_us(callback(equeue_sema_timeout, s), ms*1000);
|
||||
}
|
||||
|
||||
core_util_critical_section_enter();
|
||||
while (!*s) {
|
||||
sleep();
|
||||
core_util_critical_section_exit();
|
||||
core_util_critical_section_enter();
|
||||
}
|
||||
|
||||
signal = *s;
|
||||
*s = false;
|
||||
core_util_critical_section_exit();
|
||||
|
||||
return (signal > 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
152
NPR_14/mbed-os/events/equeue/equeue_platform.h
Normal file
152
NPR_14/mbed-os/events/equeue/equeue_platform.h
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
|
||||
/** \addtogroup events */
|
||||
/** @{*/
|
||||
/*
|
||||
* System specific implementation
|
||||
*
|
||||
* Copyright (c) 2016 Christopher Haster
|
||||
*
|
||||
* Licensed 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 EQUEUE_PLATFORM_H
|
||||
#define EQUEUE_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
// Currently supported platforms
|
||||
//
|
||||
// Uncomment to select a supported platform or reimplement this file
|
||||
// for a specific target.
|
||||
//#define EQUEUE_PLATFORM_POSIX
|
||||
//#define EQUEUE_PLATFORM_MBED
|
||||
|
||||
// Try to infer a platform if none was manually selected
|
||||
#if !defined(EQUEUE_PLATFORM_POSIX) \
|
||||
&& !defined(EQUEUE_PLATFORM_MBED)
|
||||
#if defined(__unix__)
|
||||
#define EQUEUE_PLATFORM_POSIX
|
||||
#elif defined(__MBED__)
|
||||
#define EQUEUE_PLATFORM_MBED
|
||||
#else
|
||||
#warning "Unknown platform! Please update equeue_platform.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Platform includes
|
||||
#if defined(EQUEUE_PLATFORM_POSIX)
|
||||
#include <pthread.h>
|
||||
#elif defined(EQUEUE_PLATFORM_MBED)
|
||||
#include "cmsis_os2.h"
|
||||
#include "mbed_rtos_storage.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Platform millisecond counter
|
||||
//
|
||||
// Return a tick that represents the number of milliseconds that have passed
|
||||
// since an arbitrary point in time. The granularity does not need to be at
|
||||
// the millisecond level, however the accuracy of the equeue library is
|
||||
// limited by the accuracy of this tick.
|
||||
//
|
||||
// Must intentionally overflow to 0 after 2^32-1
|
||||
unsigned equeue_tick(void);
|
||||
|
||||
|
||||
// Platform mutex type
|
||||
//
|
||||
// The equeue library requires at minimum a non-recursive mutex that is
|
||||
// safe in interrupt contexts. The mutex section is help for a bounded
|
||||
// amount of time, so simply disabling interrupts is acceptable
|
||||
//
|
||||
// If irq safety is not required, a regular blocking mutex can be used.
|
||||
#if defined(EQUEUE_PLATFORM_POSIX)
|
||||
typedef pthread_mutex_t equeue_mutex_t;
|
||||
#elif defined(EQUEUE_PLATFORM_WINDOWS)
|
||||
typedef CRITICAL_SECTION equeue_mutex_t;
|
||||
#elif defined(EQUEUE_PLATFORM_MBED)
|
||||
typedef unsigned equeue_mutex_t;
|
||||
#elif defined(EQUEUE_PLATFORM_FREERTOS)
|
||||
typedef UBaseType_t equeue_mutex_t;
|
||||
#endif
|
||||
|
||||
// Platform mutex operations
|
||||
//
|
||||
// The equeue_mutex_create and equeue_mutex_destroy manage the lifetime
|
||||
// of the mutex. On error, equeue_mutex_create should return a negative
|
||||
// error code.
|
||||
//
|
||||
// The equeue_mutex_lock and equeue_mutex_unlock lock and unlock the
|
||||
// underlying mutex.
|
||||
int equeue_mutex_create(equeue_mutex_t *mutex);
|
||||
void equeue_mutex_destroy(equeue_mutex_t *mutex);
|
||||
void equeue_mutex_lock(equeue_mutex_t *mutex);
|
||||
void equeue_mutex_unlock(equeue_mutex_t *mutex);
|
||||
|
||||
|
||||
// Platform semaphore type
|
||||
//
|
||||
// The equeue library requires a binary semaphore type that can be safely
|
||||
// signaled from interrupt contexts and from inside a equeue_mutex section.
|
||||
//
|
||||
// The equeue_signal_wait is relied upon by the equeue library to sleep the
|
||||
// processor between events. Spurious wakeups have no negative-effects.
|
||||
//
|
||||
// A counting semaphore will also work, however may cause the event queue
|
||||
// dispatch loop to run unnecessarily. For that matter, equeue_signal_wait
|
||||
// may even be implemented as a single return statement.
|
||||
#if defined(EQUEUE_PLATFORM_POSIX)
|
||||
typedef struct equeue_sema {
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
bool signal;
|
||||
} equeue_sema_t;
|
||||
#elif defined(EQUEUE_PLATFORM_MBED) && defined(MBED_CONF_RTOS_PRESENT)
|
||||
typedef struct equeue_sema {
|
||||
osEventFlagsId_t id;
|
||||
mbed_rtos_storage_event_flags_t mem;
|
||||
} equeue_sema_t;
|
||||
#elif defined(EQUEUE_PLATFORM_MBED)
|
||||
typedef volatile int equeue_sema_t;
|
||||
#endif
|
||||
|
||||
// Platform semaphore operations
|
||||
//
|
||||
// The equeue_sema_create and equeue_sema_destroy manage the lifetime
|
||||
// of the semaphore. On error, equeue_sema_create should return a negative
|
||||
// error code.
|
||||
//
|
||||
// The equeue_sema_signal marks a semaphore as signalled such that the next
|
||||
// equeue_sema_wait will return true.
|
||||
//
|
||||
// The equeue_sema_wait waits for a semaphore to be signalled or returns
|
||||
// immediately if equeue_sema_signal had been called since the last
|
||||
// equeue_sema_wait. The equeue_sema_wait returns true if it detected that
|
||||
// equeue_sema_signal had been called. If ms is negative, equeue_sema_wait
|
||||
// will wait for a signal indefinitely.
|
||||
int equeue_sema_create(equeue_sema_t *sema);
|
||||
void equeue_sema_destroy(equeue_sema_t *sema);
|
||||
void equeue_sema_signal(equeue_sema_t *sema);
|
||||
bool equeue_sema_wait(equeue_sema_t *sema, int ms);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue