mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 20:43:36 +01:00
dma: add a new driver to support r61524
Also add a power interface (without driving code) and switch toolchain because the previous sh4eb-nofpu-elf toolchain was not completely FPU-free.
This commit is contained in:
parent
f33cb3cf80
commit
04231ea5d6
18 changed files with 578 additions and 144 deletions
|
@ -47,8 +47,8 @@ or both. There are a few dependencies:
|
||||||
* A suitable GCC toolcahin in the `PATH`. You can absolutely *not* build gint
|
* A suitable GCC toolcahin in the `PATH`. You can absolutely *not* build gint
|
||||||
with your system compiler!
|
with your system compiler!
|
||||||
* For fx-9860G II, `sh3eb-elf` is strongly advised
|
* For fx-9860G II, `sh3eb-elf` is strongly advised
|
||||||
* For fx-CG 50, `sh4eb-nofpu-elf` is slightly better but `sh3eb-elf` is
|
* For fx-CG 50, `sh4eb-elf` (with `-m4-nofpu`) is slightly better but
|
||||||
completely fine
|
`sh3eb-elf` is completely fine
|
||||||
* The [fxSDK](http://git.planet-casio.com/lephe/fxsdk) installed and available
|
* The [fxSDK](http://git.planet-casio.com/lephe/fxsdk) installed and available
|
||||||
in the PATH. You will need `fxsdk` and `fxconv` to build gint, and if you
|
in the PATH. You will need `fxsdk` and `fxconv` to build gint, and if you
|
||||||
intend to develop add-ins for fx-9860G II, you probably want `fxg1a` as well.
|
intend to develop add-ins for fx-9860G II, you probably want `fxg1a` as well.
|
||||||
|
@ -83,7 +83,7 @@ with `--prefix`, or if you built your compiler as root.
|
||||||
### Building for fx-CG 50
|
### Building for fx-CG 50
|
||||||
|
|
||||||
Create a build directory and configure in it. The default toolchain is
|
Create a build directory and configure in it. The default toolchain is
|
||||||
`sh4eb-nofpu-elf`, if you wish to build with `sh3eb-elf`, you need to add a
|
`sh4eb-elf`, if you wish to build with `sh3eb-elf`, you need to add a
|
||||||
command-line option `--toolchain=sh3eb-elf`.
|
command-line option `--toolchain=sh3eb-elf`.
|
||||||
|
|
||||||
% mkdir build.cg && cd build.cg
|
% mkdir build.cg && cd build.cg
|
||||||
|
|
6
configure
vendored
6
configure
vendored
|
@ -45,7 +45,7 @@ Target selection:
|
||||||
|
|
||||||
fxcg50 covers just the fx-CG 50; there is some unofficial compatibility with
|
fxcg50 covers just the fx-CG 50; there is some unofficial compatibility with
|
||||||
fx-CG 10/20. All of these are SH4-only.
|
fx-CG 10/20. All of these are SH4-only.
|
||||||
Default toolchain is 'sh4eb-nofpu-elf'.
|
Default toolchain is 'sh4eb-elf'.
|
||||||
|
|
||||||
Build options:
|
Build options:
|
||||||
--toolchain=TRIPLET Build with a different toolchain
|
--toolchain=TRIPLET Build with a different toolchain
|
||||||
|
@ -102,11 +102,13 @@ for arg; do case "$arg" in
|
||||||
toolchain=${toolchain:-sh3eb-elf};;
|
toolchain=${toolchain:-sh3eb-elf};;
|
||||||
"fxcg50")
|
"fxcg50")
|
||||||
target=fxcg50
|
target=fxcg50
|
||||||
toolchain=${toolchain:-sh4eb-nofpu-elf};;
|
toolchain=${toolchain:-sh4eb-elf};;
|
||||||
*)
|
*)
|
||||||
echo "error: invalid target '$target'"
|
echo "error: invalid target '$target'"
|
||||||
fail=true
|
fail=true
|
||||||
esac;;
|
esac;;
|
||||||
|
--toolchain=*)
|
||||||
|
toolchain=${arg#*=};;
|
||||||
|
|
||||||
--prefix=*)
|
--prefix=*)
|
||||||
prefix=${arg#*=};;
|
prefix=${arg#*=};;
|
||||||
|
|
69
include/gint/dma.h
Normal file
69
include/gint/dma.h
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
//---
|
||||||
|
// gint:dma - Direct Memory Access for efficient data transfer
|
||||||
|
//
|
||||||
|
// Currently this module is used only to transfer data to the display on
|
||||||
|
// fxcg50, but fast memcpy() is apparently possible as well.
|
||||||
|
//---
|
||||||
|
|
||||||
|
#ifndef GINT_DMA
|
||||||
|
#define GINT_DMA
|
||||||
|
|
||||||
|
#include <gint/defs/types.h>
|
||||||
|
|
||||||
|
/* dma_size_t - Transfer block size */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* Normal transfers of 1, 2, 4, 8, 16 or 32 bytes at a time */
|
||||||
|
DMA_1B = 0,
|
||||||
|
DMA_2B = 1,
|
||||||
|
DMA_4B = 2,
|
||||||
|
DMA_8B = 7,
|
||||||
|
DMA_16B = 3,
|
||||||
|
DMA_32B = 4,
|
||||||
|
|
||||||
|
/* Transfers of 16 or 32 bytes divided in two operations */
|
||||||
|
DMA_16B_DIV = 11,
|
||||||
|
DMA_32B_DIV = 12,
|
||||||
|
|
||||||
|
} dma_size_t;
|
||||||
|
|
||||||
|
/* dma_address_t - Addressing mode for source and destination regions */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* Fixed address mode: the same address is read/written at each step */
|
||||||
|
DMA_FIXED = 0,
|
||||||
|
/* Increment: address is incremented by transfer size at each step */
|
||||||
|
DMA_INC = 1,
|
||||||
|
/* Decrement: only allowed for 1/2/4-byte transfers */
|
||||||
|
DMA_DEC = 2,
|
||||||
|
/* Fixed division mode: address is fixed even in 16/32-divide mode */
|
||||||
|
DMA_FIXEDDIV = 3,
|
||||||
|
|
||||||
|
} dma_address_t;
|
||||||
|
|
||||||
|
/* dma_transfer() - Start a data transfer on channel 0
|
||||||
|
|
||||||
|
This function returns just when the transfer starts. The transfer will end
|
||||||
|
later on and the DMA will be stopped by an interrupt. Call
|
||||||
|
dma_transfer_wait() if you need to wait for the transfer to finish. Don't
|
||||||
|
start a new transfer until the current one is finished!
|
||||||
|
|
||||||
|
@size Transfer size
|
||||||
|
@blocks Number of blocks (transferred memory = size * blocks)
|
||||||
|
@src Source pointer, must be aligned with transfer size
|
||||||
|
@src_mode Source address mode
|
||||||
|
@dst Destination address, must be aligned with transfer size
|
||||||
|
@dst_mode Destination address mode */
|
||||||
|
void dma_transfer(dma_size_t size, uint length,
|
||||||
|
void *src, dma_address_t src_mode,
|
||||||
|
void *dst, dma_address_t dst_mode);
|
||||||
|
|
||||||
|
/* dma_transfer_wait() - Wait for a transfer on channel 0 to finish
|
||||||
|
|
||||||
|
You should call this function when you need to transfer to be complete
|
||||||
|
before continuing execution. If you are sure that the transfer is finished,
|
||||||
|
this is not necessary (the only way to know is to look at the DMA registers
|
||||||
|
or record interrupts). */
|
||||||
|
void dma_transfer_wait(void);
|
||||||
|
|
||||||
|
#endif /* GINT_DMA */
|
|
@ -1,9 +1,9 @@
|
||||||
//---
|
//---
|
||||||
// gint:core:cpg - Clock Pulse Generator
|
// gint:mpu:cpg - Clock Pulse Generator
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#ifndef GINT_CORE_CPG
|
#ifndef GINT_MPU_CPG
|
||||||
#define GINT_CORE_CPG
|
#define GINT_MPU_CPG
|
||||||
|
|
||||||
#include <gint/defs/attributes.h>
|
#include <gint/defs/attributes.h>
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
|
@ -79,4 +79,4 @@ typedef volatile struct
|
||||||
|
|
||||||
#define SH7305_CPG (*((sh7305_cpg_t *)0xa4150000))
|
#define SH7305_CPG (*((sh7305_cpg_t *)0xa4150000))
|
||||||
|
|
||||||
#endif /* GINT_CORE_CPG */
|
#endif /* GINT_MPU_CPG */
|
||||||
|
|
89
include/gint/mpu/dma.h
Normal file
89
include/gint/mpu/dma.h
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
//---
|
||||||
|
// gint:mpu:dma - Direct Memory Access control
|
||||||
|
//
|
||||||
|
// The DMA is a major module on fxcg50 because it is needed to send data
|
||||||
|
// to the display at a reasonable speed. On fx9860g, it is very rarely
|
||||||
|
// used, if ever.
|
||||||
|
//---
|
||||||
|
|
||||||
|
#ifndef GINT_MPU_DMA
|
||||||
|
#define GINT_MPU_DMA
|
||||||
|
|
||||||
|
#include <gint/defs/types.h>
|
||||||
|
|
||||||
|
//---
|
||||||
|
// SH7305 Direct Memory Access Controller. Refer to:
|
||||||
|
// "Renesas SH7724 User's Manual: Hardware"
|
||||||
|
// Section 16: "Direct Memory Access Controller (DMAC)"
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* sh7305_dma_channel_t - One of the main 6 channels of the DMA
|
||||||
|
Note that the many settings are only available on channels 0 to 3 (denoted
|
||||||
|
by [0..3]) or on channels 0 and 1 (denoted by [0,1]).
|
||||||
|
The documentation is apparently wrong about the placement is TS[3:2], the
|
||||||
|
neighbouring read-only bit must be swapped before TS[3:2]. */
|
||||||
|
typedef volatile struct
|
||||||
|
{
|
||||||
|
uint32_t SAR;
|
||||||
|
uint32_t DAR;
|
||||||
|
|
||||||
|
/* Mind that the 8 upper bits should always be written as 0 */
|
||||||
|
uint32_t TCR;
|
||||||
|
|
||||||
|
lword_union(CHCR,
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t LCKN :1; /* Bus Right Release Enable */
|
||||||
|
uint32_t :2;
|
||||||
|
uint32_t RPT :3; /* Repeat setting [0..3] */
|
||||||
|
uint32_t DA :1; /* DREQ Asynchronous [0,1] */
|
||||||
|
|
||||||
|
uint32_t DO :1; /* DMA Overrun [0,1] */
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t TS_32 :2; /* Transfer Size (upper half) */
|
||||||
|
uint32_t HE :1; /* Half-End flag [0..3] */
|
||||||
|
uint32_t HIE :1; /* Half-end Interrupt Enable [0..3] */
|
||||||
|
uint32_t AM :1; /* Acknowledge mode [0,1] */
|
||||||
|
uint32_t AL :1; /* Acknowledge level [0,1] */
|
||||||
|
|
||||||
|
uint32_t DM :2; /* Destination address Mode */
|
||||||
|
uint32_t SM :2; /* Source address Mode */
|
||||||
|
uint32_t RS :4; /* Resource Select [0,1] */
|
||||||
|
|
||||||
|
uint32_t DL :1; /* DREQ Level [0,1] */
|
||||||
|
uint32_t DS :1; /* DREQ Source select[0,1] */
|
||||||
|
uint32_t TB :1; /* Transfer Bus Mode */
|
||||||
|
uint32_t TS_10 :2; /* Transfer Size (lower half) */
|
||||||
|
uint32_t IE :1; /* Interrupt Enable */
|
||||||
|
uint32_t TE :1; /* Transfer End flag */
|
||||||
|
uint32_t DE :1; /* DMA Enable */
|
||||||
|
);
|
||||||
|
|
||||||
|
} GPACKED(4) sh7305_dma_channel_t;
|
||||||
|
|
||||||
|
/* sh7305_dma_t - DMA Controller */
|
||||||
|
typedef volatile struct
|
||||||
|
{
|
||||||
|
sh7305_dma_channel_t DMA0;
|
||||||
|
sh7305_dma_channel_t DMA1;
|
||||||
|
sh7305_dma_channel_t DMA2;
|
||||||
|
sh7305_dma_channel_t DMA3;
|
||||||
|
|
||||||
|
word_union(OR,
|
||||||
|
uint16_t CMS :4; /* Cycle steal Mode Select */
|
||||||
|
uint16_t :2;
|
||||||
|
uint16_t PR :2; /* PRiority mode */
|
||||||
|
uint16_t :5;
|
||||||
|
uint16_t AE :1; /* Address Error flag */
|
||||||
|
uint16_t NMIF :1; /* NMI Flag */
|
||||||
|
uint16_t DME :1; /* DMA Master Enable */
|
||||||
|
);
|
||||||
|
pad(14);
|
||||||
|
|
||||||
|
sh7305_dma_channel_t DMA4;
|
||||||
|
sh7305_dma_channel_t DMA5;
|
||||||
|
|
||||||
|
} GPACKED(4) sh7305_dma_t;
|
||||||
|
|
||||||
|
#define SH7305_DMA (*((sh7305_dma_t *)0xfe008020))
|
||||||
|
|
||||||
|
#endif /* GINT_MPU_DMA */
|
|
@ -1,5 +1,5 @@
|
||||||
//---
|
//---
|
||||||
// gint:core:intc - Interrupt Controller
|
// gint:mpu:intc - Interrupt Controller
|
||||||
//
|
//
|
||||||
// The interrupt controller is unwieldy because SH7705 and SH7305 have a
|
// The interrupt controller is unwieldy because SH7705 and SH7305 have a
|
||||||
// completely different interface. Everything here is split up and you'll
|
// completely different interface. Everything here is split up and you'll
|
||||||
|
@ -9,8 +9,8 @@
|
||||||
// management. This is probably what you are looking for.
|
// management. This is probably what you are looking for.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#ifndef GINT_CORE_INTC
|
#ifndef GINT_MPU_INTC
|
||||||
#define GINT_CORE_INTC
|
#define GINT_MPU_INTC
|
||||||
|
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
|
|
||||||
|
@ -296,4 +296,4 @@ typedef struct
|
||||||
extern sh7705_intc_t SH7705_INTC;
|
extern sh7705_intc_t SH7705_INTC;
|
||||||
extern sh7305_intc_t SH7305_INTC;
|
extern sh7305_intc_t SH7305_INTC;
|
||||||
|
|
||||||
#endif /* GINT_CORE_INTC */
|
#endif /* GINT_MPU_INTC */
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
//---
|
//---
|
||||||
// gint:core:pfc - Pin Function Controller
|
// gint:mpu:pfc - Pin Function Controller
|
||||||
//
|
//
|
||||||
// The Pin Function Controller has a simple register interface, the main
|
// The Pin Function Controller has a simple register interface, the main
|
||||||
// difficulty is still understanding the role of its pins.
|
// difficulty is still understanding the role of its pins.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#ifndef GINT_CORE_PFC
|
#ifndef GINT_MPU_PFC
|
||||||
#define GINT_CORE_PFC
|
#define GINT_MPU_PFC
|
||||||
|
|
||||||
#include <gint/defs/attributes.h>
|
#include <gint/defs/attributes.h>
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
|
@ -75,4 +75,4 @@ typedef volatile struct
|
||||||
// TODO: Document the SH7305 Pin Function Controller
|
// TODO: Document the SH7305 Pin Function Controller
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#endif /* GINT_CORE_PFC */
|
#endif /* GINT_MPU_PFC */
|
||||||
|
|
102
include/gint/mpu/power.h
Normal file
102
include/gint/mpu/power.h
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
//---
|
||||||
|
// gint:mpu:power- Standby modes and power management
|
||||||
|
//---
|
||||||
|
|
||||||
|
#ifndef GINT_MPU_POWER
|
||||||
|
#define GINT_MPU_POWER
|
||||||
|
|
||||||
|
#include <gint/defs/types.h>
|
||||||
|
|
||||||
|
//---
|
||||||
|
// SH7305 Standby modes and power management Refer to:
|
||||||
|
// "Renesas SH7724 User's Manual: Hardware"
|
||||||
|
// Section 18: "Reset and Power-Down Modes"
|
||||||
|
//---
|
||||||
|
|
||||||
|
typedef volatile struct
|
||||||
|
{
|
||||||
|
/* Standby Control Register: only one of the bits may be set at any
|
||||||
|
given time. Setting several bits is prohibited! */
|
||||||
|
lword_union(STBCR,
|
||||||
|
uint32_t :24;
|
||||||
|
uint32_t STBY :1; /* Map [sleep] to standby mode */
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t RSTBY :1; /* Map [sleep] to R-standby mode */
|
||||||
|
uint32_t USTBY :1; /* Map [sleep] to U-standby mode */
|
||||||
|
uint32_t :4;
|
||||||
|
);
|
||||||
|
pad(12);
|
||||||
|
|
||||||
|
/* Module Stop Control Register 0
|
||||||
|
Stopping the TLB (bit 31), IC (bit 30 or OC (bit 29) seems somewhat
|
||||||
|
dangerous, plus requires special operations. */
|
||||||
|
lword_union(MSTPCR0,
|
||||||
|
uint32_t TLB :1;
|
||||||
|
uint32_t IC :1;
|
||||||
|
uint32_t OC :1;
|
||||||
|
uint32_t RS :1;
|
||||||
|
uint32_t IL :1;
|
||||||
|
uint32_t SndCache :1;
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t FPU :1;
|
||||||
|
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t INTC :1;
|
||||||
|
uint32_t DMAC0 :1;
|
||||||
|
uint32_t SuperHyway :1;
|
||||||
|
uint32_t HUDI :1;
|
||||||
|
uint32_t DBG :1;
|
||||||
|
uint32_t UDB :1;
|
||||||
|
uint32_t Debug :1;
|
||||||
|
|
||||||
|
uint32_t TMU0 :1;
|
||||||
|
uint32_t CMT :1;
|
||||||
|
uint32_t RWDT :1;
|
||||||
|
uint32_t DMAC1 :1;
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t TMU1 :1;
|
||||||
|
uint32_t SCIF0 :1;
|
||||||
|
uint32_t SCIF1 :1;
|
||||||
|
|
||||||
|
uint32_t SCIF2 :1;
|
||||||
|
uint32_t SCIF3 :1;
|
||||||
|
uint32_t SCIF4 :1;
|
||||||
|
uint32_t SCIF5 :1;
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t MSIOF0 :1;
|
||||||
|
uint32_t MSIOF1 :1;
|
||||||
|
uint32_t :1;
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Module Stop Control Register 1 */
|
||||||
|
lword_union(MSTPCR1,
|
||||||
|
uint32_t :19;
|
||||||
|
uint32_t KEYSC :1;
|
||||||
|
uint32_t RTC :1;
|
||||||
|
uint32_t :1;
|
||||||
|
uint32_t I2C0 :1;
|
||||||
|
uint32_t I2C1 :1;
|
||||||
|
uint32_t :8;
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Module Stop Control Register 2
|
||||||
|
I stripped down this one to remove any fancy modules from the SH7724
|
||||||
|
that are unlikely to even be present in the SH7305. */
|
||||||
|
lword_union(MSTPCR2,
|
||||||
|
uint32_t :6;
|
||||||
|
uint32_t TPU :1;
|
||||||
|
uint32_t :4;
|
||||||
|
uint32_t USB0 :1;
|
||||||
|
uint32_t :20;
|
||||||
|
);
|
||||||
|
pad(4);
|
||||||
|
|
||||||
|
/* Boot Address Register
|
||||||
|
I really don't suggest writing to BAR. */
|
||||||
|
uint32_t const BAR;
|
||||||
|
|
||||||
|
} sh7305_power_t;
|
||||||
|
|
||||||
|
#define SH7305_POWER (*((sh7305_power_t *)0xa4150020))
|
||||||
|
|
||||||
|
#endif /* GINT_MPU_POWER */
|
|
@ -1,9 +1,9 @@
|
||||||
//---
|
//---
|
||||||
// gint:mod:rtc - Real-Time Clock
|
// gint:mpu:rtc - Real-Time Clock
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#ifndef GINT_CORE_RTC
|
#ifndef GINT_MPU_RTC
|
||||||
#define GINT_CORE_RTC
|
#define GINT_MPU_RTC
|
||||||
|
|
||||||
#include <gint/defs/attributes.h>
|
#include <gint/defs/attributes.h>
|
||||||
|
|
||||||
|
@ -75,4 +75,4 @@ typedef volatile struct
|
||||||
#define SH7705_RTC (*((rtc_t *)0xfffffec0))
|
#define SH7705_RTC (*((rtc_t *)0xfffffec0))
|
||||||
#define SH7305_RTC (*((rtc_t *)0xa413fec0))
|
#define SH7305_RTC (*((rtc_t *)0xa413fec0))
|
||||||
|
|
||||||
#endif /* GINT_CORE_RTC */
|
#endif /* GINT_MPU_RTC */
|
||||||
|
|
|
@ -20,8 +20,8 @@ include $(CONFIG)
|
||||||
ifeq "$(CONFIG.TOOLCHAIN)" "sh3eb-elf"
|
ifeq "$(CONFIG.TOOLCHAIN)" "sh3eb-elf"
|
||||||
machine := -m3 -mb
|
machine := -m3 -mb
|
||||||
endif
|
endif
|
||||||
ifeq "$(CONFIG.TOOLCHAIN)" "sh4eb-nofpu-elf"
|
ifeq "$(CONFIG.TOOLCHAIN)" "sh4eb-elf"
|
||||||
machine := -m4 -mb
|
machine := -m4-nofpu -mb
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Compiler flags, assembler flags, dependency generation, archiving
|
# Compiler flags, assembler flags, dependency generation, archiving
|
||||||
|
|
|
@ -97,8 +97,12 @@ void bootlog_mapped(int rom, int ram)
|
||||||
|
|
||||||
print(20, 3, "%c%c", (rom >= (int)rom_size) ? 'F' : 'f',
|
print(20, 3, "%c%c", (rom >= (int)rom_size) ? 'F' : 'f',
|
||||||
isSH3() ? 'u' : 'U');
|
isSH3() ? 'u' : 'U');
|
||||||
print(9, 2, (ram > 8192) ? "E" : "e");
|
|
||||||
print(19, 1, "M");
|
print(19, 1, "M");
|
||||||
|
|
||||||
|
#ifdef FX9860G
|
||||||
|
print(9, 2, (ram > 8192) ? "E" : "e");
|
||||||
|
#endif
|
||||||
|
|
||||||
dupdate();
|
dupdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +136,7 @@ void bootlog_driver(const char *drv, const char *status)
|
||||||
print(x, y, "%3s", drv);
|
print(x, y, "%3s", drv);
|
||||||
x += 4;
|
x += 4;
|
||||||
|
|
||||||
if(x + y >= 22) y++;
|
if(x + y >= 22) x=1, y++;
|
||||||
|
|
||||||
/* Positioning for the driver message */
|
/* Positioning for the driver message */
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
** gint:core:exch - Exception handlers
|
** gint:core:exch - Exception handlers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.global _exch_entry_7305
|
.global _exch_entry_7305
|
||||||
|
|
||||||
#ifdef FX9860G
|
#ifdef FX9860G
|
||||||
.global _exch_entry_7705
|
.global _exch_entry_7705
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.section .gint.blocks, "ax"
|
.section .gint.blocks, "ax"
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
/* SH7305-TYPE DEBUG EXCEPTION HANDLER - 26 BYTES */
|
/* SH7305-TYPE DEBUG EXCEPTION HANDLER - 26 BYTES */
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,14 @@
|
||||||
** blocks depending on its configuration.
|
** blocks depending on its configuration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.global _inth_entry_7305
|
.global _inth_entry_7305
|
||||||
|
|
||||||
#ifdef FX9860G
|
#ifdef FX9860G
|
||||||
.global _inth_entry_7705
|
.global _inth_entry_7705
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
.section .gint.blocks, "ax"
|
.section .gint.blocks, "ax"
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
/* Interrupt handlers
|
/* Interrupt handlers
|
||||||
|
|
||||||
|
@ -100,8 +100,8 @@ _inth_entry_7705:
|
||||||
1: .long 0xa4000000 /* INTEVT2 register */
|
1: .long 0xa4000000 /* INTEVT2 register */
|
||||||
2: .long _inth_remap
|
2: .long _inth_remap
|
||||||
|
|
||||||
.section .gint.data
|
.section .gint.data
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
/* EVENT CODE TRANSLATION TABLE - 96 BYTES */
|
/* EVENT CODE TRANSLATION TABLE - 96 BYTES */
|
||||||
|
|
||||||
|
|
140
src/dma/dma.c
Normal file
140
src/dma/dma.c
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
#include <gint/mpu.h>
|
||||||
|
#include <gint/mpu/dma.h>
|
||||||
|
#include <gint/mpu/power.h>
|
||||||
|
#include <gint/mpu/intc.h>
|
||||||
|
#include <gint/dma.h>
|
||||||
|
#include <gint/drivers.h>
|
||||||
|
#include <gint/clock.h>
|
||||||
|
|
||||||
|
#define DMA SH7305_DMA
|
||||||
|
#define INTC SH7305_INTC
|
||||||
|
#define POWER SH7305_POWER
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Driver interface
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* dma_transfer() - Perform a data transfer */
|
||||||
|
void dma_transfer(dma_size_t size, uint blocks,
|
||||||
|
void *src, dma_address_t src_mode,
|
||||||
|
void *dst, dma_address_t dst_mode)
|
||||||
|
{
|
||||||
|
/* Safety guard: only start a transfer if there's not one running */
|
||||||
|
if(DMA.DMA0.CHCR.DE) return;
|
||||||
|
|
||||||
|
/* Disable DMA0 and disable the master DMA switch */
|
||||||
|
DMA.DMA0.CHCR.DE = 0;
|
||||||
|
DMA.OR.DME = 0;
|
||||||
|
|
||||||
|
/* Set DMA source and target address */
|
||||||
|
DMA.DMA0.SAR = (uint32_t)src & 0x1fffffff;
|
||||||
|
DMA.DMA0.DAR = (uint32_t)dst & 0x1fffffff;
|
||||||
|
|
||||||
|
/* Set the number of blocks to be transferred */
|
||||||
|
DMA.DMA0.TCR = blocks;
|
||||||
|
|
||||||
|
/* Fill in CHCR. Set RS=0100 (auto-request) and the user-provided
|
||||||
|
values for TS (transfer size), DM and SM (address modes) */
|
||||||
|
DMA.DMA0.CHCR.lword = 0x00000400;
|
||||||
|
DMA.DMA0.CHCR.TS_32 = (size >> 2);
|
||||||
|
DMA.DMA0.CHCR.TS_10 = (size & 3);
|
||||||
|
DMA.DMA0.CHCR.DM = dst_mode;
|
||||||
|
DMA.DMA0.CHCR.SM = src_mode;
|
||||||
|
DMA.DMA0.CHCR.IE = 1;
|
||||||
|
|
||||||
|
/* Prepare DMAOR by enabling the master switch and clearing the
|
||||||
|
blocking flags. */
|
||||||
|
DMA.OR.DME = 1;
|
||||||
|
DMA.OR.AE = 0;
|
||||||
|
DMA.OR.NMIF = 0;
|
||||||
|
|
||||||
|
/* Enable channel 0, starting the DMA transfer. */
|
||||||
|
DMA.DMA0.CHCR.DE = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* dma_transfer_wait() - Wait for a transfer on channel 0 to finish */
|
||||||
|
void dma_transfer_wait(void)
|
||||||
|
{
|
||||||
|
/* The master switch is cut when the transfer ends */
|
||||||
|
while(DMA.OR.DME) sleep();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Initialization
|
||||||
|
//---
|
||||||
|
|
||||||
|
static void init(void)
|
||||||
|
{
|
||||||
|
/* This driver is not implemented on SH3 */
|
||||||
|
if(isSH3()) return;
|
||||||
|
|
||||||
|
/* Install the interrupt handler from dma/inth.s */
|
||||||
|
extern void inth_dma_dma0(void);
|
||||||
|
gint_inthandler(0x800, inth_dma_dma0, 32);
|
||||||
|
|
||||||
|
/* Set interrupt priority to 3 */
|
||||||
|
gint_intlevel(16, 3);
|
||||||
|
|
||||||
|
/* Unmask the DMA0 interrupt */
|
||||||
|
INTC.MSKCLR->IMR1 = 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Context system for this driver
|
||||||
|
//---
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
uint32_t SAR0, DAR0, TCR0, CHCR0;
|
||||||
|
uint16_t OR;
|
||||||
|
int clock;
|
||||||
|
|
||||||
|
} GPACKED(4) ctx_t;
|
||||||
|
|
||||||
|
/* One buffer for the system state will go in gint's .bss section */
|
||||||
|
GBSS static ctx_t sys_ctx;
|
||||||
|
|
||||||
|
static void ctx_save(void *buf)
|
||||||
|
{
|
||||||
|
ctx_t *ctx = buf;
|
||||||
|
|
||||||
|
ctx->SAR0 = DMA.DMA0.SAR;
|
||||||
|
ctx->DAR0 = DMA.DMA0.DAR;
|
||||||
|
ctx->TCR0 = DMA.DMA0.TCR;
|
||||||
|
ctx->CHCR0 = DMA.DMA0.CHCR.lword;
|
||||||
|
|
||||||
|
ctx->OR = DMA.OR.word;
|
||||||
|
|
||||||
|
/* Save the supply status of the DMA0 clock */
|
||||||
|
ctx->clock = POWER.MSTPCR0.DMAC0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ctx_restore(void *buf)
|
||||||
|
{
|
||||||
|
ctx_t *ctx = buf;
|
||||||
|
|
||||||
|
DMA.DMA0.SAR = ctx->SAR0;
|
||||||
|
DMA.DMA0.DAR = ctx->DAR0;
|
||||||
|
DMA.DMA0.TCR = ctx->TCR0;
|
||||||
|
DMA.DMA0.CHCR.lword = ctx->CHCR0;
|
||||||
|
|
||||||
|
DMA.OR.word = ctx->OR;
|
||||||
|
|
||||||
|
/* Restore the supply status of the DMA0 clock */
|
||||||
|
POWER.MSTPCR0.DMAC0 = ctx->clock;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Driver structure definition
|
||||||
|
//---
|
||||||
|
|
||||||
|
gint_driver_t drv_dma = {
|
||||||
|
.name = "DMA",
|
||||||
|
.init = init,
|
||||||
|
.ctx_size = sizeof(ctx_t),
|
||||||
|
.sys_ctx = &sys_ctx,
|
||||||
|
.ctx_save = ctx_save,
|
||||||
|
.ctx_restore = ctx_restore,
|
||||||
|
};
|
||||||
|
|
||||||
|
GINT_DECLARE_DRIVER(2, drv_dma);
|
32
src/dma/inth.s
Normal file
32
src/dma/inth.s
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
** gint:dma:inth - Interrupt handler for the DMA
|
||||||
|
** An easy one, just clears some flags and marks all transfers as finished.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.global _inth_dma_dma0
|
||||||
|
.section .gint.blocks, "ax"
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
/* DMA TRANSFER ENDED INTERRUPT HANDLER - BYTES */
|
||||||
|
|
||||||
|
_inth_dma_dma0:
|
||||||
|
/* Clear the TE flag and DMA Enable in CHCR */
|
||||||
|
mov.l 1f, r1
|
||||||
|
mov.l @r1, r0
|
||||||
|
mov #-4, r2
|
||||||
|
and r2, r0
|
||||||
|
mov.l r0, @r1
|
||||||
|
|
||||||
|
/* Clear the AE and NMIF flags in OR, and cut the master switch */
|
||||||
|
add #0x34, r1
|
||||||
|
mov.w @r1, r0
|
||||||
|
shlr8 r0
|
||||||
|
shll8 r0
|
||||||
|
mov.w r0, @r1
|
||||||
|
|
||||||
|
rte
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
|
||||||
|
1: .long 0xfe00802c /* CHCR0 - OR is 0x34 bytes after this */
|
|
@ -2,11 +2,16 @@
|
||||||
// gint:r61524 - Renesas R61524 driver
|
// gint:r61524 - Renesas R61524 driver
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#include <gint/drivers.h>
|
|
||||||
#include <gint/defs/types.h>
|
#include <gint/defs/types.h>
|
||||||
|
#include <gint/drivers.h>
|
||||||
|
#include <gint/dma.h>
|
||||||
|
#include <core/std.h>
|
||||||
|
|
||||||
#ifdef FXCG50
|
#ifdef FXCG50
|
||||||
|
|
||||||
|
#define DMA SH7305_DMA
|
||||||
|
#define POWER SH7305_POWER
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Device specification sheet
|
// Device specification sheet
|
||||||
//---
|
//---
|
||||||
|
@ -83,21 +88,39 @@ GINLINE static void write(uint16_t data)
|
||||||
}
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Driver functions
|
// Window management
|
||||||
//---
|
//---
|
||||||
|
|
||||||
void pixel(int ha, int va, int color)
|
void r61524_win_get(uint16_t *HSA, uint16_t *HEA, uint16_t *VSA, uint16_t *VEA)
|
||||||
{
|
{
|
||||||
select(ram_address_horizontal);
|
select(horizontal_ram_start);
|
||||||
write(ha);
|
*HSA = read();
|
||||||
|
select(horizontal_ram_end);
|
||||||
|
*HEA = read();
|
||||||
|
|
||||||
select(ram_address_vertical);
|
select(vertical_ram_start);
|
||||||
write(va);
|
*VSA = read();
|
||||||
|
select(vertical_ram_end);
|
||||||
select(write_data);
|
*VEA = read();
|
||||||
write(color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void r61524_win_set(uint16_t HSA, uint16_t HEA, uint16_t VSA, uint16_t VEA)
|
||||||
|
{
|
||||||
|
select(horizontal_ram_start);
|
||||||
|
write(HSA);
|
||||||
|
select(horizontal_ram_end);
|
||||||
|
write(HEA);
|
||||||
|
|
||||||
|
select(vertical_ram_start);
|
||||||
|
write(VSA);
|
||||||
|
select(vertical_ram_end);
|
||||||
|
write(VEA);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Driver functions
|
||||||
|
//---
|
||||||
|
|
||||||
void r61524_test(void)
|
void r61524_test(void)
|
||||||
{
|
{
|
||||||
uint16_t device_name;
|
uint16_t device_name;
|
||||||
|
@ -109,10 +132,6 @@ void r61524_test(void)
|
||||||
uint16_t lpc;
|
uint16_t lpc;
|
||||||
int VEM, COL;
|
int VEM, COL;
|
||||||
|
|
||||||
uint32_t AD;
|
|
||||||
uint16_t HSA, HEA;
|
|
||||||
uint16_t VSA, VEA;
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
||||||
select(device_code_read);
|
select(device_code_read);
|
||||||
|
@ -126,7 +145,7 @@ void r61524_test(void)
|
||||||
{
|
{
|
||||||
print(1, 2, "Aborting.");
|
print(1, 2, "Aborting.");
|
||||||
Bdisp_PutDisp_DD();
|
Bdisp_PutDisp_DD();
|
||||||
delay(40);
|
getkey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,22 +169,6 @@ void r61524_test(void)
|
||||||
VEM = (lpc >> 4) & 1;
|
VEM = (lpc >> 4) & 1;
|
||||||
COL = lpc & 1;
|
COL = lpc & 1;
|
||||||
|
|
||||||
/* Shift by 9, not 8, because of horizontal/vertical range inversion */
|
|
||||||
select(ram_address_horizontal);
|
|
||||||
AD = read();
|
|
||||||
select(ram_address_vertical);
|
|
||||||
AD |= read() << 9;
|
|
||||||
|
|
||||||
select(horizontal_ram_start);
|
|
||||||
HSA = read();
|
|
||||||
select(horizontal_ram_end);
|
|
||||||
HEA = read();
|
|
||||||
|
|
||||||
select(vertical_ram_start);
|
|
||||||
VSA = read();
|
|
||||||
select(vertical_ram_end);
|
|
||||||
VEA = read();
|
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
|
||||||
print(15, 4, " SM=?");
|
print(15, 4, " SM=?");
|
||||||
|
@ -194,62 +197,53 @@ void r61524_test(void)
|
||||||
print_hex(12, 6, COL, 1);
|
print_hex(12, 6, COL, 1);
|
||||||
|
|
||||||
Bdisp_PutDisp_DD();
|
Bdisp_PutDisp_DD();
|
||||||
delay(50);
|
getkey();
|
||||||
|
|
||||||
//---
|
/* Bdisp_AllClr_VRAM();
|
||||||
|
print(1, 1, "MSTPCR0=????????");
|
||||||
|
print_hex(9, 1, POWER.MSTPCR0.lword, 8);
|
||||||
|
|
||||||
Bdisp_AllClr_VRAM();
|
print(1, 2, "DMAOR=????");
|
||||||
|
print_hex(7, 2, DMA.OR.word, 4);
|
||||||
|
|
||||||
print(1, 1, "Address=?????");
|
print(1, 3, "SAR=????????");
|
||||||
print_hex(9, 1, AD, 5);
|
print_hex(5, 3, DMA.DMA0.SAR, 8);
|
||||||
|
print(1, 4, "DAR=????????");
|
||||||
print(1, 2, "HSA=??? HEA=???");
|
print_hex(5, 4, DMA.DMA0.DAR, 8);
|
||||||
print_hex(5, 2, HSA, 3);
|
print(1, 5, "TCR=????????");
|
||||||
print_hex(14, 2, HEA, 3);
|
print_hex(5, 5, DMA.DMA0.TCR, 8);
|
||||||
print(1, 3, "VSA=??? VEA=???");
|
print(1, 6, "CHCR=????????");
|
||||||
print_hex(5, 3, VSA, 3);
|
print_hex(6, 6, DMA.DMA0.CHCR, 8);
|
||||||
print_hex(14, 3, VEA, 3);
|
|
||||||
|
|
||||||
Bdisp_PutDisp_DD();
|
Bdisp_PutDisp_DD();
|
||||||
delay(50);
|
getkey(); */
|
||||||
|
}
|
||||||
|
|
||||||
//
|
void r61524_dma_test(uint16_t *vram)
|
||||||
|
{
|
||||||
Bdisp_AllClr_VRAM();
|
int y1 = 0;
|
||||||
Bdisp_PutDisp_DD();
|
int height = 224;
|
||||||
|
|
||||||
//---
|
|
||||||
|
|
||||||
select(horizontal_ram_start);
|
|
||||||
write(0);
|
|
||||||
select(horizontal_ram_end);
|
|
||||||
write(395);
|
|
||||||
|
|
||||||
select(vertical_ram_start);
|
|
||||||
write(0);
|
|
||||||
select(vertical_ram_end);
|
|
||||||
write(223);
|
|
||||||
|
|
||||||
//---
|
|
||||||
|
|
||||||
|
/* Move the window to the desired region, then select address 0 */
|
||||||
|
r61524_win_set(0, 395, y1, y1 + height - 1);
|
||||||
select(ram_address_horizontal);
|
select(ram_address_horizontal);
|
||||||
write(HEA);
|
write(0);
|
||||||
select(ram_address_vertical);
|
select(ram_address_vertical);
|
||||||
write(VSA);
|
write(0);
|
||||||
|
|
||||||
|
/* Bind address 0xb4000000 to the data write command */
|
||||||
select(write_data);
|
select(write_data);
|
||||||
|
|
||||||
uint16_t color;
|
void *src = vram;
|
||||||
for(int v = 0; v < 224; v++)
|
void *dst = (void *)0xb4000000;
|
||||||
for(int h = 0; h < 396; h++)
|
|
||||||
{
|
|
||||||
// int offset = 396 * v + h;
|
|
||||||
// uint8_t *src = gimp_image.pixel_data + 2 * offset;
|
|
||||||
color = 0x3eb7; // (src[1] << 8) | src[0];
|
|
||||||
|
|
||||||
write(color);
|
/* The thing is, 396 is not a multiple of 32.
|
||||||
}
|
To make things simple, we can choose to always send a multiple of 8
|
||||||
|
rows, which makes the 32 factor appear. */
|
||||||
|
int blocks = 198 * (height >> 3);
|
||||||
|
|
||||||
delay(200);
|
dma_transfer(DMA_32B, blocks, src, DMA_INC, dst, DMA_FIXED);
|
||||||
|
dma_transfer_wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
|
@ -269,33 +263,34 @@ GBSS static ctx_t sys_ctx;
|
||||||
static void ctx_save(void *buf)
|
static void ctx_save(void *buf)
|
||||||
{
|
{
|
||||||
ctx_t *ctx = buf;
|
ctx_t *ctx = buf;
|
||||||
|
r61524_win_get(&ctx->HSA, &ctx->HEA, &ctx->VSA, &ctx->VEA);
|
||||||
select(horizontal_ram_start);
|
|
||||||
ctx->HSA = read();
|
|
||||||
select(horizontal_ram_end);
|
|
||||||
ctx->HEA = read();
|
|
||||||
|
|
||||||
select(vertical_ram_start);
|
|
||||||
ctx->VSA = read();
|
|
||||||
select(vertical_ram_end);
|
|
||||||
ctx->VEA = read();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ctx_restore(void *buf)
|
static void ctx_restore(void *buf)
|
||||||
{
|
{
|
||||||
ctx_t *ctx = buf;
|
ctx_t *ctx = buf;
|
||||||
|
r61524_win_set(ctx->HSA, ctx->HEA, ctx->VSA, ctx->VEA);
|
||||||
select(horizontal_ram_start);
|
|
||||||
write(ctx->HSA);
|
|
||||||
select(horizontal_ram_end);
|
|
||||||
write(ctx->HEA);
|
|
||||||
|
|
||||||
select(vertical_ram_start);
|
|
||||||
write(ctx->VSA);
|
|
||||||
select(vertical_ram_end);
|
|
||||||
write(ctx->VEA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Driver status string
|
||||||
|
//---
|
||||||
|
|
||||||
|
#ifdef GINT_BOOT_LOG
|
||||||
|
|
||||||
|
/* r6524_status() - status string */
|
||||||
|
static const char *r6524_status(void)
|
||||||
|
{
|
||||||
|
select(device_code_read);
|
||||||
|
uint16_t dev = read();
|
||||||
|
|
||||||
|
static char str[8];
|
||||||
|
sprintf(str, "%4xF-b", dev);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Driver structure definition
|
// Driver structure definition
|
||||||
//---
|
//---
|
||||||
|
@ -303,6 +298,7 @@ static void ctx_restore(void *buf)
|
||||||
gint_driver_t drv_r61524 = {
|
gint_driver_t drv_r61524 = {
|
||||||
.name = "R61524",
|
.name = "R61524",
|
||||||
.init = NULL,
|
.init = NULL,
|
||||||
|
.status = GINT_DRIVER_STATUS(r6524_status),
|
||||||
.ctx_size = sizeof(ctx_t),
|
.ctx_size = sizeof(ctx_t),
|
||||||
.sys_ctx = &sys_ctx,
|
.sys_ctx = &sys_ctx,
|
||||||
.ctx_save = ctx_save,
|
.ctx_save = ctx_save,
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
** stop if the callback returns non-zero.
|
** stop if the callback returns non-zero.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.global _inth_rtc_pri
|
.global _inth_rtc_pri
|
||||||
.global _inth_rtc_pri_helper
|
.global _inth_rtc_pri_helper
|
||||||
.section .gint.blocks, "ax"
|
.section .gint.blocks, "ax"
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
/* RTC PERIODIC INTERRUPT HANDLER - 56 BYTES */
|
/* RTC PERIODIC INTERRUPT HANDLER - 56 BYTES */
|
||||||
|
|
||||||
|
|
|
@ -5,19 +5,19 @@
|
||||||
** from each interrupt handler to the next.
|
** from each interrupt handler to the next.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Gates for the standard Timer Unit (TMU) */
|
/* Gates for the standard Timer Unit (TMU) */
|
||||||
.global _inth_tmu_0
|
.global _inth_tmu_0
|
||||||
.global _inth_tmu_1
|
.global _inth_tmu_1
|
||||||
.global _inth_tmu_2
|
.global _inth_tmu_2
|
||||||
.global _inth_tmu_storage
|
.global _inth_tmu_storage
|
||||||
|
|
||||||
/* Gates for the extra timers (informally called ETMU) */
|
/* Gates for the extra timers (informally called ETMU) */
|
||||||
.global _inth_tmu_extra2
|
.global _inth_tmu_extra2
|
||||||
.global _inth_tmu_extra_help
|
.global _inth_tmu_extra_help
|
||||||
.global _inth_tmu_extra_others
|
.global _inth_tmu_extra_others
|
||||||
|
|
||||||
.section .gint.blocks, "ax"
|
.section .gint.blocks, "ax"
|
||||||
.align 4
|
.align 4
|
||||||
|
|
||||||
/* TMU INTERRUPT HANDLERS - 128 BYTES
|
/* TMU INTERRUPT HANDLERS - 128 BYTES
|
||||||
Unfortunately I did not manage to write a handler that cleared the interrupt
|
Unfortunately I did not manage to write a handler that cleared the interrupt
|
||||||
|
|
Loading…
Reference in a new issue