未验证 提交 e02f1afd 编写于 作者: B Bernard Xiong 提交者: GitHub

Merge pull request #2256 from foss-for-synopsys-dwc-arc-processors/arc_support

[bsp][synopsys] add the support of synopsys arc emsk
from building import *
cwd = GetCurrentDir()
embarc_arc_hal_SRCS = Split("""
arc/arc_cache.c
arc/arc_exc_asm.S
arc/arc_exception.c
arc/arc_timer.c
arc/startup/arc_cxx_support.c
arc/startup/arc_startup.S
device/designware/uart/dw_uart.c
device/designware/gpio/dw_gpio.c
""")
ASFLAGS = ' -I' + cwd
src = embarc_arc_hal_SRCS
path = [cwd,
cwd + '/arc',
cwd + '/arc/startup'
]
group = DefineGroup('embarc', src, depend = [], CPPPATH = path, ASFLAGS = ASFLAGS)
Return('group')
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-15
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup ARC_HAL_MISC_CACHE
* \brief implementation of cache related functions
*/
#include "inc/arc/arc_cache.h"
#define DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y))
struct cache_config {
uint8_t ver; /* version */
uint8_t assoc; /* Cache Associativity */
uint16_t line; /* cache line/block size */
uint32_t capacity; /* capacity */
};
static struct cache_config icache_config, dcache_config;
/**
* \brief invalidate multi instruction cache lines
*
* \param[in] start_addr start address in instruction cache
* \param[in] size the bytes to be invalidated
* \return 0, succeeded, -1, failed
*/
int32_t icache_invalidate_mlines(uint32_t start_addr, uint32_t size)
{
if (!icache_available()) return -1;
if ((size == 0) || (size > icache_config.capacity)) {
return -1;
}
uint32_t end_addr;
uint32_t line_size;
uint32_t status;
line_size = (uint32_t)(icache_config.line);
end_addr = start_addr + size - 1;
start_addr &= (uint32_t)(~(line_size - 1));
status = cpu_lock_save();
do {
_arc_aux_write(AUX_IC_IVIL, start_addr);
Asm("nop_s");
Asm("nop_s");
Asm("nop_s");
start_addr += line_size;
} while (start_addr <= end_addr);
cpu_unlock_restore(status);
return 0;
}
/**
* \brief lock multi lines in instruction cache
*
* \param[in] start_addr start address in instruction cache
* \param[in] size the bytes to be locked
* \return 0, succeeded, -1, failed (cache already locked or other reasons)
*/
int32_t icache_lock_mlines(uint32_t start_addr, uint32_t size)
{
if (!icache_available()) return -1;
if ((size == 0) || (size > icache_config.capacity)) {
return -1;
}
uint32_t end_addr;
uint32_t line_size;
uint32_t status;
int32_t ercd = 0;
line_size = (uint32_t)(icache_config.line);
end_addr = start_addr + size - 1;
start_addr &= (uint32_t)(~(line_size - 1));
status = cpu_lock_save();
do {
_arc_aux_write(AUX_IC_LIL, start_addr);
if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) {
start_addr += line_size;
} else {
ercd = -1; /* the operation failed */
break;
}
} while (start_addr <= end_addr);
cpu_unlock_restore(status);
return ercd;
}
/**
* \brief directly write icache internal ram
*
* \param[in] cache_addr, icache internal address(way+index+offset)
* \param[in] tag cache tag to write (tag+lock bit+valid bit)
* \param[in] data cache data to write
* \return 0, succeeded, -1, failed
*/
int32_t icache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data)
{
if (!icache_available()) return -1;
if (_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS) {
return -1;
}
_arc_aux_write(AUX_IC_RAM_ADDR, cache_addr);
_arc_aux_write(AUX_IC_TAG, tag );
_arc_aux_write(AUX_IC_DATA, data);
return 0;
}
/**
* \brief directly read icache internal ram
*
* \param[in] cache_addr, icache internal address(way+index+offset)
* \param[out] tag cache tag to read (tag+index+lock bit+valid bit)
* \param[out] data cache data to read
* \return 0, succeeded, -1, failed
*/
int32_t icache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data)
{
if (!icache_available()) return -1;
if (_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS) {
return -1;
}
_arc_aux_write(AUX_IC_RAM_ADDR, cache_addr);
*tag = _arc_aux_read(AUX_IC_TAG);
*data = _arc_aux_read(AUX_IC_DATA);
return 0;
}
/**
* \brief indirectly read icache internal ram
*
* \param[in] mem_addr, memory address
* \param[out] tag cache tag to read
* \param[out] data cache data to read
* \return 0, succeeded, -1, failed
*/
int32_t icache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data)
{
if (!icache_available()) return -1;
if (!(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_INDIRECT_ACCESS)) {
return -1;
}
_arc_aux_write(AUX_IC_RAM_ADDR, mem_addr);
if(_arc_aux_read(AUX_IC_CTRL) & IC_CTRL_OP_SUCCEEDED) {
*tag = _arc_aux_read(AUX_IC_TAG);
*data = _arc_aux_read(AUX_IC_DATA);
} else {
return -1; /* the specified memory is not in icache */
}
return 0;
}
/**
* \brief invalidate multi data cache lines
*
* \param[in] start_addr start address in data cache
* \param[in] size the bytes to be invalidated
* \return 0, succeeded, -1, failed
*/
int32_t dcache_invalidate_mlines(uint32_t start_addr, uint32_t size)
{
if (!dcache_available()) return -1;
uint32_t end_addr;
uint32_t line_size;
uint32_t status;
if ((size == 0) || (size > dcache_config.capacity)) {
return -1;
}
line_size = (uint32_t)(dcache_config.line);
end_addr = start_addr + size - 1;
start_addr &= (uint32_t)(~(line_size - 1));
status = cpu_lock_save();
do {
_arc_aux_write(AUX_DC_IVDL, start_addr);
Asm("nop_s");
Asm("nop_s");
Asm("nop_s");
/* wait for flush completion */
while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
start_addr += line_size;
} while (start_addr <= end_addr);
cpu_unlock_restore(status);
return 0;
}
/**
* \brief flush multi lines in data cache
*
* \param[in] start_addr start address
* \param[in] size the bytes to be flushed
* \return 0, succeeded, -1, failed
*/
int32_t dcache_flush_mlines(uint32_t start_addr, uint32_t size)
{
if (!dcache_available()) return -1;
if ((size == 0) || (size > dcache_config.capacity)) {
return -1;
}
uint32_t end_addr;
uint32_t line_size;
uint32_t status;
line_size = (uint32_t)(dcache_config.line);
end_addr = start_addr + size - 1;
start_addr &= (uint32_t)(~(line_size - 1));
status = cpu_lock_save();
do {
_arc_aux_write(AUX_DC_FLDL, start_addr);
Asm("nop_s");
Asm("nop_s");
Asm("nop_s");
/* wait for flush completion */
while (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
start_addr += line_size;
} while (start_addr <= end_addr);
cpu_unlock_restore(status);
return 0;
}
/**
* \brief lock multi lines in data cache
*
* \param[in] start_addr start address in data cache
* \param[in] size the bytes to be locked
* \return 0, succeeded, -1, failed
*/
int32_t dcache_lock_mlines(uint32_t start_addr, uint32_t size)
{
if (!dcache_available()) return -1;
if ((size == 0) || (size > dcache_config.capacity)) {
return -1;
}
uint32_t end_addr;
uint32_t line_size;
uint32_t status;
int32_t ercd = 0;
line_size = (uint32_t)(dcache_config.line);
end_addr = start_addr + size - 1;
start_addr &= (uint32_t)(~(line_size - 1));
status = cpu_lock_save();
do {
_arc_aux_write(AUX_DC_LDL, start_addr);
Asm("nop_s");
if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) {
start_addr += line_size;
} else {
ercd = -1; /* the operation failed */
break;
}
} while (start_addr <= end_addr);
cpu_unlock_restore(status);
return ercd;
}
/**
* \brief directly write dcache internal ram
*
* \param[in] cache_addr, dcache internal address(way+index+offset)
* \param[in] tag cache tag to write
* \param[in] data cache data to write
* \return 0, succeeded, -1, failed
*/
int32_t dcache_direct_write(uint32_t cache_addr, uint32_t tag, uint32_t data)
{
if (!dcache_available()) return -1;
if (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS) {
return -1;
}
_arc_aux_write(AUX_DC_RAM_ADDR, cache_addr);
_arc_aux_write(AUX_DC_TAG, tag);
_arc_aux_write(AUX_DC_DATA, data);
return 0;
}
/**
* \brief directly read dcache internal ram
*
* \param[in] cache_addr, dcache internal address(way+index+offset)
* \param[out] tag cache tag to read
* \param[out] data cache data to read
* \return 0, succeeded, -1, failed
*/
int32_t dcache_direct_read(uint32_t cache_addr, uint32_t *tag, uint32_t *data)
{
if (!dcache_available()) return -1;
if (_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS) {
return -1;
}
_arc_aux_write(AUX_DC_RAM_ADDR, cache_addr);
*tag = _arc_aux_read(AUX_DC_TAG);
*data = _arc_aux_read(AUX_DC_DATA);
return 0;
}
/**
* \brief indirectly read dcache internal ram
*
* \param[in] mem_addr, memory address(tag+index+offset)
* \param[out] tag cache tag to read
* \param[out] data cache data to read
* \return 0, succeeded, -1, failed
*/
int32_t dcache_indirect_read(uint32_t mem_addr, uint32_t *tag, uint32_t *data)
{
if (!dcache_available()) return -1;
if (!(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_INDIRECT_ACCESS)) {
return -1;
}
_arc_aux_write(AUX_DC_RAM_ADDR, mem_addr);
if(_arc_aux_read(AUX_DC_CTRL) & DC_CTRL_OP_SUCCEEDED) {
*tag = _arc_aux_read(AUX_DC_TAG);
*data = _arc_aux_read(AUX_DC_DATA);
} else {
return -1; /* the specified memory is not in dcache */
}
return 0;
}
/**
* \brief initialize cache
* 1. invalidate icache and dcache
* 2. Only support ARCv2 cache
*/
void arc_cache_init(void)
{
uint32_t build_cfg;
build_cfg = _arc_aux_read(AUX_BCR_D_CACHE);
dcache_config.ver = build_cfg & 0xff;
if (dcache_config.ver >= 0x04) { /* ARCv2 */
dcache_enable(DC_CTRL_DISABLE_FLUSH_LOCKED |
DC_CTRL_INDIRECT_ACCESS | DC_CTRL_INVALID_FLUSH);
dcache_invalidate();
dcache_config.assoc = 1 << ((build_cfg >> 8) & 0xf);
dcache_config.capacity = 512 << ((build_cfg >> 12) & 0xf);
dcache_config.line = 16 << ((build_cfg >> 16) & 0xf);
}
build_cfg = _arc_aux_read(AUX_BCR_I_CACHE);
icache_config.ver = build_cfg & 0xff;
if (icache_config.ver >= 0x04) { /* ARCv2 */
icache_config.assoc = 1 << ((build_cfg >> 8) & 0xf);
icache_config.capacity = 512 << ((build_cfg >> 12) & 0xf);
icache_config.line = 8 << ((build_cfg >> 16) & 0xf);
icache_enable(IC_CTRL_IC_ENABLE);
icache_invalidate();
}
}
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-15
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup ARC_HAL_EXCEPTION_CPU
* \brief assembly part of exception and interrupt processing
*/
/**
* \addtogroup ARC_HAL_EXCEPTION_CPU
* @{
*/
/* function documentation */
/**
* \fn void exc_entry_cpu(void)
* \brief default entry of CPU exceptions, such as TLB miss and swap.
*
* \fn void exc_entry_int(void)
* \brief normal interrupt exception entry.
* In default, all interrupt exceptions are installed with normal entry.
* If FIRQ is required, exc_entry_firq should be the entry.
*
* \fn void exc_entry_firq(void)
* \brief firq exception entry
*/
/** }@ */
/** @cond EXCEPTION_ASM */
#define __ASSEMBLY__
#include "inc/arc/arc.h"
#include "inc/arc/arc_asm_common.h"
.file "arc_exc_asm.S"
/* entry for cpu exception handling */
.text
.global exc_entry_cpu
.weak exc_entry_cpu
.align 4
exc_entry_cpu:
EXCEPTION_PROLOGUE
mov r3, sp /* as exception handler's para(exc_frame) */
/* exc_nest_count +1 */
ld r0, [exc_nest_count]
add r0, r0, 1
st r0, [exc_nest_count]
/* find the exception cause */
lr r0, [AUX_ECR]
lsr r0, r0, 16
bmsk r0, r0, 7
mov r1, exc_int_handler_table
ld.as r2, [r1, r0]
mov r0, r3
jl [r2] /* jump to exception handler where interrupts are not allowed! */
/* interrupts are not allowed */
exc_return:
/* exc_nest_count -1 */
ld r0, [exc_nest_count]
sub r0, r0, 1
st r0, [exc_nest_count]
EXCEPTION_EPILOGUE
rtie
/****** entry for normal interrupt exception handling ******/
.global exc_entry_int
.weak exc_entry_int
.align 4
exc_entry_int:
clri /* disable interrupt */
#if ARC_FEATURE_FIRQ == 1
#if ARC_FEATURE_RGF_NUM_BANKS > 1
lr r0, [AUX_IRQ_ACT] /* check whether it is P0 interrupt */
btst r0, 0
bnz exc_entry_firq
#else
PUSH r10
lr r10, [AUX_IRQ_ACT]
btst r10, 0
POP r10
bnz exc_entry_firq
#endif
#endif
INTERRUPT_PROLOGUE /* save scratch regs, this will be affected */
/* exc_nest_count +1 */
ld r0, [exc_nest_count]
add r0, r0, 1
st r0, [exc_nest_count]
lr r0, [AUX_IRQ_CAUSE]
mov r1, exc_int_handler_table
ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */
/* for the case of software triggered interrupt */
lr r3, [AUX_IRQ_HINT]
cmp r3, r0
bne.d irq_hint_handled
xor r3, r3, r3
sr r3, [AUX_IRQ_HINT]
irq_hint_handled:
seti /* enable higher priority interrupt */
mov r0, sp
jl [r2] /* jump to interrupt handler */
/* no interrupts are allowed from here */
int_return:
clri /* disable interrupt */
/* exc_nest_count -1 */
ld r0, [exc_nest_count]
sub r0, r0, 1
st r0, [exc_nest_count]
INTERRUPT_EPILOGUE
rtie
/****** entry for fast irq exception handling ******/
.global exc_entry_firq
.weak exc_entry_firq
.align 4
exc_entry_firq:
clri /* disable interrupt */
SAVE_FIQ_EXC_REGS
/* exc_nest_count +1 */
ld r0, [exc_nest_count]
add r0, r0, 1
st r0, [exc_nest_count]
lr r0, [AUX_IRQ_CAUSE]
mov r1, exc_int_handler_table
ld.as r2, [r1, r0] /* r2 = _kernel_exc_tbl + irqno *4 */
/* for the case of software triggered interrupt */
lr r3, [AUX_IRQ_HINT]
cmp r3, r0
bne.d firq_hint_handled
xor r3, r3, r3
sr r3, [AUX_IRQ_HINT]
firq_hint_handled:
jl [r2] /* jump to interrupt handler */
/* no interrupts are allowed from here */
firq_return:
/* exc_nest_count -1 */
ld r0, [exc_nest_count]
sub r0, r0, 1
st r0, [exc_nest_count]
RESTORE_FIQ_EXC_REGS
rtie
/** @endcond */
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-15
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT
* \brief C Implementation of exception and interrupt management
*/
#include "inc/arc/arc_exception.h"
#include "inc/arc/arc_cache.h"
//#define DBG_LESS
//#include "embARC_debug.h"
/**
* \addtogroup ARC_HAL_EXCEPTION_CPU
* @{
* \var exc_entry_table
* \brief exception entry table
*
* install exception entry table to ARC_AUX_INT_VECT_BASE in startup.
* According to ARCv2 ISA, vectors are fetched in instruction space and thus
* may be present in ICCM, Instruction Cache, or
* main memory accessed by instruction fetch logic.
* So it is put into a specific section .vector.
*
* Please note that the exc_entry_table maybe cached in ARC. Some functions is
* defined in .s files.
*
*/
/**
* \ingroup ARC_HAL_EXCEPTION_CPU
* \brief default cpu exception handler
* \param p_excinf pointer to the exception frame
*/
static void exc_handler_default(void *p_excinf)
{
// uint32_t excpt_cause_reg = 0;
// uint32_t excpt_ret_reg = 0;
// uint32_t exc_no = 0;
// excpt_cause_reg = _arc_aux_read(AUX_ECR);
// excpt_ret_reg = _arc_aux_read(AUX_ERRET);
// exc_no = (excpt_cause_reg >> 16) & 0xff;
Asm("kflag 1");
}
/**
* \ingroup ARC_HAL_EXCEPTION_INTERRUPT
* \brief default interrupt handler
* \param[in] p_excinf information for interrupt handler
*/
static void int_handler_default(void *p_excinf)
{
// uint32_t int_cause_reg = 0;
// int_cause_reg = _arc_aux_read(AUX_IRQ_CAUSE);
Asm("kflag 1");
}
__attribute__ ((aligned(1024), section(".vector")))
EXC_ENTRY exc_entry_table[NUM_EXC_ALL] = {
[0] = _arc_reset,
[1 ... NUM_EXC_CPU-1] = exc_entry_cpu,
[NUM_EXC_CPU ... NUM_EXC_ALL-1] = exc_entry_int
};
/**
* \var exc_int_handler_table
* \brief the cpu exception and interrupt exception handler table
* called in exc_entry_default and exc_entry_int
*/
EXC_HANDLER exc_int_handler_table[NUM_EXC_ALL] = {
[0 ... NUM_EXC_CPU-1] = exc_handler_default,
[NUM_EXC_CPU ... NUM_EXC_ALL-1] = int_handler_default
};
/**
* \var exc_nest_count
* \brief the counter for exc/int processing, =0 no int/exc
* >1 in int/exc processing
* @}
*/
uint32_t exc_nest_count;
typedef struct aux_irq_ctrl_field {
/* note: little endian */
uint32_t save_nr_gpr_pairs: 5; /** Indicates number of general-purpose register pairs saved, from 0 to 8/16 */
uint32_t res: 4; /** Reserved */
uint32_t save_blink: 1; /** Indicates whether to save and restore BLINK */
uint32_t save_lp_regs: 1; /** Indicates whether to save and restore loop registers (LP_COUNT, LP_START, LP_END) */
uint32_t save_u_to_u: 1; /** Indicates if user context is saved to user stack */
uint32_t res2: 1; /** Reserved */
uint32_t save_idx_regs: 1; /** Indicates whether to save and restore code-density registers (EI_BASE, JLI_BASE, LDI_BASE) */
uint32_t res3: 18; /** Reserved */
} aux_irq_ctrl_field_t;
typedef union {
aux_irq_ctrl_field_t bits;
uint32_t value;
} aux_irq_ctrl_t;
/**
* \ingroup ARC_HAL_EXCEPTION_CPU ARC_HAL_EXCEPTION_INTERRUPT
* \brief intialize the exception and interrupt handling
*/
void exc_int_init(void)
{
uint32_t i;
uint32_t status;
aux_irq_ctrl_t ictrl;
ictrl.value = 0;
#ifndef ARC_FEATURE_RF16
ictrl.bits.save_nr_gpr_pairs = 6; /* r0 to r11 (r12 saved manually) */
#else
ictrl.bits.save_nr_gpr_pairs = 3; /* r0 to r3, r10, r11 */
#endif
ictrl.bits.save_blink = 1;
ictrl.bits.save_lp_regs = 1; /* LP_COUNT, LP_START, LP_END */
ictrl.bits.save_u_to_u = 0; /* user ctxt saved on kernel stack */
ictrl.bits.save_idx_regs = 1; /* JLI, LDI, EI */
status = arc_lock_save();
for (i = NUM_EXC_CPU; i < NUM_EXC_ALL; i++) {
/* interrupt level triggered, disabled, priority is the lowest */
_arc_aux_write(AUX_IRQ_SELECT, i);
_arc_aux_write(AUX_IRQ_ENABLE, 0);
_arc_aux_write(AUX_IRQ_TRIGGER, 0);
#if defined(ARC_FEATURE_SEC_PRESENT) && (SECURESHIELD_VERSION < 2)
_arc_aux_write(AUX_IRQ_PRIORITY, (1 << AUX_IRQ_PRIORITY_BIT_S)|(INT_PRI_MAX - INT_PRI_MIN));
#else
_arc_aux_write(AUX_IRQ_PRIORITY, INT_PRI_MAX - INT_PRI_MIN);
#endif
}
_arc_aux_write(AUX_IRQ_CTRL, ictrl.value);
arc_unlock_restore(status);
/** ipm should be set after cpu unlock restore to avoid reset of the status32 value */
arc_int_ipm_set((INT_PRI_MAX - INT_PRI_MIN));
}
/**
* \ingroup ARC_HAL_EXCEPTION_CPU
* \brief install a CPU exception entry
* \param[in] excno exception number
* \param[in] entry the entry of exception to install
*/
int32_t exc_entry_install(const uint32_t excno, EXC_ENTRY entry)
{
uint32_t status;
EXC_ENTRY *table = (EXC_ENTRY *)_arc_aux_read(AUX_INT_VECT_BASE);
if (excno < NUM_EXC_ALL && entry != NULL
&& table[excno] != entry) {
status = cpu_lock_save();
/* directly write to mem, as arc gets exception handler from mem not from cache */
/* FIXME, here maybe icache is dirty, need to be invalidated */
table[excno] = entry;
if (_arc_aux_read(AUX_BCR_D_CACHE) > 0x2) {
/* dcache is available */
dcache_flush_line((uint32_t)&table[excno]);
}
if (_arc_aux_read(AUX_BCR_D_CACHE) > 0x2) {
/* icache is available */
icache_invalidate_line((uint32_t)&table[excno]);
}
cpu_unlock_restore(status);
return 0;
}
return -1;
}
/**
* \ingroup ARC_HAL_EXCEPTION_CPU
* \brief get the installed CPU exception entry
* \param[in] excno exception number
* \return the installed CPU exception entry
*/
EXC_ENTRY exc_entry_get(const uint32_t excno)
{
if (excno < NUM_EXC_ALL) {
return exc_entry_table[excno];
}
return NULL;
}
/**
* \ingroup ARC_HAL_EXCEPTION_CPU
* \brief install an exception handler
* \param[in] excno exception number
* \param[in] handler the handler of exception to install
*/
int32_t exc_handler_install(const uint32_t excno, EXC_HANDLER handler)
{
if (excno < NUM_EXC_ALL && handler != NULL) {
exc_int_handler_table[excno] = handler;
return 0;
}
return -1;
}
/**
* \ingroup ARC_HAL_EXCEPTION_CPU
* \brief get the installed exception handler
* \param[in] excno exception number
* \return the installed exception handler or NULL
*/
EXC_HANDLER exc_handler_get(const uint32_t excno)
{
if (excno < NUM_EXC_ALL) {
return exc_int_handler_table[excno];
}
return NULL;
}
#ifndef EMBARC_OVERRIDE_ARC_INTERRUPT_MANAGEMENT
/**
* \brief disable the specific interrupt
*
* \param[in] intno interrupt number
*/
int32_t int_disable(const uint32_t intno)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
arc_int_disable(intno);
return 0;
}
return -1;
}
/**
* \brief enable the specific int
*
* \param[in] intno interrupt number
*/
int32_t int_enable(const uint32_t intno)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
arc_int_enable(intno);
return 0;
}
return -1;
}
/**
* \brief check whether the specific int is enabled
*
* \param[in] intno interrupt number
* \return 0 disabled, 1 enabled, < 0 error
*/
int32_t int_enabled(const uint32_t intno)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
_arc_aux_write(AUX_IRQ_SELECT, intno);
return _arc_aux_read(AUX_IRQ_ENABLE);
}
return -1;
}
/**
* \brief get the interrupt priority mask
*
* \returns interrupt priority mask, negative num
*/
int32_t int_ipm_get(void)
{
return ((int32_t)arc_int_ipm_get() + INT_PRI_MIN);
}
/**
* \brief set the interrupt priority mask
*
* \param[in] intpri interrupt priority
*/
int32_t int_ipm_set(int32_t intpri)
{
if (intpri >= INT_PRI_MIN && intpri <= INT_PRI_MAX) {
intpri = intpri - INT_PRI_MIN;
arc_int_ipm_set(intpri);
return 0;
}
return -1;
}
/**
* \brief get current interrupt priority mask
*
* \param[in] intno interrupt number
* \return <0 interrupt priority, 0 error
*/
int32_t int_pri_get(const uint32_t intno)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
return (int32_t)arc_int_pri_get(intno) + INT_PRI_MIN;
}
return 0;
}
/**
* \brief set interrupt priority
*
* \param[in] intno interrupt number
* \param[in] intpri interrupt priority
* \return <0 error, 0 ok
*/
int32_t int_pri_set(const uint32_t intno, int32_t intpri)
{
uint32_t status;
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
status = cpu_lock_save();
intpri = intpri - INT_PRI_MIN;
arc_int_pri_set(intno,(uint32_t)intpri);
cpu_unlock_restore(status);
return 0;
}
return -1;
}
/**
* \brief set interrupt secure or not secure
* This function is valid in secureshield v2
* \param[in] intno interrupt number
* \param[in] secure, 0 for normal, >0 for secure
* \return <0 error, 0 ok
*/
int32_t int_secure_set(const uint32_t intno, uint32_t secure)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
arc_int_secure_set(intno, secure);
return 0;
}
return -1;
}
/**
* \brief probe the pending status of interrupt
*
* \param[in] intno interrupt number
*
* \returns 1 pending, 0 no pending, -1 error
*/
int32_t int_probe(const uint32_t intno)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
return arc_int_probe(intno);
}
return -1;
}
/**
* \brief trigger the interrupt in software
*
* \param[in] intno interrupt number
* \return 0 ok, -1 error
*/
int32_t int_sw_trigger(const uint32_t intno)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
arc_int_sw_trigger(intno);
return 0;
}
return -1;
}
/**
* \brief config the interrupt level triggered or pulse triggered
*
* \param[in] intno interrupt number
* \param[in] level, 0-level trigger, 1-pulse triggered
* \return 0 ok, -1 error
*/
int32_t int_level_config(const uint32_t intno, const uint32_t level)
{
if (intno >= NUM_EXC_CPU && intno < NUM_EXC_ALL) {
arc_int_level_config(intno, level);
return 0;
}
return -1;
}
/**
* \brief lock cpu, disable interrupts
*/
void cpu_lock(void)
{
arc_lock();
}
/**
* \brief unlock cpu, enable interrupts to happen
*/
void cpu_unlock(void)
{
arc_unlock();
}
/**
* \brief lock cpu and return status
*
* \returns cpu status
*/
uint32_t cpu_lock_save(void)
{
return arc_lock_save();
}
/**
* \brief unlock cpu with the specific status
*
* \param[in] status cpu status saved by cpu_lock_save
*/
void cpu_unlock_restore(const uint32_t status)
{
arc_unlock_restore(status);
}
/**
* \ingroup ARC_HAL_EXCEPTION_INTERRUPT
* \brief install an interrupt handler
* \param[in] intno interrupt number
* \param[in] handler interrupt handler to install
*/
int32_t int_handler_install(const uint32_t intno, INT_HANDLER handler)
{
/*!< \todo parameter check ? */
if (intno >= NUM_EXC_CPU) {
return exc_handler_install(intno, handler);
}
return -1;
}
/**
* \ingroup ARC_HAL_EXCEPTION_INTERRUPT
* \brief get the installed an interrupt handler
* \param[in] intno interrupt number
* \return the installed interrupt handler or NULL
*/
INT_HANDLER int_handler_get(const uint32_t intno)
{
if (intno >= NUM_EXC_CPU) {
return exc_handler_get(intno);
}
return NULL;
}
#endif /* EMBARC_OVERRIDE_ARC_INTERRUPT_MANAGEMENT */
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-15
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup ARC_HAL_MISC_TIMER
* \brief implementation of internal timer related functions
* \todo RTC support should be improved if RTC is enabled
*/
#include "inc/arc/arc_timer.h"
#include "inc/arc/arc.h"
#include "inc/arc/arc_builtin.h"
/**
* \brief check whether the specific timer present
* \param[in] no timer number
* \retval 1 present
* \retval 0 not present
*/
int32_t arc_timer_present(const uint32_t no)
{
uint32_t bcr = _arc_aux_read(AUX_BCR_TIMERS);
switch (no) {
case TIMER_0:
bcr = (bcr >> 8) & 1;
break;
case TIMER_1:
bcr = (bcr >> 9) & 1;
break;
case TIMER_RTC:
bcr = (bcr >> 10) & 1;
break;
default:
bcr = 0;
/* illegal argument so return false */
break;
}
return (int)bcr;
}
/**
* \brief start the specific timer
* \param[in] no timer number
* \param[in] mode timer mode
* \param[in] val timer limit value (not for RTC)
* \return 0 success, -1 failure
*/
int32_t arc_timer_start(const uint32_t no, const uint32_t mode, const uint32_t val)
{
if (arc_timer_present(no) == 0) {
return -1;
}
switch (no) {
case TIMER_0:
_arc_aux_write(AUX_TIMER0_CTRL, 0);
_arc_aux_write(AUX_TIMER0_LIMIT, val);
_arc_aux_write(AUX_TIMER0_CTRL, mode);
_arc_aux_write(AUX_TIMER0_CNT, 0);
break;
case TIMER_1:
_arc_aux_write(AUX_TIMER1_CTRL, 0);
_arc_aux_write(AUX_TIMER1_LIMIT, val);
_arc_aux_write(AUX_TIMER1_CTRL, mode);
_arc_aux_write(AUX_TIMER1_CNT, 0);
break;
case TIMER_RTC:
_arc_aux_write(AUX_RTC_CTRL, mode);
break;
default:
return -1;
}
return 0;
}
/**
* \brief stop and clear the specific timer
*
* \param[in] no timer number
* \return 0 success, -1 failure
*/
int32_t arc_timer_stop(const uint32_t no)
{
if (arc_timer_present(no) == 0) {
return -1;
}
switch (no) {
case TIMER_0 :
_arc_aux_write(AUX_TIMER0_CTRL, 0);
_arc_aux_write(AUX_TIMER0_LIMIT,0);
_arc_aux_write(AUX_TIMER0_CNT, 0);
break;
case TIMER_1:
_arc_aux_write(AUX_TIMER1_CTRL, 0);
_arc_aux_write(AUX_TIMER1_LIMIT,0);
_arc_aux_write(AUX_TIMER1_CNT, 0);
break;
case TIMER_RTC:
_arc_aux_write(AUX_RTC_CTRL, TIMER_RTC_CLEAR);
break;
default:
return -1;
}
return 0;
}
/**
* \brief get timer current tick
*
* \param[in] no timer number
* \param[out] val, timer value
* \return 0 success, -1 failure
*/
int32_t arc_timer_current(const uint32_t no, void *val)
{
if (arc_timer_present(no) == 0) {
return -1;
}
switch (no) {
case TIMER_0 :
*((uint32_t *)val) = _arc_aux_read(AUX_TIMER0_CNT);
break;
case TIMER_1 :
*((uint32_t *)val) = _arc_aux_read(AUX_TIMER1_CNT);
break;
case TIMER_RTC:
*((uint64_t *)val) = _arc_aux_read(AUX_RTC_LOW);
break;
default :
return -1;
}
return 0;
}
/**
* \brief clear the interrupt pending bit of timer
*
* \param[in] no timer number
* \return 0 success, -1 failure
*/
int32_t arc_timer_int_clear(const uint32_t no)
{
uint32_t val;
if (arc_timer_present(no) == 0) {
return -1;
}
switch (no) {
case TIMER_0 :
val = _arc_aux_read(AUX_TIMER0_CTRL);
val &= ~TIMER_CTRL_IP;
_arc_aux_write(AUX_TIMER0_CTRL, val);
break;
case TIMER_1 :
val = _arc_aux_read(AUX_TIMER1_CTRL);
val &= ~TIMER_CTRL_IP;
_arc_aux_write(AUX_TIMER1_CTRL, val);
break;
default :
return -1;
}
return 0;
}
/**
* \brief init internal timer
*/
void arc_timer_init(void)
{
arc_timer_stop(TIMER_0);
arc_timer_stop(TIMER_1);
arc_timer_stop(TIMER_RTC);
}
/*
* Copyright (c) 2012-2014 Wind River Systems, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* ------------------------------------------
* Copyright (c) 2015, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2016-03-02
* \author Wayne Ren(wei.ren@synopsys.com)
--------------------------------------------- */
#include "embARC_BSP_config.h"
#if defined(__GNU__)
/* embARC's GNU C++ support takes reference from Zephyr (cpp_xxx.c) */
/**
* @file - Constructor module
* @brief
* The ctors section contains a list of function pointers that execute the
* C++ constructors of static global objects. These must be executed before
* the application's main() routine.
*
* NOTE: Not all compilers put those function pointers into the ctors section;
* some put them into the init_array section instead.
*/
/* What a constructor function pointer looks like */
typedef void (*CtorFuncPtr)(void);
/* Constructor function pointer list is generated by the linker script. */
extern CtorFuncPtr __CTOR_LIST__[];
extern CtorFuncPtr __CTOR_END__[];
/**
*
* @brief Invoke all C++ style global object constructors
*
* This routine is invoked before the execution of the
* application's main().
*/
void __do_global_ctors_aux(void)
{
unsigned int nCtors;
nCtors = (unsigned int)__CTOR_LIST__[0];
while (nCtors >= 1) {
__CTOR_LIST__[nCtors--]();
}
}
typedef void (*DtorFuncPtr)(void);
extern DtorFuncPtr __DTOR_LIST__[];
extern DtorFuncPtr __DTOR_END__[];
/**
*
* @brief Invoke all C++ style global object destructors
*
* This routine is invoked after the execution of the
* application's main().
*/
void __do_global_dtors_aux(void)
{
unsigned int nDtors;
unsigned int i;
nDtors = (unsigned int)__DTOR_LIST__[0];
i = 0;
while (i <= nDtors) {
__DTOR_LIST__[i++]();
}
}
void *__dso_handle = 0;
/**
* @brief Register destructor for a global object
*
* @param destructor the global object destructor function
* @param objptr global object pointer
* @param dso Dynamic Shared Object handle for shared libraries
*
* Function does nothing at the moment, assuming the global objects
* do not need to be deleted
*
* @return N/A
*/
int __cxa_atexit(void (*destructor)(void *), void *objptr, void *dso)
{
return 0;
}
typedef void (*func_ptr)(void);
extern func_ptr __init_array_start[0];
extern func_ptr __init_array_end[0];
/**
* @brief Execute initialization routines referenced in .init_array section
*
* @return N/A
*/
void __do_init_array_aux(void)
{
for (func_ptr *func = __init_array_start;
func < __init_array_end;
func++) {
(*func)();
}
}
/**
* @brief Stub for pure virtual functions
*
* This routine is needed for linking C++ code that uses pure virtual
* functions.
*
* @return N/A
*/
void __cxa_pure_virtual(void)
{
while (1) {
;
}
}
#endif
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-15
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup ARC_HAL_STARTUP
* \brief assembly part of startup process
*/
/**
* \addtogroup ARC_HAL_STARTUP
* @{
*/
/** @cond STARTUP_ASM */
#define __ASSEMBLY__
#include "embARC_BSP_config.h"
#include "inc/arc/arc.h"
.file "arc_startup.S"
.weak _f_sdata /* start of small data, defined in link script */
.weak init_hardware_hook /* app hardware init hook */
.weak init_software_hook /* app software init hook */
.extern board_main
.extern exc_entry_table
/* initial vector table */
.section .init_vector, "a"
.long _arc_reset
.section .init_bootstrap, "ax"
.global _arc_reset
.global _start
.align 4
_start:
_arc_reset:
_arc_reset_stage1:
kflag STATUS32_RESET_VALUE
/* STAGE 1 */
/* necessary hardware should be done first to speed up initialization
1. system clk
2. mem controller must be initialized before any access to external
mem.
3. others
*/
_arc_cache_init_start:
lr r0, [AUX_BCR_D_CACHE]
cmp r0, 2
/* invalidate dcache */
jle _arc_icache_init
mov r0, 1
sr r0, [AUX_DC_IVDC]
sr r0, [AUX_DC_CTRL]
_arc_icache_init:
lr r0, [AUX_BCR_I_CACHE]
cmp r0, 2
jle _arc_cache_init_end
/* invalidate icache */
mov r0, 1
sr r0, [AUX_IC_IVIC]
nop_s
nop_s
nop_s
sr r0, [AUX_IC_CTRL]
_arc_cache_init_end:
mov r0, init_hardware_hook
cmp r0, 0
jlne [r0]
/* STAGE 2: init necessary registers */
_arc_reset_stage2:
mov r0, 0
/* interrupt related init */
sr r0, [AUX_IRQ_ACT]
sr r0, [AUX_IRQ_CTRL]
sr r0, [AUX_IRQ_HINT]
/* use the new vector table to replace the old one */
#if defined(ARC_FEATURE_SEC_PRESENT) && (SECURESHIELD_VERSION < 2)
sr exc_entry_table, [AUX_INT_VECT_BASE_S]
#else
sr exc_entry_table, [AUX_INT_VECT_BASE]
#endif
/* init stack */
#if ARC_FEATURE_RGF_BANKED_REGS >= 16 && ARC_FEATURE_RGF_BANKED_REGS > 1 && ARC_FEATURE_FIRQ == 1
#if _STACKSIZE < 512
#error "not enough stack size for irq and firq"
#endif
/* switch to register bank1 */
lr r0, [AUX_STATUS32]
bic r0, r0, 0x70000
or r0, r0, 0x10000
kflag r0
/* set sp, gp, fp in bank1 */
mov sp, _e_stack
mov gp, _f_sdata
mov fp, 0
/* come back to bank0 */
lr r0, [AUX_STATUS32]
bic r0, r0, 0x70000
kflag r0
mov sp, _e_stack-256
#else
mov sp, _e_stack /* init stack pointer */
#endif
mov gp, _f_sdata /* init small-data base register */
mov fp, 0 /* init fp register */
_arc_reset_stage3:
_s3_copy_text:
mov r0, _f_text
mov r1, _load_addr_text
cmp r0, r1
/* if load addr == run addr, no need to copy */
jeq _s3_copy_rodata
mov r3, _e_text
_s3_copy_text_loop:
ld.ab r2, [r1, 4]
st.ab r2, [r0, 4]
cmp r0, r3
jlt _s3_copy_text_loop
_s3_copy_rodata:
mov r0, _f_rodata
mov r1, _load_addr_rodata
cmp r0, r1
/* if load addr == run addr, no need to copy */
jeq _s3_copy_data
mov r3, _e_rodata
_s3_copy_rodata_loop:
ld.ab r2, [r1, 4]
st.ab r2, [r0, 4]
cmp r0, r3
jlt _s3_copy_rodata_loop
_s3_copy_data:
mov r0, _f_data
mov r1, _load_addr_data
cmp r0, r1
jeq _s3_clear_bss
/* if load addr == run addr, no need to copy */
mov r3, _e_data
_s3_copy_data_loop:
ld.ab r2, [r1, 4]
st.ab r2, [r0, 4]
cmp r0, r3
jlt _s3_copy_data_loop
_s3_clear_bss:
mov r0, _f_bss
mov r1, _e_bss
cmp r0, r1
jge _arc_reset_call_main
mov r2, 0
_s3_clear_bss_loop:
st.ab r2, [r0, 4]
cmp r0, r1
jlt _s3_clear_bss_loop
/* STAGE 3: go to main */
_arc_reset_call_main:
/* \todo add cpp init here */
mov r0, init_software_hook
cmp r0, 0
jlne [r0]
/* board level library init */
/* early init of interrupt and exception */
jl exc_int_init
/* init cache */
jl arc_cache_init
#if defined(__MW__)
jl _init
#elif defined(__GNU__)
jl __do_global_ctors_aux
jl __do_init_array_aux
#endif
jl board_main /* board-level main */
#if defined(__MW__)
jl _fini
#elif defined(__GNU__)
jl __do_global_dtors_aux
#endif
.global _exit_loop
.global _exit_halt
.align 4
_exit_halt:
_exit_loop:
flag 0x1
nop
nop
nop
b _exit_loop
#if defined(__MW__)
.global _init, _fini
.section ".init",text
_init:
.cfa_bf _init
push %blink
.cfa_push {%blink}
.section ".init$999999", text, 1, 2, check_text_align=0
pop %blink
.cfa_pop {%blink}
j [%blink]
.cfa_ef
.section ".fini", text
_fini:
.cfa_bf _fini
push %blink
.cfa_push {%blink}
.section ".fini$999999", text, 1, 2, check_text_align=0
pop %blink
.cfa_pop {%blink}
j [%blink]
.cfa_ef
#endif
/** @endcond */
/** }@*/
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-22
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \defgroup DEVICE_DW_GPIO Designware GPIO Driver
* \ingroup DEVICE_DW
* \brief Designware GPIO Driver Implementation
*/
/**
* \file
* \brief designware gpio driver
* \ingroup DEVICE_DW_GPIO
* \brief Designware GPIO driver
*/
#include "inc/embARC_toolchain.h"
#include "inc/embARC_error.h"
#include "inc/arc/arc_exception.h"
#include "device/designware/gpio/dw_gpio.h"
/** check expressions used in DesignWare GPIO driver implementation */
#define DW_GPIO_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit)
#ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK
/** valid check of uart info object */
#define VALID_CHK_GPIO_INFO_OBJECT(gpioinfo_obj_ptr) { \
DW_GPIO_CHECK_EXP((gpioinfo_obj_ptr)!=NULL, E_OBJ); \
DW_GPIO_CHECK_EXP(((gpioinfo_obj_ptr)->gpio_ctrl)!=NULL, E_OBJ); \
}
#endif
/**
* \defgroup DEVICE_DW_GPIO_STATIC DesignWare GPIO Driver Static Functions
* \ingroup DEVICE_DW_GPIO
* \brief Static or inline functions, variables for DesignWare GPIO handle gpio operations,
* only used in this file
* @{
*/
Inline uint32_t dw_gpio_read_ext(DW_GPIO_PORT_PTR port)
{
return port->regs->EXT_PORTS[port->no];
}
Inline uint32_t dw_gpio_read_dir(DW_GPIO_PORT_PTR port)
{
return port->regs->SWPORTS[port->no].DDR;
}
Inline uint32_t dw_gpio_read_dr(DW_GPIO_PORT_PTR port)
{
return port->regs->SWPORTS[port->no].DR;
}
Inline uint32_t dw_gpio_read_mthd(DW_GPIO_PORT_PTR port)
{
return port->regs->INTEN;
}
Inline void dw_gpio_int_enable(DW_GPIO_PORT_PTR port, uint32_t bit_mask)
{
port->regs->INTEN |= bit_mask;
}
Inline void dw_gpio_int_disable(DW_GPIO_PORT_PTR port, uint32_t bit_mask)
{
port->regs->INTEN &= (~bit_mask);
}
Inline void dw_gpio_int_mask(DW_GPIO_PORT_PTR port, uint32_t bit_mask)
{
port->regs->INTMASK |= bit_mask;
}
Inline void dw_gpio_int_unmask(DW_GPIO_PORT_PTR port, uint32_t bit_mask)
{
port->regs->INTMASK &= (~bit_mask);
}
Inline uint32_t dw_gpio_int_read_level(DW_GPIO_PORT_PTR port)
{
return port->regs->INTTYPE_LEVEL;
}
Inline uint32_t dw_gpio_int_read_polarity(DW_GPIO_PORT_PTR port)
{
return port->regs->INT_POLARITY;
}
Inline uint32_t dw_gpio_int_read_debounce(DW_GPIO_PORT_PTR port)
{
return port->regs->DEBOUNCE;
}
Inline uint32_t dw_gpio_int_read_status(DW_GPIO_PORT_PTR port)
{
return port->regs->INTSTATUS;
}
Inline void dw_gpio_int_clear(DW_GPIO_PORT_PTR port, uint32_t bit_mask)
{
port->regs->PORTA_EOI = bit_mask;
}
static void dw_gpio_int_write_level(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_level)
{
uint32_t reg_val;
reg_val = port->regs->INTTYPE_LEVEL;
reg_val &= (~bit_mask);
bit_level &= bit_mask;
reg_val |= bit_level;
port->regs->INTTYPE_LEVEL = reg_val;
}
static void dw_gpio_int_write_polarity(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_polarity)
{
uint32_t reg_val;
reg_val = port->regs->INT_POLARITY;
reg_val &= (~bit_mask);
bit_polarity &= bit_mask;
reg_val |= bit_polarity;
port->regs->INT_POLARITY = reg_val;
}
static void dw_gpio_int_write_debounce(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t bit_debounce)
{
uint32_t reg_val;
reg_val = port->regs->DEBOUNCE;
reg_val &= (~bit_mask);
bit_debounce &= bit_mask;
reg_val |= bit_debounce;
port->regs->DEBOUNCE = reg_val;
}
static void dw_gpio_set_int_cfg(DW_GPIO_PORT_PTR port, DEV_GPIO_INT_CFG *int_cfg)
{
dw_gpio_int_write_level(port, int_cfg->int_bit_mask, int_cfg->int_bit_type);
dw_gpio_int_write_polarity(port, int_cfg->int_bit_mask, int_cfg->int_bit_polarity);
dw_gpio_int_write_debounce(port, int_cfg->int_bit_mask, int_cfg->int_bit_debounce);
}
static void dw_gpio_get_int_cfg(DW_GPIO_PORT_PTR port, DEV_GPIO_INT_CFG *int_cfg)
{
int_cfg->int_bit_type = dw_gpio_int_read_level(port) & int_cfg->int_bit_mask;
int_cfg->int_bit_polarity = dw_gpio_int_read_polarity(port) & int_cfg->int_bit_mask;
int_cfg->int_bit_debounce = dw_gpio_int_read_debounce(port) & int_cfg->int_bit_mask;
}
static void dw_gpio_write_dr(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t val)
{
uint32_t temp_reg;
temp_reg = port->regs->SWPORTS[port->no].DR;
temp_reg &= ~bit_mask;
val &= bit_mask;
temp_reg |= val;
port->regs->SWPORTS[port->no].DR = temp_reg;
}
static void dw_gpio_write_dir(DW_GPIO_PORT_PTR port, uint32_t bit_mask, uint32_t val)
{
uint32_t temp_reg;
temp_reg = port->regs->SWPORTS[port->no].DDR;
temp_reg &= ~bit_mask;
val &= bit_mask;
temp_reg |= val;
port->regs->SWPORTS[port->no].DDR = temp_reg;
}
static uint32_t dw_gpio_read_val(DW_GPIO_PORT_PTR port)
{
uint32_t val;
val = dw_gpio_read_ext(port) & (~dw_gpio_read_dir(port));
val |= dw_gpio_read_dr(port) & dw_gpio_read_dir(port);
return val;
}
/** @} end of group DEVICE_DW_GPIO_STATIC */
/* interface for DEV_GPIO */
/** Open designware gpio device with specified io direction configuration */
int32_t dw_gpio_open(DEV_GPIO *gpio_obj, uint32_t dir)
{
int32_t ercd = E_OK;
DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info);
/* START ERROR CHECK */
VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr);
/* END OF ERROR CHECK */
DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl);
DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ);
port_info_ptr->opn_cnt ++;
if (port_info_ptr->opn_cnt > 1) { /* opened before */
if (dir == port_info_ptr->direction) { /* direction is the same */
return E_OK;
} else { /* open with different direction */
return E_OPNED;
}
}
dw_gpio_write_dir(port, port->valid_bit_mask, dir);
if (port->no == DW_GPIO_PORT_A) {
dw_gpio_int_clear(port, DW_GPIO_MASK_ALL);
dw_gpio_int_disable(port, DW_GPIO_MASK_ALL);
dw_gpio_int_unmask(port, DW_GPIO_MASK_ALL);
/* install gpio interrupt handler */
int_handler_install(port->intno, port->int_handler);
int_disable(port->intno);
/** Set int type, int polarity and debounce configuration to default settings of device gpio */
dw_gpio_set_int_cfg(port, (DEV_GPIO_INT_CFG *)(&gpio_int_cfg_default));
port_info_ptr->method = dw_gpio_read_mthd(port);
} else {
port_info_ptr->method = DEV_GPIO_BITS_MTHD_DEFAULT;
}
dw_gpio_write_dr(port, port->valid_bit_mask, 0);
port_info_ptr->direction = dir;
port_info_ptr->extra = NULL;
error_exit:
return ercd;
}
/** Close designware gpio device */
int32_t dw_gpio_close(DEV_GPIO *gpio_obj)
{
int32_t ercd = E_OK;
DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info);
/* START ERROR CHECK */
VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr);
/* END OF ERROR CHECK */
DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl);
DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ);
DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_OK);
port_info_ptr->opn_cnt --;
if (port_info_ptr->opn_cnt == 0) {
dw_gpio_write_dr(port, port->valid_bit_mask, 0);
dw_gpio_write_dir(port, port->valid_bit_mask, 0);
if (port->no == DW_GPIO_PORT_A) {
dw_gpio_int_clear(port, DW_GPIO_MASK_ALL);
dw_gpio_int_disable(port, DW_GPIO_MASK_ALL);
int_disable(port->intno);
}
port_info_ptr->direction = 0;
port_info_ptr->method = 0;
port_info_ptr->extra = NULL;
} else {
ercd = E_OPNED;
}
error_exit:
return ercd;
}
/** Read designware gpio device value */
int32_t dw_gpio_read(DEV_GPIO *gpio_obj, uint32_t *val, uint32_t mask)
{
int32_t ercd = E_OK;
DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info);
/* START ERROR CHECK */
VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr);
/* END OF ERROR CHECK */
DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl);
DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ);
DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED);
DW_GPIO_CHECK_EXP(val!=NULL, E_PAR);
//*val = dw_gpio_read_ext(port) & mask;
*val = dw_gpio_read_val(port) & mask;
error_exit:
return ercd;
}
/** Write designware gpio device value */
int32_t dw_gpio_write(DEV_GPIO *gpio_obj, uint32_t val, uint32_t mask)
{
int32_t ercd = E_OK;
DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info);
/* START ERROR CHECK */
VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr);
/* END OF ERROR CHECK */
DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl);
DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ);
DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED);
dw_gpio_write_dr(port, mask, val);
error_exit:
return ercd;
}
/** Control designware gpio device */
int32_t dw_gpio_control(DEV_GPIO *gpio_obj, uint32_t ctrl_cmd, void *param)
{
int32_t ercd = E_OK;
DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info);
/* START ERROR CHECK */
VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr);
/* END OF ERROR CHECK */
DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl);
DW_GPIO_CHECK_EXP(port->no <= DW_GPIO_PORT_D, E_OBJ);
DW_GPIO_CHECK_EXP(port_info_ptr->opn_cnt > 0, E_CLSED);
uint32_t val32; /** to receive unsigned int value */
if (ctrl_cmd == GPIO_CMD_SET_BIT_DIR_INPUT) {
val32 = (uint32_t)param;
dw_gpio_write_dir(port, val32, DW_GPIO_INPUT_ALL);
port_info_ptr->direction = dw_gpio_read_dir(port);
} else if (ctrl_cmd == GPIO_CMD_SET_BIT_DIR_OUTPUT) {
val32 = (uint32_t)param;
dw_gpio_write_dir(port, val32, DW_GPIO_OUTPUT_ALL);
port_info_ptr->direction = dw_gpio_read_dir(port);
} else if (ctrl_cmd == GPIO_CMD_GET_BIT_DIR) {
DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
port_info_ptr->direction = dw_gpio_read_dir(port);
*((int32_t *)param) = port_info_ptr->direction;
} else {
DW_GPIO_CHECK_EXP(port->no == DW_GPIO_PORT_A, E_NOSPT);
/* output pin cannot be used as interrupt */
DEV_GPIO_INT_CFG *gpio_int_cfg;
DEV_GPIO_BIT_ISR *port_bit_isr;
switch (ctrl_cmd) {
case GPIO_CMD_SET_BIT_INT_CFG:
DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
gpio_int_cfg = (DEV_GPIO_INT_CFG *)param;
dw_gpio_set_int_cfg(port, gpio_int_cfg);
break;
case GPIO_CMD_GET_BIT_INT_CFG:
DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
gpio_int_cfg = (DEV_GPIO_INT_CFG *)param;
/** read configuration, each bit stands for different configuration */
dw_gpio_get_int_cfg(port, gpio_int_cfg);
break;
case GPIO_CMD_SET_BIT_ISR:
DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
port_bit_isr = (DEV_GPIO_BIT_ISR *)param;
if (port_bit_isr->int_bit_ofs < port->gpio_bit_isr->int_bit_max_cnt) {
port->gpio_bit_isr->int_bit_handler_ptr[port_bit_isr->int_bit_ofs] = port_bit_isr->int_bit_handler;
} else {
ercd = E_PAR;
}
break;
case GPIO_CMD_GET_BIT_ISR:
DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
port_bit_isr = (DEV_GPIO_BIT_ISR *)param;
if (port_bit_isr->int_bit_ofs < port->gpio_bit_isr->int_bit_max_cnt) {
port_bit_isr->int_bit_handler = port->gpio_bit_isr->int_bit_handler_ptr[port_bit_isr->int_bit_ofs];
} else {
ercd = E_PAR;
}
break;
case GPIO_CMD_ENA_BIT_INT:
val32 = (uint32_t)param;
dw_gpio_int_enable(port, val32);
port_info_ptr->method = dw_gpio_read_mthd(port);
if (port_info_ptr->method) {
int_enable(port->intno);
}
break;
case GPIO_CMD_DIS_BIT_INT:
val32 = (uint32_t)param;
dw_gpio_int_disable(port, val32);
port_info_ptr->method = dw_gpio_read_mthd(port);
if (port_info_ptr->method == 0) {
int_disable(port->intno);
}
break;
case GPIO_CMD_GET_BIT_MTHD:
DW_GPIO_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
port_info_ptr->method = dw_gpio_read_mthd(port);
*((int32_t *)param) = port_info_ptr->method;
break;
default:
ercd = E_NOSPT;
break;
}
}
error_exit:
return ercd;
}
/** designware gpio interrupt process */
int32_t dw_gpio_isr_handler(DEV_GPIO *gpio_obj, void *ptr)
{
int32_t ercd = E_OK;
DEV_GPIO_INFO_PTR port_info_ptr = &(gpio_obj->gpio_info);
/* START ERROR CHECK */
VALID_CHK_GPIO_INFO_OBJECT(port_info_ptr);
/* END OF ERROR CHECK */
DW_GPIO_PORT_PTR port = (DW_GPIO_PORT_PTR)(port_info_ptr->gpio_ctrl);
DW_GPIO_CHECK_EXP(port->no == DW_GPIO_PORT_A, E_NOSPT);
uint32_t i, gpio_bit_isr_state;
uint32_t max_int_bit_count = 0;
/** read interrupt status */
gpio_bit_isr_state = dw_gpio_int_read_status(port);
if (port->gpio_bit_isr) {
max_int_bit_count = (port->gpio_bit_isr->int_bit_max_cnt);
} else {
dw_gpio_int_clear(port, gpio_bit_isr_state);
}
for (i=0; i<max_int_bit_count; i++) {
if (gpio_bit_isr_state & (1<<i)) {
/* this bit interrupt enabled */
if (port->gpio_bit_isr->int_bit_handler_ptr[i]) {
port->gpio_bit_isr->int_bit_handler_ptr[i](gpio_obj);
}
dw_gpio_int_clear(port, (1<<i)); /** clear this bit interrupt */
}
}
error_exit:
return ercd;
}
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-22
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \brief designware gpio driver
* \ingroup DEVICE_DW_GPIO
* \brief Designware GPIO driver header file
*/
#ifndef _DW_GPIO_H_
#define _DW_GPIO_H_
#include "device/device_hal/inc/dev_gpio.h"
#include "inc/arc/arc_exception.h"
#define DW_GPIO_PORT_A (0x00)
#define DW_GPIO_PORT_B (0x01)
#define DW_GPIO_PORT_C (0x02)
#define DW_GPIO_PORT_D (0x03)
#define DW_GPIO_INT_ACT_LOW GPIO_INT_ACTIVE_LOW
#define DW_GPIO_INT_ACT_HIGH GPIO_INT_ACTIVE_HIGH
#define DW_GPIO_INT_LEVEL_TRIG GPIO_INT_LEVEL_TRIG
#define DW_GPIO_INT_EDGE_TRIG GPIO_INT_EDGE_TRIG
#define DW_GPIO_INT_NO_DEBOUNCE GPIO_INT_NO_DEBOUNCE
#define DW_GPIO_INT_DEBOUNCE GPIO_INT_DEBOUNCE
#define DW_GPIO_ALL_ZERO (0x0)
#define DW_GPIO_ALL_ONE (0xffffffff)
#define DW_GPIO_MASK_ALL (0xffffffff)
#define DW_GPIO_INPUT_ALL (0x0)
#define DW_GPIO_OUTPUT_ALL (0xffffffff)
/**
* \name DesignWare GPIO Register Structure
* \brief contains definitions of DesignWare GPIO register structure.
* @{
*/
typedef struct port_ctrl {
uint32_t DR;
uint32_t DDR;
uint32_t CTRL;
} PORT_CTRL;
/* DW GPIO PORTS Registers */
typedef volatile struct dw_gpio_reg {
PORT_CTRL SWPORTS[4];
uint32_t INTEN; /*!< (0x30) */
uint32_t INTMASK; /*!< (0x34) */
uint32_t INTTYPE_LEVEL; /*!< (0x38) */
uint32_t INT_POLARITY; /*!< (0x3c) */
uint32_t INTSTATUS; /*!< (0x40) */
uint32_t RAW_INTSTATUS; /*!< (0x44) */
uint32_t DEBOUNCE; /*!< (0x48) */
uint32_t PORTA_EOI; /*!< (0x4c) */
uint32_t EXT_PORTS[4]; /*!< (0x50) -A
(0x54) -B
(0x58) -C
(0x5c) -D */
uint32_t LS_SYNC; /*!< (0x60) */
uint32_t ID_CODE; /*!< (0x64) */
uint32_t RESERVED_3; /*!< (0x68) */
uint32_t VER_ID_CODE; /*!< (0x6c) */
uint32_t CONFIG_REG2; /*!< (0x70) */
uint32_t CONFIG_REG1; /*!< (0x74) */
} DW_GPIO_REG, *DW_GPIO_REG_PTR;
/** @} */
/** interrupt handler for each port bit */
typedef struct dw_gpio_bit_isr {
uint32_t int_bit_max_cnt; /*!< max bit count for each port */
DEV_GPIO_HANDLER *int_bit_handler_ptr; /*!< interrupt handler pointer */
} DW_GPIO_BIT_ISR, * DW_GPIO_BIT_ISR_PTR;
/**
* \brief DesignWare GPIO control structure definition
* \details implement of dev_gpio_info::gpio_ctrl
*/
typedef struct dw_gpio_port {
uint32_t no; /*!< gpio port number */
DW_GPIO_REG_PTR regs; /*!< gpio port register */
uint32_t intno; /*!< gpio interrupt vector number */
uint32_t valid_bit_mask; /*!< valid bit mask of gpio port */
INT_HANDLER int_handler; /*!< gpio interrupt handler */
DW_GPIO_BIT_ISR_PTR gpio_bit_isr; /*!< gpio bit handler struct */
} DW_GPIO_PORT, *DW_GPIO_PORT_PTR;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \name DesignWare GPIO Function Declaration
* \brief contains declarations of designware gpio functions.
* \details This are only used in gpio object implementation source file
* @{
*/
extern int32_t dw_gpio_open(DEV_GPIO *gpio_obj, uint32_t dir);
extern int32_t dw_gpio_close(DEV_GPIO *gpio_obj);
extern int32_t dw_gpio_read(DEV_GPIO *gpio_obj, uint32_t *val, uint32_t mask);
extern int32_t dw_gpio_write(DEV_GPIO *gpio_obj, uint32_t val, uint32_t mask);
extern int32_t dw_gpio_control(DEV_GPIO *gpio_obj, uint32_t ctrl_cmd, void *param);
extern int32_t dw_gpio_isr_handler(DEV_GPIO *gpio_obj, void *ptr);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* _DW_GPIO_H_ */
此差异已折叠。
/* ------------------------------------------
* Copyright (c) 2017, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2017.03
* \date 2014-06-30
* \author Huaqi Fang(Huaqi.Fang@synopsys.com)
--------------------------------------------- */
/**
* \file
* \brief designware iic driver header file
* \ingroup DEVICE_DW_IIC
*/
#ifndef _DW_IIC_H_
#define _DW_IIC_H_
#include "device/device_hal/inc/dev_iic.h"
#include "inc/arc/arc_exception.h"
/**
* If this header file is included,
* will indicate that this designware iic device
* is used
*/
#define DEVICE_USE_DESIGNWARE_IIC
/**
* \defgroup DEVICE_DW_IIC_INFO DesignWare IIC Related Information
* \ingroup DEVICE_DW_IIC
* \brief Defines some macros of DesignWare IIC need.
* \details macros like, iic number
* @{
*/
#define DW_IIC_MASTER_SUPPORTED (0x1) /*!< Support Designware IIC Master Mode */
#define DW_IIC_SLAVE_SUPPORTED (0x2) /*!< Support Designware IIC Slave Mode */
/*!< Support Designware IIC Both Master and Slave Mode */
#define DW_IIC_BOTH_SUPPORTED (DW_IIC_MASTER_SUPPORTED|DW_IIC_SLAVE_SUPPORTED)
/** @} */
/**
* \defgroup DEVICE_DW_IIC_REGSTRUCT DesignWare IIC Register Structure
* \ingroup DEVICE_DW_IIC
* \brief contains definitions of DesignWare IIC register structure.
* \details detailed description of DesignWare IIC register information
* @{
*/
/**
* \brief DesignWare IIC register structure
* \details Detailed struct description of DesignWare IIC
* block register information, implementation of dev_iic_info::iic_regs
*/
typedef volatile struct dw_iic_reg {
uint32_t IC_CON; /*!< (0x00) : IIC control */
uint32_t IC_TAR; /*!< (0x04) : IIC target address */
uint32_t IC_SAR; /*!< (0x08) : IIC slave address */
uint32_t IC_HS_MADDR; /*!< (0x0c) : IIC HS Master Mode Code address */
uint32_t IC_DATA_CMD; /*!< (0x10) : IIC Rx/Tx Data Buffer and Command */
uint32_t IC_SS_SCL_HCNT; /*!< (0x14) : Standard Speed IIC clock SCL High Count */
uint32_t IC_SS_SCL_LCNT; /*!< (0x18) : Standard Speed IIC clock SCL Low Count */
uint32_t IC_FS_SCL_HCNT; /*!< (0x1c) : Fast Speed IIC clock SCL Low Count */
uint32_t IC_FS_SCL_LCNT; /*!< (0x20) : Fast Speed IIC clock SCL Low Count */
uint32_t IC_HS_SCL_HCNT; /*!< (0x24) : High Speed IIC clock SCL Low Count */
uint32_t IC_HS_SCL_LCNT; /*!< (0x28) : High Speed IIC clock SCL Low Count */
uint32_t IC_INTR_STAT; /*!< (0x2c) : IIC Interrupt Status */
uint32_t IC_INTR_MASK; /*!< (0x30) : IIC Interrupt Mask */
uint32_t IC_RAW_INTR_STAT; /*!< (0x34) : IIC Raw Interrupt Status */
uint32_t IC_RX_TL; /*!< (0x38) : IIC Receive FIFO Threshold */
uint32_t IC_TX_TL; /*!< (0x3c) : IIC Transmit FIFO Threshold */
uint32_t IC_CLR_INTR; /*!< (0x40) : Clear combined and Individual Interrupts */
uint32_t IC_CLR_RX_UNDER; /*!< (0x44) : Clear RX_UNDER Interrupt */
uint32_t IC_CLR_RX_OVER; /*!< (0x48) : Clear RX_OVER Interrupt */
uint32_t IC_CLR_TX_OVER; /*!< (0x4c) : Clear TX_OVER Interrupt */
uint32_t IC_CLR_RD_REQ; /*!< (0x50) : Clear RQ_REQ Interrupt */
uint32_t IC_CLR_TX_ABRT; /*!< (0x54) : Clear TX_ABRT Interrupt */
uint32_t IC_CLR_RX_DONE; /*!< (0x58) : Clear RX_DONE Interrupt */
uint32_t IC_CLR_ACTIVITY; /*!< (0x5c) : Clear ACTIVITY Interrupt */
uint32_t IC_CLR_STOP_DET; /*!< (0x60) : Clear STOP_DET Interrupt */
uint32_t IC_CLR_START_DET; /*!< (0x64) : Clear START_DET Interrupt */
uint32_t IC_CLR_GEN_CALL; /*!< (0x68) : Clear GEN_CALL Interrupt */
uint32_t IC_ENABLE; /*!< (0x6c) : IIC Enable */
uint32_t IC_STATUS; /*!< (0x70) : IIC Status */
uint32_t IC_TXFLR; /*!< (0x74) : Transmit FIFO Level Register */
uint32_t IC_RXFLR; /*!< (0x78) : Receive FIFO Level Register */
uint32_t IC_SDA_HOLD; /*!< (0x7c) : SDA Hold Time Length Reg */
uint32_t IC_TX_ABRT_SOURCE; /*!< (0x80) : IIC Transmit Abort Status Reg */
uint32_t IC_SLV_DATA_NACK_ONLY; /*!< (0x84) : Generate SLV_DATA_NACK Register */
uint32_t IC_DMA_CR; /*!< (0x88) : DMA Control Register */
uint32_t IC_DMA_TDLR; /*!< (0x8c) : DMA Transmit Data Level */
uint32_t IC_DMA_RDLR; /*!< (0x90) : DMA Receive Data Level */
uint32_t IC_SDA_SETUP; /*!< (0x94) : SDA Setup Register */
uint32_t IC_ACK_GENERAL_CALL; /*!< (0x98) : ACK General Call Register */
uint32_t IC_ENABLE_STATUS; /*!< (0x9c) : Enable Status Register */
uint32_t IC_FS_SPKLEN; /*!< (0xa0) : ISS and FS spike suppression limit */
uint32_t IC_HS_SPKLEN; /*!< (0xa4) : HS spike suppression limit */
uint32_t RESERVED[19]; /*!< (0xa8) : Reserved */
uint32_t IC_COMP_PARAM_1; /*!< (0xf4) : Component Parameter Register */
uint32_t IC_COMP_VERSION; /*!< (0xf8) : Component Version ID Reg */
uint32_t IC_COMP_TYPE; /*!< (0xfc) : Component Type Reg */
} DW_IIC_REG, *DW_IIC_REG_PTR;
/** @} */
/** Spike Suppression Limit Configurations */
typedef struct dw_iic_spklen {
uint32_t fs_spklen; /*!< value for IC_FS_SPKLEN, Tsp for fast mode is 50ns */
uint32_t hs_spklen; /*!< value for IC_HS_SPKLEN, Tsp for high-speed mode is 10ns */
} DW_IIC_SPKLEN, *DW_IIC_SPKLEN_PTR;
/** IIC Clock SCL High and Low Count Configurations for Different Speed */
typedef struct dw_iic_scl_cnt {
uint32_t ss_scl_hcnt; /*!< value for IC_SS_SCL_HCNT */
uint32_t ss_scl_lcnt; /*!< value for IC_SS_SCL_LCNT */
uint32_t fs_scl_hcnt; /*!< value for IC_FS_SCL_HCNT */
uint32_t fs_scl_lcnt; /*!< value for IC_FS_SCL_LCNT */
uint32_t hs_scl_hcnt; /*!< value for IC_HS_SCL_HCNT */
uint32_t hs_scl_lcnt; /*!< value for IC_HS_SCL_LCNT */
} DW_IIC_SCL_CNT, *DW_IIC_SCL_CNT_PTR;
#define DW_IIC_GINT_DISABLED (0) /*!< designware interrupt disabled for control iic irq/fiq */
#define DW_IIC_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control iic irq/fiq */
#define DW_IIC_TXINT_ENABLE (1<<1) /*!< designware interrupt enabled for control transmit process */
#define DW_IIC_RXINT_ENABLE (1<<2) /*!< designware interrupt enabled for control transmit process */
typedef struct dw_iic_buffer {
DEV_BUFFER *buf;
uint32_t ofs;
uint32_t len;
} DW_IIC_BUFFER, *DW_IIC_BUFFER_PTR;
/**
* \brief DesignWare IIC control structure definition
* \details implement of dev_iic_info::iic_ctrl
*/
typedef struct dw_iic_ctrl {
DW_IIC_REG *dw_iic_regs; /*!< iic device registers */
/* Variables which should be set during object implementation */
uint32_t support_modes; /*!< supported iic modes */
uint32_t tx_fifo_len; /*!< transmit fifo length */
uint32_t rx_fifo_len; /*!< receive fifo length */
uint32_t iic_master_code; /*!< value for IC_HS_MADDR */
uint32_t retry_cnt; /*!< retry count for TX or RX */
uint32_t intno; /*!< iic interrupt vector number */
INT_HANDLER dw_iic_int_handler; /*!< iic interrupt handler */
DW_IIC_SPKLEN iic_spklen; /*!< iic spike suppression length settings */
DW_IIC_SCL_CNT iic_scl_cnt; /*!< iic scl count settings */
/* Variables which always change during iic operation */
uint32_t int_status; /*!< iic interrupt status */
uint32_t iic_tx_over; /*!< iic tx overflow count */
uint32_t iic_rx_over; /*!< iic rx overflow count */
DW_IIC_BUFFER dw_iic_rxbuf; /*!< iic read buffer for receive data */
} DW_IIC_CTRL, *DW_IIC_CTRL_PTR;
/*!< One possible value for \ref dw_iic_ctrl::retry_cnt */
#define DW_IIC_MAX_RETRY_COUNT (100000)
#if DW_IIC_USE_IC_CLK_MHZ == 100 /*!< 100MHz */
/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */
static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1};
/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */
#if DW_IIC_USE_HS_BUS_LOADING_100PF
static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0x6, 0x10};
#else
static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0xc, 0x20};
#endif
#elif DW_IIC_USE_IC_CLK_MHZ == 50 /* 50MHz */
/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */
static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1};
/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */
#if DW_IIC_USE_HS_BUS_LOADING_100PF
static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x00c8, 0x00eb, 0x001e, 0x0041, 0x6, 0x8};
#else
static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x00c8, 0x00eb, 0x001e, 0x0041, 0x6, 0x10};
#endif
#else /* Default 100MHz */
/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */
static const DW_IIC_SPKLEN dw_iic_spklen_const = {5, 1};
/*!< One possible value for \ref dw_iic_ctrl::iic_spklen */
#if DW_IIC_USE_HS_BUS_LOADING_100PF
static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0x6, 0x10};
#else
static const DW_IIC_SCL_CNT dw_iic_sclcnt_const = {0x0190, 0x01d6, 0x003c, 0x0082, 0xc, 0x20};
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup DEVICE_DW_IIC_FUNCDLR DesignWare IIC Function Declaration
* \ingroup DEVICE_DW_IIC
* \brief Contains declarations of designware iic functions.
* \details This are only used in iic object implementation source file
* @{
*/
extern int32_t dw_iic_open (DEV_IIC *iic_obj, uint32_t mode, uint32_t param);
extern int32_t dw_iic_close (DEV_IIC *iic_obj);
extern int32_t dw_iic_control (DEV_IIC *iic_obj, uint32_t ctrl_cmd, void *param);
extern int32_t dw_iic_write (DEV_IIC *iic_obj, const void *data, uint32_t len);
extern int32_t dw_iic_read (DEV_IIC *iic_obj, void *data, uint32_t len);
extern void dw_iic_isr(DEV_IIC *iic_obj, void *ptr);
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* _DW_IIC_H_ */
/* ------------------------------------------
* Copyright (c) 2017, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2017.03
* \date 2014-06-30
* \author Huaqi Fang(Huaqi.Fang@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup DEVICE_DW_IIC
* \brief DesignWare IIC driver hardware description related header file
* \details detailed hardware related definitions of DesignWare IIC driver
*/
#ifndef _DEVICE_DW_IIC_HAL_H_
#define _DEVICE_DW_IIC_HAL_H_
#include "device/designware/iic/dw_iic_hal_cfg.h"
/** Enable Designware IIC */
#define DW_IIC_ENABLE (1)
/** Disable Designware IIC */
#define DW_IIC_DISABLE (0)
/** Stop Condition issue after this byte */
#define IC_DATA_CMD_STOP (1 << 9)
/** Restart Condition issue after this byte */
#define IC_DATA_CMD_RESTART (1 << 10)
/** No Restart or stop condition after this byte */
#define IC_DATA_CMD_NONE (0)
/** Perform a write request */
#define IC_DATA_CMD_WRITE_REQ (0)
/** Perform a read request */
#define IC_DATA_CMD_READ_REQ (1 << 8)
/** Fields of IC_CON register */
/* DW_APB I2C IP Config Dependencies. */
#if DW_IIC_ALLOW_RESTART
#define IC_CON_RESTART_EN (1 << 5)
#else
#define IC_CON_RESTART_EN (0x00)
#endif
/* Master Addressing Mode Config */
#if DW_IIC_MST_10_BIT_ADDR_SUPPORT
#define MST_10_BIT_ADDR_MODE (1 << 4)
#define IC_10BITADDR_MASTER (1 << 12)
#else
#define MST_10_BIT_ADDR_MODE (0x00)
#define IC_10BITADDR_MASTER (0x00)
#endif
/* Slave Addressing Mode Config */
#if DW_IIC_SLV_10_BIT_ADDR_SUPPORT
#define SLV_10_BIT_ADDR_MODE (1 << 3)
#else
#define SLV_10_BIT_ADDR_MODE (0x00)
#endif
#if DW_IIC_SPECIAL_START_BYTE
#define IC_TAR_SPECIAL (1 << 11)
#define IC_TAR_GC_OR_START (1 << 10)
#else
#define IC_TAR_SPECIAL (0x00)
#define IC_TAR_GC_OR_START (0x00)
#endif
/** 7bit IIC address mask for target address register */
#define IC_TAR_7BIT_ADDR_MASK (0x7F)
/** 7bit IIC address mask for slave address register */
#define IC_SAR_7BIT_ADDR_MASK (0x7F)
/** 10bit IIC address mask for target address register */
#define IC_TAR_10BIT_ADDR_MASK (0x3FF)
/** 10bit IIC address mask for slave address register */
#define IC_SAR_10BIT_ADDR_MASK (0x3FF)
/** Speed modes of IC_CON */
#define IC_CON_SPEED_MASK (0x6)
#define IC_CON_SPEED_STANDARD (0x2)
#define IC_CON_SPEED_FAST (0x4)
#define IC_CON_SPEED_HIGH (0x6)
/** Working mode of IC_CON */
#define IC_CON_MST_SLV_MODE_MASK (0x41)
#define IC_CON_ENA_MASTER_MODE (0x41)
#define IC_CON_ENA_SLAVE_MODE (0)
/* IIC interrupt control */
#define IC_INT_DISABLE_ALL (0x0)
#define IC_INT_ENABLE_ALL (0x7FF)
/* Interrupt Register Fields */
#define IC_INTR_STAT_GEN_CALL (1 << 11)
#define IC_INTR_STAT_START_DET (1 << 10)
#define IC_INTR_STAT_STOP_DET (1 << 9)
#define IC_INTR_STAT_ACTIVITY (1 << 8)
#define IC_INTR_STAT_RX_DONE (1 << 7)
#define IC_INTR_STAT_TX_ABRT (1 << 6)
#define IC_INTR_STAT_RD_REQ (1 << 5)
#define IC_INTR_STAT_TX_EMPTY (1 << 4)
#define IC_INTR_STAT_TX_OVER (1 << 3)
#define IC_INTR_STAT_RX_FULL (1 << 2)
#define IC_INTR_STAT_RX_OVER (1 << 1)
#define IC_INTR_STAT_RX_UNDER (1 << 0)
/* Interrupt enable mask as master */
#define IC_INT_MST_TX_ENABLE (IC_INTR_STAT_TX_EMPTY|IC_INTR_STAT_TX_OVER|IC_INTR_STAT_TX_ABRT)
#define IC_INT_MST_RX_ENABLE (IC_INTR_STAT_TX_EMPTY|IC_INTR_STAT_RX_FULL|IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER|IC_INTR_STAT_TX_ABRT)
/* Interrupt enable mask as master */
#define IC_INT_SLV_COMMON_ENABLE (IC_INTR_STAT_START_DET|IC_INTR_STAT_STOP_DET)
#define IC_INT_SLV_TX_ENABLE (IC_INTR_STAT_RD_REQ|IC_INTR_STAT_TX_ABRT)
#define IC_INT_SLV_RX_ENABLE (IC_INTR_STAT_RX_FULL|IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)
/* IC_ENABLE_STATUS Bits */
#define IC_ENABLE_STATUS_IC_EN (1 << 0)
#define IC_ENABLE_STATUS_SLV_DIS (1 << 1)
#define IC_ENABLE_STATUS_SLV_RX_LOST (1 << 2)
/* IIC TX & RX threshold settings */
#define IIC_TX_THRESHOLD (0)
#define IIC_RX_THRESHOLD (0)
/* DW_APB IIC (DW_IC_STATUS) Status Register Fields. */
#define IC_STATUS_ACTIVITY (0x01)
#define IC_STATUS_TFNF (0x02) /* (1 << 1) */
#define IC_STATUS_TFE (0x04) /* (1 << 2) */
#define IC_STATUS_RFNE (0x08) /* (1 << 3) */
#define IC_STATUS_RFF (0x10) /* (1 << 4) */
#define IC_STATUS_MASTER_ACT (0x20) /* (1 << 5) */
#define IC_STATUS_SLAVE_ACT (0x40) /* (1 << 6) */
/* IC_TX_ABRT_SOURCE Register Bit Fields */
#define IC_TX_ABRT_7B_ADDR_NOACK (1 << 0)
#define IC_TX_ABRT_10ADDR1_NOACK (1 << 1)
#define IC_TX_ABRT_10ADDR2_NOACK (1 << 2)
#define IC_TX_ABRT_TXDATA_NOACK (1 << 3)
#define IC_TX_ABRT_GCALL_NOACK (1 << 4)
#define IC_TX_ABRT_GCALL_READ (1 << 5)
#define IC_TX_ABRT_HS_ACKDET (1 << 6)
#define IC_TX_ABRT_SBYTE_ACKDET (1 << 7)
#define IC_TX_ABRT_HS_NORSTRT (1 << 8)
#define IC_TX_ABRT_SBYTE_NORSTRT (1 << 9)
#define IC_TX_ABRT_10B_RD_NORSTRT (1 << 10)
#define IC_TX_ABRT_MASTER_DIS (1 << 11)
#define IC_TX_ABRT_ARB_LOST (1 << 12)
#define IC_TX_ABRT_SLVFLUSH_TXFIFO (1 << 13)
#define IC_TX_ABRT_SLV_ARBLOST (1 << 14)
#define IC_TX_ABRT_SLVRD_INTX (1 << 15)
/* Combined bits for iic abort source as master */
#define IIC_MST_ABRT_ADDR_NOACK (IC_TX_ABRT_7B_ADDR_NOACK|IC_TX_ABRT_10ADDR1_NOACK|IC_TX_ABRT_10ADDR1_NOACK)
#define IIC_MST_ABRT_LOST_BUS (IC_TX_ABRT_ARB_LOST)
#define IIC_MST_ABRT_DATA_NOACK (IC_TX_ABRT_TXDATA_NOACK)
/* Combined bits for iic abort source as slave */
#define IIC_SLV_ABRT_LOST_BUS (IC_TX_ABRT_ARB_LOST|IC_TX_ABRT_SLV_ARBLOST)
/** @} */
#endif /* _DEVICE_DW_IIC_HAL_H_ */
/* ------------------------------------------
* Copyright (c) 2017, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2017.03
* \date 2014-07-01
* \author Huaqi Fang(Huaqi.Fang@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup DEVICE_DW_IIC
* \brief DesignWare IIC driver hardware description
* related header file configuration file
* \details configuration file to enable or disable some function of iic
*/
#ifndef _DEVICE_DW_IIC_HAL_CFG_H_
#define _DEVICE_DW_IIC_HAL_CFG_H_
#ifndef DW_IIC_ALLOW_RESTART
#define DW_IIC_ALLOW_RESTART (1) /*!< allow restart configuration */
#endif
#ifdef DW_IIC_SPECIAL_START_BYTE
#define DW_IIC_SPECIAL_START_BYTE (0) /*!< SPECIAL bit enable in IC_TAR */
#endif
#ifndef DW_IIC_MST_10_BIT_ADDR_SUPPORT
#define DW_IIC_MST_10_BIT_ADDR_SUPPORT (1) /*!< enable 10-bit address mode */
#endif
#ifdef DW_IIC_SLV_10_BIT_ADDR_SUPPORT
#define DW_IIC_SLV_10_BIT_ADDR_SUPPORT (1) /*!< slave 10-bit addressing mode */
#endif
#ifndef DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT
#define DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT (0) /*!< Dynamic target address update support */
#endif
#ifndef DW_IIC_DISABLE_MAX_T_POLL_CNT
#define DW_IIC_DISABLE_MAX_T_POLL_CNT (1250) /*!< Timeout count, approximate to be 25us in 50MHz CPU @ Standard mode */
#endif
#ifndef DW_IIC_CALC_FIFO_LEN_ENABLE
#define DW_IIC_CALC_FIFO_LEN_ENABLE (1) /*!< Default enable calculate fifo length */
#endif
#ifndef DW_IIC_USE_IC_CLK_MHZ
#define DW_IIC_USE_IC_CLK_MHZ (50) /*!< Default use 50MHz IC_CLK */
#endif
#ifndef DW_IIC_USE_HS_BUS_LOADING_100PF
#define DW_IIC_USE_HS_BUS_LOADING_100PF (1) /*!< Use bus loading 100pf */
#endif
#endif /* _DEVICE_DW_IIC_HAL_CFG_H_ */
此差异已折叠。
/* ------------------------------------------
* Copyright (c) 2017, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2017.03
* \date 2014-06-25
* \author Huaqi Fang(Huaqi.Fang@synopsys.com)
--------------------------------------------- */
/**
* \file
* \brief DesignWare SPI driver header file
* \ingroup DEVICE_DW_SPI
*/
#ifndef _DEVICE_DW_SPI_H_
#define _DEVICE_DW_SPI_H_
#include "device/device_hal/inc/dev_spi.h"
/**
* if this header file is included,
* will indicate that this designware spi device
* is used
*/
#define DEVICE_USE_DESIGNWARE_SPI
#define DW_SPI_IN_FREE (0) /*!< Currently not in spi transfer */
#define DW_SPI_IN_XFER (DEV_IN_TX|DEV_IN_RX|DEV_IN_XFER) /*!< Currently in spi transfer */
#define DW_SPI_IN_TX (DEV_IN_TX|DEV_IN_XFER) /*!< Currently in spi tx */
#define DW_SPI_IN_RX (DEV_IN_RX|DEV_IN_XFER) /*!< Currently in spi rx */
#define DW_SPI_GINT_DISABLED (0) /*!< designware interrupt disabled for control iic irq/fiq */
#define DW_SPI_GINT_ENABLE (1<<0) /*!< designware interrupt enabled for control iic irq/fiq */
#define DW_SPI_MASTER_SUPPORTED (0x1) /*!< Support Designware SPI Master Mode */
#define DW_SPI_SLAVE_SUPPORTED (0x2) /*!< Support Designware SPI Slave Mode */
/*!< Support Designware SPI Both Master and Slave Mode */
#define DW_SPI_BOTH_SUPPORTED (DW_SPI_MASTER_SUPPORTED|DW_SPI_SLAVE_SUPPORTED)
/**
* \defgroup DEVICE_DW_SPI_REGSTRUCT DesignWare SPI Register Structure
* \ingroup DEVICE_DW_SPI
* \brief contains definitions of DesignWare SPI register structure.
* \details detailed description of DesignWare SPI register information
* @{
*/
/**
* \brief DesignWare SPI register structure
* \details Detailed struct description of DesignWare SPI
* block register information, implementation of dev_spi_info::spi_regs
*/
typedef volatile struct dw_spi_reg
{
/*!< Control Register */
/*!< SPI Control Register 0 (0x0) */
uint32_t CTRLR0;
/*!< SPI Control Register 1 (0x4) */
uint32_t CTRLR1;
/*!< Enable Register */
/*!< SPI Enable Register (0x8) */
uint32_t SSIENR;
/*!< SPI Microwire Control Register (0xC) */
uint32_t MWCR;
/*!< SPI Slave Enable Register (0x10) */
uint32_t SER;
/*!< SPI Baud Rate Select Register (0x14) */
uint32_t BAUDR;
/*!< TX and RX FIFO Control Register */
/*!< SPI Transmit FIFO Threshold Level Register (0x18) */
uint32_t TXFTLR;
/*!< SPI Receive FIFO Threshold Level Register (0x1C) */
uint32_t RXFTLR;
/*!< SPI Transmit FIFO Level Register (0x20) */
uint32_t TXFLR;
/*!< SPI Receive FIFO Level Register (0x24) */
uint32_t RXFLR;
/*!< SPI Status Register (0x28) */
uint32_t SR;
/*!< Interrupt Enable/Disable/Control Registers */
/*!< SPI Interrupt Mask Register (0x2C) */
uint32_t IMR;
/*!< SPI Interrupt Status Register (0x30) */
uint32_t ISR;
/*!< SPI Raw Interrupt Status Register (0x34) */
uint32_t RISR;
/*!< SPI Transmit FIFO Overflow Interrupt Clear Register (0x38) */
uint32_t TXOICR;
/*!< SPI Receive FIFO Overflow Interrupt Clear Register (0x3C) */
uint32_t RXOICR;
/*!< SPI Receive FIFO Underflow Interrupt Clear Register (0x40) */
uint32_t RXUICR;
/*!< SPI Multi-Master Interrupt Clear Register (0x44) */
uint32_t MSTICR;
/*!< SPI Interrupt Clear Register (0x48) */
uint32_t ICR;
/*!< DMA Control Register (0x4C) */
uint32_t DMACR;
/*!< DMA Transmit Data Level (0x50) */
uint32_t DMATDLR;
/*!< DMA Receive Data Level (0x54) */
uint32_t DMARDLR;
/*!< SPI Identification Register (0x58) */
uint32_t IDR;
/*!< SPI CoreKit ID Register (Value after Reset : 0x3332322A) (0x5C) */
uint32_t SSI_VER_ID;
/*!< Data Register */
/*!< SPI DATA Register for both Read and Write (0x60) */
uint32_t DATAREG;
} DW_SPI_REG, *DW_SPI_REG_PTR;
/** @} */
/** Designware SPI Message Transfer */
typedef struct dw_spi_transfer {
uint32_t xfer_len;
uint32_t tx_idx;
uint32_t rx_idx;
uint32_t nbytes;
DEV_SPI_TRANSFER *tx_xfer;
DEV_SPI_TRANSFER *rx_xfer;
} DW_SPI_TRANSFER, *DW_SPI_TRANSFER_PTR;
/**
* \brief DesignWare SPI control structure definition
* \details implement of dev_spi_info::dev_spi_info
*/
typedef struct dw_spi_ctrl {
DW_SPI_REG *dw_spi_regs; /*!< spi register */
/* Variables which should be set during object implementation */
uint32_t support_modes; /*!< supported spi modes */
uint32_t intno; /*!< interrupt no */
uint32_t dw_apb_bus_freq; /*!< spi ip apb bus frequency */
uint32_t tx_fifo_len; /*!< transmit fifo length */
uint32_t rx_fifo_len; /*!< receive fifo length */
INT_HANDLER dw_spi_int_handler; /*!< spi interrupt handler */
/* Variables which always change during iic operation */
uint32_t int_status; /*!< iic interrupt status */
DW_SPI_TRANSFER dw_xfer; /*!< designware spi transfer */
} DW_SPI_CTRL, *DW_SPI_CTRL_PTR;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup DEVICE_DW_SPI_FUNCDLR DesignWare SPI Function Declaration
* \ingroup DEVICE_DW_SPI
* \brief contains declarations of designware spi functions.
* \details This are only used in \ref dw_spi_obj.c
* @{
*/
extern int32_t dw_spi_open (DEV_SPI *spi_obj, uint32_t mode, uint32_t param);
extern int32_t dw_spi_close (DEV_SPI *spi_obj);
extern int32_t dw_spi_control (DEV_SPI *spi_obj, uint32_t ctrl_cmd, void *param);
extern int32_t dw_spi_write (DEV_SPI *spi_obj, const void *data, uint32_t len);
extern int32_t dw_spi_read (DEV_SPI *spi_obj, void *data, uint32_t len);
extern void dw_spi_isr(DEV_SPI *spi_obj, void *ptr);
/** @} */
#ifdef __cplusplus
}
#endif
/** @} */
#endif /* _DEVICE_DW_SPI_H_ */
/* ------------------------------------------
* Copyright (c) 2017, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2017.03
* \date 2014-06-25
* \author Huaqi Fang(Huaqi.Fang@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup DEVICE_DW_SPI
* \brief DesignWare SPI driver hardware description related header file
* \details detailed hardware related definitions of DesignWare SPI driver
*/
#ifndef _DEVICE_DW_SPI_HAL_H_
#define _DEVICE_DW_SPI_HAL_H_
#include "device/designware/spi/dw_spi_hal_cfg.h"
/* DW APB SPI bit definitions */
/**
* \name DesignWare SPI HAL CTRL0 Macros
* \brief DesignWare SPI hal ctrl0 macros,
* include dfs, scph, scppl, tmod, etc
* @{
*/
#define DW_SPI_CTRLR0_DFS_MASK (0xf)
#define DW_SPI_CTRLR0_SC_OFS (6)
#define DW_SPI_CTRLR0_SC_MASK (0xC0)
#define DW_SPI_CTRLR0_SCPH_HIGH (0x40)
#define DW_SPI_CTRLR0_SCPH_LOW (0)
#define DW_SPI_CTRLR0_SCPOL_HIGH (0x80)
#define DW_SPI_CTRLR0_SCPOL_LOW (0)
#define DW_SPI_CTRLR0_TMOD_MASK (0x300)
#define DW_SPI_TMOD_TRANSMIT_RECEIVE (0)
#define DW_SPI_TMOD_TRANSMIT_ONLY (0x100)
#define DW_SPI_TMOD_RECEIVE_ONLY (0x200)
#define DW_SPI_TMOD_EEPROM_READ_ONLY (0x300)
#define DW_SPI_CTRLR0_FRF_MOTOROLA (0x0)
#define DW_SPI_CTRLR0_FRF_TI (0x10)
#define DW_SPI_CTRLR0_FRF_MICROWIRE (0x20)
#define DW_SPI_CTRLR0_SLV_OE_DISABLE (1<<10)
#define DW_SPI_CTRLR0_SLV_OE_ENABLE (0)
/** @} */
/**
* \name DesignWare SPI HAL ISR Flags
* \brief DesignWare SPI hal Interrupt Status Flags
* @{
*/
#define DW_SPI_TX_OVERFLOW_ERROR (0x2)
#define DW_SPI_RX_UNDERFLOW_ERROR (0x4)
#define DW_SPI_RX_OVERFLOW_ERROR (0x8)
#define DW_SPI_ISR_RX_FIFO_INT_MASK (0x10)
#define DW_SPI_ISR_TX_FIFO_INT_MASK (0x1)
#define DW_SPI_ISR_TX_OVERFLOW_INT_MASK (0x2)
#define DW_SPI_ISR_RX_UNDERFLOW_INT_MASK (0x4)
#define DW_SPI_ISR_RX_OVERFLOW_INT_MASK (0x8)
/** @} */
/**
* \name DesignWare SPI HAL SR Flags
* \brief DesignWare SPI hal Status Flags
* @{
*/
#define DW_SPI_SR_DCOL (0x40)
#define DW_SPI_SR_TXE (0x20)
#define DW_SPI_SR_RFF (0x10)
#define DW_SPI_SR_RFNE (0x8)
#define DW_SPI_SR_TFE (0x4)
#define DW_SPI_SR_TFNF (0x2)
#define DW_SPI_SR_BUSY (0x1)
/** @} */
/**
* \name DesignWare SPI HAL SSI Enable Macros
* \brief DesignWare SPI hal ssi enable macros
* @{
*/
/* Macros */
#define DW_SPI_SSI_ENABLE (1) /*!< SSI Enable */
#define DW_SPI_SSI_DISABLE (0) /*!< SSI Disable */
/** @} */
/**
* \name DesignWare SPI HAL IMR Macros
* \brief DesignWare SPI hal interrupt mask macros
* @{
*/
#define DW_SPI_IMR_MSTIM (0x20) /*!< Multi-Master Contention Interrupt Mask */
#define DW_SPI_IMR_RXFIM (0x10) /*!< Receive FIFO Full Interrupt Mask */
#define DW_SPI_IMR_RXOIM (0x08) /*!< Receive FIFO Overflow Interrupt Mask */
#define DW_SPI_IMR_RXUIM (0x04) /*!< Receive FIFO Underflow Interrupt Mask */
#define DW_SPI_IMR_TXOIM (0x02) /*!< Transmit FIFO Overflow Interrupt Mask */
#define DW_SPI_IMR_TXEIM (0x01) /*!< Transmit FIFO Empty Interrupt Mask */
#define DW_SPI_IMR_XFER (DW_SPI_IMR_TXEIM|DW_SPI_IMR_RXFIM|DW_SPI_IMR_TXOIM|DW_SPI_IMR_RXOIM|DW_SPI_IMR_RXUIM)
/** @} */
#define DW_SPI_SSI_IDLE (1)
#define DW_SPI_SPI_TRANSMIT (1)
#define DW_SPI_SPI_RECEIVE (2)
#define DW_SPI_SSI_MASTER (1)
#define DW_SPI_SSI_SLAVE (0)
#endif /* _DEVICE_DW_SPI_HAL_H_ */
/* ------------------------------------------
* Copyright (c) 2017, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2017.03
* \date 2015-09-09
* \author Huaqi Fang(Huaqi.Fang@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup DEVICE_DW_SPI
* \brief DesignWare SPI driver hardware description
* related header file configuration file
* \details configuration file to enable or disable some function of spi
*/
#ifndef _DEVICE_DW_SPI_HAL_CFG_H_
#define _DEVICE_DW_SPI_HAL_CFG_H_
#ifndef DW_SPI_CALC_FIFO_LEN_ENABLE
#define DW_SPI_CALC_FIFO_LEN_ENABLE (1) /*!< Defaultly enable calculate fifo length */
#endif
#ifndef DW_SPI_MAX_FIFO_LENGTH
#define DW_SPI_MAX_FIFO_LENGTH (256) /*!< Max FIFO depth for designware SPI device */
#endif
#ifndef DW_SPI_MIN_FIFO_LENGTH
#define DW_SPI_MIN_FIFO_LENGTH (2) /*!< Min FIFO depth for designware SPI device */
#endif
#endif /* _DEVICE_DW_SPI_HAL_CFG_H_ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/* ------------------------------------------
* Copyright (c) 2016, Synopsys, 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:
* 1) Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2) Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* 3) Neither the name of the Synopsys, 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.
*
* \version 2016.05
* \date 2014-07-15
* \author Wayne Ren(Wei.Ren@synopsys.com)
--------------------------------------------- */
/**
* \file
* \ingroup ARC_HAL_MISC_TIMER
* \brief header file of ARC internal timer
*/
/**
* \addtogroup ARC_HAL_MISC_TIMER
* @{
*/
#ifndef _ARC_HAL_TIMER_H_
#define _ARC_HAL_TIMER_H_
#include "inc/arc/arc.h"
#include "inc/embARC_toolchain.h"
/**
* \name arc internal timers names
* @{
*/
#define TIMER_0 0 /*!< macro name for arc internal timer 0 */
#define TIMER_1 1 /*!< macro name for arc internal timer 1 */
#define TIMER_RTC 2 /*!< macro name for arc internal RTC */
/** @} */
/**
* \name bit definition of RTC CTRL reg
* @{
*/
#define TIMER_RTC_ENABLE 0x01 /*!< enable RTC */
#define TIMER_RTC_CLEAR 0x02 /* clears the AUX_RTC_LOW and AUX_RTC_HIGH */
#define TIMER_RTC_STATUS_A0 0x40000000 /*!< track bit of atomicity of reads of RTC */
#define TIMER_RTC_STATUS_A1 0x80000000 /*!< track bit of atomicity of reads of RTC */
/** @} */
/**
* \name bit definition of timer CTRL reg
* @{
*/
#define TIMER_CTRL_IE (1 << 0) /*!< Interrupt when count reaches limit */
#define TIMER_CTRL_NH (1 << 1) /*!< Count only when CPU NOT halted */
#define TIMER_CTRL_W (1 << 2) /*!< watchdog enable */
#define TIMER_CTRL_IP (1 << 3) /*!< interrupt pending */
/** @} */
#ifdef __cplusplus
extern "C" {
#endif
extern int32_t arc_timer_present(const uint32_t no);
extern int32_t arc_timer_start(const uint32_t no, const uint32_t mode, const uint32_t val);
extern int32_t arc_timer_stop(const uint32_t no);
extern int32_t arc_timer_current(const uint32_t no, void* val);
extern int32_t arc_timer_int_clear(const uint32_t no);
extern void arc_timer_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _ARC_HAL_TIMER_H_ */
/** }@*/
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册