import ChibiOS 2.0.8

This commit is contained in:
NIIBE Yutaka
2010-11-30 13:54:43 +09:00
parent 27543cfeca
commit c560d0ad0c
1982 changed files with 5318 additions and 4046 deletions

View File

@@ -0,0 +1,404 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup IO HAL
* @brief Hardware Abstraction Layer.
* @details Under ChibiOS/RT the set of the various device driver interfaces
* is called the HAL subsystem: Hardware Abstraction Layer.<br>
* A device driver is usually split in two layers:
* - High Level Device Driver (<b>HLD</b>). This layer contains the definitions
* of the driver's APIs and the platform independent part of the driver.<br>
* An HLD is composed by two files:
* - @<driver@>.c, the HLD implementation file. This file must be
* included in the Makefile in order to use the driver.
* - @<driver@>.h, the HLD header file. This file is implicitly
* included by the HAL header file @p hal.h.
* .
* - Low Level Device Driver (<b>LLD</b>). This layer contains the platform
* dependent part of the driver.<br>
* A LLD is composed by two files:
* - @<driver@>_lld.c, the LLD implementation file. This file must be
* included in the Makefile in order to use the driver.
* - @<driver@>_lld.h, the LLD header file. This file is implicitly
* included by the HLD header file.
* .
* The LLD may be not present in those drivers that do not access the
* hardware directly but through other device drivers, as example the
* @ref MMC_SPI driver uses the @ref SPI and @ref PAL drivers in order
* to implement its functionalities.
* .
* <h2>Available Device Drivers</h2>
* The I/O subsystem currently includes support for:
* - @ref HAL.
* - @ref PAL.
* - @ref SERIAL.
* - @ref ADC.
* - @ref CAN.
* - @ref MAC.
* - @ref MMC_SPI.
* - @ref SPI.
* .
*/
/**
* @defgroup HAL HAL Driver
* @brief Hardware Abstraction Layer.
* @details The HAL driver performs the system initialization and includes
* the platform support code shared by the other drivers.
*
* @ingroup IO
*/
/**
* @defgroup HAL_LLD HAL Low Level Driver
* @brief @ref HAL low level driver template.
*
* @ingroup HAL
*/
/**
* @defgroup HAL_CONF Configuration
* @brief @ref HAL Configuration.
*
* @ingroup HAL
*/
/**
* @defgroup PAL PAL Driver
* @brief I/O Ports Abstraction Layer
* @details This module defines an abstract interface for digital I/O ports.
* Note that most I/O ports functions are just macros. The macros
* have default software implementations that can be redefined in a
* @ref PAL_LLD if the target hardware supports special features like, as
* example, atomic bit set/reset/masking. Please refer to the ports specific
* documentation for details.<br>
* The @ref PAL has the advantage to make the access to the I/O ports platform
* independent and still be optimized for the specific architectures.<br>
* Note that the @ref PAL_LLD may also offer non standard macro and functions
* in order to support specific features but, of course, the use of such
* interfaces would not be portable. Such interfaces shall be marked with
* the architecture name inside the function names.
*
* <h2>Implementation Rules</h2>
* In implementing an @ref PAL_LLD there are some rules/behaviors that
* should be respected.
*
* <h3>Writing on input pads</h3>
* The behavior is not specified but there are implementations better than
* others, this is the list of possible implementations, preferred options
* are on top:
* -# The written value is not actually output but latched, should the pads
* be reprogrammed as outputs the value would be in effect.
* -# The write operation is ignored.
* -# The write operation has side effects, as example disabling/enabling
* pull up/down resistors or changing the pad direction. This scenario is
* discouraged, please try to avoid this scenario.
* .
* <h3>Reading from output pads</h3>
* The behavior is not specified but there are implementations better than
* others, this is the list of possible implementations, preferred options
* are on top:
* -# The actual pads states are read (not the output latch).
* -# The output latch value is read (regardless of the actual pads states).
* -# Unspecified, please try to avoid this scenario.
* .
* <h3>Writing unused or unimplemented port bits</h3>
* The behavior is not specified.
*
* <h3>Reading from unused or unimplemented port bits</h3>
* The behavior is not specified.
*
* <h3>Reading or writing on pins associated to other functionalities</h3>
* The behavior is not specified.
*
* <h2>Usage</h2>
* The use of I/O ports requires the inclusion of the header file @p pal.h,
* this file is not automatically included @p ch.h like the other header
* files.
*
* @ingroup IO
*/
/**
* @defgroup PAL_LLD PAL Low Level Driver
* @brief @ref PAL low level driver template.
* @details This file is a template for an I/O port low level driver.
*
* @ingroup PAL
*/
/**
* @defgroup SERIAL Serial Driver
* @brief Generic Serial Driver.
* @details This module implements a generic full duplex serial driver. The
* driver implements a @p SerialDriver interface and uses I/O Queues for
* communication between the upper and the lower driver. Event flags are used
* to notify the application about incoming data, outgoing data and other I/O
* events.<br>
* The module also contains functions that make the implementation of the
* interrupt service routines much easier.
*
* @ingroup IO
*/
/**
* @defgroup SERIAL_LLD Serial Low Level Driver
* @brief @ref SERIAL low level driver template.
* @details This file is a template for a serial low level driver.
*
* @ingroup SERIAL
*/
/**
* @defgroup SPI SPI Driver
* @brief Generic SPI Driver.
* @details This module implements a generic SPI driver. The driver implements
* a state machine internally:
* @dot
digraph example {
rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8];
uninit [label="SPI_UNINIT", style="bold"];
stop [label="SPI_STOP\nLow Power"];
ready [label="SPI_READY\nClock Enabled"];
active [label="SPI_ACTIVE\nBus Active"];
uninit -> stop [label="spiInit()"];
stop -> ready [label="spiStart()"];
ready -> ready [label="spiStart()"];
ready -> ready [label="spiIgnore()"];
ready -> stop [label="spiStop()"];
stop -> stop [label="spiStop()"];
ready -> active [label="spiSelect()"];
active -> active [label="spiSelect()"];
active -> ready [label="spiUnselect()"];
ready -> ready [label="spiUnselect()"];
active -> active [label="spiIgnore()\nspiExchange()\nspiSend()\nspiReceive()"];
}
* @enddot
*
* The driver is not thread safe for performance reasons, if you need to access
* the SPI bus from multiple thread then use the @p spiAcquireBus() and
* @p spiReleaseBus() APIs in order to gain exclusive access.
*
* @ingroup IO
*/
/**
* @defgroup SPI_LLD SPI Low Level Driver
* @brief @ref SPI low level driver template.
* @details This file is a template for a SPI low level driver.
*
* @ingroup SPI
*/
/**
* @defgroup ADC ADC Driver
* @brief Generic ADC Driver.
* @details This module implements a generic ADC driver. The driver implements
* a state machine internally:
* @dot
digraph example {
rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8];
uninit [label="ADC_UNINIT", style="bold"];
stop [label="ADC_STOP\nLow Power"];
ready [label="ADC_READY\nClock Enabled"];
running [label="ADC_RUNNING"];
complete [label="ADC_COMPLETE"];
uninit -> stop [label="adcInit()"];
stop -> ready [label="adcStart()"];
ready -> ready [label="adcStart()"];
ready -> ready [label="adcWaitConversion()"];
ready -> stop [label="adcStop()"];
stop -> stop [label="adcStop()"];
ready -> running [label="adcStartConversion()"];
running -> ready [label="adcStopConversion()"];
running -> complete [label="End of Conversion"];
complete -> running [label="adcStartConversion()"];
complete -> ready [label="adcStopConversion()"];
complete -> ready [label="adcWaitConversion()"];
complete -> stop [label="adcStop()"];
}
* @enddot
*
* The driver supports a continuous conversion mode with circular buffer,
* callback functions allow to process the converted data in real time.
* Please refer to the documentation of the function @p adcStartConversion().
*
* @ingroup IO
*/
/**
* @defgroup ADC_LLD ADC Low Level Driver
* @brief @ref ADC low level driver template.
* @details This file is a template for a ADC low level driver.
*
* @ingroup ADC
*/
/**
* @defgroup CAN CAN Driver
* @brief Generic CAN Driver.
* @details This module implements a generic ADC driver. The driver implements
* a state machine internally:
* @dot
digraph example {
rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8];
uninit [label="CAN_UNINIT", style="bold"];
stop [label="CAN_STOP\nLow Power"];
ready [label="CAN_READY\nClock Enabled"];
sleep [label="CAN_SLEEP\nLow Power"];
uninit -> stop [label="canInit()"];
stop -> stop [label="canStop()"];
stop -> ready [label="canStart()"];
ready -> stop [label="canStop()"];
ready -> ready [label="canReceive()\ncanTransmit()"];
ready -> ready [label="canStart()"];
ready -> sleep [label="canSleep()"];
sleep -> sleep [label="canSleep()"];
sleep -> ready [label="canWakeup()"];
sleep -> ready [label="wakeup event"];
}
* @enddot
*
* @ingroup IO
*/
/**
* @defgroup CAN_LLD CAN Low Level Driver
* @brief @ref CAN low level driver template.
*
* @ingroup CAN
*/
/**
* @defgroup PWM PWM Driver
* @brief Generic PWM Driver.
* @details This module implements a generic PWM driver. The driver implements
* a state machine internally:
* @dot
digraph example {
rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8];
uninit [label="PWM_UNINIT", style="bold"];
stop [label="PWM_STOP\nLow Power"];
ready [label="PWM_READY\nClock Enabled"];
uninit -> stop [label="pwmInit()"];
stop -> stop [label="pwmStop()"];
stop -> ready [label="pwmStart()"];
ready -> stop [label="pwmStop()"];
ready -> ready [label="pwmEnableChannel()\npwmDisableChannel()"];
}
* @enddot
*
* @ingroup IO
*/
/**
* @defgroup PWM_LLD PWM Low Level Driver
* @brief @ref PWM low level driver template.
*
* @ingroup PWM
*/
/**
* @defgroup MAC MAC Driver
* @brief Generic MAC driver.
* @details This module implements a generic interface for MAC (Media
* Access Control) drivers, as example Ethernet controllers.
*
* @ingroup IO
*/
/**
* @defgroup MAC_LLD MAC Low Level Driver
* @brief @ref MAC low level driver template.
* @details This file is a template for a MAC low level driver.
*
* @ingroup MAC
*/
/**
* @defgroup MMC_SPI MMC over SPI Driver
* @brief Generic MMC driver.
* @details This module implements a portable MMC driver that uses a SPI
* driver as physical layer.<br>
* The driver implements the following state machine:
* @dot
digraph example {
rankdir="LR";
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.8", height="0.8"];
edge [fontname=Helvetica, fontsize=8];
any [label="Any State"];
stop2 [label="MMC_STOP\nLow Power"];
uninit [label="MMC_UNINIT", style="bold"];
stop [label="MMC_STOP\nLow Power"];
wait [label="MMC_WAIT\nWaiting Card"];
inserted [label="MMC_INSERTED\nCard Inserted"];
ready [label="MMC_READY\nCard Ready"];
reading [label="MMC_READING\nReading"];
writing [label="MMC_WRITING\nWriting"];
uninit -> stop [label="mmcInit()"];
stop -> wait [label="mmcStart()", constraint=false];
wait -> inserted [label="insertion (inserted event)"];
inserted -> inserted [label="mmcDisconnect()"];
inserted -> ready [label="mmcConnect()"];
ready -> ready [label="mmcConnect()"];
ready -> inserted [label="mmcDisconnect()"];
ready -> reading [label="mmcStartSequentialRead()"];
reading -> reading [label="mmcSequentialRead()"];
reading -> ready [label="mmcStopSequentialRead()"];
reading -> ready [label="read error"];
ready -> writing [label="mmcStartSequentialWrite()"];
writing -> writing [label="mmcSequentialWrite()"];
writing -> ready [label="mmcStopSequentialWrite()"];
writing -> ready [label="write error"];
inserted -> wait [label="removal (removed event)"];
ready -> wait [label="removal (removed event)"];
reading -> wait [label="removal (removed event)"];
writing -> wait [label="removal (removed event)"];
any -> stop2 [label="mmcStop()"];
}
* @enddot
*
* The MMC drivers currently supports only cards with capacity up to 2GB
* and does not implement CRC checking. Hot plugging and removal are supported
* through kernel events.
*
* @ingroup IO
*/

View File

@@ -0,0 +1,14 @@
# List of all the ChibiOS/RT HAL files, there is no need to remove the files
# from this list, you can disable parts of the kernel by editing halconf.h.
HALSRC = ${CHIBIOS}/os/hal/src/hal.c \
${CHIBIOS}/os/hal/src/adc.c \
${CHIBIOS}/os/hal/src/can.c \
${CHIBIOS}/os/hal/src/mac.c \
${CHIBIOS}/os/hal/src/pal.c \
${CHIBIOS}/os/hal/src/pwm.c \
${CHIBIOS}/os/hal/src/serial.c \
${CHIBIOS}/os/hal/src/spi.c \
${CHIBIOS}/os/hal/src/mmc_spi.c
# Required include directories
HALINC = ${CHIBIOS}/os/hal/include

View File

@@ -0,0 +1,103 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file adc.h
* @brief ADC Driver macros and structures.
*
* @addtogroup ADC
* @{
*/
#ifndef _ADC_H_
#define _ADC_H_
#if CH_HAL_USE_ADC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !CH_USE_SEMAPHORES
#error "ADC driver requires CH_USE_SEMAPHORES"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver state machine possible states.
*/
typedef enum {
ADC_UNINIT = 0, /**< @brief Not initialized. */
ADC_STOP = 1, /**< @brief Stopped. */
ADC_READY = 2, /**< @brief Ready. */
ADC_RUNNING = 3, /**< @brief Conversion running. */
ADC_COMPLETE = 4 /**< @brief Conversion complete.*/
} adcstate_t;
#include "adc_lld.h"
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void adcInit(void);
void adcObjectInit(ADCDriver *adcp);
void adcStart(ADCDriver *adcp, const ADCConfig *config);
void adcStop(ADCDriver *adcp);
bool_t adcStartConversion(ADCDriver *adcp,
const ADCConversionGroup *grpp,
adcsample_t *samples,
size_t depth,
adccallback_t callback);
void adcStopConversion(ADCDriver *adcp);
msg_t adcWaitConversion(ADCDriver *adcp, systime_t timeout);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_ADC */
#endif /* _ADC_H_ */
/** @} */

View File

@@ -0,0 +1,139 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file can.h
* @brief CAN Driver macros and structures.
*
* @addtogroup CAN
* @{
*/
#ifndef _CAN_H_
#define _CAN_H_
#if CH_HAL_USE_CAN || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Errors rate warning.
*/
#define CAN_LIMIT_WARNING 1
/**
* @brief Errors rate error.
*/
#define CAN_LIMIT_ERROR 2
/**
* @brief Bus off condition reached.
*/
#define CAN_BUS_OFF_ERROR 4
/**
* @brief Framing error of some kind on the CAN bus.
*/
#define CAN_FRAMING_ERROR 8
/**
* @brief Overflow in receive queue.
*/
#define CAN_OVERFLOW_ERROR 16
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Sleep mode related APIs inclusion switch.
*/
#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__)
#define CAN_USE_SLEEP_MODE TRUE
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !CH_USE_SEMAPHORES || !CH_USE_EVENTS
#error "CAN driver requires CH_USE_SEMAPHORES and CH_USE_EVENTS"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver state machine possible states.
*/
typedef enum {
CAN_UNINIT = 0, /**< @brief Not initialized. */
CAN_STOP = 1, /**< @brief Stopped. */
CAN_STARTING = 2, /**< @brief Starting. */
CAN_READY = 3, /**< @brief Ready. */
CAN_SLEEP = 4 /**< @brief Sleep state. */
} canstate_t;
#include "can_lld.h"
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Adds some flags to the CAN status mask.
*
* @param[in] canp pointer to the @p CANDriver object
* @param[in] mask flags to be added to the status mask
*/
#define canAddFlagsI(canp, mask) ((canp)->cd_status |= (mask))
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void canInit(void);
void canObjectInit(CANDriver *canp);
void canStart(CANDriver *canp, const CANConfig *config);
void canStop(CANDriver *canp);
msg_t canTransmit(CANDriver *canp, const CANTxFrame *ctfp, systime_t timeout);
msg_t canReceive(CANDriver *canp, CANRxFrame *crfp, systime_t timeout);
canstatus_t canGetAndClearFlags(CANDriver *canp);
#if CAN_USE_SLEEP_MODE
void canSleep(CANDriver *canp);
void canWakeup(CANDriver *canp);
#endif /* CAN_USE_SLEEP_MODE */
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_CAN */
#endif /* _CAN_H_ */
/** @} */

View File

@@ -0,0 +1,66 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file hal.h
* @brief HAL subsystem header.
*
* @addtogroup HAL
* @{
*/
#ifndef _HAL_H_
#define _HAL_H_
#include "board.h"
#include "halconf.h"
#include "hal_lld.h"
#include "pal.h"
#include "adc.h"
#include "can.h"
#include "mac.h"
#include "pwm.h"
#include "serial.h"
#include "spi.h"
#include "mmc_spi.h"
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void halInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_H_ */
/** @} */

View File

@@ -0,0 +1,129 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file mac.h
* @brief MAC Driver macros and structures.
* @addtogroup MAC
* @{
*/
#ifndef _MAC_H_
#define _MAC_H_
#if CH_HAL_USE_MAC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !CH_USE_SEMAPHORES || !CH_USE_EVENTS
#error "the MAC driver requires CH_USE_SEMAPHORES and CH_USE_EVENTS"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
#include "mac_lld.h"
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Returns the received frames event source.
*
* @param[in] macp pointer to the @p MACDriver object
* @return The pointer to the @p EventSource structure.
*/
#if CH_USE_EVENTS || defined(__DOXYGEN__)
#define macGetReceiveEventSource(macp) (&(macp)->md_rdevent)
#endif
/**
* @brief Writes to a transmit descriptor's stream.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
* @param[in] buf pointer to the buffer containing the data to be written
* @param[in] size number of bytes to be written
* @return The number of bytes written into the descriptor's
* stream, this value can be less than the amount
* specified in the parameter @p size if the maximum frame
* size is reached.
*/
#define macWriteTransmitDescriptor(tdp, buf, size) \
mac_lld_write_transmit_descriptor(tdp, buf, size)
/**
* @brief Reads from a receive descriptor's stream.
*
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
* @param[in] buf pointer to the buffer that will receive the read data
* @param[in] size number of bytes to be read
* @return The number of bytes read from the descriptor's stream, this
* value can be less than the amount specified in the
* parameter @p size if there are no more bytes to read.
*/
#define macReadReceiveDescriptor(rdp, buf, size) \
mac_lld_read_receive_descriptor(rdp, buf, size)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void macInit(void);
void macObjectInit(MACDriver *macp);
void macSetAddress(MACDriver *macp, const uint8_t *p);
msg_t macWaitTransmitDescriptor(MACDriver *macp,
MACTransmitDescriptor *tdp,
systime_t time);
void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp);
msg_t macWaitReceiveDescriptor(MACDriver *macp,
MACReceiveDescriptor *rdp,
systime_t time);
void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp);
bool_t macPollLinkStatus(MACDriver *macp);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_MAC */
#endif /* _MAC_H_ */
/** @} */

View File

@@ -0,0 +1,195 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/*
* Parts of this file are borrowed by the Linux include file linux/mii.h:
* Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
*/
/*-*
* @file mii.h
* @brief MII Driver macros and structures.
*
* @addtogroup MII
* @{
*/
#ifndef _MII_H_
#define _MII_H_
/*
* Generic MII registers. Note, not all registers are present on all PHY
* devices and some extra registers may be present.
*/
#define MII_BMCR 0x00 /**< Basic mode control register. */
#define MII_BMSR 0x01 /**< Basic mode status register. */
#define MII_PHYSID1 0x02 /**< PHYS ID 1. */
#define MII_PHYSID2 0x03 /**< PHYS ID 2. */
#define MII_ADVERTISE 0x04 /**< Advertisement control reg. */
#define MII_LPA 0x05 /**< Link partner ability reg. */
#define MII_EXPANSION 0x06 /**< Expansion register. */
#define MII_CTRL1000 0x09 /**< 1000BASE-T control. */
#define MII_STAT1000 0x0a /**< 1000BASE-T status. */
#define MII_ESTATUS 0x0f /**< Extended Status. */
#define MII_DCOUNTER 0x12 /**< Disconnect counter. */
#define MII_FCSCOUNTER 0x13 /**< False carrier counter. */
#define MII_NWAYTEST 0x14 /**< N-way auto-neg test reg. */
#define MII_RERRCOUNTER 0x15 /**< Receive error counter. */
#define MII_SREVISION 0x16 /**< Silicon revision. */
#define MII_RESV1 0x17 /**< Reserved. */
#define MII_LBRERROR 0x18 /**< Lpback, rx, bypass error. */
#define MII_PHYADDR 0x19 /**< PHY address. */
#define MII_RESV2 0x1a /**< Reserved. */
#define MII_TPISTATUS 0x1b /**< TPI status for 10mbps. */
#define MII_NCONFIG 0x1c /**< Network interface config. */
/*
* Basic mode control register.
*/
#define BMCR_RESV 0x003f /**< Unused. */
#define BMCR_SPEED1000 0x0040 /**< MSB of Speed (1000). */
#define BMCR_CTST 0x0080 /**< Collision test. */
#define BMCR_FULLDPLX 0x0100 /**< Full duplex. */
#define BMCR_ANRESTART 0x0200 /**< Auto negotiation restart. */
#define BMCR_ISOLATE 0x0400 /**< Disconnect DP83840 from MII. */
#define BMCR_PDOWN 0x0800 /**< Powerdown. */
#define BMCR_ANENABLE 0x1000 /**< Enable auto negotiation. */
#define BMCR_SPEED100 0x2000 /**< Select 100Mbps. */
#define BMCR_LOOPBACK 0x4000 /**< TXD loopback bits. */
#define BMCR_RESET 0x8000 /**< Reset. */
/*
* Basic mode status register.
*/
#define BMSR_ERCAP 0x0001 /**< Ext-reg capability. */
#define BMSR_JCD 0x0002 /**< Jabber detected. */
#define BMSR_LSTATUS 0x0004 /**< Link status. */
#define BMSR_ANEGCAPABLE 0x0008 /**< Able to do auto-negotiation. */
#define BMSR_RFAULT 0x0010 /**< Remote fault detected. */
#define BMSR_ANEGCOMPLETE 0x0020 /**< Auto-negotiation complete. */
#define BMSR_RESV 0x00c0 /**< Unused. */
#define BMSR_ESTATEN 0x0100 /**< Extended Status in R15. */
#define BMSR_100HALF2 0x0200 /**< Can do 100BASE-T2 HDX. */
#define BMSR_100FULL2 0x0400 /**< Can do 100BASE-T2 FDX. */
#define BMSR_10HALF 0x0800 /**< Can do 10mbps, half-duplex. */
#define BMSR_10FULL 0x1000 /**< Can do 10mbps, full-duplex. */
#define BMSR_100HALF 0x2000 /**< Can do 100mbps, half-duplex. */
#define BMSR_100FULL 0x4000 /**< Can do 100mbps, full-duplex. */
#define BMSR_100BASE4 0x8000 /**< Can do 100mbps, 4k packets. */
/*
* Advertisement control register.
*/
#define ADVERTISE_SLCT 0x001f /**< Selector bits. */
#define ADVERTISE_CSMA 0x0001 /**< Only selector supported. */
#define ADVERTISE_10HALF 0x0020 /**< Try for 10mbps half-duplex. */
#define ADVERTISE_1000XFULL 0x0020 /**< Try for 1000BASE-X full-duplex.*/
#define ADVERTISE_10FULL 0x0040 /**< Try for 10mbps full-duplex. */
#define ADVERTISE_1000XHALF 0x0040 /**< Try for 1000BASE-X half-duplex.*/
#define ADVERTISE_100HALF 0x0080 /**< Try for 100mbps half-duplex. */
#define ADVERTISE_1000XPAUSE 0x0080 /**< Try for 1000BASE-X pause. */
#define ADVERTISE_100FULL 0x0100 /**< Try for 100mbps full-duplex. */
#define ADVERTISE_1000XPSE_ASYM 0x0100 /**< Try for 1000BASE-X asym pause. */
#define ADVERTISE_100BASE4 0x0200 /**< Try for 100mbps 4k packets. */
#define ADVERTISE_PAUSE_CAP 0x0400 /**< Try for pause. */
#define ADVERTISE_PAUSE_ASYM 0x0800 /**< Try for asymetric pause. */
#define ADVERTISE_RESV 0x1000 /**< Unused. */
#define ADVERTISE_RFAULT 0x2000 /**< Say we can detect faults. */
#define ADVERTISE_LPACK 0x4000 /**< Ack link partners response. */
#define ADVERTISE_NPAGE 0x8000 /**< Next page bit. */
#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
ADVERTISE_CSMA)
#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
ADVERTISE_100HALF | ADVERTISE_100FULL)
/*
* Link partner ability register.
*/
#define LPA_SLCT 0x001f /**< Same as advertise selector. */
#define LPA_10HALF 0x0020 /**< Can do 10mbps half-duplex. */
#define LPA_1000XFULL 0x0020 /**< Can do 1000BASE-X full-duplex. */
#define LPA_10FULL 0x0040 /**< Can do 10mbps full-duplex. */
#define LPA_1000XHALF 0x0040 /**< Can do 1000BASE-X half-duplex. */
#define LPA_100HALF 0x0080 /**< Can do 100mbps half-duplex. */
#define LPA_1000XPAUSE 0x0080 /**< Can do 1000BASE-X pause. */
#define LPA_100FULL 0x0100 /**< Can do 100mbps full-duplex. */
#define LPA_1000XPAUSE_ASYM 0x0100 /**< Can do 1000BASE-X pause asym. */
#define LPA_100BASE4 0x0200 /**< Can do 100mbps 4k packets. */
#define LPA_PAUSE_CAP 0x0400 /**< Can pause. */
#define LPA_PAUSE_ASYM 0x0800 /**< Can pause asymetrically. */
#define LPA_RESV 0x1000 /**< Unused. */
#define LPA_RFAULT 0x2000 /**< Link partner faulted. */
#define LPA_LPACK 0x4000 /**< Link partner acked us. */
#define LPA_NPAGE 0x8000 /**< Next page bit. */
#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL)
#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
/*
* Expansion register for auto-negotiation.
*/
#define EXPANSION_NWAY 0x0001 /**< Can do N-way auto-nego. */
#define EXPANSION_LCWP 0x0002 /**< Got new RX page code word. */
#define EXPANSION_ENABLENPAGE 0x0004 /**< This enables npage words. */
#define EXPANSION_NPCAPABLE 0x0008 /**< Link partner supports npage. */
#define EXPANSION_MFAULTS 0x0010 /**< Multiple faults detected. */
#define EXPANSION_RESV 0xffe0 /**< Unused. */
#define ESTATUS_1000_TFULL 0x2000 /**< Can do 1000BT Full. */
#define ESTATUS_1000_THALF 0x1000 /**< Can do 1000BT Half. */
/*
* N-way test register.
*/
#define NWAYTEST_RESV1 0x00ff /**< Unused. */
#define NWAYTEST_LOOPBACK 0x0100 /**< Enable loopback for N-way. */
#define NWAYTEST_RESV2 0xfe00 /**< Unused. */
/*
* 1000BASE-T Control register.
*/
#define ADVERTISE_1000FULL 0x0200 /**< Advertise 1000BASE-T full duplex.*/
#define ADVERTISE_1000HALF 0x0100 /**< Advertise 1000BASE-T half duplex.*/
/*
* 1000BASE-T Status register.
*/
#define LPA_1000LOCALRXOK 0x2000 /**< Link partner local receiver status.*/
#define LPA_1000REMRXOK 0x1000 /**< Link partner remote receiver status.*/
#define LPA_1000FULL 0x0800 /**< Link partner 1000BASE-T full duplex.*/
#define LPA_1000HALF 0x0400 /**< Link partner 1000BASE-T half duplex.*/
/*
* PHY identifiers.
*/
#define MII_DM9161_ID 0x0181b8a0
#define MII_AM79C875_ID 0x00225540
#define MII_KS8721_ID 0x00221610
#endif /* _MII_H_ */
/*-* @} */

View File

@@ -0,0 +1,228 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file mmc_spi.h
* @brief MMC over SPI driver header.
*
* @addtogroup MMC_SPI
* @{
*/
#ifndef _MMC_SPI_H_
#define _MMC_SPI_H_
#if CH_HAL_USE_MMC_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define MMC_CMD0_RETRY 10
#define MMC_CMD1_RETRY 100
#define MMC_WAIT_DATA 10000
#define MMC_CMDGOIDLE 0
#define MMC_CMDINIT 1
#define MMC_CMDREADCSD 9
#define MMC_CMDSTOP 12
#define MMC_CMDSETBLOCKLEN 16
#define MMC_CMDREAD 17
#define MMC_CMDREADMULTIPLE 18
#define MMC_CMDWRITE 24
#define MMC_CMDWRITEMULTIPLE 25
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Block size for MMC transfers.
*/
#if !defined(MMC_SECTOR_SIZE) || defined(__DOXYGEN__)
#define MMC_SECTOR_SIZE 512
#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.
* 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
/**
* @brief Number of positive insertion queries before generating the
* insertion event.
*/
#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
#define MMC_POLLING_INTERVAL 10
#endif
/**
* @brief Interval, in milliseconds, between insertion queries.
*/
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
#define MMC_POLLING_DELAY 10
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !CH_HAL_USE_SPI || !CH_USE_EVENTS
#error "MMC_SPI driver requires CH_HAL_USE_SPI and CH_USE_EVENTS"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver state machine possible states.
*/
typedef enum {
MMC_UNINIT = 0, /**< @brief Not initialized. */
MMC_STOP = 1, /**< @brief Stopped. */
MMC_WAIT = 2, /**< @brief Waiting card. */
MMC_INSERTED = 3, /**< @brief Card inserted. */
MMC_READY = 4, /**< @brief Card ready. */
MMC_READING = 5, /**< @brief Reading. */
MMC_WRITING = 6 /**< @brief Writing. */
} mmcstate_t;
/**
* @brief Function used to query some hardware status bits.
*
* @return The status.
*/
typedef bool_t (*mmcquery_t)(void);
/**
* @brief Driver configuration structure.
*/
typedef struct {
} MMCConfig;
/**
* @brief Structure representing a MMC driver.
*/
typedef struct {
/**
* @brief Driver state.
*/
mmcstate_t mmc_state;
/**
* @brief Current configuration data.
*/
const MMCConfig *mmc_config;
/**
* @brief SPI driver associated to this MMC driver.
*/
SPIDriver *mmc_spip;
/**
* @brief SPI low speed configuration used during initialization.
*/
const SPIConfig *mmc_lscfg;
/**
* @brief SPI high speed configuration used during transfers.
*/
const SPIConfig *mmc_hscfg;
/**
* @brief Write protect status query function.
*/
mmcquery_t mmc_is_protected;
/**
* @brief Insertion status query function.
*/
mmcquery_t mmc_is_inserted;
/**
* @brief Card insertion event source.
*/
EventSource mmc_inserted_event;
/**
* @brief Card removal event source.
*/
EventSource mmc_removed_event;
/**
* @brief MMC insertion polling timer.
*/
VirtualTimer mmc_vt;
/**
* @brief Insertion counter.
*/
uint_fast8_t mmc_cnt;
} MMCDriver;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Returns the driver state.
*/
#define mmcGetDriverState(mmcp) ((mmcp)->mmc_state)
/**
* @brief Returns the write protect status.
*/
#define mmcIsWriteProtected(mmcp) ((mmcp)->mmc_is_protected())
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void mmcInit(void);
void mmcObjectInit(MMCDriver *mmcp, SPIDriver *spip,
const SPIConfig *lscfg, const SPIConfig *hscfg,
mmcquery_t is_protected, mmcquery_t is_inserted);
void mmcStart(MMCDriver *mmcp, const MMCConfig *config);
void mmcStop(MMCDriver *mmcp);
bool_t mmcConnect(MMCDriver *mmcp);
bool_t mmcDisconnect(MMCDriver *mmcp);
bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk);
bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer);
bool_t mmcStopSequentialRead(MMCDriver *mmcp);
bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk);
bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer);
bool_t mmcStopSequentialWrite(MMCDriver *mmcp);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_MMC_SPI */
#endif /* _MMC_SPI_H_ */
/** @} */

View File

@@ -0,0 +1,508 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file pal.h
* @brief I/O Ports Abstraction Layer macros, types and structures.
*
* @addtogroup PAL
* @{
*/
#ifndef _PAL_H_
#define _PAL_H_
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Bits in a mode word dedicated as mode selector.
* @details The other bits are not defined and may be used as device-specific
* option bits.
*/
#define PAL_MODE_MASK 0xF
/**
* @brief After reset state.
* @details The state itself is not specified and is architecture dependent,
* it is guaranteed to be equal to the after-reset state. It is
* usually an input state.
*/
#define PAL_MODE_RESET 0
/**
* @brief Safe state for <b>unconnected</b> pads.
* @details The state itself is not specified and is architecture dependent,
* it may be mapped on @p PAL_MODE_INPUT_PULLUP,
* @p PAL_MODE_INPUT_PULLDOWN or @p PAL_MODE_OUTPUT_PUSHPULL as
* example.
*/
#define PAL_MODE_UNCONNECTED 1
/**
* @brief Regular input high-Z pad.
*/
#define PAL_MODE_INPUT 2
/**
* @brief Input pad with weak pull up resistor.
*/
#define PAL_MODE_INPUT_PULLUP 3
/**
* @brief Input pad with weak pull down resistor.
*/
#define PAL_MODE_INPUT_PULLDOWN 4
/**
* @brief Analog input mode.
*/
#define PAL_MODE_INPUT_ANALOG 5
/**
* @brief Push-pull output pad.
*/
#define PAL_MODE_OUTPUT_PUSHPULL 6
/**
* @brief Open-drain output pad.
*/
#define PAL_MODE_OUTPUT_OPENDRAIN 7
/**
* @brief Logical low state.
*/
#define PAL_LOW 0
/**
* @brief Logical high state.
*/
#define PAL_HIGH 1
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
#include "pal_lld.h"
/**
* @brief I/O bus descriptor.
* @details This structure describes a group of contiguous digital I/O lines
* that have to be handled as bus.
* @note I/O operations on a bus do not affect I/O lines on the same port but
* not belonging to the bus.
*/
typedef struct {
/**
* @brief Port identifier.
*/
ioportid_t bus_portid;
/**
* @brief Bus mask aligned to port bit 0.
* @note The bus mask implicitly define the bus width. A logical AND is
* performed on the bus data.
*/
ioportmask_t bus_mask;
/**
* @brief Offset, within the port, of the least significant bit of the bus.
*/
uint_fast8_t bus_offset;
} IOBus;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Port bit helper macro.
* @details This macro calculates the mask of a bit within a port.
*
* @param[in] n bit position within the port
* @return The bit mask.
*/
#define PAL_PORT_BIT(n) ((ioportmask_t)(1 << (n)))
/**
* @brief Bits group mask helper.
* @details This macro calculates the mask of a bits group.
*
* @param[in] width group width
* @return The group mask.
*/
#define PAL_GROUP_MASK(width) ((ioportmask_t)(1 << (width)) - 1)
/**
* @brief Data part of a static I/O bus initializer.
* @details This macro should be used when statically initializing an I/O bus
* that is part of a bigger structure.
*
* @param[in] name name of the IOBus variable
* @param[in] port I/O port descriptor
* @param[in] width bus width in bits
* @param[in] offset bus bit offset within the port
*/
#define _IOBUS_DATA(name, port, width, offset) \
{port, PAL_GROUP_MASK(width), offset}
/**
* @brief Static I/O bus initializer.
*
* @param[in] name name of the IOBus variable
* @param[in] port I/O port descriptor
* @param[in] width bus width in bits
* @param[in] offset bus bit offset within the port
*/
#define IOBUS_DECL(name, port, width, offset) \
IOBus name = _IOBUS_DATA(name, port, width, offset)
/**
* @brief PAL subsystem initialization.
*
* @param[in] config pointer to an architecture specific configuration
* structure. This structure is defined in the low level driver
* header.
*/
#define palInit(config) pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
* @note The default implementation always return zero and computes the
* parameter eventual side effects.
*
* @param[in] port port identifier
* @return The port logical states.
*/
#if !defined(pal_lld_readport) || defined(__DOXYGEN__)
#define palReadPort(port) ((void)(port), 0)
#else
#define palReadPort(port) pal_lld_readport(port)
#endif
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
* @note The default implementation always return zero and computes the
* parameter eventual side effects.
*
* @param[in] port port identifier
* @return The latched logical states.
*/
#if !defined(pal_lld_readlatch) || defined(__DOXYGEN__)
#define palReadLatch(port) ((void)(port), 0)
#else
#define palReadLatch(port) pal_lld_readlatch(port)
#endif
/**
* @brief Writes a bits mask on a I/O port.
* @note The default implementation does nothing except computing the
* parameters eventual side effects.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*/
#if !defined(pal_lld_writeport) || defined(__DOXYGEN__)
#define palWritePort(port, bits) ((void)(port), (void)(bits))
#else
#define palWritePort(port, bits) pal_lld_writeport(port, bits)
#endif
/**
* @brief Sets a bits mask on a I/O port.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
* @p chSysUnlock().
* @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*/
#if !defined(pal_lld_setport) || defined(__DOXYGEN__)
#define palSetPort(port, bits) { \
palWritePort(port, palReadLatch(port) | (bits)); \
}
#else
#define palSetPort(port, bits) pal_lld_setport(port, bits)
#endif
/**
* @brief Clears a bits mask on a I/O port.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
* @p chSysUnlock().
* @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*
*/
#if !defined(pal_lld_clearport) || defined(__DOXYGEN__)
#define palClearPort(port, bits) { \
palWritePort(port, palReadLatch(port) & ~(bits)); \
}
#else
#define palClearPort(port, bits) pal_lld_clearport(port, bits)
#endif
/**
* @brief Toggles a bits mask on a I/O port.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
* @p chSysUnlock().
* @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be XORed on the specified port
*/
#if !defined(pal_lld_toggleport) || defined(__DOXYGEN__)
#define palTogglePort(port, bits) { \
palWritePort(port, palReadLatch(port) ^ (bits)); \
}
#else
#define palTogglePort(port, bits) pal_lld_toggleport(port, bits)
#endif
/**
* @brief Reads a group of bits.
*
* @param[in] port port identifier
* @param[in] mask group mask, a logical AND is performed on the input
* data
* @param[in] offset group bit offset within the port
* @return The group logical states.
*/
#if !defined(pal_lld_readgroup) || defined(__DOXYGEN__)
#define palReadGroup(port, mask, offset) \
((palReadPort(port) >> (offset)) & (mask))
#else
#define palReadGroup(port, mask, offset) pal_lld_readgroup(port, mask, offset)
#endif
/**
* @brief Writes a group of bits.
*
* @param[in] port port identifier
* @param[in] mask group mask, a logical AND is performed on the
* output data
* @param[in] offset group bit offset within the port
* @param[in] bits bits to be written. Values exceeding the group
* width are masked.
*/
#if !defined(pal_lld_writegroup) || defined(__DOXYGEN__)
#define palWriteGroup(port, mask, offset, bits) { \
palWritePort(port, (palReadLatch(port) & ~((mask) << (offset))) | \
(((bits) & (mask)) << (offset))); \
}
#else
#define palWriteGroup(port, mask, offset, bits) \
pal_lld_writegroup(port, mask, offset, bits)
#endif
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] mode group mode
*
*/
#if !defined(pal_lld_setgroupmode) || defined(__DOXYGEN__)
#define palSetGroupMode(port, mask, mode)
#else
#define palSetGroupMode(port, mask, mode) pal_lld_setgroupmode(port, mask, mode)
#endif
/**
* @brief Reads an input pad logical state.
* @note The default implementation not necessarily optimal. Low level
* drivers may optimize the function by using specific hardware
* or coding.
* @note The default implementation internally uses the @p palReadPort().
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @return The logical state.
* @retval PAL_LOW low logical state.
* @retval PAL_HIGH high logical state.
*
*/
#if !defined(pal_lld_readpad) || defined(__DOXYGEN__)
#define palReadPad(port, pad) ((palReadPort(port) >> (pad)) & 1)
#else
#define palReadPad(port, pad) pal_lld_readpad(port, pad)
#endif
/**
* @brief Writes a logical state on an output pad.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
* @p chSysUnlock().
* @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
* @note The default implementation internally uses the @p palReadLatch()
* and @p palWritePort().
*
* @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
*/
#if !defined(pal_lld_writepad) || defined(__DOXYGEN__)
#define palWritePad(port, pad, bit) { \
palWritePort(port, (palReadLatch(port) & ~PAL_PORT_BIT(pad)) | \
(((bit) & 1) << pad)); \
}
#else
#define palWritePad(port, pad, bit) pal_lld_writepad(port, pad, bit)
#endif
/**
* @brief Sets a pad logical state to @p PAL_HIGH.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
* @p chSysUnlock().
* @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
* @note The default implementation internally uses the @p palSetPort().
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*/
#if !defined(pal_lld_setpad) || defined(__DOXYGEN__)
#define palSetPad(port, pad) palSetPort(port, PAL_PORT_BIT(pad))
#else
#define palSetPad(port, pad) pal_lld_setpad(port, pad)
#endif
/**
* @brief Clears a pad logical state to @p PAL_LOW.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
* @p chSysUnlock().
* @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
* @note The default implementation internally uses the @p palClearPort().
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*/
#if !defined(pal_lld_clearpad) || defined(__DOXYGEN__)
#define palClearPad(port, pad) palClearPort(port, PAL_PORT_BIT(pad))
#else
#define palClearPad(port, pad) pal_lld_clearpad(port, pad)
#endif
/**
* @brief Toggles a pad logical state.
* @note The operation is not guaranteed to be atomic on all the
* architectures, for atomicity and/or portability reasons you may
* need to enclose port I/O operations between @p chSysLock() and
* @p chSysUnlock().
* @note The default implementation is non atomic and not necessarily
* optimal. Low level drivers may optimize the function by using
* specific hardware or coding.
* @note The default implementation internally uses the @p palTogglePort().
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*/
#if !defined(pal_lld_togglepad) || defined(__DOXYGEN__)
#define palTogglePad(port, pad) palTogglePort(port, PAL_PORT_BIT(pad))
#else
#define palTogglePad(port, pad) pal_lld_togglepad(port, pad)
#endif
/**
* @brief Pad mode setup.
* @details This function programs a pad with the specified mode.
* @note The default implementation not necessarily optimal. Low level
* drivers may optimize the function by using specific hardware
* or coding.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @param[in] mode pad mode
*/
#if !defined(pal_lld_setpadmode) || defined(__DOXYGEN__)
#define palSetPadMode(port, pad, mode) \
palSetGroupMode(port, PAL_PORT_BIT(pad), mode)
#else
#define palSetPadMode(port, pad, mode) pal_lld_setpadmode(port, pad, mode)
#endif
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
ioportmask_t palReadBus(IOBus *bus);
void palWriteBus(IOBus *bus, ioportmask_t bits);
void palSetBusMode(IOBus *bus, uint_fast8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* _PAL_H_ */
#endif /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,127 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file pwm.h
* @brief PWM Driver macros and structures.
*
* @addtogroup PWM
* @{
*/
#ifndef _PWM_H_
#define _PWM_H_
#if CH_HAL_USE_PWM || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver state machine possible states.
*/
typedef enum {
PWM_UNINIT = 0, /**< Not initialized. */
PWM_STOP = 1, /**< Stopped. */
PWM_READY = 2, /**< Ready. */
} pwmstate_t;
/**
* @brief PWM logic mode.
*/
typedef enum {
PWM_OUTPUT_DISABLED = 0, /**< Output not driven, callback only. */
PWM_OUTPUT_ACTIVE_HIGH = 1, /**< Idle is logic level 0. */
PWM_OUTPUT_ACTIVE_LOW = 2 /**< Idle is logic level 1. */
} pwmmode_t;
#include "pwm_lld.h"
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Enables a PWM channel.
* @details Programs (or reprograms) a PWM channel.
* @note This function has to be invoked from a lock zone.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier
* @param[in] width PWM pulse width as clock pulses number
*/
#define pwmEnableChannelI(pwmp, channel, width) \
pwm_lld_enable_channel(pwmp, channel, width)
/**
* @brief Disables a PWM channel.
* @details The channel is disabled and its output line returned to the
* idle state.
* @note This function has to be invoked from a lock zone.
*
* @param[in] pwmp pointer to a @p PWMDriver object
* @param[in] channel PWM channel identifier
*/
#define pwmDisableChannelI(pwmp, channel) \
pwm_lld_disable_channel(pwmp, channel)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void pwmInit(void);
void pwmObjectInit(PWMDriver *pwmp);
void pwmStart(PWMDriver *pwmp, const PWMConfig *config);
void pwmStop(PWMDriver *pwmp);
void pwmEnableChannel(PWMDriver *pwmp,
pwmchannel_t channel,
pwmcnt_t width);
void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_PWM */
#endif /* _PWM_H_ */
/** @} */

View File

@@ -0,0 +1,305 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file serial.h
* @brief Serial Driver macros and structures.
*
* @addtogroup SERIAL
* @{
*/
#ifndef _SERIAL_H_
#define _SERIAL_H_
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/** @brief No pending conditions.*/
#define SD_NO_ERROR 0
/** @brief Connection happened.*/
#define SD_CONNECTED 1
/** @brief Disconnection happened.*/
#define SD_DISCONNECTED 2
/** @brief Parity error happened.*/
#define SD_PARITY_ERROR 4
/** @brief Framing error happened.*/
#define SD_FRAMING_ERROR 8
/** @brief Overflow happened.*/
#define SD_OVERRUN_ERROR 16
/** @brief Noise on the line.*/
#define SD_NOISE_ERROR 32
/** @brief Break detected.*/
#define SD_BREAK_DETECTED 64
/*===========================================================================*/
/* Driver pre-compile time 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 64
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if !CH_USE_QUEUES && !CH_USE_EVENTS
#error "Serial Driver requires CH_USE_QUEUES and CH_USE_EVENTS"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver state machine possible states.
*/
typedef enum {
SD_UNINIT = 0, /**< @brief Not initialized. */
SD_STOP = 1, /**< @brief Stopped. */
SD_READY = 2 /**< @brief Ready. */
} sdstate_t;
/**
* @brief Structure representing a serial driver.
*/
typedef struct _SerialDriver SerialDriver;
#include "serial_lld.h"
/**
* @brief @p SerialDriver specific methods.
*/
#define _serial_driver_methods \
_base_asynchronous_channel_methods
/**
* @brief @p SerialDriver virtual methods table.
*/
struct SerialDriverVMT {
_serial_driver_methods
};
/**
* @extends BaseAsynchronousChannel
*
* @brief Full duplex serial driver class.
* @details This class extends @p BaseAsynchronousChannel by adding physical
* I/O queues.
*/
struct _SerialDriver {
/** @brief Virtual Methods Table.*/
const struct SerialDriverVMT *vmt;
_serial_driver_data
};
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Direct output check on a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* checks directly the output queue. This is faster but cannot
* be used to check different channels implementations.
*
* @see chIOPutWouldBlock()
*/
#define sdPutWouldBlock(sdp) chOQIsFull(&(sdp)->oqueue)
/**
* @brief Direct input check on a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* checks directly the input queue. This is faster but cannot
* be used to check different channels implementations.
*
* @see chIOGetWouldBlock()
*/
#define sdGetWouldBlock(sdp) chIQIsEmpty(&(sdp)->iqueue)
/**
* @brief Direct write to a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* writes directly on the output queue. This is faster but cannot
* be used to write to different channels implementations.
*
* @see chIOPut()
*/
#define sdPut(sdp, b) chOQPut(&(sdp)->oqueue, b)
/**
* @brief Direct write to a @p SerialDriver with timeout specification.
* @details This function bypasses the indirect access to the channel and
* writes directly on the output queue. This is faster but cannot
* be used to write to different channels implementations.
*
* @see chIOPutTimeout()
*/
#define sdPutTimeout(sdp, b, t) chOQPutTimeout(&(sdp)->iqueue, b, t)
/**
* @brief Direct read from a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* reads directly from the input queue. This is faster but cannot
* be used to read from different channels implementations.
*
* @see chIOGet()
*/
#define sdGet(sdp) chIQGet(&(sdp)->iqueue)
/**
* @brief Direct read from a @p SerialDriver with timeout specification.
* @details This function bypasses the indirect access to the channel and
* reads directly from the input queue. This is faster but cannot
* be used to read from different channels implementations.
*
* @see chIOGetTimeout()
*/
#define sdGetTimeout(sdp, t) chIQGetTimeout(&(sdp)->iqueue, t)
/**
* @brief Direct blocking write to a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* writes directly to the output queue. This is faster but cannot
* be used to write from different channels implementations.
*
* @see chIOWriteTimeout()
*/
#define sdWrite(sdp, b, n) \
chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_INFINITE)
/**
* @brief Direct blocking write to a @p SerialDriver with timeout
* specification.
* @details This function bypasses the indirect access to the channel and
* writes directly to the output queue. This is faster but cannot
* be used to write from different channels implementations.
*
* @see chIOWriteTimeout()
*/
#define sdWriteTimeout(sdp, b, n, t) \
chOQWriteTimeout(&(sdp)->oqueue, b, n, t)
/**
* @brief Direct non-blocking write to a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* writes directly to the output queue. This is faster but cannot
* be used to write from different channels implementations.
*
* @see chIOWriteTimeout()
*/
#define sdAsynchronousWrite(sdp, b, n) \
chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_IMMEDIATE)
/**
* @brief Direct blocking read from a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* reads directly from the input queue. This is faster but cannot
* be used to read from different channels implementations.
*
* @see chIOReadTimeout()
*/
#define sdRead(sdp, b, n) \
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_INFINITE)
/**
* @brief Direct blocking read from a @p SerialDriver with timeout
* specification.
* @details This function bypasses the indirect access to the channel and
* reads directly from the input queue. This is faster but cannot
* be used to read from different channels implementations.
*
* @see chIOReadTimeout()
*/
#define sdReadTimeout(sdp, b, n, t) \
chIQReadTimeout(&(sdp)->iqueue, b, n, t)
/**
* @brief Direct non-blocking read from a @p SerialDriver.
* @details This function bypasses the indirect access to the channel and
* reads directly from the input queue. This is faster but cannot
* be used to read from different channels implementations.
*
* @see chIOReadTimeout()
*/
#define sdAsynchronousRead(sdp, b, n) \
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)
/**
* @brief Returns the status change event source.
* @details The status change event source is broadcasted when the channel
* status is updated, the status flags can then be fetched and
* cheared by using @p sdGetAndClearFlags().
*
* @param[in] ip pointer to a @p SerialDriver object
* @return A pointer to an @p EventSource object.
*/
#define sdGetStatusChangeEventSource(ip) (&((ip)->vmt->sevent))
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void sdInit(void);
void sdObjectInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify);
void sdStart(SerialDriver *sdp, const SerialConfig *config);
void sdStop(SerialDriver *sdp);
void sdIncomingDataI(SerialDriver *sdp, uint8_t b);
msg_t sdRequestDataI(SerialDriver *sdp);
void sdAddFlagsI(SerialDriver *sdp, sdflags_t mask);
sdflags_t sdGetAndClearFlags(SerialDriver *sdp);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_H_ */
/** @} */

View File

@@ -0,0 +1,112 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file spi.h
* @brief SPI Driver macros and structures.
*
* @addtogroup SPI
* @{
*/
#ifndef _SPI_H_
#define _SPI_H_
#if CH_HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Enables the mutual exclusion APIs on the SPI bus.
*/
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
#define SPI_USE_MUTUAL_EXCLUSION TRUE
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if SPI_USE_MUTUAL_EXCLUSION && !CH_USE_MUTEXES && !CH_USE_SEMAPHORES
#error "SPI_USE_MUTUAL_EXCLUSION requires CH_USE_MUTEXES and/or CH_USE_SEMAPHORES"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver state machine possible states.
*/
typedef enum {
SPI_UNINIT = 0, /**< @brief Not initialized. */
SPI_STOP = 1, /**< @brief Stopped. */
SPI_READY = 2, /**< @brief Ready. */
SPI_ACTIVE = 3 /**< @brief Slave selected. */
} spistate_t;
#include "spi_lld.h"
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void spiInit(void);
void spiObjectInit(SPIDriver *spip);
void spiStart(SPIDriver *spip, const SPIConfig *config);
void spiStop(SPIDriver *spip);
void spiSelect(SPIDriver *spip);
void spiUnselect(SPIDriver *spip);
void spiIgnore(SPIDriver *spip, size_t n);
void spiExchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf);
void spiSend(SPIDriver *spip, size_t n, const void *txbuf);
void spiReceive(SPIDriver *spip, size_t n, void *rxbuf);
#if SPI_USE_MUTUAL_EXCLUSION
void spiAcquireBus(SPIDriver *spip);
void spiReleaseBus(SPIDriver *spip);
#endif /* SPI_USE_MUTUAL_EXCLUSION */
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_SPI */
#endif /* _SPI_H_ */
/** @} */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,84 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support - ROUSSET -
* ----------------------------------------------------------------------------
* Copyright (c) 2006, Atmel Corporation
* 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 disclaiimer below.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the disclaimer below in the documentation and/or
* other materials provided with the distribution.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "aic.h"
#include <board.h>
//------------------------------------------------------------------------------
// Exported functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Configures the interrupt associated with the given source, using the
/// specified mode and interrupt handler.
/// \param source Interrupt source to configure.
/// \param mode Triggering mode of the interrupt.
/// \param handler Interrupt handler function.
//------------------------------------------------------------------------------
void AIC_ConfigureIT(unsigned int source,
unsigned int mode,
void (*handler)( void ))
{
// Disable the interrupt first
AT91C_BASE_AIC->AIC_IDCR = 1 << source;
// Configure mode and handler
AT91C_BASE_AIC->AIC_SMR[source] = mode;
AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;
// Clear interrupt
AT91C_BASE_AIC->AIC_ICCR = 1 << source;
}
//------------------------------------------------------------------------------
/// Enables interrupts coming from the given (unique) source.
/// \param source Interrupt source to enable.
//------------------------------------------------------------------------------
void AIC_EnableIT(unsigned int source)
{
AT91C_BASE_AIC->AIC_IECR = 1 << source;
}
//------------------------------------------------------------------------------
/// Disables interrupts coming from the given (unique) source.
/// \param source Interrupt source to enable.
//------------------------------------------------------------------------------
void AIC_DisableIT(unsigned int source)
{
AT91C_BASE_AIC->AIC_IDCR = 1 << source;
}

View File

@@ -0,0 +1,78 @@
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support - ROUSSET -
* ----------------------------------------------------------------------------
* Copyright (c) 2006, Atmel Corporation
* 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 disclaiimer below.
*
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the disclaimer below in the documentation and/or
* other materials provided with the distribution.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
/// \dir
/// !Purpose
///
/// Methods and definitions for configuring interrupts using the Advanced
/// Interrupt Controller (AIC).
///
/// !Usage
/// -# Configure an interrupt source using AIC_ConfigureIT
/// -# Enable or disable interrupt generation of a particular source with
/// AIC_EnableIT and AIC_DisableIT.
//------------------------------------------------------------------------------
#ifndef AIC_H
#define AIC_H
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include <board.h>
//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------
#ifndef AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL
/// Redefinition of missing constant.
#define AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE
#endif
//------------------------------------------------------------------------------
// Global functions
//------------------------------------------------------------------------------
extern void AIC_ConfigureIT(unsigned int source,
unsigned int mode,
void (*handler)( void ));
extern void AIC_EnableIT(unsigned int source);
extern void AIC_DisableIT(unsigned int source);
#endif //#ifndef AIC_H

View File

@@ -0,0 +1,63 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
#ifndef _AT91SAM7_H_
#define _AT91SAM7_H_
/*
* Supported platforms.
*/
#define SAM7S64 0
#define SAM7S128 1
#define SAM7S256 2
#define SAM7S512 3
#define SAM7X128 4
#define SAM7X256 5
#define SAM7X512 6
#ifndef SAM7_PLATFORM
#error "SAM7 platform not defined"
#endif
#if SAM7_PLATFORM == SAM7S64
#include "at91lib/AT91SAM7S64.h"
#elif SAM7_PLATFORM == SAM7S128
#include "at91lib/AT91SAM7S128.h"
#elif SAM7_PLATFORM == SAM7S256
#include "at91lib/AT91SAM7S256.h"
#elif SAM7_PLATFORM == SAM7S512
#include "at91lib/AT91SAM7S512.h"
#elif SAM7_PLATFORM == SAM7X128
#include "at91lib/AT91SAM7X128.h"
#elif SAM7_PLATFORM == SAM7X256
#include "at91lib/AT91SAM7X256.h"
#elif SAM7_PLATFORM == SAM7X512
#include "at91lib/AT91SAM7X512.h"
#else
#error "SAM7 platform not supported"
#endif
#endif /* _AT91SAM7_H_ */

View File

@@ -0,0 +1,145 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/at91sam7_mii.c
* @brief AT91SAM7 low level MII driver code.
* @addtogroup AT91SAM7_MII
* @{
*/
#include "ch.h"
#include "hal.h"
#include "at91sam7_mii.h"
#if CH_HAL_USE_MAC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level MII driver initialization.
*/
void miiInit(void) {
}
/**
* @brief Resets a PHY device.
*
* @param[in] macp pointer to the @p MACDriver object
*/
void miiReset(MACDriver *macp) {
(void)macp;
/*
* Disables the pullups on all the pins that are latched on reset by the PHY.
*/
AT91C_BASE_PIOB->PIO_PPUDR = PHY_LATCHED_PINS;
#ifdef PIOB_PHY_PD_MASK
/*
* PHY power control.
*/
AT91C_BASE_PIOB->PIO_OER = PIOB_PHY_PD_MASK; // Becomes an output.
AT91C_BASE_PIOB->PIO_PPUDR = PIOB_PHY_PD_MASK; // Default pullup disabled.
#if (PHY_HARDWARE == PHY_DAVICOM_9161)
AT91C_BASE_PIOB->PIO_CODR = PIOB_PHY_PD_MASK; // Output to low level.
#else
AT91C_BASE_PIOB->PIO_SODR = PIOB_PHY_PD_MASK; // Output to high level.
#endif
#endif // PIOB_PHY_PD_MASK
/*
* PHY reset by pulsing the NRST pin.
*/
AT91C_BASE_RSTC->RSTC_RMR = 0xA5000100;
AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
while (!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL))
;
}
/**
* @brief Reads a PHY register through the MII interface.
*
* @param[in] macp pointer to the @p MACDriver object
* @param addr the register address
* @return The register value.
*/
phyreg_t miiGet(MACDriver *macp, phyaddr_t addr) {
(void)macp;
AT91C_BASE_EMAC->EMAC_MAN = (0b01 << 30) | /* SOF */
(0b10 << 28) | /* RW */
(PHY_ADDRESS << 23) | /* PHYA */
(addr << 18) | /* REGA */
(0b10 << 16); /* CODE */
while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE))
;
return (phyreg_t)(AT91C_BASE_EMAC->EMAC_MAN & 0xFFFF);
}
/**
* @brief Writes a PHY register through the MII interface.
*
* @param[in] macp pointer to the @p MACDriver object
* @param addr the register address
* @param value the new register value
*/
void miiPut(MACDriver *macp, phyaddr_t addr, phyreg_t value) {
(void)macp;
AT91C_BASE_EMAC->EMAC_MAN = (0b01 << 30) | /* SOF */
(0b01 << 28) | /* RW */
(PHY_ADDRESS << 23) | /* PHYA */
(addr << 18) | /* REGA */
(0b10 << 16) | /* CODE */
value;
while (!( AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE))
;
}
#endif /* CH_HAL_USE_MAC */
/** @} */

View File

@@ -0,0 +1,120 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/at91sam7_mii.h
* @brief AT91SAM7 low level MII driver header.
* @addtogroup AT91SAM7_MII
* @{
*/
#ifndef _AT91SAM7_MII_H_
#define _AT91SAM7_MII_H_
#if CH_HAL_USE_MAC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define PHY_MICREL_KS8721 0
#define PHY_DAVICOM_9161 1
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief PHY manufacturer and model.
*/
#if !defined(PHY_HARDWARE) || defined(__DOXYGEN__)
#define PHY_HARDWARE PHY_MICREL_KS8721
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/**
* @brief Pins latched by the PHY at reset.
*/
#if PHY_HARDWARE == PHY_MICREL_KS8721
#define PHY_ADDRESS 1
#define PHY_ID MII_KS8721_ID
#define PHY_LATCHED_PINS (AT91C_PB4_ECRS | AT91C_PB5_ERX0 | \
AT91C_PB6_ERX1 | AT91C_PB7_ERXER | \
AT91C_PB13_ERX2 | AT91C_PB14_ERX3 | \
AT91C_PB15_ERXDV_ECRSDV | AT91C_PB16_ECOL | \
AT91C_PIO_PB26)
#elif PHY_HARDWARE == PHY_DAVICOM_9161
#define PHY_ADDRESS 0
#define PHY_ID MII_DM9161_ID
#define PHY_LATCHED_PINS (AT91C_PB0_ETXCK_EREFCK | AT91C_PB4_ECRS | \
AT91C_PB5_ERX0 | AT91C_PB6_ERX1 | \
AT91C_PB7_ERXER | AT91C_PB13_ERX2 | \
AT91C_PB14_ERX3 | AT91C_PB15_ERXDV_ECRSDV | \
AT91C_PB16_ECOL | AT91C_PB17_ERXCK)
#endif /* PHY_HARDWARE */
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a PHY register value.
*/
typedef uint16_t phyreg_t;
/**
* @brief Type of a PHY register address.
*/
typedef uint8_t phyaddr_t;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void miiInit(void);
void miiReset(MACDriver *macp);
phyreg_t miiGet(MACDriver *macp, phyaddr_t addr);
void miiPut(MACDriver *macp, phyaddr_t addr, phyreg_t value);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_MAC */
#endif /* _AT91SAM7_MII_H_ */
/** @} */

View File

@@ -0,0 +1,146 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/hal_lld.c
* @brief AT91SAM7 HAL subsystem low level driver source.
* @addtogroup AT91SAM7_HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
*/
const PALConfig pal_default_config =
{
{VAL_PIOA_ODSR, VAL_PIOA_OSR, VAL_PIOA_PUSR},
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
(SAM7_PLATFORM == SAM7X512)
{VAL_PIOB_ODSR, VAL_PIOB_OSR, VAL_PIOB_PUSR}
#endif
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
static CH_IRQ_HANDLER(spurious_handler) {
CH_IRQ_PROLOGUE();
AT91SAM7_SPURIOUS_HANDLER_HOOK();
AT91C_BASE_AIC->AIC_EOICR = 0;
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
unsigned i;
/* FIQ Handler weak symbol defined in vectors.s.*/
void FiqHandler(void);
/* Default AIC setup, the device drivers will modify it as needed.*/
AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFF;
AT91C_BASE_AIC->AIC_SVR[0] = (AT91_REG)FiqHandler;
for (i = 1; i < 31; i++) {
AT91C_BASE_AIC->AIC_SVR[i] = (AT91_REG)NULL;
AT91C_BASE_AIC->AIC_EOICR = (AT91_REG)i;
}
AT91C_BASE_AIC->AIC_SPU = (AT91_REG)spurious_handler;
}
/**
* @brief AT91SAM7 clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
*/
void at91sam7_clock_init(void) {
/* wait for reset */
while((AT91C_BASE_RSTC->RSTC_RSR & (AT91C_RSTC_SRCMP | AT91C_RSTC_NRSTL)) != AT91C_RSTC_NRSTL)
;
/* enable reset */
AT91C_BASE_RSTC->RSTC_RMR = ((0xA5 << 24) | AT91C_RSTC_URSTEN);
/* Flash Memory: 1 wait state, about 50 cycles in a microsecond.*/
#if SAM7_PLATFORM == SAM7X512
AT91C_BASE_MC->MC0_FMR = (AT91C_MC_FMCN & (50 << 16)) | AT91C_MC_FWS_1FWS;
AT91C_BASE_MC->MC1_FMR = (AT91C_MC_FMCN & (50 << 16)) | AT91C_MC_FWS_1FWS;
#else
AT91C_BASE_MC->MC_FMR = (AT91C_MC_FMCN & (50 << 16)) | AT91C_MC_FWS_1FWS;
#endif
/* Enables the main oscillator and waits 56 slow cycles as startup time.*/
AT91C_BASE_PMC->PMC_MOR = (AT91C_CKGR_OSCOUNT & (7 << 8)) | AT91C_CKGR_MOSCEN;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS))
;
/* PLL setup: DIV = 14, MUL = 72, PLLCOUNT = 10
PLLfreq = 96109714 Hz (rounded).*/
AT91C_BASE_PMC->PMC_PLLR = (AT91C_CKGR_DIV & 14) |
(AT91C_CKGR_PLLCOUNT & (10 << 8)) |
(AT91SAM7_USBDIV) |
(AT91C_CKGR_MUL & (72 << 16));
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK))
;
/* Master clock = PLLfreq / 2 = 48054858 Hz (rounded).*/
AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
;
AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY))
;
}
/** @} */

View File

@@ -0,0 +1,94 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/hal_lld.h
* @brief AT91SAM7 HAL subsystem low level driver header.
* @addtogroup AT91SAM7_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "at91sam7.h"
#include "at91lib/aic.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "AT91SAM7x"
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Default action for the spurious handler, nothing.
*/
#if !defined(AT91SAM7_SPURIOUS_HANDLER_HOOK) || defined(__DOXYGEN__)
#define AT91SAM7_SPURIOUS_HANDLER_HOOK()
#endif
/**
* @brief Default divider for the USB clock - half the PLL clock.
*/
#if !defined(AT91SAM7_USBDIV) || defined(__DOXYGEN__)
#define AT91SAM7_USBDIV AT91C_CKGR_USBDIV_1
#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 at91sam7_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,514 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/mac_lld.c
* @brief AT91SAM7 low level MAC driver code.
* @addtogroup AT91SAM7_MAC
* @{
*/
#include <string.h>
#include "ch.h"
#include "hal.h"
#include "mii.h"
#include "at91sam7_mii.h"
#if CH_HAL_USE_MAC || defined(__DOXYGEN__)
#define EMAC_PIN_MASK (AT91C_PB0_ETXCK_EREFCK | AT91C_PB1_ETXEN | \
AT91C_PB2_ETX0 | AT91C_PB3_ETX1 | \
AT91C_PB4_ECRS | AT91C_PB5_ERX0 | \
AT91C_PB6_ERX1 | AT91C_PB7_ERXER | \
AT91C_PB8_EMDC | AT91C_PB9_EMDIO | \
AT91C_PB10_ETX2 | AT91C_PB11_ETX3 | \
AT91C_PB12_ETXER | AT91C_PB13_ERX2 | \
AT91C_PB14_ERX3 | AT91C_PB15_ERXDV_ECRSDV | \
AT91C_PB16_ECOL | AT91C_PB17_ERXCK)
#define RSR_BITS (AT91C_EMAC_BNA | AT91C_EMAC_REC | AT91C_EMAC_OVR)
#define TSR_BITS (AT91C_EMAC_UBR | AT91C_EMAC_COL | AT91C_EMAC_RLES | \
AT91C_EMAC_BEX | AT91C_EMAC_COMP | AT91C_EMAC_UND)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief Ethernet driver 1.
*/
MACDriver ETH1;
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
#ifndef __DOXYGEN__
static bool_t link_up;
static uint8_t default_mac[] = {0xAA, 0x55, 0x13, 0x37, 0x01, 0x10};
static EMACDescriptor *rxptr;
static EMACDescriptor *txptr;
static EMACDescriptor rd[EMAC_RECEIVE_DESCRIPTORS]
__attribute__((aligned(8)));
static EMACDescriptor td[EMAC_TRANSMIT_DESCRIPTORS]
__attribute__((aligned(8)));
static uint8_t rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE]
__attribute__((aligned(8)));
static uint8_t tb[EMAC_TRANSMIT_DESCRIPTORS * EMAC_TRANSMIT_BUFFERS_SIZE]
__attribute__((aligned(8)));
#endif
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief IRQ handler.
*/
/** @cond never*/
__attribute__((noinline))
/** @endcond*/
static void serve_interrupt(void) {
uint32_t isr, rsr, tsr;
/* Fix for the EMAC errata */
isr = AT91C_BASE_EMAC->EMAC_ISR;
rsr = AT91C_BASE_EMAC->EMAC_RSR;
tsr = AT91C_BASE_EMAC->EMAC_TSR;
if ((isr & AT91C_EMAC_RCOMP) || (rsr & RSR_BITS)) {
if (rsr & AT91C_EMAC_REC) {
chSysLockFromIsr();
chSemResetI(&ETH1.md_rdsem, 0);
#if CH_USE_EVENTS
chEvtBroadcastI(&ETH1.md_rdevent);
#endif
chSysUnlockFromIsr();
}
AT91C_BASE_EMAC->EMAC_RSR = RSR_BITS;
}
if ((isr & AT91C_EMAC_TCOMP) || (tsr & TSR_BITS)) {
if (tsr & AT91C_EMAC_COMP) {
chSysLockFromIsr();
chSemResetI(&ETH1.md_tdsem, 0);
chSysUnlockFromIsr();
}
AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
}
AT91C_BASE_AIC->AIC_EOICR = 0;
}
/**
* @brief Cleans an incomplete frame.
* @param from the start position of the incomplete frame
*/
static void cleanup(EMACDescriptor *from) {
while (from != rxptr) {
from->w1 &= ~W1_R_OWNERSHIP;
if (++from >= &rd[EMAC_RECEIVE_DESCRIPTORS])
from = rd;
}
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief EMAC IRQ veneer handler.
*/
CH_IRQ_HANDLER(irq_handler) {
CH_IRQ_PROLOGUE();
serve_interrupt();
CH_IRQ_EPILOGUE();
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level MAC initialization.
*/
void mac_lld_init(void) {
unsigned i;
miiInit();
macObjectInit(&ETH1);
/*
* Buffers initialization.
*/
for (i = 0; i < EMAC_RECEIVE_DESCRIPTORS; i++) {
rd[i].w1 = (uint32_t)&rb[i * EMAC_RECEIVE_BUFFERS_SIZE];
rd[i].w2 = 0;
}
rd[EMAC_RECEIVE_DESCRIPTORS - 1].w1 |= W1_R_WRAP;
rxptr = rd;
for (i = 0; i < EMAC_TRANSMIT_DESCRIPTORS; i++) {
td[i].w1 = (uint32_t)&tb[i * EMAC_TRANSMIT_BUFFERS_SIZE];
td[i].w2 = EMAC_TRANSMIT_BUFFERS_SIZE | W2_T_LAST_BUFFER | W2_T_USED;
}
td[EMAC_TRANSMIT_DESCRIPTORS - 1].w2 |= W2_T_WRAP;
txptr = td;
/*
* Associated PHY initialization.
*/
miiReset(&ETH1);
/*
* EMAC pins setup and clock enable. Note, PB18 is not included because it is
* used as #PD control and not as EF100.
*/
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC;
AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK;
AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK;
AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK;
/*
* EMAC Initial setup.
*/
AT91C_BASE_EMAC->EMAC_NCR = 0; /* Stopped but MCE active.*/
AT91C_BASE_EMAC->EMAC_NCFGR = 2 << 10; /* MDC-CLK = MCK / 32 */
AT91C_BASE_EMAC->EMAC_USRIO = AT91C_EMAC_CLKEN;/* Enable EMAC in MII mode.*/
AT91C_BASE_EMAC->EMAC_RBQP = (AT91_REG)rd; /* RX descriptors list.*/
AT91C_BASE_EMAC->EMAC_TBQP = (AT91_REG)td; /* TX descriptors list.*/
AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_OVR |
AT91C_EMAC_REC |
AT91C_EMAC_BNA; /* Clears RSR.*/
AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_DRFCS;/* Initial NCFGR settings.*/
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TE |
AT91C_EMAC_RE |
AT91C_EMAC_CLRSTAT;/* Initial NCR settings.*/
mac_lld_set_address(&ETH1, default_mac);
/*
* PHY device identification.
*/
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
if ((miiGet(&ETH1, MII_PHYSID1) != (PHY_ID >> 16)) ||
((miiGet(&ETH1, MII_PHYSID2) & 0xFFF0) != (PHY_ID & 0xFFF0)))
chSysHalt();
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
/*
* Interrupt configuration.
*/
AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
AIC_ConfigureIT(AT91C_ID_EMAC,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | EMAC_INTERRUPT_PRIORITY,
irq_handler);
AIC_EnableIT(AT91C_ID_EMAC);
}
/**
* @brief Low level MAC address setup.
*
* @param[in] macp pointer to the @p MACDriver object
* @param[in] p pointer to a six bytes buffer containing the MAC address. If
* this parameter is set to @p NULL then a system default MAC is
* used. The MAC address must be aligned with the most significant
* byte first.
*/
void mac_lld_set_address(MACDriver *macp, const uint8_t *p) {
(void)macp;
AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((p[3] << 24) | (p[2] << 16) |
(p[1] << 8) | p[0]);
AT91C_BASE_EMAC->EMAC_SA1H = (AT91_REG)((p[5] << 8) | p[4]);
}
/**
* @brief Returns a transmission descriptor.
* @details One of the available transmission descriptors is locked and
* returned.
*
* @param[in] macp pointer to the @p MACDriver object
* @param[out] tdp pointer to a @p MACTransmitDescriptor structure
* @return The operation status.
* @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT descriptor not available.
*/
msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
MACTransmitDescriptor *tdp) {
EMACDescriptor *edp;
(void)macp;
if (!link_up)
return RDY_TIMEOUT;
chSysLock();
edp = txptr;
if (!(edp->w2 & W2_T_USED) || (edp->w2 & W2_T_LOCKED)) {
chSysUnlock();
return RDY_TIMEOUT;
}
/*
* Set the buffer size and configuration, the buffer is also marked
* as locked.
*/
if (++txptr >= &td[EMAC_TRANSMIT_DESCRIPTORS]) {
edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER | W2_T_WRAP;
txptr = td;
}
else
edp->w2 = W2_T_LOCKED | W2_T_USED | W2_T_LAST_BUFFER;
chSysUnlock();
tdp->td_offset = 0;
tdp->td_size = EMAC_TRANSMIT_BUFFERS_SIZE;
tdp->td_physdesc = edp;
return RDY_OK;
}
/**
* @brief Writes to a transmit descriptor's stream.
*
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
* @param[in] buf pointer to the buffer cointaining the data to be written
* @param[in] size number of bytes to be written
* @return The number of bytes written into the descriptor's stream, this
* value can be less than the amount specified in the parameter
* @p size if the maximum frame size is reached.
*/
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size) {
if (size > tdp->td_size - tdp->td_offset)
size = tdp->td_size - tdp->td_offset;
if (size > 0) {
memcpy((uint8_t *)(tdp->td_physdesc->w1 & W1_T_ADDRESS_MASK) +
tdp->td_offset,
buf, size);
tdp->td_offset += size;
}
return size;
}
/**
* @brief Releases a transmit descriptor and starts the transmission of the
* enqueued data as a single frame.
*
* @param[in] tdp the pointer to the @p MACTransmitDescriptor structure
*/
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
chSysLock();
tdp->td_physdesc->w2 = (tdp->td_physdesc->w2 &
~(W2_T_LOCKED | W2_T_USED | W2_T_LENGTH_MASK)) |
tdp->td_offset;
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
chSysUnlock();
}
/**
* @brief Returns a receive descriptor.
*
* @param[in] macp pointer to the @p MACDriver object
* @param[out] rdp pointer to a @p MACReceiveDescriptor structure
* @return The operation status.
* @retval RDY_OK the descriptor was obtained.
* @retval RDY_TIMEOUT descriptor not available.
*/
msg_t max_lld_get_receive_descriptor(MACDriver *macp,
MACReceiveDescriptor *rdp) {
unsigned n;
EMACDescriptor *edp;
(void)macp;
n = EMAC_RECEIVE_DESCRIPTORS;
/*
* Skips unused buffers, if any.
*/
skip:
while ((n > 0) && !(rxptr->w1 & W1_R_OWNERSHIP)) {
if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
rxptr = rd;
n--;
}
/*
* Skips fragments, if any, cleaning them up.
*/
while ((n > 0) && (rxptr->w1 & W1_R_OWNERSHIP) &&
!(rxptr->w2 & W2_R_FRAME_START)) {
rxptr->w1 &= ~W1_R_OWNERSHIP;
if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
rxptr = rd;
n--;
}
/*
* Now compute the total frame size skipping eventual incomplete frames
* or holes...
*/
restart:
edp = rxptr;
while (n > 0) {
if (!(rxptr->w1 & W1_R_OWNERSHIP)) {
/* Empty buffer for some reason... cleaning up the incomplete frame.*/
cleanup(edp);
goto skip;
}
/*
* End Of Frame found.
*/
if (rxptr->w2 & W2_R_FRAME_END) {
rdp->rd_offset = 0;
rdp->rd_size = rxptr->w2 & W2_T_LENGTH_MASK;
rdp->rd_physdesc = edp;
return RDY_OK;
}
if ((edp != rxptr) && (rxptr->w2 & W2_R_FRAME_START)) {
/* Found another start... cleaning up the incomplete frame.*/
cleanup(edp);
goto restart; /* Another start buffer for some reason... */
}
if (++rxptr >= &rd[EMAC_RECEIVE_DESCRIPTORS])
rxptr = rd;
n--;
}
return RDY_TIMEOUT;
}
/**
* @brief Reads from a receive descriptor's stream.
*
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
* @param[in] buf pointer to the buffer that will receive the read data
* @param[in] size number of bytes to be read
* @return The number of bytes read from the descriptor's stream, this
* value can be less than the amount specified in the parameter
* @p size if there are no more bytes to read.
*/
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf,
size_t size) {
if (size > rdp->rd_size - rdp->rd_offset)
size = rdp->rd_size - rdp->rd_offset;
if (size > 0) {
uint8_t *src = (uint8_t *)(rdp->rd_physdesc->w1 & W1_R_ADDRESS_MASK) +
rdp->rd_offset;
uint8_t *limit = &rb[EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE];
if (src >= limit)
src -= EMAC_RECEIVE_DESCRIPTORS * EMAC_RECEIVE_BUFFERS_SIZE;
if (src + size > limit ) {
memcpy(buf, src, (size_t)(limit - src));
memcpy(buf + (size_t)(limit - src), rb, size - (size_t)(limit - src));
}
else
memcpy(buf, src, size);
rdp->rd_offset += size;
}
return size;
}
/**
* @brief Releases a receive descriptor.
* @details The descriptor and its buffer are made available for more incoming
* frames.
*
* @param[in] rdp the pointer to the @p MACReceiveDescriptor structure
*/
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
bool_t done;
EMACDescriptor *edp = rdp->rd_physdesc;
unsigned n = EMAC_RECEIVE_DESCRIPTORS;
do {
done = ((edp->w2 & W2_R_FRAME_END) != 0);
chDbgAssert(edp->w1 & W1_R_OWNERSHIP,
"mac_lld_release_receive_descriptor(), #1",
"found not owned descriptor");
edp->w1 &= ~(W1_R_OWNERSHIP | W2_R_FRAME_START | W2_R_FRAME_END);
if (++edp >= &rd[EMAC_RECEIVE_DESCRIPTORS])
edp = rd;
n--;
}
while ((n > 0) && !done);
/*
* Make rxptr point to the descriptor where the next frame will most
* likely appear.
*/
rxptr = edp;
}
/**
* @brief Updates and returns the link status.
*
* @param[in] macp pointer to the @p MACDriver object
* @return The link status.
* @retval TRUE if the link is active.
* @retval FALSE if the link is down.
*/
bool_t mac_lld_poll_link_status(MACDriver *macp) {
uint32_t ncfgr, bmsr, bmcr, lpa;
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
(void)miiGet(macp, MII_BMSR);
bmsr = miiGet(macp, MII_BMSR);
if (!(bmsr & BMSR_LSTATUS)) {
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
return link_up = FALSE;
}
ncfgr = AT91C_BASE_EMAC->EMAC_NCFGR & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
bmcr = miiGet(macp, MII_BMCR);
if (bmcr & BMCR_ANENABLE) {
lpa = miiGet(macp, MII_LPA);
if (lpa & (LPA_100HALF | LPA_100FULL | LPA_100BASE4))
ncfgr |= AT91C_EMAC_SPD;
if (lpa & (LPA_10FULL | LPA_100FULL))
ncfgr |= AT91C_EMAC_FD;
}
else {
if (bmcr & BMCR_SPEED100)
ncfgr |= AT91C_EMAC_SPD;
if (bmcr & BMCR_FULLDPLX)
ncfgr |= AT91C_EMAC_FD;
}
AT91C_BASE_EMAC->EMAC_NCFGR = ncfgr;
AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
return link_up = TRUE;
}
#endif /* CH_HAL_USE_MAC */
/** @} */

View File

@@ -0,0 +1,207 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/mac_lld.h
* @brief AT91SAM7 low level MAC driver header.
* @addtogroup AT91SAM7_MAC
* @{
*/
#ifndef _MAC_LLD_H_
#define _MAC_LLD_H_
#if CH_HAL_USE_MAC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define EMAC_RECEIVE_BUFFERS_SIZE 128 /* Do not modify */
#define EMAC_TRANSMIT_BUFFERS_SIZE MAC_BUFFERS_SIZE
#define EMAC_RECEIVE_DESCRIPTORS \
(((((MAC_BUFFERS_SIZE - 1) | (EMAC_RECEIVE_BUFFERS_SIZE - 1)) + 1) \
/ EMAC_RECEIVE_BUFFERS_SIZE) * MAC_RECEIVE_BUFFERS)
#define EMAC_TRANSMIT_DESCRIPTORS MAC_TRANSMIT_BUFFERS
#define W1_R_OWNERSHIP 0x00000001
#define W1_R_WRAP 0x00000002
#define W1_R_ADDRESS_MASK 0xFFFFFFFC
#define W2_R_LENGTH_MASK 0x00000FFF
#define W2_R_FRAME_START 0x00004000
#define W2_R_FRAME_END 0x00008000
#define W2_R_CFI 0x00010000
#define W2_R_VLAN_PRIO_MASK 0x000E0000
#define W2_R_PRIO_TAG_DETECTED 0x00100000
#define W2_R_VLAN_TAG_DETECTED 0x00200000
#define W2_R_TYPE_ID_MATCH 0x00400000
#define W2_R_ADDR4_MATCH 0x00800000
#define W2_R_ADDR3_MATCH 0x01000000
#define W2_R_ADDR2_MATCH 0x02000000
#define W2_R_ADDR1_MATCH 0x04000000
#define W2_R_RFU1 0x08000000
#define W2_R_ADDR_EXT_MATCH 0x10000000
#define W2_R_UNICAST_MATCH 0x20000000
#define W2_R_MULTICAST_MATCH 0x40000000
#define W2_R_BROADCAST_DETECTED 0x80000000
#define W1_T_ADDRESS_MASK 0xFFFFFFFF
#define W2_T_LENGTH_MASK 0x000007FF
#define W2_T_LOCKED 0x00000800 /* Not an EMAC flag, used by the driver */
#define W2_T_RFU1 0x00003000
#define W2_T_LAST_BUFFER 0x00008000
#define W2_T_NO_CRC 0x00010000
#define W2_T_RFU2 0x07FE0000
#define W2_T_BUFFERS_EXHAUSTED 0x08000000
#define W2_T_TRANSMIT_UNDERRUN 0x10000000
#define W2_T_RETRY_LIMIT_EXC 0x20000000
#define W2_T_WRAP 0x40000000
#define W2_T_USED 0x80000000
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Number of available transmit buffers.
*/
#if !defined(MAC_TRANSMIT_BUFFERS) || defined(__DOXYGEN__)
#define MAC_TRANSMIT_BUFFERS 2
#endif
/**
* @brief Number of available receive buffers.
*/
#if !defined(MAC_RECEIVE_BUFFERS) || defined(__DOXYGEN__)
#define MAC_RECEIVE_BUFFERS 2
#endif
/**
* @brief Maximum supported frame size.
*/
#if !defined(MAC_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define MAC_BUFFERS_SIZE 1518
#endif
/**
* @brief Interrupt priority level for the EMAC device.
*/
#if !defined(EMAC_INTERRUPT_PRIORITY) || defined(__DOXYGEN__)
#define EMAC_INTERRUPT_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 3)
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Structure representing a buffer physical descriptor.
* @note It represents both descriptor types.
*/
typedef struct {
uint32_t w1;
uint32_t w2;
} EMACDescriptor;
/**
* @brief Structure representing a MAC driver.
*/
typedef struct {
Semaphore md_tdsem; /**< Transmit semaphore. */
Semaphore md_rdsem; /**< Receive semaphore. */
#if CH_USE_EVENTS
EventSource md_rdevent; /**< Receive event source. */
#endif
/* End of the mandatory fields.*/
} MACDriver;
/**
* @brief Structure representing a transmit descriptor.
*/
typedef struct {
size_t td_offset; /**< Current write offset. */
size_t td_size; /**< Available space size. */
/* End of the mandatory fields.*/
EMACDescriptor *td_physdesc; /**< Pointer to the physical
descriptor. */
} MACTransmitDescriptor;
/**
* @brief Structure representing a receive descriptor.
*/
typedef struct {
size_t rd_offset; /**< Current read offset. */
size_t rd_size; /**< Available data size. */
/* End of the mandatory fields.*/
EMACDescriptor *rd_physdesc; /**< Pointer to the first descriptor
of the buffers chain. */
} MACReceiveDescriptor;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if !defined(__DOXYGEN__)
extern MACDriver ETH1;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void mac_lld_init(void);
void mac_lld_set_address(MACDriver *macp, const uint8_t *p);
msg_t max_lld_get_transmit_descriptor(MACDriver *macp,
MACTransmitDescriptor *tdp);
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
uint8_t *buf,
size_t size);
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp);
msg_t max_lld_get_receive_descriptor(MACDriver *macp,
MACReceiveDescriptor *rdp);
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
uint8_t *buf,
size_t size);
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp);
bool_t mac_lld_poll_link_status(MACDriver *macp);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_MAC */
#endif /* _MAC_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,156 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/pal_lld.c
* @brief AT91SAM7 PIO low level driver code.
* @addtogroup AT91SAM7_PAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief AT91SAM7 I/O ports configuration.
* @details PIO registers initialization.
*
* @param[in] config the AT91SAM7 ports configuration
*/
void _pal_lld_init(const PALConfig *config) {
uint32_t ports = (1 << AT91C_ID_PIOA);
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
(SAM7_PLATFORM == SAM7X512)
ports |= (1 << AT91C_ID_PIOB);
#endif
AT91C_BASE_PMC->PMC_PCER = ports;
/*
* PIOA setup.
*/
AT91C_BASE_PIOA->PIO_PPUER = config->P0Data.pusr; /* Pull-up as spec.*/
AT91C_BASE_PIOA->PIO_PPUDR = ~config->P0Data.pusr;
AT91C_BASE_PIOA->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/
AT91C_BASE_PIOA->PIO_ODSR = config->P0Data.odsr; /* Data as specified.*/
AT91C_BASE_PIOA->PIO_OER = config->P0Data.osr; /* Dir. as specified.*/
AT91C_BASE_PIOA->PIO_ODR = ~config->P0Data.osr;
AT91C_BASE_PIOA->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/
AT91C_BASE_PIOA->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/
AT91C_BASE_PIOA->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/
AT91C_BASE_PIOA->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/
AT91C_BASE_PIOA->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/
/*
* PIOB setup.
*/
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
(SAM7_PLATFORM == SAM7X512)
AT91C_BASE_PIOB->PIO_PPUER = config->P1Data.pusr; /* Pull-up as spec.*/
AT91C_BASE_PIOB->PIO_PPUDR = ~config->P1Data.pusr;
AT91C_BASE_PIOB->PIO_PER = 0xFFFFFFFF; /* PIO enabled.*/
AT91C_BASE_PIOB->PIO_ODSR = config->P1Data.odsr; /* Data as specified.*/
AT91C_BASE_PIOB->PIO_OER = config->P1Data.osr; /* Dir. as specified.*/
AT91C_BASE_PIOB->PIO_ODR = ~config->P1Data.osr;
AT91C_BASE_PIOB->PIO_IFDR = 0xFFFFFFFF; /* Filter disabled.*/
AT91C_BASE_PIOB->PIO_IDR = 0xFFFFFFFF; /* Int. disabled.*/
AT91C_BASE_PIOB->PIO_MDDR = 0xFFFFFFFF; /* Push Pull drive.*/
AT91C_BASE_PIOB->PIO_ASR = 0xFFFFFFFF; /* Peripheral A.*/
AT91C_BASE_PIOB->PIO_OWER = 0xFFFFFFFF; /* Write enabled.*/
#endif
}
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @note @p PAL_MODE_RESET is implemented as input with pull-up.
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high
* state.
* @note @p PAL_MODE_OUTPUT_OPENDRAIN also enables the pull-up resistor.
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode) {
switch (mode & PAL_MODE_MASK) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT_PULLUP:
port->PIO_PPUER = mask;
port->PIO_ODR = mask;
break;
case PAL_MODE_INPUT:
case PAL_MODE_INPUT_ANALOG:
port->PIO_PPUDR = mask;
port->PIO_ODR = mask;
break;
case PAL_MODE_UNCONNECTED:
port->PIO_SODR = mask;
/* Falls in */
case PAL_MODE_OUTPUT_PUSHPULL:
port->PIO_PPUDR = mask;
port->PIO_OER = mask;
port->PIO_MDDR = mask;
break;
case PAL_MODE_OUTPUT_OPENDRAIN:
port->PIO_PPUER = mask;
port->PIO_OER = mask;
port->PIO_MDER = mask;
}
}
#endif /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,262 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/pal_lld.h
* @brief AT91SAM7 PIO low level driver header.
* @addtogroup AT91SAM7_PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
#undef PAL_MODE_INPUT_PULLDOWN
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @brief PIO port setup info.
*/
typedef struct {
/** Initial value for ODSR register (data).*/
uint32_t odsr;
/** Initial value for OSR register (direction).*/
uint32_t osr;
/** Initial value for PUSR register (Pull-ups).*/
uint32_t pusr;
} at91sam7_pio_setup_t;
/**
* @brief AT91SAM7 PIO 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 Port 0 setup data.*/
at91sam7_pio_setup_t P0Data;
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
(SAM7_PLATFORM == SAM7X512) || defined(__DOXYGEN__)
/** @brief Port 1 setup data.*/
at91sam7_pio_setup_t P1Data;
#endif
} PALConfig;
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Port Identifier.
* @details This type can be a scalar or some kind of pointer, do not make
* any assumption about it, use the provided macros when populating
* variables of this type.
*/
typedef AT91PS_PIO ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief PIO port A identifier.
*/
#define IOPORT1 AT91C_BASE_PIOA
/**
* @brief PIO port B identifier.
*/
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
(SAM7_PLATFORM == SAM7X512) || defined(__DOXYGEN__)
#define IOPORT2 AT91C_BASE_PIOB
#endif
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in a file named pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*/
#define pal_lld_init(config) _pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
* @details This function is implemented by reading the PIO_PDSR register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @return The port bits.
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_readport(port) ((port)->PIO_PDSR)
/**
* @brief Reads the output latch.
* @details This function is implemented by reading the PIO_ODSR register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @return The latched logical states.
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_readlatch(port) ((port)->PIO_ODSR)
/**
* @brief Writes a bits mask on a I/O port.
* @details This function is implemented by writing the PIO_ODSR register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @param[in] bits the bits to be written on the specified port
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_writeport(port, bits) { \
(port)->PIO_ODSR = (bits); \
}
/**
* @brief Sets a bits mask on a I/O port.
* @details This function is implemented by writing the PIO_SODR register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @param[in] bits the bits to be ORed on the specified port
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_setport(port, bits) { \
(port)->PIO_SODR = (bits); \
}
/**
* @brief Clears a bits mask on a I/O port.
* @details This function is implemented by writing the PIO_CODR register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @param[in] bits the bits to be cleared on the specified port
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_clearport(port, bits) { \
(port)->PIO_CODR = (bits); \
}
/**
* @brief Writes a group of bits.
* @details This function is implemented by writing the PIO_OWER, PIO_ODSR and
* PIO_OWDR registers, the implementation is not atomic because the
* multiple accesses.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] offset the group bit offset within the port
* @param[in] bits the bits to be written. Values exceeding the group width
* are masked.
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_writegroup(port, mask, offset, bits) { \
(port)->PIO_OWER = (mask) << (offset); \
(port)->PIO_ODSR = (bits) << (offset); \
(port)->PIO_OWDR = (mask) << (offset); \
}
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with high
* state.
*/
#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
/**
* @brief Writes a logical state on an output pad.
*
* @param[in] port the port identifier
* @param[in] pad the pad number within the port
* @param[out] bit the logical value, the value must be @p 0 or @p 1
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
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,
uint_fast8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_PAL */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,100 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup AT91SAM7 AT91SAM7 Support
* @brief AT91SAM7 specific support.
* @details The AT91SAM7 support includes:
* - Buffered, interrupt driven, serial driver.
* - EMAC driver with MII support.
* - A demo supporting the kernel test suite.
* - A Web server demo using the uIP TCP/IP stack.
* - A Web server demo using the lwIP TCP/IP stack.
* .
* @ingroup ARM7
*/
/**
* @defgroup AT91SAM7_HAL AT91SAM7 HAL Support
* @brief HAL support.
*
* @ingroup AT91SAM7
*/
/**
* @defgroup AT91SAM7_PAL AT91SAM7 I/O Ports Support
* @brief I/O Ports peripherals support.
* @details This module supports the AT91SAM7 PIO controller. The controller
* supports the following features (see @ref PAL):
* - 32 bits wide ports.
* - Atomic set/reset functions.
* - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
* <h2>Supported Setup Modes</h2>
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
* - @p PAL_MODE_INPUT_ANALOG (same as @p PAL_MODE_INPUT).
* - @p PAL_MODE_INPUT_PULLUP.
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* - @p PAL_MODE_OUTPUT_OPENDRAIN.
* .
* Any attempt to setup an invalid mode is ignored.
*
* <h2>Suboptimal Behavior</h2>
* Some PIO features are less than optimal:
* - Pad/port toggling operations are not atomic.
* - Pad/group mode setup is not atomic.
* .
* @ingroup AT91SAM7
*/
/**
* @defgroup AT91SAM7_SERIAL AT91SAM7 USART Support
* @brief USART peripherals support.
* @details The serial driver supports the AT91SAM7 USART peripherals.
*
* @ingroup AT91SAM7
*/
/**
* @defgroup AT91SAM7_MAC AT91SAM7 EMAC Support
* @brief EMAC peripheral support.
* @details the @ref MAC supports the AT91SAM7 EMAC peripheral.
*
* @ingroup AT91SAM7
*/
/**
* @defgroup AT91SAM7_MII AT91SAM7 MII Support
* @brief EMAC+PHY peripheral support.
* @details This driver supports the AT91SAM7 EMAC peripheral communicating
* with an external PHY transceiver. The driver currently supports
* the Micrel KS8721 PHY and the Davicom DV9161 modules.
*
* @ingroup AT91SAM7
*/

View File

@@ -0,0 +1,10 @@
# List of all the AT91SAM7 platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/AT91SAM7/hal_lld.c \
${CHIBIOS}/os/hal/platforms/AT91SAM7/pal_lld.c \
${CHIBIOS}/os/hal/platforms/AT91SAM7/serial_lld.c \
${CHIBIOS}/os/hal/platforms/AT91SAM7/mac_lld.c \
${CHIBIOS}/os/hal/platforms/AT91SAM7/at91sam7_mii.c \
${CHIBIOS}/os/hal/platforms/AT91SAM7/at91lib/aic.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/AT91SAM7

View File

@@ -0,0 +1,365 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/serial_lld.c
* @brief AT91SAM7 low level serial driver code.
*
* @addtogroup AT91SAM7_SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
#if SAM7_PLATFORM == SAM7S256
#define SAM7_USART0_RX AT91C_PA5_RXD0
#define SAM7_USART0_TX AT91C_PA6_TXD0
#define SAM7_USART1_RX AT91C_PA21_RXD1
#define SAM7_USART1_TX AT91C_PA22_TXD1
#define SAM7_DBGU_RX AT91C_PA9_DRXD
#define SAM7_DBGU_TX AT91C_PA10_DTXD
#elif SAM7_PLATFORM == SAM7X256
#define SAM7_USART0_RX AT91C_PA0_RXD0
#define SAM7_USART0_TX AT91C_PA1_TXD0
#define SAM7_USART1_RX AT91C_PA5_RXD1
#define SAM7_USART1_TX AT91C_PA6_TXD1
#define SAM7_DBGU_RX AT91C_PA27_DRXD
#define SAM7_DBGU_TX AT91C_PA28_DTXD
#else
#error "serial lines not defined for this SAM7 version"
#endif
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if USE_SAM7_USART0 || defined(__DOXYGEN__)
/** @brief USART0 serial driver identifier.*/
SerialDriver SD1;
#endif
#if USE_SAM7_USART1 || defined(__DOXYGEN__)
/** @brief USART1 serial driver identifier.*/
SerialDriver SD2;
#endif
#if USE_SAM7_DBGU_UART || defined(__DOXYGEN__)
/** @brief DBGU_UART serial driver identifier.*/
SerialDriver SD3;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/** @brief Driver default configuration.*/
static const SerialConfig default_config = {
SERIAL_DEFAULT_BITRATE,
AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK |
AT91C_US_CHRL_8_BITS | AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief USART initialization.
*
* @param[in] sdp communication channel associated to the USART
* @param[in] config the architecture-dependent serial driver configuration
*/
static void usart_init(SerialDriver *sdp, const SerialConfig *config) {
AT91PS_USART u = sdp->usart;
/* Disables IRQ sources and stop operations.*/
u->US_IDR = 0xFFFFFFFF;
u->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA;
/* New parameters setup.*/
if (config->sc_mr & AT91C_US_OVER)
u->US_BRGR = MCK / (config->sc_speed * 8);
else
u->US_BRGR = MCK / (config->sc_speed * 16);
u->US_MR = config->sc_mr;
u->US_RTOR = 0;
u->US_TTGR = 0;
/* Enables operations and IRQ sources.*/
u->US_CR = AT91C_US_RXEN | AT91C_US_TXEN | AT91C_US_DTREN | AT91C_US_RTSEN;
u->US_IER = AT91C_US_RXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE |
AT91C_US_RXBRK;
}
/**
* @brief USART de-initialization.
*
* @param[in] u pointer to an USART I/O block
*/
static void usart_deinit(AT91PS_USART u) {
/* Disables IRQ sources and stop operations.*/
u->US_IDR = 0xFFFFFFFF;
u->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA;
u->US_MR = 0;
u->US_RTOR = 0;
u->US_TTGR = 0;
}
/**
* @brief Error handling routine.
*
* @param[in] err USART CSR register value
* @param[in] sdp communication channel associated to the USART
*/
static void set_error(SerialDriver *sdp, AT91_REG csr) {
sdflags_t sts = 0;
if (csr & AT91C_US_OVRE)
sts |= SD_OVERRUN_ERROR;
if (csr & AT91C_US_PARE)
sts |= SD_PARITY_ERROR;
if (csr & AT91C_US_FRAME)
sts |= SD_FRAMING_ERROR;
if (csr & AT91C_US_RXBRK)
sts |= SD_BREAK_DETECTED;
chSysLockFromIsr();
sdAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
#if defined(__GNUC__)
__attribute__((noinline))
#endif
#if !USE_SAM7_DBGU_UART
static
#endif
/**
* @brief Common IRQ handler.
*
* @param[in] sdp communication channel associated to the USART
*/
void sd_lld_serve_interrupt(SerialDriver *sdp) {
uint32_t csr;
AT91PS_USART u = sdp->usart;
csr = u->US_CSR;
if (csr & AT91C_US_RXRDY) {
chSysLockFromIsr();
sdIncomingDataI(sdp, u->US_RHR);
chSysUnlockFromIsr();
}
if ((u->US_IMR & AT91C_US_TXRDY) && (csr & AT91C_US_TXRDY)) {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chEvtBroadcastI(&sdp->oevent);
u->US_IDR = AT91C_US_TXRDY;
}
else
u->US_THR = b;
chSysUnlockFromIsr();
}
csr &= (AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK);
if (csr != 0) {
set_error(sdp, csr);
u->US_CR = AT91C_US_RSTSTA;
}
AT91C_BASE_AIC->AIC_EOICR = 0;
}
#if USE_SAM7_USART0 || defined(__DOXYGEN__)
static void notify1(void) {
AT91C_BASE_US0->US_IER = AT91C_US_TXRDY;
}
#endif
#if USE_SAM7_USART1 || defined(__DOXYGEN__)
static void notify2(void) {
AT91C_BASE_US1->US_IER = AT91C_US_TXRDY;
}
#endif
#if USE_SAM7_DBGU_UART || defined(__DOXYGEN__)
static void notify3(void) {
AT91C_BASE_DBGU->DBGU_IER = AT91C_US_TXRDY;
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if USE_SAM7_USART0 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(USART0IrqHandler) {
CH_IRQ_PROLOGUE();
sd_lld_serve_interrupt(&SD1);
AT91C_BASE_AIC->AIC_EOICR = 0;
CH_IRQ_EPILOGUE();
}
#endif
#if USE_SAM7_USART1 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(USART1IrqHandler) {
CH_IRQ_PROLOGUE();
sd_lld_serve_interrupt(&SD2);
AT91C_BASE_AIC->AIC_EOICR = 0;
CH_IRQ_EPILOGUE();
}
#endif
// note - DBGU_UART IRQ is the SysIrq in board.c
// since it's not vectored separately by the AIC
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_SAM7_USART0
sdObjectInit(&SD1, NULL, notify1);
SD1.usart = AT91C_BASE_US0;
AT91C_BASE_PIOA->PIO_PDR = SAM7_USART0_RX | SAM7_USART0_TX;
AT91C_BASE_PIOA->PIO_ASR = SAM7_USART0_RX | SAM7_USART0_TX;
AT91C_BASE_PIOA->PIO_PPUDR = SAM7_USART0_RX | SAM7_USART0_TX;
AIC_ConfigureIT(AT91C_ID_US0,
AT91C_AIC_SRCTYPE_HIGH_LEVEL | SAM7_USART0_PRIORITY,
USART0IrqHandler);
#endif
#if USE_SAM7_USART1
sdObjectInit(&SD2, NULL, notify2);
SD2.usart = AT91C_BASE_US1;
AT91C_BASE_PIOA->PIO_PDR = SAM7_USART1_RX | SAM7_USART1_TX;
AT91C_BASE_PIOA->PIO_ASR = SAM7_USART1_RX | SAM7_USART1_TX;
AT91C_BASE_PIOA->PIO_PPUDR = SAM7_USART1_RX | SAM7_USART1_TX;
AIC_ConfigureIT(AT91C_ID_US1,
AT91C_AIC_SRCTYPE_HIGH_LEVEL | SAM7_USART1_PRIORITY,
USART1IrqHandler);
#endif
#if USE_SAM7_DBGU_UART
sdObjectInit(&SD3, NULL, notify3);
// this is a little cheap, but OK for now since there's enough overlap
// between dbgu and usart register maps. it means we can reuse all the
// same usart interrupt handling and config that already exists
SD3.usart = (AT91PS_USART)AT91C_BASE_DBGU;
AT91C_BASE_PIOA->PIO_PDR = SAM7_DBGU_RX | SAM7_DBGU_TX;
AT91C_BASE_PIOA->PIO_ASR = SAM7_DBGU_RX | SAM7_DBGU_TX;
AT91C_BASE_PIOA->PIO_PPUDR = SAM7_DBGU_RX | SAM7_DBGU_TX;
#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.
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
if (sdp->state == SD_STOP) {
#if USE_SAM7_USART0
if (&SD1 == sdp) {
/* Starts the clock and clears possible sources of immediate interrupts.*/
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US0);
/* Enables associated interrupt vector.*/
AIC_EnableIT(AT91C_ID_US0);
}
#endif
#if USE_SAM7_USART1
if (&SD2 == sdp) {
/* Starts the clock and clears possible sources of immediate interrupts.*/
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US1);
/* Enables associated interrupt vector.*/
AIC_EnableIT(AT91C_ID_US1);
}
#endif
// note - no explicit start for SD3 (DBGU_UART) since it's not included in the AIC or PMC
}
usart_init(sdp, config);
}
/**
* @brief Low level serial driver stop.
* @details De-initializes the USART, stops the associated clock, resets the
* interrupt vector.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->state == SD_READY) {
usart_deinit(sdp->usart);
#if USE_SAM7_USART0
if (&SD1 == sdp) {
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_US0);
AIC_DisableIT(AT91C_ID_US0);
return;
}
#endif
#if USE_SAM7_USART1
if (&SD2 == sdp) {
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_US1);
AIC_DisableIT(AT91C_ID_US1);
return;
}
#endif
#if USE_SAM7_DBGU_UART
if (&SD3 == sdp) {
AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF;
return;
}
#endif
}
}
#endif /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,185 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AT91SAM7/serial_lld.h
* @brief AT91SAM7 low level serial driver header.
*
* @addtogroup AT91SAM7_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_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 USART1 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SAM7_USART0) || defined(__DOXYGEN__)
#define USE_SAM7_USART0 TRUE
#endif
/**
* @brief UART1 driver enable switch.
* @details If set to @p TRUE the support for USART2 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SAM7_USART1) || defined(__DOXYGEN__)
#define USE_SAM7_USART1 TRUE
#endif
/**
* @brief DBGU UART driver enable switch.
* @details If set to @p TRUE the support for the DBGU UART is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SAM7_DBGU_UART) || defined(__DOXYGEN__)
#define USE_SAM7_DBGU_UART TRUE
#endif
/**
* @brief UART1 interrupt priority level setting.
*/
#if !defined(SAM7_USART0_PRIORITY) || defined(__DOXYGEN__)
#define SAM7_USART0_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
#endif
/**
* @brief UART2 interrupt priority level setting.
*/
#if !defined(SAM7_USART1_PRIORITY) || defined(__DOXYGEN__)
#define SAM7_USART1_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
#endif
/**
* @brief DBGU_UART interrupt priority level setting.
*/
#if !defined(SAM7_DBGU_UART_PRIORITY) || defined(__DOXYGEN__)
#define SAM7_DBGU_UART_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Serial Driver condition flags type.
*/
typedef uint32_t sdflags_t;
/**
* @brief AT91SAM7 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.
* @details This is written to the US_BRGR register of the appropriate AT91S_USART
*/
uint32_t sc_speed;
/**
* @brief Initialization value for the MR register.
* @details This is written to the US_MR register of the appropriate AT91S_USART
*/
uint32_t sc_mr;
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* 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.*/ \
AT91PS_USART usart;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_SAM7_USART0 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if USE_SAM7_USART1 && !defined(__DOXYGEN__)
extern SerialDriver SD2;
#endif
#if USE_SAM7_DBGU_UART
extern SerialDriver SD3;
#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);
#if USE_SAM7_DBGU_UART
void sd_lld_serve_interrupt(SerialDriver *sdp);
#endif
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,64 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AVR/hal_lld.c
* @brief AVR HAL subsystem low level driver code.
* @addtogroup AVR_HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
}
/** @} */

View File

@@ -0,0 +1,76 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AVR/hal_lld.h
* @brief AVR HAL subsystem low level driver header.
* @addtogroup AVR_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "ATmega128"
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,48 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup AVR_DRIVERS AVR Drivers
* @brief Device drivers included in the AVR support.
*
* @ingroup AVR
*/
/**
* @defgroup AVR_HAL AVR HAL Support
* @brief HAL support.
*
* @ingroup AVR_DRIVERS
*/
/**
* @defgroup AVR_SERIAL AVR USART Support
* @brief USART support.
* @details The serial driver supports both the AVR USARTs in asynchronous
* mode.
*
* @ingroup AVR_DRIVERS
*/

View File

@@ -0,0 +1,6 @@
# List of all the AVR platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/AVR/hal_lld.c \
${CHIBIOS}/os/hal/platforms/AVR/serial_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/AVR

View File

@@ -0,0 +1,289 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AVR/serial_lld.c
* @brief AVR low level serial driver code.
*
* @addtogroup AVR_SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief USART0 serial driver identifier.
* @note The name does not follow the convention used in the other ports
* (COMn) because a name conflict with the AVR headers.
*/
#if USE_AVR_USART0 || defined(__DOXYGEN__)
SerialDriver SD1;
#endif
/**
* @brief USART1 serial driver identifier.
* @note The name does not follow the convention used in the other ports
* (COMn) because a name conflict with the AVR headers.
*/
#if USE_AVR_USART1 || defined(__DOXYGEN__)
SerialDriver SD2;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief Driver default configuration.
*/
static const SerialConfig default_config = {
UBRR(SERIAL_DEFAULT_BITRATE),
(1 << UCSZ1) | (1 << UCSZ0)
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void set_error(uint8_t sra, SerialDriver *sdp) {
sdflags_t sts = 0;
if (sra & (1 << DOR))
sts |= SD_OVERRUN_ERROR;
if (sra & (1 << UPE))
sts |= SD_PARITY_ERROR;
if (sra & (1 << FE))
sts |= SD_FRAMING_ERROR;
chSysLockFromIsr();
sdAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
#if USE_AVR_USART0 || defined(__DOXYGEN__)
static void notify1(void) {
UCSR0B |= (1 << UDRIE);
}
/**
* @brief USART0 initialization.
*
* @param[in] config the architecture-dependent serial driver configuration
*/
static void usart0_init(const SerialConfig *config) {
UBRR0L = config->sc_brr;
UBRR0H = config->sc_brr >> 8;
UCSR0A = 0;
UCSR0B = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
UCSR0C = config->sc_csrc;
}
/**
* @brief USART0 de-initialization.
*/
static void usart0_deinit(void) {
UCSR0A = 0;
UCSR0B = 0;
UCSR0C = 0;
}
#endif
#if USE_AVR_USART1 || defined(__DOXYGEN__)
static void notify2(void) {
UCSR1B |= (1 << UDRIE);
}
/**
* @brief USART1 initialization.
*
* @param[in] config the architecture-dependent serial driver configuration
*/
static void usart1_init(const SerialConfig *config) {
UBRR1L = config->sc_brr;
UBRR1H = config->sc_brr >> 8;
UCSR1A = 0;
UCSR1B = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
UCSR1C = config->sc_csrc;
}
/**
* @brief USART1 de-initialization.
*/
static void usart1_deinit(void) {
UCSR1A = 0;
UCSR1B = 0;
UCSR1C = 0;
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if USE_AVR_USART0 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(USART0_RX_vect) {
uint8_t sra;
CH_IRQ_PROLOGUE();
sra = UCSR0A;
if (sra & ((1 << DOR) | (1 << UPE) | (1 << FE)))
set_error(sra, &SD1);
chSysLockFromIsr();
sdIncomingDataI(&SD1, UDR0);
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
}
CH_IRQ_HANDLER(USART0_UDRE_vect) {
msg_t b;
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
b = sdRequestDataI(&SER1);
chSysUnlockFromIsr();
if (b < Q_OK)
UCSR0B &= ~(1 << UDRIE);
else
UDR0 = b;
CH_IRQ_EPILOGUE();
}
#endif /* USE_AVR_USART0 */
#if USE_AVR_USART1 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(USART1_RX_vect) {
uint8_t sra;
CH_IRQ_PROLOGUE();
sra = UCSR1A;
if (sra & ((1 << DOR) | (1 << UPE) | (1 << FE)))
set_error(sra, &SD2);
chSysLockFromIsr();
sdIncomingDataI(&SD2, UDR1);
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
}
CH_IRQ_HANDLER(USART1_UDRE_vect) {
msg_t b;
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
b = sdRequestDataI(&SD2);
chSysUnlockFromIsr();
if (b < Q_OK)
UCSR1B &= ~(1 << UDRIE);
else
UDR1 = b;
CH_IRQ_EPILOGUE();
}
#endif /* USE_AVR_USART1 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_AVR_USART0
sdObjectInit(&SD1, NULL, notify1);
#endif
#if USE_AVR_USART1
sdObjectInit(&SD2, NULL, notify2);
#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.
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
#if USE_AVR_USART0
if (&SD1 == sdp) {
usart0_init(config);
return;
}
#endif
#if USE_AVR_USART1
if (&SD2 == sdp) {
usart1_init(config);
return;
}
#endif
}
/**
* @brief Low level serial driver stop.
* @details De-initializes the USART, stops the associated clock, resets the
* interrupt vector.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
void sd_lld_stop(SerialDriver *sdp) {
#if USE_AVR_USART0
if (&SD1 == sdp)
usart0_deinit();
#endif
#if USE_AVR_USART1
if (&SD2 == sdp)
usart1_deinit();
#endif
}
#endif /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,151 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file AVR/serial_lld.h
* @brief AVR low level serial driver header.
*
* @addtogroup AVR_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief USART0 driver enable switch.
* @details If set to @p TRUE the support for USART0 is included.
* @note The default is @p FALSE.
*/
#if !defined(USE_AVR_USART0) || defined(__DOXYGEN__)
#define USE_AVR_USART0 TRUE
#endif
/**
* @brief USART1 driver enable switch.
* @details If set to @p TRUE the support for USART1 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_AVR_USART1) || defined(__DOXYGEN__)
#define USE_AVR_USART1 TRUE
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Serial Driver condition flags type.
*/
typedef uint8_t sdflags_t;
/**
* @brief AVR 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 Initialization value for the BRR register.
*/
uint16_t sc_brr;
/**
* @brief Initialization value for the CSRC register.
*/
uint8_t sc_csrc;
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Macro for baud rate computation.
* @note Make sure the final baud rate is within tolerance.
*/
#define UBRR(b) ((F_CPU / (b << 4)) - 1)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_AVR_USART0 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if USE_AVR_USART1 && !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 /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,499 @@
/**************************************************************************//**
* @file LPC11xx.h
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File for
* NXP LPC11xx Device Series
* @version V1.00
* @date 17. November 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __LPC11xx_H__
#define __LPC11xx_H__
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup LPC11xx_Definitions LPC11xx Definitions
This file defines all structures and symbols for LPC11xx:
- Registers and bitfields
- peripheral base address
- peripheral ID
- PIO definitions
@{
*/
/******************************************************************************/
/* Processor and Core Peripherals */
/******************************************************************************/
/** @addtogroup LPC11xx_CMSIS LPC11xx CMSIS Definitions
Configuration of the Cortex-M0 Processor and Core Peripherals
@{
*/
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn
{
/****** Cortex-M0 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M0 Hard Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M0 SV Call Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M0 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M0 System Tick Interrupt */
/****** LPC13xx Specific Interrupt Numbers *******************************************************/
WAKEUP0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */
WAKEUP1_IRQn = 1, /*!< There are 13 pins in total for LPC11xx */
WAKEUP2_IRQn = 2,
WAKEUP3_IRQn = 3,
WAKEUP4_IRQn = 4,
WAKEUP5_IRQn = 5,
WAKEUP6_IRQn = 6,
WAKEUP7_IRQn = 7,
WAKEUP8_IRQn = 8,
WAKEUP9_IRQn = 9,
WAKEUP10_IRQn = 10,
WAKEUP11_IRQn = 11,
WAKEUP12_IRQn = 12,
SSP1_IRQn = 14, /*!< SSP1 Interrupt */
I2C_IRQn = 15, /*!< I2C Interrupt */
TIMER_16_0_IRQn = 16, /*!< 16-bit Timer0 Interrupt */
TIMER_16_1_IRQn = 17, /*!< 16-bit Timer1 Interrupt */
TIMER_32_0_IRQn = 18, /*!< 32-bit Timer0 Interrupt */
TIMER_32_1_IRQn = 19, /*!< 32-bit Timer1 Interrupt */
SSP0_IRQn = 20, /*!< SSP0 Interrupt */
UART_IRQn = 21, /*!< UART Interrupt */
ADC_IRQn = 24, /*!< A/D Converter Interrupt */
WDT_IRQn = 25, /*!< Watchdog timer Interrupt */
BOD_IRQn = 26, /*!< Brown Out Detect(BOD) Interrupt */
EINT3_IRQn = 28, /*!< External Interrupt 3 Interrupt */
EINT2_IRQn = 29, /*!< External Interrupt 2 Interrupt */
EINT1_IRQn = 30, /*!< External Interrupt 1 Interrupt */
EINT0_IRQn = 31, /*!< External Interrupt 0 Interrupt */
} IRQn_Type;
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
/* Configuration of the Cortex-M3 Processor and Core Peripherals */
#define __MPU_PRESENT 0 /*!< MPU present or not */
#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
/*@}*/ /* end of group LPC11xx_CMSIS */
#include "core_cm0.h" /* Cortex-M0 processor and core peripherals */
#include "system_LPC11xx.h" /* System Header */
/******************************************************************************/
/* Device Specific Peripheral Registers structures */
/******************************************************************************/
#if defined ( __CC_ARM )
#pragma anon_unions
#endif
/*------------- System Control (SYSCON) --------------------------------------*/
/** @addtogroup LPC11xx_SYSCON LPC11xx System Control Block
@{
*/
typedef struct
{
__IO uint32_t SYSMEMREMAP; /*!< Offset: 0x000 System memory remap (R/W) */
__IO uint32_t PRESETCTRL; /*!< Offset: 0x004 Peripheral reset control (R/W) */
__IO uint32_t SYSPLLCTRL; /*!< Offset: 0x008 System PLL control (R/W) */
__IO uint32_t SYSPLLSTAT; /*!< Offset: 0x00C System PLL status (R/ ) */
uint32_t RESERVED0[4];
__IO uint32_t SYSOSCCTRL; /*!< Offset: 0x020 System oscillator control (R/W) */
__IO uint32_t WDTOSCCTRL; /*!< Offset: 0x024 Watchdog oscillator control (R/W) */
__IO uint32_t IRCCTRL; /*!< Offset: 0x028 IRC control (R/W) */
uint32_t RESERVED1[1];
__IO uint32_t SYSRESSTAT; /*!< Offset: 0x030 System reset status Register (R/ ) */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /*!< Offset: 0x040 System PLL clock source select (R/W) */
__IO uint32_t SYSPLLCLKUEN; /*!< Offset: 0x044 System PLL clock source update enable (R/W) */
uint32_t RESERVED3[10];
__IO uint32_t MAINCLKSEL; /*!< Offset: 0x070 Main clock source select (R/W) */
__IO uint32_t MAINCLKUEN; /*!< Offset: 0x074 Main clock source update enable (R/W) */
__IO uint32_t SYSAHBCLKDIV; /*!< Offset: 0x078 System AHB clock divider (R/W) */
uint32_t RESERVED4[1];
__IO uint32_t SYSAHBCLKCTRL; /*!< Offset: 0x080 System AHB clock control (R/W) */
uint32_t RESERVED5[4];
__IO uint32_t SSP0CLKDIV; /*!< Offset: 0x094 SSP0 clock divider (R/W) */
__IO uint32_t UARTCLKDIV; /*!< Offset: 0x098 UART clock divider (R/W) */
__IO uint32_t SSP1CLKDIV; /*!< Offset: 0x09C SSP1 clock divider (R/W) */
uint32_t RESERVED6[4];
__IO uint32_t SYSTICKCLKDIV; /*!< Offset: 0x0B0 SYSTICK clock divider (R/W) */
uint32_t RESERVED7[7];
__IO uint32_t WDTCLKSEL; /*!< Offset: 0x0D0 WDT clock source select (R/W) */
__IO uint32_t WDTCLKUEN; /*!< Offset: 0x0D4 WDT clock source update enable (R/W) */
__IO uint32_t WDTCLKDIV; /*!< Offset: 0x0D8 WDT clock divider (R/W) */
uint32_t RESERVED8[1];
__IO uint32_t CLKOUTCLKSEL; /*!< Offset: 0x0E0 CLKOUT clock source select (R/W) */
__IO uint32_t CLKOUTUEN; /*!< Offset: 0x0E4 CLKOUT clock source update enable (R/W) */
__IO uint32_t CLKOUTDIV; /*!< Offset: 0x0E8 CLKOUT clock divider (R/W) */
uint32_t RESERVED9[5];
__IO uint32_t PIOPORCAP0; /*!< Offset: 0x100 POR captured PIO status 0 (R/ ) */
__IO uint32_t PIOPORCAP1; /*!< Offset: 0x104 POR captured PIO status 1 (R/ ) */
uint32_t RESERVED10[18];
__IO uint32_t BODCTRL; /*!< Offset: 0x150 BOD control (R/W) */
uint32_t RESERVED11[1];
__IO uint32_t SYSTCKCAL; /*!< Offset: 0x158 System tick counter calibration (R/W) */
uint32_t RESERVED12[41];
__IO uint32_t STARTAPRP0; /*!< Offset: 0x200 Start logic edge control Register 0 (R/W) */
__IO uint32_t STARTERP0; /*!< Offset: 0x204 Start logic signal enable Register 0 (R/W) */
__IO uint32_t STARTRSRP0CLR; /*!< Offset: 0x208 Start logic reset Register 0 ( /W) */
__IO uint32_t STARTSRP0; /*!< Offset: 0x20C Start logic status Register 0 (R/W) */
uint32_t RESERVED14[8];
__IO uint32_t PDSLEEPCFG; /*!< Offset: 0x230 Power-down states in Deep-sleep mode (R/W) */
__IO uint32_t PDAWAKECFG; /*!< Offset: 0x234 Power-down states after wake-up (R/W) */
__IO uint32_t PDRUNCFG; /*!< Offset: 0x238 Power-down configuration Register (R/W) */
uint32_t RESERVED15[110];
__I uint32_t DEVICE_ID; /*!< Offset: 0x3F4 Device ID (R/ ) */
} LPC_SYSCON_TypeDef;
/*@}*/ /* end of group LPC11xx_SYSCON */
/*------------- Pin Connect Block (IOCON) --------------------------------*/
/** @addtogroup LPC11xx_IOCON LPC11xx I/O Configuration Block
@{
*/
typedef struct
{
__IO uint32_t PIO2_6; /*!< Offset: 0x000 I/O configuration for pin PIO2_6 (R/W) */
uint32_t RESERVED0[1];
__IO uint32_t PIO2_0; /*!< Offset: 0x008 I/O configuration for pin PIO2_0/DTR/SSEL1 (R/W) */
__IO uint32_t RESET_PIO0_0; /*!< Offset: 0x00C I/O configuration for pin RESET/PIO0_0 (R/W) */
__IO uint32_t PIO0_1; /*!< Offset: 0x010 I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2 (R/W) */
__IO uint32_t PIO1_8; /*!< Offset: 0x014 I/O configuration for pin PIO1_8/CT16B1_CAP0 (R/W) */
uint32_t RESERVED1[1];
__IO uint32_t PIO0_2; /*!< Offset: 0x01C I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 (R/W) */
__IO uint32_t PIO2_7; /*!< Offset: 0x020 I/O configuration for pin PIO2_7 (R/W) */
__IO uint32_t PIO2_8; /*!< Offset: 0x024 I/O configuration for pin PIO2_8 (R/W) */
__IO uint32_t PIO2_1; /*!< Offset: 0x028 I/O configuration for pin PIO2_1/nDSR/SCK1 (R/W) */
__IO uint32_t PIO0_3; /*!< Offset: 0x02C I/O configuration for pin PIO0_3 (R/W) */
__IO uint32_t PIO0_4; /*!< Offset: 0x030 I/O configuration for pin PIO0_4/SCL (R/W) */
__IO uint32_t PIO0_5; /*!< Offset: 0x034 I/O configuration for pin PIO0_5/SDA (R/W) */
__IO uint32_t PIO1_9; /*!< Offset: 0x038 I/O configuration for pin PIO1_9/CT16B1_MAT0 (R/W) */
__IO uint32_t PIO3_4; /*!< Offset: 0x03C I/O configuration for pin PIO3_4 (R/W) */
__IO uint32_t PIO2_4; /*!< Offset: 0x040 I/O configuration for pin PIO2_4 (R/W) */
__IO uint32_t PIO2_5; /*!< Offset: 0x044 I/O configuration for pin PIO2_5 (R/W) */
__IO uint32_t PIO3_5; /*!< Offset: 0x048 I/O configuration for pin PIO3_5 (R/W) */
__IO uint32_t PIO0_6; /*!< Offset: 0x04C I/O configuration for pin PIO0_6/SCK0 (R/W) */
__IO uint32_t PIO0_7; /*!< Offset: 0x050 I/O configuration for pin PIO0_7/nCTS (R/W) */
__IO uint32_t PIO2_9; /*!< Offset: 0x054 I/O configuration for pin PIO2_9 (R/W) */
__IO uint32_t PIO2_10; /*!< Offset: 0x058 I/O configuration for pin PIO2_10 (R/W) */
__IO uint32_t PIO2_2; /*!< Offset: 0x05C I/O configuration for pin PIO2_2/DCD/MISO1 (R/W) */
__IO uint32_t PIO0_8; /*!< Offset: 0x060 I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 (R/W) */
__IO uint32_t PIO0_9; /*!< Offset: 0x064 I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 (R/W) */
__IO uint32_t JTAG_TCK_PIO0_10; /*!< Offset: 0x068 I/O configuration for pin SWCLK/PIO0_10/SCK0/CT16B0_MAT2 (R/W) */
__IO uint32_t PIO1_10; /*!< Offset: 0x06C I/O configuration for pin PIO1_10/AD6/CT16B1_MAT1 (R/W) */
__IO uint32_t PIO2_11; /*!< Offset: 0x070 I/O configuration for pin PIO2_11/SCK0 (R/W) */
__IO uint32_t JTAG_TDI_PIO0_11; /*!< Offset: 0x074 I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 (R/W) */
__IO uint32_t JTAG_TMS_PIO1_0; /*!< Offset: 0x078 I/O configuration for pin TMS/PIO1_0/AD1/CT32B1_CAP0 (R/W) */
__IO uint32_t JTAG_TDO_PIO1_1; /*!< Offset: 0x07C I/O configuration for pin TDO/PIO1_1/AD2/CT32B1_MAT0 (R/W) */
__IO uint32_t JTAG_nTRST_PIO1_2; /*!< Offset: 0x080 I/O configuration for pin nTRST/PIO1_2/AD3/CT32B1_MAT1 (R/W) */
__IO uint32_t PIO3_0; /*!< Offset: 0x084 I/O configuration for pin PIO3_0/nDTR (R/W) */
__IO uint32_t PIO3_1; /*!< Offset: 0x088 I/O configuration for pin PIO3_1/nDSR (R/W) */
__IO uint32_t PIO2_3; /*!< Offset: 0x08C I/O configuration for pin PIO2_3/RI/MOSI1 (R/W) */
__IO uint32_t ARM_SWDIO_PIO1_3; /*!< Offset: 0x090 I/O configuration for pin SWDIO/PIO1_3/AD4/CT32B1_MAT2 (R/W) */
__IO uint32_t PIO1_4; /*!< Offset: 0x094 I/O configuration for pin PIO1_4/AD5/CT32B1_MAT3 (R/W) */
__IO uint32_t PIO1_11; /*!< Offset: 0x098 I/O configuration for pin PIO1_11/AD7 (R/W) */
__IO uint32_t PIO3_2; /*!< Offset: 0x09C I/O configuration for pin PIO3_2/nDCD (R/W) */
__IO uint32_t PIO1_5; /*!< Offset: 0x0A0 I/O configuration for pin PIO1_5/nRTS/CT32B0_CAP0 (R/W) */
__IO uint32_t PIO1_6; /*!< Offset: 0x0A4 I/O configuration for pin PIO1_6/RXD/CT32B0_MAT0 (R/W) */
__IO uint32_t PIO1_7; /*!< Offset: 0x0A8 I/O configuration for pin PIO1_7/TXD/CT32B0_MAT1 (R/W) */
__IO uint32_t PIO3_3; /*!< Offset: 0x0AC I/O configuration for pin PIO3_3/nRI (R/W) */
__IO uint32_t SCK_LOC; /*!< Offset: 0x0B0 SCK pin location select Register (R/W) */
__IO uint32_t DSR_LOC; /*!< Offset: 0x0B4 DSR pin location select Register (R/W) */
__IO uint32_t DCD_LOC; /*!< Offset: 0x0B8 DCD pin location select Register (R/W) */
__IO uint32_t RI_LOC; /*!< Offset: 0x0BC RI pin location Register (R/W) */
} LPC_IOCON_TypeDef;
/*@}*/ /* end of group LPC11xx_IOCON */
/*------------- Power Management Unit (PMU) --------------------------*/
/** @addtogroup LPC11xx_PMU LPC11xx Power Management Unit
@{
*/
typedef struct
{
__IO uint32_t PCON; /*!< Offset: 0x000 Power control Register (R/W) */
__IO uint32_t GPREG0; /*!< Offset: 0x004 General purpose Register 0 (R/W) */
__IO uint32_t GPREG1; /*!< Offset: 0x008 General purpose Register 1 (R/W) */
__IO uint32_t GPREG2; /*!< Offset: 0x00C General purpose Register 2 (R/W) */
__IO uint32_t GPREG3; /*!< Offset: 0x010 General purpose Register 3 (R/W) */
__IO uint32_t GPREG4; /*!< Offset: 0x014 General purpose Register 4 (R/W) */
} LPC_PMU_TypeDef;
/*@}*/ /* end of group LPC11xx_PMU */
/*------------- General Purpose Input/Output (GPIO) --------------------------*/
/** @addtogroup LPC11xx_GPIO LPC11xx General Purpose Input/Output
@{
*/
typedef struct
{
union {
__IO uint32_t MASKED_ACCESS[4096]; /*!< Offset: 0x0000 to 0x3FFC Port data Register for pins PIOn_0 to PIOn_11 (R/W) */
struct {
uint32_t RESERVED0[4095];
__IO uint32_t DATA; /*!< Offset: 0x3FFC Port data Register (R/W) */
};
};
uint32_t RESERVED1[4096];
__IO uint32_t DIR; /*!< Offset: 0x8000 Data direction Register (R/W) */
__IO uint32_t IS; /*!< Offset: 0x8004 Interrupt sense Register (R/W) */
__IO uint32_t IBE; /*!< Offset: 0x8008 Interrupt both edges Register (R/W) */
__IO uint32_t IEV; /*!< Offset: 0x800C Interrupt event Register (R/W) */
__IO uint32_t IE; /*!< Offset: 0x8010 Interrupt mask Register (R/W) */
__IO uint32_t RIS; /*!< Offset: 0x8014 Raw interrupt status Register (R/ ) */
__IO uint32_t MIS; /*!< Offset: 0x8018 Masked interrupt status Register (R/ ) */
__IO uint32_t IC; /*!< Offset: 0x801C Interrupt clear Register (R/W) */
} LPC_GPIO_TypeDef;
/*@}*/ /* end of group LPC11xx_GPIO */
/*------------- Timer (TMR) --------------------------------------------------*/
/** @addtogroup LPC11xx_TMR LPC11xx 16/32-bit Counter/Timer
@{
*/
typedef struct
{
__IO uint32_t IR; /*!< Offset: 0x000 Interrupt Register (R/W) */
__IO uint32_t TCR; /*!< Offset: 0x004 Timer Control Register (R/W) */
__IO uint32_t TC; /*!< Offset: 0x008 Timer Counter Register (R/W) */
__IO uint32_t PR; /*!< Offset: 0x00C Prescale Register (R/W) */
__IO uint32_t PC; /*!< Offset: 0x010 Prescale Counter Register (R/W) */
__IO uint32_t MCR; /*!< Offset: 0x014 Match Control Register (R/W) */
__IO uint32_t MR0; /*!< Offset: 0x018 Match Register 0 (R/W) */
__IO uint32_t MR1; /*!< Offset: 0x01C Match Register 1 (R/W) */
__IO uint32_t MR2; /*!< Offset: 0x020 Match Register 2 (R/W) */
__IO uint32_t MR3; /*!< Offset: 0x024 Match Register 3 (R/W) */
__IO uint32_t CCR; /*!< Offset: 0x028 Capture Control Register (R/W) */
__I uint32_t CR0; /*!< Offset: 0x02C Capture Register 0 (R/ ) */
uint32_t RESERVED1[3];
__IO uint32_t EMR; /*!< Offset: 0x03C External Match Register (R/W) */
uint32_t RESERVED2[12];
__IO uint32_t CTCR; /*!< Offset: 0x070 Count Control Register (R/W) */
__IO uint32_t PWMC; /*!< Offset: 0x074 PWM Control Register (R/W) */
} LPC_TMR_TypeDef;
/*@}*/ /* end of group LPC11xx_TMR */
/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
/** @addtogroup LPC11xx_UART LPC11xx Universal Asynchronous Receiver/Transmitter
@{
*/
typedef struct
{
union {
__I uint32_t RBR; /*!< Offset: 0x000 Receiver Buffer Register (R/ ) */
__O uint32_t THR; /*!< Offset: 0x000 Transmit Holding Register ( /W) */
__IO uint32_t DLL; /*!< Offset: 0x000 Divisor Latch LSB (R/W) */
};
union {
__IO uint32_t DLM; /*!< Offset: 0x004 Divisor Latch MSB (R/W) */
__IO uint32_t IER; /*!< Offset: 0x000 Interrupt Enable Register (R/W) */
};
union {
__I uint32_t IIR; /*!< Offset: 0x008 Interrupt ID Register (R/ ) */
__O uint32_t FCR; /*!< Offset: 0x008 FIFO Control Register ( /W) */
};
__IO uint32_t LCR; /*!< Offset: 0x00C Line Control Register (R/W) */
__IO uint32_t MCR; /*!< Offset: 0x010 Modem control Register (R/W) */
__I uint32_t LSR; /*!< Offset: 0x014 Line Status Register (R/ ) */
__I uint32_t MSR; /*!< Offset: 0x018 Modem status Register (R/ ) */
__IO uint32_t SCR; /*!< Offset: 0x01C Scratch Pad Register (R/W) */
__IO uint32_t ACR; /*!< Offset: 0x020 Auto-baud Control Register (R/W) */
uint32_t RESERVED0;
__IO uint32_t FDR; /*!< Offset: 0x028 Fractional Divider Register (R/W) */
uint32_t RESERVED1;
__IO uint32_t TER; /*!< Offset: 0x030 Transmit Enable Register (R/W) */
uint32_t RESERVED2[6];
__IO uint32_t RS485CTRL; /*!< Offset: 0x04C RS-485/EIA-485 Control Register (R/W) */
__IO uint32_t ADRMATCH; /*!< Offset: 0x050 RS-485/EIA-485 address match Register (R/W) */
__IO uint32_t RS485DLY; /*!< Offset: 0x054 RS-485/EIA-485 direction control delay Register (R/W) */
__I uint32_t FIFOLVL; /*!< Offset: 0x058 FIFO Level Register (R/ ) */
} LPC_UART_TypeDef;
/*@}*/ /* end of group LPC11xx_UART */
/*------------- Synchronous Serial Communication (SSP) -----------------------*/
/** @addtogroup LPC11xx_SSP LPC11xx Synchronous Serial Port
@{
*/
typedef struct
{
__IO uint32_t CR0; /*!< Offset: 0x000 Control Register 0 (R/W) */
__IO uint32_t CR1; /*!< Offset: 0x004 Control Register 1 (R/W) */
__IO uint32_t DR; /*!< Offset: 0x008 Data Register (R/W) */
__I uint32_t SR; /*!< Offset: 0x00C Status Registe (R/ ) */
__IO uint32_t CPSR; /*!< Offset: 0x010 Clock Prescale Register (R/W) */
__IO uint32_t IMSC; /*!< Offset: 0x014 Interrupt Mask Set and Clear Register (R/W) */
__IO uint32_t RIS; /*!< Offset: 0x018 Raw Interrupt Status Register (R/W) */
__IO uint32_t MIS; /*!< Offset: 0x01C Masked Interrupt Status Register (R/W) */
__IO uint32_t ICR; /*!< Offset: 0x020 SSPICR Interrupt Clear Register (R/W) */
} LPC_SSP_TypeDef;
/*@}*/ /* end of group LPC11xx_SSP */
/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
/** @addtogroup LPC11xx_I2C LPC11xx I2C-Bus Interface
@{
*/
typedef struct
{
__IO uint32_t CONSET; /*!< Offset: 0x000 I2C Control Set Register (R/W) */
__I uint32_t STAT; /*!< Offset: 0x004 I2C Status Register (R/ ) */
__IO uint32_t DAT; /*!< Offset: 0x008 I2C Data Register (R/W) */
__IO uint32_t ADR0; /*!< Offset: 0x00C I2C Slave Address Register 0 (R/W) */
__IO uint32_t SCLH; /*!< Offset: 0x010 SCH Duty Cycle Register High Half Word (R/W) */
__IO uint32_t SCLL; /*!< Offset: 0x014 SCL Duty Cycle Register Low Half Word (R/W) */
__O uint32_t CONCLR; /*!< Offset: 0x018 I2C Control Clear Register ( /W) */
__IO uint32_t MMCTRL; /*!< Offset: 0x01C Monitor mode control register (R/W) */
__IO uint32_t ADR1; /*!< Offset: 0x020 I2C Slave Address Register 1 (R/W) */
__IO uint32_t ADR2; /*!< Offset: 0x024 I2C Slave Address Register 2 (R/W) */
__IO uint32_t ADR3; /*!< Offset: 0x028 I2C Slave Address Register 3 (R/W) */
__I uint32_t DATA_BUFFER; /*!< Offset: 0x02C Data buffer register ( /W) */
__IO uint32_t MASK0; /*!< Offset: 0x030 I2C Slave address mask register 0 (R/W) */
__IO uint32_t MASK1; /*!< Offset: 0x034 I2C Slave address mask register 1 (R/W) */
__IO uint32_t MASK2; /*!< Offset: 0x038 I2C Slave address mask register 2 (R/W) */
__IO uint32_t MASK3; /*!< Offset: 0x03C I2C Slave address mask register 3 (R/W) */
} LPC_I2C_TypeDef;
/*@}*/ /* end of group LPC11xx_I2C */
/*------------- Watchdog Timer (WDT) -----------------------------------------*/
/** @addtogroup LPC11xx_WDT LPC11xx WatchDog Timer
@{
*/
typedef struct
{
__IO uint32_t MOD; /*!< Offset: 0x000 Watchdog mode register (R/W) */
__IO uint32_t TC; /*!< Offset: 0x004 Watchdog timer constant register (R/W) */
__O uint32_t FEED; /*!< Offset: 0x008 Watchdog feed sequence register ( /W) */
__I uint32_t TV; /*!< Offset: 0x00C Watchdog timer value register (R/ ) */
} LPC_WDT_TypeDef;
/*@}*/ /* end of group LPC11xx_WDT */
/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
/** @addtogroup LPC11xx_ADC LPC11xx Analog-to-Digital Converter
@{
*/
typedef struct
{
__IO uint32_t CR; /*!< Offset: 0x000 A/D Control Register (R/W) */
__IO uint32_t GDR; /*!< Offset: 0x004 A/D Global Data Register (R/W) */
uint32_t RESERVED0;
__IO uint32_t INTEN; /*!< Offset: 0x00C A/D Interrupt Enable Register (R/W) */
__IO uint32_t DR[8]; /*!< Offset: 0x010-0x02C A/D Channel 0..7 Data Register (R/W) */
__I uint32_t STAT; /*!< Offset: 0x030 A/D Status Register (R/ ) */
} LPC_ADC_TypeDef;
/*@}*/ /* end of group LPC11xx_ADC */
#if defined ( __CC_ARM )
#pragma no_anon_unions
#endif
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000)
#define LPC_WDT_BASE (LPC_APB0_BASE + 0x04000)
#define LPC_UART_BASE (LPC_APB0_BASE + 0x08000)
#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000)
#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000)
#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000)
#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000)
#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000)
#define LPC_PMU_BASE (LPC_APB0_BASE + 0x38000)
#define LPC_SSP0_BASE (LPC_APB0_BASE + 0x40000)
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
#define LPC_SSP1_BASE (LPC_APB0_BASE + 0x58000)
/* AHB peripherals */
#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000)
#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000)
#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE )
#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE )
#define LPC_UART ((LPC_UART_TypeDef *) LPC_UART_BASE )
#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE)
#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE)
#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE)
#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE)
#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )
#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE )
#define LPC_SSP0 ((LPC_SSP_TypeDef *) LPC_SSP0_BASE )
#define LPC_SSP1 ((LPC_SSP_TypeDef *) LPC_SSP1_BASE )
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
#ifdef __cplusplus
}
#endif
#endif /* __LPC11xx_H__ */

View File

@@ -0,0 +1,139 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC11xx/hal_lld.c
* @brief LPC11xx HAL subsystem low level driver source.
*
* @addtogroup LPC11xx_HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/**
* @brief Register missing in NXP header file.
*/
#define FLASHCFG (*((volatile uint32_t *)0x4003C010))
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
*/
const PALConfig pal_default_config = {
{VAL_GPIO0DATA, VAL_GPIO0DIR},
{VAL_GPIO1DATA, VAL_GPIO1DIR},
{VAL_GPIO2DATA, VAL_GPIO2DIR},
{VAL_GPIO3DATA, VAL_GPIO3DIR},
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
/* SysTick initialization using the system clock.*/
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, CORTEX_PRIORITY_SYSTICK);
SysTick->LOAD = LPC11xx_SYSCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
}
/**
* @brief LPC11xx clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
*/
void lpc111x_clock_init(void) {
unsigned i;
/* Flash wait states setting, the code takes care to not touch TBD bits.*/
FLASHCFG = (FLASHCFG & ~3) | LPC11xx_FLASHCFG_FLASHTIM;
/* System oscillator initialization if required.*/
#if LPC11xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
#if LPC11xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC
LPC_SYSCON->SYSOSCCTRL = LPC11xx_SYSOSCCTRL;
LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* System oscillator ON. */
for (i = 0; i < 200; i++)
__NOP(); /* Stabilization delay. */
#endif /* LPC11xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC */
/* PLL initialization if required.*/
LPC_SYSCON->SYSPLLCLKSEL = LPC11xx_PLLCLK_SOURCE;
LPC_SYSCON->SYSPLLCLKUEN = 1; /* Really required? */
LPC_SYSCON->SYSPLLCLKUEN = 0;
LPC_SYSCON->SYSPLLCLKUEN = 1;
LPC_SYSCON->SYSPLLCTRL = LPC11xx_SYSPLLCTRL_MSEL | LPC11xx_SYSPLLCTRL_PSEL;
LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* System PLL ON. */
while ((LPC_SYSCON->SYSPLLSTAT & 1) == 0) /* Wait PLL lock. */
;
#endif /* LPC11xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT */
/* Main clock source selection.*/
LPC_SYSCON->MAINCLKSEL = LPC11xx_MAINCLK_SOURCE;
LPC_SYSCON->MAINCLKUEN = 1; /* Really required? */
LPC_SYSCON->MAINCLKUEN = 0;
LPC_SYSCON->MAINCLKUEN = 1;
while ((LPC_SYSCON->MAINCLKUEN & 1) == 0) /* Wait switch completion. */
;
/* ABH divider initialization, peripheral clocks are initially disabled,
the various device drivers will handle their own setup except GPIO and
IOCON that are left enabled.*/
LPC_SYSCON->SYSAHBCLKDIV = LPC11xx_SYSABHCLK_DIV;
LPC_SYSCON->SYSAHBCLKCTRL = 0x0001005F;
/* Peripheral clock dividers initialization.*/
LPC_SYSCON->UARTCLKDIV = LPC11xx_UART_PCLK_DIV;
/* Memory remapping, vectors always in ROM.*/
LPC_SYSCON->SYSMEMREMAP = 2;
}
/** @} */

View File

@@ -0,0 +1,237 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC11xx/hal_lld.h
* @brief HAL subsystem low level driver header template.
*
* @addtogroup LPC11xx_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "LPC11xx.h"
#include "nvic.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "LPC11xx"
#define IRCOSCCLK 12000000 /**< High speed internal clock. */
#define WDGOSCCLK 1600000 /**< Watchdog internal clock. */
#define SYSPLLCLKSEL_IRCOSC 0 /**< Internal RC oscillator
clock source. */
#define SYSPLLCLKSEL_SYSOSC 1 /**< System oscillator clock
source. */
#define SYSMAINCLKSEL_IRCOSC 0 /**< Clock source is IRC. */
#define SYSMAINCLKSEL_PLLIN 1 /**< Clock source is PLLIN. */
#define SYSMAINCLKSEL_WDGOSC 2 /**< Clock source is WDGOSC. */
#define SYSMAINCLKSEL_PLLOUT 3 /**< Clock source is PLLOUT. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief System PLL clock source.
*/
#if !defined(LPC11xx_PLLCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC11xx_PLLCLK_SOURCE SYSPLLCLKSEL_SYSOSC
#endif
/**
* @brief System PLL multiplier.
* @note The value must be in the 1..32 range and the final frequency
* must not exceed the CCO ratings.
*/
#if !defined(LPC11xx_SYSPLL_MUL) || defined(__DOXYGEN__)
#define LPC11xx_SYSPLL_MUL 4
#endif
/**
* @brief System PLL divider.
* @note The value must be chosen between (2, 4, 8, 16).
*/
#if !defined(LPC11xx_SYSPLL_DIV) || defined(__DOXYGEN__)
#define LPC11xx_SYSPLL_DIV 4
#endif
/**
* @brief System main clock source.
*/
#if !defined(LPC11xx_MAINCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC11xx_MAINCLK_SOURCE SYSMAINCLKSEL_PLLOUT
#endif
/**
* @brief AHB clock divider.
* @note The value must be chosen between (1...255).
*/
#if !defined(LPC11xx_SYSCLK_DIV) || defined(__DOXYGEN__)
#define LPC11xx_SYSABHCLK_DIV 1
#endif
/**
* @brief UART clock divider.
* @note The value must be chosen between (1...255).
*/
#if !defined(LPC11xx_UART_PCLK_DIV) || defined(__DOXYGEN__)
#define LPC11xx_UART_PCLK_DIV 1
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/**
* @brief Calculated SYSOSCCTRL setting.
*/
#if (SYSOSCCLK < 18000000) || defined(__DOXYGEN__)
#define LPC11xx_SYSOSCCTRL 0
#else
#define LPC11xx_SYSOSCCTRL 1
#endif
/**
* @brief PLL input clock frequency.
*/
#if (LPC11xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC) || defined(__DOXYGEN__)
#define LPC11xx_SYSPLLCLKIN SYSOSCCLK
#elif LPC11xx_PLLCLK_SOURCE == SYSPLLCLKSEL_IRCOCS
#define LPC11xx_SYSPLLCLKIN IRCOSCCLK
#else
#error "invalid LPC11xx_PLLCLK_SOURCE clock source specified"
#endif
/**
* @brief MSEL mask in SYSPLLCTRL register.
*/
#if (LPC11xx_SYSPLL_MUL >= 1) && (LPC11xx_SYSPLL_MUL <= 32) || \
defined(__DOXYGEN__)
#define LPC11xx_SYSPLLCTRL_MSEL (LPC11xx_SYSPLL_MUL - 1)
#else
#error "LPC11xx_SYSPLL_MUL out of range (1...32)"
#endif
/**
* @brief PSEL mask in SYSPLLCTRL register.
*/
#if (LPC11xx_SYSPLL_DIV == 2) || defined(__DOXYGEN__)
#define LPC11xx_SYSPLLCTRL_PSEL (0 << 5)
#elif LPC11xx_SYSPLL_DIV == 4
#define LPC11xx_SYSPLLCTRL_PSEL (1 << 5)
#elif LPC11xx_SYSPLL_DIV == 8
#define LPC11xx_SYSPLLCTRL_PSEL (2 << 5)
#elif LPC11xx_SYSPLL_DIV == 16
#define LPC11xx_SYSPLLCTRL_PSEL (3 << 5)
#else
#error "invalid LPC11xx_SYSPLL_DIV value (2,4,8,16)"
#endif
/**
* @brief CCP frequency.
*/
#define LPC11xx_SYSPLLCCO (LPC11xx_SYSPLLCLKIN * LPC11xx_SYSPLL_MUL * \
LPC11xx_SYSPLL_DIV)
#if (LPC11xx_SYSPLLCCO < 156000000) || (LPC11xx_SYSPLLCCO > 320000000)
#error "CCO frequency out of the acceptable range (156...320)"
#endif
/**
* @brief PLL output clock frequency.
*/
#define LPC11xx_SYSPLLCLKOUT (LPC11xx_SYSPLLCCO / LPC11xx_SYSPLL_DIV)
#if (LPC11xx_MAINCLK_SOURCE == SYSMAINCLKSEL_IRCOCS) || defined(__DOXYGEN__)
#define LPC11xx_MAINCLK IRCOSCCLK
#elif LPC11xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLIN
#define LPC11xx_MAINCLK LPC11xx_SYSPLLCLKIN
#elif LPC11xx_MAINCLK_SOURCE == SYSMAINCLKSEL_WDGOSC
#define LPC11xx_MAINCLK WDGOSCCLK
#elif LPC11xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
#define LPC11xx_MAINCLK LPC11xx_SYSPLLCLKOUT
#else
#error "invalid LPC11xx_MAINCLK_SOURCE clock source specified"
#endif
/**
* @brief AHB clock.
*/
#define LPC11xx_SYSCLK (LPC11xx_MAINCLK / LPC11xx_SYSABHCLK_DIV)
#if LPC11xx_SYSCLK > 50000000
#error "AHB clock frequency out of the acceptable range (50MHz max)"
#endif
/**
* @brief Flash wait states.
*/
#if (LPC11xx_SYSCLK <= 20000000) || defined(__DOXYGEN__)
#define LPC11xx_FLASHCFG_FLASHTIM 0
#elif LPC11xx_SYSCLK <= 40000000
#define LPC11xx_FLASHCFG_FLASHTIM 1
#else
#define LPC11xx_FLASHCFG_FLASHTIM 2
#endif
/**
* @brief UART clock.
*/
#define LPC11xx_UART_PCLK (LPC11xx_MAINCLK / LPC11xx_UART_PCLK_DIV)
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void lpc111x_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,112 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC11xx/pal_lld.c
* @brief LPC11xx GPIO low level driver code.
*
* @addtogroup LPC11xx_PAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief LPC11xx I/O ports configuration.
* @details GPIO unit registers initialization.
*
* @param[in] config the LPC11xx ports configuration
*/
void _pal_lld_init(const PALConfig *config) {
LPC_GPIO0->DIR = config->P0.dir;
LPC_GPIO1->DIR = config->P1.dir;
LPC_GPIO2->DIR = config->P2.dir;
LPC_GPIO3->DIR = config->P3.dir;
LPC_GPIO0->DATA = config->P0.data;
LPC_GPIO1->DATA = config->P1.data;
LPC_GPIO2->DATA = config->P2.data;
LPC_GPIO3->DATA = config->P3.data;
}
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @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.
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode) {
switch (mode & PAL_MODE_MASK) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT:
port->DIR &= ~mask;
break;
case PAL_MODE_UNCONNECTED:
palSetPort(port, PAL_WHOLE_PORT);
case PAL_MODE_OUTPUT_PUSHPULL:
port->DIR |= mask;
break;
}
}
#endif /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,316 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC11xx/pal_lld.h
* @brief LPC11xx GPIO low level driver header.
*
* @addtogroup LPC11xx_PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
#undef PAL_MODE_INPUT_PULLUP
#undef PAL_MODE_INPUT_PULLDOWN
#undef PAL_MODE_INPUT_ANALOG
#undef PAL_MODE_OUTPUT_OPENDRAIN
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @brief GPIO port setup info.
*/
typedef struct {
/** Initial value for FIO_PIN register.*/
uint32_t data;
/** Initial value for FIO_DIR register.*/
uint32_t dir;
} lpc111x_gpio_setup_t;
/**
* @brief GPIO static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized the digital I/O
* subsystem. This represents only the initial setup, specific pads
* or whole ports can be reprogrammed at later time.
* @note The @p IOCON block is not configured, initially all pins have
* enabled pullups and are programmed as GPIO. It is responsibility
* of the various drivers to reprogram the pins in the proper mode.
* Pins that are not handled by any driver may be programmed in
* @p board.c.
*/
typedef struct {
/** @brief GPIO 0 setup data.*/
lpc111x_gpio_setup_t P0;
/** @brief GPIO 1 setup data.*/
lpc111x_gpio_setup_t P1;
/** @brief GPIO 2 setup data.*/
lpc111x_gpio_setup_t P2;
/** @brief GPIO 3 setup data.*/
lpc111x_gpio_setup_t P3;
} PALConfig;
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32
/**
* @brief Whole port mask.
* @brief This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFF)
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Port Identifier.
*/
typedef LPC_GPIO_TypeDef *ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief GPIO0 port identifier.
*/
#define IOPORT1 LPC_GPIO0
#define GPIO0 LPC_GPIO0
/**
* @brief GPIO1 port identifier.
*/
#define IOPORT2 LPC_GPIO1
#define GPIO1 LPC_GPIO1
/**
* @brief GPIO2 port identifier.
*/
#define IOPORT3 LPC_GPIO2
#define GPIO2 LPC_GPIO2
/**
* @brief GPIO3 port identifier.
*/
#define IOPORT4 LPC_GPIO3
#define GPIO3 LPC_GPIO3
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @param[in] config architecture-dependent ports configuration
*/
#define pal_lld_init(config) _pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @return The port bits.
*/
#define pal_lld_readport(port) ((port)->DATA)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @return The latched logical states.
*/
#define pal_lld_readlatch(port) ((port)->DATA)
/**
* @brief Writes a bits mask on a I/O port.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*/
#define pal_lld_writeport(port, bits) ((port)->DATA = (bits))
/**
* @brief Sets a bits mask on a I/O port.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*/
#define pal_lld_setport(port, bits) ((port)->MASKED_ACCESS[bits] = 0xFFFFFFFF)
/**
* @brief Clears a bits mask on a I/O port.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*/
#define pal_lld_clearport(port, bits) ((port)->MASKED_ACCESS[bits] = 0)
/**
* @brief Reads a group of bits.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @return The group logical states.
*/
#define pal_lld_readgroup(port, mask, offset) \
((port)->MASKED_ACCESS[(mask) << (offset)])
/**
* @brief Writes a group of bits.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] bits bits to be written. Values exceeding the group width
* are masked.
*/
#define pal_lld_writegroup(port, mask, offset, bits) \
((port)->MASKED_ACCESS[(mask) << (offset)] = (bits))
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note This function is not meant to be invoked directly by the
* application code.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] mode group mode
*/
#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
/**
* @brief Writes a logical state on an output pad.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @param[out] bit logical value, the value must be @p PAL_LOW or
* @p PAL_HIGH
*/
#define pal_lld_writepad(port, pad, bit) \
((port)->MASKED_ACCESS[(mask) << (pad)] = (bit) << (pad))
/**
* @brief Sets a pad logical state to @p PAL_HIGH.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*/
#define pal_lld_setpad(port, pad) \
((port)->MASKED_ACCESS[1 << (pad)] = 1 << (pad))
/**
* @brief Clears a pad logical state to @p PAL_LOW.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*/
#define pal_lld_clearpad(port, pad) \
((port)->MASKED_ACCESS[1 << (pad)] = 0)
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_init(const PALConfig *config);
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_PAL */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,82 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup LPC11xx LPC11xx Support
* @brief LPC11xx specific support.
* @details The LPC11xx support includes:
* - I/O ports driver.
* - Buffered, interrupt driven, serial driver.
* - A demo supporting the kernel test suite.
* .
* @ingroup ARMCMx
*/
/**
* @defgroup LPC11xx_HAL LPC11xx HAL Support
* @brief HAL support.
*
* @ingroup LPC11xx
*/
/**
* @defgroup LPC11xx_PAL LPC11xx I/O Ports Support
* @brief I/O Ports peripherals support.
* @details This module supports the LPC11xx GPIO controller. The controller
* supports the following features (see @ref PAL):
* - 12 bits wide ports.
* - Atomic set/reset functions.
* - Atomic set+reset function (atomic bus operations).
* - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
* <h2>Supported Setup Modes</h2>
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* .
* Any attempt to setup an invalid mode is ignored.
*
* <h2>Suboptimal Behavior</h2>
* Some GPIO features are less than optimal:
* - Pad/port toggling operations are not atomic.
* - Pull-up and Pull-down resistors cannot be programmed through the PAL
* driver and must be programmed separately.
* - Reading of the output latch for pads programmed as input is not possible,
* the input pin value is returned instead.
* .
* @ingroup LPC11xx
*/
/**
* @defgroup LPC11xx_SERIAL LPC11xx UART Support
* @brief UART peripherals support.
* @details The serial driver supports the LPC11xx UART taking advantage of
* its deep hardware buffers.
*
* @ingroup LPC11xx
*/

View File

@@ -0,0 +1,7 @@
# List of all the LPC11xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC11xx/hal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC11xx/serial_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/LPC11xx

View File

@@ -0,0 +1,297 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC11xx/serial_lld.c
* @brief LPC11xx low level serial driver code.
*
* @addtogroup LPC11xx_SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if USE_LPC11xx_UART0 || defined(__DOXYGEN__)
/** @brief UART0 serial driver identifier.*/
SerialDriver SD1;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/** @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) {
LPC_UART_TypeDef *u = sdp->uart;
uint32_t div = LPC11xx_UART_PCLK / (config->sc_speed << 4);
u->LCR = config->sc_lcr | LCR_DLAB;
u->DLL = div;
u->DLM = div >> 8;
u->LCR = config->sc_lcr;
u->FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | config->sc_fcr;
u->ACR = 0;
u->FDR = 0x10;
u->TER = TER_ENABLE;
u->IER = IER_RBR | IER_STATUS;
}
/**
* @brief UART de-initialization.
*
* @param[in] u pointer to an UART I/O block
*/
static void uart_deinit(LPC_UART_TypeDef *u) {
u->LCR = LCR_DLAB;
u->DLL = 1;
u->DLM = 0;
u->LCR = 0;
u->FDR = 0x10;
u->IER = 0;
u->FCR = FCR_RXRESET | FCR_TXRESET;
u->ACR = 0;
u->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) {
sdflags_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();
sdAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
/**
* @brief Common IRQ handler.
* @note Tries hard to clear all the pending interrupt sources, we don't
* want to go through the whole ISR and have another interrupt soon
* after.
*
* @param[in] u pointer to an UART I/O block
* @param[in] sdp communication channel associated to the UART
*/
static void serve_interrupt(SerialDriver *sdp) {
LPC_UART_TypeDef *u = sdp->uart;
while (TRUE) {
switch (u->IIR & IIR_SRC_MASK) {
case IIR_SRC_NONE:
return;
case IIR_SRC_ERROR:
set_error(sdp, u->LSR);
break;
case IIR_SRC_TIMEOUT:
case IIR_SRC_RX:
chSysLockFromIsr();
if (chIQIsEmpty(&sdp->iqueue))
chEvtBroadcastI(&sdp->ievent);
chSysUnlockFromIsr();
while (u->LSR & LSR_RBR_FULL) {
chSysLockFromIsr();
if (chIQPutI(&sdp->iqueue, u->RBR) < Q_OK)
sdAddFlagsI(sdp, SD_OVERRUN_ERROR);
chSysUnlockFromIsr();
}
break;
case IIR_SRC_TX:
{
int i = LPC11xx_UART_FIFO_PRELOAD;
do {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->oqueue);
chSysUnlockFromIsr();
if (b < Q_OK) {
u->IER &= ~IER_THRE;
chSysLockFromIsr();
chEvtBroadcastI(&sdp->oevent);
chSysUnlockFromIsr();
break;
}
u->THR = b;
} while (--i);
}
break;
default:
(void) u->THR;
(void) u->RBR;
}
}
}
/**
* @brief Attempts a TX FIFO preload.
*/
static void preload(SerialDriver *sdp) {
LPC_UART_TypeDef *u = sdp->uart;
if (u->LSR & LSR_THRE) {
int i = LPC11xx_UART_FIFO_PRELOAD;
do {
msg_t b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chEvtBroadcastI(&sdp->oevent);
return;
}
u->THR = b;
} while (--i);
}
u->IER |= IER_THRE;
}
/**
* @brief Driver SD1 output notification.
*/
#if USE_LPC11xx_UART0 || defined(__DOXYGEN__)
static void notify1(void) {
preload(&SD1);
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief UART0 IRQ handler.
*/
#if USE_LPC11xx_UART0 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(Vector94) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD1);
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_LPC11xx_UART0
sdObjectInit(&SD1, NULL, notify1);
SD1.uart = LPC_UART;
LPC_IOCON->PIO1_6 = 0xC1; /* RDX without resistors. */
LPC_IOCON->PIO1_7 = 0xC1; /* TDX without resistors. */
#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.
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
if (sdp->state == SD_STOP) {
#if USE_LPC11xx_UART0
if (&SD1 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12);
NVICEnableVector(UART_IRQn,
CORTEX_PRIORITY_MASK(LPC11xx_UART0_PRIORITY));
}
#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
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->state == SD_READY) {
uart_deinit(sdp->uart);
#if USE_LPC11xx_UART0
if (&SD1 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 12);
NVICDisableVector(UART_IRQn);
return;
}
#endif
}
}
#endif /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,208 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC11xx/serial_lld.h
* @brief LPC11xx low level serial driver header.
*
* @addtogroup LPC11xx_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define IIR_SRC_MASK 0x0F
#define IIR_SRC_NONE 0x01
#define IIR_SRC_MODEM 0x00
#define IIR_SRC_TX 0x02
#define IIR_SRC_RX 0x04
#define IIR_SRC_ERROR 0x06
#define IIR_SRC_TIMEOUT 0x0C
#define IER_RBR 1
#define IER_THRE 2
#define IER_STATUS 4
#define LCR_WL5 0
#define LCR_WL6 1
#define LCR_WL7 2
#define LCR_WL8 3
#define LCR_STOP1 0
#define LCR_STOP2 4
#define LCR_NOPARITY 0
#define LCR_PARITYODD 0x08
#define LCR_PARITYEVEN 0x18
#define LCR_PARITYONE 0x28
#define LCR_PARITYZERO 0x38
#define LCR_BREAK_ON 0x40
#define LCR_DLAB 0x80
#define FCR_ENABLE 1
#define FCR_RXRESET 2
#define FCR_TXRESET 4
#define FCR_TRIGGER0 0
#define FCR_TRIGGER1 0x40
#define FCR_TRIGGER2 0x80
#define FCR_TRIGGER3 0xC0
#define LSR_RBR_FULL 1
#define LSR_OVERRUN 2
#define LSR_PARITY 4
#define LSR_FRAMING 8
#define LSR_BREAK 0x10
#define LSR_THRE 0x20
#define LSR_TEMT 0x40
#define LSR_RXFE 0x80
#define TER_ENABLE 0x80
/*===========================================================================*/
/* 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_LPC11xx_UART0) || defined(__DOXYGEN__)
#define USE_LPC11xx_UART0 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(LPC11xx_UART_FIFO_PRELOAD) || defined(__DOXYGEN__)
#define LPC11xx_UART_FIFO_PRELOAD 16
#endif
/**
* @brief UART0 interrupt priority level setting.
*/
#if !defined(LPC11xx_UART0_PRIORITY) || defined(__DOXYGEN__)
#define LPC11xx_UART0_PRIORITY 3
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (LPC11xx_UART_FIFO_PRELOAD < 1) || (LPC11xx_UART_FIFO_PRELOAD > 16)
#error "invalid LPC11xx_UART_FIFO_PRELOAD setting"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Serial Driver condition flags type.
*/
typedef uint32_t sdflags_t;
/**
* @brief LPC11xx 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.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* 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.*/ \
LPC_UART_TypeDef *uart;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_LPC11xx_UART0 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#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 /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,64 @@
/**************************************************************************//**
* @file system_LPC11xx.h
* @brief CMSIS Cortex-M0 Device Peripheral Access Layer Header File
* for the NXP LPC11xx Device Series
* @version V1.00
* @date 17. November 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC11xx_H
#define __SYSTEM_LPC11xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC11x_H */

View File

@@ -0,0 +1,493 @@
/**************************************************************************//**
* @file LPC13xx.h
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File for
* NXP LPC13xx Device Series
* @version V1.01
* @date 19. October 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __LPC13xx_H__
#define __LPC13xx_H__
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Non Maskable Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** LPC13xx Specific Interrupt Numbers *******************************************************/
WAKEUP0_IRQn = 0, /*!< All I/O pins can be used as wakeup source. */
WAKEUP1_IRQn = 1, /*!< There are 40 pins in total for LPC17xx */
WAKEUP2_IRQn = 2,
WAKEUP3_IRQn = 3,
WAKEUP4_IRQn = 4,
WAKEUP5_IRQn = 5,
WAKEUP6_IRQn = 6,
WAKEUP7_IRQn = 7,
WAKEUP8_IRQn = 8,
WAKEUP9_IRQn = 9,
WAKEUP10_IRQn = 10,
WAKEUP11_IRQn = 11,
WAKEUP12_IRQn = 12,
WAKEUP13_IRQn = 13,
WAKEUP14_IRQn = 14,
WAKEUP15_IRQn = 15,
WAKEUP16_IRQn = 16,
WAKEUP17_IRQn = 17,
WAKEUP18_IRQn = 18,
WAKEUP19_IRQn = 19,
WAKEUP20_IRQn = 20,
WAKEUP21_IRQn = 21,
WAKEUP22_IRQn = 22,
WAKEUP23_IRQn = 23,
WAKEUP24_IRQn = 24,
WAKEUP25_IRQn = 25,
WAKEUP26_IRQn = 26,
WAKEUP27_IRQn = 27,
WAKEUP28_IRQn = 28,
WAKEUP29_IRQn = 29,
WAKEUP30_IRQn = 30,
WAKEUP31_IRQn = 31,
WAKEUP32_IRQn = 32,
WAKEUP33_IRQn = 33,
WAKEUP34_IRQn = 34,
WAKEUP35_IRQn = 35,
WAKEUP36_IRQn = 36,
WAKEUP37_IRQn = 37,
WAKEUP38_IRQn = 38,
WAKEUP39_IRQn = 39,
I2C_IRQn = 40, /*!< I2C Interrupt */
TIMER_16_0_IRQn = 41, /*!< 16-bit Timer0 Interrupt */
TIMER_16_1_IRQn = 42, /*!< 16-bit Timer1 Interrupt */
TIMER_32_0_IRQn = 43, /*!< 32-bit Timer0 Interrupt */
TIMER_32_1_IRQn = 44, /*!< 32-bit Timer1 Interrupt */
SSP_IRQn = 45, /*!< SSP Interrupt */
UART_IRQn = 46, /*!< UART Interrupt */
USB_IRQn = 47, /*!< USB Regular Interrupt */
USB_FIQn = 48, /*!< USB Fast Interrupt */
ADC_IRQn = 49, /*!< A/D Converter Interrupt */
WDT_IRQn = 50, /*!< Watchdog timer Interrupt */
BOD_IRQn = 51, /*!< Brown Out Detect(BOD) Interrupt */
EINT3_IRQn = 53, /*!< External Interrupt 3 Interrupt */
EINT2_IRQn = 54, /*!< External Interrupt 2 Interrupt */
EINT1_IRQn = 55, /*!< External Interrupt 1 Interrupt */
EINT0_IRQn = 56, /*!< External Interrupt 0 Interrupt */
} IRQn_Type;
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
/* Configuration of the Cortex-M3 Processor and Core Peripherals */
#define __MPU_PRESENT 1 /*!< MPU present or not */
#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
#include "system_LPC13xx.h" /* System Header */
/******************************************************************************/
/* Device Specific Peripheral registers structures */
/******************************************************************************/
#if defined ( __CC_ARM )
#pragma anon_unions
#endif
/*------------- System Control (SYSCON) --------------------------------------*/
typedef struct
{
__IO uint32_t SYSMEMREMAP; /* Sys mem. Remap, Offset 0x0 */
__IO uint32_t PRESETCTRL;
__IO uint32_t SYSPLLCTRL; /* Sys PLL control */
__IO uint32_t SYSPLLSTAT;
__IO uint32_t USBPLLCTRL; /* USB PLL control, offset 0x10 */
__IO uint32_t USBPLLSTAT;
uint32_t RESERVED0[2];
__IO uint32_t SYSOSCCTRL; /* Offset 0x20 */
__IO uint32_t WDTOSCCTRL;
__IO uint32_t IRCCTRL;
uint32_t RESERVED1[1];
__IO uint32_t SYSRESSTAT; /* Offset 0x30 */
uint32_t RESERVED2[3];
__IO uint32_t SYSPLLCLKSEL; /* Offset 0x40 */
__IO uint32_t SYSPLLCLKUEN;
__IO uint32_t USBPLLCLKSEL;
__IO uint32_t USBPLLCLKUEN;
uint32_t RESERVED3[8];
__IO uint32_t MAINCLKSEL; /* Offset 0x70 */
__IO uint32_t MAINCLKUEN;
__IO uint32_t SYSAHBCLKDIV;
uint32_t RESERVED4[1];
__IO uint32_t SYSAHBCLKCTRL; /* Offset 0x80 */
uint32_t RESERVED5[4];
__IO uint32_t SSPCLKDIV;
__IO uint32_t UARTCLKDIV;
uint32_t RESERVED6[4];
__IO uint32_t TRACECLKDIV;
__IO uint32_t SYSTICKCLKDIV; /* Offset 0xB0 */
uint32_t RESERVED7[3];
__IO uint32_t USBCLKSEL; /* Offset 0xC0 */
__IO uint32_t USBCLKUEN;
__IO uint32_t USBCLKDIV;
uint32_t RESERVED8[1];
__IO uint32_t WDTCLKSEL; /* Offset 0xD0 */
__IO uint32_t WDTCLKUEN;
__IO uint32_t WDTCLKDIV;
uint32_t RESERVED9[1];
__IO uint32_t CLKOUTCLKSEL; /* Offset 0xE0 */
__IO uint32_t CLKOUTUEN;
__IO uint32_t CLKOUTDIV;
uint32_t RESERVED10[5];
__IO uint32_t PIOPORCAP0; /* Offset 0x100 */
__IO uint32_t PIOPORCAP1;
uint32_t RESERVED11[18];
__IO uint32_t BODCTRL; /* Offset 0x150 */
uint32_t RESERVED12[1];
__IO uint32_t SYSTCKCAL;
uint32_t RESERVED13[41];
__IO uint32_t STARTAPRP0; /* Offset 0x200 */
__IO uint32_t STARTERP0;
__IO uint32_t STARTRSRP0CLR;
__IO uint32_t STARTSRP0;
__IO uint32_t STARTAPRP1;
__IO uint32_t STARTERP1;
__IO uint32_t STARTRSRP1CLR;
__IO uint32_t STARTSRP1;
uint32_t RESERVED14[4];
__IO uint32_t PDSLEEPCFG; /* Offset 0x230 */
__IO uint32_t PDAWAKECFG;
__IO uint32_t PDRUNCFG;
uint32_t RESERVED15[110];
__I uint32_t DEVICE_ID;
} LPC_SYSCON_TypeDef;
/*------------- Pin Connect Block (IOCON) --------------------------------*/
typedef struct
{
__IO uint32_t PIO2_6;
uint32_t RESERVED0[1];
__IO uint32_t PIO2_0;
__IO uint32_t RESET_PIO0_0;
__IO uint32_t PIO0_1;
__IO uint32_t PIO1_8;
uint32_t RESERVED1[1];
__IO uint32_t PIO0_2;
__IO uint32_t PIO2_7;
__IO uint32_t PIO2_8;
__IO uint32_t PIO2_1;
__IO uint32_t PIO0_3;
__IO uint32_t PIO0_4;
__IO uint32_t PIO0_5;
__IO uint32_t PIO1_9;
__IO uint32_t PIO3_4;
__IO uint32_t PIO2_4;
__IO uint32_t PIO2_5;
__IO uint32_t PIO3_5;
__IO uint32_t PIO0_6;
__IO uint32_t PIO0_7;
__IO uint32_t PIO2_9;
__IO uint32_t PIO2_10;
__IO uint32_t PIO2_2;
__IO uint32_t PIO0_8;
__IO uint32_t PIO0_9;
__IO uint32_t JTAG_TCK_PIO0_10;
__IO uint32_t PIO1_10;
__IO uint32_t PIO2_11;
__IO uint32_t JTAG_TDI_PIO0_11;
__IO uint32_t JTAG_TMS_PIO1_0;
__IO uint32_t JTAG_TDO_PIO1_1;
__IO uint32_t JTAG_nTRST_PIO1_2;
__IO uint32_t PIO3_0;
__IO uint32_t PIO3_1;
__IO uint32_t PIO2_3;
__IO uint32_t ARM_SWDIO_PIO1_3;
__IO uint32_t PIO1_4;
__IO uint32_t PIO1_11;
__IO uint32_t PIO3_2;
__IO uint32_t PIO1_5;
__IO uint32_t PIO1_6;
__IO uint32_t PIO1_7;
__IO uint32_t PIO3_3;
__IO uint32_t SCKLOC; /* For HB1 only, new feature */
} LPC_IOCON_TypeDef;
/*------------- Power Management Unit (PMU) --------------------------*/
typedef struct
{
__IO uint32_t PCON;
__IO uint32_t GPREG0;
__IO uint32_t GPREG1;
__IO uint32_t GPREG2;
__IO uint32_t GPREG3;
__IO uint32_t GPREG4;
} LPC_PMU_TypeDef;
/*------------- General Purpose Input/Output (GPIO) --------------------------*/
typedef struct
{
union {
__IO uint32_t MASKED_ACCESS[4096];
struct {
uint32_t RESERVED0[4095];
__IO uint32_t DATA;
};
};
uint32_t RESERVED1[4096];
__IO uint32_t DIR;
__IO uint32_t IS;
__IO uint32_t IBE;
__IO uint32_t IEV;
__IO uint32_t IE;
__IO uint32_t RIS;
__IO uint32_t MIS;
__IO uint32_t IC;
} LPC_GPIO_TypeDef;
/*------------- Timer (TMR) --------------------------------------------------*/
typedef struct
{
__IO uint32_t IR;
__IO uint32_t TCR;
__IO uint32_t TC;
__IO uint32_t PR;
__IO uint32_t PC;
__IO uint32_t MCR;
__IO uint32_t MR0;
__IO uint32_t MR1;
__IO uint32_t MR2;
__IO uint32_t MR3;
__IO uint32_t CCR;
__I uint32_t CR0;
uint32_t RESERVED1[3];
__IO uint32_t EMR;
uint32_t RESERVED2[12];
__IO uint32_t CTCR;
__IO uint32_t PWMC;
} LPC_TMR_TypeDef;
/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
typedef struct
{
union {
__I uint32_t RBR;
__O uint32_t THR;
__IO uint32_t DLL;
};
union {
__IO uint32_t DLM;
__IO uint32_t IER;
};
union {
__I uint32_t IIR;
__O uint32_t FCR;
};
__IO uint32_t LCR;
__IO uint32_t MCR;
__I uint32_t LSR;
__I uint32_t MSR;
__IO uint32_t SCR;
__IO uint32_t ACR;
__IO uint32_t ICR;
__IO uint32_t FDR;
uint32_t RESERVED0;
__IO uint32_t TER;
uint32_t RESERVED1[6];
__IO uint32_t RS485CTRL;
__IO uint32_t ADRMATCH;
__IO uint32_t RS485DLY;
__I uint32_t FIFOLVL;
} LPC_UART_TypeDef;
/*------------- Synchronous Serial Communication (SSP) -----------------------*/
typedef struct
{
__IO uint32_t CR0;
__IO uint32_t CR1;
__IO uint32_t DR;
__I uint32_t SR;
__IO uint32_t CPSR;
__IO uint32_t IMSC;
__IO uint32_t RIS;
__IO uint32_t MIS;
__IO uint32_t ICR;
} LPC_SSP_TypeDef;
/*------------- Inter-Integrated Circuit (I2C) -------------------------------*/
typedef struct
{
__IO uint32_t CONSET;
__I uint32_t STAT;
__IO uint32_t DAT;
__IO uint32_t ADR0;
__IO uint32_t SCLH;
__IO uint32_t SCLL;
__O uint32_t CONCLR;
__IO uint32_t MMCTRL;
__IO uint32_t ADR1;
__IO uint32_t ADR2;
__IO uint32_t ADR3;
__I uint32_t DATA_BUFFER;
__IO uint32_t MASK0;
__IO uint32_t MASK1;
__IO uint32_t MASK2;
__IO uint32_t MASK3;
} LPC_I2C_TypeDef;
/*------------- Watchdog Timer (WDT) -----------------------------------------*/
typedef struct
{
__IO uint32_t MOD;
__IO uint32_t TC;
__O uint32_t FEED;
__I uint32_t TV;
} LPC_WDT_TypeDef;
/*------------- Analog-to-Digital Converter (ADC) ----------------------------*/
typedef struct
{
__IO uint32_t CR;
__IO uint32_t GDR;
uint32_t RESERVED0;
__IO uint32_t INTEN;
__I uint32_t DR0;
__I uint32_t DR1;
__I uint32_t DR2;
__I uint32_t DR3;
__I uint32_t DR4;
__I uint32_t DR5;
__I uint32_t DR6;
__I uint32_t DR7;
__I uint32_t STAT;
} LPC_ADC_TypeDef;
/*------------- Universal Serial Bus (USB) -----------------------------------*/
typedef struct
{
__I uint32_t DevIntSt; /* USB Device Interrupt Registers */
__IO uint32_t DevIntEn;
__O uint32_t DevIntClr;
__O uint32_t DevIntSet;
__O uint32_t CmdCode; /* USB Device SIE Command Registers */
__I uint32_t CmdData;
__I uint32_t RxData; /* USB Device Transfer Registers */
__O uint32_t TxData;
__I uint32_t RxPLen;
__O uint32_t TxPLen;
__IO uint32_t Ctrl;
__O uint32_t DevFIQSel;
} LPC_USB_TypeDef;
#if defined ( __CC_ARM )
#pragma no_anon_unions
#endif
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* Base addresses */
#define LPC_FLASH_BASE (0x00000000UL)
#define LPC_RAM_BASE (0x10000000UL)
#define LPC_APB0_BASE (0x40000000UL)
#define LPC_AHB_BASE (0x50000000UL)
/* APB0 peripherals */
#define LPC_I2C_BASE (LPC_APB0_BASE + 0x00000)
#define LPC_WDT_BASE (LPC_APB0_BASE + 0x04000)
#define LPC_UART_BASE (LPC_APB0_BASE + 0x08000)
#define LPC_CT16B0_BASE (LPC_APB0_BASE + 0x0C000)
#define LPC_CT16B1_BASE (LPC_APB0_BASE + 0x10000)
#define LPC_CT32B0_BASE (LPC_APB0_BASE + 0x14000)
#define LPC_CT32B1_BASE (LPC_APB0_BASE + 0x18000)
#define LPC_ADC_BASE (LPC_APB0_BASE + 0x1C000)
#define LPC_USB_BASE (LPC_APB0_BASE + 0x20000)
#define LPC_PMU_BASE (LPC_APB0_BASE + 0x38000)
#define LPC_SSP_BASE (LPC_APB0_BASE + 0x40000)
#define LPC_IOCON_BASE (LPC_APB0_BASE + 0x44000)
#define LPC_SYSCON_BASE (LPC_APB0_BASE + 0x48000)
/* AHB peripherals */
#define LPC_GPIO_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO0_BASE (LPC_AHB_BASE + 0x00000)
#define LPC_GPIO1_BASE (LPC_AHB_BASE + 0x10000)
#define LPC_GPIO2_BASE (LPC_AHB_BASE + 0x20000)
#define LPC_GPIO3_BASE (LPC_AHB_BASE + 0x30000)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define LPC_I2C ((LPC_I2C_TypeDef *) LPC_I2C_BASE )
#define LPC_WDT ((LPC_WDT_TypeDef *) LPC_WDT_BASE )
#define LPC_UART ((LPC_UART_TypeDef *) LPC_UART_BASE )
#define LPC_TMR16B0 ((LPC_TMR_TypeDef *) LPC_CT16B0_BASE)
#define LPC_TMR16B1 ((LPC_TMR_TypeDef *) LPC_CT16B1_BASE)
#define LPC_TMR32B0 ((LPC_TMR_TypeDef *) LPC_CT32B0_BASE)
#define LPC_TMR32B1 ((LPC_TMR_TypeDef *) LPC_CT32B1_BASE)
#define LPC_ADC ((LPC_ADC_TypeDef *) LPC_ADC_BASE )
#define LPC_PMU ((LPC_PMU_TypeDef *) LPC_PMU_BASE )
#define LPC_SSP ((LPC_SSP_TypeDef *) LPC_SSP_BASE )
#define LPC_IOCON ((LPC_IOCON_TypeDef *) LPC_IOCON_BASE )
#define LPC_SYSCON ((LPC_SYSCON_TypeDef *) LPC_SYSCON_BASE)
#define LPC_USB ((LPC_USB_TypeDef *) LPC_USB_BASE )
#define LPC_GPIO0 ((LPC_GPIO_TypeDef *) LPC_GPIO0_BASE )
#define LPC_GPIO1 ((LPC_GPIO_TypeDef *) LPC_GPIO1_BASE )
#define LPC_GPIO2 ((LPC_GPIO_TypeDef *) LPC_GPIO2_BASE )
#define LPC_GPIO3 ((LPC_GPIO_TypeDef *) LPC_GPIO3_BASE )
#endif // __LPC13xx_H__

View File

@@ -0,0 +1,139 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC13xx/hal_lld.c
* @brief LPC13xx HAL subsystem low level driver source.
*
* @addtogroup LPC13xx_HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/**
* @brief Register missing in NXP header file.
*/
#define FLASHCFG (*((volatile uint32_t *)0x4003C010))
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
*/
const PALConfig pal_default_config = {
{VAL_GPIO0DATA, VAL_GPIO0DIR},
{VAL_GPIO1DATA, VAL_GPIO1DIR},
{VAL_GPIO2DATA, VAL_GPIO2DIR},
{VAL_GPIO3DATA, VAL_GPIO3DIR},
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
/* SysTick initialization using the system clock.*/
NVICSetSystemHandlerPriority(HANDLER_SYSTICK, CORTEX_PRIORITY_SYSTICK);
SysTick->LOAD = LPC13xx_SYSCLK / CH_FREQUENCY - 1;
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk |
SysTick_CTRL_TICKINT_Msk;
}
/**
* @brief LPC13xx clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h.
*/
void LPC13xx_clock_init(void) {
unsigned i;
/* Flash wait states setting, the code takes care to not touch TBD bits.*/
FLASHCFG = (FLASHCFG & ~3) | LPC13xx_FLASHCFG_FLASHTIM;
/* System oscillator initialization if required.*/
#if LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
#if LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC
LPC_SYSCON->SYSOSCCTRL = LPC13xx_SYSOSCCTRL;
LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* System oscillator ON. */
for (i = 0; i < 200; i++)
__NOP(); /* Stabilization delay. */
#endif /* LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC */
/* PLL initialization if required.*/
LPC_SYSCON->SYSPLLCLKSEL = LPC13xx_PLLCLK_SOURCE;
LPC_SYSCON->SYSPLLCLKUEN = 1; /* Really required? */
LPC_SYSCON->SYSPLLCLKUEN = 0;
LPC_SYSCON->SYSPLLCLKUEN = 1;
LPC_SYSCON->SYSPLLCTRL = LPC13xx_SYSPLLCTRL_MSEL | LPC13xx_SYSPLLCTRL_PSEL;
LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* System PLL ON. */
while ((LPC_SYSCON->SYSPLLSTAT & 1) == 0) /* Wait PLL lock. */
;
#endif /* LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT */
/* Main clock source selection.*/
LPC_SYSCON->MAINCLKSEL = LPC13xx_MAINCLK_SOURCE;
LPC_SYSCON->MAINCLKUEN = 1; /* Really required? */
LPC_SYSCON->MAINCLKUEN = 0;
LPC_SYSCON->MAINCLKUEN = 1;
while ((LPC_SYSCON->MAINCLKUEN & 1) == 0) /* Wait switch completion. */
;
/* ABH divider initialization, peripheral clocks are initially disabled,
the various device drivers will handle their own setup except GPIO and
IOCON that are left enabled.*/
LPC_SYSCON->SYSAHBCLKDIV = LPC13xx_SYSABHCLK_DIV;
LPC_SYSCON->SYSAHBCLKCTRL = 0x0001005F;
/* Peripheral clock dividers initialization.*/
LPC_SYSCON->UARTCLKDIV = LPC13xx_UART_PCLK_DIV;
/* Memory remapping, vectors always in ROM.*/
LPC_SYSCON->SYSMEMREMAP = 2;
}
/** @} */

View File

@@ -0,0 +1,237 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC13xx/hal_lld.h
* @brief HAL subsystem low level driver header template.
*
* @addtogroup LPC13xx_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "LPC13xx.h"
#include "nvic.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "LPC13xx"
#define IRCOSCCLK 12000000 /**< High speed internal clock. */
#define WDGOSCCLK 1600000 /**< Watchdog internal clock. */
#define SYSPLLCLKSEL_IRCOSC 0 /**< Internal RC oscillator
clock source. */
#define SYSPLLCLKSEL_SYSOSC 1 /**< System oscillator clock
source. */
#define SYSMAINCLKSEL_IRCOSC 0 /**< Clock source is IRC. */
#define SYSMAINCLKSEL_PLLIN 1 /**< Clock source is PLLIN. */
#define SYSMAINCLKSEL_WDGOSC 2 /**< Clock source is WDGOSC. */
#define SYSMAINCLKSEL_PLLOUT 3 /**< Clock source is PLLOUT. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief System PLL clock source.
*/
#if !defined(LPC13xx_PLLCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC13xx_PLLCLK_SOURCE SYSPLLCLKSEL_SYSOSC
#endif
/**
* @brief System PLL multiplier.
* @note The value must be in the 1..32 range and the final frequency
* must not exceed the CCO ratings.
*/
#if !defined(LPC13xx_SYSPLL_MUL) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLL_MUL 6
#endif
/**
* @brief System PLL divider.
* @note The value must be chosen between (2, 4, 8, 16).
*/
#if !defined(LPC13xx_SYSPLL_DIV) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLL_DIV 4
#endif
/**
* @brief System main clock source.
*/
#if !defined(LPC13xx_MAINCLK_SOURCE) || defined(__DOXYGEN__)
#define LPC13xx_MAINCLK_SOURCE SYSMAINCLKSEL_PLLOUT
#endif
/**
* @brief AHB clock divider.
* @note The value must be chosen between (1...255).
*/
#if !defined(LPC13xx_SYSCLK_DIV) || defined(__DOXYGEN__)
#define LPC13xx_SYSABHCLK_DIV 1
#endif
/**
* @brief UART clock divider.
* @note The value must be chosen between (1...255).
*/
#if !defined(LPC13xx_UART_PCLK_DIV) || defined(__DOXYGEN__)
#define LPC13xx_UART_PCLK_DIV 1
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/**
* @brief Calculated SYSOSCCTRL setting.
*/
#if (SYSOSCCLK < 18000000) || defined(__DOXYGEN__)
#define LPC13xx_SYSOSCCTRL 0
#else
#define LPC13xx_SYSOSCCTRL 1
#endif
/**
* @brief PLL input clock frequency.
*/
#if (LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_SYSOSC) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLLCLKIN SYSOSCCLK
#elif LPC13xx_PLLCLK_SOURCE == SYSPLLCLKSEL_IRCOCS
#define LPC13xx_SYSPLLCLKIN IRCOSCCLK
#else
#error "invalid LPC13xx_PLLCLK_SOURCE clock source specified"
#endif
/**
* @brief MSEL mask in SYSPLLCTRL register.
*/
#if (LPC13xx_SYSPLL_MUL >= 1) && (LPC13xx_SYSPLL_MUL <= 32) || \
defined(__DOXYGEN__)
#define LPC13xx_SYSPLLCTRL_MSEL (LPC13xx_SYSPLL_MUL - 1)
#else
#error "LPC13xx_SYSPLL_MUL out of range (1...32)"
#endif
/**
* @brief PSEL mask in SYSPLLCTRL register.
*/
#if (LPC13xx_SYSPLL_DIV == 2) || defined(__DOXYGEN__)
#define LPC13xx_SYSPLLCTRL_PSEL (0 << 5)
#elif LPC13xx_SYSPLL_DIV == 4
#define LPC13xx_SYSPLLCTRL_PSEL (1 << 5)
#elif LPC13xx_SYSPLL_DIV == 8
#define LPC13xx_SYSPLLCTRL_PSEL (2 << 5)
#elif LPC13xx_SYSPLL_DIV == 16
#define LPC13xx_SYSPLLCTRL_PSEL (3 << 5)
#else
#error "invalid LPC13xx_SYSPLL_DIV value (2,4,8,16)"
#endif
/**
* @brief CCP frequency.
*/
#define LPC13xx_SYSPLLCCO (LPC13xx_SYSPLLCLKIN * LPC13xx_SYSPLL_MUL * \
LPC13xx_SYSPLL_DIV)
#if (LPC13xx_SYSPLLCCO < 156000000) || (LPC13xx_SYSPLLCCO > 320000000)
#error "CCO frequency out of the acceptable range (156...320)"
#endif
/**
* @brief PLL output clock frequency.
*/
#define LPC13xx_SYSPLLCLKOUT (LPC13xx_SYSPLLCCO / LPC13xx_SYSPLL_DIV)
#if (LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_IRCOCS) || defined(__DOXYGEN__)
#define LPC13xx_MAINCLK IRCOSCCLK
#elif LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLIN
#define LPC13xx_MAINCLK LPC13xx_SYSPLLCLKIN
#elif LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_WDGOSC
#define LPC13xx_MAINCLK WDGOSCCLK
#elif LPC13xx_MAINCLK_SOURCE == SYSMAINCLKSEL_PLLOUT
#define LPC13xx_MAINCLK LPC13xx_SYSPLLCLKOUT
#else
#error "invalid LPC13xx_MAINCLK_SOURCE clock source specified"
#endif
/**
* @brief AHB clock.
*/
#define LPC13xx_SYSCLK (LPC13xx_MAINCLK / LPC13xx_SYSABHCLK_DIV)
#if LPC13xx_SYSCLK > 72000000
#error "AHB clock frequency out of the acceptable range (72MHz max)"
#endif
/**
* @brief Flash wait states.
*/
#if (LPC13xx_SYSCLK <= 20000000) || defined(__DOXYGEN__)
#define LPC13xx_FLASHCFG_FLASHTIM 0
#elif LPC13xx_SYSCLK <= 40000000
#define LPC13xx_FLASHCFG_FLASHTIM 1
#else
#define LPC13xx_FLASHCFG_FLASHTIM 2
#endif
/**
* @brief UART clock.
*/
#define LPC13xx_UART_PCLK (LPC13xx_MAINCLK / LPC13xx_UART_PCLK_DIV)
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void LPC13xx_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,112 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC13xx/pal_lld.c
* @brief LPC13xx GPIO low level driver code.
*
* @addtogroup LPC13xx_PAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief LPC13xx I/O ports configuration.
* @details GPIO unit registers initialization.
*
* @param[in] config the LPC13xx ports configuration
*/
void _pal_lld_init(const PALConfig *config) {
LPC_GPIO0->DIR = config->P0.dir;
LPC_GPIO1->DIR = config->P1.dir;
LPC_GPIO2->DIR = config->P2.dir;
LPC_GPIO3->DIR = config->P3.dir;
LPC_GPIO0->DATA = config->P0.data;
LPC_GPIO1->DATA = config->P1.data;
LPC_GPIO2->DATA = config->P2.data;
LPC_GPIO3->DATA = config->P3.data;
}
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @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.
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode) {
switch (mode & PAL_MODE_MASK) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT:
port->DIR &= ~mask;
break;
case PAL_MODE_UNCONNECTED:
palSetPort(port, PAL_WHOLE_PORT);
case PAL_MODE_OUTPUT_PUSHPULL:
port->DIR |= mask;
break;
}
}
#endif /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,316 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC13xx/pal_lld.h
* @brief LPC13xx GPIO low level driver header.
*
* @addtogroup LPC13xx_PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
#undef PAL_MODE_INPUT_PULLUP
#undef PAL_MODE_INPUT_PULLDOWN
#undef PAL_MODE_INPUT_ANALOG
#undef PAL_MODE_OUTPUT_OPENDRAIN
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @brief GPIO port setup info.
*/
typedef struct {
/** Initial value for FIO_PIN register.*/
uint32_t data;
/** Initial value for FIO_DIR register.*/
uint32_t dir;
} LPC13xx_gpio_setup_t;
/**
* @brief GPIO static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized the digital I/O
* subsystem. This represents only the initial setup, specific pads
* or whole ports can be reprogrammed at later time.
* @note The @p IOCON block is not configured, initially all pins have
* enabled pullups and are programmed as GPIO. It is responsibility
* of the various drivers to reprogram the pins in the proper mode.
* Pins that are not handled by any driver may be programmed in
* @p board.c.
*/
typedef struct {
/** @brief GPIO 0 setup data.*/
LPC13xx_gpio_setup_t P0;
/** @brief GPIO 1 setup data.*/
LPC13xx_gpio_setup_t P1;
/** @brief GPIO 2 setup data.*/
LPC13xx_gpio_setup_t P2;
/** @brief GPIO 3 setup data.*/
LPC13xx_gpio_setup_t P3;
} PALConfig;
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32
/**
* @brief Whole port mask.
* @brief This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFF)
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_t;
/**
* @brief Port Identifier.
*/
typedef LPC_GPIO_TypeDef *ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief GPIO0 port identifier.
*/
#define IOPORT1 LPC_GPIO0
#define GPIO0 LPC_GPIO0
/**
* @brief GPIO1 port identifier.
*/
#define IOPORT2 LPC_GPIO1
#define GPIO1 LPC_GPIO1
/**
* @brief GPIO2 port identifier.
*/
#define IOPORT3 LPC_GPIO2
#define GPIO2 LPC_GPIO2
/**
* @brief GPIO3 port identifier.
*/
#define IOPORT4 LPC_GPIO3
#define GPIO3 LPC_GPIO3
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @param[in] config architecture-dependent ports configuration
*/
#define pal_lld_init(config) _pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @return The port bits.
*/
#define pal_lld_readport(port) ((port)->DATA)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @return The latched logical states.
*/
#define pal_lld_readlatch(port) ((port)->DATA)
/**
* @brief Writes a bits mask on a I/O port.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*/
#define pal_lld_writeport(port, bits) ((port)->DATA = (bits))
/**
* @brief Sets a bits mask on a I/O port.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be ORed on the specified port
*/
#define pal_lld_setport(port, bits) ((port)->MASKED_ACCESS[bits] = 0xFFFFFFFF)
/**
* @brief Clears a bits mask on a I/O port.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] bits bits to be cleared on the specified port
*/
#define pal_lld_clearport(port, bits) ((port)->MASKED_ACCESS[bits] = 0)
/**
* @brief Reads a group of bits.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @return The group logical states.
*/
#define pal_lld_readgroup(port, mask, offset) \
((port)->MASKED_ACCESS[(mask) << (offset)])
/**
* @brief Writes a group of bits.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] offset group bit offset within the port
* @param[in] bits bits to be written. Values exceeding the group width
* are masked.
*/
#define pal_lld_writegroup(port, mask, offset, bits) \
((port)->MASKED_ACCESS[(mask) << (offset)] = (bits))
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note This function is not meant to be invoked directly by the
* application code.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] mode group mode
*/
#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
/**
* @brief Writes a logical state on an output pad.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
* @param[out] bit logical value, the value must be @p PAL_LOW or
* @p PAL_HIGH
*/
#define pal_lld_writepad(port, pad, bit) \
((port)->MASKED_ACCESS[(mask) << (pad)] = (bit) << (pad))
/**
* @brief Sets a pad logical state to @p PAL_HIGH.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*/
#define pal_lld_setpad(port, pad) \
((port)->MASKED_ACCESS[1 << (pad)] = 1 << (pad))
/**
* @brief Clears a pad logical state to @p PAL_LOW.
* @note This function is not meant to be invoked directly by the
* application code.
* @note The @ref PAL provides a default software implementation of this
* functionality, implement this function if can optimize it by using
* special hardware functionalities or special coding.
*
* @param[in] port port identifier
* @param[in] pad pad number within the port
*/
#define pal_lld_clearpad(port, pad) \
((port)->MASKED_ACCESS[1 << (pad)] = 0)
#if !defined(__DOXYGEN__)
extern const PALConfig pal_default_config;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_init(const PALConfig *config);
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_PAL */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,82 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup LPC13xx LPC13xx Support
* @brief LPC13xx specific support.
* @details The LPC13xx support includes:
* - I/O ports driver.
* - Buffered, interrupt driven, serial driver.
* - A demo supporting the kernel test suite.
* .
* @ingroup ARMCMx
*/
/**
* @defgroup LPC13xx_HAL LPC13xx HAL Support
* @brief HAL support.
*
* @ingroup LPC13xx
*/
/**
* @defgroup LPC13xx_PAL LPC13xx I/O Ports Support
* @brief I/O Ports peripherals support.
* @details This module supports the LPC13xx GPIO controller. The controller
* supports the following features (see @ref PAL):
* - 12 bits wide ports.
* - Atomic set/reset functions.
* - Atomic set+reset function (atomic bus operations).
* - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
* <h2>Supported Setup Modes</h2>
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* .
* Any attempt to setup an invalid mode is ignored.
*
* <h2>Suboptimal Behavior</h2>
* Some GPIO features are less than optimal:
* - Pad/port toggling operations are not atomic.
* - Pull-up and Pull-down resistors cannot be programmed through the PAL
* driver and must be programmed separately.
* - Reading of the output latch for pads programmed as input is not possible,
* the input pin value is returned instead.
* .
* @ingroup LPC13xx
*/
/**
* @defgroup LPC13xx_SERIAL LPC13xx UART Support
* @brief UART peripherals support.
* @details The serial driver supports the LPC13xx UART taking advantage of
* its deep hardware buffers.
*
* @ingroup LPC13xx
*/

View File

@@ -0,0 +1,7 @@
# List of all the LPC13xx platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC13xx/hal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC13xx/serial_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/LPC13xx

View File

@@ -0,0 +1,297 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC13xx/serial_lld.c
* @brief LPC13xx low level serial driver code.
*
* @addtogroup LPC13xx_SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if USE_LPC13xx_UART0 || defined(__DOXYGEN__)
/** @brief UART0 serial driver identifier.*/
SerialDriver SD1;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/** @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) {
LPC_UART_TypeDef *u = sdp->uart;
uint32_t div = LPC13xx_UART_PCLK / (config->sc_speed << 4);
u->LCR = config->sc_lcr | LCR_DLAB;
u->DLL = div;
u->DLM = div >> 8;
u->LCR = config->sc_lcr;
u->FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | config->sc_fcr;
u->ACR = 0;
u->FDR = 0x10;
u->TER = TER_ENABLE;
u->IER = IER_RBR | IER_STATUS;
}
/**
* @brief UART de-initialization.
*
* @param[in] u pointer to an UART I/O block
*/
static void uart_deinit(LPC_UART_TypeDef *u) {
u->LCR = LCR_DLAB;
u->DLL = 1;
u->DLM = 0;
u->LCR = 0;
u->FDR = 0x10;
u->IER = 0;
u->FCR = FCR_RXRESET | FCR_TXRESET;
u->ACR = 0;
u->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) {
sdflags_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();
sdAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
/**
* @brief Common IRQ handler.
* @note Tries hard to clear all the pending interrupt sources, we don't
* want to go through the whole ISR and have another interrupt soon
* after.
*
* @param[in] u pointer to an UART I/O block
* @param[in] sdp communication channel associated to the UART
*/
static void serve_interrupt(SerialDriver *sdp) {
LPC_UART_TypeDef *u = sdp->uart;
while (TRUE) {
switch (u->IIR & IIR_SRC_MASK) {
case IIR_SRC_NONE:
return;
case IIR_SRC_ERROR:
set_error(sdp, u->LSR);
break;
case IIR_SRC_TIMEOUT:
case IIR_SRC_RX:
chSysLockFromIsr();
if (chIQIsEmpty(&sdp->iqueue))
chEvtBroadcastI(&sdp->ievent);
chSysUnlockFromIsr();
while (u->LSR & LSR_RBR_FULL) {
chSysLockFromIsr();
if (chIQPutI(&sdp->iqueue, u->RBR) < Q_OK)
sdAddFlagsI(sdp, SD_OVERRUN_ERROR);
chSysUnlockFromIsr();
}
break;
case IIR_SRC_TX:
{
int i = LPC13xx_UART_FIFO_PRELOAD;
do {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->oqueue);
chSysUnlockFromIsr();
if (b < Q_OK) {
u->IER &= ~IER_THRE;
chSysLockFromIsr();
chEvtBroadcastI(&sdp->oevent);
chSysUnlockFromIsr();
break;
}
u->THR = b;
} while (--i);
}
break;
default:
(void) u->THR;
(void) u->RBR;
}
}
}
/**
* @brief Attempts a TX FIFO preload.
*/
static void preload(SerialDriver *sdp) {
LPC_UART_TypeDef *u = sdp->uart;
if (u->LSR & LSR_THRE) {
int i = LPC13xx_UART_FIFO_PRELOAD;
do {
msg_t b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chEvtBroadcastI(&sdp->oevent);
return;
}
u->THR = b;
} while (--i);
}
u->IER |= IER_THRE;
}
/**
* @brief Driver SD1 output notification.
*/
#if USE_LPC13xx_UART0 || defined(__DOXYGEN__)
static void notify1(void) {
preload(&SD1);
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief UART0 IRQ handler.
*/
#if USE_LPC13xx_UART0 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(VectorF8) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD1);
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_LPC13xx_UART0
sdObjectInit(&SD1, NULL, notify1);
SD1.uart = LPC_UART;
LPC_IOCON->PIO1_6 = 0xC1; /* RDX without resistors. */
LPC_IOCON->PIO1_7 = 0xC1; /* TDX without resistors. */
#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.
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
if (sdp->state == SD_STOP) {
#if USE_LPC13xx_UART0
if (&SD1 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 12);
NVICEnableVector(UART_IRQn,
CORTEX_PRIORITY_MASK(LPC13xx_UART0_PRIORITY));
}
#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
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->state == SD_READY) {
uart_deinit(sdp->uart);
#if USE_LPC13xx_UART0
if (&SD1 == sdp) {
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 12);
NVICDisableVector(UART_IRQn);
return;
}
#endif
}
}
#endif /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,208 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC13xx/serial_lld.h
* @brief LPC13xx low level serial driver header.
*
* @addtogroup LPC13xx_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define IIR_SRC_MASK 0x0F
#define IIR_SRC_NONE 0x01
#define IIR_SRC_MODEM 0x00
#define IIR_SRC_TX 0x02
#define IIR_SRC_RX 0x04
#define IIR_SRC_ERROR 0x06
#define IIR_SRC_TIMEOUT 0x0C
#define IER_RBR 1
#define IER_THRE 2
#define IER_STATUS 4
#define LCR_WL5 0
#define LCR_WL6 1
#define LCR_WL7 2
#define LCR_WL8 3
#define LCR_STOP1 0
#define LCR_STOP2 4
#define LCR_NOPARITY 0
#define LCR_PARITYODD 0x08
#define LCR_PARITYEVEN 0x18
#define LCR_PARITYONE 0x28
#define LCR_PARITYZERO 0x38
#define LCR_BREAK_ON 0x40
#define LCR_DLAB 0x80
#define FCR_ENABLE 1
#define FCR_RXRESET 2
#define FCR_TXRESET 4
#define FCR_TRIGGER0 0
#define FCR_TRIGGER1 0x40
#define FCR_TRIGGER2 0x80
#define FCR_TRIGGER3 0xC0
#define LSR_RBR_FULL 1
#define LSR_OVERRUN 2
#define LSR_PARITY 4
#define LSR_FRAMING 8
#define LSR_BREAK 0x10
#define LSR_THRE 0x20
#define LSR_TEMT 0x40
#define LSR_RXFE 0x80
#define TER_ENABLE 0x80
/*===========================================================================*/
/* 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_LPC13xx_UART0) || defined(__DOXYGEN__)
#define USE_LPC13xx_UART0 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(LPC13xx_UART_FIFO_PRELOAD) || defined(__DOXYGEN__)
#define LPC13xx_UART_FIFO_PRELOAD 16
#endif
/**
* @brief UART0 interrupt priority level setting.
*/
#if !defined(LPC13xx_UART0_PRIORITY) || defined(__DOXYGEN__)
#define LPC13xx_UART0_PRIORITY 3
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (LPC13xx_UART_FIFO_PRELOAD < 1) || (LPC13xx_UART_FIFO_PRELOAD > 16)
#error "invalid LPC13xx_UART_FIFO_PRELOAD setting"
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Serial Driver condition flags type.
*/
typedef uint32_t sdflags_t;
/**
* @brief LPC13xx 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.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* 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.*/ \
LPC_UART_TypeDef *uart;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_LPC13xx_UART0 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#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 /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,64 @@
/**************************************************************************//**
* @file system_LPC13xx.h
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File
* for the NXP LPC13xx Device Series
* @version V1.01
* @date 19. October 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __SYSTEM_LPC13xx_H
#define __SYSTEM_LPC13xx_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* __SYSTEM_LPC13x_H */

View File

@@ -0,0 +1,134 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/hal_lld.c
* @brief LPC214x HAL subsystem low level driver source.
* @addtogroup LPC214x_HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
*/
const PALConfig pal_default_config =
{
VAL_PINSEL0,
VAL_PINSEL1,
VAL_PINSEL2,
{VAL_FIO0PIN, VAL_FIO0DIR},
{VAL_FIO1PIN, VAL_FIO1DIR}
};
/*===========================================================================*/
/* 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.
*/
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.
*/
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;
}
/** @} */

View File

@@ -0,0 +1,87 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/hal_lld.h
* @brief LPC214x HAL subsystem low level driver header.
* @addtogroup LPC214x_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "lpc214x.h"
#include "vic.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @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_ */
/** @} */

View File

@@ -0,0 +1,532 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file lpc214x.h
* @brief LPC214x register definitions.
*/
#ifndef _LPC214X_H_
#define _LPC214X_H_
typedef volatile uint8_t IOREG8;
typedef volatile uint16_t IOREG16;
typedef volatile uint32_t IOREG32;
/*
* System.
*/
#define MEMMAP (*((IOREG32 *)0xE01FC040))
#define PCON (*((IOREG32 *)0xE01FC0C0))
#define PCONP (*((IOREG32 *)0xE01FC0C4))
#define VPBDIV (*((IOREG32 *)0xE01FC100))
#define EXTINT (*((IOREG32 *)0xE01FC140))
#define INTWAKE (*((IOREG32 *)0xE01FC144))
#define EXTMODE (*((IOREG32 *)0xE01FC148))
#define EXTPOLAR (*((IOREG32 *)0xE01FC14C))
#define RSID (*((IOREG32 *)0xE01FC180))
#define CSPR (*((IOREG32 *)0xE01FC184))
#define SCS (*((IOREG32 *)0xE01FC1A0))
#define VPD_D4 0
#define VPD_D1 1
#define VPD_D2 2
#define VPD_RESERVED 3
#define PCTIM0 (1 << 1)
#define PCTIM1 (1 << 2)
#define PCUART0 (1 << 3)
#define PCUART1 (1 << 4)
#define PCPWM0 (1 << 5)
#define PCI2C0 (1 << 7)
#define PCSPI0 (1 << 8)
#define PCRTC (1 << 9)
#define PCSPI1 (1 << 10)
#define PCAD0 (1 << 12)
#define PCI2C1 (1 << 19)
#define PCAD1 (1 << 20)
#define PCUSB (1 << 31)
#define PCALL (PCTIM0 | PCTIM1 | PCUART0 | PCUART1 | \
PCPWM0 | PCI2C0 | PCSPI0 | PCRTC | PCSPI1 | \
PCAD0 | PCI2C1 | PCAD1 | PCUSB)
#define EINT0 1
#define EINT1 2
#define EINT2 4
#define EINT3 8
#define EXTWAKE0 1
#define EXTWAKE1 2
#define EXTWAKE2 4
#define EXTWAKE3 8
#define USBWAKE 0x20
#define BODWAKE 0x4000
#define RTCWAKE 0x8000
#define EXTMODE0 1
#define EXTMODE1 2
#define EXTMODE2 4
#define EXTMODE3 8
#define EXTPOLAR0 1
#define EXTPOLAR1 2
#define EXTPOLAR2 4
#define EXTPOLAR3 8
typedef struct {
IOREG32 PLL_CON;
IOREG32 PLL_CFG;
IOREG32 PLL_STAT;
IOREG32 PLL_FEED;
} PLL;
#define PLL0Base ((PLL *)0xE01FC080)
#define PLL1Base ((PLL *)0xE01FC0A0)
#define PLL0CON (PLL0Base->PLL_CON)
#define PLL0CFG (PLL0Base->PLL_CFG)
#define PLL0STAT (PLL0Base->PLL_STAT)
#define PLL0FEED (PLL0Base->PLL_FEED)
#define PLL1CON (PLL1Base->PLL_CON)
#define PLL1CFG (PLL1Base->PLL_CFG)
#define PLL1STAT (PLL1Base->PLL_STAT)
#define PLL1FEED (PLL1Base->PLL_FEED)
/*
* Pins.
*/
typedef struct {
IOREG32 PS_SEL0;
IOREG32 PS_SEL1;
IOREG32 _dummy[3];
IOREG32 PS_SEL2;
} PS;
#define PSBase ((PS *)0xE002C000)
#define PINSEL0 (PSBase->PS_SEL0)
#define PINSEL1 (PSBase->PS_SEL1)
#define PINSEL2 (PSBase->PS_SEL2)
/*
* VIC
*/
#define SOURCE_WDT 0
#define SOURCE_ARMCore0 2
#define SOURCE_ARMCore1 3
#define SOURCE_Timer0 4
#define SOURCE_Timer1 5
#define SOURCE_UART0 6
#define SOURCE_UART1 7
#define SOURCE_PWM0 8
#define SOURCE_I2C0 9
#define SOURCE_SPI0 10
#define SOURCE_SPI1 11
#define SOURCE_PLL 12
#define SOURCE_RTC 13
#define SOURCE_EINT0 14
#define SOURCE_EINT1 15
#define SOURCE_EINT2 16
#define SOURCE_EINT3 17
#define SOURCE_ADC0 18
#define SOURCE_I2C1 19
#define SOURCE_BOD 20
#define SOURCE_ADC1 21
#define SOURCE_USB 22
#define INTMASK(n) (1 << (n))
#define ALLINTMASK (INTMASK(SOURCE_WDT) | INTMASK(SOURCE_ARMCore0) | \
INTMASK(SOURCE_ARMCore1) | INTMASK(SOURCE_Timer0) | \
INTMASK(SOURCE_Timer1) | INTMASK(SOURCE_UART0) | \
INTMASK(SOURCE_UART1) | INTMASK(SOURCE_PWM0) | \
INTMASK(SOURCE_I2C0) | INTMASK(SOURCE_SPI0) | \
INTMASK(SOURCE_SPI1) | INTMASK(SOURCE_PLL) | \
INTMASK(SOURCE_RTC) | INTMASK(SOURCE_EINT0) | \
INTMASK(SOURCE_EINT1) | INTMASK(SOURCE_EINT2) | \
INTMASK(SOURCE_EINT3) | INTMASK(SOURCE_ADC0) | \
INTMASK(SOURCE_I2C1) | INTMASK(SOURCE_BOD) | \
INTMASK(SOURCE_ADC1) | INTMASK(SOURCE_USB))
typedef struct {
IOREG32 VIC_IRQStatus;
IOREG32 VIC_FIQStatus;
IOREG32 VIC_RawIntr;
IOREG32 VIC_IntSelect;
IOREG32 VIC_IntEnable;
IOREG32 VIC_IntEnClear;
IOREG32 VIC_SoftInt;
IOREG32 VIC_SoftIntClear;
IOREG32 VIC_Protection;
IOREG32 unused1[3];
IOREG32 VIC_VectAddr;
IOREG32 VIC_DefVectAddr;
IOREG32 unused2[50];
IOREG32 VIC_VectAddrs[16];
IOREG32 unused3[48];
IOREG32 VIC_VectCntls[16];
} VIC;
#define VICBase ((VIC *)0xFFFFF000)
#define VICVectorsBase ((IOREG32 *)0xFFFFF100)
#define VICControlsBase ((IOREG32 *)0xFFFFF200)
#define VICIRQStatus (VICBase->VIC_IRQStatus)
#define VICFIQStatus (VICBase->VIC_FIQStatus)
#define VICRawIntr (VICBase->VIC_RawIntr)
#define VICIntSelect (VICBase->VIC_IntSelect)
#define VICIntEnable (VICBase->VIC_IntEnable)
#define VICIntEnClear (VICBase->VIC_IntEnClear)
#define VICSoftInt (VICBase->VIC_SoftInt)
#define VICSoftIntClear (VICBase->VIC_SoftIntClear)
#define VICProtection (VICBase->VIC_Protection)
#define VICVectAddr (VICBase->VIC_VectAddr)
#define VICDefVectAddr (VICBase->VIC_DefVectAddr)
#define VICVectAddrs(n) (VICBase->VIC_VectAddrs[n])
#define VICVectCntls(n) (VICBase->VIC_VectCntls[n])
/*
* MAM.
*/
typedef struct {
IOREG32 MAM_Control;
IOREG32 MAM_Timing;
} MAM;
#define MAMBase ((MAM *)0xE01FC000)
#define MAMCR (MAMBase->MAM_Control)
#define MAMTIM (MAMBase->MAM_Timing)
/*
* GPIO - FIO.
*/
typedef struct {
IOREG32 IO_PIN;
IOREG32 IO_SET;
IOREG32 IO_DIR;
IOREG32 IO_CLR;
} GPIO;
#define GPIO0Base ((GPIO *)0xE0028000)
#define IO0PIN (GPIO0Base->IO_PIN)
#define IO0SET (GPIO0Base->IO_SET)
#define IO0DIR (GPIO0Base->IO_DIR)
#define IO0CLR (GPIO0Base->IO_CLR)
#define GPIO1Base ((GPIO *)0xE0028010)
#define IO1PIN (GPIO1Base->IO_PIN)
#define IO1SET (GPIO1Base->IO_SET)
#define IO1DIR (GPIO1Base->IO_DIR)
#define IO1CLR (GPIO1Base->IO_CLR)
typedef struct {
IOREG32 FIO_DIR;
IOREG32 unused1;
IOREG32 unused2;
IOREG32 unused3;
IOREG32 FIO_MASK;
IOREG32 FIO_PIN;
IOREG32 FIO_SET;
IOREG32 FIO_CLR;
} FIO;
#define FIO0Base ((FIO *)0x3FFFC000)
#define FIO0DIR (FIO0Base->FIO_DIR)
#define FIO0MASK (FIO0Base->FIO_MASK)
#define FIO0PIN (FIO0Base->FIO_PIN)
#define FIO0SET (FIO0Base->FIO_SET)
#define FIO0CLR (FIO0Base->FIO_CLR)
#define FIO1Base ((FIO *)0x3FFFC020)
#define FIO1DIR (FIO1Base->FIO_DIR)
#define FIO1MASK (FIO1Base->FIO_MASK)
#define FIO1PIN (FIO1Base->FIO_PIN)
#define FIO1SET (FIO1Base->FIO_SET)
#define FIO1CLR (FIO1Base->FIO_CLR)
/*
* UART.
*/
typedef struct {
union {
IOREG32 UART_RBR;
IOREG32 UART_THR;
IOREG32 UART_DLL;
};
union {
IOREG32 UART_IER;
IOREG32 UART_DLM;
};
union {
IOREG32 UART_IIR;
IOREG32 UART_FCR;
};
IOREG32 UART_LCR;
IOREG32 UART_MCR; // UART1 only
IOREG32 UART_LSR;
IOREG32 unused18;
IOREG32 UART_SCR;
IOREG32 UART_ACR;
IOREG32 unused24;
IOREG32 UART_FDR;
IOREG32 unused2C;
IOREG32 UART_TER;
} UART;
#define U0Base ((UART *)0xE000C000)
#define U0RBR (U0Base->UART_RBR)
#define U0THR (U0Base->UART_THR)
#define U0DLL (U0Base->UART_DLL)
#define U0IER (U0Base->UART_IER)
#define U0DLM (U0Base->UART_DLM)
#define U0IIR (U0Base->UART_IIR)
#define U0FCR (U0Base->UART_FCR)
#define U0LCR (U0Base->UART_LCR)
#define U0LSR (U0Base->UART_LSR)
#define U0SCR (U0Base->UART_SCR)
#define U0ACR (U0Base->UART_ACR)
#define U0FDR (U0Base->UART_FDR)
#define U0TER (U0Base->UART_TER)
#define U1Base ((UART *)0xE0010000)
#define U1RBR (U1Base->UART_RBR)
#define U1THR (U1Base->UART_THR)
#define U1DLL (U1Base->UART_DLL)
#define U1IER (U1Base->UART_IER)
#define U1DLM (U1Base->UART_DLM)
#define U1IIR (U1Base->UART_IIR)
#define U1FCR (U1Base->UART_FCR)
#define U1MCR (U1Base->UART_MCR)
#define U1LCR (U1Base->UART_LCR)
#define U1LSR (U1Base->UART_LSR)
#define U1SCR (U1Base->UART_SCR)
#define U1ACR (U1Base->UART_ACR)
#define U1FDR (U1Base->UART_FDR)
#define U1TER (U1Base->UART_TER)
#define IIR_SRC_MASK 0x0F
#define IIR_SRC_NONE 0x01
#define IIR_SRC_TX 0x02
#define IIR_SRC_RX 0x04
#define IIR_SRC_ERROR 0x06
#define IIR_SRC_TIMEOUT 0x0C
#define IER_RBR 1
#define IER_THRE 2
#define IER_STATUS 4
#define IIR_INT_PENDING 1
#define LCR_WL5 0
#define LCR_WL6 1
#define LCR_WL7 2
#define LCR_WL8 3
#define LCR_STOP1 0
#define LCR_STOP2 4
#define LCR_NOPARITY 0
#define LCR_PARITYODD 0x08
#define LCR_PARITYEVEN 0x18
#define LCR_PARITYONE 0x28
#define LCR_PARITYZERO 0x38
#define LCR_BREAK_ON 0x40
#define LCR_DLAB 0x80
#define FCR_ENABLE 1
#define FCR_RXRESET 2
#define FCR_TXRESET 4
#define FCR_TRIGGER0 0
#define FCR_TRIGGER1 0x40
#define FCR_TRIGGER2 0x80
#define FCR_TRIGGER3 0xC0
#define LSR_RBR_FULL 1
#define LSR_OVERRUN 2
#define LSR_PARITY 4
#define LSR_FRAMING 8
#define LSR_BREAK 0x10
#define LSR_THRE 0x20
#define LSR_TEMT 0x40
#define LSR_RXFE 0x80
#define TER_ENABLE 0x80
/*
* SSP.
*/
typedef struct {
IOREG32 SSP_CR0;
IOREG32 SSP_CR1;
IOREG32 SSP_DR;
IOREG32 SSP_SR;
IOREG32 SSP_CPSR;
IOREG32 SSP_IMSC;
IOREG32 SSP_RIS;
IOREG32 SSP_MIS;
IOREG32 SSP_ICR;
} SSP;
#define SSPBase ((SSP *)0xE0068000)
#define SSPCR0 (SSPBase->SSP_CR0)
#define SSPCR1 (SSPBase->SSP_CR1)
#define SSPDR (SSPBase->SSP_DR)
#define SSPSR (SSPBase->SSP_SR)
#define SSPCPSR (SSPBase->SSP_CPSR)
#define SSPIMSC (SSPBase->SSP_IMSC)
#define SSPRIS (SSPBase->SSP_RIS)
#define SSPMIS (SSPBase->SSP_MIS)
#define SSPICR (SSPBase->SSP_ICR)
#define CR0_DSS4BIT 3
#define CR0_DSS5BIT 4
#define CR0_DSS6BIT 5
#define CR0_DSS7BIT 6
#define CR0_DSS8BIT 7
#define CR0_DSS9BIT 8
#define CR0_DSS10BIT 9
#define CR0_DSS11BIT 0xA
#define CR0_DSS12BIT 0xB
#define CR0_DSS13BIT 0xC
#define CR0_DSS14BIT 0xD
#define CR0_DSS15BIT 0xE
#define CR0_DSS16BIT 0xF
#define CR0_FRFSPI 0
#define CR0_FRFSSI 0x10
#define CR0_FRFMW 0x20
#define CR0_CPOL 0x40
#define CR0_CPHA 0x80
#define CR0_CLOCKRATE(n) ((n) << 8)
#define CR1_LBM 1
#define CR1_SSE 2
#define CR1_MS 4
#define CR1_SOD 8
#define SR_TFE 1
#define SR_TNF 2
#define SR_RNE 4
#define SR_RFF 8
#define SR_BSY 0x10
#define IMSC_ROR 1
#define IMSC_RT 2
#define IMSC_RX 4
#define IMSC_TX 8
#define RIS_ROR 1
#define RIS_RT 2
#define RIS_RX 4
#define RIS_TX 8
#define MIS_ROR 1
#define MIS_RT 2
#define MIS_RX 4
#define MIS_TX 8
#define ICR_ROR 1
#define ICR_RT 2
/*
* Timers/Counters.
*/
typedef struct {
IOREG32 TC_IR;
IOREG32 TC_TCR;
IOREG32 TC_TC;
IOREG32 TC_PR;
IOREG32 TC_PC;
IOREG32 TC_MCR;
IOREG32 TC_MR0;
IOREG32 TC_MR1;
IOREG32 TC_MR2;
IOREG32 TC_MR3;
IOREG32 TC_CCR;
IOREG32 TC_CR0;
IOREG32 TC_CR1;
IOREG32 TC_CR2;
IOREG32 TC_CR3;
IOREG32 TC_EMR;
IOREG32 TC_CTCR;
} TC;
#define T0Base ((TC *)0xE0004000)
#define T0IR (T0Base->TC_IR)
#define T0TCR (T0Base->TC_TCR)
#define T0TC (T0Base->TC_TC)
#define T0PR (T0Base->TC_PR)
#define T0PC (T0Base->TC_PC)
#define T0MCR (T0Base->TC_MCR)
#define T0MR0 (T0Base->TC_MR0)
#define T0MR1 (T0Base->TC_MR1)
#define T0MR2 (T0Base->TC_MR2)
#define T0MR3 (T0Base->TC_MR3)
#define T0CCR (T0Base->TC_CCR)
#define T0CR0 (T0Base->TC_CR0)
#define T0CR1 (T0Base->TC_CR1)
#define T0CR2 (T0Base->TC_CR2)
#define T0CR3 (T0Base->TC_CR3)
#define T0EMR (T0Base->TC_EMR)
#define T0CTCR (T0Base->TC_CTCR)
#define T1Base ((TC *)0xE0008000)
#define T1IR (T1Base->TC_IR)
#define T1TCR (T1Base->TC_TCR)
#define T1TC (T1Base->TC_TC)
#define T1PR (T1Base->TC_PR)
#define T1PC (T1Base->TC_PC)
#define T1MCR (T1Base->TC_MCR)
#define T1MR0 (T1Base->TC_MR0)
#define T1MR1 (T1Base->TC_MR1)
#define T1MR2 (T1Base->TC_MR2)
#define T1MR3 (T1Base->TC_MR3)
#define T1CCR (T1Base->TC_CCR)
#define T1CR0 (T1Base->TC_CR0)
#define T1CR1 (T1Base->TC_CR1)
#define T1CR2 (T1Base->TC_CR2)
#define T1CR3 (T1Base->TC_CR3)
#define T1EMR (T1Base->TC_EMR)
#define T1CTCR (T1Base->TC_CTCR)
/*
* Watchdog.
*/
typedef struct {
IOREG32 WD_MOD;
IOREG32 WD_TC;
IOREG32 WD_FEED;
IOREG32 WD_TV;
} WD;
#define WDBase ((WD *)0xE0000000)
#define WDMOD (WDBase->WD_MOD)
#define WDTC (WDBase->WD_TC)
#define WDFEED (WDBase->WD_FEED)
#define WDTV (WDBase->WD_TV)
/*
* DAC.
*/
#define DACR (*((IOREG32 *)0xE006C000))
#endif /* _LPC214X_H_ */

View File

@@ -0,0 +1,120 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/pal_lld.c
* @brief LPC214x FIO low level driver code.
* @addtogroup LPC214x_PAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* 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
*/
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.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @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.
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_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 /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,264 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/pal_lld.h
* @brief LPC214x FIO low level driver header.
* @addtogroup LPC214x_PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if CH_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 Digital I/O port sized unsigned type.
*/
typedef uint32_t ioportmask_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, please put them in a file named ioports_lld.c if so. */
/*===========================================================================*/
/**
* @brief FIO subsystem initialization.
* @details Enables the access through the fast registers.
*/
#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 the port identifier
* @return the port bits
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#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 the port identifier
* @return The latched logical states.
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#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 the port identifier
* @param[in] bits the bits to be written on the specified port
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#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 the port identifier
* @param[in] bits the bits to be ORed on the specified port
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#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 the port identifier
* @param[in] bits the bits to be cleared on the specified port
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#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 the port identifier
* @param[in] mask the group mask, a logical AND is performed on the output
* data
* @param[in] offset the group bit offset within the port
* @param[in] bits the bits to be written. Values exceeding the group width
* are masked.
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#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.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @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.
*/
#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
/**
* @brief Writes a logical state on an output pad.
*
* @param[in] port the port identifier
* @param[in] pad the pad number within the port
* @param[out] bit the logical value, the value must be @p 0 or @p 1
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#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.
*/
#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,
uint_fast8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_PAL */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,97 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup LPC214x LPC214x Support
* @brief LPC214x specific support.
* @details The LPC214x support includes:
* - VIC support code.
* - I/O ports driver.
* - Buffered, interrupt driven, serial driver.
* - SPI driver.
* - A demo supporting the kernel test suite.
* - A C++ demo supporting the kernel test suite.
* - A demo integrating ChibiOS/RT with FatFS.
* .
* @ingroup ARM7
*/
/**
* @defgroup LPC214x_VIC VIC Support
* @brief VIC peripheral support.
*
* @ingroup LPC214x
*/
/**
* @defgroup LPC214x_HAL LPC214x HAL Support
* @brief HAL support.
*
* @ingroup LPC214x
*/
/**
* @defgroup LPC214x_PAL LPC214x I/O Ports Support
* @brief I/O Ports peripherals support.
* @details This module supports the LPC214x FIO controller. The controller
* supports the following features (see @ref PAL):
* - 32 bits wide ports.
* - Atomic set/reset functions.
* - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
* <h2>Supported Setup Modes</h2>
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
* - @p PAL_MODE_INPUT_ANALOG (same as @p PAL_MODE_INPUT).
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* .
* Any attempt to setup an invalid mode is ignored.
*
* <h2>Suboptimal Behavior</h2>
* - Pad/port toggling operations are not atomic.
* - Pad/group mode setup is not atomic.
* .
* @ingroup LPC214x
*/
/**
* @defgroup LPC214x_SERIAL LPC214x UART Support
* @brief UART peripherals support.
* @details The serial driver supports the LPC214x UART peripherals.
*
* @ingroup LPC214x
*/
/**
* @defgroup LPC214x_SPI LPC214x SPI Support
* @brief SSP peripheral support.
* @details The SPI driver supports the LPC214x SSP, the driver works in
* polling mode.
*
* @ingroup LPC214x
*/

View File

@@ -0,0 +1,9 @@
# List of all the LPC214x platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/LPC214x/hal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC214x/pal_lld.c \
${CHIBIOS}/os/hal/platforms/LPC214x/serial_lld.c \
${CHIBIOS}/os/hal/platforms/LPC214x/spi_lld.c \
${CHIBIOS}/os/hal/platforms/LPC214x/vic.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/LPC214x

View File

@@ -0,0 +1,345 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/serial_lld.c
* @brief LPC214x low level serial driver code.
*
* @addtogroup LPC214x_SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_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. */
/*===========================================================================*/
/** @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) {
sdflags_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();
sdAddFlagsI(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 (chIQIsEmpty(&sdp->iqueue))
chEvtBroadcastI(&sdp->ievent);
chSysUnlockFromIsr();
while (u->UART_LSR & LSR_RBR_FULL) {
chSysLockFromIsr();
if (chIQPutI(&sdp->iqueue, u->UART_RBR) < Q_OK)
sdAddFlagsI(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();
chEvtBroadcastI(&sdp->oevent);
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) {
chEvtBroadcastI(&sdp->oevent);
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(void) {
preload(&SD1);
}
#endif
/**
* @brief Driver SD2 output notification.
*/
#if USE_LPC214x_UART1 || defined(__DOXYGEN__)
static void notify2(void) {
preload(&SD2);
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/**
* @brief UART0 IRQ handler.
*/
#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.
*/
#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.
*/
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.
*/
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
*/
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 /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,182 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/serial_lld.h
* @brief LPC214x low level serial driver header.
*
* @addtogroup LPC214x_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_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 Serial Driver condition flags type.
*/
typedef uint32_t sdflags_t;
/**
* @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.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* 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 /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,229 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/spi_lld.c
* @brief LPC214x low level SPI driver code.
* @addtogroup LPC214x_SPI
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if USE_LPC214x_SPI1 || defined(__DOXYGEN__)
/** @brief SPI1 driver identifier.*/
SPIDriver SPID1;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief Synchronous SSP transfer.
*
* @param[in] n number of bytes to be exchanged
*
* @param[in] txbuf the pointer to the transmit buffer or @p NULL
* @param[out] rxbuf the pointer to the receive buffer or @p NULL
*/
void rw8(size_t n, const uint8_t *txbuf, uint8_t *rxbuf) {
size_t ntx = n;
while (n > 0) {
uint32_t sr = SSPBase->SSP_SR;
if (sr & SR_RNE) {
uint8_t w = SSPBase->SSP_DR;
if (rxbuf != NULL)
*rxbuf++ = w;
n--;
continue; /* Priority over transmission. */
}
if ((ntx > 0) && (sr & SR_TNF)) {
if (txbuf != NULL)
SSPBase->SSP_DR = *txbuf++;
else
SSPBase->SSP_DR = 0xFFFFFFFF;
ntx--;
}
}
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level SPI driver initialization.
*/
void spi_lld_init(void) {
#if USE_LPC214x_SPI1
spiObjectInit(&SPID1);
#endif
}
/**
* @brief Configures and activates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
void spi_lld_start(SPIDriver *spip) {
if (spip->spd_state == SPI_STOP) {
/* Clock activation.*/
PCONP = (PCONP & PCALL) | PCSPI1;
}
/* Configuration.*/
SSPBase->SSP_CR1 = 0;
/* Emptying the receive FIFO, it happens to not be empty while debugging.*/
while (SSPBase->SSP_SR & SR_RNE)
(void) SSPBase->SSP_DR;
SSPBase->SSP_CR0 = spip->spd_config->spc_cr0;
SSPBase->SSP_CPSR = spip->spd_config->spc_cpsr;
SSPBase->SSP_CR1 = spip->spd_config->spc_cr1 | CR1_SSE;
}
/**
* @brief Deactivates the SPI peripheral.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
void spi_lld_stop(SPIDriver *spip) {
if (spip->spd_state != SPI_STOP) {
SSPBase->SSP_CR1 = 0;
SSPBase->SSP_CR0 = 0;
SSPBase->SSP_CPSR = 0;
PCONP &= ~PCSPI1;
}
}
/**
* @brief Asserts the slave select signal and prepares for transfers.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
void spi_lld_select(SPIDriver *spip) {
palClearPad(spip->spd_config->spc_ssport, spip->spd_config->spc_sspad);
}
/**
* @brief Deasserts the slave select signal.
* @details The previously selected peripheral is unselected.
*
* @param[in] spip pointer to the @p SPIDriver object
*/
void spi_lld_unselect(SPIDriver *spip) {
palSetPad(spip->spd_config->spc_ssport, spip->spd_config->spc_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
*/
void spi_lld_ignore(SPIDriver *spip, size_t n) {
(void)spip;
rw8(n, NULL, NULL);
}
/**
* @brief Exchanges data on the SPI bus.
* @details This function performs a simultaneous transmit/receive operation.
*
* @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
*
* @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.
*/
void spi_lld_exchange(SPIDriver *spip, size_t n,
const void *txbuf, void *rxbuf) {
(void)spip;
rw8(n, txbuf, rxbuf);
}
/**
* @brief Sends data ever the SPI bus.
*
* @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
*
* @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.
*/
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
(void)spip;
rw8(n, txbuf, NULL);
}
/**
* @brief Receives data from the SPI bus.
*
* @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
*
* @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.
*/
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
(void)spip;
rw8(n, NULL, rxbuf);
}
#endif /* CH_HAL_USE_SPI */
/** @} */

View File

@@ -0,0 +1,148 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/spi_lld.h
* @brief LPC214x low level SPI driver header.
* @addtogroup LPC214x_SPI
* @{
*/
#ifndef _SPI_LLD_H_
#define _SPI_LLD_H_
#if CH_HAL_USE_SPI || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief SPI1 (SSP) driver enable switch.
* @details If set to @p TRUE the support for SPI0 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_LPC214x_SPI1) || defined(__DOXYGEN__)
#define USE_LPC214x_SPI1 TRUE
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Driver configuration structure.
*/
typedef struct {
/**
* @brief The chip select line port.
*/
ioportid_t spc_ssport;
/**
* @brief The chip select line pad number.
*/
uint16_t spc_sspad;
/**
* @brief SSP CR0 initialization data.
*/
uint16_t spc_cr0;
/**
* @brief SSP CR1 initialization data.
*/
uint16_t spc_cr1;
/**
* @brief SSP CPSR initialization data.
*/
uint32_t spc_cpsr;
} SPIConfig;
/**
* @brief Structure representing a SPI driver.
*/
typedef struct {
/**
* @brief Driver state.
*/
spistate_t spd_state;
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
/**
* @brief Mutex protecting the bus.
*/
Mutex spd_mutex;
#elif CH_USE_SEMAPHORES
Semaphore spd_semaphore;
#endif
#endif /* SPI_USE_MUTUAL_EXCLUSION */
/**
* @brief Current configuration data.
*/
const SPIConfig *spd_config;
/* End of the mandatory fields.*/
} SPIDriver;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_LPC214x_SPI1 && !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);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_SPI */
#endif /* _SPI_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,70 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file LPC214x/vic.c
* @brief LPC214x VIC peripheral support code.
*
* @addtogroup LPC214x_VIC
* @{
*/
#include "ch.h"
/**
* @brief VIC Initialization.
* @note Better reset everything in the VIC, it is a HUGE source of trouble.
*/
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
*/
void SetVICVector(void *handler, int vector, int source) {
VIC *vicp = VICBase;
vicp->VIC_VectAddrs[vector] = (IOREG32)handler;
vicp->VIC_VectCntls[vector] = (IOREG32)(source | 0x20);
}
/** @} */

View File

@@ -0,0 +1,49 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @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_ */
/** @} */

View File

@@ -0,0 +1,104 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file MSP430/hal_lld.c
* @brief MSP430 HAL subsystem low level driver source.
* @addtogroup MSP430_HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
*/
const PALConfig pal_default_config =
{
#if defined(__MSP430_HAS_PORT1__) || defined(__MSP430_HAS_PORT1_R__)
{VAL_P1OUT, VAL_P1DIR},
#endif
#if defined(__MSP430_HAS_PORT2__) || defined(__MSP430_HAS_PORT2_R__)
{VAL_P2OUT, VAL_P2DIR},
#endif
#if defined(__MSP430_HAS_PORT3__) || defined(__MSP430_HAS_PORT3_R__)
{VAL_P3OUT, VAL_P3DIR},
#endif
#if defined(__MSP430_HAS_PORT4__) || defined(__MSP430_HAS_PORT4_R__)
{VAL_P4OUT, VAL_P4DIR},
#endif
#if defined(__MSP430_HAS_PORT5__) || defined(__MSP430_HAS_PORT5_R__)
{VAL_P5OUT, VAL_P5DIR},
#endif
#if defined(__MSP430_HAS_PORT6__) || defined(__MSP430_HAS_PORT6_R__)
{VAL_P6OUT, VAL_P6DIR},
#endif
};
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
/*
* Clock sources setup.
*/
DCOCTL = VAL_DCOCTL;
BCSCTL1 = VAL_BCSCTL1;
#if MSP430_USE_CLOCK == MSP430_CLOCK_SOURCE_XT2CLK
do {
int i;
IFG1 &= ~OFIFG;
for (i = 255; i > 0; i--)
asm("nop");
} while (IFG1 & OFIFG);
#endif
BCSCTL2 = VAL_BCSCTL2;
}
/** @} */

View File

@@ -0,0 +1,119 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file MSP430/hal_lld.h
* @brief MSP430 HAL subsystem low level driver header.
* @addtogroup MSP430_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "msp430x16x.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "MSP430x16x"
#define MSP430_CLOCK_SOURCE_XT2CLK 0 /** @brief XT2CLK clock selector. */
#define MSP430_CLOCK_SOURCE_DCOCLK 1 /** @brief DCOCLK clock selector. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Clock source.
* @details The clock source can be selected from:
* - @p MSP430_CLOCK_SOURCE_XT2CLK.
* - @p MSP430_CLOCK_SOURCE_DCOCLK.
* .
*/
#if !defined(MSP430_USE_CLOCK) || defined(__DOXYGEN__)
#define MSP430_USE_CLOCK MSP430_CLOCK_SOURCE_XT2CLK
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*
* Calculating the derived clock constants.
*/
#define ACLK LFXT1CLK
#if MSP430_USE_CLOCK == MSP430_CLOCK_SOURCE_XT2CLK
#define MCLK XT2CLK
#define SMCLK (XT2CLK / 8)
#elif MSP430_USE_CLOCK == MSP430_CLOCK_SOURCE_DCOCLK
#define MCLK DCOCLK
#define SMCLK DCOCLK
#else
#error "unknown clock source specified"
#endif
/*
* Calculating the initialization values.
*/
#define VAL_DCOCTL (DCO0 | DCO1)
#if MSP430_USE_CLOCK == MSP430_CLOCK_SOURCE_XT2CLK
#define VAL_BCSCTL1 (RSEL2)
#define VAL_BCSCTL2 (SELM_2 | DIVM_0 | DIVS_3 | SELS)
#endif
#if MSP430_USE_CLOCK == MSP430_CLOCK_SOURCE_DCOCLK
#define VAL_BCSCTL1 (XT2OFF | RSEL2)
#define VAL_BCSCTL2 (SELM_0 | DIVM_0 | DIVS_0)
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,146 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file MSP430/pal_lld.c
* @brief MSP430 Digital I/O low level driver code.
* @addtogroup MSP430_PAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief MSP430 I/O ports configuration.
*
* @param[in] config the MSP430 ports configuration
*
* @note The @p PxIFG, @p PxIE and @p PxSEL registers are cleared. @p PxOUT
* and @p PxDIR are configured as specified.
*/
void _pal_lld_init(const PALConfig *config) {
#if defined(__MSP430_HAS_PORT1__) || defined(__MSP430_HAS_PORT1_R__)
IOPORT1->iop_full.ie.reg_p = 0;
IOPORT1->iop_full.ifg.reg_p = 0;
IOPORT1->iop_full.sel.reg_p = 0;
IOPORT1->iop_common.out = config->P1Data.out;
IOPORT1->iop_common.dir = config->P1Data.dir;
#endif
#if defined(__MSP430_HAS_PORT2__) || defined(__MSP430_HAS_PORT2_R__)
IOPORT2->iop_full.ie.reg_p = 0;
IOPORT2->iop_full.ifg.reg_p = 0;
IOPORT2->iop_full.sel.reg_p = 0;
IOPORT2->iop_common.out = config->P2Data.out;
IOPORT2->iop_common.dir = config->P2Data.dir;
#endif
#if defined(__MSP430_HAS_PORT3__) || defined(__MSP430_HAS_PORT3_R__)
IOPORT3->iop_simple.sel.reg_p = 0;
IOPORT3->iop_common.out = config->P3Data.out;
IOPORT3->iop_common.dir = config->P3Data.dir;
#endif
#if defined(__MSP430_HAS_PORT4__) || defined(__MSP430_HAS_PORT4_R__)
IOPORT4->iop_simple.sel.reg_p = 0;
IOPORT4->iop_common.out = config->P4Data.out;
IOPORT4->iop_common.dir = config->P4Data.dir;
#endif
#if defined(__MSP430_HAS_PORT5__) || defined(__MSP430_HAS_PORT5_R__)
IOPORT5->iop_simple.sel.reg_p = 0;
IOPORT5->iop_common.out = config->P5Data.out;
IOPORT5->iop_common.dir = config->P5Data.dir;
#endif
#if defined(__MSP430_HAS_PORT6__) || defined(__MSP430_HAS_PORT6_R__)
IOPORT6->iop_simple.sel.reg_p = 0;
IOPORT6->iop_common.out = config->P6Data.out;
IOPORT6->iop_common.dir = config->P6Data.dir;
#endif
}
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @note @p PAL_MODE_UNCONNECTED is implemented as output as recommended by
* the MSP430x1xx Family User's Guide. Unconnected pads are set to
* high logic state by default.
* @note This function does not alter the @p PxSEL registers. Alternate
* functions setup must be handled by device-specific code.
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode) {
switch (mode) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT:
port->iop_common.dir.reg_p &= ~mask;
break;
case PAL_MODE_UNCONNECTED:
port->iop_common.out.reg_p |= mask;
case PAL_MODE_OUTPUT_PUSHPULL:
port->iop_common.dir.reg_p |= mask;
break;
}
}
#endif /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,304 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file MSP430/pal_lld.h
* @brief MSP430 Digital I/O low level driver header.
* @addtogroup MSP430_PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Unsupported modes and specific modes */
/*===========================================================================*/
#undef PAL_MODE_INPUT_PULLUP
#undef PAL_MODE_INPUT_PULLDOWN
#undef PAL_MODE_INPUT_ANALOG
#undef PAL_MODE_OUTPUT_OPENDRAIN
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @brief Simplified MSP430 I/O port representation.
* @details This structure represents the common part of all the MSP430 I/O
* ports.
*/
struct port_common_t {
ioregister_t in;
ioregister_t out;
ioregister_t dir;
};
/**
* @brief Generic MSP430 I/O port.
*/
union __ioport {
struct port_common_t iop_common;
struct port_simple_t iop_simple;
struct port_full_t iop_full;
};
/**
* @brief Setup registers common to all the MSP430 ports.
*/
typedef struct {
ioregister_t out;
ioregister_t dir;
} msp430_dio_setup_t;
/**
* @brief MSP430 I/O ports 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 {
#if defined(__MSP430_HAS_PORT1__) || \
defined(__MSP430_HAS_PORT1_R__) || \
defined(__DOXYGEN__)
/** @brief Port 1 setup data.*/
msp430_dio_setup_t P1Data;
#endif
#if defined(__MSP430_HAS_PORT2__) || \
defined(__MSP430_HAS_PORT2_R__) || \
defined(__DOXYGEN__)
/** @brief Port 2 setup data.*/
msp430_dio_setup_t P2Data;
#endif
#if defined(__MSP430_HAS_PORT3__) || \
defined(__MSP430_HAS_PORT3_R__) || \
defined(__DOXYGEN__)
/** @brief Port 3 setup data.*/
msp430_dio_setup_t P3Data;
#endif
#if defined(__MSP430_HAS_PORT4__) || \
defined(__MSP430_HAS_PORT4_R__) || \
defined(__DOXYGEN__)
/** @brief Port 4 setup data.*/
msp430_dio_setup_t P4Data;
#endif
#if defined(__MSP430_HAS_PORT5__) || \
defined(__MSP430_HAS_PORT5_R__) || \
defined(__DOXYGEN__)
/** @brief Port 5 setup data.*/
msp430_dio_setup_t P5Data;
#endif
#if defined(__MSP430_HAS_PORT6__) || \
defined(__MSP430_HAS_PORT6_R__) || \
defined(__DOXYGEN__)
/** @brief Port 6 setup data.*/
msp430_dio_setup_t P6Data;
#endif
} PALConfig;
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 8
/**
* @brief Whole port mask.
* @brief This macro specifies all the valid bits into a port.
*/
#define PAL_WHOLE_PORT ((ioportmask_t)0xFF)
/**
* @brief Digital I/O port sized unsigned type.
*/
typedef uint8_t ioportmask_t;
/**
* @brief Port Identifier.
* @details This type can be a scalar or some kind of pointer, do not make
* any assumption about it, use the provided macros when populating
* variables of this type.
*/
typedef union __ioport * ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief I/O port A identifier.
* @details This port identifier is mapped on the MSP430 port 1 (P1).
*/
#if defined(__MSP430_HAS_PORT1__) || \
defined(__MSP430_HAS_PORT1_R__) || \
defined(__DOXYGEN__)
#define IOPORT1 ((ioportid_t)0x0020)
#endif
/**
* @brief I/O port B identifier.
* @details This port identifier is mapped on the MSP430 port 2 (P2).
*/
#if defined(__MSP430_HAS_PORT2__) || \
defined(__MSP430_HAS_PORT2_R__) || \
defined(__DOXYGEN__)
#define IOPORT2 ((ioportid_t)0x0028)
#endif
/**
* @brief I/O port C identifier.
* @details This port identifier is mapped on the MSP430 port 3 (P3).
*/
#if defined(__MSP430_HAS_PORT3__) || \
defined(__MSP430_HAS_PORT3_R__) || \
defined(__DOXYGEN__)
#define IOPORT3 ((ioportid_t)0x0018)
#endif
/**
* @brief I/O port D identifier.
* @details This port identifier is mapped on the MSP430 port 4 (P4).
*/
#if defined(__MSP430_HAS_PORT4__) || \
defined(__MSP430_HAS_PORT4_R__) || \
defined(__DOXYGEN__)
#define IOPORT4 ((ioportid_t)0x001c)
#endif
/**
* @brief I/O port E identifier.
* @details This port identifier is mapped on the MSP430 port 5 (P5).
*/
#if defined(__MSP430_HAS_PORT5__) || \
defined(__MSP430_HAS_PORT5_R__) || \
defined(__DOXYGEN__)
#define IOPORT5 ((ioportid_t)0x0030)
#endif
/**
* @brief I/O port F identifier.
* @details This port identifier is mapped on the MSP430 port 6 (P6).
*/
#if defined(__MSP430_HAS_PORT6__) || \
defined(__MSP430_HAS_PORT6_R__) || \
defined(__DOXYGEN__)
#define IOPORT6 ((ioportid_t)0x0034)
#endif
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in a file named pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
* @details In MSP430 programs all the ports as input.
*
* @param[in] config the MSP430 ports configuration
*/
#define pal_lld_init(config) _pal_lld_init(config)
/**
* @brief Reads the physical I/O port states.
* @details This function is implemented by reading the PxIN register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @return The port bits.
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_readport(port) ((port)->iop_common.in.reg_p)
/**
* @brief Reads the output latch.
* @details This function is implemented by reading the PxOUT register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @return The latched logical states.
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_readlatch(port) ((port)->iop_common.out.reg_p)
/**
* @brief Writes a bits mask on a I/O port.
* @details This function is implemented by writing the PxOUT register, the
* implementation has no side effects.
*
* @param[in] port the port identifier
* @param[in] bits the bits to be written on the specified port
*
* @note This function is not meant to be invoked directly by the application
* code.
*/
#define pal_lld_writeport(port, bits) { \
(port)->iop_common.out.reg_p = (bits); \
}
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @note @p PAL_MODE_UNCONNECTED is implemented as output as recommended by
* the MSP430x1xx Family User's Guide.
* @note This function does not alter the @p PxSEL registers. Alternate
* functions setup must be handled by device-specific code.
*/
#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
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,
uint_fast8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* _PAL_LLD_H_ */
#endif /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,74 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup MSP430_DRIVERS MSP430 Drivers
* @brief Device drivers included in the MSP430 support.
*
* @ingroup MSP430
*/
/**
* @defgroup MSP430_HAL MSP430 HAL Support
* @brief HAL support.
*
* @ingroup MSP430_DRIVERS
*/
/**
* @defgroup MSP430_PAL MSP430 I/O Ports Support
* @brief I/O Ports peripherals support.
* @details This module supports the MSP430 Digital I/O controller. The
* controller supports the following features (see @ref PAL):
* - 8 bits wide ports.
* - Atomic set/reset/toggle functions because special MSP430 instruction set.
* - Output latched regardless of the pad setting.
* - Direct read of input pads regardless of the pad setting.
* .
* <h2>Supported Setup Modes</h2>
* - @p PAL_MODE_RESET.
* - @p PAL_MODE_UNCONNECTED.
* - @p PAL_MODE_INPUT.
* - @p PAL_MODE_OUTPUT_PUSHPULL.
* .
* Any attempt to setup an invalid mode is ignored.
*
* <h2>Suboptimal Behavior</h2>
* Some MSP430 I/O ports features are less than optimal:
* - Bus/group writing is not atomic.
* - Pad/group mode setup is not atomic.
* .
* @ingroup MSP430_DRIVERS
*/
/**
* @defgroup MSP430_SERIAL MSP430 USART Support
* @brief USART support.
* @details The serial driver supports both the MSP430 USARTs in asynchronous
* mode.
*
* @ingroup MSP430_DRIVERS
*/

View File

@@ -0,0 +1,7 @@
# List of all the MSP430 platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/MSP430/hal_lld.c \
${CHIBIOS}/os/hal/platforms/MSP430/pal_lld.c \
${CHIBIOS}/os/hal/platforms/MSP430/serial_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/MSP430

View File

@@ -0,0 +1,316 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file MSP430/serial_lld.c
* @brief MSP430 low level serial driver code.
*
* @addtogroup MSP430_SERIAL
* @{
*/
#include <signal.h>
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
#if USE_MSP430_USART0 || defined(__DOXYGEN__)
/** @brief USART0 serial driver identifier.*/
SerialDriver SD1;
#endif
#if USE_MSP430_USART1 || defined(__DOXYGEN__)
/** @brief USART1 serial driver identifier.*/
SerialDriver SD2;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/** @brief Driver default configuration.*/
static const SerialConfig default_config = {
UBR(SERIAL_DEFAULT_BITRATE),
0,
CHAR
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void set_error(SerialDriver *sdp, uint8_t urctl) {
sdflags_t sts = 0;
if (urctl & OE)
sts |= SD_OVERRUN_ERROR;
if (urctl & PE)
sts |= SD_PARITY_ERROR;
if (urctl & FE)
sts |= SD_FRAMING_ERROR;
if (urctl & BRK)
sts |= SD_BREAK_DETECTED;
chSysLockFromIsr();
sdAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
#if USE_MSP430_USART0 || defined(__DOXYGEN__)
static void notify1(void) {
if (!(U0IE & UTXIE0)) {
msg_t b = sdRequestDataI(&SD1);
if (b != Q_EMPTY) {
U0IE |= UTXIE0;
U0TXBUF = (uint8_t)b;
}
}
}
/**
* @brief USART0 initialization.
*
* @param[in] config the architecture-dependent serial driver configuration
*/
static void usart0_init(const SerialConfig *config) {
U0CTL = SWRST; /* Resets the USART. */
/* USART init */
U0TCTL = SSEL0 | SSEL1; /* SMCLK as clock source. */
U0MCTL = config->sc_mod; /* Modulator. */
U0BR1 = (uint8_t)(config->sc_div >> 8); /* Divider high. */
U0BR0 = (uint8_t)(config->sc_div >> 0); /* Divider low. */
/* Clear USART status.*/
(void)U0RXBUF;
U0RCTL = 0;
/* USART enable.*/
U0ME |= UTXE0 + URXE0; /* Enables the USART. */
U0CTL = config->sc_ctl & ~SWRST; /* Various settings. */
U0IE |= URXIE0; /* Enables RX interrupt. */
}
/**
* @brief USART0 de-initialization.
*/
static void usart0_deinit(void) {
U0IE &= ~URXIE0;
U0CTL = SWRST;
}
#endif /* USE_MSP430_USART0 */
#if USE_MSP430_USART1 || defined(__DOXYGEN__)
static void notify2(void) {
if (!(U1IE & UTXIE1)) {
msg_t b = sdRequestDataI(&SD2);
if (b != Q_EMPTY) {
U1IE |= UTXIE1;
U1TXBUF = (uint8_t)b;
}
}
}
/**
* @brief USART1 initialization.
*
* @param[in] config the architecture-dependent serial driver configuration
*/
static void usart1_init(const SerialConfig *config) {
U1CTL = SWRST; /* Resets the USART. */
/* USART init.*/
U1TCTL = SSEL0 | SSEL1; /* SMCLK as clock source. */
U1MCTL = config->sc_mod; /* Modulator. */
U1BR1 = (uint8_t)(config->sc_div >> 8); /* Divider high. */
U1BR0 = (uint8_t)(config->sc_div >> 0); /* Divider low. */
/* Clear USART status.*/
(void)U0RXBUF;
U1RCTL = 0;
/* USART enable.*/
U1ME |= UTXE0 + URXE0; /* Enables the USART. */
U1CTL = config->sc_ctl & ~SWRST; /* Various settings. */
U1IE |= URXIE0; /* Enables RX interrupt. */
}
/**
* @brief USART1 de-initialization.
*/
static void usart1_deinit(void) {
U1IE &= ~URXIE0;
U1CTL = SWRST;
}
#endif /* USE_MSP430_USART1 */
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if USE_MSP430_USART0 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(USART0TX_VECTOR) {
msg_t b;
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
b = sdRequestDataI(&SD1);
chSysUnlockFromIsr();
if (b < Q_OK)
U0IE &= ~UTXIE0;
else
U0TXBUF = b;
CH_IRQ_EPILOGUE();
}
CH_IRQ_HANDLER(USART0RX_VECTOR) {
uint8_t urctl;
CH_IRQ_PROLOGUE();
if ((urctl = U0RCTL) & RXERR)
set_error(&SD1, urctl);
chSysLockFromIsr();
sdIncomingDataI(&SD1, U0RXBUF);
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
}
#endif /* USE_MSP430_USART0 */
#if USE_MSP430_USART1 || defined(__DOXYGEN__)
CH_IRQ_HANDLER(USART1TX_VECTOR) {
msg_t b;
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
b = sdRequestDataI(&SD2);
chSysUnlockFromIsr();
if (b < Q_OK)
U1IE &= ~UTXIE1;
else
U1TXBUF = b;
CH_IRQ_EPILOGUE();
}
CH_IRQ_HANDLER(USART1RX_VECTOR) {
uint8_t urctl;
CH_IRQ_PROLOGUE();
if ((urctl = U1RCTL) & RXERR)
set_error(&SD2, urctl);
chSysLockFromIsr();
sdIncomingDataI(&SD2, U1RXBUF);
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
}
#endif /* USE_MSP430_USART1 */
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_MSP430_USART0
sdObjectInit(&SD1, NULL, notify1);
/* I/O pins for USART0.*/
P3SEL |= BV(4) + BV(5);
#endif
#if USE_MSP430_USART1
sdObjectInit(&SD2, NULL, notify2);
/* I/O pins for USART1.*/
P3SEL |= BV(6) + BV(7);
#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.
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
#if USE_MSP430_USART0
if (&SD1 == sdp) {
usart0_init(config);
return;
}
#endif
#if USE_MSP430_USART1
if (&SD2 == sdp) {
usart1_init(config);
return;
}
#endif
}
/**
* @brief Low level serial driver stop.
* @details De-initializes the USART, stops the associated clock, resets the
* interrupt vector.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
void sd_lld_stop(SerialDriver *sdp) {
#if USE_MSP430_USART0
if (&SD1 == sdp) {
usart0_deinit();
return;
}
#endif
#if USE_MSP430_USART1
if (&SD2 == sdp) {
usart1_deinit();
return;
}
#endif
}
#endif /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,155 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file MSP430/serial_lld.h
* @brief MSP430 low level serial driver header.
*
* @addtogroup MSP430_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief USART0 driver enable switch.
* @details If set to @p TRUE the support for USART0 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_MSP430_USART0) || defined(__DOXYGEN__)
#define USE_MSP430_USART0 TRUE
#endif
/**
* @brief USART1 driver enable switch.
* @details If set to @p TRUE the support for USART1 is included.
* @note The default is @p FALSE.
*/
#if !defined(USE_MSP430_USART1) || defined(__DOXYGEN__)
#define USE_MSP430_USART1 TRUE
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Serial Driver condition flags type.
*/
typedef uint8_t sdflags_t;
/**
* @brief MSP430 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 Initialization value for the UBRx registers.
*/
uint16_t sc_div;
/**
* @brief Initialization value for the MOD register.
*/
uint8_t sc_mod;
/**
* @brief Initialization value for the CTL register.
*/
uint8_t sc_ctl;
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Macro for baud rate computation.
* @note Make sure the final baud rate is within tolerance.
*/
#define UBR(b) (SMCLK / (b))
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_MSP430_USART0 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if USE_MSP430_USART1 && !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 /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,133 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file console.c
* @brief Simulator console driver code.
* @{
*/
#include <stdio.h>
#include "ch.h"
#include "console.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief Console driver 1.
*/
BaseChannel CD1;
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static size_t writes(void *ip, const uint8_t *bp, size_t n) {
size_t ret;
(void)ip;
ret = fwrite(bp, 1, n, stdout);
fflush(stdout);
return ret;
}
static size_t reads(void *ip, uint8_t *bp, size_t n) {
(void)ip;
return fread(bp, 1, n, stdin);
}
static bool_t putwouldblock(void *ip) {
(void)ip;
return FALSE;
}
static bool_t getwouldblock(void *ip) {
(void)ip;
return TRUE;
}
static msg_t putt(void *ip, uint8_t b, systime_t time) {
(void)ip;
(void)time;
fputc(b, stdout);
fflush(stdout);
return RDY_OK;
}
static msg_t gett(void *ip, systime_t time) {
(void)ip;
(void)time;
return fgetc(stdin);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
size_t ret;
(void)ip;
(void)time;
ret = fwrite(bp, 1, n, stdout);
fflush(stdout);
return ret;
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
(void)ip;
(void)time;
return fread(bp, 1, n, stdin);
}
static const struct BaseChannelVMT vmt = {
writes, reads, putwouldblock, getwouldblock, putt, gett, writet, readt
};
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
void conInit(void) {
CD1.vmt = &vmt;
}
/** @} */

View File

@@ -0,0 +1,72 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file console.h
* @brief Simulator console driver header.
* @{
*/
#ifndef _CONSOLE_H_
#define _CONSOLE_H_
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
extern BaseChannel CD1;
#ifdef __cplusplus
extern "C" {
#endif
void conInit(void);
#ifdef __cplusplus
}
#endif
#endif /* _CONSOLE_H_ */
/** @} */

View File

@@ -0,0 +1,113 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file Posix/hal_lld.c
* @brief Posix HAL subsystem low level driver code.
*
* @addtogroup POSIX_HAL
* @{
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
static struct timeval nextcnt;
static struct timeval tick = {0, 1000000 / CH_FREQUENCY};
/**
* @brief PAL setup.
* @details Digital I/O ports static configuration as defined in @p board.h.
*/
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
const PALConfig pal_default_config = {
{0, 0, 0},
{0, 0, 0}
};
#endif
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
#if defined(__APPLE__)
puts("ChibiOS/RT simulator (OS X)\n");
#else
puts("ChibiOS/RT simulator (Linux)\n");
#endif
gettimeofday(&nextcnt, NULL);
timeradd(&nextcnt, &tick, &nextcnt);
}
/**
* @brief Interrupt simulation.
*/
void ChkIntSources(void) {
struct timeval tv;
#if CH_HAL_USE_SERIAL
if (sd_lld_interrupt_pending()) {
if (chSchIsRescRequiredExI())
chSchDoRescheduleI();
return;
}
#endif
gettimeofday(&tv, NULL);
if (timercmp(&tv, &nextcnt, >=)) {
timeradd(&nextcnt, &tick, &nextcnt);
chSysTimerHandlerI();
if (chSchIsRescRequiredExI())
chSchDoRescheduleI();
}
}
/** @} */

View File

@@ -0,0 +1,85 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file Posix/hal_lld.h
* @brief Posix simulator HAL subsystem low level driver header.
*
* @addtogroup POSIX_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "Linux"
#define SOCKET int
#define INVALID_SOCKET -1
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* 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 ChkIntSources(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,105 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file Posix/pal_lld.c
* @brief Posix low level simulated PAL driver code.
*
* @addtogroup POSIX_PAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_PAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief VIO1 simulated port.
*/
sim_vio_port_t vio_port_1;
/**
* @brief VIO2 simulated port.
*/
sim_vio_port_t vio_port_2;
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Pads mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
*
* @param[in] port the port identifier
* @param[in] mask the group mask
* @param[in] mode the mode
*
* @note This function is not meant to be invoked directly by the application
* code.
* @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.
*/
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode) {
switch (mode) {
case PAL_MODE_RESET:
case PAL_MODE_INPUT:
port->dir &= ~mask;
break;
case PAL_MODE_UNCONNECTED:
port->latch |= mask;
case PAL_MODE_OUTPUT_PUSHPULL:
port->dir |= mask;
break;
}
}
#endif /* CH_HAL_USE_PAL */
/** @} */

View File

@@ -0,0 +1,210 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file Posix/pal_lld.h
* @brief Posix low level simulated PAL driver header.
*
* @addtogroup POSIX_PAL
* @{
*/
#ifndef _PAL_LLD_H_
#define _PAL_LLD_H_
#if CH_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
#undef PAL_MODE_INPUT_ANALOG
/*===========================================================================*/
/* I/O Ports Types and constants. */
/*===========================================================================*/
/**
* @brief VIO port structure.
*/
typedef struct {
/**
* @brief VIO_LATCH register.
* @details This register represents the output latch of the VIO port.
*/
uint32_t latch;
/**
* @brief VIO_PIN register.
* @details This register represents the logical level at the VIO port
* pin level.
*/
uint32_t pin;
/**
* @brief VIO_DIR register.
* @details Direction of the VIO port bits, 0=input, 1=output.
*/
uint32_t dir;
} sim_vio_port_t;
/**
* @brief Virtual I/O ports static initializer.
* @details An instance of this structure must be passed to @p palInit() at
* system startup time in order to initialized 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 Virtual port 1 setup data.
*/
sim_vio_port_t VP1Data;
/**
* @brief Virtual port 2 setup data.
*/
sim_vio_port_t VP2Data;
} PALConfig;
/**
* @brief Width, in bits, of an I/O port.
*/
#define PAL_IOPORTS_WIDTH 32
/**
* @brief Whole port mask.
* @brief 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 Port Identifier.
*/
typedef sim_vio_port_t *ioportid_t;
/*===========================================================================*/
/* I/O Ports Identifiers. */
/*===========================================================================*/
/**
* @brief VIO port 1 identifier.
*/
#define IOPORT1 (&vio_port_1)
/**
* @brief VIO port 2 identifier.
*/
#define IOPORT2 (&vio_port_2)
/*===========================================================================*/
/* Implementation, some of the following macros could be implemented as */
/* functions, if so please put them in pal_lld.c. */
/*===========================================================================*/
/**
* @brief Low level PAL subsystem initialization.
*
* @param[in] config architecture-dependent ports configuration
*/
#define pal_lld_init(config) { \
vio_port_1 = (config)->VP1Data; \
vio_port_2 = (config)->VP2Data; \
}
/**
* @brief Reads the physical I/O port states.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @return The port bits.
*/
#define pal_lld_readport(port) ((port)->pin)
/**
* @brief Reads the output latch.
* @details The purpose of this function is to read back the latched output
* value.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @return The latched logical states.
*/
#define pal_lld_readlatch(port) ((port)->latch)
/**
* @brief Writes a bits mask on a I/O port.
* @note This function is not meant to be invoked directly by the
* application code.
*
* @param[in] port port identifier
* @param[in] bits bits to be written on the specified port
*/
#define pal_lld_writeport(port, bits) ((port)->latch = (bits))
/**
* @brief Pads group mode setup.
* @details This function programs a pads group belonging to the same port
* with the specified mode.
* @note This function is not meant to be invoked directly by the
* application code.
* @note Programming an unknown or unsupported mode is silently ignored.
*
* @param[in] port port identifier
* @param[in] mask group mask
* @param[in] mode group mode
*/
#define pal_lld_setgroupmode(port, mask, mode) \
_pal_lld_setgroupmode(port, mask, mode)
#if !defined(__DOXYGEN__)
extern sim_vio_port_t vio_port_1;
extern sim_vio_port_t vio_port_2;
extern const PALConfig pal_default_config;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void _pal_lld_setgroupmode(ioportid_t port,
ioportmask_t mask,
uint_fast8_t mode);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_PAL */
#endif /* _PAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,7 @@
# List of all the Posix platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/Posix/hal_lld.c \
${CHIBIOS}/os/hal/platforms/Posix/pal_lld.c \
${CHIBIOS}/os/hal/platforms/Posix/serial_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/Posix

View File

@@ -0,0 +1,273 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file Posix/serial_lld.c
* @brief Posix low level simulated serial driver code.
*
* @addtogroup POSIX_SERIAL
* @{
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief Serial driver 1 identifier.*/
#if USE_SIM_SERIAL1 || defined(__DOXYGEN__)
SerialDriver SD1;
#endif
/** @brief Serial driver 2 identifier.*/
#if USE_SIM_SERIAL2 || defined(__DOXYGEN__)
SerialDriver SD2;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/** @brief Driver default configuration.*/
static const SerialConfig default_config = {
};
static u_long nb = 1;
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void init(SerialDriver *sdp, uint16_t port) {
struct sockaddr_in sad;
struct protoent *prtp;
if ((prtp = getprotobyname("tcp")) == NULL) {
printf("%s: Error mapping protocol name to protocol number\n", sdp->com_name);
goto abort;
}
sdp->com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
if (sdp->com_listen == INVALID_SOCKET) {
printf("%s: Error creating simulator socket\n", sdp->com_name);
goto abort;
}
if (ioctl(sdp->com_listen, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on socket\n", sdp->com_name);
goto abort;
}
memset(&sad, 0, sizeof(sad));
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons(port);
if (bind(sdp->com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
printf("%s: Error binding socket\n", sdp->com_name);
goto abort;
}
if (listen(sdp->com_listen, 1) != 0) {
printf("%s: Error listening socket\n", sdp->com_name);
goto abort;
}
printf("Full Duplex Channel %s listening on port %d\n", sdp->com_name, port);
return;
abort:
if (sdp->com_listen != INVALID_SOCKET)
close(sdp->com_listen);
exit(1);
}
static bool_t connint(SerialDriver *sdp) {
if (sdp->com_data == INVALID_SOCKET) {
struct sockaddr addr;
socklen_t addrlen = sizeof(addr);
if ((sdp->com_data = accept(sdp->com_listen, &addr, &addrlen)) == INVALID_SOCKET)
return FALSE;
if (ioctl(sdp->com_data, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on data socket\n", sdp->com_name);
goto abort;
}
sdAddFlagsI(sdp, SD_CONNECTED);
return TRUE;
}
return FALSE;
abort:
if (sdp->com_listen != INVALID_SOCKET)
close(sdp->com_listen);
if (sdp->com_data != INVALID_SOCKET)
close(sdp->com_data);
exit(1);
}
static bool_t inint(SerialDriver *sdp) {
if (sdp->com_data != INVALID_SOCKET) {
int i;
uint8_t data[32];
/*
* Input.
*/
int n = recv(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
sdAddFlagsI(sdp, SD_DISCONNECTED);
return FALSE;
case INVALID_SOCKET:
if (errno == EWOULDBLOCK)
return FALSE;
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
for (i = 0; i < n; i++)
sdIncomingDataI(sdp, data[i]);
return TRUE;
}
return FALSE;
}
static bool_t outint(SerialDriver *sdp) {
if (sdp->com_data != INVALID_SOCKET) {
int n;
uint8_t data[1];
/*
* Input.
*/
n = sdRequestDataI(sdp);
if (n < 0)
return FALSE;
data[0] = (uint8_t)n;
n = send(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
sdAddFlagsI(sdp, SD_DISCONNECTED);
return FALSE;
case INVALID_SOCKET:
if (errno == EWOULDBLOCK)
return FALSE;
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
return TRUE;
}
return FALSE;
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_SIM_SERIAL1
sdObjectInit(&SD1, NULL, NULL);
SD1.com_listen = INVALID_SOCKET;
SD1.com_data = INVALID_SOCKET;
SD1.com_name = "SD1";
#endif
#if USE_SIM_SERIAL2
sdObjectInit(&SD2, NULL, NULL);
SD2.com_listen = INVALID_SOCKET;
SD2.com_data = INVALID_SOCKET;
SD2.com_name = "SD2";
#endif
}
/**
* @brief Low level serial driver configuration and (re)start.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
#if USE_SIM_SERIAL1
if (sdp == &SD1)
init(&SD1, SIM_SD1_PORT);
#endif
#if USE_SIM_SERIAL2
if (sdp == &SD2)
init(&SD2, SIM_SD2_PORT);
#endif
}
/**
* @brief Low level serial driver stop.
* @details De-initializes the USART, stops the associated clock, resets the
* interrupt vector.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
void sd_lld_stop(SerialDriver *sdp) {
(void)sdp;
}
bool_t sd_lld_interrupt_pending(void) {
return connint(&SD1) || connint(&SD2) ||
inint(&SD1) || inint(&SD2) ||
outint(&SD1) || outint(&SD2);
}
#endif /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,170 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file Posix/serial_lld.h
* @brief Posix low level simulated serial driver header.
*
* @addtogroup POSIX_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Serial buffers size.
* @details Configuration parameter, you can change the depth of the queue
* buffers depending on the requirements of your application.
*/
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
#define SERIAL_BUFFERS_SIZE 1024
#endif
/**
* @brief SD1 driver enable switch.
* @details If set to @p TRUE the support for SD1 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SIM_SERIAL1) || defined(__DOXYGEN__)
#define USE_SIM_SERIAL1 TRUE
#endif
/**
* @brief SD2 driver enable switch.
* @details If set to @p TRUE the support for SD2 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SIM_SERIAL2) || defined(__DOXYGEN__)
#define USE_SIM_SERIAL2 TRUE
#endif
/**
* @brief Listen port for SD1.
*/
#if !defined(SD1_PORT) || defined(__DOXYGEN__)
#define SIM_SD1_PORT 29001
#endif
/**
* @brief Listen port for SD2.
*/
#if !defined(SD2_PORT) || defined(__DOXYGEN__)
#define SIM_SD2_PORT 29002
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Serial Driver condition flags type.
*/
typedef uint32_t sdflags_t;
/**
* @brief Generic 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.
* @note This structure content is architecture dependent, each driver
* implementation defines its own version and the custom static
* initializers.
*/
typedef struct {
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Listen socket for simulated serial port.*/ \
SOCKET com_listen; \
/* Data socket for simulated serial port.*/ \
SOCKET com_data; \
/* Port readable name.*/ \
const char *com_name;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_SIM_SERIAL1 && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if USE_SIM_SERIAL2 && !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);
bool_t sd_lld_interrupt_pending(void);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,132 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file SPC56x/hal_lld.c
* @brief SPC563 HAL subsystem low level driver source.
*
* @addtogroup SPC563_HAL
* @{
*/
#include "ch.h"
#include "hal.h"
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level HAL driver initialization.
*/
void hal_lld_init(void) {
extern void _vectors(void);
uint32_t n;
/* Enables the branch prediction, clears and enables the BTB into the
BUCSR special register (1013).*/
asm volatile ("li %%r3, 0x0201 \t\n"
"mtspr 1013, %%r3": : : "r3");
/* FLASH wait states and prefetching setup.*/
CFLASH0.BIUCR.R = SPC563_FLASH_BIUCR | SPC563_FLASH_WS;
CFLASH0.BIUCR2.R = 0;
CFLASH0.PFCR3.R = 0;
/* Optimal crossbar settings. The DMA priority is placed above the CPU
priority in order to not starve I/O activities while the CPU is
excuting tight loops (FLASH and SRAM slave ports only).
The SRAM is parked on the load/store port, for some unknown reason it
is defaulted on the instructions port and this kills performance.*/
XBAR.SGPCR3.B.PARK = 4; /* RAM slave on load/store port.*/
XBAR.MPR0.R = 0x00030201; /* Flash slave port priorities:
eDMA (1): 0 (highest)
Core Instructions (0): 1
Undocumented (2): 2
Core Data (4): 3 */
XBAR.MPR3.R = 0x00030201; /* SRAM slave port priorities:
eDMA (1): 0 (highest)
Core Instructions (0): 1
Undocumented (2): 2
Core Data (4): 3 */
/* Downcounter timer initialized for system tick use, TB enabled for debug
and measurements.*/
n = SPC563_SYSCLK / CH_FREQUENCY;
asm volatile ("li %%r3, 0 \t\n"
"mtspr 284, %%r3 \t\n" /* Clear TBL register. */
"mtspr 285, %%r3 \t\n" /* Clear TBU register. */
"mtspr 22, %[n] \t\n" /* Init. DEC register. */
"mtspr 54, %[n] \t\n" /* Init. DECAR register.*/
"li %%r3, 0x4000 \t\n" /* TBEN bit. */
"mtspr 1008, %%r3 \t\n" /* HID0 register. */
"lis %%r3, 0x0440 \t\n" /* DIE ARE bits. */
"mtspr 340, %%r3" /* TCR register. */
: : [n] "r" (n) : "r3");
/* INTC initialization, software vector mode, 4 bytes vectors, starting
at priority 0.*/
INTC.MCR.R = 0;
INTC.CPR.R = 0;
INTC.IACKR.R = (uint32_t)_vectors;
}
/**
* @brief SPC563 clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h and
* @p hal_lld.h
*/
void spc563_clock_init(void) {
/* PLL activation.*/
FMPLL.ESYNCR1.B.EMODE = 1;
FMPLL.ESYNCR1.B.CLKCFG &= 1; /* Bypass mode, PLL off.*/
FMPLL.ESYNCR1.B.CLKCFG |= 2; /* PLL on. */
FMPLL.ESYNCR1.B.EPREDIV = SPC563_CLK_PREDIV;
FMPLL.ESYNCR1.B.EMFD = SPC563_CLK_MFD;
FMPLL.ESYNCR2.B.ERFD = SPC563_CLK_RFD;
while (!FMPLL.SYNSR.B.LOCK)
;
FMPLL.ESYNCR1.B.CLKCFG |= 4; /* Clock from the PLL. */
}
/** @} */

View File

@@ -0,0 +1,231 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file SPC56x/hal_lld.h
* @brief SPC563 HAL subsystem low level driver header.
*
* @addtogroup SPC563_HAL
* @{
*/
#ifndef _HAL_LLD_H_
#define _HAL_LLD_H_
#include "mpc563m.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief Platform name.
*/
#define PLATFORM_NAME "SPC563M64"
#define RFD_DIV2 0 /**< Divide VCO frequency by 2. */
#define RFD_DIV4 1 /**< Divide VCO frequency by 4. */
#define RFD_DIV8 2 /**< Divide VCO frequency by 8. */
#define RFD_DIV16 3 /**< Divide VCO frequency by 16.*/
/* The following settings are related to the FLASH controller, performance
and stability depends on them, be careful.*/
#define BIUCR_BANK1_TOO 0x01000000 /**< Use settings for bank1 too.*/
#define BIUCR_MASTER7_PREFETCH 0x00800000 /**< Enable master 7 prefetch. */
#define BIUCR_MASTER6_PREFETCH 0x00400000 /**< Enable master 6 prefetch. */
#define BIUCR_MASTER5_PREFETCH 0x00200000 /**< Enable master 5 prefetch. */
#define BIUCR_MASTER4_PREFETCH 0x00100000 /**< Enable master 4 prefetch. */
#define BIUCR_MASTER3_PREFETCH 0x00080000 /**< Enable master 3 prefetch. */
#define BIUCR_MASTER2_PREFETCH 0x00040000 /**< Enable master 2 prefetch. */
#define BIUCR_MASTER1_PREFETCH 0x00020000 /**< Enable master 1 prefetch. */
#define BIUCR_MASTER0_PREFETCH 0x00010000 /**< Enable master 0 prefetch. */
#define BIUCR_APC_MASK 0x0000E000 /**< APC field mask. */
#define BIUCR_APC_0 (0 << 13) /**< No additional hold cycles. */
#define BIUCR_APC_1 (1 << 13) /**< 1 additional hold cycle. */
#define BIUCR_APC_2 (2 << 13) /**< 2 additional hold cycles. */
#define BIUCR_APC_3 (3 << 13) /**< 3 additional hold cycles. */
#define BIUCR_APC_4 (4 << 13) /**< 4 additional hold cycles. */
#define BIUCR_APC_5 (5 << 13) /**< 5 additional hold cycles. */
#define BIUCR_APC_6 (6 << 13) /**< 6 additional hold cycles. */
#define BIUCR_WWSC_MASK 0x00001800 /**< WWSC field mask. */
#define BIUCR_WWSC_0 (0 << 11) /**< No write wait states. */
#define BIUCR_WWSC_1 (1 << 11) /**< 1 write wait state. */
#define BIUCR_WWSC_2 (2 << 11) /**< 2 write wait states. */
#define BIUCR_WWSC_3 (3 << 11) /**< 3 write wait states. */
#define BIUCR_RWSC_MASK 0x00001800 /**< RWSC field mask. */
#define BIUCR_RWSC_0 (0 << 8) /**< No read wait states. */
#define BIUCR_RWSC_1 (1 << 8) /**< 1 read wait state. */
#define BIUCR_RWSC_2 (2 << 8) /**< 2 read wait states. */
#define BIUCR_RWSC_3 (3 << 8) /**< 3 read wait states. */
#define BIUCR_RWSC_4 (4 << 8) /**< 4 read wait states. */
#define BIUCR_RWSC_5 (5 << 8) /**< 5 read wait states. */
#define BIUCR_RWSC_6 (6 << 8) /**< 6 read wait states. */
#define BIUCR_RWSC_7 (7 << 8) /**< 7 read wait states. */
#define BIUCR_DPFEN 0x00000040 /**< Data prefetch enable. */
#define BIUCR_IPFEN 0x00000010 /**< Instr. prefetch enable. */
#define BIUCR_PFLIM_MASK 0x00000060 /**< PFLIM field mask. */
#define BIUCR_PFLIM_NO (0 << 1) /**< No prefetching. */
#define BIUCR_PFLIM_ON_MISS (1 << 1) /**< Prefetch on miss. */
#define BIUCR_PFLIM_ON_HITMISS (2 << 1) /**< Prefetch on hit and miss. */
#define BIUCR_BFEN 0x00000001 /**< Flash buffering enable. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief Clock bypass.
* @note If set to @p TRUE then the PLL is not started and initialized, the
* external clock is used as-is and the other clock-related settings
* are ignored.
*/
#if !defined(SPC563_CLK_BYPASS) || defined(__DOXYGEN__)
#define SPC563_CLK_BYPASS FALSE
#endif
/**
* @brief Disables the overclock checks.
*/
#if !defined(SPC563_ALLOW_OVERCLOCK) || defined(__DOXYGEN__)
#define SPC563_ALLOW_OVERCLOCK FALSE
#endif
/**
* @brief External clock pre-divider.
* @note Must be in range 0...14.
* @note The effective divider factor is this value plus one.
*/
#if !defined(SPC563_CLK_PREDIV) || defined(__DOXYGEN__)
#define SPC563_CLK_PREDIV 0
#endif
/**
* @brief Multiplication factor divider.
* @note Must be in range 32...96.
*/
#if !defined(SPC563_CLK_MFD) || defined(__DOXYGEN__)
#define SPC563_CLK_MFD 40
#endif
/**
* @brief Reduced frequency divider.
*/
#if !defined(SPC563_CLK_RFD) || defined(__DOXYGEN__)
#define SPC563_CLK_RFD RFD_DIV4
#endif
/**
* @brief Flash buffer and prefetching settings.
* @note Please refer to the SPC563M64 reference manual about the meaning
* of the following bits, if in doubt DO NOT MODIFY IT.
* @note Do not specify the APC, WWSC, RWSC bits in this value because
* those are calculated from the system clock and ORed with this
* value.
*/
#if !defined(SPC563_FLASH_BIUCR) || defined(__DOXYGEN__)
#define SPC563_FLASH_BIUCR (BIUCR_BANK1_TOO | \
BIUCR_MASTER4_PREFETCH | \
BIUCR_MASTER0_PREFETCH | \
BIUCR_DPFEN | \
BIUCR_IPFEN | \
BIUCR_PFLIM_ON_MISS | \
BIUCR_BFEN)
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
#if (SPC563_CLK_PREDIV < 0) || (SPC563_CLK_PREDIV > 14)
#error "invalid SPC563_CLK_PREDIV value specified"
#endif
#if (SPC563_CLK_MFD < 32) || (SPC563_CLK_MFD > 96)
#error "invalid SPC563_CLK_MFD value specified"
#endif
#if (SPC563_CLK_RFD != RFD_DIV2) && (SPC563_CLK_RFD != RFD_DIV4) && \
(SPC563_CLK_RFD != RFD_DIV8) && (SPC563_CLK_RFD != RFD_DIV16)
#error "invalid SPC563_CLK_RFD value specified"
#endif
/**
* @brief PLL output clock.
*/
#define SPC563_PLLCLK ((EXTCLK / (SPC563_CLK_PREDIV + 1)) * SPC563_CLK_MFD)
#if (SPC563_PLLCLK < 256000000) || (SPC563_PLLCLK > 512000000)
#error "VCO frequency out of the acceptable range (256...512)"
#endif
/**
* @brief PLL output clock.
*/
#if !SPC563_CLK_BYPASS || defined(__DOXYGEN__)
#define SPC563_SYSCLK (SPC563_PLLCLK / (1 << (SPC563_CLK_RFD + 1)))
#else
#define SPC563_SYSCLK EXTCLK
#endif
#if (SPC563_SYSCLK > 80000000) && !SPC563_ALLOW_OVERCLOCK
#error "System clock above maximum rated frequency (80MHz)"
#endif
/**
* @brief Flash wait states are a function of the system clock.
*/
#if (SPC563_SYSCLK <= 30000000) || defined(__DOXYGEN__)
#define SPC563_FLASH_WS (BIUCR_APC_0 | BIUCR_RWSC_0 | BIUCR_WWSC_1)
#elif SPC563_SYSCLK <= 60000000
#define SPC563_FLASH_WS (BIUCR_APC_1 | BIUCR_RWSC_1 | BIUCR_WWSC_1)
#else
#define SPC563_FLASH_WS (BIUCR_APC_2 | BIUCR_RWSC_2 | BIUCR_WWSC_1)
#endif
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
void hal_lld_init(void);
void spc563_clock_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _HAL_LLD_H_ */
/** @} */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @defgroup SPC563_DRIVERS SPC563 Drivers
* @brief Device drivers included in the SPC563 support.
*
* @ingroup PPC
*/
/**
* @defgroup SPC563_HAL SPC563 HAL Support
* @brief HAL support.
*
* @ingroup SPC563_DRIVERS
*/
/**
* @defgroup SPC563_SERIAL SPC563 ESCI Support
* @brief ESCI support.
* @details The serial driver supports both the SPC563 ESCIs in asynchronous
* mode.
*
* @ingroup SPC563_DRIVERS
*/

View File

@@ -0,0 +1,6 @@
# List of all the SPC56x platform files.
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/SPC56x/hal_lld.c \
${CHIBIOS}/os/hal/platforms/SPC56x/serial_lld.c
# Required include directories
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/SPC56x

View File

@@ -0,0 +1,302 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file SPC56x/serial_lld.c
* @brief SPC563 low level serial driver code.
*
* @addtogroup SPC563_SERIAL
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/**
* @brief eSCI-A serial driver identifier.
*/
#if USE_SPC563_ESCIA || defined(__DOXYGEN__)
SerialDriver SD1;
#endif
/**
* @brief eSCI-B serial driver identifier.
*/
#if USE_SPC563_ESCIB || defined(__DOXYGEN__)
SerialDriver SD2;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/**
* @brief Driver default configuration.
*/
static const SerialConfig default_config = {
SERIAL_DEFAULT_BITRATE,
SD_MODE_NORMAL | SD_MODE_PARITY_NONE
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/**
* @brief eSCI initialization.
* @details This function must be invoked with interrupts disabled.
*
* @param[in] sdp pointer to a @p SerialDriver object
* @param[in] config the architecture-dependent serial driver configuration
*/
static void esci_init(SerialDriver *sdp, const SerialConfig *config) {
volatile struct ESCI_tag *escip = sdp->escip;
uint8_t mode = config->sc_mode;
escip->CR2.R = 0; /* MDIS off. */
escip->CR1.R = 0;
escip->LCR.R = 0;
escip->CR1.B.SBR = SPC563_SYSCLK / (16 * config->sc_speed);
if (mode & SD_MODE_LOOPBACK)
escip->CR1.B.LOOPS = 1;
switch (mode & SD_MODE_PARITY) {
case SD_MODE_PARITY_ODD:
escip->CR1.B.PT = 1;
case SD_MODE_PARITY_EVEN:
escip->CR1.B.PE = 1;
escip->CR1.B.M = 1; /* Makes it 8 bits data + 1 bit parity. */
default:
;
}
escip->LPR.R = 0;
escip->CR1.R |= 0x0000002C; /* RIE, TE, RE to 1. */
escip->CR2.R |= 0x000F; /* ORIE, NFIE, FEIE, PFIE to 1. */
}
/**
* @brief eSCI de-initialization.
* @details This function must be invoked with interrupts disabled.
*
* @param[in] escip pointer to an eSCI I/O block
*/
static void esci_deinit(volatile struct ESCI_tag *escip) {
escip->LPR.R = 0;
escip->SR.R = 0xFFFFFFFF;
escip->CR1.R = 0;
escip->CR2.R = 0x8000; /* MDIS on. */
}
/**
* @brief Error handling routine.
*
* @param[in] sdp pointer to a @p SerialDriver object
* @param[in] sr eSCI SR register value
*/
static void set_error(SerialDriver *sdp, uint32_t sr) {
sdflags_t sts = 0;
if (sr & 0x08000000)
sts |= SD_OVERRUN_ERROR;
if (sr & 0x04000000)
sts |= SD_NOISE_ERROR;
if (sr & 0x02000000)
sts |= SD_FRAMING_ERROR;
if (sr & 0x01000000)
sts |= SD_PARITY_ERROR;
/* if (sr & 0x00000000)
sts |= SD_BREAK_DETECTED;*/
chSysLockFromIsr();
sdAddFlagsI(sdp, sts);
chSysUnlockFromIsr();
}
/**
* @brief Common IRQ handler.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
static void serve_interrupt(SerialDriver *sdp) {
volatile struct ESCI_tag *escip = sdp->escip;
uint32_t sr = escip->SR.R;
escip->SR.R = 0x3FFFFFFF; /* Does not clear TDRE | TC.*/
if (sr & 0x0F000000) /* OR | NF | FE | PF. */
set_error(sdp, sr);
if (sr & 0x20000000) { /* RDRF. */
chSysLockFromIsr();
sdIncomingDataI(sdp, escip->DR.B.D);
chSysUnlockFromIsr();
}
if (escip->CR1.B.TIE && (sr & 0x80000000)) { /* TDRE. */
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chEvtBroadcastI(&sdp->oevent);
escip->CR1.B.TIE = 0;
}
else {
ESCI_A.SR.B.TDRE = 1;
escip->DR.R = (uint16_t)b;
}
chSysUnlockFromIsr();
}
}
#if USE_SPC563_ESCIA || defined(__DOXYGEN__)
static void notify1(void) {
if (ESCI_A.SR.B.TDRE) {
msg_t b = sdRequestDataI(&SD1);
if (b != Q_EMPTY) {
ESCI_A.SR.B.TDRE = 1;
ESCI_A.CR1.B.TIE = 1;
ESCI_A.DR.R = (uint16_t)b;
}
}
/* if (!ESCI_A.CR1.B.TIE) {
msg_t b = sdRequestDataI(&SD1);
if (b != Q_EMPTY) {
ESCI_A.CR1.B.TIE = 1;
ESCI_A.DR.R = (uint16_t)b;
}
}*/
}
#endif
#if USE_SPC563_ESCIB || defined(__DOXYGEN__)
static void notify2(void) {
if (ESCI_B.SR.B.TDRE) {
msg_t b = sdRequestDataI(&SD2);
if (b != Q_EMPTY) {
ESCI_B.SR.B.TDRE = 1;
ESCI_B.CR1.B.TIE = 1;
ESCI_B.DR.R = (uint16_t)b;
}
}
/* if (!ESCI_B.CR1.B.TIE) {
msg_t b = sdRequestDataI(&SD2);
if (b != Q_EMPTY) {
ESCI_B.CR1.B.TIE = 1;
ESCI_B.DR.R = (uint16_t)b;
}
}*/
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if USE_SPC563_ESCIA || defined(__DOXYGEN__)
/**
* @brief eSCI-A interrupt handler.
*/
CH_IRQ_HANDLER(vector146) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD1);
CH_IRQ_EPILOGUE();
}
#endif
#if USE_SPC563_ESCIB || defined(__DOXYGEN__)
/**
* @brief eSCI-B interrupt handler.
*/
CH_IRQ_HANDLER(vector149) {
CH_IRQ_PROLOGUE();
serve_interrupt(&SD2);
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level serial driver initialization.
*/
void sd_lld_init(void) {
#if USE_SPC563_ESCIA
sdObjectInit(&SD1, NULL, notify1);
SD1.escip = &ESCI_A;
ESCI_A.CR2.R = 0x8000; /* MDIS ON. */
INTC.PSR[146].R = SPC563_ESCIA_PRIORITY;
#endif
#if USE_SPC563_ESCIB
sdObjectInit(&SD2, NULL, notify2);
SD2.escip = &ESCI_B;
ESCI_B.CR2.R = 0x8000; /* MDIS ON. */
INTC.PSR[149].R = SPC563_ESCIB_PRIORITY;
#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.
*/
void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) {
if (config == NULL)
config = &default_config;
esci_init(sdp, config);
}
/**
* @brief Low level serial driver stop.
*
* @param[in] sdp pointer to a @p SerialDriver object
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->state == SD_READY)
esci_deinit(sdp->escip);
}
#endif /* CH_HAL_USE_SERIAL */
/** @} */

View File

@@ -0,0 +1,172 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file SPC56x/serial_lld.h
* @brief SPC563 low level serial driver header.
*
* @addtogroup SPC563_SERIAL
* @{
*/
#ifndef _SERIAL_LLD_H_
#define _SERIAL_LLD_H_
#if CH_HAL_USE_SERIAL || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define SD_MODE_PARITY 0x03 /**< @brief Parity field mask. */
#define SD_MODE_PARITY_NONE 0x00 /**< @brief No parity. */
#define SD_MODE_PARITY_EVEN 0x01 /**< @brief Even parity. */
#define SD_MODE_PARITY_ODD 0x02 /**< @brief Odd parity. */
#define SD_MODE_NORMAL 0x00 /**< @brief Normal operations. */
#define SD_MODE_LOOPBACK 0x80 /**< @brief Internal loopback. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief eSCI-A driver enable switch.
* @details If set to @p TRUE the support for eSCI-A is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SPC563_ESCIA) || defined(__DOXYGEN__)
#define USE_SPC563_ESCIA TRUE
#endif
/**
* @brief eSCI-B driver enable switch.
* @details If set to @p TRUE the support for eSCI-B is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_SPC563_ESCIB) || defined(__DOXYGEN__)
#define USE_SPC563_ESCIB TRUE
#endif
/**
* @brief eSCI-A interrupt priority level setting.
*/
#if !defined(SPC563_ESCIA_PRIORITY) || defined(__DOXYGEN__)
#define SPC563_ESCIA_PRIORITY 8
#endif
/**
* @brief eSCI-B interrupt priority level setting.
*/
#if !defined(SPC563_ESCIB_PRIORITY) || defined(__DOXYGEN__)
#define SPC563_ESCIB_PRIORITY 8
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief Serial Driver condition flags type.
*/
typedef uint8_t sdflags_t;
/**
* @brief Generic 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.
* @note This structure content is architecture dependent, each driver
* implementation defines its own version and the custom static
* initializers.
*/
typedef struct {
/**
* @brief Bit rate.
*/
uint32_t sc_speed;
/**
* @brief Mode flags.
*/
uint8_t sc_mode;
} SerialConfig;
/**
* @brief @p SerialDriver specific data.
*/
#define _serial_driver_data \
_base_asynchronous_channel_data \
/* Driver state.*/ \
sdstate_t state; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* 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 volatile eSCI registers block.*/ \
volatile struct ESCI_tag *escip;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_SPC563_ESCIA && !defined(__DOXYGEN__)
extern SerialDriver SD1;
#endif
#if USE_SPC563_ESCIB && !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 /* CH_HAL_USE_SERIAL */
#endif /* _SERIAL_LLD_H_ */
/** @} */

View File

@@ -0,0 +1,37 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file SPC56x/typedefs.h
* @brief Dummy typedefs file.
*/
#ifndef _TYPEDEFS_H_
#define _TYPEDEFS_H_
#include "chtypes.h"
#endif /* _TYPEDEFS_H_ */

View File

@@ -0,0 +1,252 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file STM32/adc_lld.c
* @brief STM32 ADC subsystem low level driver source.
* @addtogroup STM32_ADC
* @{
*/
#include "ch.h"
#include "hal.h"
#if CH_HAL_USE_ADC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/** @brief ADC1 driver identifier.*/
#if USE_STM32_ADC1 || defined(__DOXYGEN__)
ADCDriver ADCD1;
#endif
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if USE_STM32_ADC1 || defined(__DOXYGEN__)
/**
* @brief ADC1 DMA interrupt handler (channel 1).
*/
CH_IRQ_HANDLER(Vector6C) {
uint32_t isr;
CH_IRQ_PROLOGUE();
isr = DMA1->ISR;
DMA1->IFCR |= DMA_IFCR_CGIF1 | DMA_IFCR_CTCIF1 |
DMA_IFCR_CHTIF1 | DMA_IFCR_CTEIF1;
if ((isr & DMA_ISR_HTIF1) != 0) {
/* Half transfer processing.*/
if (ADCD1.ad_callback != NULL) {
/* Invokes the callback passing the 1st half of the buffer.*/
ADCD1.ad_callback(ADCD1.ad_samples, ADCD1.ad_depth / 2);
}
}
if ((isr & DMA_ISR_TCIF1) != 0) {
/* Transfer complete processing.*/
if (!ADCD1.ad_grpp->acg_circular) {
/* End conversion.*/
adc_lld_stop_conversion(&ADCD1);
ADCD1.ad_grpp = NULL;
ADCD1.ad_state = ADC_COMPLETE;
chSysLockFromIsr();
chSemResetI(&ADCD1.ad_sem, 0);
chSysUnlockFromIsr();
}
/* Callback handling.*/
if (ADCD1.ad_callback != NULL) {
if (ADCD1.ad_depth > 1) {
/* Invokes the callback passing the 2nd half of the buffer.*/
size_t half = ADCD1.ad_depth / 2;
ADCD1.ad_callback(ADCD1.ad_samples + half, half);
}
else {
/* Invokes the callback passing the whole buffer.*/
ADCD1.ad_callback(ADCD1.ad_samples, ADCD1.ad_depth);
}
}
}
if ((isr & DMA_ISR_TEIF1) != 0) {
/* DMA error processing.*/
STM32_ADC1_DMA_ERROR_HOOK();
}
CH_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/**
* @brief Low level ADC driver initialization.
*/
void adc_lld_init(void) {
#if USE_STM32_ADC1
/* ADC reset, ensures reset state in order to avoid trouble with JTAGs.*/
RCC->APB2RSTR = RCC_APB2RSTR_ADC1RST;
RCC->APB2RSTR = 0;
/* Driver initialization.*/
adcObjectInit(&ADCD1);
ADCD1.ad_adc = ADC1;
ADCD1.ad_dma = DMA1_Channel1;
ADCD1.ad_dmaprio = STM32_ADC1_DMA_PRIORITY << 12;
/* Temporary activation.*/
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
ADC1->CR1 = 0;
ADC1->CR2 = ADC_CR2_ADON;
/* Reset calibration just to be safe.*/
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
;
/* Calibration.*/
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
;
/* Return the ADC in low power mode.*/
ADC1->CR2 = 0;
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
#endif
}
/**
* @brief Configures and activates the ADC peripheral.
*
* @param[in] adcp pointer to the @p ADCDriver object
*/
void adc_lld_start(ADCDriver *adcp) {
/* If in stopped state then enables the ADC and DMA clocks.*/
if (adcp->ad_state == ADC_STOP) {
#if USE_STM32_ADC1
if (&ADCD1 == adcp) {
dmaEnable(DMA1_ID); /* NOTE: Must be enabled before the IRQs.*/
NVICEnableVector(DMA1_Channel1_IRQn,
CORTEX_PRIORITY_MASK(STM32_ADC1_IRQ_PRIORITY));
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
}
#endif
/* ADC setup, the calibration procedure has already been performed
during initialization.*/
adcp->ad_adc->CR1 = ADC_CR1_SCAN;
adcp->ad_adc->CR2 = 0;
}
}
/**
* @brief Deactivates the ADC peripheral.
*
* @param[in] adcp pointer to the @p ADCDriver object
*/
void adc_lld_stop(ADCDriver *adcp) {
/* If in ready state then disables the ADC clock.*/
if (adcp->ad_state == ADC_READY) {
#if USE_STM32_ADC1
if (&ADCD1 == adcp) {
ADC1->CR1 = 0;
ADC1->CR2 = 0;
NVICDisableVector(DMA1_Channel1_IRQn);
dmaDisable(DMA1_ID);
RCC->APB2ENR &= ~RCC_APB2ENR_ADC1EN;
}
#endif
}
}
/**
* @brief Starts an ADC conversion.
*
* @param[in] adcp pointer to the @p ADCDriver object
*/
void adc_lld_start_conversion(ADCDriver *adcp) {
uint32_t ccr, n;
const ADCConversionGroup *grpp = adcp->ad_grpp;
/* DMA setup.*/
adcp->ad_dma->CMAR = (uint32_t)adcp->ad_samples;
ccr = adcp->ad_dmaprio | DMA_CCR1_EN | DMA_CCR1_MSIZE_0 | DMA_CCR1_PSIZE_0 |
DMA_CCR1_MINC | DMA_CCR1_TCIE | DMA_CCR1_TEIE;
if (grpp->acg_circular)
ccr |= DMA_CCR1_CIRC;
if (adcp->ad_depth > 1) {
/* If the buffer depth is greater than one then the half transfer interrupt
interrupt is enabled in order to allows streaming processing.*/
ccr |= DMA_CCR1_HTIE;
n = (uint32_t)grpp->acg_num_channels * (uint32_t)adcp->ad_depth;
}
else
n = (uint32_t)grpp->acg_num_channels;
adcp->ad_dma->CNDTR = n;
adcp->ad_dma->CCR = ccr;
/* ADC setup.*/
adcp->ad_adc->SMPR1 = grpp->acg_smpr1;
adcp->ad_adc->SMPR2 = grpp->acg_smpr2;
adcp->ad_adc->SQR1 = grpp->acg_sqr1;
adcp->ad_adc->SQR2 = grpp->acg_sqr2;
adcp->ad_adc->SQR3 = grpp->acg_sqr3;
adcp->ad_adc->CR1 = grpp->acg_cr1 | ADC_CR1_SCAN;
adcp->ad_adc->CR2 = grpp->acg_cr2 | ADC_CR2_DMA | ADC_CR2_ADON;
/* ADC start.*/
adcp->ad_adc->CR2 |= ADC_CR2_SWSTART | ADC_CR2_EXTTRIG;
}
/**
* @brief Stops an ongoing conversion.
*
* @param[in] adcp pointer to the @p ADCDriver object
*/
void adc_lld_stop_conversion(ADCDriver *adcp) {
adcp->ad_dma->CCR = 0;
adcp->ad_adc->CR2 = 0;
}
#endif /* CH_HAL_USE_ADC */
/** @} */

View File

@@ -0,0 +1,286 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT 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.
ChibiOS/RT 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 <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
/**
* @file STM32/adc_lld.h
* @brief STM32 ADC subsystem low level driver header.
* @addtogroup STM32_ADC
* @{
*/
#ifndef _ADC_LLD_H_
#define _ADC_LLD_H_
#if CH_HAL_USE_ADC || defined(__DOXYGEN__)
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
#define ADC_CR2_EXTSEL_SRC(n) ((n) << 17) /**< @brief Trigger source. */
#define ADC_CR2_EXTSEL_SWSTART (7 << 17) /**< @brief Software trigger. */
#define ADC_CHANNEL_IN0 0 /**< @brief External analog input 0. */
#define ADC_CHANNEL_IN1 1 /**< @brief External analog input 1. */
#define ADC_CHANNEL_IN2 2 /**< @brief External analog input 2. */
#define ADC_CHANNEL_IN3 3 /**< @brief External analog input 3. */
#define ADC_CHANNEL_IN4 4 /**< @brief External analog input 4. */
#define ADC_CHANNEL_IN5 5 /**< @brief External analog input 5. */
#define ADC_CHANNEL_IN6 6 /**< @brief External analog input 6. */
#define ADC_CHANNEL_IN7 7 /**< @brief External analog input 7. */
#define ADC_CHANNEL_IN8 8 /**< @brief External analog input 8. */
#define ADC_CHANNEL_IN9 9 /**< @brief External analog input 9. */
#define ADC_CHANNEL_IN10 10 /**< @brief External analog input 10. */
#define ADC_CHANNEL_IN11 11 /**< @brief External analog input 11. */
#define ADC_CHANNEL_IN12 12 /**< @brief External analog input 12. */
#define ADC_CHANNEL_IN13 13 /**< @brief External analog input 13. */
#define ADC_CHANNEL_IN14 14 /**< @brief External analog input 14. */
#define ADC_CHANNEL_IN15 15 /**< @brief External analog input 15. */
#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/**
* @brief ADC1 driver enable switch.
* @details If set to @p TRUE the support for ADC1 is included.
* @note The default is @p TRUE.
*/
#if !defined(USE_STM32_ADC1) || defined(__DOXYGEN__)
#define USE_STM32_ADC1 TRUE
#endif
/**
* @brief ADC1 DMA priority (0..3|lowest..highest).
*/
#if !defined(STM32_ADC1_DMA_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC1_DMA_PRIORITY 3
#endif
/**
* @brief ADC1 interrupt priority level setting.
*/
#if !defined(STM32_ADC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
#define STM32_ADC1_IRQ_PRIORITY 5
#endif
/**
* @brief ADC1 DMA error hook.
* @note The default action for DMA errors is a system halt because DMA error
* can only happen because programming errors.
*/
#if !defined(STM32_ADC1_DMA_ERROR_HOOK) || defined(__DOXYGEN__)
#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()
#endif
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/**
* @brief ADC sample data type.
*/
typedef uint16_t adcsample_t;
/**
* @brief Channels number in a conversion group.
*/
typedef uint16_t adc_channels_num_t;
/**
* @brief ADC notification callback type.
* @param[in] buffer pointer to the most recent samples data
* @param[in] n number of buffer rows available starting from @p buffer
*/
typedef void (*adccallback_t)(adcsample_t *buffer, size_t n);
/**
* @brief Conversion group configuration structure.
* @details This implementation-dependent structure describes a conversion
* operation.
*/
typedef struct {
/**
* @brief Enables the circular buffer mode for the group.
*/
bool_t acg_circular;
/**
* @brief Number of the analog channels belonging to the conversion group.
*/
adc_channels_num_t acg_num_channels;
/* End of the mandatory fields.*/
/**
* @brief ADC CR1 register initialization data.
* @note All the required bits must be defined into this field except
* @p ADC_CR1_SCAN that is enforced inside the driver.
*/
uint32_t acg_cr1;
/**
* @brief ADC CR2 register initialization data.
* @note All the required bits must be defined into this field except
* @p ADC_CR2_DMA and @p ADC_CR2_ADON that are enforced inside the
* driver.
*/
uint32_t acg_cr2;
/**
* @brief ADC SMPR1 register initialization data.
*/
uint32_t acg_smpr1;
/**
* @brief ADC SMPR2 register initialization data.
*/
uint32_t acg_smpr2;
/**
* @brief ADC SQR1 register initialization data.
*/
uint32_t acg_sqr1;
/**
* @brief ADC SQR2 register initialization data.
*/
uint32_t acg_sqr2;
/**
* @brief ADC SQR3 register initialization data.
*/
uint32_t acg_sqr3;
} ADCConversionGroup;
/**
* @brief Driver configuration structure.
* @note It could be empty on some architectures.
*/
typedef struct {
/* * <----------
* @brief ADC prescaler setting.
* @note This field can assume one of the following values:
* @p RCC_CFGR_ADCPRE_DIV2, @p RCC_CFGR_ADCPRE_DIV4,
* @p RCC_CFGR_ADCPRE_DIV6, @p RCC_CFGR_ADCPRE_DIV8.
*/
/* uint32_t ac_prescaler;*/
} ADCConfig;
/**
* @brief Structure representing an ADC driver.
*/
typedef struct {
/**
* @brief Driver state.
*/
adcstate_t ad_state;
/**
* @brief Current configuration data.
*/
const ADCConfig *ad_config;
/**
* @brief Synchronization semaphore.
*/
Semaphore ad_sem;
/**
* @brief Current callback function or @p NULL.
*/
adccallback_t ad_callback;
/**
* @brief Current samples buffer pointer or @p NULL.
*/
adcsample_t *ad_samples;
/**
* @brief Current samples buffer depth or @p 0.
*/
size_t ad_depth;
/**
* @brief Current conversion group pointer or @p NULL.
*/
const ADCConversionGroup *ad_grpp;
/* End of the mandatory fields.*/
/**
* @brief Pointer to the ADCx registers block.
*/
ADC_TypeDef *ad_adc;
/**
* @brief Pointer to the DMA channel registers block.
*/
DMA_Channel_TypeDef *ad_dma;
/**
* @brief DMA priority bit mask.
*/
uint32_t ad_dmaprio;
} ADCDriver;
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
#define ADC_SQR3_SQ0_N(n) ((n) << 0)
#define ADC_SQR3_SQ1_N(n) ((n) << 5)
#define ADC_SQR3_SQ2_N(n) ((n) << 10)
#define ADC_SQR3_SQ3_N(n) ((n) << 15)
#define ADC_SQR3_SQ4_N(n) ((n) << 20)
#define ADC_SQR3_SQ5_N(n) ((n) << 25)
#define ADC_SQR2_SQ6_N(n) ((n) << 0)
#define ADC_SQR2_SQ7_N(n) ((n) << 5)
#define ADC_SQR2_SQ8_N(n) ((n) << 10)
#define ADC_SQR2_SQ9_N(n) ((n) << 15)
#define ADC_SQR2_SQ10_N(n) ((n) << 20)
#define ADC_SQR2_SQ11_N(n) ((n) << 25)
#define ADC_SQR1_SQ13_N(n) ((n) << 0)
#define ADC_SQR1_SQ14_N(n) ((n) << 5)
#define ADC_SQR1_SQ15_N(n) ((n) << 10)
#define ADC_SQR1_SQ16_N(n) ((n) << 15)
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#if USE_STM32_ADC1 && !defined(__DOXYGEN__)
extern ADCDriver ADCD1;
#endif
#ifdef __cplusplus
extern "C" {
#endif
void adc_lld_init(void);
void adc_lld_start(ADCDriver *adcp);
void adc_lld_stop(ADCDriver *adcp);
void adc_lld_start_conversion(ADCDriver *adcp);
void adc_lld_stop_conversion(ADCDriver *adcp);
#ifdef __cplusplus
}
#endif
#endif /* CH_HAL_USE_ADC */
#endif /* _ADC_LLD_H_ */
/** @} */

Some files were not shown because too many files have changed in this diff Show More