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 /** \addtogroup pio_capture_module Working with PIO Parallel Capture Mode 00031 * \ingroup peripherals_module 00032 * The PIO Parallel Capture Mode driver provides the interface to configure 00033 * and use the PIO Parallel Capture Mode peripheral.\n 00034 * 00035 * The PIO Controller integrates an interface able to read data from a CMOS digital 00036 * image sensor, a high-speed parallel ADC, a DSP synchronous port in synchronous 00037 * mode, etc.... For better understanding and to ease reading, the following 00038 * description uses an example with a CMOS digital image sensor 00039 * 00040 * To use the PIO Parallel Capture, the user has to follow these few steps: 00041 * <ul> 00042 * <li> Enable PIOA peripheral clock </li> 00043 * <li> Configure the PDC </li> 00044 * <li> Configure the PIO Capture interrupt </li> 00045 * <li> Enable the PDC </li> 00046 * <li> Enable the PIO Capture </li> 00047 * <li> Wait for interrupt </li> 00048 * <li> Disable the interrupt </li> 00049 * <li> Read the DATA </li> 00050 * </ul> 00051 * 00052 * For more accurate information, please look at the PIO Parallel Capture Mode 00053 * section of the Datasheet. 00054 * 00055 * <b>API Usage:</b> 00056 * 00057 * -# Configurate the interrupt for PIOA, can be done by 00058 * PIO_InitializeInterrupts() 00059 * -# Initialize the PIO Parallel Capture API by filing the SpioCaptureInit 00060 * structure 00061 * options: 00062 * - alwaysSampling: for sample data with or without take in account 00063 * ENABLE pins. 00064 * - halfSampling: for sample all data or only one time out of two 00065 * -# Call PIO_CaptureInit() for init and enable the PDC, init the PIO capture. 00066 * -# Call PIO_CaptureEnable() for enable the PIO Parallel Capture. 00067 * -# When an interrupt is received, the PIO_CaptureHandler() is call and the 00068 * respective callback is launch. 00069 * -# When the transfer is complete, the user need to disable interrupt with 00070 * PIO_CaptureDisableIt(). Otherwise, the PDC will send an interrupt. 00071 * -# The data receive by the PIO Parallel Capture is inside the buffer passed 00072 * in the PIO_CaptureInit(). 00073 * 00074 * Related files :\n 00075 * \ref pio_capture.c\n 00076 * \ref pio_capture.h\n 00077 */ 00078 /*@{*/ 00079 /*@}*/ 00080 /** 00081 * \file 00082 * 00083 * Implementation of PIO Parallel Capture. 00084 * 00085 */ 00086 00087 /*---------------------------------------------------------------------------- 00088 * Headers 00089 *----------------------------------------------------------------------------*/ 00090 00091 #include "chip.h" 00092 00093 #include <assert.h> 00094 00095 #define PIO_PCISR_RXBUFF (0x1u<<3) 00096 #define PIO_PCISR_ENDRX (0x1u<<2) 00097 /*---------------------------------------------------------------------------- 00098 * Local Functions 00099 *----------------------------------------------------------------------------*/ 00100 /** Copy the API structure for interrupt handler */ 00101 static SpioCaptureInit* _PioCaptureCopy; 00102 00103 /*---------------------------------------------------------------------------- 00104 * Global Functions 00105 *----------------------------------------------------------------------------*/ 00106 00107 /*----------------------------------------------------------------------------*/ 00108 /** 00109 * \brief The PIO_CaptureHandler must be called by the PIO Capture Interrupt 00110 * Service Routine with the corresponding PIO Capture instance. 00111 */ 00112 /*----------------------------------------------------------------------------*/ 00113 extern void PIO_CaptureHandler( void ) 00114 { 00115 volatile uint32_t pio_captureSr; 00116 uint32_t k; 00117 00118 /* Read the status register*/ 00119 pio_captureSr = PIOA->PIO_PCISR ; 00120 k = pio_captureSr; 00121 pio_captureSr = k & PIOA->PIO_PCIMR ; 00122 00123 if (pio_captureSr & PIO_PCISR_DRDY) { 00124 /* Parallel Capture Mode Data Ready */ 00125 if ( _PioCaptureCopy->CbkDataReady != NULL ) { 00126 _PioCaptureCopy->CbkDataReady( _PioCaptureCopy ); 00127 } else { 00128 TRACE_DEBUG("IT PIO Capture Data Ready received (no callback)\n\r"); 00129 } 00130 } 00131 00132 if (pio_captureSr & PIO_PCISR_OVRE) { 00133 /* Parallel Capture Mode Overrun Error */ 00134 if ( _PioCaptureCopy->CbkOverrun != NULL ) { 00135 _PioCaptureCopy->CbkOverrun( _PioCaptureCopy ); 00136 } else { 00137 TRACE_DEBUG("IT PIO Capture Overrun Error received (no callback)\n\r"); 00138 } 00139 } 00140 00141 if (pio_captureSr & PIO_PCISR_RXBUFF) { 00142 /* Reception Buffer Full */ 00143 if ( _PioCaptureCopy->CbkBuffFull != NULL ) { 00144 _PioCaptureCopy->CbkBuffFull( _PioCaptureCopy ); 00145 } else { 00146 TRACE_DEBUG("IT PIO Capture Reception Buffer Full received \ 00147 (no callback)\n\r"); 00148 } 00149 } 00150 00151 if (pio_captureSr & PIO_PCISR_ENDRX) { 00152 /* End of Reception Transfer */ 00153 if ( _PioCaptureCopy->CbkEndReception != NULL ) { 00154 _PioCaptureCopy->CbkEndReception( _PioCaptureCopy ); 00155 } else { 00156 TRACE_DEBUG("IT PIO Capture End of Reception Transfer \ 00157 received (no callback)\n\r"); 00158 } 00159 } 00160 } 00161 00162 /*----------------------------------------------------------------------------*/ 00163 /** 00164 * \brief Disable Interrupt of the PIO Capture 00165 * \param itToDisable : Interrupt to disable 00166 */ 00167 /*----------------------------------------------------------------------------*/ 00168 void PIO_CaptureDisableIt( uint32_t itToDisable ) 00169 { 00170 /* Parallel capture mode is enabled */ 00171 PIOA->PIO_PCIDR = itToDisable; 00172 } 00173 00174 /*----------------------------------------------------------------------------*/ 00175 /** 00176 * \brief Enable Interrupt of the PIO Capture 00177 * \param itToEnable : Interrupt to enable 00178 */ 00179 /*----------------------------------------------------------------------------*/ 00180 void PIO_CaptureEnableIt( uint32_t itToEnable ) 00181 { 00182 /* Parallel capture mode is enabled */ 00183 PIOA->PIO_PCIER = itToEnable; 00184 } 00185 00186 /*----------------------------------------------------------------------------*/ 00187 /** 00188 * \brief Enable the PIO Capture 00189 */ 00190 /*----------------------------------------------------------------------------*/ 00191 void PIO_CaptureEnable( void ) 00192 { 00193 /* PDC: Receive Pointer Register */ 00194 // PIOA->PIO_RPR = (uint32_t)_PioCaptureCopy->pData ; 00195 // /* PDC: Receive Counter Register */ 00196 // /* Starts peripheral data transfer if corresponding channel is active */ 00197 // PIOA->PIO_RCR = PIO_RCR_RXCTR(_PioCaptureCopy->dPDCsize) ; 00198 00199 /* Parallel capture mode is enabled */ 00200 PIOA->PIO_PCMR |= PIO_PCMR_PCEN ; 00201 } 00202 00203 /*----------------------------------------------------------------------------*/ 00204 /** 00205 * \brief Disable the PIO Capture 00206 */ 00207 /*----------------------------------------------------------------------------*/ 00208 void PIO_CaptureDisable( void ) 00209 { 00210 /* Parallel capture mode is disabled */ 00211 PIOA->PIO_PCMR &= (uint32_t)(~PIO_PCMR_PCEN) ; 00212 } 00213 00214 /*----------------------------------------------------------------------------*/ 00215 /** 00216 * \brief Initialize the PIO Capture 00217 * \param dsize : 00218 * 0 = The reception data in the PIO_PCRHR register is a BYTE (8-bit). 00219 * 1 = The reception data in the PIO_PCRHR register is a HALF-WORD (16-bit). 00220 * 2/3 = The reception data in the PIO_PCRHR register is a WORD (32-bit). 00221 * \param alwaysSampling: ALWYS: Parallel Capture Mode Always Sampling 00222 * 0 = The parallel capture mode samples the data when both data enables are active. 00223 * 1 = The parallel capture mode samples the data whatever the data enables are. 00224 * \param halfSampling: HALFS: Parallel Capture Mode Half Sampling 00225 * 0 = The parallel capture mode samples all the data. 00226 * 1 = The parallel capture mode samples the data only one time out of two. 00227 * \param modeFirstSample: FRSTS: Parallel Capture Mode First Sample 00228 * This bit is useful only if the HALFS bit is set to 1. If data are numbered 00229 * in the order that they are received with an index from 0 to n: 00230 * 0 = Only data with an even index are sampled. 00231 * 1 = Only data with an odd index are sampled. 00232 */ 00233 /*----------------------------------------------------------------------------*/ 00234 void PIO_CaptureInit( SpioCaptureInit *pInit ) 00235 { 00236 PMC_EnablePeripheral( ID_PIOA ); 00237 00238 assert( (pInit->dsize < 0x4) ) ; 00239 assert( (pInit->alwaysSampling < 2) ); 00240 assert( (pInit->halfSampling < 2) ); 00241 assert( (pInit->modeFirstSample < 2) ); 00242 /* Copy the API structure for interrupt handler */ 00243 _PioCaptureCopy = pInit; 00244 00245 if ( pInit->CbkDataReady != NULL ) { 00246 PIOA->PIO_PCIER = PIO_PCISR_DRDY; 00247 } 00248 00249 if ( pInit->CbkOverrun != NULL ) { 00250 PIOA->PIO_PCIER = PIO_PCISR_OVRE; 00251 } 00252 00253 if ( pInit->CbkEndReception != NULL ) { 00254 PIOA->PIO_PCIER = PIO_PCISR_ENDRX; 00255 } 00256 00257 if ( pInit->CbkBuffFull != NULL ) { 00258 PIOA->PIO_PCIER = PIO_PCISR_RXBUFF; 00259 } 00260 } 00261