SAMV71 Xplained Ultra Software Package 1.5

pio.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------- */
00002 /*                  Atmel Microcontroller Software Support                      */
00003 /*                       SAM Software Package License                           */
00004 /* ---------------------------------------------------------------------------- */
00005 /* Copyright (c) 2015, Atmel Corporation                                        */
00006 /*                                                                              */
00007 /* All rights reserved.                                                         */
00008 /*                                                                              */
00009 /* Redistribution and use in source and binary forms, with or without           */
00010 /* modification, are permitted provided that the following condition is met:    */
00011 /*                                                                              */
00012 /* - Redistributions of source code must retain the above copyright notice,     */
00013 /* this list of conditions and the disclaimer below.                            */
00014 /*                                                                              */
00015 /* Atmel's name may not be used to endorse or promote products derived from     */
00016 /* this software without specific prior written permission.                     */
00017 /*                                                                              */
00018 /* DISCLAIMER:  THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR   */
00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE   */
00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,      */
00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */
00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,  */
00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    */
00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING         */
00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */
00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                           */
00028 /* ---------------------------------------------------------------------------- */
00029 
00030 /** \file */
00031 
00032 /*----------------------------------------------------------------------------
00033  *        Headers
00034  *----------------------------------------------------------------------------*/
00035 #include "chip.h"
00036 
00037 /*----------------------------------------------------------------------------
00038  *        Local functions
00039  *----------------------------------------------------------------------------*/
00040 
00041 /**
00042  * \brief Configures one or more pin(s) of a PIO controller as being controlled by
00043  * peripheral A. Optionally, the corresponding internal pull-up(s) can be enabled.
00044  *
00045  * \param pio  Pointer to a PIO controller.
00046  * \param mask  Bitmask of one or more pin(s) to configure.
00047  * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
00048  *                      configured.
00049  */
00050 static void PIO_SetPeripheralA(
00051     Pio *pio,
00052     unsigned int mask,
00053     unsigned char enablePullUp)
00054 {
00055     unsigned int abcdsr;
00056     /* Disable interrupts on the pin(s) */
00057     pio->PIO_IDR = mask;
00058 
00059     /* Enable the pull-up(s) if necessary */
00060     if (enablePullUp)
00061         pio->PIO_PUER = mask;
00062     else
00063         pio->PIO_PUDR = mask;
00064 
00065     abcdsr = pio->PIO_ABCDSR[0];
00066     pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
00067     abcdsr = pio->PIO_ABCDSR[1];
00068     pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
00069     pio->PIO_PDR = mask;
00070 }
00071 
00072 /**
00073  * \brief Configures one or more pin(s) of a PIO controller as being controlled
00074  * by peripheral B. Optionally, the corresponding internal pull-up(s) can be
00075  * enabled.
00076  *
00077  * \param pio  Pointer to a PIO controller.
00078  * \param mask  Bitmask of one or more pin(s) to configure.
00079  * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
00080  *                      configured.
00081  */
00082 static void PIO_SetPeripheralB(
00083     Pio *pio,
00084     unsigned int mask,
00085     unsigned char enablePullUp)
00086 {
00087     unsigned int abcdsr;
00088     /* Disable interrupts on the pin(s) */
00089     pio->PIO_IDR = mask;
00090 
00091     /* Enable the pull-up(s) if necessary */
00092     if (enablePullUp)
00093         pio->PIO_PUER = mask;
00094     else
00095         pio->PIO_PUDR = mask;
00096 
00097     abcdsr = pio->PIO_ABCDSR[0];
00098     pio->PIO_ABCDSR[0] = (mask | abcdsr);
00099     abcdsr = pio->PIO_ABCDSR[1];
00100     pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
00101 
00102     pio->PIO_PDR = mask;
00103 }
00104 
00105 /**
00106  * \brief Configures one or more pin(s) of a PIO controller as being controlled
00107  * by peripheral C. Optionally, the corresponding internal pull-up(s) can be
00108  * enabled.
00109  *
00110  * \param pio  Pointer to a PIO controller.
00111  * \param mask  Bitmask of one or more pin(s) to configure.
00112  * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
00113  *                      configured.
00114  */
00115 static void PIO_SetPeripheralC(
00116     Pio *pio,
00117     unsigned int mask,
00118     unsigned char enablePullUp)
00119 {
00120     unsigned int abcdsr;
00121     /* Disable interrupts on the pin(s) */
00122     pio->PIO_IDR = mask;
00123 
00124     /* Enable the pull-up(s) if necessary */
00125     if (enablePullUp)
00126         pio->PIO_PUER = mask;
00127     else
00128         pio->PIO_PUDR = mask;
00129 
00130     abcdsr = pio->PIO_ABCDSR[0];
00131     pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
00132     abcdsr = pio->PIO_ABCDSR[1];
00133     pio->PIO_ABCDSR[1] = (mask | abcdsr);
00134 
00135     pio->PIO_PDR = mask;
00136 }
00137 
00138 /**
00139  * \brief Configures one or more pin(s) of a PIO controller as being controlled
00140  * by peripheral D. Optionally, the corresponding internal pull-up(s) can be
00141  * enabled.
00142  *
00143  * \param pio  Pointer to a PIO controller.
00144  * \param mask  Bitmask of one or more pin(s) to configure.
00145  * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
00146  *                      configured.
00147  */
00148 static void PIO_SetPeripheralD(
00149     Pio *pio,
00150     unsigned int mask,
00151     unsigned char enablePullUp)
00152 {
00153     unsigned int abcdsr;
00154     /* Disable interrupts on the pin(s) */
00155     pio->PIO_IDR = mask;
00156 
00157     /* Enable the pull-up(s) if necessary */
00158     if (enablePullUp)
00159         pio->PIO_PUER = mask;
00160     else
00161         pio->PIO_PUDR = mask;
00162 
00163     abcdsr = pio->PIO_ABCDSR[0];
00164     pio->PIO_ABCDSR[0] = (mask | abcdsr);
00165     abcdsr = pio->PIO_ABCDSR[1];
00166     pio->PIO_ABCDSR[1] = (mask | abcdsr);
00167 
00168     pio->PIO_PDR = mask;
00169 }
00170 
00171 /**
00172  * \brief Configures one or more pin(s) or a PIO controller as inputs. Optionally,
00173  * the corresponding internal pull-up(s) and glitch filter(s) can be enabled.
00174  *
00175  * \param pio  Pointer to a PIO controller.
00176  * \param mask  Bitmask indicating which pin(s) to configure as input(s).
00177  * \param enablePullUp  Indicates if the internal pull-up(s) must be enabled.
00178  * \param enableFilter  Indicates if the glitch filter(s) must be enabled.
00179  */
00180 static void PIO_SetInput(
00181     Pio *pio,
00182     unsigned int mask,
00183     unsigned char attribute)
00184 {
00185     /* Disable interrupts */
00186     pio->PIO_IDR = mask;
00187 
00188     /* Enable pull-up(s) if necessary */
00189     if (attribute & PIO_PULLUP)
00190         pio->PIO_PUER = mask;
00191     else
00192         pio->PIO_PUDR = mask;
00193 
00194     /* Enable Input Filter if necessary */
00195     if (attribute & (PIO_DEGLITCH | PIO_DEBOUNCE))
00196         pio->PIO_IFER = mask;
00197     else
00198         pio->PIO_IFDR = mask;
00199 
00200     /* Enable de-glitch or de-bounce if necessary */
00201     if (attribute & PIO_DEGLITCH)
00202         pio->PIO_IFSCDR = mask;
00203     else {
00204         if (attribute & PIO_DEBOUNCE)
00205             pio->PIO_IFSCER = mask;
00206     }
00207 
00208     /* Configure pin as input */
00209     pio->PIO_ODR = mask;
00210     pio->PIO_PER = mask;
00211 }
00212 
00213 /**
00214  * \brief Configures one or more pin(s) of a PIO controller as outputs, with the
00215  * given default value. Optionally, the multi-drive feature can be enabled
00216  * on the pin(s).
00217  *
00218  * \param pio  Pointer to a PIO controller.
00219  * \param mask  Bitmask indicating which pin(s) to configure.
00220  * \param defaultValue  Default level on the pin(s).
00221  * \param enableMultiDrive  Indicates if the pin(s) shall be configured as
00222  *                          open-drain.
00223  * \param enablePullUp  Indicates if the pin shall have its pull-up activated.
00224  */
00225 static void PIO_SetOutput(
00226     Pio *pio,
00227     unsigned int mask,
00228     unsigned char defaultValue,
00229     unsigned char enableMultiDrive,
00230     unsigned char enablePullUp)
00231 {
00232     /* Disable interrupts */
00233     pio->PIO_IDR = mask;
00234 
00235     /* Enable pull-up(s) if necessary */
00236     if (enablePullUp)
00237         pio->PIO_PUER = mask;
00238     else
00239         pio->PIO_PUDR = mask;
00240 
00241     /* Enable multi-drive if necessary */
00242     if (enableMultiDrive)
00243         pio->PIO_MDER = mask;
00244     else
00245         pio->PIO_MDDR = mask;
00246 
00247     /* Set default value */
00248     if (defaultValue)
00249         pio->PIO_SODR = mask;
00250     else
00251         pio->PIO_CODR = mask;
00252 
00253     /* Configure pin(s) as output(s) */
00254     pio->PIO_OER = mask;
00255     pio->PIO_PER = mask;
00256 }
00257 
00258 /*----------------------------------------------------------------------------
00259  *         Global functions
00260  *----------------------------------------------------------------------------*/
00261 
00262 /**
00263  * \brief Configures a list of Pin instances, each of which can either hold a
00264  * single pin or a group of pins, depending on the mask value; all pins are
00265  * configured by this function. The size of the array must also be provided and
00266  *  is easily computed using PIO_LISTSIZE whenever its length is not known in
00267  * advance.
00268  *
00269  * \param list  Pointer to a list of Pin instances.
00270  * \param size  Size of the Pin list (calculated using PIO_LISTSIZE).
00271  *
00272  * \return 1 if the pins have been configured properly; otherwise 0.
00273  */
00274 uint8_t PIO_Configure(const Pin *list, uint32_t size)
00275 {
00276     /* Configure pins */
00277     while (size > 0) {
00278         switch (list->type) {
00279         case PIO_PERIPH_A:
00280             PIO_SetPeripheralA(list->pio,
00281                                list->mask,
00282                                (list->attribute & PIO_PULLUP) ? 1 : 0);
00283             break;
00284 
00285         case PIO_PERIPH_B:
00286             PIO_SetPeripheralB(list->pio,
00287                                list->mask,
00288                                (list->attribute & PIO_PULLUP) ? 1 : 0);
00289             break;
00290 
00291         case PIO_PERIPH_C:
00292             PIO_SetPeripheralC(list->pio,
00293                                list->mask,
00294                                (list->attribute & PIO_PULLUP) ? 1 : 0);
00295             break;
00296 
00297         case PIO_PERIPH_D:
00298             PIO_SetPeripheralD(list->pio,
00299                                list->mask,
00300                                (list->attribute & PIO_PULLUP) ? 1 : 0);
00301             break;
00302 
00303         case PIO_INPUT:
00304 #ifndef __FPGA
00305             PMC_EnablePeripheral(list->id);
00306 #endif
00307             PIO_SetInput(list->pio,
00308                          list->mask,
00309                          list->attribute);
00310             break;
00311 
00312         case PIO_OUTPUT_0:
00313         case PIO_OUTPUT_1:
00314             PIO_SetOutput(list->pio,
00315                           list->mask,
00316                           (list->type == PIO_OUTPUT_1),
00317                           (list->attribute & PIO_OPENDRAIN) ? 1 : 0,
00318                           (list->attribute & PIO_PULLUP) ? 1 : 0);
00319             break;
00320 
00321         default: return 0;
00322         }
00323 
00324         list++;
00325         size--;
00326     }
00327 
00328     return 1;
00329 }
00330 
00331 /**
00332  * \brief Sets a high output level on all the PIOs defined in the given Pin
00333  * instance.
00334  * This has no immediate effects on PIOs that are not output, but the PIO
00335  * controller will memorize the value they are changed to outputs.
00336  *
00337  * \param pin  Pointer to a Pin instance describing one or more pins.
00338  */
00339 void PIO_Set(const Pin *pin)
00340 {
00341     pin->pio->PIO_SODR = pin->mask;
00342 }
00343 
00344 /**
00345  * \brief Sets a low output level on all the PIOs defined in the given Pin
00346  * instance.
00347  * This has no immediate effects on PIOs that are not output, but the PIO
00348  * controller will memorize the value they are changed to outputs.
00349  *
00350  * \param pin  Pointer to a Pin instance describing one or more pins.
00351  */
00352 void PIO_Clear(const Pin *pin)
00353 {
00354     pin->pio->PIO_CODR = pin->mask;
00355 }
00356 
00357 /**
00358  * \brief Returns 1 if one or more PIO of the given Pin instance currently have
00359  * a high level; otherwise returns 0. This method returns the actual value that
00360  * is being read on the pin. To return the supposed output value of a pin, use
00361  * PIO_GetOutputDataStatus() instead.
00362  *
00363  * \param pin  Pointer to a Pin instance describing one or more pins.
00364  *
00365  * \return 1 if the Pin instance contains at least one PIO that currently has
00366  * a high level; otherwise 0.
00367  */
00368 unsigned char PIO_Get(const Pin *pin)
00369 {
00370     unsigned int reg;
00371 
00372     if ((pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1))
00373         reg = pin->pio->PIO_ODSR;
00374     else
00375         reg = pin->pio->PIO_PDSR;
00376 
00377     if ((reg & pin->mask) == 0)
00378         return 0;
00379     else
00380         return 1;
00381 }
00382 
00383 /**
00384  * \brief Returns 1 if one or more PIO of the given Pin are configured to output
00385  * a high level (even if they are not output).
00386  * To get the actual value of the pin, use PIO_Get() instead.
00387  *
00388  * \param pin  Pointer to a Pin instance describing one or more pins.
00389  *
00390  * \return 1 if the Pin instance contains at least one PIO that is configured
00391  * to output a high level; otherwise 0.
00392  */
00393 unsigned char PIO_GetOutputDataStatus(const Pin *pin)
00394 {
00395     if ((pin->pio->PIO_ODSR & pin->mask) == 0)
00396         return 0;
00397     else
00398         return 1;
00399 }
00400 
00401 /**
00402  * \brief Configures Glitch or Denouncing filter for input.
00403  *
00404  * \param pin  Pointer to a Pin instance describing one or more pins.
00405  * \param cuttoff  Cut off frequency for denounce filter.
00406  */
00407 void PIO_SetDebounceFilter(const Pin *pin, uint32_t cuttoff)
00408 {
00409     Pio *pio = pin->pio;
00410 
00411     pio->PIO_IFSCER = pin->mask; /* set Denouncing, 0 bit field no effect */
00412     pio->PIO_SCDR = ((32678 / (2 * (cuttoff))) - 1) & 0x3FFF;
00413     /* the lowest 14 bits work */
00414 }
00415 
00416 /**
00417  * \brief Enable write protect.
00418  *
00419  * \param pin  Pointer to a Pin instance describing one or more pins.
00420  */
00421 void PIO_EnableWriteProtect(const Pin *pin)
00422 {
00423     Pio *pio = pin->pio;
00424 
00425     pio->PIO_WPMR = (PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_EN);
00426 }
00427 
00428 /**
00429  * \brief Disable write protect.
00430  *
00431  * \param pin  Pointer to a Pin instance describing one or more pins.
00432  */
00433 
00434 void PIO_DisableWriteProtect(const Pin *pin)
00435 {
00436     Pio *pio = pin->pio;
00437 
00438     pio->PIO_WPMR = (PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_DIS);
00439 }
00440 
00441 /**
00442  * \brief Get write protect violation information.
00443  *
00444  * \param pin  Pointer to a Pin instance describing one or more pins.
00445  */
00446 uint32_t PIO_GetWriteProtectViolationInfo(const Pin *pin)
00447 {
00448     Pio *pio = pin->pio;
00449     return (pio->PIO_WPSR);
00450 }
00451 
00452 /**
00453  *  \brief Set pin type
00454  * the pin is controlled by the corresponding peripheral (A, B, C, D,E)
00455  * \param pin      Pointer to a Pin instance describing one or more pins.
00456  * \param pinType  PIO_PERIPH_A, PIO_PERIPH_B, ...
00457  */
00458 void PIO_SetPinType(Pin *pin, uint8_t pinType)
00459 {
00460     pin->type = pinType;
00461 }
00462 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines