ChibiOS/RT
2.5.1
pal_lld.h
Go to the documentation of this file.
00001 /*
00002     ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
00003                  2011,2012 Giovanni Di Sirio.
00004 
00005     This file is part of ChibiOS/RT.
00006 
00007     ChibiOS/RT is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     ChibiOS/RT is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 /**
00022  * @file  AVR/pal_lld.h
00023  * @brief AVR GPIO low level driver header.
00024  *
00025  * @addtogroup PAL
00026  * @{
00027  */
00028 
00029 #ifndef _PAL_LLD_H_
00030 #define _PAL_LLD_H_
00031 
00032 #if HAL_USE_PAL || defined(__DOXYGEN__)
00033 
00034 /*===========================================================================*/
00035 /* Unsupported modes and specific modes                                      */
00036 /*===========================================================================*/
00037 
00038 #undef PAL_MODE_INPUT_PULLDOWN
00039 #undef PAL_MODE_OUTPUT_OPENDRAIN
00040 
00041 /*===========================================================================*/
00042 /* I/O Ports Types and constants.                                            */
00043 /*===========================================================================*/
00044 
00045 /**
00046  * @brief   Width, in bits, of an I/O port.
00047  */
00048 #define PAL_IOPORTS_WIDTH 8
00049 
00050 /**
00051  * @brief   Whole port mask.
00052  * @details This macro specifies all the valid bits into a port.
00053  */
00054 #define PAL_WHOLE_PORT ((ioportmask_t)0xFF)
00055 
00056 /**
00057  * @brief   AVR setup registers.
00058  */
00059 typedef struct  {
00060   uint8_t  out;
00061   uint8_t  dir;
00062 } avr_gpio_setup_t;
00063 
00064 /**
00065  * @brief   AVR registers block.
00066  * @note    On some devices registers do not follow this layout on some
00067  *          ports, the ports with abnormal layout cannot be used through
00068  *          PAL driver. Example: PORT F on Mega128.
00069  */
00070 typedef struct  {
00071   volatile uint8_t  in;
00072   volatile uint8_t  dir;
00073   volatile uint8_t  out;
00074 } avr_gpio_registers_t;
00075 
00076 /**
00077  * @brief   Generic I/O ports static initializer.
00078  * @details An instance of this structure must be passed to @p palInit() at
00079  *          system startup time in order to initialized the digital I/O
00080  *          subsystem. This represents only the initial setup, specific pads
00081  *          or whole ports can be reprogrammed at later time.
00082  */
00083 typedef struct {
00084 #if defined(PORTA) || defined(__DOXYGEN__)
00085   avr_gpio_setup_t porta;
00086 #endif
00087 #if defined(PORTB) || defined(__DOXYGEN__)
00088   avr_gpio_setup_t portb;
00089 #endif
00090 #if defined(PORTC) || defined(__DOXYGEN__)
00091   avr_gpio_setup_t portc;
00092 #endif
00093 #if defined(PORTD) || defined(__DOXYGEN__)
00094   avr_gpio_setup_t portd;
00095 #endif
00096 #if defined(PORTE) || defined(__DOXYGEN__)
00097   avr_gpio_setup_t porte;
00098 #endif
00099 #if defined(PORTF) || defined(__DOXYGEN__)
00100   avr_gpio_setup_t portf;
00101 #endif
00102 #if defined(PORTG) || defined(__DOXYGEN__)
00103   avr_gpio_setup_t portg;
00104 #endif
00105 #if defined(PORTH) || defined(__DOXYGEN__)
00106   avr_gpio_setup_t porth;
00107 #endif
00108 #if defined(PORTJ) || defined(__DOXYGEN__)
00109   avr_gpio_setup_t portj;
00110 #endif
00111 #if defined(PORTK) || defined(__DOXYGEN__)
00112   avr_gpio_setup_t portk;
00113 #endif
00114 #if defined(PORTL) || defined(__DOXYGEN__)
00115   avr_gpio_setup_t portl;
00116 #endif
00117 } PALConfig;
00118 
00119 /**
00120  * @brief   Digital I/O port sized unsigned type.
00121  */
00122 typedef uint8_t ioportmask_t;
00123 
00124 /**
00125  * @brief   Digital I/O modes.
00126  */
00127 typedef uint8_t iomode_t;
00128 
00129 /**
00130  * @brief   Port Identifier.
00131  * @details This type can be a scalar or some kind of pointer, do not make
00132  *          any assumption about it, use the provided macros when populating
00133  *          variables of this type.
00134  */
00135 typedef avr_gpio_registers_t *ioportid_t;
00136 
00137 /*===========================================================================*/
00138 /* I/O Ports Identifiers.                                                    */
00139 /*===========================================================================*/
00140 
00141 #if defined(PORTA) || defined(__DOXYGEN__)
00142 /**
00143  * @brief   GPIO port A identifier.
00144  */
00145 #define IOPORT1     ((volatile avr_gpio_registers_t *)&PINA)
00146 #endif
00147 
00148 #if defined(PORTB) || defined(__DOXYGEN__)
00149 /**
00150  * @brief   GPIO port B identifier.
00151  */
00152 #define IOPORT2     ((volatile avr_gpio_registers_t *)&PINB)
00153 #endif
00154 
00155 #if defined(PORTC) || defined(__DOXYGEN__)
00156 /**
00157  * @brief   GPIO port C identifier.
00158  */
00159 #define IOPORT3     ((volatile avr_gpio_registers_t *)&PINC)
00160 #endif
00161 
00162 #if defined(PORTD) || defined(__DOXYGEN__)
00163 /**
00164  * @brief   GPIO port D identifier.
00165  */
00166 #define IOPORT4     ((volatile avr_gpio_registers_t *)&PIND)
00167 #endif
00168 
00169 #if defined(PORTE) || defined(__DOXYGEN__)
00170 /**
00171  * @brief   GPIO port E identifier.
00172  */
00173 #define IOPORT5     ((volatile avr_gpio_registers_t *)&PINE)
00174 #endif
00175 
00176 #if defined(PORTF) || defined(__DOXYGEN__)
00177 /**
00178  * @brief   GPIO port F identifier.
00179  */
00180 #define IOPORT6     ((volatile avr_gpio_registers_t *)&PINF)
00181 #endif
00182 
00183 #if defined(PORTG) || defined(__DOXYGEN__)
00184 /**
00185  * @brief   GPIO port G identifier.
00186  */
00187 #define IOPORT7     ((volatile avr_gpio_registers_t *)&PING)
00188 #endif
00189 
00190 #if defined(PORTH) || defined(__DOXYGEN__)
00191 /**
00192  * @brief   GPIO port H identifier.
00193  */
00194 #define IOPORT8         ((volatile avr_gpio_registers_t *)&PINH)
00195 #endif
00196 
00197 #if defined(PORTJ) || defined(__DOXYGEN__)
00198 /**
00199  * @brief   GPIO port J identifier.
00200  */
00201 #define IOPORT9         ((volatile avr_gpio_registers_t *)&PINJ)
00202 #endif
00203 
00204 #if defined(PORTK) || defined(__DOXYGEN__)
00205 /**
00206  * @brief   GPIO port K identifier.
00207  */
00208 #define IOPORT10        ((volatile avr_gpio_registers_t *)&PINK)
00209 #endif
00210 
00211 #if defined(PORTL) || defined(__DOXYGEN__)
00212 /**
00213  * @brief   GPIO port L identifier.
00214  */
00215 #define IOPORT11        ((volatile avr_gpio_registers_t *)&PINL)
00216 #endif
00217 
00218 /*===========================================================================*/
00219 /* Implementation, some of the following macros could be implemented as      */
00220 /* functions, if so please put them in pal_lld.c.                            */
00221 /*===========================================================================*/
00222 
00223 /**
00224  * @brief   Low level PAL subsystem initialization.
00225  *
00226  * @param[in] config the architecture-dependent ports configuration
00227  *
00228  * @notapi
00229  */
00230 #define pal_lld_init(config) _pal_lld_init(config)
00231 
00232 /**
00233  * @brief   Reads the physical I/O port states.
00234  *
00235  * @param[in] port      port identifier
00236  * @return              The port bits.
00237  *
00238  * @notapi
00239  */
00240 #define pal_lld_readport(port) ((port)->in)
00241 
00242 /**
00243  * @brief   Reads the output latch.
00244  * @details The purpose of this function is to read back the latched output
00245  *          value.
00246  *
00247  * @param[in] port      port identifier
00248  * @return              The latched logical states.
00249  *
00250  * @notapi
00251  */
00252 #define pal_lld_readlatch(port) ((port)->out)
00253 
00254 /**
00255  * @brief   Writes a bits mask on a I/O port.
00256  *
00257  * @param[in] port      port identifier
00258  * @param[in] bits      bits to be written on the specified port
00259  *
00260  * @notapi
00261  */
00262 #define pal_lld_writeport(port, bits) ((port)->out = bits)
00263 
00264 /**
00265  * @brief   Pads group mode setup.
00266  * @details This function programs a pads group belonging to the same port
00267  *          with the specified mode.
00268  * @note    Programming an unknown or unsupported mode is silently ignored.
00269  *
00270  * @param[in] port      port identifier
00271  * @param[in] mask      group mask
00272  * @param[in] offset    group bit offset within the port
00273  * @param[in] mode      group mode
00274  *
00275  * @notapi
00276  */
00277 #define pal_lld_setgroupmode(port, mask, offset, mode)                      \
00278   _pal_lld_setgroupmode(port, mask << offset, mode)
00279 
00280 /**
00281  * @brief   Sets a pad logical state to @p PAL_HIGH.
00282  *
00283  * @param[in] port      port identifier
00284  * @param[in] pad       pad number within the port
00285  *
00286  * @notapi
00287  */
00288 #define pal_lld_setpad(port, pad)                                           \
00289 __asm__ __volatile__                                                        \
00290 (                                                                           \
00291   "sbi %0,%1\n\t"                                                         \
00292   :                                                                       \
00293   : "I" (_SFR_IO_ADDR(port->out)),                                        \
00294     "I" (pad)                                                             \
00295                                                             \
00296 )
00297 
00298 /**
00299  * @brief   Clears a pad logical state to @p PAL_LOW.
00300  *
00301  * @param[in] port      port identifier
00302  * @param[in] pad       pad number within the port
00303  *
00304  * @notapi
00305  */
00306 #define pal_lld_clearpad(port, pad)                                         \
00307 __asm__ __volatile__                                                        \
00308 (                                                                           \
00309   "cbi %0,%1\n\t"                                                         \
00310   :                                                                       \
00311   : "I" (_SFR_IO_ADDR(port->out)),                                        \
00312     "I" (pad)                                                             \
00313                                                             \
00314 )
00315 
00316 extern ROMCONST PALConfig pal_default_config;
00317 
00318 #ifdef __cplusplus
00319 extern "C" {
00320 #endif
00321   void _pal_lld_init(const PALConfig *config);
00322   void _pal_lld_setgroupmode(ioportid_t port,
00323                              ioportmask_t mask,
00324                              iomode_t mode);
00325 #ifdef __cplusplus
00326 }
00327 #endif
00328 
00329 #endif /* HAL_USE_PAL */
00330 
00331 #endif /* _PAL_LLD_H_ */
00332 
00333 /** @} */