Skip to content

Commit

Permalink
drivers: serial: Rework Silabs Gecko UART Driver
Browse files Browse the repository at this point in the history
Introduces the location property and adds the ability to use values
generated by the device tree configuration.

Signed-off-by: Diego Sueiro <diego.sueiro@gmail.com>
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
  • Loading branch information
diegosueiro authored and galak committed Oct 16, 2018
1 parent eb20984 commit 0c7a28c
Show file tree
Hide file tree
Showing 18 changed files with 330 additions and 149 deletions.
3 changes: 0 additions & 3 deletions boards/arm/efm32hg_slstk3400a/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ if UART_GECKO
config USART_GECKO_1
def_bool y

config USART_GECKO_1_GPIO_LOC
default 4

endif # UART_GECKO

endif # BOARD_EFM32HG_SLSTK3400A
6 changes: 4 additions & 2 deletions boards/arm/efm32hg_slstk3400a/efm32hg_slstk3400a.dts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
compatible = "silabs,efm32hg_slstk3400a", "silabs,efm32hg";

chosen {
zephyr,console = &uart1;
zephyr,console = &usart1;
zephyr,sram = &sram0;
zephyr,flash = &flash0;
};
Expand All @@ -23,6 +23,7 @@
led1 = &led1;
sw0 = &button0;
sw1 = &button1;
usart-1 = &usart1;
};

leds {
Expand Down Expand Up @@ -53,7 +54,8 @@

};

&uart1 {
&usart1 {
current-speed = <115200>;
location = <4>;
status = "ok";
};
3 changes: 0 additions & 3 deletions boards/arm/efm32wg_stk3800/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ if UART_GECKO
config UART_GECKO_0
def_bool y

config UART_GECKO_0_GPIO_LOC
default 1

endif # UART_GECKO

endif # BOARD_EFM32WG_STK3800
5 changes: 5 additions & 0 deletions boards/arm/efm32wg_stk3800/efm32wg_stk3800.dts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
model = "Silicon Labs EFM32WG STK3800 board";
compatible = "silabs,efm32wg_stk3800", "silabs,efm32wg";

aliases {
uart-0 = &uart0;
};

chosen {
zephyr,console = &uart0;
zephyr,sram = &sram0;
Expand Down Expand Up @@ -54,5 +58,6 @@

&uart0 {
current-speed = <115200>;
location = <1>;
status = "ok";
};
3 changes: 0 additions & 3 deletions boards/arm/efr32_slwstk6061a/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ if UART_GECKO
config USART_GECKO_0
def_bool y

config USART_GECKO_0_GPIO_LOC
default 0

endif # UART_GECKO

endif # BOARD_EFR32_SLWSTK6061A
9 changes: 7 additions & 2 deletions boards/arm/efr32_slwstk6061a/efr32_slwstk6061a.dts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@
model = "Silicon Labs EFR32 SLWSTK6061A board";
compatible = "silabs,efr32_slwstk6061a", "silabs,efr32fg1p";

aliases {
usart-0 = &usart0;
};

chosen {
zephyr,console = &uart0;
zephyr,console = &usart0;
zephyr,sram = &sram0;
zephyr,flash = &flash0;
};
Expand Down Expand Up @@ -53,7 +57,8 @@

};

&uart0 {
&usart0 {
current-speed = <115200>;
location = <0>;
status = "ok";
};
205 changes: 144 additions & 61 deletions drivers/serial/uart_gecko.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ static void uart_gecko_init_pins(struct device *dev)
soc_gpio_configure(&config->pin_tx);
#if defined(_USART_ROUTEPEN_MASK) || defined(_UART_ROUTEPEN_MASK)
config->base->ROUTEPEN = USART_ROUTEPEN_RXPEN | USART_ROUTEPEN_TXPEN;
config->base->ROUTELOC0 = (config->loc << _USART_ROUTELOC0_TXLOC_SHIFT) |
config->base->ROUTELOC0 =
(config->loc << _USART_ROUTELOC0_TXLOC_SHIFT) |
(config->loc << _USART_ROUTELOC0_RXLOC_SHIFT);
config->base->ROUTELOC1 = _USART_ROUTELOC1_RESETVALUE;
#else
Expand Down Expand Up @@ -297,35 +298,35 @@ static void uart_gecko_config_func_0(struct device *dev);
#endif

static const struct uart_gecko_config uart_gecko_0_config = {
.base = UART0,
.base = (USART_TypeDef *)CONFIG_UART_GECKO_0_BASE_ADDRESS,
.clock = cmuClock_UART0,
.baud_rate = CONFIG_UART_GECKO_0_BAUD_RATE,
.baud_rate = CONFIG_UART_GECKO_0_CURRENT_SPEED,
.pin_rx = PIN_UART0_RXD,
.pin_tx = PIN_UART0_TXD,
.loc = CONFIG_UART_GECKO_0_GPIO_LOC,
.loc = CONFIG_UART_GECKO_0_LOCATION,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = uart_gecko_config_func_0,
#endif
};

static struct uart_gecko_data uart_gecko_0_data;

DEVICE_AND_API_INIT(uart_0, CONFIG_UART_GECKO_0_NAME,
&uart_gecko_init,
&uart_gecko_0_data, &uart_gecko_0_config,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&uart_gecko_driver_api);
DEVICE_AND_API_INIT(uart_0, CONFIG_UART_GECKO_0_LABEL, &uart_gecko_init, &uart_gecko_0_data,
&uart_gecko_0_config, PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uart_gecko_driver_api);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void uart_gecko_config_func_0(struct device *dev)
{
IRQ_CONNECT(UART0_RX_IRQn, CONFIG_UART_GECKO_0_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(uart_0), 0);
IRQ_CONNECT(UART0_TX_IRQn, CONFIG_UART_GECKO_0_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(uart_0), 0);

irq_enable(UART0_TX_IRQn);
irq_enable(UART0_RX_IRQn);
IRQ_CONNECT(CONFIG_UART_GECKO_0_IRQ_RX,
CONFIG_UART_GECKO_0_IRQ_RX_PRIORITY, uart_gecko_isr,
DEVICE_GET(uart_0), 0);
IRQ_CONNECT(CONFIG_UART_GECKO_0_IRQ_TX,
CONFIG_UART_GECKO_0_IRQ_TX_PRIORITY, uart_gecko_isr,
DEVICE_GET(uart_0), 0);

irq_enable(CONFIG_UART_GECKO_0_IRQ_RX);
irq_enable(CONFIG_UART_GECKO_0_IRQ_TX);
}
#endif

Expand All @@ -338,35 +339,35 @@ static void uart_gecko_config_func_1(struct device *dev);
#endif

static const struct uart_gecko_config uart_gecko_1_config = {
.base = UART1,
.base = (USART_TypeDef *)CONFIG_UART_GECKO_1_BASE_ADDRESS,
.clock = cmuClock_UART1,
.baud_rate = CONFIG_UART_GECKO_1_BAUD_RATE,
.baud_rate = CONFIG_UART_GECKO_1_CURRENT_SPEED,
.pin_rx = PIN_UART1_RXD,
.pin_tx = PIN_UART1_TXD,
.loc = CONFIG_UART_GECKO_1_GPIO_LOC,
.loc = CONFIG_UART_GECKO_1_LOCATION,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = uart_gecko_config_func_1,
#endif
};

static struct uart_gecko_data uart_gecko_1_data;

DEVICE_AND_API_INIT(uart_1, CONFIG_UART_GECKO_1_NAME,
&uart_gecko_init,
&uart_gecko_1_data, &uart_gecko_1_config,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&uart_gecko_driver_api);
DEVICE_AND_API_INIT(uart_1, CONFIG_UART_GECKO_1_LABEL, &uart_gecko_init, &uart_gecko_1_data,
&uart_gecko_1_config, PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uart_gecko_driver_api);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void uart_gecko_config_func_1(struct device *dev)
{
IRQ_CONNECT(UART1_RX_IRQn, CONFIG_UART_GECKO_1_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(uart_1), 0);
IRQ_CONNECT(UART1_TX_IRQn, CONFIG_UART_GECKO_1_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(uart_1), 0);

irq_enable(UART1_RX_IRQn);
irq_enable(UART1_TX_IRQn);
IRQ_CONNECT(CONFIG_UART_GECKO_1_IRQ_RX,
CONFIG_UART_GECKO_1_IRQ_RX_PRIORITY, uart_gecko_isr,
DEVICE_GET(uart_1), 0);
IRQ_CONNECT(CONFIG_UART_GECKO_1_IRQ_TX,
CONFIG_UART_GECKO_1_IRQ_TX_PRIORITY, uart_gecko_isr,
DEVICE_GET(uart_1), 0);

irq_enable(CONFIG_UART_GECKO_1_IRQ_RX);
irq_enable(CONFIG_UART_GECKO_1_IRQ_TX);
}
#endif

Expand All @@ -379,35 +380,35 @@ static void usart_gecko_config_func_0(struct device *dev);
#endif

static const struct uart_gecko_config usart_gecko_0_config = {
.base = USART0,
.base = (USART_TypeDef *)CONFIG_USART_GECKO_0_BASE_ADDRESS,
.clock = cmuClock_USART0,
.baud_rate = CONFIG_USART_GECKO_0_BAUD_RATE,
.baud_rate = CONFIG_USART_GECKO_0_CURRENT_SPEED,
.pin_rx = PIN_USART0_RXD,
.pin_tx = PIN_USART0_TXD,
.loc = CONFIG_USART_GECKO_0_GPIO_LOC,
.loc = CONFIG_USART_GECKO_0_LOCATION,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = usart_gecko_config_func_0,
#endif
};

static struct uart_gecko_data usart_gecko_0_data;

DEVICE_AND_API_INIT(usart_0, CONFIG_USART_GECKO_0_NAME,
&uart_gecko_init,
&usart_gecko_0_data, &usart_gecko_0_config,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&uart_gecko_driver_api);
DEVICE_AND_API_INIT(usart_0, CONFIG_USART_GECKO_0_LABEL, &uart_gecko_init,
&usart_gecko_0_data, &usart_gecko_0_config, PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uart_gecko_driver_api);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void usart_gecko_config_func_0(struct device *dev)
{
IRQ_CONNECT(USART0_RX_IRQn, CONFIG_USART_GECKO_0_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(usart_0), 0);
IRQ_CONNECT(USART0_TX_IRQn, CONFIG_USART_GECKO_0_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(usart_0), 0);

irq_enable(USART0_TX_IRQn);
irq_enable(USART0_RX_IRQn);
IRQ_CONNECT(CONFIG_USART_GECKO_0_IRQ_RX,
CONFIG_USART_GECKO_0_IRQ_RX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_0), 0);
IRQ_CONNECT(CONFIG_USART_GECKO_0_IRQ_TX,
CONFIG_USART_GECKO_0_IRQ_TX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_0), 0);

irq_enable(CONFIG_USART_GECKO_0_IRQ_RX);
irq_enable(CONFIG_USART_GECKO_0_IRQ_TX);
}
#endif

Expand All @@ -420,36 +421,118 @@ static void usart_gecko_config_func_1(struct device *dev);
#endif

static const struct uart_gecko_config usart_gecko_1_config = {
.base = USART1,
.base = (USART_TypeDef *)CONFIG_USART_GECKO_1_BASE_ADDRESS,
.clock = cmuClock_USART1,
.baud_rate = CONFIG_USART_GECKO_1_BAUD_RATE,
.baud_rate = CONFIG_USART_GECKO_1_CURRENT_SPEED,
.pin_rx = PIN_USART1_RXD,
.pin_tx = PIN_USART1_TXD,
.loc = CONFIG_USART_GECKO_1_GPIO_LOC,
.loc = CONFIG_USART_GECKO_1_LOCATION,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = usart_gecko_config_func_1,
#endif
};

static struct uart_gecko_data usart_gecko_1_data;

DEVICE_AND_API_INIT(usart_1, CONFIG_USART_GECKO_1_NAME,
&uart_gecko_init,
&usart_gecko_1_data, &usart_gecko_1_config,
PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
&uart_gecko_driver_api);
DEVICE_AND_API_INIT(usart_1, CONFIG_USART_GECKO_1_LABEL, &uart_gecko_init,
&usart_gecko_1_data, &usart_gecko_1_config, PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uart_gecko_driver_api);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void usart_gecko_config_func_1(struct device *dev)
{
IRQ_CONNECT(USART1_RX_IRQn, CONFIG_USART_GECKO_1_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(usart_1), 0);
IRQ_CONNECT(USART1_TX_IRQn, CONFIG_USART_GECKO_1_IRQ_PRI,
uart_gecko_isr, DEVICE_GET(usart_1), 0);
IRQ_CONNECT(CONFIG_USART_GECKO_1_IRQ_RX,
CONFIG_USART_GECKO_1_IRQ_RX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_1), 0);
IRQ_CONNECT(CONFIG_USART_GECKO_1_IRQ_TX,
CONFIG_USART_GECKO_1_IRQ_TX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_1), 0);

irq_enable(CONFIG_USART_GECKO_1_IRQ_RX);
irq_enable(CONFIG_USART_GECKO_1_IRQ_TX);
}
#endif

#endif /* CONFIG_USART_GECKO_1 */

#ifdef CONFIG_USART_GECKO_2

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void usart_gecko_config_func_2(struct device *dev);
#endif

static const struct uart_gecko_config usart_gecko_2_config = {
.base = (USART_TypeDef *)CONFIG_USART_GECKO_2_BASE_ADDRESS,
.clock = cmuClock_USART2,
.baud_rate = CONFIG_USART_GECKO_2_CURRENT_SPEED,
.pin_rx = PIN_USART2_RXD,
.pin_tx = PIN_USART2_TXD,
.loc = CONFIG_USART_GECKO_2_LOCATION,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = usart_gecko_config_func_2,
#endif
};

irq_enable(USART1_RX_IRQn);
irq_enable(USART1_TX_IRQn);
static struct uart_gecko_data usart_gecko_2_data;

DEVICE_AND_API_INIT(usart_2, CONFIG_USART_GECKO_2_LABEL, &uart_gecko_init,
&usart_gecko_2_data, &usart_gecko_2_config, PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uart_gecko_driver_api);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void usart_gecko_config_func_2(struct device *dev)
{
IRQ_CONNECT(CONFIG_USART_GECKO_2_IRQ_RX,
CONFIG_USART_GECKO_2_IRQ_RX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_2), 0);
IRQ_CONNECT(CONFIG_USART_GECKO_2_IRQ_TX,
CONFIG_USART_GECKO_2_IRQ_TX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_2), 0);

irq_enable(CONFIG_USART_GECKO_2_IRQ_RX);
irq_enable(CONFIG_USART_GECKO_2_IRQ_TX);
}
#endif

#endif /* CONFIG_UART_GECKO_1 */
#endif /* CONFIG_USART_GECKO_2 */

#ifdef CONFIG_USART_GECKO_3

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void usart_gecko_config_func_3(struct device *dev);
#endif

static const struct uart_gecko_config usart_gecko_3_config = {
.base = (USART_TypeDef *)CONFIG_USART_GECKO_3_BASE_ADDRESS,
.clock = cmuClock_USART3,
.baud_rate = CONFIG_USART_GECKO_3_CURRENT_SPEED,
.pin_rx = PIN_USART3_RXD,
.pin_tx = PIN_USART3_TXD,
.loc = CONFIG_USART_GECKO_3_LOCATION,
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
.irq_config_func = usart_gecko_config_func_3,
#endif
};

static struct uart_gecko_data usart_gecko_3_data;

DEVICE_AND_API_INIT(usart_3, CONFIG_USART_GECKO_3_LABEL, &uart_gecko_init,
&usart_gecko_3_data, &usart_gecko_3_config, PRE_KERNEL_1,
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &uart_gecko_driver_api);

#ifdef CONFIG_UART_INTERRUPT_DRIVEN
static void usart_gecko_config_func_3(struct device *dev)
{
IRQ_CONNECT(CONFIG_USART_GECKO_3_IRQ_RX,
CONFIG_USART_GECKO_3_IRQ_RX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_3), 0);
IRQ_CONNECT(CONFIG_USART_GECKO_3_IRQ_TX,
CONFIG_USART_GECKO_3_IRQ_TX_PRIORITY, uart_gecko_isr,
DEVICE_GET(usart_3), 0);

irq_enable(CONFIG_USART_GECKO_3_IRQ_RX);
irq_enable(CONFIG_USART_GECKO_3_IRQ_TX);
}
#endif

#endif /* CONFIG_USART_GECKO_3 */
Loading

0 comments on commit 0c7a28c

Please sign in to comment.