mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-12-02 21:11:47 +00:00
ChibiOS 2.6.8, until I can figure out where to get it from git.
This commit is contained in:
152
firmware/chibios/os/hal/dox/adc.dox
Executable file
152
firmware/chibios/os/hal/dox/adc.dox
Executable file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 ADC ADC Driver
|
||||
* @brief Generic ADC Driver.
|
||||
* @details This module implements a generic ADC (Analog to Digital Converter)
|
||||
* driver supporting a variety of buffer and conversion modes.
|
||||
* @pre In order to use the ADC driver the @p HAL_USE_ADC option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section adc_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
size="5, 7";
|
||||
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="ADC_STOP\nLow Power"];
|
||||
uninit [label="ADC_UNINIT", style="bold"];
|
||||
ready [label="ADC_READY\nClock Enabled"];
|
||||
active [label="ADC_ACTIVE\nConverting"];
|
||||
error [label="ADC_ERROR\nError"];
|
||||
complete [label="ADC_COMPLETE\nComplete"];
|
||||
|
||||
uninit -> stop [label="\n adcInit()", constraint=false];
|
||||
stop -> ready [label="\nadcStart()"];
|
||||
ready -> ready [label="\nadcStart()\nadcStopConversion()"];
|
||||
ready -> stop [label="\nadcStop()"];
|
||||
stop -> stop [label="\nadcStop()"];
|
||||
ready -> active [label="\nadcStartConversion() (async)\nadcConvert() (sync)"];
|
||||
active -> ready [label="\nadcStopConversion()\nsync return"];
|
||||
active -> active [label="\nasync callback (half buffer, circular)\nasync callback (full buffer)\n>acg_endcb<"];
|
||||
active -> complete [label="\n\nasync callback (full buffer)\n>end_cb<"];
|
||||
active -> error [label="\n\nasync callback (error)\n>error_cb<"];
|
||||
complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
|
||||
complete -> ready [label="\ncallback return"];
|
||||
error -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
|
||||
error -> ready [label="\ncallback return"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="ADC_STOP\nLow Power"];
|
||||
uninit [label="ADC_UNINIT", style="bold"];
|
||||
ready [label="ADC_READY\nClock Enabled"];
|
||||
active [label="ADC_ACTIVE\nConverting"];
|
||||
error [label="ADC_ERROR\nError"];
|
||||
complete [label="ADC_COMPLETE\nComplete"];
|
||||
|
||||
uninit -> stop [label="\n adcInit()", constraint=false];
|
||||
stop -> ready [label="\nadcStart()"];
|
||||
ready -> ready [label="\nadcStart()\nadcStopConversion()"];
|
||||
ready -> stop [label="\nadcStop()"];
|
||||
stop -> stop [label="\nadcStop()"];
|
||||
ready -> active [label="\nadcStartConversion() (async)\nadcConvert() (sync)"];
|
||||
active -> ready [label="\nadcStopConversion()\nsync return"];
|
||||
active -> active [label="\nasync callback (half buffer, circular)\nasync callback (full buffer)\n>acg_endcb<"];
|
||||
active -> complete [label="\n\nasync callback (full buffer)\n>end_cb<"];
|
||||
active -> error [label="\n\nasync callback (error)\n>error_cb<"];
|
||||
complete -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
|
||||
complete -> ready [label="\ncallback return"];
|
||||
error -> active [label="\nadcStartConversionI()\nthen\ncallback return"];
|
||||
error -> ready [label="\ncallback return"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
*
|
||||
* @section adc_2 ADC Operations
|
||||
* The ADC driver is quite complex, an explanation of the terminology and of
|
||||
* the operational details follows.
|
||||
*
|
||||
* @subsection adc_2_1 ADC Conversion Groups
|
||||
* The @p ADCConversionGroup is the objects that specifies a physical
|
||||
* conversion operation. This structure contains some standard fields and
|
||||
* several implementation-dependent fields.<br>
|
||||
* The standard fields define the CG mode, the number of channels belonging
|
||||
* to the CG and the optional callbacks.<br>
|
||||
* The implementation-dependent fields specify the physical ADC operation
|
||||
* mode, the analog channels belonging to the group and any other
|
||||
* implementation-specific setting. Usually the extra fields just mirror
|
||||
* the physical ADC registers, please refer to the vendor's MCU Reference
|
||||
* Manual for details about the available settings. Details are also available
|
||||
* into the documentation of the ADC low level drivers and in the various
|
||||
* sample applications.
|
||||
*
|
||||
* @subsection adc_2_2 ADC Conversion Modes
|
||||
* The driver supports several conversion modes:
|
||||
* - <b>One Shot</b>, the driver performs a single group conversion then stops.
|
||||
* - <b>Linear Buffer</b>, the driver performs a series of group conversions
|
||||
* then stops. This mode is like a one shot conversion repeated N times,
|
||||
* the buffer pointer increases after each conversion. The buffer is
|
||||
* organized as an S(CG)*N samples matrix, when S(CG) is the conversion
|
||||
* group size (number of channels) and N is the buffer depth (number of
|
||||
* repeated conversions).
|
||||
* - <b>Circular Buffer</b>, much like the linear mode but the operation does
|
||||
* not stop when the buffer is filled, it is automatically restarted
|
||||
* with the buffer pointer wrapping back to the buffer base.
|
||||
* .
|
||||
* @subsection adc_2_3 ADC Callbacks
|
||||
* The driver is able to invoke callbacks during the conversion process. A
|
||||
* callback is invoked when the operation has been completed or, in circular
|
||||
* mode, when the buffer has been filled and the operation is restarted. In
|
||||
* circular mode a callback is also invoked when the buffer is half filled.<br>
|
||||
* The "half filled" and "filled" callbacks in circular mode allow to
|
||||
* implement "streaming processing" of the sampled data, while the driver is
|
||||
* busy filling one half of the buffer the application can process the
|
||||
* other half, this allows for continuous interleaved operations.
|
||||
*
|
||||
* The driver is not thread safe for performance reasons, if you need to access
|
||||
* the ADC bus from multiple threads then use the @p adcAcquireBus() and
|
||||
* @p adcReleaseBus() APIs in order to gain exclusive access.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
99
firmware/chibios/os/hal/dox/can.dox
Executable file
99
firmware/chibios/os/hal/dox/can.dox
Executable file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 CAN CAN Driver
|
||||
* @brief Generic CAN Driver.
|
||||
* @details This module implements a generic CAN (Controller Area Network)
|
||||
* driver allowing the exchange of information at frame level.
|
||||
* @pre In order to use the CAN driver the @p HAL_USE_CAN option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section can_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="CAN_STOP\nLow Power"];
|
||||
uninit [label="CAN_UNINIT", style="bold"];
|
||||
starting [label="CAN_STARTING\nInitializing"];
|
||||
ready [label="CAN_READY\nClock Enabled"];
|
||||
sleep [label="CAN_SLEEP\nLow Power"];
|
||||
|
||||
uninit -> stop [label=" canInit()", constraint=false];
|
||||
stop -> stop [label="\ncanStop()"];
|
||||
stop -> ready [label="\ncanStart()\n(fast implementation)"];
|
||||
stop -> starting [label="\ncanStart()\n(slow implementation)"];
|
||||
starting -> starting [label="\ncanStart()\n(other thread)"];
|
||||
starting -> ready [label="\ninitialization complete\n(all threads)"];
|
||||
ready -> stop [label="\ncanStop()"];
|
||||
ready -> ready [label="\ncanStart()\ncanReceive()\ncanTransmit()"];
|
||||
ready -> sleep [label="\ncanSleep()"];
|
||||
sleep -> sleep [label="\ncanSleep()"];
|
||||
sleep -> ready [label="\ncanWakeup()"];
|
||||
sleep -> ready [label="\nhardware\nwakeup event"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="CAN_STOP\nLow Power"];
|
||||
uninit [label="CAN_UNINIT", style="bold"];
|
||||
starting [label="CAN_STARTING\nInitializing"];
|
||||
ready [label="CAN_READY\nClock Enabled"];
|
||||
sleep [label="CAN_SLEEP\nLow Power"];
|
||||
|
||||
uninit -> stop [label=" canInit()", constraint=false];
|
||||
stop -> stop [label="\ncanStop()"];
|
||||
stop -> ready [label="\ncanStart()\n(fast implementation)"];
|
||||
stop -> starting [label="\ncanStart()\n(slow implementation)"];
|
||||
starting -> starting [label="\ncanStart()\n(other thread)"];
|
||||
starting -> ready [label="\ninitialization complete\n(all threads)"];
|
||||
ready -> stop [label="\ncanStop()"];
|
||||
ready -> ready [label="\ncanStart()\ncanReceive()\ncanTransmit()"];
|
||||
ready -> sleep [label="\ncanSleep()"];
|
||||
sleep -> sleep [label="\ncanSleep()"];
|
||||
sleep -> ready [label="\ncanWakeup()"];
|
||||
sleep -> ready [label="\nhardware\nwakeup event"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
91
firmware/chibios/os/hal/dox/ext.dox
Executable file
91
firmware/chibios/os/hal/dox/ext.dox
Executable file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 EXT EXT Driver
|
||||
* @brief Generic EXT Driver.
|
||||
* @details This module implements a generic EXT (EXTernal) driver.
|
||||
* @pre In order to use the EXT driver the @p HAL_USE_EXT option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section ext_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Sans, fontsize=8];
|
||||
|
||||
uninit [label="EXT_UNINIT", style="bold"];
|
||||
stop [label="EXT_STOP\nLow Power"];
|
||||
active [label="EXT_ACTIVE"];
|
||||
|
||||
uninit -> stop [label="extInit()"];
|
||||
stop -> stop [label="\nextStop()"];
|
||||
stop -> active [label="\nextStart()"];
|
||||
active -> stop [label="\nextStop()"];
|
||||
active -> active [label="\nextStart()"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Sans, fontsize=8];
|
||||
|
||||
uninit [label="EXT_UNINIT", style="bold"];
|
||||
stop [label="EXT_STOP\nLow Power"];
|
||||
active [label="EXT_ACTIVE"];
|
||||
|
||||
uninit -> stop [label="extInit()"];
|
||||
stop -> stop [label="\nextStop()"];
|
||||
stop -> active [label="\nextStart()"];
|
||||
active -> stop [label="\nextStop()"];
|
||||
active -> active [label="\nextStart()"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
*
|
||||
* @section ext_2 EXT Operations.
|
||||
* This driver abstracts generic external interrupt sources, a callback
|
||||
* is invoked when a programmable transition is detected on one of the
|
||||
* configured channels. Several channel modes are possible.
|
||||
* - <b>EXT_CH_MODE_DISABLED</b>, channel not used.
|
||||
* - <b>EXT_CH_MODE_RISING_EDGE</b>, callback on a rising edge.
|
||||
* - <b>EXT_CH_MODE_FALLING_EDGE</b>, callback on a falling edge.
|
||||
* - <b>EXT_CH_MODE_BOTH_EDGES</b>, callback on a both edges.
|
||||
* .
|
||||
* @ingroup IO
|
||||
*/
|
||||
85
firmware/chibios/os/hal/dox/gpt.dox
Executable file
85
firmware/chibios/os/hal/dox/gpt.dox
Executable file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 GPT GPT Driver
|
||||
* @brief Generic GPT Driver.
|
||||
* @details This module implements a generic GPT (General Purpose Timer)
|
||||
* driver. The timer can be programmed in order to trigger callbacks
|
||||
* after a specified time period or continuously with a specified
|
||||
* interval.
|
||||
* @pre In order to use the GPT driver the @p HAL_USE_GPT option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section gpt_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="GPT_STOP\nLow Power"];
|
||||
uninit [label="GPT_UNINIT", style="bold"];
|
||||
ready [label="GPT_READY\nClock Enabled"];
|
||||
continuous [label="GPT_CONT..S\nContinuous\nMode"];
|
||||
oneshot [label="GPT_ONESHOT\nOne Shot\nMode"];
|
||||
|
||||
uninit -> stop [label=" gptInit()", constraint=false];
|
||||
stop -> stop [label="\ngptStop()"];
|
||||
stop -> ready [label="\ngptStart()"];
|
||||
ready -> stop [label="\ngptStop()"];
|
||||
ready -> ready [label="\ngptStart()"];
|
||||
ready -> continuous [label="\ngptStartContinuous()"];
|
||||
continuous -> ready [label="\ngptStopTimer()"];
|
||||
continuous -> continuous [label=">callback<"];
|
||||
ready -> oneshot [label="\ngptStartOneShot()\ngptPolledDelay()"];
|
||||
oneshot -> ready [label="\n>callback<\nor\nDelay Over"];
|
||||
}
|
||||
* @enddot
|
||||
*
|
||||
* @section gpt_2 GPT Operations.
|
||||
* This driver abstracts a generic timer composed of:
|
||||
* - A clock prescaler.
|
||||
* - A main up counter.
|
||||
* - A comparator register that resets the main counter to zero when the limit
|
||||
* is reached. A callback is invoked when this happens.
|
||||
* .
|
||||
* The timer can operate in three different modes:
|
||||
* - <b>Continuous Mode</b>, a periodic callback is invoked until the driver
|
||||
* is explicitly stopped.
|
||||
* - <b>One Shot Mode</b>, a callback is invoked after the programmed period
|
||||
* and then the timer automatically stops.
|
||||
* - <b>Delay Mode</b>, the timer is used for inserting a brief delay into
|
||||
* the execution flow, no callback is invoked in this mode.
|
||||
* .
|
||||
* @ingroup IO
|
||||
*/
|
||||
43
firmware/chibios/os/hal/dox/hal.dox
Executable file
43
firmware/chibios/os/hal/dox/hal.dox
Executable file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL HAL Driver
|
||||
* @brief Hardware Abstraction Layer.
|
||||
* @details The HAL (Hardware Abstraction Layer) driver performs the system
|
||||
* initialization and includes the platform support code shared by
|
||||
* the other drivers. This driver does contain any API function
|
||||
* except for a general initialization function @p halInit() that
|
||||
* must be invoked before any HAL service can be used, usually the
|
||||
* HAL initialization should be performed immediately before the
|
||||
* kernel initialization.<br>
|
||||
* Some HAL driver implementations also offer a custom early clock
|
||||
* setup function that can be invoked before the C runtime
|
||||
* initialization in order to accelerate the startup time.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
109
firmware/chibios/os/hal/dox/i2c.dox
Executable file
109
firmware/chibios/os/hal/dox/i2c.dox
Executable file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 I2C I2C Driver
|
||||
* @brief Generic I2C Driver.
|
||||
* @details This module implements a generic I2C (Inter-Integrated Circuit)
|
||||
* driver.
|
||||
* @pre In order to use the I2C driver the @p HAL_USE_I2C option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section i2c_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="I2C_STOP\nLow Power"];
|
||||
uninit [label="I2C_UNINIT", style="bold"];
|
||||
ready [label="I2C_READY\nClock Enabled"];
|
||||
active_tx [label="I2C_ACTIVE_TX\nBus TX Active"];
|
||||
active_rx [label="I2C_ACTIVE_RX\nBus RX Active"];
|
||||
locked [label="I2C_LOCKED\nBus Locked"];
|
||||
|
||||
uninit -> stop [label="i2cInit()", constraint=false];
|
||||
stop -> stop [label="i2cStop()"];
|
||||
stop -> ready [label="i2cStart()"];
|
||||
ready -> ready [label="i2cStart()"];
|
||||
ready -> stop [label="i2cStop()"];
|
||||
ready -> active_tx [label="i2cMasterTransmit()"];
|
||||
ready -> active_rx [label="i2cMasterReceive()"];
|
||||
active_tx -> ready [label="completed"];
|
||||
active_rx -> ready [label="completed"];
|
||||
active_tx -> locked [label="RDY_TIMEOUT"];
|
||||
active_rx -> locked [label="RDY_TIMEOUT"];
|
||||
locked -> stop [label="i2cStop()"];
|
||||
locked -> ready [label="i2cStart()"];
|
||||
}
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="I2C_STOP\nLow Power"];
|
||||
uninit [label="I2C_UNINIT", style="bold"];
|
||||
ready [label="I2C_READY\nClock Enabled"];
|
||||
active_tx [label="I2C_ACTIVE_TX\nBus TX Active"];
|
||||
active_rx [label="I2C_ACTIVE_RX\nBus RX Active"];
|
||||
locked [label="I2C_LOCKED\nBus Locked"];
|
||||
|
||||
uninit -> stop [label="i2cInit()", constraint=false];
|
||||
stop -> stop [label="i2cStop()"];
|
||||
stop -> ready [label="i2cStart()"];
|
||||
ready -> ready [label="i2cStart()"];
|
||||
ready -> stop [label="i2cStop()"];
|
||||
ready -> active_tx [label="i2cMasterTransmit()"];
|
||||
ready -> active_rx [label="i2cMasterReceive()"];
|
||||
active_tx -> ready [label="completed"];
|
||||
active_rx -> ready [label="completed"];
|
||||
active_tx -> locked [label="RDY_TIMEOUT"];
|
||||
active_rx -> locked [label="RDY_TIMEOUT"];
|
||||
locked -> stop [label="i2cStop()"];
|
||||
locked -> ready [label="i2cStart()"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
* The driver is not thread safe for performance reasons, if you need to access
|
||||
* the I2C bus from multiple threads then use the @p i2cAcquireBus() and
|
||||
* @p i2cReleaseBus() APIs in order to gain exclusive access.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
38
firmware/chibios/os/hal/dox/i2s.dox
Executable file
38
firmware/chibios/os/hal/dox/i2s.dox
Executable file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 I2S I2S Driver
|
||||
* @brief Generic I2S Driver.
|
||||
* @details This module implements a generic I2S driver.
|
||||
* @pre In order to use the I2S driver the @p HAL_USE_I2S option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section i2s_1 Driver State Machine
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
117
firmware/chibios/os/hal/dox/icu.dox
Executable file
117
firmware/chibios/os/hal/dox/icu.dox
Executable file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup ICU ICU Driver
|
||||
* @brief Generic ICU Driver.
|
||||
* @details This module implements a generic ICU (Input Capture Unit) driver.
|
||||
* @pre In order to use the ICU driver the @p HAL_USE_ICU option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section icu_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Sans, fontsize=8];
|
||||
|
||||
stop [label="ICU_STOP\nLow Power"];
|
||||
uninit [label="ICU_UNINIT", style="bold"];
|
||||
ready [label="ICU_READY\nClock Enabled"];
|
||||
waiting [label="ICU_WAITING"];
|
||||
active [label="ICU_ACTIVE"];
|
||||
idle [label="ICU_IDLE"];
|
||||
|
||||
uninit -> stop [label=" icuInit()", constraint=false];
|
||||
stop -> stop [label="\nicuStop()"];
|
||||
stop -> ready [label="\nicuStart()"];
|
||||
ready -> stop [label="\nicuStop()"];
|
||||
ready -> ready [label="\nicuStart()\nicuDisable()"];
|
||||
ready -> waiting [label="\nicuEnable()"];
|
||||
waiting -> active [label="\nStart Front"];
|
||||
waiting -> ready [label="\nicuDisable()"];
|
||||
waiting -> waiting [label="\nStop Front"];
|
||||
active -> idle [label="\nStop Front\n>width_cb<"];
|
||||
active -> ready [label="\nicuDisable()\nicuDisableI()"];
|
||||
idle -> active [label="\nStart Front\n>period_cb<"];
|
||||
idle -> ready [label="\nicuDisable()\nicuDisableI()"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Sans, fontsize=8];
|
||||
|
||||
stop [label="ICU_STOP\nLow Power"];
|
||||
uninit [label="ICU_UNINIT", style="bold"];
|
||||
ready [label="ICU_READY\nClock Enabled"];
|
||||
waiting [label="ICU_WAITING"];
|
||||
active [label="ICU_ACTIVE"];
|
||||
idle [label="ICU_IDLE"];
|
||||
|
||||
uninit -> stop [label=" icuInit()", constraint=false];
|
||||
stop -> stop [label="\nicuStop()"];
|
||||
stop -> ready [label="\nicuStart()"];
|
||||
ready -> stop [label="\nicuStop()"];
|
||||
ready -> ready [label="\nicuStart()\nicuDisable()"];
|
||||
ready -> waiting [label="\nicuEnable()"];
|
||||
waiting -> active [label="\nStart Front"];
|
||||
waiting -> ready [label="\nicuDisable()"];
|
||||
waiting -> waiting [label="\nStop Front"];
|
||||
active -> idle [label="\nStop Front\n>width_cb<"];
|
||||
active -> ready [label="\nicuDisable()\nicuDisableI()"];
|
||||
idle -> active [label="\nStart Front\n>period_cb<"];
|
||||
idle -> ready [label="\nicuDisable()\nicuDisableI()"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
*
|
||||
* @section icu_2 ICU Operations.
|
||||
* This driver abstracts a generic Input Capture Unit composed of:
|
||||
* - A clock prescaler.
|
||||
* - A main up counter.
|
||||
* - Two capture registers triggered by the rising and falling edges on
|
||||
* the sampled input.
|
||||
* .
|
||||
* The ICU unit can be programmed to synchronize on the rising or falling
|
||||
* edge of the sample input:
|
||||
* - <b>ICU_INPUT_ACTIVE_HIGH</b>, a rising edge is the start signal.
|
||||
* - <b>ICU_INPUT_ACTIVE_LOW</b>, a falling edge is the start signal.
|
||||
* .
|
||||
* After the activation the ICU unit can be in one of the following
|
||||
* states at any time:
|
||||
* - <b>ICU_WAITING</b>, waiting the first start signal.
|
||||
* - <b>ICU_ACTIVE</b>, after a start signal.
|
||||
* - <b>ICU_IDLE</b>, after a stop signal.
|
||||
* .
|
||||
* Callbacks are invoked when start or stop signals occur.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
111
firmware/chibios/os/hal/dox/io_block.dox
Executable file
111
firmware/chibios/os/hal/dox/io_block.dox
Executable file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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_BLOCK Abstract I/O Block Device
|
||||
* @ingroup IO
|
||||
*
|
||||
* @section io_block_1 Driver State Machine
|
||||
* The drivers implementing this interface shall implement the following
|
||||
* state machine internally. Not all the driver functionalities can be used
|
||||
* in any moment, any transition not explicitly shown in the following
|
||||
* diagram has to be considered an error and shall be captured by an
|
||||
* assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Sans, fontsize=8];
|
||||
|
||||
stop [label="BLK_STOP\nLow Power"];
|
||||
uninit [label="BLK_UNINIT", style="bold"];
|
||||
active [label="BLK_ACTIVE\nClock Enabled"];
|
||||
connecting [label="BLK_CONN.ING\nConnecting"];
|
||||
disconnecting [label="BLK_DISC.ING\nDisconnecting"];
|
||||
ready [label="BLK_READY\nCard Ready"];
|
||||
reading [label="BLK_READING\nReading"];
|
||||
writing [label="BLK_WRITING\nWriting"];
|
||||
|
||||
uninit -> stop [label=" blkInit()", constraint=false];
|
||||
stop -> stop [label="\nblkStop()"];
|
||||
stop -> active [label="\nblkStart()"];
|
||||
active -> stop [label="\nblkStop()"];
|
||||
active -> active [label="\nblkStart()\nblkDisconnect()"];
|
||||
active -> connecting [label="\nblkConnect()"];
|
||||
connecting -> ready [label="\nconnection\nsuccessful"];
|
||||
connecting -> ready [label="\nblkConnect()", dir="back"];
|
||||
connecting -> active [label="\nconnection\nfailed"];
|
||||
disconnecting -> ready [label="\nblkDisconnect()", dir="back"];
|
||||
active -> disconnecting [label="\ndisconnection\nfinished", dir="back"];
|
||||
ready -> reading [label="\nblkRead()"];
|
||||
reading -> ready [label="\nread finished\nread error"];
|
||||
ready -> writing [label="\nblkWrite()"];
|
||||
writing -> ready [label="\nwrite finished\nwrite error"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
|
||||
node [shape=circle, fontname=Sans, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Sans, fontsize=8];
|
||||
|
||||
stop [label="BLK_STOP\nLow Power"];
|
||||
uninit [label="BLK_UNINIT", style="bold"];
|
||||
active [label="BLK_ACTIVE\nClock Enabled"];
|
||||
connecting [label="BLK_CONN.ING\nConnecting"];
|
||||
disconnecting [label="BLK_DISC.ING\nDisconnecting"];
|
||||
ready [label="BLK_READY\nCard Ready"];
|
||||
reading [label="BLK_READING\nReading"];
|
||||
writing [label="BLK_WRITING\nWriting"];
|
||||
syncing [label="BLK_SYNCING\nSynchronizing"];
|
||||
|
||||
uninit -> stop [label=" blkInit()", constraint=false];
|
||||
stop -> stop [label="\nblkStop()"];
|
||||
stop -> active [label="\nblkStart()"];
|
||||
active -> stop [label="\nblkStop()"];
|
||||
active -> active [label="\nblkStart()\nblkDisconnect()"];
|
||||
active -> connecting [label="\nblkConnect()"];
|
||||
connecting -> ready [label="\nconnection\nsuccessful"];
|
||||
connecting -> ready [label="\nblkConnect()", dir="back"];
|
||||
connecting -> active [label="\nconnection\nfailed"];
|
||||
disconnecting -> ready [label="\nblkDisconnect()", dir="back"];
|
||||
active -> disconnecting [label="\ndisconnection\nfinished", dir="back"];
|
||||
ready -> reading [label="\nblkRead()"];
|
||||
reading -> ready [label="\nread finished\nread error"];
|
||||
ready -> writing [label="\nblkWrite()"];
|
||||
writing -> ready [label="\nwrite finished\nwrite error"];
|
||||
ready -> syncing [label="\nblkSync()"];
|
||||
syncing -> ready [label="\nsynchronization finished"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
*/
|
||||
31
firmware/chibios/os/hal/dox/io_channel.dox
Executable file
31
firmware/chibios/os/hal/dox/io_channel.dox
Executable file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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_CHANNEL Abstract I/O Channel
|
||||
* @ingroup IO
|
||||
*/
|
||||
37
firmware/chibios/os/hal/dox/mac.dox
Executable file
37
firmware/chibios/os/hal/dox/mac.dox
Executable file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 MAC MAC Driver
|
||||
* @brief Generic MAC driver.
|
||||
* @details This module implements a generic MAC (Media Access Control)
|
||||
* driver for Ethernet controllers.
|
||||
* @pre In order to use the MAC driver the @p HAL_USE_MAC option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
46
firmware/chibios/os/hal/dox/mmc_spi.dox
Executable file
46
firmware/chibios/os/hal/dox/mmc_spi.dox
Executable file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 MMC_SPI MMC over SPI Driver
|
||||
* @brief Generic MMC driver.
|
||||
* @details This module implements a portable MMC/SD driver that uses a SPI
|
||||
* driver as physical layer. Hot plugging and removal are supported
|
||||
* through kernel events.
|
||||
* @pre In order to use the MMC_SPI driver the @p HAL_USE_MMC_SPI and
|
||||
* @p HAL_USE_SPI options must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section mmc_spi_1 Driver State Machine
|
||||
* This driver implements a state machine internally, see the @ref IO_BLOCK
|
||||
* module documentation for details.
|
||||
*
|
||||
* @section mmc_spi_2 Driver Operations
|
||||
* This driver allows to read or write single or multiple 512 bytes blocks
|
||||
* on a SD Card.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
35
firmware/chibios/os/hal/dox/mmcsd.dox
Executable file
35
firmware/chibios/os/hal/dox/mmcsd.dox
Executable file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 MMCSD MMC/SD Block Device
|
||||
* @details This module implements a common ancestor for all device drivers
|
||||
* accessing MMC or SD cards. This interface inherits the state
|
||||
* machine and the interface from the @ref IO_BLOCK module.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
81
firmware/chibios/os/hal/dox/pal.dox
Executable file
81
firmware/chibios/os/hal/dox/pal.dox
Executable file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 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
|
||||
* PAL Low Level Driver if the target hardware supports special
|
||||
* features like, for 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 PAL Low Level Driver 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.
|
||||
* @pre In order to use the PAL driver the @p HAL_USE_PAL option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section pal_1 Implementation Rules
|
||||
* In implementing a PAL Low Level Driver there are some rules/behaviors that
|
||||
* should be respected.
|
||||
*
|
||||
* @subsection pal_1_1 Writing on input pads
|
||||
* 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.
|
||||
* .
|
||||
* @subsection pal_1_2 Reading from output pads
|
||||
* 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.
|
||||
* .
|
||||
* @subsection pal_1_3 Writing unused or unimplemented port bits
|
||||
* The behavior is not specified.
|
||||
*
|
||||
* @subsection pal_1_4 Reading from unused or unimplemented port bits
|
||||
* The behavior is not specified.
|
||||
*
|
||||
* @subsection pal_1_5 Reading or writing on pins associated to other functionalities
|
||||
* The behavior is not specified.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
76
firmware/chibios/os/hal/dox/pwm.dox
Executable file
76
firmware/chibios/os/hal/dox/pwm.dox
Executable file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 PWM PWM Driver
|
||||
* @brief Generic PWM Driver.
|
||||
* @details This module implements a generic PWM (Pulse Width Modulation)
|
||||
* driver.
|
||||
* @pre In order to use the PWM driver the @p HAL_USE_PWM option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section pwm_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
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
|
||||
*
|
||||
* @section pwm_2 PWM Operations.
|
||||
* This driver abstracts a generic PWM timer composed of:
|
||||
* - A clock prescaler.
|
||||
* - A main up counter.
|
||||
* - A comparator register that resets the main counter to zero when the limit
|
||||
* is reached. An optional callback can be generated when this happens.
|
||||
* - An array of @p PWM_CHANNELS PWM channels, each channel has an output,
|
||||
* a comparator and is able to invoke an optional callback when a comparator
|
||||
* match with the main counter happens.
|
||||
* .
|
||||
* A PWM channel output can be in two different states:
|
||||
* - <b>IDLE</b>, when the channel is disabled or after a match occurred.
|
||||
* - <b>ACTIVE</b>, when the channel is enabled and a match didn't occur yet
|
||||
* in the current PWM cycle.
|
||||
* .
|
||||
* Note that the two states can be associated to both logical zero or one in
|
||||
* the @p PWMChannelConfig structure.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
37
firmware/chibios/os/hal/dox/rtc.dox
Executable file
37
firmware/chibios/os/hal/dox/rtc.dox
Executable file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 RTC RTC Driver
|
||||
* @brief Real Time Clock Abstraction Layer
|
||||
* @details This module defines an abstract interface for a Real Time Clock
|
||||
* Peripheral.
|
||||
* @pre In order to use the RTC driver the @p HAL_USE_RTC option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
44
firmware/chibios/os/hal/dox/sdc.dox
Executable file
44
firmware/chibios/os/hal/dox/sdc.dox
Executable file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 SDC SDC Driver
|
||||
* @brief Generic SD Card Driver.
|
||||
* @details This module implements a generic SDC (Secure Digital Card) driver.
|
||||
* @pre In order to use the SDC driver the @p HAL_USE_SDC option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section sdc_1 Driver State Machine
|
||||
* This driver implements a state machine internally, see the @ref IO_BLOCK
|
||||
* module documentation for details.
|
||||
*
|
||||
* @section sdc_2 Driver Operations
|
||||
* This driver allows to read or write single or multiple 512 bytes blocks
|
||||
* on a SD Card.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
68
firmware/chibios/os/hal/dox/serial.dox
Executable file
68
firmware/chibios/os/hal/dox/serial.dox
Executable file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 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.
|
||||
* @pre In order to use the SERIAL driver the @p HAL_USE_SERIAL option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
*
|
||||
* @section serial_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
uninit [label="SD_UNINIT", style="bold"];
|
||||
stop [label="SD_STOP\nLow Power"];
|
||||
ready [label="SD_READY\nClock Enabled"];
|
||||
|
||||
uninit -> stop [label=" sdInit()"];
|
||||
stop -> stop [label="\nsdStop()"];
|
||||
stop -> ready [label="\nsdStart()"];
|
||||
ready -> stop [label="\nsdStop()"];
|
||||
ready -> ready [label="\nsdStart()"];
|
||||
ready -> ready [label="\nAny I/O operation"];
|
||||
}
|
||||
* @enddot
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
63
firmware/chibios/os/hal/dox/serial_usb.dox
Executable file
63
firmware/chibios/os/hal/dox/serial_usb.dox
Executable file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 SERIAL_USB Serial over USB Driver
|
||||
* @brief Serial over USB Driver.
|
||||
* @details This module implements an USB Communication Device Class
|
||||
* (CDC) as a normal serial communication port accessible from
|
||||
* the device application.
|
||||
* @pre In order to use the USB over Serial driver the
|
||||
* @p HAL_USE_SERIAL_USB option must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section usb_serial_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
uninit [label="SDU_UNINIT", style="bold"];
|
||||
stop [label="SDU_STOP\nLow Power"];
|
||||
ready [label="SDU_READY\nClock Enabled"];
|
||||
|
||||
uninit -> stop [label=" sduInit()"];
|
||||
stop -> stop [label="\nsduStop()"];
|
||||
stop -> ready [label="\nsduStart()"];
|
||||
ready -> stop [label="\nsduStop()"];
|
||||
ready -> ready [label="\nsduStart()"];
|
||||
ready -> ready [label="\nAny I/O operation"];
|
||||
}
|
||||
* @enddot
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
101
firmware/chibios/os/hal/dox/spi.dox
Executable file
101
firmware/chibios/os/hal/dox/spi.dox
Executable file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 SPI SPI Driver
|
||||
* @brief Generic SPI Driver.
|
||||
* @details This module implements a generic SPI (Serial Peripheral Interface)
|
||||
* driver allowing bidirectional and monodirectional transfers,
|
||||
* complex atomic transactions are supported as well.
|
||||
* @pre In order to use the SPI driver the @p HAL_USE_SPI option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section spi_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="SPI_STOP\nLow Power"];
|
||||
uninit [label="SPI_UNINIT", style="bold"];
|
||||
ready [label="SPI_READY\nClock Enabled"];
|
||||
active [label="SPI_ACTIVE\nBus Active"];
|
||||
complete [label="SPI_COMPLETE\nComplete"];
|
||||
|
||||
uninit -> stop [label="\n spiInit()", constraint=false];
|
||||
stop -> ready [label="\nspiStart()"];
|
||||
ready -> ready [label="\nspiSelect()\nspiUnselect()\nspiStart()"];
|
||||
ready -> stop [label="\nspiStop()"];
|
||||
stop -> stop [label="\nspiStop()"];
|
||||
ready -> active [label="\nspiStartXXXI() (async)\nspiXXX() (sync)"];
|
||||
active -> ready [label="\nsync return"];
|
||||
active -> complete [label="\nasync callback\n>spc_endcb<"];
|
||||
complete -> active [label="\nspiStartXXXI() (async)\nthen\ncallback return"];
|
||||
complete -> ready [label="\ncallback return"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="SPI_STOP\nLow Power"];
|
||||
uninit [label="SPI_UNINIT", style="bold"];
|
||||
ready [label="SPI_READY\nClock Enabled"];
|
||||
active [label="SPI_ACTIVE\nBus Active"];
|
||||
complete [label="SPI_COMPLETE\nComplete"];
|
||||
|
||||
uninit -> stop [label="\n spiInit()", constraint=false];
|
||||
stop -> ready [label="\nspiStart()"];
|
||||
ready -> ready [label="\nspiSelect()\nspiUnselect()\nspiStart()"];
|
||||
ready -> stop [label="\nspiStop()"];
|
||||
stop -> stop [label="\nspiStop()"];
|
||||
ready -> active [label="\nspiStartXXX() (async)\nspiXXX() (sync)"];
|
||||
active -> ready [label="\nsync return"];
|
||||
active -> complete [label="\nasync callback\n>spc_endcb<"];
|
||||
complete -> active [label="\nspiStartXXXI() (async)\nthen\ncallback return"];
|
||||
complete -> ready [label="\ncallback return"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
*
|
||||
* The driver is not thread safe for performance reasons, if you need to access
|
||||
* the SPI bus from multiple threads then use the @p spiAcquireBus() and
|
||||
* @p spiReleaseBus() APIs in order to gain exclusive access.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
38
firmware/chibios/os/hal/dox/tm.dox
Executable file
38
firmware/chibios/os/hal/dox/tm.dox
Executable file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 TM Time Measurement Driver
|
||||
*
|
||||
* @brief Time Measurement unit.
|
||||
* @details This module implements a time measurement mechanism able to
|
||||
* monitor a portion of code and store the best/worst/last
|
||||
* measurement. The measurement is performed using the realtime
|
||||
* counter mechanism abstracted in the HAL driver.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
132
firmware/chibios/os/hal/dox/uart.dox
Executable file
132
firmware/chibios/os/hal/dox/uart.dox
Executable file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 UART UART Driver
|
||||
* @brief Generic UART Driver.
|
||||
* @details This driver abstracts a generic UART (Universal Asynchronous
|
||||
* Receiver Transmitter) peripheral, the API is designed to be:
|
||||
* - Unbuffered and copy-less, transfers are always directly performed
|
||||
* from/to the application-level buffers without extra copy
|
||||
* operations.
|
||||
* - Asynchronous, the API is always non blocking.
|
||||
* - Callbacks capable, operations completion and other events are
|
||||
* notified using callbacks.
|
||||
* .
|
||||
* Special hardware features like deep hardware buffers, DMA transfers
|
||||
* are hidden to the user but fully supportable by the low level
|
||||
* implementations.<br>
|
||||
* This driver model is best used where communication events are
|
||||
* meant to drive an higher level state machine, as example:
|
||||
* - RS485 drivers.
|
||||
* - Multipoint network drivers.
|
||||
* - Serial protocol decoders.
|
||||
* .
|
||||
* If your application requires a synchronous buffered driver then
|
||||
* the @ref SERIAL should be used instead.
|
||||
* @pre In order to use the UART driver the @p HAL_USE_UART option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section uart_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
uninit [label="UART_UNINIT", style="bold"];
|
||||
stop [label="UART_STOP\nLow Power"];
|
||||
ready [label="UART_READY\nClock Enabled"];
|
||||
|
||||
uninit -> stop [label="\nuartInit()"];
|
||||
stop -> ready [label="\nuartStart()"];
|
||||
ready -> ready [label="\nuartStart()"];
|
||||
ready -> stop [label="\nuartStop()"];
|
||||
stop -> stop [label="\nuartStop()"];
|
||||
}
|
||||
* @enddot
|
||||
*
|
||||
* @subsection uart_1_1 Transmitter sub State Machine
|
||||
* The follow diagram describes the transmitter state machine, this diagram
|
||||
* is valid while the driver is in the @p UART_READY state. This state
|
||||
* machine is automatically reset to the @p TX_IDLE state each time the
|
||||
* driver enters the @p UART_READY state.
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
tx_idle [label="TX_IDLE", style="bold"];
|
||||
tx_active [label="TX_ACTIVE"];
|
||||
tx_complete [label="TX_COMPLETE"];
|
||||
tx_fatal [label="Fatal Error", style="bold"];
|
||||
|
||||
tx_idle -> tx_active [label="\nuartStartSend()"];
|
||||
tx_idle -> tx_idle [label="\nuartStopSend()\n>uc_txend2<"];
|
||||
tx_active -> tx_complete [label="\nbuffer transmitted\n>uc_txend1<"];
|
||||
tx_active -> tx_idle [label="\nuartStopSend()"];
|
||||
tx_active -> tx_fatal [label="\nuartStartSend()"];
|
||||
tx_complete -> tx_active [label="\nuartStartSendI()\nthen\ncallback return"];
|
||||
tx_complete -> tx_idle [label="\ncallback return"];
|
||||
}
|
||||
* @enddot
|
||||
*
|
||||
* @subsection uart_1_2 Receiver sub State Machine
|
||||
* The follow diagram describes the receiver state machine, this diagram
|
||||
* is valid while the driver is in the @p UART_READY state. This state
|
||||
* machine is automatically reset to the @p RX_IDLE state each time the
|
||||
* driver enters the @p UART_READY state.
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
rx_idle [label="RX_IDLE", style="bold"];
|
||||
rx_active [label="RX_ACTIVE"];
|
||||
rx_complete [label="RX_COMPLETE"];
|
||||
rx_fatal [label="Fatal Error", style="bold"];
|
||||
|
||||
rx_idle -> rx_idle [label="\nuartStopReceive()\n>uc_rxchar<\n>uc_rxerr<"];
|
||||
rx_idle -> rx_active [label="\nuartStartReceive()"];
|
||||
|
||||
rx_active -> rx_complete [label="\nbuffer filled\n>uc_rxend<"];
|
||||
rx_active -> rx_idle [label="\nuartStopReceive()"];
|
||||
rx_active -> rx_active [label="\nreceive error\n>uc_rxerr<"];
|
||||
rx_active -> rx_fatal [label="\nuartStartReceive()"];
|
||||
rx_complete -> rx_active [label="\nuartStartReceiveI()\nthen\ncallback return"];
|
||||
rx_complete -> rx_idle [label="\ncallback return"];
|
||||
}
|
||||
* @enddot
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
191
firmware/chibios/os/hal/dox/usb.dox
Executable file
191
firmware/chibios/os/hal/dox/usb.dox
Executable file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 USB USB Driver
|
||||
* @brief Generic USB Driver.
|
||||
* @details This module implements a generic USB (Universal Serial Bus) driver
|
||||
* supporting device-mode operations.
|
||||
* @pre In order to use the USB driver the @p HAL_USE_USB option
|
||||
* must be enabled in @p halconf.h.
|
||||
*
|
||||
* @section usb_1 Driver State Machine
|
||||
* The driver implements a state machine internally, not all the driver
|
||||
* functionalities can be used in any moment, any transition not explicitly
|
||||
* shown in the following diagram has to be considered an error and shall
|
||||
* be captured by an assertion (if enabled).
|
||||
* @if LATEX_PDF
|
||||
* @dot
|
||||
digraph example {
|
||||
size="5, 7";
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="USB_STOP\nLow Power"];
|
||||
uninit [label="USB_UNINIT", style="bold"];
|
||||
ready [label="USB_READY\nClock Enabled"];
|
||||
selected [label="\nUSB_SELECTED\naddress\nassigned"];
|
||||
active [label="\nUSB_ACTIVE\nconfiguration\nselected"];
|
||||
|
||||
uninit -> stop [label=" usbInit()", constraint=false];
|
||||
stop -> stop [label="\nusbStop()"];
|
||||
stop -> ready [label="\nusbStart()"];
|
||||
ready -> stop [label="\nusbStop()"];
|
||||
ready -> ready [label="\n\nusbStart()"];
|
||||
ready -> ready [label="\nSUSPEND/WAKEUP\n>event_cb<"];
|
||||
ready -> selected [label="\nSET_ADDRESS\n>event_cb<"];
|
||||
selected -> stop [label="\nusbStop()"];
|
||||
selected -> ready [label="\nUSB RESET\n>event_cb<"];
|
||||
selected -> selected [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<"];
|
||||
selected -> active [label="\nSET_CONF(n)\n>event_cb<"];
|
||||
active -> stop [label="\nusbStop()"];
|
||||
active -> selected [label="\nSET_CONF(0)\n>event_cb<"];
|
||||
active -> active [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<\n\nEndpoints Activity\n >in_cb< or >out_cb<"];
|
||||
active -> ready [label="\nUSB RESET\n>event_cb<"];
|
||||
}
|
||||
* @enddot
|
||||
* @else
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
stop [label="USB_STOP\nLow Power"];
|
||||
uninit [label="USB_UNINIT", style="bold"];
|
||||
ready [label="USB_READY\nClock Enabled"];
|
||||
selected [label="\nUSB_SELECTED\naddress\nassigned"];
|
||||
active [label="\nUSB_ACTIVE\nconfiguration\nselected"];
|
||||
|
||||
uninit -> stop [label=" usbInit()", constraint=false];
|
||||
stop -> stop [label="\nusbStop()"];
|
||||
stop -> ready [label="\nusbStart()"];
|
||||
ready -> stop [label="\nusbStop()"];
|
||||
ready -> ready [label="\n\nusbStart()"];
|
||||
ready -> ready [label="\nSUSPEND/WAKEUP\n>event_cb<"];
|
||||
ready -> selected [label="\nSET_ADDRESS\n>event_cb<"];
|
||||
selected -> stop [label="\nusbStop()"];
|
||||
selected -> ready [label="\nUSB RESET\n>event_cb<"];
|
||||
selected -> selected [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<"];
|
||||
selected -> active [label="\nSET_CONF(n)\n>event_cb<"];
|
||||
active -> stop [label="\nusbStop()"];
|
||||
active -> selected [label="\nSET_CONF(0)\n>event_cb<"];
|
||||
active -> active [label="\nSUSPEND/WAKEUP\n>event_cb<\n\nValid EP0 Message\n>requests_hook_cb<\n\nGET DESCRIPTOR\n>get_descriptor_cb<\n\nEndpoints Activity\n >in_cb< or >out_cb<"];
|
||||
active -> ready [label="\nUSB RESET\n>event_cb<"];
|
||||
}
|
||||
* @enddot
|
||||
* @endif
|
||||
*
|
||||
* @section usb_2 USB Operations
|
||||
* The USB driver is quite complex and USB is complex in itself, it is
|
||||
* recommended to study the USB specification before trying to use the
|
||||
* driver.
|
||||
*
|
||||
* @subsection usb_2_1 USB Implementation
|
||||
* The USB driver abstracts the inner details of the underlying USB hardware.
|
||||
* The driver works asynchronously and communicates with the application
|
||||
* using callbacks. The application is responsible of the descriptors and
|
||||
* strings required by the USB device class to be implemented and of the
|
||||
* handling of the specific messages sent over the endpoint zero. Standard
|
||||
* messages are handled internally to the driver. The application can use
|
||||
* hooks in order to handle custom messages or override the handling of the
|
||||
* default handling of standard messages.
|
||||
*
|
||||
* @subsection usb_2_2 USB Endpoints
|
||||
* USB endpoints are the objects that the application uses to exchange
|
||||
* data with the host. There are two kind of endpoints:
|
||||
* - <b>IN</b> endpoints are used by the application to transmit data to
|
||||
* the host.<br>
|
||||
* - <b>OUT</b> endpoints are used by the application to receive data from
|
||||
* the host.
|
||||
* .
|
||||
* The driver invokes a callback after finishing an IN or OUT transaction.
|
||||
* States diagram for OUT endpoints in transaction mode:
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
disabled [label="EP_DISABLED\nDisabled", style="bold"];
|
||||
receiving [label="EP_BUSY\nReceiving"];
|
||||
idle [label="EP_IDLE\nReady"];
|
||||
|
||||
disabled -> idle [label="\nusbInitEndpointI()"];
|
||||
idle -> receiving [label="\nusbPrepareReceive()\nusbStartReceiveI()"];
|
||||
receiving -> receiving [label="\nmore packets"];
|
||||
receiving -> idle [label="\nreception end\n>out_cb<"];
|
||||
receiving -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
|
||||
idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
|
||||
}
|
||||
* @enddot
|
||||
* <br><br>
|
||||
* States diagram for IN endpoints in transaction mode:
|
||||
* @dot
|
||||
digraph example {
|
||||
rankdir="LR";
|
||||
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true",
|
||||
width="0.9", height="0.9"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
disabled [label="EP_DISABLED\nDisabled", style="bold"];
|
||||
transmitting [label="EP_BUSY\nTransmitting"];
|
||||
idle [label="EP_IDLE\nReady"];
|
||||
|
||||
disabled -> idle [label="\usbInitEndpointI()"];
|
||||
idle -> transmitting [label="\nusbPrepareTransmit()\nusbStartTransmitI()"];
|
||||
transmitting -> transmitting [label="\nmore packets"];
|
||||
transmitting -> idle [label="\ntransmission end\n>in_cb<"];
|
||||
transmitting -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
|
||||
idle -> disabled [label="\nUSB RESET\nusbDisableEndpointsI()"];
|
||||
}
|
||||
* @enddot
|
||||
* <br><br>
|
||||
*
|
||||
* @subsection usb_2_4 USB Callbacks
|
||||
* The USB driver uses callbacks in order to interact with the application.
|
||||
* There are several kinds of callbacks to be handled:
|
||||
* - Driver events callback. As example errors, suspend event, reset event
|
||||
* etc.
|
||||
* - Messages Hook callback. This hook allows the application to implement
|
||||
* handling of custom messages or to override the default handling of
|
||||
* standard messages on endpoint zero.
|
||||
* - Descriptor Requested callback. When the driver endpoint zero handler
|
||||
* receives a GET DESCRIPTOR message and needs to send a descriptor to
|
||||
* the host it queries the application using this callback.
|
||||
* - Start of Frame callback. This callback is invoked each time a SOF
|
||||
* packet is received.
|
||||
* - Endpoint callbacks. Each endpoint informs the application about I/O
|
||||
* conditions using those callbacks.
|
||||
* .
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
90
firmware/chibios/os/hal/hal.dox
Executable file
90
firmware/chibios/os/hal/hal.dox
Executable file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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. The HAL is the
|
||||
* abstract interface between ChibiOS/RT application and hardware.
|
||||
*
|
||||
* @section hal_device_driver_arch HAL Device Drivers Architecture
|
||||
* 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:
|
||||
* - @p @<driver@>.c, the HLD implementation file. This file must be
|
||||
* included in the Makefile in order to use the driver.
|
||||
* - @p @<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:
|
||||
* - @p @<driver@>_lld.c, the LLD implementation file. This file must be
|
||||
* included in the Makefile in order to use the driver.
|
||||
* - @p @<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
|
||||
* MMC_SPI driver uses the SPI and PAL drivers in order to implement
|
||||
* its functionalities.
|
||||
* .
|
||||
* @subsection hal_device_driver_diagram Diagram
|
||||
* @dot
|
||||
digraph example {
|
||||
graph [size="5, 7", pad="1.5, 0"];
|
||||
node [shape=rectangle, fontname=Helvetica, fontsize=8,
|
||||
fixedsize="true", width="2.0", height="0.4"];
|
||||
edge [fontname=Helvetica, fontsize=8];
|
||||
|
||||
app [label="Application"];
|
||||
hld [label="High Level Driver"];
|
||||
lld [label="Low Level Driver"];
|
||||
hw [label="Microcontroller Hardware"];
|
||||
hal_lld [label="HAL shared low level code"];
|
||||
|
||||
app->hld;
|
||||
hld->lld;
|
||||
lld-> hw;
|
||||
lld->hal_lld;
|
||||
hal_lld->hw;
|
||||
}
|
||||
* @enddot
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup HAL_CONF Configuration
|
||||
* @brief HAL Configuration.
|
||||
* @details The file @p halconf.h contains the high level settings for all
|
||||
* the drivers supported by the HAL. The low level, platform dependent,
|
||||
* settings are contained in the @p mcuconf.h file instead and are describe
|
||||
* in the various platforms reference manuals.
|
||||
*
|
||||
* @ingroup IO
|
||||
*/
|
||||
25
firmware/chibios/os/hal/hal.mk
Executable file
25
firmware/chibios/os/hal/hal.mk
Executable file
@@ -0,0 +1,25 @@
|
||||
# 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 HAL 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/ext.c \
|
||||
${CHIBIOS}/os/hal/src/gpt.c \
|
||||
${CHIBIOS}/os/hal/src/i2c.c \
|
||||
${CHIBIOS}/os/hal/src/icu.c \
|
||||
${CHIBIOS}/os/hal/src/mac.c \
|
||||
${CHIBIOS}/os/hal/src/mmc_spi.c \
|
||||
${CHIBIOS}/os/hal/src/mmcsd.c \
|
||||
${CHIBIOS}/os/hal/src/pal.c \
|
||||
${CHIBIOS}/os/hal/src/pwm.c \
|
||||
${CHIBIOS}/os/hal/src/rtc.c \
|
||||
${CHIBIOS}/os/hal/src/sdc.c \
|
||||
${CHIBIOS}/os/hal/src/serial.c \
|
||||
${CHIBIOS}/os/hal/src/serial_usb.c \
|
||||
${CHIBIOS}/os/hal/src/spi.c \
|
||||
${CHIBIOS}/os/hal/src/tm.c \
|
||||
${CHIBIOS}/os/hal/src/uart.c \
|
||||
${CHIBIOS}/os/hal/src/usb.c
|
||||
|
||||
# Required include directories
|
||||
HALINC = ${CHIBIOS}/os/hal/include
|
||||
316
firmware/chibios/os/hal/include/adc.h
Executable file
316
firmware/chibios/os/hal/include/adc.h
Executable file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name ADC configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if ADC_USE_MUTUAL_EXCLUSION && !CH_USE_MUTEXES && !CH_USE_SEMAPHORES
|
||||
#error "ADC_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 {
|
||||
ADC_UNINIT = 0, /**< Not initialized. */
|
||||
ADC_STOP = 1, /**< Stopped. */
|
||||
ADC_READY = 2, /**< Ready. */
|
||||
ADC_ACTIVE = 3, /**< Converting. */
|
||||
ADC_COMPLETE = 4, /**< Conversion complete. */
|
||||
ADC_ERROR = 5 /**< Conversion complete. */
|
||||
} adcstate_t;
|
||||
|
||||
#include "adc_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
#if ADC_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Resumes a thread waiting for a conversion completion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _adc_reset_i(adcp) { \
|
||||
if ((adcp)->thread != NULL) { \
|
||||
Thread *tp = (adcp)->thread; \
|
||||
(adcp)->thread = NULL; \
|
||||
tp->p_u.rdymsg = RDY_RESET; \
|
||||
chSchReadyI(tp); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resumes a thread waiting for a conversion completion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _adc_reset_s(adcp) { \
|
||||
if ((adcp)->thread != NULL) { \
|
||||
Thread *tp = (adcp)->thread; \
|
||||
(adcp)->thread = NULL; \
|
||||
chSchWakeupS(tp, RDY_RESET); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wakes up the waiting thread.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _adc_wakeup_isr(adcp) { \
|
||||
chSysLockFromIsr(); \
|
||||
if ((adcp)->thread != NULL) { \
|
||||
Thread *tp; \
|
||||
tp = (adcp)->thread; \
|
||||
(adcp)->thread = NULL; \
|
||||
tp->p_u.rdymsg = RDY_OK; \
|
||||
chSchReadyI(tp); \
|
||||
} \
|
||||
chSysUnlockFromIsr(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wakes up the waiting thread with a timeout message.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _adc_timeout_isr(adcp) { \
|
||||
chSysLockFromIsr(); \
|
||||
if ((adcp)->thread != NULL) { \
|
||||
Thread *tp; \
|
||||
tp = (adcp)->thread; \
|
||||
(adcp)->thread = NULL; \
|
||||
tp->p_u.rdymsg = RDY_TIMEOUT; \
|
||||
chSchReadyI(tp); \
|
||||
} \
|
||||
chSysUnlockFromIsr(); \
|
||||
}
|
||||
|
||||
#else /* !ADC_USE_WAIT */
|
||||
#define _adc_reset_i(adcp)
|
||||
#define _adc_reset_s(adcp)
|
||||
#define _adc_wakeup_isr(adcp)
|
||||
#define _adc_timeout_isr(adcp)
|
||||
#endif /* !ADC_USE_WAIT */
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, half buffer event.
|
||||
* @details This code handles the portable part of the ISR code:
|
||||
* - Callback invocation.
|
||||
* .
|
||||
* @note This macro is meant to be used in the low level drivers
|
||||
* implementation only.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _adc_isr_half_code(adcp) { \
|
||||
if ((adcp)->grpp->end_cb != NULL) { \
|
||||
(adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth / 2); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, full buffer event.
|
||||
* @details This code handles the portable part of the ISR code:
|
||||
* - Callback invocation.
|
||||
* - Waiting thread wakeup, if any.
|
||||
* - Driver state transitions.
|
||||
* .
|
||||
* @note This macro is meant to be used in the low level drivers
|
||||
* implementation only.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _adc_isr_full_code(adcp) { \
|
||||
if ((adcp)->grpp->circular) { \
|
||||
/* Callback handling.*/ \
|
||||
if ((adcp)->grpp->end_cb != NULL) { \
|
||||
if ((adcp)->depth > 1) { \
|
||||
/* Invokes the callback passing the 2nd half of the buffer.*/ \
|
||||
size_t half = (adcp)->depth / 2; \
|
||||
size_t half_index = half * (adcp)->grpp->num_channels; \
|
||||
(adcp)->grpp->end_cb(adcp, (adcp)->samples + half_index, half); \
|
||||
} \
|
||||
else { \
|
||||
/* Invokes the callback passing the whole buffer.*/ \
|
||||
(adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
/* End conversion.*/ \
|
||||
adc_lld_stop_conversion(adcp); \
|
||||
if ((adcp)->grpp->end_cb != NULL) { \
|
||||
(adcp)->state = ADC_COMPLETE; \
|
||||
/* Invoke the callback passing the whole buffer.*/ \
|
||||
(adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
|
||||
if ((adcp)->state == ADC_COMPLETE) { \
|
||||
(adcp)->state = ADC_READY; \
|
||||
(adcp)->grpp = NULL; \
|
||||
} \
|
||||
} \
|
||||
else { \
|
||||
(adcp)->state = ADC_READY; \
|
||||
(adcp)->grpp = NULL; \
|
||||
} \
|
||||
_adc_wakeup_isr(adcp); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, error event.
|
||||
* @details This code handles the portable part of the ISR code:
|
||||
* - Callback invocation.
|
||||
* - Waiting thread timeout signaling, if any.
|
||||
* - Driver state transitions.
|
||||
* .
|
||||
* @note This macro is meant to be used in the low level drivers
|
||||
* implementation only.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
* @param[in] err platform dependent error code
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _adc_isr_error_code(adcp, err) { \
|
||||
adc_lld_stop_conversion(adcp); \
|
||||
if ((adcp)->grpp->error_cb != NULL) { \
|
||||
(adcp)->state = ADC_ERROR; \
|
||||
(adcp)->grpp->error_cb(adcp, err); \
|
||||
if ((adcp)->state == ADC_ERROR) \
|
||||
(adcp)->state = ADC_READY; \
|
||||
} \
|
||||
(adcp)->grpp = NULL; \
|
||||
_adc_timeout_isr(adcp); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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);
|
||||
void adcStartConversion(ADCDriver *adcp,
|
||||
const ADCConversionGroup *grpp,
|
||||
adcsample_t *samples,
|
||||
size_t depth);
|
||||
void adcStartConversionI(ADCDriver *adcp,
|
||||
const ADCConversionGroup *grpp,
|
||||
adcsample_t *samples,
|
||||
size_t depth);
|
||||
void adcStopConversion(ADCDriver *adcp);
|
||||
void adcStopConversionI(ADCDriver *adcp);
|
||||
#if ADC_USE_WAIT
|
||||
msg_t adcConvert(ADCDriver *adcp,
|
||||
const ADCConversionGroup *grpp,
|
||||
adcsample_t *samples,
|
||||
size_t depth);
|
||||
#endif
|
||||
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
void adcAcquireBus(ADCDriver *adcp);
|
||||
void adcReleaseBus(ADCDriver *adcp);
|
||||
#endif /* ADC_USE_MUTUAL_EXCLUSION */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
#endif /* _ADC_H_ */
|
||||
|
||||
/** @} */
|
||||
165
firmware/chibios/os/hal/include/can.h
Executable file
165
firmware/chibios/os/hal/include/can.h
Executable file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_CAN || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name CAN status flags
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Special mailbox identifier.
|
||||
*/
|
||||
#define CAN_ANY_MAILBOX 0
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name CAN configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Sleep mode related APIs inclusion switch.
|
||||
* @details This option can only be enabled if the CAN implementation supports
|
||||
* the sleep mode, see the macro @p CAN_SUPPORTS_SLEEP exported by
|
||||
* the underlying implementation.
|
||||
*/
|
||||
#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, /**< Not initialized. */
|
||||
CAN_STOP = 1, /**< Stopped. */
|
||||
CAN_STARTING = 2, /**< Starting. */
|
||||
CAN_READY = 3, /**< Ready. */
|
||||
CAN_SLEEP = 4 /**< Sleep state. */
|
||||
} canstate_t;
|
||||
|
||||
#include "can_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Converts a mailbox index to a bit mask.
|
||||
*/
|
||||
#define CAN_MAILBOX_TO_MASK(mbx) (1 << ((mbx) - 1))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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,
|
||||
canmbx_t mailbox,
|
||||
const CANTxFrame *ctfp,
|
||||
systime_t timeout);
|
||||
msg_t canReceive(CANDriver *canp,
|
||||
canmbx_t mailbox,
|
||||
CANRxFrame *crfp,
|
||||
systime_t timeout);
|
||||
#if CAN_USE_SLEEP_MODE
|
||||
void canSleep(CANDriver *canp);
|
||||
void canWakeup(CANDriver *canp);
|
||||
#endif /* CAN_USE_SLEEP_MODE */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_CAN */
|
||||
|
||||
#endif /* _CAN_H_ */
|
||||
|
||||
/** @} */
|
||||
161
firmware/chibios/os/hal/include/ext.h
Executable file
161
firmware/chibios/os/hal/include/ext.h
Executable file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 ext.h
|
||||
* @brief EXT Driver macros and structures.
|
||||
*
|
||||
* @addtogroup EXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _EXT_H_
|
||||
#define _EXT_H_
|
||||
|
||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name EXT channel modes
|
||||
* @{
|
||||
*/
|
||||
#define EXT_CH_MODE_EDGES_MASK 3 /**< @brief Mask of edges field. */
|
||||
#define EXT_CH_MODE_DISABLED 0 /**< @brief Channel disabled. */
|
||||
#define EXT_CH_MODE_RISING_EDGE 1 /**< @brief Rising edge callback. */
|
||||
#define EXT_CH_MODE_FALLING_EDGE 2 /**< @brief Falling edge callback. */
|
||||
#define EXT_CH_MODE_BOTH_EDGES 3 /**< @brief Both edges callback. */
|
||||
|
||||
#define EXT_CH_MODE_AUTOSTART 4 /**< @brief Channel started
|
||||
automatically on driver start. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
EXT_UNINIT = 0, /**< Not initialized. */
|
||||
EXT_STOP = 1, /**< Stopped. */
|
||||
EXT_ACTIVE = 2, /**< Active. */
|
||||
} extstate_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing a EXT driver.
|
||||
*/
|
||||
typedef struct EXTDriver EXTDriver;
|
||||
|
||||
#include "ext_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables an EXT channel.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
* @param[in] channel channel to be enabled
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define extChannelEnableI(extp, channel) ext_lld_channel_enable(extp, channel)
|
||||
|
||||
/**
|
||||
* @brief Disables an EXT channel.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
* @param[in] channel channel to be disabled
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define extChannelDisableI(extp, channel) ext_lld_channel_disable(extp, channel)
|
||||
|
||||
/**
|
||||
* @brief Changes the operation mode of a channel.
|
||||
* @note This function attempts to write over the current configuration
|
||||
* structure that must have been not declared constant. This
|
||||
* violates the @p const qualifier in @p extStart() but it is
|
||||
* intentional. This function cannot be used if the configuration
|
||||
* structure is declared @p const.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
* @param[in] channel channel to be changed
|
||||
* @param[in] extcp new configuration for the channel
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define extSetChannelMode(extp, channel, extcp) { \
|
||||
chSysLock(); \
|
||||
extSetChannelModeI(extp, channel, extcp); \
|
||||
chSysUnlock(); \
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void extInit(void);
|
||||
void extObjectInit(EXTDriver *extp);
|
||||
void extStart(EXTDriver *extp, const EXTConfig *config);
|
||||
void extStop(EXTDriver *extp);
|
||||
void extChannelEnable(EXTDriver *extp, expchannel_t channel);
|
||||
void extChannelDisable(EXTDriver *extp, expchannel_t channel);
|
||||
void extSetChannelModeI(EXTDriver *extp,
|
||||
expchannel_t channel,
|
||||
const EXTChannelConfig *extcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_EXT */
|
||||
|
||||
#endif /* _EXT_H_ */
|
||||
|
||||
/** @} */
|
||||
130
firmware/chibios/os/hal/include/gpt.h
Executable file
130
firmware/chibios/os/hal/include/gpt.h
Executable file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 gpt.h
|
||||
* @brief GPT Driver macros and structures.
|
||||
*
|
||||
* @addtogroup GPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GPT_H_
|
||||
#define _GPT_H_
|
||||
|
||||
#if HAL_USE_GPT || 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 {
|
||||
GPT_UNINIT = 0, /**< Not initialized. */
|
||||
GPT_STOP = 1, /**< Stopped. */
|
||||
GPT_READY = 2, /**< Ready. */
|
||||
GPT_CONTINUOUS = 3, /**< Active in continuous mode. */
|
||||
GPT_ONESHOT = 4 /**< Active in one shot mode. */
|
||||
} gptstate_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing a GPT driver.
|
||||
*/
|
||||
typedef struct GPTDriver GPTDriver;
|
||||
|
||||
/**
|
||||
* @brief GPT notification callback type.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
*/
|
||||
typedef void (*gptcallback_t)(GPTDriver *gptp);
|
||||
|
||||
#include "gpt_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Changes the interval of GPT peripheral.
|
||||
* @details This function changes the interval of a running GPT unit.
|
||||
* @pre The GPT unit must have been activated using @p gptStart().
|
||||
* @pre The GPT unit must have been running in continuous mode using
|
||||
* @p gptStartContinuous().
|
||||
* @post The GPT unit interval is changed to the new value.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
* @param[in] interval new cycle time in timer ticks
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define gptChangeIntervalI(gptp, interval) { \
|
||||
gpt_lld_change_interval(gptp, interval); \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void gptInit(void);
|
||||
void gptObjectInit(GPTDriver *gptp);
|
||||
void gptStart(GPTDriver *gptp, const GPTConfig *config);
|
||||
void gptStop(GPTDriver *gptp);
|
||||
void gptStartContinuous(GPTDriver *gptp, gptcnt_t interval);
|
||||
void gptStartContinuousI(GPTDriver *gptp, gptcnt_t interval);
|
||||
void gptChangeInterval(GPTDriver *gptp, gptcnt_t interval);
|
||||
void gptStartOneShot(GPTDriver *gptp, gptcnt_t interval);
|
||||
void gptStartOneShotI(GPTDriver *gptp, gptcnt_t interval);
|
||||
void gptStopTimer(GPTDriver *gptp);
|
||||
void gptStopTimerI(GPTDriver *gptp);
|
||||
void gptPolledDelay(GPTDriver *gptp, gptcnt_t interval);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_GPT */
|
||||
|
||||
#endif /* _GPT_H_ */
|
||||
|
||||
/** @} */
|
||||
219
firmware/chibios/os/hal/include/hal.h
Executable file
219
firmware/chibios/os/hal/include/hal.h
Executable file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 "ch.h"
|
||||
#include "board.h"
|
||||
#include "halconf.h"
|
||||
|
||||
#include "hal_lld.h"
|
||||
|
||||
/* Abstract interfaces.*/
|
||||
#include "io_channel.h"
|
||||
#include "io_block.h"
|
||||
|
||||
/* Shared headers.*/
|
||||
#include "mmcsd.h"
|
||||
|
||||
/* Layered drivers.*/
|
||||
#include "tm.h"
|
||||
#include "pal.h"
|
||||
#include "adc.h"
|
||||
#include "can.h"
|
||||
#include "ext.h"
|
||||
#include "gpt.h"
|
||||
#include "i2c.h"
|
||||
#include "icu.h"
|
||||
#include "mac.h"
|
||||
#include "pwm.h"
|
||||
#include "rtc.h"
|
||||
#include "serial.h"
|
||||
#include "sdc.h"
|
||||
#include "spi.h"
|
||||
#include "uart.h"
|
||||
#include "usb.h"
|
||||
|
||||
/* Complex drivers.*/
|
||||
#include "mmc_spi.h"
|
||||
#include "serial_usb.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if HAL_IMPLEMENTS_COUNTERS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @name Time conversion utilities for the realtime counter
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Seconds to realtime ticks.
|
||||
* @details Converts from seconds to realtime ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] sec number of seconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define S2RTT(sec) (halGetCounterFrequency() * (sec))
|
||||
|
||||
/**
|
||||
* @brief Milliseconds to realtime ticks.
|
||||
* @details Converts from milliseconds to realtime ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] msec number of milliseconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define MS2RTT(msec) (((halGetCounterFrequency() + 999UL) / 1000UL) * (msec))
|
||||
|
||||
/**
|
||||
* @brief Microseconds to realtime ticks.
|
||||
* @details Converts from microseconds to realtime ticks number.
|
||||
* @note The result is rounded upward to the next tick boundary.
|
||||
*
|
||||
* @param[in] usec number of microseconds
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define US2RTT(usec) (((halGetCounterFrequency() + 999999UL) / 1000000UL) * \
|
||||
(usec))
|
||||
|
||||
/**
|
||||
* @brief Realtime ticks to seconds to.
|
||||
* @details Converts from realtime ticks number to seconds.
|
||||
*
|
||||
* @param[in] ticks number of ticks
|
||||
* @return The number of seconds.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define RTT2S(ticks) ((ticks) / halGetCounterFrequency())
|
||||
|
||||
/**
|
||||
* @brief Realtime ticks to milliseconds.
|
||||
* @details Converts from realtime ticks number to milliseconds.
|
||||
*
|
||||
* @param[in] ticks number of ticks
|
||||
* @return The number of milliseconds.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define RTT2MS(ticks) ((ticks) / (halGetCounterFrequency() / 1000UL))
|
||||
|
||||
/**
|
||||
* @brief Realtime ticks to microseconds.
|
||||
* @details Converts from realtime ticks number to microseconds.
|
||||
*
|
||||
* @param[in] ticks number of ticks
|
||||
* @return The number of microseconds.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define RTT2US(ticks) ((ticks) / (halGetCounterFrequency() / 1000000UL))
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the current value of the system free running counter.
|
||||
* @note This is an optional service that could not be implemented in
|
||||
* all HAL implementations.
|
||||
* @note This function can be called from any context.
|
||||
*
|
||||
* @return The value of the system free running counter of
|
||||
* type halrtcnt_t.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define halGetCounterValue() hal_lld_get_counter_value()
|
||||
|
||||
/**
|
||||
* @brief Realtime counter frequency.
|
||||
* @note This is an optional service that could not be implemented in
|
||||
* all HAL implementations.
|
||||
* @note This function can be called from any context.
|
||||
*
|
||||
* @return The realtime counter frequency of type halclock_t.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define halGetCounterFrequency() hal_lld_get_counter_frequency()
|
||||
/** @} */
|
||||
#endif /* HAL_IMPLEMENTS_COUNTERS */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void halInit(void);
|
||||
#if HAL_IMPLEMENTS_COUNTERS
|
||||
bool_t halIsCounterWithin(halrtcnt_t start, halrtcnt_t end);
|
||||
void halPolledDelay(halrtcnt_t ticks);
|
||||
#endif /* HAL_IMPLEMENTS_COUNTERS */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HAL_H_ */
|
||||
|
||||
/** @} */
|
||||
154
firmware/chibios/os/hal/include/i2c.h
Executable file
154
firmware/chibios/os/hal/include/i2c.h
Executable file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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.
|
||||
*/
|
||||
/*
|
||||
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
|
||||
aka barthess.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file i2c.h
|
||||
* @brief I2C Driver macros and structures.
|
||||
*
|
||||
* @addtogroup I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name I2C bus error conditions
|
||||
* @{
|
||||
*/
|
||||
#define I2CD_NO_ERROR 0x00 /**< @brief No error. */
|
||||
#define I2CD_BUS_ERROR 0x01 /**< @brief Bus Error. */
|
||||
#define I2CD_ARBITRATION_LOST 0x02 /**< @brief Arbitration Lost. */
|
||||
#define I2CD_ACK_FAILURE 0x04 /**< @brief Acknowledge Failure. */
|
||||
#define I2CD_OVERRUN 0x08 /**< @brief Overrun/Underrun. */
|
||||
#define I2CD_PEC_ERROR 0x10 /**< @brief PEC Error in
|
||||
reception. */
|
||||
#define I2CD_TIMEOUT 0x20 /**< @brief Hardware timeout. */
|
||||
#define I2CD_SMB_ALERT 0x40 /**< @brief SMBus Alert. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables the mutual exclusion APIs on the I2C bus.
|
||||
*/
|
||||
#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define I2C_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if I2C_USE_MUTUAL_EXCLUSION && !CH_USE_MUTEXES && !CH_USE_SEMAPHORES
|
||||
#error "I2C_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 {
|
||||
I2C_UNINIT = 0, /**< Not initialized. */
|
||||
I2C_STOP = 1, /**< Stopped. */
|
||||
I2C_READY = 2, /**< Ready. */
|
||||
I2C_ACTIVE_TX = 3, /**< Transmitting. */
|
||||
I2C_ACTIVE_RX = 4, /**< Receiving. */
|
||||
I2C_LOCKED = 5 /**> Bus or driver locked. */
|
||||
} i2cstate_t;
|
||||
|
||||
#include "i2c_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Wrap i2cMasterTransmitTimeout function with TIME_INFINITE timeout.
|
||||
* @api
|
||||
*/
|
||||
#define i2cMasterTransmit(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes) \
|
||||
(i2cMasterTransmitTimeout(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes, \
|
||||
TIME_INFINITE))
|
||||
|
||||
/**
|
||||
* @brief Wrap i2cMasterReceiveTimeout function with TIME_INFINITE timeout.
|
||||
* @api
|
||||
*/
|
||||
#define i2cMasterReceive(i2cp, addr, rxbuf, rxbytes) \
|
||||
(i2cMasterReceiveTimeout(i2cp, addr, rxbuf, rxbytes, TIME_INFINITE))
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void i2cInit(void);
|
||||
void i2cObjectInit(I2CDriver *i2cp);
|
||||
void i2cStart(I2CDriver *i2cp, const I2CConfig *config);
|
||||
void i2cStop(I2CDriver *i2cp);
|
||||
i2cflags_t i2cGetErrors(I2CDriver *i2cp);
|
||||
msg_t i2cMasterTransmitTimeout(I2CDriver *i2cp,
|
||||
i2caddr_t addr,
|
||||
const uint8_t *txbuf, size_t txbytes,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout);
|
||||
msg_t i2cMasterReceiveTimeout(I2CDriver *i2cp,
|
||||
i2caddr_t addr,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout);
|
||||
#if I2C_USE_MUTUAL_EXCLUSION
|
||||
void i2cAcquireBus(I2CDriver *i2cp);
|
||||
void i2cReleaseBus(I2CDriver *i2cp);
|
||||
#endif /* I2C_USE_MUTUAL_EXCLUSION */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_I2C */
|
||||
|
||||
#endif /* _I2C_H_ */
|
||||
|
||||
/** @} */
|
||||
203
firmware/chibios/os/hal/include/icu.h
Executable file
203
firmware/chibios/os/hal/include/icu.h
Executable file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 icu.h
|
||||
* @brief ICU Driver macros and structures.
|
||||
*
|
||||
* @addtogroup ICU
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ICU_H_
|
||||
#define _ICU_H_
|
||||
|
||||
#if HAL_USE_ICU || 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 {
|
||||
ICU_UNINIT = 0, /**< Not initialized. */
|
||||
ICU_STOP = 1, /**< Stopped. */
|
||||
ICU_READY = 2, /**< Ready. */
|
||||
ICU_WAITING = 3, /**< Waiting first edge. */
|
||||
ICU_ACTIVE = 4, /**< Active cycle phase. */
|
||||
ICU_IDLE = 5, /**< Idle cycle phase. */
|
||||
} icustate_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an ICU driver.
|
||||
*/
|
||||
typedef struct ICUDriver ICUDriver;
|
||||
|
||||
/**
|
||||
* @brief ICU notification callback type.
|
||||
*
|
||||
* @param[in] icup pointer to a @p ICUDriver object
|
||||
*/
|
||||
typedef void (*icucallback_t)(ICUDriver *icup);
|
||||
|
||||
#include "icu_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables the input capture.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define icuEnableI(icup) icu_lld_enable(icup)
|
||||
|
||||
/**
|
||||
* @brief Disables the input capture.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define icuDisableI(icup) icu_lld_disable(icup)
|
||||
|
||||
/**
|
||||
* @brief Returns the width of the latest pulse.
|
||||
* @details The pulse width is defined as number of ticks between the start
|
||||
* edge and the stop edge.
|
||||
* @note This function is meant to be invoked from the width capture
|
||||
* callback only.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define icuGetWidth(icup) icu_lld_get_width(icup)
|
||||
|
||||
/**
|
||||
* @brief Returns the width of the latest cycle.
|
||||
* @details The cycle width is defined as number of ticks between a start
|
||||
* edge and the next start edge.
|
||||
* @note This function is meant to be invoked from the width capture
|
||||
* callback only.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
* @return The number of ticks.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define icuGetPeriod(icup) icu_lld_get_period(icup)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Common ISR code, ICU width event.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _icu_isr_invoke_width_cb(icup) { \
|
||||
if ((icup)->state != ICU_WAITING) { \
|
||||
(icup)->state = ICU_IDLE; \
|
||||
(icup)->config->width_cb(icup); \
|
||||
} \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, ICU period event.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _icu_isr_invoke_period_cb(icup) { \
|
||||
icustate_t previous_state = (icup)->state; \
|
||||
(icup)->state = ICU_ACTIVE; \
|
||||
if (previous_state != ICU_WAITING) \
|
||||
(icup)->config->period_cb(icup); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, ICU timer overflow event.
|
||||
*
|
||||
* @param[in] icup pointer to the @p ICUDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _icu_isr_invoke_overflow_cb(icup) { \
|
||||
(icup)->config->overflow_cb(icup); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void icuInit(void);
|
||||
void icuObjectInit(ICUDriver *icup);
|
||||
void icuStart(ICUDriver *icup, const ICUConfig *config);
|
||||
void icuStop(ICUDriver *icup);
|
||||
void icuEnable(ICUDriver *icup);
|
||||
void icuDisable(ICUDriver *icup);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_ICU */
|
||||
|
||||
#endif /* _ICU_H_ */
|
||||
|
||||
/** @} */
|
||||
276
firmware/chibios/os/hal/include/io_block.h
Executable file
276
firmware/chibios/os/hal/include/io_block.h
Executable file
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 io_block.h
|
||||
* @brief I/O block devices access.
|
||||
* @details This header defines an abstract interface useful to access generic
|
||||
* I/O block devices in a standardized way.
|
||||
*
|
||||
* @addtogroup IO_BLOCK
|
||||
* @details This module defines an abstract interface for accessing generic
|
||||
* block devices.<br>
|
||||
* Note that no code is present, just abstract interfaces-like
|
||||
* structures, you should look at the system as to a set of
|
||||
* abstract C++ classes (even if written in C). This system
|
||||
* has then advantage to make the access to block devices
|
||||
* independent from the implementation logic.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _IO_BLOCK_H_
|
||||
#define _IO_BLOCK_H_
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
BLK_UNINIT = 0, /**< Not initialized. */
|
||||
BLK_STOP = 1, /**< Stopped. */
|
||||
BLK_ACTIVE = 2, /**< Interface active. */
|
||||
BLK_CONNECTING = 3, /**< Connection in progress. */
|
||||
BLK_DISCONNECTING = 4, /**< Disconnection in progress. */
|
||||
BLK_READY = 5, /**< Device ready. */
|
||||
BLK_READING = 6, /**< Read operation in progress. */
|
||||
BLK_WRITING = 7, /**< Write operation in progress. */
|
||||
BLK_SYNCING = 8 /**< Sync. operation in progress. */
|
||||
} blkstate_t;
|
||||
|
||||
/**
|
||||
* @brief Block device info.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t blk_size; /**< @brief Block size in bytes. */
|
||||
uint32_t blk_num; /**< @brief Total number of blocks. */
|
||||
} BlockDeviceInfo;
|
||||
|
||||
/**
|
||||
* @brief @p BaseBlockDevice specific methods.
|
||||
*/
|
||||
#define _base_block_device_methods \
|
||||
/* Removable media detection.*/ \
|
||||
bool_t (*is_inserted)(void *instance); \
|
||||
/* Removable write protection detection.*/ \
|
||||
bool_t (*is_protected)(void *instance); \
|
||||
/* Connection to the block device.*/ \
|
||||
bool_t (*connect)(void *instance); \
|
||||
/* Disconnection from the block device.*/ \
|
||||
bool_t (*disconnect)(void *instance); \
|
||||
/* Reads one or more blocks.*/ \
|
||||
bool_t (*read)(void *instance, uint32_t startblk, \
|
||||
uint8_t *buffer, uint32_t n); \
|
||||
/* Writes one or more blocks.*/ \
|
||||
bool_t (*write)(void *instance, uint32_t startblk, \
|
||||
const uint8_t *buffer, uint32_t n); \
|
||||
/* Write operations synchronization.*/ \
|
||||
bool_t (*sync)(void *instance); \
|
||||
/* Obtains info about the media.*/ \
|
||||
bool_t (*get_info)(void *instance, BlockDeviceInfo *bdip);
|
||||
|
||||
/**
|
||||
* @brief @p BaseBlockDevice specific data.
|
||||
*/
|
||||
#define _base_block_device_data \
|
||||
/* Driver state.*/ \
|
||||
blkstate_t state;
|
||||
|
||||
/**
|
||||
* @brief @p BaseBlockDevice virtual methods table.
|
||||
*/
|
||||
struct BaseBlockDeviceVMT {
|
||||
_base_block_device_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Base block device class.
|
||||
* @details This class represents a generic, block-accessible, device.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief Virtual Methods Table.*/
|
||||
const struct BaseBlockDeviceVMT *vmt;
|
||||
_base_block_device_data
|
||||
} BaseBlockDevice;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseBlockDevice)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the driver state.
|
||||
* @note Can be called in ISR context.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
*
|
||||
* @return The driver state.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define blkGetDriverState(ip) ((ip)->state)
|
||||
|
||||
/**
|
||||
* @brief Determines if the device is transferring data.
|
||||
* @note Can be called in ISR context.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
*
|
||||
* @return The driver state.
|
||||
* @retval FALSE the device is not transferring data.
|
||||
* @retval TRUE the device not transferring data.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define blkIsTransferring(ip) ((((ip)->state) == BLK_CONNECTING) || \
|
||||
(((ip)->state) == BLK_DISCONNECTING) || \
|
||||
(((ip)->state) == BLK_READING) || \
|
||||
(((ip)->state) == BLK_WRITING))
|
||||
|
||||
/**
|
||||
* @brief Returns the media insertion status.
|
||||
* @note On some implementations this function can only be called if the
|
||||
* device is not transferring data.
|
||||
* The function @p blkIsTransferring() should be used before calling
|
||||
* this function.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
*
|
||||
* @return The media state.
|
||||
* @retval FALSE media not inserted.
|
||||
* @retval TRUE media inserted.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkIsInserted(ip) ((ip)->vmt->is_inserted(ip))
|
||||
|
||||
/**
|
||||
* @brief Returns the media write protection status.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
*
|
||||
* @return The media state.
|
||||
* @retval FALSE writable media.
|
||||
* @retval TRUE non writable media.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkIsWriteProtected(ip) ((ip)->vmt->is_protected(ip))
|
||||
|
||||
/**
|
||||
* @brief Performs the initialization procedure on the block device.
|
||||
* @details This function should be performed before I/O operations can be
|
||||
* attempted on the block device and after insertion has been
|
||||
* confirmed using @p blkIsInserted().
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval CH_SUCCESS operation succeeded.
|
||||
* @retval CH_FAILED operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkConnect(ip) ((ip)->vmt->connect(ip))
|
||||
|
||||
/**
|
||||
* @brief Terminates operations on the block device.
|
||||
* @details This operation safely terminates operations on the block device.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval CH_SUCCESS operation succeeded.
|
||||
* @retval CH_FAILED operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkDisconnect(ip) ((ip)->vmt->disconnect(ip))
|
||||
|
||||
/**
|
||||
* @brief Reads one or more blocks.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
* @param[in] startblk first block to read
|
||||
* @param[out] buf pointer to the read buffer
|
||||
* @param[in] n number of blocks to read
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval CH_SUCCESS operation succeeded.
|
||||
* @retval CH_FAILED operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkRead(ip, startblk, buf, n) \
|
||||
((ip)->vmt->read(ip, startblk, buf, n))
|
||||
|
||||
/**
|
||||
* @brief Writes one or more blocks.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
* @param[in] startblk first block to write
|
||||
* @param[out] buf pointer to the write buffer
|
||||
* @param[in] n number of blocks to write
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval CH_SUCCESS operation succeeded.
|
||||
* @retval CH_FAILED operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkWrite(ip, startblk, buf, n) \
|
||||
((ip)->vmt->write(ip, startblk, buf, n))
|
||||
|
||||
/**
|
||||
* @brief Ensures write synchronization.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval CH_SUCCESS operation succeeded.
|
||||
* @retval CH_FAILED operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkSync(ip) ((ip)->vmt->sync(ip))
|
||||
|
||||
/**
|
||||
* @brief Returns a media information structure.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseBlockDevice or derived class
|
||||
* @param[out] bdip pointer to a @p BlockDeviceInfo structure
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval CH_SUCCESS operation succeeded.
|
||||
* @retval CH_FAILED operation failed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define blkGetInfo(ip, bdip) ((ip)->vmt->get_info(ip, bdip))
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _IO_BLOCK_H_ */
|
||||
|
||||
/** @} */
|
||||
301
firmware/chibios/os/hal/include/io_channel.h
Executable file
301
firmware/chibios/os/hal/include/io_channel.h
Executable file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 io_channel.h
|
||||
* @brief I/O channels access.
|
||||
* @details This header defines an abstract interface useful to access generic
|
||||
* I/O serial devices in a standardized way.
|
||||
*
|
||||
* @addtogroup IO_CHANNEL
|
||||
* @details This module defines an abstract interface for I/O channels by
|
||||
* extending the @p BaseSequentialStream interface.<br>
|
||||
* Note that no code is present, I/O channels are just abstract
|
||||
* interface like structures, you should look at the systems as
|
||||
* to a set of abstract C++ classes (even if written in C).
|
||||
* Specific device drivers can use/extend the interface and
|
||||
* implement them.<br>
|
||||
* This system has the advantage to make the access to channels
|
||||
* independent from the implementation logic.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _IO_CHANNEL_H_
|
||||
#define _IO_CHANNEL_H_
|
||||
|
||||
/**
|
||||
* @brief @p BaseChannel specific methods.
|
||||
*/
|
||||
#define _base_channel_methods \
|
||||
_base_sequential_stream_methods \
|
||||
/* Channel put method with timeout specification.*/ \
|
||||
msg_t (*putt)(void *instance, uint8_t b, systime_t time); \
|
||||
/* Channel get method with timeout specification.*/ \
|
||||
msg_t (*gett)(void *instance, systime_t time); \
|
||||
/* Channel write method with timeout specification.*/ \
|
||||
size_t (*writet)(void *instance, const uint8_t *bp, \
|
||||
size_t n, systime_t time); \
|
||||
/* Channel read method with timeout specification.*/ \
|
||||
size_t (*readt)(void *instance, uint8_t *bp, size_t n, systime_t time);
|
||||
|
||||
/**
|
||||
* @brief @p BaseChannel specific data.
|
||||
* @note It is empty because @p BaseChannel is only an interface without
|
||||
* implementation.
|
||||
*/
|
||||
#define _base_channel_data \
|
||||
_base_sequential_stream_data
|
||||
|
||||
/**
|
||||
* @extends BaseSequentialStreamVMT
|
||||
*
|
||||
* @brief @p BaseChannel virtual methods table.
|
||||
*/
|
||||
struct BaseChannelVMT {
|
||||
_base_channel_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends BaseSequentialStream
|
||||
*
|
||||
* @brief Base channel class.
|
||||
* @details This class represents a generic, byte-wide, I/O channel. This class
|
||||
* introduces generic I/O primitives with timeout specification.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief Virtual Methods Table.*/
|
||||
const struct BaseChannelVMT *vmt;
|
||||
_base_channel_data
|
||||
} BaseChannel;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseChannel)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Channel blocking byte write with timeout.
|
||||
* @details This function writes a byte value to a channel. If the channel
|
||||
* is not ready to accept data then the calling thread is suspended.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseChannel or derived class
|
||||
* @param[in] b the byte value to be written to the channel
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval Q_OK if the operation succeeded.
|
||||
* @retval Q_TIMEOUT if the specified time expired.
|
||||
* @retval Q_RESET if the channel associated queue (if any) was reset.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chnPutTimeout(ip, b, time) ((ip)->vmt->putt(ip, b, time))
|
||||
|
||||
/**
|
||||
* @brief Channel blocking byte read with timeout.
|
||||
* @details This function reads a byte value from a channel. If the data
|
||||
* is not available then the calling thread is suspended.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseChannel or derived class
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return A byte value from the queue.
|
||||
* @retval Q_TIMEOUT if the specified time expired.
|
||||
* @retval Q_RESET if the channel associated queue (if any) has been
|
||||
* reset.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chnGetTimeout(ip, time) ((ip)->vmt->gett(ip, time))
|
||||
|
||||
/**
|
||||
* @brief Channel blocking write.
|
||||
* @details The function writes data from a buffer to a channel. If the channel
|
||||
* is not ready to accept data then the calling thread is suspended.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseChannel or derived class
|
||||
* @param[out] bp pointer to the data buffer
|
||||
* @param[in] n the maximum amount of data to be transferred
|
||||
*
|
||||
* @return The number of bytes transferred.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chnWrite(ip, bp, n) chSequentialStreamWrite(ip, bp, n)
|
||||
|
||||
/**
|
||||
* @brief Channel blocking write with timeout.
|
||||
* @details The function writes data from a buffer to a channel. If the channel
|
||||
* is not ready to accept data then the calling thread is suspended.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseChannel or derived class
|
||||
* @param[out] bp pointer to the data buffer
|
||||
* @param[in] n the maximum amount of data to be transferred
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The number of bytes transferred.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chnWriteTimeout(ip, bp, n, time) ((ip)->vmt->writet(ip, bp, n, time))
|
||||
|
||||
/**
|
||||
* @brief Channel blocking read.
|
||||
* @details The function reads data from a channel into a buffer. If the data
|
||||
* is not available then the calling thread is suspended.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseChannel or derived class
|
||||
* @param[in] bp pointer to the data buffer
|
||||
* @param[in] n the maximum amount of data to be transferred
|
||||
*
|
||||
* @return The number of bytes transferred.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chnRead(ip, bp, n) chSequentialStreamRead(ip, bp, n)
|
||||
|
||||
/**
|
||||
* @brief Channel blocking read with timeout.
|
||||
* @details The function reads data from a channel into a buffer. If the data
|
||||
* is not available then the calling thread is suspended.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseChannel or derived class
|
||||
* @param[in] bp pointer to the data buffer
|
||||
* @param[in] n the maximum amount of data to be transferred
|
||||
* @param[in] time the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_IMMEDIATE immediate timeout.
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The number of bytes transferred.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chnReadTimeout(ip, bp, n, time) ((ip)->vmt->readt(ip, bp, n, time))
|
||||
/** @} */
|
||||
|
||||
#if CH_USE_EVENTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @name I/O status flags added to the event listener
|
||||
* @{
|
||||
*/
|
||||
/** @brief No pending conditions.*/
|
||||
#define CHN_NO_ERROR 0
|
||||
/** @brief Connection happened.*/
|
||||
#define CHN_CONNECTED 1
|
||||
/** @brief Disconnection happened.*/
|
||||
#define CHN_DISCONNECTED 2
|
||||
/** @brief Data available in the input queue.*/
|
||||
#define CHN_INPUT_AVAILABLE 4
|
||||
/** @brief Output queue empty.*/
|
||||
#define CHN_OUTPUT_EMPTY 8
|
||||
/** @brief Transmission end.*/
|
||||
#define CHN_TRANSMISSION_END 16
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief @p BaseAsynchronousChannel specific methods.
|
||||
*/
|
||||
#define _base_asynchronous_channel_methods \
|
||||
_base_channel_methods \
|
||||
|
||||
/**
|
||||
* @brief @p BaseAsynchronousChannel specific data.
|
||||
*/
|
||||
#define _base_asynchronous_channel_data \
|
||||
_base_channel_data \
|
||||
/* I/O condition event source.*/ \
|
||||
EventSource event;
|
||||
|
||||
/**
|
||||
* @extends BaseChannelVMT
|
||||
*
|
||||
* @brief @p BaseAsynchronousChannel virtual methods table.
|
||||
*/
|
||||
struct BaseAsynchronousChannelVMT {
|
||||
_base_asynchronous_channel_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends BaseChannel
|
||||
*
|
||||
* @brief Base asynchronous channel class.
|
||||
* @details This class extends @p BaseChannel by adding event sources fields
|
||||
* for asynchronous I/O for use in an event-driven environment.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief Virtual Methods Table.*/
|
||||
const struct BaseAsynchronousChannelVMT *vmt;
|
||||
_base_asynchronous_channel_data
|
||||
} BaseAsynchronousChannel;
|
||||
|
||||
/**
|
||||
* @name Macro Functions (BaseAsynchronousChannel)
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the I/O condition event source.
|
||||
* @details The event source is broadcasted when an I/O condition happens.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
|
||||
* class
|
||||
* @return A pointer to an @p EventSource object.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define chnGetEventSource(ip) (&((ip)->event))
|
||||
|
||||
/**
|
||||
* @brief Adds status flags to the listeners's flags mask.
|
||||
* @details This function is usually called from the I/O ISRs in order to
|
||||
* notify I/O conditions such as data events, errors, signal
|
||||
* changes etc.
|
||||
*
|
||||
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived
|
||||
* class
|
||||
* @param[in] flags condition flags to be added to the listener flags mask
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define chnAddFlagsI(ip, flags) { \
|
||||
chEvtBroadcastFlagsI(&(ip)->event, flags); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
#endif /* CH_USE_EVENTS */
|
||||
|
||||
#endif /* _IO_CHANNEL_H_ */
|
||||
|
||||
/** @} */
|
||||
221
firmware/chibios/os/hal/include/mac.h
Executable file
221
firmware/chibios/os/hal/include/mac.h
Executable file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_MAC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name MAC configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables an event sources for incoming packets.
|
||||
*/
|
||||
#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_ZERO_COPY FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables an event sources for incoming packets.
|
||||
*/
|
||||
#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__)
|
||||
#define MAC_USE_EVENTS TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !CH_USE_SEMAPHORES || !CH_USE_EVENTS
|
||||
#error "the MAC driver requires CH_USE_SEMAPHORES"
|
||||
#endif
|
||||
|
||||
#if MAC_USE_EVENTS && !CH_USE_EVENTS
|
||||
#error "the MAC driver requires CH_USE_EVENTS"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
MAC_UNINIT = 0, /**< Not initialized. */
|
||||
MAC_STOP = 1, /**< Stopped. */
|
||||
MAC_ACTIVE = 2 /**< Active. */
|
||||
} macstate_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing a MAC driver.
|
||||
*/
|
||||
typedef struct MACDriver MACDriver;
|
||||
|
||||
#include "mac_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the received frames event source.
|
||||
*
|
||||
* @param[in] macp pointer to the @p MACDriver object
|
||||
* @return The pointer to the @p EventSource structure.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#if MAC_USE_EVENTS || defined(__DOXYGEN__)
|
||||
#define macGetReceiveEventSource(macp) (&(macp)->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.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#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.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define macReadReceiveDescriptor(rdp, buf, size) \
|
||||
mac_lld_read_receive_descriptor(rdp, buf, size)
|
||||
|
||||
#if MAC_USE_ZERO_COPY || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Returns a pointer to the next transmit buffer in the descriptor
|
||||
* chain.
|
||||
* @note The API guarantees that enough buffers can be requested to fill
|
||||
* a whole frame.
|
||||
*
|
||||
* @param[in] tdp pointer to a @p MACTransmitDescriptor structure
|
||||
* @param[in] size size of the requested buffer. Specify the frame size
|
||||
* on the first call then scale the value down subtracting
|
||||
* the amount of data already copied into the previous
|
||||
* buffers.
|
||||
* @param[out] sizep pointer to variable receiving the real buffer size.
|
||||
* The returned value can be less than the amount
|
||||
* requested, this means that more buffers must be
|
||||
* requested in order to fill the frame data entirely.
|
||||
* @return Pointer to the returned buffer.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define macGetNextTransmitBuffer(tdp, size, sizep) \
|
||||
mac_lld_get_next_transmit_buffer(tdp, size, sizep)
|
||||
|
||||
/**
|
||||
* @brief Returns a pointer to the next receive buffer in the descriptor
|
||||
* chain.
|
||||
* @note The API guarantees that the descriptor chain contains a whole
|
||||
* frame.
|
||||
*
|
||||
* @param[in] rdp pointer to a @p MACReceiveDescriptor structure
|
||||
* @param[out] sizep pointer to variable receiving the buffer size, it is
|
||||
* zero when the last buffer has already been returned.
|
||||
* @return Pointer to the returned buffer.
|
||||
* @retval NULL if the buffer chain has been entirely scanned.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define macGetNextReceiveBuffer(rdp, sizep) \
|
||||
mac_lld_get_next_receive_buffer(rdp, sizep)
|
||||
#endif /* MAC_USE_ZERO_COPY */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void macInit(void);
|
||||
void macObjectInit(MACDriver *macp);
|
||||
void macStart(MACDriver *macp, const MACConfig *config);
|
||||
void macStop(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 /* HAL_USE_MAC */
|
||||
|
||||
#endif /* _MAC_H_ */
|
||||
|
||||
/** @} */
|
||||
169
firmware/chibios/os/hal/include/mii.h
Executable file
169
firmware/chibios/os/hal/include/mii.h
Executable file
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 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_ANNPTR 0x07 /**< 1000BASE-T control. */
|
||||
#define MII_CTRL1000 0x09 /**< 1000BASE-T control. */
|
||||
#define MII_STAT1000 0x0a /**< 1000BASE-T status. */
|
||||
#define MII_ESTATUS 0x0f /**< Extended Status. */
|
||||
#define MII_PHYSTS 0x10 /**< PHY Status register. */
|
||||
#define MII_MICR 0x11 /**< MII Interrupt ctrl register. */
|
||||
#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 0x007f /**< Unused. */
|
||||
#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 bit. */
|
||||
#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_MFPRESUPPCAP 0x0040 /**< Able to suppress preamble. */
|
||||
#define BMSR_RESV 0x0780 /**< Unused. */
|
||||
#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_10FULL 0x0040 /**< Try for 10mbps full-duplex. */
|
||||
#define ADVERTISE_100HALF 0x0080 /**< Try for 100mbps half-duplex. */
|
||||
#define ADVERTISE_100FULL 0x0100 /**< Try for 100mbps full-duplex. */
|
||||
#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_10FULL 0x0040 /**< Can do 10mbps full-duplex. */
|
||||
#define LPA_100HALF 0x0080 /**< Can do 100mbps half-duplex. */
|
||||
#define LPA_100FULL 0x0100 /**< Can do 100mbps full-duplex. */
|
||||
#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. */
|
||||
|
||||
/*
|
||||
* N-way test register.
|
||||
*/
|
||||
#define NWAYTEST_RESV1 0x00ff /**< Unused. */
|
||||
#define NWAYTEST_LOOPBACK 0x0100 /**< Enable loopback for N-way. */
|
||||
#define NWAYTEST_RESV2 0xfe00 /**< Unused. */
|
||||
|
||||
/*
|
||||
* PHY identifiers.
|
||||
*/
|
||||
#define MII_DM9161_ID 0x0181b8a0
|
||||
#define MII_AM79C875_ID 0x00225540
|
||||
#define MII_KS8721_ID 0x00221610
|
||||
#define MII_STE101P_ID 0x00061C50
|
||||
#define MII_DP83848I_ID 0x20005C90
|
||||
#define MII_LAN8710A_ID 0x0007C0F1
|
||||
|
||||
#endif /* _MII_H_ */
|
||||
|
||||
/** @} */
|
||||
206
firmware/chibios/os/hal/include/mmc_spi.h
Executable file
206
firmware/chibios/os/hal/include/mmc_spi.h
Executable file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_MMC_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define MMC_CMD0_RETRY 10
|
||||
#define MMC_CMD1_RETRY 100
|
||||
#define MMC_ACMD41_RETRY 100
|
||||
#define MMC_WAIT_DATA 10000
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name MMC_SPI configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !HAL_USE_SPI || !SPI_USE_WAIT
|
||||
#error "MMC_SPI driver requires HAL_USE_SPI and SPI_USE_WAIT"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief MMC/SD over SPI driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief SPI driver associated to this MMC driver.
|
||||
*/
|
||||
SPIDriver *spip;
|
||||
/**
|
||||
* @brief SPI low speed configuration used during initialization.
|
||||
*/
|
||||
const SPIConfig *lscfg;
|
||||
/**
|
||||
* @brief SPI high speed configuration used during transfers.
|
||||
*/
|
||||
const SPIConfig *hscfg;
|
||||
} MMCConfig;
|
||||
|
||||
/**
|
||||
* @brief @p MMCDriver specific methods.
|
||||
*/
|
||||
#define _mmc_driver_methods \
|
||||
_mmcsd_block_device_methods
|
||||
|
||||
/**
|
||||
* @extends MMCSDBlockDeviceVMT
|
||||
*
|
||||
* @brief @p MMCDriver virtual methods table.
|
||||
*/
|
||||
struct MMCDriverVMT {
|
||||
_mmc_driver_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends MMCSDBlockDevice
|
||||
*
|
||||
* @brief Structure representing a MMC/SD over SPI driver.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Virtual Methods Table.
|
||||
*/
|
||||
const struct MMCDriverVMT *vmt;
|
||||
_mmcsd_block_device_data
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const MMCConfig *config;
|
||||
/***
|
||||
* @brief Addresses use blocks instead of bytes.
|
||||
*/
|
||||
bool_t block_addresses;
|
||||
} MMCDriver;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the card insertion status.
|
||||
* @note This macro wraps a low level function named
|
||||
* @p sdc_lld_is_card_inserted(), this function must be
|
||||
* provided by the application because it is not part of the
|
||||
* SDC driver.
|
||||
*
|
||||
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||
* @return The card state.
|
||||
* @retval FALSE card not inserted.
|
||||
* @retval TRUE card inserted.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define mmcIsCardInserted(mmcp) mmc_lld_is_card_inserted(mmcp)
|
||||
|
||||
/**
|
||||
* @brief Returns the write protect status.
|
||||
*
|
||||
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||
* @return The card state.
|
||||
* @retval FALSE card not inserted.
|
||||
* @retval TRUE card inserted.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define mmcIsWriteProtected(mmcp) mmc_lld_is_write_protected(mmcp)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void mmcInit(void);
|
||||
void mmcObjectInit(MMCDriver *mmcp);
|
||||
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);
|
||||
bool_t mmcSync(MMCDriver *mmcp);
|
||||
bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip);
|
||||
bool_t mmcErase(MMCDriver *mmcp, uint32_t startblk, uint32_t endblk);
|
||||
bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp);
|
||||
bool_t mmc_lld_is_write_protected(MMCDriver *mmcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_MMC_SPI */
|
||||
|
||||
#endif /* _MMC_SPI_H_ */
|
||||
|
||||
/** @} */
|
||||
286
firmware/chibios/os/hal/include/mmcsd.h
Executable file
286
firmware/chibios/os/hal/include/mmcsd.h
Executable file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 mmcsd.h
|
||||
* @brief MMC/SD cards common header.
|
||||
* @details This header defines an abstract interface useful to access MMC/SD
|
||||
* I/O block devices in a standardized way.
|
||||
*
|
||||
* @addtogroup MMCSD
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MMCSD_H_
|
||||
#define _MMCSD_H_
|
||||
|
||||
#if HAL_USE_MMC_SPI || HAL_USE_SDC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Fixed block size for MMC/SD block devices.
|
||||
*/
|
||||
#define MMCSD_BLOCK_SIZE 512
|
||||
|
||||
/**
|
||||
* @brief Mask of error bits in R1 responses.
|
||||
*/
|
||||
#define MMCSD_R1_ERROR_MASK 0xFDFFE008
|
||||
|
||||
/**
|
||||
* @brief Fixed pattern for CMD8.
|
||||
*/
|
||||
#define MMCSD_CMD8_PATTERN 0x000001AA
|
||||
|
||||
/**
|
||||
* @name SD/MMC status conditions
|
||||
* @{
|
||||
*/
|
||||
#define MMCSD_STS_IDLE 0
|
||||
#define MMCSD_STS_READY 1
|
||||
#define MMCSD_STS_IDENT 2
|
||||
#define MMCSD_STS_STBY 3
|
||||
#define MMCSD_STS_TRAN 4
|
||||
#define MMCSD_STS_DATA 5
|
||||
#define MMCSD_STS_RCV 6
|
||||
#define MMCSD_STS_PRG 7
|
||||
#define MMCSD_STS_DIS 8
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name SD/MMC commands
|
||||
* @{
|
||||
*/
|
||||
#define MMCSD_CMD_GO_IDLE_STATE 0
|
||||
#define MMCSD_CMD_INIT 1
|
||||
#define MMCSD_CMD_ALL_SEND_CID 2
|
||||
#define MMCSD_CMD_SEND_RELATIVE_ADDR 3
|
||||
#define MMCSD_CMD_SET_BUS_WIDTH 6
|
||||
#define MMCSD_CMD_SEL_DESEL_CARD 7
|
||||
#define MMCSD_CMD_SEND_IF_COND 8
|
||||
#define MMCSD_CMD_SEND_CSD 9
|
||||
#define MMCSD_CMD_SEND_CID 10
|
||||
#define MMCSD_CMD_STOP_TRANSMISSION 12
|
||||
#define MMCSD_CMD_SEND_STATUS 13
|
||||
#define MMCSD_CMD_SET_BLOCKLEN 16
|
||||
#define MMCSD_CMD_READ_SINGLE_BLOCK 17
|
||||
#define MMCSD_CMD_READ_MULTIPLE_BLOCK 18
|
||||
#define MMCSD_CMD_SET_BLOCK_COUNT 23
|
||||
#define MMCSD_CMD_WRITE_BLOCK 24
|
||||
#define MMCSD_CMD_WRITE_MULTIPLE_BLOCK 25
|
||||
#define MMCSD_CMD_ERASE_RW_BLK_START 32
|
||||
#define MMCSD_CMD_ERASE_RW_BLK_END 33
|
||||
#define MMCSD_CMD_ERASE 38
|
||||
#define MMCSD_CMD_APP_OP_COND 41
|
||||
#define MMCSD_CMD_LOCK_UNLOCK 42
|
||||
#define MMCSD_CMD_APP_CMD 55
|
||||
#define MMCSD_CMD_READ_OCR 58
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name CSD record offsets
|
||||
*/
|
||||
/**
|
||||
* @brief Slice position of values in CSD register.
|
||||
*/
|
||||
/* CSD version 2.0 */
|
||||
#define MMCSD_CSD_20_CRC_SLICE 7,1
|
||||
#define MMCSD_CSD_20_FILE_FORMAT_SLICE 11,10
|
||||
#define MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE 12,12
|
||||
#define MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE 13,13
|
||||
#define MMCSD_CSD_20_COPY_SLICE 14,14
|
||||
#define MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE 15,15
|
||||
#define MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE 21,21
|
||||
#define MMCSD_CSD_20_WRITE_BL_LEN_SLICE 25,12
|
||||
#define MMCSD_CSD_20_R2W_FACTOR_SLICE 28,26
|
||||
#define MMCSD_CSD_20_WP_GRP_ENABLE_SLICE 31,31
|
||||
#define MMCSD_CSD_20_WP_GRP_SIZE_SLICE 38,32
|
||||
#define MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE 45,39
|
||||
#define MMCSD_CSD_20_ERASE_BLK_EN_SLICE 46,46
|
||||
#define MMCSD_CSD_20_C_SIZE_SLICE 69,48
|
||||
#define MMCSD_CSD_20_DSR_IMP_SLICE 76,76
|
||||
#define MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE 77,77
|
||||
#define MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE 78,78
|
||||
#define MMCSD_CSD_20_READ_BL_PARTIAL_SLICE 79,79
|
||||
#define MMCSD_CSD_20_READ_BL_LEN_SLICE 83,80
|
||||
#define MMCSD_CSD_20_CCC_SLICE 95,84
|
||||
#define MMCSD_CSD_20_TRANS_SPEED_SLICE 103,96
|
||||
#define MMCSD_CSD_20_NSAC_SLICE 111,104
|
||||
#define MMCSD_CSD_20_TAAC_SLICE 119,112
|
||||
#define MMCSD_CSD_20_STRUCTURE_SLICE 127,126
|
||||
|
||||
/* CSD version 1.0 */
|
||||
#define MMCSD_CSD_10_CRC_SLICE MMCSD_CSD_20_CRC_SLICE
|
||||
#define MMCSD_CSD_10_FILE_FORMAT_SLICE MMCSD_CSD_20_FILE_FORMAT_SLICE
|
||||
#define MMCSD_CSD_10_TMP_WRITE_PROTECT_SLICE MMCSD_CSD_20_TMP_WRITE_PROTECT_SLICE
|
||||
#define MMCSD_CSD_10_PERM_WRITE_PROTECT_SLICE MMCSD_CSD_20_PERM_WRITE_PROTECT_SLICE
|
||||
#define MMCSD_CSD_10_COPY_SLICE MMCSD_CSD_20_COPY_SLICE
|
||||
#define MMCSD_CSD_10_FILE_FORMAT_GRP_SLICE MMCSD_CSD_20_FILE_FORMAT_GRP_SLICE
|
||||
#define MMCSD_CSD_10_WRITE_BL_PARTIAL_SLICE MMCSD_CSD_20_WRITE_BL_PARTIAL_SLICE
|
||||
#define MMCSD_CSD_10_WRITE_BL_LEN_SLICE MMCSD_CSD_20_WRITE_BL_LEN_SLICE
|
||||
#define MMCSD_CSD_10_R2W_FACTOR_SLICE MMCSD_CSD_20_R2W_FACTOR_SLICE
|
||||
#define MMCSD_CSD_10_WP_GRP_ENABLE_SLICE MMCSD_CSD_20_WP_GRP_ENABLE_SLICE
|
||||
#define MMCSD_CSD_10_WP_GRP_SIZE_SLICE MMCSD_CSD_20_WP_GRP_SIZE_SLICE
|
||||
#define MMCSD_CSD_10_ERASE_SECTOR_SIZE_SLICE MMCSD_CSD_20_ERASE_SECTOR_SIZE_SLICE
|
||||
#define MMCSD_CSD_10_ERASE_BLK_EN_SLICE MMCSD_CSD_20_ERASE_BLK_EN_SLICE
|
||||
#define MMCSD_CSD_10_C_SIZE_MULT_SLICE 49,47
|
||||
#define MMCSD_CSD_10_VDD_W_CURR_MAX_SLICE 52,50
|
||||
#define MMCSD_CSD_10_VDD_W_CURR_MIN_SLICE 55,53
|
||||
#define MMCSD_CSD_10_VDD_R_CURR_MAX_SLICE 58,56
|
||||
#define MMCSD_CSD_10_VDD_R_CURR_MIX_SLICE 61,59
|
||||
#define MMCSD_CSD_10_C_SIZE_SLICE 73,62
|
||||
#define MMCSD_CSD_10_DSR_IMP_SLICE MMCSD_CSD_20_DSR_IMP_SLICE
|
||||
#define MMCSD_CSD_10_READ_BLK_MISALIGN_SLICE MMCSD_CSD_20_READ_BLK_MISALIGN_SLICE
|
||||
#define MMCSD_CSD_10_WRITE_BLK_MISALIGN_SLICE MMCSD_CSD_20_WRITE_BLK_MISALIGN_SLICE
|
||||
#define MMCSD_CSD_10_READ_BL_PARTIAL_SLICE MMCSD_CSD_20_READ_BL_PARTIAL_SLICE
|
||||
#define MMCSD_CSD_10_READ_BL_LEN_SLICE 83, 80
|
||||
#define MMCSD_CSD_10_CCC_SLICE MMCSD_CSD_20_CCC_SLICE
|
||||
#define MMCSD_CSD_10_TRANS_SPEED_SLICE MMCSD_CSD_20_TRANS_SPEED_SLICE
|
||||
#define MMCSD_CSD_10_NSAC_SLICE MMCSD_CSD_20_NSAC_SLICE
|
||||
#define MMCSD_CSD_10_TAAC_SLICE MMCSD_CSD_20_TAAC_SLICE
|
||||
#define MMCSD_CSD_10_STRUCTURE_SLICE MMCSD_CSD_20_STRUCTURE_SLICE
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief @p MMCSDBlockDevice specific methods.
|
||||
*/
|
||||
#define _mmcsd_block_device_methods \
|
||||
_base_block_device_methods
|
||||
|
||||
/**
|
||||
* @brief @p MMCSDBlockDevice specific data.
|
||||
* @note It is empty because @p MMCSDBlockDevice is only an interface
|
||||
* without implementation.
|
||||
*/
|
||||
#define _mmcsd_block_device_data \
|
||||
_base_block_device_data \
|
||||
/* Card CID.*/ \
|
||||
uint32_t cid[4]; \
|
||||
/* Card CSD.*/ \
|
||||
uint32_t csd[4]; \
|
||||
/* Total number of blocks in card.*/ \
|
||||
uint32_t capacity;
|
||||
|
||||
/**
|
||||
* @extends BaseBlockDeviceVMT
|
||||
*
|
||||
* @brief @p MMCSDBlockDevice virtual methods table.
|
||||
*/
|
||||
struct MMCSDBlockDeviceVMT {
|
||||
_base_block_device_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends BaseBlockDevice
|
||||
*
|
||||
* @brief MCC/SD block device class.
|
||||
* @details This class represents a, block-accessible, MMC/SD device.
|
||||
*/
|
||||
typedef struct {
|
||||
/** @brief Virtual Methods Table.*/
|
||||
const struct MMCSDBlockDeviceVMT *vmt;
|
||||
_mmcsd_block_device_data
|
||||
} MMCSDBlockDevice;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name R1 response utilities
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the R1 response contains error flags.
|
||||
*
|
||||
* @param[in] r1 the r1 response
|
||||
*/
|
||||
#define MMCSD_R1_ERROR(r1) (((r1) & MMCSD_R1_ERROR_MASK) != 0)
|
||||
|
||||
/**
|
||||
* @brief Returns the status field of an R1 response.
|
||||
*
|
||||
* @param[in] r1 the r1 response
|
||||
*/
|
||||
#define MMCSD_R1_STS(r1) (((r1) >> 9) & 15)
|
||||
|
||||
/**
|
||||
* @brief Evaluates to @p TRUE if the R1 response indicates a locked card.
|
||||
*
|
||||
* @param[in] r1 the r1 response
|
||||
*/
|
||||
#define MMCSD_R1_IS_CARD_LOCKED(r1) (((r1) >> 21) & 1)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the card capacity in blocks.
|
||||
*
|
||||
* @param[in] ip pointer to a @p MMCSDBlockDevice or derived class
|
||||
*
|
||||
* @return The card capacity.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define mmcsdGetCardCapacity(ip) ((ip)->capacity)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
uint32_t mmcsdGetCapacity(uint32_t csd[4]);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_MMC_SPI || HAL_USE_MMC_SDC*/
|
||||
|
||||
#endif /* _MMCSD_H_ */
|
||||
|
||||
/** @} */
|
||||
562
firmware/chibios/os/hal/include/pal.h
Executable file
562
firmware/chibios/os/hal/include/pal.h
Executable file
@@ -0,0 +1,562 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Pads mode constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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 for
|
||||
* 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
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Logic level constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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 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 mask;
|
||||
/**
|
||||
* @brief Offset, within the port, of the least significant bit of the bus.
|
||||
*/
|
||||
uint_fast8_t 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.
|
||||
*/
|
||||
#if !defined(PAL_PORT_BIT) || defined(__DOXYGEN__)
|
||||
#define PAL_PORT_BIT(n) ((ioportmask_t)(1 << (n)))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Bits group mask helper.
|
||||
* @details This macro calculates the mask of a bits group.
|
||||
*
|
||||
* @param[in] width group width
|
||||
* @return The group mask.
|
||||
*/
|
||||
#if !defined(PAL_GROUP_MASK) || defined(__DOXYGEN__)
|
||||
#define PAL_GROUP_MASK(width) ((ioportmask_t)(1 << (width)) - 1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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)
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief PAL subsystem initialization.
|
||||
* @note This function is implicitly invoked by @p halInit(), there is
|
||||
* no need to explicitly initialize the driver.
|
||||
*
|
||||
* @param[in] config pointer to an architecture specific configuration
|
||||
* structure. This structure is defined in the low level driver
|
||||
* header.
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The port logical states.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be written on the specified port
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be ORed on the specified port
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be cleared on the specified port
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be XORed on the specified port
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] mode group mode
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#if !defined(pal_lld_setgroupmode) || defined(__DOXYGEN__)
|
||||
#define palSetGroupMode(port, mask, offset, mode)
|
||||
#else
|
||||
#define palSetGroupMode(port, mask, offset, mode) \
|
||||
pal_lld_setgroupmode(port, mask, offset, 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().
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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().
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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().
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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().
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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().
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#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.
|
||||
* @note The function can be called from any context.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] mode pad mode
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#if !defined(pal_lld_setpadmode) || defined(__DOXYGEN__)
|
||||
#define palSetPadMode(port, pad, mode) \
|
||||
palSetGroupMode(port, PAL_PORT_BIT(pad), 0, 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, iomode_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _PAL_H_ */
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
/** @} */
|
||||
259
firmware/chibios/os/hal/include/pwm.h
Executable file
259
firmware/chibios/os/hal/include/pwm.h
Executable file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_PWM || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PWM output mode macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Standard output modes mask.
|
||||
*/
|
||||
#define PWM_OUTPUT_MASK 0x0F
|
||||
|
||||
/**
|
||||
* @brief Output not driven, callback only.
|
||||
*/
|
||||
#define PWM_OUTPUT_DISABLED 0x00
|
||||
|
||||
/**
|
||||
* @brief Positive PWM logic, active is logic level one.
|
||||
*/
|
||||
#define PWM_OUTPUT_ACTIVE_HIGH 0x01
|
||||
|
||||
/**
|
||||
* @brief Inverse PWM logic, active is logic level zero.
|
||||
*/
|
||||
#define PWM_OUTPUT_ACTIVE_LOW 0x02
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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 Type of a structure representing a PWM driver.
|
||||
*/
|
||||
typedef struct PWMDriver PWMDriver;
|
||||
|
||||
/**
|
||||
* @brief PWM notification callback type.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
*/
|
||||
typedef void (*pwmcallback_t)(PWMDriver *pwmp);
|
||||
|
||||
#include "pwm_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name PWM duty cycle conversion
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Converts from fraction to pulse width.
|
||||
* @note Be careful with rounding errors, this is integer math not magic.
|
||||
* You can specify tenths of thousandth but make sure you have the
|
||||
* proper hardware resolution by carefully choosing the clock source
|
||||
* and prescaler settings, see @p PWM_COMPUTE_PSC.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] denominator denominator of the fraction
|
||||
* @param[in] numerator numerator of the fraction
|
||||
* @return The pulse width to be passed to @p pwmEnableChannel().
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define PWM_FRACTION_TO_WIDTH(pwmp, denominator, numerator) \
|
||||
((pwmcnt_t)((((pwmcnt_t)(pwmp)->period) * \
|
||||
(pwmcnt_t)(numerator)) / (pwmcnt_t)(denominator)))
|
||||
|
||||
/**
|
||||
* @brief Converts from degrees to pulse width.
|
||||
* @note Be careful with rounding errors, this is integer math not magic.
|
||||
* You can specify hundredths of degrees but make sure you have the
|
||||
* proper hardware resolution by carefully choosing the clock source
|
||||
* and prescaler settings, see @p PWM_COMPUTE_PSC.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] degrees degrees as an integer between 0 and 36000
|
||||
* @return The pulse width to be passed to @p pwmEnableChannel().
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define PWM_DEGREES_TO_WIDTH(pwmp, degrees) \
|
||||
PWM_FRACTION_TO_WIDTH(pwmp, 36000, degrees)
|
||||
|
||||
/**
|
||||
* @brief Converts from percentage to pulse width.
|
||||
* @note Be careful with rounding errors, this is integer math not magic.
|
||||
* You can specify tenths of thousandth but make sure you have the
|
||||
* proper hardware resolution by carefully choosing the clock source
|
||||
* and prescaler settings, see @p PWM_COMPUTE_PSC.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] percentage percentage as an integer between 0 and 10000
|
||||
* @return The pulse width to be passed to @p pwmEnableChannel().
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define PWM_PERCENTAGE_TO_WIDTH(pwmp, percentage) \
|
||||
PWM_FRACTION_TO_WIDTH(pwmp, 10000, percentage)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Changes the period the PWM peripheral.
|
||||
* @details This function changes the period of a PWM unit that has already
|
||||
* been activated using @p pwmStart().
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The PWM unit period is changed to the new value.
|
||||
* @note If a period is specified that is shorter than the pulse width
|
||||
* programmed in one of the channels then the behavior is not
|
||||
* guaranteed.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] value new cycle time in ticks
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define pwmChangePeriodI(pwmp, value) { \
|
||||
(pwmp)->period = (value); \
|
||||
pwm_lld_change_period(pwmp, value); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a PWM channel.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is active using the specified configuration.
|
||||
* @note Depending on the hardware implementation this function has
|
||||
* effect starting on the next cycle (recommended implementation)
|
||||
* or immediately (fallback implementation).
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
|
||||
* @param[in] width PWM pulse width as clock pulses number
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define pwmEnableChannelI(pwmp, channel, width) \
|
||||
pwm_lld_enable_channel(pwmp, channel, width)
|
||||
|
||||
/**
|
||||
* @brief Disables a PWM channel.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is disabled and its output line returned to the
|
||||
* idle state.
|
||||
* @note Depending on the hardware implementation this function has
|
||||
* effect starting on the next cycle (recommended implementation)
|
||||
* or immediately (fallback implementation).
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define pwmDisableChannelI(pwmp, channel) \
|
||||
pwm_lld_disable_channel(pwmp, channel)
|
||||
|
||||
/**
|
||||
* @brief Returns a PWM channel status.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define pwmIsChannelEnabledI(pwmp, channel) \
|
||||
pwm_lld_is_channel_enabled(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 pwmChangePeriod(PWMDriver *pwmp, pwmcnt_t period);
|
||||
void pwmEnableChannel(PWMDriver *pwmp,
|
||||
pwmchannel_t channel,
|
||||
pwmcnt_t width);
|
||||
void pwmDisableChannel(PWMDriver *pwmp, pwmchannel_t channel);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PWM */
|
||||
|
||||
#endif /* _PWM_H_ */
|
||||
|
||||
/** @} */
|
||||
178
firmware/chibios/os/hal/include/rtc.h
Executable file
178
firmware/chibios/os/hal/include/rtc.h
Executable file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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.
|
||||
*/
|
||||
/*
|
||||
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
|
||||
aka barthess.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file rtc.h
|
||||
* @brief RTC Driver macros and structures.
|
||||
*
|
||||
* @addtogroup RTC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _RTC_H_
|
||||
#define _RTC_H_
|
||||
|
||||
#if HAL_USE_RTC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Date/Time bit masks
|
||||
* @{
|
||||
*/
|
||||
#define RTC_TIME_SECONDS_MASK 0x0000001F /* @brief Seconds mask. */
|
||||
#define RTC_TIME_MINUTES_MASK 0x000007E0 /* @brief Minutes mask. */
|
||||
#define RTC_TIME_HOURS_MASK 0x0000F800 /* @brief Hours mask. */
|
||||
#define RTC_DATE_DAYS_MASK 0x001F0000 /* @brief Days mask. */
|
||||
#define RTC_DATE_MONTHS_MASK 0x01E00000 /* @brief Months mask. */
|
||||
#define RTC_DATE_YEARS_MASK 0xFE000000 /* @brief Years mask. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an RTC driver.
|
||||
*/
|
||||
typedef struct RTCDriver RTCDriver;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an RTC time stamp.
|
||||
*/
|
||||
typedef struct RTCTime RTCTime;
|
||||
|
||||
#include "rtc_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Set current time.
|
||||
*
|
||||
* @param[in] rtcp pointer to RTC driver structure
|
||||
* @param[in] timespec pointer to a @p RTCTime structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define rtcSetTimeI(rtcp, timespec) rtc_lld_set_time(rtcp, timespec)
|
||||
|
||||
/**
|
||||
* @brief Get current time.
|
||||
*
|
||||
* @param[in] rtcp pointer to RTC driver structure
|
||||
* @param[out] timespec pointer to a @p RTCTime structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define rtcGetTimeI(rtcp, timespec) rtc_lld_get_time(rtcp, timespec)
|
||||
|
||||
#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Set alarm time.
|
||||
*
|
||||
* @param[in] rtcp pointer to RTC driver structure
|
||||
* @param[in] alarm alarm identifier
|
||||
* @param[in] alarmspec pointer to a @p RTCAlarm structure or @p NULL
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define rtcSetAlarmI(rtcp, alarm, alarmspec) \
|
||||
rtc_lld_set_alarm(rtcp, alarm, alarmspec)
|
||||
|
||||
/**
|
||||
* @brief Get current alarm.
|
||||
* @note If an alarm has not been set then the returned alarm specification
|
||||
* is not meaningful.
|
||||
*
|
||||
* @param[in] rtcp pointer to RTC driver structure
|
||||
* @param[in] alarm alarm identifier
|
||||
* @param[out] alarmspec pointer to a @p RTCAlarm structure
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define rtcGetAlarmI(rtcp, alarm, alarmspec) \
|
||||
rtc_lld_get_alarm(rtcp, alarm, alarmspec)
|
||||
#endif /* RTC_ALARMS > 0 */
|
||||
|
||||
#if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Enables or disables RTC callbacks.
|
||||
* @details This function enables or disables the callback, use a @p NULL
|
||||
* pointer in order to disable it.
|
||||
*
|
||||
* @param[in] rtcp pointer to RTC driver structure
|
||||
* @param[in] callback callback function pointer or @p NULL
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define rtcSetCallbackI(rtcp, callback) rtc_lld_set_callback(rtcp, callback)
|
||||
#endif /* RTC_SUPPORTS_CALLBACKS */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void rtcInit(void);
|
||||
void rtcSetTime(RTCDriver *rtcp, const RTCTime *timespec);
|
||||
void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec);
|
||||
#if RTC_ALARMS > 0
|
||||
void rtcSetAlarm(RTCDriver *rtcp,
|
||||
rtcalarm_t alarm,
|
||||
const RTCAlarm *alarmspec);
|
||||
void rtcGetAlarm(RTCDriver *rtcp, rtcalarm_t alarm, RTCAlarm *alarmspec);
|
||||
#endif
|
||||
uint32_t rtcGetTimeFat(RTCDriver *rtcp);
|
||||
#if RTC_SUPPORTS_CALLBACKS
|
||||
void rtcSetCallback(RTCDriver *rtcp, rtccb_t callback);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_RTC */
|
||||
#endif /* _RTC_H_ */
|
||||
|
||||
/** @} */
|
||||
189
firmware/chibios/os/hal/include/sdc.h
Executable file
189
firmware/chibios/os/hal/include/sdc.h
Executable file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 sdc.h
|
||||
* @brief SDC Driver macros and structures.
|
||||
*
|
||||
* @addtogroup SDC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SDC_H_
|
||||
#define _SDC_H_
|
||||
|
||||
#if HAL_USE_SDC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name SD cart types
|
||||
* @{
|
||||
*/
|
||||
#define SDC_MODE_CARDTYPE_MASK 0xF /**< @brief Card type mask. */
|
||||
#define SDC_MODE_CARDTYPE_SDV11 0 /**< @brief Card is SD V1.1.*/
|
||||
#define SDC_MODE_CARDTYPE_SDV20 1 /**< @brief Card is SD V2.0.*/
|
||||
#define SDC_MODE_CARDTYPE_MMC 2 /**< @brief Card is MMC. */
|
||||
#define SDC_MODE_HIGH_CAPACITY 0x10 /**< @brief High cap.card. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name SDC bus error conditions
|
||||
* @{
|
||||
*/
|
||||
#define SDC_NO_ERROR 0 /**< @brief No error. */
|
||||
#define SDC_CMD_CRC_ERROR 1 /**< @brief Command CRC error. */
|
||||
#define SDC_DATA_CRC_ERROR 2 /**< @brief Data CRC error. */
|
||||
#define SDC_DATA_TIMEOUT 4 /**< @brief HW write timeout. */
|
||||
#define SDC_COMMAND_TIMEOUT 8 /**< @brief HW read timeout. */
|
||||
#define SDC_TX_UNDERRUN 16 /**< @brief TX buffer underrun. */
|
||||
#define SDC_RX_OVERRUN 32 /**< @brief RX buffer overrun. */
|
||||
#define SDC_STARTBIT_ERROR 64 /**< @brief Start bit missing. */
|
||||
#define SDC_OVERFLOW_ERROR 128 /**< @brief Card overflow error. */
|
||||
#define SDC_UNHANDLED_ERROR 0xFFFFFFFF
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name SDC configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Number of initialization attempts before rejecting the card.
|
||||
* @note Attempts are performed at 10mS intervals.
|
||||
*/
|
||||
#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__)
|
||||
#define SDC_INIT_RETRY 100
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Include support for MMC cards.
|
||||
* @note MMC support is not yet implemented so this option must be kept
|
||||
* at @p FALSE.
|
||||
*/
|
||||
#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__)
|
||||
#define SDC_MMC_SUPPORT FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Delays insertions.
|
||||
* @details If enabled this options inserts delays into the MMC waiting
|
||||
* routines releasing some extra CPU time for the threads with
|
||||
* lower priority, this may slow down the driver a bit however.
|
||||
*/
|
||||
#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||
#define SDC_NICE_WAITING TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#include "sdc_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the card insertion status.
|
||||
* @note This macro wraps a low level function named
|
||||
* @p sdc_lld_is_card_inserted(), this function must be
|
||||
* provided by the application because it is not part of the
|
||||
* SDC driver.
|
||||
*
|
||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
||||
* @return The card state.
|
||||
* @retval FALSE card not inserted.
|
||||
* @retval TRUE card inserted.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdcIsCardInserted(sdcp) (sdc_lld_is_card_inserted(sdcp))
|
||||
|
||||
/**
|
||||
* @brief Returns the write protect status.
|
||||
* @note This macro wraps a low level function named
|
||||
* @p sdc_lld_is_write_protected(), this function must be
|
||||
* provided by the application because it is not part of the
|
||||
* SDC driver.
|
||||
*
|
||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
||||
* @return The card state.
|
||||
* @retval FALSE not write protected.
|
||||
* @retval TRUE write protected.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sdcInit(void);
|
||||
void sdcObjectInit(SDCDriver *sdcp);
|
||||
void sdcStart(SDCDriver *sdcp, const SDCConfig *config);
|
||||
void sdcStop(SDCDriver *sdcp);
|
||||
bool_t sdcConnect(SDCDriver *sdcp);
|
||||
bool_t sdcDisconnect(SDCDriver *sdcp);
|
||||
bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
|
||||
uint8_t *buffer, uint32_t n);
|
||||
bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
|
||||
const uint8_t *buffer, uint32_t n);
|
||||
sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp);
|
||||
bool_t sdcSync(SDCDriver *sdcp);
|
||||
bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip);
|
||||
bool_t sdcErase(SDCDriver *mmcp, uint32_t startblk, uint32_t endblk);
|
||||
bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SDC */
|
||||
|
||||
#endif /* _SDC_H_ */
|
||||
|
||||
/** @} */
|
||||
323
firmware/chibios/os/hal/include/serial.h
Executable file
323
firmware/chibios/os/hal/include/serial.h
Executable file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Serial status flags
|
||||
* @{
|
||||
*/
|
||||
#define SD_PARITY_ERROR 32 /**< @brief Parity error happened. */
|
||||
#define SD_FRAMING_ERROR 64 /**< @brief Framing error happened. */
|
||||
#define SD_OVERRUN_ERROR 128 /**< @brief Overflow happened. */
|
||||
#define SD_NOISE_ERROR 256 /**< @brief Noise on the line. */
|
||||
#define SD_BREAK_DETECTED 512 /**< @brief Break detected. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Serial configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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 16 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_BUFFERS_SIZE 16
|
||||
#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, /**< Not initialized. */
|
||||
SD_STOP = 1, /**< Stopped. */
|
||||
SD_READY = 2 /**< 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
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannelVMT
|
||||
*
|
||||
* @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. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Direct output check on a @p SerialDriver.
|
||||
* @note 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.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdPutWouldBlock(sdp) chOQIsFullI(&(sdp)->oqueue)
|
||||
|
||||
/**
|
||||
* @brief Direct input check on a @p SerialDriver.
|
||||
* @note 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.
|
||||
*
|
||||
* @deprecated
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdGetWouldBlock(sdp) chIQIsEmptyI(&(sdp)->iqueue)
|
||||
|
||||
/**
|
||||
* @brief Direct write to a @p SerialDriver.
|
||||
* @note 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 chnPutTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdPut(sdp, b) chOQPut(&(sdp)->oqueue, b)
|
||||
|
||||
/**
|
||||
* @brief Direct write to a @p SerialDriver with timeout specification.
|
||||
* @note 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 chnPutTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdPutTimeout(sdp, b, t) chOQPutTimeout(&(sdp)->oqueue, b, t)
|
||||
|
||||
/**
|
||||
* @brief Direct read from a @p SerialDriver.
|
||||
* @note 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 chnGetTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdGet(sdp) chIQGet(&(sdp)->iqueue)
|
||||
|
||||
/**
|
||||
* @brief Direct read from a @p SerialDriver with timeout specification.
|
||||
* @note 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 chnGetTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdGetTimeout(sdp, t) chIQGetTimeout(&(sdp)->iqueue, t)
|
||||
|
||||
/**
|
||||
* @brief Direct blocking write to a @p SerialDriver.
|
||||
* @note 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 chnWrite()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdWrite(sdp, b, n) \
|
||||
chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_INFINITE)
|
||||
|
||||
/**
|
||||
* @brief Direct blocking write to a @p SerialDriver with timeout
|
||||
* specification.
|
||||
* @note 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 to different channels implementations.
|
||||
*
|
||||
* @see chnWriteTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdWriteTimeout(sdp, b, n, t) \
|
||||
chOQWriteTimeout(&(sdp)->oqueue, b, n, t)
|
||||
|
||||
/**
|
||||
* @brief Direct non-blocking write to a @p SerialDriver.
|
||||
* @note 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 to different channels implementations.
|
||||
*
|
||||
* @see chnWriteTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdAsynchronousWrite(sdp, b, n) \
|
||||
chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_IMMEDIATE)
|
||||
|
||||
/**
|
||||
* @brief Direct blocking read from a @p SerialDriver.
|
||||
* @note 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 chnRead()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdRead(sdp, b, n) \
|
||||
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_INFINITE)
|
||||
|
||||
/**
|
||||
* @brief Direct blocking read from a @p SerialDriver with timeout
|
||||
* specification.
|
||||
* @note 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 chnReadTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdReadTimeout(sdp, b, n, t) \
|
||||
chIQReadTimeout(&(sdp)->iqueue, b, n, t)
|
||||
|
||||
/**
|
||||
* @brief Direct non-blocking read from a @p SerialDriver.
|
||||
* @note 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 chnReadTimeout()
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define sdAsynchronousRead(sdp, b, n) \
|
||||
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
#endif /* _SERIAL_H_ */
|
||||
|
||||
/** @} */
|
||||
241
firmware/chibios/os/hal/include/serial_usb.h
Executable file
241
firmware/chibios/os/hal/include/serial_usb.h
Executable file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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_usb.h
|
||||
* @brief Serial over USB Driver macros and structures.
|
||||
*
|
||||
* @addtogroup SERIAL_USB
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_USB_H_
|
||||
#define _SERIAL_USB_H_
|
||||
|
||||
#if HAL_USE_SERIAL_USB || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name CDC specific messages.
|
||||
* @{
|
||||
*/
|
||||
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00
|
||||
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01
|
||||
#define CDC_SET_COMM_FEATURE 0x02
|
||||
#define CDC_GET_COMM_FEATURE 0x03
|
||||
#define CDC_CLEAR_COMM_FEATURE 0x04
|
||||
#define CDC_SET_AUX_LINE_STATE 0x10
|
||||
#define CDC_SET_HOOK_STATE 0x11
|
||||
#define CDC_PULSE_SETUP 0x12
|
||||
#define CDC_SEND_PULSE 0x13
|
||||
#define CDC_SET_PULSE_TIME 0x14
|
||||
#define CDC_RING_AUX_JACK 0x15
|
||||
#define CDC_SET_LINE_CODING 0x20
|
||||
#define CDC_GET_LINE_CODING 0x21
|
||||
#define CDC_SET_CONTROL_LINE_STATE 0x22
|
||||
#define CDC_SEND_BREAK 0x23
|
||||
#define CDC_SET_RINGER_PARMS 0x30
|
||||
#define CDC_GET_RINGER_PARMS 0x31
|
||||
#define CDC_SET_OPERATION_PARMS 0x32
|
||||
#define CDC_GET_OPERATION_PARMS 0x33
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Line Control bit definitions.
|
||||
* @{
|
||||
*/
|
||||
#define LC_STOP_1 0
|
||||
#define LC_STOP_1P5 1
|
||||
#define LC_STOP_2 2
|
||||
|
||||
#define LC_PARITY_NONE 0
|
||||
#define LC_PARITY_ODD 1
|
||||
#define LC_PARITY_EVEN 2
|
||||
#define LC_PARITY_MARK 3
|
||||
#define LC_PARITY_SPACE 4
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name SERIAL_USB configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Serial over USB buffers size.
|
||||
* @details Configuration parameter, the buffer size must be a multiple of
|
||||
* the USB data endpoint maximum packet size.
|
||||
* @note The default is 256 bytes for both the transmission and receive
|
||||
* buffers.
|
||||
*/
|
||||
#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__)
|
||||
#define SERIAL_USB_BUFFERS_SIZE 256
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !HAL_USE_USB || !CH_USE_QUEUES || !CH_USE_EVENTS
|
||||
#error "Serial over USB Driver requires HAL_USE_USB, CH_USE_QUEUES, "
|
||||
"CH_USE_EVENTS"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of Line Coding structure.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t dwDTERate[4];
|
||||
uint8_t bCharFormat;
|
||||
uint8_t bParityType;
|
||||
uint8_t bDataBits;
|
||||
} cdc_linecoding_t;
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
SDU_UNINIT = 0, /**< Not initialized. */
|
||||
SDU_STOP = 1, /**< Stopped. */
|
||||
SDU_READY = 2 /**< Ready. */
|
||||
} sdustate_t;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a serial over USB driver.
|
||||
*/
|
||||
typedef struct SerialUSBDriver SerialUSBDriver;
|
||||
|
||||
/**
|
||||
* @brief Serial over USB Driver configuration structure.
|
||||
* @details An instance of this structure must be passed to @p sduStart()
|
||||
* in order to configure and start the driver operations.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief USB driver to use.
|
||||
*/
|
||||
USBDriver *usbp;
|
||||
/**
|
||||
* @brief Bulk IN endpoint used for outgoing data transfer.
|
||||
*/
|
||||
usbep_t bulk_in;
|
||||
/**
|
||||
* @brief Bulk OUT endpoint used for incoming data transfer.
|
||||
*/
|
||||
usbep_t bulk_out;
|
||||
/**
|
||||
* @brief Interrupt IN endpoint used for notifications.
|
||||
*/
|
||||
usbep_t int_in;
|
||||
} SerialUSBConfig;
|
||||
|
||||
/**
|
||||
* @brief @p SerialDriver specific data.
|
||||
*/
|
||||
#define _serial_usb_driver_data \
|
||||
_base_asynchronous_channel_data \
|
||||
/* Driver state.*/ \
|
||||
sdustate_t state; \
|
||||
/* Input queue.*/ \
|
||||
InputQueue iqueue; \
|
||||
/* Output queue.*/ \
|
||||
OutputQueue oqueue; \
|
||||
/* Input buffer.*/ \
|
||||
uint8_t ib[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* Output buffer.*/ \
|
||||
uint8_t ob[SERIAL_USB_BUFFERS_SIZE]; \
|
||||
/* End of the mandatory fields.*/ \
|
||||
/* Current configuration data.*/ \
|
||||
const SerialUSBConfig *config;
|
||||
|
||||
/**
|
||||
* @brief @p SerialUSBDriver specific methods.
|
||||
*/
|
||||
#define _serial_usb_driver_methods \
|
||||
_base_asynchronous_channel_methods
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannelVMT
|
||||
*
|
||||
* @brief @p SerialDriver virtual methods table.
|
||||
*/
|
||||
struct SerialUSBDriverVMT {
|
||||
_serial_usb_driver_methods
|
||||
};
|
||||
|
||||
/**
|
||||
* @extends BaseAsynchronousChannel
|
||||
*
|
||||
* @brief Full duplex serial driver class.
|
||||
* @details This class extends @p BaseAsynchronousChannel by adding physical
|
||||
* I/O queues.
|
||||
*/
|
||||
struct SerialUSBDriver {
|
||||
/** @brief Virtual Methods Table.*/
|
||||
const struct SerialUSBDriverVMT *vmt;
|
||||
_serial_usb_driver_data
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void sduInit(void);
|
||||
void sduObjectInit(SerialUSBDriver *sdp);
|
||||
void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config);
|
||||
void sduStop(SerialUSBDriver *sdup);
|
||||
void sduConfigureHookI(SerialUSBDriver *sdup);
|
||||
bool_t sduRequestsHook(USBDriver *usbp);
|
||||
void sduDataTransmitted(USBDriver *usbp, usbep_t ep);
|
||||
void sduDataReceived(USBDriver *usbp, usbep_t ep);
|
||||
void sduInterruptTransmitted(USBDriver *usbp, usbep_t ep);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SERIAL_USB */
|
||||
|
||||
#endif /* _SERIAL_USB_H_ */
|
||||
|
||||
/** @} */
|
||||
331
firmware/chibios/os/hal/include/spi.h
Executable file
331
firmware/chibios/os/hal/include/spi.h
Executable file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name SPI configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Enables synchronous APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_WAIT TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs.
|
||||
* @note Disabling this option saves both code and data space.
|
||||
*/
|
||||
#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
|
||||
#define SPI_USE_MUTUAL_EXCLUSION TRUE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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, /**< Not initialized. */
|
||||
SPI_STOP = 1, /**< Stopped. */
|
||||
SPI_READY = 2, /**< Ready. */
|
||||
SPI_ACTIVE = 3, /**< Exchanging data. */
|
||||
SPI_COMPLETE = 4 /**< Asynchronous operation complete. */
|
||||
} spistate_t;
|
||||
|
||||
#include "spi_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Asserts the slave select signal and prepares for transfers.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define spiSelectI(spip) { \
|
||||
spi_lld_select(spip); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deasserts the slave select signal.
|
||||
* @details The previously selected peripheral is unselected.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define spiUnselectI(spip) { \
|
||||
spi_lld_unselect(spip); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ignores data on the SPI bus.
|
||||
* @details This asynchronous function starts the transmission of a series of
|
||||
* idle words on the SPI bus and ignores the received data.
|
||||
* @pre A slave must have been selected using @p spiSelect() or
|
||||
* @p spiSelectI().
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define spiStartIgnoreI(spip, n) { \
|
||||
(spip)->state = SPI_ACTIVE; \
|
||||
spi_lld_ignore(spip, n); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges data on the SPI bus.
|
||||
* @details This asynchronous function starts a simultaneous transmit/receive
|
||||
* operation.
|
||||
* @pre A slave must have been selected using @p spiSelect() or
|
||||
* @p spiSelectI().
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below
|
||||
* or equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be exchanged
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define spiStartExchangeI(spip, n, txbuf, rxbuf) { \
|
||||
(spip)->state = SPI_ACTIVE; \
|
||||
spi_lld_exchange(spip, n, txbuf, rxbuf); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the SPI bus.
|
||||
* @details This asynchronous function starts a transmit operation.
|
||||
* @pre A slave must have been selected using @p spiSelect() or
|
||||
* @p spiSelectI().
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below
|
||||
* or equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define spiStartSendI(spip, n, txbuf) { \
|
||||
(spip)->state = SPI_ACTIVE; \
|
||||
spi_lld_send(spip, n, txbuf); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives data from the SPI bus.
|
||||
* @details This asynchronous function starts a receive operation.
|
||||
* @pre A slave must have been selected using @p spiSelect() or
|
||||
* @p spiSelectI().
|
||||
* @post At the end of the operation the configured callback is invoked.
|
||||
* @note The buffers are organized as uint8_t arrays for data sizes below
|
||||
* or equal to 8 bits else it is organized as uint16_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define spiStartReceiveI(spip, n, rxbuf) { \
|
||||
(spip)->state = SPI_ACTIVE; \
|
||||
spi_lld_receive(spip, n, rxbuf); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges one frame using a polled wait.
|
||||
* @details This synchronous function exchanges one frame using a polled
|
||||
* synchronization method. This function is useful when exchanging
|
||||
* small amount of data on high speed channels, usually in this
|
||||
* situation is much more efficient just wait for completion using
|
||||
* polling than suspending the thread waiting for an interrupt.
|
||||
* @note This API is implemented as a macro in order to minimize latency.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] frame the data frame to send over the SPI bus
|
||||
* @return The received data frame from the SPI bus.
|
||||
*/
|
||||
#define spiPolledExchange(spip, frame) spi_lld_polled_exchange(spip, frame)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
#if SPI_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waits for operation completion.
|
||||
* @details This function waits for the driver to complete the current
|
||||
* operation.
|
||||
* @pre An operation must be running while the function is invoked.
|
||||
* @note No more than one thread can wait on a SPI driver using
|
||||
* this function.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _spi_wait_s(spip) { \
|
||||
chDbgAssert((spip)->thread == NULL, \
|
||||
"_spi_wait(), #1", "already waiting"); \
|
||||
(spip)->thread = chThdSelf(); \
|
||||
chSchGoSleepS(THD_STATE_SUSPENDED); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wakes up the waiting thread.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _spi_wakeup_isr(spip) { \
|
||||
chSysLockFromIsr(); \
|
||||
if ((spip)->thread != NULL) { \
|
||||
Thread *tp = (spip)->thread; \
|
||||
(spip)->thread = NULL; \
|
||||
tp->p_u.rdymsg = RDY_OK; \
|
||||
chSchReadyI(tp); \
|
||||
} \
|
||||
chSysUnlockFromIsr(); \
|
||||
}
|
||||
#else /* !SPI_USE_WAIT */
|
||||
#define _spi_wait_s(spip)
|
||||
#define _spi_wakeup_isr(spip)
|
||||
#endif /* !SPI_USE_WAIT */
|
||||
|
||||
/**
|
||||
* @brief Common ISR code.
|
||||
* @details This code handles the portable part of the ISR code:
|
||||
* - Callback invocation.
|
||||
* - Waiting thread wakeup, if any.
|
||||
* - Driver state transitions.
|
||||
* .
|
||||
* @note This macro is meant to be used in the low level drivers
|
||||
* implementation only.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _spi_isr_code(spip) { \
|
||||
if ((spip)->config->end_cb) { \
|
||||
(spip)->state = SPI_COMPLETE; \
|
||||
(spip)->config->end_cb(spip); \
|
||||
if ((spip)->state == SPI_COMPLETE) \
|
||||
(spip)->state = SPI_READY; \
|
||||
} \
|
||||
else \
|
||||
(spip)->state = SPI_READY; \
|
||||
_spi_wakeup_isr(spip); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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 spiStartIgnore(SPIDriver *spip, size_t n);
|
||||
void spiStartExchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
void spiStartSend(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
void spiStartReceive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
#if SPI_USE_WAIT
|
||||
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);
|
||||
#endif /* SPI_USE_WAIT */
|
||||
#if SPI_USE_MUTUAL_EXCLUSION
|
||||
void spiAcquireBus(SPIDriver *spip);
|
||||
void spiReleaseBus(SPIDriver *spip);
|
||||
#endif /* SPI_USE_MUTUAL_EXCLUSION */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SPI */
|
||||
|
||||
#endif /* _SPI_H_ */
|
||||
|
||||
/** @} */
|
||||
125
firmware/chibios/os/hal/include/tm.h
Executable file
125
firmware/chibios/os/hal/include/tm.h
Executable file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 tm.h
|
||||
* @brief Time Measurement driver header.
|
||||
*
|
||||
* @addtogroup TM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _TM_H_
|
||||
#define _TM_H_
|
||||
|
||||
#if HAL_USE_TM || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a Time Measurement object.
|
||||
* @note Start/stop of measurements is performed through the function
|
||||
* pointers in order to avoid inlining of those functions which
|
||||
* could compromise measurement accuracy.
|
||||
* @note The maximum measurable time period depends on the implementation
|
||||
* of the realtime counter in the HAL driver.
|
||||
* @note The measurement is not 100% cycle-accurate, it can be in excess
|
||||
* of few cycles depending on the compiler and target architecture.
|
||||
* @note Interrupts can affect measurement if the measurement is performed
|
||||
* with interrupts enabled.
|
||||
*/
|
||||
typedef struct TimeMeasurement TimeMeasurement;
|
||||
|
||||
/**
|
||||
* @brief Time Measurement structure.
|
||||
*/
|
||||
struct TimeMeasurement {
|
||||
void (*start)(TimeMeasurement *tmp); /**< @brief Starts a measurement. */
|
||||
void (*stop)(TimeMeasurement *tmp); /**< @brief Stops a measurement. */
|
||||
halrtcnt_t last; /**< @brief Last measurement. */
|
||||
halrtcnt_t worst; /**< @brief Worst measurement. */
|
||||
halrtcnt_t best; /**< @brief Best measurement. */
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Starts a measurement.
|
||||
* @pre The @p TimeMeasurement must be initialized.
|
||||
* @note This function can be invoked in any context.
|
||||
*
|
||||
* @param[in,out] tmp pointer to a @p TimeMeasurement structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define tmStartMeasurement(tmp) (tmp)->start(tmp)
|
||||
|
||||
/**
|
||||
* @brief Stops a measurement.
|
||||
* @pre The @p TimeMeasurement must be initialized.
|
||||
* @note This function can be invoked in any context.
|
||||
*
|
||||
* @param[in,out] tmp pointer to a @p TimeMeasurement structure
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define tmStopMeasurement(tmp) (tmp)->stop(tmp)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void tmInit(void);
|
||||
void tmObjectInit(TimeMeasurement *tmp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_TM */
|
||||
|
||||
#endif /* _TM_H_ */
|
||||
|
||||
/** @} */
|
||||
129
firmware/chibios/os/hal/include/uart.h
Executable file
129
firmware/chibios/os/hal/include/uart.h
Executable file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 uart.h
|
||||
* @brief UART Driver macros and structures.
|
||||
*
|
||||
* @addtogroup UART
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _UART_H_
|
||||
#define _UART_H_
|
||||
|
||||
#if HAL_USE_UART || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name UART status flags
|
||||
* @{
|
||||
*/
|
||||
#define UART_NO_ERROR 0 /**< @brief No pending conditions. */
|
||||
#define UART_PARITY_ERROR 4 /**< @brief Parity error happened. */
|
||||
#define UART_FRAMING_ERROR 8 /**< @brief Framing error happened. */
|
||||
#define UART_OVERRUN_ERROR 16 /**< @brief Overflow happened. */
|
||||
#define UART_NOISE_ERROR 32 /**< @brief Noise on the line. */
|
||||
#define UART_BREAK_DETECTED 64 /**< @brief Break detected. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
UART_UNINIT = 0, /**< Not initialized. */
|
||||
UART_STOP = 1, /**< Stopped. */
|
||||
UART_READY = 2 /**< Ready. */
|
||||
} uartstate_t;
|
||||
|
||||
/**
|
||||
* @brief Transmitter state machine states.
|
||||
*/
|
||||
typedef enum {
|
||||
UART_TX_IDLE = 0, /**< Not transmitting. */
|
||||
UART_TX_ACTIVE = 1, /**< Transmitting. */
|
||||
UART_TX_COMPLETE = 2 /**< Buffer complete. */
|
||||
} uarttxstate_t;
|
||||
|
||||
/**
|
||||
* @brief Receiver state machine states.
|
||||
*/
|
||||
typedef enum {
|
||||
UART_RX_IDLE = 0, /**< Not receiving. */
|
||||
UART_RX_ACTIVE = 1, /**< Receiving. */
|
||||
UART_RX_COMPLETE = 2 /**< Buffer complete. */
|
||||
} uartrxstate_t;
|
||||
|
||||
#include "uart_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void uartInit(void);
|
||||
void uartObjectInit(UARTDriver *uartp);
|
||||
void uartStart(UARTDriver *uartp, const UARTConfig *config);
|
||||
void uartStop(UARTDriver *uartp);
|
||||
void uartStartSend(UARTDriver *uartp, size_t n, const void *txbuf);
|
||||
void uartStartSendI(UARTDriver *uartp, size_t n, const void *txbuf);
|
||||
size_t uartStopSend(UARTDriver *uartp);
|
||||
size_t uartStopSendI(UARTDriver *uartp);
|
||||
void uartStartReceive(UARTDriver *uartp, size_t n, void *rxbuf);
|
||||
void uartStartReceiveI(UARTDriver *uartp, size_t n, void *rxbuf);
|
||||
size_t uartStopReceive(UARTDriver *uartp);
|
||||
size_t uartStopReceiveI(UARTDriver *uartp);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_UART */
|
||||
|
||||
#endif /* _UART_H_ */
|
||||
|
||||
/** @} */
|
||||
585
firmware/chibios/os/hal/include/usb.h
Executable file
585
firmware/chibios/os/hal/include/usb.h
Executable file
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
|
||||
2011,2012,2013 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 usb.h
|
||||
* @brief USB Driver macros and structures.
|
||||
*
|
||||
* @addtogroup USB
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _USB_H_
|
||||
#define _USB_H_
|
||||
|
||||
#if HAL_USE_USB || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define USB_RTYPE_DIR_MASK 0x80
|
||||
#define USB_RTYPE_DIR_HOST2DEV 0x00
|
||||
#define USB_RTYPE_DIR_DEV2HOST 0x80
|
||||
#define USB_RTYPE_TYPE_MASK 0x60
|
||||
#define USB_RTYPE_TYPE_STD 0x00
|
||||
#define USB_RTYPE_TYPE_CLASS 0x20
|
||||
#define USB_RTYPE_TYPE_VENDOR 0x40
|
||||
#define USB_RTYPE_TYPE_RESERVED 0x60
|
||||
#define USB_RTYPE_RECIPIENT_MASK 0x1F
|
||||
#define USB_RTYPE_RECIPIENT_DEVICE 0x00
|
||||
#define USB_RTYPE_RECIPIENT_INTERFACE 0x01
|
||||
#define USB_RTYPE_RECIPIENT_ENDPOINT 0x02
|
||||
#define USB_RTYPE_RECIPIENT_OTHER 0x03
|
||||
|
||||
#define USB_REQ_GET_STATUS 0
|
||||
#define USB_REQ_CLEAR_FEATURE 1
|
||||
#define USB_REQ_SET_FEATURE 3
|
||||
#define USB_REQ_SET_ADDRESS 5
|
||||
#define USB_REQ_GET_DESCRIPTOR 6
|
||||
#define USB_REQ_SET_DESCRIPTOR 7
|
||||
#define USB_REQ_GET_CONFIGURATION 8
|
||||
#define USB_REQ_SET_CONFIGURATION 9
|
||||
#define USB_REQ_GET_INTERFACE 10
|
||||
#define USB_REQ_SET_INTERFACE 11
|
||||
#define USB_REQ_SYNCH_FRAME 12
|
||||
|
||||
#define USB_DESCRIPTOR_DEVICE 1
|
||||
#define USB_DESCRIPTOR_CONFIGURATION 2
|
||||
#define USB_DESCRIPTOR_STRING 3
|
||||
#define USB_DESCRIPTOR_INTERFACE 4
|
||||
#define USB_DESCRIPTOR_ENDPOINT 5
|
||||
#define USB_DESCRIPTOR_DEVICE_QUALIFIER 6
|
||||
#define USB_DESCRIPTOR_OTHER_SPEED_CFG 7
|
||||
#define USB_DESCRIPTOR_INTERFACE_POWER 8
|
||||
#define USB_DESCRIPTOR_INTERFACE_ASSOCIATION 11
|
||||
|
||||
#define USB_FEATURE_ENDPOINT_HALT 0
|
||||
#define USB_FEATURE_DEVICE_REMOTE_WAKEUP 1
|
||||
#define USB_FEATURE_TEST_MODE 2
|
||||
|
||||
#define USB_EARLY_SET_ADDRESS 0
|
||||
#define USB_LATE_SET_ADDRESS 1
|
||||
|
||||
#define USB_EP0_STATUS_STAGE_SW 0
|
||||
#define USB_EP0_STATUS_STAGE_HW 1
|
||||
|
||||
#define USB_SET_ADDRESS_ACK_SW 0
|
||||
#define USB_SET_ADDRESS_ACK_HW 1
|
||||
|
||||
/**
|
||||
* @name Helper macros for USB descriptors
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Helper macro for index values into descriptor strings.
|
||||
*/
|
||||
#define USB_DESC_INDEX(i) ((uint8_t)(i))
|
||||
|
||||
/**
|
||||
* @brief Helper macro for byte values into descriptor strings.
|
||||
*/
|
||||
#define USB_DESC_BYTE(b) ((uint8_t)(b))
|
||||
|
||||
/**
|
||||
* @brief Helper macro for word values into descriptor strings.
|
||||
*/
|
||||
#define USB_DESC_WORD(w) \
|
||||
(uint8_t)((w) & 255), \
|
||||
(uint8_t)(((w) >> 8) & 255)
|
||||
|
||||
/**
|
||||
* @brief Helper macro for BCD values into descriptor strings.
|
||||
*/
|
||||
#define USB_DESC_BCD(bcd) \
|
||||
(uint8_t)((bcd) & 255), \
|
||||
(uint8_t)(((bcd) >> 8) & 255)
|
||||
|
||||
/**
|
||||
* @brief Device Descriptor helper macro.
|
||||
*/
|
||||
#define USB_DESC_DEVICE(bcdUSB, bDeviceClass, bDeviceSubClass, \
|
||||
bDeviceProtocol, bMaxPacketSize, idVendor, \
|
||||
idProduct, bcdDevice, iManufacturer, \
|
||||
iProduct, iSerialNumber, bNumConfigurations) \
|
||||
USB_DESC_BYTE(18), \
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_DEVICE), \
|
||||
USB_DESC_BCD(bcdUSB), \
|
||||
USB_DESC_BYTE(bDeviceClass), \
|
||||
USB_DESC_BYTE(bDeviceSubClass), \
|
||||
USB_DESC_BYTE(bDeviceProtocol), \
|
||||
USB_DESC_BYTE(bMaxPacketSize), \
|
||||
USB_DESC_WORD(idVendor), \
|
||||
USB_DESC_WORD(idProduct), \
|
||||
USB_DESC_BCD(bcdDevice), \
|
||||
USB_DESC_INDEX(iManufacturer), \
|
||||
USB_DESC_INDEX(iProduct), \
|
||||
USB_DESC_INDEX(iSerialNumber), \
|
||||
USB_DESC_BYTE(bNumConfigurations)
|
||||
|
||||
/**
|
||||
* @brief Configuration Descriptor helper macro.
|
||||
*/
|
||||
#define USB_DESC_CONFIGURATION(wTotalLength, bNumInterfaces, \
|
||||
bConfigurationValue, iConfiguration, \
|
||||
bmAttributes, bMaxPower) \
|
||||
USB_DESC_BYTE(9), \
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_CONFIGURATION), \
|
||||
USB_DESC_WORD(wTotalLength), \
|
||||
USB_DESC_BYTE(bNumInterfaces), \
|
||||
USB_DESC_BYTE(bConfigurationValue), \
|
||||
USB_DESC_INDEX(iConfiguration), \
|
||||
USB_DESC_BYTE(bmAttributes), \
|
||||
USB_DESC_BYTE(bMaxPower)
|
||||
|
||||
/**
|
||||
* @brief Interface Descriptor helper macro.
|
||||
*/
|
||||
#define USB_DESC_INTERFACE(bInterfaceNumber, bAlternateSetting, \
|
||||
bNumEndpoints, bInterfaceClass, \
|
||||
bInterfaceSubClass, bInterfaceProtocol, \
|
||||
iInterface) \
|
||||
USB_DESC_BYTE(9), \
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_INTERFACE), \
|
||||
USB_DESC_BYTE(bInterfaceNumber), \
|
||||
USB_DESC_BYTE(bAlternateSetting), \
|
||||
USB_DESC_BYTE(bNumEndpoints), \
|
||||
USB_DESC_BYTE(bInterfaceClass), \
|
||||
USB_DESC_BYTE(bInterfaceSubClass), \
|
||||
USB_DESC_BYTE(bInterfaceProtocol), \
|
||||
USB_DESC_INDEX(iInterface)
|
||||
|
||||
/**
|
||||
* @brief Interface Association Descriptor helper macro.
|
||||
*/
|
||||
#define USB_DESC_INTERFACE_ASSOCIATION(bFirstInterface, \
|
||||
bInterfaceCount, bFunctionClass, \
|
||||
bFunctionSubClass, bFunctionProcotol, \
|
||||
iInterface) \
|
||||
USB_DESC_BYTE(8), \
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_INTERFACE_ASSOCIATION), \
|
||||
USB_DESC_BYTE(bFirstInterface), \
|
||||
USB_DESC_BYTE(bInterfaceCount), \
|
||||
USB_DESC_BYTE(bFunctionClass), \
|
||||
USB_DESC_BYTE(bFunctionSubClass), \
|
||||
USB_DESC_BYTE(bFunctionProcotol), \
|
||||
USB_DESC_INDEX(iInterface)
|
||||
|
||||
/**
|
||||
* @brief Endpoint Descriptor helper macro.
|
||||
*/
|
||||
#define USB_DESC_ENDPOINT(bEndpointAddress, bmAttributes, wMaxPacketSize, \
|
||||
bInterval) \
|
||||
USB_DESC_BYTE(7), \
|
||||
USB_DESC_BYTE(USB_DESCRIPTOR_ENDPOINT), \
|
||||
USB_DESC_BYTE(bEndpointAddress), \
|
||||
USB_DESC_BYTE(bmAttributes), \
|
||||
USB_DESC_WORD(wMaxPacketSize), \
|
||||
USB_DESC_BYTE(bInterval)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Endpoint types and settings
|
||||
* @{
|
||||
*/
|
||||
#define USB_EP_MODE_TYPE 0x0003 /**< Endpoint type mask. */
|
||||
#define USB_EP_MODE_TYPE_CTRL 0x0000 /**< Control endpoint. */
|
||||
#define USB_EP_MODE_TYPE_ISOC 0x0001 /**< Isochronous endpoint. */
|
||||
#define USB_EP_MODE_TYPE_BULK 0x0002 /**< Bulk endpoint. */
|
||||
#define USB_EP_MODE_TYPE_INTR 0x0003 /**< Interrupt endpoint. */
|
||||
#define USB_EP_MODE_LINEAR_BUFFER 0x0000 /**< Linear buffer mode. */
|
||||
#define USB_EP_MODE_QUEUE_BUFFER 0x0010 /**< Queue buffer mode. */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an USB driver.
|
||||
*/
|
||||
typedef struct USBDriver USBDriver;
|
||||
|
||||
/**
|
||||
* @brief Type of an endpoint identifier.
|
||||
*/
|
||||
typedef uint8_t usbep_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a driver state machine possible states.
|
||||
*/
|
||||
typedef enum {
|
||||
USB_UNINIT = 0, /**< Not initialized. */
|
||||
USB_STOP = 1, /**< Stopped. */
|
||||
USB_READY = 2, /**< Ready, after bus reset. */
|
||||
USB_SELECTED = 3, /**< Address assigned. */
|
||||
USB_ACTIVE = 4 /**< Active, configuration selected.*/
|
||||
} usbstate_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an endpoint status.
|
||||
*/
|
||||
typedef enum {
|
||||
EP_STATUS_DISABLED = 0, /**< Endpoint not active. */
|
||||
EP_STATUS_STALLED = 1, /**< Endpoint opened but stalled. */
|
||||
EP_STATUS_ACTIVE = 2 /**< Active endpoint. */
|
||||
} usbepstatus_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an endpoint zero state machine states.
|
||||
*/
|
||||
typedef enum {
|
||||
USB_EP0_WAITING_SETUP, /**< Waiting for SETUP data. */
|
||||
USB_EP0_TX, /**< Transmitting. */
|
||||
USB_EP0_WAITING_TX0, /**< Waiting transmit 0. */
|
||||
USB_EP0_WAITING_STS, /**< Waiting status. */
|
||||
USB_EP0_RX, /**< Receiving. */
|
||||
USB_EP0_SENDING_STS, /**< Sending status. */
|
||||
USB_EP0_ERROR /**< Error, EP0 stalled. */
|
||||
} usbep0state_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an enumeration of the possible USB events.
|
||||
*/
|
||||
typedef enum {
|
||||
USB_EVENT_RESET = 0, /**< Driver has been reset by host. */
|
||||
USB_EVENT_ADDRESS = 1, /**< Address assigned. */
|
||||
USB_EVENT_CONFIGURED = 2, /**< Configuration selected. */
|
||||
USB_EVENT_SUSPEND = 3, /**< Entering suspend mode. */
|
||||
USB_EVENT_WAKEUP = 4, /**< Leaving suspend mode. */
|
||||
USB_EVENT_STALLED = 5 /**< Endpoint 0 error, stalled. */
|
||||
} usbevent_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an USB descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Descriptor size in unicode characters.
|
||||
*/
|
||||
size_t ud_size;
|
||||
/**
|
||||
* @brief Pointer to the descriptor.
|
||||
*/
|
||||
const uint8_t *ud_string;
|
||||
} USBDescriptor;
|
||||
|
||||
/**
|
||||
* @brief Type of an USB generic notification callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object triggering the
|
||||
* callback
|
||||
*/
|
||||
typedef void (*usbcallback_t)(USBDriver *usbp);
|
||||
|
||||
/**
|
||||
* @brief Type of an USB endpoint callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object triggering the
|
||||
* callback
|
||||
* @param[in] ep endpoint number
|
||||
*/
|
||||
typedef void (*usbepcallback_t)(USBDriver *usbp, usbep_t ep);
|
||||
|
||||
/**
|
||||
* @brief Type of an USB event notification callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object triggering the
|
||||
* callback
|
||||
* @param[in] event event type
|
||||
*/
|
||||
typedef void (*usbeventcb_t)(USBDriver *usbp, usbevent_t event);
|
||||
|
||||
/**
|
||||
* @brief Type of a requests handler callback.
|
||||
* @details The request is encoded in the @p usb_setup buffer.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object triggering the
|
||||
* callback
|
||||
* @return The request handling exit code.
|
||||
* @retval FALSE Request not recognized by the handler.
|
||||
* @retval TRUE Request handled.
|
||||
*/
|
||||
typedef bool_t (*usbreqhandler_t)(USBDriver *usbp);
|
||||
|
||||
/**
|
||||
* @brief Type of an USB descriptor-retrieving callback.
|
||||
*/
|
||||
typedef const USBDescriptor * (*usbgetdescriptor_t)(USBDriver *usbp,
|
||||
uint8_t dtype,
|
||||
uint8_t dindex,
|
||||
uint16_t lang);
|
||||
|
||||
#include "usb_lld.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Macro Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the driver state.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @return The driver state.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define usbGetDriverStateI(usbp) ((usbp)->state)
|
||||
|
||||
/**
|
||||
* @brief Fetches a 16 bits word value from an USB message.
|
||||
*
|
||||
* @param[in] p pointer to the 16 bits word
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define usbFetchWord(p) ((uint16_t)*(p) | ((uint16_t)*((p) + 1) << 8))
|
||||
|
||||
/**
|
||||
* @brief Connects the USB device.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define usbConnectBus(usbp) usb_lld_connect_bus(usbp)
|
||||
|
||||
/**
|
||||
* @brief Disconnect the USB device.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define usbDisconnectBus(usbp) usb_lld_disconnect_bus(usbp)
|
||||
|
||||
/**
|
||||
* @brief Returns the current frame number.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @return The current frame number.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define usbGetFrameNumber(usbp) usb_lld_get_frame_number(usbp)
|
||||
|
||||
/**
|
||||
* @brief Returns the status of an IN endpoint.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @return The operation status.
|
||||
* @retval FALSE Endpoint ready.
|
||||
* @retval TRUE Endpoint transmitting.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define usbGetTransmitStatusI(usbp, ep) ((usbp)->transmitting & (1 << (ep)))
|
||||
|
||||
/**
|
||||
* @brief Returns the status of an OUT endpoint.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @return The operation status.
|
||||
* @retval FALSE Endpoint ready.
|
||||
* @retval TRUE Endpoint receiving.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define usbGetReceiveStatusI(usbp, ep) ((usbp)->receiving & (1 << (ep)))
|
||||
|
||||
/**
|
||||
* @brief Returns the exact size of a receive transaction.
|
||||
* @details The received size can be different from the size specified in
|
||||
* @p usbStartReceiveI() because the last packet could have a size
|
||||
* different from the expected one.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @return Received data size.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
#define usbGetReceiveTransactionSizeI(usbp, ep) \
|
||||
usb_lld_get_transaction_size(usbp, ep)
|
||||
|
||||
/**
|
||||
* @brief Request transfer setup.
|
||||
* @details This macro is used by the request handling callbacks in order to
|
||||
* prepare a transaction over the endpoint zero.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] buf pointer to a buffer for the transaction data
|
||||
* @param[in] n number of bytes to be transferred
|
||||
* @param[in] endcb callback to be invoked after the transfer or @p NULL
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
#define usbSetupTransfer(usbp, buf, n, endcb) { \
|
||||
(usbp)->ep0next = (buf); \
|
||||
(usbp)->ep0n = (n); \
|
||||
(usbp)->ep0endcb = (endcb); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads a setup packet from the dedicated packet buffer.
|
||||
* @details This function must be invoked in the context of the @p setup_cb
|
||||
* callback in order to read the received setup packet.
|
||||
* @pre In order to use this function the endpoint must have been
|
||||
* initialized as a control endpoint.
|
||||
* @note This function can be invoked both in thread and IRQ context.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
* @param[out] buf buffer where to copy the packet data
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
#define usbReadSetup(usbp, ep, buf) usb_lld_read_setup(usbp, ep, buf)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Low Level driver helper macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Common ISR code, usb event callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] evt USB event code
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_event_cb(usbp, evt) { \
|
||||
if (((usbp)->config->event_cb) != NULL) \
|
||||
(usbp)->config->event_cb(usbp, evt); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, SOF callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_sof_cb(usbp) { \
|
||||
if (((usbp)->config->sof_cb) != NULL) \
|
||||
(usbp)->config->sof_cb(usbp); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, setup packet callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_setup_cb(usbp, ep) { \
|
||||
(usbp)->epc[ep]->setup_cb(usbp, ep); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, IN endpoint callback.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_in_cb(usbp, ep) { \
|
||||
(usbp)->transmitting &= ~(1 << (ep)); \
|
||||
(usbp)->epc[ep]->in_cb(usbp, ep); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Common ISR code, OUT endpoint event.
|
||||
*
|
||||
* @param[in] usbp pointer to the @p USBDriver object
|
||||
* @param[in] ep endpoint number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define _usb_isr_invoke_out_cb(usbp, ep) { \
|
||||
(usbp)->receiving &= ~(1 << (ep)); \
|
||||
(usbp)->epc[ep]->out_cb(usbp, ep); \
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void usbInit(void);
|
||||
void usbObjectInit(USBDriver *usbp);
|
||||
void usbStart(USBDriver *usbp, const USBConfig *config);
|
||||
void usbStop(USBDriver *usbp);
|
||||
void usbInitEndpointI(USBDriver *usbp, usbep_t ep,
|
||||
const USBEndpointConfig *epcp);
|
||||
void usbDisableEndpointsI(USBDriver *usbp);
|
||||
void usbReadSetupI(USBDriver *usbp, usbep_t ep, uint8_t *buf);
|
||||
void usbPrepareReceive(USBDriver *usbp, usbep_t ep,
|
||||
uint8_t *buf, size_t n);
|
||||
void usbPrepareTransmit(USBDriver *usbp, usbep_t ep,
|
||||
const uint8_t *buf, size_t n);
|
||||
void usbPrepareQueuedReceive(USBDriver *usbp, usbep_t ep,
|
||||
InputQueue *iqp, size_t n);
|
||||
void usbPrepareQueuedTransmit(USBDriver *usbp, usbep_t ep,
|
||||
OutputQueue *oqp, size_t n);
|
||||
bool_t usbStartReceiveI(USBDriver *usbp, usbep_t ep);
|
||||
bool_t usbStartTransmitI(USBDriver *usbp, usbep_t ep);
|
||||
bool_t usbStallReceiveI(USBDriver *usbp, usbep_t ep);
|
||||
bool_t usbStallTransmitI(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_reset(USBDriver *usbp);
|
||||
void _usb_ep0setup(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_ep0in(USBDriver *usbp, usbep_t ep);
|
||||
void _usb_ep0out(USBDriver *usbp, usbep_t ep);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_USB */
|
||||
|
||||
#endif /* _USB_H_ */
|
||||
|
||||
/** @} */
|
||||
387
firmware/chibios/os/hal/platforms/AT91SAM7/adc_lld.c
Executable file
387
firmware/chibios/os/hal/platforms/AT91SAM7/adc_lld.c
Executable file
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
This file has been contributed by:
|
||||
Andrew Hannam aka inmarket.
|
||||
*/
|
||||
/**
|
||||
* @file AT91SAM7/adc_lld.c
|
||||
* @brief AT91SAM7 ADC subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/**
|
||||
* @brief ADC1 Prescaler
|
||||
* @detail Prescale = RoundUp(MCK / 2 / ADCClock - 1)
|
||||
*/
|
||||
#if ((((MCK/2)+(AT91_ADC1_CLOCK-1))/AT91_ADC1_CLOCK)-1) > 255
|
||||
#define AT91_ADC1_PRESCALE 255
|
||||
#else
|
||||
#define AT91_ADC1_PRESCALE ((((MCK/2)+(AT91_ADC1_CLOCK-1))/AT91_ADC1_CLOCK)-1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 Startup Time
|
||||
* @details Startup = RoundUp(ADCClock / 400,000 - 1)
|
||||
* @note Corresponds to a startup delay > 20uS (as required from the datasheet)
|
||||
*/
|
||||
#if (((AT91_ADC1_CLOCK+399999)/400000)-1) > 127
|
||||
#define AT91_ADC1_STARTUP 127
|
||||
#else
|
||||
#define AT91_ADC1_STARTUP (((AT91_ADC1_CLOCK+399999)/400000)-1)
|
||||
#endif
|
||||
|
||||
#if AT91_ADC1_RESOLUTION == 8
|
||||
#define AT91_ADC1_MAINMODE (((AT91_ADC1_SHTM & 0x0F) << 24) | ((AT91_ADC1_STARTUP & 0x7F) << 16) | ((AT91_ADC1_PRESCALE & 0xFF) << 8) | AT91C_ADC_LOWRES_8_BIT)
|
||||
#else
|
||||
#define AT91_ADC1_MAINMODE (((AT91_ADC1_SHTM & 0x0F) << 24) | ((AT91_ADC1_STARTUP & 0x7F) << 16) | ((AT91_ADC1_PRESCALE & 0xFF) << 8) | AT91C_ADC_LOWRES_10_BIT)
|
||||
#endif
|
||||
|
||||
#if AT91_ADC1_TIMER < 0 || AT91_ADC1_TIMER > 2
|
||||
#error "Unknown Timer specified for ADC1"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !ADC_USE_ADC1
|
||||
#error "You must specify ADC_USE_ADC1 if you have specified HAL_USE_ADC"
|
||||
#endif
|
||||
|
||||
/** @brief ADC1 driver identifier.*/
|
||||
ADCDriver ADCD1;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define ADCReg1 ((AT91S_ADC *)AT91C_ADC_CR)
|
||||
|
||||
#if AT91_ADC1_MAINMODE == 2
|
||||
#define ADCTimer1 ((AT91S_TC *)AT91C_TC2_CCR)
|
||||
#define AT91_ADC1_TIMERMODE AT91C_ADC_TRGSEL_TIOA2
|
||||
#define AT91_ADC1_TIMERID AT91C_ID_TC2
|
||||
#elif AT91_ADC1_MAINMODE == 1
|
||||
#define ADCTimer1 ((AT91S_TC *)AT91C_TC1_CCR)
|
||||
#define AT91_ADC1_TIMERMODE AT91C_ADC_TRGSEL_TIOA1
|
||||
#define AT91_ADC1_TIMERID AT91C_ID_TC1
|
||||
#else
|
||||
#define ADCTimer1 ((AT91S_TC *)AT91C_TC0_CCR)
|
||||
#define AT91_ADC1_TIMERMODE AT91C_ADC_TRGSEL_TIOA0
|
||||
#define AT91_ADC1_TIMERID AT91C_ID_TC0
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#define adc_sleep() ADCReg1->ADC_MR = (AT91_ADC1_MAINMODE | AT91C_ADC_SLEEP_MODE | AT91C_ADC_TRGEN_DIS)
|
||||
#define adc_wake() ADCReg1->ADC_MR = (AT91_ADC1_MAINMODE | AT91C_ADC_SLEEP_NORMAL_MODE | AT91C_ADC_TRGEN_DIS)
|
||||
#define adc_disable() { \
|
||||
ADCReg1->ADC_IDR = 0xFFFFFFFF; \
|
||||
ADCReg1->ADC_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS; \
|
||||
adc_wake(); \
|
||||
ADCReg1->ADC_CHDR = 0xFF; \
|
||||
}
|
||||
#define adc_clrint() { \
|
||||
uint32_t isr, dummy; \
|
||||
\
|
||||
isr = ADCReg1->ADC_SR; \
|
||||
if ((isr & AT91C_ADC_DRDY)) dummy = ADCReg1->ADC_LCDR; \
|
||||
if ((isr & AT91C_ADC_EOC0)) dummy = ADCReg1->ADC_CDR0; \
|
||||
if ((isr & AT91C_ADC_EOC1)) dummy = ADCReg1->ADC_CDR1; \
|
||||
if ((isr & AT91C_ADC_EOC2)) dummy = ADCReg1->ADC_CDR2; \
|
||||
if ((isr & AT91C_ADC_EOC3)) dummy = ADCReg1->ADC_CDR3; \
|
||||
if ((isr & AT91C_ADC_EOC4)) dummy = ADCReg1->ADC_CDR4; \
|
||||
if ((isr & AT91C_ADC_EOC5)) dummy = ADCReg1->ADC_CDR5; \
|
||||
if ((isr & AT91C_ADC_EOC6)) dummy = ADCReg1->ADC_CDR6; \
|
||||
if ((isr & AT91C_ADC_EOC7)) dummy = ADCReg1->ADC_CDR7; \
|
||||
(void) dummy; \
|
||||
}
|
||||
#define adc_stop() { \
|
||||
adc_disable(); \
|
||||
adc_clrint(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* We must keep stack usage to a minimum - the default AT91SAM7 isr stack size is very small.
|
||||
* We sacrifice some speed and code size in order to achieve this by accessing the structure
|
||||
* and registers directly rather than through the passed in pointers. This works because the
|
||||
* AT91SAM7 supports only a single ADC device (although with 8 channels).
|
||||
*/
|
||||
static void handleint(void) {
|
||||
uint32_t isr;
|
||||
|
||||
isr = ADCReg1->ADC_SR;
|
||||
|
||||
if (ADCD1.grpp) {
|
||||
|
||||
/* ADC overflow condition, this could happen only if the DMA is unable to read data fast enough.*/
|
||||
if ((isr & AT91C_ADC_GOVRE)) {
|
||||
_adc_isr_error_code(&ADCD1, ADC_ERR_OVERFLOW);
|
||||
|
||||
/* Transfer complete processing.*/
|
||||
} else if ((isr & AT91C_ADC_RXBUFF)) {
|
||||
if (ADCD1.grpp->circular) {
|
||||
/* setup the DMA again */
|
||||
ADCReg1->ADC_RPR = (uint32_t)ADCD1.samples;
|
||||
if (ADCD1.depth <= 1) {
|
||||
ADCReg1->ADC_RCR = ADCD1.grpp->num_channels;
|
||||
ADCReg1->ADC_RNPR = 0;
|
||||
ADCReg1->ADC_RNCR = 0;
|
||||
} else {
|
||||
ADCReg1->ADC_RCR = ADCD1.depth/2 * ADCD1.grpp->num_channels;
|
||||
ADCReg1->ADC_RNPR = (uint32_t)(ADCD1.samples + (ADCD1.depth/2 * ADCD1.grpp->num_channels));
|
||||
ADCReg1->ADC_RNCR = (ADCD1.depth - ADCD1.depth/2) * ADCD1.grpp->num_channels;
|
||||
}
|
||||
ADCReg1->ADC_PTCR = AT91C_PDC_RXTEN; // DMA enabled
|
||||
}
|
||||
_adc_isr_full_code(&ADCD1);
|
||||
|
||||
/* Half transfer processing.*/
|
||||
} else if ((isr & AT91C_ADC_ENDRX)) {
|
||||
// Make sure we get a full complete next time.
|
||||
ADCReg1->ADC_RNPR = 0;
|
||||
ADCReg1->ADC_RNCR = 0;
|
||||
_adc_isr_half_code(&ADCD1);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Spurious interrupt - Make sure it doesn't happen again */
|
||||
adc_disable();
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief ADC interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(ADC_IRQHandler) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
handleint();
|
||||
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level ADC driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_init(void) {
|
||||
/* Turn on ADC in the power management controller */
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_ADC);
|
||||
|
||||
/* Driver object initialization.*/
|
||||
adcObjectInit(&ADCD1);
|
||||
|
||||
ADCReg1->ADC_CR = 0; // 0 or AT91C_ADC_SWRST if you want to do a ADC reset
|
||||
adc_stop();
|
||||
adc_sleep();
|
||||
|
||||
/* Setup interrupt handler */
|
||||
AIC_ConfigureIT(AT91C_ID_ADC,
|
||||
AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91_ADC_IRQ_PRIORITY,
|
||||
ADC_IRQHandler);
|
||||
AIC_EnableIT(AT91C_ID_ADC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_start(ADCDriver *adcp) {
|
||||
|
||||
/* If in stopped state then wake up the ADC */
|
||||
if (adcp->state == ADC_STOP) {
|
||||
|
||||
/* Take it out of sleep mode */
|
||||
/* We could stay in sleep mode provided total conversion rate < 44kHz but we can't guarantee that here */
|
||||
adc_wake();
|
||||
|
||||
/* TODO: We really should perform a conversion here just to ensure that we are out of sleep mode */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the ADC peripheral.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_stop(ADCDriver *adcp) {
|
||||
if (adcp->state != ADC_READY) {
|
||||
adc_stop();
|
||||
adc_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts an ADC conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_start_conversion(ADCDriver *adcp) {
|
||||
uint32_t i;
|
||||
(void) adcp;
|
||||
|
||||
/* Make sure everything is stopped first */
|
||||
adc_stop();
|
||||
|
||||
/* Safety check the trigger value */
|
||||
switch(ADCD1.grpp->trigger & ~ADC_TRIGGER_SOFTWARE) {
|
||||
case ADC_TRIGGER_TIMER:
|
||||
case ADC_TRIGGER_EXTERNAL:
|
||||
break;
|
||||
default:
|
||||
((ADCConversionGroup *)ADCD1.grpp)->trigger = ADC_TRIGGER_SOFTWARE;
|
||||
ADCD1.depth = 1;
|
||||
((ADCConversionGroup *)ADCD1.grpp)->circular = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Count the real number of activated channels in case the user got it wrong */
|
||||
((ADCConversionGroup *)ADCD1.grpp)->num_channels = 0;
|
||||
for(i=1; i < 0x100; i <<= 1) {
|
||||
if ((ADCD1.grpp->channelselects & i))
|
||||
((ADCConversionGroup *)ADCD1.grpp)->num_channels++;
|
||||
}
|
||||
|
||||
/* Set the channels */
|
||||
ADCReg1->ADC_CHER = ADCD1.grpp->channelselects;
|
||||
|
||||
/* Set up the DMA */
|
||||
ADCReg1->ADC_RPR = (uint32_t)ADCD1.samples;
|
||||
if (ADCD1.depth <= 1 || !ADCD1.grpp->circular) {
|
||||
ADCReg1->ADC_RCR = ADCD1.depth * ADCD1.grpp->num_channels;
|
||||
ADCReg1->ADC_RNPR = 0;
|
||||
ADCReg1->ADC_RNCR = 0;
|
||||
} else {
|
||||
ADCReg1->ADC_RCR = ADCD1.depth/2 * ADCD1.grpp->num_channels;
|
||||
ADCReg1->ADC_RNPR = (uint32_t)(ADCD1.samples + (ADCD1.depth/2 * ADCD1.grpp->num_channels));
|
||||
ADCReg1->ADC_RNCR = (ADCD1.depth - ADCD1.depth/2) * ADCD1.grpp->num_channels;
|
||||
}
|
||||
ADCReg1->ADC_PTCR = AT91C_PDC_RXTEN;
|
||||
|
||||
/* Set up interrupts */
|
||||
ADCReg1->ADC_IER = AT91C_ADC_GOVRE | AT91C_ADC_ENDRX | AT91C_ADC_RXBUFF;
|
||||
|
||||
/* Set the trigger */
|
||||
switch(ADCD1.grpp->trigger & ~ADC_TRIGGER_SOFTWARE) {
|
||||
case ADC_TRIGGER_TIMER:
|
||||
// Set up the timer if ADCD1.grpp->frequency != 0
|
||||
if (ADCD1.grpp->frequency) {
|
||||
/* Turn on Timer in the power management controller */
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91_ADC1_TIMERID);
|
||||
|
||||
/* Disable the clock and the interrupts */
|
||||
ADCTimer1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
ADCTimer1->TC_IDR = 0xFFFFFFFF;
|
||||
|
||||
/* Set the Mode of the Timer Counter and calculate the period */
|
||||
i = (MCK/2)/ADCD1.grpp->frequency;
|
||||
if (i < (0x10000<<0)) {
|
||||
ADCTimer1->TC_CMR = (AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_LDRA_RISING |
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV1_CLOCK);
|
||||
} else if (i < (0x10000<<2)) {
|
||||
i >>= 2;
|
||||
ADCTimer1->TC_CMR = (AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_LDRA_RISING |
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV2_CLOCK);
|
||||
} else if (i < (0x10000<<4)) {
|
||||
i >>= 4;
|
||||
ADCTimer1->TC_CMR = (AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_LDRA_RISING |
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV3_CLOCK);
|
||||
} else if (i < (0x10000<<6)) {
|
||||
i >>= 6;
|
||||
ADCTimer1->TC_CMR = (AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_LDRA_RISING |
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV4_CLOCK);
|
||||
} else {
|
||||
i >>= 9;
|
||||
ADCTimer1->TC_CMR = (AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_LDRA_RISING |
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV5_CLOCK);
|
||||
}
|
||||
|
||||
/* RC is the period, RC-RA is the pulse width (in this case = 1) */
|
||||
ADCTimer1->TC_RC = i;
|
||||
ADCTimer1->TC_RA = i - 1;
|
||||
|
||||
/* Start the timer counter */
|
||||
ADCTimer1->TC_CCR = (AT91C_TC_CLKEN |AT91C_TC_SWTRG);
|
||||
}
|
||||
|
||||
ADCReg1->ADC_MR = AT91_ADC1_MAINMODE | AT91C_ADC_SLEEP_NORMAL_MODE | AT91C_ADC_TRGEN_EN | AT91_ADC1_TIMERMODE;
|
||||
break;
|
||||
|
||||
case ADC_TRIGGER_EXTERNAL:
|
||||
/* Make sure the ADTRG pin is set as an input - assume pull-ups etc have already been set */
|
||||
#if (SAM7_PLATFORM == SAM7S64) || (SAM7_PLATFORM == SAM7S128) || (SAM7_PLATFORM == SAM7S256) || (SAM7_PLATFORM == SAM7S512)
|
||||
AT91C_BASE_PIOA->PIO_ODR = AT91C_PA8_ADTRG;
|
||||
#elif (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || (SAM7_PLATFORM == SAM7X512)
|
||||
AT91C_BASE_PIOB->PIO_ODR = AT91C_PB18_ADTRG;
|
||||
#endif
|
||||
ADCReg1->ADC_MR = AT91_ADC1_MAINMODE | AT91C_ADC_SLEEP_NORMAL_MODE | AT91C_ADC_TRGEN_EN | AT91C_ADC_TRGSEL_EXT;
|
||||
break;
|
||||
|
||||
default:
|
||||
ADCReg1->ADC_MR = AT91_ADC1_MAINMODE | AT91C_ADC_SLEEP_NORMAL_MODE | AT91C_ADC_TRGEN_DIS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Manually start a conversion if we need to */
|
||||
if (ADCD1.grpp->trigger & ADC_TRIGGER_SOFTWARE)
|
||||
ADCReg1->ADC_CR = AT91C_ADC_START;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops an ongoing conversion.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void adc_lld_stop_conversion(ADCDriver *adcp) {
|
||||
(void) adcp;
|
||||
adc_stop();
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_ADC */
|
||||
|
||||
/** @} */
|
||||
303
firmware/chibios/os/hal/platforms/AT91SAM7/adc_lld.h
Executable file
303
firmware/chibios/os/hal/platforms/AT91SAM7/adc_lld.h
Executable file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
This file has been contributed by:
|
||||
Andrew Hannam aka inmarket.
|
||||
*/
|
||||
/**
|
||||
* @file AT91SAM7/adc_lld.h
|
||||
* @brief AT91SAM7 ADC subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _ADC_LLD_H_
|
||||
#define _ADC_LLD_H_
|
||||
|
||||
#if HAL_USE_ADC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Trigger Sources
|
||||
* @{
|
||||
*/
|
||||
#define ADC_TRIGGER_SOFTWARE 0x8000 /**< @brief Software Triggering - Can be combined with another value */
|
||||
#define ADC_TRIGGER_TIMER 0x0001 /**< @brief TIO Timer Counter Channel */
|
||||
#define ADC_TRIGGER_EXTERNAL 0x0002 /**< @brief External Trigger */
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @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(ADC_USE_ADC1) || defined(__DOXYGEN__)
|
||||
#define ADC_USE_ADC1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 Timer to use when a periodic conversion is requested.
|
||||
* @details Should be set to 0..2
|
||||
* @note The default is 0
|
||||
*/
|
||||
#if !defined(AT91_ADC1_TIMER) || defined(__DOXYGEN__)
|
||||
#define AT91_ADC1_TIMER 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 Resolution.
|
||||
* @details Either 8 or 10 bits
|
||||
* @note The default is 10 bits.
|
||||
*/
|
||||
#if !defined(AT91_ADC1_RESOLUTION) || defined(__DOXYGEN__)
|
||||
#define AT91_ADC1_RESOLUTION 10
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 Clock
|
||||
* @details Maximum is 5MHz for 10bit or 8MHz for 8bit
|
||||
* @note The default is calculated from AT91_ADC1_RESOLUTION to give the fastest possible ADCClock
|
||||
*/
|
||||
#if !defined(AT91_ADC1_CLOCK) || defined(__DOXYGEN__)
|
||||
#if AT91_ADC1_RESOLUTION == 8
|
||||
#define AT91_ADC1_CLOCK 8000000
|
||||
#else
|
||||
#define AT91_ADC1_CLOCK 5000000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC1 Sample and Hold Time
|
||||
* @details SHTM = RoundUp(ADCClock * SampleHoldTime). Range = RoundUp(ADCClock / 1,666,666) to 15
|
||||
* @note Default corresponds to the minimum sample and hold time (600nS from the datasheet)
|
||||
* @note Increasing the Sample Hold Time increases the ADC input impedance
|
||||
*/
|
||||
#if !defined(AT91_ADC1_SHTM) || defined(__DOXYGEN__)
|
||||
#define AT91_ADC1_SHTM 0
|
||||
#endif
|
||||
#if AT91_ADC1_SHTM < ((AT91_ADC1_CLOCK+1666665)/1666666)
|
||||
#undef AT91_ADC1_SHTM
|
||||
#define AT91_ADC1_SHTM ((AT91_ADC1_CLOCK+1666665)/1666666)
|
||||
#endif
|
||||
#if AT91_ADC1_SHTM > 15
|
||||
#undef AT91_ADC1_SHTM
|
||||
#define AT91_ADC1_SHTM 15
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief ADC interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(AT91_ADC_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define AT91_ADC_IRQ_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(AT91_DMA_REQUIRED)
|
||||
#define AT91_DMA_REQUIRED
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief ADC sample data type.
|
||||
*/
|
||||
#if AT91_ADC1_RESOLUTION == AT91C_ADC_LOWRES_8_BIT
|
||||
typedef uint8_t adcsample_t;
|
||||
#else
|
||||
typedef uint16_t adcsample_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Channels number in a conversion group.
|
||||
*/
|
||||
typedef uint16_t adc_channels_num_t;
|
||||
|
||||
/**
|
||||
* @brief Possible ADC failure causes.
|
||||
* @note Error codes are architecture dependent and should not relied
|
||||
* upon.
|
||||
*/
|
||||
typedef enum {
|
||||
ADC_ERR_OVERFLOW = 0, /**< ADC overflow condition. Something is not working fast enough. */
|
||||
} adcerror_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an ADC driver.
|
||||
*/
|
||||
typedef struct ADCDriver ADCDriver;
|
||||
|
||||
/**
|
||||
* @brief ADC notification callback type.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object triggering the
|
||||
* callback
|
||||
* @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)(ADCDriver *adcp, adcsample_t *buffer, size_t n);
|
||||
|
||||
/**
|
||||
* @brief ADC error callback type.
|
||||
*
|
||||
* @param[in] adcp pointer to the @p ADCDriver object triggering the
|
||||
* callback
|
||||
* @param[in] err ADC error code
|
||||
*/
|
||||
typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
|
||||
|
||||
/**
|
||||
* @brief Conversion group configuration structure.
|
||||
* @details This implementation-dependent structure describes a conversion
|
||||
* operation.
|
||||
* @note The use of this configuration structure requires knowledge of
|
||||
* STM32 ADC cell registers interface, please refer to the STM32
|
||||
* reference manual for details.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Enables the circular buffer mode for the group.
|
||||
*/
|
||||
bool_t circular;
|
||||
/**
|
||||
* @brief Number of the analog channels belonging to the conversion group.
|
||||
*/
|
||||
adc_channels_num_t num_channels;
|
||||
/**
|
||||
* @brief Callback function associated to the group or @p NULL.
|
||||
*/
|
||||
adccallback_t end_cb;
|
||||
/**
|
||||
* @brief Error callback or @p NULL.
|
||||
*/
|
||||
adcerrorcallback_t error_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Select the ADC Channels to read.
|
||||
* @details The number of bits at logic level one in this register must
|
||||
* be equal to the number in the @p num_channels field.
|
||||
*/
|
||||
uint16_t channelselects;
|
||||
/**
|
||||
* @brief Select how to trigger the conversion.
|
||||
*/
|
||||
uint16_t trigger;
|
||||
/**
|
||||
* @brief When in ADC_TRIGGER_TIMER trigger mode - what frequency?
|
||||
*/
|
||||
uint32_t frequency;
|
||||
} ADCConversionGroup;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
} ADCConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an ADC driver.
|
||||
*/
|
||||
struct ADCDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
adcstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const ADCConfig *config;
|
||||
/**
|
||||
* @brief Current samples buffer pointer or @p NULL.
|
||||
*/
|
||||
adcsample_t *samples;
|
||||
/**
|
||||
* @brief Current samples buffer depth or @p 0.
|
||||
*/
|
||||
size_t depth;
|
||||
/**
|
||||
* @brief Current conversion group pointer or @p NULL.
|
||||
*/
|
||||
const ADCConversionGroup *grpp;
|
||||
#if ADC_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
Thread *thread;
|
||||
#endif
|
||||
#if ADC_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the peripheral.
|
||||
*/
|
||||
Mutex mutex;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
Semaphore semaphore;
|
||||
#endif
|
||||
#endif /* ADC_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(ADC_DRIVER_EXT_FIELDS)
|
||||
ADC_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if ADC_USE_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 /* HAL_USE_ADC */
|
||||
|
||||
#endif /* _ADC_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
3352
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7A3.h
Executable file
3352
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7A3.h
Executable file
File diff suppressed because it is too large
Load Diff
2229
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S128.h
Executable file
2229
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S128.h
Executable file
File diff suppressed because it is too large
Load Diff
2229
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S256.h
Executable file
2229
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S256.h
Executable file
File diff suppressed because it is too large
Load Diff
2303
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S512.h
Executable file
2303
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S512.h
Executable file
File diff suppressed because it is too large
Load Diff
2229
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S64.h
Executable file
2229
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7S64.h
Executable file
File diff suppressed because it is too large
Load Diff
2914
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7X128.h
Executable file
2914
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7X128.h
Executable file
File diff suppressed because it is too large
Load Diff
2918
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7X256.h
Executable file
2918
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7X256.h
Executable file
File diff suppressed because it is too large
Load Diff
2984
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7X512.h
Executable file
2984
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/AT91SAM7X512.h
Executable file
File diff suppressed because it is too large
Load Diff
84
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/aic.c
Executable file
84
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/aic.c
Executable 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;
|
||||
}
|
||||
|
||||
78
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/aic.h
Executable file
78
firmware/chibios/os/hal/platforms/AT91SAM7/at91lib/aic.h
Executable 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
|
||||
|
||||
56
firmware/chibios/os/hal/platforms/AT91SAM7/at91sam7.h
Executable file
56
firmware/chibios/os/hal/platforms/AT91SAM7/at91sam7.h
Executable file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#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
|
||||
#define SAM7A3 7
|
||||
|
||||
#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"
|
||||
#elif SAM7_PLATFORM == SAM7A3
|
||||
#include "at91lib/AT91SAM7A3.h"
|
||||
#else
|
||||
#error "SAM7 platform not supported"
|
||||
#endif
|
||||
|
||||
#endif /* _AT91SAM7_H_ */
|
||||
144
firmware/chibios/os/hal/platforms/AT91SAM7/at91sam7_mii.c
Executable file
144
firmware/chibios/os/hal/platforms/AT91SAM7/at91sam7_mii.c
Executable file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file 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 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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void miiInit(void) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets a PHY device.
|
||||
*
|
||||
* @param[in] macp pointer to the @p MACDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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
|
||||
|
||||
/*
|
||||
* 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[in] addr the register address
|
||||
* @return The register value.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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[in] addr the register address
|
||||
* @param[in] value the new register value
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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 /* HAL_USE_MAC */
|
||||
|
||||
/** @} */
|
||||
111
firmware/chibios/os/hal/platforms/AT91SAM7/at91sam7_mii.h
Executable file
111
firmware/chibios/os/hal/platforms/AT91SAM7/at91sam7_mii.h
Executable file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/at91sam7_mii.h
|
||||
* @brief AT91SAM7 low level MII driver header.
|
||||
*
|
||||
* @addtogroup AT91SAM7_MII
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _AT91SAM7_MII_H_
|
||||
#define _AT91SAM7_MII_H_
|
||||
|
||||
#if 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 /* HAL_USE_MAC */
|
||||
|
||||
#endif /* _AT91SAM7_MII_H_ */
|
||||
|
||||
/** @} */
|
||||
235
firmware/chibios/os/hal/platforms/AT91SAM7/ext_lld.c
Executable file
235
firmware/chibios/os/hal/platforms/AT91SAM7/ext_lld.c
Executable file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/ext_lld.c
|
||||
* @brief AT91SAM7 EXT subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup EXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EXTDA driver identifier.
|
||||
*/
|
||||
EXTDriver EXTDA;
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512) || (SAM7_PLATFORM == SAM7A3)
|
||||
/**
|
||||
* @brief EXTDB driver identifier.
|
||||
*/
|
||||
EXTDriver EXTDB;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Handles external interrupts.
|
||||
*
|
||||
* @param[in] extp pointer to the driver that received the interrupt
|
||||
*/
|
||||
static void ext_lld_serveInterrupt(EXTDriver *extp) {
|
||||
uint32_t irqFlags;
|
||||
uint32_t ch;
|
||||
|
||||
chSysLockFromIsr();
|
||||
|
||||
/* Read flags of pending PIO interrupts.*/
|
||||
irqFlags = extp->pio->PIO_ISR;
|
||||
|
||||
/* Call callback function for any pending interrupt.*/
|
||||
for(ch = 0; ch < EXT_MAX_CHANNELS; ch++) {
|
||||
|
||||
/* Check if the channel is activated and if its IRQ flag is set.*/
|
||||
if((extp->config->channels[ch].mode &
|
||||
EXT_CH_MODE_ENABLED & EXT_CH_MODE_EDGES_MASK)
|
||||
&& ((1 << ch) & irqFlags)) {
|
||||
(extp->config->channels[ch].cb)(extp, ch);
|
||||
}
|
||||
}
|
||||
|
||||
chSysUnlockFromIsr();
|
||||
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EXTI[0] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(EXTIA_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
ext_lld_serveInterrupt(&EXTDA);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512) || (SAM7_PLATFORM == SAM7A3)
|
||||
/**
|
||||
* @brief EXTI[1] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(EXTIB_IRQHandler) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
ext_lld_serveInterrupt(&EXTDB);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level EXT driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_init(void) {
|
||||
|
||||
/* Driver initialization.*/
|
||||
extObjectInit(&EXTDA);
|
||||
|
||||
/* Set PIO base addresses.*/
|
||||
EXTDA.pio = AT91C_BASE_PIOA;
|
||||
|
||||
/* Set peripheral IDs.*/
|
||||
EXTDA.pid = AT91C_ID_PIOA;
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512) || (SAM7_PLATFORM == SAM7A3)
|
||||
/* Same for PIOB.*/
|
||||
extObjectInit(&EXTDB);
|
||||
EXTDB.pio = AT91C_BASE_PIOB;
|
||||
EXTDB.pid = AT91C_ID_PIOB;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the EXT peripheral.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_start(EXTDriver *extp) {
|
||||
uint16_t ch;
|
||||
uint32_t ier = 0;
|
||||
const EXTConfig *config = extp->config;
|
||||
|
||||
switch(extp->pid) {
|
||||
case AT91C_ID_PIOA:
|
||||
AIC_ConfigureIT(AT91C_ID_PIOA, SAM7_computeSMR(config->mode,
|
||||
config->priority),
|
||||
EXTIA_IRQHandler);
|
||||
break;
|
||||
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512) || (SAM7_PLATFORM == SAM7A3)
|
||||
case AT91C_ID_PIOB:
|
||||
AIC_ConfigureIT(AT91C_ID_PIOB, SAM7_computeSMR(config->mode,
|
||||
config->priority),
|
||||
EXTIB_IRQHandler);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Enable and Disable channels with respect to config.*/
|
||||
for(ch = 0; ch < EXT_MAX_CHANNELS; ch++) {
|
||||
ier |= (config->channels[ch].mode & EXT_CH_MODE_EDGES_MASK & EXT_CH_MODE_ENABLED ? 1 : 0) << ch;
|
||||
}
|
||||
extp->pio->PIO_IER = ier;
|
||||
extp->pio->PIO_IDR = ~ier;
|
||||
|
||||
/* Enable interrupt on corresponding PIO port in AIC.*/
|
||||
AIC_EnableIT(extp->pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the EXT peripheral.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_stop(EXTDriver *extp) {
|
||||
|
||||
/* Disable interrupt on corresponding PIO port in AIC.*/
|
||||
AIC_DisableIT(extp->pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables an EXT channel.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
* @param[in] channel channel to be enabled
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {
|
||||
|
||||
chDbgCheck((extp->config->channels[channel].cb != NULL),
|
||||
"Call back pointer can not be NULL");
|
||||
|
||||
extp->pio->PIO_IER = (1 << channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables an EXT channel.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
* @param[in] channel channel to be disabled
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) {
|
||||
|
||||
extp->pio->PIO_IDR = (1 << channel);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_EXT */
|
||||
|
||||
/** @} */
|
||||
239
firmware/chibios/os/hal/platforms/AT91SAM7/ext_lld.h
Executable file
239
firmware/chibios/os/hal/platforms/AT91SAM7/ext_lld.h
Executable file
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/ext_lld.h
|
||||
* @brief AT91SAM7 EXT subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup EXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _EXT_LLD_H_
|
||||
#define _EXT_LLD_H_
|
||||
|
||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Pointer to the SAM7 AIC register block.
|
||||
*/
|
||||
#define SAM7_EXT_AIC ((AT91PS_AIC *)AT91C_BASE_AIC)
|
||||
|
||||
/**
|
||||
* @brief Number of channels within one ext driver.
|
||||
*/
|
||||
#define EXT_MAX_CHANNELS 32
|
||||
|
||||
/**
|
||||
* @brief Mask of priority bits in interrupt mode register.
|
||||
*/
|
||||
#define SAM7_EXT_PRIORITY_MASK 0x00000007
|
||||
|
||||
/**
|
||||
* @brief Shifter for priority bits in interrupt mode register.
|
||||
*/
|
||||
#define SAM7_EXT_PRIORITY_SHIFTER 0
|
||||
|
||||
/**
|
||||
* @brief Shifter for mode bits in interrupt mode register.
|
||||
*/
|
||||
#define SAM7_EXT_MODE_SHIFTER 5
|
||||
|
||||
/*
|
||||
* On the SAM7 architecture, a single channel can only be enables or disabled
|
||||
* Hence, undefine the other channel mode constants
|
||||
*/
|
||||
#ifdef EXT_CH_MODE_RISING_EDGE
|
||||
#undef EXT_CH_MODE_RISING_EDGE
|
||||
#endif
|
||||
|
||||
#ifdef EXT_CH_MODE_FALLING_EDGE
|
||||
#undef EXT_CH_MODE_FALLING_EDGE
|
||||
#endif
|
||||
|
||||
#ifdef EXT_CH_MODE_BOTH_EDGES
|
||||
#undef EXT_CH_MODE_BOTH_EDGES
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name EXT channels mode
|
||||
* @{
|
||||
*/
|
||||
#define EXT_CH_MODE_ENABLED 1 /**< @brief Channel is enabled. */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EXT drivers mode
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Mask for modes.
|
||||
*/
|
||||
#define SAM7_EXT_MODE_MASK AT91C_AIC_SRCTYPE
|
||||
/**
|
||||
* @brief Falling edge callback.
|
||||
*/
|
||||
#define SAM7_EXT_MODE_FALLING_EDGE AT91C_AIC_SRCTYPE_EXT_NEGATIVE_EDGE
|
||||
/**
|
||||
* @brief Rising edge callback.
|
||||
*/
|
||||
#define SAM7_EXT_MODE_RISING_EDGE AT91C_AIC_SRCTYPE_POSITIVE_EDGE
|
||||
/**
|
||||
* @brief High-level callback.
|
||||
*/
|
||||
#define SAM7_EXT_MODE_HIGH_LEVEL AT91C_AIC_SRCTYPE_HIGH_LEVEL
|
||||
/**
|
||||
* @brief Low-level callback.
|
||||
*/
|
||||
#define SAM7_EXT_MODE_LOW_LEVEL AT91C_AIC_SRCTYPE_EXT_LOW_LEVEL
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name EXT drivers priorities
|
||||
* @{
|
||||
*/
|
||||
#define SAM7_EXT_PRIOR_HIGHEST AT91C_AIC_PRIOR_HIGHEST
|
||||
#define SAM7_EXT_PRIOR_LOWEST AT91C_AIC_PRIOR_LOWEST
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EXT channel identifier.
|
||||
*/
|
||||
typedef uint32_t expchannel_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an EXT generic notification callback.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXPDriver object triggering the
|
||||
* callback
|
||||
*/
|
||||
typedef void (*extcallback_t)(EXTDriver *extp, expchannel_t channel);
|
||||
|
||||
/**
|
||||
* @brief Channel configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel mode.
|
||||
*/
|
||||
uint32_t mode;
|
||||
/**
|
||||
* @brief Channel callback.
|
||||
*/
|
||||
extcallback_t cb;
|
||||
} EXTChannelConfig;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel configurations.
|
||||
*/
|
||||
EXTChannelConfig channels[EXT_MAX_CHANNELS];
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief interrupt mode.
|
||||
*/
|
||||
uint32_t mode;
|
||||
/**
|
||||
* @brief interrupt priority.
|
||||
*/
|
||||
uint32_t priority;
|
||||
} EXTConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an EXT driver.
|
||||
*/
|
||||
struct EXTDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
extstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const EXTConfig *config;
|
||||
/* End of the mandatory fields.*/
|
||||
|
||||
/**
|
||||
* @brief Pointer to the corresponding PIO registers block.
|
||||
*/
|
||||
AT91PS_PIO pio;
|
||||
/**
|
||||
* @brief peripheral ID of the corresponding PIO block.
|
||||
*/
|
||||
uint32_t pid;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Computes the content for the interrupt source mode register.
|
||||
*/
|
||||
#define SAM7_computeSMR(mode, prio) ( \
|
||||
((mode & SAM7_EXT_MODE_MASK) << SAM7_EXT_MODE_SHIFTER) | \
|
||||
((prio & SAM7_EXT_PRIORITY_MASK) << SAM7_EXT_PRIORITY_SHIFTER) \
|
||||
)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern EXTDriver EXTDA;
|
||||
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512) || (SAM7_PLATFORM == SAM7A3)
|
||||
extern EXTDriver EXTDB;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void ext_lld_init(void);
|
||||
void ext_lld_start(EXTDriver *extp);
|
||||
void ext_lld_stop(EXTDriver *extp);
|
||||
void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel);
|
||||
void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_EXT */
|
||||
|
||||
#endif /* _EXT_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
451
firmware/chibios/os/hal/platforms/AT91SAM7/gpt_lld.c
Executable file
451
firmware/chibios/os/hal/platforms/AT91SAM7/gpt_lld.c
Executable file
@@ -0,0 +1,451 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/gpt_lld.c
|
||||
* @brief AT91SAM7 GPT subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup GPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_GPT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPTD1 driver identifier.
|
||||
* @note The driver GPTD1 allocates the complex timer TC0 when enabled.
|
||||
*/
|
||||
#if AT91_GPT_USE_TC0 || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD1;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD2 driver identifier.
|
||||
* @note The driver GPTD2 allocates the timer TC1 when enabled.
|
||||
*/
|
||||
#if AT91_GPT_USE_TC1 || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD2;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD3 driver identifier.
|
||||
* @note The driver GPTD3 allocates the timer TC2 when enabled.
|
||||
*/
|
||||
#if AT91_GPT_USE_TC2 || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD3;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Shared IRQ handler.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
*/
|
||||
static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
|
||||
// Read the status to clear the interrupts
|
||||
{ uint32_t isr = gptp->tc->TC_SR; (void) isr; }
|
||||
|
||||
// Do the callback
|
||||
gptp->config->callback(gptp);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if AT91_GPT_USE_TC0
|
||||
/**
|
||||
* @brief TC1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(TC0_IRQHandler) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
gpt_lld_serve_interrupt(&GPTD1);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* AT91_GPT_USE_TC0 */
|
||||
|
||||
#if AT91_GPT_USE_TC1
|
||||
/**
|
||||
* @brief TC1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(TC1_IRQHandler) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
gpt_lld_serve_interrupt(&GPTD2);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* AT91_GPT_USE_TC1 */
|
||||
|
||||
#if AT91_GPT_USE_TC2
|
||||
/**
|
||||
* @brief TC1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(TC2_IRQHandler) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
gpt_lld_serve_interrupt(&GPTD2);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
}
|
||||
#endif /* AT91_GPT_USE_TC2 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level GPT driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_init(void) {
|
||||
|
||||
#if AT91_GPT_USE_TC0
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0); // Turn on the power
|
||||
GPTD1.tc = AT91C_BASE_TC0;
|
||||
gptObjectInit(&GPTD1);
|
||||
gpt_lld_stop(&GPTD1); // Make sure it is disabled
|
||||
AIC_ConfigureIT(AT91C_ID_TC0, AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91_GPT_TC0_IRQ_PRIORITY, TC0_IRQHandler);
|
||||
AIC_EnableIT(AT91C_ID_TC0);
|
||||
#endif
|
||||
|
||||
#if AT91_GPT_USE_TC1
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); // Turn on the power
|
||||
GPTD2.tc = AT91C_BASE_TC1;
|
||||
gptObjectInit(&GPTD2);
|
||||
gpt_lld_stop(&GPTD2); // Make sure it is disabled
|
||||
AIC_ConfigureIT(AT91C_ID_TC1, AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91_GPT_TC1_IRQ_PRIORITY, TC1_IRQHandler);
|
||||
AIC_EnableIT(AT91C_ID_TC1);
|
||||
#endif
|
||||
|
||||
#if AT91_GPT_USE_TC2
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC2); // Turn on the power
|
||||
GPTD3.tc = AT91C_BASE_TC2;
|
||||
gptObjectInit(&GPTD3);
|
||||
gpt_lld_stop(&GPTD3); // Make sure it is disabled
|
||||
AIC_ConfigureIT(AT91C_ID_TC2, AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91_GPT_TC2_IRQ_PRIORITY, TC2_IRQHandler);
|
||||
AIC_EnableIT(AT91C_ID_TC2);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the GPT peripheral.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_start(GPTDriver *gptp) {
|
||||
uint32_t cmr, bmr;
|
||||
|
||||
bmr = *AT91C_TCB_BMR;
|
||||
cmr = (AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET |
|
||||
AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO);
|
||||
|
||||
// Calculate clock
|
||||
switch(gptp->config->clocksource) {
|
||||
case GPT_CLOCK_MCLK:
|
||||
switch(gptp->config->frequency) {
|
||||
case MCK/2: cmr |= AT91C_TC_CLKS_TIMER_DIV1_CLOCK; break;
|
||||
case MCK/8: cmr |= AT91C_TC_CLKS_TIMER_DIV2_CLOCK; break;
|
||||
case MCK/32: cmr |= AT91C_TC_CLKS_TIMER_DIV3_CLOCK; break;
|
||||
case MCK/128: cmr |= AT91C_TC_CLKS_TIMER_DIV4_CLOCK; break;
|
||||
case MCK/1024: cmr |= AT91C_TC_CLKS_TIMER_DIV5_CLOCK; break;
|
||||
default:
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #1", "invalid frequency");
|
||||
cmr |= AT91C_TC_CLKS_TIMER_DIV5_CLOCK;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GPT_CLOCK_FREQUENCY:
|
||||
/* The mode and period will be calculated when the timer is started */
|
||||
cmr |= AT91C_TC_CLKS_TIMER_DIV5_CLOCK;
|
||||
break;
|
||||
case GPT_CLOCK_RE_TCLK0:
|
||||
case GPT_CLOCK_FE_TCLK0:
|
||||
if ((gptp->config->clocksource & 1)) cmr |= AT91C_TC_CLKI;
|
||||
cmr |= AT91C_TC_CLKS_XC0;
|
||||
#if AT91_GPT_USE_TC0
|
||||
if (gptp == &GPTD1) bmr = (bmr & ~AT91C_TCB_TC0XC0S) | AT91C_TCB_TC0XC0S_TCLK0;
|
||||
#endif
|
||||
break;
|
||||
case GPT_CLOCK_RE_TCLK1:
|
||||
case GPT_CLOCK_FE_TCLK1:
|
||||
if ((gptp->config->clocksource & 1)) cmr |= AT91C_TC_CLKI;
|
||||
cmr |= AT91C_TC_CLKS_XC1;
|
||||
#if AT91_GPT_USE_TC1
|
||||
if (gptp == &GPTD2) bmr = (bmr & ~AT91C_TCB_TC1XC1S) | AT91C_TCB_TC1XC1S_TCLK1;
|
||||
#endif
|
||||
break;
|
||||
case GPT_CLOCK_RE_TCLK2:
|
||||
case GPT_CLOCK_FE_TCLK2:
|
||||
if ((gptp->config->clocksource & 1)) cmr |= AT91C_TC_CLKI;
|
||||
cmr |= AT91C_TC_CLKS_XC2;
|
||||
#if AT91_GPT_USE_TC2
|
||||
if (gptp == &GPTD3) bmr = (bmr & ~AT91C_TCB_TC2XC2S) | AT91C_TCB_TC2XC2S_TCLK2;
|
||||
#endif
|
||||
break;
|
||||
case GPT_CLOCK_RE_TC0:
|
||||
case GPT_CLOCK_FE_TC0:
|
||||
if ((gptp->config->clocksource & 1)) cmr |= AT91C_TC_CLKI;
|
||||
#if AT91_GPT_USE_TC0
|
||||
if (gptp == &GPTD1) {
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #2", "invalid clock");
|
||||
cmr |= AT91C_TC_CLKS_XC0;
|
||||
bmr = (bmr & ~AT91C_TCB_TC0XC0S) | AT91C_TCB_TC0XC0S_NONE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if AT91_GPT_USE_TC1
|
||||
if (gptp == &GPTD2) {
|
||||
cmr |= AT91C_TC_CLKS_XC1;
|
||||
bmr = (bmr & ~AT91C_TCB_TC1XC1S) | AT91C_TCB_TC1XC1S_TIOA0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if AT91_GPT_USE_TC2
|
||||
if (gptp == &GPTD3) {
|
||||
cmr |= AT91C_TC_CLKS_XC2;
|
||||
bmr = (bmr & ~AT91C_TCB_TC2XC2S) | AT91C_TCB_TC2XC2S_TIOA0;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #3", "invalid GPT device");
|
||||
cmr |= AT91C_TC_CLKS_TIMER_DIV5_CLOCK;
|
||||
break;
|
||||
case GPT_CLOCK_RE_TC1:
|
||||
case GPT_CLOCK_FE_TC1:
|
||||
if ((gptp->config->clocksource & 1)) cmr |= AT91C_TC_CLKI;
|
||||
#if AT91_GPT_USE_TC0
|
||||
if (gptp == &GPTD1) {
|
||||
cmr |= AT91C_TC_CLKS_XC0;
|
||||
bmr = (bmr & ~AT91C_TCB_TC0XC0S) | AT91C_TCB_TC0XC0S_TIOA1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if AT91_GPT_USE_TC1
|
||||
if (gptp == &GPTD2) {
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #4", "invalid clock");
|
||||
cmr |= AT91C_TC_CLKS_XC1;
|
||||
bmr = (bmr & ~AT91C_TCB_TC1XC1S) | AT91C_TCB_TC1XC1S_NONE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if AT91_GPT_USE_TC2
|
||||
if (gptp == &GPTD3) {
|
||||
cmr |= AT91C_TC_CLKS_XC2;
|
||||
bmr = (bmr & ~AT91C_TCB_TC2XC2S) | AT91C_TCB_TC2XC2S_TIOA1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #5", "invalid GPT device");
|
||||
cmr |= AT91C_TC_CLKS_TIMER_DIV5_CLOCK;
|
||||
break;
|
||||
case GPT_CLOCK_RE_TC2:
|
||||
case GPT_CLOCK_FE_TC2:
|
||||
if ((gptp->config->clocksource & 1)) cmr |= AT91C_TC_CLKI;
|
||||
#if AT91_GPT_USE_TC0
|
||||
if (gptp == &GPTD1) {
|
||||
cmr |= AT91C_TC_CLKS_XC0;
|
||||
bmr = (bmr & ~AT91C_TCB_TC0XC0S) | AT91C_TCB_TC0XC0S_TIOA2;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if AT91_GPT_USE_TC1
|
||||
if (gptp == &GPTD2) {
|
||||
cmr |= AT91C_TC_CLKS_XC1;
|
||||
bmr = (bmr & ~AT91C_TCB_TC1XC1S) | AT91C_TCB_TC1XC1S_TIOA2;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if AT91_GPT_USE_TC2
|
||||
if (gptp == &GPTD3) {
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #6", "invalid clock");
|
||||
cmr |= AT91C_TC_CLKS_XC2;
|
||||
bmr = (bmr & ~AT91C_TCB_TC2XC2S) | AT91C_TCB_TC2XC2S_NONE;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #7", "invalid GPT device");
|
||||
cmr |= AT91C_TC_CLKS_TIMER_DIV5_CLOCK;
|
||||
break;
|
||||
default:
|
||||
chDbgAssert(TRUE, "gpt_lld_start(), #8", "invalid clock");
|
||||
cmr |= AT91C_TC_CLKS_TIMER_DIV5_CLOCK;
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate clock gating
|
||||
chDbgAssert(gptp->config->clockgate == GPT_GATE_NONE || gptp->config->clockgate == GPT_GATE_TCLK0
|
||||
|| gptp->config->clockgate == GPT_GATE_TCLK1 || gptp->config->clockgate == GPT_GATE_TCLK2
|
||||
, "gpt_lld_start(), #9", "invalid clockgate");
|
||||
cmr |= ((uint32_t)(gptp->config->clockgate & 0x03)) << 4; // special magic numbers here
|
||||
|
||||
// Calculate triggers
|
||||
chDbgAssert(gptp->config->trigger == GPT_TRIGGER_NONE
|
||||
|| gptp->config->trigger == GPT_TRIGGER_RE_TIOB || gptp->config->trigger == GPT_TRIGGER_FE_TIOB || gptp->config->trigger == GPT_TRIGGER_BE_TIOB
|
||||
|| gptp->config->trigger == GPT_TRIGGER_RE_TCLK0 || gptp->config->trigger == GPT_TRIGGER_FE_TCLK0 || gptp->config->trigger == GPT_TRIGGER_BE_TCLK0
|
||||
|| gptp->config->trigger == GPT_TRIGGER_RE_TCLK1 || gptp->config->trigger == GPT_TRIGGER_FE_TCLK1 || gptp->config->trigger == GPT_TRIGGER_BE_TCLK1
|
||||
|| gptp->config->trigger == GPT_TRIGGER_RE_TCLK2 || gptp->config->trigger == GPT_TRIGGER_FE_TCLK2 || gptp->config->trigger == GPT_TRIGGER_BE_TCLK2
|
||||
, "gpt_lld_start(), #10", "invalid trigger");
|
||||
cmr |= ((uint32_t)(gptp->config->trigger & 0x03)) << 10; // special magic numbers here
|
||||
cmr |= ((uint32_t)(gptp->config->trigger & 0x30)) << (8-4); // special magic numbers here
|
||||
|
||||
/* Set everything up but disabled */
|
||||
gptp->tc->TC_CCR = AT91C_TC_CLKDIS;
|
||||
gptp->tc->TC_IDR = 0xFFFFFFFF;
|
||||
gptp->tc->TC_CMR = cmr;
|
||||
gptp->tc->TC_RC = 65535;
|
||||
gptp->tc->TC_RA = 32768;
|
||||
*AT91C_TCB_BMR = bmr;
|
||||
cmr = gptp->tc->TC_SR; // Clear any pending interrupts
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the GPT peripheral.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_stop(GPTDriver *gptp) {
|
||||
gptp->tc->TC_CCR = AT91C_TC_CLKDIS;
|
||||
gptp->tc->TC_IDR = 0xFFFFFFFF;
|
||||
{ uint32_t isr = gptp->tc->TC_SR; (void)isr; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the timer in continuous mode.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
* @param[in] interval period in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
|
||||
gpt_lld_change_interval(gptp, interval);
|
||||
if (gptp->state == GPT_ONESHOT)
|
||||
gptp->tc->TC_CMR |= AT91C_TC_CPCDIS;
|
||||
else
|
||||
gptp->tc->TC_CMR &= ~AT91C_TC_CPCDIS;
|
||||
gptp->tc->TC_CCR = AT91C_TC_CLKEN|AT91C_TC_SWTRG;
|
||||
if (gptp->config->callback)
|
||||
gptp->tc->TC_IER = AT91C_TC_CPCS|AT91C_TC_COVFS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the timer.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_stop_timer(GPTDriver *gptp) {
|
||||
gptp->tc->TC_CCR = AT91C_TC_CLKDIS;
|
||||
gptp->tc->TC_IDR = 0xFFFFFFFF;
|
||||
{ uint32_t isr = gptp->tc->TC_SR; (void)isr; }
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes the interval of GPT peripheral.
|
||||
* @details This function changes the interval of a running GPT unit.
|
||||
* @pre The GPT unit must have been activated using @p gptStart().
|
||||
* @pre The GPT unit must have been running in continuous mode using
|
||||
* @p gptStartContinuous().
|
||||
* @post The GPT unit interval is changed to the new value.
|
||||
* @note The function has effect at the next cycle start.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
* @param[in] interval new cycle time in timer ticks
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_change_interval(GPTDriver *gptp, gptcnt_t interval) {
|
||||
if (gptp->config->clocksource == GPT_CLOCK_FREQUENCY) {
|
||||
uint32_t rc, cmr;
|
||||
|
||||
// Reset the timer to the (possibly) new frequency value
|
||||
rc = (MCK/2)/gptp->config->frequency;
|
||||
if (rc < (0x10000<<0)) {
|
||||
cmr = AT91C_TC_CLKS_TIMER_DIV1_CLOCK;
|
||||
} else if (rc < (0x10000<<2)) {
|
||||
rc >>= 2;
|
||||
cmr = AT91C_TC_CLKS_TIMER_DIV2_CLOCK;
|
||||
} else if (rc < (0x10000<<4)) {
|
||||
rc >>= 4;
|
||||
cmr = AT91C_TC_CLKS_TIMER_DIV3_CLOCK;
|
||||
} else if (rc < (0x10000<<6)) {
|
||||
rc >>= 6;
|
||||
cmr = AT91C_TC_CLKS_TIMER_DIV4_CLOCK;
|
||||
} else {
|
||||
rc >>= 9;
|
||||
cmr = AT91C_TC_CLKS_TIMER_DIV5_CLOCK;
|
||||
}
|
||||
gptp->tc->TC_CMR = (gptp->tc->TC_CMR & ~AT91C_TC_CLKS) | cmr;
|
||||
gptp->tc->TC_RC = rc;
|
||||
gptp->tc->TC_RA = rc/2;
|
||||
} else {
|
||||
gptp->tc->TC_RC = interval;
|
||||
gptp->tc->TC_RA = interval/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the timer in one shot mode and waits for completion.
|
||||
* @details This function specifically polls the timer waiting for completion
|
||||
* in order to not have extra delays caused by interrupt servicing,
|
||||
* this function is only recommended for short delays.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
* @param[in] interval time interval in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
|
||||
|
||||
gpt_lld_change_interval(gptp, interval);
|
||||
gptp->tc->TC_CMR |= AT91C_TC_CPCDIS;
|
||||
gptp->tc->TC_CCR = AT91C_TC_CLKEN|AT91C_TC_SWTRG;
|
||||
while (!(gptp->tc->TC_SR & (AT91C_TC_CPCS|AT91C_TC_COVFS)));
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_GPT */
|
||||
|
||||
/** @} */
|
||||
230
firmware/chibios/os/hal/platforms/AT91SAM7/gpt_lld.h
Executable file
230
firmware/chibios/os/hal/platforms/AT91SAM7/gpt_lld.h
Executable file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/gpt_lld.h
|
||||
* @brief AT91SAM7 GPT subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup GPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GPT_LLD_H_
|
||||
#define _GPT_LLD_H_
|
||||
|
||||
#if HAL_USE_GPT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief GPTD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPTD1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(AT91_GPT_USE_TC0) || defined(__DOXYGEN__)
|
||||
#define AT91_GPT_USE_TC0 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPTD2 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(AT91_GPT_USE_TC1) || defined(__DOXYGEN__)
|
||||
#define AT91_GPT_USE_TC1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPTD3 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(AT91_GPT_USE_TC2) || defined(__DOXYGEN__)
|
||||
#define AT91_GPT_USE_TC3 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(AT91_GPT_TC0_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define AT91_GPT_TC0_IRQ_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD2 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(AT91_GPT_TC1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define AT91_GPT_TC1_IRQ_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPTD3 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(AT91_GPT_TC2_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define AT91_GPT_TC2_IRQ_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !AT91_GPT_USE_TC0 && !AT91_GPT_USE_TC1 && !AT91_GPT_USE_TC2
|
||||
#error "GPT driver activated but no TC peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPT frequency type.
|
||||
*/
|
||||
typedef uint32_t gptfreq_t;
|
||||
|
||||
/**
|
||||
* @brief GPT counter type.
|
||||
*/
|
||||
typedef uint16_t gptcnt_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
gptfreq_t frequency;
|
||||
/**
|
||||
* @brief Timer callback pointer.
|
||||
* @note This callback is invoked on GPT counter events.
|
||||
*/
|
||||
gptcallback_t callback;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Timer Clock Source.
|
||||
*/
|
||||
uint8_t clocksource;
|
||||
#define GPT_CLOCK_MCLK 0 // @< Internal clock. frequency must = MCLK/2, MCLK/8, MCLK/32, MCLK/128 or MCLK/1024
|
||||
#define GPT_CLOCK_FREQUENCY 1 // @< Internal clock. interval is ignored. frequency determines rate
|
||||
#define GPT_CLOCK_RE_TCLK0 2 // @< External TCLK0. Rising Edge
|
||||
#define GPT_CLOCK_FE_TCLK0 3 // @< External TCLK0. Falling Edge
|
||||
#define GPT_CLOCK_RE_TCLK1 4 // @< External TCLK1. Rising Edge
|
||||
#define GPT_CLOCK_FE_TCLK1 5 // @< External TCLK1. Falling Edge
|
||||
#define GPT_CLOCK_RE_TCLK2 6 // @< External TCLK2. Rising Edge
|
||||
#define GPT_CLOCK_FE_TCLK2 7 // @< External TCLK2. Falling Edge
|
||||
#define GPT_CLOCK_RE_TC0 8 // @< TC0 output. Rising Edge. Do not use on TC0
|
||||
#define GPT_CLOCK_FE_TC0 9 // @< TC0 output. Falling Edge. Do not use on TC0
|
||||
#define GPT_CLOCK_RE_TC1 10 // @< TC1 output. Rising Edge. Do not use on TC1
|
||||
#define GPT_CLOCK_FE_TC1 11 // @< TC1 output. Falling Edge. Do not use on TC1
|
||||
#define GPT_CLOCK_RE_TC2 12 // @< TC2 output. Rising Edge. Do not use on TC2
|
||||
#define GPT_CLOCK_FE_TC2 13 // @< TC2 output. Falling Edge. Do not use on TC2
|
||||
uint8_t clockgate;
|
||||
#define GPT_GATE_NONE 0 // @< Clock gating off
|
||||
#define GPT_GATE_TCLK0 1 // @< Clock on TCLK0 active high signal. If using this on TC0 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_GATE_TCLK1 2 // @< Clock on TCLK1 active high signal. If using this on TC1 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_GATE_TCLK2 3 // @< Clock on TCLK2 active high signal. If using this on TC2 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
uint8_t trigger;
|
||||
#define GPT_TRIGGER_NONE 0x00 // @< Start immediately
|
||||
#define GPT_TRIGGER_RE_TIOB 0x10 // @< Start on TIOB signal. Rising Edge.
|
||||
#define GPT_TRIGGER_FE_TIOB 0x20 // @< Start on TIOB signal. Falling Edge.
|
||||
#define GPT_TRIGGER_BE_TIOB 0x30 // @< Start on TIOB signal. Both Edges.
|
||||
#define GPT_TRIGGER_RE_TCLK0 0x11 // @< Start on TCLK0 signal. Rising Edge. If using this on TC0 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_FE_TCLK0 0x21 // @< Start on TCLK0 signal. Falling Edge. If using this on TC0 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_BE_TCLK0 0x31 // @< Start on TCLK0 signal. Both Edges. If using this on TC0 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_RE_TCLK1 0x12 // @< Start on TCLK1 signal. Rising Edge. If using this on TC1 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_FE_TCLK1 0x22 // @< Start on TCLK1 signal. Falling Edge. If using this on TC1 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_BE_TCLK1 0x32 // @< Start on TCLK1 signal. Both Edges. If using this on TC1 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_RE_TCLK2 0x13 // @< Start on TCLK2 signal. Rising Edge. If using this on TC2 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_FE_TCLK2 0x23 // @< Start on TCLK2 signal. Falling Edge. If using this on TC2 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
#define GPT_TRIGGER_BE_TCLK2 0x33 // @< Start on TCLK2 signal. Both Edges. If using this on TC2 with GPT_CLOCK_xx_TIMx, the TIMx output will be used instead.
|
||||
} GPTConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a GPT driver.
|
||||
*/
|
||||
struct GPTDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
gptstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const GPTConfig *config;
|
||||
#if defined(GPT_DRIVER_EXT_FIELDS)
|
||||
GPT_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the TCx registers block.
|
||||
*/
|
||||
AT91S_TC *tc;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if AT91_GPT_USE_TC0 && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD1;
|
||||
#endif
|
||||
|
||||
#if AT91_GPT_USE_TC1 && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD2;
|
||||
#endif
|
||||
|
||||
#if AT91_GPT_USE_TC2 && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD3;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void gpt_lld_init(void);
|
||||
void gpt_lld_start(GPTDriver *gptp);
|
||||
void gpt_lld_stop(GPTDriver *gptp);
|
||||
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
|
||||
void gpt_lld_stop_timer(GPTDriver *gptp);
|
||||
void gpt_lld_change_interval(GPTDriver *gptp, gptcnt_t interval);
|
||||
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_GPT */
|
||||
|
||||
#endif /* _GPT_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
129
firmware/chibios/os/hal/platforms/AT91SAM7/hal_lld.c
Executable file
129
firmware/chibios/os/hal/platforms/AT91SAM7/hal_lld.c
Executable file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/hal_lld.c
|
||||
* @brief AT91SAM7 HAL subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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.
|
||||
* @note This function must be invoked only after the system reset.
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
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))
|
||||
;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
90
firmware/chibios/os/hal/platforms/AT91SAM7/hal_lld.h
Executable file
90
firmware/chibios/os/hal/platforms/AT91SAM7/hal_lld.h
Executable file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/hal_lld.h
|
||||
* @brief AT91SAM7 HAL subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HAL_LLD_H_
|
||||
#define _HAL_LLD_H_
|
||||
|
||||
#include "at91sam7.h"
|
||||
#include "at91lib/aic.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Defines the support for realtime counters in the HAL.
|
||||
*/
|
||||
#define HAL_IMPLEMENTS_COUNTERS FALSE
|
||||
|
||||
/**
|
||||
* @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_ */
|
||||
|
||||
/** @} */
|
||||
464
firmware/chibios/os/hal/platforms/AT91SAM7/i2c_lld.c
Executable file
464
firmware/chibios/os/hal/platforms/AT91SAM7/i2c_lld.c
Executable file
@@ -0,0 +1,464 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
|
||||
aka barthess.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/i2c_lld.c
|
||||
* @brief AT91SAM7 I2C subsystem low level driver source.
|
||||
* @note I2C peripheral interrupts on AT91SAM7 platform must have highest
|
||||
* priority in system.
|
||||
*
|
||||
* @addtogroup I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief I2C1 driver identifier.*/
|
||||
#if SAM7_I2C_USE_I2C1 || defined(__DOXYGEN__)
|
||||
I2CDriver I2CD1;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Wakes up the waiting thread.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
* @param[in] msg wakeup message
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define wakeup_isr(i2cp, msg) { \
|
||||
chSysLockFromIsr(); \
|
||||
if ((i2cp)->thread != NULL) { \
|
||||
Thread *tp = (i2cp)->thread; \
|
||||
(i2cp)->thread = NULL; \
|
||||
tp->p_u.rdymsg = (msg); \
|
||||
chSchReadyI(tp); \
|
||||
} \
|
||||
chSysUnlockFromIsr(); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void _i2c_lld_serve_rx_interrupt(I2CDriver *i2cp){
|
||||
if (i2cp->rxbytes == 1)
|
||||
AT91C_BASE_TWI->TWI_CR |= AT91C_TWI_STOP;
|
||||
|
||||
*(i2cp->rxbuf) = AT91C_BASE_TWI->TWI_RHR;
|
||||
i2cp->rxbuf++;
|
||||
i2cp->rxbytes--;
|
||||
if (i2cp->rxbytes == 0){
|
||||
AT91C_BASE_TWI->TWI_IDR = AT91C_TWI_RXRDY;
|
||||
AT91C_BASE_TWI->TWI_IER = AT91C_TWI_TXCOMP;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function.
|
||||
* @note During write operation you do not need to set STOP manually.
|
||||
* It sets automatically when THR and shift registers becomes empty.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void _i2c_lld_serve_tx_interrupt(I2CDriver *i2cp){
|
||||
|
||||
if (i2cp->txbytes == 0){
|
||||
AT91C_BASE_TWI->TWI_IDR = AT91C_TWI_TXRDY;
|
||||
AT91C_BASE_TWI->TWI_IER = AT91C_TWI_TXCOMP;
|
||||
}
|
||||
else{
|
||||
AT91C_BASE_TWI->TWI_THR = *(i2cp->txbuf);
|
||||
i2cp->txbuf++;
|
||||
i2cp->txbytes--;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C shared ISR code.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void i2c_lld_serve_interrupt(I2CDriver *i2cp) {
|
||||
|
||||
uint32_t sr;
|
||||
sr = AT91C_BASE_TWI->TWI_SR;
|
||||
/* this masking doing in official Atmel driver. Is it needed ??? */
|
||||
sr &= AT91C_BASE_TWI->TWI_IMR;
|
||||
|
||||
if (sr & AT91C_TWI_NACK){
|
||||
i2cp->errors |= I2CD_ACK_FAILURE;
|
||||
wakeup_isr(i2cp, RDY_RESET);
|
||||
return;
|
||||
}
|
||||
if (sr & AT91C_TWI_RXRDY){
|
||||
_i2c_lld_serve_rx_interrupt(i2cp);
|
||||
}
|
||||
else if (sr & AT91C_TWI_TXRDY){
|
||||
_i2c_lld_serve_tx_interrupt(i2cp);
|
||||
}
|
||||
else if (sr & AT91C_TWI_TXCOMP){
|
||||
AT91C_BASE_TWI->TWI_IDR = AT91C_TWI_TXCOMP;
|
||||
wakeup_isr(i2cp, RDY_OK);
|
||||
}
|
||||
else
|
||||
chDbgPanic("Invalid value");
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SAM7_I2C_USE_I2C1 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief I2C1 event interrupt handler.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
CH_IRQ_HANDLER(TWI_IRQHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
i2c_lld_serve_interrupt(&I2CD1);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* STM32_I2C_USE_I2C1 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level I2C driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void i2c_lld_init(void) {
|
||||
|
||||
#if SAM7_I2C_USE_I2C1
|
||||
i2cObjectInit(&I2CD1);
|
||||
I2CD1.thread = NULL;
|
||||
I2CD1.txbuf = NULL;
|
||||
I2CD1.rxbuf = NULL;
|
||||
I2CD1.txbytes = 0;
|
||||
I2CD1.rxbytes = 0;
|
||||
|
||||
#if SAM7_PLATFORM == SAM7S512 || SAM7_PLATFORM == SAM7S256 || SAM7_PLATFORM == SAM7S128 || SAM7_PLATFORM == SAM7S64
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_MDER = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PA3_TWD | AT91C_PA4_TWCK;
|
||||
#elif SAM7_PLATFORM == SAM7X512 || SAM7_PLATFORM == SAM7X256 || SAM7_PLATFORM == SAM7X128
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA10_TWD | AT91C_PA11_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA10_TWD | AT91C_PA11_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_MDER = AT91C_PA10_TWD | AT91C_PA11_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PA10_TWD | AT91C_PA11_TWCK;
|
||||
#elif SAM7_PLATFORM == SAM7A3
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA0_TWD | AT91C_PA1_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA0_TWD | AT91C_PA1_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_MDER = AT91C_PA0_TWD | AT91C_PA1_TWCK;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PA0_TWD | AT91C_PA1_TWCK;
|
||||
#else
|
||||
#error "SAM7 platform not supported"
|
||||
#endif
|
||||
|
||||
AIC_ConfigureIT(AT91C_ID_TWI,
|
||||
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | SAM7_I2C_I2C1_IRQ_PRIORITY,
|
||||
TWI_IRQHandler);
|
||||
#endif /* STM32_I2C_USE_I2C1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the I2C peripheral.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void i2c_lld_start(I2CDriver *i2cp) {
|
||||
|
||||
volatile uint32_t fake;
|
||||
|
||||
/* If in stopped state then enables the I2C clocks.*/
|
||||
if (i2cp->state == I2C_STOP) {
|
||||
|
||||
#if SAM7_I2C_USE_I2C1
|
||||
if (&I2CD1 == i2cp) {
|
||||
/* enable peripheral clock */
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TWI);
|
||||
|
||||
/* Enables associated interrupt vector.*/
|
||||
AIC_EnableIT(AT91C_ID_TWI);
|
||||
|
||||
/* Reset */
|
||||
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_SWRST;
|
||||
fake = AT91C_BASE_TWI->TWI_RHR;
|
||||
|
||||
/* Set master mode */
|
||||
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSDIS;
|
||||
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_MSEN;
|
||||
|
||||
/* Setup I2C parameters. */
|
||||
AT91C_BASE_TWI->TWI_CWGR = i2cp->config->cwgr;
|
||||
}
|
||||
#endif /* STM32_I2C_USE_I2C1 */
|
||||
}
|
||||
|
||||
(void)fake;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the I2C peripheral.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void i2c_lld_stop(I2CDriver *i2cp) {
|
||||
|
||||
/* If not in stopped state then disables the I2C clock.*/
|
||||
if (i2cp->state != I2C_STOP) {
|
||||
|
||||
#if SAM7_I2C_USE_I2C1
|
||||
if (&I2CD1 == i2cp) {
|
||||
AT91C_BASE_TWI->TWI_IDR = AT91C_TWI_TXCOMP | AT91C_TWI_RXRDY |
|
||||
AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
||||
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_TWI);
|
||||
AIC_DisableIT(AT91C_ID_TWI);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives data via the I2C bus as master.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
* @param[in] addr slave device address
|
||||
* @param[out] rxbuf pointer to the receive buffer
|
||||
* @param[in] rxbytes number of bytes to be received
|
||||
* @param[in] timeout this value is ignored on SAM7 platform.
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the function succeeded.
|
||||
* @retval RDY_RESET if one or more I2C errors occurred, the errors can
|
||||
* be retrieved using @p i2cGetErrors().
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout) {
|
||||
(void)timeout;
|
||||
|
||||
/* delete trash from RHR*/
|
||||
volatile uint32_t fake;
|
||||
fake = AT91C_BASE_TWI->TWI_RHR;
|
||||
(void)fake;
|
||||
|
||||
/* Initializes driver fields.*/
|
||||
i2cp->rxbuf = rxbuf;
|
||||
i2cp->rxbytes = rxbytes;
|
||||
|
||||
i2cp->txbuf = NULL;
|
||||
i2cp->txbytes = 0;
|
||||
|
||||
/* tune master mode register */
|
||||
AT91C_BASE_TWI->TWI_MMR = 0;
|
||||
AT91C_BASE_TWI->TWI_MMR |= (addr << 16) | AT91C_TWI_MREAD;
|
||||
|
||||
/* enable just needed interrupts */
|
||||
AT91C_BASE_TWI->TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK;
|
||||
|
||||
/* In single data byte master read or write, the START and STOP must both be set. */
|
||||
if (rxbytes == 1)
|
||||
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP | AT91C_TWI_START;
|
||||
else
|
||||
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
|
||||
|
||||
/* Waits for the operation completion.*/
|
||||
i2cp->thread = chThdSelf();
|
||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||
|
||||
return chThdSelf()->p_u.rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read data via the I2C bus as master using internal slave addressing.
|
||||
* @details Address bytes must be written in special purpose SAM7 registers.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
* @param[in] addr slave device address
|
||||
* @param[in] txbuf pointer to the transmit buffer
|
||||
* @param[in] txbytes number of bytes to be transmitted
|
||||
* @param[out] rxbuf pointer to the receive buffer
|
||||
* @param[in] rxbytes number of bytes to be received
|
||||
* @param[in] timeout this value is ignored on SAM7 platform.
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the function succeeded.
|
||||
* @retval RDY_RESET if one or more I2C errors occurred, the errors can
|
||||
* be retrieved using @p i2cGetErrors().
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
msg_t i2c_lld_transceive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
const uint8_t *txbuf, size_t txbytes,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout) {
|
||||
(void)timeout;
|
||||
|
||||
/* delete trash from RHR*/
|
||||
volatile uint32_t fake;
|
||||
fake = AT91C_BASE_TWI->TWI_RHR;
|
||||
(void)fake;
|
||||
|
||||
/* Initializes driver fields.*/
|
||||
i2cp->rxbuf = rxbuf;
|
||||
i2cp->rxbytes = rxbytes;
|
||||
|
||||
/* tune master mode register */
|
||||
AT91C_BASE_TWI->TWI_MMR = 0;
|
||||
AT91C_BASE_TWI->TWI_MMR |= (addr << 16) | (txbytes << 8) | AT91C_TWI_MREAD;
|
||||
|
||||
/* store internal slave address in TWI_IADR registers */
|
||||
AT91C_BASE_TWI->TWI_IADR = 0;
|
||||
while (txbytes > 0){
|
||||
AT91C_BASE_TWI->TWI_IADR = (AT91C_BASE_TWI->TWI_IADR << 8);
|
||||
AT91C_BASE_TWI->TWI_IADR |= *(txbuf++);
|
||||
txbytes--;
|
||||
}
|
||||
|
||||
/* enable just needed interrupts */
|
||||
AT91C_BASE_TWI->TWI_IER = AT91C_TWI_RXRDY | AT91C_TWI_NACK;
|
||||
|
||||
/* Internal address of I2C slave was set in special Atmel registers.
|
||||
* Now we must call read function. The I2C cell automatically sends
|
||||
* bytes from IADR register to bus and issues repeated start. */
|
||||
if (rxbytes == 1)
|
||||
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_STOP | AT91C_TWI_START;
|
||||
else
|
||||
AT91C_BASE_TWI->TWI_CR = AT91C_TWI_START;
|
||||
|
||||
/* Waits for the operation completion.*/
|
||||
i2cp->thread = chThdSelf();
|
||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||
|
||||
return chThdSelf()->p_u.rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmits data via the I2C bus as master.
|
||||
* @details When performing reading through write you can not write more than
|
||||
* 3 bytes of data to I2C slave. This is SAM7 platform limitation.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
* @param[in] addr slave device address
|
||||
* @param[in] txbuf pointer to the transmit buffer
|
||||
* @param[in] txbytes number of bytes to be transmitted
|
||||
* @param[out] rxbuf pointer to the receive buffer
|
||||
* @param[in] rxbytes number of bytes to be received
|
||||
* @param[in] timeout this value is ignored on SAM7 platform.
|
||||
*
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the function succeeded.
|
||||
* @retval RDY_RESET if one or more I2C errors occurred, the errors can
|
||||
* be retrieved using @p i2cGetErrors().
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
const uint8_t *txbuf, size_t txbytes,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout) {
|
||||
(void)timeout;
|
||||
|
||||
/* SAM7 specific check */
|
||||
chDbgCheck(((rxbytes == 0) ||
|
||||
((txbytes > 0) && (txbytes < 4) && (rxbuf != NULL))),
|
||||
"i2c_lld_master_transmit_timeout");
|
||||
|
||||
/* prepare to read through write operation */
|
||||
if (rxbytes > 0){
|
||||
return i2c_lld_transceive_timeout(i2cp, addr, txbuf, txbytes, rxbuf,
|
||||
rxbytes, timeout);
|
||||
}
|
||||
else{
|
||||
if (txbytes == 1){
|
||||
/* In single data byte master read or write, the START and STOP
|
||||
* must both be set. */
|
||||
AT91C_BASE_TWI->TWI_CR |= AT91C_TWI_STOP;
|
||||
}
|
||||
AT91C_BASE_TWI->TWI_MMR = 0;
|
||||
AT91C_BASE_TWI->TWI_MMR |= addr << 16;
|
||||
|
||||
/* enable just needed interrupts */
|
||||
AT91C_BASE_TWI->TWI_IER = AT91C_TWI_TXRDY | AT91C_TWI_NACK;
|
||||
|
||||
/* correct size and pointer because first byte will be written
|
||||
* for issue start condition */
|
||||
i2cp->txbuf = txbuf + 1;
|
||||
i2cp->txbytes = txbytes - 1;
|
||||
|
||||
/* According to datasheet there is no need to set START manually
|
||||
* we just need to write first byte in THR */
|
||||
AT91C_BASE_TWI->TWI_THR = txbuf[0];
|
||||
|
||||
/* Waits for the operation completion.*/
|
||||
i2cp->thread = chThdSelf();
|
||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||
|
||||
return chThdSelf()->p_u.rdymsg;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_I2C */
|
||||
|
||||
/** @} */
|
||||
204
firmware/chibios/os/hal/platforms/AT91SAM7/i2c_lld.h
Executable file
204
firmware/chibios/os/hal/platforms/AT91SAM7/i2c_lld.h
Executable file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
|
||||
aka barthess.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/i2c_lld.h
|
||||
* @brief AT91SAM7 I2C subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _I2C_LLD_H_
|
||||
#define _I2C_LLD_H_
|
||||
|
||||
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Peripheral clock frequency.
|
||||
*/
|
||||
#define I2C_CLK_FREQ ((STM32_PCLK1) / 1000000)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief I2C1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for I2C1 is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(SAM7_I2C_USE_I2C1) || defined(__DOXYGEN__)
|
||||
#define SAM7_I2C_USE_I2C1 FALSE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief I2C1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SAM7_I2C_I2C1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SAM7_I2C_I2C1_IRQ_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief error checks */
|
||||
#if !SAM7_I2C_USE_I2C1
|
||||
#error "I2C driver activated but no I2C peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type representing I2C address.
|
||||
*/
|
||||
typedef uint16_t i2caddr_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Driver condition flags type.
|
||||
*/
|
||||
typedef uint32_t i2cflags_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief CWGR regitster content.
|
||||
*/
|
||||
uint32_t cwgr;
|
||||
} I2CConfig;
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an I2C driver.
|
||||
*/
|
||||
typedef struct I2CDriver I2CDriver;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an I2C driver.
|
||||
*/
|
||||
struct I2CDriver{
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
i2cstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const I2CConfig *config;
|
||||
/**
|
||||
* @brief Error flags.
|
||||
*/
|
||||
i2cflags_t errors;
|
||||
/**
|
||||
* @brief Pointer to receive buffer.
|
||||
*/
|
||||
uint8_t *rxbuf;
|
||||
/**
|
||||
* @brief Pointer to transmit buffer.
|
||||
*/
|
||||
const uint8_t *txbuf;
|
||||
/**
|
||||
* @brief Bytes count to be received.
|
||||
*/
|
||||
size_t rxbytes;
|
||||
/**
|
||||
* @brief Bytes count to be transmitted.
|
||||
*/
|
||||
size_t txbytes;
|
||||
#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the bus.
|
||||
*/
|
||||
Mutex mutex;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
Semaphore semaphore;
|
||||
#endif
|
||||
#endif /* I2C_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(I2C_DRIVER_EXT_FIELDS)
|
||||
I2C_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Thread waiting for I/O completion.
|
||||
*/
|
||||
Thread *thread;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Get errors from I2C driver.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
#if SAM7_I2C_USE_I2C1
|
||||
extern I2CDriver I2CD1;
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void i2c_lld_init(void);
|
||||
void i2c_lld_start(I2CDriver *i2cp);
|
||||
void i2c_lld_stop(I2CDriver *i2cp);
|
||||
msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
const uint8_t *txbuf, size_t txbytes,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout);
|
||||
msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_I2C */
|
||||
|
||||
#endif /* _I2C_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
551
firmware/chibios/os/hal/platforms/AT91SAM7/mac_lld.c
Executable file
551
firmware/chibios/os/hal/platforms/AT91SAM7/mac_lld.c
Executable file
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/mac_lld.c
|
||||
* @brief AT91SAM7 low level MAC driver code.
|
||||
*
|
||||
* @addtogroup MAC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "mii.h"
|
||||
#include "at91sam7_mii.h"
|
||||
|
||||
#if 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 ETHD1;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifndef __DOXYGEN__
|
||||
|
||||
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(ÐD1.rdsem, 0);
|
||||
#if MAC_USE_EVENTS
|
||||
chEvtBroadcastI(ÐD1.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(ÐD1.tdsem, 0);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
AT91C_BASE_EMAC->EMAC_TSR = TSR_BITS;
|
||||
}
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cleans an incomplete frame.
|
||||
*
|
||||
* @param[in] 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief MAC address setup.
|
||||
*
|
||||
* @param[in] p pointer to a six bytes buffer containing the MAC
|
||||
* address
|
||||
*/
|
||||
static void set_address(const uint8_t *p) {
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EMAC IRQ handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(irq_handler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
serve_interrupt();
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level MAC initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void mac_lld_init(void) {
|
||||
|
||||
miiInit();
|
||||
macObjectInit(ÐD1);
|
||||
|
||||
/*
|
||||
* Associated PHY initialization.
|
||||
*/
|
||||
miiReset(ÐD1);
|
||||
|
||||
/*
|
||||
* EMAC pins setup. Note, PB18 is not included because it is
|
||||
* used as #PD control and not as EF100.
|
||||
*/
|
||||
AT91C_BASE_PIOB->PIO_ASR = EMAC_PIN_MASK;
|
||||
AT91C_BASE_PIOB->PIO_PDR = EMAC_PIN_MASK;
|
||||
AT91C_BASE_PIOB->PIO_PPUDR = EMAC_PIN_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the MAC peripheral.
|
||||
*
|
||||
* @param[in] macp pointer to the @p MACDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void mac_lld_start(MACDriver *macp) {
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* EMAC clock enable.
|
||||
*/
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_EMAC;
|
||||
|
||||
/*
|
||||
* 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.*/
|
||||
if (macp->config->mac_address == NULL)
|
||||
set_address(default_mac);
|
||||
else
|
||||
set_address(macp->config->mac_address);
|
||||
|
||||
/*
|
||||
* PHY device identification.
|
||||
*/
|
||||
AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
|
||||
if ((miiGet(ÐD1, MII_PHYSID1) != (PHY_ID >> 16)) ||
|
||||
((miiGet(ÐD1, 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 Deactivates the MAC peripheral.
|
||||
*
|
||||
* @param[in] macp pointer to the @p MACDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void mac_lld_stop(MACDriver *macp) {
|
||||
|
||||
(void)macp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 has been obtained.
|
||||
* @retval RDY_TIMEOUT descriptor not available.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
msg_t mac_lld_get_transmit_descriptor(MACDriver *macp,
|
||||
MACTransmitDescriptor *tdp) {
|
||||
EMACDescriptor *edp;
|
||||
|
||||
(void)macp;
|
||||
|
||||
if (!macp->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->offset = 0;
|
||||
tdp->size = EMAC_TRANSMIT_BUFFERS_SIZE;
|
||||
tdp->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 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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp,
|
||||
uint8_t *buf,
|
||||
size_t size) {
|
||||
|
||||
if (size > tdp->size - tdp->offset)
|
||||
size = tdp->size - tdp->offset;
|
||||
if (size > 0) {
|
||||
memcpy((uint8_t *)(tdp->physdesc->w1 & W1_T_ADDRESS_MASK) +
|
||||
tdp->offset,
|
||||
buf, size);
|
||||
tdp->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
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) {
|
||||
|
||||
chSysLock();
|
||||
tdp->physdesc->w2 = (tdp->physdesc->w2 &
|
||||
~(W2_T_LOCKED | W2_T_USED | W2_T_LENGTH_MASK)) |
|
||||
tdp->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 has been obtained.
|
||||
* @retval RDY_TIMEOUT descriptor not available.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
msg_t mac_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->offset = 0;
|
||||
rdp->size = rxptr->w2 & W2_T_LENGTH_MASK;
|
||||
rdp->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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp,
|
||||
uint8_t *buf,
|
||||
size_t size) {
|
||||
if (size > rdp->size - rdp->offset)
|
||||
size = rdp->size - rdp->offset;
|
||||
if (size > 0) {
|
||||
uint8_t *src = (uint8_t *)(rdp->physdesc->w1 & W1_R_ADDRESS_MASK) +
|
||||
rdp->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->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
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) {
|
||||
bool_t done;
|
||||
EMACDescriptor *edp = rdp->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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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 macp->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 macp->link_up = TRUE;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_MAC */
|
||||
|
||||
/** @} */
|
||||
252
firmware/chibios/os/hal/platforms/AT91SAM7/mac_lld.h
Executable file
252
firmware/chibios/os/hal/platforms/AT91SAM7/mac_lld.h
Executable file
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/mac_lld.h
|
||||
* @brief AT91SAM7 low level MAC driver header.
|
||||
*
|
||||
* @addtogroup MAC
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _MAC_LLD_H_
|
||||
#define _MAC_LLD_H_
|
||||
|
||||
#if HAL_USE_MAC || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief This implementation does not support the zero-copy mode API.
|
||||
*/
|
||||
#define MAC_SUPPORTS_ZERO_COPY FALSE
|
||||
|
||||
#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. */
|
||||
#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 Driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief MAC address.
|
||||
*/
|
||||
const uint8_t *mac_address;
|
||||
/* End of the mandatory fields.*/
|
||||
} MACConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a MAC driver.
|
||||
*/
|
||||
struct MACDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
macstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const MACConfig *config;
|
||||
/**
|
||||
* @brief Transmit semaphore.
|
||||
*/
|
||||
Semaphore tdsem;
|
||||
/**
|
||||
* @brief Receive semaphore.
|
||||
*/
|
||||
Semaphore rdsem;
|
||||
#if MAC_USE_EVENTS || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Receive event.
|
||||
*/
|
||||
EventSource rdevent;
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Link status flag.
|
||||
*/
|
||||
bool_t link_up;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Structure representing a transmit descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Current write offset.
|
||||
*/
|
||||
size_t offset;
|
||||
/**
|
||||
* @brief Available space size.
|
||||
*/
|
||||
size_t size;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the physical descriptor.
|
||||
*/
|
||||
EMACDescriptor *physdesc;
|
||||
} MACTransmitDescriptor;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a receive descriptor.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Current read offset.
|
||||
*/
|
||||
size_t offset;
|
||||
/**
|
||||
* @brief Available data size.
|
||||
*/
|
||||
size_t size;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the first descriptor of the buffers chain.
|
||||
*/
|
||||
EMACDescriptor *physdesc;
|
||||
} MACReceiveDescriptor;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern MACDriver ETHD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void mac_lld_init(void);
|
||||
void mac_lld_start(MACDriver *macp);
|
||||
void mac_lld_stop(MACDriver *macp);
|
||||
msg_t mac_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 mac_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 /* HAL_USE_MAC */
|
||||
|
||||
#endif /* _MAC_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
159
firmware/chibios/os/hal/platforms/AT91SAM7/pal_lld.c
Executable file
159
firmware/chibios/os/hal/platforms/AT91SAM7/pal_lld.c
Executable file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/pal_lld.c
|
||||
* @brief AT91SAM7 PIO low level driver code.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief AT91SAM7 I/O ports configuration.
|
||||
* @details PIO registers initialization.
|
||||
*
|
||||
* @param[in] config the AT91SAM7 ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_init(const PALConfig *config) {
|
||||
|
||||
uint32_t ports = (1 << AT91C_ID_PIOA);
|
||||
#if (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512) || (SAM7_PLATFORM == SAM7A3)
|
||||
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) || (SAM7_PLATFORM == SAM7A3)
|
||||
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.
|
||||
* @note This function is not meant to be invoked directly from 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.
|
||||
*
|
||||
* @param[in] port the port identifier
|
||||
* @param[in] mask the group mask
|
||||
* @param[in] mode the mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode) {
|
||||
|
||||
if (mode & AT91_PAL_OPENDRAIN)
|
||||
port->PIO_MDER = mask;
|
||||
else
|
||||
port->PIO_MDDR = mask;
|
||||
if (mode & AT91_PAL_PULLUP)
|
||||
port->PIO_PPUER = mask;
|
||||
else
|
||||
port->PIO_PPUDR = mask;
|
||||
if (mode & AT91_PAL_OUT_SET)
|
||||
port->PIO_SODR = mask;
|
||||
if (mode & AT91_PAL_OUT_CLEAR)
|
||||
port->PIO_CODR = mask;
|
||||
|
||||
switch (mode & AT91_PAL_DIR_MASK) {
|
||||
case AT91_PAL_DIR_INPUT:
|
||||
port->PIO_ODR = mask;
|
||||
port->PIO_PER = mask;
|
||||
break;
|
||||
case AT91_PAL_DIR_OUTPUT:
|
||||
port->PIO_OER = mask;
|
||||
port->PIO_PER = mask;
|
||||
break;
|
||||
case AT91_PAL_DIR_PERIPH_A:
|
||||
port->PIO_OER = mask;
|
||||
port->PIO_PDR = mask;
|
||||
port->PIO_ASR = mask;
|
||||
break;
|
||||
case AT91_PAL_DIR_PERIPH_B:
|
||||
port->PIO_OER = mask;
|
||||
port->PIO_PDR = mask;
|
||||
port->PIO_BSR = mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
/** @} */
|
||||
292
firmware/chibios/os/hal/platforms/AT91SAM7/pal_lld.h
Executable file
292
firmware/chibios/os/hal/platforms/AT91SAM7/pal_lld.h
Executable file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/pal_lld.h
|
||||
* @brief AT91SAM7 PIO low level driver header.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PAL_LLD_H_
|
||||
#define _PAL_LLD_H_
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Unsupported modes and specific modes */
|
||||
/*===========================================================================*/
|
||||
|
||||
// AT91: Port direction
|
||||
#define AT91_PAL_DIR_MASK 0x03
|
||||
#define AT91_PAL_DIR_INPUT 0x00
|
||||
#define AT91_PAL_DIR_OUTPUT 0x01
|
||||
#define AT91_PAL_DIR_PERIPH_A 0x02
|
||||
#define AT91_PAL_DIR_PERIPH_B 0x03
|
||||
|
||||
// AT91: Additional flags
|
||||
#define AT91_PAL_OUT_SET 0x04
|
||||
#define AT91_PAL_OUT_CLEAR 0x08
|
||||
#define AT91_PAL_PULLUP 0x10
|
||||
#define AT91_PAL_OPENDRAIN 0x20
|
||||
|
||||
// Unsupported
|
||||
#undef PAL_MODE_INPUT_PULLDOWN
|
||||
|
||||
// Redefine the standard io modes
|
||||
#undef PAL_MODE_RESET
|
||||
#undef PAL_MODE_UNCONNECTED
|
||||
#undef PAL_MODE_INPUT
|
||||
#undef PAL_MODE_INPUT_PULLUP
|
||||
#undef PAL_MODE_INPUT_ANALOG
|
||||
#undef PAL_MODE_OUTPUT_PUSHPULL
|
||||
#undef PAL_MODE_OUTPUT_OPENDRAIN
|
||||
#define PAL_MODE_RESET (AT91_PAL_DIR_INPUT|AT91_PAL_PULLUP)
|
||||
#define PAL_MODE_UNCONNECTED (AT91_PAL_DIR_OUTPUT|AT91_PAL_OUT_SET)
|
||||
#define PAL_MODE_INPUT (AT91_PAL_DIR_INPUT)
|
||||
#define PAL_MODE_INPUT_PULLUP (AT91_PAL_DIR_INPUT|AT91_PAL_PULLUP)
|
||||
#define PAL_MODE_INPUT_ANALOG (AT91_PAL_DIR_INPUT)
|
||||
#define PAL_MODE_OUTPUT_PUSHPULL (AT91_PAL_DIR_OUTPUT)
|
||||
#define PAL_MODE_OUTPUT_OPENDRAIN (AT91_PAL_DIR_OUTPUT|AT91_PAL_PULLUP|AT91_PAL_OPENDRAIN)
|
||||
|
||||
// Add the AT91 specific ones
|
||||
#define PAL_MODE_PERIPH_A_PUSHPULL (AT91_PAL_DIR_PERIPH_A)
|
||||
#define PAL_MODE_PERIPH_A_OPENDRAIN (AT91_PAL_DIR_PERIPH_A|AT91_PAL_PULLUP|AT91_PAL_OPENDRAIN)
|
||||
#define PAL_MODE_PERIPH_B_PUSHPULL (AT91_PAL_DIR_PERIPH_A)
|
||||
#define PAL_MODE_PERIPH_B_OPENDRAIN (AT91_PAL_DIR_PERIPH_A|AT91_PAL_PULLUP|AT91_PAL_OPENDRAIN)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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) || (SAM7_PLATFORM == SAM7A3) || \
|
||||
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 Whole port mask.
|
||||
* @details This macro specifies all the valid bits into a port.
|
||||
*/
|
||||
#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFF)
|
||||
|
||||
/**
|
||||
* @brief Digital I/O port sized unsigned type.
|
||||
*/
|
||||
typedef uint32_t ioportmask_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O modes.
|
||||
*/
|
||||
typedef uint32_t iomode_t;
|
||||
|
||||
/**
|
||||
* @brief Port Identifier.
|
||||
* @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) || (SAM7_PLATFORM == SAM7A3) || \
|
||||
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 pal_lld.c. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level PAL subsystem initialization.
|
||||
*
|
||||
* @param[in] config architecture-dependent ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#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 port identifier
|
||||
* @return The port bits.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#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 port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#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
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#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 port identifier
|
||||
* @param[in] bits bits to be ORed on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#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 port identifier
|
||||
* @param[in] bits bits to be cleared on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#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 port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset the group bit offset within the port
|
||||
* @param[in] bits bits to be written. Values exceeding the group
|
||||
* width are masked.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writegroup(port, mask, offset, bits) \
|
||||
((port)->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.
|
||||
* @note @p PAL_MODE_UNCONNECTED is implemented as push pull output with
|
||||
* high state.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] mask group mask
|
||||
* @param[in] offset group bit offset within the port
|
||||
* @param[in] mode group mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setgroupmode(port, mask, offset, mode) \
|
||||
_pal_lld_setgroupmode(port, mask << offset, mode)
|
||||
|
||||
/**
|
||||
* @brief Writes a logical state on an output pad.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
* @param[in] bit logical value, the value must be @p PAL_LOW or
|
||||
* @p PAL_HIGH
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writepad(port, pad, bit) pal_lld_writegroup(port, 1, pad, bit)
|
||||
|
||||
extern const PALConfig pal_default_config;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _pal_lld_init(const PALConfig *config);
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
#endif /* _PAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
136
firmware/chibios/os/hal/platforms/AT91SAM7/platform.dox
Executable file
136
firmware/chibios/os/hal/platforms/AT91SAM7/platform.dox
Executable file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AT91SAM7 AT91SAM7 Drivers
|
||||
* @details This section describes all the supported drivers on the AT91SAM7
|
||||
* platform and the implementation details of the single drivers.
|
||||
*
|
||||
* @ingroup platforms
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AT91SAM7_HAL AT91SAM7 Initialization Support
|
||||
* @details The AT91SAM7 HAL support is responsible for system initialization.
|
||||
*
|
||||
* @section at91sam7_hal_1 Supported HW resources
|
||||
* - MC.
|
||||
* - PMC.
|
||||
* .
|
||||
* @section at91sam7_hal_2 AT91SAM7 HAL driver implementation features
|
||||
* - PLLs startup and stabilization.
|
||||
* - Clock source selection.
|
||||
* - Flash wait states.
|
||||
* .
|
||||
* @ingroup AT91SAM7
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AT91SAM7_MAC AT91SAM7 MAC Support
|
||||
* @details The AT91SAM7 MAC driver supports the EMAC peripheral.
|
||||
*
|
||||
* @section at91sam7_mac_1 Supported HW resources
|
||||
* - EMAC.
|
||||
* .
|
||||
* @ingroup AT91SAM7
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AT91SAM7_MII AT91SAM7 MII 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. This driver
|
||||
* is used internally by the MAC driver.
|
||||
*
|
||||
* @ingroup AT91SAM7
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AT91SAM7_PAL AT91SAM7 PAL Support
|
||||
* @details The AT91SAM7 PAL driver supports the PIO peripherals.
|
||||
*
|
||||
* @section at91sam7_pal_1 Supported HW resources
|
||||
* - PIOA.
|
||||
* - PIOB.
|
||||
* .
|
||||
* @section at91sam7_pal_2 AT91SAM7 PAL driver implementation features
|
||||
* The PAL driver implementation fully supports the following hardware
|
||||
* capabilities:
|
||||
* - 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.
|
||||
* .
|
||||
* @section at91sam7_pal_3 Supported PAL setup modes
|
||||
* The AT91SAM7 PAL driver supports the following I/O modes:
|
||||
* - @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.
|
||||
*
|
||||
* @section at91sam7_pal_4 Suboptimal behavior
|
||||
* The AT91SAM7 PIO is less than optimal in several areas, the limitations
|
||||
* should be taken in account while using the PAL driver:
|
||||
* - Pad/port toggling operations are not atomic.
|
||||
* - Pad/group mode setup is not atomic.
|
||||
* .
|
||||
* @ingroup AT91SAM7
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AT91SAM7_SERIAL AT91SAM7 Serial Support
|
||||
* @details The AT91SAM7 Serial driver uses the USART/UART peripherals in a
|
||||
* buffered, interrupt driven, implementation.
|
||||
*
|
||||
* @section at91sam7_serial_1 Supported HW resources
|
||||
* The serial driver can support any of the following hardware resources:
|
||||
* - USART1.
|
||||
* - USART2.
|
||||
* - DBGU.
|
||||
* .
|
||||
* @section at91sam7_serial_2 AT91SAM7 Serial driver implementation features
|
||||
* - Clock stop for reduced power usage when the driver is in stop state.
|
||||
* - Each USART can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Fully interrupt driven.
|
||||
* - Programmable priority levels for each USART.
|
||||
* .
|
||||
* @ingroup AT91SAM7
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AT91SAM7_SPI AT91SAM7 SPI Support
|
||||
* @details The SPI driver supports the AT91SAM7 SPI peripherals using DMA
|
||||
* channels for maximum performance.
|
||||
*
|
||||
* @section at91sam7_spi_1 Supported HW resources
|
||||
* - SPI1.
|
||||
* - SPI2.
|
||||
* .
|
||||
* @section at91sam7_spi_2 AT91SAM7 SPI driver implementation features
|
||||
* - Clock stop for reduced power usage when the driver is in stop state.
|
||||
* - Each SPI can be independently enabled and programmed. Unused
|
||||
* peripherals are left in low power mode.
|
||||
* - Programmable interrupt priority levels for each SPI.
|
||||
* - DMA is used for receiving and transmitting.
|
||||
* .
|
||||
* @ingroup AT91SAM7
|
||||
*/
|
||||
16
firmware/chibios/os/hal/platforms/AT91SAM7/platform.mk
Executable file
16
firmware/chibios/os/hal/platforms/AT91SAM7/platform.mk
Executable file
@@ -0,0 +1,16 @@
|
||||
# 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/i2c_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AT91SAM7/adc_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AT91SAM7/ext_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AT91SAM7/serial_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AT91SAM7/spi_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AT91SAM7/mac_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AT91SAM7/pwm_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AT91SAM7/gpt_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
|
||||
467
firmware/chibios/os/hal/platforms/AT91SAM7/pwm_lld.c
Executable file
467
firmware/chibios/os/hal/platforms/AT91SAM7/pwm_lld.c
Executable file
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
This file has been contributed by:
|
||||
Andrew Hannam aka inmarket.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/pwm_lld.c
|
||||
* @brief AT91SAM7 PWM Driver subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup PWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef UNUSED
|
||||
#elif defined(__GNUC__)
|
||||
# define UNUSED(x) UNUSED_ ## x __attribute__((unused))
|
||||
#elif defined(__LCLINT__)
|
||||
# define UNUSED(x) /*@unused@*/ x
|
||||
#else
|
||||
# define UNUSED(x) x
|
||||
#endif
|
||||
|
||||
#define PWMC_M ((AT91S_PWMC *)AT91C_PWMC_MR)
|
||||
|
||||
#define PWM_MCK_MASK 0x0F00
|
||||
#define PWM_MCK_SHIFT 8
|
||||
|
||||
typedef struct pindef {
|
||||
uint32_t portpin; /* Set to 0 if this pin combination is invalid */
|
||||
AT91S_PIO *pio;
|
||||
AT91_REG *perab;
|
||||
} pindef_t;
|
||||
|
||||
typedef struct pwmpindefs {
|
||||
pindef_t pin[3];
|
||||
} pwmpindefs_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if PWM_USE_PWM1 && !defined(__DOXYGEN__)
|
||||
PWMDriver PWMD1;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM2 && !defined(__DOXYGEN__)
|
||||
PWMDriver PWMD2;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM3 && !defined(__DOXYGEN__)
|
||||
PWMDriver PWMD3;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM4 && !defined(__DOXYGEN__)
|
||||
PWMDriver PWMD4;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7S64) || (SAM7_PLATFORM == SAM7S128) || \
|
||||
(SAM7_PLATFORM == SAM7S256) || (SAM7_PLATFORM == SAM7S512)
|
||||
|
||||
#if PWM_USE_PWM1 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP1 = {{
|
||||
{ AT91C_PA0_PWM0 , AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_ASR },
|
||||
{ AT91C_PA11_PWM0, AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
{ AT91C_PA23_PWM0, AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
}};
|
||||
#endif
|
||||
#if PWM_USE_PWM2 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP2 = {{
|
||||
{ AT91C_PA1_PWM1 , AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_ASR },
|
||||
{ AT91C_PA12_PWM1, AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
{ AT91C_PA24_PWM1, AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
}};
|
||||
#endif
|
||||
#if PWM_USE_PWM3 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP3 = {{
|
||||
{ AT91C_PA2_PWM2 , AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_ASR },
|
||||
{ AT91C_PA13_PWM2, AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
{ AT91C_PA25_PWM2, AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
}};
|
||||
#endif
|
||||
#if PWM_USE_PWM4 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP4 = {{
|
||||
{ AT91C_PA7_PWM3 , AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
{ AT91C_PA14_PWM3, AT91C_BASE_PIOA, &AT91C_BASE_PIOA->PIO_BSR },
|
||||
{ 0, 0, 0 },
|
||||
}};
|
||||
#endif
|
||||
|
||||
#elif (SAM7_PLATFORM == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512)
|
||||
|
||||
#if PWM_USE_PWM1 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP1 = {{
|
||||
{ AT91C_PB19_PWM0, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_ASR },
|
||||
{ AT91C_PB27_PWM0, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_BSR },
|
||||
{ 0, 0, 0 },
|
||||
}};
|
||||
#endif
|
||||
#if PWM_USE_PWM2 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP2 = {{
|
||||
{ AT91C_PB20_PWM1, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_ASR },
|
||||
{ AT91C_PB28_PWM1, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_BSR },
|
||||
{ 0, 0, 0 },
|
||||
}};
|
||||
#endif
|
||||
#if PWM_USE_PWM3 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP3 = {{
|
||||
{ AT91C_PB21_PWM2, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_ASR },
|
||||
{ AT91C_PB29_PWM2, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_BSR },
|
||||
{ 0, 0, 0 },
|
||||
}};
|
||||
#endif
|
||||
#if PWM_USE_PWM4 && !defined(__DOXYGEN__)
|
||||
static const pwmpindefs_t PWMP4 = {{
|
||||
{ AT91C_PB22_PWM3, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_ASR },
|
||||
{ AT91C_PB30_PWM3, AT91C_BASE_PIOB, &AT91C_BASE_PIOB->PIO_BSR },
|
||||
{ 0, 0, 0 },
|
||||
}};
|
||||
#endif
|
||||
|
||||
#else
|
||||
#error "PWM pins not defined for this SAM7 version"
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM2 && !defined(__DOXYGEN__)
|
||||
PWMDriver PWMD2;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM3 && !defined(__DOXYGEN__)
|
||||
PWMDriver PWMD3;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM4 && !defined(__DOXYGEN__)
|
||||
PWMDriver PWMD4;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((noinline))
|
||||
#endif
|
||||
/**
|
||||
* @brief Common IRQ handler.
|
||||
*/
|
||||
static void pwm_lld_serve_interrupt(void) {
|
||||
uint32_t isr;
|
||||
|
||||
isr = PWMC_M->PWMC_ISR;
|
||||
#if PWM_USE_PWM1
|
||||
if ((isr & 1) && PWMD1.config->channels[0].callback)
|
||||
PWMD1.config->channels[0].callback(&PWMD1);
|
||||
#endif
|
||||
#if PWM_USE_PWM2
|
||||
if ((isr & 2) && PWMD2.config->channels[0].callback)
|
||||
PWMD2.config->channels[0].callback(&PWMD2);
|
||||
#endif
|
||||
#if PWM_USE_PWM3
|
||||
if ((isr & 4) && PWMD3.config->channels[0].callback)
|
||||
PWMD3.config->channels[0].callback(&PWMD3);
|
||||
#endif
|
||||
#if PWM_USE_PWM4
|
||||
if ((isr & 8) && PWMD4.config->channels[0].callback)
|
||||
PWMD4.config->channels[0].callback(&PWMD4);
|
||||
#endif
|
||||
}
|
||||
|
||||
CH_IRQ_HANDLER(PWMIrqHandler) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
pwm_lld_serve_interrupt();
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level PWM driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_init(void) {
|
||||
|
||||
/* Driver initialization.*/
|
||||
#if PWM_USE_PWM1 && !defined(__DOXYGEN__)
|
||||
pwmObjectInit(&PWMD1);
|
||||
PWMD1.chbit = 1;
|
||||
PWMD1.reg = AT91C_BASE_PWMC_CH0;
|
||||
PWMD1.pins = &PWMP1;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM2 && !defined(__DOXYGEN__)
|
||||
pwmObjectInit(&PWMD2);
|
||||
PWMD2.chbit = 2;
|
||||
PWMD2.reg = AT91C_BASE_PWMC_CH1;
|
||||
PWMD2.pins = &PWMP2;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM3 && !defined(__DOXYGEN__)
|
||||
pwmObjectInit(&PWMD3);
|
||||
PWMD3.chbit = 4;
|
||||
PWMD3.reg = AT91C_BASE_PWMC_CH2;
|
||||
PWMD3.pins = &PWMP3;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM4 && !defined(__DOXYGEN__)
|
||||
pwmObjectInit(&PWMD4);
|
||||
PWMD4.chbit = 8;
|
||||
PWMD4.reg = AT91C_BASE_PWMC_CH3;
|
||||
PWMD4.pins = &PWMP4;
|
||||
#endif
|
||||
|
||||
/* Turn on PWM in the power management controller */
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_PWMC);
|
||||
|
||||
/* Setup interrupt handler */
|
||||
PWMC_M->PWMC_IDR = 0xFFFFFFFF;
|
||||
AIC_ConfigureIT(AT91C_ID_PWMC,
|
||||
AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91SAM7_PWM_PRIORITY,
|
||||
PWMIrqHandler);
|
||||
AIC_EnableIT(AT91C_ID_PWMC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the PWM peripheral.
|
||||
*
|
||||
* @param[in] pwmp pointer to the @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_start(PWMDriver *pwmp) {
|
||||
uint32_t mode, mr, div, pre;
|
||||
|
||||
/* Steps:
|
||||
1. Turn the IO pin to a PWM output
|
||||
2. Configuration of Clock if DIVA or DIVB used
|
||||
3. Selection of the clock for each channel (CPRE field in the PWM_CMRx register)
|
||||
4. Configuration of the waveform alignment for each channel (CALG field in the PWM_CMRx register)
|
||||
5. Configuration of the output waveform polarity for each channel (CPOL in the PWM_CMRx register)
|
||||
6. Configuration of the period for each channel (CPRD in the PWM_CPRDx register). Writing in
|
||||
PWM_CPRDx Register is possible while the channel is disabled. After validation of the
|
||||
channel, the user must use PWM_CUPDx Register to update PWM_CPRDx
|
||||
7. Enable Interrupts (Writing CHIDx in the PWM_IER register)
|
||||
*/
|
||||
|
||||
/* Make sure it is off first */
|
||||
pwm_lld_disable_channel(pwmp, 0);
|
||||
|
||||
/* Configuration.*/
|
||||
mode = pwmp->config->channels[0].mode;
|
||||
|
||||
/* Step 1 */
|
||||
if (mode & PWM_OUTPUT_PIN1) {
|
||||
pwmp->pins->pin[0].perab[0] = pwmp->pins->pin[0].portpin; /* Select A or B peripheral */
|
||||
pwmp->pins->pin[0].pio->PIO_PDR = pwmp->pins->pin[0].portpin; /* Turn PIO into PWM output */
|
||||
pwmp->pins->pin[0].pio->PIO_MDDR = pwmp->pins->pin[0].portpin; /* Turn off PIO multi-drive */
|
||||
if (mode & PWM_DISABLEPULLUP_PIN1)
|
||||
pwmp->pins->pin[0].pio->PIO_PPUDR = pwmp->pins->pin[0].portpin; /* Turn off PIO pullup */
|
||||
else
|
||||
pwmp->pins->pin[0].pio->PIO_PPUER = pwmp->pins->pin[0].portpin; /* Turn on PIO pullup */
|
||||
}
|
||||
if (mode & PWM_OUTPUT_PIN2) {
|
||||
pwmp->pins->pin[1].perab[0] = pwmp->pins->pin[1].portpin;
|
||||
pwmp->pins->pin[1].pio->PIO_PDR = pwmp->pins->pin[1].portpin;
|
||||
pwmp->pins->pin[1].pio->PIO_MDDR = pwmp->pins->pin[1].portpin;
|
||||
if (mode & PWM_DISABLEPULLUP_PIN2)
|
||||
pwmp->pins->pin[1].pio->PIO_PPUDR = pwmp->pins->pin[1].portpin;
|
||||
else
|
||||
pwmp->pins->pin[1].pio->PIO_PPUER = pwmp->pins->pin[1].portpin;
|
||||
}
|
||||
if ((mode & PWM_OUTPUT_PIN3) && pwmp->pins->pin[2].portpin) {
|
||||
pwmp->pins->pin[2].perab[0] = pwmp->pins->pin[2].portpin;
|
||||
pwmp->pins->pin[2].pio->PIO_PDR = pwmp->pins->pin[2].portpin;
|
||||
pwmp->pins->pin[2].pio->PIO_MDDR = pwmp->pins->pin[2].portpin;
|
||||
if (mode & PWM_DISABLEPULLUP_PIN3)
|
||||
pwmp->pins->pin[2].pio->PIO_PPUDR = pwmp->pins->pin[2].portpin;
|
||||
else
|
||||
pwmp->pins->pin[2].pio->PIO_PPUER = pwmp->pins->pin[2].portpin;
|
||||
}
|
||||
|
||||
/* Step 2 */
|
||||
if ((mode & PWM_MCK_MASK) == PWM_MCK_DIV_CLKA) {
|
||||
if (!pwmp->config->frequency) {
|
||||
/* As slow as we go */
|
||||
PWMC_M->PWMC_MR = (PWMC_M->PWMC_MR & 0xFFFF0000) | (10 << 8) | (255 << 0);
|
||||
} else if (pwmp->config->frequency > MCK) {
|
||||
/* Just use MCLK */
|
||||
mode &= ~PWM_MCK_MASK;
|
||||
} else {
|
||||
div = MCK / pwmp->config->frequency;
|
||||
if (mode & PWM_OUTPUT_CENTER) div >>= 1;
|
||||
for(pre = 0; div > 255 && pre < 10; pre++) div >>= 1;
|
||||
if (div > 255) div = 255;
|
||||
PWMC_M->PWMC_MR = (PWMC_M->PWMC_MR & 0xFFFF0000) | (pre << 8) | (div << 0);
|
||||
}
|
||||
} else if ((mode & PWM_MCK_MASK) == PWM_MCK_DIV_CLKB) {
|
||||
if (!pwmp->config->frequency) {
|
||||
/* As slow as we go */
|
||||
PWMC_M->PWMC_MR = (PWMC_M->PWMC_MR & 0x0000FFFF) | (10 << 24) | (255 << 16);
|
||||
} else if (pwmp->config->frequency > MCK) {
|
||||
/* Just use MCLK */
|
||||
mode &= ~PWM_MCK_MASK;
|
||||
} else {
|
||||
div = MCK / pwmp->config->frequency;
|
||||
if (mode & PWM_OUTPUT_CENTER) div >>= 1;
|
||||
for(pre = 0; div > 255 && pre < 10; pre++) div >>= 1;
|
||||
if (div > 255) div = 255;
|
||||
PWMC_M->PWMC_MR = (PWMC_M->PWMC_MR & 0x0000FFFF) | (pre << 24) | (div << 16);
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 3 -> 5 */
|
||||
mr = (mode & PWM_MCK_MASK) >> PWM_MCK_SHIFT;
|
||||
if (mode & PWM_OUTPUT_CENTER) mr |= AT91C_PWMC_CALG;
|
||||
if (mode & PWM_OUTPUT_ACTIVE_HIGH) mr |= AT91C_PWMC_CPOL;
|
||||
pwmp->reg->PWMC_CMR = mr;
|
||||
|
||||
/* Step 6 */
|
||||
pwmp->reg->PWMC_CPRDR = pwmp->period;
|
||||
|
||||
/* Step 7 */
|
||||
if (pwmp->config->channels[0].callback)
|
||||
PWMC_M->PWMC_IER = pwmp->chbit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the PWM peripheral.
|
||||
*
|
||||
* @param[in] pwmp pointer to the @p PWMDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_stop(PWMDriver *pwmp) {
|
||||
/* Make sure it is off */
|
||||
pwm_lld_disable_channel(pwmp, 0);
|
||||
|
||||
/* Turn the pin back to a PIO pin - we have forgotten pull-up and multi-drive state for the pin though */
|
||||
if (pwmp->config->channels[0].mode & PWM_OUTPUT_PIN1)
|
||||
pwmp->pins->pin[0].pio->PIO_PER = pwmp->pins->pin[0].portpin;
|
||||
if (pwmp->config->channels[0].mode & PWM_OUTPUT_PIN2)
|
||||
pwmp->pins->pin[1].pio->PIO_PER = pwmp->pins->pin[1].portpin;
|
||||
if ((pwmp->config->channels[0].mode & PWM_OUTPUT_PIN3) && pwmp->pins->pin[2].portpin)
|
||||
pwmp->pins->pin[2].pio->PIO_PER = pwmp->pins->pin[2].portpin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes the period the PWM peripheral.
|
||||
* @details This function changes the period of a PWM unit that has already
|
||||
* been activated using @p pwmStart().
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The PWM unit period is changed to the new value.
|
||||
* @note The function has effect at the next cycle start.
|
||||
* @note If a period is specified that is shorter than the pulse width
|
||||
* programmed in one of the channels then the behavior is not
|
||||
* guaranteed.
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] period new cycle time in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period) {
|
||||
pwmp->period = period;
|
||||
|
||||
if (PWMC_M->PWMC_SR & pwmp->chbit) {
|
||||
pwmp->reg->PWMC_CMR |= AT91C_PWMC_CPD;
|
||||
pwmp->reg->PWMC_CUPDR = period;
|
||||
} else {
|
||||
pwmp->reg->PWMC_CPRDR = period;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a PWM channel.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is active using the specified configuration.
|
||||
* @note Depending on the hardware implementation this function has
|
||||
* effect starting on the next cycle (recommended implementation)
|
||||
* or immediately (fallback implementation).
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
|
||||
* @param[in] width PWM pulse width as clock pulses number
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||
pwmchannel_t UNUSED(channel),
|
||||
pwmcnt_t width) {
|
||||
/*
|
||||
6. Configuration of the duty cycle for each channel (CDTY in the PWM_CDTYx register).
|
||||
Writing in PWM_CDTYx Register is possible while the channel is disabled. After validation of
|
||||
the channel, the user must use PWM_CUPDx Register to update PWM_CDTYx.
|
||||
7. Enable the PWM channel (Writing CHIDx in the PWM_ENA register)
|
||||
*/
|
||||
|
||||
/* Step 6 */
|
||||
if (PWMC_M->PWMC_SR & pwmp->chbit) {
|
||||
pwmp->reg->PWMC_CMR &= ~AT91C_PWMC_CPD;
|
||||
pwmp->reg->PWMC_CUPDR = width;
|
||||
} else {
|
||||
pwmp->reg->PWMC_CDTYR = width;
|
||||
PWMC_M->PWMC_ENA = pwmp->chbit;
|
||||
}
|
||||
|
||||
/* Step 7 */
|
||||
PWMC_M->PWMC_ENA = pwmp->chbit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a PWM channel.
|
||||
* @pre The PWM unit must have been activated using @p pwmStart().
|
||||
* @post The channel is disabled and its output line returned to the
|
||||
* idle state.
|
||||
* @note Depending on the hardware implementation this function has
|
||||
* effect starting on the next cycle (recommended implementation)
|
||||
* or immediately (fallback implementation).
|
||||
*
|
||||
* @param[in] pwmp pointer to a @p PWMDriver object
|
||||
* @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1)
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t UNUSED(channel)) {
|
||||
PWMC_M->PWMC_IDR = pwmp->chbit;
|
||||
PWMC_M->PWMC_DIS = pwmp->chbit;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PWM */
|
||||
|
||||
/** @} */
|
||||
284
firmware/chibios/os/hal/platforms/AT91SAM7/pwm_lld.h
Executable file
284
firmware/chibios/os/hal/platforms/AT91SAM7/pwm_lld.h
Executable file
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
/*
|
||||
This file has been contributed by:
|
||||
Andrew Hannam aka inmarket.
|
||||
*/
|
||||
/**
|
||||
* @file AT91SAM7/pwm_lld.h
|
||||
* @brief AT91SAM7 PWM Driver subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup PWM
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PWM_LLD_H_
|
||||
#define _PWM_LLD_H_
|
||||
|
||||
#if HAL_USE_PWM || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Number of PWM channels per PWM driver.
|
||||
*/
|
||||
#define PWM_CHANNELS 1
|
||||
|
||||
/**
|
||||
* @brief PWM device interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(AT91SAM7_PWM_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define AT91SAM7_PWM_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 4)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(PWM_USE_PWM1) || defined(__DOXYGEN__)
|
||||
#define PWM_USE_PWM1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(PWM_USE_PWM2) || defined(__DOXYGEN__)
|
||||
#define PWM_USE_PWM2 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(PWM_USE_PWM3) || defined(__DOXYGEN__)
|
||||
#define PWM_USE_PWM3 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWMD4 driver enable switch.
|
||||
* @details If set to @p TRUE the support for PWMD1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(PWM_USE_PWM4) || defined(__DOXYGEN__)
|
||||
#define PWM_USE_PWM4 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief PWM left (count up) logic
|
||||
*/
|
||||
#define PWM_OUTPUT_LEFT 0x00000000
|
||||
|
||||
/**
|
||||
* @brief PWM center (count up-down) logic. Gives symetric waveform
|
||||
*/
|
||||
#define PWM_OUTPUT_CENTER 0x00000010
|
||||
|
||||
/**
|
||||
* @brief PWM Master Clock = MCK / 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, CLKA or CLKB. CLKA or CLKB uses the frequency field
|
||||
*/
|
||||
#define PWM_MCK_DIV_1 0x00000000
|
||||
#define PWM_MCK_DIV_2 0x00000100
|
||||
#define PWM_MCK_DIV_4 0x00000200
|
||||
#define PWM_MCK_DIV_8 0x00000300
|
||||
#define PWM_MCK_DIV_16 0x00000400
|
||||
#define PWM_MCK_DIV_32 0x00000500
|
||||
#define PWM_MCK_DIV_64 0x00000600
|
||||
#define PWM_MCK_DIV_128 0x00000700
|
||||
#define PWM_MCK_DIV_256 0x00000800
|
||||
#define PWM_MCK_DIV_512 0x00000900
|
||||
#define PWM_MCK_DIV_1024 0x00000A00
|
||||
#define PWM_MCK_DIV_CLKA 0x00000B00
|
||||
#define PWM_MCK_DIV_CLKB 0x00000C00
|
||||
|
||||
/**
|
||||
* @brief Which PWM output pins to turn on. PIN1 is the lowest numbered pin, PIN2 next lowest, and then on some packages PIN3.
|
||||
*/
|
||||
#define PWM_OUTPUT_PIN1 0x00001000
|
||||
#define PWM_OUTPUT_PIN2 0x00002000
|
||||
#define PWM_OUTPUT_PIN3 0x00004000
|
||||
|
||||
/**
|
||||
* @brief Which PWM output pins should have pullups disabled.
|
||||
*/
|
||||
#define PWM_DISABLEPULLUP_PIN1 0x00010000
|
||||
#define PWM_DISABLEPULLUP_PIN2 0x00020000
|
||||
#define PWM_DISABLEPULLUP_PIN3 0x00040000
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief PWM mode type.
|
||||
*/
|
||||
typedef uint32_t pwmmode_t;
|
||||
|
||||
/**
|
||||
* @brief PWM channel type.
|
||||
*/
|
||||
typedef uint8_t pwmchannel_t;
|
||||
|
||||
/**
|
||||
* @brief PWM counter type.
|
||||
*/
|
||||
typedef uint16_t pwmcnt_t;
|
||||
|
||||
/**
|
||||
* @brief PWM driver channel configuration structure.
|
||||
* @note Some architectures may not be able to support the channel mode
|
||||
* or the callback, in this case the fields are ignored.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel active logic level.
|
||||
*/
|
||||
pwmmode_t mode;
|
||||
/**
|
||||
* @brief Channel callback pointer.
|
||||
* @note This callback is invoked on the channel compare event. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/* End of the mandatory fields.*/
|
||||
} PWMChannelConfig;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
uint32_t frequency;
|
||||
/**
|
||||
* @brief PWM period in ticks.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* period specifications.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
/**
|
||||
* @brief Periodic callback pointer.
|
||||
* @note This callback is invoked on PWM counter reset. If set to
|
||||
* @p NULL then the callback is disabled.
|
||||
*/
|
||||
pwmcallback_t callback;
|
||||
/**
|
||||
* @brief Channels configurations.
|
||||
*/
|
||||
PWMChannelConfig channels[PWM_CHANNELS];
|
||||
/* End of the mandatory fields.*/
|
||||
} PWMConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an PWM driver.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
struct PWMDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
pwmstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const PWMConfig *config;
|
||||
/**
|
||||
* @brief Current PWM period in ticks.
|
||||
*/
|
||||
pwmcnt_t period;
|
||||
#if defined(PWM_DRIVER_EXT_FIELDS)
|
||||
PWM_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
|
||||
/* End of the mandatory fields.*/
|
||||
|
||||
/**
|
||||
* @brief The PWM internal channel number as a bit mask (1, 2, 4 or 8).
|
||||
*/
|
||||
uint32_t chbit;
|
||||
/**
|
||||
* @brief Pointer to the PWMCx registers block.
|
||||
*/
|
||||
AT91S_PWMC_CH *reg;
|
||||
/**
|
||||
* @brief Pointer to the output pins descriptor.
|
||||
*/
|
||||
const struct pwmpindefs *pins;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if PWM_USE_PWM1 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD1;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM2 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD2;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM3 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD3;
|
||||
#endif
|
||||
|
||||
#if PWM_USE_PWM4 && !defined(__DOXYGEN__)
|
||||
extern PWMDriver PWMD4;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void pwm_lld_init(void);
|
||||
void pwm_lld_start(PWMDriver *pwmp);
|
||||
void pwm_lld_stop(PWMDriver *pwmp);
|
||||
void pwm_lld_change_period(PWMDriver *pwmp, pwmcnt_t period);
|
||||
void pwm_lld_enable_channel(PWMDriver *pwmp,
|
||||
pwmchannel_t channel,
|
||||
pwmcnt_t width);
|
||||
void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PWM */
|
||||
|
||||
#endif /* _PWM_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
444
firmware/chibios/os/hal/platforms/AT91SAM7/serial_lld.c
Executable file
444
firmware/chibios/os/hal/platforms/AT91SAM7/serial_lld.c
Executable file
@@ -0,0 +1,444 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/serial_lld.c
|
||||
* @brief AT91SAM7 low level serial driver code.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7S64) || (SAM7_PLATFORM == SAM7S128) || \
|
||||
(SAM7_PLATFORM == SAM7S256) || (SAM7_PLATFORM == SAM7S512)
|
||||
|
||||
#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 == SAM7X128) || (SAM7_PLATFORM == SAM7X256) || \
|
||||
(SAM7_PLATFORM == SAM7X512)
|
||||
|
||||
#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
|
||||
|
||||
#elif (SAM7_PLATFORM == SAM7A3)
|
||||
#define SAM7_USART0_RX AT91C_PA2_RXD0
|
||||
#define SAM7_USART0_TX AT91C_PA3_TXD0
|
||||
#define SAM7_USART1_RX AT91C_PA7_RXD1
|
||||
#define SAM7_USART1_TX AT91C_PA8_TXD1
|
||||
#define SAM7_USART2_RX AT91C_PA9_RXD2
|
||||
#define SAM7_USART2_TX AT91C_PA10_TXD2
|
||||
#define SAM7_DBGU_RX AT91C_PA30_DRXD
|
||||
#define SAM7_DBGU_TX AT91C_PA31_DTXD
|
||||
|
||||
#else
|
||||
#error "serial lines not defined for this SAM7 version"
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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 (SAM7_PLATFORM == SAM7A3)
|
||||
#if USE_SAM7_USART2 || defined(__DOXYGEN__)
|
||||
/** @brief USART2 serial driver identifier.*/
|
||||
SerialDriver SD3;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_SAM7_DBGU_UART || defined(__DOXYGEN__)
|
||||
/** @brief DBGU_UART serial driver identifier.*/
|
||||
SerialDriver SDDBG;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @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) {
|
||||
flagsmask_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();
|
||||
chnAddFlagsI(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) {
|
||||
chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY);
|
||||
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(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
AT91C_BASE_US0->US_IER = AT91C_US_TXRDY;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_SAM7_USART1 || defined(__DOXYGEN__)
|
||||
static void notify2(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
AT91C_BASE_US1->US_IER = AT91C_US_TXRDY;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7A3)
|
||||
#if USE_SAM7_USART2 || defined(__DOXYGEN__)
|
||||
static void notify3(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
AT91C_BASE_US2->US_IER = AT91C_US_TXRDY;
|
||||
}
|
||||
#endif
|
||||
#endif /* (SAM7_PLATFORM == SAM7A3) */
|
||||
|
||||
#if USE_SAM7_DBGU_UART || defined(__DOXYGEN__)
|
||||
static void notify_dbg(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
AT91C_BASE_DBGU->DBGU_IER = AT91C_US_TXRDY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_SAM7_USART0 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief USART0 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
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__)
|
||||
/**
|
||||
* @brief USART1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(USART1IrqHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
sd_lld_serve_interrupt(&SD2);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7A3)
|
||||
#if USE_SAM7_USART2 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief USART2 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(USART2IrqHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
sd_lld_serve_interrupt(&SD3);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
#endif /* (SAM7_PLATFORM == SAM7A3) */
|
||||
|
||||
/* 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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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 (SAM7_PLATFORM == SAM7A3)
|
||||
#if USE_SAM7_USART2
|
||||
sdObjectInit(&SD3, NULL, notify3);
|
||||
SD3.usart = AT91C_BASE_US2;
|
||||
AT91C_BASE_PIOA->PIO_PDR = SAM7_USART2_RX | SAM7_USART2_TX;
|
||||
AT91C_BASE_PIOA->PIO_ASR = SAM7_USART2_RX | SAM7_USART2_TX;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = SAM7_USART2_RX | SAM7_USART2_TX;
|
||||
AIC_ConfigureIT(AT91C_ID_US2,
|
||||
AT91C_AIC_SRCTYPE_HIGH_LEVEL | SAM7_USART2_PRIORITY,
|
||||
USART2IrqHandler);
|
||||
#endif
|
||||
#endif /* (SAM7_PLATFORM == SAM7A3) */
|
||||
|
||||
#if USE_SAM7_DBGU_UART
|
||||
sdObjectInit(&SDDBG, NULL, notify_dbg);
|
||||
/* 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.*/
|
||||
SDDBG.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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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
|
||||
#if (SAM7_PLATFORM == SAM7A3)
|
||||
#if USE_SAM7_USART2
|
||||
if (&SD3 == sdp) {
|
||||
/* Starts the clock and clears possible sources of immediate interrupts.*/
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_US2);
|
||||
/* Enables associated interrupt vector.*/
|
||||
AIC_EnableIT(AT91C_ID_US2);
|
||||
}
|
||||
#endif
|
||||
#endif /* (SAM7_PLATFORM == SAM7A3) */
|
||||
/* 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
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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 (&SDDBG == sdp) {
|
||||
AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SERIAL */
|
||||
|
||||
/** @} */
|
||||
191
firmware/chibios/os/hal/platforms/AT91SAM7/serial_lld.h
Executable file
191
firmware/chibios/os/hal/platforms/AT91SAM7/serial_lld.h
Executable file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/serial_lld.h
|
||||
* @brief AT91SAM7 low level serial driver header.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_LLD_H_
|
||||
#define _SERIAL_LLD_H_
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief UART0 driver enable switch.
|
||||
* @details If set to @p TRUE the support for 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
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7A3)
|
||||
/**
|
||||
* @brief UART2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for USART3 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(USE_SAM7_USART2) || defined(__DOXYGEN__)
|
||||
#define USE_SAM7_USART2 TRUE
|
||||
#endif
|
||||
#endif /* (SAM7_PLATFORM == SAM7A3) */
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
#if (SAM7_PLATFORM == SAM7A3)
|
||||
/**
|
||||
* @brief UART2 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(SAM7_USART2_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define SAM7_USART2_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 2)
|
||||
#endif
|
||||
#endif /* (SAM7_PLATFORM == SAM7A3) */
|
||||
|
||||
/**
|
||||
* @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 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; \
|
||||
/* 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 (SAM7_PLATFORM == SAM7A3)
|
||||
#if USE_SAM7_USART2 && !defined(__DOXYGEN__)
|
||||
extern SerialDriver SD3;
|
||||
#endif
|
||||
#endif
|
||||
#if USE_SAM7_DBGU_UART
|
||||
extern SerialDriver SDDBG;
|
||||
#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 /* HAL_USE_SERIAL */
|
||||
|
||||
#endif /* _SERIAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
436
firmware/chibios/os/hal/platforms/AT91SAM7/spi_lld.c
Executable file
436
firmware/chibios/os/hal/platforms/AT91SAM7/spi_lld.c
Executable file
@@ -0,0 +1,436 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/spi_lld.c
|
||||
* @brief AT91SAM7 low level SPI driver code.
|
||||
*
|
||||
* @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI0 || defined(__DOXYGEN__)
|
||||
/** @brief SPI1 driver identifier.*/
|
||||
SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI1 || defined(__DOXYGEN__)
|
||||
/** @brief SPI2 driver identifier.*/
|
||||
SPIDriver SPID2;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Idle line value.
|
||||
* @details This thing's DMA apparently does not allow to *not* increment
|
||||
* the memory pointer so a buffer filled with ones is required
|
||||
* somewhere.
|
||||
* @note This buffer size also limits the maximum transfer size, 512B,
|
||||
* for @p spiReceive() and @p spiIgnore(). @p spiSend() and
|
||||
* @p spiExchange are not affected.
|
||||
*/
|
||||
static const uint16_t idle_buf[] = {
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
|
||||
0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes a SPI device.
|
||||
*/
|
||||
static void spi_init(AT91PS_SPI spi) {
|
||||
|
||||
/* Software reset must be written twice (errata for revision B parts).*/
|
||||
spi->SPI_CR = AT91C_SPI_SWRST;
|
||||
spi->SPI_CR = AT91C_SPI_SWRST;
|
||||
spi->SPI_RCR = 0;
|
||||
spi->SPI_RNCR = 0;
|
||||
spi->SPI_TCR = 0;
|
||||
spi->SPI_TNCR = 0;
|
||||
spi->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
|
||||
spi->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((noinline))
|
||||
#endif
|
||||
/**
|
||||
* @brief Shared interrupt handling code.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*/
|
||||
static void spi_lld_serve_interrupt(SPIDriver *spip) {
|
||||
uint32_t sr = spip->spi->SPI_SR;
|
||||
|
||||
if ((sr & AT91C_SPI_ENDRX) != 0) {
|
||||
(void)spip->spi->SPI_RDR; /* Clears eventual overflow.*/
|
||||
spip->spi->SPI_PTCR = AT91C_PDC_RXTDIS |
|
||||
AT91C_PDC_TXTDIS; /* PDC disabled. */
|
||||
spip->spi->SPI_IDR = AT91C_SPI_ENDRX; /* Interrupt disabled. */
|
||||
spip->spi->SPI_CR = AT91C_SPI_SPIDIS; /* SPI disabled. */
|
||||
/* Portable SPI ISR code defined in the high level driver, note, it is
|
||||
a macro.*/
|
||||
_spi_isr_code(spip);
|
||||
}
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI0 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief SPI0 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPI0IrqHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
spi_lld_serve_interrupt(&SPID1);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI1 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief SPI1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(SPI1IrqHandler) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
spi_lld_serve_interrupt(&SPID2);
|
||||
AT91C_BASE_AIC->AIC_EOICR = 0;
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level SPI driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_init(void) {
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI0
|
||||
spiObjectInit(&SPID1);
|
||||
SPID1.spi = AT91C_BASE_SPI0;
|
||||
spi_init(AT91C_BASE_SPI0);
|
||||
AT91C_BASE_PIOA->PIO_PDR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
|
||||
AT91C_BASE_PIOA->PIO_ASR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
|
||||
AIC_ConfigureIT(AT91C_ID_SPI0,
|
||||
AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91SAM7_SPI0_PRIORITY,
|
||||
SPI0IrqHandler);
|
||||
#endif
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI1
|
||||
spiObjectInit(&SPID2);
|
||||
SPID2.spi = AT91C_BASE_SPI1;
|
||||
spi_init(AT91C_BASE_SPI1);
|
||||
AT91C_BASE_PIOA->PIO_PDR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
|
||||
AT91C_BASE_PIOA->PIO_BSR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
|
||||
AT91C_BASE_PIOA->PIO_PPUDR = SPI1_MISO | SPI1_MOSI | SPI1_SCK;
|
||||
AIC_ConfigureIT(AT91C_ID_SPI1,
|
||||
AT91C_AIC_SRCTYPE_HIGH_LEVEL | AT91SAM7_SPI1_PRIORITY,
|
||||
SPI1IrqHandler);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_start(SPIDriver *spip) {
|
||||
|
||||
if (spip->state == SPI_STOP) {
|
||||
#if AT91SAM7_SPI_USE_SPI0
|
||||
if (&SPID1 == spip) {
|
||||
/* Clock activation.*/
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI0);
|
||||
/* Enables associated interrupt vector.*/
|
||||
AIC_EnableIT(AT91C_ID_SPI0);
|
||||
// Setup the chip select pin
|
||||
// No bug here but control CS0 automatically anyway
|
||||
if (spip->config->ssport == AT91C_BASE_PIOA && spip->config->sspad == SPI0_CS0) {
|
||||
AT91C_BASE_PIOA->PIO_PDR = 1 << SPI0_CS0;
|
||||
AT91C_BASE_PIOA->PIO_OER = 1 << SPI0_CS0;
|
||||
AT91C_BASE_PIOA->PIO_ASR = 1 << SPI0_CS0;
|
||||
} else if (spip->config->ssport) {
|
||||
uint32_t mask;
|
||||
|
||||
mask = 1 << spip->config->sspad;
|
||||
spip->config->ssport->PIO_SODR = mask;
|
||||
spip->config->ssport->PIO_OER = mask;
|
||||
spip->config->ssport->PIO_PER = mask;
|
||||
spip->config->ssport->PIO_MDDR = mask;
|
||||
spip->config->ssport->PIO_PPUDR = mask;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if AT91SAM7_SPI_USE_SPI1
|
||||
if (&SPID2 == spip) {
|
||||
/* Clock activation.*/
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI1);
|
||||
/* Enables associated interrupt vector.*/
|
||||
AIC_EnableIT(AT91C_ID_SPI1);
|
||||
// Setup the chip select pin
|
||||
// A bug in SPI1 requires that the CS be automatically controlled if it matches the CS0 pin.
|
||||
// If it is not automatically controlled SPI1 will turn off when data is written.
|
||||
// If you are not using CS0 make absolutely sure you don't use it as an output pin and
|
||||
// clear it otherwise you will get the bug in anyway.
|
||||
if (spip->config->ssport == AT91C_BASE_PIOA && spip->config->sspad == SPI1_CS0) {
|
||||
AT91C_BASE_PIOA->PIO_PDR = 1 << SPI1_CS0;
|
||||
AT91C_BASE_PIOA->PIO_OER = 1 << SPI1_CS0;
|
||||
AT91C_BASE_PIOA->PIO_BSR = 1 << SPI1_CS0;
|
||||
} else if (spip->config->ssport) {
|
||||
uint32_t mask;
|
||||
|
||||
mask = 1 << spip->config->sspad;
|
||||
spip->config->ssport->PIO_SODR = mask;
|
||||
spip->config->ssport->PIO_OER = mask;
|
||||
spip->config->ssport->PIO_PER = mask;
|
||||
spip->config->ssport->PIO_MDDR = mask;
|
||||
spip->config->ssport->PIO_PPUDR = mask;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Configuration.*/
|
||||
spip->spi->SPI_CSR[0] = spip->config->csr;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the SPI peripheral.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_stop(SPIDriver *spip) {
|
||||
|
||||
if (spip->state != SPI_STOP) {
|
||||
#if AT91SAM7_SPI_USE_SPI0
|
||||
if (&SPID1 == spip) {
|
||||
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_SPI0);
|
||||
AIC_DisableIT(AT91C_ID_SPI0);
|
||||
}
|
||||
#endif
|
||||
#if AT91SAM7_SPI_USE_SPI1
|
||||
if (&SPID1 == spip) {
|
||||
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_SPI1);
|
||||
AIC_DisableIT(AT91C_ID_SPI0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Asserts the slave select signal and prepares for transfers.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_select(SPIDriver *spip) {
|
||||
|
||||
// Not needed for CS0 but it doesn't hurt either
|
||||
palClearPad(spip->config->ssport, spip->config->sspad);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deasserts the slave select signal.
|
||||
* @details The previously selected peripheral is unselected.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_unselect(SPIDriver *spip) {
|
||||
|
||||
// Not needed for CS0 but it doesn't hurt either
|
||||
palSetPad(spip->config->ssport, spip->config->sspad);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ignores data on the SPI bus.
|
||||
* @details This function transmits a series of idle words on the SPI bus and
|
||||
* ignores the received data. This function can be invoked even
|
||||
* when a slave select signal has not been yet asserted.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be ignored
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_ignore(SPIDriver *spip, size_t n) {
|
||||
|
||||
spip->spi->SPI_TCR = n;
|
||||
spip->spi->SPI_RCR = n;
|
||||
spip->spi->SPI_TPR = (AT91_REG)idle_buf;
|
||||
spip->spi->SPI_RPR = (AT91_REG)idle_buf;
|
||||
spip->spi->SPI_IER = AT91C_SPI_ENDRX;
|
||||
spip->spi->SPI_CR = AT91C_SPI_SPIEN;
|
||||
spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges data on the SPI bus.
|
||||
* @details This function performs a simultaneous transmit/receive operation.
|
||||
* @note The buffers are organized as uint8_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to be exchanged
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf) {
|
||||
|
||||
spip->spi->SPI_TCR = n;
|
||||
spip->spi->SPI_RCR = n;
|
||||
spip->spi->SPI_TPR = (AT91_REG)txbuf;
|
||||
spip->spi->SPI_RPR = (AT91_REG)rxbuf;
|
||||
spip->spi->SPI_IER = AT91C_SPI_ENDRX;
|
||||
spip->spi->SPI_CR = AT91C_SPI_SPIEN;
|
||||
spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends data over the SPI bus.
|
||||
* @note The buffers are organized as uint8_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to send
|
||||
* @param[in] txbuf the pointer to the transmit buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) {
|
||||
|
||||
spip->spi->SPI_TCR = n;
|
||||
spip->spi->SPI_RCR = n;
|
||||
spip->spi->SPI_TPR = (AT91_REG)txbuf;
|
||||
spip->spi->SPI_RPR = (AT91_REG)idle_buf;
|
||||
spip->spi->SPI_IER = AT91C_SPI_ENDRX;
|
||||
spip->spi->SPI_CR = AT91C_SPI_SPIEN;
|
||||
spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives data from the SPI bus.
|
||||
* @note The buffers are organized as uint8_t arrays.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] n number of words to receive
|
||||
* @param[out] rxbuf the pointer to the receive buffer
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) {
|
||||
|
||||
spip->spi->SPI_TCR = n;
|
||||
spip->spi->SPI_RCR = n;
|
||||
spip->spi->SPI_TPR = (AT91_REG)idle_buf;
|
||||
spip->spi->SPI_RPR = (AT91_REG)rxbuf;
|
||||
spip->spi->SPI_IER = AT91C_SPI_ENDRX;
|
||||
spip->spi->SPI_CR = AT91C_SPI_SPIEN;
|
||||
spip->spi->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exchanges one frame using a polled wait.
|
||||
* @details This synchronous function exchanges one frame using a polled
|
||||
* synchronization method. This function is useful when exchanging
|
||||
* small amount of data on high speed channels, usually in this
|
||||
* situation is much more efficient just wait for completion using
|
||||
* polling than suspending the thread waiting for an interrupt.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object
|
||||
* @param[in] frame the data frame to send over the SPI bus
|
||||
* @return The received data frame from the SPI bus.
|
||||
*/
|
||||
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame) {
|
||||
|
||||
spip->spi->SPI_CR = AT91C_SPI_SPIEN;
|
||||
spip->spi->SPI_TDR = frame;
|
||||
while ((spip->spi->SPI_SR & AT91C_SPI_RDRF) == 0)
|
||||
;
|
||||
return spip->spi->SPI_RDR;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SPI */
|
||||
|
||||
/** @} */
|
||||
234
firmware/chibios/os/hal/platforms/AT91SAM7/spi_lld.h
Executable file
234
firmware/chibios/os/hal/platforms/AT91SAM7/spi_lld.h
Executable file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AT91SAM7/spi_lld.h
|
||||
* @brief AT91SAM7 low level SPI driver header.
|
||||
*
|
||||
* @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SPI_LLD_H_
|
||||
#define _SPI_LLD_H_
|
||||
|
||||
#if HAL_USE_SPI || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Device compatibility.. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if SAM7_PLATFORM == SAM7S512 || SAM7_PLATFORM == SAM7S256 || SAM7_PLATFORM == SAM7S128 || SAM7_PLATFORM == SAM7S64
|
||||
#define SPI0_MISO AT91C_PA12_MISO
|
||||
#define SPI0_MOSI AT91C_PA13_MOSI
|
||||
#define SPI0_SCK AT91C_PA14_SPCK
|
||||
#define SPI0_CS0 11 // PA11
|
||||
#elif SAM7_PLATFORM == SAM7X512 || SAM7_PLATFORM == SAM7X256 || SAM7_PLATFORM == SAM7X128
|
||||
#define SPI0_MISO AT91C_PA16_SPI0_MISO
|
||||
#define SPI0_MOSI AT91C_PA17_SPI0_MOSI
|
||||
#define SPI0_SCK AT91C_PA18_SPI0_SPCK
|
||||
#define SPI0_CS0 12 // PA12
|
||||
#define SPI1_MISO AT91C_PA24_SPI1_MISO
|
||||
#define SPI1_MOSI AT91C_PA23_SPI1_MOSI
|
||||
#define SPI1_SCK AT91C_PA22_SPI1_SPCK
|
||||
#define SPI1_CS0 21 // PA21
|
||||
#elif SAM7_PLATFORM == SAM7A3
|
||||
#define SPI0_MISO AT91C_PA15_SPI0_MISO
|
||||
#define SPI0_MOSI AT91C_PA16_SPI0_MOSI
|
||||
#define SPI0_SCK AT91C_PA17_SPI0_SPCK
|
||||
#define SPI0_CS0 11 // PA11
|
||||
#define SPI1_MISO AT91C_PA8_SPI1_MISO
|
||||
#define SPI1_MOSI AT91C_PA9_SPI1_MOSI
|
||||
#define SPI1_SCK AT91C_PA10_SPI1_SPCK
|
||||
#define SPI1_CS0 4 // PA4
|
||||
#else
|
||||
#error "SAM7 platform not supported"
|
||||
#endif
|
||||
|
||||
#if defined (AT91C_BASE_SPI)
|
||||
#define AT91C_BASE_SPI0 AT91C_BASE_SPI
|
||||
#define AT91C_ID_SPI0 AT91C_ID_SPI
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief SPID1 enable switch (SPI0 device).
|
||||
* @details If set to @p TRUE the support for SPI0 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(AT91SAM7_SPI_USE_SPI0) || defined(__DOXYGEN__)
|
||||
#define AT91SAM7_SPI_USE_SPI0 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPID2 enable switch (SPI1 device).
|
||||
* @details If set to @p TRUE the support for SPI1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(AT91SAM7_SPI_USE_SPI1) || defined(__DOXYGEN__)
|
||||
#define AT91SAM7_SPI_USE_SPI1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI0 device interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(AT91SAM7_SPI0_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define AT91SAM7_SPI0_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief SPI1 device interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(AT91SAM7_SPI1_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define AT91SAM7_SPI1_PRIORITY (AT91C_AIC_PRIOR_HIGHEST - 1)
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined (AT91C_BASE_SPI) && AT91SAM7_SPI_USE_SPI1
|
||||
#error "SPI1 not present"
|
||||
#endif
|
||||
|
||||
#if !AT91SAM7_SPI_USE_SPI0 && !AT91SAM7_SPI_USE_SPI1
|
||||
#error "SPI driver activated but no SPI peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an SPI driver.
|
||||
*/
|
||||
typedef struct SPIDriver SPIDriver;
|
||||
|
||||
/**
|
||||
* @brief SPI notification callback type.
|
||||
*
|
||||
* @param[in] spip pointer to the @p SPIDriver object triggering the
|
||||
* callback
|
||||
*/
|
||||
typedef void (*spicallback_t)(SPIDriver *spip);
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Operation complete callback or @p NULL.
|
||||
*/
|
||||
spicallback_t end_cb;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief The chip select line port.
|
||||
*/
|
||||
ioportid_t ssport;
|
||||
/**
|
||||
* @brief The chip select line pad number.
|
||||
*/
|
||||
uint16_t sspad;
|
||||
/**
|
||||
* @brief SPI Chip Select Register initialization data.
|
||||
*/
|
||||
uint32_t csr;
|
||||
} SPIConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a SPI driver.
|
||||
*/
|
||||
struct SPIDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
spistate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const SPIConfig *config;
|
||||
#if SPI_USE_WAIT || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Waiting thread.
|
||||
*/
|
||||
Thread *thread;
|
||||
#endif /* SPI_USE_WAIT */
|
||||
#if SPI_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the bus.
|
||||
*/
|
||||
Mutex mutex;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
Semaphore semaphore;
|
||||
#endif
|
||||
#endif /* SPI_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(SPI_DRIVER_EXT_FIELDS)
|
||||
SPI_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the SPIx registers block.
|
||||
*/
|
||||
AT91PS_SPI spi;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI0 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID1;
|
||||
#endif
|
||||
|
||||
#if AT91SAM7_SPI_USE_SPI1 && !defined(__DOXYGEN__)
|
||||
extern SPIDriver SPID2;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void spi_lld_init(void);
|
||||
void spi_lld_start(SPIDriver *spip);
|
||||
void spi_lld_stop(SPIDriver *spip);
|
||||
void spi_lld_select(SPIDriver *spip);
|
||||
void spi_lld_unselect(SPIDriver *spip);
|
||||
void spi_lld_ignore(SPIDriver *spip, size_t n);
|
||||
void spi_lld_exchange(SPIDriver *spip, size_t n,
|
||||
const void *txbuf, void *rxbuf);
|
||||
void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf);
|
||||
void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf);
|
||||
uint16_t spi_lld_polled_exchange(SPIDriver *spip, uint16_t frame);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_SPI */
|
||||
|
||||
#endif /* _SPI_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
57
firmware/chibios/os/hal/platforms/AVR/hal_lld.c
Executable file
57
firmware/chibios/os/hal/platforms/AVR/hal_lld.c
Executable file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/hal_lld.c
|
||||
* @brief AVR HAL subsystem low level driver code.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level HAL driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void hal_lld_init(void) {
|
||||
|
||||
}
|
||||
|
||||
/** @} */
|
||||
72
firmware/chibios/os/hal/platforms/AVR/hal_lld.h
Executable file
72
firmware/chibios/os/hal/platforms/AVR/hal_lld.h
Executable file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/hal_lld.h
|
||||
* @brief AVR HAL subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup HAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _HAL_LLD_H_
|
||||
#define _HAL_LLD_H_
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Defines the support for realtime counters in the HAL.
|
||||
*/
|
||||
#define HAL_IMPLEMENTS_COUNTERS FALSE
|
||||
|
||||
/**
|
||||
* @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_ */
|
||||
|
||||
/** @} */
|
||||
289
firmware/chibios/os/hal/platforms/AVR/i2c_lld.c
Executable file
289
firmware/chibios/os/hal/platforms/AVR/i2c_lld.c
Executable file
@@ -0,0 +1,289 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/i2c_lld.c
|
||||
* @brief AVR I2C subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief I2C driver identifier.*/
|
||||
#if USE_AVR_I2C || defined(__DOXYGEN__)
|
||||
I2CDriver I2CD;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Wakes up the waiting thread.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
* @param[in] msg wakeup message
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define wakeup_isr(i2cp, msg) { \
|
||||
chSysLockFromIsr(); \
|
||||
if ((i2cp)->thread != NULL) { \
|
||||
Thread *tp = (i2cp)->thread; \
|
||||
(i2cp)->thread = NULL; \
|
||||
tp->p_u.rdymsg = (msg); \
|
||||
chSchReadyI(tp); \
|
||||
} \
|
||||
chSysUnlockFromIsr(); \
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if USE_AVR_I2C || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief I2C event interrupt handler.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
CH_IRQ_HANDLER(TWI_vect) {
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
I2CDriver *i2cp = &I2CD;
|
||||
|
||||
switch (TWSR & 0xF8) {
|
||||
case TWI_START:
|
||||
case TWI_REPEAT_START:
|
||||
TWDR = (i2cp->addr << 1);
|
||||
if ((i2cp->txbuf == NULL) || (i2cp->txbytes == 0) || (i2cp->txidx == i2cp->txbytes)) {
|
||||
TWDR |= 0x01;
|
||||
}
|
||||
TWCR = ((1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
break;
|
||||
case TWI_MASTER_TX_ADDR_ACK:
|
||||
case TWI_MASTER_TX_DATA_ACK:
|
||||
if (i2cp->txidx < i2cp->txbytes) {
|
||||
TWDR = i2cp->txbuf[i2cp->txidx++];
|
||||
TWCR = ((1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
} else {
|
||||
if (i2cp->rxbuf && i2cp->rxbytes) {
|
||||
TWCR = ((1 << TWSTA) | (1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
} else {
|
||||
TWCR = ((1 << TWSTO) | (1 << TWINT) | (1 << TWEN));
|
||||
wakeup_isr(i2cp, RDY_OK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TWI_MASTER_RX_ADDR_ACK:
|
||||
if (i2cp->rxidx == (i2cp->rxbytes - 1)) {
|
||||
TWCR = ((1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
} else {
|
||||
TWCR = ((1 << TWEA) | (1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
}
|
||||
break;
|
||||
case TWI_MASTER_RX_DATA_ACK:
|
||||
i2cp->rxbuf[i2cp->rxidx++] = TWDR;
|
||||
if (i2cp->rxidx == (i2cp->rxbytes - 1)) {
|
||||
TWCR = ((1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
} else {
|
||||
TWCR = ((1 << TWEA) | (1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
}
|
||||
break;
|
||||
case TWI_MASTER_RX_DATA_NACK:
|
||||
i2cp->rxbuf[i2cp->rxidx] = TWDR;
|
||||
TWCR = ((1 << TWSTO) | (1 << TWINT) | (1 << TWEN));
|
||||
wakeup_isr(i2cp, RDY_OK);
|
||||
case TWI_MASTER_TX_ADDR_NACK:
|
||||
case TWI_MASTER_TX_DATA_NACK:
|
||||
case TWI_MASTER_RX_ADDR_NACK:
|
||||
i2cp->errors |= I2CD_ACK_FAILURE;
|
||||
break;
|
||||
case TWI_ARBITRATION_LOST:
|
||||
i2cp->errors |= I2CD_ARBITRATION_LOST;
|
||||
break;
|
||||
case TWI_BUS_ERROR:
|
||||
i2cp->errors |= I2CD_BUS_ERROR;
|
||||
break;
|
||||
default:
|
||||
/* FIXME: only gets here if there are other MASTERs in the bus */
|
||||
TWCR = ((1 << TWSTO) | (1 << TWINT) | (1 << TWEN));
|
||||
wakeup_isr(i2cp, RDY_RESET);
|
||||
}
|
||||
|
||||
if (i2cp->errors != I2CD_NO_ERROR) {
|
||||
TWCR = ((1 << TWSTO) | (1 << TWINT) | (1 << TWEN));
|
||||
wakeup_isr(i2cp, RDY_RESET);
|
||||
}
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* USE_AVR_I2C */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level I2C driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void i2c_lld_init(void) {
|
||||
i2cObjectInit(&I2CD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the I2C peripheral.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void i2c_lld_start(I2CDriver *i2cp) {
|
||||
|
||||
/* TODO: Test TWI without external pull-ups (use internal) */
|
||||
|
||||
/* Configure prescaler to 1 */
|
||||
TWSR &= 0xF8;
|
||||
|
||||
/* Configure baudrate */
|
||||
TWBR = ((F_CPU / i2cp->config->clock_speed) - 16) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the I2C peripheral.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void i2c_lld_stop(I2CDriver *i2cp) {
|
||||
|
||||
if (i2cp->state != I2C_STOP) {
|
||||
/* Disable TWI subsystem and stop all operations */
|
||||
TWCR &= ~(1 << TWEN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives data via the I2C bus as master.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
* @param[in] addr slave device address
|
||||
* @param[out] rxbuf pointer to the receive buffer
|
||||
* @param[in] rxbytes number of bytes to be received
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the function succeeded.
|
||||
* @retval RDY_RESET if one or more I2C errors occurred, the errors can
|
||||
* be retrieved using @p i2cGetErrors().
|
||||
* @retval RDY_TIMEOUT if a timeout occurred before operation end. <b>After a
|
||||
* timeout the driver must be stopped and restarted
|
||||
* because the bus is in an uncertain state</b>.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout) {
|
||||
i2cp->addr = addr;
|
||||
i2cp->txbuf = NULL;
|
||||
i2cp->txbytes = 0;
|
||||
i2cp->txidx = 0;
|
||||
i2cp->rxbuf = rxbuf;
|
||||
i2cp->rxbytes = rxbytes;
|
||||
i2cp->rxidx = 0;
|
||||
|
||||
/* Send START */
|
||||
TWCR = ((1 << TWSTA) | (1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
|
||||
chSysLock();
|
||||
i2cp->thread = chThdSelf();
|
||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||
chSysUnlock();
|
||||
|
||||
return chThdSelf()->p_u.rdymsg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Transmits data via the I2C bus as master.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
* @param[in] addr slave device address
|
||||
* @param[in] txbuf pointer to the transmit buffer
|
||||
* @param[in] txbytes number of bytes to be transmitted
|
||||
* @param[out] rxbuf pointer to the receive buffer
|
||||
* @param[in] rxbytes number of bytes to be received
|
||||
* @param[in] timeout the number of ticks before the operation timeouts,
|
||||
* the following special values are allowed:
|
||||
* - @a TIME_INFINITE no timeout.
|
||||
* .
|
||||
* @return The operation status.
|
||||
* @retval RDY_OK if the function succeeded.
|
||||
* @retval RDY_RESET if one or more I2C errors occurred, the errors can
|
||||
* be retrieved using @p i2cGetErrors().
|
||||
* @retval RDY_TIMEOUT if a timeout occurred before operation end. <b>After a
|
||||
* timeout the driver must be stopped and restarted
|
||||
* because the bus is in an uncertain state</b>.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
const uint8_t *txbuf, size_t txbytes,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout) {
|
||||
i2cp->addr = addr;
|
||||
i2cp->txbuf = txbuf;
|
||||
i2cp->txbytes = txbytes;
|
||||
i2cp->txidx = 0;
|
||||
i2cp->rxbuf = rxbuf;
|
||||
i2cp->rxbytes = rxbytes;
|
||||
i2cp->rxidx = 0;
|
||||
|
||||
TWCR = ((1 << TWSTA) | (1 << TWINT) | (1 << TWEN) | (1 << TWIE));
|
||||
|
||||
chSysLock();
|
||||
i2cp->thread = chThdSelf();
|
||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||
chSysUnlock();
|
||||
|
||||
return chThdSelf()->p_u.rdymsg;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_I2C */
|
||||
|
||||
/** @} */
|
||||
224
firmware/chibios/os/hal/platforms/AVR/i2c_lld.h
Executable file
224
firmware/chibios/os/hal/platforms/AVR/i2c_lld.h
Executable file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/i2c_lld.h
|
||||
* @brief AVR I2C subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _I2C_LLD_H_
|
||||
#define _I2C_LLD_H_
|
||||
|
||||
#if HAL_USE_I2C || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/** @brief START transmitted.*/
|
||||
#define TWI_START 0x08
|
||||
/** @brief Repeated START transmitted.*/
|
||||
#define TWI_REPEAT_START 0x10
|
||||
/** @brief Arbitration Lost.*/
|
||||
#define TWI_ARBITRATION_LOST 0x38
|
||||
/** @brief Bus errors.*/
|
||||
#define TWI_BUS_ERROR 0x00
|
||||
|
||||
/** @brief SLA+W transmitted with ACK response.*/
|
||||
#define TWI_MASTER_TX_ADDR_ACK 0x18
|
||||
/** @brief SLA+W transmitted with NACK response.*/
|
||||
#define TWI_MASTER_TX_ADDR_NACK 0x20
|
||||
/** @brief DATA transmitted with ACK response.*/
|
||||
#define TWI_MASTER_TX_DATA_ACK 0x28
|
||||
/** @brief DATA transmitted with NACK response.*/
|
||||
#define TWI_MASTER_TX_DATA_NACK 0x30
|
||||
|
||||
/** @brief SLA+R transmitted with ACK response.*/
|
||||
#define TWI_MASTER_RX_ADDR_ACK 0x40
|
||||
/** @brief SLA+R transmitted with NACK response.*/
|
||||
#define TWI_MASTER_RX_ADDR_NACK 0x48
|
||||
/** @brief DATA received with ACK response.*/
|
||||
#define TWI_MASTER_RX_DATA_ACK 0x50
|
||||
/** @brief DATA received with NACK response.*/
|
||||
#define TWI_MASTER_RX_DATA_NACK 0x58
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief I2C driver enable switch.
|
||||
* @details If set to @p TRUE the support for I2C is included.
|
||||
* @note The default is @p FALSE.
|
||||
*/
|
||||
#if !defined(USE_AVR_I2C) || defined(__DOXYGEN__)
|
||||
#define USE_AVR_I2C FALSE
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Type representing I2C address.
|
||||
*/
|
||||
typedef uint8_t i2caddr_t;
|
||||
|
||||
/**
|
||||
* @brief I2C Driver condition flags type.
|
||||
*/
|
||||
typedef uint8_t i2cflags_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note Implementations may extend this structure to contain more,
|
||||
* architecture dependent, fields.
|
||||
*/
|
||||
typedef struct {
|
||||
|
||||
/**
|
||||
* @brief Specifies the I2C clock frequency.
|
||||
*/
|
||||
uint32_t clock_speed;
|
||||
|
||||
} I2CConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an I2C driver.
|
||||
*/
|
||||
struct I2CDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
i2cstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const I2CConfig *config;
|
||||
/**
|
||||
* @brief Error flags.
|
||||
*/
|
||||
i2cflags_t errors;
|
||||
#if I2C_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
|
||||
#if CH_USE_MUTEXES || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Mutex protecting the bus.
|
||||
*/
|
||||
Mutex mutex;
|
||||
#elif CH_USE_SEMAPHORES
|
||||
Semaphore semaphore;
|
||||
#endif
|
||||
#endif /* I2C_USE_MUTUAL_EXCLUSION */
|
||||
#if defined(I2C_DRIVER_EXT_FIELDS)
|
||||
I2C_DRIVER_EXT_FIELDS
|
||||
#endif
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Thread waiting for I/O completion.
|
||||
*/
|
||||
Thread *thread;
|
||||
/**
|
||||
* @brief Address of slave device.
|
||||
*/
|
||||
i2caddr_t addr;
|
||||
/**
|
||||
* @brief Pointer to the buffer with data to send.
|
||||
*/
|
||||
const uint8_t *txbuf;
|
||||
/**
|
||||
* @brief Number of bytes of data to send.
|
||||
*/
|
||||
size_t txbytes;
|
||||
/**
|
||||
* @brief Current index in buffer when sending data.
|
||||
*/
|
||||
size_t txidx;
|
||||
/**
|
||||
* @brief Pointer to the buffer to put received data.
|
||||
*/
|
||||
uint8_t *rxbuf;
|
||||
/**
|
||||
* @brief Number of bytes of data to receive.
|
||||
*/
|
||||
size_t rxbytes;
|
||||
/**
|
||||
* @brief Current index in buffer when receiving data.
|
||||
*/
|
||||
size_t rxidx;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Type of a structure representing an I2C driver.
|
||||
*/
|
||||
typedef struct I2CDriver I2CDriver;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Get errors from I2C driver.
|
||||
*
|
||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define i2c_lld_get_errors(i2cp) ((i2cp)->errors)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
#if USE_AVR_I2C
|
||||
extern I2CDriver I2CD;
|
||||
#endif
|
||||
#endif /* !defined(__DOXYGEN__) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void i2c_lld_init(void);
|
||||
void i2c_lld_start(I2CDriver *i2cp);
|
||||
void i2c_lld_stop(I2CDriver *i2cp);
|
||||
msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
const uint8_t *txbuf, size_t txbytes,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout);
|
||||
msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||
uint8_t *rxbuf, size_t rxbytes,
|
||||
systime_t timeout);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_I2C */
|
||||
|
||||
#endif /* _I2C_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
157
firmware/chibios/os/hal/platforms/AVR/pal_lld.c
Executable file
157
firmware/chibios/os/hal/platforms/AVR/pal_lld.c
Executable file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/pal_lld.c
|
||||
* @brief AVR GPIO low level driver code.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief AVR GPIO ports configuration.
|
||||
* @details GPIO registers initialization.
|
||||
*
|
||||
* @param[in] config the AVR ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_init(const PALConfig *config) {
|
||||
|
||||
#if defined(PORTA) || defined(__DOXYGEN__)
|
||||
PORTA = config->porta.out;
|
||||
DDRA = config->porta.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTB) || defined(__DOXYGEN__)
|
||||
PORTB = config->portb.out;
|
||||
DDRB = config->portb.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTC) || defined(__DOXYGEN__)
|
||||
PORTC = config->portc.out;
|
||||
DDRC = config->portc.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTD) || defined(__DOXYGEN__)
|
||||
PORTD = config->portd.out;
|
||||
DDRD = config->portd.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTE) || defined(__DOXYGEN__)
|
||||
PORTE = config->porte.out;
|
||||
DDRE = config->porte.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTF) || defined(__DOXYGEN__)
|
||||
PORTF = config->portf.out;
|
||||
DDRF = config->portf.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTG) || defined(__DOXYGEN__)
|
||||
PORTG = config->portg.out;
|
||||
DDRG = config->portg.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTH) || defined(__DOXYGEN__)
|
||||
PORTH = config->porth.out;
|
||||
DDRH = config->porth.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTJ) || defined(__DOXYGEN__)
|
||||
PORTJ = config->portj.out;
|
||||
DDRJ = config->portj.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTK) || defined(__DOXYGEN__)
|
||||
PORTK = config->portk.out;
|
||||
DDRK = config->portk.dir;
|
||||
#endif
|
||||
|
||||
#if defined(PORTL) || defined(__DOXYGEN__)
|
||||
PORTL = config->portl.out;
|
||||
DDRL = config->portl.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 AVR Family User's Guide. Unconnected pads are set to input
|
||||
* with pull-up by default.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode) {
|
||||
|
||||
switch (mode) {
|
||||
case PAL_MODE_RESET:
|
||||
case PAL_MODE_INPUT:
|
||||
case PAL_MODE_INPUT_ANALOG:
|
||||
port->dir &= ~mask;
|
||||
port->out &= ~mask;
|
||||
break;
|
||||
case PAL_MODE_UNCONNECTED:
|
||||
case PAL_MODE_INPUT_PULLUP:
|
||||
port->dir &= ~mask;
|
||||
port->out |= mask;
|
||||
break;
|
||||
case PAL_MODE_OUTPUT_PUSHPULL:
|
||||
port->dir |= mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
/** @} */
|
||||
329
firmware/chibios/os/hal/platforms/AVR/pal_lld.h
Executable file
329
firmware/chibios/os/hal/platforms/AVR/pal_lld.h
Executable file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/pal_lld.h
|
||||
* @brief AVR GPIO low level driver header.
|
||||
*
|
||||
* @addtogroup PAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _PAL_LLD_H_
|
||||
#define _PAL_LLD_H_
|
||||
|
||||
#if HAL_USE_PAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Unsupported modes and specific modes */
|
||||
/*===========================================================================*/
|
||||
|
||||
#undef PAL_MODE_INPUT_PULLDOWN
|
||||
#undef PAL_MODE_OUTPUT_OPENDRAIN
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Types and constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Width, in bits, of an I/O port.
|
||||
*/
|
||||
#define PAL_IOPORTS_WIDTH 8
|
||||
|
||||
/**
|
||||
* @brief Whole port mask.
|
||||
* @details This macro specifies all the valid bits into a port.
|
||||
*/
|
||||
#define PAL_WHOLE_PORT ((ioportmask_t)0xFF)
|
||||
|
||||
/**
|
||||
* @brief AVR setup registers.
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t out;
|
||||
uint8_t dir;
|
||||
} avr_gpio_setup_t;
|
||||
|
||||
/**
|
||||
* @brief AVR registers block.
|
||||
* @note On some devices registers do not follow this layout on some
|
||||
* ports, the ports with abnormal layout cannot be used through
|
||||
* PAL driver. Example: PORT F on Mega128.
|
||||
*/
|
||||
typedef struct {
|
||||
volatile uint8_t in;
|
||||
volatile uint8_t dir;
|
||||
volatile uint8_t out;
|
||||
} avr_gpio_registers_t;
|
||||
|
||||
/**
|
||||
* @brief Generic 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 {
|
||||
#if defined(PORTA) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t porta;
|
||||
#endif
|
||||
#if defined(PORTB) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portb;
|
||||
#endif
|
||||
#if defined(PORTC) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portc;
|
||||
#endif
|
||||
#if defined(PORTD) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portd;
|
||||
#endif
|
||||
#if defined(PORTE) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t porte;
|
||||
#endif
|
||||
#if defined(PORTF) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portf;
|
||||
#endif
|
||||
#if defined(PORTG) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portg;
|
||||
#endif
|
||||
#if defined(PORTH) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t porth;
|
||||
#endif
|
||||
#if defined(PORTJ) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portj;
|
||||
#endif
|
||||
#if defined(PORTK) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portk;
|
||||
#endif
|
||||
#if defined(PORTL) || defined(__DOXYGEN__)
|
||||
avr_gpio_setup_t portl;
|
||||
#endif
|
||||
} PALConfig;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O port sized unsigned type.
|
||||
*/
|
||||
typedef uint8_t ioportmask_t;
|
||||
|
||||
/**
|
||||
* @brief Digital I/O modes.
|
||||
*/
|
||||
typedef uint8_t iomode_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 avr_gpio_registers_t *ioportid_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* I/O Ports Identifiers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if defined(PORTA) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port A identifier.
|
||||
*/
|
||||
#define IOPORT1 ((volatile avr_gpio_registers_t *)&PINA)
|
||||
#endif
|
||||
|
||||
#if defined(PORTB) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port B identifier.
|
||||
*/
|
||||
#define IOPORT2 ((volatile avr_gpio_registers_t *)&PINB)
|
||||
#endif
|
||||
|
||||
#if defined(PORTC) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port C identifier.
|
||||
*/
|
||||
#define IOPORT3 ((volatile avr_gpio_registers_t *)&PINC)
|
||||
#endif
|
||||
|
||||
#if defined(PORTD) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port D identifier.
|
||||
*/
|
||||
#define IOPORT4 ((volatile avr_gpio_registers_t *)&PIND)
|
||||
#endif
|
||||
|
||||
#if defined(PORTE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port E identifier.
|
||||
*/
|
||||
#define IOPORT5 ((volatile avr_gpio_registers_t *)&PINE)
|
||||
#endif
|
||||
|
||||
#if defined(PORTF) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port F identifier.
|
||||
*/
|
||||
#define IOPORT6 ((volatile avr_gpio_registers_t *)&PINF)
|
||||
#endif
|
||||
|
||||
#if defined(PORTG) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port G identifier.
|
||||
*/
|
||||
#define IOPORT7 ((volatile avr_gpio_registers_t *)&PING)
|
||||
#endif
|
||||
|
||||
#if defined(PORTH) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port H identifier.
|
||||
*/
|
||||
#define IOPORT8 ((volatile avr_gpio_registers_t *)&PINH)
|
||||
#endif
|
||||
|
||||
#if defined(PORTJ) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port J identifier.
|
||||
*/
|
||||
#define IOPORT9 ((volatile avr_gpio_registers_t *)&PINJ)
|
||||
#endif
|
||||
|
||||
#if defined(PORTK) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port K identifier.
|
||||
*/
|
||||
#define IOPORT10 ((volatile avr_gpio_registers_t *)&PINK)
|
||||
#endif
|
||||
|
||||
#if defined(PORTL) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief GPIO port L identifier.
|
||||
*/
|
||||
#define IOPORT11 ((volatile avr_gpio_registers_t *)&PINL)
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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 the architecture-dependent ports configuration
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_init(config) _pal_lld_init(config)
|
||||
|
||||
/**
|
||||
* @brief Reads the physical I/O port states.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The port bits.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readport(port) ((port)->in)
|
||||
|
||||
/**
|
||||
* @brief Reads the output latch.
|
||||
* @details The purpose of this function is to read back the latched output
|
||||
* value.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @return The latched logical states.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_readlatch(port) ((port)->out)
|
||||
|
||||
/**
|
||||
* @brief Writes a bits mask on a I/O port.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] bits bits to be written on the specified port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_writeport(port, bits) ((port)->out = bits)
|
||||
|
||||
/**
|
||||
* @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] offset group bit offset within the port
|
||||
* @param[in] mode group mode
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setgroupmode(port, mask, offset, mode) \
|
||||
_pal_lld_setgroupmode(port, mask << offset, mode)
|
||||
|
||||
/**
|
||||
* @brief Sets a pad logical state to @p PAL_HIGH.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_setpad(port, pad) \
|
||||
__asm__ __volatile__ \
|
||||
( \
|
||||
"sbi %0,%1\n\t" \
|
||||
: \
|
||||
: "I" (_SFR_IO_ADDR(port->out)), \
|
||||
"I" (pad) \
|
||||
\
|
||||
)
|
||||
|
||||
/**
|
||||
* @brief Clears a pad logical state to @p PAL_LOW.
|
||||
*
|
||||
* @param[in] port port identifier
|
||||
* @param[in] pad pad number within the port
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
#define pal_lld_clearpad(port, pad) \
|
||||
__asm__ __volatile__ \
|
||||
( \
|
||||
"cbi %0,%1\n\t" \
|
||||
: \
|
||||
: "I" (_SFR_IO_ADDR(port->out)), \
|
||||
"I" (pad) \
|
||||
\
|
||||
)
|
||||
|
||||
extern ROMCONST PALConfig pal_default_config;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void _pal_lld_init(const PALConfig *config);
|
||||
void _pal_lld_setgroupmode(ioportid_t port,
|
||||
ioportmask_t mask,
|
||||
iomode_t mode);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_PAL */
|
||||
|
||||
#endif /* _PAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
110
firmware/chibios/os/hal/platforms/AVR/platform.dox
Executable file
110
firmware/chibios/os/hal/platforms/AVR/platform.dox
Executable file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AVR_DRIVERS AVR Drivers
|
||||
* @details This section describes all the supported drivers on the AVR
|
||||
* platform and the implementation details of the single drivers.
|
||||
*
|
||||
* @ingroup platforms
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AVR_HAL AVR Initialization Support
|
||||
* @details On the AVR platform the HAL driver is a stub and does not perform
|
||||
* any platform-specific initialization, it still performs the
|
||||
* initialization of the other drivers.
|
||||
*
|
||||
* @ingroup AVR_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AVR_PAL AVR PAL Support
|
||||
* @details The AVR PAL driver uses the PORT peripherals.
|
||||
*
|
||||
* @section avr_pal_1 Supported HW resources
|
||||
* - PORTA.
|
||||
* - PORTB.
|
||||
* - PORTC.
|
||||
* - PORTD.
|
||||
* - PORTE.
|
||||
* - PORTF.
|
||||
* - PORTG.
|
||||
* .
|
||||
* @section avr_pal_2 AVR PAL driver implementation features
|
||||
* The AVR PAL driver implementation fully supports the following hardware
|
||||
* capabilities:
|
||||
* - 8 bits wide ports.
|
||||
* - Atomic set/reset functions.
|
||||
* - Output latched regardless of the pad setting.
|
||||
* - Direct read of input pads regardless of the pad setting.
|
||||
* .
|
||||
* @section avr_pal_3 Supported PAL setup modes
|
||||
* The AVR PAL driver supports the following I/O modes:
|
||||
* - @p PAL_MODE_RESET.
|
||||
* - @p PAL_MODE_UNCONNECTED.
|
||||
* - @p PAL_MODE_INPUT.
|
||||
* - @p PAL_MODE_INPUT_PULLUP.
|
||||
* - @p PAL_MODE_INPUT_ANALOG.
|
||||
* - @p PAL_MODE_OUTPUT_PUSHPULL.
|
||||
* .
|
||||
* Any attempt to setup an invalid mode is ignored.
|
||||
*
|
||||
* @section avr_pal_4 Suboptimal behavior
|
||||
* The AVR PORT is less than optimal in several areas, the limitations
|
||||
* should be taken in account while using the PAL driver:
|
||||
* - Pad/port toggling operations are not atomic.
|
||||
* - Pad/group mode setup is not atomic.
|
||||
* - Group set+reset function is not atomic.
|
||||
* - Writing on pads/groups/ports programmed as input with pull-up
|
||||
* resistor changes the resistor setting because the output latch is
|
||||
* used for resistor selection.
|
||||
* - The PORT registers layout on some devices is not regular (it does
|
||||
* not have contiguous PIN, DDR, PORT registers in this order), such
|
||||
* ports cannot be accessed using the PAL driver. For example, PORT F
|
||||
* on ATmega128. Verify the user manual of your device.
|
||||
* .
|
||||
* @ingroup AVR_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AVR_SERIAL AVR Serial Support
|
||||
* @details The AVR Serial driver uses the USART peripherals in a
|
||||
* buffered, interrupt driven, implementation.
|
||||
*
|
||||
* @section avr_serial_1 Supported HW resources
|
||||
* The serial driver can support any of the following hardware resources:
|
||||
* - USART0.
|
||||
* - USART1.
|
||||
* .
|
||||
* @section avr_serial_2 AVR Serial driver implementation features
|
||||
* - Each USART can be independently enabled and programmed.
|
||||
* - Fully interrupt driven.
|
||||
* .
|
||||
* @ingroup AVR_DRIVERS
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup AVR_I2C AVR I2C Support
|
||||
* @details The AVR I2C driver uses the TWI peripheral in an interrupt
|
||||
* driven, implementation.
|
||||
*
|
||||
* @section avr_i2c Supported HW resources
|
||||
* The i2c driver can support the following hardware resource:
|
||||
* - I2C.
|
||||
* .
|
||||
* @ingroup AVR_DRIVERS
|
||||
*/
|
||||
8
firmware/chibios/os/hal/platforms/AVR/platform.mk
Executable file
8
firmware/chibios/os/hal/platforms/AVR/platform.mk
Executable file
@@ -0,0 +1,8 @@
|
||||
# List of all the AVR platform files.
|
||||
PLATFORMSRC = ${CHIBIOS}/os/hal/platforms/AVR/hal_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AVR/pal_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AVR/serial_lld.c \
|
||||
${CHIBIOS}/os/hal/platforms/AVR/i2c_lld.c
|
||||
|
||||
# Required include directories
|
||||
PLATFORMINC = ${CHIBIOS}/os/hal/platforms/AVR
|
||||
360
firmware/chibios/os/hal/platforms/AVR/serial_lld.c
Executable file
360
firmware/chibios/os/hal/platforms/AVR/serial_lld.c
Executable file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/serial_lld.c
|
||||
* @brief AVR low level serial driver code.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if 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 and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Driver default configuration.
|
||||
*/
|
||||
static const SerialConfig default_config = {
|
||||
UBRR(SERIAL_DEFAULT_BITRATE),
|
||||
USART_CHAR_SIZE_8
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
static void set_error(uint8_t sra, SerialDriver *sdp) {
|
||||
flagsmask_t sts = 0;
|
||||
uint8_t dor = 0;
|
||||
uint8_t upe = 0;
|
||||
uint8_t fe = 0;
|
||||
|
||||
#if USE_AVR_USART0
|
||||
if (&SD1 == sdp) {
|
||||
dor = (1 << DOR0);
|
||||
upe = (1 << UPE0);
|
||||
fe = (1 << FE0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_AVR_USART1
|
||||
if (&SD2 == sdp) {
|
||||
dor = (1 << DOR1);
|
||||
upe = (1 << UPE1);
|
||||
fe = (1 << FE1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sra & dor)
|
||||
sts |= SD_OVERRUN_ERROR;
|
||||
if (sra & upe)
|
||||
sts |= SD_PARITY_ERROR;
|
||||
if (sra & fe)
|
||||
sts |= SD_FRAMING_ERROR;
|
||||
chSysLockFromIsr();
|
||||
chnAddFlagsI(sdp, sts);
|
||||
chSysUnlockFromIsr();
|
||||
}
|
||||
|
||||
#if USE_AVR_USART0 || defined(__DOXYGEN__)
|
||||
static void notify1(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
UCSR0B |= (1 << UDRIE0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
|
||||
switch (config->sc_bits_per_char) {
|
||||
case USART_CHAR_SIZE_5:
|
||||
UCSR0C = 0;
|
||||
break;
|
||||
case USART_CHAR_SIZE_6:
|
||||
UCSR0C = (1 << UCSZ00);
|
||||
break;
|
||||
case USART_CHAR_SIZE_7:
|
||||
UCSR0C = (1 << UCSZ01);
|
||||
break;
|
||||
case USART_CHAR_SIZE_9:
|
||||
UCSR0B |= (1 << UCSZ02);
|
||||
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
|
||||
break;
|
||||
case USART_CHAR_SIZE_8:
|
||||
default:
|
||||
UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(GenericQueue *qp) {
|
||||
|
||||
(void)qp;
|
||||
UCSR1B |= (1 << UDRIE1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);
|
||||
switch (config->sc_bits_per_char) {
|
||||
case USART_CHAR_SIZE_5:
|
||||
UCSR1C = 0;
|
||||
break;
|
||||
case USART_CHAR_SIZE_6:
|
||||
UCSR1C = (1 << UCSZ10);
|
||||
break;
|
||||
case USART_CHAR_SIZE_7:
|
||||
UCSR1C = (1 << UCSZ11);
|
||||
break;
|
||||
case USART_CHAR_SIZE_9:
|
||||
UCSR1B |= (1 << UCSZ12);
|
||||
UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
|
||||
break;
|
||||
case USART_CHAR_SIZE_8:
|
||||
default:
|
||||
UCSR1C = (1 << UCSZ10) | (1 << UCSZ11);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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__)
|
||||
/**
|
||||
* @brief USART0 RX interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(USART0_RX_vect) {
|
||||
uint8_t sra;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
sra = UCSR0A;
|
||||
if (sra & ((1 << DOR0) | (1 << UPE0) | (1 << FE0)))
|
||||
set_error(sra, &SD1);
|
||||
chSysLockFromIsr();
|
||||
sdIncomingDataI(&SD1, UDR0);
|
||||
chSysUnlockFromIsr();
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART0 TX interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(USART0_UDRE_vect) {
|
||||
msg_t b;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
chSysLockFromIsr();
|
||||
b = sdRequestDataI(&SD1);
|
||||
chSysUnlockFromIsr();
|
||||
if (b < Q_OK)
|
||||
UCSR0B &= ~(1 << UDRIE0);
|
||||
else
|
||||
UDR0 = b;
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* USE_AVR_USART0 */
|
||||
|
||||
#if USE_AVR_USART1 || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief USART1 RX interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(USART1_RX_vect) {
|
||||
uint8_t sra;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
sra = UCSR1A;
|
||||
if (sra & ((1 << DOR1) | (1 << UPE1) | (1 << FE1)))
|
||||
set_error(sra, &SD2);
|
||||
chSysLockFromIsr();
|
||||
sdIncomingDataI(&SD2, UDR1);
|
||||
chSysUnlockFromIsr();
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 TX interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(USART1_UDRE_vect) {
|
||||
msg_t b;
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
chSysLockFromIsr();
|
||||
b = sdRequestDataI(&SD2);
|
||||
chSysUnlockFromIsr();
|
||||
if (b < Q_OK)
|
||||
UCSR1B &= ~(1 << UDRIE1);
|
||||
else
|
||||
UDR1 = b;
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* USE_AVR_USART1 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level serial driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
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 /* HAL_USE_SERIAL */
|
||||
|
||||
/** @} */
|
||||
158
firmware/chibios/os/hal/platforms/AVR/serial_lld.h
Executable file
158
firmware/chibios/os/hal/platforms/AVR/serial_lld.h
Executable file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file AVR/serial_lld.h
|
||||
* @brief AVR low level serial driver header.
|
||||
*
|
||||
* @addtogroup SERIAL
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _SERIAL_LLD_H_
|
||||
#define _SERIAL_LLD_H_
|
||||
|
||||
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief 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 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 Number of bits per character (USART_CHAR_SIZE_5 to USART_CHAR_SIZE_9).
|
||||
*/
|
||||
uint8_t sc_bits_per_char;
|
||||
} 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; \
|
||||
/* 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)
|
||||
|
||||
/**
|
||||
* @brief Macro for baud rate computation when U2Xn == 1.
|
||||
* @note Make sure the final baud rate is within tolerance.
|
||||
*/
|
||||
#define UBRR2x(b) (((F_CPU / b) >> 3) - 1)
|
||||
|
||||
/**
|
||||
* @brief Macro for baud rate computation.
|
||||
* @note Make sure the final baud rate is within tolerance.
|
||||
* @note This version uses floating point math for greater accuracy.
|
||||
*/
|
||||
#define UBRR_F(b) ((((double) F_CPU / (double) b) / 16.0) - 0.5)
|
||||
|
||||
/**
|
||||
* @brief Macro for baud rate computation when U2Xn == 1.
|
||||
* @note Make sure the final baud rate is within tolerance.
|
||||
* @note This version uses floating point math for greater accuracy.
|
||||
*/
|
||||
#define UBRR2x_F(b) ((((double) F_CPU / (double) b) / 8.0) - 0.5)
|
||||
|
||||
#define USART_CHAR_SIZE_5 0
|
||||
#define USART_CHAR_SIZE_6 1
|
||||
#define USART_CHAR_SIZE_7 2
|
||||
#define USART_CHAR_SIZE_8 3
|
||||
#define USART_CHAR_SIZE_9 4
|
||||
|
||||
/*===========================================================================*/
|
||||
/* 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 /* HAL_USE_SERIAL */
|
||||
|
||||
#endif /* _SERIAL_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
668
firmware/chibios/os/hal/platforms/LPC11Uxx/LPC11Uxx.h
Executable file
668
firmware/chibios/os/hal/platforms/LPC11Uxx/LPC11Uxx.h
Executable file
@@ -0,0 +1,668 @@
|
||||
|
||||
/****************************************************************************************************//**
|
||||
* @file LPC11Uxx.h
|
||||
*
|
||||
*
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File for
|
||||
* default LPC11Uxx Device Series
|
||||
*
|
||||
* @version V0.1
|
||||
* @date 21. March 2011
|
||||
*
|
||||
* @note Generated with SFDGen V2.6 Build 3j (beta) on Thursday, 17.03.2011 13:19:45
|
||||
*
|
||||
* from CMSIS SVD File 'LPC11U1x_svd.xml' Version 0.1,
|
||||
* created on Wednesday, 16.03.2011 20:30:42, last modified on Thursday, 17.03.2011 20:19:40
|
||||
*
|
||||
*******************************************************************************************************/
|
||||
|
||||
|
||||
|
||||
/** @addtogroup NXP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup LPC11Uxx
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef __LPC11UXX_H__
|
||||
#define __LPC11UXX_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#pragma anon_unions
|
||||
#endif
|
||||
|
||||
/* Interrupt Number Definition */
|
||||
|
||||
typedef enum {
|
||||
// ------------------------- Cortex-M0 Processor Exceptions Numbers -----------------------------
|
||||
Reset_IRQn = -15, /*!< 1 Reset Vector, invoked on Power up and warm reset */
|
||||
NonMaskableInt_IRQn = -14, /*!< 2 Non maskable Interrupt, cannot be stopped or preempted */
|
||||
HardFault_IRQn = -13, /*!< 3 Hard Fault, all classes of Fault */
|
||||
SVCall_IRQn = -5, /*!< 11 System Service Call via SVC instruction */
|
||||
DebugMonitor_IRQn = -4, /*!< 12 Debug Monitor */
|
||||
PendSV_IRQn = -2, /*!< 14 Pendable request for system service */
|
||||
SysTick_IRQn = -1, /*!< 15 System Tick Timer */
|
||||
// --------------------------- LPC11Uxx Specific Interrupt Numbers ------------------------------
|
||||
FLEX_INT0_IRQn = 0, /*!< All I/O pins can be routed to below 8 interrupts. */
|
||||
FLEX_INT1_IRQn = 1,
|
||||
FLEX_INT2_IRQn = 2,
|
||||
FLEX_INT3_IRQn = 3,
|
||||
FLEX_INT4_IRQn = 4,
|
||||
FLEX_INT5_IRQn = 5,
|
||||
FLEX_INT6_IRQn = 6,
|
||||
FLEX_INT7_IRQn = 7,
|
||||
GINT0_IRQn = 8, /*!< Grouped Interrupt 0 */
|
||||
GINT1_IRQn = 9, /*!< Grouped Interrupt 1 */
|
||||
Reserved0_IRQn = 10, /*!< Reserved Interrupt */
|
||||
Reserved1_IRQn = 11,
|
||||
Reserved2_IRQn = 12,
|
||||
Reserved3_IRQn = 13,
|
||||
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 */
|
||||
USB_IRQn = 22, /*!< USB IRQ Interrupt */
|
||||
USB_FIQn = 23, /*!< USB FIQ Interrupt */
|
||||
ADC_IRQn = 24, /*!< A/D Converter Interrupt */
|
||||
WDT_IRQn = 25, /*!< Watchdog timer Interrupt */
|
||||
BOD_IRQn = 26, /*!< Brown Out Detect(BOD) Interrupt */
|
||||
FMC_IRQn = 27, /*!< Flash Memory Controller Interrupt */
|
||||
Reserved4_IRQn = 28, /*!< Reserved Interrupt */
|
||||
Reserved5_IRQn = 29, /*!< Reserved Interrupt */
|
||||
USBWakeup_IRQn = 30, /*!< USB wakeup Interrupt */
|
||||
Reserved6_IRQn = 31, /*!< Reserved Interrupt */
|
||||
} IRQn_Type;
|
||||
|
||||
|
||||
/** @addtogroup Configuration_of_CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Processor and Core Peripheral Section */ /* Configuration of the Cortex-M0 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 Configuration_of_CMSIS */
|
||||
|
||||
#include "core_cm0.h" /*!< Cortex-M0 processor and core peripherals */
|
||||
#include "system_LPC11Uxx.h" /*!< LPC11Uxx System */
|
||||
|
||||
/** @addtogroup Device_Peripheral_Registers
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- I2C -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x I2C-bus controller Modification date=3/16/2011 Major revision=0 Minor revision=3 (I2C)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40000000) I2C Structure */
|
||||
__IO uint32_t CONSET; /*!< (@ 0x40000000) I2C Control Set Register */
|
||||
__I uint32_t STAT; /*!< (@ 0x40000004) I2C Status Register */
|
||||
__IO uint32_t DAT; /*!< (@ 0x40000008) I2C Data Register. */
|
||||
__IO uint32_t ADR0; /*!< (@ 0x4000000C) I2C Slave Address Register 0 */
|
||||
__IO uint32_t SCLH; /*!< (@ 0x40000010) SCH Duty Cycle Register High Half Word */
|
||||
__IO uint32_t SCLL; /*!< (@ 0x40000014) SCL Duty Cycle Register Low Half Word */
|
||||
__IO uint32_t CONCLR; /*!< (@ 0x40000018) I2C Control Clear Register*/
|
||||
__IO uint32_t MMCTRL; /*!< (@ 0x4000001C) Monitor mode control register*/
|
||||
__IO uint32_t ADR1; /*!< (@ 0x40000020) I2C Slave Address Register 1*/
|
||||
__IO uint32_t ADR2; /*!< (@ 0x40000024) I2C Slave Address Register 2*/
|
||||
__IO uint32_t ADR3; /*!< (@ 0x40000028) I2C Slave Address Register 3*/
|
||||
__I uint32_t DATA_BUFFER; /*!< (@ 0x4000002C) Data buffer register */
|
||||
union{
|
||||
__IO uint32_t MASK[4]; /*!< (@ 0x40000030) I2C Slave address mask register */
|
||||
struct{
|
||||
__IO uint32_t MASK0;
|
||||
__IO uint32_t MASK1;
|
||||
__IO uint32_t MASK2;
|
||||
__IO uint32_t MASK3;
|
||||
};
|
||||
};
|
||||
} LPC_I2C_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- WWDT -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x Windowed Watchdog Timer (WWDT) Modification date=3/16/2011 Major revision=0 Minor revision=3 (WWDT)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40004000) WWDT Structure */
|
||||
__IO uint32_t MOD; /*!< (@ 0x40004000) Watchdog mode register*/
|
||||
__IO uint32_t TC; /*!< (@ 0x40004004) Watchdog timer constant register */
|
||||
__IO uint32_t FEED; /*!< (@ 0x40004008) Watchdog feed sequence register */
|
||||
__I uint32_t TV; /*!< (@ 0x4000400C) Watchdog timer value register */
|
||||
__IO uint32_t CLKSEL; /*!< (@ 0x40004010) Watchdog clock select register. */
|
||||
__IO uint32_t WARNINT; /*!< (@ 0x40004014) Watchdog Warning Interrupt compare value. */
|
||||
__IO uint32_t WINDOW; /*!< (@ 0x40004018) Watchdog Window compare value. */
|
||||
} LPC_WWDT_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- USART -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x USART Modification date=3/16/2011 Major revision=0 Minor revision=3 (USART)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40008000) USART Structure */
|
||||
|
||||
union {
|
||||
__IO uint32_t DLL; /*!< (@ 0x40008000) Divisor Latch LSB. Least significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */
|
||||
__O uint32_t THR; /*!< (@ 0x40008000) Transmit Holding Register. The next character to be transmitted is written here. (DLAB=0) */
|
||||
__I uint32_t RBR; /*!< (@ 0x40008000) Receiver Buffer Register. Contains the next received character to be read. (DLAB=0) */
|
||||
};
|
||||
|
||||
union {
|
||||
__IO uint32_t IER; /*!< (@ 0x40008004) Interrupt Enable Register. Contains individual interrupt enable bits for the 7 potential USART interrupts. (DLAB=0) */
|
||||
__IO uint32_t DLM; /*!< (@ 0x40008004) Divisor Latch MSB. Most significant byte of the baud rate divisor value. The full divisor is used to generate a baud rate from the fractional rate divider. (DLAB=1) */
|
||||
};
|
||||
|
||||
union {
|
||||
__O uint32_t FCR; /*!< (@ 0x40008008) FIFO Control Register. Controls USART FIFO usage and modes. */
|
||||
__I uint32_t IIR; /*!< (@ 0x40008008) Interrupt ID Register. Identifies which interrupt(s) are pending. */
|
||||
};
|
||||
__IO uint32_t LCR; /*!< (@ 0x4000800C) Line Control Register. Contains controls for frame formatting and break generation. */
|
||||
__IO uint32_t MCR; /*!< (@ 0x40008010) Modem Control Register. */
|
||||
__I uint32_t LSR; /*!< (@ 0x40008014) Line Status Register. Contains flags for transmit and receive status, including line errors. */
|
||||
__I uint32_t MSR; /*!< (@ 0x40008018) Modem Status Register. */
|
||||
__IO uint32_t SCR; /*!< (@ 0x4000801C) Scratch Pad Register. Eight-bit temporary storage for software. */
|
||||
__IO uint32_t ACR; /*!< (@ 0x40008020) Auto-baud Control Register. Contains controls for the auto-baud feature. */
|
||||
__IO uint32_t ICR; /*!< (@ 0x40008024) IrDA Control Register. Enables and configures the IrDA (remote control) mode. */
|
||||
__IO uint32_t FDR; /*!< (@ 0x40008028) Fractional Divider Register. Generates a clock input for the baud rate divider. */
|
||||
__IO uint32_t OSR; /*!< (@ 0x4000802C) Oversampling Register. Controls the degree of oversampling during each bit time. */
|
||||
__IO uint32_t TER; /*!< (@ 0x40008030) Transmit Enable Register. Turns off USART transmitter for use with software flow control. */
|
||||
__I uint32_t RESERVED0[3];
|
||||
__IO uint32_t HDEN; /*!< (@ 0x40008040) Half duplex enable register. */
|
||||
__I uint32_t RESERVED1;
|
||||
__IO uint32_t SCICTRL; /*!< (@ 0x40008048) Smart Card Interface Control register. Enables and configures the Smart Card Interface feature. */
|
||||
__IO uint32_t RS485CTRL; /*!< (@ 0x4000804C) RS-485/EIA-485 Control. Contains controls to configure various aspects of RS-485/EIA-485 modes. */
|
||||
__IO uint32_t RS485ADRMATCH; /*!< (@ 0x40008050) RS-485/EIA-485 address match. Contains the address match value for RS-485/EIA-485 mode. */
|
||||
__IO uint32_t RS485DLY; /*!< (@ 0x40008054) RS-485/EIA-485 direction control delay. */
|
||||
__IO uint32_t SYNCCTRL;
|
||||
} LPC_USART_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- Timer -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x 32-bitcounter/timers CT32B0/1 Modification date=3/16/2011 Major revision=0 Minor revision=3
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40014000) CT32B0 Structure */
|
||||
__IO uint32_t IR; /*!< (@ 0x40014000) Interrupt Register */
|
||||
__IO uint32_t TCR; /*!< (@ 0x40014004) Timer Control Register */
|
||||
__IO uint32_t TC; /*!< (@ 0x40014008) Timer Counter */
|
||||
__IO uint32_t PR; /*!< (@ 0x4001400C) Prescale Register */
|
||||
__IO uint32_t PC; /*!< (@ 0x40014010) Prescale Counter */
|
||||
__IO uint32_t MCR; /*!< (@ 0x40014014) Match Control Register */
|
||||
union {
|
||||
__IO uint32_t MR[4]; /*!< (@ 0x40014018) Match Register */
|
||||
struct{
|
||||
__IO uint32_t MR0; /*!< (@ 0x40018018) Match Register. MR0 */
|
||||
__IO uint32_t MR1; /*!< (@ 0x4001801C) Match Register. MR1 */
|
||||
__IO uint32_t MR2; /*!< (@ 0x40018020) Match Register. MR2 */
|
||||
__IO uint32_t MR3; /*!< (@ 0x40018024) Match Register. MR3 */
|
||||
};
|
||||
};
|
||||
__IO uint32_t CCR; /*!< (@ 0x40014028) Capture Control Register */
|
||||
union{
|
||||
__I uint32_t CR[4]; /*!< (@ 0x4001402C) Capture Register */
|
||||
struct{
|
||||
__I uint32_t CR0; /*!< (@ 0x4001802C) Capture Register. CR 0 */
|
||||
__I uint32_t CR1; /*!< (@ 0x40018030) Capture Register. CR 1 */
|
||||
__I uint32_t CR2; /*!< (@ 0x40018034) Capture Register. CR 2 */
|
||||
__I uint32_t CR3; /*!< (@ 0x40018038) Capture Register. CR 3 */
|
||||
};
|
||||
};
|
||||
__IO uint32_t EMR; /*!< (@ 0x4001403C) External Match Register */
|
||||
__I uint32_t RESERVED0[12];
|
||||
__IO uint32_t CTCR; /*!< (@ 0x40014070) Count Control Register */
|
||||
__IO uint32_t PWMC; /*!< (@ 0x40014074) PWM Control Register */
|
||||
} LPC_CTxxBx_Type;
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- ADC -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x ADC Modification date=3/16/2011 Major revision=0 Minor revision=3 (ADC)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x4001C000) ADC Structure */
|
||||
__IO uint32_t CR; /*!< (@ 0x4001C000) A/D Control Register */
|
||||
__IO uint32_t GDR; /*!< (@ 0x4001C004) A/D Global Data Register */
|
||||
__I uint32_t RESERVED0[1];
|
||||
__IO uint32_t INTEN; /*!< (@ 0x4001C00C) A/D Interrupt Enable Register */
|
||||
union{
|
||||
__I uint32_t DR[8]; /*!< (@ 0x4001C010) A/D Channel Data Register*/
|
||||
struct{
|
||||
__IO uint32_t DR0; /*!< (@ 0x40020010) A/D Channel Data Register 0*/
|
||||
__IO uint32_t DR1; /*!< (@ 0x40020014) A/D Channel Data Register 1*/
|
||||
__IO uint32_t DR2; /*!< (@ 0x40020018) A/D Channel Data Register 2*/
|
||||
__IO uint32_t DR3; /*!< (@ 0x4002001C) A/D Channel Data Register 3*/
|
||||
__IO uint32_t DR4; /*!< (@ 0x40020020) A/D Channel Data Register 4*/
|
||||
__IO uint32_t DR5; /*!< (@ 0x40020024) A/D Channel Data Register 5*/
|
||||
__IO uint32_t DR6; /*!< (@ 0x40020028) A/D Channel Data Register 6*/
|
||||
__IO uint32_t DR7; /*!< (@ 0x4002002C) A/D Channel Data Register 7*/
|
||||
};
|
||||
};
|
||||
__I uint32_t STAT; /*!< (@ 0x4001C030) A/D Status Register. */
|
||||
} LPC_ADC_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- PMU -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x Power Management Unit (PMU) Modification date=3/16/2011 Major revision=0 Minor revision=3 (PMU)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40038000) PMU Structure */
|
||||
__IO uint32_t PCON; /*!< (@ 0x40038000) Power control register */
|
||||
union{
|
||||
__IO uint32_t GPREG[4]; /*!< (@ 0x40038004) General purpose register 0 */
|
||||
struct{
|
||||
__IO uint32_t GPREG0; /*!< (@ 0x40038004) General purpose register 0 */
|
||||
__IO uint32_t GPREG1; /*!< (@ 0x40038008) General purpose register 1 */
|
||||
__IO uint32_t GPREG2; /*!< (@ 0x4003800C) General purpose register 2 */
|
||||
__IO uint32_t GPREG3; /*!< (@ 0x40038010) General purpose register 3 */
|
||||
};
|
||||
};
|
||||
} LPC_PMU_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- FLASHCTRL -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x Flash programming firmware Modification date=3/17/2011 Major revision=0 Minor revision=3 (FLASHCTRL)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x4003C000) FLASHCTRL Structure */
|
||||
__I uint32_t RESERVED0[4];
|
||||
__IO uint32_t FLASHCFG; /*!< (@ 0x4003C010) Flash memory access time configuration register */
|
||||
__I uint32_t RESERVED1[3];
|
||||
__IO uint32_t FMSSTART; /*!< (@ 0x4003C020) Signature start address register */
|
||||
__IO uint32_t FMSSTOP; /*!< (@ 0x4003C024) Signature stop-address register */
|
||||
__I uint32_t RESERVED2[1];
|
||||
__I uint32_t FMSW0; /*!< (@ 0x4003C02C) Word 0 [31:0] */
|
||||
__I uint32_t FMSW1; /*!< (@ 0x4003C030) Word 1 [63:32] */
|
||||
__I uint32_t FMSW2; /*!< (@ 0x4003C034) Word 2 [95:64] */
|
||||
__I uint32_t FMSW3; /*!< (@ 0x4003C038) Word 3 [127:96] */
|
||||
__I uint32_t RESERVED3[1001];
|
||||
__I uint32_t FMSTAT; /*!< (@ 0x4003CFE0) Signature generation status register */
|
||||
__I uint32_t RESERVED4[1];
|
||||
__IO uint32_t FMSTATCLR; /*!< (@ 0x4003CFE8) Signature generation status clear register */
|
||||
} LPC_FLASHCTRL_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- SSP0/1 -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x SSP/SPI Modification date=3/16/2011 Major revision=0 Minor revision=3 (SSP0)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40040000) SSP0 Structure */
|
||||
__IO uint32_t CR0; /*!< (@ 0x40040000) Control Register 0. Selects the serial clock rate, bus type, and data size. */
|
||||
__IO uint32_t CR1; /*!< (@ 0x40040004) Control Register 1. Selects master/slave and other modes. */
|
||||
__IO uint32_t DR; /*!< (@ 0x40040008) Data Register. Writes fill the transmit FIFO, and reads empty the receive FIFO. */
|
||||
__I uint32_t SR; /*!< (@ 0x4004000C) Status Register */
|
||||
__IO uint32_t CPSR; /*!< (@ 0x40040010) Clock Prescale Register */
|
||||
__IO uint32_t IMSC; /*!< (@ 0x40040014) Interrupt Mask Set and Clear Register */
|
||||
__I uint32_t RIS; /*!< (@ 0x40040018) Raw Interrupt Status Register */
|
||||
__I uint32_t MIS; /*!< (@ 0x4004001C) Masked Interrupt Status Register */
|
||||
__IO uint32_t ICR; /*!< (@ 0x40040020) SSPICR Interrupt Clear Register */
|
||||
} LPC_SSPx_Type;
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- IOCONFIG -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x I/O configuration Modification date=3/16/2011 Major revision=0 Minor revision=3 (IOCONFIG)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40044000) IOCONFIG Structure */
|
||||
__IO uint32_t RESET_PIO0_0; /*!< (@ 0x40044000) I/O configuration for pin RESET/PIO0_0 */
|
||||
__IO uint32_t PIO0_1; /*!< (@ 0x40044004) I/O configuration for pin PIO0_1/CLKOUT/CT32B0_MAT2/USB_FTOGGLE */
|
||||
__IO uint32_t PIO0_2; /*!< (@ 0x40044008) I/O configuration for pin PIO0_2/SSEL0/CT16B0_CAP0 */
|
||||
__IO uint32_t PIO0_3; /*!< (@ 0x4004400C) I/O configuration for pin PIO0_3/USB_VBUS */
|
||||
__IO uint32_t PIO0_4; /*!< (@ 0x40044010) I/O configuration for pin PIO0_4/SCL */
|
||||
__IO uint32_t PIO0_5; /*!< (@ 0x40044014) I/O configuration for pin PIO0_5/SDA */
|
||||
__IO uint32_t PIO0_6; /*!< (@ 0x40044018) I/O configuration for pin PIO0_6/USB_CONNECT/SCK0 */
|
||||
__IO uint32_t PIO0_7; /*!< (@ 0x4004401C) I/O configuration for pin PIO0_7/CTS */
|
||||
__IO uint32_t PIO0_8; /*!< (@ 0x40044020) I/O configuration for pin PIO0_8/MISO0/CT16B0_MAT0 */
|
||||
__IO uint32_t PIO0_9; /*!< (@ 0x40044024) I/O configuration for pin PIO0_9/MOSI0/CT16B0_MAT1 */
|
||||
__IO uint32_t SWCLK_PIO0_10; /*!< (@ 0x40044028) I/O configuration for pin SWCLK/PIO0_10/ SCK0/CT16B0_MAT2 */
|
||||
__IO uint32_t TDI_PIO0_11; /*!< (@ 0x4004402C) I/O configuration for pin TDI/PIO0_11/AD0/CT32B0_MAT3 */
|
||||
__IO uint32_t TMS_PIO0_12; /*!< (@ 0x40044030) I/O configuration for pin TMS/PIO0_12/AD1/CT32B1_CAP0 */
|
||||
__IO uint32_t TDO_PIO0_13; /*!< (@ 0x40044034) I/O configuration for pin TDO/PIO0_13/AD2/CT32B1_MAT0 */
|
||||
__IO uint32_t TRST_PIO0_14; /*!< (@ 0x40044038) I/O configuration for pin TRST/PIO0_14/AD3/CT32B1_MAT1 */
|
||||
__IO uint32_t SWDIO_PIO0_15; /*!< (@ 0x4004403C) I/O configuration for pin SWDIO/PIO0_15/AD4/CT32B1_MAT2 */
|
||||
__IO uint32_t PIO0_16; /*!< (@ 0x40044040) I/O configuration for pin PIO0_16/AD5/CT32B1_MAT3/ WAKEUP */
|
||||
__IO uint32_t PIO0_17; /*!< (@ 0x40044044) I/O configuration for pin PIO0_17/RTS/CT32B0_CAP0/SCLK */
|
||||
__IO uint32_t PIO0_18; /*!< (@ 0x40044048) I/O configuration for pin PIO0_18/RXD/CT32B0_MAT0 */
|
||||
__IO uint32_t PIO0_19; /*!< (@ 0x4004404C) I/O configuration for pin PIO0_19/TXD/CT32B0_MAT1 */
|
||||
__IO uint32_t PIO0_20; /*!< (@ 0x40044050) I/O configuration for pin PIO0_20/CT16B1_CAP0 */
|
||||
__IO uint32_t PIO0_21; /*!< (@ 0x40044054) I/O configuration for pin PIO0_21/CT16B1_MAT0/MOSI1 */
|
||||
__IO uint32_t PIO0_22; /*!< (@ 0x40044058) I/O configuration for pin PIO0_22/AD6/CT16B1_MAT1/MISO1 */
|
||||
__IO uint32_t PIO0_23; /*!< (@ 0x4004405C) I/O configuration for pin PIO0_23/AD7 */
|
||||
__IO uint32_t PIO1_0; /*!< Offset: 0x060 */
|
||||
__IO uint32_t PIO1_1;
|
||||
__IO uint32_t PIO1_2;
|
||||
__IO uint32_t PIO1_3;
|
||||
__IO uint32_t PIO1_4; /*!< Offset: 0x070 */
|
||||
__IO uint32_t PIO1_5; /*!< (@ 0x40044074) I/O configuration for pin PIO1_5/CT32B1_CAP1 */
|
||||
__IO uint32_t PIO1_6;
|
||||
__IO uint32_t PIO1_7;
|
||||
__IO uint32_t PIO1_8; /*!< Offset: 0x080 */
|
||||
__IO uint32_t PIO1_9;
|
||||
__IO uint32_t PIO1_10;
|
||||
__IO uint32_t PIO1_11;
|
||||
__IO uint32_t PIO1_12; /*!< Offset: 0x090 */
|
||||
__IO uint32_t PIO1_13; /*!< (@ 0x40044094) I/O configuration for pin PIO1_13/DTR/CT16B0_MAT0/TXD */
|
||||
__IO uint32_t PIO1_14; /*!< (@ 0x40044098) I/O configuration for pin PIO1_14/DSR/CT16B0_MAT1/RXD */
|
||||
__IO uint32_t PIO1_15; /*!< (@ 0x4004409C) I/O configuration for pin PIO1_15/DCD/ CT16B0_MAT2/SCK1 */
|
||||
__IO uint32_t PIO1_16; /*!< (@ 0x400440A0) I/O configuration for pin PIO1_16/RI/CT16B0_CAP0 */
|
||||
__IO uint32_t PIO1_17;
|
||||
__IO uint32_t PIO1_18;
|
||||
__IO uint32_t PIO1_19; /*!< (@ 0x400440AC) I/O configuration for pin PIO1_19/DTR/SSEL1 */
|
||||
__IO uint32_t PIO1_20; /*!< (@ 0x400440B0) I/O configuration for pin PIO1_20/DSR/SCK1 */
|
||||
__IO uint32_t PIO1_21; /*!< (@ 0x400440B4) I/O configuration for pin PIO1_21/DCD/MISO1 */
|
||||
__IO uint32_t PIO1_22; /*!< (@ 0x400440B8) I/O configuration for pin PIO1_22/RI/MOSI1 */
|
||||
__IO uint32_t PIO1_23; /*!< (@ 0x400440BC) I/O configuration for pin PIO1_23/CT16B1_MAT1/SSEL1 */
|
||||
__IO uint32_t PIO1_24; /*!< (@ 0x400440C0) I/O configuration for pin PIO1_24/ CT32B0_MAT0 */
|
||||
__IO uint32_t PIO1_25; /*!< (@ 0x400440C4) I/O configuration for pin PIO1_25/CT32B0_MAT1 */
|
||||
__IO uint32_t PIO1_26; /*!< (@ 0x400440C8) I/O configuration for pin PIO1_26/CT32B0_MAT2/ RXD */
|
||||
__IO uint32_t PIO1_27; /*!< (@ 0x400440CC) I/O configuration for pin PIO1_27/CT32B0_MAT3/ TXD */
|
||||
__IO uint32_t PIO1_28; /*!< (@ 0x400440D0) I/O configuration for pin PIO1_28/CT32B0_CAP0/ SCLK */
|
||||
__IO uint32_t PIO1_29; /*!< (@ 0x400440D4) I/O configuration for pin PIO1_29/SCK0/ CT32B0_CAP1 */
|
||||
__IO uint32_t PIO1_30;
|
||||
__IO uint32_t PIO1_31; /*!< (@ 0x400440DC) I/O configuration for pin PIO1_31 */
|
||||
} LPC_IOCON_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- SYSCON -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x System control block Modification date=3/16/2011 Major revision=0 Minor revision=3 (SYSCON)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40048000) SYSCON Structure */
|
||||
__IO uint32_t SYSMEMREMAP; /*!< (@ 0x40048000) System memory remap */
|
||||
__IO uint32_t PRESETCTRL; /*!< (@ 0x40048004) Peripheral reset control */
|
||||
__IO uint32_t SYSPLLCTRL; /*!< (@ 0x40048008) System PLL control */
|
||||
__I uint32_t SYSPLLSTAT; /*!< (@ 0x4004800C) System PLL status */
|
||||
__IO uint32_t USBPLLCTRL; /*!< (@ 0x40048010) USB PLL control */
|
||||
__I uint32_t USBPLLSTAT; /*!< (@ 0x40048014) USB PLL status */
|
||||
__I uint32_t RESERVED0[2];
|
||||
__IO uint32_t SYSOSCCTRL; /*!< (@ 0x40048020) System oscillator control */
|
||||
__IO uint32_t WDTOSCCTRL; /*!< (@ 0x40048024) Watchdog oscillator control */
|
||||
__I uint32_t RESERVED1[2];
|
||||
__IO uint32_t SYSRSTSTAT; /*!< (@ 0x40048030) System reset status register */
|
||||
__I uint32_t RESERVED2[3];
|
||||
__IO uint32_t SYSPLLCLKSEL; /*!< (@ 0x40048040) System PLL clock source select */
|
||||
__IO uint32_t SYSPLLCLKUEN; /*!< (@ 0x40048044) System PLL clock source update enable */
|
||||
__IO uint32_t USBPLLCLKSEL; /*!< (@ 0x40048048) USB PLL clock source select */
|
||||
__IO uint32_t USBPLLCLKUEN; /*!< (@ 0x4004804C) USB PLL clock source update enable */
|
||||
__I uint32_t RESERVED3[8];
|
||||
__IO uint32_t MAINCLKSEL; /*!< (@ 0x40048070) Main clock source select */
|
||||
__IO uint32_t MAINCLKUEN; /*!< (@ 0x40048074) Main clock source update enable */
|
||||
__IO uint32_t SYSAHBCLKDIV; /*!< (@ 0x40048078) System clock divider */
|
||||
__I uint32_t RESERVED4[1];
|
||||
__IO uint32_t SYSAHBCLKCTRL; /*!< (@ 0x40048080) System clock control */
|
||||
__I uint32_t RESERVED5[4];
|
||||
__IO uint32_t SSP0CLKDIV; /*!< (@ 0x40048094) SSP0 clock divider */
|
||||
__IO uint32_t UARTCLKDIV; /*!< (@ 0x40048098) UART clock divider */
|
||||
__IO uint32_t SSP1CLKDIV; /*!< (@ 0x4004809C) SSP1 clock divider */
|
||||
__I uint32_t RESERVED6[8];
|
||||
__IO uint32_t USBCLKSEL; /*!< (@ 0x400480C0) USB clock source select */
|
||||
__IO uint32_t USBCLKUEN; /*!< (@ 0x400480C4) USB clock source update enable */
|
||||
__IO uint32_t USBCLKDIV; /*!< (@ 0x400480C8) USB clock source divider */
|
||||
__I uint32_t RESERVED7[5];
|
||||
__IO uint32_t CLKOUTSEL; /*!< (@ 0x400480E0) CLKOUT clock source select */
|
||||
__IO uint32_t CLKOUTUEN; /*!< (@ 0x400480E4) CLKOUT clock source update enable */
|
||||
__IO uint32_t CLKOUTDIV; /*!< (@ 0x400480E8) CLKOUT clock divider */
|
||||
__I uint32_t RESERVED8[5];
|
||||
__I uint32_t PIOPORCAP0; /*!< (@ 0x40048100) POR captured PIO status 0 */
|
||||
__I uint32_t PIOPORCAP1; /*!< (@ 0x40048104) POR captured PIO status 1 */
|
||||
__I uint32_t RESERVED9[18];
|
||||
__IO uint32_t BODCTRL; /*!< (@ 0x40048150) Brown-Out Detect */
|
||||
__IO uint32_t SYSTCKCAL; /*!< (@ 0x40048154) System tick counter calibration */
|
||||
__I uint32_t RESERVED10[6];
|
||||
__IO uint32_t IRQLATENCY; /*!< (@ 0x40048170) IQR delay */
|
||||
__IO uint32_t NMISRC; /*!< (@ 0x40048174) NMI Source Control */
|
||||
__IO uint32_t PINTSEL[8]; /*!< (@ 0x40048178) GPIO Pin Interrupt Select register 0 */
|
||||
__IO uint32_t USBCLKCTRL; /*!< (@ 0x40048198) USB clock control */
|
||||
__I uint32_t USBCLKST; /*!< (@ 0x4004819C) USB clock status */
|
||||
__I uint32_t RESERVED11[25];
|
||||
__IO uint32_t STARTERP0; /*!< (@ 0x40048204) Start logic 0 interrupt wake-up enable register 0 */
|
||||
__I uint32_t RESERVED12[3];
|
||||
__IO uint32_t STARTERP1; /*!< (@ 0x40048214) Start logic 1 interrupt wake-up enable register 1 */
|
||||
__I uint32_t RESERVED13[6];
|
||||
__IO uint32_t PDSLEEPCFG; /*!< (@ 0x40048230) Power-down states in deep-sleep mode */
|
||||
__IO uint32_t PDAWAKECFG; /*!< (@ 0x40048234) Power-down states for wake-up from deep-sleep */
|
||||
__IO uint32_t PDRUNCFG; /*!< (@ 0x40048238) Power configuration register */
|
||||
__I uint32_t RESERVED14[110];
|
||||
__I uint32_t DEVICE_ID; /*!< (@ 0x400483F4) Device ID */
|
||||
} LPC_SYSCON_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- GPIO_PIN_INT -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (GPIO_PIN_INT)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x4004C000) GPIO_PIN_INT Structure */
|
||||
__IO uint32_t ISEL; /*!< (@ 0x4004C000) Pin Interrupt Mode register */
|
||||
__IO uint32_t IENR; /*!< (@ 0x4004C004) Pin Interrupt Enable (Rising) register */
|
||||
__IO uint32_t SIENR; /*!< (@ 0x4004C008) Set Pin Interrupt Enable (Rising) register */
|
||||
__IO uint32_t CIENR; /*!< (@ 0x4004C00C) Clear Pin Interrupt Enable (Rising) register */
|
||||
__IO uint32_t IENF; /*!< (@ 0x4004C010) Pin Interrupt Enable Falling Edge / Active Level register */
|
||||
__IO uint32_t SIENF; /*!< (@ 0x4004C014) Set Pin Interrupt Enable Falling Edge / Active Level register */
|
||||
__IO uint32_t CIENF; /*!< (@ 0x4004C018) Clear Pin Interrupt Enable Falling Edge / Active Level address */
|
||||
__IO uint32_t RISE; /*!< (@ 0x4004C01C) Pin Interrupt Rising Edge register */
|
||||
__IO uint32_t FALL; /*!< (@ 0x4004C020) Pin Interrupt Falling Edge register */
|
||||
__IO uint32_t IST; /*!< (@ 0x4004C024) Pin Interrupt Status register */
|
||||
} LPC_GPIO_PIN_INT_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- GPIO_GROUP_INT0/1 -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (GPIO_GROUP_INT0)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x4005C000) GPIO_GROUP_INT0 Structure */
|
||||
__IO uint32_t CTRL; /*!< (@ 0x4005C000) GPIO grouped interrupt control register */
|
||||
__I uint32_t RESERVED0[7];
|
||||
__IO uint32_t PORT_POL[2]; /*!< (@ 0x4005C020) GPIO grouped interrupt port 0 polarity register */
|
||||
__I uint32_t RESERVED1[6];
|
||||
__IO uint32_t PORT_ENA[2]; /*!< (@ 0x4005C040) GPIO grouped interrupt port 0/1 enable register */
|
||||
} LPC_GPIO_GROUP_INTx_Type;
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- USB -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x USB2.0device controller Modification date=3/16/2011 Major revision=0 Minor revision=3 (USB)
|
||||
*/
|
||||
|
||||
typedef struct { /*!< (@ 0x40080000) USB Structure */
|
||||
__IO uint32_t DEVCMDSTAT; /*!< (@ 0x40080000) USB Device Command/Status register */
|
||||
__IO uint32_t INFO; /*!< (@ 0x40080004) USB Info register */
|
||||
__IO uint32_t EPLISTSTART; /*!< (@ 0x40080008) USB EP Command/Status List start address */
|
||||
__IO uint32_t DATABUFSTART; /*!< (@ 0x4008000C) USB Data buffer start address */
|
||||
__IO uint32_t LPM; /*!< (@ 0x40080010) Link Power Management register */
|
||||
__IO uint32_t EPSKIP; /*!< (@ 0x40080014) USB Endpoint skip */
|
||||
__IO uint32_t EPINUSE; /*!< (@ 0x40080018) USB Endpoint Buffer in use */
|
||||
__IO uint32_t EPBUFCFG; /*!< (@ 0x4008001C) USB Endpoint Buffer Configuration register */
|
||||
__IO uint32_t INTSTAT; /*!< (@ 0x40080020) USB interrupt status register */
|
||||
__IO uint32_t INTEN; /*!< (@ 0x40080024) USB interrupt enable register */
|
||||
__IO uint32_t INTSETSTAT; /*!< (@ 0x40080028) USB set interrupt status register */
|
||||
__IO uint32_t INTROUTING; /*!< (@ 0x4008002C) USB interrupt routing register */
|
||||
__I uint32_t RESERVED0[1];
|
||||
__I uint32_t EPTOGGLE; /*!< (@ 0x40080034) USB Endpoint toggle register */
|
||||
} LPC_USB_Type;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- GPIO_PORT -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Product name title=UM10462 Chapter title=LPC11U1x GPIO Modification date=3/17/2011 Major revision=0 Minor revision=3 (GPIO_PORT)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
__IO uint8_t B0[32]; /*!< (@ 0x50000000) Byte pin registers port 0; pins PIO0_0 to PIO0_31 */
|
||||
__IO uint8_t B1[32]; /*!< (@ 0x50000020) Byte pin registers port 1 */
|
||||
};
|
||||
__IO uint8_t B[64]; /*!< (@ 0x50000000) Byte pin registers port 0/1 */
|
||||
};
|
||||
__I uint32_t RESERVED0[1008];
|
||||
union {
|
||||
struct {
|
||||
__IO uint32_t W0[32]; /*!< (@ 0x50001000) Word pin registers port 0 */
|
||||
__IO uint32_t W1[32]; /*!< (@ 0x50001080) Word pin registers port 1 */
|
||||
};
|
||||
__IO uint32_t W[64]; /*!< (@ 0x50001000) Word pin registers port 0/1 */
|
||||
};
|
||||
uint32_t RESERVED1[960];
|
||||
__IO uint32_t DIR[2]; /* 0x2000 */
|
||||
uint32_t RESERVED2[30];
|
||||
__IO uint32_t MASK[2]; /* 0x2080 */
|
||||
uint32_t RESERVED3[30];
|
||||
__IO uint32_t PIN[2]; /* 0x2100 */
|
||||
uint32_t RESERVED4[30];
|
||||
__IO uint32_t MPIN[2]; /* 0x2180 */
|
||||
uint32_t RESERVED5[30];
|
||||
__IO uint32_t SET[2]; /* 0x2200 */
|
||||
uint32_t RESERVED6[30];
|
||||
__O uint32_t CLR[2]; /* 0x2280 */
|
||||
uint32_t RESERVED7[30];
|
||||
__O uint32_t NOT[2]; /* 0x2300 */
|
||||
} LPC_GPIO_Type;
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#pragma no_anon_unions
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- Peripheral memory map -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
#define LPC_I2C_BASE (0x40000000)
|
||||
#define LPC_WWDT_BASE (0x40004000)
|
||||
#define LPC_USART_BASE (0x40008000)
|
||||
#define LPC_CT16B0_BASE (0x4000C000)
|
||||
#define LPC_CT16B1_BASE (0x40010000)
|
||||
#define LPC_CT32B0_BASE (0x40014000)
|
||||
#define LPC_CT32B1_BASE (0x40018000)
|
||||
#define LPC_ADC_BASE (0x4001C000)
|
||||
#define LPC_PMU_BASE (0x40038000)
|
||||
#define LPC_FLASHCTRL_BASE (0x4003C000)
|
||||
#define LPC_SSP0_BASE (0x40040000)
|
||||
#define LPC_SSP1_BASE (0x40058000)
|
||||
#define LPC_IOCON_BASE (0x40044000)
|
||||
#define LPC_SYSCON_BASE (0x40048000)
|
||||
#define LPC_GPIO_PIN_INT_BASE (0x4004C000)
|
||||
#define LPC_GPIO_GROUP_INT0_BASE (0x4005C000)
|
||||
#define LPC_GPIO_GROUP_INT1_BASE (0x40060000)
|
||||
#define LPC_USB_BASE (0x40080000)
|
||||
#define LPC_GPIO_BASE (0x50000000)
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ----- Peripheral declaration -----
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
#define LPC_I2C ((LPC_I2C_Type *) LPC_I2C_BASE)
|
||||
#define LPC_WWDT ((LPC_WWDT_Type *) LPC_WWDT_BASE)
|
||||
#define LPC_USART ((LPC_USART_Type *) LPC_USART_BASE)
|
||||
#define LPC_CT16B0 ((LPC_CTxxBx_Type *) LPC_CT16B0_BASE)
|
||||
#define LPC_CT16B1 ((LPC_CTxxBx_Type *) LPC_CT16B1_BASE)
|
||||
#define LPC_CT32B0 ((LPC_CTxxBx_Type *) LPC_CT32B0_BASE)
|
||||
#define LPC_CT32B1 ((LPC_CTxxBx_Type *) LPC_CT32B1_BASE)
|
||||
#define LPC_ADC ((LPC_ADC_Type *) LPC_ADC_BASE)
|
||||
#define LPC_PMU ((LPC_PMU_Type *) LPC_PMU_BASE)
|
||||
#define LPC_FLASHCTRL ((LPC_FLASHCTRL_Type *) LPC_FLASHCTRL_BASE)
|
||||
#define LPC_SSP0 ((LPC_SSPx_Type *) LPC_SSP0_BASE)
|
||||
#define LPC_SSP1 ((LPC_SSPx_Type *) LPC_SSP1_BASE)
|
||||
#define LPC_IOCON ((LPC_IOCON_Type *) LPC_IOCON_BASE)
|
||||
#define LPC_SYSCON ((LPC_SYSCON_Type *) LPC_SYSCON_BASE)
|
||||
#define LPC_GPIO_PIN_INT ((LPC_GPIO_PIN_INT_Type *) LPC_GPIO_PIN_INT_BASE)
|
||||
#define LPC_GPIO_GROUP_INT0 ((LPC_GPIO_GROUP_INTx_Type*) LPC_GPIO_GROUP_INT0_BASE)
|
||||
#define LPC_GPIO_GROUP_INT1 ((LPC_GPIO_GROUP_INTx_Type*) LPC_GPIO_GROUP_INT1_BASE)
|
||||
#define LPC_USB ((LPC_USB_Type *) LPC_USB_BASE)
|
||||
#define LPC_GPIO ((LPC_GPIO_Type *) LPC_GPIO_BASE)
|
||||
|
||||
|
||||
/** @} */ /* End of group Device_Peripheral_Registers */
|
||||
/** @} */ /* End of group (null) */
|
||||
/** @} */ /* End of group LPC11Uxx */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // __LPC11UXX_H__
|
||||
167
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld.c
Executable file
167
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld.c
Executable file
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC11Uxx/ext_lld.c
|
||||
* @brief LPC11Uxx EXT subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup EXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
||||
|
||||
#include "ext_lld_isr.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EXTD1 driver identifier.
|
||||
*/
|
||||
EXTDriver EXTD1;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level EXT driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_init(void) {
|
||||
|
||||
/* Driver initialization.*/
|
||||
extObjectInit(&EXTD1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the EXT peripheral.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_start(EXTDriver *extp) {
|
||||
int i;
|
||||
|
||||
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<19);
|
||||
/* Configuration of automatic channels.*/
|
||||
for (i = 0; i < EXT_MAX_CHANNELS; i++)
|
||||
if (extp->config->channels[i].mode & EXT_CH_MODE_AUTOSTART)
|
||||
ext_lld_channel_enable(extp, i);
|
||||
else
|
||||
ext_lld_channel_disable(extp, i);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the EXT peripheral.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_stop(EXTDriver *extp) {
|
||||
int i;
|
||||
|
||||
if (extp->state == EXT_ACTIVE)
|
||||
for (i = 0; i < EXT_MAX_CHANNELS; i++)
|
||||
ext_lld_exti_irq_disable(i);
|
||||
|
||||
LPC_GPIO_PIN_INT->ISEL = 0;
|
||||
LPC_GPIO_PIN_INT->CIENR = EXT_CHANNELS_MASK;
|
||||
LPC_GPIO_PIN_INT->RISE = EXT_CHANNELS_MASK;
|
||||
LPC_GPIO_PIN_INT->FALL = EXT_CHANNELS_MASK;
|
||||
LPC_GPIO_PIN_INT->IST = EXT_CHANNELS_MASK;
|
||||
|
||||
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1<<19);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables an EXT channel.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
* @param[in] channel channel to be enabled
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel) {
|
||||
|
||||
/* program the IOpin for this channel */
|
||||
LPC_SYSCON->PINTSEL[channel] = extp->config->channels[channel].iopin;
|
||||
|
||||
/* Programming edge irq enables */
|
||||
if (extp->config->channels[channel].mode & EXT_CH_MODE_RISING_EDGE)
|
||||
LPC_GPIO_PIN_INT->SIENR = (1 << channel);
|
||||
else
|
||||
LPC_GPIO_PIN_INT->CIENR = (1 << channel);
|
||||
|
||||
if (extp->config->channels[channel].mode & EXT_CH_MODE_FALLING_EDGE)
|
||||
LPC_GPIO_PIN_INT->SIENF = (1 << channel);
|
||||
else
|
||||
LPC_GPIO_PIN_INT->CIENF = (1 << channel);
|
||||
|
||||
LPC_GPIO_PIN_INT->RISE = (1<<channel);
|
||||
LPC_GPIO_PIN_INT->FALL = (1<<channel);
|
||||
LPC_GPIO_PIN_INT->IST = (1<<channel);
|
||||
|
||||
ext_lld_exti_irq_enable( channel );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables an EXT channel.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXTDriver object
|
||||
* @param[in] channel channel to be disabled
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel) {
|
||||
(void)extp;
|
||||
|
||||
ext_lld_exti_irq_disable(channel);
|
||||
|
||||
LPC_GPIO_PIN_INT->ISEL &= ~(1 << channel);
|
||||
LPC_GPIO_PIN_INT->CIENR = (1 << channel);
|
||||
LPC_GPIO_PIN_INT->RISE = (1 << channel);
|
||||
LPC_GPIO_PIN_INT->FALL = (1 << channel);
|
||||
LPC_GPIO_PIN_INT->IST = (1 << channel);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_EXT */
|
||||
|
||||
/** @} */
|
||||
152
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld.h
Executable file
152
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld.h
Executable file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC11Uxx/ext_lld.h
|
||||
* @brief LPC11Uxx EXT subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup EXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _EXT_LLD_H_
|
||||
#define _EXT_LLD_H_
|
||||
|
||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Available number of EXT channels.
|
||||
*/
|
||||
#define EXT_MAX_CHANNELS 8
|
||||
|
||||
/**
|
||||
* @brief Mask of the available channels.
|
||||
*/
|
||||
#define EXT_CHANNELS_MASK ((1 << EXT_MAX_CHANNELS) - 1)
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief EXT channel identifier.
|
||||
*/
|
||||
typedef uint32_t expchannel_t;
|
||||
|
||||
/**
|
||||
|
||||
* @brief EXT channel callback reason.
|
||||
*/
|
||||
typedef uint32_t expreason_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an EXT generic notification callback.
|
||||
*
|
||||
* @param[in] extp pointer to the @p EXPDriver object triggering the
|
||||
* callback
|
||||
*/
|
||||
typedef void (*extcallback_t)(EXTDriver *extp,
|
||||
expchannel_t channel,
|
||||
expreason_t reason);
|
||||
|
||||
/**
|
||||
* @brief Channel configuration structure.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel mode.
|
||||
*/
|
||||
uint8_t mode;
|
||||
/**
|
||||
* @brief IO Pin.
|
||||
*/
|
||||
uint8_t iopin;
|
||||
/**
|
||||
* @brief Channel callback.
|
||||
*/
|
||||
extcallback_t cb;
|
||||
} EXTChannelConfig;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Channel configurations.
|
||||
*/
|
||||
EXTChannelConfig channels[EXT_MAX_CHANNELS];
|
||||
/* End of the mandatory fields.*/
|
||||
} EXTConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing an EXT driver.
|
||||
*/
|
||||
struct EXTDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
extstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const EXTConfig *config;
|
||||
/* End of the mandatory fields.*/
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern EXTDriver EXTD1;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void ext_lld_init(void);
|
||||
void ext_lld_start(EXTDriver *extp);
|
||||
void ext_lld_stop(EXTDriver *extp);
|
||||
void ext_lld_channel_enable(EXTDriver *extp, expchannel_t channel);
|
||||
void ext_lld_channel_disable(EXTDriver *extp, expchannel_t channel);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_EXT */
|
||||
|
||||
#endif /* _EXT_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
194
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld_isr.c
Executable file
194
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld_isr.c
Executable file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC11Uxx/ext_lld_isr.c
|
||||
* @brief LPC11Uxx EXT subsystem low level driver ISR code.
|
||||
*
|
||||
* @addtogroup EXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
||||
|
||||
#include "ext_lld_isr.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
static void ext_lld_interrupt( uint32_t n ) {
|
||||
uint32_t reason;
|
||||
|
||||
reason = ((LPC_GPIO_PIN_INT->RISE)>> n ) & 0x01;
|
||||
reason |= ((LPC_GPIO_PIN_INT->FALL)>>(n-1)) & 0x02;
|
||||
LPC_GPIO_PIN_INT->RISE = (1<<n);
|
||||
LPC_GPIO_PIN_INT->FALL = (1<<n);
|
||||
LPC_GPIO_PIN_INT->IST = (1<<n);
|
||||
EXTD1.config->channels[n].cb(&EXTD1, n, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[0] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector40) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(0);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[1] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector44) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(1);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[2] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector48) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(2);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[3] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector4C) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(3);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[4] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector50) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(4);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[5] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector54) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(5);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[6] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector58) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(6);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXT[7] interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector5C) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
ext_lld_interrupt(7);
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
static const uint8_t LPC11_EXT_EXTIn_IRQ_PRIORITY[] =
|
||||
{ LPC11_EXT_EXTI0_IRQ_PRIORITY,
|
||||
LPC11_EXT_EXTI1_IRQ_PRIORITY,
|
||||
LPC11_EXT_EXTI2_IRQ_PRIORITY,
|
||||
LPC11_EXT_EXTI3_IRQ_PRIORITY,
|
||||
LPC11_EXT_EXTI4_IRQ_PRIORITY,
|
||||
LPC11_EXT_EXTI5_IRQ_PRIORITY,
|
||||
LPC11_EXT_EXTI6_IRQ_PRIORITY,
|
||||
LPC11_EXT_EXTI7_IRQ_PRIORITY };
|
||||
|
||||
/**
|
||||
* @brief Enables EXTI IRQ sources.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_exti_irq_enable( uint32_t exti_n ) {
|
||||
|
||||
nvicEnableVector(FLEX_INT0_IRQn + exti_n,
|
||||
CORTEX_PRIORITY_MASK(LPC11_EXT_EXTIn_IRQ_PRIORITY[exti_n]));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables EXTI IRQ sources.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void ext_lld_exti_irq_disable( uint32_t exti_n ) {
|
||||
|
||||
nvicDisableVector(FLEX_INT0_IRQn + exti_n);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_EXT */
|
||||
|
||||
/** @} */
|
||||
129
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld_isr.h
Executable file
129
firmware/chibios/os/hal/platforms/LPC11Uxx/ext_lld_isr.h
Executable file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC11Uxx/ext_lld_isr.h
|
||||
* @brief LPC11Uxx EXT subsystem low level driver ISR header.
|
||||
*
|
||||
* @addtogroup EXT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _EXT_LLD_ISR_H_
|
||||
#define _EXT_LLD_ISR_H_
|
||||
|
||||
#if HAL_USE_EXT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @name Configuration options
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief EXTI0 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI0_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI0_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EXTI1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI1_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EXTI2 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI2_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI2_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EXTI3 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI3_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI3_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EXTI4 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI4_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI4_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EXTI5 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI5_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI5_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EXTI6 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI6_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI6_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief EXTI7 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC11_EXT_EXTI7_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC11_EXT_EXTI7_IRQ_PRIORITY 3
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void ext_lld_exti_irq_enable( uint32_t exti_n );
|
||||
void ext_lld_exti_irq_disable( uint32_t exti_n );
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_EXT */
|
||||
|
||||
#endif /* _EXT_LLD_ISR_H_ */
|
||||
|
||||
/** @} */
|
||||
338
firmware/chibios/os/hal/platforms/LPC11Uxx/gpt_lld.c
Executable file
338
firmware/chibios/os/hal/platforms/LPC11Uxx/gpt_lld.c
Executable file
@@ -0,0 +1,338 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC11Uxx/gpt_lld.c
|
||||
* @brief LPC11Uxx GPT subsystem low level driver source.
|
||||
*
|
||||
* @addtogroup GPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
#if HAL_USE_GPT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPT1 driver identifier.
|
||||
* @note The driver GPT1 allocates the complex timer CT16B0 when enabled.
|
||||
*/
|
||||
#if LPC_GPT_USE_CT16B0 || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD1;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT2 driver identifier.
|
||||
* @note The driver GPT2 allocates the timer CT16B1 when enabled.
|
||||
*/
|
||||
#if LPC_GPT_USE_CT16B1 || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD2;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT3 driver identifier.
|
||||
* @note The driver GPT3 allocates the timer CT32B0 when enabled.
|
||||
*/
|
||||
#if LPC_GPT_USE_CT32B0 || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD3;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT4 driver identifier.
|
||||
* @note The driver GPT4 allocates the timer CT32B1 when enabled.
|
||||
*/
|
||||
#if LPC_GPT_USE_CT32B1 || defined(__DOXYGEN__)
|
||||
GPTDriver GPTD4;
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local variables and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Shared IRQ handler.
|
||||
*
|
||||
* @param[in] gptp pointer to a @p GPTDriver object
|
||||
*/
|
||||
static void gpt_lld_serve_interrupt(GPTDriver *gptp) {
|
||||
|
||||
gptp->tmr->IR = 1; /* Clear interrupt on match MR0.*/
|
||||
if (gptp->state == GPT_ONESHOT) {
|
||||
gptp->state = GPT_READY; /* Back in GPT_READY state. */
|
||||
gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */
|
||||
}
|
||||
gptp->config->callback(gptp);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver interrupt handlers. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if LPC_GPT_USE_CT16B0
|
||||
/**
|
||||
* @brief CT16B0 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector80) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
gpt_lld_serve_interrupt(&GPTD1);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* LPC_GPT_USE_CT16B0 */
|
||||
|
||||
#if LPC_GPT_USE_CT16B1
|
||||
/**
|
||||
* @brief CT16B1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector84) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
gpt_lld_serve_interrupt(&GPTD2);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* LPC_GPT_USE_CT16B0 */
|
||||
|
||||
#if LPC_GPT_USE_CT32B0
|
||||
/**
|
||||
* @brief CT32B0 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector88) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
gpt_lld_serve_interrupt(&GPTD3);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* LPC_GPT_USE_CT32B0 */
|
||||
|
||||
#if LPC_GPT_USE_CT32B1
|
||||
/**
|
||||
* @brief CT32B1 interrupt handler.
|
||||
*
|
||||
* @isr
|
||||
*/
|
||||
CH_IRQ_HANDLER(Vector8C) {
|
||||
|
||||
CH_IRQ_PROLOGUE();
|
||||
|
||||
gpt_lld_serve_interrupt(&GPTD4);
|
||||
|
||||
CH_IRQ_EPILOGUE();
|
||||
}
|
||||
#endif /* LPC_GPT_USE_CT32B1 */
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Low level GPT driver initialization.
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_init(void) {
|
||||
|
||||
#if LPC_GPT_USE_CT16B0
|
||||
/* Driver initialization.*/
|
||||
GPTD1.tmr = LPC_CT16B0;
|
||||
gptObjectInit(&GPTD1);
|
||||
#endif
|
||||
|
||||
#if LPC_GPT_USE_CT16B1
|
||||
/* Driver initialization.*/
|
||||
GPTD2.tmr = LPC_CT16B1;
|
||||
gptObjectInit(&GPTD2);
|
||||
#endif
|
||||
|
||||
#if LPC_GPT_USE_CT32B0
|
||||
/* Driver initialization.*/
|
||||
GPTD3.tmr = LPC_CT32B0;
|
||||
gptObjectInit(&GPTD3);
|
||||
#endif
|
||||
|
||||
#if LPC_GPT_USE_CT32B1
|
||||
/* Driver initialization.*/
|
||||
GPTD4.tmr = LPC_CT32B1;
|
||||
gptObjectInit(&GPTD4);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures and activates the GPT peripheral.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_start(GPTDriver *gptp) {
|
||||
uint32_t pr;
|
||||
|
||||
if (gptp->state == GPT_STOP) {
|
||||
/* Clock activation.*/
|
||||
#if LPC_GPT_USE_CT16B0
|
||||
if (&GPTD1 == gptp) {
|
||||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 7);
|
||||
nvicEnableVector(TIMER_16_0_IRQn, CORTEX_PRIORITY_MASK(2));
|
||||
}
|
||||
#endif
|
||||
#if LPC_GPT_USE_CT16B1
|
||||
if (&GPTD2 == gptp) {
|
||||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
|
||||
nvicEnableVector(TIMER_16_1_IRQn, CORTEX_PRIORITY_MASK(3));
|
||||
}
|
||||
#endif
|
||||
#if LPC_GPT_USE_CT32B0
|
||||
if (&GPTD3 == gptp) {
|
||||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 9);
|
||||
nvicEnableVector(TIMER_32_0_IRQn, CORTEX_PRIORITY_MASK(2));
|
||||
}
|
||||
#endif
|
||||
#if LPC_GPT_USE_CT32B1
|
||||
if (&GPTD4 == gptp) {
|
||||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
|
||||
nvicEnableVector(TIMER_32_1_IRQn, CORTEX_PRIORITY_MASK(2));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Prescaler value calculation.*/
|
||||
pr = (uint16_t)((LPC_SYSCLK / gptp->config->frequency) - 1);
|
||||
chDbgAssert(((uint32_t)(pr + 1) * gptp->config->frequency) == LPC_SYSCLK,
|
||||
"gpt_lld_start(), #1", "invalid frequency");
|
||||
|
||||
/* Timer configuration.*/
|
||||
gptp->tmr->PR = pr;
|
||||
gptp->tmr->IR = 1;
|
||||
gptp->tmr->MCR = 0;
|
||||
gptp->tmr->TCR = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates the GPT peripheral.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_stop(GPTDriver *gptp) {
|
||||
|
||||
if (gptp->state == GPT_READY) {
|
||||
gptp->tmr->MCR = 0;
|
||||
gptp->tmr->TCR = 0;
|
||||
|
||||
#if LPC_GPT_USE_CT16B0
|
||||
if (&GPTD1 == gptp) {
|
||||
nvicDisableVector(TIMER_16_0_IRQn);
|
||||
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 7);
|
||||
}
|
||||
#endif
|
||||
#if LPC_GPT_USE_CT16B1
|
||||
if (&GPTD2 == gptp) {
|
||||
nvicDisableVector(TIMER_16_1_IRQn);
|
||||
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
|
||||
}
|
||||
#endif
|
||||
#if LPC_GPT_USE_CT32B0
|
||||
if (&GPTD3 == gptp) {
|
||||
nvicDisableVector(TIMER_32_0_IRQn);
|
||||
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 9);
|
||||
}
|
||||
#endif
|
||||
#if LPC_GPT_USE_CT32B1
|
||||
if (&GPTD4 == gptp) {
|
||||
nvicDisableVector(TIMER_32_1_IRQn);
|
||||
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 10);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the timer in continuous mode.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
* @param[in] interval period in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) {
|
||||
|
||||
gptp->tmr->MR0 = interval - 1;
|
||||
gptp->tmr->IR = 1;
|
||||
gptp->tmr->MCR = 3; /* IRQ and clr TC on match MR0. */
|
||||
gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
|
||||
gptp->tmr->TCR = 1; /* Timer enabled. */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the timer.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_stop_timer(GPTDriver *gptp) {
|
||||
|
||||
gptp->tmr->IR = 1;
|
||||
gptp->tmr->MCR = 0;
|
||||
gptp->tmr->TCR = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the timer in one shot mode and waits for completion.
|
||||
* @details This function specifically polls the timer waiting for completion
|
||||
* in order to not have extra delays caused by interrupt servicing,
|
||||
* this function is only recommended for short delays.
|
||||
*
|
||||
* @param[in] gptp pointer to the @p GPTDriver object
|
||||
* @param[in] interval time interval in ticks
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) {
|
||||
|
||||
gptp->tmr->MR0 = interval - 1;
|
||||
gptp->tmr->IR = 1;
|
||||
gptp->tmr->MCR = 4; /* Stop TC on match MR0. */
|
||||
gptp->tmr->TCR = 2; /* Reset counter and prescaler. */
|
||||
gptp->tmr->TCR = 1; /* Timer enabled. */
|
||||
while (gptp->tmr->TCR & 1)
|
||||
;
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_GPT */
|
||||
|
||||
/** @} */
|
||||
204
firmware/chibios/os/hal/platforms/LPC11Uxx/gpt_lld.h
Executable file
204
firmware/chibios/os/hal/platforms/LPC11Uxx/gpt_lld.h
Executable file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file LPC11Uxx/gpt_lld.h
|
||||
* @brief LPC11Uxx GPT subsystem low level driver header.
|
||||
*
|
||||
* @addtogroup GPT
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef _GPT_LLD_H_
|
||||
#define _GPT_LLD_H_
|
||||
|
||||
#if HAL_USE_GPT || defined(__DOXYGEN__)
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPT1 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPT1 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(LPC_GPT_USE_CT16B0) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_USE_CT16B0 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT2 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPT2 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(LPC_GPT_USE_CT16B1) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_USE_CT16B1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT3 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPT3 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(LPC_GPT_USE_CT32B0) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_USE_CT32B0 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT4 driver enable switch.
|
||||
* @details If set to @p TRUE the support for GPT4 is included.
|
||||
* @note The default is @p TRUE.
|
||||
*/
|
||||
#if !defined(LPC_GPT_USE_CT32B1) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_USE_CT32B1 TRUE
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT1 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC_GPT_CT16B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_CT16B0_IRQ_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT2 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC_GPT_CT16B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_CT16B1_IRQ_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT3 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC_GPT_CT32B0_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_CT32B0_IRQ_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief GPT4 interrupt priority level setting.
|
||||
*/
|
||||
#if !defined(LPC_GPT_CT32B1_IRQ_PRIORITY) || defined(__DOXYGEN__)
|
||||
#define LPC_GPT_CT32B1_IRQ_PRIORITY 2
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if !LPC_GPT_USE_CT16B0 && !LPC_GPT_USE_CT16B1 && \
|
||||
!LPC_GPT_USE_CT32B0 && !LPC_GPT_USE_CT32B1
|
||||
#error "GPT driver activated but no CT peripheral assigned"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief GPT frequency type.
|
||||
*/
|
||||
typedef uint32_t gptfreq_t;
|
||||
|
||||
/**
|
||||
* @brief GPT counter type.
|
||||
*/
|
||||
typedef uint32_t gptcnt_t;
|
||||
|
||||
/**
|
||||
* @brief Driver configuration structure.
|
||||
* @note It could be empty on some architectures.
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Timer clock in Hz.
|
||||
* @note The low level can use assertions in order to catch invalid
|
||||
* frequency specifications.
|
||||
*/
|
||||
gptfreq_t frequency;
|
||||
/**
|
||||
* @brief Timer callback pointer.
|
||||
* @note This callback is invoked on GPT counter events.
|
||||
*/
|
||||
gptcallback_t callback;
|
||||
/* End of the mandatory fields.*/
|
||||
} GPTConfig;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a GPT driver.
|
||||
*/
|
||||
struct GPTDriver {
|
||||
/**
|
||||
* @brief Driver state.
|
||||
*/
|
||||
gptstate_t state;
|
||||
/**
|
||||
* @brief Current configuration data.
|
||||
*/
|
||||
const GPTConfig *config;
|
||||
/* End of the mandatory fields.*/
|
||||
/**
|
||||
* @brief Pointer to the CTxxBy registers block.
|
||||
*/
|
||||
LPC_CTxxBx_Type *tmr;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Driver macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if LPC_GPT_USE_CT16B0 && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD1;
|
||||
#endif
|
||||
|
||||
#if LPC_GPT_USE_CT16B1 && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD2;
|
||||
#endif
|
||||
|
||||
#if LPC_GPT_USE_CT32B0 && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD3;
|
||||
#endif
|
||||
|
||||
#if LPC_GPT_USE_CT32B1 && !defined(__DOXYGEN__)
|
||||
extern GPTDriver GPTD4;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void gpt_lld_init(void);
|
||||
void gpt_lld_start(GPTDriver *gptp);
|
||||
void gpt_lld_stop(GPTDriver *gptp);
|
||||
void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period);
|
||||
void gpt_lld_stop_timer(GPTDriver *gptp);
|
||||
void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAL_USE_GPT */
|
||||
|
||||
#endif /* _GPT_LLD_H_ */
|
||||
|
||||
/** @} */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user