Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NUC472/M453] Support single UART shared by multiple serial objects and other updates #3211

Merged
merged 4 commits into from
Nov 10, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,47 +17,8 @@
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H

#define DEVICE_PORTIN 1
#define DEVICE_PORTOUT 1
#define DEVICE_PORTINOUT 1

#define DEVICE_INTERRUPTIN 1

#define DEVICE_ANALOGIN 1
#define DEVICE_ANALOGOUT 0

#define DEVICE_SERIAL 1
#define DEVICE_SERIAL_FC 1
#define DEVICE_SERIAL_ASYNCH 1

#define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 1
#define DEVICE_I2C_ASYNCH 1

#define DEVICE_SPI 1
#define DEVICE_SPI_ASYNCH 1
#define DEVICE_SPISLAVE 1

#define DEVICE_RTC 1

#define DEVICE_ETHERNET 0

#define DEVICE_PWMOUT 1

#define DEVICE_SEMIHOST 0
#define DEVICE_LOCALFILESYSTEM 0
#define DEVICE_ID_LENGTH 24

#define DEVICE_SLEEP 1

#define DEVICE_DEBUG_AWARENESS 0

#define DEVICE_STDIO_MESSAGES 1

#define DEVICE_ERROR_RED 0

#define DEVICE_LOWPOWERTIMER 1

#include "objects.h"

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ LR_IROM1 0x00000000 {
; uvisor-lib.a (+RW +ZI)
;}

ARM_LIB_STACK 0x20000000 EMPTY 0x1000 {
ARM_LIB_STACK 0x20000000 EMPTY 0x800 {
}

ER_IRAMVEC 0x20001000 EMPTY (4*(16 + 64)) { ; Reserve for vectors
ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 64)) { ; Reserve for vectors
}

RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ LR_IROM1 0x00000000 {
; uvisor-lib.a (+RW +ZI)
;}

ARM_LIB_STACK 0x20000000 EMPTY 0x1000 {
ARM_LIB_STACK 0x20000000 EMPTY 0x800 {
}

ER_IRAMVEC 0x20001000 EMPTY (4*(16 + 64)) { ; Reserve for vectors
ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 64)) { ; Reserve for vectors
}

RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* Nuvoton M453 GCC linker script file
*/

StackSize = 0x1000;
StackSize = 0x800;

MEMORY
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ define symbol __ICFEDIT_region_ROM_end__ = 0x00040000;
define symbol __ICFEDIT_region_IRAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_IRAM_end__ = 0x20008000;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x1000;
define symbol __ICFEDIT_size_cstack__ = 0x800;
define symbol __ICFEDIT_size_heap__ = 0x4000;
/**** End of ICF editor section. ###ICF###*/

Expand Down
124 changes: 71 additions & 53 deletions targets/TARGET_NUVOTON/TARGET_M451/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#endif

struct nu_uart_var {
uint32_t ref_cnt; // Reference count of the H/W module
serial_t * obj;
uint32_t fifo_size_tx;
uint32_t fifo_size_rx;
Expand Down Expand Up @@ -80,6 +81,7 @@ static int serial_is_irq_en(serial_t *obj, SerialIrq irq);
#endif

static struct nu_uart_var uart0_var = {
.ref_cnt = 0,
.obj = NULL,
.fifo_size_tx = 16,
.fifo_size_rx = 16,
Expand All @@ -91,6 +93,7 @@ static struct nu_uart_var uart0_var = {
#endif
};
static struct nu_uart_var uart1_var = {
.ref_cnt = 0,
.obj = NULL,
.fifo_size_tx = 16,
.fifo_size_rx = 16,
Expand All @@ -102,6 +105,7 @@ static struct nu_uart_var uart1_var = {
#endif
};
static struct nu_uart_var uart2_var = {
.ref_cnt = 0,
.obj = NULL,
.fifo_size_tx = 16,
.fifo_size_rx = 16,
Expand All @@ -113,6 +117,7 @@ static struct nu_uart_var uart2_var = {
#endif
};
static struct nu_uart_var uart3_var = {
.ref_cnt = 0,
.obj = NULL,
.fifo_size_tx = 16,
.fifo_size_rx = 16,
Expand Down Expand Up @@ -142,7 +147,7 @@ extern void mbed_sdk_init(void);

void serial_init(serial_t *obj, PinName tx, PinName rx)
{
// NOTE: serial_init() gets called from _sys_open() timing of which is before main()/mbed_hal_init().
// NOTE: With armcc, serial_init() gets called from _sys_open() timing of which is before main()/mbed_sdk_init().
mbed_sdk_init();

// Determine which UART_x the pins are used for
Expand All @@ -156,32 +161,31 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->serial.uart);

// Reset this module
SYS_ResetModule(modinit->rsetidx);
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;

// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);
if (! var->ref_cnt) {
// Reset this module
SYS_ResetModule(modinit->rsetidx);

// Select IP clock source
CLK_SetModuleClock(modinit->clkidx, modinit->clksrc, modinit->clkdiv);
// Enable IP clock
CLK_EnableModuleClock(modinit->clkidx);

pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);
// FIXME: Why PullUp?
//if (tx != NC) {
// pin_mode(tx, PullUp);
//}
//if (rx != NC) {
// pin_mode(rx, PullUp);
//}
obj->serial.pin_tx = tx;
obj->serial.pin_rx = rx;
pinmap_pinout(tx, PinMap_UART_TX);
pinmap_pinout(rx, PinMap_UART_RX);

obj->serial.pin_tx = tx;
obj->serial.pin_rx = rx;
}
var->ref_cnt ++;

// Configure the UART module and set its baudrate
serial_baud(obj, 9600);
// Configure data bits, parity, and stop bits
serial_format(obj, 8, ParityNone, 1);

obj->serial.vec = ((struct nu_uart_var *) modinit->var)->vec;
obj->serial.vec = var->vec;

#if DEVICE_SERIAL_ASYNCH
obj->serial.dma_usage_tx = DMA_USAGE_NEVER;
Expand All @@ -192,51 +196,61 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
#endif

// For stdio management
if (obj == &stdio_uart) {
if (obj->serial.uart == STDIO_UART) {
stdio_uart_inited = 1;
/* NOTE: Not required anymore because stdio_uart will be manually initialized in mbed-drivers/source/retarget.cpp from mbed beta */
//memcpy(&stdio_uart, obj, sizeof(serial_t));
memcpy(&stdio_uart, obj, sizeof(serial_t));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what has changed that is now uncommented?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@0xc0170 That was to meet mbed OS 3.0. Now I change it back to meet mbed OS 2.0/5.0.

}

// Mark this module to be inited.
int i = modinit - uart_modinit_tab;
uart_modinit_mask |= 1 << i;
if (var->ref_cnt) {
// Mark this module to be inited.
int i = modinit - uart_modinit_tab;
uart_modinit_mask |= 1 << i;
}
}

void serial_free(serial_t *obj)
{
#if DEVICE_SERIAL_ASYNCH
if (obj->serial.dma_chn_id_tx != DMA_ERROR_OUT_OF_CHANNELS) {
dma_channel_free(obj->serial.dma_chn_id_tx);
obj->serial.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS;
}
if (obj->serial.dma_chn_id_rx != DMA_ERROR_OUT_OF_CHANNELS) {
dma_channel_free(obj->serial.dma_chn_id_rx);
obj->serial.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS;
}
#endif

UART_Close((UART_T *) NU_MODBASE(obj->serial.uart));

const struct nu_modinit_s *modinit = get_modinit(obj->serial.uart, uart_modinit_tab);
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->serial.uart);

UART_DISABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk | UART_INTEN_RXTOIEN_Msk));
NVIC_DisableIRQ(modinit->irq_n);
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;

// Disable IP clock
CLK_DisableModuleClock(modinit->clkidx);
var->ref_cnt --;
if (! var->ref_cnt) {
#if DEVICE_SERIAL_ASYNCH
if (obj->serial.dma_chn_id_tx != DMA_ERROR_OUT_OF_CHANNELS) {
dma_channel_free(obj->serial.dma_chn_id_tx);
obj->serial.dma_chn_id_tx = DMA_ERROR_OUT_OF_CHANNELS;
}
if (obj->serial.dma_chn_id_rx != DMA_ERROR_OUT_OF_CHANNELS) {
dma_channel_free(obj->serial.dma_chn_id_rx);
obj->serial.dma_chn_id_rx = DMA_ERROR_OUT_OF_CHANNELS;
}
#endif

UART_Close((UART_T *) NU_MODBASE(obj->serial.uart));

((struct nu_uart_var *) modinit->var)->obj = NULL;
UART_DISABLE_INT(((UART_T *) NU_MODBASE(obj->serial.uart)), (UART_INTEN_RDAIEN_Msk | UART_INTEN_THREIEN_Msk | UART_INTEN_RXTOIEN_Msk));
NVIC_DisableIRQ(modinit->irq_n);

if (obj == &stdio_uart) {
// Disable IP clock
CLK_DisableModuleClock(modinit->clkidx);
}

if (var->obj == obj) {
var->obj = NULL;
}

if (obj->serial.uart == STDIO_UART) {
stdio_uart_inited = 0;
}

// Mark this module to be deinited.
int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i);
if (! var->ref_cnt) {
// Mark this module to be deinited.
int i = modinit - uart_modinit_tab;
uart_modinit_mask &= ~(1 << i);
}
}

void serial_baud(serial_t *obj, int baudrate) {
Expand Down Expand Up @@ -317,7 +331,6 @@ void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
MBED_ASSERT(modinit != NULL);
MBED_ASSERT(modinit->modname == obj->serial.uart);

((struct nu_uart_var *) modinit->var)->obj = obj;
obj->serial.irq_handler = (uint32_t) handler;
obj->serial.irq_id = id;

Expand All @@ -335,6 +348,11 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable)
NVIC_SetVector(modinit->irq_n, (uint32_t) obj->serial.vec);
NVIC_EnableIRQ(modinit->irq_n);

struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
// Multiple serial S/W objects for single UART H/W module possibly.
// Bind serial S/W object to UART H/W module as interrupt is enabled.
var->obj = obj;

switch (irq) {
// NOTE: Setting inten_msk first to avoid race condition
case RxIrq:
Expand Down Expand Up @@ -634,7 +652,7 @@ int serial_irq_handler_asynch(serial_t *obj)
int event_rx = 0;
int event_tx = 0;

// Necessary for both interrup way and DMA way
// Necessary for both interrupt way and DMA way
if (serial_is_irq_en(obj, RxIrq)) {
event_rx = serial_rx_event_check(obj);
if (event_rx) {
Expand Down Expand Up @@ -996,9 +1014,9 @@ static void serial_tx_enable_interrupt(serial_t *obj, uint32_t handler, uint8_t
MBED_ASSERT(modinit->modname == obj->serial.uart);

// Necessary for both interrupt way and DMA way
((struct nu_uart_var *) modinit->var)->obj = obj;
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
// With our own async vector, tx/rx handlers can be different.
obj->serial.vec = ((struct nu_uart_var *) modinit->var)->vec_async;
obj->serial.vec = var->vec_async;
obj->serial.irq_handler_tx_async = (void (*)(void)) handler;
serial_irq_set(obj, TxIrq, enable);
}
Expand All @@ -1010,9 +1028,9 @@ static void serial_rx_enable_interrupt(serial_t *obj, uint32_t handler, uint8_t
MBED_ASSERT(modinit->modname == obj->serial.uart);

// Necessary for both interrupt way and DMA way
((struct nu_uart_var *) modinit->var)->obj = obj;
struct nu_uart_var *var = (struct nu_uart_var *) modinit->var;
// With our own async vector, tx/rx handlers can be different.
obj->serial.vec = ((struct nu_uart_var *) modinit->var)->vec_async;
obj->serial.vec = var->vec_async;
obj->serial.irq_handler_rx_async = (void (*) (void)) handler;
serial_irq_set(obj, RxIrq, enable);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,8 @@
#ifndef MBED_DEVICE_H
#define MBED_DEVICE_H

#define DEVICE_PORTIN 1
#define DEVICE_PORTOUT 1
#define DEVICE_PORTINOUT 1

#define DEVICE_INTERRUPTIN 1

#define DEVICE_ANALOGIN 1
#define DEVICE_ANALOGOUT 0

#define DEVICE_SERIAL 1
#define DEVICE_SERIAL_FC 1
#define DEVICE_SERIAL_ASYNCH 1

#define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 1
#define DEVICE_I2C_ASYNCH 1

#define DEVICE_SPI 1
#define DEVICE_SPI_ASYNCH 1
#define DEVICE_SPISLAVE 1


#define DEVICE_RTC 1

#define DEVICE_ETHERNET 0

#define DEVICE_PWMOUT 1

#define DEVICE_SEMIHOST 0
#define DEVICE_LOCALFILESYSTEM 0
#define DEVICE_ID_LENGTH 24

#define DEVICE_SLEEP 1

#define DEVICE_DEBUG_AWARENESS 0

#define DEVICE_STDIO_MESSAGES 1

#define DEVICE_ERROR_RED 0

#define DEVICE_LOWPOWERTIMER 1

#include "objects.h"

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ LR_IROM1 0x00000000 {
; uvisor-lib.a (+RW +ZI)
;}

ARM_LIB_STACK 0x20000000 EMPTY 0x3000 {
ARM_LIB_STACK 0x20000000 EMPTY 0x800 {
}

ER_IRAMVEC 0x20003000 EMPTY (4*(16 + 142)) { ; Reserve for vectors
ER_IRAMVEC 0x20000800 EMPTY (4*(16 + 142)) { ; Reserve for vectors
}

RW_IRAM1 AlignExpr(+0, 16) { ; 16 byte-aligned
Expand Down
Loading