SAMD20: Now runs, but no serial output

This commit is contained in:
Gregory Nutt
2014-02-17 14:21:22 -06:00
parent 93ca836b85
commit 0fd29be0d2
8 changed files with 98 additions and 78 deletions
+5 -5
View File
@@ -96,11 +96,11 @@
*/ */
#define GPIO_PULL_SHIFT (20) /* Bits 20-21: Pull-up/down resistor control */ #define GPIO_PULL_SHIFT (20) /* Bits 20-21: Pull-up/down resistor control */
#define GPIO_PULL_MASK (3 << GPIO_FUNC_SHIFT) #define GPIO_PULL_MASK (3 << GPIO_PULL_SHIFT)
# define GPIO_PULL_NONE (0 << GPIO_FUNC_SHIFT) # define GPIO_PULL_NONE (0 << GPIO_PULL_SHIFT)
# define GPIO_PULL_UP (1 << GPIO_FUNC_SHIFT) # define GPIO_PULL_UP (1 << GPIO_PULL_SHIFT)
# define GPIO_PULL_DOWN (2 << GPIO_FUNC_SHIFT) # define GPIO_PULL_DOWN (2 << GPIO_PULL_SHIFT)
# define GPIO_PULL_BUSKEEPER (3 << GPIO_FUNC_SHIFT) # define GPIO_PULL_BUSKEEPER (3 << GPIO_PULL_SHIFT)
/* Peripheral Function /* Peripheral Function
* *
+11 -11
View File
@@ -116,21 +116,21 @@ sam_wait_synchronization(const struct sam_usart_config_s * const config)
static inline void static inline void
sam_gclk_configure(const struct sam_usart_config_s * const config) sam_gclk_configure(const struct sam_usart_config_s * const config)
{ {
uint8_t regval; uint16_t regval;
uint8_t glckcore; uint8_t glckcore;
/* Set up the SERCOMn_GCLK_ID_CORE clock */ /* Set up the SERCOMn_GCLK_ID_CORE clock */
glckcore = (uint8_t)SERCOM_GCLK_ID_CORE(config->sercom); glckcore = (uint8_t)SERCOM_GCLK_ID_CORE(config->sercom);
regval = (glckcore << GCLK_CLKCTRL_ID_SHIFT); regval = ((uint16_t)glckcore << GCLK_CLKCTRL_ID_SHIFT);
/* Select and disable generic clock channel */ /* Select and disable generic clock channel */
putreg8(regval, SAM_GCLK_CLKCTRL); putreg16(regval, SAM_GCLK_CLKCTRL);
/* Wait for clock to become disabled */ /* Wait for clock to become disabled */
while ((getreg8(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0); while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0);
/* Select the SERCOMn_GCLK_ID_CORE clock generator */ /* Select the SERCOMn_GCLK_ID_CORE clock generator */
@@ -147,12 +147,12 @@ sam_gclk_configure(const struct sam_usart_config_s * const config)
/* Write the new configuration */ /* Write the new configuration */
putreg8(regval, SAM_GCLK_CLKCTRL); putreg16(regval, SAM_GCLK_CLKCTRL);
/* Enable the GCLK */ /* Enable the GCLK */
regval |= GCLK_CLKCTRL_CLKEN; regval |= GCLK_CLKCTRL_CLKEN;
putreg8(regval, SAM_GCLK_CLKCTRL); putreg16(regval, SAM_GCLK_CLKCTRL);
/* Set up the SERCOM_GCLK_ID_SLOW clock */ /* Set up the SERCOM_GCLK_ID_SLOW clock */
@@ -160,11 +160,11 @@ sam_gclk_configure(const struct sam_usart_config_s * const config)
/* Select and disable generic clock channel */ /* Select and disable generic clock channel */
putreg8(regval, SAM_GCLK_CLKCTRL); putreg16(regval, SAM_GCLK_CLKCTRL);
/* Wait for clock to become disabled */ /* Wait for clock to become disabled */
while ((getreg8(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0); while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0);
/* Select the SERCOM_GCLK_ID_SLOW clock generator */ /* Select the SERCOM_GCLK_ID_SLOW clock generator */
@@ -181,12 +181,12 @@ sam_gclk_configure(const struct sam_usart_config_s * const config)
/* Write the new configuration */ /* Write the new configuration */
putreg8(regval, SAM_GCLK_CLKCTRL); putreg16(regval, SAM_GCLK_CLKCTRL);
/* Enable the GCLK */ /* Enable the GCLK */
regval |= GCLK_CLKCTRL_CLKEN; regval |= GCLK_CLKCTRL_CLKEN;
putreg8(regval, SAM_GCLK_CLKCTRL); putreg16(regval, SAM_GCLK_CLKCTRL);
} }
#endif #endif
@@ -317,7 +317,7 @@ sam_usart_configure(const struct sam_usart_config_s * const config)
/* Write configuration to CTRLA */ /* Write configuration to CTRLA */
putreg32(ctrlb, config->base + SAM_USART_CTRLA_OFFSET); putreg32(ctrla, config->base + SAM_USART_CTRLA_OFFSET);
return OK; return OK;
} }
#endif #endif
+5 -5
View File
@@ -146,7 +146,7 @@ static inline void sam_configinput(uintptr_t base, port_pinset_t pinset)
{ {
/* Select the upper half word and adjust the bit setting */ /* Select the upper half word and adjust the bit setting */
regval = PORT_WRCONFIG_HWSEL; regval |= PORT_WRCONFIG_HWSEL;
pin -= 16; pin -= 16;
} }
@@ -243,7 +243,7 @@ static inline void sam_configoutput(uintptr_t base, port_pinset_t pinset)
{ {
/* Select the upper half word and adjust the bit setting */ /* Select the upper half word and adjust the bit setting */
regval = PORT_WRCONFIG_HWSEL; regval |= PORT_WRCONFIG_HWSEL;
pin -= 16; pin -= 16;
} }
@@ -320,7 +320,7 @@ static inline void sam_configperiph(uintptr_t base, port_pinset_t pinset)
{ {
/* Select the upper half word and adjust the bit setting */ /* Select the upper half word and adjust the bit setting */
regval = PORT_WRCONFIG_HWSEL; regval |= PORT_WRCONFIG_HWSEL;
pin -= 16; pin -= 16;
} }
@@ -329,7 +329,7 @@ static inline void sam_configperiph(uintptr_t base, port_pinset_t pinset)
/* Set the pin function */ /* Set the pin function */
func = (pinset & PORT_FUNC_MASK) >> PORT_FUNC_SHIFT; func = (pinset & PORT_FUNC_MASK) >> PORT_FUNC_SHIFT;
regval = (func << PORT_WRCONFIG_PMUX_SHIFT); regval |= (func << PORT_WRCONFIG_PMUX_SHIFT);
/* Check for pull-up/down selection */ /* Check for pull-up/down selection */
@@ -401,7 +401,7 @@ static inline void sam_configreset(uintptr_t base, port_pinset_t pinset)
{ {
/* Select the upper half word and adjust the bit setting */ /* Select the upper half word and adjust the bit setting */
regval = PORT_WRCONFIG_HWSEL; regval |= PORT_WRCONFIG_HWSEL;
pin -= 16; pin -= 16;
} }
+4 -4
View File
@@ -106,10 +106,10 @@
*/ */
#define PORT_PULL_SHIFT (20) /* Bits 20-21: Pull-up/down resistor control */ #define PORT_PULL_SHIFT (20) /* Bits 20-21: Pull-up/down resistor control */
#define PORT_PULL_MASK (3 << PORT_FUNC_SHIFT) #define PORT_PULL_MASK (3 << PORT_PULL_SHIFT)
# define PORT_PULL_NONE (0 << PORT_FUNC_SHIFT) # define PORT_PULL_NONE (0 << PORT_PULL_SHIFT)
# define PORT_PULL_UP (1 << PORT_FUNC_SHIFT) # define PORT_PULL_UP (1 << PORT_PULL_SHIFT)
# define PORT_PULL_DOWN (2 << PORT_FUNC_SHIFT) # define PORT_PULL_DOWN (2 << PORT_PULL_SHIFT)
/* Peripheral Function /* Peripheral Function
* *
+27 -8
View File
@@ -660,15 +660,21 @@ static int sam_usart5_interrupt(int irq, void *context)
static int sam_setup(struct uart_dev_s *dev) static int sam_setup(struct uart_dev_s *dev)
{ {
int ret = 0;
#ifndef CONFIG_SUPPRESS_UART_CONFIG #ifndef CONFIG_SUPPRESS_UART_CONFIG
struct sam_dev_s *priv = (struct sam_dev_s*)dev->priv; struct sam_dev_s *priv = (struct sam_dev_s*)dev->priv;
/* Configure the SERCOM as a USART */ /* Configure the SERCOM as a USART. Don't reconfigure the console UART;
* that was already done in sam_lowputc.c.
*/
return sam_usart_initialize(priv->config); if (!dev->isconsole)
#else {
return OK; ret = sam_usart_initialize(priv->config);
}
#endif #endif
return ret;
} }
/**************************************************************************** /****************************************************************************
@@ -676,7 +682,7 @@ static int sam_setup(struct uart_dev_s *dev)
* *
* Description: * Description:
* Disable the USART. This method is called when the serial port is * Disable the USART. This method is called when the serial port is
* closed * closed. The exception is the serial console which is never shutdown.
* *
****************************************************************************/ ****************************************************************************/
@@ -685,11 +691,15 @@ static void sam_shutdown(struct uart_dev_s *dev)
struct sam_dev_s *priv = (struct sam_dev_s*)dev->priv; struct sam_dev_s *priv = (struct sam_dev_s*)dev->priv;
/* Resetting the SERCOM restores all registers to the reget state and /* Resetting the SERCOM restores all registers to the reget state and
* disables the SERCOM. * disables the SERCOM. Ignore any requests to shutown the console
* device (shouldn't happen).
*/ */
if (!dev->isconsole)
{
sam_usart_reset(priv->config); sam_usart_reset(priv->config);
} }
}
/**************************************************************************** /****************************************************************************
* Name: sam_attach * Name: sam_attach
@@ -743,7 +753,13 @@ static void sam_detach(struct uart_dev_s *dev)
struct sam_dev_s *priv = (struct sam_dev_s*)dev->priv; struct sam_dev_s *priv = (struct sam_dev_s*)dev->priv;
const struct sam_usart_config_s * const config = priv->config; const struct sam_usart_config_s * const config = priv->config;
/* Disable interrupts at the SERCOM device and at the NVIC */
sam_disableallints(priv);
up_disable_irq(config->irq); up_disable_irq(config->irq);
/* Detach the interrupt handler */
irq_detach(config->irq); irq_detach(config->irq);
} }
@@ -933,6 +949,10 @@ static bool sam_txempty(struct uart_dev_s *dev)
* serial console will be available during bootup. This must be called * serial console will be available during bootup. This must be called
* before sam_serialinit. * before sam_serialinit.
* *
* NOTE: On this platform up_earlyserialinit() does not really do
* anything of consequence and probably could be eliminated with little
* effort.
*
****************************************************************************/ ****************************************************************************/
void up_earlyserialinit(void) void up_earlyserialinit(void)
@@ -956,11 +976,10 @@ void up_earlyserialinit(void)
sam_disableallints(TTYS5_DEV.priv); sam_disableallints(TTYS5_DEV.priv);
#endif #endif
/* Configuration whichever one is the console */ /* Mark the serial console (if any) */
#ifdef HAVE_SERIAL_CONSOLE #ifdef HAVE_SERIAL_CONSOLE
CONSOLE_DEV.isconsole = true; CONSOLE_DEV.isconsole = true;
sam_setup(&CONSOLE_DEV);
#endif #endif
} }
+1 -1
View File
@@ -406,7 +406,7 @@ Serial Consoles
SERCOM4 is available on connectors EXT1 and EXT3 SERCOM4 is available on connectors EXT1 and EXT3
PIN EXT1 EXT3 GPIO Function PIN EXT1 EXT3 GPIO Function
---- ---- ------ ----------- ---- ---- ---- ------------------
13 PB09 PB13 SERCOM4 / USART RX 13 PB09 PB13 SERCOM4 / USART RX
14 PB08 PB12 SERCOM4 / USART TX 14 PB08 PB12 SERCOM4 / USART TX
19 19 GND 19 19 GND
+1
View File
@@ -59,6 +59,7 @@
* OSC8M Output = 8MHz * OSC8M Output = 8MHz
* `- GCLK1 Input = 8MHz Prescaler = 1 output = 8MHz * `- GCLK1 Input = 8MHz Prescaler = 1 output = 8MHz
* `- DFLL Input = 8MHz Multiplier = 6 output = 48MHz * `- DFLL Input = 8MHz Multiplier = 6 output = 48MHz
* `- GCLK0 Input = 48MHz Prescaler = 1 output = 48MHz
* `- PM Input = 48Mhz CPU divider = 1 CPU frequency = 48MHz * `- PM Input = 48Mhz CPU divider = 1 CPU frequency = 48MHz
* APBA divider = 1 APBA frequency = 48MHz * APBA divider = 1 APBA frequency = 48MHz
* APBB divider = 1 APBB frequency = 48MHz * APBB divider = 1 APBB frequency = 48MHz