mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-01-06 08:53:36 +01:00
299 lines
7.4 KiB
C
299 lines
7.4 KiB
C
//---
|
|
// gint:core:intc - Interrupt Controller
|
|
//
|
|
// The interrupt controller is unwieldy because SH7705 and SH7305 have a
|
|
// completely different interface. Everything here is split up and you'll
|
|
// have to explicitly handle both to be able to use the device.
|
|
//
|
|
// gint's API provides higher-level and platform-agnostic interrupt
|
|
// management. This is probably what you are looking for.
|
|
//---
|
|
|
|
#ifndef GINT_CORE_INTC
|
|
#define GINT_CORE_INTC
|
|
|
|
#include <defs/types.h>
|
|
|
|
//---
|
|
// SH7705 Interrupt Controller. Refer to:
|
|
// "Renesas SH7705 Group Hardware Manual"
|
|
// Section 6: "Interrupt Controller (INTC)"
|
|
//---
|
|
|
|
/* sh7705_intc_ipc_t - Interrupt Priority Controller
|
|
A set of 16-bit register that control the interrupt priorities. The SH7705's
|
|
IPC has its registers scattered everywhere in the memory, so there is a
|
|
pointer for each register. The SH7305 needs only one pointer for the whole
|
|
IPC because the registers are in a contiguous area. */
|
|
typedef struct
|
|
{
|
|
volatile word_union(*IPRA,
|
|
uint16_t TMU0 :4; /* Timer 0 */
|
|
uint16_t TMU1 :4; /* Timer 1 */
|
|
uint16_t TMU2 :4; /* Timer 2 */
|
|
uint16_t RTC :4; /* Real-Time Clock */
|
|
);
|
|
|
|
volatile word_union(*IPRB,
|
|
uint16_t WDT :4; /* Watchdog Timer */
|
|
uint16_t REF :4; /* BSC Refresh Request, SDRAM (?) */
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
);
|
|
|
|
volatile word_union(*IPRC,
|
|
uint16_t IRQ3 :4; /* Interrupt request 3 */
|
|
uint16_t IRQ2 :4; /* Interrupt request 2 */
|
|
uint16_t IRQ1 :4; /* Interrupt request 1 */
|
|
uint16_t IRQ0 :4; /* Interrupt request 0 */
|
|
);
|
|
|
|
volatile word_union(*IPRD,
|
|
uint16_t PINT0_7 :4; /* External interrupt pins 0 to 7 */
|
|
uint16_t PINT8_15 :4; /* External interrupt pins 8 to 15 */
|
|
uint16_t IRQ5 :4; /* Interrupt request 5 */
|
|
uint16_t IRQ4 :4; /* Interrupt request 4 */
|
|
);
|
|
|
|
volatile word_union(*IPRE,
|
|
uint16_t DMAC :4; /* Direct Memory Access Controller */
|
|
uint16_t SCIF0 :4; /* Serial Communication Interface 0 */
|
|
uint16_t SCIF2 :4; /* Serial Communication Interface 2 */
|
|
uint16_t ADC :4; /* Analog/Decimal Converter */
|
|
);
|
|
|
|
volatile word_union(*IPRF,
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
uint16_t USB :4; /* USB Controller */
|
|
uint16_t :4;
|
|
);
|
|
|
|
volatile word_union(*IPRG,
|
|
uint16_t TPU0 :4; /* Timer Pulse Unit 0 */
|
|
uint16_t TPU1 :4; /* Timer Pulse Unit 1 */
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
);
|
|
|
|
volatile word_union(*IPRH,
|
|
uint16_t TPU2 :4; /* Timer Pulse Unit 2 */
|
|
uint16_t TPU3 :4; /* Timer Pulse Unit 3 */
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
);
|
|
|
|
} PACKED(4) sh7705_intc_ipc_t;
|
|
|
|
/* sh7705_intc_icr1_t - Interrupt Control Register 1 (general) */
|
|
typedef volatile word_union(sh7705_intc_icr1_t,
|
|
uint16_t MAI :1; /* Mask All Interrupts */
|
|
uint16_t IRQLVL :1; /* Interrupt Request Level Detect */
|
|
uint16_t BLMSK :1; /* Enable NMI when BL is set */
|
|
uint16_t :1;
|
|
uint16_t IRQ5E :2; /* IRQ 5 Edge Detection */
|
|
uint16_t IRQ4E :2; /* etc. */
|
|
uint16_t IRQ3E :2;
|
|
uint16_t IRQ2E :2;
|
|
uint16_t IRQ1E :2;
|
|
uint16_t IRQ0E :2;
|
|
);
|
|
|
|
/* sh7705_intc_t - the SH7705 interrupt controller */
|
|
typedef struct
|
|
{
|
|
/* All interrupt priority registers */
|
|
union {
|
|
sh7705_intc_ipc_t _;
|
|
volatile uint16_t *IPRS[8];
|
|
} PACKED(4);
|
|
|
|
/* Control registers */
|
|
sh7705_intc_icr1_t *ICR1;
|
|
|
|
} PACKED(4) sh7705_intc_t;
|
|
|
|
|
|
|
|
//---
|
|
// SH7305 Interrupt Controller. Refer to:
|
|
// "Renesas SH7724 User's Manual: Hardware"
|
|
// Section 13: "Interrupt Controller (INTC)"
|
|
//---
|
|
|
|
/* sh7305_intc_ipc_t - Interrupt Priority Controller
|
|
Some of the fields have been left unnamed because they correspond to SH7724
|
|
peripheral modules that are *very* unlikely to even exist in the SH7305, let
|
|
alone by of any use to us */
|
|
typedef volatile struct
|
|
{
|
|
word_union(IPRA,
|
|
uint16_t TMU0_0 :4; /* TMU0 Channel 0 */
|
|
uint16_t TMU0_1 :4; /* TMU0 Channel 1 */
|
|
uint16_t TMU0_2 :4; /* TMU0 Channel 2 */
|
|
uint16_t IrDA :4; /* Infrared Communication */
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRB,
|
|
uint16_t :4;
|
|
uint16_t LCDC :4; /* LCD Controller */
|
|
uint16_t DMAC1A :4; /* Direct Memory Access Controller 1 */
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRC,
|
|
uint16_t TMU1_0 :4; /* TMU1 Channel 0 */
|
|
uint16_t TMU1_1 :4; /* TMU1 Channel 1 */
|
|
uint16_t TMU1_2 :4; /* TMU1 Channel 2 */
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRD,
|
|
uint16_t :4;
|
|
uint16_t MMCIF :4; /* MultiMedia Card Interface */
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRE,
|
|
uint16_t DMAC0A :4; /* Direct Memory Access Controller 0 */
|
|
uint16_t :4;
|
|
uint16_t ETMU3 :4; /* Extra TMU 3 */
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRF,
|
|
uint16_t KEYSC :4; /* Key Scan Interface */
|
|
uint16_t DMACOB :4; /* DMAC0 transfer/error info */
|
|
uint16_t USB0_1 :4; /* USB controller */
|
|
uint16_t CMT :4; /* Compare Match Timer */
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRG,
|
|
uint16_t SCIF0 :4; /* SCIF0 transfer/error info */
|
|
uint16_t ETMU1 :4; /* Extra TMU 1 */
|
|
uint16_t ETMU2 :4; /* Extra TMU 2 */
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRH,
|
|
uint16_t MSIOF0 :4; /* Clock-synchronized SCIF channel 0 */
|
|
uint16_t MSIOF1 :4; /* Clock-synchronized SCIF channel 1 */
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRI,
|
|
uint16_t ETMU4 :4; /* Extra TMU 4 */
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRJ,
|
|
uint16_t ETMU0 :4; /* Extra TMU 0 */
|
|
uint16_t :4;
|
|
uint16_t FSI :4; /* FIFO-Buffered Serial Interface */
|
|
uint16_t SDHI1 :4; /* SD Card Host Interface channel 1 */
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRK,
|
|
uint16_t RTC :4; /* Real-Time Clock */
|
|
uint16_t DMAC1B :4; /* DMAC1 transfer/error info */
|
|
uint16_t :4;
|
|
uint16_t SDHI0 :4; /* SD Card Host Interface channel 0 */
|
|
);
|
|
pad(2);
|
|
|
|
word_union(IPRL,
|
|
uint16_t ETMU5 :4; /* Extra TMU 5 */
|
|
uint16_t :4;
|
|
uint16_t TPU :4; /* Timer-Pulse Unit */
|
|
uint16_t :4;
|
|
);
|
|
pad(2);
|
|
|
|
} PACKED(4) sh7305_intc_ipc_t;
|
|
|
|
/* sh7305_intc_masks_t - Interrupt mask management
|
|
Writing 1 to IMR masks interrupts; writing 1 to IMCRs clears the masks.
|
|
Writing 0 is ignored; reading from IMCRs yields undefined values */
|
|
typedef volatile struct
|
|
{
|
|
uint8_t IMR0; pad(3);
|
|
uint8_t IMR1; pad(3);
|
|
uint8_t IMR2; pad(3);
|
|
uint8_t IMR3; pad(3);
|
|
uint8_t IMR4; pad(3);
|
|
uint8_t IMR5; pad(3);
|
|
uint8_t IMR6; pad(3);
|
|
uint8_t IMR7; pad(3);
|
|
uint8_t IMR8; pad(3);
|
|
uint8_t IMR9; pad(3);
|
|
uint8_t IMR10; pad(3);
|
|
uint8_t IMR11; pad(3);
|
|
uint8_t IMR12;
|
|
|
|
} PACKED(4) sh7305_intc_masks_t;
|
|
|
|
|
|
/* sh7305_intc_userimask_t - User Interrupt Mask
|
|
Sets the minimum required level for interrupts to be accepted.
|
|
|
|
WARNING: Writing to this register is only allowed when the upper bits of the
|
|
operand (ie. the new value of USERIMASK) are 0xa5; otherwise, the write is
|
|
ignored. To modify the value of this register, do not access the bit field
|
|
directly, backup the variable and modify it:
|
|
|
|
void set_user_imask(int new_level)
|
|
{
|
|
sh7305_intc_userimask_t mask = *(INTC._7305.USERIMASK);
|
|
mask._0xa5 = 0xa5;
|
|
mask.UIMASK = new_level & 0x0f;
|
|
*(INTC._7305.USERIMASK) = mask;
|
|
}
|
|
*/
|
|
typedef volatile lword_union(sh7305_intc_userimask_t,
|
|
uint32_t _0xa5 :8; /* Always set to 0xa5 before writing */
|
|
uint32_t :16;
|
|
uint32_t UIMASK :4; /* User Interrupt Mask Level */
|
|
uint32_t :4;
|
|
);
|
|
|
|
/* sh7305_intc_t - the SH7305 interrupt controller */
|
|
typedef struct
|
|
{
|
|
/* Interrupt priority registers */
|
|
union {
|
|
sh7305_intc_ipc_t *_;
|
|
volatile uint16_t *IPRS;
|
|
};
|
|
|
|
/* Interrupt mask & mask clear registers */
|
|
sh7305_intc_masks_t *MSK;
|
|
sh7305_intc_masks_t *MSKCLR;
|
|
|
|
/* Other registers */
|
|
sh7305_intc_userimask_t *USERIMASK;
|
|
|
|
} PACKED(4) sh7305_intc_t;
|
|
|
|
//---
|
|
// Forward definitions
|
|
//---
|
|
|
|
/* Provided by core/gint.c */
|
|
extern sh7705_intc_t INTC3;
|
|
extern sh7305_intc_t INTC4;
|
|
|
|
#endif /* GINT_CORE_INTC */
|