Skip to content

Commit 59ce41f

Browse files
authored
Merge pull request #8049 from OpenNuvoton/nuvoton_fix_hal_sleep
Nuvoton: Fix mbed_hal-sleep test failed
2 parents 3b17888 + a65e3d4 commit 59ce41f

File tree

21 files changed

+1237
-849
lines changed

21 files changed

+1237
-849
lines changed

targets/TARGET_NUVOTON/TARGET_M2351/TARGET_NUMAKER_PFM_M2351/TARGET_M23_NS/NuMaker-mbed-TZ-secure-example.hex

Lines changed: 862 additions & 786 deletions
Large diffs are not rendered by default.

targets/TARGET_NUVOTON/TARGET_M2351/device/stddriver_secure.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,18 @@ void SYS_UnlockReg_S(void)
197197
SYS_UnlockReg();
198198
}
199199

200+
__NONSECURE_ENTRY
201+
void CLK_Idle_S(void)
202+
{
203+
CLK_Idle();
204+
}
205+
206+
__NONSECURE_ENTRY
207+
void CLK_PowerDown_S(void)
208+
{
209+
CLK_PowerDown();
210+
}
211+
200212
static bool check_mod_ns(int modclass, uint32_t modidx)
201213
{
202214
const nu_modidx_ns_t *modidx_ns = modidx_ns_tab;

targets/TARGET_NUVOTON/TARGET_M2351/device/stddriver_secure.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@ void SYS_LockReg_S(void);
7171
__NONSECURE_ENTRY
7272
void SYS_UnlockReg_S(void);
7373

74+
/* Secure CLK_Idle */
75+
__NONSECURE_ENTRY
76+
void CLK_Idle_S(void);
77+
78+
/* Secure CLK_PowerDown */
79+
__NONSECURE_ENTRY
80+
void CLK_PowerDown_S(void);
81+
7482
#ifdef __cplusplus
7583
}
7684
#endif

targets/TARGET_NUVOTON/TARGET_M2351/lp_ticker.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
#if DEVICE_LPTICKER
2020

2121
#include "sleep_api.h"
22-
#include "mbed_wait_api.h"
2322
#include "mbed_assert.h"
2423
#include "nu_modutil.h"
24+
#include "nu_timer.h"
2525
#include "nu_miscutil.h"
2626
#include "partition_M2351.h"
2727

@@ -135,24 +135,24 @@ void lp_ticker_init(void)
135135
// Continuous mode
136136
// NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451/M480/M2351. In M451/M480/M2351, TIMER_CNT is updated continuously by default.
137137
timer_base->CTL = TIMER_CONTINUOUS_MODE | prescale_timer/* | TIMER_CTL_CNTDATEN_Msk*/;
138-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
138+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
139139

140140
timer_base->CMP = cmp_timer;
141-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
141+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
142142

143143
// Set vector
144144
NVIC_SetVector(TIMER_MODINIT.irq_n, (uint32_t) TIMER_MODINIT.var);
145145

146146
NVIC_DisableIRQ(TIMER_MODINIT.irq_n);
147147

148148
TIMER_EnableInt(timer_base);
149-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
149+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
150150

151151
TIMER_EnableWakeup(timer_base);
152-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
152+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
153153

154154
TIMER_Start(timer_base);
155-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
155+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
156156

157157
/* Wait for timer to start counting and raise active flag */
158158
while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk));

targets/TARGET_NUVOTON/TARGET_M2351/serial_api.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "nu_modutil.h"
2626
#include "nu_bitutil.h"
2727
#include <string.h>
28+
#include <stdbool.h>
2829

2930
#if DEVICE_SERIAL_ASYNCH
3031
#include "dma_api.h"
@@ -87,6 +88,8 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch);
8788
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
8889
#endif
8990

91+
bool serial_can_deep_sleep(void);
92+
9093
static struct nu_uart_var uart0_var = {
9194
.ref_cnt = 0,
9295
.obj = NULL,
@@ -1171,4 +1174,23 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
11711174
}
11721175

11731176
#endif // #if DEVICE_SERIAL_ASYNCH
1177+
1178+
bool serial_can_deep_sleep(void)
1179+
{
1180+
bool sleep_allowed = 1;
1181+
const struct nu_modinit_s *modinit = uart_modinit_tab;
1182+
while (modinit->var != NULL) {
1183+
struct nu_uart_var *uart_var = (struct nu_uart_var *) modinit->var;
1184+
UART_T *uart_base = (UART_T *) NU_MODBASE(modinit->modname);
1185+
if (uart_var->ref_cnt > 0) {
1186+
if (!UART_IS_TX_EMPTY(uart_base)) {
1187+
sleep_allowed = 0;
1188+
break;
1189+
}
1190+
}
1191+
modinit++;
1192+
}
1193+
return sleep_allowed;
1194+
}
1195+
11741196
#endif // #if DEVICE_SERIAL

targets/TARGET_NUVOTON/TARGET_M2351/sleep.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,30 +22,48 @@
2222
#include "device.h"
2323
#include "objects.h"
2424
#include "PeripheralPins.h"
25+
#include <stdbool.h>
2526

26-
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
27+
#if DEVICE_SERIAL
28+
bool serial_can_deep_sleep(void);
29+
#endif
2730

2831
/**
2932
* Enter idle mode, in which just CPU is halted.
3033
*/
31-
__NONSECURE_ENTRY
3234
void hal_sleep(void)
3335
{
36+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
3437
SYS_UnlockReg();
3538
CLK_Idle();
3639
SYS_LockReg();
40+
#else
41+
SYS_UnlockReg_S();
42+
CLK_Idle_S();
43+
SYS_LockReg_S();
44+
#endif
3745
}
3846

3947
/**
4048
* Enter power-down mode, in which HXT/HIRC are halted.
4149
*/
42-
__NONSECURE_ENTRY
4350
void hal_deepsleep(void)
4451
{
52+
#if DEVICE_SERIAL
53+
if (!serial_can_deep_sleep()) {
54+
return;
55+
}
56+
#endif
57+
58+
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
4559
SYS_UnlockReg();
4660
CLK_PowerDown();
4761
SYS_LockReg();
62+
#else
63+
SYS_UnlockReg_S();
64+
CLK_PowerDown_S();
65+
SYS_LockReg_S();
66+
#endif
4867
}
4968

5069
#endif
51-
#endif

targets/TARGET_NUVOTON/TARGET_M451/lp_ticker.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
#if DEVICE_LPTICKER
2020

2121
#include "sleep_api.h"
22-
#include "mbed_wait_api.h"
2322
#include "mbed_assert.h"
2423
#include "nu_modutil.h"
24+
#include "nu_timer.h"
2525
#include "nu_miscutil.h"
2626

2727
/* Micro seconds per second */
@@ -101,24 +101,24 @@ void lp_ticker_init(void)
101101
// Continuous mode
102102
// NOTE: TIMER_CTL_CNTDATEN_Msk exists in NUC472, but not in M451. In M451, TIMER_CNT is updated continuously by default.
103103
timer_base->CTL = TIMER_CONTINUOUS_MODE | prescale_timer/* | TIMER_CTL_CNTDATEN_Msk*/;
104-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
104+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
105105

106106
timer_base->CMP = cmp_timer;
107-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
107+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
108108

109109
// Set vector
110110
NVIC_SetVector(TIMER_MODINIT.irq_n, (uint32_t) TIMER_MODINIT.var);
111111

112112
NVIC_DisableIRQ(TIMER_MODINIT.irq_n);
113113

114114
TIMER_EnableInt(timer_base);
115-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
115+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
116116

117117
TIMER_EnableWakeup(timer_base);
118-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
118+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
119119

120120
TIMER_Start(timer_base);
121-
wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
121+
nu_busy_wait_us((NU_US_PER_SEC / NU_TMRCLK_PER_SEC) * 3);
122122

123123
/* Wait for timer to start counting and raise active flag */
124124
while(! (timer_base->CTL & TIMER_CTL_ACTSTS_Msk));

targets/TARGET_NUVOTON/TARGET_M451/serial_api.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "nu_modutil.h"
2626
#include "nu_bitutil.h"
2727
#include <string.h>
28+
#include <stdbool.h>
2829

2930
#if DEVICE_SERIAL_ASYNCH
3031
#include "dma_api.h"
@@ -83,6 +84,8 @@ static void serial_check_dma_usage(DMAUsage *dma_usage, int *dma_ch);
8384
static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
8485
#endif
8586

87+
bool serial_can_deep_sleep(void);
88+
8689
static struct nu_uart_var uart0_var = {
8790
.ref_cnt = 0,
8891
.obj = NULL,
@@ -1088,4 +1091,23 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq)
10881091
}
10891092

10901093
#endif // #if DEVICE_SERIAL_ASYNCH
1094+
1095+
bool serial_can_deep_sleep(void)
1096+
{
1097+
bool sleep_allowed = 1;
1098+
const struct nu_modinit_s *modinit = uart_modinit_tab;
1099+
while (modinit->var != NULL) {
1100+
struct nu_uart_var *uart_var = (struct nu_uart_var *) modinit->var;
1101+
UART_T *uart_base = (UART_T *) NU_MODBASE(modinit->modname);
1102+
if (uart_var->ref_cnt > 0) {
1103+
if (!UART_IS_TX_EMPTY(uart_base)) {
1104+
sleep_allowed = 0;
1105+
break;
1106+
}
1107+
}
1108+
modinit++;
1109+
}
1110+
return sleep_allowed;
1111+
}
1112+
10911113
#endif // #if DEVICE_SERIAL

targets/TARGET_NUVOTON/TARGET_M451/sleep.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@
2222
#include "device.h"
2323
#include "objects.h"
2424
#include "PeripheralPins.h"
25+
#include <stdbool.h>
26+
27+
#if DEVICE_SERIAL
28+
bool serial_can_deep_sleep(void);
29+
#endif
2530

2631
/**
2732
* Enter idle mode, in which just CPU is halted.
@@ -38,6 +43,12 @@ void hal_sleep(void)
3843
*/
3944
void hal_deepsleep(void)
4045
{
46+
#if DEVICE_SERIAL
47+
if (!serial_can_deep_sleep()) {
48+
return;
49+
}
50+
#endif
51+
4152
SYS_UnlockReg();
4253
CLK_PowerDown();
4354
SYS_LockReg();

0 commit comments

Comments
 (0)