Add power management register defintions and clock control logic for the SAM4L
This commit is contained in:
parent
82d37c755b
commit
19b38fa95f
@ -4902,4 +4902,9 @@
|
||||
LED interfaces (2013-6-5).
|
||||
* arch/arm/src/sam34/sam4l_gpio.c and arch/arm/src/sam34/chip/sam4l_gpio.h:
|
||||
Fix GPIO port address; fix compilation errors (2013-6-5).
|
||||
|
||||
* arch/arm/src/sam34/chip/sam4l_flashcalw.h: Add header file
|
||||
for SAM4L FLASH and PICOCACHE definitions (2013-6-5).
|
||||
* arch/arm/src/sam34/chip/sam4l_pm.h: Add header file for SAM4L
|
||||
Power Management. Leveraged from AVR32 (2013-6-5).
|
||||
* arch/arm/src/sam34/sarm4l_clockconfig.c: SAM4L clock configuration
|
||||
logic (leveraged from AVR32).
|
||||
|
@ -4,6 +4,8 @@
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* This file is derived from nuttx/arch/avr/src/at32uc3/at32uc3_flashc.h.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -33,8 +35,8 @@
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4LFLASHCALW_H
|
||||
#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4LFLASHCALW_H
|
||||
#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_FLASHCALW_H
|
||||
#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_FLASHCALW_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
@ -343,5 +345,5 @@
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4LFLASHCALW_H */
|
||||
#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_FLASHCALW_H */
|
||||
|
||||
|
335
arch/arm/src/sam34/chip/sam4l_pm.h
Normal file
335
arch/arm/src/sam34/chip/sam4l_pm.h
Normal file
@ -0,0 +1,335 @@
|
||||
/************************************************************************************
|
||||
* arch/avr/src/sam34/sam4l_pm.h
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* This file is derived from nuttx/arch/avr/src/at32uc3/at32uc3_pm.h.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifndef __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PM_H
|
||||
#define __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PM_H
|
||||
|
||||
/************************************************************************************
|
||||
* Included Files
|
||||
************************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "chip/sam_memorymap.h"
|
||||
|
||||
/************************************************************************************
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
/* Register offsets *****************************************************************/
|
||||
|
||||
#define SAM_PM_MCCTRL_OFFSET 0x0000 /* Main Clock Control Register */
|
||||
#define SAM_PM_CPUSEL_OFFSET 0x0004 /* CPU Clock Select Register */
|
||||
#define SAM_PM_PBASEL_OFFSET 0x000c /* PBA Clock Select Register */
|
||||
#define SAM_PM_PBBSEL_OFFSET 0x0010 /* PBB Clock Select Register */
|
||||
#define SAM_PM_PBCSEL_OFFSET 0x0014 /* PBC Clock Select Register */
|
||||
#define SAM_PM_PBDSEL_OFFSET 0x0018 /* PBD Clock Select Register */
|
||||
#define SAM_PM_CPUMASK_OFFSET 0x0020 /* CPU Mask Register */
|
||||
#define SAM_PM_HSBMASK_OFFSET 0x0024 /* HSB Mask Register */
|
||||
#define SAM_PM_PBAMASK_OFFSET 0x0028 /* PBA Mask Register */
|
||||
#define SAM_PM_PBBMASK_OFFSET 0x002c /* PBB Mask Register */
|
||||
#define SAM_PM_PBCMASK_OFFSET 0x0030 /* PBC Mask Register */
|
||||
#define SAM_PM_PBDMASK_OFFSET 0x0034 /* PBD Mask Register */
|
||||
#define SAM_PM_PBADIVMASK_OFFSET 0x0040 /* PBA Divided Mask */
|
||||
#define SAM_PM_CFDCTRL_OFFSET 0x0054 /* Clock Failure Detector Control */
|
||||
#define SAM_PM_UNLOCK_OFFSET 0x0058 /* Unlock Register */
|
||||
#define SAM_PM_IER_OFFSET 0x00c0 /* Interrupt Enable Register */
|
||||
#define SAM_PM_IDR_OFFSET 0x00c4 /* Interrupt Disable Register */
|
||||
#define SAM_PM_IMR_OFFSET 0x00c8 /* Interrupt Mask Register */
|
||||
#define SAM_PM_ISR_OFFSET 0x00cc /* Interrupt Status Register */
|
||||
#define SAM_PM_ICR_OFFSET 0x00d0 /* Interrupt Clear Register */
|
||||
#define SAM_PM_SR_OFFSET 0x00d4 /* Status Register Register */
|
||||
#define SAM_PM_PPCR_OFFSET 0x0160 /* Peripheral Power Control Register */
|
||||
#define SAM_PM_RCAUSE_OFFSET 0x0180 /* Reset Cause Register */
|
||||
#define SAM_PM_WCAUSE_OFFSET 0x0184 /* Wake Cause Register */
|
||||
#define SAM_PM_AWEN_OFFSET 0x0188 /* Asynchronous Wake Up Enable Register */
|
||||
#define SAM_PM_PROTCTRL_OFFSET 0x018c /* Protection Control Register */
|
||||
#define SAM_PM_FASTSLEEP_OFFSET 0x0194 /* Fast Sleep Register */
|
||||
#define SAM_PM_CONFIG_OFFSET 0x03f8 /* Configuration Register */
|
||||
#define SAM_PM_VERSION_OFFSET 0x03fc /* Version Register */
|
||||
|
||||
/* Register Addresses ***************************************************************/
|
||||
|
||||
#define SAM_PM_MCCTRL (SAM_PM_BASE+SAM_PM_MCCTRL_OFFSET)
|
||||
#define SAM_PM_CPUSEL (SAM_PM_BASE+SAM_PM_CPUSEL_OFFSET)
|
||||
#define SAM_PM_PBASEL (SAM_PM_BASE+SAM_PM_PBASEL_OFFSET)
|
||||
#define SAM_PM_PBBSEL (SAM_PM_BASE+SAM_PM_PBBSEL_OFFSET)
|
||||
#define SAM_PM_PBCSEL (SAM_PM_BASE+SAM_PM_PBCSEL_OFFSET)
|
||||
#define SAM_PM_PBDSEL (SAM_PM_BASE+SAM_PM_PBDSEL_OFFSET)
|
||||
#define SAM_PM_CPUMASK (SAM_PM_BASE+SAM_PM_CPUMASK_OFFSET)
|
||||
#define SAM_PM_HSBMASK (SAM_PM_BASE+SAM_PM_HSBMASK_OFFSET)
|
||||
#define SAM_PM_PBAMASK (SAM_PM_BASE+SAM_PM_PBAMASK_OFFSET)
|
||||
#define SAM_PM_PBBMASK (SAM_PM_BASE+SAM_PM_PBBMASK_OFFSET)
|
||||
#define SAM_PM_PBCMASK (SAM_PM_BASE+SAM_PM_PBCMASK_OFFSET)
|
||||
#define SAM_PM_PBDMASK (SAM_PM_BASE+SAM_PM_PBDMASK_OFFSET)
|
||||
#define SAM_PM_PBADIVMASK (SAM_PM_BASE+SAM_PM_PBADIVMASK_OFFSET)
|
||||
#define SAM_PM_CFDCTRL (SAM_PM_BASE+SAM_PM_CFDCTRL_OFFSET)
|
||||
#define SAM_PM_UNLOCK (SAM_PM_BASE+SAM_PM_UNLOCK_OFFSET)
|
||||
#define SAM_PM_IER (SAM_PM_BASE+SAM_PM_IER_OFFSET)
|
||||
#define SAM_PM_IDR (SAM_PM_BASE+SAM_PM_IDR_OFFSET)
|
||||
#define SAM_PM_IMR (SAM_PM_BASE+SAM_PM_IMR_OFFSET)
|
||||
#define SAM_PM_ISR (SAM_PM_BASE+SAM_PM_ISR_OFFSET)
|
||||
#define SAM_PM_ICR (SAM_PM_BASE+SAM_PM_ICR_OFFSET)
|
||||
#define SAM_PM_SR (SAM_PM_BASE+SAM_PM_SR_OFFSET)
|
||||
#define SAM_PM_PPCR (SAM_PM_BASE+SAM_PM_PPCR_OFFSET)
|
||||
#define SAM_PM_RCAUSE (SAM_PM_BASE+SAM_PM_RCAUSE_OFFSET)
|
||||
#define SAM_PM_WCAUSE (SAM_PM_BASE+SAM_PM_WCAUSE_OFFSET)
|
||||
#define SAM_PM_AWEN (SAM_PM_BASE+SAM_PM_AWEN_OFFSET)
|
||||
#define SAM_PM_PROTCTRL (SAM_PM_BASE+SAM_PM_PROTCTRL_OFFSET)
|
||||
#define SAM_PM_FASTSLEEP (SAM_PM_BASE+SAM_PM_FASTSLEEP_OFFSET)
|
||||
#define SAM_PM_CONFIG (SAM_PM_BASE+SAM_PM_CONFIG_OFFSET)
|
||||
#define SAM_PM_VERSION (SAM_PM_BASE+SAM_PM_VERSION_OFFSET)
|
||||
|
||||
/* Register Bit-field Definitions ***************************************************/
|
||||
|
||||
/* Main Clock Control Register Bit-field Definitions */
|
||||
|
||||
#define PM_MCCTRL_MCSEL_SHIFT (0) /* Bits 0-2: Main Clock Select */
|
||||
#define PM_MCCTRL_MCSEL_MASK (7 << PM_MCCTRL_MCSEL_SHIFT)
|
||||
# define PM_MCCTRL_MCSEL_RCSYS (0 << PM_MCCTRL_MCSEL_SHIFT) /* System RC oscillator */
|
||||
# define PM_MCCTRL_MCSEL_OSC0 (1 << PM_MCCTRL_MCSEL_SHIFT) /* Oscillator0 */
|
||||
# define PM_MCCTRL_MCSEL_PLL (2 << PM_MCCTRL_MCSEL_SHIFT) /* PLL */
|
||||
# define PM_MCCTRL_MCSEL_DFLL (3 << PM_MCCTRL_MCSEL_SHIFT) /* DFLL */
|
||||
# define PM_MCCTRL_MCSEL_RC80M (4 << PM_MCCTRL_MCSEL_SHIFT) /* 80MHz RC oscillator */
|
||||
# define PM_MCCTRL_MCSEL_RCFAST (5 << PM_MCCTRL_MCSEL_SHIFT) /* 4/8/12 MHz RC oscillator */
|
||||
# define PM_MCCTRL_MCSEL_RC1M (6 << PM_MCCTRL_MCSEL_SHIFT) /* 1 MHz RC oscillator */
|
||||
|
||||
/* CPU Clock Select Register Bit-field Definitions */
|
||||
|
||||
#define PM_CPUSEL_SHIFT (0) /* Bits 0-2: CPU Clock Select */
|
||||
#define PM_CPUSEL_MASK (7 << PM_CPUSEL_CPUSEL_SHIFT)
|
||||
#define PM_CPUSEL_CPUDIV (1 << 7) /* Bit 7: CPU Division */
|
||||
|
||||
/* PBA/PBB/PBC/PBD Clock Select Register Bit-field Definitions */
|
||||
|
||||
#define PM_PBSEL_SHIFT (0) /* Bits 0-2: PBx Clock Select */
|
||||
#define PM_PBSEL_MASK (7 << PM_PBASEL_SHIFT)
|
||||
#define PM_PBSEL_DIV (1 << 7) /* Bit 7: PBx Division */
|
||||
|
||||
/* CPU Mask Register Bit-field Definitions */
|
||||
|
||||
#define PM_CPUMASK_OCD (1 << 0) /* Bit 0: OCD */
|
||||
|
||||
/* HSB Mask Register Bit-field Definitions */
|
||||
|
||||
#define PM_HSBMASK_PDCA (1 << 0) /* Bit 0: PDCA */
|
||||
#define PM_HSBMASK_FLASHCALW (1 << 1) /* Bit 1: FLASHCALW */
|
||||
#define PM_HSBMASK_HRAMC1 (1 << 2) /* Bit 2: HRAMC1 (picoCache RAM) */
|
||||
#define PM_HSBMASK_USBC (1 << 3) /* Bit 3: USBC */
|
||||
#define PM_HSBMASK_CRCCU (1 << 4) /* Bit 4: CRCCU */
|
||||
#define PM_HSBMASK_APBA (1 << 5) /* Bit 5: APBA bridge */
|
||||
#define PM_HSBMASK_APBB (1 << 6) /* Bit 5: APBB bridge */
|
||||
#define PM_HSBMASK_APBC (1 << 7) /* Bit 5: APBC bridge */
|
||||
#define PM_HSBMASK_APBD (1 << 8) /* Bit 5: APBD bridge */
|
||||
#define PM_HSBMASK_AESA (1 << 9) /* Bit 5: AESA */
|
||||
|
||||
/* PBA Mask Register Bit-field Definitions */
|
||||
|
||||
#define PM_PBAMASK_IISC (1 << 0) /* Bit 0: IISC */
|
||||
#define PM_PBAMASK_SPI (1 << 1) /* Bit 1: SPI */
|
||||
#define PM_PBAMASK_TC0 (1 << 2) /* Bit 2: TC0 */
|
||||
#define PM_PBAMASK_TC1 (1 << 3) /* Bit 3: TC1 */
|
||||
#define PM_PBAMASK_TWIM0 (1 << 4) /* Bit 4: TWIM0 */
|
||||
#define PM_PBAMASK_TWIS0 (1 << 5) /* Bit 5: TWIS0 */
|
||||
#define PM_PBAMASK_TWIM1 (1 << 6) /* Bit 6: TWIM1 */
|
||||
#define PM_PBAMASK_TWIS1 (1 << 7) /* Bit 7: TWIS1 */
|
||||
#define PM_PBAMASK_USART0 (1 << 8) /* Bit 8: USART0 */
|
||||
#define PM_PBAMASK_USART1 (1 << 9) /* Bit 9: USART1 */
|
||||
#define PM_PBAMASK_USART2 (1 << 10) /* Bit 10: USART2 */
|
||||
#define PM_PBAMASK_USART3 (1 << 11) /* Bit 11: USART3 */
|
||||
#define PM_PBAMASK_ADCIFE (1 << 12) /* Bit 12: ADCIFE */
|
||||
#define PM_PBAMASK_DACC (1 << 13) /* Bit 13: DACC */
|
||||
#define PM_PBAMASK_ACIFC (1 << 14) /* Bit 14: ACIFC */
|
||||
#define PM_PBAMASK_GLOC (1 << 15) /* Bit 15: GLOC */
|
||||
#define PM_PBAMASK_ABDACB (1 << 16) /* Bit 16: ABDACB */
|
||||
#define PM_PBAMASK_TRNG (1 << 17) /* Bit 17: TRNG */
|
||||
#define PM_PBAMASK_PARC (1 << 18) /* Bit 18: PARC */
|
||||
#define PM_PBAMASK_CATB (1 << 19) /* Bit 19: CATB */
|
||||
#define PM_PBAMASK_TWIM2 (1 << 21) /* Bit 21: TWIM2 */
|
||||
#define PM_PBAMASK_TWIM3 (1 << 22) /* Bit 22: TWIM3 */
|
||||
#define PM_PBAMASK_LCDCA (1 << 23) /* Bit 23: LCDCA*/
|
||||
|
||||
/* PBB Mask Register Bit-field Definitions */
|
||||
|
||||
#define PM_PBBMASK_FLASHCALW (1 << 0) /* Bit 0: FLASHCALW */
|
||||
#define PM_PBBMASK_HRAMC1 (1 << 1) /* Bit 1: HRAMC1 */
|
||||
#define PM_PBBMASK_HMATRIX (1 << 2) /* Bit 2: HMATRIX */
|
||||
#define PM_PBBMASK_PDCA (1 << 3) /* Bit 3: PDCA */
|
||||
#define PM_PBBMASK_CRCCU (1 << 4) /* Bit 4: CRCCU */
|
||||
#define PM_PBBMASK_USBC (1 << 5) /* Bit 5: USBC */
|
||||
#define PM_PBBMASK_PEVC (1 << 6) /* Bit 6: PEVC */
|
||||
|
||||
/* PBC Mask Register Bit-field Definitions */
|
||||
|
||||
#define PM_PBCMASK_PM (1 << 0) /* Bit 0: PM */
|
||||
#define PM_PBCMASK_CHIPID (1 << 1) /* Bit 1: CHIPID */
|
||||
#define PM_PBCMASK_SCIF (1 << 2) /* Bit 2: SCIF */
|
||||
#define PM_PBCMASK_FREQM (1 << 3) /* Bit 3: FREQM */
|
||||
#define PM_PBCMASK_GPIO (1 << 4) /* Bit 4: GPIO */
|
||||
|
||||
/* PBD Mask Register Bit-field Definitions */
|
||||
|
||||
#define PM_PBDMASK_BPM (1 << 0) /* Bit 0: BPM */
|
||||
#define PM_PBDMASK_BSCIF (1 << 1) /* Bit 1: BSCIF */
|
||||
#define PM_PBDMASK_AST (1 << 2) /* Bit 2: AST */
|
||||
#define PM_PBDMASK_WDT (1 << 3) /* Bit 3: WDT */
|
||||
#define PM_PBDMASK_EIC (1 << 4) /* Bit 4: EIC */
|
||||
#define PM_PBDMASK_PICOUART (1 << 5) /* Bit 5: PICOUART */
|
||||
|
||||
/* PBA Divided Mask */
|
||||
|
||||
#define PM_PBADIVMASK_TIMER_CLOCK2 (1 << 0) /* Bit 0: TIMER_CLOCK2 (TC0-1) */
|
||||
#define PM_PBADIVMASK_CLK_USART (1 << 2) /* Bit 2: CLK_USART/DIV (USART0-3) */
|
||||
#define PM_PBADIVMASK_TIMER_CLOCK3 (1 << 2) /* Bit 2: TIMER_CLOCK3 (TC0-1) */
|
||||
#define PM_PBADIVMASK_TIMER_CLOCK4 (1 << 4) /* Bit 4: TIMER_CLOCK4 (TC0-1) */
|
||||
#define PM_PBADIVMASK_TIMER_CLOCK5 (1 << 6) /* Bit 5: TIMER_CLOCK5 (TC0-1) */
|
||||
|
||||
/* Clock Failure Detector Control */
|
||||
|
||||
#define PM_CFDCTRL_CFDEN (1 << 0) /* Bit 0: Clock Failure Detection Enable */
|
||||
#define PM_CFDCTRL_SFV (1 << 31) /* Bit 31: Store Final Value */
|
||||
|
||||
/* Unlock Register */
|
||||
|
||||
#define PM_UNLOCK_ADDR_SHIFT (0) /* Bits 0-9: Unlock Address */
|
||||
#define PM_UNLOCK_ADDR_MASK (0x3ff << PM_UNLOCK_ADDR_SHIFT)
|
||||
#define PM_UNLOCK_KEY_SHIFT (24) /* Bits 24-31: Unlock Key */
|
||||
#define PM_UNLOCK_KEY_MASK (0xff << PM_UNLOCK_KEY_SHIFT)
|
||||
|
||||
/* Interrupt Enable Register Bit-field Definitions */
|
||||
/* Interrupt Disable Register Bit-field Definitions */
|
||||
/* Interrupt Mask Register Bit-field Definitions */
|
||||
/* Interrupt Status Register Bit-field Definitions */
|
||||
/* Interrupt Clear Register Bit-field Definitions */
|
||||
/* Status Register Register */
|
||||
|
||||
#define PM_INT_CFD (1 << 0) /* Bit 0: CFD */
|
||||
#define PM_INT_CKRDY (1 << 5) /* Bit 5: CKRDY */
|
||||
#define PM_INT_WAKE (1 << 8) /* Bit 8: WAKE */
|
||||
|
||||
/* Peripheral Power Control Register */
|
||||
|
||||
#define PM_PPCR_RSTPUN (1 << 0) /* Bit 0: Reset Pullup */
|
||||
#define PM_PPCR_CATBRCMASK (1 << 1) /* Bit 1: CAT Request Clock Mask */
|
||||
#define PM_PPCR_ACIFCRCMASK (1 << 2) /* Bit 2: ACIFC Request Clock Mask */
|
||||
#define PM_PPCR_ASTRCMASK (1 << 3) /* Bit 3: AST Request Clock Mask */
|
||||
#define PM_PPCR_TWIS0RCMASK (1 << 4) /* Bit 4: TWIS0 Request Clock Mask */
|
||||
#define PM_PPCR_TWIS1RCMASK (1 << 5) /* Bit 5: TWIS1 Request Clock Mask */
|
||||
#define PM_PPCR_PEVCRCMASK (1 << 6) /* Bit 6: PEVC Request Clock Mask */
|
||||
#define PM_PPCR_ADCIFERCMASK (1 << 7) /* Bit 7: ADCIFE Request Clock Mask */
|
||||
#define PM_PPCR_VREGRCMASK (1 << 8) /* Bit 8: VREG Request Clock Mask */
|
||||
#define PM_PPCR_FWBGREF (1 << 9) /* Bit 9: Flash Wait BGREF */
|
||||
#define PM_PPCR_FWBOD18 (1 << 10) /* Bit 10: Flash Wait BOD18 */
|
||||
|
||||
/* Reset Cause Register */
|
||||
|
||||
#define PM_RCAUSE_POR (1 << 0) /* Bit 0: Power-on Reset */
|
||||
#define PM_RCAUSE_BOD (1 << 1) /* Bit 1: Brown-out Reset */
|
||||
#define PM_RCAUSE_EXT (1 << 2) /* Bit 2: External Reset Pin */
|
||||
#define PM_RCAUSE_WDT (1 << 3) /* Bit 3: Watchdog Reset */
|
||||
#define PM_RCAUSE_BKUP (1 << 6) /* Bit 6: Backup reset */
|
||||
#define PM_RCAUSE_OCDRST (1 << 8) /* Bit 8: OCD Reset */
|
||||
#define PM_RCAUSE_POR33 (1 << 10) /* Bit 10: Power-on 3.3v Reset */
|
||||
#define PM_RCAUSE_BOD33 (1 << 13) /* Bit 13: Brown-out 3.3v Reset */
|
||||
|
||||
/* Wake Cause Register */
|
||||
|
||||
#define PM_WCAUSE_TWIS0 (1 << 0) /* Bit 0: 0 TWI Slave 0 */
|
||||
#define PM_WCAUSE_TWIS1 (1 << 1) /* Bit 1: 1 TWI Slave 1 */
|
||||
#define PM_WCAUSE_USBC (1 << 2) /* Bit 2: 2 USBC */
|
||||
#define PM_WCAUSE_PSOK (1 << 3) /* Bit 3: 3 PSOK */
|
||||
#define PM_WCAUSE_BOD18 (1 << 4) /* Bit 4: 4 BOD18 IRQ */
|
||||
#define PM_WCAUSE_BOD33 (1 << 5) /* Bit 5: 5 BOD33 IRQ */
|
||||
#define PM_WCAUSE_PICOUART (1 << 6) /* Bit 6: 6 PICOUART */
|
||||
#define PM_WCAUSE_LCDCA (1 << 7) /* Bit 7: 7 LCDCA */
|
||||
#define PM_WCAUSE_EIC (1 << 16) /* Bit 16: 16 EIC */
|
||||
#define PM_WCAUSE_AST (1 << 17) /* Bit 17: 17 AST */
|
||||
|
||||
/* Asynchronous Wake Up Enable Register Bit-field Definitions */
|
||||
|
||||
#define PM_AWEN_TWIS0 (1 << 0) /* Bit 0: TWI Slave 0 */
|
||||
#define PM_AWEN_TWIS1 (1 << 1) /* Bit 1: TWI Slave 1 */
|
||||
#define PM_AWEN_USBC (1 << 2) /* Bit 2: USBC */
|
||||
#define PM_AWEN_PSOK (1 << 3) /* Bit 3: PSOK */
|
||||
#define PM_AWEN_BOD18 (1 << 4) /* Bit 4: BOD18 IRQ */
|
||||
#define PM_AWEN_BOD33 (1 << 5) /* Bit 5: BOD33 IRQ */
|
||||
#define PM_AWEN_PICOUART (1 << 6) /* Bit 6: PICOUART */
|
||||
#define PM_AWEN_LCDCA (1 << 7) /* Bit 7: LCDCA */
|
||||
|
||||
/* Protection Control Register */
|
||||
|
||||
/* Fast Sleep Register */
|
||||
#define PM_FASTSLEEP_
|
||||
#define PM_FASTSLEEP_OSC (1 << 0) /* Bit 0: Oscillator */
|
||||
#define PM_FASTSLEEP_PLL (1 << 0) /* Bit 0: PLL */
|
||||
#define PM_FASTSLEEP_FASTRCOSC_SHIFT (0) /* Bits 0-9: FASTRCOSC */
|
||||
#define PM_FASTSLEEP_FASTRCOSC_MASK (31 << PM_FASTSLEEP_FASTRCOSC_SHIFT)
|
||||
# define PM_FASTSLEEP_RC80 (1 << PM_FASTSLEEP_FASTRCOSC_SHIFT)
|
||||
# define PM_FASTSLEEP_RCFAST (2 << PM_FASTSLEEP_FASTRCOSC_SHIFT)
|
||||
# define PM_FASTSLEEP_RC1M (4 << PM_FASTSLEEP_FASTRCOSC_SHIFT)
|
||||
#define PM_FASTSLEEP_DFLL (1 << 0) /* Bit 0: DFLL */
|
||||
|
||||
/* Configuration Register */
|
||||
|
||||
#define PM_CONFIG_PBA (1 << 0) /* Bit 0: APBA Implemented */
|
||||
#define PM_CONFIG_PBB (1 << 1) /* Bit 1: APBB Implemented */
|
||||
#define PM_CONFIG_PBC (1 << 2) /* Bit 2: APBC Implemented */
|
||||
#define PM_CONFIG_PBD (1 << 3) /* Bit 3: APBD Implemented */
|
||||
#define PM_CONFIG_HSBPEVC (1 << 7) /* Bit 7: HSB PEVC Clock Implemented */
|
||||
|
||||
/* Version Register */
|
||||
|
||||
#define PM_VERSION_SHIFT (0) /* Bits 0-11: Version Number */
|
||||
#define PM_VERSION_MASK (0xfff << PM_VERSION_VERSION_SHIFT)
|
||||
#define PM_VERSION_VARIANT_SHIFT (16) /* Bits 16-19: Variant Number */
|
||||
#define PM_VERSION_VARIANT_MASK (15 << PM_VERSION_VARIANT_SHIFT)
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Data
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
|
||||
#endif /* __ARCH_ARM_SRC_SAM34_CHIP_SAM4L_PM_H */
|
||||
|
506
arch/arm/src/sam34/sam4l_clockconfig.c
Normal file
506
arch/arm/src/sam34/sam4l_clockconfig.c
Normal file
@ -0,0 +1,506 @@
|
||||
/****************************************************************************
|
||||
* arch/avr/src/sam34/sam4l_clockconfig.c
|
||||
*
|
||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* This file is derived from nuttx/arch/avr/src/at32uc3/at32uc3_clkinit.c
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <arch/board/board.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
|
||||
#include "up_internal.h"
|
||||
#include "chip/sam4l_pm.h"
|
||||
#include "chip/sam4l_flashcalw.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#if defined(SAM_CLOCK_OSC0) || \
|
||||
(defined (SAM_CLOCK_PLL0) && defined(SAM_CLOCK_PLL0_OSC0)) || \
|
||||
(defined (SAM_CLOCK_PLL1) && defined(SAM_CLOCK_PLL1_OSC0))
|
||||
# define NEED_OSC0
|
||||
#endif
|
||||
|
||||
#if defined(SAM_CLOCK_OSC1) || \
|
||||
(defined (SAM_CLOCK_PLL0) && defined(SAM_CLOCK_PLL0_OSC1)) || \
|
||||
(defined (SAM_CLOCK_PLL1) && defined(SAM_CLOCK_PLL1_OSC1))
|
||||
# define NEED_OSC1
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enableosc32
|
||||
*
|
||||
* Description:
|
||||
* Initialiaze the 32KHz oscillaor. This oscillaor is used by the RTC
|
||||
* logic to provide the sysem timer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef SAM_CLOCK_OSC32
|
||||
static inline void up_enableosc32(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Select the 32KHz oscillator crystal */
|
||||
|
||||
regval = getreg32(SAM_PM_OSCCTRL32);
|
||||
regval &= ~PM_OSCCTRL32_MODE_MASK;
|
||||
regval |= PM_OSCCTRL32_MODE_XTAL;
|
||||
putreg32(regval, SAM_PM_OSCCTRL32);
|
||||
|
||||
/* Enable the 32-kHz clock */
|
||||
|
||||
regval = getreg32(SAM_PM_OSCCTRL32);
|
||||
regval &= ~PM_OSCCTRL32_STARTUP_MASK;
|
||||
regval |= PM_OSCCTRL32_EN|(SAM_OSC32STARTUP << PM_OSCCTRL32_STARTUP_SHIFT);
|
||||
putreg32(regval, SAM_PM_OSCCTRL32);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enableosc0
|
||||
*
|
||||
* Description:
|
||||
* Initialiaze OSC0 settings per the definitions in the board.h file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NEED_OSC0
|
||||
static inline void up_enableosc0(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable OSC0 in the correct crystal mode by setting the mode value in OSCCTRL0 */
|
||||
|
||||
regval = getreg32(SAM_PM_OSCCTRL0);
|
||||
regval &= ~PM_OSCCTRL_MODE_MASK;
|
||||
#if SAM_FOSC0 < 900000
|
||||
regval |= PM_OSCCTRL_MODE_XTALp9; /* Crystal XIN 0.4-0.9MHz */
|
||||
#elif SAM_FOSC0 < 3000000
|
||||
regval |= PM_OSCCTRL_MODE_XTAL3; /* Crystal XIN 0.9-3.0MHz */
|
||||
#elif SAM_FOSC0 < 8000000
|
||||
regval |= PM_OSCCTRL_MODE_XTAL8; /* Crystal XIN 3.0-8.0MHz */
|
||||
#else
|
||||
regval |= PM_OSCCTRL_MODE_XTALHI; /* Crystal XIN above 8.0MHz */
|
||||
#endif
|
||||
putreg32(regval, SAM_PM_OSCCTRL0);
|
||||
|
||||
/* Enable OSC0 using the startup time provided in board.h. This startup time
|
||||
* is critical and depends on the characteristics of the crystal.
|
||||
*/
|
||||
|
||||
regval = getreg32(SAM_PM_OSCCTRL0);
|
||||
regval &= ~PM_OSCCTRL_STARTUP_MASK;
|
||||
regval |= (SAM_OSC0STARTUP << PM_OSCCTRL_STARTUP_SHIFT);
|
||||
putreg32(regval, SAM_PM_OSCCTRL0);
|
||||
|
||||
/* Enable OSC0 */
|
||||
|
||||
regval = getreg32(SAM_PM_MCCTRL);
|
||||
regval |= PM_MCCTRL_OSC0EN;
|
||||
putreg32(regval, SAM_PM_MCCTRL);
|
||||
|
||||
/* Wait for OSC0 to be ready */
|
||||
|
||||
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_OSC0RDY) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enableosc1
|
||||
*
|
||||
* Description:
|
||||
* Initialiaze OSC0 settings per the definitions in the board.h file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef NEED_OSC1
|
||||
static inline void up_enableosc1(void)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Enable OSC1 in the correct crystal mode by setting the mode value in OSCCTRL1 */
|
||||
|
||||
regval = getreg32(SAM_PM_OSCCTRL1);
|
||||
regval &= ~PM_OSCCTRL_MODE_MASK;
|
||||
#if SAM_FOSC1 < 900000
|
||||
regval |= PM_OSCCTRL_MODE_XTALp9; /* Crystal XIN 0.4-0.9MHz */
|
||||
#elif SAM_FOSC1 < 3000000
|
||||
regval |= PM_OSCCTRL_MODE_XTAL3; /* Crystal XIN 0.9-3.0MHz */
|
||||
#elif SAM_FOSC1 < 8000000
|
||||
regval |= PM_OSCCTRL_MODE_XTAL8; /* Crystal XIN 3.0-8.0MHz */
|
||||
#else
|
||||
regval |= PM_OSCCTRL_MODE_XTALHI; /* Crystal XIN above 8.0MHz */
|
||||
#endif
|
||||
putreg32(regval, SAM_PM_OSCCTRL1);
|
||||
|
||||
/* Enable OSC1 using the startup time provided in board.h. This startup time
|
||||
* is critical and depends on the characteristics of the crystal.
|
||||
*/
|
||||
|
||||
regval = getreg32(SAM_PM_OSCCTRL1);
|
||||
regval &= ~PM_OSCCTRL_STARTUP_MASK;
|
||||
regval |= (SAM_OSC1STARTUP << PM_OSCCTRL_STARTUP_SHIFT);
|
||||
putreg32(regval, SAM_PM_OSCCTRL1);
|
||||
|
||||
/* Enable OSC1 */
|
||||
|
||||
regval = getreg32(SAM_PM_MCCTRL);
|
||||
regval |= PM_MCCTRL_OSC1EN;
|
||||
putreg32(regval, SAM_PM_MCCTRL);
|
||||
|
||||
/* Wait for OSC1 to be ready */
|
||||
|
||||
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_OSC1RDY) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enablepll0
|
||||
*
|
||||
* Description:
|
||||
* Initialiaze PLL0 settings per the definitions in the board.h file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef SAM_CLOCK_PLL0
|
||||
static inline void up_enablepll0(void)
|
||||
{
|
||||
/* Setup PLL0 */
|
||||
|
||||
regval = (SAM_PLL0_DIV << PM_PLL_PLLDIV_SHIFT) | (SAM_PLL0_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
|
||||
|
||||
/* Select PLL0/1 oscillator */
|
||||
|
||||
#if SAM_CLOCK_PLL_OSC1
|
||||
regval |= PM_PLL_PLLOSC;
|
||||
#endif
|
||||
|
||||
putreg32(regval, SAM_PM_PLL0);
|
||||
|
||||
/* Set PLL0 options */
|
||||
|
||||
regval = getreg32(SAM_PM_PLL0);
|
||||
regval &= ~PM_PLL_PLLOPT_MASK
|
||||
#if SAM_PLL0_FREQ < 160000000
|
||||
regval |= PM_PLL_PLLOPT_VCO;
|
||||
#endif
|
||||
#if SAM_PLL0_DIV2 != 0
|
||||
regval |= PM_PLL_PLLOPT_XTRADIV;
|
||||
#endif
|
||||
#if SAM_PLL0_WBWM != 0
|
||||
regval |= PM_PLL_PLLOPT_WBWDIS;
|
||||
#endif
|
||||
putreg32(regval, SAM_PM_PLL0)
|
||||
|
||||
/* Enable PLL0 */
|
||||
|
||||
regval = getreg32(SAM_PM_PLL0);
|
||||
regval |= PM_PLL_PLLEN;
|
||||
putreg32(regval, SAM_PM_PLL0)
|
||||
|
||||
/* Wait for PLL0 locked. */
|
||||
|
||||
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_LOCK0) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_enablepll1
|
||||
*
|
||||
* Description:
|
||||
* Initialiaze PLL1 settings per the definitions in the board.h file.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef SAM_CLOCK_PLL1
|
||||
static inline void up_enablepll1(void)
|
||||
{
|
||||
/* Setup PLL1 */
|
||||
|
||||
regval = (SAM_PLL1_DIV << PM_PLL_PLLDIV_SHIFT) | (SAM_PLL1_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
|
||||
|
||||
/* Select PLL0/1 oscillator */
|
||||
|
||||
#if SAM_CLOCK_PLL_OSC1
|
||||
regval |= PM_PLL_PLLOSC;
|
||||
#endif
|
||||
|
||||
putreg32(regval, SAM_PM_PLL1);
|
||||
|
||||
/* Set PLL1 options */
|
||||
|
||||
regval = getreg32(SAM_PM_PLL1);
|
||||
regval &= ~PM_PLL_PLLOPT_MASK
|
||||
#if SAM_PLL1_FREQ < 160000000
|
||||
regval |= PM_PLL_PLLOPT_VCO;
|
||||
#endif
|
||||
#if SAM_PLL1_DIV2 != 0
|
||||
regval |= PM_PLL_PLLOPT_XTRADIV;
|
||||
#endif
|
||||
#if SAM_PLL1_WBWM != 0
|
||||
regval |= PM_PLL_PLLOPT_WBWDIS;
|
||||
#endif
|
||||
putreg32(regval, SAM_PM_PLL1)
|
||||
|
||||
/* Enable PLL1 */
|
||||
|
||||
regval = getreg32(SAM_PM_PLL1);
|
||||
regval |= PM_PLL_PLLEN;
|
||||
putreg32(regval, SAM_PM_PLL1)
|
||||
|
||||
/* Wait for PLL1 locked. */
|
||||
|
||||
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_LOCK1) == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_clksel
|
||||
*
|
||||
* Description:
|
||||
* Configure derived clocks.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_clksel(void)
|
||||
{
|
||||
uint32_t regval = 0;
|
||||
|
||||
#if SAM_CKSEL_CPUDIV != 0
|
||||
regval |= PM_CKSEL_CPUDIV;
|
||||
regval |= (SAM_CKSEL_CPUDIV << PM_CKSEL_CPUSEL_SHIFT)
|
||||
#endif
|
||||
|
||||
#if SAM_CKSEL_HSBDIV != 0
|
||||
regval |= PM_CKSEL_HSBDIV;
|
||||
regval |= (SAM_CKSEL_HSBDIV << PM_CKSEL_HSBSEL_SHIFT)
|
||||
#endif
|
||||
|
||||
#if SAM_CKSEL_PBADIV != 0
|
||||
regval |= PM_CKSEL_PBADIV;
|
||||
regval |= (SAM_CKSEL_PBADIV << PM_CKSEL_PBASEL_SHIFT)
|
||||
#endif
|
||||
|
||||
#if SAM_CKSEL_PBBDIV != 0
|
||||
regval |= PM_CKSEL_PBBDIV;
|
||||
regval |= (SAM_CKSEL_PBBDIV << PM_CKSEL_PBBSEL_SHIFT)
|
||||
#endif
|
||||
|
||||
putreg32(regval, SAM_PM_CKSEL);
|
||||
|
||||
/* Wait for CLKRDY */
|
||||
|
||||
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_CKRDY) == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_fws
|
||||
*
|
||||
* Description:
|
||||
* Setup FLASH wait states.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void up_fws(uint32_t cpuclock)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = getreg32(SAM_FLASHCALW_FCR);
|
||||
if (cpuclock > SAM_FLASHCALW_FWS0_MAXFREQ)
|
||||
{
|
||||
regval |= FLASHCALW_FCR_FWS;
|
||||
}
|
||||
else
|
||||
{
|
||||
regval &= ~FLASHCALW_FCR_FWS;
|
||||
}
|
||||
putreg32(regval, SAM_FLASHCALW_FCR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_mainclk
|
||||
*
|
||||
* Description:
|
||||
* Select the main clock.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void up_mainclk(uint32_t mcsel)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = getreg32(SAM_PM_MCCTRL);
|
||||
regval &= ~PM_MCCTRL_MCSEL_MASK;
|
||||
regval |= mcsel;
|
||||
putreg32(regval, SAM_PM_MCCTRL);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_usbclock
|
||||
*
|
||||
* Description:
|
||||
* Setup the USBB GCLK.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_USBDEV
|
||||
static inline void up_usbclock(void)
|
||||
{
|
||||
uint32_t regval = 0;
|
||||
|
||||
#if defined(SAM_CLOCK_USB_PLL0) || defined(SAM_CLOCK_USB_PLL1)
|
||||
regval |= PM_GCCTRL_PLLSEL;
|
||||
#endif
|
||||
#if defined(SAM_CLOCK_USB_OSC1) || defined(SAM_CLOCK_USB_PLL1)
|
||||
regval |= PM_GCCTRL_OSCSEL;
|
||||
#endif
|
||||
#if SAM_CLOCK_USB_DIV > 0
|
||||
|
||||
|
||||
u_avr32_pm_gcctrl.GCCTRL.diven = diven;
|
||||
u_avr32_pm_gcctrl.GCCTRL.div = div;
|
||||
#endif
|
||||
putreg32(regval, SAM_PM_GCCTRL(SAM_PM_GCLK_USBB))
|
||||
|
||||
/* Enable USB GCLK */
|
||||
|
||||
regval = getreg32(SAM_PM_GCCTRL(SAM_PM_GCLK_USBB))
|
||||
regval |= PM_GCCTRL_CEN;
|
||||
putreg32(regval, SAM_PM_GCCTRL(SAM_PM_GCLK_USBB))
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_clockconfig
|
||||
*
|
||||
* Description:
|
||||
* Called to initialize the SAM3/4. This does whatever setup is needed to
|
||||
* put the SoC in a usable state. This includes the initialization of
|
||||
* clocking using the settings in board.h.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sam_clockconfig(void)
|
||||
{
|
||||
#ifdef SAM_CLOCK_OSC32
|
||||
/* Enable the 32KHz oscillator (need by the RTC module) */
|
||||
|
||||
up_enableosc32();
|
||||
#endif
|
||||
|
||||
#ifdef NEED_OSC0
|
||||
/* Enable OSC0 using the settings in board.h */
|
||||
|
||||
up_enableosc0();
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
|
||||
up_fws(SAM_FOSC0);
|
||||
|
||||
/* Then switch the main clock to OSC0 */
|
||||
|
||||
up_mainclk(PM_MCCTRL_MCSEL_OSC0);
|
||||
#endif
|
||||
|
||||
#ifdef NEED_OSC1
|
||||
/* Enable OSC1 using the settings in board.h */
|
||||
|
||||
up_enableosc1();
|
||||
#endif
|
||||
|
||||
#ifdef SAM_CLOCK_PLL0
|
||||
/* Enable PLL0 using the settings in board.h */
|
||||
|
||||
up_enablepll0();
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
|
||||
up_fws(SAM_CPU_CLOCK);
|
||||
|
||||
/* Then switch the main clock to PLL0 */
|
||||
|
||||
up_mainclk(PM_MCCTRL_MCSEL_PLL0);
|
||||
#endif
|
||||
|
||||
#ifdef SAM_CLOCK_PLL1
|
||||
/* Enable PLL1 using the settings in board.h */
|
||||
|
||||
up_enablepll1();
|
||||
#endif
|
||||
|
||||
/* Configure derived clocks */
|
||||
|
||||
up_clksel();
|
||||
|
||||
/* Set up the USBB GCLK */
|
||||
|
||||
#ifdef CONFIG_USBDEV
|
||||
void up_usbclock();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,10 +79,7 @@ extern "C"
|
||||
* Description:
|
||||
* Called to initialize the SAM3/4. This does whatever setup is needed to put the
|
||||
* SoC in a usable state. This includes the initialization of clocking using the
|
||||
* settings in board.h. (After power-on reset, the sam3u is initially running on
|
||||
* a 4MHz internal RC clock). This function also performs other low-level chip
|
||||
* initialization of the chip including EFC, master clock, IRQ and watchdog
|
||||
* configuration.
|
||||
* settings in board.h.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
|
152
mm/README.txt
152
mm/README.txt
@ -3,78 +3,110 @@ mm/README.txt
|
||||
|
||||
This directory contains the NuttX memory management logic. This include:
|
||||
|
||||
1) The standard memory management functions as prototyped in stdlib.h as
|
||||
specified in the Base definitions volume of IEEE Std 1003.1-2001. This
|
||||
include the files:
|
||||
1) Standard Memory Management Functions:
|
||||
|
||||
o Standard Interfaces: mm_malloc.c, mm_calloc.c, mm_realloc.c,
|
||||
The standard memory management functions as prototyped in stdlib.h as
|
||||
specified in the Base definitions volume of IEEE Std 1003.1-2001. This
|
||||
include the files:
|
||||
|
||||
o Standard Interfaces: mm_malloc.c, mm_calloc.c, mm_realloc.c,
|
||||
mm_memalign.c, mm_free.c
|
||||
o Less-Standard Interfaces: mm_zalloc.c, mm_mallinfo.c
|
||||
o Internal Implementation: mm_initialize.c mm_sem.c mm_addfreechunk.c
|
||||
o Less-Standard Interfaces: mm_zalloc.c, mm_mallinfo.c
|
||||
o Internal Implementation: mm_initialize.c mm_sem.c mm_addfreechunk.c
|
||||
mm_size2ndx.c mm_shrinkchunk.c, mm_internal.h
|
||||
o Build and Configuration files: Kconfig, Makefile
|
||||
o Build and Configuration files: Kconfig, Makefile
|
||||
|
||||
Memory Models:
|
||||
|
||||
o Small Memory Model. If the MCU supports only 16-bit data addressing
|
||||
then the small memory model is automatically used. The maximum size
|
||||
of the heap is then 64K. The small memory model can also be forced
|
||||
MCUs with wider addressing by defining CONFIG_SMALL_MEMORY in the
|
||||
NuttX configuration file.
|
||||
o Large Memory Model. Otherwise, the allocator uses a model that
|
||||
supports a heap of up to 4G.
|
||||
o Small Memory Model. If the MCU supports only 16-bit data addressing
|
||||
then the small memory model is automatically used. The maximum size
|
||||
of the heap is then 64K. The small memory model can also be forced
|
||||
MCUs with wider addressing by defining CONFIG_SMALL_MEMORY in the
|
||||
NuttX configuration file.
|
||||
o Large Memory Model. Otherwise, the allocator uses a model that
|
||||
supports a heap of up to 4G.
|
||||
|
||||
This implementation uses a variable length allocator with the following
|
||||
properties:
|
||||
This implementation uses a variable length allocator with the following
|
||||
properties:
|
||||
|
||||
o Overhead: Either 8- or 4-bytes per allocation for large and small
|
||||
models, respectively.
|
||||
o Alignment: All allocations are aligned to 8- or 4-bytes for large
|
||||
and small models, respectively.
|
||||
o Overhead: Either 8- or 4-bytes per allocation for large and small
|
||||
models, respectively.
|
||||
o Alignment: All allocations are aligned to 8- or 4-bytes for large
|
||||
and small models, respectively.
|
||||
|
||||
2) Granule Allocator. A non-standard granule allocator is also available
|
||||
in this directory The granule allocator allocates memory in units
|
||||
of a fixed sized block ("granule"). Allocations may be aligned to a user-
|
||||
provided address boundary.
|
||||
Multiple Heaps:
|
||||
|
||||
The granule allocator interfaces are defined in nuttx/include/nuttx/gran.h.
|
||||
The granule allocator consists of these files in this directory:
|
||||
This allocator can be used to manage multiple heaps (albeit with some
|
||||
non-standard interfaces). A heap is represented by struct mm_heap_s
|
||||
as defined in the file include/nuttx/mm.h. To create another heap
|
||||
instance, you would allocate a heap structure, most likely statically
|
||||
in memory:
|
||||
|
||||
mm_gran.h, mm_granalloc.c, mm_grancritical.c, mm_granfree.c
|
||||
mm_graninit.c
|
||||
include <nuttx/mm.h>
|
||||
static struct mm_heap_s g_myheap;
|
||||
|
||||
The granule allocator is not used anywhere within the base NuttX code
|
||||
as of this writing. The intent of the granule allocator is to provide
|
||||
a tool to support platform-specific management of aligned DMA memory.
|
||||
Then initialize the heap using:
|
||||
|
||||
NOTE: Because each granule may be aligned and each allocation is in
|
||||
units of the granule size, selection of the granule size is important:
|
||||
Larger granules will give better performance and less overhead but more
|
||||
losses of memory due to quantization waste. Additional memory waste
|
||||
can occur from alignment; Of course, heap alignment should no be
|
||||
used unless (a) you are using the granule allocator to manage DMA memory
|
||||
and (b) your hardware has specific memory alignment requirements.
|
||||
mm_initialize(&g_myheap, myheap_start, myheap_size);
|
||||
|
||||
The current implementation also restricts the maximum allocation size
|
||||
to 32 granules. That restriction could be eliminated with some
|
||||
additional coding effort, but currently requires larger granule
|
||||
sizes for larger allocations.
|
||||
Where mm_initialize() and all related interfaces are prototyped in the
|
||||
header file include/nuttx/mm.h.
|
||||
|
||||
Geneneral Usage Example. This is an example using the GCC section
|
||||
attribute to position a DMA heap in memory (logic in the linker script
|
||||
would assign the section .dmaheap to the DMA memory.
|
||||
|
||||
FAR uint32_t g_dmaheap[DMAHEAP_SIZE] __attribute__((section(.dmaheap)));
|
||||
|
||||
The heap is created by calling gran_initialize. Here the granual size
|
||||
is set to 64 bytes and the alignment to 16 bytes:
|
||||
|
||||
GRAN_HANDLE handle = gran_initialize(g_dmaheap, DMAHEAP_SIZE, 6, 4);
|
||||
|
||||
Then the GRAN_HANDLE can be used to allocate memory (There is no
|
||||
GRAN_HANDLE if CONFIG_GRAN_SINGLE=y):
|
||||
|
||||
FAR uint8_t *dma_memory = (FAR uint8_t *)gran_alloc(handle, 47);
|
||||
|
||||
The actual memory allocates will be 64 byte (wasting 17 bytes) and
|
||||
will be aligned at least to (1 << log2align).
|
||||
After the new heap instance has been initialized, it can then be used
|
||||
with these almost familiar interfaces: mm_malloc(), mm_realloc(), mm_free(),
|
||||
etc. These are 'almost familiar' because they are analogous of the
|
||||
standard malloc(), realloc(), free(), etc. except that they expect a
|
||||
reference to the initialized heap structure as the first parameter.
|
||||
|
||||
In fact, the standard malloc(), realloc(), free() use this same mechanism,
|
||||
but with a global heap structure called g_mmheap.
|
||||
|
||||
2) Granule Allocator.
|
||||
|
||||
A non-standard granule allocator is also available in this directory The
|
||||
granule allocator allocates memory in units of a fixed sized block ("granule").
|
||||
Allocations may be aligned to a user-provided address boundary.
|
||||
|
||||
The granule allocator interfaces are defined in nuttx/include/nuttx/gran.h.
|
||||
The granule allocator consists of these files in this directory:
|
||||
|
||||
mm_gran.h, mm_granalloc.c, mm_grancritical.c, mm_granfree.c
|
||||
mm_graninit.c
|
||||
|
||||
The granule allocator is not used anywhere within the base NuttX code
|
||||
as of this writing. The intent of the granule allocator is to provide
|
||||
a tool to support platform-specific management of aligned DMA memory.
|
||||
|
||||
NOTE: Because each granule may be aligned and each allocation is in
|
||||
units of the granule size, selection of the granule size is important:
|
||||
Larger granules will give better performance and less overhead but more
|
||||
losses of memory due to quantization waste. Additional memory waste
|
||||
can occur from alignment; Of course, heap alignment should no be
|
||||
used unless (a) you are using the granule allocator to manage DMA memory
|
||||
and (b) your hardware has specific memory alignment requirements.
|
||||
|
||||
The current implementation also restricts the maximum allocation size
|
||||
to 32 granules. That restriction could be eliminated with some
|
||||
additional coding effort, but currently requires larger granule
|
||||
sizes for larger allocations.
|
||||
|
||||
General Usage Example.
|
||||
|
||||
This is an example using the GCC section attribute to position a DMA
|
||||
heap in memory (logic in the linker script would assign the section
|
||||
.dmaheap to the DMA memory.
|
||||
|
||||
FAR uint32_t g_dmaheap[DMAHEAP_SIZE] __attribute__((section(.dmaheap)));
|
||||
|
||||
The heap is created by calling gran_initialize. Here the granule size
|
||||
is set to 64 bytes and the alignment to 16 bytes:
|
||||
|
||||
GRAN_HANDLE handle = gran_initialize(g_dmaheap, DMAHEAP_SIZE, 6, 4);
|
||||
|
||||
Then the GRAN_HANDLE can be used to allocate memory (There is no
|
||||
GRAN_HANDLE if CONFIG_GRAN_SINGLE=y):
|
||||
|
||||
FAR uint8_t *dma_memory = (FAR uint8_t *)gran_alloc(handle, 47);
|
||||
|
||||
The actual memory allocates will be 64 byte (wasting 17 bytes) and
|
||||
will be aligned at least to (1 << log2align).
|
||||
|
Loading…
Reference in New Issue
Block a user