2 * Copyright (c) 2006 M. Warner Losh. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * This software is derived from software provide by Kwikbyte who specifically
25 * disclaimed copyright on the code.
30 #ifndef __LIBAT91RM9200_H
31 #define __LIBAT91RM9200_H
33 #include "at91rm9200.h"
35 //*----------------------------------------------------------------------------
36 //* \fn AT91F_PMC_EnablePeriphClock
37 //* \brief Enable peripheral clock
38 //*----------------------------------------------------------------------------
40 AT91F_PMC_EnablePeriphClock (
41 AT91PS_PMC pPMC, // \arg pointer to PMC controller
42 unsigned int periphIds) // \arg IDs of peripherals to enable
44 pPMC->PMC_PCER = periphIds;
47 /* *****************************************************************************
49 ***************************************************************************** */
50 //*----------------------------------------------------------------------------
51 //* \fn AT91F_PIO_CfgPeriph
52 //* \brief Enable pins to be drived by peripheral
53 //*----------------------------------------------------------------------------
55 void AT91F_PIO_CfgPeriph(
56 AT91PS_PIO pPio, // \arg pointer to a PIO controller
57 unsigned int periphAEnable, // \arg PERIPH A to enable
58 unsigned int periphBEnable) // \arg PERIPH B to enable
61 pPio->PIO_ASR = periphAEnable;
62 pPio->PIO_BSR = periphBEnable;
63 pPio->PIO_PDR = (periphAEnable | periphBEnable); // Set in Periph mode
66 /* *****************************************************************************
68 ***************************************************************************** */
69 //* Classic MCI Mode Register Configuration with PDC mode enabled and MCK = MCI Clock
70 #define AT91C_MCI_MR_PDCMODE (AT91C_MCI_CLKDIV |\
72 (AT91C_MCI_PWSDIV<<1) |\
75 //* Classic MCI Data Timeout Register Configuration with 1048576 MCK cycles between 2 data transfer
76 #define AT91C_MCI_DTOR_1MEGA_CYCLES (AT91C_MCI_DTOCYC | AT91C_MCI_DTOMUL)
78 //* Classic MCI SDCard Register Configuration with 1-bit data bus on slot A
79 #define AT91C_MCI_MMC_SLOTA (AT91C_MCI_SCDSEL & 0x0)
81 //* Classic MCI SDCard Register Configuration with 1-bit data bus on slot B
82 #define AT91C_MCI_MMC_SLOTB (AT91C_MCI_SCDSEL)
84 //* Classic MCI SDCard Register Configuration with 4-bit data bus on slot A
85 #define AT91C_MCI_SDCARD_4BITS_SLOTA ( (AT91C_MCI_SCDSEL & 0x0) | AT91C_MCI_SCDBUS )
87 //* Classic MCI SDCard Register Configuration with 4-bit data bus on slot B
88 #define AT91C_MCI_SDCARD_4BITS_SLOTB (AT91C_MCI_SCDSEL | AT91C_MCI_SCDBUS)
92 //*----------------------------------------------------------------------------
93 //* \fn AT91F_MCI_Configure
94 //* \brief Configure the MCI
95 //*----------------------------------------------------------------------------
97 void AT91F_MCI_Configure(
98 AT91PS_MCI pMCI, // \arg pointer to a MCI controller
99 unsigned int DTOR_register, // \arg Data Timeout Register to be programmed
100 unsigned int MR_register, // \arg Mode Register to be programmed
101 unsigned int SDCR_register) // \arg SDCard Register to be programmed
104 pMCI->MCI_CR = AT91C_MCI_MCIEN | AT91C_MCI_PWSEN;
106 //* Disable all the interrupts
107 pMCI->MCI_IDR = 0xFFFFFFFF;
109 //* Set the Data Timeout Register
110 pMCI->MCI_DTOR = DTOR_register;
112 //* Set the Mode Register
113 pMCI->MCI_MR = MR_register;
115 //* Set the SDCard Register
116 pMCI->MCI_SDCR = SDCR_register;
119 //*----------------------------------------------------------------------------
120 //* \fn AT91F_MCI_EnableIt
121 //* \brief Enable MCI IT
122 //*----------------------------------------------------------------------------
124 void AT91F_MCI_EnableIt(
125 AT91PS_MCI pMCI, // \arg pointer to a MCI controller
126 unsigned int flag) // \arg IT to be enabled
128 //* Write to the IER register
129 pMCI->MCI_IER = flag;
132 //*----------------------------------------------------------------------------
133 //* \fn AT91F_MCI_DisableIt
134 //* \brief Disable MCI IT
135 //*----------------------------------------------------------------------------
137 void AT91F_MCI_DisableIt(
138 AT91PS_MCI pMCI, // \arg pointer to a MCI controller
139 unsigned int flag) // \arg IT to be disabled
141 //* Write to the IDR register
142 pMCI->MCI_IDR = flag;
145 //*----------------------------------------------------------------------------
146 //* \fn AT91F_MCI_Enable_Interface
147 //* \brief Enable the MCI Interface
148 //*----------------------------------------------------------------------------
150 void AT91F_MCI_Enable_Interface(
151 AT91PS_MCI pMCI) // \arg pointer to a MCI controller
154 pMCI->MCI_CR = AT91C_MCI_MCIEN;
157 //*----------------------------------------------------------------------------
158 //* \fn AT91F_MCI_Disable_Interface
159 //* \brief Disable the MCI Interface
160 //*----------------------------------------------------------------------------
162 void AT91F_MCI_Disable_Interface(
163 AT91PS_MCI pMCI) // \arg pointer to a MCI controller
166 pMCI->MCI_CR = AT91C_MCI_MCIDIS;
169 //*----------------------------------------------------------------------------
170 //* \fn AT91F_MCI_Cfg_ModeRegister
171 //* \brief Configure the MCI Mode Register
172 //*----------------------------------------------------------------------------
174 void AT91F_MCI_Cfg_ModeRegister(
175 AT91PS_MCI pMCI, // \arg pointer to a MCI controller
176 unsigned int mode_register) // \arg value to set in the mode register
178 //* Configure the MCI MR
179 pMCI->MCI_MR = mode_register;
182 /* *****************************************************************************
184 ***************************************************************************** */
185 #define AT91C_AIC_BRANCH_OPCODE ((void (*) ()) 0xE51FFF20) // ldr, pc, [pc, #-&F20]
187 //*----------------------------------------------------------------------------
188 //* \fn AT91F_AIC_ConfigureIt
189 //* \brief Interrupt Handler Initialization
190 //*----------------------------------------------------------------------------
191 static inline unsigned int
192 AT91F_AIC_ConfigureIt(
193 AT91PS_AIC pAic, // \arg pointer to the AIC registers
194 unsigned int irq_id, // \arg interrupt number to initialize
195 unsigned int priority, // \arg priority to give to the interrupt
196 unsigned int src_type, // \arg activation and sense of activation
197 void (*newHandler) (void) ) // \arg address of the interrupt handler
199 unsigned int oldHandler;
202 oldHandler = pAic->AIC_SVR[irq_id];
204 mask = 0x1 << irq_id ;
205 //* Disable the interrupt on the interrupt controller
206 pAic->AIC_IDCR = mask ;
207 //* Save the interrupt handler routine pointer and the interrupt priority
208 pAic->AIC_SVR[irq_id] = (unsigned int) newHandler ;
209 //* Store the Source Mode Register
210 pAic->AIC_SMR[irq_id] = src_type | priority ;
211 //* Clear the interrupt on the interrupt controller
212 pAic->AIC_ICCR = mask ;
217 //*----------------------------------------------------------------------------
218 //* \fn AT91F_AIC_EnableIt
219 //* \brief Enable corresponding IT number
220 //*----------------------------------------------------------------------------
222 void AT91F_AIC_EnableIt(
223 AT91PS_AIC pAic, // \arg pointer to the AIC registers
224 unsigned int irq_id ) // \arg interrupt number to initialize
226 //* Enable the interrupt on the interrupt controller
227 pAic->AIC_IECR = 0x1 << irq_id ;
230 //*----------------------------------------------------------------------------
231 //* \fn AT91F_AIC_DisableIt
232 //* \brief Disable corresponding IT number
233 //*----------------------------------------------------------------------------
236 AT91PS_AIC pAic, // \arg pointer to the AIC registers
237 unsigned int irq_id ) // \arg interrupt number to initialize
239 unsigned int mask = 0x1 << irq_id;
240 //* Disable the interrupt on the interrupt controller
241 pAic->AIC_IDCR = mask ;
242 //* Clear the interrupt on the Interrupt Controller ( if one is pending )
243 pAic->AIC_ICCR = mask ;
246 //*----------------------------------------------------------------------------
247 //* \fn AT91F_AIC_ClearIt
248 //* \brief Clear corresponding IT number
249 //*----------------------------------------------------------------------------
252 AT91PS_AIC pAic, // \arg pointer to the AIC registers
253 unsigned int irq_id) // \arg interrupt number to initialize
255 //* Clear the interrupt on the Interrupt Controller ( if one is pending )
256 pAic->AIC_ICCR = (0x1 << irq_id);
259 //*----------------------------------------------------------------------------
260 //* \fn AT91F_AIC_AcknowledgeIt
261 //* \brief Acknowledge corresponding IT number
262 //*----------------------------------------------------------------------------
264 AT91F_AIC_AcknowledgeIt(
265 AT91PS_AIC pAic) // \arg pointer to the AIC registers
267 pAic->AIC_EOICR = pAic->AIC_EOICR;
270 //*----------------------------------------------------------------------------
271 //* \fn AT91F_AIC_SetExceptionVector
272 //* \brief Configure vector handler
273 //*----------------------------------------------------------------------------
274 static inline unsigned int
275 AT91F_AIC_SetExceptionVector(
276 unsigned int *pVector, // \arg pointer to the AIC registers
277 void (*Handler)(void) ) // \arg Interrupt Handler
279 unsigned int oldVector = *pVector;
281 if ((unsigned int) Handler == (unsigned int) AT91C_AIC_BRANCH_OPCODE)
282 *pVector = (unsigned int) AT91C_AIC_BRANCH_OPCODE;
284 *pVector = (((((unsigned int) Handler) - ((unsigned int) pVector) - 0x8) >> 2) & 0x00FFFFFF) | 0xEA000000;
289 //*----------------------------------------------------------------------------
290 //* \fn AT91F_AIC_Trig
291 //* \brief Trig an IT
292 //*----------------------------------------------------------------------------
295 AT91PS_AIC pAic, // \arg pointer to the AIC registers
296 unsigned int irq_id) // \arg interrupt number
298 pAic->AIC_ISCR = (0x1 << irq_id) ;
301 //*----------------------------------------------------------------------------
302 //* \fn AT91F_AIC_IsActive
303 //* \brief Test if an IT is active
304 //*----------------------------------------------------------------------------
305 static inline unsigned int
307 AT91PS_AIC pAic, // \arg pointer to the AIC registers
308 unsigned int irq_id) // \arg Interrupt Number
310 return (pAic->AIC_ISR & (0x1 << irq_id));
313 //*----------------------------------------------------------------------------
314 //* \fn AT91F_AIC_IsPending
315 //* \brief Test if an IT is pending
316 //*----------------------------------------------------------------------------
317 static inline unsigned int
319 AT91PS_AIC pAic, // \arg pointer to the AIC registers
320 unsigned int irq_id) // \arg Interrupt Number
322 return (pAic->AIC_IPR & (0x1 << irq_id));
325 //*----------------------------------------------------------------------------
326 //* \fn AT91F_AIC_Open
327 //* \brief Set exception vectors and AIC registers to default values
328 //*----------------------------------------------------------------------------
331 AT91PS_AIC pAic, // \arg pointer to the AIC registers
332 void (*IrqHandler)(void), // \arg Default IRQ vector exception
333 void (*FiqHandler)(void), // \arg Default FIQ vector exception
334 void (*DefaultHandler)(void), // \arg Default Handler set in ISR
335 void (*SpuriousHandler)(void), // \arg Default Spurious Handler
336 unsigned int protectMode) // \arg Debug Control Register
340 // Disable all interrupts and set IVR to the default handler
341 for (i = 0; i < 32; ++i) {
342 AT91F_AIC_DisableIt(pAic, i);
343 AT91F_AIC_ConfigureIt(pAic, i, AT91C_AIC_PRIOR_LOWEST, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, DefaultHandler);
346 // Set the IRQ exception vector
347 AT91F_AIC_SetExceptionVector((unsigned int *) 0x18, IrqHandler);
348 // Set the Fast Interrupt exception vector
349 AT91F_AIC_SetExceptionVector((unsigned int *) 0x1C, FiqHandler);
351 pAic->AIC_SPU = (unsigned int) SpuriousHandler;
352 pAic->AIC_DCR = protectMode;
355 //*----------------------------------------------------------------------------
356 //* \fn AT91F_MCI_CfgPMC
357 //* \brief Enable Peripheral clock in PMC for MCI
358 //*----------------------------------------------------------------------------
360 AT91F_MCI_CfgPMC(void)
362 AT91F_PMC_EnablePeriphClock(
363 AT91C_BASE_PMC, // PIO controller base address
364 ((unsigned int) 1 << AT91C_ID_MCI));
367 //*----------------------------------------------------------------------------
368 //* \fn AT91F_MCI_CfgPIO
369 //* \brief Configure PIO controllers to drive MCI signals
370 //*----------------------------------------------------------------------------
372 AT91F_MCI_CfgPIO(void)
374 // Configure PIO controllers to periph mode
376 AT91C_BASE_PIOA, // PIO controller base address
377 ((unsigned int) AT91C_PA28_MCCDA ) |
378 ((unsigned int) AT91C_PA29_MCDA0 ) |
379 ((unsigned int) AT91C_PA27_MCCK ), // Peripheral A
381 // Configure PIO controllers to periph mode
383 AT91C_BASE_PIOB, // PIO controller base address
385 ((unsigned int) AT91C_PB5_MCDA3 ) |
386 ((unsigned int) AT91C_PB3_MCDA1 ) |
387 ((unsigned int) AT91C_PB4_MCDA2 )); // Peripheral B
391 /* *****************************************************************************
393 ***************************************************************************** */
394 //*----------------------------------------------------------------------------
395 //* \fn AT91F_PDC_SetNextRx
396 //* \brief Set the next receive transfer descriptor
397 //*----------------------------------------------------------------------------
399 AT91F_PDC_SetNextRx (
400 AT91PS_PDC pPDC, // \arg pointer to a PDC controller
401 char *address, // \arg address to the next bloc to be received
402 unsigned int bytes) // \arg number of bytes to be received
404 pPDC->PDC_RNPR = (unsigned int) address;
405 pPDC->PDC_RNCR = bytes;
408 //*----------------------------------------------------------------------------
409 //* \fn AT91F_PDC_SetNextTx
410 //* \brief Set the next transmit transfer descriptor
411 //*----------------------------------------------------------------------------
414 AT91PS_PDC pPDC, // \arg pointer to a PDC controller
415 char *address, // \arg address to the next bloc to be transmitted
416 unsigned int bytes) // \arg number of bytes to be transmitted
418 pPDC->PDC_TNPR = (unsigned int) address;
419 pPDC->PDC_TNCR = bytes;
422 //*----------------------------------------------------------------------------
423 //* \fn AT91F_PDC_SetRx
424 //* \brief Set the receive transfer descriptor
425 //*----------------------------------------------------------------------------
428 AT91PS_PDC pPDC, // \arg pointer to a PDC controller
429 char *address, // \arg address to the next bloc to be received
430 unsigned int bytes) // \arg number of bytes to be received
432 pPDC->PDC_RPR = (unsigned int) address;
433 pPDC->PDC_RCR = bytes;
436 //*----------------------------------------------------------------------------
437 //* \fn AT91F_PDC_SetTx
438 //* \brief Set the transmit transfer descriptor
439 //*----------------------------------------------------------------------------
442 AT91PS_PDC pPDC, // \arg pointer to a PDC controller
443 char *address, // \arg address to the next bloc to be transmitted
444 unsigned int bytes) // \arg number of bytes to be transmitted
446 pPDC->PDC_TPR = (unsigned int) address;
447 pPDC->PDC_TCR = bytes;
450 //*----------------------------------------------------------------------------
451 //* \fn AT91F_PDC_EnableTx
452 //* \brief Enable transmit
453 //*----------------------------------------------------------------------------
456 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
458 pPDC->PDC_PTCR = AT91C_PDC_TXTEN;
461 //*----------------------------------------------------------------------------
462 //* \fn AT91F_PDC_EnableRx
463 //* \brief Enable receive
464 //*----------------------------------------------------------------------------
467 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
469 pPDC->PDC_PTCR = AT91C_PDC_RXTEN;
472 //*----------------------------------------------------------------------------
473 //* \fn AT91F_PDC_DisableTx
474 //* \brief Disable transmit
475 //*----------------------------------------------------------------------------
478 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
480 pPDC->PDC_PTCR = AT91C_PDC_TXTDIS;
483 //*----------------------------------------------------------------------------
484 //* \fn AT91F_PDC_DisableRx
485 //* \brief Disable receive
486 //*----------------------------------------------------------------------------
489 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
491 pPDC->PDC_PTCR = AT91C_PDC_RXTDIS;
494 //*----------------------------------------------------------------------------
495 //* \fn AT91F_PDC_IsTxEmpty
496 //* \brief Test if the current transfer descriptor has been sent
497 //*----------------------------------------------------------------------------
499 AT91F_PDC_IsTxEmpty( // \return return 1 if transfer is complete
500 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
502 return !(pPDC->PDC_TCR);
505 //*----------------------------------------------------------------------------
506 //* \fn AT91F_PDC_IsNextTxEmpty
507 //* \brief Test if the next transfer descriptor has been moved to the current td
508 //*----------------------------------------------------------------------------
510 AT91F_PDC_IsNextTxEmpty( // \return return 1 if transfer is complete
511 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
513 return !(pPDC->PDC_TNCR);
516 //*----------------------------------------------------------------------------
517 //* \fn AT91F_PDC_IsRxEmpty
518 //* \brief Test if the current transfer descriptor has been filled
519 //*----------------------------------------------------------------------------
521 AT91F_PDC_IsRxEmpty( // \return return 1 if transfer is complete
522 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
524 return !(pPDC->PDC_RCR);
527 //*----------------------------------------------------------------------------
528 //* \fn AT91F_PDC_IsNextRxEmpty
529 //* \brief Test if the next transfer descriptor has been moved to the current td
530 //*----------------------------------------------------------------------------
532 AT91F_PDC_IsNextRxEmpty( // \return return 1 if transfer is complete
533 AT91PS_PDC pPDC ) // \arg pointer to a PDC controller
535 return !(pPDC->PDC_RNCR);
538 //*----------------------------------------------------------------------------
539 //* \fn AT91F_PDC_Open
540 //* \brief Open PDC: disable TX and RX reset transfer descriptors, re-enable RX and TX
541 //*----------------------------------------------------------------------------
544 AT91PS_PDC pPDC) // \arg pointer to a PDC controller
546 //* Disable the RX and TX PDC transfer requests
547 AT91F_PDC_DisableRx(pPDC);
548 AT91F_PDC_DisableTx(pPDC);
550 //* Reset all Counter register Next buffer first
551 AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0);
552 AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
553 AT91F_PDC_SetTx(pPDC, (char *) 0, 0);
554 AT91F_PDC_SetRx(pPDC, (char *) 0, 0);
556 //* Enable the RX and TX PDC transfer requests
557 AT91F_PDC_EnableRx(pPDC);
558 AT91F_PDC_EnableTx(pPDC);
561 //*----------------------------------------------------------------------------
562 //* \fn AT91F_PDC_Close
563 //* \brief Close PDC: disable TX and RX reset transfer descriptors
564 //*----------------------------------------------------------------------------
567 AT91PS_PDC pPDC) // \arg pointer to a PDC controller
569 //* Disable the RX and TX PDC transfer requests
570 AT91F_PDC_DisableRx(pPDC);
571 AT91F_PDC_DisableTx(pPDC);
573 //* Reset all Counter register Next buffer first
574 AT91F_PDC_SetNextTx(pPDC, (char *) 0, 0);
575 AT91F_PDC_SetNextRx(pPDC, (char *) 0, 0);
576 AT91F_PDC_SetTx(pPDC, (char *) 0, 0);
577 AT91F_PDC_SetRx(pPDC, (char *) 0, 0);
581 //*----------------------------------------------------------------------------
582 //* \fn AT91F_PDC_SendFrame
583 //* \brief Close PDC: disable TX and RX reset transfer descriptors
584 //*----------------------------------------------------------------------------
585 static inline unsigned int
589 unsigned int szBuffer,
591 unsigned int szNextBuffer )
593 if (AT91F_PDC_IsTxEmpty(pPDC)) {
594 //* Buffer and next buffer can be initialized
595 AT91F_PDC_SetTx(pPDC, pBuffer, szBuffer);
596 AT91F_PDC_SetNextTx(pPDC, pNextBuffer, szNextBuffer);
599 else if (AT91F_PDC_IsNextTxEmpty(pPDC)) {
600 //* Only one buffer can be initialized
601 AT91F_PDC_SetNextTx(pPDC, pBuffer, szBuffer);
605 //* All buffer are in use...
610 //*----------------------------------------------------------------------------
611 //* \fn AT91F_PDC_ReceiveFrame
612 //* \brief Close PDC: disable TX and RX reset transfer descriptors
613 //*----------------------------------------------------------------------------
614 static inline unsigned int
615 AT91F_PDC_ReceiveFrame(
618 unsigned int szBuffer,
620 unsigned int szNextBuffer )
622 if (AT91F_PDC_IsRxEmpty(pPDC)) {
623 //* Buffer and next buffer can be initialized
624 AT91F_PDC_SetRx(pPDC, pBuffer, szBuffer);
625 AT91F_PDC_SetNextRx(pPDC, pNextBuffer, szNextBuffer);
628 else if (AT91F_PDC_IsNextRxEmpty(pPDC)) {
629 //* Only one buffer can be initialized
630 AT91F_PDC_SetNextRx(pPDC, pBuffer, szBuffer);
634 //* All buffer are in use...