SAM3S8/SD8 Software Package: libraries/libchip_sam3s/source/pio.c Source File

SAM3S8/SD8 Software Package 1.2

# pio.c

Go to the documentation of this file.

    00001 /* ----------------------------------------------------------------------------
    00002  *         ATMEL Microcontroller Software Support
    00003  * ----------------------------------------------------------------------------
    00004  * Copyright (c) 2010, 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     }
    00063     else {
    00064
    00065         pio->PIO_PUDR = mask;
    00066     }
    00067
    00068     abcdsr = pio->PIO_ABCDSR[0];
    00069     pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
    00070     abcdsr = pio->PIO_ABCDSR[1];
    00071     pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
    00072     pio->PIO_PDR = mask;
    00073 }
    00074
    00075 /**
    00076  * \brief Configures one or more pin(s) of a PIO controller as being controlled by
    00077  * peripheral B. Optionally, the corresponding internal pull-up(s) can be enabled.
    00078  *
    00079  * \param pio  Pointer to a PIO controller.
    00080  * \param mask  Bitmask of one or more pin(s) to configure.
    00081  * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
    00082  *                      configured.
    00083  */
    00084 static void PIO_SetPeripheralB(
    00085     Pio *pio,
    00086     unsigned int mask,
    00087     unsigned char enablePullUp)
    00088 {
    00089     unsigned int abcdsr;
    00090     /* Disable interrupts on the pin(s) */
    00091     pio->PIO_IDR = mask;
    00092
    00093     /* Enable the pull-up(s) if necessary */
    00094     if (enablePullUp) {
    00095
    00096         pio->PIO_PUER = mask;
    00097     }
    00098     else {
    00099
    00100         pio->PIO_PUDR = mask;
    00101     }
    00102
    00103     abcdsr = pio->PIO_ABCDSR[0];
    00104     pio->PIO_ABCDSR[0] = (mask | abcdsr);
    00105     abcdsr = pio->PIO_ABCDSR[1];
    00106     pio->PIO_ABCDSR[1] &= (~mask & abcdsr);
    00107
    00108     pio->PIO_PDR = mask;
    00109 }
    00110
    00111 /**
    00112  * \brief Configures one or more pin(s) of a PIO controller as being controlled by
    00113  * peripheral C. Optionally, the corresponding internal pull-up(s) can be enabled.
    00114  *
    00115  * \param pio  Pointer to a PIO controller.
    00116  * \param mask  Bitmask of one or more pin(s) to configure.
    00117  * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
    00118  *                      configured.
    00119  */
    00120 static void PIO_SetPeripheralC(
    00121     Pio *pio,
    00122     unsigned int mask,
    00123     unsigned char enablePullUp)
    00124 {
    00125     unsigned int abcdsr;
    00126     /* Disable interrupts on the pin(s) */
    00127     pio->PIO_IDR = mask;
    00128
    00129     /* Enable the pull-up(s) if necessary */
    00130     if (enablePullUp) {
    00131
    00132         pio->PIO_PUER = mask;
    00133     }
    00134     else {
    00135
    00136         pio->PIO_PUDR = mask;
    00137     }
    00138
    00139     abcdsr = pio->PIO_ABCDSR[0];
    00140     pio->PIO_ABCDSR[0] &= (~mask & abcdsr);
    00141     abcdsr = pio->PIO_ABCDSR[1];
    00142     pio->PIO_ABCDSR[1] = (mask | abcdsr);
    00143
    00144     pio->PIO_PDR = mask;
    00145 }
    00146
    00147 /**
    00148  * \brief Configures one or more pin(s) of a PIO controller as being controlled by
    00149  * peripheral D. Optionally, the corresponding internal pull-up(s) can be enabled.
    00150  *
    00151  * \param pio  Pointer to a PIO controller.
    00152  * \param mask  Bitmask of one or more pin(s) to configure.
    00153  * \param enablePullUp  Indicates if the pin(s) internal pull-up shall be
    00154  *                      configured.
    00155  */
    00156 static void PIO_SetPeripheralD(
    00157     Pio *pio,
    00158     unsigned int mask,
    00159     unsigned char enablePullUp)
    00160 {
    00161     unsigned int abcdsr;
    00162     /* Disable interrupts on the pin(s) */
    00163     pio->PIO_IDR = mask;
    00164
    00165     /* Enable the pull-up(s) if necessary */
    00166     if (enablePullUp) {
    00167
    00168         pio->PIO_PUER = mask;
    00169     }
    00170     else {
    00171
    00172         pio->PIO_PUDR = mask;
    00173     }
    00174
    00175     abcdsr = pio->PIO_ABCDSR[0];
    00176     pio->PIO_ABCDSR[0] = (mask | abcdsr);
    00177     abcdsr = pio->PIO_ABCDSR[1];
    00178     pio->PIO_ABCDSR[1] = (mask | abcdsr);
    00179
    00180     pio->PIO_PDR = mask;
    00181 }
    00182
    00183 /**
    00184  * \brief Configures one or more pin(s) or a PIO controller as inputs. Optionally,
    00185  * the corresponding internal pull-up(s) and glitch filter(s) can be enabled.
    00186  *
    00187  * \param pio  Pointer to a PIO controller.
    00188  * \param mask  Bitmask indicating which pin(s) to configure as input(s).
    00189  * \param enablePullUp  Indicates if the internal pull-up(s) must be enabled.
    00190  * \param enableFilter  Indicates if the glitch filter(s) must be enabled.
    00191  */
    00192 static void PIO_SetInput(
    00193     Pio *pio,
    00194     unsigned int mask,
    00195     unsigned char attribute)
    00196 {
    00197     /* Disable interrupts */
    00198     pio->PIO_IDR = mask;
    00199
    00200     /* Enable pull-up(s) if necessary */
    00201     if (attribute & PIO_PULLUP)
    00202         pio->PIO_PUER = mask;
    00203     else
    00204         pio->PIO_PUDR = mask;
    00205
    00206     /* Enable Input Filter if necessary */
    00207     if (attribute & (PIO_DEGLITCH | PIO_DEBOUNCE))
    00208         pio->PIO_IFER = mask;
    00209     else
    00210         pio->PIO_IFDR = mask;
    00211
    00212     /* Enable de-glitch or de-bounce if necessary */
    00213     if (attribute & PIO_DEGLITCH)
    00214     {
    00215         pio->PIO_IFSCDR = mask;
    00216     }
    00217     else
    00218     {
    00219         if (attribute & PIO_DEBOUNCE)
    00220         {
    00221             pio->PIO_IFSCER = mask;
    00222         }
    00223     }
    00224
    00225     /* Configure pin as input */
    00226     pio->PIO_ODR = mask;
    00227     pio->PIO_PER = mask;
    00228 }
    00229
    00230 /**
    00231  * \brief Configures one or more pin(s) of a PIO controller as outputs, with the
    00232  * given default value. Optionally, the multi-drive feature can be enabled
    00233  * on the pin(s).
    00234  *
    00235  * \param pio  Pointer to a PIO controller.
    00236  * \param mask  Bitmask indicating which pin(s) to configure.
    00237  * \param defaultValue  Default level on the pin(s).
    00238  * \param enableMultiDrive  Indicates if the pin(s) shall be configured as
    00239  *                          open-drain.
    00240  * \param enablePullUp  Indicates if the pin shall have its pull-up activated.
    00241  */
    00242 static void PIO_SetOutput(
    00243     Pio *pio,
    00244     unsigned int mask,
    00245     unsigned char defaultValue,
    00246     unsigned char enableMultiDrive,
    00247     unsigned char enablePullUp)
    00248 {
    00249     /* Disable interrupts */
    00250     pio->PIO_IDR = mask;
    00251
    00252     /* Enable pull-up(s) if necessary */
    00253     if (enablePullUp) {
    00254
    00255         pio->PIO_PUER = mask;
    00256     }
    00257     else {
    00258
    00259         pio->PIO_PUDR = mask;
    00260     }
    00261
    00262     /* Enable multi-drive if necessary */
    00263     if (enableMultiDrive) {
    00264
    00265         pio->PIO_MDER = mask;
    00266     }
    00267     else {
    00268
    00269         pio->PIO_MDDR = mask;
    00270     }
    00271
    00272     /* Set default value */
    00273     if (defaultValue) {
    00274
    00275         pio->PIO_SODR = mask;
    00276     }
    00277     else {
    00278
    00279         pio->PIO_CODR = mask;
    00280     }
    00281
    00282     /* Configure pin(s) as output(s) */
    00283     pio->PIO_OER = mask;
    00284     pio->PIO_PER = mask;
    00285 }
    00286
    00287 /*----------------------------------------------------------------------------
    00288  *         Global functions
    00289  *----------------------------------------------------------------------------*/
    00290
    00291 /**
    00292  * \brief Configures a list of Pin instances, each of which can either hold a single
    00293  * pin or a group of pins, depending on the mask value; all pins are configured
    00294  * by this function. The size of the array must also be provided and is easily
    00295  * computed using PIO_LISTSIZE whenever its length is not known in advance.
    00296  *
    00297  * \param list  Pointer to a list of Pin instances.
    00298  * \param size  Size of the Pin list (calculated using PIO_LISTSIZE).
    00299  *
    00300  * \return 1 if the pins have been configured properly; otherwise 0.
    00301  */
    00302 uint8_t PIO_Configure( const Pin *list, uint32_t size )
    00303 {
    00304     /* Configure pins */
    00305     while ( size > 0 )
    00306     {
    00307         switch ( list->type )
    00308         {
    00309
    00310             case PIO_PERIPH_A:
    00311                 PIO_SetPeripheralA(list->pio,
    00312                                    list->mask,
    00313                                    (list->attribute & PIO_PULLUP) ? 1 : 0);
    00314             break;
    00315
    00316             case PIO_PERIPH_B:
    00317                 PIO_SetPeripheralB(list->pio,
    00318                                    list->mask,
    00319                                    (list->attribute & PIO_PULLUP) ? 1 : 0);
    00320             break;
    00321
    00322             case PIO_PERIPH_C:
    00323                 PIO_SetPeripheralC(list->pio,
    00324                                    list->mask,
    00325                                    (list->attribute & PIO_PULLUP) ? 1 : 0);
    00326             break;
    00327
    00328             case PIO_PERIPH_D:
    00329                 PIO_SetPeripheralD(list->pio,
    00330                                    list->mask,
    00331                                    (list->attribute & PIO_PULLUP) ? 1 : 0);
    00332             break;
    00333             case PIO_INPUT:
    00334                 PMC_EnablePeripheral(list->id);
    00335                 PIO_SetInput(list->pio,
    00336                              list->mask,
    00337                              list->attribute);
    00338                 break;
    00339
    00340             case PIO_OUTPUT_0:
    00341             case PIO_OUTPUT_1:
    00342                 PIO_SetOutput(list->pio,
    00343                               list->mask,
    00344                               (list->type == PIO_OUTPUT_1),
    00345                               (list->attribute & PIO_OPENDRAIN) ? 1 : 0,
    00346                               (list->attribute & PIO_PULLUP) ? 1 : 0);
    00347                 break;
    00348
    00349             default: return 0;
    00350         }
    00351
    00352         list++;
    00353         size--;
    00354     }
    00355
    00356     return 1;
    00357 }
    00358
    00359 /**
    00360  * \brief Sets a high output level on all the PIOs defined in the given Pin instance.
    00361  * This has no immediate effects on PIOs that are not output, but the PIO
    00362  * controller will memorize the value they are changed to outputs.
    00363  *
    00364  * \param pin  Pointer to a Pin instance describing one or more pins.
    00365  */
    00366 void PIO_Set(const Pin *pin)
    00367 {
    00368     pin->pio->PIO_SODR = pin->mask;
    00369 }
    00370
    00371 /**
    00372  * \brief Sets a low output level on all the PIOs defined in the given Pin instance.
    00373  * This has no immediate effects on PIOs that are not output, but the PIO
    00374  * controller will memorize the value they are changed to outputs.
    00375  *
    00376  * \param pin  Pointer to a Pin instance describing one or more pins.
    00377  */
    00378 void PIO_Clear(const Pin *pin)
    00379 {
    00380     pin->pio->PIO_CODR = pin->mask;
    00381 }
    00382
    00383 /**
    00384  * \brief Returns 1 if one or more PIO of the given Pin instance currently have
    00385  * a high level; otherwise returns 0. This method returns the actual value that
    00386  * is being read on the pin. To return the supposed output value of a pin, use
    00387  * PIO_GetOutputDataStatus() instead.
    00388  *
    00389  * \param pin  Pointer to a Pin instance describing one or more pins.
    00390  *
    00391  * \return 1 if the Pin instance contains at least one PIO that currently has
    00392  * a high level; otherwise 0.
    00393  */
    00394 unsigned char PIO_Get( const Pin *pin )
    00395 {
    00396     unsigned int reg ;
    00397
    00398     if ( (pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1) )
    00399     {
    00400         reg = pin->pio->PIO_ODSR ;
    00401     }
    00402     else
    00403     {
    00404         reg = pin->pio->PIO_PDSR ;
    00405     }
    00406
    00407     if ( (reg & pin->mask) == 0 )
    00408     {
    00409         return 0 ;
    00410     }
    00411     else
    00412     {
    00413         return 1 ;
    00414     }
    00415 }
    00416
    00417 /**
    00418  * \brief Returns 1 if one or more PIO of the given Pin are configured to output a
    00419  * high level (even if they are not output).
    00420  * To get the actual value of the pin, use PIO_Get() instead.
    00421  *
    00422  * \param pin  Pointer to a Pin instance describing one or more pins.
    00423  *
    00424  * \return 1 if the Pin instance contains at least one PIO that is configured
    00425  * to output a high level; otherwise 0.
    00426  */
    00427 unsigned char PIO_GetOutputDataStatus(const Pin *pin)
    00428 {
    00429     if ((pin->pio->PIO_ODSR & pin->mask) == 0) {
    00430
    00431         return 0;
    00432     }
    00433     else {
    00434
    00435         return 1;
    00436     }
    00437 }
    00438
    00439 /*
    00440  * \brief Configures Glitch or Debouncing filter for input.
    00441  *
    00442  * \param pin  Pointer to a Pin instance describing one or more pins.
    00443  * \param cuttoff  Cutt off frequency for debounce filter.
    00444  */
    00445 void PIO_SetDebounceFilter( const Pin *pin, uint32_t cuttoff )
    00446 {
    00447     Pio *pio = pin->pio;
    00448
    00449     pio->PIO_IFSCER = pin->mask; /* set Debouncing, 0 bit field no effect */
    00450     pio->PIO_SCDR = ((32678/(2*(cuttoff))) - 1) & 0x3FFF; /* the lowest 14 bits work */
    00451 }
    00452
    00453 /*
    00454  * \brief Enable write protect.
    00455  *
    00456  * \param pin  Pointer to a Pin instance describing one or more pins.
    00457  */
    00458 void PIO_EnableWriteProtect( const Pin *pin )
    00459 {
    00460    Pio *pio = pin->pio;
    00461
    00462    pio->PIO_WPMR = ( PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_EN );
    00463 }
    00464
    00465 /*
    00466  * \brief Disable write protect.
    00467  *
    00468  * \param pin  Pointer to a Pin instance describing one or more pins.
    00469  */
    00470
    00471 void PIO_DisableWriteProtect( const Pin *pin )
    00472 {
    00473    Pio *pio = pin->pio;
    00474
    00475    pio->PIO_WPMR = ( PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_DIS );
    00476 }
    00477
    00478 /*
    00479  * \brief Get write protect violation information.
    00480  *
    00481  * \param pin  Pointer to a Pin instance describing one or more pins.
    00482  */
    00483
    00484 uint32_t PIO_GetWriteProtectViolationInfo( const Pin * pin )
    00485 {
    00486     Pio *pio = pin->pio;
    00487     return (pio->PIO_WPSR);
    00488 }
    00489 /* \brief Set pin type
    00490  * the pin is controlled by the corresponding peripheral (A, B, C, D,E)
    00491  * \param pin      Pointer to a Pin instance describing one or more pins.
    00492  * \param pinType  PIO_PERIPH_A, PIO_PERIPH_B, ...
    00493  */
    00494
    00495 void PIO_SetPinType( Pin * pin, uint8_t pinType)
    00496 {
    00497     pin->type = pinType;
    00498 }
    00499

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines