The watchdog timer on the chip used in the prizm's should use the following two addresses
0xa4520000 - WTCNT
0xa4520004 - WTCSR
It works basically as described in the hardware manual for SH7730.
In order to use the watchdog timer it might also be necessary to clear bit 13 on the MSTPCR0(0xa4150030) register, otherwise the RCLK signal won't be passed to the WDT.
The custom chip used is in fact based of the SH7724 which is part of renesas's shmobile line of chips. The basis for this conclusion is the fact that the PVR register which specifies the processor core version is an exact match with the SH7724 in addition many of the IO modules also match up with the SH7724, including the FRQCR register which is located at 0xa4150000 and has the following structure.
31: Kick
Writing 1 here updates CPG settings
29-24: PLL
Multiplier = (PLL + 1) * 2
23-20: I_CLK
CPU Clock Divisor
15-12: SH_CLK
SuperHighway Clock Divisor
11-8: B_CLK
Bus Clock Divisor
3-0: P_CLK
Peripheral Clock Divisor
Divisor values:
0000 x1/2
0001 x1/3
0010 x1/4
0011 x1/6
0100 x1/8
0101 x1/12
0110 x1/16
1000 x1/24
1001 x1/32
1010 x1/36
1011 x1/48
1101 x1/72
The Kick bit has to have a 1 written to it before the CPU will update any changes done to the FRQCR register. All the information on the layout of the FRQCR came from the linux kernel since there is no datasheet available for the SH7724 without signing an NDA with renesas.
Also I should mention is not necessary to run from physical memory in order to access hardware registers on this chip. Since address translation only effects access to addresses in the P0 and P3 memory regions and all CPU/IO registers are in the P2 or P4 regions you can access them just fine while running from virtual memory.
Below is a set of assembly routines I wrote that can be assembled using a GCC toolchain and then called from C code that allows you to use the WDT as well as set adjust the clock.
Code:
0xa4520000 - WTCNT
0xa4520004 - WTCSR
It works basically as described in the hardware manual for SH7730.
In order to use the watchdog timer it might also be necessary to clear bit 13 on the MSTPCR0(0xa4150030) register, otherwise the RCLK signal won't be passed to the WDT.
The custom chip used is in fact based of the SH7724 which is part of renesas's shmobile line of chips. The basis for this conclusion is the fact that the PVR register which specifies the processor core version is an exact match with the SH7724 in addition many of the IO modules also match up with the SH7724, including the FRQCR register which is located at 0xa4150000 and has the following structure.
31: Kick
Writing 1 here updates CPG settings
29-24: PLL
Multiplier = (PLL + 1) * 2
23-20: I_CLK
CPU Clock Divisor
15-12: SH_CLK
SuperHighway Clock Divisor
11-8: B_CLK
Bus Clock Divisor
3-0: P_CLK
Peripheral Clock Divisor
Divisor values:
0000 x1/2
0001 x1/3
0010 x1/4
0011 x1/6
0100 x1/8
0101 x1/12
0110 x1/16
1000 x1/24
1001 x1/32
1010 x1/36
1011 x1/48
1101 x1/72
The Kick bit has to have a 1 written to it before the CPU will update any changes done to the FRQCR register. All the information on the layout of the FRQCR came from the linux kernel since there is no datasheet available for the SH7724 without signing an NDA with renesas.
Also I should mention is not necessary to run from physical memory in order to access hardware registers on this chip. Since address translation only effects access to addresses in the P0 and P3 memory regions and all CPU/IO registers are in the P2 or P4 regions you can access them just fine while running from virtual memory.
Below is a set of assembly routines I wrote that can be assembled using a GCC toolchain and then called from C code that allows you to use the WDT as well as set adjust the clock.
Code:
.global _disable_wdt, _enable_wdt, _set_wtcnt, _disable_mstpcr, _enable_mstpcr
.global _set_pll_mult, _frqcr_kick, _set_iclk_div, _set_shclk_div, _set_bclk_div, _set_pclk_div
/*
* SH7724 Watchdog timer and clock setting code
* By Brian Johnson
*/
/*
* FRQCR
* 31: Kick
* Writing 1 here updates CPG settings
* 29-24: PLL
* Multiplier = (PLL + 1) * 2
* 23-20: I_CLK
* CPU Clock Divisor
* 15-12: SH_CLK
* SuperHighway Clock Divisor
* 11-8: B_CLK
* Bus Clock Divisor
* 3-0: P_CLK
* Peripheral Clock Divisor
*
* Divisor values:
* 0000 x1/2
* 0001 x1/3
* 0010 x1/4
* 0011 x1/6
* 0100 x1/8
* 0101 x1/12
* 0110 x1/16
* 1000 x1/24
* 1001 x1/32
* 1010 x1/36
* 1011 x1/48
* 1101 x1/72
*
* Updates to the FRQCR do not go into effect until 1 is written to the kick bit.
*---------------------------------------------------------------------------------
*
* Before using the watchdog timer it migt be necessary to call enable_mtspcr(0, 13),
* this will enable the RCLK signal to the WDT.
*/
/* void frqcr_kick() */
_frqcr_kick:
mov.l frqcr, r1
mov #0x80, r0
shll16 r0
shll8 r0
mov.l @r1, r2
or r0, r2
mov.l r2, @r1
rts
nop
/* void set_pclk_div(int divisor) */
_set_pclk_div:
mov r4, r0
and #0xF, r0
mov.l frqcr, r1
mov.l pclk_mask, r3
mov.l @r1, r2
and r3, r2
or r0, r2
mov.l r2, @r1
rts
nop
/* void set_bclk_div(int divisor) */
_set_bclk_div:
mov r4, r0
and #0xF, r0
shll8 r0
mov.l frqcr, r1
mov.l bclk_mask, r3
mov.l @r1, r2
and r3, r2
or r0, r2
mov.l r2, @r1
rts
nop
/* void set_shclk_div(int divisor) */
_set_shclk_div:
mov r4, r0
and #0xF, r0
shll8 r0
shll2 r0
shll2 r0
mov.l frqcr, r1
mov.l shclk_mask, r3
mov.l @r1, r2
and r3, r2
or r0, r2
mov.l r2, @r1
rts
nop
/* void set_iclk_div(int divisor) */
_set_iclk_div:
mov r4, r0
and #0xF, r0
shll16 r0
shll2 r0
shll2 r0
mov.l frqcr, r1
mov.l iclk_mask, r3
mov.l @r1, r2
and r3, r2
or r0, r2
mov.l r2, @r1
rts
nop
/* void set_pll_mult(int multiplier) */
_set_pll_mult:
mov r4, r0
and #0x3F, r0
shll16 r0
shll8 r0
mov.l frqcr, r1
mov.l pll_mask, r3
mov.l @r1, r2
and r3, r2
or r0, r2
mov.l r2, @r1
rts
nop
.align 2
frqcr:
.long 0xa4150000
pll_mask:
.long 0xC0FFFFFF
iclk_mask:
.long 0xFF0FFFFF
shclk_mask:
.long 0xFFFF0FFF
bclk_mask:
.long 0xFFFFF0FF
pclk_mask:
.long 0xFFFFFFF0
/* void disable_mstpcr(int nr, int bit) */
_disable_mstpcr:
extu.b r5, r5
mov r4, r0
and #3, r0
shll2 r0
mov.l mstpcr, r1
mov.l @(r0,r1), r2
mov #1, r3
shld r5, r3
or r3, r2
mov.l r2, @(r0,r1)
rts
nop
/* void enable_mstpcr(int nr, int bit) */
_enable_mstpcr:
extu.b r5, r5
mov r4, r0
and #3, r0
shll2 r0
mov.l mstpcr, r1
mov.l @(r0,r1), r2
mov #1, r3
shld r5, r3
not r3, r3
and r3, r2
mov.l r2, @(r0,r1)
rts
nop
.align 2
mstpcr:
.long 0xa4150030
/* void set_wtcnt(char val) */
_set_wtcnt:
extu.b r4,r4
mov.l wtcnt, r1
mov #0x5a, r2
shll8 r2
or r2, r4
mov.w r4, @r1
rts
nop
wtcnt:
.long 0xa4520000
/* void disable_wdt() */
_disable_wdt:
mov.l wtcsr, r1
mov #0xa5, r4
shll8 r4
mov.w r4, @r1
rts
nop
/* void enable_wdt(int timer) */
_enable_wdt:
mov.l wtcsr, r1
mov r4, r0
and #7, r0
or #0x80, r0
mov #0xa5, r4
shll8 r4
or r4, r0
mov.w r0, @r1
rts
nop
wtcsr:
.long 0xa4520004