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 /** \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 if (pio_captureSr & PIO_PCISR_OVRE) { 00132 /* Parallel Capture Mode Overrun Error */ 00133 if (_PioCaptureCopy->CbkOverrun != NULL) 00134 _PioCaptureCopy->CbkOverrun(_PioCaptureCopy); 00135 else 00136 TRACE_DEBUG("IT PIO Capture Overrun Error received (no callback)\n\r"); 00137 } 00138 00139 if (pio_captureSr & PIO_PCISR_RXBUFF) { 00140 /* Reception Buffer Full */ 00141 if (_PioCaptureCopy->CbkBuffFull != NULL) 00142 _PioCaptureCopy->CbkBuffFull(_PioCaptureCopy); 00143 else { 00144 TRACE_DEBUG("IT PIO Capture Reception Buffer Full received \ 00145 (no callback)\n\r"); 00146 } 00147 } 00148 00149 if (pio_captureSr & PIO_PCISR_ENDRX) { 00150 /* End of Reception Transfer */ 00151 if (_PioCaptureCopy->CbkEndReception != NULL) 00152 _PioCaptureCopy->CbkEndReception(_PioCaptureCopy); 00153 else { 00154 TRACE_DEBUG("IT PIO Capture End of Reception Transfer \ 00155 received (no callback)\n\r"); 00156 } 00157 } 00158 } 00159 00160 /*----------------------------------------------------------------------------*/ 00161 /** 00162 * \brief Disable Interrupt of the PIO Capture 00163 * \param itToDisable : Interrupt to disable 00164 */ 00165 /*----------------------------------------------------------------------------*/ 00166 void PIO_CaptureDisableIt(uint32_t itToDisable) 00167 { 00168 /* Parallel capture mode is enabled */ 00169 PIOA->PIO_PCIDR = itToDisable; 00170 } 00171 00172 /*----------------------------------------------------------------------------*/ 00173 /** 00174 * \brief Enable Interrupt of the PIO Capture 00175 * \param itToEnable : Interrupt to enable 00176 */ 00177 /*----------------------------------------------------------------------------*/ 00178 void PIO_CaptureEnableIt(uint32_t itToEnable) 00179 { 00180 /* Parallel capture mode is enabled */ 00181 PIOA->PIO_PCIER = itToEnable; 00182 } 00183 00184 /*----------------------------------------------------------------------------*/ 00185 /** 00186 * \brief Enable the PIO Capture 00187 */ 00188 /*----------------------------------------------------------------------------*/ 00189 void PIO_CaptureEnable(void) 00190 { 00191 /* PDC: Receive Pointer Register */ 00192 // PIOA->PIO_RPR = (uint32_t)_PioCaptureCopy->pData; 00193 // /* PDC: Receive Counter Register */ 00194 // /* Starts peripheral data transfer if corresponding channel is active */ 00195 // PIOA->PIO_RCR = PIO_RCR_RXCTR(_PioCaptureCopy->dPDCsize); 00196 00197 /* Parallel capture mode is enabled */ 00198 PIOA->PIO_PCMR |= PIO_PCMR_PCEN; 00199 } 00200 00201 /*----------------------------------------------------------------------------*/ 00202 /** 00203 * \brief Disable the PIO Capture 00204 */ 00205 /*----------------------------------------------------------------------------*/ 00206 void PIO_CaptureDisable(void) 00207 { 00208 /* Parallel capture mode is disabled */ 00209 PIOA->PIO_PCMR &= (uint32_t)(~PIO_PCMR_PCEN); 00210 } 00211 00212 /*----------------------------------------------------------------------------*/ 00213 /** 00214 * \brief Initialize the PIO Capture 00215 * \param dsize : 00216 * 0 = The reception data in the PIO_PCRHR register is a BYTE (8-bit). 00217 * 1 = The reception data in the PIO_PCRHR register is a HALF-WORD (16-bit). 00218 * 2/3 = The reception data in the PIO_PCRHR register is a WORD (32-bit). 00219 * \param alwaysSampling: ALWYS: Parallel Capture Mode Always Sampling 00220 * 0 = The parallel capture mode samples the data when both data enables are active. 00221 * 1 = The parallel capture mode samples the data whatever the data enables are. 00222 * \param halfSampling: HALFS: Parallel Capture Mode Half Sampling 00223 * 0 = The parallel capture mode samples all the data. 00224 * 1 = The parallel capture mode samples the data only one time out of two. 00225 * \param modeFirstSample: FRSTS: Parallel Capture Mode First Sample 00226 * This bit is useful only if the HALFS bit is set to 1. If data are numbered 00227 * in the order that they are received with an index from 0 to n: 00228 * 0 = Only data with an even index are sampled. 00229 * 1 = Only data with an odd index are sampled. 00230 */ 00231 /*----------------------------------------------------------------------------*/ 00232 void PIO_CaptureInit(SpioCaptureInit *pInit) 00233 { 00234 PMC_EnablePeripheral(ID_PIOA); 00235 00236 assert((pInit->dsize < 0x4)); 00237 assert((pInit->alwaysSampling < 2)); 00238 assert((pInit->halfSampling < 2)); 00239 assert((pInit->modeFirstSample < 2)); 00240 /* Copy the API structure for interrupt handler */ 00241 _PioCaptureCopy = pInit; 00242 00243 if (pInit->CbkDataReady != NULL) 00244 PIOA->PIO_PCIER = PIO_PCISR_DRDY; 00245 00246 if (pInit->CbkOverrun != NULL) 00247 PIOA->PIO_PCIER = PIO_PCISR_OVRE; 00248 00249 if (pInit->CbkEndReception != NULL) 00250 PIOA->PIO_PCIER = PIO_PCISR_ENDRX; 00251 00252 if (pInit->CbkBuffFull != NULL) 00253 PIOA->PIO_PCIER = PIO_PCISR_RXBUFF; 00254 } 00255