git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7387 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
66ea340bb1
commit
0320aa5314
|
@ -24,6 +24,11 @@
|
|||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>OLIMEX_LPC_P2148</name>
|
||||
<type>2</type>
|
||||
<locationURI>CHIBIOS/os/hal/boards/OLIMEX_LPC_P2148</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>os</name>
|
||||
<type>2</type>
|
||||
|
|
|
@ -105,13 +105,13 @@ PROJECT = ch
|
|||
|
||||
# Imported source files and paths
|
||||
CHIBIOS = ../../..
|
||||
#include $(CHIBIOS)/os/hal/hal.mk
|
||||
#include $(CHIBIOS)/os/hal/boards/ST_STM32VL_DISCOVERY/board.mk
|
||||
#include $(CHIBIOS)/os/hal/ports/STM32/STM32F1xx/platform.mk
|
||||
#include $(CHIBIOS)/os/hal/osal/rt/osal.mk
|
||||
include $(CHIBIOS)/os/hal/hal.mk
|
||||
include $(CHIBIOS)/os/hal/boards/OLIMEX_LPC_P2148/board.mk
|
||||
include $(CHIBIOS)/os/hal/ports/LPC/LPC214x/platform.mk
|
||||
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
|
||||
include $(CHIBIOS)/os/rt/rt.mk
|
||||
include $(CHIBIOS)/os/rt/ports/ARM/compilers/GCC/mk/port_lpc214x.mk
|
||||
#include $(CHIBIOS)/test/rt/test.mk
|
||||
include $(CHIBIOS)/test/rt/test.mk
|
||||
|
||||
# Define linker script file here
|
||||
LDSCRIPT = $(PORTLD)/LPC2148.ld
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file templates/halconf.h
|
||||
* @brief HAL configuration header.
|
||||
* @details HAL configuration file, this file allows to enable or disable the
|
||||
* various device drivers from your application. You may also use
|
||||
* this file in order to override the device drivers default settings.
|
||||
*
|
||||
* @addtogroup HAL_CONF
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HALCONF_H_
|
||||
#define _HALCONF_H_
|
||||
|
||||
#include "mcuconf.h"
|
||||
|
||||
/**
|
||||
* @brief Enables the PAL subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_PAL TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the ADC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ADC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the CAN subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_CAN FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the EXT subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_EXT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the GPT subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_GPT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the I2C subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_I2C FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the I2S subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_I2S FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the ICU subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_ICU FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the MAC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_MAC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the MMC_SPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_MMC_SPI FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the PWM subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_PWM FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the RTC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_RTC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SDC subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SDC FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SERIAL subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SERIAL over USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SERIAL_USB FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the SPI subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_SPI FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the UART subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_UART) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_UART FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the USB subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_USB) || defined(__DOXYGEN__)
|
||||
#define HAL_USE_USB FALSE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* ADC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* CAN driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Sleep mode related APIs inclusion switch.
|
||||
*/
|
||||
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
|
||||
#define CAN_USE_SLEEP_MODE TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I2C driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the mutual exclusion APIs on the I2C bus.
|
||||
*/
|
||||
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MAC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables an event sources for incoming packets.
|
||||
*/
|
||||
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_ZERO_COPY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables an event sources for incoming packets.
|
||||
*/
|
||||
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_EVENTS TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* MMC_SPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Delays insertions.
|
||||
* @details If enabled this options inserts delays into the MMC waiting
|
||||
* routines releasing some extra CPU time for the threads with
|
||||
* lower priority, this may slow down the driver a bit however.
|
||||
* This option is recommended also if the SPI driver does not
|
||||
* use a DMA channel and heavily loads the CPU.
|
||||
*/
|
||||
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define MMC_NICE_WAITING TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SDC driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of initialization attempts before rejecting the card.
|
||||
* @note Attempts are performed at 10mS intervals.
|
||||
*/
|
||||
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_RETRY 100
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Include support for MMC cards.
|
||||
* @note MMC support is not yet implemented so this option must be kept
|
||||
* at @p FALSE.
|
||||
*/
|
||||
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
|
||||
#define SDC_MMC_SUPPORT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Delays insertions.
|
||||
* @details If enabled this options inserts delays into the MMC waiting
|
||||
* routines releasing some extra CPU time for the threads with
|
||||
* lower priority, this may slow down the driver a bit however.
|
||||
*/
|
||||
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define SDC_NICE_WAITING TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SERIAL driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Default bit rate.
|
||||
* @details Configuration parameter, this is the baud rate selected for the
|
||||
* default configuration.
|
||||
*/
|
||||
#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_DEFAULT_BITRATE 38400
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Serial buffers size.
|
||||
* @details Configuration parameter, you can change the depth of the queue
|
||||
* buffers depending on the requirements of your application.
|
||||
* @note The default is 64 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_BUFFERS_SIZE 16
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* SPI driver related settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
#endif /* _HALCONF_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* LPC214x drivers configuration.
|
||||
* The following settings override the default settings present in
|
||||
* the various device driver implementation headers.
|
||||
* Note that the settings for each driver only have effect if the driver
|
||||
* is enabled in halconf.h.
|
||||
*/
|
||||
|
||||
/*
|
||||
* ADC driver system settings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* CAN driver system settings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MAC driver system settings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PWM driver system settings.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SERIAL driver system settings.
|
||||
*/
|
||||
#define USE_LPC214x_UART0 TRUE
|
||||
#define USE_LPC214x_UART1 TRUE
|
||||
#define LPC214x_UART_FIFO_PRELOAD 16
|
||||
#define LPC214x_UART0_PRIORITY 1
|
||||
#define LPC214x_UART1_PRIORITY 2
|
||||
|
||||
/*
|
||||
* SPI driver system settings.
|
||||
*/
|
||||
#define USE_LPC214x_SPI1 TRUE
|
|
@ -42,9 +42,9 @@ static CH_IRQ_HANDLER(T0IrqHandler) {
|
|||
CH_IRQ_PROLOGUE();
|
||||
T0IR = 1; /* Clear interrupt on match MR0. */
|
||||
|
||||
chSysLockFromIsr();
|
||||
chSysLockFromISR();
|
||||
chSysTimerHandlerI();
|
||||
chSysUnlockFromIsr();
|
||||
chSysUnlockFromISR();
|
||||
|
||||
VICVectAddr = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
|
@ -87,7 +87,7 @@ void boardInit(void) {
|
|||
VICIntEnable = INTMASK(SOURCE_Timer0);
|
||||
TC *timer = T0Base;
|
||||
timer->TC_PR = VAL_TC0_PRESCALER;
|
||||
timer->TC_MR0 = (PCLK / CH_FREQUENCY) / (VAL_TC0_PRESCALER + 1);
|
||||
timer->TC_MR0 = (PCLK / CH_CFG_ST_FREQUENCY) / (VAL_TC0_PRESCALER + 1);
|
||||
timer->TC_MCR = 3; /* Interrupt and clear TC on match MR0. */
|
||||
timer->TC_TCR = 2; /* Reset counter and prescaler. */
|
||||
timer->TC_TCR = 1; /* Timer enabled. */
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/hal_lld.c
|
||||
* @brief LPC214x HAL subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Non-vectored IRQs handler, the default action can be overridden by
|
||||
* redefining the @p LPC214x_NON_VECTORED_IRQ_HOOK() hook macro.
|
||||
*/
|
||||
static CH_IRQ_HANDLER(irq_handler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
LPC214x_NON_VECTORED_IRQ_HOOK();
|
||||
|
||||
VICVectAddr = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level HAL driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void hal_lld_init(void) {
|
||||
|
||||
vic_init();
|
||||
VICDefVectAddr = (IOREG32)irq_handler;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LPC214x clocks and PLL initialization.
|
||||
* @note All the involved constants come from the file @p board.h.
|
||||
* @note This function must be invoked only after the system reset.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
void lpc214x_clock_init(void) {
|
||||
|
||||
/*
|
||||
* All peripherals clock disabled by default in order to save power.
|
||||
*/
|
||||
PCONP = PCRTC | PCTIM0;
|
||||
|
||||
/*
|
||||
* MAM setup.
|
||||
*/
|
||||
MAMTIM = 0x3; /* 3 cycles for flash accesses. */
|
||||
MAMCR = 0x2; /* MAM fully enabled. */
|
||||
|
||||
/*
|
||||
* PLL setup for Fosc=12MHz and CCLK=48MHz.
|
||||
* P=2 M=3.
|
||||
*/
|
||||
PLL *pll = PLL0Base;
|
||||
pll->PLL_CFG = 0x23; /* P and M values. */
|
||||
pll->PLL_CON = 0x1; /* Enables the PLL 0. */
|
||||
pll->PLL_FEED = 0xAA;
|
||||
pll->PLL_FEED = 0x55;
|
||||
while (!(pll->PLL_STAT & 0x400))
|
||||
; /* Wait for PLL lock. */
|
||||
|
||||
pll->PLL_CON = 0x3; /* Connects the PLL. */
|
||||
pll->PLL_FEED = 0xAA;
|
||||
pll->PLL_FEED = 0x55;
|
||||
|
||||
/*
|
||||
* VPB setup.
|
||||
* PCLK = CCLK / 4.
|
||||
*/
|
||||
VPBDIV = VPD_D4;
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/hal_lld.h
|
||||
* @brief LPC214x HAL subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HAL_LLD_H_
|
||||
#define _HAL_LLD_H_
|
||||
|
||||
#include "lpc214x.h"
|
||||
#include "vic.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Defines the support for realtime counters in the HAL.
|
||||
*/
|
||||
#define HAL_IMPLEMENTS_COUNTERS FALSE
|
||||
|
||||
/**
|
||||
* @brief Platform name.
|
||||
*/
|
||||
#define PLATFORM_NAME "LPC214x"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Default action for the non vectored IRQ handler, nothing.
|
||||
*/
|
||||
#if !defined(LPC214x_NON_VECTORED_IRQ_HOOK) || defined(__DOXYGEN__)
|
||||
#define LPC214x_NON_VECTORED_IRQ_HOOK()
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void hal_lld_init(void);
|
||||
void lpc214x_clock_init(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/pal_lld.c
|
||||
* @brief LPC214x FIO low level driver code.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief LPC214x I/O ports configuration.
|
||||
* @details FIO units and PINSEL registers initialization.
|
||||
*
|
||||
* @param[in] config the LPC214x ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_init(const PALConfig *config) {
|
||||
|
||||
/* Enables the access through the fast registers.*/
|
||||
SCS = 3;
|
||||
|
||||
/* I/O pads initial assignment, device drivers may change this setup at a
|
||||
* later time.*/
|
||||
PINSEL0 = config->pinsel0;
|
||||
PINSEL1 = config->pinsel1;
|
||||
PINSEL2 = config->pinsel2;
|
||||
|
||||
/* I/O pads direction initial setting.*/
|
||||
FIO0Base->FIO_MASK = 0;
|
||||
FIO0Base->FIO_PIN = config->P0Data.pin;
|
||||
FIO0Base->FIO_DIR = config->P0Data.dir;
|
||||
FIO1Base->FIO_MASK = 0;
|
||||
FIO1Base->FIO_PIN = config->P1Data.pin;
|
||||
FIO1Base->FIO_DIR = config->P1Data.dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pads mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with
|
||||
* high state.
|
||||
* @note This function does not alter the @p PINSELx registers. Alternate
|
||||
* functions setup must be handled by device-specific code.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] mask the group mask
|
||||
* @param[in] mode the mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode) {
|
||||
|
||||
switch (mode) {
|
||||
case PAL_MODE_RESET:
|
||||
case PAL_MODE_INPUT:
|
||||
port->FIO_DIR &= ~mask;
|
||||
break;
|
||||
case PAL_MODE_UNCONNECTED:
|
||||
port->FIO_PIN |= mask;
|
||||
case PAL_MODE_OUTPUT_PUSHPULL:
|
||||
port->FIO_DIR |= mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/pal_lld.h
|
||||
* @brief LPC214x FIO low level driver header.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PAL_LLD_H_
|
||||
#define _PAL_LLD_H_
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Unsupported modes and specific modes */
|
||||
/*===========================================================================*/
|
||||
|
||||
#undef PAL_MODE_INPUT_PULLUP
|
||||
#undef PAL_MODE_INPUT_PULLDOWN
|
||||
#undef PAL_MODE_OUTPUT_OPENDRAIN
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Types and constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief FIO port setup info.
|
||||
*/
|
||||
typedef struct {
|
||||
/** Initial value for FIO_PIN register.*/
|
||||
uint32_t pin;
|
||||
/** Initial value for FIO_DIR register.*/
|
||||
uint32_t dir;
|
||||
} lpc214x_fio_setup_t;
|
||||
|
||||
/**
|
||||
* @brief LPC214x FIO static initializer.
|
||||
* @details An instance of this structure must be passed to @p palInit() at
|
||||
* system startup time in order to initialize the digital I/O
|
||||
* subsystem. This represents only the initial setup, specific pads
|
||||
* or whole ports can be reprogrammed at later time.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief PINSEL0 initial value.*/
|
||||
uint32_t pinsel0;
|
||||
/** @brief PINSEL1 initial value.*/
|
||||
uint32_t pinsel1;
|
||||
/** @brief PINSEL2 initial value.*/
|
||||
uint32_t pinsel2;
|
||||
/** @brief Port 0 setup data.*/
|
||||
lpc214x_fio_setup_t P0Data;
|
||||
/** @brief Port 1 setup data.*/
|
||||
lpc214x_fio_setup_t P1Data;
|
||||
} PALConfig;
|
||||
|
||||
/**
|
||||
* @brief Width, in bits, of an I/O port.
|
||||
*/
|
||||
#define PAL_IOPORTS_WIDTH 32
|
||||
|
||||
/**
|
||||
* @brief Whole port mask.
|
||||
* @details This macro specifies all the valid bits into a port.
|
||||
*/
|
||||
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFF)
|
||||
|
||||
/**
|
||||
* @brief Digital I/O port sized unsigned type.
|
||||
*/
|
||||
typedef uint32_t ioportmask_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O modes.
|
||||
*/
|
||||
typedef uint32_t iomode_t;
|
||||
|
||||
/**
|
||||
* @brief Port Identifier.
|
||||
*/
|
||||
typedef FIO * ioportid_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Identifiers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief FIO port 0 identifier.
|
||||
*/
|
||||
#define IOPORT1 FIO0Base
|
||||
|
||||
/**
|
||||
* @brief FIO port 1 identifier.
|
||||
*/
|
||||
#define IOPORT2 FIO1Base
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Implementation, some of the following macros could be implemented as */
|
||||
/* functions, if so please put them in pal_lld.c. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief FIO subsystem initialization.
|
||||
* @details Enables the access through the fast registers.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_init(config) _pal_lld_init(config)
|
||||
|
||||
/**
|
||||
* @brief Reads an I/O port.
|
||||
* @details This function is implemented by reading the FIO PIN register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The port bits.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readport(port) ((port)->FIO_PIN)
|
||||
|
||||
/**
|
||||
* @brief Reads the output latch.
|
||||
* @details This function is implemented by reading the FIO SET register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readlatch(port) ((port)->FIO_SET)
|
||||
|
||||
/**
|
||||
* @brief Writes a bits mask on a I/O port.
|
||||
* @details This function is implemented by writing the FIO PIN register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be written on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writeport(port, bits) ((port)->FIO_PIN = (bits))
|
||||
|
||||
/**
|
||||
* @brief Sets a bits mask on a I/O port.
|
||||
* @details This function is implemented by writing the FIO SET register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be ORed on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setport(port, bits) ((port)->FIO_SET = (bits))
|
||||
|
||||
/**
|
||||
* @brief Clears a bits mask on a I/O port.
|
||||
* @details This function is implemented by writing the FIO CLR register, the
|
||||
* implementation has no side effects.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be cleared on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_clearport(port, bits) ((port)->FIO_CLR = (bits))
|
||||
|
||||
/**
|
||||
* @brief Writes a value on an I/O bus.
|
||||
* @details This function is implemented by writing the FIO PIN and MASK
|
||||
* registers, the implementation is not atomic because the multiple
|
||||
* accesses.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask, a logical AND is performed on the
|
||||
* output data
|
||||
* @param[in] offset the group bit offset within the port
|
||||
* @param[in] bits bits to be written. Values exceeding the group
|
||||
* width are masked.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writegroup(port, mask, offset, bits) \
|
||||
((port)->FIO_MASK = ~((mask) << (offset)), \
|
||||
(port)->FIO_PIN = (bits) << (offset), \
|
||||
(port)->FIO_MASK = 0)
|
||||
|
||||
/**
|
||||
* @brief Pads group mode setup.
|
||||
* @details This function programs a pads group belonging to the same port
|
||||
* with the specified mode.
|
||||
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with
|
||||
* high state.
|
||||
* @note This function does not alter the @p PINSELx registers. Alternate
|
||||
* functions setup must be handled by device-specific code.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] mode group mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setgroupmode(port, mask, offset, mode) \
|
||||
_pal_lld_setgroupmode(port, mask << offset, mode)
|
||||
|
||||
/**
|
||||
* @brief Writes a logical state on an output pad.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] bit logical value, the value must be @p PAL_LOW or
|
||||
* @p PAL_HIGH
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
|
||||
|
||||
/**
|
||||
* @brief FIO port setup.
|
||||
* @details This function programs the pins direction within a port.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_lpc214x_set_direction(port, dir) ((port)->FIO_DIR = (dir))
|
||||
|
||||
extern const PALConfig pal_default_config;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _pal_lld_init(const PALConfig *config);
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
#endif /* _PAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,9 @@
|
|||
# List of all the LPC214x platform files.
|
||||
PLATFORMSRC = ${CHIBIOS}/os/hal/ports/LPC/LPC214x/hal_lld.c \
|
||||
${CHIBIOS}/os/hal/ports/LPC/LPC214x/pal_lld.c \
|
||||
${CHIBIOS}/os/hal/ports/LPC/LPC214x/serial_lld.c \
|
||||
${CHIBIOS}/os/hal/ports/LPC/LPC214x/spi_lld.c \
|
||||
${CHIBIOS}/os/hal/ports/LPC/LPC214x/vic.c
|
||||
|
||||
# Required include directories
|
||||
PLATFORMINC = ${CHIBIOS}/os/hal/ports/LPC/LPC214x
|
|
@ -0,0 +1,346 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/serial_lld.c
|
||||
* @brief LPC214x low level serial driver code.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_LPC214x_UART0 || defined(__DOXYGEN__)
|
||||
/** @brief UART0 serial driver identifier.*/
|
||||
SerialDriver SD1;
|
||||
#endif
|
||||
|
||||
#if USE_LPC214x_UART1 || defined(__DOXYGEN__)
|
||||
/** @brief UART1 serial driver identifier.*/
|
||||
SerialDriver SD2;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief Driver default configuration.*/
|
||||
static const SerialConfig default_config = {
|
||||
SERIAL_DEFAULT_BITRATE,
|
||||
LCR_WL8 | LCR_STOP1 | LCR_NOPARITY,
|
||||
FCR_TRIGGER0
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART initialization.
|
||||
*
|
||||
* @param[in] sdp communication channel associated to the UART
|
||||
* @param[in] config the architecture-dependent serial driver configuration
|
||||
*/
|
||||
static void uart_init(SerialDriver *sdp, const SerialConfig *config) {
|
||||
UART *u = sdp->uart;
|
||||
|
||||
uint32_t div = PCLK / (config->sc_speed << 4);
|
||||
u->UART_LCR = config->sc_lcr | LCR_DLAB;
|
||||
u->UART_DLL = div;
|
||||
u->UART_DLM = div >> 8;
|
||||
u->UART_LCR = config->sc_lcr;
|
||||
u->UART_FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | config->sc_fcr;
|
||||
u->UART_ACR = 0;
|
||||
u->UART_FDR = 0x10;
|
||||
u->UART_TER = TER_ENABLE;
|
||||
u->UART_IER = IER_RBR | IER_STATUS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART de-initialization.
|
||||
*
|
||||
* @param[in] u pointer to an UART I/O block
|
||||
*/
|
||||
static void uart_deinit(UART *u) {
|
||||
|
||||
u->UART_LCR = LCR_DLAB;
|
||||
u->UART_DLL = 1;
|
||||
u->UART_DLM = 0;
|
||||
u->UART_LCR = 0;
|
||||
u->UART_FDR = 0x10;
|
||||
u->UART_IER = 0;
|
||||
u->UART_FCR = FCR_RXRESET | FCR_TXRESET;
|
||||
u->UART_ACR = 0;
|
||||
u->UART_TER = TER_ENABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Error handling routine.
|
||||
*
|
||||
* @param[in] sdp communication channel associated to the UART
|
||||
* @param[in] err UART LSR register value
|
||||
*/
|
||||
static void set_error(SerialDriver *sdp, IOREG32 err) {
|
||||
eventflags_t sts = 0;
|
||||
|
||||
if (err & LSR_OVERRUN)
|
||||
sts |= SD_OVERRUN_ERROR;
|
||||
if (err & LSR_PARITY)
|
||||
sts |= SD_PARITY_ERROR;
|
||||
if (err & LSR_FRAMING)
|
||||
sts |= SD_FRAMING_ERROR;
|
||||
if (err & LSR_BREAK)
|
||||
sts |= SD_BREAK_DETECTED;
|
||||
chSysLockFromISR();
|
||||
chnAddFlagsI(sdp, sts);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((noinline))
|
||||
#endif
|
||||
/**
|
||||
* @brief Common IRQ handler.
|
||||
* @note Tries hard to clear all the pending interrupt sources, we dont want
|
||||
* to go through the whole ISR and have another interrupt soon after.
|
||||
*
|
||||
* @param[in] sdp communication channel associated to the UART
|
||||
*/
|
||||
static void serve_interrupt(SerialDriver *sdp) {
|
||||
UART *u = sdp->uart;
|
||||
|
||||
while (TRUE) {
|
||||
switch (u->UART_IIR & IIR_SRC_MASK) {
|
||||
case IIR_SRC_NONE:
|
||||
return;
|
||||
case IIR_SRC_ERROR:
|
||||
set_error(sdp, u->UART_LSR);
|
||||
break;
|
||||
case IIR_SRC_TIMEOUT:
|
||||
case IIR_SRC_RX:
|
||||
chSysLockFromISR();
|
||||
if (chIQIsEmptyI(&sdp->iqueue))
|
||||
chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE);
|
||||
chSysUnlockFromISR();
|
||||
while (u->UART_LSR & LSR_RBR_FULL) {
|
||||
chSysLockFromISR();
|
||||
if (chIQPutI(&sdp->iqueue, u->UART_RBR) < Q_OK)
|
||||
chnAddFlagsI(sdp, SD_OVERRUN_ERROR);
|
||||
chSysUnlockFromISR();
|
||||
}
|
||||
break;
|
||||
case IIR_SRC_TX:
|
||||
{
|
||||
int i = LPC214x_UART_FIFO_PRELOAD;
|
||||
do {
|
||||
msg_t b;
|
||||
|
||||
chSysLockFromISR();
|
||||
b = chOQGetI(&sdp->oqueue);
|
||||
chSysUnlockFromISR();
|
||||
if (b < Q_OK) {
|
||||
u->UART_IER &= ~IER_THRE;
|
||||
chSysLockFromISR();
|
||||
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||
chSysUnlockFromISR();
|
||||
break;
|
||||
}
|
||||
u->UART_THR = b;
|
||||
} while (--i);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
(void) u->UART_THR;
|
||||
(void) u->UART_RBR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Attempts a TX FIFO preload.
|
||||
*/
|
||||
static void preload(SerialDriver *sdp) {
|
||||
UART *u = sdp->uart;
|
||||
|
||||
if (u->UART_LSR & LSR_THRE) {
|
||||
int i = LPC214x_UART_FIFO_PRELOAD;
|
||||
do {
|
||||
msg_t b = chOQGetI(&sdp->oqueue);
|
||||
if (b < Q_OK) {
|
||||
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||
return;
|
||||
}
|
||||
u->UART_THR = b;
|
||||
} while (--i);
|
||||
}
|
||||
u->UART_IER |= IER_THRE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Driver SD1 output notification.
|
||||
*/
|
||||
#if USE_LPC214x_UART0 || defined(__DOXYGEN__)
|
||||
static void notify1(io_queue_t *qp) {
|
||||
|
||||
(void)qp;
|
||||
preload(&SD1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Driver SD2 output notification.
|
||||
*/
|
||||
#if USE_LPC214x_UART1 || defined(__DOXYGEN__)
|
||||
static void notify2(io_queue_t *qp) {
|
||||
|
||||
(void)qp;
|
||||
preload(&SD2);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART0 IRQ handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
#if USE_LPC214x_UART0 || defined(__DOXYGEN__)
|
||||
CH_IRQ_HANDLER(UART0IrqHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(&SD1);
|
||||
VICVectAddr = 0;
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief UART1 IRQ handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
#if USE_LPC214x_UART1 || defined(__DOXYGEN__)
|
||||
CH_IRQ_HANDLER(UART1IrqHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(&SD2);
|
||||
VICVectAddr = 0;
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_init(void) {
|
||||
|
||||
#if USE_LPC214x_UART0
|
||||
sdObjectInit(&SD1, NULL, notify1);
|
||||
SD1.uart = U0Base;
|
||||
SetVICVector(UART0IrqHandler, LPC214x_UART0_PRIORITY, SOURCE_UART0);
|
||||
#endif
|
||||
#if USE_LPC214x_UART1
|
||||
sdObjectInit(&SD2, NULL, notify2);
|
||||
SD2.uart = U1Base;
|
||||
SetVICVector(UART1IrqHandler, LPC214x_UART1_PRIORITY, SOURCE_UART1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver configuration and (re)start.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
* @param[in] config the architecture-dependent serial driver configuration.
|
||||
* If this parameter is set to @p NULL then a default
|
||||
* configuration is used.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
|
||||
|
||||
if (config == NULL)
|
||||
config = &default_config;
|
||||
|
||||
if (sdp->state == SD_STOP) {
|
||||
#if USE_LPC214x_UART0
|
||||
if (&SD1 == sdp) {
|
||||
PCONP = (PCONP & PCALL) | PCUART0;
|
||||
VICIntEnable = INTMASK(SOURCE_UART0);
|
||||
}
|
||||
#endif
|
||||
#if USE_LPC214x_UART1
|
||||
if (&SD2 == sdp) {
|
||||
PCONP = (PCONP & PCALL) | PCUART1;
|
||||
VICIntEnable = INTMASK(SOURCE_UART1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
uart_init(sdp, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver stop.
|
||||
* @details De-initializes the UART, stops the associated clock, resets the
|
||||
* interrupt vector.
|
||||
*
|
||||
* @param[in] sdp pointer to a @p SerialDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void sd_lld_stop(SerialDriver *sdp) {
|
||||
|
||||
if (sdp->state == SD_READY) {
|
||||
uart_deinit(sdp->uart);
|
||||
#if USE_LPC214x_UART0
|
||||
if (&SD1 == sdp) {
|
||||
PCONP = (PCONP & PCALL) & ~PCUART0;
|
||||
VICIntEnClear = INTMASK(SOURCE_UART0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if USE_LPC214x_UART1
|
||||
if (&SD2 == sdp) {
|
||||
PCONP = (PCONP & PCALL) & ~PCUART1;
|
||||
VICIntEnClear = INTMASK(SOURCE_UART1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/serial_lld.h
|
||||
* @brief LPC214x low level serial driver header.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_LLD_H_
|
||||
#define _SERIAL_LLD_H_
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART0 driver enable switch.
|
||||
* @details If set to @p TRUE the support for UART0 is included.
|
||||
* @note The default is @p TRUE .
|
||||
*/
|
||||
#if !defined(USE_LPC214x_UART0) || defined(__DOXYGEN__)
|
||||
#define USE_LPC214x_UART0 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief UART1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for UART1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(USE_LPC214x_UART1) || defined(__DOXYGEN__)
|
||||
#define USE_LPC214x_UART1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief FIFO preload parameter.
|
||||
* @details Configuration parameter, this values defines how many bytes are
|
||||
* preloaded in the HW transmit FIFO for each interrupt, the maximum
|
||||
* value is 16 the minimum is 1.
|
||||
* @note An high value reduces the number of interrupts generated but can
|
||||
* also increase the worst case interrupt response time because the
|
||||
* preload loops.
|
||||
*/
|
||||
#if !defined(LPC214x_UART_FIFO_PRELOAD) || defined(__DOXYGEN__)
|
||||
#define LPC214x_UART_FIFO_PRELOAD 16
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief UART0 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC214x_UART0_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC214x_UART0_PRIORITY 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief UART1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC214x_UART1_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC214x_UART1_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (LPC214x_UART_FIFO_PRELOAD < 1) || (LPC214x_UART_FIFO_PRELOAD > 16)
|
||||
#error "invalid LPC214x_UART_FIFO_PRELOAD setting"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief LPC214x Serial Driver configuration structure.
|
||||
* @details An instance of this structure must be passed to @p sdStart()
|
||||
* in order to configure and start a serial driver operations.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Bit rate.
|
||||
*/
|
||||
uint32_t sc_speed;
|
||||
/**
|
||||
* @brief Initialization value for the LCR register.
|
||||
*/
|
||||
uint32_t sc_lcr;
|
||||
/**
|
||||
* @brief Initialization value for the FCR register.
|
||||
*/
|
||||
uint32_t sc_fcr;
|
||||
} SerialConfig;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
#define _serial_driver_data \
|
||||
_base_asynchronous_channel_data \
|
||||
/* Driver state.*/ \
|
||||
sdstate_t state; \
|
||||
/* Input queue.*/ \
|
||||
input_queue_t iqueue; \
|
||||
/* Output queue.*/ \
|
||||
output_queue_t oqueue; \
|
||||
/* Input circular buffer.*/ \
|
||||
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
|
||||
/* Output circular buffer.*/ \
|
||||
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
/* Pointer to the USART registers block.*/ \
|
||||
UART *uart;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_LPC214x_UART0 && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD1;
|
||||
#endif
|
||||
#if USE_LPC214x_UART1 && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD2;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sd_lld_init(void);
|
||||
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config);
|
||||
void sd_lld_stop(SerialDriver *sdp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
#endif /* _SERIAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/spi_lld.c
|
||||
* @brief LPC214x low level SPI driver code.
|
||||
*
|
||||
* @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if LPC214x_SPI_USE_SSP || defined(__DOXYGEN__)
|
||||
/** @brief SPI1 driver identifier.*/
|
||||
SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Preloads the transmit FIFO.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
static void ssp_fifo_preload(SPIDriver *spip) {
|
||||
SSP *ssp = spip->ssp;
|
||||
uint32_t n = spip->txcnt > LPC214x_SSP_FIFO_DEPTH ?
|
||||
LPC214x_SSP_FIFO_DEPTH : spip->txcnt;
|
||||
|
||||
while(((ssp->SSP_SR & SR_TNF) != 0) && (n > 0)) {
|
||||
if (spip->txptr != NULL) {
|
||||
if ((ssp->SSP_CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
|
||||
ssp->SSP_DR = *(uint16_t *)spip->txptr++;
|
||||
else
|
||||
ssp->SSP_DR = *(uint8_t *)spip->txptr++;
|
||||
}
|
||||
else
|
||||
ssp->SSP_DR = 0xFFFFFFFF;
|
||||
n--;
|
||||
spip->txcnt--;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((noinline))
|
||||
#endif
|
||||
/**
|
||||
* @brief Common IRQ handler.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
static void serve_interrupt(SPIDriver *spip) {
|
||||
SSP *ssp = spip->ssp;
|
||||
|
||||
if ((ssp->SSP_MIS & MIS_ROR) != 0) {
|
||||
/* The overflow condition should never happen because priority is given
|
||||
to receive but a hook macro is provided anyway...*/
|
||||
LPC214x_SPI_SSP_ERROR_HOOK();
|
||||
}
|
||||
ssp->SSP_ICR = ICR_RT | ICR_ROR;
|
||||
while ((ssp->SSP_SR & SR_RNE) != 0) {
|
||||
if (spip->rxptr != NULL) {
|
||||
if ((ssp->SSP_CR0 & CR0_DSSMASK) > CR0_DSS8BIT)
|
||||
*(uint16_t *)spip->rxptr++ = ssp->SSP_DR;
|
||||
else
|
||||
*(uint8_t *)spip->rxptr++ = ssp->SSP_DR;
|
||||
}
|
||||
else
|
||||
(void)ssp->SSP_DR;
|
||||
if (--spip->rxcnt == 0) {
|
||||
osalDbgAssert(spip->txcnt == 0, "counter out of synch");
|
||||
/* Stops the IRQ sources.*/
|
||||
ssp->SSP_IMSC = 0;
|
||||
/* Portable SPI ISR code defined in the high level driver, note, it is
|
||||
a macro.*/
|
||||
_spi_isr_code(spip);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ssp_fifo_preload(spip);
|
||||
if (spip->txcnt == 0)
|
||||
ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_RX;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if LPC214x_SPI_USE_SSP || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief SPI1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPI1IrqHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt(&SPID1);
|
||||
VICVectAddr = 0;
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level SPI driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_init(void) {
|
||||
|
||||
#if LPC214x_SPI_USE_SSP
|
||||
spiObjectInit(&SPID1);
|
||||
SPID1.ssp = SSPBase;
|
||||
SetVICVector(SPI1IrqHandler, LPC214x_SPI_SSP_IRQ_PRIORITY, SOURCE_SPI1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_start(SPIDriver *spip) {
|
||||
|
||||
if (spip->state == SPI_STOP) {
|
||||
/* Clock activation.*/
|
||||
#if LPC214x_SPI_USE_SSP
|
||||
if (&SPID1 == spip) {
|
||||
PCONP = (PCONP & PCALL) | PCSPI1;
|
||||
VICIntEnable = INTMASK(SOURCE_SPI1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/* Configuration.*/
|
||||
spip->ssp->SSP_CR1 = 0;
|
||||
/* Emptying the receive FIFO, it happens to not be empty while debugging.*/
|
||||
while (spip->ssp->SSP_SR & SR_RNE)
|
||||
(void) spip->ssp->SSP_DR;
|
||||
spip->ssp->SSP_ICR = ICR_RT | ICR_ROR;
|
||||
spip->ssp->SSP_CR0 = spip->config->cr0;
|
||||
spip->ssp->SSP_CPSR = spip->config->cpsr;
|
||||
spip->ssp->SSP_CR1 = CR1_SSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_stop(SPIDriver *spip) {
|
||||
|
||||
if (spip->state != SPI_STOP) {
|
||||
spip->ssp->SSP_CR1 = 0;
|
||||
spip->ssp->SSP_CR0 = 0;
|
||||
spip->ssp->SSP_CPSR = 0;
|
||||
#if LPC214x_SPI_USE_SSP
|
||||
if (&SPID1 == spip) {
|
||||
PCONP = (PCONP & PCALL) & ~PCSPI1;
|
||||
VICIntEnClear = INTMASK(SOURCE_SPI1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Asserts the slave select signal and prepares for transfers.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_select(SPIDriver *spip) {
|
||||
|
||||
palClearPad(spip->config->ssport, spip->config->sspad);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deasserts the slave select signal.
|
||||
* @details The previously selected peripheral is unselected.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_unselect(SPIDriver *spip) {
|
||||
|
||||
palSetPad(spip->config->ssport, spip->config->sspad);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ignores data on the SPI bus.
|
||||
* @details This function transmits a series of idle words on the SPI bus and
|
||||
* ignores the received data. This function can be invoked even
|
||||
* when a slave select signal has not been yet asserted.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||
|
||||
spip->rxptr = NULL;
|
||||
spip->txptr = NULL;
|
||||
spip->rxcnt = spip->txcnt = n;
|
||||
ssp_fifo_preload(spip);
|
||||
spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges data on the SPI bus.
|
||||
* @details This asynchronous function starts a simultaneous transmit/receive
|
||||
* operation.
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be exchanged
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
|
||||
spip->rxptr = rxbuf;
|
||||
spip->txptr = txbuf;
|
||||
spip->rxcnt = spip->txcnt = n;
|
||||
ssp_fifo_preload(spip);
|
||||
spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the SPI bus.
|
||||
* @details This asynchronous function starts a transmit operation.
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
|
||||
spip->rxptr = NULL;
|
||||
spip->txptr = txbuf;
|
||||
spip->rxcnt = spip->txcnt = n;
|
||||
ssp_fifo_preload(spip);
|
||||
spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives data from the SPI bus.
|
||||
* @details This asynchronous function starts a receive operation.
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below or
|
||||
* equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
|
||||
spip->rxptr = rxbuf;
|
||||
spip->txptr = NULL;
|
||||
spip->rxcnt = spip->txcnt = n;
|
||||
ssp_fifo_preload(spip);
|
||||
spip->ssp->SSP_IMSC = IMSC_ROR | IMSC_RT | IMSC_TX | IMSC_RX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges one frame using a polled wait.
|
||||
* @details This synchronous function exchanges one frame using a polled
|
||||
* synchronization method. This function is useful when exchanging
|
||||
* small amount of data on high speed channels, usually in this
|
||||
* situation is much more efficient just wait for completion using
|
||||
* polling than suspending the thread waiting for an interrupt.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] frame the data frame to send over the SPI bus
|
||||
* @return The received data frame from the SPI bus.
|
||||
*/
|
||||
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
|
||||
|
||||
spip->ssp->SSP_DR = (uint32_t)frame;
|
||||
while ((spip->ssp->SSP_SR & SR_RNE) == 0)
|
||||
;
|
||||
return (uint16_t)spip->ssp->SSP_DR;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SPI */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/spi_lld.h
|
||||
* @brief LPC214x low level SPI driver header.
|
||||
*
|
||||
* @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SPI_LLD_H_
|
||||
#define _SPI_LLD_H_
|
||||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Hardware FIFO depth.
|
||||
*/
|
||||
#define LPC214x_SSP_FIFO_DEPTH 8
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief SPI1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for SSP is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(LPC214x_SPI_USE_SSP) || defined(__DOXYGEN__)
|
||||
#define LPC214x_SPI_USE_SSP TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SSP interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC214x_SPI_SSP_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC214x_SPI_SSP_IRQ_PRIORITY 4
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Overflow error hook.
|
||||
* @details The default action is to stop the system.
|
||||
*/
|
||||
#if !defined(LPC214x_SPI_SSP_ERROR_HOOK) || defined(__DOXYGEN__)
|
||||
#define LPC214x_SPI_SSP_ERROR_HOOK() chSysHalt()
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !LPC214x_SPI_USE_SSP
|
||||
#error "SPI driver activated but no SPI peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an SPI driver.
|
||||
*/
|
||||
typedef struct SPIDriver SPIDriver;
|
||||
|
||||
/**
|
||||
* @brief SPI notification callback type.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object triggering the
|
||||
* callback
|
||||
*/
|
||||
typedef void (*spicallback_t)(SPIDriver *spip);
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Operation complete callback or @p NULL.
|
||||
*/
|
||||
spicallback_t end_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief The chip select line port.
|
||||
*/
|
||||
ioportid_t ssport;
|
||||
/**
|
||||
* @brief The chip select line pad number.
|
||||
*/
|
||||
uint16_t sspad;
|
||||
/**
|
||||
* @brief SSP CR0 initialization data.
|
||||
*/
|
||||
uint16_t cr0;
|
||||
/**
|
||||
* @brief SSP CPSR initialization data.
|
||||
*/
|
||||
uint32_t cpsr;
|
||||
} SPIConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a SPI driver.
|
||||
*/
|
||||
struct SPIDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
spistate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const SPIConfig *config;
|
||||
#if SPI_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
Thread *thread;
|
||||
#endif /* SPI_USE_WAIT */
|
||||
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the bus.
|
||||
*/
|
||||
Mutex mutex;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
Semaphore semaphore;
|
||||
#endif
|
||||
#endif /* SPI_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(SPI_DRIVER_EXT_FIELDS)
|
||||
SPI_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the SSP registers block.
|
||||
*/
|
||||
SSP *ssp;
|
||||
/**
|
||||
* @brief Number of bytes yet to be received.
|
||||
*/
|
||||
uint32_t rxcnt;
|
||||
/**
|
||||
* @brief Receive pointer or @p NULL.
|
||||
*/
|
||||
void *rxptr;
|
||||
/**
|
||||
* @brief Number of bytes yet to be transmitted.
|
||||
*/
|
||||
uint32_t txcnt;
|
||||
/**
|
||||
* @brief Transmit pointer or @p NULL.
|
||||
*/
|
||||
const void *txptr;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if LPC214x_SPI_USE_SSP && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void spi_lld_init(void);
|
||||
void spi_lld_start(SPIDriver *spip);
|
||||
void spi_lld_stop(SPIDriver *spip);
|
||||
void spi_lld_select(SPIDriver *spip);
|
||||
void spi_lld_unselect(SPIDriver *spip);
|
||||
void spi_lld_ignore(SPIDriver *spip, size_t n);
|
||||
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SPI */
|
||||
|
||||
#endif /* _SPI_LLD_H_ */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/vic.c
|
||||
* @brief LPC214x VIC peripheral support code.
|
||||
*
|
||||
* @addtogroup LPC214x_VIC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/**
|
||||
* @brief VIC Initialization.
|
||||
* @note Better reset everything in the VIC, it is a HUGE source of trouble.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void vic_init(void) {
|
||||
int i;
|
||||
|
||||
VIC *vic = VICBase;
|
||||
vic->VIC_IntSelect = 0; /* All sources assigned to IRQ. */
|
||||
vic->VIC_SoftIntClear = ALLINTMASK; /* No interrupts enforced */
|
||||
vic->VIC_IntEnClear = ALLINTMASK; /* All sources disabled. */
|
||||
for (i = 0; i < 16; i++) {
|
||||
vic->VIC_VectCntls[i] = 0;
|
||||
vic->VIC_VectAddrs[i] = 0;
|
||||
vic->VIC_VectAddr = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes a VIC vector.
|
||||
* @details Set a vector for an interrupt source and enables it.
|
||||
*
|
||||
* @param[in] handler the pointer to the IRQ service routine
|
||||
* @param[in] vector the vector number
|
||||
* @param[in] source the IRQ source to be associated to the vector
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
void SetVICVector(void *handler, int vector, int source) {
|
||||
|
||||
VIC *vicp = VICBase;
|
||||
vicp->VIC_VectAddrs[vector] = (IOREG32)handler;
|
||||
vicp->VIC_VectCntls[vector] = (IOREG32)(source | 0x20);
|
||||
}
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006-2014 Giovanni Di Sirio
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC214x/vic.h
|
||||
* @brief LPC214x VIC peripheral support header.
|
||||
*
|
||||
* @addtogroup LPC214x_VIC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _VIC_H_
|
||||
#define _VIC_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void vic_init(void);
|
||||
void SetVICVector(void *handler, int vector, int source);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _VIC_H_ */
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue