📄 var_misc.c
字号:
MASK_TBL_ENTRY(0, 0), // 063 RSV
//---------------------------------------------------------------------------------
// TPU 4
//
MASK_TBL_ENTRY(CYGARC_TIER4, BIT(0)), // 064 TGI4A
MASK_TBL_ENTRY(CYGARC_TIER4, BIT(1)), // 065 TGI4B
MASK_TBL_ENTRY(CYGARC_TIER4, BIT(4)), // 066 TCI4V
MASK_TBL_ENTRY(CYGARC_TIER4, BIT(5)), // 067 TCI4U
//---------------------------------------------------------------------------------
// TPU 5
//
MASK_TBL_ENTRY(CYGARC_TIER5, BIT(0)), // 068 TGI5A
MASK_TBL_ENTRY(CYGARC_TIER5, BIT(1)), // 069 TGI5B
MASK_TBL_ENTRY(CYGARC_TIER5, BIT(4)), // 070 TCI5V
MASK_TBL_ENTRY(CYGARC_TIER5, BIT(5)), // 071 TCI5U
//---------------------------------------------------------------------------------
// TMR 0
//
MASK_TBL_ENTRY(CYGARC_8TCR0, BIT(6)), // 072 CMIA0
MASK_TBL_ENTRY(CYGARC_8TCR0, BIT(7)), // 073 CMIB0
MASK_TBL_ENTRY(CYGARC_8TCR0, BIT(5)), // 074 OVI0
MASK_TBL_ENTRY(0, 0), // 075 RSV
//---------------------------------------------------------------------------------
// TMR 1
//
MASK_TBL_ENTRY(CYGARC_8TCR1, BIT(6)), // 076 CMIA1
MASK_TBL_ENTRY(CYGARC_8TCR1, BIT(7)), // 077 CMIB1
MASK_TBL_ENTRY(CYGARC_8TCR1, BIT(5)), // 078 OVI1
MASK_TBL_ENTRY(0, 0), // 079 RSV
//---------------------------------------------------------------------------------
// DMAC
//
MASK_TBL_ENTRY(CYGARC_DMABCRL, BIT(0)), // 080 DMTEND0A
MASK_TBL_ENTRY(CYGARC_DMABCRL, BIT(1)), // 081 DMTEND0B
MASK_TBL_ENTRY(CYGARC_DMABCRL, BIT(2)), // 082 DMTEND1A
MASK_TBL_ENTRY(CYGARC_DMABCRL, BIT(3)), // 083 DMTEND1B
//---------------------------------------------------------------------------------
// EXDMAC
//
MASK_TBL_ENTRY(CYGARC_EDMDR0L, BIT(7)), // 084 EXDMTEND0A
MASK_TBL_ENTRY(CYGARC_EDMDR1L, BIT(7)), // 085 EXDMTEND0B
MASK_TBL_ENTRY(CYGARC_EDMDR2L, BIT(7)), // 086 EXDMTEND1A
MASK_TBL_ENTRY(CYGARC_EDMDR3L, BIT(7)), // 087 EXDMTEND1B
//---------------------------------------------------------------------------------
// SCI 0
//
MASK_TBL_ENTRY(CYGARC_SCR0, BIT(6)), // 088 ERI0
MASK_TBL_ENTRY(CYGARC_SCR0, BIT(6)), // 089 RXI0
MASK_TBL_ENTRY(CYGARC_SCR0, BIT(7)), // 090 TXI0
MASK_TBL_ENTRY(CYGARC_SCR0, BIT(2)), // 091 TEI0
//---------------------------------------------------------------------------------
// SCI 1
//
MASK_TBL_ENTRY(CYGARC_SCR1, BIT(6)), // 092 ERI1
MASK_TBL_ENTRY(CYGARC_SCR1, BIT(6)), // 093 RXI1
MASK_TBL_ENTRY(CYGARC_SCR1, BIT(7)), // 094 TXI1
MASK_TBL_ENTRY(CYGARC_SCR1, BIT(2)), // 095 TEI1
//---------------------------------------------------------------------------------
// SCI 2
//
MASK_TBL_ENTRY(CYGARC_SCR2, BIT(6)), // 096 ERI2
MASK_TBL_ENTRY(CYGARC_SCR2, BIT(6)), // 097 RXI2
MASK_TBL_ENTRY(CYGARC_SCR2, BIT(7)), // 098 TXI2
MASK_TBL_ENTRY(CYGARC_SCR2, BIT(2)) // 099 TEI2
};
//==========================================================================
// SET INTERRUPT PRIORITY
///
/// Provides control over the hardware priority of the interrupt.
///
/// \param vector The interrupt whose level is to be set.
/// \param level The priority level to be set for the selectd interrupt.
//==========================================================================
void hal_interrupt_set_level(int vector, int level)
{
cyg_uint32 prio_reg;
cyg_uint16 prio_data;
cyg_uint16 mask;
int_prio_conf_t *pint_regs; // points to interrupt config structure
static const cyg_uint16 prio_grp_mask_tbl[4] =
{
0x0007, 0x0070, 0x0700, 0x7000
};
//
// We do not check vector ranges with assertions here because
// this is already done in cyg_interrupt_mask and the user should
// not call this funcion directly. But we check priority because
// cyg_interrupt_set_level does not know about H8S priority ranges
//
CYG_ASSERT(CYGNUM_HAL_INT_PRIO_LOWEST <= level
&& CYGNUM_HAL_INT_PRIO_HIGHEST >= level, "invalid interrupt priority level" );
pint_regs = (int_prio_conf_t *)&hal_int_prio_conf_tbl[vector]; // get pointer to configuration data
//
// check if a reserved vector is used
//
CYG_ASSERT(pint_regs->prio_bit_group != PRIO_RESERVED, "Reserved interrupt vector not available");
//
// if assertions are disabled and a reserved vector is used then we
// maybe work with the dummy register 0 and an invalid bitgroup value -
// therefore we have to make it valid now
//
pint_regs->prio_bit_group &= PRIO_BITGRP_MASK;
prio_reg = hal_prio_reg_tbl[pint_regs->prio_reg_no]; // get priority register
//
// now set up the selected priority
//
HAL_READ_UINT16(prio_reg, prio_data); // read value from priority register
mask = prio_grp_mask_tbl[pint_regs->prio_bit_group]; // create mask
prio_data &= ~mask; // clear priority to zero
prio_data |= (level << (pint_regs->prio_bit_group << 2)); // set new priority
HAL_WRITE_UINT16(prio_reg, prio_data); // write priority back into priority register
//
// we store the priority settings in the hal_int_prio_tbl[] for
// fast access from vectors.asm
//
hal_int_prio_tbl[vector] = level;
}
//==========================================================================
// SET INTERRUPT DETECTION MODE
///
/// Provides control over how an interrupt signal is detected.
///
/// \param vector The interrupt vector to be configured
///
/// \param level Set to true if the interrupt is detected by level, and
/// false if it is edge triggered.
///
/// \param up If the interrupt is set to level detect, then if this
/// is true it is detected by a high signal level, and
/// if false by a low signal level. If the interrupt is set
/// to edge triggered, then if this is true it is triggered
/// by a rising edge and if false by a falling edge.
//==========================================================================
void hal_interrupt_configure(int vector, int level, int up)
{
#define INT_REQ_LEVEL_LOW 0x00
#define INT_REQ_EDGE_FALLING 0x01
#define INT_REQ_EDGE_RISING 0x10
#define INT_REQ_EDGE_BOTH 0x11
cyg_uint16 reg_data; // temprorary stores register data
cyg_uint16 mask; // required for masking
cyg_uint32 iscr; // interrupt sense control register address
cyg_uint8 int_req_conf; // contains configuration data to be written into iscr
//
// Check if vector, level and up are valid values
//
CYG_ASSERT(!(up && level), "Cannot trigger on high level!");
CYG_ASSERT((CYGNUM_HAL_INTERRUPT_EXTERNAL_0 <= vector
&& CYGNUM_HAL_INTERRUPT_EXTERNAL_15 >= vector)
|| CYGNUM_HAL_INTERRUPT_NMI, "only external interrupts and NMI are configurable" );
CYG_ASSERT(!(level && (vector == CYGNUM_HAL_INTERRUPT_NMI)), "NMI cannot trigger on level - only rising or falling edge");
//
// NMI interrupt needs special treatment - only rising or falling edge
// is configurable for NMI
//
if (CYGNUM_HAL_INTERRUPT_NMI == vector)
{
HAL_READ_UINT8(CYGARC_INTCR, reg_data);
if (up)
{
reg_data |= CYGARC_INTCR_NMIEG_RIS;
}
else
{
reg_data &= ~CYGARC_INTCR_NMIEG_RIS;
}
HAL_WRITE_UINT8(CYGARC_INTCR, reg_data);
return;
}
//
// if it is not NMI then we are here and it is an external interrupt
//
int_req_conf = INT_REQ_EDGE_FALLING;
if (level)
{
int_req_conf = INT_REQ_LEVEL_LOW;
}
if (up)
{
int_req_conf = INT_REQ_EDGE_RISING;
}
//
// decide if we need ISCRL or ISCRH
//
iscr = (vector <= CYGNUM_HAL_INTERRUPT_EXTERNAL_7) ? CYGARC_ISCRL : CYGARC_ISCRH;
mask = 3 << (((vector - CYGNUM_HAL_INTERRUPT_EXTERNAL_0) & 7) << 1);
//
// Read value, write new configuration data and store value back into
// iscr register
//
HAL_READ_UINT16(iscr, reg_data);
reg_data &= ~mask;
reg_data |= int_req_conf << (((vector - CYGNUM_HAL_INTERRUPT_EXTERNAL_0) & 7) << 1);
HAL_WRITE_UINT16(iscr, reg_data);
}
//==========================================================================
// ATTACH ISR TO VECTOR
///
/// Attach ISR to given vector.
/// Attaches the ISR, data pointer and object pointer to the given
/// vector. When an interrupt occurs on this vector the ISR is called
/// using the C calling convention and the vector number and data pointer
/// are passed to it as the first and second arguments respectively.
///
/// \param vector Vector number of vector where VSR should be attached
/// \param isr Points to interrupt service routine
/// \param data Pointer to data
/// \param object Pointer to interrupt object
///
/// \note Normally HAL_INTERRUP_ATTACH is only a simple macro in
/// hal_intr.h. I made this a function in order to execute
/// different asserts here
//==========================================================================
void hal_interrupt_attach(int vector, CYG_ADDRESS isr, CYG_ADDRWORD data, CYG_ADDRESS object)
{
cyg_uint32 index;
HAL_TRANSLATE_VECTOR(vector, index);
//
// If the user disabled the watchdog timer overflow code then we check
// here, if user tries to use this vector. Set_level is called each time
// an interrupt vector is attached.
//
#if !defined(CYGBLD_HAL_H8S_WATCHDOG_INTERRUPT_CODE)
CYG_ASSERT(CYGNUM_HAL_INTERRUPT_WOVI != vector, "Watchdog timer overflow interrupt code not supported" );
#endif
CYG_ASSERT(hal_int_mask_tbl[index].address != 0, "H8S interrupt vector not supported");
//
// now attach the interrupt data if the vector is free
//
if (hal_interrupt_handlers[index] == (CYG_ADDRESS)HAL_DEFAULT_ISR)
{
hal_interrupt_handlers[index] = (CYG_ADDRESS)isr;
hal_interrupt_data[index] = (CYG_ADDRWORD)data;
hal_interrupt_objects[index] = (CYG_ADDRESS)object;
}
}
//==========================================================================
// HARDWARE RESET
///
/// Triggers reset with internal watchdog.
/// We use the H8S/2674 buildtin watchdog for triggering a hardware
/// reset. This can be overwritten in different platforms
//==========================================================================
#ifndef CYGPKG_HAL_H8S_WDRESET_DEFINED
void h8s_reset_watchdog(void)
{
cyg_uint8 tmp;
//
// Dummy read to reset OVF bit
//
HAL_READ_UINT8(CYGARC_TCSRR, tmp);
tmp &= ~CYGARC_TCSR_OVF;
tmp |= CYGARC_TCSR_WT;
//
// Setup timer as watchdog timer with clock/2 and clear overflow flag
//
HAL_WRITE_UINT16(CYGARC_TCSRW, tmp | CYGARC_TCSR_MAGIC);
//
// enable reset if timer overflows
//
HAL_WRITE_UINT8(CYGARC_RSTCSRR, tmp);
tmp |= CYGARC_RSTCSR_RSTE;
HAL_WRITE_UINT16(CYGARC_RSTCSRW, tmp | CYGARC_RSTCSR_DATA_MAGIC);
//
// setup timer up counter register
//
HAL_WRITE_UINT16(CYGARC_TCNTW, 0x80 | CYGARC_TCNT_MAGIC);
//
//
// start timer - Set Timer Enable bit in TCSR
//
HAL_READ_UINT8(CYGARC_TCSRR, tmp);
tmp |= CYGARC_TCSR_TME;
HAL_WRITE_UINT16(CYGARC_TCSRW, tmp | CYGARC_TCSR_MAGIC);
//
// loop untill h8s resets
//
while (1)
{
// do nothing
}
}
#endif
//------------------------------------------------------------------------
// End of var_misc.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -