SAMV71 Xplained Ultra Software Package 1.4

pio.c

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