[BSP] add i.MX 6UL BSP

This commit is contained in:
Bernard Xiong
2017-11-01 13:30:17 +08:00
parent fed0e98160
commit f6170a6e5b
97 changed files with 72741 additions and 4 deletions

26
bsp/imx6ul/KConfig Normal file
View File

@@ -0,0 +1,26 @@
mainmenu "RT-Thread Configuration"
config $BSP_DIR
string
option env="BSP_ROOT"
default "."
config $RTT_DIR
string
option env="RTT_ROOT"
default "../.."
config $PKGS_DIR
string
option env="PKGS_ROOT"
default "packages"
config BOARD_IMX6UL
bool
select ARCH_ARM_CORTEX_A7
default y
source "$RTT_DIR/KConfig"
source "$PKGS_DIR/KConfig"
source "$BSP_DIR/drivers/Kconfig"

10
bsp/imx6ul/Makefile Normal file
View File

@@ -0,0 +1,10 @@
scons:=python ${SCONS}\scons.py
all:
@$(scons)
clean:
@$(scons) -c
copy:
@$(scons) --copy -s

17
bsp/imx6ul/README.md Normal file
View File

@@ -0,0 +1,17 @@
# i.MX6 SoloX
Freescale's Smart Application Blueprint for Rapid Engineering (SABRE) board for smart devices
Rev.B
CPU: MCIMX6X4EVM10AB
* ARM Cortex-A9 @ 1GHz
* ARM Cortex-M4 @ 200MHz
* Freescale PF0200 PMIC
* 1GB DDR3
* 32 MB x2 QuadSPI Flash
* Freescale MMA8451 3-Axis Accelerometer
* Freescale MAG3110 3D Magnetometer

14
bsp/imx6ul/SConscript Normal file
View File

@@ -0,0 +1,14 @@
# for module compiling
import os
Import('RTT_ROOT')
cwd = str(Dir('#'))
objs = []
list = os.listdir(cwd)
for d in list:
path = os.path.join(cwd, d)
if os.path.isfile(os.path.join(path, 'SConscript')):
objs = objs + SConscript(os.path.join(d, 'SConscript'))
Return('objs')

30
bsp/imx6ul/SConstruct Normal file
View File

@@ -0,0 +1,30 @@
import os
import sys
import rtconfig
if os.getenv('RTT_ROOT'):
RTT_ROOT = os.getenv('RTT_ROOT')
else:
RTT_ROOT = os.path.join(os.getcwd(), '..', '..')
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
from building import *
TARGET = 'rtthread-imx6.' + rtconfig.TARGET_EXT
env = Environment(tools = ['mingw'],
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
CXX= rtconfig.CXX, CXXFLAGS = rtconfig.CFLAGS,
AR = rtconfig.AR, ARFLAGS = '-rc',
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
Export('RTT_ROOT')
Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT)
# make a building
DoBuilding(TARGET, objs)

View File

@@ -0,0 +1,11 @@
Import('RTT_ROOT')
Import('rtconfig')
from building import *
cwd = os.path.join(str(Dir('#')), 'applications')
src = Glob('*.c')
CPPPATH = [cwd, str(Dir('#'))]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,45 @@
/*
* File : application.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2012, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2012-11-20 Bernard the first version
*/
#include <rtthread.h>
#include <sdk_version.h>
#include <ccm_pll.h>
void show_freq(void)
{
rt_kprintf("CPU: %d MHz\n", get_main_clock(CPU_CLK)/1000000);
rt_kprintf("DDR: %d MHz\n", get_main_clock(MMDC_CH0_AXI_CLK)/1000000);
rt_kprintf("IPG: %d MHz\n", get_main_clock(IPG_CLK)/1000000);
}
void init_thread(void* parameter)
{
rt_kprintf("Freescale i.MX6 Platform SDK %s\n", SDK_VERSION_STRING);
show_freq();
rt_components_init();
}
int rt_application_init()
{
rt_thread_t tid;
tid = rt_thread_create("init", init_thread, RT_NULL,
1024, RT_THREAD_PRIORITY_MAX/3, 10);
if (tid != RT_NULL) rt_thread_startup(tid);
return 0;
}

View File

@@ -0,0 +1,74 @@
/*
* File : startup.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006, RT-Thread Develop Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2012-12-05 Bernard the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include <board.h>
extern int rt_application_init(void);
extern void rt_hw_board_init(void);
/**
* This function will startup RT-Thread RTOS.
*/
void rtthread_startup(void)
{
// platform_init();
// print_version();
/* initialzie hardware interrupt */
rt_hw_interrupt_init();
/* initialize board */
rt_hw_board_init();
/* show RT-Thread version */
rt_show_version();
/* initialize memory system */
#ifdef RT_USING_HEAP
rt_system_heap_init(HEAP_BEGIN, HEAP_END);
#endif
/* initialize scheduler system */
rt_system_scheduler_init();
/* initialize timer and soft timer thread */
rt_system_timer_init();
rt_system_timer_thread_init();
/* initialize application */
rt_application_init();
/* initialize idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
}
int main(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
/* invoke rtthread_startup */
rtthread_startup();
return 0;
}

View File

View File

@@ -0,0 +1,10 @@
from building import *
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('iomux/*.c')
CPPPATH = [cwd, cwd + '/iomux']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@@ -0,0 +1,79 @@
/*
* File : board.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2016, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2012-11-20 Bernard the first version
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include <registers/regsarmglobaltimer.h>
#include <registers/regsepit.h>
#include <imx_uart.h>
#include <epit.h>
#include <cortex_a.h>
static void rt_hw_timer_isr(int vector, void *param)
{
rt_tick_increase();
epit_get_compare_event(HW_EPIT1);
}
int rt_hw_timer_init(void)
{
uint32_t freq;
// Make sure the timer is off.
HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0;
HW_ARMGLOBALTIMER_CONTROL.B.FCR0 =1;
HW_ARMGLOBALTIMER_CONTROL.B.FCR1 =0;
HW_ARMGLOBALTIMER_CONTROL.B.DBG_ENABLE =0;
// Clear counter.
HW_ARMGLOBALTIMER_COUNTER_HI_WR(0);
HW_ARMGLOBALTIMER_COUNTER_LO_WR(0);
// Now turn on the timer.
HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1;
freq = get_main_clock(IPG_CLK);
epit_init(HW_EPIT1, CLKSRC_IPG_CLK, freq / 1000000,
SET_AND_FORGET, 10000, WAIT_MODE_EN | STOP_MODE_EN);
epit_counter_enable(HW_EPIT1, 10000, IRQ_MODE);
rt_hw_interrupt_install(IMX_INT_EPIT1, rt_hw_timer_isr, RT_NULL, "tick");
rt_hw_interrupt_umask(IMX_INT_EPIT1);
return 0;
}
INIT_BOARD_EXPORT(rt_hw_timer_init);
/**
* This function will initialize hardware board
*/
void rt_hw_board_init(void)
{
enable_neon_fpu();
disable_strict_align_check();
rt_components_board_init();
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
}
/*@}*/

View File

@@ -0,0 +1,36 @@
/*
* File : board.h
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2013, RT-Thread Development Team
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rt-thread.org/license/LICENSE
*
* Change Logs:
* Date Author Notes
* 2013-07-06 Bernard the first version
*/
#ifndef __BOARD_H__
#define __BOARD_H__
#include <registers.h>
#include <irq_numbers.h>
#define CONFIG_MX6
#define CONFIG_MX6UL
#if defined(__CC_ARM)
extern int Image$$RW_IRAM1$$ZI$$Limit;
#define HEAP_BEGIN ((void*)&Image$$RW_IRAM1$$ZI$$Limit)
#elif defined(__GNUC__)
extern int __bss_end;
#define HEAP_BEGIN ((void*)&__bss_end)
#endif
#define HEAP_END (void*)(0x80000000 + 32 * 1024 * 1024)
void rt_hw_board_init(void);
#endif

View File

@@ -0,0 +1,36 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* 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 HOLDER 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.
*/
// File: iomux_config.c
/* ------------------------------------------------------------------------------
* <auto-generated>
* This code was generated by a tool.
* Runtime Version:3.4.0.0
*
* Changes to this file may cause incorrect behavior and will be lost if
* the code is regenerated.
* </auto-generated>
* ------------------------------------------------------------------------------
*/
#include "iomux_config.h"
// Function to configure iomux for i.MX6SL board MCIMX6SLEVK rev. B.
void iomux_config(void)
{
uart1_iomux_config();
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* 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 HOLDER 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.
*/
// File: iomux_config.h
/* ------------------------------------------------------------------------------
* <auto-generated>
* This code was generated by a tool.
* Runtime Version:3.4.0.0
*
* Changes to this file may cause incorrect behavior and will be lost if
* the code is regenerated.
* </auto-generated>
* ------------------------------------------------------------------------------
*/
#ifndef _IOMUX_CONFIG_H_
#define _IOMUX_CONFIG_H_
// Board and Module IOMUXC configuration function prototypes.
#if defined(__cplusplus)
extern "C" {
#endif
// Board IOMUXC configuration function.
void iomux_config(void);
// Module IOMUXC configuration functions.
void uart1_iomux_config(void);
#if defined(__cplusplus)
}
#endif
#endif // _IOMUX_CONFIG_H_

View File

@@ -0,0 +1,109 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* 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 HOLDER 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.
*/
// File: uart_iomux_config.c
/* ------------------------------------------------------------------------------
* <auto-generated>
* This code was generated by a tool.
* Runtime Version:3.4.0.0
*
* Changes to this file may cause incorrect behavior and will be lost if
* the code is regenerated.
* </auto-generated>
* ------------------------------------------------------------------------------
*/
#include "iomux_config.h"
#include "registers/regsuart.h"
#include "iomux_register.h"
#include "io.h"
#include <assert.h>
#define MX6UL_PAD_UART1_TX_DATA__UART1_TX1 (IOMUXC_BASE_ADDR+0x084)
#define MX6UL_PAD_UART1_RX_DATA__UART1_RX1 (IOMUXC_BASE_ADDR+0x088)
#define IOMUXC_UART1_UART_RXD_MUX_SELECT_INPUT1 (IOMUXC_BASE_ADDR+0x624)
void uart1_iomux_config(void)
{
/* UART1 TXD */
MX6UL_PAD_UART1_TX_DATA__UART1_TX(0x10b0);
/* UART1 RXD */
MX6UL_PAD_UART1_RX_DATA__UART1_RX(0x10b0);
}
void uart2_iomux_config(void)
{
}
void uart3_iomux_config(void)
{
}
void uart4_iomux_config(void)
{
}
void uart5_iomux_config(void)
{
}
void uart6_iomux_config(void)
{
}
void uart7_iomux_config(void)
{
}
void uart8_iomux_config(void)
{
}
void uart_iomux_config(int instance)
{
switch (instance)
{
case HW_UART1:
return uart1_iomux_config();
case HW_UART2:
return uart2_iomux_config();
case HW_UART3:
return uart3_iomux_config();
case HW_UART4:
return uart4_iomux_config();
case HW_UART5:
return uart5_iomux_config();
case HW_UART6:
return uart5_iomux_config();
case HW_UART7:
return uart5_iomux_config();
case HW_UART8:
return uart5_iomux_config();
default:
assert(false);
}
}

202
bsp/imx6ul/drivers/serial.c Normal file
View File

@@ -0,0 +1,202 @@
/*
* serial.c UART driver
*
* COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd
*
* This file is part of RT-Thread (http://www.rt-thread.org)
* Maintainer: bernard.xiong <bernard.xiong at gmail.com>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion
*/
#include <rthw.h>
#include <registers/regsuart.h>
#include <imx_uart.h>
#include <rtdevice.h>
#include "serial.h"
struct hw_uart_device
{
uint32_t instance;
int irqno;
};
static void rt_hw_uart_isr(int irqno, void *param)
{
struct rt_serial_device *serial = (struct rt_serial_device *)param;
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
}
static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
struct hw_uart_device *uart;
uint32_t baudrate;
uint8_t parity, stopbits, datasize, flowcontrol;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
baudrate = cfg->baud_rate;
switch (cfg->data_bits)
{
case DATA_BITS_8:
datasize = EIGHTBITS;
break;
case DATA_BITS_7:
datasize = SEVENBITS;
break;
}
if (cfg->stop_bits == STOP_BITS_1) stopbits = STOPBITS_ONE;
else if (cfg->stop_bits == STOP_BITS_2) stopbits = STOPBITS_TWO;
parity = PARITY_NONE;
flowcontrol = FLOWCTRL_OFF;
/* Initialize UART */
uart_init(uart->instance, baudrate, parity, stopbits, datasize, flowcontrol);
rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, "uart");
rt_hw_interrupt_mask(uart->irqno);
/* Set the IRQ mode for the Rx FIFO */
uart_set_FIFO_mode(uart->instance, RX_FIFO, 1, IRQ_MODE);
return RT_EOK;
}
static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
struct hw_uart_device *uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
/* disable rx irq */
rt_hw_interrupt_mask(uart->irqno);
break;
case RT_DEVICE_CTRL_SET_INT:
/* enable rx irq */
rt_hw_interrupt_umask(uart->irqno);
break;
}
return RT_EOK;
}
static int uart_putc(struct rt_serial_device *serial, char c)
{
struct hw_uart_device *uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
uart_putchar(uart->instance, (uint8_t*)&c);
return 1;
}
static int uart_getc(struct rt_serial_device *serial)
{
int ch;
struct hw_uart_device *uart;
RT_ASSERT(serial != RT_NULL);
uart = (struct hw_uart_device *)serial->parent.user_data;
ch = uart_getchar(uart->instance);
if (ch == NONE_CHAR) ch = -1;
return ch;
}
static const struct rt_uart_ops _uart_ops =
{
uart_configure,
uart_control,
uart_putc,
uart_getc,
};
#ifdef RT_USING_UART0
/* UART device driver structure */
static struct hw_uart_device _uart0_device =
{
HW_UART0,
IMX_INT_UART0
};
static struct rt_serial_device _serial0;
#endif
#ifdef RT_USING_UART1
/* UART1 device driver structure */
static struct hw_uart_device _uart1_device =
{
HW_UART1,
IMX_INT_UART1
};
static struct rt_serial_device _serial1;
#endif
int rt_hw_uart_init(void)
{
struct hw_uart_device *uart;
struct serial_configure config;
config.baud_rate = BAUD_RATE_115200;
config.bit_order = BIT_ORDER_LSB;
config.data_bits = DATA_BITS_8;
config.parity = PARITY_NONE;
config.stop_bits = STOP_BITS_1;
config.invert = NRZ_NORMAL;
config.bufsz = RT_SERIAL_RB_BUFSZ;
#ifdef RT_USING_UART0
uart = &_uart0_device;
_serial0.ops = &_uart_ops;
_serial0.config = config;
/* register UART1 device */
rt_hw_serial_register(&_serial0, "uart0",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart);
#endif
#ifdef RT_USING_UART1
uart = &_uart1_device;
_serial1.ops = &_uart_ops;
_serial1.config = config;
/* register UART1 device */
rt_hw_serial_register(&_serial1, "uart1",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart);
#endif
return 0;
}
INIT_BOARD_EXPORT(rt_hw_uart_init);

View File

@@ -0,0 +1,39 @@
/*
* UART driver
*
* COPYRIGHT (C) 2013, Shanghai Real-Thread Technology Co., Ltd
*
* This file is part of RT-Thread (http://www.rt-thread.org)
* Maintainer: bernard.xiong <bernard.xiong at gmail.com>
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Change Logs:
* Date Author Notes
* 2013-03-30 Bernard the first verion
*/
#ifndef __UART_H__
#define __UART_H__
#include <board.h>
int rt_hw_uart_init(void);
#endif

99
bsp/imx6ul/imx6.lds Normal file
View File

@@ -0,0 +1,99 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
SECTIONS
{
. = 0x80100000;
__text_start = .;
.text :
{
*(.vectors)
*(.text)
*(.text.*)
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
. = ALIGN(4);
/* section information for modules */
. = ALIGN(4);
__rtmsymtab_start = .;
KEEP(*(RTMSymTab))
__rtmsymtab_end = .;
/* section information for initialization */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
} =0
__text_end = .;
__rodata_start = .;
.rodata : { *(.rodata) *(.rodata.*) }
__rodata_end = .;
. = ALIGN(4);
.ctors :
{
PROVIDE(__ctors_start__ = .);
KEEP(*(SORT(.ctors.*)))
KEEP(*(.ctors))
PROVIDE(__ctors_end__ = .);
}
.dtors :
{
PROVIDE(__dtors_start__ = .);
KEEP(*(SORT(.dtors.*)))
KEEP(*(.dtors))
PROVIDE(__dtors_end__ = .);
}
. = ALIGN(16 * 1024);
.l1_page_table :
{
__l1_page_table_start = .;
. += 16K;
}
__data_start = .;
. = ALIGN(4);
.data :
{
*(.data)
*(.data.*)
}
__data_end = .;
. = ALIGN(4);
__bss_start = __data_end;
.bss :
{
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(4);
}
. = ALIGN(4);
__bss_end = .;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
_end = .;
}

View File

@@ -0,0 +1,26 @@
from building import *
cwd = GetCurrentDir()
src = Split('''
drivers/epit.c
drivers/gpt.c
drivers/imx_timer.c
drivers/imx_i2c.c
drivers/imx_uart.c
cpu/armv7_cache.c
cpu/gic.c
cpu/ccm_pll2.c
cpu/mmu.c
cpu/cortex_a_gcc.S
''')
CPPPATH = [ cwd + '/cpu',
cwd + '/include',
cwd + '/include/mx6ul',
cwd + '/include/mx6ul/registers'
]
CPPDEFINES = ['CHIP_MX6UL']
group = DefineGroup('Platform', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)
Return('group')

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
//! @addtogroup cortexa9
//! @{
/*!
* @file arm_cp_registers.h
* @brief Definitions for ARM coprocessor registers.
*/
#ifndef __ARM_CP_REGISTERS_H__
#define __ARM_CP_REGISTERS_H__
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @name ACTLR
//@{
#define BM_ACTLR_SMP (1 << 6)
//@}
//! @name DFSR
//@{
#define BM_DFSR_WNR (1 << 11) //!< Write not Read bit. 0=read, 1=write.
#define BM_DFSR_FS4 (0x400) //!< Fault status bit 4..
#define BP_DFSR_FS4 (10) //!< Bit position for FS[4].
#define BM_DFSR_FS (0xf) //!< Fault status bits [3:0].
//@}
//! @name SCTLR
//@{
#define BM_SCTLR_TE (1 << 30) //!< Thumb exception enable.
#define BM_SCTLR_AFE (1 << 29) //!< Access flag enable.
#define BM_SCTLR_TRE (1 << 28) //!< TEX remap enable.
#define BM_SCTLR_NMFI (1 << 27) //!< Non-maskable FIQ support.
#define BM_SCTLR_EE (1 << 25) //!< Exception endianess.
#define BM_SCTLR_VE (1 << 24) //!< Interrupt vectors enable.
#define BM_SCTLR_FI (1 << 21) //!< Fast interrupt configurable enable.
#define BM_SCTLR_RR (1 << 14) //!< Round Robin
#define BM_SCTLR_V (1 << 13) //!< Vectors
#define BM_SCTLR_I (1 << 12) //!< Instruction cache enable
#define BM_SCTLR_Z (1 << 11) //!< Branch prediction enable
#define BM_SCTLR_SW (1 << 10) //!< SWP and SWPB enable
#define BM_SCTLR_CP15BEN (1 << 5) //!< CP15 barrier enable
#define BM_SCTLR_C (1 << 2) //!< Data cache enable
#define BM_SCTLR_A (1 << 1) //!< Alignment check enable
#define BM_SCTLR_M (1 << 0) //!< MMU enable
//@}
//! @}
#endif // __ARM_CP_REGISTERS_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,348 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
#include "cortex_a.h"
#include "arm_cp_registers.h"
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
//! @brief Check if dcache is enabled or disabled
int arm_dcache_state_query()
{
uint32_t sctlr; // System Control Register
// read sctlr
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
if (sctlr & BM_SCTLR_C)
{
return 1;
}
return 0;
}
void arm_dcache_enable()
{
uint32_t sctlr; // System Control Register
// read sctlr
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
if (!(sctlr & BM_SCTLR_C))
{
// set C bit (data caching enable)
sctlr |= BM_SCTLR_C;
// write modified sctlr
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
}
void arm_dcache_disable()
{
uint32_t sctlr; // System Control Register
// read sctlr
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
// set C bit (data caching enable)
sctlr &= ~BM_SCTLR_C;
// write modified sctlr
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
void arm_dcache_invalidate()
{
uint32_t csid; // Cache Size ID
uint32_t wayset; // wayset parameter
int num_sets; // number of sets
int num_ways; // number of ways
_ARM_MRC(15, 1, csid, 0, 0, 0); // Read Cache Size ID
// Fill number of sets and number of ways from csid register This walues are decremented by 1
num_ways = (csid >> 0x03) & 0x3FFu; //((csid& csid_ASSOCIATIVITY_MASK) >> csid_ASSOCIATIVITY_SHIFT)
// Invalidation all lines (all Sets in all ways)
while (num_ways >= 0)
{
num_sets = (csid >> 0x0D) & 0x7FFFu; //((csid & csid_NUMSETS_MASK) >> csid_NUMSETS_SHIFT)
while (num_sets >= 0 )
{
wayset = (num_sets << 5u) | (num_ways << 30u); //(num_sets << SETWAY_SET_SHIFT) | (num_sets << 3SETWAY_WAY_SHIFT)
// invalidate line if we know set and way
_ARM_MCR(15, 0, wayset, 7, 6, 2);
num_sets--;
}
num_ways--;
}
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
void arm_dcache_invalidate_line(const void * addr)
{
uint32_t csidr = 0, line_size = 0;
uint32_t va;
// get the cache line size
_ARM_MRC(15, 1, csidr, 0, 0, 0);
line_size = 1 << ((csidr & 0x7) + 4);
va = (uint32_t) addr & (~(line_size - 1)); //addr & va_VIRTUAL_ADDRESS_MASK
// Invalidate data cache line by va to PoC (Point of Coherency).
_ARM_MCR(15, 0, va, 7, 6, 1);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
void arm_dcache_invalidate_mlines(const void * addr, size_t length)
{
uint32_t va;
uint32_t csidr = 0, line_size = 0;
// get the cache line size
_ARM_MRC(15, 1, csidr, 0, 0, 0);
line_size = 1 << ((csidr & 0x7) + 4);
// align the address with line
const void * end_addr = (const void *)((uint32_t)addr + length);
do
{
// Clean data cache line to PoC (Point of Coherence) by va.
va = (uint32_t) ((uint32_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK
_ARM_MCR(15, 0, va, 7, 6, 1);
// increment addres to next line and decrement lenght
addr = (const void *) ((uint32_t)addr + line_size);
} while (addr < end_addr);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
void arm_dcache_flush()
{
uint32_t csid; // Cache Size ID
uint32_t wayset; // wayset parameter
int num_sets; // number of sets
int num_ways; // number of ways
_ARM_MRC(15, 1, csid, 0, 0, 0); // Read Cache Size ID
// Fill number of sets and number of ways from csid register This walues are decremented by 1
num_ways = (csid >> 0x03) & 0x3FFu; //((csid& csid_ASSOCIATIVITY_MASK) >> csid_ASSOCIATIVITY_SHIFT`)
while (num_ways >= 0)
{
num_sets = (csid >> 0x0D) & 0x7FFFu; //((csid & csid_NUMSETS_MASK) >> csid_NUMSETS_SHIFT )
while (num_sets >= 0 )
{
wayset = (num_sets << 5u) | (num_ways << 30u); //(num_sets << SETWAY_SET_SHIFT) | (num_ways << 3SETWAY_WAY_SHIFT)
// FLUSH (clean) line if we know set and way
_ARM_MCR(15, 0, wayset, 7, 10, 2);
num_sets--;
}
num_ways--;
}
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
void arm_dcache_flush_line(const void * addr)
{
uint32_t csidr = 0, line_size = 0;
uint32_t va;
// get the cache line size
_ARM_MRC(15, 1, csidr, 0, 0, 0);
line_size = 1 << ((csidr & 0x7) + 4);
va = (uint32_t) addr & (~(line_size - 1)); //addr & va_VIRTUAL_ADDRESS_MASK
// Clean data cache line to PoC (Point of Coherence) by va.
_ARM_MCR(15, 0, va, 7, 10, 1);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
void arm_dcache_flush_mlines(const void * addr, size_t length)
{
uint32_t va;
uint32_t csidr = 0, line_size = 0;
const void * end_addr = (const void *)((uint32_t)addr + length);
// get the cache line size
_ARM_MRC(15, 1, csidr, 0, 0, 0);
line_size = 1 << ((csidr & 0x7) + 4);
do
{
// Clean data cache line to PoC (Point of Coherence) by va.
va = (uint32_t) ((uint32_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK
_ARM_MCR(15, 0, va, 7, 10, 1);
// increment addres to next line and decrement lenght
addr = (const void *) ((uint32_t)addr + line_size);
} while (addr < end_addr);
// All Cache, Branch predictor and TLB maintenance operations before followed instruction complete
_ARM_DSB();
}
int arm_icache_state_query()
{
uint32_t sctlr; // System Control Register
// read sctlr
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
if (sctlr & BM_SCTLR_I)
{
return 1;
}
return 0;
}
void arm_icache_enable()
{
uint32_t sctlr ;// System Control Register
// read sctlr
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
// ignore the operation if I is enabled already
if(!(sctlr & BM_SCTLR_I))
{
// set I bit (instruction caching enable)
sctlr |= BM_SCTLR_I;
// write modified sctlr
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
// synchronize context on this processor
_ARM_ISB();
}
}
void arm_icache_disable()
{
uint32_t sctlr ;// System Control Register
// read sctlr
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
// Clear I bit (instruction caching enable)
sctlr &= ~BM_SCTLR_I;
// write modified sctlr
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
// synchronize context on this processor
_ARM_ISB();
}
void arm_icache_invalidate()
{
uint32_t SBZ = 0x0u;
_ARM_MCR(15, 0, SBZ, 7, 5, 0);
// synchronize context on this processor
_ARM_ISB();
}
void arm_icache_invalidate_is()
{
uint32_t SBZ = 0x0u;
_ARM_MCR(15, 0, SBZ, 7, 1, 0);
// synchronize context on this processor
_ARM_ISB();
}
void arm_icache_invalidate_line(const void * addr)
{
uint32_t csidr = 0, line_size = 0;
uint32_t va;
// get the cache line size
_ARM_MRC(15, 1, csidr, 0, 0, 0);
line_size = 1 << ((csidr & 0x7) + 4);
va = (uint32_t) addr & (~(line_size - 1)); //addr & va_VIRTUAL_ADDRESS_MASK
// Invalidate instruction cache by va to PoU (Point of unification).
_ARM_MCR(15, 0, va, 7, 5, 1);
// synchronize context on this processor
_ARM_ISB();
}
void arm_icache_invalidate_mlines(const void * addr, size_t length)
{
uint32_t va;
uint32_t csidr = 0, line_size = 0;
const void * end_addr = (const void *)((uint32_t)addr + length);
// get the cache line size
_ARM_MRC(15, 1, csidr, 0, 0, 0);
line_size = 1 << ((csidr & 0x7) + 4);
do
{
// Clean data cache line to PoC (Point of Coherence) by va.
va = (uint32_t) ((uint32_t)addr & (~(line_size - 1))); //addr & va_VIRTUAL_ADDRESS_MASK
_ARM_MCR(15, 0, va, 7, 5, 1);
// increment addres to next line and decrement lenght
addr = (const void *) ((uint32_t)addr + line_size);
} while (addr < end_addr);
// synchronize context on this processor
_ARM_ISB();
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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 _CCM_PLL_H_
#define _CCM_PLL_H_
#include "sdk_types.h"
//! @addtogroup diag_clocks
//! @{
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
#define CLK_SRC_32K 32768
//! @brief Create a clock gate bit mask value.
//! @param x 0..15, for CG0 to CG15
#define CG(x) (3 << (x*2))
//! @brief Constants for CCM CCGR register fields.
enum _clock_gate_constants
{
CLOCK_ON = 0x3, //!< Clock always on in both run and stop modes.
CLOCK_ON_RUN = 0x1, //!< Clock on only in run mode.
CLOCK_OFF = 0x0 //!< Clocked gated off.
};
//! @brief Low power mdoes.
typedef enum _lp_modes {
RUN_MODE,
WAIT_MODE,
STOP_MODE,
} lp_modes_t;
//! @brief Main clock sources.
typedef enum _main_clocks {
CPU_CLK,
AXI_CLK,
MMDC_CH0_AXI_CLK,
AHB_CLK,
IPG_CLK,
IPG_PER_CLK,
MMDC_CH1_AXI_CLK,
} main_clocks_t;
//! @brief Peripheral clocks.
typedef enum _peri_clocks {
UART1_MODULE_CLK,
UART2_MODULE_CLK,
UART3_MODULE_CLK,
UART4_MODULE_CLK,
UART5_MODULE_CLK,
UART6_MODULE_CLK,
UART7_MODULE_CLK,
UART8_MODULE_CLK,
SSI1_BAUD,
SSI2_BAUD,
CSI_BAUD,
MSTICK1_CLK,
MSTICK2_CLK,
RAWNAND_CLK,
USB_CLK,
VPU_CLK,
SPI_CLK,
CAN_CLK
} peri_clocks_t;
//! @brief Available PLLs.
typedef enum plls {
PLL1,
PLL2,
PLL3,
PLL4,
PLL5,
} plls_t;
extern const uint32_t PLL1_OUTPUT;
extern const uint32_t PLL2_OUTPUT[];
extern const uint32_t PLL3_OUTPUT[];
extern const uint32_t PLL4_OUTPUT;
extern const uint32_t PLL5_OUTPUT;
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
//! @brief Set/unset clock gating for a peripheral.
//! @param base_address configure clock gating for that module from the base address.
//! @param gating_mode clock gating mode: CLOCK_ON or CLOCK_OFF.
void clock_gating_config(uint32_t base_address, uint32_t gating_mode);
//! @brief Returns the frequency of a clock in megahertz.
uint32_t get_main_clock(main_clocks_t clk);
//! @brief Returns the frequency of a clock in megahertz.
uint32_t get_peri_clock(peri_clocks_t clk);
//! @brief Inits clock sources.
void ccm_init(void);
//! @brief Prepare and enter in a low power mode.
//! @param lp_mode low power mode : WAIT_MODE or STOP_MODE.
void ccm_enter_low_power(lp_modes_t lp_mode);
//! @brief Mask/unmask an interrupt source that can wake up the processor when in a
//! low power mode.
//!
//! @param irq_id ID of the interrupt to mask/unmask.
//! @param doEnable Pass true to unmask the source ID.
void ccm_set_lpm_wakeup_source(uint32_t irq_id, bool doEnable);
#if defined(__cplusplus)
}
#endif
//! @}
#endif
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,341 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
#include "sdk.h"
#include "registers/regsccm.h"
#include "registers/regsccmanalog.h"
#include "registers/regsuart.h"
#include "registers/regsepit.h"
#include "registers/regsspba.h"
#include "registers/regssdmaarm.h"
#include "registers/regsgpt.h"
#include "registers/regsi2c.h"
#include "registers/regsecspi.h"
#include "ccm_pll.h"
//#include "hardware.h"
//#include "soc_memory_map.h"
#define HW_ANADIG_REG_CORE (ANATOP_IPS_BASE_ADDR + 0x140)
#define HW_ANADIG_PLL_SYS_RW (ANATOP_IPS_BASE_ADDR + 0x000)
#define HW_ANADIG_REG_CORE_V_CORE_VALUE_mv(x) ((((x)-700)/25) << 0)
#define HW_ANADIG_REG_CORE_V_SOC_VALUE_mv(x) ((((x)-700)/25) << 18)
#define HW_ANADIG_REG_CORE_V_CORE_MSK 0x1F
#define HW_ANADIG_REG_CORE_V_SOC_MSK (0x1F << 18)
uint32_t g_arm_clk = 528000000;
const uint32_t PLL2_OUTPUT[] = { 528000000, 396000000, 352000000, 198000000 };
const uint32_t PLL3_OUTPUT[] = { 480000000, 720000000, 540000000, 508235294, 454736842 };
const uint32_t PLL4_OUTPUT = 650000000;
const uint32_t PLL5_OUTPUT = 650000000;
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
void set_soc_core_voltage(unsigned int v_core_mv, unsigned int v_soc_mv)
{
unsigned int val, val_v_core, val_v_soc;
val = reg32_read(HW_ANADIG_REG_CORE);
val &= ~HW_ANADIG_REG_CORE_V_CORE_MSK;
val &= ~HW_ANADIG_REG_CORE_V_SOC_MSK;
val_v_core = HW_ANADIG_REG_CORE_V_CORE_VALUE_mv(v_core_mv);
val_v_soc = HW_ANADIG_REG_CORE_V_SOC_VALUE_mv(v_soc_mv);
val |= val_v_core | val_v_soc;
reg32_write(HW_ANADIG_REG_CORE, val);
}
void setup_clk(void)
{
uint32_t div_select;
uint32_t temp;
uint32_t arm_clk = g_arm_clk/1000000;
switch(arm_clk)
{
case 400:
div_select = 33;
set_soc_core_voltage(1150, 1175);
return;
case 528:
div_select = 44;
set_soc_core_voltage(1250, 1250);
break;
case 756:
div_select = 63;
set_soc_core_voltage(1250, 1250);
printf("ARM Clock set to 756MHz\r\n");
break;
default:
return;
}
// first, make sure ARM_PODF is clear
HW_CCM_CACRR_WR(0);
// write the div_select value into HW_ANADIG_PLL_SYS_RW
// this will re-program the PLL to the new freq
temp = readl(HW_ANADIG_PLL_SYS_RW);
temp |= 0x10000;// set BYBASS
writel(temp, HW_ANADIG_PLL_SYS_RW);
temp = readl(HW_ANADIG_PLL_SYS_RW);
temp &= ~(0x0000007F);
temp |= div_select; // Update div
writel(temp, HW_ANADIG_PLL_SYS_RW);
/* Wait for PLL to lock */
while(!(readl(HW_ANADIG_PLL_SYS_RW) & 0x80000000));
/*disable BYPASS*/
temp = readl(HW_ANADIG_PLL_SYS_RW);
temp &= ~0x10000;
writel(temp, HW_ANADIG_PLL_SYS_RW);
}
void ccm_init(void)
{
HW_CCM_CCGR0_WR(0xffffffff);
HW_CCM_CCGR1_WR(0xffffffff); // EPIT, ESAI, GPT enabled by driver
HW_CCM_CCGR2_WR(0xffffffff); // I2C enabled by driver
HW_CCM_CCGR3_WR(0xffffffff);
HW_CCM_CCGR4_WR(0xffffffff); // GPMI, Perfmon enabled by driver
HW_CCM_CCGR5_WR(0xffffffff); // UART, SATA enabled by driver
HW_CCM_CCGR6_WR(0xffffffff);
/*
* Keep default settings at reset.
* pre_periph_clk_sel is by default at 0, so the selected output
* of PLL2 is the main output at 528MHz.
* => by default, ahb_podf divides by 4 => AHB_CLK@132MHz.
* => by default, ipg_podf divides by 2 => IPG_CLK@66MHz.
*/
HW_CCM_CBCDR.U = BF_CCM_CBCDR_AHB_PODF(3)
| BF_CCM_CBCDR_AXI_PODF(1)
| BF_CCM_CBCDR_IPG_PODF(1);
setup_clk();
/* Power up 480MHz PLL */
reg32_write_mask(HW_CCM_ANALOG_PLL_USB1_ADDR, 0x00001000, 0x00001000);
/* Enable 480MHz PLL */
reg32_write_mask(HW_CCM_ANALOG_PLL_USB1_ADDR, 0x00002000, 0x00002000);
reg32_write_mask(HW_CCM_CSCDR1_ADDR, 0x00000000, 0x0000003F);
}
uint32_t get_main_clock(main_clocks_t clock)
{
uint32_t ret_val = 0;
uint32_t pre_periph_clk_sel = HW_CCM_CBCMR.B.PRE_PERIPH_CLK_SEL;
switch (clock) {
case CPU_CLK:
ret_val = g_arm_clk;
break;
case AXI_CLK:
ret_val = PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AXI_PODF + 1);
break;
case MMDC_CH0_AXI_CLK:
ret_val = PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.MMDC_CH0_AXI_PODF + 1);
break;
case AHB_CLK:
ret_val = PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AHB_PODF + 1);
break;
case IPG_CLK:
ret_val =
PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AHB_PODF +
1) / (HW_CCM_CBCDR.B.IPG_PODF + 1);
break;
case IPG_PER_CLK:
ret_val =
PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AHB_PODF +
1) / (HW_CCM_CBCDR.B.IPG_PODF +
1) / (HW_CCM_CSCMR1.B.PERCLK_PODF + 1);
break;
default:
break;
}
return ret_val;
}
uint32_t get_peri_clock(peri_clocks_t clock)
{
uint32_t ret_val = 0;
switch (clock)
{
case UART1_MODULE_CLK:
case UART2_MODULE_CLK:
case UART3_MODULE_CLK:
case UART4_MODULE_CLK:
case UART5_MODULE_CLK:
case UART6_MODULE_CLK:
case UART7_MODULE_CLK:
case UART8_MODULE_CLK:
// UART source clock is a fixed PLL3 / 6
ret_val = PLL3_OUTPUT[0] / 6 / (HW_CCM_CSCDR1.B.UART_CLK_PODF + 1);
break;
case SPI_CLK:
ret_val = PLL3_OUTPUT[0] / 8 / (HW_CCM_CSCDR2.B.ECSPI_CLK_PODF + 1);
break;
case RAWNAND_CLK:
ret_val =
PLL3_OUTPUT[0] / (HW_CCM_CS2CDR.B.ENFC_CLK_PRED + 1) / (HW_CCM_CS2CDR.B.ENFC_CLK_PODF +
1);
break;
case CAN_CLK:
// For i.mx6dq/sdl CAN source clock is a fixed PLL3 / 8
ret_val = PLL3_OUTPUT[0] / 8 / (HW_CCM_CSCMR2.B.CAN_CLK_PODF + 1);
break;
default:
break;
}
return ret_val;
}
void ccm_ccgr_config(uint32_t ccm_ccgrx, uint32_t cgx_offset, uint32_t gating_mode)
{
if (gating_mode == CLOCK_ON)
{
*(volatile uint32_t *)(ccm_ccgrx) |= cgx_offset;
}
else
{
*(volatile uint32_t *)(ccm_ccgrx) &= ~cgx_offset;
}
}
void clock_gating_config(uint32_t base_address, uint32_t gating_mode)
{
uint32_t ccm_ccgrx = 0;
uint32_t cgx_offset = 0;
switch (base_address)
{
case REGS_UART1_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(12);
break;
case REGS_UART2_BASE:
ccm_ccgrx = HW_CCM_CCGR0_ADDR;
cgx_offset = CG(14);
break;
case REGS_UART3_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(5);
break;
case REGS_UART4_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(12);
break;
case REGS_UART5_BASE:
ccm_ccgrx = HW_CCM_CCGR3_ADDR;
cgx_offset = CG(1);
break;
case REGS_UART6_BASE:
ccm_ccgrx = HW_CCM_CCGR3_ADDR;
cgx_offset = CG(3);
break;
case REGS_UART7_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(13);
break;
case REGS_UART8_BASE:
ccm_ccgrx = HW_CCM_CCGR6_ADDR;
cgx_offset = CG(7);
break;
case REGS_SPBA_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(6);
break;
case REGS_SDMAARM_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(3);
break;
case REGS_EPIT1_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(6);
break;
case REGS_EPIT2_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(7);
break;
case REGS_GPT1_BASE:
case REGS_GPT2_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(10)|CG(11);
break;
case REGS_I2C1_BASE:
ccm_ccgrx = HW_CCM_CCGR2_ADDR;
cgx_offset = CG(3);
break;
case REGS_I2C2_BASE:
ccm_ccgrx = HW_CCM_CCGR2_ADDR;
cgx_offset = CG(4);
break;
case REGS_I2C3_BASE:
ccm_ccgrx = HW_CCM_CCGR2_ADDR;
cgx_offset = CG(5);
break;
case REGS_ECSPI1_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(0);
break;
case REGS_ECSPI2_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(1);
break;
case REGS_ECSPI3_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(2);
break;
case REGS_ECSPI4_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(3);
break;
default:
break;
}
// apply changes only if a valid address was found
if (ccm_ccgrx != 0)
{
ccm_ccgr_config(ccm_ccgrx, cgx_offset, gating_mode);
}
}
////////////////////////////////////////////////////////////////////////////////
// End of file
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,228 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
#if !defined(__CORTEX_A_H__)
#define __CORTEX_A9H__
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
//! @addtogroup cortexa9
//! @{
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @name Instruction macros
//@{
#define _ARM_NOP() asm volatile ("nop\n\t")
#define _ARM_WFI() asm volatile ("wfi\n\t")
#define _ARM_WFE() asm volatile ("wfe\n\t")
#define _ARM_SEV() asm volatile ("sev\n\t")
#define _ARM_DSB() asm volatile ("dsb\n\t")
#define _ARM_ISB() asm volatile ("isb\n\t")
#define _ARM_MRC(coproc, opcode1, Rt, CRn, CRm, opcode2) \
asm volatile ("mrc p" #coproc ", " #opcode1 ", %[output], c" #CRn ", c" #CRm ", " #opcode2 "\n" : [output] "=r" (Rt))
#define _ARM_MCR(coproc, opcode1, Rt, CRn, CRm, opcode2) \
asm volatile ("mcr p" #coproc ", " #opcode1 ", %[input], c" #CRn ", c" #CRm ", " #opcode2 "\n" :: [input] "r" (Rt))
//@}
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
//! @name Misc
//@{
//! @brief Enable or disable the IRQ and FIQ state.
bool arm_set_interrupt_state(bool enable);
//! @brief Get current CPU ID.
int cpu_get_current(void);
//! @brief Enable the NEON MPE.
void enable_neon_fpu(void);
//! @brief Disable aborts on unaligned accesses.
void disable_strict_align_check(void);
//! @brief Get base address of private perpherial space.
//!
//! @return The address of the ARM CPU's private peripherals.
uint32_t get_arm_private_peripheral_base(void);
//@}
//! @name Data cache operations
//@{
//! @brief Check if dcache is enabled or disabled.
int arm_dcache_state_query();
//! @brief Enables data cache at any available cache level.
//!
//! Works only if MMU is enabled!
void arm_dcache_enable();
//! @brief Disables the data cache at any available cache level.
void arm_dcache_disable();
//! @brief Invalidates the entire data cache.
void arm_dcache_invalidate();
//! @brief Invalidate a line of data cache.
void arm_dcache_invalidate_line(const void * addr);
//! @brief Invalidate a number of lines of data cache.
//!
//! Number of lines depends on length parameter and size of line.
//! Size of line for A9 L1 cache is 32B.
void arm_dcache_invalidate_mlines(const void * addr, size_t length);
//! @brief Flush (clean) all lines of cache (all sets in all ways).
void arm_dcache_flush();
//! @brief Flush (clean) one line of cache.
void arm_dcache_flush_line(const void * addr);
// @brief Flush (clean) multiple lines of cache.
//!
//! Number of lines depends on length parameter and size of line.
void arm_dcache_flush_mlines(const void * addr, size_t length);
//@}
//! @name Instrution cache operations
//@{
//! @brief Check if icache is enabled or disabled.
int arm_icache_state_query();
//! @brief Enables instruction cache at any available cache level.
//!
//! Works without enabled MMU too!
void arm_icache_enable();
//! @brief Disables the instruction cache at any available cache level.
void arm_icache_disable();
//! @brief Invalidates the entire instruction cache.
void arm_icache_invalidate();
//! @brief Invalidates the entire instruction cache inner shareable.
void arm_icache_invalidate_is();
//! @brief Invalidate a line of the instruction cache.
void arm_icache_invalidate_line(const void * addr);
//! @brief Invalidate a number of lines of instruction cache.
//!
//! Number of lines depends on length parameter and size of line.
void arm_icache_invalidate_mlines(const void * addr, size_t length);
//@}
//! @name TLB operations
//@{
//! @brief Invalidate entire unified TLB.
void arm_unified_tlb_invalidate(void);
//! @brief Invalidate entire unified TLB Inner Shareable.
void arm_unified_tlb_invalidate_is(void);
//@}
//! @name Branch predictor operations
//@{
//! @brief Enable branch prediction.
void arm_branch_prediction_enable(void);
//! @brief Disable branch prediction.
void arm_branch_prediction_disable(void);
//! @brief Invalidate entire branch predictor array.
void arm_branch_target_cache_invalidate(void);
//! @brief Invalidate entire branch predictor array Inner Shareable
void arm_branch_target_cache_invalidate_is(void);
//@}
//! @name SCU
//@{
//! @brief Enables the SCU.
void scu_enable(void);
//! @brief Set this CPU as participating in SMP.
void scu_join_smp(void);
//! @brief Set this CPU as not participating in SMP.
void scu_leave_smp(void);
//! @brief Determine which CPUs are participating in SMP.
//!
//! The return value is 1 bit per core:
//! - bit 0 - CPU 0
//! - bit 1 - CPU 1
//! - etc...
unsigned int scu_get_cpus_in_smp(void);
//! @brief Enable the broadcasting of cache & TLB maintenance operations.
//!
//! When enabled AND in SMP, broadcast all "inner sharable"
//! cache and TLM maintenance operations to other SMP cores
void scu_enable_maintenance_broadcast(void);
//! @brief Disable the broadcasting of cache & TLB maintenance operations.
void scu_disable_maintenance_broadcast(void);
//! @brief Invalidates the SCU copy of the tag rams for the specified core.
//!
//! Typically only done at start-up.
//! Possible flow:
//! - Invalidate L1 caches
//! - Invalidate SCU copy of TAG RAMs
//! - Join SMP
//!
//! @param cpu 0x0=CPU 0, 0x1=CPU 1, etc...
//! @param ways The ways to invalidate. Pass 0xf to invalidate all ways.
void scu_secure_invalidate(unsigned int cpu, unsigned int ways);
//@}
#if defined(__cplusplus)
}
#endif
//! @}
#endif // __CORTEX_A_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,327 @@
/*
* Copyright (c) 2010-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file cortexA9.s
* @brief This file contains cortexA9 functions
*
*/
.code 32
.section ".text","ax"
/*
* bool arm_set_interrupt_state(bool enable)
*/
.global arm_set_interrupt_state
.func arm_set_interrupt_state
arm_set_interrupt_state:
mrs r2,CPSR @ read CPSR (Current Program Status Register)
teq r0,#0
bicne r1,r2,#0xc0 @ disable IRQ and FIQ
orreq r1,r2,#0xc0 @ enable IRQ and FIQ
msr CPSR_c,r1
tst r2,#0x80
movne r0,#0
moveq r0,#1
bx lr
.endfunc
.global cpu_get_current
@ int cpu_get_current(void)@
@ get current CPU ID
.func cpu_get_current
cpu_get_current:
mrc p15, 0, r0, c0, c0, 5
and r0, r0, #3
BX lr
.endfunc @cpu_get_current()@
.global enable_neon_fpu
.func enable_neon_fpu
enable_neon_fpu:
/* set NSACR, both Secure and Non-secure access are allowed to NEON */
MRC p15, 0, r0, c1, c1, 2
ORR r0, r0, #(0x3<<10) @ enable fpu/neon
MCR p15, 0, r0, c1, c1, 2
/* Set the CPACR for access to CP10 and CP11*/
LDR r0, =0xF00000
MCR p15, 0, r0, c1, c0, 2
/* Set the FPEXC EN bit to enable the FPU */
MOV r3, #0x40000000
@VMSR FPEXC, r3
MCR p10, 7, r3, c8, c0, 0
.endfunc
.global disable_strict_align_check
.func disable_strict_align_check
disable_strict_align_check:
/*Ray's note: disable strict alignment fault checking.
without disabling this, data abort will happen when accessing
the BPB structure of file system since it is packed.*/
push {r0, lr}
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(0x1<<1) @clear A bit of SCTLR
mcr p15, 0, r0, c1, c0, 0
pop {r0, pc}
.endfunc
.global disable_L1_cache
.func disable_L1_cache
disable_L1_cache:
push {r0-r6, lr}
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(0x1<<12)
bic r0, r0, #(0x1<<11)
bic r0, r0, #(0x1<<2)
bic r0, r0, #(0x1<<0)
mcr p15, 0, r0, c1, c0, 0
pop {r0-r6, pc}
.endfunc
.global get_arm_private_peripheral_base
@ uint32_t get_arm_private_peripheral_base(void)@
.func get_arm_private_peripheral_base
get_arm_private_peripheral_base:
@ Get base address of private perpherial space
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
bx lr
.endfunc @get_arm_private_peripheral_base()@
@ ------------------------------------------------------------
@ TLB
@ ------------------------------------------------------------
.global arm_unified_tlb_invalidate
@ void arm_unified_tlb_invalidate(void)@
.func arm_unified_tlb_invalidate
arm_unified_tlb_invalidate:
mov r0, #1
mcr p15, 0, r0, c8, c7, 0 @ TLBIALL - Invalidate entire unified TLB
dsb
bx lr
.endfunc
.global arm_unified_tlb_invalidate_is
@ void arm_unified_tlb_invalidate_is(void)@
.func arm_unified_tlb_invalidate_is
arm_unified_tlb_invalidate_is:
mov r0, #1
mcr p15, 0, r0, c8, c3, 0 @ TLBIALLIS - Invalidate entire unified TLB Inner Shareable
dsb
bx lr
.endfunc
@ ------------------------------------------------------------
@ Branch Prediction
@ ------------------------------------------------------------
.global arm_branch_prediction_enable
@ void arm_branch_prediction_enable(void)
.func arm_branch_prediction_enable
arm_branch_prediction_enable:
mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
orr r0, r0, #(1 << 11) @ Set the Z bit (bit 11)
mcr p15, 0,r0, c1, c0, 0 @ Write SCTLR
bx lr
.endfunc
.global arm_branch_prediction_disable
@ void arm_branch_prediction_disable(void)
.func arm_branch_prediction_disable
arm_branch_prediction_disable:
mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR
bic r0, r0, #(1 << 11) @ Clear the Z bit (bit 11)
mcr p15, 0,r0, c1, c0, 0 @ Write SCTLR
bx lr
.endfunc
.global arm_branch_target_cache_invalidate
@ void arm_branch_target_cache_invalidate(void)
.func arm_branch_target_cache_invalidate
arm_branch_target_cache_invalidate:
mov r0, #0
mcr p15, 0, r0, c7, c5, 6 @ BPIALL - Invalidate entire branch predictor array
bx lr
.endfunc
.global arm_branch_target_cache_invalidate_is
@ void arm_branch_target_cache_invalidate_is(void)
.func arm_branch_target_cache_invalidate_is
arm_branch_target_cache_invalidate_is:
mov r0, #0
mcr p15, 0, r0, c7, c1, 6 @ BPIALLIS - Invalidate entire branch predictor array Inner Shareable
bx lr
.endfunc
@ ------------------------------------------------------------
@ SCU
@ ------------------------------------------------------------
@ SCU offset from base of private peripheral space --> 0x000
.global scu_enable
@ void scu_enable(void)
@ Enables the SCU
.func scu_enable
scu_enable:
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
ldr r1, [r0, #0x0] @ Read the SCU Control Register
orr r1, r1, #0x1 @ Set bit 0 (The Enable bit)
str r1, [r0, #0x0] @ Write back modifed value
bx lr
.endfunc
@ ------------------------------------------------------------
.global scu_join_smp
@ void scu_join_smp(void)
@ Set this CPU as participating in SMP
.func scu_join_smp
scu_join_smp:
@ SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg
mrc p15, 0, r0, c1, c0, 1 @ Read ACTLR
orr r0, r0, #0x040 @ Set bit 6
mcr p15, 0, r0, c1, c0, 1 @ Write ACTLR
bx lr
.endfunc
@ ------------------------------------------------------------
.global scu_leave_smp
@ void scu_leave_smp(void)
@ Set this CPU as NOT participating in SMP
.func scu_leave_smp
scu_leave_smp:
@ SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg
mrc p15, 0, r0, c1, c0, 1 @ Read ACTLR
bic r0, r0, #0x040 @ Clear bit 6
mcr p15, 0, r0, c1, c0, 1 @ Write ACTLR
bx lr
.endfunc
@ ------------------------------------------------------------
.global scu_get_cpus_in_smp
@ unsigned int scu_get_cpus_in_smp(void)
@ The return value is 1 bit per core:
@ bit 0 - CPU 0
@ bit 1 - CPU 1
@ etc...
.func scu_get_cpus_in_smp
scu_get_cpus_in_smp:
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
ldr r0, [r0, #0x004] @ Read SCU Configuration register
mov r0, r0, lsr #4 @ Bits 7:4 gives the cores in SMP mode, shift then mask
and r0, r0, #0x0F
bx lr
.endfunc
@ ------------------------------------------------------------
.global scu_enable_maintenance_broadcast
@ void scu_enable_maintenance_broadcast(void)
@ Enable the broadcasting of cache & TLB maintenance operations
@ When enabled AND in SMP, broadcast all "inner sharable"
@ cache and TLM maintenance operations to other SMP cores
.func scu_enable_maintenance_broadcast
scu_enable_maintenance_broadcast:
mrc p15, 0, r0, c1, c0, 1 @ Read Aux Ctrl register
orr r0, r0, #0x01 @ Set the FW bit (bit 0)
mcr p15, 0, r0, c1, c0, 1 @ Write Aux Ctrl register
bx lr
.endfunc
@ ------------------------------------------------------------
.global scu_disable_maintenance_broadcast
@ void scu_disable_maintenance_broadcast(void)
@ Disable the broadcasting of cache & TLB maintenance operations
.func scu_disable_maintenance_broadcast
scu_disable_maintenance_broadcast:
mrc p15, 0, r0, c1, c0, 1 @ Read Aux Ctrl register
bic r0, r0, #0x01 @ Clear the FW bit (bit 0)
mcr p15, 0, r0, c1, c0, 1 @ Write Aux Ctrl register
bx lr
.endfunc
@ ------------------------------------------------------------
.global scu_secure_invalidate
@ void scu_secure_invalidate(unsigned int cpu, unsigned int ways)
@ cpu: 0x0=CPU 0 0x1=CPU 1 etc...
@ This function invalidates the SCU copy of the tag rams
@ for the specified core. typically only done at start-up.
@ Possible flow:
@ - Invalidate L1 caches
@ - Invalidate SCU copy of TAG RAMs
@ - Join SMP
.func scu_secure_invalidate
scu_secure_invalidate:
and r0, r0, #0x03 @ Mask off unused bits of CPU ID
mov r0, r0, lsl #2 @ Convert into bit offset (four bits per core)
and r1, r1, #0x0F @ Mask off unused bits of ways
mov r1, r1, lsl r0 @ Shift ways into the correct CPU field
mrc p15, 4, r2, c15, c0, 0 @ Read periph base address
str r1, [r2, #0x0C] @ Write to SCU Invalidate All in Secure State
bx lr
.endfunc
@ ------------------------------------------------------------
@ End of cortexA9.s
@ ------------------------------------------------------------
.end

View File

@@ -0,0 +1,243 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
#include <assert.h>
#include "gic.h"
#include "gic_registers.h"
#include "cortex_a.h"
////////////////////////////////////////////////////////////////////////////////
// Prototypes
////////////////////////////////////////////////////////////////////////////////
static inline gicd_t * gic_get_gicd(void);
static inline gicc_t * gic_get_gicc(void);
static inline uint32_t irq_get_register_offset(uint32_t irqID);
static inline uint32_t irq_get_bit_offset(uint32_t irqID);
static inline uint32_t irq_get_bit_mask(uint32_t irqID);
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
static inline gicd_t * gic_get_gicd(void)
{
uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset;
return (gicd_t *)base;
}
static inline gicc_t * gic_get_gicc(void)
{
uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset;
return (gicc_t *)base;
}
static inline uint32_t irq_get_register_offset(uint32_t irqID)
{
return irqID / 32;
}
static inline uint32_t irq_get_bit_offset(uint32_t irqID)
{
return irqID & 0x1f;
}
static inline uint32_t irq_get_bit_mask(uint32_t irqID)
{
return 1 << irq_get_bit_offset(irqID);
}
void gic_enable(bool enableIt)
{
gicd_t * gicd = gic_get_gicd();
if (enableIt)
{
// Enable both secure and non-secure.
gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1;
}
else
{
// Clear the enable bits.
gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1);
}
}
void gic_set_irq_security(uint32_t irqID, bool isSecure)
{
gicd_t * gicd = gic_get_gicd();
uint32_t reg = irq_get_register_offset(irqID);
uint32_t mask = irq_get_bit_mask(irqID);
uint32_t value = gicd->IGROUPRn[reg];
if (!isSecure)
{
value &= ~mask;
}
else
{
value |= mask;
}
gicd->IGROUPRn[reg] = value;
}
void gic_enable_irq(uint32_t irqID, bool isEnabled)
{
gicd_t * gicd = gic_get_gicd();
uint32_t reg = irq_get_register_offset(irqID);
uint32_t mask = irq_get_bit_mask(irqID);
// Select set-enable or clear-enable register based on enable flag.
if (isEnabled)
{
gicd->ISENABLERn[reg] = mask;
}
else
{
gicd->ICENABLERn[reg] = mask;
}
}
void gic_set_irq_priority(uint32_t ID, uint32_t priority)
{
gicd_t * gicd = gic_get_gicd();
// Update the priority register. The priority registers are byte accessible, and the register
// struct has the priority registers as a byte array, so we can just index directly by the
// interrupt ID.
gicd->IPRIORITYRn[ID] = priority & 0xff;
}
void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt)
{
// Make sure the CPU number is valid.
assert(cpuNumber <= 7);
gicd_t * gicd = gic_get_gicd();
uint8_t cpuMask = 1 << cpuNumber;
// Like the priority registers, the target registers are byte accessible, and the register
// struct has the them as a byte array, so we can just index directly by the
// interrupt ID.
if (enableIt)
{
gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff);
}
else
{
gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff);
}
}
void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list)
{
gicd_t * gicd = gic_get_gicd();
gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter)
| (target_list << kBP_GICD_SGIR_CPUTargetList)
| (irqID & 0xf);
}
void gic_cpu_enable(bool enableIt)
{
gicc_t * gicc = gic_get_gicc();
if (enableIt)
{
gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS;
}
else
{
gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS);
}
}
void gic_set_cpu_priority_mask(uint32_t priority)
{
gicc_t * gicc = gic_get_gicc();
gicc->PMR = priority & 0xff;
}
uint32_t gic_read_irq_ack(void)
{
gicc_t * gicc = gic_get_gicc();
return gicc->IAR;
}
void gic_write_end_of_irq(uint32_t irqID)
{
gicc_t * gicc = gic_get_gicc();
gicc->EOIR = irqID;
}
void gic_init(void)
{
gicd_t * gicd = gic_get_gicd();
// First disable the distributor.
gic_enable(false);
// Clear all pending interrupts.
int i;
for (i = 0; i < 32; ++i)
{
gicd->ICPENDRn[i] = 0xffffffff;
}
// Set all interrupts to secure.
for (i = 0; i < 8; ++i)
{
gicd->IGROUPRn[i] = 0;
}
// Init the GIC CPU interface.
gic_init_cpu();
// Now enable the distributor.
gic_enable(true);
}
void gic_init_cpu(void)
{
// Init the GIC CPU interface.
gic_set_cpu_priority_mask(0xff);
// Disable preemption.
gicc_t * gicc = gic_get_gicc();
gicc->BPR = 7;
// Enable signaling the CPU.
gic_cpu_enable(true);
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
#include "sdk_types.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Offsets to the GIC registers.
enum _gic_base_offsets
{
kGICDBaseOffset = 0x1000, //!< GIC distributor offset.
#if defined(CHIP_MX6UL)
kGICCBaseOffset = 0x2000 //!< GIC CPU interface offset.
#else
kGICCBaseOffset = 0x100 //!< GIC CPU interface offset.
#endif
};
//! @brief GIC distributor registers.
//!
//! Uses the GICv2 register names, but does not include GICv2 registers.
//!
//! The IPRIORITYRn and ITARGETSRn registers are byte accessible, so their types are uint8_t
//! instead of uint32_t to reflect this. These members are indexed directly with the interrupt
//! number.
struct _gicd_registers
{
uint32_t CTLR; //!< Distributor Control Register.
uint32_t TYPER; //!< Interrupt Controller Type Register.
uint32_t IIDR; //!< Distributor Implementer Identification Register.
uint32_t _reserved0[29];
uint32_t IGROUPRn[8]; //!< Interrupt Group Registers.
uint32_t _reserved1[24];
uint32_t ISENABLERn[32]; //!< Interrupt Set-Enable Registers.
uint32_t ICENABLERn[32]; //!< Interrupt Clear-Enable Registers.
uint32_t ISPENDRn[32]; //!< Interrupt Set-Pending Registers.
uint32_t ICPENDRn[32]; //!< Interrupt Clear-Pending Registers.
uint32_t ICDABRn[32]; //!< Active Bit Registers.
uint32_t _reserved2[32];
uint8_t IPRIORITYRn[255 * sizeof(uint32_t)]; //!< Interrupt Priority Registers. (Byte accessible)
uint32_t _reserved3;
uint8_t ITARGETSRn[255 * sizeof(uint32_t)]; //!< Interrupt Processor Targets Registers. (Byte accessible)
uint32_t _reserved4;
uint32_t ICFGRn[64]; //!< Interrupt Configuration Registers.
uint32_t _reserved5[128];
uint32_t SGIR; //!< Software Generated Interrupt Register
};
//! @brief Bitfields constants for the GICD_CTLR register.
enum _gicd_ctlr_fields
{
kBM_GICD_CTLR_EnableGrp1 = (1 << 1),
kBM_GICD_CTLR_EnableGrp0 = (1 << 0)
};
//! @brief Bitfields constants for the GICD_SGIR register.
enum _gicd_sgir_fields
{
kBP_GICD_SGIR_TargetListFilter = 24,
kBM_GICD_SGIR_TargetListFilter = (0x3 << kBP_GICD_SGIR_TargetListFilter),
kBP_GICD_SGIR_CPUTargetList = 16,
kBM_GICD_SGIR_CPUTargetList = (0xff << kBP_GICD_SGIR_CPUTargetList),
kBP_GICD_SGIR_NSATT = 15,
kBM_GICD_SGIR_NSATT = (1 << kBP_GICD_SGIR_NSATT),
kBP_GICD_SGIR_SGIINTID = 0,
kBM_GICD_SGIR_SGIINTID = 0xf
};
//! @brief GIC CPU interface registers.
//!
//! Uses the GICv2 register names. Does not include GICv2 registers.
struct _gicc_registers
{
uint32_t CTLR; //!< CPU Interface Control Register.
uint32_t PMR; //!< Interrupt Priority Mask Register.
uint32_t BPR; //!< Binary Point Register.
uint32_t IAR; //!< Interrupt Acknowledge Register.
uint32_t EOIR; //!< End of Interrupt Register.
uint32_t RPR; //!< Running Priority Register.
uint32_t HPPIR; //!< Highest Priority Pending Interrupt Register.
uint32_t ABPR; //!< Aliased Binary Point Register. (only visible with a secure access)
uint32_t _reserved[56];
uint32_t IIDR; //!< CPU Interface Identification Register.
};
//! @brief Bitfields constants for the GICC_CTLR register.
enum _gicc_ctlr_fields
{
kBP_GICC_CTLR_EnableS = 0,
kBM_GICC_CTLR_EnableS = (1 << 0),
kBP_GICC_CTLR_EnableNS = 1,
kBM_GICC_CTLR_EnableNS = (1 << 1),
kBP_GICC_CTLR_AckCtl = 2,
kBM_GICC_CTLR_AckCtl = (1 << 2),
kBP_GICC_CTLR_FIQEn = 3,
kBM_GICC_CTLR_FIQEn = (1 << 3),
kBP_GICC_CTLR_SBPR = 4,
kBM_GICC_CTLR_SBPR = (1 << 4)
};
//! @brier Type for the GIC distributor registers.
typedef volatile struct _gicd_registers gicd_t;
//! @brier Type for the GIC CPU interface registers.
typedef volatile struct _gicc_registers gicc_t;
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,285 @@
/*
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file mmu.c
* @brief System memory arangement.
*/
#include "cortex_a.h"
#include "mmu.h"
#include "arm_cp_registers.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Size in bytes of the first-level page table.
#define MMU_L1_PAGE_TABLE_SIZE (16 * 1024)
//! @brief First-level 1MB section descriptor entry.
typedef union mmu_l1_section {
uint32_t u;
struct {
uint32_t id:2; //!< ID
uint32_t b:1; //!< Bufferable
uint32_t c:1; //!< Cacheable
uint32_t xn:1; //!< Execute-not
uint32_t domain:4; //!< Domain
uint32_t _impl_defined:1; //!< Implementation defined, should be zero.
uint32_t ap1_0:2; //!< Access permissions AP[1:0]
uint32_t tex:3; //!< TEX remap
uint32_t ap2:1; //!< Access permissions AP[2]
uint32_t s:1; //!< Shareable
uint32_t ng:1; //!< Not-global
uint32_t _zero:1; //!< Should be zero.
uint32_t ns:1; //!< Non-secure
uint32_t address:12; //!< Physical base address
};
} mmu_l1_section_t;
enum {
kMMU_L1_Section_ID = 2, //!< ID value for a 1MB section first-level entry.
kMMU_L1_Section_Address_Shift = 20 //!< Bit offset of the physical base address field.
};
////////////////////////////////////////////////////////////////////////////////
// Externs
////////////////////////////////////////////////////////////////////////////////
extern char __l1_page_table_start;
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
void mmu_enable()
{
// invalidate all tlb
arm_unified_tlb_invalidate();
// read SCTLR
uint32_t sctlr;
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
// set MMU enable bit
sctlr |= BM_SCTLR_M;
// write modified SCTLR
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
}
void mmu_disable()
{
// read current SCTLR
uint32_t sctlr;
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
// clear MMU enable bit
sctlr &=~ BM_SCTLR_M;
// write modified SCTLR
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
}
void mmu_init()
{
// Get the L1 page table base address.
uint32_t * table = (uint32_t *)&__l1_page_table_start;
uint32_t share_attr = kShareable;
// write table address to TTBR0
_ARM_MCR(15, 0, table, 2, 0, 0);
// set Client mode for all Domains
uint32_t dacr = 0x55555555;
_ARM_MCR(15, 0, dacr, 3, 0, 0); // MCR p15, 0, <Rd>, c3, c0, 0 ; Write DACR
// Clear the L1 table.
bzero(table, MMU_L1_PAGE_TABLE_SIZE);
// Create default mappings.
mmu_map_l1_range(0x00000000, 0x00000000, 0x00900000, kStronglyOrdered, kShareable, kRWAccess); // ROM and peripherals
mmu_map_l1_range(0x00900000, 0x00900000, 0x00100000, kStronglyOrdered, kShareable, kRWAccess); // OCRAM
mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kStronglyOrdered, kShareable, kRWAccess); // More peripherals
// Check whether SMP is enabled. If it is not, then we don't want to make SDRAM shareable.
uint32_t actlr = 0x0;
_ARM_MRC(15, 0, actlr, 1, 0, 1);
if (actlr & BM_ACTLR_SMP)
{
share_attr = kShareable;
}
else
{
share_attr = kNonshareable;
}
#if defined(CHIP_MX6DQ) || defined(CHIP_MX6SDL)
mmu_map_l1_range(0x10000000, 0x10000000, 0x80000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 2GB DDR
#elif defined(CHIP_MX6SL) || defined(CHIP_MX6UL)
mmu_map_l1_range(0x80000000, 0x80000000, 0x40000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 1GB DDR
#else
#error Unknown chip type!
#endif
}
void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access)
{
register mmu_l1_section_t entry;
entry.u = 0;
// Set constant attributes.
entry.id = kMMU_L1_Section_ID;
entry.xn = 0; // Allow execution
entry.domain = 0; // Domain 0
entry.ng = 0; // Global
entry.ns = 0; // Secure
// Set attributes based on the selected memory type.
switch (memoryType)
{
case kStronglyOrdered:
entry.c = 0;
entry.b = 0;
entry.tex = 0;
entry.s = 1; // Ignored
break;
case kDevice:
if (isShareable)
{
entry.c = 0;
entry.b = 1;
entry.tex = 0;
entry.s = 1; // Ignored
}
else
{
entry.c = 0;
entry.b = 0;
entry.tex = 2;
entry.s = 0; // Ignored
}
break;
case kOuterInner_WB_WA:
entry.c = 1;
entry.b = 1;
entry.tex = 1;
entry.s = isShareable;
break;
case kOuterInner_WT:
entry.c = 1;
entry.b = 0;
entry.tex = 0;
entry.s = isShareable;
break;
case kNoncacheable:
entry.c = 0;
entry.b = 0;
entry.tex = 1;
entry.s = isShareable;
break;
}
// Set attributes from specified access mode.
switch (access)
{
case kNoAccess:
entry.ap2 = 0;
entry.ap1_0 = 0;
break;
case kROAccess:
entry.ap2 = 1;
entry.ap1_0 = 3;
break;
case kRWAccess:
entry.ap2 = 0;
entry.ap1_0 = 3;
break;
}
// Get the L1 page table base address.
uint32_t * table = (uint32_t *)&__l1_page_table_start;
// Convert addresses to 12-bit bases.
uint32_t vbase = va >> kMMU_L1_Section_Address_Shift;
uint32_t pbase = pa >> kMMU_L1_Section_Address_Shift;
uint32_t entries = length >> kMMU_L1_Section_Address_Shift;
// Fill in L1 page table entries.
for (; entries > 0; ++pbase, ++vbase, --entries)
{
entry.address = pbase;
table[vbase] = entry.u;
}
// Invalidate TLB
arm_unified_tlb_invalidate();
}
bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress)
{
uint32_t pa = 0;
// VA to PA translation with privileged read permission check
_ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 0);
// Read PA register
_ARM_MRC(15, 0, pa, 7, 4, 0);
// First bit of returned value is Result of conversion (0 is successful translation)
if (pa & 1)
{
// We can try write permission also
// VA to PA translation with privileged write permission check
_ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 1);
// Read PA register
_ARM_MRC(15, 0, pa, 7, 4, 0);
// First bit of returned value is Result of conversion (0 is successful translation)
if (pa & 1)
{
return false;
}
}
if (physicalAddress)
{
// complete address returning base + offset
pa = (pa & 0xfffff000) | (virtualAddress & 0x00000fff);
*physicalAddress = pa;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,157 @@
/*
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
//! @addtogroup diag_mmu
//! @{
/*!
* @file mmu.h
* @brief System memory arrangement.
*/
#ifndef _MMU_H_
#define _MMU_H_
#include "sdk.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Memory region attributes.
typedef enum _mmu_memory_type
{
kStronglyOrdered,
kDevice,
kOuterInner_WB_WA,
kOuterInner_WT,
kNoncacheable,
} mmu_memory_type_t;
//! @brief Memory region shareability options.
typedef enum _mmu_shareability
{
kShareable = 1,
kNonshareable = 0
} mmu_shareability_t;
//! @brief Access permissions for a memory region.
typedef enum _mmu_access
{
kNoAccess,
kROAccess,
kRWAccess
} mmu_access_t;
////////////////////////////////////////////////////////////////////////////////
// Prototypes
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Enable the MMU.
*
* The L1 page tables and MMU settings must have already been configured by
* calling mmu_init() before the MMU is enabled.
*/
void mmu_enable();
/*!
* @brief Disable the MMU.
*/
void mmu_disable();
/*!
* @brief Set up the default first-level page table.
*
* Initializes the L1 page table with the following regions:
* - 0x00000000...0x00900000 : ROM and peripherals, strongly-ordered
* - 0x00900000...0x00a00000 : OCRAM, strongly-ordered
* - For MX6DQ or MX6SDL: 0x10000000...0x90000000 : DDR, normal, outer inner, write-back, write-allocate
* - For MX6SL: 0x80000000...0xc0000000 : DDR, normal, outer inner, write-back, write-allocate
*
* If the CPU is participating in SMP, then the DDR regions are made shareable. Otherwise they
* are marked as non-shareable.
*
* The TTBR0 register is set to the base of the L1 table.
*
* All memory domains are configured to allow client access. However, note that only domain 0 is
* used by mmu_map_l1_range().
*/
void mmu_init();
/*!
* @brief Maps a range of memory in the first-level page table.
*
* Entries in the first-level page table are filled in for the range of virtual addresses
* starting at @a va and continuing for @a length bytes. These virtual addreses are mapped
* to the physical addresses starting at @a pa and continuing for @a length bytes. All table
* entries for the range of mapped memory have the same attributes, which are selected with
* the @a memoryType, @a isShareable, and @a access parameters.
*
* @param pa The base physical address of the range to which the virtual address will be mapped.
* @param va The base virtual address of the range.
* @param length The size of the range to be mapped, in bytes. This value must be divisible by 1MB.
* @param memoryType The type of the memory region. This controls caching, buffering, ordering of
* memory accesses, and other attributes of the region.
* @param isShareable The shareability of the physical memory. Ignored for strongly-ordered memory.
* @param access Access permissions.
*/
void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access);
/*!
* @brief Convert virtual address to physical.
*
* First attempts a priviledged read translation for the current security mode. If that fails,
* a priviledged write translation, also for the current security mode, is attempted. If this
* second attempt at translation fails, then false will be returned.
*
* @param virtualAddress Virtual address to convert to a physical address.
* @param[out] physicalAddress This parameter is filled in with the physical address corresponding
* to the virtual address passed in @a virtualAddress.
* @retval true The address returned through @a physicalAddress is valid.
* @retval false The conversion failed for some reason.
*/
bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress);
#if defined(__cplusplus)
}
#endif
//! @}
#endif // _MMU_H_
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,203 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file epit.c
* @brief EPIT driver source file.
*
* @ingroup diag_timer
*/
#include "epit.h"
#include "imx_timer.h"
#include "interrupt.h"
#include "ccm_pll.h"
#include "registers/regsepit.h"
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
void epit_reload_counter(uint32_t instance, uint32_t load_val)
{
// set the load register especially if RLD=reload_mode=SET_AND_FORGET=1
HW_EPIT_LR_WR(instance, load_val);
}
uint32_t epit_get_counter_value(uint32_t instance)
{
return HW_EPIT_CNR_RD(instance);
}
void epit_set_compare_event(uint32_t instance, uint32_t compare_val)
{
HW_EPIT_CMPR_WR(instance, compare_val);
}
uint32_t epit_get_compare_event(uint32_t instance)
{
uint32_t status_register;
// get the status
status_register = HW_EPIT_SR_RD(instance);
// clear it if found set
if (status_register & BM_EPIT_SR_OCIF)
{
HW_EPIT_SR_SET(instance, BM_EPIT_SR_OCIF);
}
// return the read value before the bit was cleared
return status_register & BM_EPIT_SR_OCIF;
}
void epit_counter_disable(uint32_t instance)
{
/* temporary workaround for the discovered issue when disabling the
* counter during end of count/reload/set compare flag ??.
* Set to the max value so that it ensures that the counter couldn't
* reach 0 when it is disabled.
*/
HW_EPIT_LR_WR(instance, 0xFFFFFFFF);
// disable the counter
HW_EPIT_CR_CLR(instance, BM_EPIT_CR_EN);
// ensure to leave the counter in a proper state
// by disabling the output compare interrupt
HW_EPIT_CR_CLR(instance, BM_EPIT_CR_OCIEN);
// and clearing possible remaining compare event
HW_EPIT_SR_SET(instance, BM_EPIT_SR_OCIF);
}
void epit_counter_enable(uint32_t instance, uint32_t load_val, uint32_t irq_mode)
{
// set the load register especially if RLD=reload_mode=SET_AND_FORGET=1
// and if the value is different from 0 which is the lowest counter value
if (load_val != 0)
{
HW_EPIT_LR_WR(instance, load_val);
}
// ensure to start the counter in a proper state
// by clearing possible remaining compare event
HW_EPIT_SR_SET(instance, BM_EPIT_SR_OCIF);
// set the mode when the output compare event occur: IRQ or polling
if (irq_mode == IRQ_MODE)
{
HW_EPIT_CR_SET(instance, BM_EPIT_CR_OCIEN);
}
else
{
// polling
HW_EPIT_CR_CLR(instance, BM_EPIT_CR_OCIEN);
}
// finally, enable the counter
HW_EPIT_CR_SET(instance, BM_EPIT_CR_EN);
}
void epit_setup_interrupt(uint32_t instance, void (*irq_subroutine)(void), bool enableIt)
{
uint32_t irq_id = EPIT_IRQS(instance);
if (enableIt)
{
// register the IRQ sub-routine
register_interrupt_routine(irq_id, irq_subroutine);
// enable the IRQ
enable_interrupt(irq_id, CPU_0, 0);
}
else
{
// disable the IRQ
disable_interrupt(irq_id, CPU_0);
}
}
void epit_init(uint32_t instance, uint32_t clock_src, uint32_t prescaler,
uint32_t reload_mode, uint32_t load_val, uint32_t low_power_mode)
{
uint32_t control_reg_tmp = 0;
uint32_t base = REGS_EPIT_BASE(instance);
// enable the source clocks to the EPIT port
clock_gating_config(base, CLOCK_ON);
// start with a known state by disabling and reseting the module
HW_EPIT_CR_WR(instance, BM_EPIT_CR_SWR);
// wait for the reset to complete
while ((HW_EPIT_CR(instance).B.SWR) != 0) ;
// set the reference source clock for the counter
control_reg_tmp |= BF_EPIT_CR_CLKSRC(clock_src);
// set the counter clock prescaler value - 0 to 4095
control_reg_tmp |= BF_EPIT_CR_PRESCALAR(prescaler-1);
// set the reload mode
if (reload_mode == SET_AND_FORGET)
{
control_reg_tmp |= BM_EPIT_CR_RLD;
}
// set behavior for low power mode
if (low_power_mode & WAIT_MODE_EN)
{
control_reg_tmp |= BM_EPIT_CR_WAITEN;
}
if (low_power_mode & STOP_MODE_EN)
{
control_reg_tmp |= BM_EPIT_CR_STOPEN;
}
// make the counter start from a known value when enabled, this is loaded from
// EPITLR register if RLD=reload_mode=1 or 0xFFFFFFFF if RLD=reload_mode=0
control_reg_tmp |= BM_EPIT_CR_IOVW | BM_EPIT_CR_ENMOD;
// finally write the control register
HW_EPIT_CR_WR(instance, control_reg_tmp);
// initialize the load register especially if RLD=reload_mode=SET_AND_FORGET=1
// and if the value is different from 0 which is the lowest counter value
if (load_val != 0)
{
HW_EPIT_LR_WR(instance, load_val);
}
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,239 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file gpt.c
* @brief GPT driver source file.
*
* @ingroup diag_timer
*/
#include "sdk.h"
#include "gpt.h"
#include "imx_timer.h"
#include "registers/regsgpt.h"
#include "interrupt.h"
#include "ccm_pll.h"
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
static inline void gpt_clear_all_events(void)
{
HW_GPT_SR_WR(kGPTAllEvents);
}
uint32_t gpt_get_rollover_event(void)
{
// clear it if found set
if (HW_GPT_SR.B.ROV)
{
HW_GPT_SR_WR(BM_GPT_SR_ROV);
return kGPTRollover;
}
// return the read value before the bit was cleared
return 0;
}
uint32_t gpt_get_capture_event(uint8_t flag, uint32_t * capture_val)
{
// get the capture status bit
flag &= kGPTInputCapture1 | kGPTInputCapture2;
uint32_t status_register = HW_GPT_SR_RD() & flag;
// Read the captured timer value.
if (capture_val)
{
if (status_register == kGPTInputCapture1)
{
*(uint32_t *) capture_val = HW_GPT_ICR1.B.CAPT;
}
else if (status_register == kGPTInputCapture2)
{
*(uint32_t *) capture_val = HW_GPT_ICR2.B.CAPT;
}
}
// Clear the flag.
HW_GPT_SR_WR(status_register);
// return the read value before the bit was cleared
return status_register;
}
void gpt_set_capture_event(uint8_t cap_input, uint8_t cap_input_mode)
{
// set the new input mode
switch (cap_input)
{
case kGPTInputCapture1:
HW_GPT_CR.B.IM1 = cap_input_mode;
break;
case kGPTInputCapture2:
HW_GPT_CR.B.IM2 = cap_input_mode;
break;
}
}
uint32_t gpt_get_compare_event(uint8_t flag)
{
// get the active compare flags
flag &= kGPTOutputCompare1 | kGPTOutputCompare2 | kGPTOutputCompare3;
uint32_t status_register = HW_GPT_SR_RD() & flag;
// clear flags which are active
if (status_register)
{
HW_GPT_SR_WR(status_register);
}
// return the read value before the flags were cleared
return status_register;
}
void gpt_set_compare_event(uint8_t cmp_output, uint8_t cmp_output_mode, uint32_t cmp_value)
{
// set the value to compare with
switch (cmp_output)
{
case kGPTOutputCompare1:
BW_GPT_CR_OM1(cmp_output_mode);
HW_GPT_OCR1_WR(cmp_value);
break;
case kGPTOutputCompare2:
BW_GPT_CR_OM2(cmp_output_mode);
HW_GPT_OCR2_WR(cmp_value);
break;
case kGPTOutputCompare3:
BW_GPT_CR_OM3(cmp_output_mode);
HW_GPT_OCR3_WR(cmp_value);
break;
}
}
void gpt_counter_disable(void)
{
// disable the counter
HW_GPT_CR.B.EN = 0;
// ensure to leave the counter in a proper state by disabling the interrupt sources
HW_GPT_IR_WR(0);
// and by clearing possible remaining events
gpt_clear_all_events();
}
void gpt_counter_enable(uint32_t irq_mode)
{
// ensure to start the counter in a proper state by clearing possible remaining events
gpt_clear_all_events();
// enable the interrupts or clear the register for polling
HW_GPT_IR_WR(irq_mode & kGPTAllEvents);
// finally, enable the counter
HW_GPT_CR.B.EN = 1;
}
void gpt_setup_interrupt(void (*irq_subroutine)(void), bool enableIt)
{
uint32_t irq_id = IMX_INT_GPT;
if (enableIt)
{
// register the IRQ sub-routine
register_interrupt_routine(irq_id, irq_subroutine);
// enable the IRQ
enable_interrupt(irq_id, CPU_0, 0);
}
else
{
// disable the IRQ
disable_interrupt(irq_id, CPU_0);
}
}
void gpt_init(uint32_t clock_src, uint32_t prescaler, uint32_t counter_mode, uint32_t low_power_mode)
{
uint32_t control_reg_tmp = 0;
uint32_t base = GPT_BASE_ADDR;
// enable the source clocks to the GPT port
clock_gating_config(base, CLOCK_ON);
// start with a known state by disabling and reseting the module
HW_GPT_CR_WR(BM_GPT_CR_SWR);
// wait for the reset to complete
while (HW_GPT_CR.B.SWR != 0) ;
// set the reference source clock for the counter
if (clock_src == CLKSRC_CKIL)
{
// CKIL source is 0x4 for GPT but 0x3 for EPIT
clock_src++;
}
control_reg_tmp |= BF_GPT_CR_CLKSRC(clock_src);
// the prescaler can be changed at any time, and
// this affects the output clock immediately
HW_GPT_PR_WR(BF_GPT_PR_PRESCALER(prescaler - 1));
// set the counter mode
control_reg_tmp |= BF_GPT_CR_FRR(counter_mode);
// set behavior for low power mode
if (low_power_mode & WAIT_MODE_EN)
{
control_reg_tmp |= BM_GPT_CR_WAITEN;
}
if (low_power_mode & STOP_MODE_EN)
{
control_reg_tmp |= BM_GPT_CR_STOPEN;
}
// specify from where the counter starts to count when enabled
// this code makes it start from 0
control_reg_tmp |= BM_GPT_CR_ENMOD;
// finally write the control register
HW_GPT_CR_WR(control_reg_tmp);
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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 __IMX_I2C_INTERNAL_H__
#define __IMX_I2C_INTERNAL_H__
#include "imx_i2c.h"
#include "registers/regsi2c.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! Max number of operations to wait to receive ack.
#define WAIT_RXAK_LOOPS 1000000
//! Max number of operations to wait until busy.
#define WAIT_BUSY_LOOPS 100000
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Setup I2C interrupt.
*
* It enables or disables the related HW module interrupt, and attached the related
* sub-routine into the vector table.
*
* @param port Pointer to the I2C module structure.
* @param state Enable or disable the interrupt. Pass true to enable.
*/
void i2c_setup_interrupt(uint32_t instance, void (*irq_subroutine)(void), bool state);
/*!
* @brief I2C interrupt routine for slave transfers.
*/
void i2c_slave_interrupt_routine(void);
//! @brief Returns the I2C controller instance from a request struct.
unsigned i2c_get_request_instance(const imx_i2c_request_t * rq);
#if defined(__cplusplus)
}
#endif
#endif // __IMX_I2C_INTERNAL_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,184 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file timer.c
* @brief Basic timer functions
*
* @ingroup diag_timer
*/
#include <assert.h>
#include "imx_timer.h"
#include "sdk.h"
#include "epit.h"
#include "registers/regsarmglobaltimer.h"
#include "ccm_pll.h"
////////////////////////////////////////////////////////////////////////////////
// Prototypes
////////////////////////////////////////////////////////////////////////////////
static void time_init_global_timer();
////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////
uint32_t g_microsecondTimerMultiple=8;
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
void hal_delay_us(uint32_t usecs)
{
uint32_t instance = g_system_timer_port;
if (usecs == 0) {
return;
}
/* enable the counter first */
epit_counter_enable(instance, usecs, POLLING_MODE);
/* wait for the compare event */
while (!epit_get_compare_event(instance)) ;
/* disable the counter to save power */
epit_counter_disable(instance);
}
void system_time_init(void)
{
uint32_t freq;
// Init microsecond tick counter.
time_init_global_timer();
/* EPIT1 is used for the delay function */
/* Initialize the EPIT timer used for system time functions */
/* typical IPG_CLK is in MHz, so divide it to get a reference
clock of 1MHz => 1us per count */
freq = get_main_clock(IPG_CLK);
epit_init(g_system_timer_port, CLKSRC_IPG_CLK, freq / 1000000,
SET_AND_FORGET, 1000, WAIT_MODE_EN | STOP_MODE_EN);
}
#if defined(CHIP_MX6UL)
//! Init the ARM global timer to a microsecond-frequency clock.
void time_init_global_timer()
{
// Make sure the timer is off.
HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0;
HW_ARMGLOBALTIMER_CONTROL.B.FCR0 =1;
HW_ARMGLOBALTIMER_CONTROL.B.FCR1 =0;
HW_ARMGLOBALTIMER_CONTROL.B.DBG_ENABLE =0;
// Clear counter.
HW_ARMGLOBALTIMER_COUNTER_HI_WR(0);
HW_ARMGLOBALTIMER_COUNTER_LO_WR(0);
// Now turn on the timer.
HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1;
}
uint64_t time_get_microseconds()
{
// First read upper.
uint32_t upper = HW_ARMGLOBALTIMER_COUNTER_HI_RD();
uint32_t lower = HW_ARMGLOBALTIMER_COUNTER_LO_RD();
return (((uint64_t)upper << 32) | (uint64_t)lower)/8;
}
#else
//! Init the ARM global timer to a microsecond-frequency clock.
void time_init_global_timer()
{
// The ARM private peripheral clock is half the CPU clock.
uint32_t periphClock = get_main_clock(CPU_CLK) / 2;
uint32_t prescaler = (periphClock / 1000000) - 1;
// Divide down the prescaler until it fits into 8 bits. We add up the number of ticks
// it takes to equal a microsecond interval.
g_microsecondTimerMultiple = 1;
while (prescaler > 0xff)
{
prescaler /= 2;
++g_microsecondTimerMultiple;
}
// Make sure the timer is off.
HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0;
// Clear counter.
HW_ARMGLOBALTIMER_COUNTERn_WR(0, 0);
HW_ARMGLOBALTIMER_COUNTERn_WR(1, 0);
// Set prescaler and clear other flags.
HW_ARMGLOBALTIMER_CONTROL_WR(BF_ARMGLOBALTIMER_CONTROL_PRESCALER(prescaler));
// Now turn on the timer.
HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1;
}
uint64_t time_get_microseconds()
{
// First read upper.
uint32_t upper = HW_ARMGLOBALTIMER_COUNTERn_RD(1);
uint32_t lower;
while (true)
{
// Read lower.
lower = HW_ARMGLOBALTIMER_COUNTERn_RD(0);
// Read upper again.
uint32_t newUpper = HW_ARMGLOBALTIMER_COUNTERn_RD(1);
// If the first and second read of the upper bits are the same, then return.
if (newUpper == upper)
{
return (((uint64_t)upper << 32) | (uint64_t)lower) / g_microsecondTimerMultiple;
}
// Otherwise, start over again.
upper = newUpper;
}
return 0;
}
#endif
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,219 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file imx_uart.c
* @brief UART driver.
* @ingroup diag_uart
*/
#include "sdk.h"
#include "registers/regsuart.h"
#include "imx_uart.h"
#include "ccm_pll.h"
#include "interrupt.h"
#define UART_UFCR_RFDIV BF_UART_UFCR_RFDIV(4)
//#define UART_UFCR_RFDIV UART_UFCR_RFDIV_4
//#define UART_UFCR_RFDIV UART_UFCR_RFDIV_7
uint32_t uart_get_reffreq(uint32_t instance)
{
uint32_t div = UART_UFCR_RFDIV;
uint32_t ret = 0;
uint32_t freq = get_peri_clock(UART_MODULE_CLK(instance));
if (div == BF_UART_UFCR_RFDIV(4))
ret = freq / 2;
else if (div == BF_UART_UFCR_RFDIV(2))
ret = freq / 4;
else if (div == BF_UART_UFCR_RFDIV(6))
ret = freq / 7;
return ret;
}
uint8_t uart_putchar(uint32_t instance, uint8_t * ch)
{
/* Wait for Tx FIFO not full */
while (HW_UART_UTS(instance).B.TXFULL);
HW_UART_UTXD_WR(instance, *ch);
return *ch;
}
uint8_t uart_getchar(uint32_t instance)
{
uint32_t read_data;
/* If Rx FIFO has no data ready */
if (!(HW_UART_USR2(instance).B.RDR))
return NONE_CHAR;
read_data = HW_UART_URXD_RD(instance);
/* If error are detected */
if (read_data & 0x7C00)
return NONE_CHAR;
return (uint8_t) read_data;
}
void uart_set_FIFO_mode(uint32_t instance, uint8_t fifo, uint8_t trigger_level,
uint8_t service_mode)
{
if (fifo == TX_FIFO) {
/* Configure the TX_FIFO trigger level */
HW_UART_UFCR_CLR(instance,BM_UART_UFCR_TXTL);
HW_UART_UFCR_SET(instance, BF_UART_UFCR_TXTL(trigger_level));
/* Configure the TX_FIFO service mode */
/* Default mode is polling: IRQ and DMA requests are disabled */
HW_UART_UCR1_CLR(instance,(BM_UART_UCR1_TRDYEN | BM_UART_UCR1_TXDMAEN));
if (service_mode == DMA_MODE)
HW_UART_UCR1_SET(instance,BM_UART_UCR1_TXDMAEN);
else if (service_mode == IRQ_MODE)
HW_UART_UCR1_SET(instance,BM_UART_UCR1_TRDYEN);
} else { /* fifo = RX_FIFO */
/* Configure the RX_FIFO trigger level */
HW_UART_UFCR_CLR(instance,BM_UART_UFCR_RXTL);
HW_UART_UFCR_SET(instance,BF_UART_UFCR_RXTL(trigger_level));
/* Configure the RX_FIFO service mode */
/* Default mode is polling: IRQ and DMA requests are disabled */
HW_UART_UCR1_CLR(instance,(BM_UART_UCR1_RRDYEN | BM_UART_UCR1_RXDMAEN));
if (service_mode == DMA_MODE)
HW_UART_UCR1_SET(instance,BM_UART_UCR1_RXDMAEN);
else if (service_mode == IRQ_MODE)
HW_UART_UCR1_SET(instance,BM_UART_UCR1_RRDYEN);
}
}
void uart_set_loopback_mode(uint32_t instance, uint8_t state)
{
if (state == TRUE)
HW_UART_UTS_SET(instance, BM_UART_UTS_LOOP);
else
HW_UART_UTS_CLR(instance, BM_UART_UTS_LOOP);
}
void uart_setup_interrupt(uint32_t instance, void (*irq_subroutine)(void), uint8_t state)
{
uint32_t irq_id = UART_IRQS(instance);
if (state == TRUE) {
/* register the IRQ sub-routine */
register_interrupt_routine(irq_id, irq_subroutine);
/* enable the IRQ */
enable_interrupt(irq_id, CPU_0, 0);
} else
/* disable the IRQ */
disable_interrupt(irq_id, CPU_0);
}
void uart_init(uint32_t instance, uint32_t baudrate, uint8_t parity,
uint8_t stopbits, uint8_t datasize, uint8_t flowcontrol)
{
uint32_t base = REGS_UART_BASE(instance);
/* configure the I/O for the port */
uart_iomux_config(instance);
/* enable the source clocks to the UART port */
clock_gating_config(base, CLOCK_ON);
/* Wait for UART to finish transmitting before changing the configuration */
while (!(HW_UART_UTS(instance).B.TXEMPTY)) ;
/* Disable UART */
HW_UART_UCR1_CLR(instance,BM_UART_UCR1_UARTEN );
/* Configure FIFOs trigger level to half-full and half-empty */
HW_UART_UFCR_WR(instance, BF_UART_UFCR_RXTL(16) | UART_UFCR_RFDIV | BF_UART_UFCR_TXTL(16));
/* Setup One Millisecond timer */
HW_UART_ONEMS_WR(instance, uart_get_reffreq(instance) / 1000);
/* Set parity */
if (parity == PARITY_NONE)
HW_UART_UCR2_CLR(instance,(BM_UART_UCR2_PREN| BM_UART_UCR2_PROE));
else if (parity == PARITY_ODD)
HW_UART_UCR2_SET(instance,(BM_UART_UCR2_PREN| BM_UART_UCR2_PROE));
else { /* parity == PARITY_EVEN */
HW_UART_UCR2_SET(instance, BM_UART_UCR2_PREN);
HW_UART_UCR2_CLR(instance, BM_UART_UCR2_PROE);
}
/* Set stop bit */
if (stopbits == STOPBITS_ONE)
HW_UART_UCR2_CLR(instance, BM_UART_UCR2_STPB);
else /* stopbits == STOPBITS_TWO */
HW_UART_UCR2_SET(instance, BM_UART_UCR2_STPB);
/* Set data size */
if (datasize == EIGHTBITS)
HW_UART_UCR2_SET(instance, BM_UART_UCR2_WS);
else /* stopbits == STOPBITS_TWO */
HW_UART_UCR2_CLR(instance, BM_UART_UCR2_WS);
/* Configure the flow control */
if (flowcontrol == FLOWCTRL_ON) {
/* transmit done when RTS asserted */
HW_UART_UCR2_CLR(instance, BM_UART_UCR2_IRTS );
/* CTS controlled by the receiver */
HW_UART_UCR2_SET(instance, BM_UART_UCR2_CTSC );
} else { /* flowcontrol == FLOWCTRL_OFF */
/* Ignore RTS */
HW_UART_UCR2_SET(instance, BM_UART_UCR2_IRTS);
/* CTS controlled by the CTS bit */
HW_UART_UCR2_CLR(instance, BM_UART_UCR2_CTSC);
}
/* the reference manual says that this bit must always be set */
HW_UART_UCR3_SET(instance, BM_UART_UCR3_RXDMUXSEL);
/* Enable UART */
HW_UART_UCR1_SET(instance, BM_UART_UCR1_UARTEN);
/* Enable FIFOs and does software reset to clear status flags, reset
the transmit and receive state machine, and reset the FIFOs */
HW_UART_UCR2_SET(instance, BM_UART_UCR2_TXEN | BM_UART_UCR2_RXEN | BM_UART_UCR2_SRST);
/* Set the numerator value minus one of the BRM ratio */
HW_UART_UBIR_WR(instance, (baudrate / 100) - 1);
/* Set the denominator value minus one of the BRM ratio */
HW_UART_UBMR_WR(instance, ((uart_get_reffreq(instance) / 1600) - 1));
/* Optional: prevent the UART to enter debug state. Useful when debugging
the code with a JTAG and without active IRQ */
HW_UART_UTS_SET(instance, BM_UART_UTS_DBGEN);
}

View File

@@ -0,0 +1,170 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
//! @addtogroup diag_epit
//! @{
/*!
* @file epit.h
* @brief EPIT driver public interface.
*/
#ifndef __EPIT_H__
#define __EPIT_H__
#include "imx_timer.h"
#include "sdk.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Free running reload mode.
//!
//! When the counter reaches zero it rolls over to 0xFFFF_FFFF.
#define FREE_RUNNING 0
//! @brief Set and forget reload mode.
//!
//! When the counter reaches zero it reloads from the modulus register.
#define SET_AND_FORGET 1
//! @brief Pass to epit_counter_enable() to enable interrupts.
#define IRQ_MODE 1
//! @brief Get the irq id of RPIT by instance number.
//! @param x I2C instance number, from 1 through 2.
#define EPIT_IRQS(x) ( (x) == HW_EPIT1 ? IMX_INT_EPIT1 : (x) == HW_EPIT2 ? IMX_INT_EPIT2 : 0xFFFFFFFF)
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initialize the EPIT timer.
*
* @param instance the EPIT instance number.
* @param clock_src Source clock of the counter: CLKSRC_OFF, CLKSRC_IPG_CLK,
* CLKSRC_PER_CLK, CLKSRC_CKIL.
* @param prescaler Prescaler of source clock from 1 to 4096.
* @param reload_mode Counter reload mode: FREE_RUNNING or SET_AND_FORGET.
* @param load_val Load value from where the counter start.
* @param low_power_mode Low power during which the timer is enabled:
* WAIT_MODE_EN and/or STOP_MODE_EN.
*/
void epit_init(uint32_t instance, uint32_t clock_src, uint32_t prescaler,
uint32_t reload_mode, uint32_t load_val, uint32_t low_power_mode);
/*!
* @brief Setup EPIT interrupt.
*
* It enables or disables the related HW module interrupt, and attached the related sub-routine
* into the vector table.
*
* @param instance the EPIT instance number.
* @param irq_subroutine the EPIT interrupt interrupt routine.
* @param enableIt True to enable the interrupt, false to disable.
*/
void epit_setup_interrupt(uint32_t instance, void (*irq_subroutine)(void), bool enableIt);
/*!
* @brief Enable the EPIT module.
*
* Used typically when the epit_init is done, and other interrupt related settings are ready.
*
* In interrupt mode, when the interrupt fires you should call epit_get_compare_event() to
* clear the compare flag.
*
* @param instance the EPIT instance number.
* @param load_val Load value from where the counter starts.
* @param irq_mode Interrupt mode: IRQ_MODE or POLLING_MODE.
*/
void epit_counter_enable(uint32_t instance, uint32_t load_val, uint32_t irq_mode);
/*!
* @brief Disable the counter.
*
* It saves energy when not used.
*
* @param instance the EPIT instance number.
*/
void epit_counter_disable(uint32_t instance);
/*!
* @brief Get the output compare status flag and clear it if set.
*
* This function can typically be used for polling method, but
* is also used to clear the status compare flag in IRQ mode.
*
* @param instance the EPIT instance number.
* @return Value of the compare event flag.
*/
uint32_t epit_get_compare_event(uint32_t instance);
/*!
* @brief Set the output compare register.
*
*
* @param instance the EPIT instance number.
* @param Value of the compare register.
*/
void epit_set_compare_event(uint32_t instance, uint32_t compare_val);
/*!
* @brief Get the counter value.
*
*
* @param instance the EPIT instance number.
* @return Value of the counter register.
*/
uint32_t epit_get_counter_value(uint32_t instance);
/*!
* @brief Reload the counter with a known value.
*
* @param instance the EPIT instance number.
* @param load_val Value loaded into the timer counter.
*/
void epit_reload_counter(uint32_t instance, uint32_t load_val);
#if defined(__cplusplus)
}
#endif
//! @}
#endif //__EPIT_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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 __GIC_H__
#define __GIC_H__
#include "sdk_types.h"
//! @addtogroup gic
//! @{
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Options for sending a software generated interrupt.
//!
//! These options are used for the @a filter_list parameter of the gic_send_sgi()
//! function. They control how to select which CPUs that the interrupt is
//! sent to.
enum _gicd_sgi_filter
{
//! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter.
kGicSgiFilter_UseTargetList = 0,
//! Forward the interrupt to all CPU interfaces except that of the processor that requested
//! the interrupt.
kGicSgiFilter_AllOtherCPUs = 1,
//! Forward the interrupt only to the CPU interface of the processor that requested the
//! interrupt.
kGicSgiFilter_OnlyThisCPU = 2
};
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
//! @name Initialization
//@{
//! @brief Init interrupt handling.
//!
//! This function is intended to be called only by the primary CPU init code, so it will
//! only be called once during system bootup.
//!
//! Also inits the current CPU. You don't need to call gic_init_cpu() separately.
//!
//! @post The interrupt distributor and the current CPU interface are enabled. All interrupts
//! that were pending are cleared, and all interrupts are made secure (group 0).
void gic_init(void);
//! @brief Init the current CPU's GIC interface.
//!
//! @post Enables the CPU interface and sets the priority mask to 255. Interrupt preemption
//! is disabled by setting the Binary Point to a value of 7.
void gic_init_cpu(void);
//@}
//! @name GIC Interrupt Distributor Functions
//@{
//! @brief Enable or disable the GIC Distributor.
//!
//! Enables or disables the GIC distributor passing both secure (group 0) and non-secure
//! (group 1) interrupts to the CPU interfaces.
//!
//! @param enableIt Pass true to enable or false to disable.
void gic_enable(bool enableIt);
//! @brief Set the security mode for an interrupt.
//!
//! @param irqID The interrupt number.
//! @param isSecure Whether the interrupt is taken to secure mode.
void gic_set_irq_security(uint32_t irqID, bool isSecure);
//! @brief Enable or disable an interrupt.
//!
//! @param irqID The number of the interrupt to control.
//! @param isEnabled Pass true to enable or false to disable.
void gic_enable_irq(uint32_t irqID, bool isEnabled);
//! @brief Set whether a CPU will receive a particular interrupt.
//!
//! @param irqID The interrupt number.
//! @param cpuNumber The CPU number. The first CPU core is 0.
//! @param enableIt Whether to send the interrupt to the specified CPU. Pass true to enable
//! or false to disable.
void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt);
//! @brief Set an interrupt's priority.
//!
//! @param irq_id The interrupt number.
//! @param priority The priority for the interrupt. In the range of 0 through 0xff, with
//! 0 being the highest priority.
void gic_set_irq_priority(uint32_t irq_id, uint32_t priority);
//! @brief Send a software generated interrupt to a specific CPU.
//!
//! @param irq_id The interrupt number to send.
//! @param target_list Each bit indicates a CPU to which the interrupt will be forwarded.
//! Bit 0 is CPU 0, bit 1 is CPU 1, and so on. If the value is 0, then the interrupt
//! will not be forwarded to any CPUs. This parameter is only used if @a filter_list
//! is set to #kGicSgiFilter_UseTargetList.
//! @param filter_list One of the enums of the #_gicd_sgi_filter enumeration. The selected
//! option determines which CPUs the interrupt will be sent to. If the value
//! is #kGicSgiFilter_UseTargetList, then the @a target_list parameter is used.
void gic_send_sgi(uint32_t irq_id, uint32_t target_list, uint32_t filter_list);
//@}
//! @name GIC CPU Interface Functions
//@{
//! @brief Enable or disable the interface to the GIC for the current CPU.
//!
//! @param enableIt Pass true to enable or false to disable.
void gic_cpu_enable(bool enableIt);
//! @brief Set the mask of which interrupt priorities the CPU will receive.
//!
//! @param priority The lowest priority that will be passed to the current CPU. Pass 0xff to
//! allow all priority interrupts to signal the CPU.
void gic_set_cpu_priority_mask(uint32_t priority);
//! @brief Acknowledge starting of interrupt handling and get the interrupt number.
//!
//! Normally, this function is called at the beginning of the IRQ handler. It tells the GIC
//! that you are starting to handle an interupt, and returns the number of the interrupt you
//! need to handle. After the interrupt is handled, you should call gic_write_end_of_irq()
//! to signal that the interrupt is completely handled.
//!
//! In some cases, a spurious interrupt might happen. One possibility is if another CPU handles
//! the interrupt. When a spurious interrupt occurs, the end of the interrupt should be indicated
//! but nothing else.
//!
//! @return The number for the highest priority interrupt available for the calling CPU. If
//! the return value is 1022 or 1023, a spurious interrupt has occurred.
uint32_t gic_read_irq_ack(void);
//! @brief Signal the end of handling an interrupt.
//!
//! @param irq_id The number of the interrupt for which handling has finished.
void gic_write_end_of_irq(uint32_t irq_id);
//@}
#if defined(__cplusplus)
}
#endif
//! @}
#endif // __GIC_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,224 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
//! @addtogroup diag_gpt
//! @{
/*!
* @file gpt.h
* @brief GPT driver public interface.
*/
#ifndef __GPT_H__
#define __GPT_H__
#include "imx_timer.h"
#include "sdk.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Possible events for the GPT.
//!
//! These constants are intended to be combined together to form a bitmask. Several
//! of the GPT driver APIs use such a bitmask. For instance, gpt_counter_enable()
//! accepts a bitmask that selects the events for which interrupts should be enabled.
//!
//! Note that the values of these enums happen to be the bitmasks for the respective
//! fields in the HW_GPT_SR and HW_GPT_IR registers, so a mask constructed from them
//! can be used directly with register values.
enum _gpt_events
{
kGPTNoEvent = 0, //!< No events enabled.
kGPTRollover = 1 << 5, //!< Rollover event.
kGPTInputCapture1 = 1 << 3, //!< Input capture 1 event.
kGPTInputCapture2 = 1 << 4, //!< Input capture 2 event.
kGPTOutputCompare1 = 1 << 0, //!< Output compare 1 event.
kGPTOutputCompare2 = 1 << 1, //!< Output compare 2 event.
kGPTOutputCompare3 = 1 << 2, //!< Output compare 3 event.
//! Combined mask of all GPT events.
kGPTAllEvents = kGPTRollover | kGPTInputCapture1 | kGPTInputCapture2
| kGPTOutputCompare1 | kGPTOutputCompare2 | kGPTOutputCompare3
};
//! @brief GPT counter modes.
enum _gpt_counter_mode
{
RESTART_MODE = 0,
FREE_RUN_MODE = 1
};
//! @brief Supported input capture modes.
enum _gpt_capture_modes
{
INPUT_CAP_DISABLE = 0, //!< input capture event disabled
INPUT_CAP_RISING_EDGE = 1, //!< input capture event on a rising edge
INPUT_CAP_FALLING_EDGE = 2, //!< input capture event on a falling edge
INPUT_CAP_BOTH_EDGE = 3 //!< input capture event on a both edge
};
//! @brief Supported output modes.
enum _gpt_compare_modes
{
OUTPUT_CMP_DISABLE = 0, //!< output disconnected from pad
OUTPUT_CMP_TOGGLE = 1, //!< output toggle mode
OUTPUT_CMP_CLEAR = 2, //!< output set low mode
OUTPUT_CMP_SET = 3, //!< output set high mode
OUTPUT_CMP_LOWPULSE = 4 //!< output set high mode
};
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initialize the GPT timer.
*
* @param clock_src Source clock of the counter: CLKSRC_OFF, CLKSRC_IPG_CLK,
* CLKSRC_PER_CLK, CLKSRC_CKIL, CLKSRC_CLKIN.
* @param prescaler Prescaler of the source clock from 1 to 4096.
* @param counter_mode Counter mode: FREE_RUN_MODE or RESTART_MODE.
* @param low_power_mode Low power during which the timer is enabled:
* WAIT_MODE_EN and/or STOP_MODE_EN.
*/
void gpt_init(uint32_t clock_src, uint32_t prescaler, uint32_t counter_mode, uint32_t low_power_mode);
/*!
* @brief Setup GPT interrupt.
*
* It enables or disables the related HW module interrupt, and attached the
* related sub-routine into the vector table.
*
* @param irq_subroutine the GPT interrupt interrupt routine.
* @param enableIt Pass true to enable the interrupt.
*/
void gpt_setup_interrupt(void (*irq_subroutine)(void), bool enableIt);
/*!
* @brief Enable the GPT module.
*
* Used typically when the gpt_init is done, and other interrupt related settings are ready.
*
* If a value of #kGPTNoEvent is passed for @a irq_mode, then no interrupts will be enabled.
* This effectively puts the timer into polling mode, where you must call gpt_get_x_event()
* to check for an event having occurred.
*
* @param irq_mode Mask of events to enable interrupts for, such as #kGPTRollover or
* #kGPTOutputCompare1. See the #_gpt_events enum for the complete list. Pass
* #kGPTNoEvent to prevent any interrupts from being enabled, which effectively puts
* the timer into polling mode.
*/
void gpt_counter_enable(uint32_t irq_mode);
/*!
* @brief Disable the counter.
*
* It saves power when not used.
*
*/
void gpt_counter_disable(void);
/*!
* @brief Get rollover event flag and clear it if set.
*
* This function can typically be used for polling method, but
* is also used to clear the status compare flag in IRQ mode.
*
* @return Either 0 of kGPTRollover.
*/
uint32_t gpt_get_rollover_event(void);
/*!
* @brief Get a captured value when an event occured, and clear the flag if set.
*
* Use this function to check for an input capture event having occurred, either in
* the event ISR or to check manually in polling mode. Pass the input channel to check
* in the @a flag parameter. If that channel fired, its captured timer value will be
* read and placed in @a capture_val (if not NULL). The event that fired will be cleared
* and its event mask returned as the return value from the function. If no event
* occurred, the function returns 0.
*
* @param flag Which channel to check, either #kGPTInputCapture1 or #kGPTInputCapture2.
* Only one channel may be specified.
* @param capture_val The capture register value is returned through this parameter if
* the specified event occurred. May be NULL if not required.
* @return Mask of input specified capture event that occurred, or 0 if no event occurred.
*/
uint32_t gpt_get_capture_event(uint8_t flag, uint32_t * capture_val);
/*!
* @brief Set the input capture mode.
*
* @param cap_input The input capture channel to configure, either #kGPTInputCapture1
* or #kGPTInputCapture2.
* @param cap_input_mode Capture input mode: #INPUT_CAP_DISABLE, #INPUT_CAP_BOTH_EDGE,
* #INPUT_CAP_FALLING_EDGE, #INPUT_CAP_RISING_EDGE.
*/
void gpt_set_capture_event(uint8_t cap_input, uint8_t cap_input_mode);
/*!
* @brief Get a compare event flag and clear it if set.
*
* This function can typically be used for polling method, but
* is also used to clear the status compare flag in IRQ mode.
*
* @param flag Checked compare event flag such GPTSR_OF1, GPTSR_OF2, GPTSR_OF3.
* @return The value of the compare event flag.
*/
uint32_t gpt_get_compare_event(uint8_t flag);
/*!
* @brief Set a compare event by programming the compare register and
* compare output mode.
*
* @param cmp_output The channel to configure. Must be one of #kGPTOutputCompare1,
* #kGPTOutputCompare2, or #kGPTOutputCompare3.
* @param cmp_output_mode Compare output mode: #OUTPUT_CMP_DISABLE, #OUTPUT_CMP_TOGGLE,
* #OUTPUT_CMP_CLEAR, #OUTPUT_CMP_SET, #OUTPUT_CMP_LOWPULSE.
* @param cmp_value Compare value for the compare register.
*/
void gpt_set_compare_event(uint8_t cmp_output, uint8_t cmp_output_mode, uint32_t cmp_value);
#if defined(__cplusplus)
}
#endif
//! @}
#endif //__GPT_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,232 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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 __IMX_I2C_H__
#define __IMX_I2C_H__
#include "sdk_types.h"
//! @addtogroup diag_i2c
//! @{
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Read/write address bits
//!
//! Bit 0 of the i2c device address cycle to indicate r/w. 0 is for write, 1 is for read.
enum _i2c_rq {
I2C_WRITE = 0,
I2C_READ = 1
};
//! @brief I2C Error Codes
enum _i2c_err {
ERR_TX = -1,
ERR_RX = -2,
ERR_ARB_LOST = -3,
ERR_NO_ACK = -4,
ERR_XFER = -5,
ERR_RX_ACK = -6,
ERR_NO_ACK_ON_START = -7,
ERR_INVALID_REQUEST = -8
};
//! Default slave address used for the MX6.
enum _i2c_slave_id {
IMX6_DEFAULT_SLAVE_ID = 0x60
};
//! @brief Info required to talk to an I2C device.
//!
//! Pairs an I2C port number with a device address.
//!
//! While the device address is often fixed and known in advance by the driver,
//! some devices have configurable addresses that can be changed with pin
//! settings. Thus, the same device may have different adresses on different
//! boards depending on how these pins are tied.
//!
//! Note that the @a address member's value is @i not pre-shifted. The 7-bit
//! address is right aligned within the byte, and the top bit is always set to 0.
typedef struct i2c_device_info {
uint8_t port; //!< I2C controller instance to which the device is connected. Starts at 1.
uint8_t address; //!< I2C device address in lower 7 bits.
uint32_t freq; //!< Maximum transfer speed in bits per second.
} i2c_device_info_t;
/*!
* @brief An I2C transfer descriptor.
*
* To perform an I2C transfer, the caller first fills in an instance of this struct. Then
* i2c_xfer() is called, passing a pointer to the #imx_i2c_request_t struct.
*
* @a ctl_addr should be set to either a valid controller instance number from 1 through
* the number of I2C instances on the chip, or the base address of the controller.
*
* If @a device is set to a non-NULL value, it is a pointer to an #i2c_device_info_t struct
* to use instead of the @a ctl_addr and @a dev_addr members of this struct.
*/
typedef struct imx_i2c_request {
uint32_t ctl_addr; //!< Either the I2C controller base address or instance number starting at 1.
uint32_t dev_addr; //!< The I2C device address.
uint32_t reg_addr; //!< The register address within the target device.
uint32_t reg_addr_sz; //!< Number of bytes for the address of I2C device register.
uint8_t *buffer; //!< Buffer to hold the data.
uint32_t buffer_sz; //!< The number of bytes for read/write.
int32_t (*slave_receive) (const struct imx_i2c_request *rq); //!< Function for slave to receive data from master.
int32_t (*slave_transmit) (const struct imx_i2c_request *rq); //!< Function for slave to transmit data to master.
const i2c_device_info_t * device; //!< Optional pointer to device info struct. Overrides @a ctl_addr and @a dev_addr if set.
} imx_i2c_request_t;
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Initialize the I2C module
*
* Mainly enable the I2C clock, module itself and the I2C clock prescaler.
*
* @param base Either the base address of I2C module or the module's instance number. (also assigned for I2Cx_CLK)
* @param baud The desired data rate in bits per second.
*
* @return 0 if successful; non-zero otherwise
*/
int i2c_init(uint32_t base, uint32_t baud);
/*!
* @brief Perform a single I2C transfer in the selected direction.
*
* This is a rather simple function that can be used for most I2C devices.
*
* Common steps for both READ and WRITE:
* - step 1: issue start signal
* - step 2: put I2C device addr on the bus (always 1 byte write. the dir always I2C_WRITE)
* - step 3: offset of the I2C device write (offset within the device. can be 1-4 bytes)
*
* For READ:
* - step 4: do repeat-start
* - step 5: send slave address again, but indicate a READ operation by setting LSB bit
* - Step 6: change to receive mode
* - Step 7: dummy read
* - Step 8: reading
*
* For WRITE:
* - Step 4: do data write
* - Step 5: generate STOP by clearing MSTA bit
*
* @param rq Pointer to #imx_i2c_request_t.
* @param dir #I2C_READ or #I2C_WRITE
*
* @return 0 on success; non-zero otherwise
*/
int i2c_xfer(const imx_i2c_request_t *rq, int dir);
/*!
* @brief Perform I2C read transfer.
*
* @param rq Pointer to #imx_i2c_request_t.
*/
int i2c_read(const imx_i2c_request_t *rq);
/*!
* @brief Perform I2C write transfer.
*
* @param rq Pointer to #imx_i2c_request_t.
*/
int i2c_write(const imx_i2c_request_t *rq);
/*!
* @brief I2C handler for the slave mode.
*
* The function is based on the flow chart for typical I2C polling routine described in the
* I2C controller chapter of the reference manual.
*
* @param rq Pointer to #imx_i2c_request_t.
*/
void i2c_slave_handler(const imx_i2c_request_t *rq);
/*!
* @brief Handle the I2C transfers in slave mode.
*
* The slave mode behaves like any device with g_addr_cycle of address + g_data_cycle of data.
* Master read =
* START - SLAVE_ID/W - ACK - MEM_ADDR - ACK - START - SLAVE_ID/R - ACK - DATAx - NACK - STOP
*
* Example for a 16-bit address access:
* - 1st IRQ - receive the slave address and Write flag from master.
* - 2nd IRQ - receive the lower byte of the requested 16-bit address.
* - 3rd IRQ - receive the higher byte of the requested 16-bit address.
* - 4th IRQ - receive the slave address and Read flag from master.
* - 5th and next IRQ - transmit the data as long as NACK and STOP is not asserted.
*
* Master write =
* START - SLAVE_ID/W - ACK - MEM_ADDR - ACK - DATAx - NACK - STOP
*
* - 1st IRQ - receive the slave address and Write flag from master.
* - 2nd IRQ - receive the lower byte of the requested 16-bit address.
* - 3rd IRQ - receive the higher byte of the requested 16-bit address.
* - 4th and next IRQ - receive the data as long STOP is not asserted.
*
* @param port Pointer to the I2C module structure.
* @param rq Pointer to #imx_i2c_request_t.
*/
void i2c_slave_xfer(imx_i2c_request_t *rq);
////////////////////////////////////////////////////////////////////////////////
// Board support
////////////////////////////////////////////////////////////////////////////////
//! @name Board support functions
//!
//! These functions are called by the driver in order to factor out board
//! specific functionality. They must be defined by the board support
//! library or the application.
//@{
//! @brief Configure IOMUX for the I2C driver.
void i2c_iomux_config(int instance);
//@}
#if defined(__cplusplus)
}
#endif
//! @}
#endif /* __IMX_I2C_H__ */
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
//! @addtogroup diag_timer
//! @{
/*!
* @file timer.h
* @brief various defines used by the timer driver.
*/
#ifndef __TIMER_H__
#define __TIMER_H__
#include "sdk.h"
////////////////////////////////////////////////////////////////////////////////
// Constants
////////////////////////////////////////////////////////////////////////////////
//! @brief Options for low power mode support for the timers.
//!
//! These constants are bit masks that are or'd together to select in which low
//! power modes the timer will continue counting.
enum _timer_low_power_modes
{
WAIT_MODE_EN = 1, //!< Timer is enabled in wait mode.
STOP_MODE_EN = 2 //!< Timer is enabled in stop mode.
};
//! @brief Available clock sources for the timers.
enum _timer_clock_sources
{
CLKSRC_OFF = 0, //!< clock source is OFF
CLKSRC_IPG_CLK = 1, //!< clock source is peripheral clock
CLKSRC_PER_CLK = 2, //!< clock source is high-freq reference clock
CLKSRC_CLKIN = 3, //!< clock source is external from a CLKIN input
CLKSRC_CKIL = 3 //!< clock source is low-freq reference clock
};
//! @brief Do not enable interrupts.
#define POLLING_MODE 0
////////////////////////////////////////////////////////////////////////////////
// Externs
////////////////////////////////////////////////////////////////////////////////
extern uint32_t g_system_timer_port;
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
//! @brief Delay for a given number of microseconds.
//!
//! system_time_init() must have been called before using this function.
//!
//! @param usecs Delay in microseconds.
void hal_delay_us(uint32_t usecs);
//! @brief Init system timer facilities.
//!
//! Inits the EPIT timer used for delay, and inits the microsecond counter.
void system_time_init(void);
//! @brief Return the current microsecond counter value.
//!
//! @return The number of microseconds elapsed since system_time_init()
//! was called. This value may roll over before reaching all ones.
uint64_t time_get_microseconds();
#if defined(__cplusplus)
}
#endif
//! @}
#endif // __TIMER_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 2010-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file imx_uart.h
* @brief various defines used by imx_uart.c
*/
#ifndef __IMX_UART_H__
#define __IMX_UART_H__
#include "sdk.h"
//! @addtogroup diag_uart
//! @{
//////////////////////////////////////////////////////////////////////////
//Constants
/////////////////////////////////////////////////////////////////////////
/* UART specific defines */
//! @brief Modes of the PARITY for UART transfer.
enum _uart_parity
{
PARITY_NONE = 0, //!< PARITY mode is PARITY_NONE.
PARITY_EVEN = 2, //!< PARITY mode is PARITY_EVEN.
PARITY_ODD = 3 //!< PARITY mode is PARITY_ODD.
};
//! @brief Number of stopbits after a character.
enum _uart_stopbits
{
STOPBITS_ONE = 0, //!< One stopbits after a character.
STOPBITS_TWO = 1 //!< Two stopbits after a character.
};
//! @brief Flow control mode for UART transfer.
enum _uart_flowctrl
{
FLOWCTRL_OFF = 0, //!< Flow control off for UART transfer.
FLOWCTRL_ON = 1 //!< Flow control on for UART transfer.
};
//! @brief Specify the FIFO for UART transfer.
enum _uart_fifo
{
TX_FIFO = 0, //!< Config the TX fifo for UART transfer.
RX_FIFO = 1 //!< Config the RX fifo for UART transfer.
};
//! @brief Specify the number of bits in a data
enum _uart_bits
{
SEVENBITS = 0, //!< Config seven bits in a data.
EIGHTBITS = 1 //!< Config eight bits in a data.
};
//! @brief Specify the service mode
#define DMA_MODE 2 //!< Config the service mode for dma request.
#define IRQ_MODE 1 //!< Config the service mode for interrupt.
#define UART_MODULE_CLK(x) ((x) == HW_UART1 ? UART1_MODULE_CLK : (x) == HW_UART2 ? UART2_MODULE_CLK : (x) == HW_UART3 ? UART3_MODULE_CLK : (x) == HW_UART4 ? UART4_MODULE_CLK : -1)
#define UART_IRQS(x) ((x) == HW_UART1 ? IMX_INT_UART1 : (x) == HW_UART2 ? IMX_INT_UART2 : (x) == HW_UART3 ? IMX_INT_UART3 : (x) == HW_UART4 ? IMX_INT_UART4 : (x) == HW_UART5 ? IMX_INT_UART5 : 0xFFFFFFFF)
//////////////////////////////////////////////////////////////////////////
//API
/////////////////////////////////////////////////////////////////////////
/*!
* @brief Initialize the UART port
*
* @param instance the UART instance number.
* @param baudrate serial baud rate such 9600, 57600, 115200, etc.
* @param parity enable parity checking: PARITY_NONE, PARITY_EVEN,
* PARITY_ODD.
* @param stopbits number of stop bits: STOPBITS_ONE, STOPBITS_TWO.
* @param datasize number of bits in a data: SEVENBITS, EIGHTBITS,
* NINEBITS (like RS-485 but not supported).
* @param flowcontrol enable (RTS/CTS) hardware flow control:
* FLOWCTRL_ON, FLOWCTRL_OFF.
*/
void uart_init(uint32_t instance, uint32_t baudrate, uint8_t parity,uint8_t stopbits, uint8_t datasize, uint8_t flowcontrol);
/*!
* @brief Output a character to UART port
*
* @param instance the UART instance number.
* @param ch pointer to the character for output
* @return the character that has been sent
*/
uint8_t uart_putchar(uint32_t instance, uint8_t * ch);
/*!
* @brief Receive a character on the UART port
*
* @param instance the UART instance number.
* @return a character received from the UART port; if the RX FIFO
* is empty or errors are detected, it returns NONE_CHAR
*/
uint8_t uart_getchar(uint32_t instance);
/*!
* @brief Configure the RX or TX FIFO level and trigger mode
*
* @param instance the UART instance number.
* @param fifo FIFO to configure: RX_FIFO or TX_FIFO.
* @param trigger_level set the trigger level of the FIFO to generate
* an IRQ or a DMA request: number of characters.
* @param service_mode FIFO served with DMA or IRQ or polling (default).
*/
void uart_set_FIFO_mode(uint32_t instance, uint8_t fifo, uint8_t trigger_level,
uint8_t service_mode);
/*!
* @brief Enables UART loopback test mode
*
* @param instance the UART instance number.
* @param state enable/disable the loopback mode
*/
void uart_set_loopback_mode(uint32_t instance, uint8_t state);
/*!
* @brief Setup UART interrupt. It enables or disables the related HW module
* interrupt, and attached the related sub-routine into the vector table.
*
* @param instance the UART instance number.
* @param irq_subroutine the UART interrupt interrupt routine.
* @param state ENABLE or DISABLE the interrupt.
*/
void uart_setup_interrupt(uint32_t instance, void (*irq_subroutine)(void), uint8_t state);
/*!
* @brief Obtain UART reference frequency
*
* @param instance the UART instance number.
* @return reference frequency in Hz
*/
uint32_t uart_get_reffreq(uint32_t instance);
//! @name Board support functions
//!
//! These functions are called by the driver in order to factor out board
//! specific functionality. They must be defined by the board support
//! library or the application.
//@{
//! @brief Configure IOMUX for the UART driver.
void uart_iomux_config(int instance);
//@}
//! @}
#endif //__IMX_UART_H__

View File

@@ -0,0 +1,101 @@
/*
* Copyright (c) 2009-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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 __INTERRUPT_H__
#define __INTERRUPT_H__
#include "sdk_types.h"
#include "irq_numbers.h"
//! @addtogroup diag_interrupt
//! @{
/*!
* @file interrupt.h
* @brief Interface for the interrupt manager.
*/
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief
typedef enum {
CPU_0,
CPU_1,
CPU_2,
CPU_3,
} cpuid_e;
//! @brief Interrupt service routine.
typedef void (*irq_hdlr_t) (void);
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
//! @brief Enable an interrupt.
//!
//! Sets the interrupt priority and makes it non-secure. Then the interrupt is
//! enabled on the CPU specified by @a cpu_id.
//!
//! @param irq_id The interrupt number to enable.
//! @param cpu_id The index of the CPU for which the interrupt will be enabled.
//! @param priority The interrupt priority, from 0-255. Lower numbers have higher priority.
void enable_interrupt(uint32_t irq_id, uint32_t cpu_id, uint32_t priority);
//! @brief Disable an interrupt on the specified CPU.
//!
//! @param irq_id The interrupt number to disabled.
//! @param cpu_id The index of the CPU for which the interrupt will be disabled.
void disable_interrupt(uint32_t irq_id, uint32_t cpu_id);
//! @brief Set the interrupt service routine for the specified interrupt.
//!
//! @param irq_id The interrupt number.
//! @param isr Function that will be called to handle the interrupt.
void register_interrupt_routine(uint32_t irq_id, irq_hdlr_t isr);
//! @brief Interrupt handler that simply prints a message.
void default_interrupt_routine(void);
#if defined(__cplusplus)
}
#endif
//! @}
#endif
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,144 @@
/*
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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.
*/
/*!
* @file io.h
* @brief Register access macros.
*
* @ingroup diag_init
*/
#ifndef __IO_H__
#define __IO_H__
#include "sdk_types.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sdk.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @name Register read functions
//@{
#define reg8_read(addr) *((volatile uint8_t *)(addr))
#define reg16_read(addr) *((volatile uint16_t *)(addr))
#define reg32_read(addr) *((volatile uint32_t *)(addr))
//@}
//! @name Register write functions
//@{
#define reg8_write(addr,val) *((volatile uint8_t *)(addr)) = (val)
#define reg16_write(addr,val) *((volatile uint16_t *)(addr)) = (val)
#define reg32_write(addr,val) *((volatile uint32_t *)(addr)) = (val)
//@}
//! @name Memory read functions
//@{
#define mem8_read(addr) *((volatile uint8_t *)(addr))
#define mem16_read(addr) *((volatile uint16_t *)(addr))
#define mem32_read(addr) *((volatile uint32_t *)(addr))
//@}
//! @name Memory write functions
//@{
#define mem8_write(addr,val) *((volatile uint8_t *)(addr)) = (val)
#define mem16_write(addr,val) *((volatile uint16_t *)(addr)) = (val)
#define mem32_write(addr,val) *((volatile uint32_t *)(addr)) = (val)
//@}
//! @name Read functions
//@{
#define readb(a) reg8_read(a)
#define readw(a) reg16_read(a)
#define readl(a) reg32_read(a)
//@}
//! @name Write functrions
//!
//! The prefered method to access registers.
//@{
#define writeb(v, a) reg8_write(a, v)
#define writew(v, a) reg16_write(a, v)
#define writel(v, a) reg32_write(a, v)
//@}
//! @name Bit set/clear functions
//@{
#define reg8setbit(addr,bitpos) \
reg8_write((addr),(reg8_read((addr)) | (1<<(bitpos))))
#define reg16setbit(addr,bitpos) \
reg16_write((addr),(reg16_read((addr)) | (1<<(bitpos))))
#define reg32setbit(addr,bitpos) \
reg32_write((addr),(reg32_read((addr)) | (1<<(bitpos))))
#define reg8clrbit(addr,bitpos) \
reg8_write((addr),(reg8_read((addr)) & (0xFF ^ (1<<(bitpos)))))
#define reg16clrbit(addr,bitpos) \
reg16_write((addr),(reg16_read((addr)) & (0xFFFF ^ (1<<(bitpos)))))
#define reg32clrbit(addr,bitpos) \
reg32_write((addr),(reg32_read((addr)) & (0xFFFFFFFF ^ (1<<(bitpos)))))
//@}
//! @name Masked write functions
//@{
#define reg8_write_mask(addr, data, mask) \
reg8_write((addr),((reg8_read(addr) & (~mask)) | (mask & data)))
#define reg16_write_mask(addr, data, mask) \
reg16_write((addr),((reg16_read(addr) & (~mask)) | (mask & data)))
#define reg32_write_mask(addr, data, mask) \
reg32_write((addr),((reg32_read(addr) & (~mask)) | (mask & data)))
#define gen_msk32(start, end) ((0xFFFFFFFF << (start)) ^ (0xFFFFFFFF << ((end + 1))))
#define reg32_set_field(addr, start, end, val) \
reg32_write_mask(addr, (val) << (start), gen_msk32((start, end)))
//@}
/*!
* This macro is used to get certain bit field from a number
*/
#define GET_FIELD(val, len, sh) ((val >> sh) & ((1 << len) - 1))
/*!
* This macro is used to set certain bit field inside a number
*/
#define SET_FIELD(val, len, sh, nval) ((val & ~(((1 << len) - 1) << sh)) | (nval << sh))
#endif // __IO_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2011-2012, Freescale Semiconductor, Inc. All Rights Reserved
* THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
* BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
* Freescale Semiconductor, Inc.
*/
#ifndef _CCM_PLL_REG_DEFINE_H_
#define _CCM_PLL_REG_DEFINE_H_
//#########################################
//# DPLLIP peripheral defines
//#########################################
#define DPLLIP_DP_CTL_OFFSET 0x000
#define DPLLIP_DP_CONFIG_OFFSET 0x004
#define DPLLIP_DP_OP_OFFSET 0x008
#define DPLLIP_DP_MFD_OFFSET 0x00C
#define DPLLIP_DP_MFN_OFFSET 0x010
#define DPLLIP_DP_MFNMINUS_OFFSET 0x014
#define DPLLIP_DP_MFNPLUS_OFFSET 0x018
#define DPLLIP_DP_HFS_OP_OFFSET 0x01C
#define DPLLIP_DP_HFS_MFD_OFFSET 0x020
#define DPLLIP_DP_HFS_MFN_OFFSET 0x024
#define DPLLIP_DP_MFN_TOGC_OFFSET 0x028
#define DPLLIP_DP_DESTAT_OFFSET 0x02C
#define DPLLIP1_DP_CONFIG DPLLIP1_BASE_ADDR+DPLLIP_DP_CONFIG_OFFSET
#define DPLLIP1_DP_CTL DPLLIP1_BASE_ADDR+DPLLIP_DP_CTL_OFFSET
#define DPLLIP1_DP_OP DPLLIP1_BASE_ADDR+DPLLIP_DP_OP_OFFSET
#define DPLLIP1_DP_MFD DPLLIP1_BASE_ADDR+DPLLIP_DP_MFD_OFFSET
#define DPLLIP1_DP_MFN DPLLIP1_BASE_ADDR+DPLLIP_DP_MFN_OFFSET
#define DPLLIP2_DP_CONFIG DPLLIP2_BASE_ADDR+DPLLIP_DP_CONFIG_OFFSET
#define DPLLIP2_DP_CTL DPLLIP2_BASE_ADDR+DPLLIP_DP_CTL_OFFSET
#define DPLLIP2_DP_OP DPLLIP2_BASE_ADDR+DPLLIP_DP_OP_OFFSET
#define DPLLIP2_DP_MFD DPLLIP2_BASE_ADDR+DPLLIP_DP_MFD_OFFSET
#define DPLLIP2_DP_MFN DPLLIP2_BASE_ADDR+DPLLIP_DP_MFN_OFFSET
#define DPLLIP3_DP_CONFIG DPLLIP3_BASE_ADDR+DPLLIP_DP_CONFIG_OFFSET
#define DPLLIP3_DP_CTL DPLLIP3_BASE_ADDR+DPLLIP_DP_CTL_OFFSET
#define DPLLIP3_DP_OP DPLLIP3_BASE_ADDR+DPLLIP_DP_OP_OFFSET
#define DPLLIP3_DP_MFD DPLLIP3_BASE_ADDR+DPLLIP_DP_MFD_OFFSET
#define DPLLIP3_DP_MFN DPLLIP3_BASE_ADDR+DPLLIP_DP_MFN_OFFSET
//#########################################
//# CCM peripheral defines
//#########################################
#define CCM_CCR_OFFSET 0x00
#define CCM_CCDR_OFFSET 0x04
#define CCM_CSR_OFFSET 0x08
#define CCM_CCSR_OFFSET 0x0C
#define CCM_CACRR_OFFSET 0x10
#define CCM_CBCDR_OFFSET 0x14
#define CCM_CBCMR_OFFSET 0X18
#define CCM_CSCMR1_OFFSET 0x1c
#define CCM_CSCMR2_OFFSET 0x20
#define CCM_CSCDR1_OFFSET 0x24
#define CCM_CS1CDR_OFFSET 0x28
#define CCM_CS2CDR_OFFSET 0x2c
#define CCM_CDCDR_OFFSET 0x30
#define CCM_CHSCCDR_OFFSET 0x34
#define CCM_CSCDR2_OFFSET 0x38
#define CCM_CSCDR3_OFFSET 0x3c
#define CCM_CSCDR4_OFFSET 0x40
#define CCM_CWDR_OFFSET 0x44
#define CCM_CDHIPR_OFFSET 0x48
#define CCM_CDCR_OFFSET 0x4c
#define CCM_CTOR_OFFSET 0x50
#define CCM_CLPCR_OFFSET 0x54
#define CCM_CISR_OFFSET 0x58
#define CCM_CIMR_OFFSET 0x5c
#define CCM_CCOSR_OFFSET 0x60
#define CCM_CGPR_OFFSET 0x64
#define CCM_CCGR0_OFFSET 0x68
#define CCM_CCGR1_OFFSET 0x6c
#define CCM_CCGR2_OFFSET 0x70
#define CCM_CCGR3_OFFSET 0x74
#define CCM_CCGR4_OFFSET 0x78
#define CCM_CCGR5_OFFSET 0x7c
#define CCM_CCGR6_OFFSET 0x80
#define CCM_CCGR7_OFFSET 0x84
#define CCM_CMEOR_OFFSET 0x88
#define CCM_CCR CCM_BASE_ADDR+CCM_CCR_OFFSET
#define CCM_CCDR CCM_BASE_ADDR+CCM_CCDR_OFFSET
#define CCM_CSR CCM_BASE_ADDR+CCM_CSR_OFFSET
#define CCM_CCSR CCM_BASE_ADDR+CCM_CCSR_OFFSET
#define CCM_CACRR CCM_BASE_ADDR+CCM_CACRR_OFFSET
#define CCM_CBCDR CCM_BASE_ADDR+CCM_CBCDR_OFFSET
#define CCM_CBCMR CCM_BASE_ADDR+CCM_CBCMR_OFFSET
#define CCM_CSCMR1 CCM_BASE_ADDR+CCM_CSCMR1_OFFSET
#define CCM_CSCMR2 CCM_BASE_ADDR+CCM_CSCMR2_OFFSET
#define CCM_CSCDR1 CCM_BASE_ADDR+CCM_CSCDR1_OFFSET
#define CCM_CS1CDR CCM_BASE_ADDR+CCM_CS1CDR_OFFSET
#define CCM_CS2CDR CCM_BASE_ADDR+CCM_CS2CDR_OFFSET
#define CCM_CDCDR CCM_BASE_ADDR+CCM_CDCDR_OFFSET
#define CCM_CHSCCDR CCM_BASE_ADDR+CCM_CHSCCDR_OFFSET
#define CCM_CSCDR2 CCM_BASE_ADDR+CCM_CSCDR2_OFFSET
#define CCM_CSCDR3 CCM_BASE_ADDR+CCM_CSCDR3_OFFSET
#define CCM_CSCDR4 CCM_BASE_ADDR+CCM_CSCDR4_OFFSET
#define CCM_CWDR CCM_BASE_ADDR+CCM_CWDR_OFFSET
#define CCM_CDHIPR CCM_BASE_ADDR+CCM_CDHIPR_OFFSET
#define CCM_CDCR CCM_BASE_ADDR+CCM_CDCR_OFFSET
#define CCM_CTOR CCM_BASE_ADDR+CCM_CTOR_OFFSET
#define CCM_CLPCR CCM_BASE_ADDR+CCM_CLPCR_OFFSET
#define CCM_CISR CCM_BASE_ADDR+CCM_CISR_OFFSET
#define CCM_CIMR CCM_BASE_ADDR+CCM_CIMR_OFFSET
#define CCM_CCOSR CCM_BASE_ADDR+CCM_CCOSR_OFFSET
#define CCM_CGPR CCM_BASE_ADDR+CCM_CGPR_OFFSET
#define CCM_CCGR0 CCM_BASE_ADDR+CCM_CCGR0_OFFSET
#define CCM_CCGR1 CCM_BASE_ADDR+CCM_CCGR1_OFFSET
#define CCM_CCGR2 CCM_BASE_ADDR+CCM_CCGR2_OFFSET
#define CCM_CCGR3 CCM_BASE_ADDR+CCM_CCGR3_OFFSET
#define CCM_CCGR4 CCM_BASE_ADDR+CCM_CCGR4_OFFSET
#define CCM_CCGR5 CCM_BASE_ADDR+CCM_CCGR5_OFFSET
#define CCM_CCGR6 CCM_BASE_ADDR+CCM_CCGR6_OFFSET
#define CCM_CCGR7 CCM_BASE_ADDR+CCM_CCGR7_OFFSET
#define CCM_CMEOR CCM_BASE_ADDR+CCM_CMEOR_OFFSET
//#########################################
//# CCM peripheral defines used by prog_pll.c and hardware.c
//#########################################
#define CLKCTL_CCGR1 CCM_CCGR1_OFFSET
#define CLKCTL_CSCMR1 CCM_CSCMR1_OFFSET
#define CLKCTL_CSCDR1 CCM_CSCDR1_OFFSET
#define CLKCTL_CBCMR CCM_CBCMR_OFFSET
#define CLKCTL_CBCDR CCM_CBCDR_OFFSET
#define CLKCTL_CCSR CCM_CCSR_OFFSET
#define CLKCTL_CDHIPR CCM_CDHIPR_OFFSET
#define CLKCTL_CACRR CCM_CACRR_OFFSET
#define CLKCTL_CSCDR2 CCM_CSCDR2_OFFSET
#define CLKCTL_CS1CDR CCM_CS1CDR_OFFSET
#define CLKCTL_CS2CDR CCM_CS2CDR_OFFSET
#define CLKCTL_CSCMR2 CCM_CSCMR2_OFFSET
#define PLL1_BASE_ADDR DPLLIP1_BASE_ADDR
#define PLL2_BASE_ADDR DPLLIP2_BASE_ADDR
#define PLL3_BASE_ADDR DPLLIP3_BASE_ADDR
#define PLL4_BASE_ADDR DPLLIP4_BASE_ADDR
#define PLL_DP_CTL DPLLIP_DP_CTL_OFFSET
#define PLL_DP_CONFIG DPLLIP_DP_CONFIG_OFFSET
#define PLL_DP_OP DPLLIP_DP_OP_OFFSET
#define PLL_DP_MFD DPLLIP_DP_MFD_OFFSET
#define PLL_DP_MFN DPLLIP_DP_MFN_OFFSET
#define PLL_DP_MFNMINUS DPLLIP_DP_MFNMINUS_OFFSET
#define PLL_DP_MFNPLUS DPLLIP_DP_MFNPLUS_OFFSET
#define PLL_DP_HFS_OP DPLLIP_DP_HFS_OP_OFFSET
#define PLL_DP_HFS_MFD DPLLIP_DP_HFS_MFD_OFFSET
#define PLL_DP_HFS_MFN DPLLIP_DP_HFS_MFN_OFFSET
#define PLL_DP_TOGC DPLLIP_DP_MFN_TOGC_OFFSET
#define PLL_DP_DESTAT DPLLIP_DP_DESTAT_OFFSET
#endif

View File

@@ -0,0 +1,472 @@
/*
* Copyright (c) 2014 - 2015, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. 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 HOLDER 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 _FSL_BITACCESS_H
#define _FSL_BITACCESS_H 1
#include <stdint.h>
#include <stdlib.h>
/* IO definitions (access restrictions to peripheral registers) */
#ifdef __cplusplus
#define __I volatile /*!< Defines 'read only' permissions */
#else
#define __I volatile const /*!< Defines 'read only' permissions */
#endif
#define __O volatile /*!< Defines 'write only' permissions */
#define __IO volatile /*!< Defines 'read / write' permissions */
/*
* Macros for single instance registers
*/
#define BF_SET(reg, field) HW_##reg##_SET(BM_##reg##_##field)
#define BF_CLR(reg, field) HW_##reg##_CLR(BM_##reg##_##field)
#define BF_TOG(reg, field) HW_##reg##_TOG(BM_##reg##_##field)
#define BF_SETV(reg, field, v) HW_##reg##_SET(BF_##reg##_##field(v))
#define BF_CLRV(reg, field, v) HW_##reg##_CLR(BF_##reg##_##field(v))
#define BF_TOGV(reg, field, v) HW_##reg##_TOG(BF_##reg##_##field(v))
#define BV_FLD(reg, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BV_VAL(reg, field, sym) BV_##reg##_##field##__##sym
#define BF_RD(reg, field) HW_##reg.B.field
#define BF_WR(reg, field, v) BW_##reg##_##field(v)
#define BF_CS1(reg, f1, v1) \
(HW_##reg##_CLR(BM_##reg##_##f1), \
HW_##reg##_SET(BF_##reg##_##f1(v1)))
#define BF_CS2(reg, f1, v1, f2, v2) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2)))
#define BF_CS3(reg, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3)))
#define BF_CS4(reg, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4)))
#define BF_CS5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5)))
#define BF_CS6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6)))
#define BF_CS7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7)))
#define BF_CS8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8)))
/*
* Macros for multiple instance registers
*/
#define BF_SETn(reg, n, field) HW_##reg##_SET(n, BM_##reg##_##field)
#define BF_CLRn(reg, n, field) HW_##reg##_CLR(n, BM_##reg##_##field)
#define BF_TOGn(reg, n, field) HW_##reg##_TOG(n, BM_##reg##_##field)
#define BF_SETVn(reg, n, field, v) HW_##reg##_SET(n, BF_##reg##_##field(v))
#define BF_CLRVn(reg, n, field, v) HW_##reg##_CLR(n, BF_##reg##_##field(v))
#define BF_TOGVn(reg, n, field, v) HW_##reg##_TOG(n, BF_##reg##_##field(v))
#define BV_FLDn(reg, n, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BV_VALn(reg, n, field, sym) BV_##reg##_##field##__##sym
#define BF_RDn(reg, n, field) HW_##reg(n).B.field
#define BF_WRn(reg, n, field, v) BW_##reg##_##field(n, v)
#define BF_CS1n(reg, n, f1, v1) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1))))
#define BF_CS2n(reg, n, f1, v1, f2, v2) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2))))
#define BF_CS3n(reg, n, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3))))
#define BF_CS4n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4))))
#define BF_CS5n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5))))
#define BF_CS6n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6))))
#define BF_CS7n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7))))
#define BF_CS8n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8))))
/*
* Macros for single instance MULTI-BLOCK registers
*/
#define BFn_SET(reg, blk, field) HW_##reg##_SET(blk, BM_##reg##_##field)
#define BFn_CLR(reg, blk, field) HW_##reg##_CLR(blk, BM_##reg##_##field)
#define BFn_TOG(reg, blk, field) HW_##reg##_TOG(blk, BM_##reg##_##field)
#define BFn_SETV(reg, blk, field, v) HW_##reg##_SET(blk, BF_##reg##_##field(v))
#define BFn_CLRV(reg, blk, field, v) HW_##reg##_CLR(blk, BF_##reg##_##field(v))
#define BFn_TOGV(reg, blk, field, v) HW_##reg##_TOG(blk, BF_##reg##_##field(v))
#define BVn_FLD(reg, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BVn_VAL(reg, field, sym) BV_##reg##_##field##__##sym
#define BFn_RD(reg, blk, field) HW_##reg(blk).B.field
#define BFn_WR(reg, blk, field, v) BW_##reg##_##field(blk, v)
#define BFn_CS1(reg, blk, f1, v1) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1)))
#define BFn_CS2(reg, blk, f1, v1, f2, v2) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2)))
#define BFn_CS3(reg, blk, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3)))
#define BFn_CS4(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4)))
#define BFn_CS5(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5)))
#define BFn_CS6(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6)))
#define BFn_CS7(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7)))
#define BFn_CS8(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8)))
/*
* Macros for MULTI-BLOCK multiple instance registers
*/
#define BFn_SETn(reg, blk, n, field) HW_##reg##_SET(blk, n, BM_##reg##_##field)
#define BFn_CLRn(reg, blk, n, field) HW_##reg##_CLR(blk, n, BM_##reg##_##field)
#define BFn_TOGn(reg, blk, n, field) HW_##reg##_TOG(blk, n, BM_##reg##_##field)
#define BFn_SETVn(reg, blk, n, field, v) HW_##reg##_SET(blk, n, BF_##reg##_##field(v))
#define BFn_CLRVn(reg, blk, n, field, v) HW_##reg##_CLR(blk, n, BF_##reg##_##field(v))
#define BFn_TOGVn(reg, blk, n, field, v) HW_##reg##_TOG(blk, n, BF_##reg##_##field(v))
#define BVn_FLDn(reg, blk, n, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BVn_VALn(reg, blk, n, field, sym) BV_##reg##_##field##__##sym
#define BFn_RDn(reg, blk, n, field) HW_##reg(n).B.field
#define BFn_WRn(reg, blk, n, field, v) BW_##reg##_##field(n, v)
#define BFn_CS1n(reg, blk, n, f1, v1) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1))))
#define BFn_CS2n(reg, blk, n, f1, v1, f2, v2) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2))))
#define BFn_CS3n(reg, blk, n, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3))))
#define BFn_CS4n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4))))
#define BFn_CS5n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5))))
#define BFn_CS6n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6))))
#define BFn_CS7n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7))))
#define BFn_CS8n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8))))
#endif /* _FSL_BITACCESS_H */
/******************************************************************************/

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2011-2012, Freescale Semiconductor, Inc. All Rights Reserved
* THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
* BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
* Freescale Semiconductor, Inc.
*/
/*!
* @file functions.h
* @brief This header file contains functions info.
*
*/
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
//----------------------------------------------------------------------
// Some Genaral Macros
//----------------------------------------------------------------------
//#define FALSE 0
//#define TRUE 1
#define DUMMY_INFO 0xf00f00
#define reg8_read(addr) *((BYTE *)(addr))
#define reg16_read(addr) *((HALF *)(addr))
#define reg32_read(addr) *(WORD *)((addr))
#define reg32_read_bit(addr,bitpos) (reg32_read(addr) & (1<<(bitpos)))
#define reg8_write(addr,val) *((BYTE *)(addr)) = (val)
#define reg16_write(addr,val) *((HALF *)(addr)) = (val)
#define reg32_write(addr,val) *((WORD *)(addr)) = (val)
#define mem8_read(addr) *((BYTE *)(addr))
#define mem16_read(addr) *((HALF *)(addr))
#define mem32_read(addr) *(WORD *)((addr))
#define mem8_write(addr,val) *((BYTE *)(addr)) = (val)
#define mem16_write(addr,val) *((HALF *)(addr)) = (val)
#define mem32_write(addr,val) *((WORD *)(addr)) = (val)
#define reg8setbit(addr,bitpos) \
reg8_write((addr),(reg8_read((addr)) | (1<<(bitpos))))
#define reg16setbit(addr,bitpos) \
reg16_write((addr),(reg16_read((addr)) | (1<<(bitpos))))
#define reg32setbit(addr,bitpos) \
reg32_write((addr),(reg32_read((addr)) | (1<<(bitpos))))
#define reg8clrbit(addr,bitpos) \
reg8_write((addr),(reg8_read((addr)) & (0xFF ^ (1<<(bitpos)))))
#define reg16clrbit(addr,bitpos) \
reg16_write((addr),(reg16_read((addr)) & (0xFFFF ^ (1<<(bitpos)))))
#define reg32clrbit(addr,bitpos) \
reg32_write((addr),(reg32_read((addr)) & (0xFFFFFFFF ^ (1<<(bitpos)))))
// ##### EXPORTED TYPE DEFINITIONS ################################################# {{{1
typedef volatile unsigned long WORD;
typedef volatile unsigned short HALF;
typedef volatile unsigned char BYTE;
//----------------------------------------------------------------------
// Write With Mask (write only certain bits)
//----------------------------------------------------------------------
void reg8_write_mask(WORD addr, BYTE wdata, BYTE mask);
void reg16_write_mask(WORD addr, HALF wdata, HALF mask);
void reg32_write_mask(WORD addr, WORD wdata, WORD mask);
#endif //FUNCTIONS_H

View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 2011-2012, Freescale Semiconductor, Inc. All Rights Reserved
* THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
* BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
* Freescale Semiconductor, Inc.
*/
#ifndef _GPIO_DEFINE_H_
#define _GPIO_DEFINE_H_
#if 0
#define GPIO_DR_OFFSET 0x0000
#define GPIO_GDIR_OFFSET 0x0004
#define GPIO_PSR_OFFSET 0x0008
#endif
typedef enum {
GPIO_PORT1 = 0,
GPIO_PORT2 = 1,
GPIO_PORT3 = 2,
GPIO_PORT4 = 3,
GPIO_PORT5 = 4,
GPIO_PORT6 = 5,
GPIO_PORT7 = 6,
} GPIO_PORT;
typedef struct {
unsigned int DR;
unsigned int GDIR;
unsigned int PSR;
unsigned int ICR1;
unsigned int ICR2;
unsigned int IMR;
unsigned int ISR;
unsigned int EDGE_SEL;
} CSP_GPIO_REGS, *PCSP_GPIO_REGS;
#define GPIO_GDIR_INPUT 0 // GPIO pin is input
#define GPIO_GDIR_OUTPUT 1 // GPIO pin is output
#define GPIO_LOW_LEVEL 0 // GPIO pin is low
#define GPIO_HIGH_LEVEL 1 // GPIO pin is high
#define GPIO_ICR_LOW_LEVEL 0 // Interrupt is low-level
#define GPIO_ICR_HIGH_LEVEL 1 // Interrupt is high-level
#define GPIO_ICR_RISE_EDGE 2 // Interrupt is rising edge
#define GPIO_ICR_FALL_EDGE 3 // Interrupt is falling edge
#define GPIO_IMR_MASKED 0 // Interrupt is masked
#define GPIO_IMR_UNMASKED 1 // Interrupt is unmasked
#define GPIO_EDGE_SEL_DISABLE 0 // Edge select is disabled
#define GPIO_EDGE_SEL_ENABLE 1 // Edge select is enabled
#define GPIO_PIN_MASK(pin) (1U << (pin))
#define GPIO_PIN_VAL(val, pin) ((val) << (pin))
#define GPIO_ICR_MASK(pin) (0x3U << ((pin) << 1))
#define GPIO_ICR_VAL(val, pin) ((val) << ((pin) << 1))
//#########################################
//# GPIO peripheral defines
//#########################################
#define GPIO_DR0_OFFSET 0x00 // 32bit gpio pta data direction reg
#define GPIO_GDIR0_OFFSET 0x04 // 32bit gpio pta output config 1 reg
#define GPIO_PSR0_OFFSET 0x08 // 32bit gpio pta output config 2 reg
#define GPIO_ICR1_OFFSET 0x0C // 32bit gpio pta input config A1 reg
#define GPIO_ICR2_OFFSET 0x10 // 32bit gpio pta input config A2 reg
#define GPIO_IMR_OFFSET 0x14 // 32bit gpio pta input config B1 reg
#define GPIO_ISR_OFFSET 0x18 // GPIO Interrupt Status Register
#define GPIO_EDGE_SEL_OFFSET 0x1C // GPIO Edge Detect Register
#define GPIO1_DR GPIO1_BASE_ADDR+0x00
#define GPIO1_GDIR GPIO1_BASE_ADDR+0x04
#define GPIO1_PSR GPIO1_BASE_ADDR+0x08
#define GPIO1_ICR1 GPIO1_BASE_ADDR+0x0C
#define GPIO1_ICR2 GPIO1_BASE_ADDR+0x10
#define GPIO1_IMR GPIO1_BASE_ADDR+0x14
#define GPIO1_ISR GPIO1_BASE_ADDR+0x18
#define GPIO1_EDGE_SEL GPIO1_BASE_ADDR+0x1C
#define GPIO2_DR GPIO2_BASE_ADDR+0x00
#define GPIO2_GDIR GPIO2_BASE_ADDR+0x04
#define GPIO2_PSR GPIO2_BASE_ADDR+0x08
#define GPIO2_ICR1 GPIO2_BASE_ADDR+0x0C
#define GPIO2_ICR2 GPIO2_BASE_ADDR+0x10
#define GPIO2_IMR GPIO2_BASE_ADDR+0x14
#define GPIO2_ISR GPIO2_BASE_ADDR+0x18
#define GPIO2_EDGE_SEL GPIO2_BASE_ADDR+0x1C
#define GPIO3_DR GPIO3_BASE_ADDR+0x00
#define GPIO3_GDIR GPIO3_BASE_ADDR+0x04
#define GPIO3_PSR GPIO3_BASE_ADDR+0x08
#define GPIO3_ICR1 GPIO3_BASE_ADDR+0x0C
#define GPIO3_ICR2 GPIO3_BASE_ADDR+0x10
#define GPIO3_IMR GPIO3_BASE_ADDR+0x14
#define GPIO3_ISR GPIO3_BASE_ADDR+0x18
#define GPIO3_EDGE_SEL GPIO3_BASE_ADDR+0x1C
#define GPIO4_DR GPIO4_BASE_ADDR+0x00
#define GPIO4_GDIR GPIO4_BASE_ADDR+0x04
#define GPIO4_PSR GPIO4_BASE_ADDR+0x08
#define GPIO4_ICR1 GPIO4_BASE_ADDR+0x0C
#define GPIO4_ICR2 GPIO4_BASE_ADDR+0x10
#define GPIO4_IMR GPIO4_BASE_ADDR+0x14
#define GPIO4_ISR GPIO4_BASE_ADDR+0x18
#define GPIO4_EDGE_SEL GPIO4_BASE_ADDR+0x1C
#define GPIO5_DR GPIO5_BASE_ADDR+0x00
#define GPIO5_GDIR GPIO5_BASE_ADDR+0x04
#define GPIO5_PSR GPIO5_BASE_ADDR+0x08
#define GPIO5_ICR1 GPIO5_BASE_ADDR+0x0C
#define GPIO5_ICR2 GPIO5_BASE_ADDR+0x10
#define GPIO5_IMR GPIO5_BASE_ADDR+0x14
#define GPIO5_ISR GPIO5_BASE_ADDR+0x18
#define GPIO5_EDGE_SEL GPIO5_BASE_ADDR+0x1C
#define GPIO6_DR GPIO6_BASE_ADDR+0x00
#define GPIO6_GDIR GPIO6_BASE_ADDR+0x04
#define GPIO6_PSR GPIO6_BASE_ADDR+0x08
#define GPIO6_ICR1 GPIO6_BASE_ADDR+0x0C
#define GPIO6_ICR2 GPIO6_BASE_ADDR+0x10
#define GPIO6_IMR GPIO6_BASE_ADDR+0x14
#define GPIO6_ISR GPIO6_BASE_ADDR+0x18
#define GPIO6_EDGE_SEL GPIO6_BASE_ADDR+0x1C
#define GPIO7_DR GPIO7_BASE_ADDR+0x00
#define GPIO7_GDIR GPIO7_BASE_ADDR+0x04
#define GPIO7_PSR GPIO7_BASE_ADDR+0x08
#define GPIO7_ICR1 GPIO7_BASE_ADDR+0x0C
#define GPIO7_ICR2 GPIO7_BASE_ADDR+0x10
#define GPIO7_IMR GPIO7_BASE_ADDR+0x14
#define GPIO7_ISR GPIO7_BASE_ADDR+0x18
#define GPIO7_EDGE_SEL GPIO7_BASE_ADDR+0x1C
#endif

View File

@@ -0,0 +1,398 @@
/*
* Copyright (C) 2012, Freescale Semiconductor, Inc. All Rights Reserved
* THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
* BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
* Freescale Semiconductor, Inc.
*/
/*!
* @file hardware.h
* @brief header file with chip defines to be included by all the tests/utils
*
* @ingroup diag_init
*/
#ifndef HARDWARE_H_
#define HARDWARE_H_
#include "soc_memory_map.h"
#include "functions.h"
#include "io.h"
#include "iomux_define.h"
#include "iomux_register.h"
#include "iomux_config.h"
#include "gpio_define.h"
#include "ccm_pll_reg_define.h"
#include "imx_i2c.h"
#include "imx_spi.h"
#include "imx_sata.h"
#include "pmic.h"
#include "regsgpmi.h"
#include "regsapbh.h"
#define ESDCTL_ESDSCR_OFFSET 0x1C
// PLL definitions
#define HW_ANADIG_USB1_PLL_480_CTRL_RW (ANATOP_IPS_BASE_ADDR+0x10)
#define HW_ANADIG_PLL_528_RW (ANATOP_IPS_BASE_ADDR+0x30)
#define HW_ANADIG_PLL_528_NUM (ANATOP_IPS_BASE_ADDR+0x50)
#define HW_ANADIG_PLL_528_DENOM (ANATOP_IPS_BASE_ADDR+0x60)
#define HW_ANADIG_PFD_528_RW (ANATOP_IPS_BASE_ADDR+0x100)
#define HW_ANADIG_PLL_SYS_RW (ANATOP_IPS_BASE_ADDR+0x000)
#define HW_ANADIG_REG_CORE (ANATOP_IPS_BASE_ADDR + 0x140)
#define HW_ANADIG_REG_CORE_V_CORE_VALUE_mv(x) ((((x)-700)/25) << 0)
#define HW_ANADIG_REG_CORE_V_SOC_VALUE_mv(x) ((((x)-700)/25) << 18)
#define HW_ANADIG_REG_CORE_V_CORE_MSK 0x1F
#define HW_ANADIG_REG_CORE_V_SOC_MSK (0x1F << 18)
// audio defines
#define WM8960_I2C_DEV_ADDR (0x34>>1)
#define WM8960_I2C_BASE_ADDR I2C2_BASE_ADDR
#define WM8958_I2C_DEV_ADDR (0x34>>1)
#define WM8958_I2C_BASE_ADDR I2C1_BASE_ADDR
#define WM8962_I2C_DEV_ADDR (0x34>>1)
#define WM8962_I2C_BASE_ADDR I2C4_BASE_ADDR
#define SGTL5000_I2C_BASE I2C1_BASE_ADDR // audio codec on i2c1
#define SGTL5000_I2C_ID 0x0A
// SGTL5000 specific register values
#define CHIP_REF_CTRL_REG_VALUE 0x01FF // VDDA/2
#define CHIP_LINE_OUT_CTRL_REG_VALUE 0x0322 // VDDIO/2
#define CHIP_LINE_OUT_VOL_REG_VALUE 0x0F0F // based on VDDA and VDDIO values
#define CHIP_CLK_TOP_CTRL_REG_VALUE 0 // pass through, Input OSC 13.5MHz, default configuration for sample rate, 48KHz
#define CHIP_PLL_CTRL_REG_VALUE ((14 << 11) | (1154))
#define CHIP_CLK_CTRL_REG_VALUE ((0x2 << 2) | (0x3))
#define CHIP_CLK_CTRL_REG_MCLK_FREQ_VALUE 0x3 /*12MHz =256*Fs */
#define CHIP_PLL_CTRL_REG_VALUE2 ((16 << 11) | (786)) // for CodecInit2
#define SI476x_I2C_BASE I2C2_BASE_ADDR
#define SI476x_I2C_ID (0xC6 >> 1)
#define OS81050_I2C_BASE I2C3_BASE_ADDR
#define OS81050_I2C_ID (0x40 >> 1)
#define ADV7180_I2C_BASE I2C3_BASE_ADDR
#define ADV7180_I2C_ID (0x42 >> 1)
#if defined(SABRE_LITE)
#define P1003_TSC_I2C_BASE I2C3_BASE_ADDR
#else //default SABRE_AI
#define P1003_TSC_I2C_BASE I2C2_BASE_ADDR
#endif
#define P1003_TSC_I2C_ID 4
// MAX7310 I2C settings
/* For the SABRE AI board which has 3 MAX7310 */
#ifdef SABRE_AI
#define MAX7310_NBR 3
#define MAX7310_I2C_BASE_ID0 I2C3_BASE_ADDR
#define MAX7310_I2C_ID0 0x30
#define MAX7310_ID0_DEF_DIR 0x00 // init direction for the I/O
#define MAX7310_ID0_DEF_VAL 0xFF // init value for the output
/* Number 1 controls: CTRL_0, CTRL_1, CTRL_2, CTRL_3, CTRL_4, PORT3_P116,
PORT2_P81, PORT3_P101
*/
#define MAX7310_I2C_BASE_ID1 I2C3_BASE_ADDR
#define MAX7310_I2C_ID1 0x32
#define MAX7310_ID1_DEF_DIR 0x00 // init direction for the I/O
/*Set the max7310_id1 's default value for ctrl_x */
#define MAX7310_ID1_DEF_VAL 0xE7 // init value for the output
#define MAX7310_I2C_BASE_ID2 I2C3_BASE_ADDR
#define MAX7310_I2C_ID2 0x34
#define MAX7310_ID2_DEF_DIR 0x00 // init direction for the I/O
/*Set the max7310_id1 's default value for ctrl_x */
#define MAX7310_ID2_DEF_VAL 0x57 // init value for the output
/* For the EVB board which has 2 MAX7310 */
#endif
#ifdef EVB
#define MAX7310_NBR 2
/* Number 1 controls: BACKLIGHT_ON, PORT3_P114, CPU_PER_RST_B, PORT3_P110,
PORT3_P105, PORT3_P112, PORT3_P107, PORT3_P109.
*/
#define MAX7310_I2C_BASE_ID0 I2C3_BASE_ADDR
#define MAX7310_I2C_ID0 (0x36 >> 1)
#define MAX7310_ID0_DEF_DIR 0x00 // init direction for the I/O
#define MAX7310_ID0_DEF_VAL 0xFF // init value for the output
/* Number 1 controls: CTRL_0, CTRL_1, CTRL_2, CTRL_3, CTRL_4, PORT3_P116,
PORT2_P81, PORT3_P101
*/
#define MAX7310_I2C_BASE_ID1 I2C3_BASE_ADDR
#define MAX7310_I2C_ID1 (0x3E >> 1)
#define MAX7310_ID1_DEF_DIR 0x00 // init direction for the I/O
/*Set the max7310_id1 's default value for ctrl_x */
#define MAX7310_ID1_DEF_VAL 0x09 // init value for the output
#endif
/* use that defined for boards that doesn't have any MAX7310 */
#if defined(SMART_DEVICE) || defined(SABRE_LITE)
/* dummy value for build */
#define MAX7310_NBR 0
#endif
/* create an array of I2C requests for all used expanders on the board */
struct imx_i2c_request max7310_i2c_req_array[MAX7310_NBR];
#define MMA8450_I2C_ID 0x1C
#define MMA8451_I2C_ID 0x1C
#define MAG3112_I2C_ID 0x1D
#define MAG3110_I2C_ID 0x0E
#define ISL29023_I2C_ID 0x44
#define FXLS8471Q_I2C_ID 0x1E
#define MAX11801_I2C_BASE I2C3_BASE_ADDR
#define MAX11801_I2C_ID (0x90 >> 1)
#ifdef SABRE_AI
#define CS42888_I2C_BASE I2C2_BASE_ADDR
#endif
#ifdef EVB
#define CS42888_I2C_BASE I2C1_BASE_ADDR
#endif
/* use that defined for boards that doesn't have any CS42888 */
#if defined(SMART_DEVICE) || defined(SABRE_LITE)
#define CS42888_I2C_BASE DUMMY_VALUE_NOT_USED
#endif
#define CS42888_I2C_ID (0x90 >> 1)
#define AT24Cx_I2C_BASE I2C3_BASE_ADDR
#define AT24Cx_I2C_ID 0x50
// USB test defines
#define USBH1_BASE_ADDR (USBOH2_USB_BASE_ADDR + 0x200)
#define USBH2_BASE_ADDR (USBOH2_USB_BASE_ADDR + 0x400)
#define USBH3_BASE_ADDR (USBOH2_USB_BASE_ADDR + 0x600)
#define USB_OTG_MIRROR_REG (USBOH2_USB_BASE_ADDR+0x804)
#define USB_CLKONOFF_CTRL (USBOH2_USB_BASE_ADDR+0x824)
#define USBH2_VIEWPORT (USBH2_BASE_ADDR + 0x170)
#define USB_CTRL_1 (USBOH2_USB_BASE_ADDR + 0x810)
#define UH2_PORTSC1 (USBH2_BASE_ADDR + 0x184)
#define IIM_BASE_ADDR 0x0
#define M4IF_REGISTERS_BASE_ADDR 0x0
#define ESDHC1_BASE_ADDR 0x0
#define ESDHC2_BASE_ADDR 0x1
#define ESDHC3_BASE_ADDR 0x2
#define DPLLIP1_BASE_ADDR 0x0
#define DPLLIP2_BASE_ADDR 0x1
#define DPLLIP3_BASE_ADDR 0x2
#define DPLLIP4_BASE_ADDR 0x3
#define USDHC_ADMA_BUFFER 0x00910000
/*qh and td pointers defintion*/
#define QH_BUFFER 0x00908000 // internal RAM
#define TD_BUFFER 0x00908100 // internal RAM
// input CKIL clock
#define __CLK_TCK 32768
#define FREQ_24MHZ 24000000
#define CKIH 22579200
// I2C specific defines
// For LTC Board ID
#define BOARD_ID_I2C_BASE I2C2_BASE_ADDR
// register defines for the SRTC function of the SNVS
#define SRTC_LPSCMR (SNVS_BASE_ADDR + 0x50)
#define SRTC_LPSCLR (SNVS_BASE_ADDR + 0x54)
#define SRTC_LPCR (SNVS_BASE_ADDR + 0x38)
#define SRTC_HPCMR (SNVS_BASE_ADDR + 0x24)
#define SRTC_HPCLR (SNVS_BASE_ADDR + 0x28)
#define SRTC_HPCR (SNVS_BASE_ADDR + 0x08)
//provide macros for test enter and exit outputs
#define TEST_ENTER(name) printf ("Running test: %s\n", name)
#define TEST_EXIT(name) do {printf (" ..Test: %s\n", name); \
} while (0)
enum main_clocks {
CPU_CLK,
AHB_CLK,
IPG_CLK,
IPG_PER_CLK,
DDR_CLK,
NFC_CLK,
USB_CLK,
VPU_CLK,
};
enum peri_clocks {
UART1_BAUD,
UART2_BAUD,
UART3_BAUD,
UART4_BAUD,
SSI1_BAUD,
SSI2_BAUD,
CSI_BAUD,
MSTICK1_CLK,
MSTICK2_CLK,
SPI1_CLK = ECSPI1_BASE_ADDR,
SPI2_CLK = ECSPI2_BASE_ADDR,
};
enum plls {
PLL1,
PLL2,
PLL3,
PLL4,
};
enum display_type {
DISP_DEV_NULL = 0,
DISP_DEV_TFTLCD,
DISP_DEV_LVDS,
DISP_DEV_VGA,
DISP_DEV_HDMI,
DISP_DEV_TV,
DISP_DEV_MIPI,
};
enum lvds_panel_bit_mode {
LVDS_PANEL_18BITS_MODE = 0x0,
LVDS_PANEL_24BITS_MODE = 0x1,
};
enum shift_reg_bit{
HDMI_nRST = 1,
ENET1_nRST = 2,
ENET2_nRST = 4,
CAN1_2_STBY = 8,
BT_nPWD = 16,
CSI_RST = 32,
CSI_PWDN = 64,
LCD_nPWREN = 128,
ALL_BITS = 0xFF,
};
void set_shift_reg(enum shift_reg_bit b, bool state);
void peri_pwr_en(bool enable);
void pf0100_enable_vgen5_3v3(void);
void pf0100_disable_vgen5_3v3(void);
void pf0100_enable_vgen2_1v5(void);
void pf0100_disable_vgen2_1v5(void);
void sd3_reset(void);
u32 pll_clock(enum plls pll);
u32 get_main_clock(enum main_clocks clk);
u32 get_peri_clock(enum peri_clocks clk);
void clock_setup(u32 core_clk, u32 ahb_div);
void io_cfg_i2c(u32 module_base);
void usdhc_iomux_config(u32 module_base);
bool usdhc_card_detected(unsigned int base_address);
bool usdhc_write_protected(unsigned int base_address);
void freq_populate(void);
void show_freq(void);
void show_ddr_config(void);
void board_init(void);
void reset_usb_hub(void);
void usb_clock_enable(void);
void usb_init_phy(void);
void imx_enet_setup(void);
void esai_iomux(void);
void gpmi_nand_pinmux_config(void);
void gpmi_nand_clk_setup(void);
void imx_enet_iomux(int id);
void imx_enet_power_on_reset(void);
void imx_enet_hw_init(int id);
void usb_iomux_config(void);
void usb_vbus_power_on(void);
void usb_vbus_power_off(void);
void imx_ar8031_reset(void);
void imx_KSZ9021RN_reset(void);
int read_mac(u8 * mac_data);
int program_mac(u8 * fuse_data);
void mlb_io_config(void);
int esai_codec_power_on(void);
void hdmi_pgm_iomux(void);
void hdmi_clock_set(unsigned int pclk);
void lvds_power_on(char *panel_name);
void sata_clock_disable(void);
void sata_power_off(void);
void weim_nor_flash_cs_setup(void);
void show_boot_switch_info(void);
void hdmi_power_on(void);
void camera_power_on(void);
void camera_power_off(void);
void camera_reset(void);
void camera_clock_setting(void);
void audio_codec_power_on(void);
extern void gpio_backlight_lvds_en(void);
extern void init_clock(u32 rate);
extern void hal_delay_us(unsigned int);
extern int max7310_init(unsigned int, unsigned int, unsigned int);
extern void max7310_set_gpio_output(unsigned int, unsigned int, unsigned int);
extern void AUDMUXRoute(int intPort, int extPort, int Master); // defined in ssi.c driver
extern int mx6ul_evk_show_headphone(void);
extern imx_spi_init_func_t spi_init_flash;
extern imx_spi_xfer_func_t spi_xfer_flash;
extern struct imx_spi_dev imx_spi_nor;
extern u32 usbh_EHCI_test_mode_base;
extern u32 usbh_dev_enum_test_base;
extern u32 usbo_dev_enum_test_base;
extern u32 usbh_hub251x_test_base;
extern int ipu_display_panel[];
extern u32 ddr_density, ddr_num_of_cs;
extern u32 mmcsd_bus_width, mmc_sd_base_address;
/* list of tests */
extern int spi_nor_test_enable;
extern int pmic_mc13892_test_enable;
extern int pf0100_i2c_device_id_test_enable;
extern int fec_test_enable;
extern int lan9220_test_enable;
extern int enet_test_enable;
extern int ksz8081rnb_test_enable;
extern int KSZ9021RN_test_enable;
extern int ds90ur124_test_enable;
extern int adv7180_test_enable;
extern int ard_mb_reset_test_enable;
extern int ard_mb_expander_reset_test_enable;
extern int si476x_test_enable;
extern int esai_test_enable;
extern int weim_nor_flash_test_enable;
extern int max7310_i2c_device_id_test_enable;
extern int nand_test_enable;
extern int usbh_EHCI_test_mode_test_enable;
extern int usbh_dev_enum_test_enable;
extern int usbo_dev_enum_test_enable;
extern int usbh_hub251x_test_enable;
extern int i2s_audio_test_enable;
extern int gps_test_enable;
extern int gpio_keyboard_test_enable;
extern int smbus_test_enable;
extern int touch_screen_test_enable;
extern int ipu_display_test_enable;
extern int ddr_test_enable;
extern int mlb_os81050_test_enable;
extern int i2c_id_check_test_enable;
extern int i2c_device_id_check_mag3112_test_enable;
extern int i2c_device_id_check_mag3110_test_enable;
extern int i2c_device_id_check_isl29023_test_enable;
extern int i2c_device_id_check_mma8451_test_enable;
extern int i2c_device_id_check_cs42888_test_enable;
extern int i2c_device_id_check_p1003_test_enable;
extern int mmcsd_test_enable;
extern int eeprom_test_enable;
extern int mipi_test_enable;
extern int touch_button_test_enable;
extern int android_buttons_test_enable;
extern int can_test_enable;
extern int camera_flashtest_enable;
extern int camera_test_enable;
extern int epd_test_enable;
extern int lcd_test_enable;
extern int lvds_test_enable;
#define PMIC_MC13892_I2C_BASE I2C2_BASE_ADDR
#define PMIC_LTC3589_I2C_BASE I2C2_BASE_ADDR
#define PMIC_DA9053_I2C_BASE I2C1_BASE_ADDR
#define PMIC_PF0100_I2C_BASE I2C1_BASE_ADDR
#endif /*HARDWARE_H_ */

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More