Skip to content

Commit 3ca5c36

Browse files
authored
Merge pull request #4241 from OpenNuvoton/nuvoton
[NUC472/M453] Fix serial error with sync/async calls interlaced
2 parents 07c8b21 + 08c778d commit 3ca5c36

File tree

8 files changed

+240
-198
lines changed

8 files changed

+240
-198
lines changed

targets/TARGET_NUVOTON/TARGET_M451/TARGET_NUMAKER_PFM_M453/objects.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ struct serial_s {
6161
void (*vec)(void);
6262
uint32_t irq_handler;
6363
uint32_t irq_id;
64+
uint32_t irq_en;
6465
uint32_t inten_msk;
6566

6667
// Async transfer related fields

targets/TARGET_NUVOTON/TARGET_M451/dma_api.c

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#include "nu_bitutil.h"
2424
#include "dma.h"
2525

26+
#define NU_PDMA_CH_MAX PDMA_CH_MAX /* Specify maximum channels of PDMA */
27+
#define NU_PDMA_CH_Pos 0 /* Specify first channel number of PDMA */
28+
#define NU_PDMA_CH_Msk (((1 << NU_PDMA_CH_MAX) - 1) << NU_PDMA_CH_Pos)
29+
2630
struct nu_dma_chn_s {
2731
void (*handler)(uint32_t, uint32_t);
2832
uint32_t id;
@@ -31,7 +35,7 @@ struct nu_dma_chn_s {
3135

3236
static int dma_inited = 0;
3337
static uint32_t dma_chn_mask = 0;
34-
static struct nu_dma_chn_s dma_chn_arr[PDMA_CH_MAX];
38+
static struct nu_dma_chn_s dma_chn_arr[NU_PDMA_CH_MAX];
3539

3640
static void pdma_vec(void);
3741
static const struct nu_modinit_s dma_modinit = {DMA_0, PDMA_MODULE, 0, 0, PDMA_RST, PDMA_IRQn, (void *) pdma_vec};
@@ -44,7 +48,7 @@ void dma_init(void)
4448
}
4549

4650
dma_inited = 1;
47-
dma_chn_mask = 0;
51+
dma_chn_mask = ~NU_PDMA_CH_Msk;
4852
memset(dma_chn_arr, 0x00, sizeof (dma_chn_arr));
4953

5054
// Reset this module
@@ -65,25 +69,12 @@ int dma_channel_allocate(uint32_t capabilities)
6569
dma_init();
6670
}
6771

68-
#if 1
6972
int i = nu_cto(dma_chn_mask);
7073
if (i != 32) {
7174
dma_chn_mask |= 1 << i;
72-
memset(dma_chn_arr + i, 0x00, sizeof (struct nu_dma_chn_s));
75+
memset(dma_chn_arr + i - NU_PDMA_CH_Pos, 0x00, sizeof (struct nu_dma_chn_s));
7376
return i;
7477
}
75-
#else
76-
int i;
77-
78-
for (i = 0; i < PDMA_CH_MAX; i ++) {
79-
if ((dma_chn_mask & (1 << i)) == 0) {
80-
// Channel available
81-
dma_chn_mask |= 1 << i;
82-
memset(dma_chn_arr + i, 0x00, sizeof (struct nu_dma_chn_s));
83-
return i;
84-
}
85-
}
86-
#endif
8778

8879
// No channel available
8980
return DMA_ERROR_OUT_OF_CHANNELS;
@@ -102,9 +93,9 @@ void dma_set_handler(int channelid, uint32_t handler, uint32_t id, uint32_t even
10293
{
10394
MBED_ASSERT(dma_chn_mask & (1 << channelid));
10495

105-
dma_chn_arr[channelid].handler = (void (*)(uint32_t, uint32_t)) handler;
106-
dma_chn_arr[channelid].id = id;
107-
dma_chn_arr[channelid].event = event;
96+
dma_chn_arr[channelid - NU_PDMA_CH_Pos].handler = (void (*)(uint32_t, uint32_t)) handler;
97+
dma_chn_arr[channelid - NU_PDMA_CH_Pos].id = id;
98+
dma_chn_arr[channelid - NU_PDMA_CH_Pos].event = event;
10899

109100
// Set interrupt vector if someone has removed it.
110101
NVIC_SetVector(dma_modinit.irq_n, (uint32_t) dma_modinit.var);
@@ -127,14 +118,14 @@ static void pdma_vec(void)
127118
PDMA_CLR_ABORT_FLAG(abtsts);
128119

129120
while (abtsts) {
130-
int chn_id = nu_ctz(abtsts);
121+
int chn_id = nu_ctz(abtsts) - PDMA_ABTSTS_ABTIFn_Pos + NU_PDMA_CH_Pos;
131122
if (dma_chn_mask & (1 << chn_id)) {
132-
struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id;
123+
struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id - NU_PDMA_CH_Pos;
133124
if (dma_chn->handler && (dma_chn->event & DMA_EVENT_ABORT)) {
134125
dma_chn->handler(dma_chn->id, DMA_EVENT_ABORT);
135126
}
136127
}
137-
abtsts &= ~(1 << chn_id);
128+
abtsts &= ~(1 << (chn_id - NU_PDMA_CH_Pos + PDMA_ABTSTS_ABTIFn_Pos));
138129
}
139130
}
140131

@@ -145,14 +136,14 @@ static void pdma_vec(void)
145136
PDMA_CLR_TD_FLAG(tdsts);
146137

147138
while (tdsts) {
148-
int chn_id = nu_ctz(tdsts);
139+
int chn_id = nu_ctz(tdsts) - PDMA_TDSTS_TDIFn_Pos + NU_PDMA_CH_Pos;
149140
if (dma_chn_mask & (1 << chn_id)) {
150-
struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id;
141+
struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id - NU_PDMA_CH_Pos;
151142
if (dma_chn->handler && (dma_chn->event & DMA_EVENT_TRANSFER_DONE)) {
152143
dma_chn->handler(dma_chn->id, DMA_EVENT_TRANSFER_DONE);
153144
}
154145
}
155-
tdsts &= ~(1 << chn_id);
146+
tdsts &= ~(1 << (chn_id - NU_PDMA_CH_Pos + PDMA_TDSTS_TDIFn_Pos));
156147
}
157148
}
158149

@@ -170,14 +161,14 @@ static void pdma_vec(void)
170161
PDMA->INTSTS = reqto;
171162

172163
while (reqto) {
173-
int chn_id = nu_ctz(reqto) - PDMA_INTSTS_REQTOFn_Pos;
164+
int chn_id = nu_ctz(reqto) - PDMA_INTSTS_REQTOFn_Pos + NU_PDMA_CH_Pos;
174165
if (dma_chn_mask & (1 << chn_id)) {
175-
struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id;
166+
struct nu_dma_chn_s *dma_chn = dma_chn_arr + chn_id - NU_PDMA_CH_Pos;
176167
if (dma_chn->handler && (dma_chn->event & DMA_EVENT_TIMEOUT)) {
177168
dma_chn->handler(dma_chn->id, DMA_EVENT_TIMEOUT);
178169
}
179170
}
180-
reqto &= ~(1 << (chn_id + PDMA_INTSTS_REQTOFn_Pos));
171+
reqto &= ~(1 << (chn_id - NU_PDMA_CH_Pos + PDMA_INTSTS_REQTOFn_Pos));
181172
}
182173
}
183174
}

targets/TARGET_NUVOTON/TARGET_M451/pwmout_api.c

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,9 @@ void pwmout_init(pwmout_t* obj, PinName pin)
9999

100100
((struct nu_pwm_var *) modinit->var)->en_msk |= 1 << chn;
101101

102-
if (((struct nu_pwm_var *) modinit->var)->en_msk) {
103-
// Mark this module to be inited.
104-
int i = modinit - pwm_modinit_tab;
105-
pwm_modinit_mask |= 1 << i;
106-
}
102+
// Mark this module to be inited.
103+
int i = modinit - pwm_modinit_tab;
104+
pwm_modinit_mask |= 1 << i;
107105
}
108106

109107
void pwmout_free(pwmout_t* obj)
@@ -122,11 +120,9 @@ void pwmout_free(pwmout_t* obj)
122120
CLK_DisableModuleClock(modinit->clkidx);
123121
}
124122

125-
if (((struct nu_pwm_var *) modinit->var)->en_msk == 0) {
126-
// Mark this module to be deinited.
127-
int i = modinit - pwm_modinit_tab;
128-
pwm_modinit_mask &= ~(1 << i);
129-
}
123+
// Mark this module to be deinited.
124+
int i = modinit - pwm_modinit_tab;
125+
pwm_modinit_mask &= ~(1 << i);
130126
}
131127

132128
void pwmout_write(pwmout_t* obj, float value)

0 commit comments

Comments
 (0)